using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Revitalize.Framework.Minigame.SeasideScrambleMinigame; using StardewValley; using StardustCore.UIUtilities; namespace Revitalize.Framework.Minigame.SeasideScrambleMinigame { /// /// TODO: Finish character select screen. /// -Make Sound effects happen /// -make prompt for color selection /// -a,d for keyboard /// -dpad for p2-4 /// Also add interface for game entity for camera to consistently have a focus target. /// -Make moving target enemies /// -Make a sound effect play when they break /// -Fix positioning of status effects on player HUD /// -Add effect on player for a more visual representation of status effects. /// /// -Make shooting gallary game mode /// -Make shooting gallery map wider. /// -Add in score system for shooting gallery mode. /// /// -Make More guns /// public class SeasideScramble : StardewValley.Minigames.IMinigame { /// /// A static reference to the game. /// public static SeasideScramble self; public SeasideScrambleMap currentMap; public Dictionary SeasideScrambleMaps; public int currentNumberOfPlayers { get { return this.players.Count; } } public const int maxPlayers = 4; public Dictionary players; public bool quitGame; public Vector2 topLeftScreenCoordinate; public SSCTextureUtilities textureUtils; public SSCCamera camera; public SSCMenus.SSCMenuManager menuManager; public Vector2 oldMousePosition; public SSCEntities.SSCEntityManager entities; public SSCGuns.SSCGunManager guns; public SSCFonts.SSCFont gameFont; /// /// The current game mode. /// public SSCEnums.SSCGameMode gameMode; public bool friendlyFireEnabled; /// /// RNG. /// public Random random { get { return Game1.random; } } /// /// Constuctor. /// public SeasideScramble() { self = this; this.camera = new SSCCamera(); //this.viewport = new xTile.Dimensions.Rectangle(StardewValley.Game1.viewport); this.topLeftScreenCoordinate = new Vector2((float)(this.camera.viewport.Width / 2 - 384), (float)(this.camera.viewport.Height / 2 - 384)); this.LoadTextures(); this.entities = new SSCEntities.SSCEntityManager(); this.LoadMaps(); this.loadStartingMap(); this.quitGame = false; this.players = new Dictionary(); //this.players.Add(SSCEnums.PlayerID.One, new SSCPlayer(SSCEnums.PlayerID.One)); //this.getPlayer(SSCEnums.PlayerID.One).setColor(Color.PaleVioletRed); this.menuManager = new SSCMenus.SSCMenuManager(); this.menuManager.addNewMenu(new SSCMenus.TitleScreen(this.camera.viewport)); this.oldMousePosition = new Vector2(Game1.getMousePosition().X, Game1.getMousePosition().Y); this.gameFont = new SSCFonts.SSCFont(new SSCFonts.SSCFontCharacterSheet()); this.guns = new SSCGuns.SSCGunManager(); } public SSCPlayer getPlayer(SSCEnums.PlayerID id) { if (this.players.ContainsKey(id)) { return this.players[id]; } else return null; } /// /// Loads in all of the necessary textures for Seaside Scramble. /// private void LoadTextures() { this.textureUtils = new SSCTextureUtilities(); TextureManager playerManager = new TextureManager("SSCPlayer"); playerManager.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Graphics", "Player")); TextureManager mapTextureManager = new TextureManager("SSCMaps"); mapTextureManager.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Maps", "Backgrounds")); TextureManager UIManager = new TextureManager("SSCUI"); UIManager.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Graphics", "UI")); TextureManager projectileManager = new TextureManager("Projectiles"); projectileManager.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Graphics", "Projectiles")); TextureManager gunManager = new TextureManager("Guns"); gunManager.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Graphics", "Guns")); TextureManager enemies = new TextureManager("Enemies"); enemies.searchForTextures(ModCore.ModHelper, ModCore.Manifest, Path.Combine("Content", "Minigames", "SeasideScramble", "Graphics", "Enemies")); this.textureUtils.addTextureManager(playerManager); this.textureUtils.addTextureManager(mapTextureManager); this.textureUtils.addTextureManager(UIManager); this.textureUtils.addTextureManager(projectileManager); this.textureUtils.addTextureManager(gunManager); this.textureUtils.addTextureManager(enemies); } /// /// Loads in all of the maps for Seaside Scramble. /// private void LoadMaps() { this.SeasideScrambleMaps = new Dictionary(); this.SeasideScrambleMaps.Add("TestRoom", new SeasideScrambleMap(SeasideScrambleMap.LoadMap("TestRoom.tbin").Value)); this.SeasideScrambleMaps.Add("ShootingGallery", new SSCMaps.ShootingGallery(SeasideScrambleMap.LoadMap("ShootingGallery.tbin").Value)); } /// /// Loads in a default map for Seaside Scramble. /// private void loadStartingMap() { this.currentMap = this.SeasideScrambleMaps["ShootingGallery"]; } /// /// What happens when the screen changes size. /// public void changeScreenSize() { Viewport viewport = StardewValley.Game1.graphics.GraphicsDevice.Viewport; double num1 = (double)(viewport.Width / 2 - 384); viewport = StardewValley.Game1.graphics.GraphicsDevice.Viewport; double num2 = (double)(viewport.Height / 2 - 384); this.topLeftScreenCoordinate = new Vector2((float)num1, (float)num2); this.camera.viewport = new xTile.Dimensions.Rectangle(StardewValley.Game1.viewport); //throw new NotImplementedException(); } /// /// Used to update Stardew Valley while this minigame runs. True means SDV updates false means the SDV pauses all update ticks. /// /// public bool doMainGameUpdates() { return false; //throw new NotImplementedException(); } /// /// Draws all game aspects to the screen. /// /// public void draw(SpriteBatch b) { if (this.currentMap != null) { this.currentMap.draw(b); } b.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null); foreach(SSCPlayer p in this.players.Values) { p.draw(b); } /* if (this.menuManager.activeMenu != null) { this.menuManager.activeMenu.draw(b); } */ foreach (SSCPlayer p in this.players.Values) { p.drawHUD(b); if (p.playerID == SSCEnums.PlayerID.One) { p.drawMouse(b); } } this.entities.draw(b); this.menuManager.drawAll(b); b.End(); } /// /// The id of the minigame??? /// /// public string minigameId() { return "Seaside Scramble Stardew Lite Edition"; //throw new NotImplementedException(); } /// /// Sets the game mode for the game. /// /// public void setMode(SSCEnums.SSCGameMode Mode) { if (Mode == SSCEnums.SSCGameMode.None) { this.friendlyFireEnabled = false; } if(Mode== SSCEnums.SSCGameMode.ShootingGallery) { this.friendlyFireEnabled = true; } if(Mode== SSCEnums.SSCGameMode.PVP) { this.friendlyFireEnabled = true; } if(Mode== SSCEnums.SSCGameMode.Story) { this.friendlyFireEnabled = false; } this.gameMode = Mode; } //~~~~~~~~~~~~~~~~~// // Input Logic // //~~~~~~~~~~~~~~~~~// #region /// /// What happens when the left click is held. /// /// /// public void leftClickHeld(int x, int y) { //throw new NotImplementedException(); } /// /// Does this override free mous emovements? /// /// public bool overrideFreeMouseMovement() { return true; //throw new NotImplementedException(); } /// /// ??? Undocumended. /// /// public void receiveEventPoke(int data) { //throw new NotImplementedException(); } /// /// What happens when a key is pressed. /// /// public void receiveKeyPress(Keys k) { //throw new NotImplementedException(); if (k == Keys.Escape) { this.quitGame = true; } foreach(SSCPlayer player in this.players.Values) { player.receiveKeyPress(k); } if (this.menuManager.isMenuUp) { this.menuManager.activeMenu.receiveKeyPress(k); } } /// /// Gets a gamepad state. /// /// /// public GamePadState getGamepadState(PlayerIndex index) { return Microsoft.Xna.Framework.Input.GamePad.GetState(index); } /// /// Called when the minigame registeres a key on the keyboard being released. /// /// public void receiveKeyRelease(Keys K) { foreach (SSCPlayer player in this.players.Values) { player.receiveKeyRelease(K); } } /// /// Called when the minigame receives a left click. /// /// /// /// public void receiveLeftClick(int x, int y, bool playSound = true) { if (this.menuManager.activeMenu != null) { this.menuManager.activeMenu.receiveLeftClick(x, y, playSound); } foreach(SSCPlayer player in this.players.Values) { player.receiveLeftClick(x, y); } //throw new NotImplementedException(); } /// /// Called when the minigame receives a right click. /// /// /// /// public void receiveRightClick(int x, int y, bool playSound = true) { if (this.menuManager.activeMenu != null) { this.menuManager.activeMenu.receiveRightClick(x, y, playSound); } } /// /// What happens when left click is released. /// /// /// public void releaseLeftClick(int x, int y) { //throw new NotImplementedException(); } /// /// What happens when right click is released. /// /// /// public void releaseRightClick(int x, int y) { //throw new NotImplementedException(); } /// /// Receive input from a specific gamepad. /// /// /// private void receiveGamepadInput(GamePadState state,SSCEnums.PlayerID ID) { if (state == null) return; else { if (this.players.ContainsKey(ID)) { this.players[ID].receiveGamepadInput(state); } } } /// /// Returns the delta for mouse movement. /// /// public Vector2 getMouseDelta() { Vector2 ret = -1 * (this.oldMousePosition - new Vector2(Game1.getMousePosition().X, Game1.getMousePosition().Y)); return ret; } #endregion /// /// Called every update frame. /// /// /// public bool tick(GameTime time) { KeyboardState kState = Keyboard.GetState(); foreach (Keys k in kState.GetPressedKeys()) { this.receiveKeyPress(k); } for (int i = 0; i < 4; i++) { GamePadState state = this.getGamepadState((PlayerIndex)i); this.receiveGamepadInput(state,(SSCEnums.PlayerID)i); } if (this.quitGame) { return true; } if (this.currentMap != null) { this.currentMap.update(time); } if (this.menuManager.activeMenu != null) { this.menuManager.activeMenu.update(time); if (this.menuManager.activeMenu.readyToClose()) { this.menuManager.closeActiveMenu(); } foreach (SSCPlayer player in this.players.Values) { player.update(time); } } else { foreach (SSCPlayer player in this.players.Values) { if (player.playerID == SSCEnums.PlayerID.One) this.camera.centerOnPosition(player.position); player.update(time); } this.entities.update(time); } this.oldMousePosition = new Vector2(Game1.getOldMouseX(), Game1.getOldMouseY()); return false; //throw new NotImplementedException(); } /// /// Called when the minigame is quit upon. /// public void unload() { //throw new NotImplementedException(); ModCore.log("Exit the game!"); } //~~~~~~~~~~~~~~~~~~~~// // Static Functions // //~~~~~~~~~~~~~~~~~~~~// #region /// /// Translates the position passed in into the relative position on the viewport. /// /// /// /// public static Vector2 GlobalToLocal(xTile.Dimensions.Rectangle viewport, Vector2 globalPosition) { return new Vector2(globalPosition.X - (float)viewport.X, globalPosition.Y - (float)viewport.Y); } /// /// Translates the position passed in into the relative position on the viewport. /// /// /// public static Vector2 GlobalToLocal(Vector2 globalPosition) { return new Vector2(globalPosition.X - (float)SeasideScramble.self.camera.viewport.X, globalPosition.Y - (float)SeasideScramble.self.camera.viewport.Y); } #endregion } }