mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-12 20:36:25 -05:00
Dynamic character rendering based on server provided information (#56)
* Update * Partial work * More stuff * Shield rendering * tmp * Update * WeaponCode * Cleanup * Fix build * Initial inventory cleanup and sync * Update * Render body parts based on equipped torso * Initial dynamic equipment work * Update thingies
This commit is contained in:
parent
5904658dad
commit
ae10a9fa3b
@ -11,6 +11,8 @@
|
||||
FocusOnPlayer = 0x05,
|
||||
MoveRequest = 0x06,
|
||||
PlayerMove = 0x07,
|
||||
UpdateEquipment = 0x08,
|
||||
ChangeEquipment = 0x09,
|
||||
|
||||
MAX = 0xFF, // NOTE:
|
||||
// You absolutely cannot have a higher ID than this without
|
||||
|
@ -12,5 +12,6 @@ namespace OpenDiablo2.Common.Interfaces.Drawing
|
||||
void Update(long ms);
|
||||
void Render(int pixelOffsetX, int pixelOffsetY);
|
||||
void ResetAnimationData();
|
||||
void ResetCache();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
@ -13,5 +14,6 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
void Update(int ms);
|
||||
void InitializeNewGame();
|
||||
int SpawnNewPlayer(int clientHash, string playerName, eHero heroType);
|
||||
PlayerEquipment UpdateEquipment(int clientHash, string slot, ItemInstance itemInstance);
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,29 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
public delegate void OnSetSeedEvent(int clientHash, int seed);
|
||||
public delegate void OnJoinGameEvent(int clientHash, eHero heroType, string playerName);
|
||||
public delegate void OnUpdateEquipmentEvent(int clientHash, string slot, ItemInstance itemInstance);
|
||||
public delegate void OnChangeEquipment(int clientHash, Guid PlayerUID, PlayerEquipment playerEquipment);
|
||||
public delegate void OnLocatePlayersEvent(int clientHash, IEnumerable<LocationDetails> playerLocationDetails);
|
||||
public delegate void OnPlayerInfoEvent(int clientHash, IEnumerable<PlayerInfo> playerInfo);
|
||||
public delegate void OnFocusOnPlayer(int clientHash, Guid playerId);
|
||||
public delegate void OnMoveRequest(int clientHash, PointF targetCell, eMovementType movementType);
|
||||
|
||||
|
||||
public interface ISessionEventProvider
|
||||
{
|
||||
OnSetSeedEvent OnSetSeed { get; set; }
|
||||
OnJoinGameEvent OnJoinGame { get; set; }
|
||||
OnLocatePlayersEvent OnLocatePlayers { get; set; }
|
||||
|
||||
OnUpdateEquipmentEvent OnUpdateEquipment { get; set; }
|
||||
OnChangeEquipment OnChangeEquipment { get; set; }
|
||||
|
||||
OnPlayerInfoEvent OnPlayerInfo { get; set; }
|
||||
OnFocusOnPlayer OnFocusOnPlayer { get; set; }
|
||||
OnMoveRequest OnMoveRequest { get; set; }
|
||||
|
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
@ -16,5 +14,6 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
|
||||
void JoinGame(string playerName, eHero heroType);
|
||||
void MoveRequest(PointF targetCell, eMovementType movementType);
|
||||
void UpdateEquipment(string slot, ItemInstance itemInstance);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
ItemInstance ContainedItem { get; }
|
||||
Point Location { get; set; }
|
||||
string Slot { get; set; }
|
||||
|
||||
void SetContainedItem(ItemInstance containedItem);
|
||||
void Render();
|
||||
|
@ -31,7 +31,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
else if (RightArm?.Item is Weapon)
|
||||
return ((Weapon)RightArm.Item).WeaponClass.ToWeaponClass();
|
||||
else
|
||||
return eWeaponClass.None;
|
||||
return eWeaponClass.HandToHand;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Interfaces.Drawing;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
|
||||
namespace OpenDiablo2.Core.Map_Engine
|
||||
{
|
||||
@ -91,7 +92,6 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private const int SkewX = 400;
|
||||
private const int SkewY = 300;
|
||||
|
||||
@ -175,8 +175,8 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
var my = y - 300;
|
||||
return new PointF
|
||||
{
|
||||
X = (float) Math.Round((mx / (float) CellSizeXHalf) + (my / (float) CellSizeYHalf) / 2f, 1) + _cameraLocation.X,
|
||||
Y = (float) Math.Round((my / (float) CellSizeYHalf) - (mx / (float) CellSizeXHalf) / 2f, 1) + _cameraLocation.Y
|
||||
X = (float)Math.Round((mx / (float)CellSizeXHalf) + (my / (float)CellSizeYHalf) / 2f, 1) + _cameraLocation.X,
|
||||
Y = (float)Math.Round((my / (float)CellSizeYHalf) - (mx / (float)CellSizeXHalf) / 2f, 1) + _cameraLocation.Y
|
||||
};
|
||||
}
|
||||
/*
|
||||
|
@ -68,7 +68,6 @@ namespace OpenDiablo2.Core
|
||||
public MPQCOF GetPlayerAnimation(eHero hero, eMobMode mobMode, PlayerEquipment equipment)
|
||||
=> cache.AddOrGetExisting($"COF::{hero}{mobMode.ToToken()}{equipment.HashKey}", () =>
|
||||
{
|
||||
|
||||
var path = $"{ResourcePaths.PlayerAnimationBase}\\{hero.ToToken()}\\COF\\{hero.ToToken()}{mobMode.ToToken()}{equipment.WeaponClass.ToToken()}.cof";
|
||||
return MPQCOF.Load(mpqProvider.GetStream(path), Animations, hero, mobMode, equipment);
|
||||
}, new System.Runtime.Caching.CacheItemPolicy { Priority = System.Runtime.Caching.CacheItemPriority.NotRemovable });
|
||||
|
@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenDiablo2.Core.UI
|
||||
{
|
||||
@ -16,12 +16,14 @@ namespace OpenDiablo2.Core.UI
|
||||
|
||||
private readonly ItemContainerLayout itemContainerLayout;
|
||||
private readonly IMouseInfoProvider mouseInfoProvider;
|
||||
private readonly ISessionManager sessionManager;
|
||||
|
||||
public ItemInstance ContainedItem { get; internal set; }
|
||||
|
||||
private readonly Dictionary<eItemContainerType, ISprite> sprites = new Dictionary<eItemContainerType, ISprite>();
|
||||
|
||||
private Point location = new Point();
|
||||
private IMapRenderer mapRenderer;
|
||||
|
||||
public Point Location
|
||||
{
|
||||
@ -39,13 +41,16 @@ namespace OpenDiablo2.Core.UI
|
||||
private readonly ISprite placeholderSprite;
|
||||
|
||||
public Size Size { get; internal set; }
|
||||
public string Slot { get; set; }
|
||||
|
||||
public ItemContainer(IRenderWindow renderWindow, IGameState gameState, ItemContainerLayout itemContainerLayout, IMouseInfoProvider mouseInfoProvider)
|
||||
public ItemContainer(IRenderWindow renderWindow, IGameState gameState, ItemContainerLayout itemContainerLayout, IMouseInfoProvider mouseInfoProvider, ISessionManager sessionManager, IMapRenderer mapRenderer)
|
||||
{
|
||||
this.renderWindow = renderWindow;
|
||||
this.gameState = gameState;
|
||||
this.itemContainerLayout = itemContainerLayout;
|
||||
this.mouseInfoProvider = mouseInfoProvider;
|
||||
this.sessionManager = sessionManager;
|
||||
this.mapRenderer = mapRenderer;
|
||||
|
||||
placeholderSprite = renderWindow.LoadSprite(itemContainerLayout.ResourceName, itemContainerLayout.PaletteName, true);
|
||||
placeholderSprite.Location = new Point(location.X, location.Y + placeholderSprite.LocalFrameSize.Height);
|
||||
@ -63,6 +68,21 @@ namespace OpenDiablo2.Core.UI
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add all restrictions.
|
||||
public bool CanEquip(ItemInstance itemInstance)
|
||||
{
|
||||
if (Slot == "rarm" || Slot == "larm")
|
||||
return (itemInstance.Item is Weapon || (itemInstance.Item is Armor && (itemInstance.Item as Armor).Type == "shie"));
|
||||
|
||||
if (Slot == "tors")
|
||||
return (itemInstance.Item is Armor && (itemInstance.Item as Armor).Type == "tors");
|
||||
|
||||
if (Slot == "head")
|
||||
return (itemInstance.Item is Armor && (itemInstance.Item as Armor).Type == "helm");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
var hovered = mouseInfoProvider.MouseX >= location.X && mouseInfoProvider.MouseX < (location.X + this.Size.Width)
|
||||
@ -74,22 +94,31 @@ namespace OpenDiablo2.Core.UI
|
||||
if (this.ContainedItem != null)
|
||||
{
|
||||
if (this.gameState.SelectedItem != null)
|
||||
{
|
||||
if(CanEquip(this.gameState.SelectedItem))
|
||||
{
|
||||
var switchItem = this.gameState.SelectedItem;
|
||||
|
||||
this.gameState.SelectItem(this.ContainedItem);
|
||||
this.SetContainedItem(switchItem);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.gameState.SelectItem(this.ContainedItem);
|
||||
this.SetContainedItem(null);
|
||||
}
|
||||
|
||||
sessionManager.UpdateEquipment(Slot, ContainedItem);
|
||||
}
|
||||
else if (this.gameState.SelectedItem != null)
|
||||
{
|
||||
if (CanEquip(this.gameState.SelectedItem))
|
||||
{
|
||||
this.SetContainedItem(this.gameState.SelectedItem);
|
||||
this.gameState.SelectItem(null);
|
||||
|
||||
sessionManager.UpdateEquipment(Slot, ContainedItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Extensions;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
|
||||
namespace OpenDiablo2.Core.UI
|
||||
{
|
||||
@ -58,6 +59,7 @@ namespace OpenDiablo2.Core.UI
|
||||
|
||||
sessionManager.OnFocusOnPlayer += OnFocusOnPlayer;
|
||||
sessionManager.OnPlayerInfo += OnPlayerInfo;
|
||||
sessionManager.OnChangeEquipment += OnChangeEquipment;
|
||||
|
||||
panelSprite = renderWindow.LoadSprite(ResourcePaths.InventoryCharacterPanel, Palettes.Units, FrameType.GetOffset(), true);
|
||||
|
||||
@ -79,18 +81,23 @@ namespace OpenDiablo2.Core.UI
|
||||
|
||||
headContainer = createItemContainer(eItemContainerType.Helm);
|
||||
headContainer.Location = panelSprite.Location + new Size(135, 5);
|
||||
headContainer.Slot = "head";
|
||||
|
||||
neckContainer = createItemContainer(eItemContainerType.Amulet);
|
||||
neckContainer.Location = panelSprite.Location + new Size(209, 34);
|
||||
neckContainer.Slot = "neck";
|
||||
|
||||
torsoContainer = createItemContainer(eItemContainerType.Armor);
|
||||
torsoContainer.Location = panelSprite.Location + new Size(135, 75);
|
||||
torsoContainer.Slot = "tors";
|
||||
|
||||
rightHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
rightHandContainer.Location = panelSprite.Location + new Size(20, 47);
|
||||
rightHandContainer.Slot = "rarm";
|
||||
|
||||
leftHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
leftHandContainer.Location = panelSprite.Location + new Size(253, 47);
|
||||
leftHandContainer.Slot = "larm";
|
||||
|
||||
secondaryLeftHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
secondaryLeftHandContainer.Location = panelSprite.Location + new Size(24, 45);
|
||||
@ -100,45 +107,63 @@ namespace OpenDiablo2.Core.UI
|
||||
|
||||
beltContainer = createItemContainer(eItemContainerType.Belt);
|
||||
beltContainer.Location = panelSprite.Location + new Size(136, 178);
|
||||
beltContainer.Slot = "belt";
|
||||
|
||||
ringLeftContainer = createItemContainer(eItemContainerType.Ring);
|
||||
ringLeftContainer.Location = panelSprite.Location + new Size(95, 179);
|
||||
ringLeftContainer.Slot = "rrin";
|
||||
|
||||
ringRightContainer = createItemContainer(eItemContainerType.Ring);
|
||||
ringRightContainer.Location = panelSprite.Location + new Size(209, 179);
|
||||
ringRightContainer.Slot = "lrin";
|
||||
|
||||
gloveContainer = createItemContainer(eItemContainerType.Glove);
|
||||
gloveContainer.Location = panelSprite.Location + new Size(20, 179);
|
||||
gloveContainer.Slot = "glov";
|
||||
|
||||
bootsContainer = createItemContainer(eItemContainerType.Boots);
|
||||
bootsContainer.Location = panelSprite.Location + new Size(251, 178);
|
||||
bootsContainer.Slot = "feet";
|
||||
}
|
||||
|
||||
private void OnPlayerInfo(int clientHash, IEnumerable<PlayerInfo> playerInfo)
|
||||
{
|
||||
var currentPlayer = gameState.PlayerInfos.FirstOrDefault(x => x.UID == mapRenderer.FocusedPlayerId);
|
||||
if (currentPlayer != null)
|
||||
UpdateInventoryPanel(currentPlayer);
|
||||
UpdateInventoryPanel(currentPlayer.Equipment);
|
||||
}
|
||||
|
||||
private void OnFocusOnPlayer(int clientHash, Guid playerId)
|
||||
{
|
||||
var currentPlayer = gameState.PlayerInfos.FirstOrDefault(x => x.UID == playerId);
|
||||
if (currentPlayer != null)
|
||||
UpdateInventoryPanel(currentPlayer);
|
||||
if (currentPlayer != null) { }
|
||||
UpdateInventoryPanel(currentPlayer.Equipment);
|
||||
}
|
||||
|
||||
private void UpdateInventoryPanel(PlayerInfo currentPlayer)
|
||||
private void OnChangeEquipment(int clientHash, Guid playerUID, PlayerEquipment playerEquipment)
|
||||
{
|
||||
leftHandContainer.SetContainedItem(currentPlayer.Equipment.LeftArm);
|
||||
rightHandContainer.SetContainedItem(currentPlayer.Equipment.RightArm);
|
||||
torsoContainer.SetContainedItem(currentPlayer.Equipment.Torso);
|
||||
headContainer.SetContainedItem(currentPlayer.Equipment.Head);
|
||||
ringLeftContainer.SetContainedItem(currentPlayer.Equipment.LeftRing);
|
||||
ringRightContainer.SetContainedItem(currentPlayer.Equipment.RightRing);
|
||||
beltContainer.SetContainedItem(currentPlayer.Equipment.Belt);
|
||||
neckContainer.SetContainedItem(currentPlayer.Equipment.Neck);
|
||||
gloveContainer.SetContainedItem(currentPlayer.Equipment.Gloves);
|
||||
var player = gameState.PlayerInfos.FirstOrDefault(x => x.UID == playerUID);
|
||||
if (player != null)
|
||||
{
|
||||
player.Equipment = playerEquipment;
|
||||
UpdateInventoryPanel(playerEquipment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void UpdateInventoryPanel(PlayerEquipment playerEquipment)
|
||||
{
|
||||
leftHandContainer.SetContainedItem(playerEquipment.LeftArm);
|
||||
rightHandContainer.SetContainedItem(playerEquipment.RightArm);
|
||||
torsoContainer.SetContainedItem(playerEquipment.Torso);
|
||||
headContainer.SetContainedItem(playerEquipment.Head);
|
||||
ringLeftContainer.SetContainedItem(playerEquipment.LeftRing);
|
||||
ringRightContainer.SetContainedItem(playerEquipment.RightRing);
|
||||
beltContainer.SetContainedItem(playerEquipment.Belt);
|
||||
neckContainer.SetContainedItem(playerEquipment.Neck);
|
||||
gloveContainer.SetContainedItem(playerEquipment.Gloves);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ePanelType PanelType => ePanelType.Inventory;
|
||||
|
@ -16,9 +16,11 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Interfaces.Mobs;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using OpenDiablo2.Common.Services;
|
||||
|
||||
@ -100,6 +102,15 @@ namespace OpenDiablo2.GameServer_
|
||||
return newPlayer.Id;
|
||||
}
|
||||
|
||||
public PlayerEquipment UpdateEquipment(int clienthash, string slot, ItemInstance itemInstance)
|
||||
{
|
||||
var player = mobManager.Players.FirstOrDefault(x => x.ClientHash == clienthash);
|
||||
|
||||
player.Equipment.EquipItem(slot, itemInstance);
|
||||
|
||||
return player.Equipment;
|
||||
}
|
||||
|
||||
public void Update(int ms)
|
||||
{
|
||||
var seconds = ms / 1000f;
|
||||
|
@ -35,6 +35,7 @@ namespace OpenDiablo2.SDL2_
|
||||
{
|
||||
public int Direction { get; set; }
|
||||
public eMobMode MobMode { get; set; }
|
||||
public string EquipmentHash { get; set; }
|
||||
|
||||
public SDL.SDL_Rect[] SpriteRect { get; set; }
|
||||
public IntPtr[] SpriteTexture { get; set; }
|
||||
@ -80,6 +81,7 @@ namespace OpenDiablo2.SDL2_
|
||||
private readonly IGameState gameState;
|
||||
private int lastDirection = -1;
|
||||
private eMovementType lastMovementType = eMovementType.Stopped;
|
||||
private string lastEquipmentHash = string.Empty;
|
||||
|
||||
private MPQCOF animationData;
|
||||
|
||||
@ -115,10 +117,11 @@ namespace OpenDiablo2.SDL2_
|
||||
return;
|
||||
|
||||
|
||||
if ((lastDirection != MobLocation.MovementDirection) || (lastMovementType != MobLocation.MovementType))
|
||||
if ((lastDirection != MobLocation.MovementDirection) || (lastMovementType != MobLocation.MovementType) || (lastEquipmentHash != Equipment.HashKey))
|
||||
{
|
||||
lastMovementType = MobLocation.MovementType;
|
||||
lastDirection = MobLocation.MovementDirection;
|
||||
lastEquipmentHash = Equipment.HashKey;
|
||||
ResetAnimationData();
|
||||
}
|
||||
|
||||
@ -138,6 +141,11 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
}
|
||||
|
||||
public void ResetCache()
|
||||
{
|
||||
directionCache.Clear();
|
||||
}
|
||||
|
||||
public void ResetAnimationData()
|
||||
{
|
||||
|
||||
@ -160,7 +168,8 @@ namespace OpenDiablo2.SDL2_
|
||||
if (lastMobMode != MobMode)
|
||||
renderFrameIndex = 0;
|
||||
|
||||
currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[MobLocation.MovementDirection]);
|
||||
currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[MobLocation.MovementDirection] && x.EquipmentHash == Equipment.HashKey);
|
||||
|
||||
if (currentDirectionCache != null)
|
||||
return;
|
||||
|
||||
@ -264,7 +273,7 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
directionCache.SpriteTexture[frameIndex] = texture;
|
||||
directionCache.SpriteRect[frameIndex] = new SDL.SDL_Rect { x = minX, y = minY, w = frameW, h = frameH };
|
||||
|
||||
directionCache.EquipmentHash = Equipment.HashKey;
|
||||
this.directionCache.Add(directionCache);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenDiablo2.ServiceBus.Message_Frames.Client
|
||||
{
|
||||
[MessageFrame(eMessageFrameType.UpdateEquipment)]
|
||||
public sealed class MFUpdateEquipment : IMessageFrame
|
||||
{
|
||||
public ItemInstance ItemInstance { get; internal set; }
|
||||
public string Slot { get; private set; }
|
||||
|
||||
public void WriteTo(BinaryWriter bw)
|
||||
{
|
||||
bw.Write(Slot);
|
||||
bw.Write(ItemInstance);
|
||||
}
|
||||
|
||||
public void LoadFrom(BinaryReader br)
|
||||
{
|
||||
Slot = br.ReadString();
|
||||
ItemInstance = br.ReadItemInstance();
|
||||
}
|
||||
|
||||
public MFUpdateEquipment() { }
|
||||
public MFUpdateEquipment(string slot, ItemInstance itemInstance)
|
||||
{
|
||||
Slot = slot;
|
||||
ItemInstance = itemInstance;
|
||||
}
|
||||
|
||||
public void Process(int clientHash, ISessionEventProvider sessionEventProvider)
|
||||
{
|
||||
sessionEventProvider.OnUpdateEquipment(clientHash, Slot, ItemInstance);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenDiablo2.ServiceBus.Message_Frames.Server
|
||||
{
|
||||
[MessageFrame(eMessageFrameType.ChangeEquipment)]
|
||||
public sealed class MFChangeEquipment : IMessageFrame
|
||||
{
|
||||
public PlayerEquipment PlayerEquipment { get; internal set; }
|
||||
public Guid PlayerId { get; internal set; }
|
||||
|
||||
public void WriteTo(BinaryWriter bw)
|
||||
{
|
||||
bw.Write(PlayerId.ToByteArray());
|
||||
bw.Write(PlayerEquipment);
|
||||
}
|
||||
|
||||
public void LoadFrom(BinaryReader br)
|
||||
{
|
||||
PlayerId = new Guid(br.ReadBytes(16));
|
||||
PlayerEquipment = br.ReadPlayerEquipment();
|
||||
}
|
||||
|
||||
public MFChangeEquipment() { }
|
||||
public MFChangeEquipment(Guid playerId, PlayerEquipment playerEquipment)
|
||||
{
|
||||
PlayerEquipment = playerEquipment;
|
||||
PlayerId = playerId;
|
||||
}
|
||||
|
||||
public void Process(int clientHash, ISessionEventProvider sessionEventProvider)
|
||||
{
|
||||
sessionEventProvider.OnChangeEquipment(clientHash, PlayerId, PlayerEquipment);
|
||||
}
|
||||
}
|
||||
}
|
@ -59,12 +59,14 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AutofacModule.cs" />
|
||||
<Compile Include="Message Frames\Client\MFUpdateEquipment.cs" />
|
||||
<Compile Include="Message Frames\Client\MFJoinGame.cs" />
|
||||
<Compile Include="Message Frames\Client\MFMoveRequest.cs" />
|
||||
<Compile Include="Message Frames\Server\MFFocusOnPlayer.cs" />
|
||||
<Compile Include="Message Frames\Server\MFPlayerInfo.cs" />
|
||||
<Compile Include="Message Frames\Server\MFLocatePlayers.cs" />
|
||||
<Compile Include="Message Frames\Server\MFSetSeed.cs" />
|
||||
<Compile Include="Message Frames\Server\MFChangeEquipment.cs" />
|
||||
<Compile Include="SessionManager.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SessionServer.cs" />
|
||||
|
@ -26,6 +26,8 @@ using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Exceptions;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Models;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using OpenDiablo2.ServiceBus.Message_Frames.Client;
|
||||
using OpenDiablo2.ServiceBus.Message_Frames.Server;
|
||||
|
||||
@ -51,6 +53,8 @@ namespace OpenDiablo2.ServiceBus
|
||||
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
|
||||
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
|
||||
public OnMoveRequest OnMoveRequest { get; set; }
|
||||
public OnUpdateEquipmentEvent OnUpdateEquipment { get; set; }
|
||||
public OnChangeEquipment OnChangeEquipment { get; set; }
|
||||
|
||||
public SessionManager(
|
||||
eSessionType sessionType,
|
||||
@ -176,5 +180,14 @@ namespace OpenDiablo2.ServiceBus
|
||||
Send(new MFMoveRequest(targetCell, movementType));
|
||||
ProcessMessageFrame<MFLocatePlayers>();
|
||||
});
|
||||
|
||||
public void UpdateEquipment(string slot, ItemInstance itemInstance)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Send(new MFUpdateEquipment(slot, itemInstance));
|
||||
ProcessMessageFrame<MFChangeEquipment>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,12 +48,14 @@ namespace OpenDiablo2.ServiceBus
|
||||
|
||||
public OnJoinGameEvent OnJoinGame { get; set; }
|
||||
public OnMoveRequest OnMoveRequest { get; set; }
|
||||
public OnUpdateEquipmentEvent OnUpdateEquipment { get; set; }
|
||||
|
||||
// TODO: Fix interface so we don't need this in the session server
|
||||
public OnSetSeedEvent OnSetSeed { get; set; }
|
||||
public OnLocatePlayersEvent OnLocatePlayers { get; set; }
|
||||
public OnPlayerInfoEvent OnPlayerInfo { get; set; }
|
||||
public OnFocusOnPlayer OnFocusOnPlayer { get; set; }
|
||||
public OnChangeEquipment OnChangeEquipment { get; set; }
|
||||
|
||||
const int serverUpdateRate = 30;
|
||||
|
||||
@ -94,6 +96,7 @@ namespace OpenDiablo2.ServiceBus
|
||||
|
||||
OnJoinGame += OnJoinGameHandler;
|
||||
OnMoveRequest += OnMovementRequestHandler;
|
||||
OnUpdateEquipment += OnUpdateEquipmentHandler;
|
||||
|
||||
var proactor = new NetMQProactor(responseSocket, (socket, message) =>
|
||||
{
|
||||
@ -226,5 +229,15 @@ namespace OpenDiablo2.ServiceBus
|
||||
Send(new MFLocatePlayers(gameServer.Players.Select(x => x.ToPlayerLocationDetails())), true);
|
||||
Send(new MFFocusOnPlayer(gameServer.Players.First(x => x.ClientHash == clientHash).UID));
|
||||
}
|
||||
|
||||
private void OnUpdateEquipmentHandler(int clientHash, string Slot, ItemInstance itemInstance)
|
||||
{
|
||||
var player = gameServer.Players.FirstOrDefault(x => x.ClientHash == clientHash);
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var equipment = gameServer.UpdateEquipment(clientHash, Slot, itemInstance);
|
||||
Send(new MFChangeEquipment(player.UID, equipment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user