2019-07-18 01:18:51 +08:00
|
|
|
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 StardustCore.UIUtilities;
|
|
|
|
namespace Revitalize.Framework.Minigame.SeasideScrambleMinigame
|
|
|
|
{
|
2019-07-19 11:16:41 +08:00
|
|
|
/// <summary>
|
|
|
|
/// TODO: Finish character select screen. Ensure that camera snapping doesn't happen until game starts.
|
2019-07-19 13:11:46 +08:00
|
|
|
/// -Make boxes per character
|
|
|
|
/// -Make prompt to click for p1, press a for p2,3,4
|
|
|
|
/// -Make Sound effects happen
|
|
|
|
/// -make prompt for color selection
|
|
|
|
/// -a,d for keyboard
|
|
|
|
/// -dpad for p2-4
|
2019-07-19 11:16:41 +08:00
|
|
|
/// Also add interface for game entity for camera to consistently have a focus target.
|
|
|
|
/// </summary>
|
2019-07-18 01:18:51 +08:00
|
|
|
public class SeasideScramble : StardewValley.Minigames.IMinigame
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
public static SeasideScramble self;
|
|
|
|
|
|
|
|
SeasideScrambleMap currentMap;
|
2019-07-19 08:16:17 +08:00
|
|
|
public Dictionary<string, SeasideScrambleMap> SeasideScrambleMaps;
|
|
|
|
|
2019-07-19 13:10:05 +08:00
|
|
|
public int currentNumberOfPlayers
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return this.players.Count;
|
|
|
|
}
|
|
|
|
}
|
2019-07-18 01:18:51 +08:00
|
|
|
public const int maxPlayers = 4;
|
2019-07-19 08:16:17 +08:00
|
|
|
public Dictionary<SSCEnums.PlayerID, SSCPlayer> players;
|
2019-07-18 01:18:51 +08:00
|
|
|
|
|
|
|
public bool quitGame;
|
2019-07-18 03:30:08 +08:00
|
|
|
public Vector2 topLeftScreenCoordinate;
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
public SSCTextureUtilities textureUtils;
|
|
|
|
|
2019-07-18 03:30:08 +08:00
|
|
|
public SSCCamera camera;
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
public SSCMenus.SSCMenuManager menuManager;
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
public SeasideScramble()
|
|
|
|
{
|
|
|
|
self = this;
|
2019-07-18 03:30:08 +08:00
|
|
|
this.camera = new SSCCamera();
|
|
|
|
//this.viewport = new xTile.Dimensions.Rectangle(StardewValley.Game1.viewport);
|
2019-07-18 07:26:37 +08:00
|
|
|
this.topLeftScreenCoordinate = new Vector2((float)(this.camera.viewport.Width / 2 - 384), (float)(this.camera.viewport.Height / 2 - 384));
|
2019-07-18 03:30:08 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
this.LoadTextures();
|
|
|
|
|
|
|
|
this.LoadMaps();
|
|
|
|
this.loadStartingMap();
|
|
|
|
this.quitGame = false;
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
this.players = new Dictionary<SSCEnums.PlayerID, SSCPlayer>();
|
2019-07-19 11:16:41 +08:00
|
|
|
//this.players.Add(SSCEnums.PlayerID.One, new SSCPlayer(SSCEnums.PlayerID.One));
|
|
|
|
//this.getPlayer(SSCEnums.PlayerID.One).setColor(Color.PaleVioletRed);
|
2019-07-19 08:16:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
this.menuManager = new SSCMenus.SSCMenuManager();
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
this.menuManager.addNewMenu(new SSCMenus.TitleScreen(this.camera.viewport));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public SSCPlayer getPlayer(SSCEnums.PlayerID id)
|
|
|
|
{
|
|
|
|
if (this.players.ContainsKey(id))
|
|
|
|
{
|
|
|
|
return this.players[id];
|
|
|
|
}
|
|
|
|
else return null;
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void LoadTextures()
|
|
|
|
{
|
2019-07-18 07:26:37 +08:00
|
|
|
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"));
|
|
|
|
this.textureUtils.addTextureManager(playerManager);
|
|
|
|
this.textureUtils.addTextureManager(mapTextureManager);
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private void LoadMaps()
|
|
|
|
{
|
|
|
|
this.SeasideScrambleMaps = new Dictionary<string, SeasideScrambleMap>();
|
2019-07-18 07:26:37 +08:00
|
|
|
this.SeasideScrambleMaps.Add("TestRoom", new SeasideScrambleMap(SeasideScrambleMap.LoadMap("TestRoom.tbin").Value));
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
private void loadStartingMap()
|
|
|
|
{
|
|
|
|
this.currentMap = this.SeasideScrambleMaps["TestRoom"];
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// What happens when the screen changes size.
|
|
|
|
/// </summary>
|
|
|
|
public void changeScreenSize()
|
|
|
|
{
|
2019-07-18 03:30:08 +08:00
|
|
|
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);
|
2019-07-18 01:18:51 +08:00
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Used to update Stardew Valley while this minigame runs. True means SDV updates false means the SDV pauses all update ticks.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool doMainGameUpdates()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Draws all game aspects to the screen.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="b"></param>
|
|
|
|
public void draw(SpriteBatch b)
|
|
|
|
{
|
2019-07-18 07:26:37 +08:00
|
|
|
if (this.currentMap != null)
|
|
|
|
{
|
2019-07-18 01:18:51 +08:00
|
|
|
this.currentMap.draw(b);
|
|
|
|
}
|
|
|
|
b.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, (DepthStencilState)null, (RasterizerState)null);
|
2019-07-19 08:16:17 +08:00
|
|
|
|
|
|
|
foreach(SSCPlayer p in this.players.Values) {
|
|
|
|
p.draw(b);
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
/*
|
|
|
|
if (this.menuManager.activeMenu != null)
|
2019-07-18 07:26:37 +08:00
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
this.menuManager.activeMenu.draw(b);
|
2019-07-18 07:26:37 +08:00
|
|
|
}
|
2019-07-19 08:16:17 +08:00
|
|
|
*/
|
|
|
|
this.menuManager.drawAll(b);
|
2019-07-18 01:18:51 +08:00
|
|
|
b.End();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// What happens when the left click is held.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="x"></param>
|
|
|
|
/// <param name="y"></param>
|
|
|
|
public void leftClickHeld(int x, int y)
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// The id of the minigame???
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
public string minigameId()
|
|
|
|
{
|
|
|
|
return "Seaside Scramble Stardew Lite Edition";
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Does this override free mous emovements?
|
|
|
|
/// </summary>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool overrideFreeMouseMovement()
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
return true;
|
2019-07-18 01:18:51 +08:00
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// ??? Undocumended.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data"></param>
|
|
|
|
public void receiveEventPoke(int data)
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// What happens when a key is pressed.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="k"></param>
|
|
|
|
public void receiveKeyPress(Keys k)
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
2019-07-18 07:26:37 +08:00
|
|
|
if (k == Keys.Escape)
|
2019-07-18 01:18:51 +08:00
|
|
|
{
|
|
|
|
this.quitGame = true;
|
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
foreach(SSCPlayer player in this.players.Values)
|
|
|
|
{
|
|
|
|
player.receiveKeyPress(k);
|
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-19 13:10:05 +08:00
|
|
|
if (this.menuManager.isMenuUp)
|
|
|
|
{
|
|
|
|
this.menuManager.activeMenu.receiveKeyPress(k);
|
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Gets a gamepad state.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="index"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public GamePadState getGamepadState(PlayerIndex index)
|
2019-07-18 01:18:51 +08:00
|
|
|
{
|
2019-07-18 07:26:37 +08:00
|
|
|
return Microsoft.Xna.Framework.Input.GamePad.GetState(PlayerIndex.One);
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Called when the minigame registeres a key on the keyboard being released.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="K"></param>
|
2019-07-18 01:18:51 +08:00
|
|
|
public void receiveKeyRelease(Keys K)
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
foreach (SSCPlayer player in this.players.Values)
|
|
|
|
{
|
|
|
|
player.receiveKeyRelease(K);
|
|
|
|
}
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Called when the minigame receives a left click.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="x"></param>
|
|
|
|
/// <param name="y"></param>
|
|
|
|
/// <param name="playSound"></param>
|
2019-07-18 01:18:51 +08:00
|
|
|
public void receiveLeftClick(int x, int y, bool playSound = true)
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
if (this.menuManager.activeMenu != null)
|
|
|
|
{
|
|
|
|
this.menuManager.activeMenu.receiveLeftClick(x, y, playSound);
|
|
|
|
}
|
2019-07-18 01:18:51 +08:00
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Called when the minigame receives a right click.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="x"></param>
|
|
|
|
/// <param name="y"></param>
|
|
|
|
/// <param name="playSound"></param>
|
2019-07-18 01:18:51 +08:00
|
|
|
public void receiveRightClick(int x, int y, bool playSound = true)
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
if (this.menuManager.activeMenu != null)
|
|
|
|
{
|
|
|
|
this.menuManager.activeMenu.receiveRightClick(x, y, playSound);
|
|
|
|
}
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public void releaseLeftClick(int x, int y)
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void releaseRightClick(int x, int y)
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
|
|
|
|
private void receiveGamepadInput(GamePadState state,SSCEnums.PlayerID ID)
|
|
|
|
{
|
|
|
|
if (state == null) return;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this.players.ContainsKey(ID))
|
|
|
|
{
|
|
|
|
this.players[ID].receiveGamepadInput(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Called every update frame.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="time"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool tick(GameTime time)
|
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
KeyboardState kState = Keyboard.GetState();
|
2019-07-18 01:18:51 +08:00
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
foreach (Keys k in kState.GetPressedKeys())
|
2019-07-18 01:18:51 +08:00
|
|
|
{
|
|
|
|
this.receiveKeyPress(k);
|
|
|
|
}
|
2019-07-19 08:16:17 +08:00
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
GamePadState state = this.getGamepadState((PlayerIndex)i);
|
|
|
|
this.receiveGamepadInput(state,(SSCEnums.PlayerID)i);
|
|
|
|
}
|
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
|
|
|
|
if (this.quitGame)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (this.currentMap != null)
|
|
|
|
{
|
|
|
|
this.currentMap.update(time);
|
|
|
|
}
|
2019-07-19 11:16:41 +08:00
|
|
|
|
2019-07-19 08:16:17 +08:00
|
|
|
|
|
|
|
if (this.menuManager.activeMenu != null)
|
2019-07-18 07:26:37 +08:00
|
|
|
{
|
2019-07-19 08:16:17 +08:00
|
|
|
this.menuManager.activeMenu.update(time);
|
|
|
|
if (this.menuManager.activeMenu.readyToClose())
|
|
|
|
{
|
|
|
|
this.menuManager.closeActiveMenu();
|
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
}
|
2019-07-19 11:16:41 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
foreach (SSCPlayer player in this.players.Values)
|
|
|
|
{
|
|
|
|
if (player.playerID == SSCEnums.PlayerID.One) this.camera.centerOnPosition(player.position);
|
|
|
|
player.update(time);
|
|
|
|
}
|
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
return false;
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
}
|
2019-07-18 07:26:37 +08:00
|
|
|
|
2019-07-18 01:18:51 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Called when the minigame is quit upon.
|
|
|
|
/// </summary>
|
|
|
|
public void unload()
|
|
|
|
{
|
|
|
|
//throw new NotImplementedException();
|
|
|
|
ModCore.log("Exit the game!");
|
|
|
|
}
|
2019-07-18 03:30:08 +08:00
|
|
|
|
|
|
|
public static Vector2 GlobalToLocal(xTile.Dimensions.Rectangle viewport, Vector2 globalPosition)
|
|
|
|
{
|
|
|
|
return new Vector2(globalPosition.X - (float)viewport.X, globalPosition.Y - (float)viewport.Y);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2019-07-18 01:18:51 +08:00
|
|
|
}
|
|
|
|
}
|