using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Ninject; using V3.Camera; using V3.Data; using V3.Effects; using V3.Input; using V3.Map; using V3.Objects; namespace V3.Screens { // ReSharper disable once ClassNeverInstantiated.Global public class TechdemoScreen : AbstractScreen, IInitializable { private enum Creatures { Empty, Zombie, Skeleton, Peasant, Knight } private Creatures mCreatePerKey; private readonly CameraManager mCameraManager; private readonly ContentManager mContentManager; private readonly CreatureFactory mCreatureFactory; private readonly GraphicsDeviceManager mGraphicsDeviceManager; private readonly MenuActions mMenuActions; private readonly IOptionsManager mOptionsManager; private readonly IEffectsManager mEffectsManager; private readonly Selection mSelection; private readonly Transformation mTransformation; private readonly IMapManager mMapManager; private readonly IObjectsManager mObjectsManager; private readonly Pathfinder mPathfinder; private readonly Texture2D mOnePixelTexture; // Fields for handling mouse input. private Point mInitialClickPosition; private bool mLeftButtonPressed; private bool mRightButtonPressed; private Vector2 mRightButtonPosition; /// /// Creates a new game screen. /// public TechdemoScreen(IOptionsManager optionsManager, CameraManager cameraManager, ContentManager contentManager, CreatureFactory creatureFactory, GraphicsDeviceManager graphicsDeviceManager, IMapManager mapManager, MenuActions menuActions, IObjectsManager objectsManager, Pathfinder pathfinder, Selection selection, Transformation transformation, IEffectsManager effectsManager) : base(false, false) { mMapManager = mapManager; mObjectsManager = objectsManager; mCameraManager = cameraManager; mOptionsManager = optionsManager; mContentManager = contentManager; mCreatureFactory = creatureFactory; mEffectsManager = effectsManager; mTransformation = transformation; mGraphicsDeviceManager = graphicsDeviceManager; mMenuActions = menuActions; mPathfinder = pathfinder; mSelection = selection; mOnePixelTexture = contentManager.Load("Sprites/WhiteRectangle"); } public override bool HandleMouseEvent(IMouseEvent mouseEvent) { if (mouseEvent.MouseButton == MouseButton.Left && mouseEvent.ButtonState == ButtonState.Pressed) { if (!mLeftButtonPressed) { mLeftButtonPressed = true; mInitialClickPosition = mouseEvent.PositionPressed; } } else { if (mLeftButtonPressed) { mSelection.Select(mInitialClickPosition + mCameraManager.GetCamera().Location.ToPoint(), mouseEvent.PositionReleased.GetValueOrDefault() + mCameraManager.GetCamera().Location.ToPoint()); mLeftButtonPressed = false; } } if (mouseEvent.MouseButton == MouseButton.Right && mouseEvent.ButtonState == ButtonState.Pressed) { if (!mRightButtonPressed) { mRightButtonPressed = true; mInitialClickPosition = mouseEvent.PositionPressed; } } if (mouseEvent.MouseButton == MouseButton.Right && mouseEvent.ButtonState == ButtonState.Released) { if (mouseEvent.PositionReleased != null && mouseEvent.ReleasedOnScreen) { mRightButtonPressed = false; mRightButtonPosition = mouseEvent.PositionReleased.Value.ToVector2() + mCameraManager.GetCamera().Location; mSelection.Move(mouseEvent.PositionReleased.Value.ToVector2() + mCameraManager.GetCamera().Location); } } if (mouseEvent.ReleasedOnScreen) { var position = mouseEvent.PositionPressed.ToVector2() + mCameraManager.GetCamera().Location; switch (mCreatePerKey) { case Creatures.Zombie: mObjectsManager.CreateCreature(mCreatureFactory.CreateZombie(position, MovementDirection.S)); break; case Creatures.Skeleton: mObjectsManager.CreateCreature(mCreatureFactory.CreateSkeleton(position, MovementDirection.S)); break; case Creatures.Peasant: mObjectsManager.CreateCreature(mCreatureFactory.CreateMalePeasant(position, MovementDirection.S)); break; case Creatures.Knight: mObjectsManager.CreateCreature(mCreatureFactory.CreateKnight(position, MovementDirection.S)); break; } } return true; } public void Initialize() { mMapManager.Load("techdemo"); mObjectsManager.Initialize(mMapManager); mCameraManager.Initialize(mMapManager.SizeInPixel); mPathfinder.LoadGrid(mMapManager.GetPathfindingGrid()); mTransformation.mSelection = mSelection; mTransformation.LoadArea(mContentManager); // Add creatures for testing purposes. var necromancer = mCreatureFactory.CreateNecromancer(new Vector2(1592, 1609), MovementDirection.S); var king = mCreatureFactory.CreateKing(new Vector2(1500, 200), MovementDirection.S); mObjectsManager.CreatePlayerCharacter(necromancer); mObjectsManager.CreateBoss(king); int makeCreatureStrongerModifier = 100; int makePeasantsNotSoMuchStrongerModifier = 10; AddCreature(new Point(4), new Point(200, 2000), new Point(2800, 3000), makePeasantsNotSoMuchStrongerModifier); AddCreature(new Point(4), new Point(232, 2032), new Point(2800, 3000), makePeasantsNotSoMuchStrongerModifier); AddCreature(new Point(4), new Point(200, 200), new Point(2800, 1000), makeCreatureStrongerModifier); AddCreature(new Point(4), new Point(232, 232), new Point(2800, 1000), makeCreatureStrongerModifier); AddCreature(new Point(3), new Point(264, 264), new Point(2800, 1000), makeCreatureStrongerModifier); AddCreature(new Point(3), new Point(290, 290), new Point(2800, 1000), makeCreatureStrongerModifier); AddCreature(new Point(4), new Point(264, 2064), new Point(2800, 3000), makeCreatureStrongerModifier); mTransformation.ObjectsManager = mObjectsManager; } /// /// Add a generic creature to Techdemo. /// Using pixel coordinates for calculating start and end point of map. /// /// /// Density on X and Y axis. More creatures when lower. /// Start point for creating the creature batallion. /// At which point to stop creating creatures. /// Give more HP. Better for testing. private void AddCreature(Point density, Point start, Point end, int makeStronger) where T:ICreature { var type = typeof(T); for (int i = start.Y; i < end.Y; i += 32 * density.Y) { for (int j = start.X; j < end.X; j += 32 * density.X) { Vector2 position = new Vector2(j, i); ICreature creature; if (type == typeof(MalePeasant)) { creature = mCreatureFactory.CreateMalePeasant(position, MovementDirection.S); } else if (type == typeof(FemalePeasant)) { creature = mCreatureFactory.CreateFemalePeasant(position, MovementDirection.S); } else if (type == typeof(Skeleton)) { creature = mCreatureFactory.CreateSkeleton(position, MovementDirection.S); } else if (type == typeof(Zombie)) { creature = mCreatureFactory.CreateZombie(position, MovementDirection.S); } else if (type == typeof(Knight)) { creature = mCreatureFactory.CreateKnight(position, MovementDirection.S); } else if (type == typeof(SkeletonHorse)) { creature = mCreatureFactory.CreateSkeletonHorse(position, MovementDirection.S); } else if (type == typeof(Meatball)) { creature = mCreatureFactory.CreateMeatball(position, MovementDirection.S); } else if (type == typeof(KingsGuard)) { creature = mCreatureFactory.CreateKingsGuard(position, MovementDirection.S); } else if (type == typeof(SkeletonElite)) { creature = mCreatureFactory.CreateSkeletonElite(position, MovementDirection.S); } else { creature = mCreatureFactory.CreateZombie(position, MovementDirection.S); } creature.Empower(makeStronger); mObjectsManager.CreateCreature(creature); } } } public override bool HandleKeyEvent(IKeyEvent keyEvent) { if (keyEvent.KeyState == KeyState.Down) { Creatures createPerKey = Creatures.Empty; switch (keyEvent.Key) { case Keys.Escape: mMenuActions.OpenPauseScreen(); break; case Keys.F1: createPerKey = Creatures.Zombie; break; case Keys.F2: createPerKey = Creatures.Skeleton; break; case Keys.F3: createPerKey = Creatures.Peasant; break; case Keys.F4: createPerKey = Creatures.Knight; break; case Keys.F5: Rectangle cameraRectangle = mCameraManager.GetCamera().ScreenRectangle; mEffectsManager.PlayOnce(new SmokeBig(), cameraRectangle.Center, cameraRectangle.Size); mObjectsManager.ExposeTheLiving(); break; case Keys.F6: (mObjectsManager.PlayerCharacter as Necromancer)?.ChangeSex(); mEffectsManager.PlayOnce(new SmokeSmall(), mObjectsManager.PlayerCharacter.Position.ToPoint(), new Point(256)); break; } if (createPerKey == mCreatePerKey) { mCreatePerKey = Creatures.Empty; } else { mCreatePerKey = createPerKey; } } return true; } /// /// Updates the status of this object. /// /// a snapshot of the game time public override void Update(GameTime gameTime) { #if DEBUG #else try { #endif mObjectsManager.Update(gameTime, mRightButtonPressed, mRightButtonPosition, mCameraManager.GetCamera()); mCameraManager.Update(mObjectsManager.PlayerCharacter); mEffectsManager.Update(gameTime); // Call for Transformations mTransformation.Transform(); mSelection.UpdateSelection(); #if DEBUG #else } catch (System.Exception e) { System.Console.WriteLine(e.Message); } #endif } /// /// Draws this object using the given sprite batch. /// /// a snapshot of the game time /// the sprite batch to use for drawing /// this object public override void Draw(GameTime gameTime, SpriteBatch spriteBatch) { mGraphicsDeviceManager.GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, mCameraManager.GetCamera().Transform); mMapManager.DrawFloor(spriteBatch, mCameraManager.GetCamera()); mObjectsManager.Draw(spriteBatch, mCameraManager.GetCamera()); mTransformation.DrawNecroArea(spriteBatch); mEffectsManager.Draw(spriteBatch); if (mLeftButtonPressed) mSelection.Draw(spriteBatch, mInitialClickPosition + mCameraManager.GetCamera().Location.ToPoint(), Mouse.GetState().Position + mCameraManager.GetCamera().Location.ToPoint()); if (mOptionsManager.Options.DebugMode == DebugMode.Full) { mMapManager.DrawPathfindingGrid(spriteBatch, mCameraManager.GetCamera()); mObjectsManager.DrawQuadtree(spriteBatch); DrawLastSelection(spriteBatch, mSelection.LastSelection); } // Draws the selection rectangle when left mouse button is pressed. spriteBatch.End(); } private void DrawLastSelection(SpriteBatch spriteBatch, Rectangle selection) { spriteBatch.Draw(mOnePixelTexture, selection, new Color(Color.Black, 100)); } } }