StrategyRPG/Johnmagotchi/GameContent/Objects/Maps/BattleMap.cs
2026-09-25 02:33:04 -05:00

527 lines
19 KiB
C#

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.GameContent.Units;
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 serializedPlayerUnits { get; set; }
public string serializedEnemyUnits{ get; set; }
public string serializedNpcUnits { get; set; }
private MapTile [,] MapTileGrid;
private List<Unit> playerUnits;
private List<Unit> enemyUnits;
private List<Unit> 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.playerUnits = new List<Unit>();
this.npcUnits = new List<Unit>();
this.enemyUnits = new List<Unit>();
}
public void Init(ScreenManager ScreenManager){
this.OutlineEnabled = true;
this._screenManager = ScreenManager;
initArray();
_spriteBatch = new SpriteBatch(_screenManager.GraphicsDevice);
_outlineTexture = _screenManager.contentRef.Load<Texture2D>("Map-UI/outline-32");
}
public void InitFromReload(ScreenManager ScreenManager){
this.OutlineEnabled = true;
this._screenManager = ScreenManager;
_spriteBatch = new SpriteBatch(_screenManager.GraphicsDevice);
_outlineTexture = _screenManager.contentRef.Load<Texture2D>("Map-UI/outline-32");
}
public void Update()
{
foreach (Unit unit in playerUnits)
{
unit.Update();
}
foreach (Unit unit in enemyUnits)
{
unit.Update();
}
foreach (Unit unit in npcUnits)
{
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 playerUnits) {
int xLocation = (unit.xPos * MapTile.TILE_WIDTH_PX) + xOffset;
int yLocation = (unit.yPos * MapTile.TILE_HEIGHT_PX) + yOffset;
unit.DrawAt( xLocation, yLocation);
}
foreach (Unit unit in enemyUnits)
{
int xLocation = (unit.xPos * MapTile.TILE_WIDTH_PX) + xOffset;
int yLocation = (unit.yPos * MapTile.TILE_HEIGHT_PX) + yOffset;
unit.DrawAt( xLocation, yLocation);
}
foreach (Unit unit in npcUnits)
{
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<string> serializedRows = new List<string>();
for (int row = 0; row < this.height; row ++){
List<MapTile> rowData = new List<MapTile>();
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<string> serializedRows = JsonSerializer.Deserialize<List<string>>(serializedMapTiles);
for (int row= 0; row < serializedRows.Count; row++){
string currentRow = serializedRows[row];
List<MapTile> rowData = JsonSerializer.Deserialize<List<MapTile>>(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<string> player = new List<string>();
List<string> enemy = new List<string>();
List<string> npc = new List<string>();
foreach (Unit unit in playerUnits) {
player.Add(unit.GetAsSerialized());
}
foreach (Unit unit in enemyUnits) {
enemy.Add(unit.GetAsSerialized());
}
foreach (Unit unit in npcUnits)
{
npc.Add(unit.GetAsSerialized());
}
serializedPlayerUnits = JsonSerializer.Serialize(player);
serializedEnemyUnits = JsonSerializer.Serialize(enemy);
serializedNpcUnits = JsonSerializer.Serialize(npc);
TibzLog.Debug("P:" + player.Count + " E:" + enemy.Count + " N:" + npc.Count);
}
public void DeserializeUnitData() {
TibzLog.Debug("Deserializing unit data");
List<Unit> OutPlayerUnits = new List<Unit>();
List<Unit> OutEnemyUnits = new List<Unit>();
List<Unit> OutNpcUnits = new List<Unit>();
List<string> players = JsonSerializer.Deserialize<List<string>>(serializedPlayerUnits);
List<string> enemies = JsonSerializer.Deserialize<List<string>>(serializedEnemyUnits);
List<string> npcs = JsonSerializer.Deserialize<List<string>>(serializedNpcUnits);
foreach(string entry in players) {
Unit newUnit = new Unit(entry);
TibzLog.Debug(JsonSerializer.Serialize(newUnit));
OutPlayerUnits.Add(newUnit); // makes new instance from serialized string
newUnit.InitSprite(_screenManager);
}
foreach (string entry in enemies)
{
Unit newUnit = new Unit(entry);
OutEnemyUnits.Add(newUnit); // makes new instance from serialized string
newUnit.InitSprite(_screenManager);
}
foreach (string entry in npcs)
{
Unit newUnit = new Unit(entry);
OutNpcUnits.Add(newUnit); // makes new instance from serialized string
newUnit.InitSprite(_screenManager);
}
playerUnits = OutPlayerUnits;
enemyUnits = OutEnemyUnits;
npcUnits = OutNpcUnits;
TibzLog.Debug("P:" + playerUnits.Count + " E:" + enemyUnits.Count + " N:" + npcUnits.Count);
}
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;
//if (unit.isUnique == true)
//{
// //check then replace
// for (int i = 0; i < playerUnits.Count; i++)
// {
// if (playerUnits[i].id == unit.id )
// {
// playerUnits[i].xPos = xpos;
// playerUnits[i].yPos = ypos;
// return; // dont add
// }
// }
// playerUnits.Add(unit); // else add
//}
//else { playerUnits.Add(unit);
//}
playerUnits.Add(unit);
unit.stats.status.team = Units.BattleObjects.UnitCurrentStatus.UnitTeam.PLAYER;
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;
//if (unit.isUnique == true)
//{
// //check then replace
// for (int i = 0; i < enemyUnits.Count; i++)
// {
// if (enemyUnits[i].id == unit.id)
// {
// enemyUnits[i].xPos = xpos;
// enemyUnits[i].yPos = ypos;
// return; // dont add
// }
// }
// enemyUnits.Add(unit); // else add
//}
//else
//{
enemyUnits.Add(unit);
unit.stats.status.team = Units.BattleObjects.UnitCurrentStatus.UnitTeam.ENEMY;
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;
//if (unit.isUnique == true)
//{
// //check then replace
// for (int i = 0; i < npcUnits.Count; i++)
// {
// if (npcUnits[i].id == unit.id)
// {
// enemyUnits[i] = unit;
// return; // dont add
// }
// }
// npcUnits.Add(unit); // else add
//}
//else
//{
npcUnits.Add(unit);
// }
unit.InitSprite(_screenManager);
unit.stats.status.team = Units.BattleObjects.UnitCurrentStatus.UnitTeam.NPC;
TibzLog.Debug("NPC obj count: {0}", npcUnits.Count);
}
public void deleteUnit(Unit unitRef) {
int removePlayerIndex = -1;
int removeEnemyIndex = -1;
int removeNpcIndex = -1;
for (int i = 0; i < playerUnits.Count; i++)
{
if (unitRef.internalID == playerUnits[i].internalID)
{
removePlayerIndex = i;
break;
}
}
for (int i = 0; i < enemyUnits.Count; i++)
{
if (unitRef.internalID == enemyUnits[i].internalID)
{
removeEnemyIndex = i;
break;
}
}
for (int i = 0; i < npcUnits.Count; i++)
{
if (unitRef.internalID == npcUnits[i].internalID)
{
removeNpcIndex = i;
break;
}
}
if (removePlayerIndex != -1) { playerUnits.RemoveAt(removePlayerIndex); }
if (removeEnemyIndex != -1) { enemyUnits.RemoveAt(removeEnemyIndex); }
if (removeNpcIndex != -1) { npcUnits.RemoveAt(removeNpcIndex); }
}
private bool CheckIfUnitCanBePlaced(Unit unit, int x, int y) {
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 x, int y) {
return CheckIfPlayerUnits(x, y) || CheckIfEnemyUnits(x,y)|| CheckIfNpcUnits(x,y) ;
}
public bool CheckIfPlayerUnits(int CursorX, int CursorY)
{
foreach (Unit Unit in playerUnits) {
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return true; }
}
return false;
}
public bool CheckIfEnemyUnits(int CursorX, int CursorY)
{
foreach (Unit Unit in enemyUnits)
{
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return true; }
}
return false;
}
public bool CheckIfNpcUnits(int CursorX, int CursorY)
{
foreach (Unit Unit in npcUnits)
{
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return true; }
}
return false;
}
public Unit getUnitAtLocation(int CursorX, int CursorY) {
foreach (Unit Unit in playerUnits)
{
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return Unit; }
}
foreach (Unit Unit in enemyUnits)
{
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return Unit; }
}
foreach (Unit Unit in npcUnits)
{
if (Unit.xPos == CursorX && Unit.yPos == CursorY) { return Unit; }
}
return null;
}
public void moveUnit(UnitObject unitcopy, int x, int y)
{
foreach (Unit Unit in playerUnits)
{
if (Unit.internalID == unitcopy.internalID)
{
Unit.xPos = x;
Unit.yPos = y;
}
}
foreach (Unit Unit in enemyUnits)
{
if (Unit.internalID == unitcopy.internalID) { }
}
foreach (Unit Unit in npcUnits)
{
if (Unit.internalID == unitcopy.internalID) { }
}
}
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;
}
}
}