using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Threading.Tasks; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using TibzGame.Core.ScreenManager; using Johnmagotchi.Core.tools; using System.Runtime.ExceptionServices; using Johnmagotchi.GameContent.Objects.Units; namespace Johnmagotchi.GameContent.Objects { public class BattleMap { public int width { get; set; } public int height{ get; set; } public string serializedMapTiles{ get; set; } public string serializedUnits { get; set; } private MapTile [,] MapTileGrid; private List Units; //private List playerUnits; //private List enemyUnits; //private List npcUnits; private SpriteBatch _spriteBatch; private ScreenManager _screenManager; private SpriteEffects currentSpriteEffects; public Boolean OutlineEnabled; Texture2D _outlineTexture; public BattleMap(){ buildMap(10,10); } public BattleMap(int width, int height) { buildMap(width,height); } public void buildMap(int w, int h){ this.height = h; // default min height (shooting for 360 x 640 res, 40x40 pixel grid) this.width = w; MapTileGrid = new MapTile[width,height]; this.Units = new List(); //this.playerUnits = new List(); //this.npcUnits = new List(); //this.enemyUnits = new List(); } public void Init(ScreenManager ScreenManager){ this.OutlineEnabled = true; this._screenManager = ScreenManager; initArray(); _spriteBatch = new SpriteBatch(_screenManager.GraphicsDevice); _outlineTexture = _screenManager.contentRef.Load("Map-UI/outline-32"); } public void InitFromReload(ScreenManager ScreenManager){ this.OutlineEnabled = true; this._screenManager = ScreenManager; _spriteBatch = new SpriteBatch(_screenManager.GraphicsDevice); _outlineTexture = _screenManager.contentRef.Load("Map-UI/outline-32"); } public void Update() { foreach (Unit unit in Units) { unit.Update(); } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { MapTileGrid[x,y].Update(); } } } public void initArray(){ // init tiles for (int x =0; x < width; x++) { for (int y =0; y < height; y++) { MapTileGrid[x,y] = new MapTile(); MapTileGrid[x,y].Init(_screenManager); } } //set neighbors for (int x =0; x < width; x++) { for (int y =0; y < height; y++) { if (x -1 >= 0) MapTileGrid[x,y].WestNeighborType = MapTileGrid[x-1,y].Type; if (x+1 < height) MapTileGrid[x,y].WestNeighborType = MapTileGrid[x+1,y].Type; if (y -1 >= 0) MapTileGrid[x,y].WestNeighborType = MapTileGrid[x,y-1].Type; if (y+1 < height) MapTileGrid[x,y].WestNeighborType = MapTileGrid[x,y+1].Type; } } } public void DrawMap(int xOffset, int yOffset){ // this could probably be changed to only draw visible tiles instead of every single tile in the future for (int x =0; x < width; x++) { for (int y =0; y < height; y++) { int xLocation = (x * MapTile.TILE_WIDTH_PX) + xOffset; int yLocation = (y * MapTile.TILE_HEIGHT_PX)+ yOffset; MapTileGrid[x,y].DrawAt(xLocation, yLocation); } } // ADD IN an if statment, 'IF OUTLINE IS ENABLED' if (this.OutlineEnabled == true) { _spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp); for (int x =0; x < width; x++) { for (int y =0; y < height; y++) { int xLocation = (x * MapTile.TILE_WIDTH_PX) + xOffset; int yLocation = (y * MapTile.TILE_HEIGHT_PX)+ yOffset; this.DrawOutlineSquare(xLocation, yLocation); } } _spriteBatch.End(); } } private void DrawOutlineSquare(int posX, int posY) { // all rectangles should do the scaling from world coordinates to screen coordinates Rectangle tileRect = _screenManager.GetScaledRectangle(posX, posY, MapTile.TILE_WIDTH_PX, MapTile.TILE_HEIGHT_PX); _spriteBatch.Draw( _outlineTexture, tileRect, null, Color.White, 0, new Vector2(0, 0), currentSpriteEffects, 1); } public void DrawUnits(int xOffset, int yOffset) { foreach(Unit unit in Units) { int xLocation = (unit.xPos * MapTile.TILE_WIDTH_PX) + xOffset; int yLocation = (unit.yPos * MapTile.TILE_HEIGHT_PX) + yOffset; unit.DrawAt( xLocation, yLocation); } } public void ChangeTileType(int x, int y, TileType newType) { MapTileGrid[x,y].ChangeType(newType); if(x > 0){MapTileGrid[x-1,y].EastNeighborType = newType;} //update left neighbor if(x < width -1){MapTileGrid[x +1,y].WestNeighborType = newType;} //update right neighbor if(y > 0){MapTileGrid[x,y-1].SouthNeighborType = newType;} //update top neighbor if(y < height -1){MapTileGrid[x ,y+1].NorthNeighborType = newType;} //update bottom neighbor } public void serializeMapTiles(){ List serializedRows = new List(); for (int row = 0; row < this.height; row ++){ List rowData = new List(); for (int column =0; column < this.width; column++){ rowData.Add( MapTileGrid[column, row]); // grid is width, height } serializedRows.Add( JsonSerializer.Serialize(rowData)); } serializedMapTiles = JsonSerializer.Serialize(serializedRows); } public void deserializeMapTiles(){ MapTileGrid = new MapTile[width,height]; List serializedRows = JsonSerializer.Deserialize>(serializedMapTiles); for (int row= 0; row < serializedRows.Count; row++){ string currentRow = serializedRows[row]; List rowData = JsonSerializer.Deserialize>(currentRow); for (int column =0; column < rowData.Count; column++){ MapTile tile = rowData[column]; MapTileGrid[column, row] = tile; MapTileGrid[column, row].Init(_screenManager); } } // initArray(); System.Console.WriteLine("Deserialition Completed!"); } public void SerializeAll() { this.serializeMapTiles(); this.SerializeUnitData(); } public void SerializeUnitData() { List units_str = new List(); foreach (Unit unit in Units) { units_str.Add(unit.GetAsSerialized()); } serializedUnits = JsonSerializer.Serialize(units_str); TibzLog.Debug("Units: " + Units.Count); } public void DeserializeUnitData() { TibzLog.Debug("Deserializing unit data"); List outUnits = new List(); List unitsString = JsonSerializer.Deserialize>(serializedUnits); foreach(string entry in unitsString) { Unit newUnit = new Unit(entry); TibzLog.Debug(JsonSerializer.Serialize(newUnit)); outUnits.Add(newUnit); // makes new instance from serialized string newUnit.InitSprite(_screenManager); } Units = outUnits; } public void AddPlayerUnit(Unit unitRef, int xpos, int ypos) { if (! CheckIfUnitCanBePlaced(unitRef, xpos, ypos)) { return; } Unit unit = new Unit(unitRef); unit.SetShaderSet(Unit.SpriteShaderSets.PLAYER_NORMAL); unit.xPos = xpos; unit.yPos = ypos; unit.stats.status.team = Objects.Units.Stats.UnitCurrentStatus.UnitTeam.PLAYER; Units.Add(unit); unit.InitSprite(_screenManager); } public void AddEnemyUnit(Unit unitRef, int xpos, int ypos) { if (!CheckIfUnitCanBePlaced(unitRef, xpos, ypos)) { return; } Unit unit = new Unit(unitRef); unit.SetShaderSet(Unit.SpriteShaderSets.ENEMY_NORMAL); unit.xPos = xpos; unit.yPos = ypos; unit.stats.status.team = Objects.Units.Stats.UnitCurrentStatus.UnitTeam.ENEMY; Units.Add(unit); unit.InitSprite(_screenManager); } public void AddNpcUnit(Unit unitRef, int xpos, int ypos) { if (!CheckIfUnitCanBePlaced(unitRef, xpos, ypos)) { return; } Unit unit = new Unit(unitRef); unit.SetShaderSet(Unit.SpriteShaderSets.NPC_NORMAL); unit.xPos = xpos; unit.yPos = ypos; unit.stats.status.team = Objects.Units.Stats.UnitCurrentStatus.UnitTeam.NPC; Units.Add(unit); unit.InitSprite(_screenManager); } public void deleteUnit(Unit unitRef) { int removeUnitIndex = -1; for (int i = 0; i < Units.Count; i++) { if (unitRef.internalID == Units[i].internalID) { removeUnitIndex = i; break; } } if (removeUnitIndex != -1) { Units.RemoveAt(removeUnitIndex); } } private bool CheckIfUnitCanBePlaced(Unit unit, int x, int y) { if (x < 0 || y < 0 ||x > width || y>height) return false; if (MapTileGrid[x,y].Type == TileType.SEA ) { // add a && unit.Traversal type or whatever, so we check if this unit CAN stand on said tile. return false; } // else delete existing units if they overlap then return true return true; } public bool CheckIfAnyUnits(int CursorX, int CursorY) { foreach (Unit Unit in Units) { if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return true; } } return false; } public Unit getUnitAtLocation(int CursorX, int CursorY) { foreach (Unit Unit in Units) { if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return Unit; } } return null; } public void moveUnit(Unit unitcopy, int x, int y) { foreach (Unit Unit in Units) { if (Unit.internalID == unitcopy.internalID) { Unit.xPos = x; Unit.yPos = y; } } } public MapTile getTile(int x, int y) { if (x < 0 || y < 0) return null; if (x >= width || y >= height) return null; return MapTileGrid[x, y]; } public void ChangeTileHighlight(int x, int y, TileHighlight highlightType) { MapTileGrid[x, y].SetTileHighlight(highlightType); } public BattleMap GetClone() { BattleMap clone = new BattleMap(this.width, this.height); clone.Init(this._screenManager); this.SerializeAll(); clone.serializedMapTiles = this.serializedMapTiles; clone.deserializeMapTiles(); clone.serializedPlayerUnits = this.serializedPlayerUnits; clone.serializedNpcUnits = this.serializedNpcUnits; clone.serializedEnemyUnits = this.serializedEnemyUnits; clone.DeserializeUnitData(); return clone; } } }