mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-19 19:06:45 -05:00
Map engine improvements
This commit is contained in:
parent
862ea62b44
commit
602c1014cc
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces.Drawing;
|
||||
using OpenDiablo2.Common.Models;
|
||||
|
||||
@ -28,7 +29,7 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
void Draw(ISprite sprite, int xSegments, int ySegments, int offset);
|
||||
IMouseCursor LoadCursor(ISprite sprite, int frame, Point hotspot);
|
||||
void Draw(ILabel label);
|
||||
MapCellInfo CacheMapCell(MPQDT1Tile mapCell);
|
||||
MapCellInfo CacheMapCell(MPQDT1Tile mapCell, eRenderCellType cellType);
|
||||
void DrawMapCell(MapCellInfo mapCellInfo, int xPixel, int yPixel);
|
||||
ICharacterRenderer CreateCharacterRenderer();
|
||||
}
|
||||
|
@ -9,8 +9,6 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
public bool Ignore { get; set; } = false;
|
||||
public int AnimationId { get; set; }
|
||||
public int OffX { get; set; }
|
||||
public int OffY { get; set; }
|
||||
public int FrameWidth { get; set; }
|
||||
public int FrameHeight { get; set; }
|
||||
public MPQDT1Tile Tile { get; set; }
|
||||
|
@ -200,14 +200,14 @@ namespace OpenDiablo2.Core.GameState_
|
||||
{
|
||||
case eRenderCellType.Floor:
|
||||
return map.FileData.FloorLayers
|
||||
.Select(floorLayer => GetMapCellInfo(map, cellX, cellY, floorLayer.Props[idx], eRenderCellType.Floor))
|
||||
.Select(floorLayer => GetMapCellInfo(map, cellX, cellY, floorLayer.Props[idx], eRenderCellType.Floor, 0))
|
||||
.Where(x => x != null);
|
||||
|
||||
case eRenderCellType.WallUpper:
|
||||
case eRenderCellType.WallLower:
|
||||
case eRenderCellType.Roof:
|
||||
return map.FileData.WallLayers
|
||||
.Select(wallLayer => GetMapCellInfo(map, cellX, cellY, wallLayer.Props[idx], renderCellType, wallLayer.Orientations[idx]))
|
||||
.Select(wallLayer => GetMapCellInfo(map, cellX, cellY, wallLayer.Props[idx], renderCellType, wallLayer.Orientations[idx].Orientation1))
|
||||
.Where(x => x != null);
|
||||
|
||||
default:
|
||||
@ -252,7 +252,7 @@ namespace OpenDiablo2.Core.GameState_
|
||||
this.SelectedItem = item;
|
||||
}
|
||||
|
||||
private MapCellInfo GetMapCellInfo(MapInfo map, int cellX, int cellY, MPQDS1TileProps props, eRenderCellType cellType, MPQDS1WallOrientationTileProps wallOrientations = null)
|
||||
private MapCellInfo GetMapCellInfo(MapInfo map, int cellX, int cellY, MPQDS1TileProps props, eRenderCellType cellType, byte orientation)
|
||||
{
|
||||
if (!map.CellInfo.ContainsKey(cellType))
|
||||
{
|
||||
@ -260,13 +260,12 @@ namespace OpenDiablo2.Core.GameState_
|
||||
}
|
||||
|
||||
var cellInfo = map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)];
|
||||
if (cellInfo != null)
|
||||
if (cellInfo != null && cellInfo?.Tile?.Animated != true)
|
||||
return cellInfo.Ignore ? null : cellInfo;
|
||||
|
||||
|
||||
var sub_index = props.Prop2;
|
||||
var main_index = (props.Prop3 >> 4) + ((props.Prop4 & 0x03) << 4);
|
||||
var orientation = 0;
|
||||
|
||||
// Floors can't have rotations, should we blow up here?
|
||||
if (cellType == eRenderCellType.Floor && props.Prop1 == 0)
|
||||
@ -296,11 +295,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
}
|
||||
|
||||
}
|
||||
if (cellType == eRenderCellType.WallUpper || cellType == eRenderCellType.WallLower)
|
||||
else if (cellType == eRenderCellType.WallUpper || cellType == eRenderCellType.WallLower)
|
||||
{
|
||||
orientation = wallOrientations.Orientation1;
|
||||
|
||||
|
||||
if (props.Prop1 == 0)
|
||||
{
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
|
||||
@ -374,6 +370,39 @@ namespace OpenDiablo2.Core.GameState_
|
||||
else tile = tiles.First();
|
||||
}
|
||||
|
||||
switch (cellType)
|
||||
{
|
||||
case eRenderCellType.Floor:
|
||||
if (tile.Orientation != 0)
|
||||
{
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case eRenderCellType.WallLower:
|
||||
if (tile.Orientation < 1 || tile.Orientation == 10 || tile.Orientation == 11 || tile.Orientation == 13 || tile.Orientation > 14)
|
||||
{
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case eRenderCellType.WallUpper:
|
||||
if (tile.Orientation <= 15)
|
||||
{
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case eRenderCellType.Roof:
|
||||
if (tile.Orientation != 15)
|
||||
{
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = new MapCellInfo { Ignore = true };
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// This WILL happen to you
|
||||
if (tile.Width == 0 || tile.Height == 0)
|
||||
{
|
||||
@ -392,17 +421,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
var mapCellInfo = mapDataLookup.FirstOrDefault(x => x.Tile.Id == tile.Id && x.AnimationId == frame);
|
||||
if (mapCellInfo == null)
|
||||
{
|
||||
mapCellInfo = renderWindow.CacheMapCell(tile);
|
||||
mapCellInfo = renderWindow.CacheMapCell(tile, cellType);
|
||||
mapDataLookup.Add(mapCellInfo);
|
||||
|
||||
switch (cellType)
|
||||
{
|
||||
case eRenderCellType.WallUpper:
|
||||
case eRenderCellType.WallLower:
|
||||
mapCellInfo.OffY -= 80;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
map.CellInfo[cellType][cellX + (cellY * map.FileData.Width)] = mapCellInfo;
|
||||
|
@ -28,8 +28,6 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
return;
|
||||
|
||||
cameraLocation = value;
|
||||
//cOffX = (int)((cameraLocation.X - cameraLocation.Y) * (cellSizeX / 2));
|
||||
//cOffY = (int)((cameraLocation.X + cameraLocation.Y) * (cellSizeY / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +100,7 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
|
||||
const int skewX = 400;
|
||||
const int skewY = 300;
|
||||
|
||||
public void Render()
|
||||
{
|
||||
var xOffset = gameState.CameraOffset;
|
||||
@ -126,25 +125,12 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Floor))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (int ty = -7; ty <= 9; ty++)
|
||||
{
|
||||
for (int tx = -8; tx <= 8; tx++)
|
||||
{
|
||||
var ax = tx + Math.Truncate(cameraLocation.X);
|
||||
var ay = ty + Math.Truncate(cameraLocation.Y);
|
||||
|
||||
var px = (tx - ty) * (cellSizeX / 2);
|
||||
var py = (tx + ty) * (cellSizeY / 2);
|
||||
|
||||
var ox = (cx - cy) * (cellSizeX / 2);
|
||||
var oy = (cx + cy) * (cellSizeY / 2);
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallLower))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80);
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallUpper))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy + 80);
|
||||
|
||||
foreach (var character in characterRenderers.Where(x => Math.Truncate(x.LocationDetails.PlayerX) == ax && Math.Truncate(x.LocationDetails.PlayerY) == ay))
|
||||
{
|
||||
var ptx = character.LocationDetails.PlayerX - Math.Truncate(cameraLocation.X);
|
||||
@ -156,11 +142,8 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
character.Render(skewX + (int)ppx + (int)ox + xOffset, skewY + (int)ppy + (int)oy);
|
||||
}
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.WallUpper))
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy);
|
||||
|
||||
foreach (var cellInfo in gameState.GetMapCellInfo((int)ax, (int)ay, eRenderCellType.Roof))
|
||||
renderWindow.DrawMapCell(cellInfo, 320 + px + (int)ox + xOffset, 300 + py + (int)oy);
|
||||
renderWindow.DrawMapCell(cellInfo, skewX + px + (int)ox + xOffset, skewY + py + (int)oy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,11 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
|
||||
public void Generate()
|
||||
{
|
||||
var wildBorder = 5; // (4-15)
|
||||
//var wildBorder = 5; // (4-15)
|
||||
// TODO: Is there no data file that explicitly defines this??
|
||||
var townMap = gameState.LoadMap(eLevelId.Act1_Town1, new Point(0, 0));
|
||||
|
||||
/*
|
||||
Rectangle bloodMooreRect;
|
||||
|
||||
// 32-37 is grassy field?
|
||||
@ -61,6 +63,7 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
mapTile.PrimaryMap = townMap;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,8 @@ namespace OpenDiablo2.Core
|
||||
{
|
||||
public sealed class ResourceManager : IResourceManager
|
||||
{
|
||||
static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly ICache cache;
|
||||
private readonly IMPQProvider mpqProvider;
|
||||
private readonly IEngineDataManager engineDataManager;
|
||||
@ -73,10 +75,14 @@ namespace OpenDiablo2.Core
|
||||
// TODO: We need to cache this...
|
||||
byte[] binaryData;
|
||||
|
||||
using (var stream = mpqProvider.GetStream(cofLayer.GetDCCPath(armorType)))
|
||||
var streamPath = cofLayer.GetDCCPath(armorType);
|
||||
using (var stream = mpqProvider.GetStream(streamPath))
|
||||
{
|
||||
if (stream == null)
|
||||
{
|
||||
log.Error($"Could not load Player DCC: {streamPath}");
|
||||
return null;
|
||||
}
|
||||
|
||||
binaryData = new byte[stream.Length];
|
||||
stream.Read(binaryData, 0, (int)stream.Length);
|
||||
|
@ -18,6 +18,7 @@ using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Exceptions;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Interfaces.Drawing;
|
||||
@ -342,23 +343,28 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_RenderCopy(renderer, lbl.texture, IntPtr.Zero, ref destRect);
|
||||
}
|
||||
|
||||
public unsafe MapCellInfo CacheMapCell(MPQDT1Tile mapCell)
|
||||
public unsafe MapCellInfo CacheMapCell(MPQDT1Tile mapCell, eRenderCellType cellType)
|
||||
{
|
||||
var minX = mapCell.Blocks.Min(x => x.PositionX);
|
||||
var minY = mapCell.Blocks.Min(x => x.PositionY);
|
||||
var maxX = mapCell.Blocks.Max(x => x.PositionX + 32);
|
||||
var maxY = mapCell.Blocks.Max(x => x.PositionY + 32);
|
||||
var diffX = maxX - minX;
|
||||
var diffY = maxY - minY;
|
||||
var frameWidth = maxX - minX;
|
||||
var frameHeight = maxY - minY;
|
||||
|
||||
var offX = -minX;
|
||||
var offY = -minY;
|
||||
var dx = minX;
|
||||
var dy = minY;
|
||||
|
||||
var frameSize = new Size(Math.Abs(diffX), Math.Abs(diffY));
|
||||
dx -= 80;
|
||||
|
||||
var srcRect = new SDL.SDL_Rect { x = minX, y = minY, w = frameSize.Width, h = frameSize.Height };
|
||||
|
||||
var texId = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameSize.Width, frameSize.Height);
|
||||
var srcRect = new SDL.SDL_Rect { x = dx, y = dy, w = frameWidth, h = frameHeight };
|
||||
|
||||
var texId = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameWidth, frameHeight);
|
||||
|
||||
if (texId == IntPtr.Zero)
|
||||
throw new OpenDiablo2Exception("Could not create texture");
|
||||
|
||||
SDL.SDL_SetTextureBlendMode(texId, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);
|
||||
|
||||
if (SDL.SDL_LockTexture(texId, IntPtr.Zero, out IntPtr pixels, out int pitch) != 0)
|
||||
@ -373,15 +379,15 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
foreach (var block in mapCell.Blocks)
|
||||
{
|
||||
var index = block.PositionX + offX + ((block.PositionY + offY) * pitchChange);
|
||||
var index = (block.PositionX - minX) + ((block.PositionY - minY) * pitchChange);
|
||||
var xx = 0;
|
||||
var yy = 0;
|
||||
foreach (var colorIndex in block.PixelData)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (colorIndex == 0)
|
||||
continue;
|
||||
|
||||
var color = colors[colorIndex];
|
||||
|
||||
if (color > 0)
|
||||
@ -396,7 +402,6 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
index += pitchChange - 32;
|
||||
xx = 0;
|
||||
yy++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -410,10 +415,8 @@ namespace OpenDiablo2.SDL2_
|
||||
return new MapCellInfo
|
||||
{
|
||||
Tile = mapCell,
|
||||
FrameHeight = frameSize.Height,
|
||||
FrameWidth = frameSize.Width,
|
||||
OffX = offX,
|
||||
OffY = offY,
|
||||
FrameHeight = frameHeight,
|
||||
FrameWidth = frameWidth,
|
||||
Rect = srcRect.ToRectangle(),
|
||||
Texture = new SDL2Texture { Pointer = texId }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user