mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-27 21:56:19 -04:00
Inventory based on hero type (#43)
* (Try to) Render inventory based on initial equipment for each hero type
This commit is contained in:
parent
dbd3e0b74f
commit
443fea069d
@ -1,4 +1,6 @@
|
||||
namespace OpenDiablo2.Common.Enums
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenDiablo2.Common.Enums
|
||||
{
|
||||
public enum eItemContainerType
|
||||
{
|
||||
|
@ -12,7 +12,6 @@
|
||||
MoveRequest = 0x06,
|
||||
PlayerMove = 0x07,
|
||||
|
||||
|
||||
MAX = 0xFF, // NOTE:
|
||||
// You absolutely cannot have a higher ID than this without
|
||||
// changing the message header to multi-byte for ALL frame types!!!
|
||||
|
@ -19,7 +19,7 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
MPQDS1 GetMPQDS1(string resourcePath, LevelPreset level, LevelType levelType);
|
||||
MPQDT1 GetMPQDT1(string resourcePath);
|
||||
Palette GetPalette(string paletteFile);
|
||||
MPQCOF GetPlayerAnimation(eHero hero, eWeaponClass weaponClass, eMobMode mobMode);
|
||||
MPQCOF GetPlayerAnimation(eHero hero, eWeaponClass weaponClass, eMobMode mobMode, string ShieldCode, string weaponCode);
|
||||
MPQDCC GetPlayerDCC(MPQCOF.COFLayer cofLayer, eArmorType armorType, Palette palette);
|
||||
|
||||
Dictionary<string, List<AnimationData>> Animations { get; }
|
||||
|
@ -12,6 +12,8 @@ namespace OpenDiablo2.Common.Interfaces.Drawing
|
||||
eWeaponClass WeaponClass { get; set; }
|
||||
eArmorType ArmorType { get; set; }
|
||||
eMobMode MobMode { get; set; }
|
||||
string ShieldCode { get; set; }
|
||||
string WeaponCode { get; set; }
|
||||
|
||||
void Update(long ms);
|
||||
void Render(int pixelOffsetX, int pixelOffsetY);
|
||||
|
@ -16,8 +16,8 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
Palette CurrentPalette { get; }
|
||||
IEnumerable<PlayerInfo> PlayerInfos { get; }
|
||||
|
||||
Item SelectedItem { get; }
|
||||
void SelectItem(Item item);
|
||||
ItemInstance SelectedItem { get; }
|
||||
void SelectItem(ItemInstance item);
|
||||
|
||||
int CameraOffset { get; set; }
|
||||
|
||||
|
30
OpenDiablo2.Common/Interfaces/IItemInstance.cs
Normal file
30
OpenDiablo2.Common/Interfaces/IItemInstance.cs
Normal file
@ -0,0 +1,30 @@
|
||||
/* OpenDiablo 2 - An open source re-implementation of Diablo 2 in C#
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using OpenDiablo2.Common.Models;
|
||||
using System;
|
||||
using System.Runtime.Caching;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
public interface IItemInstance
|
||||
{
|
||||
Item Item { get; }
|
||||
string Name { get; }
|
||||
int Level { get; }
|
||||
bool Identified { get; }
|
||||
}
|
||||
}
|
@ -6,5 +6,6 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
public interface IItemManager
|
||||
{
|
||||
Item getItem(string code);
|
||||
ItemInstance getItemInstance(string code);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -47,8 +48,6 @@ namespace OpenDiablo2.Common.Interfaces.Mobs
|
||||
int StartingSkill { get; }
|
||||
string BaseWeaponClass { get; }
|
||||
|
||||
IEnumerable<string> ItemNames { get; }
|
||||
IEnumerable<string> ItemLocs { get; }
|
||||
IEnumerable<int> ItemCounts { get; }
|
||||
List<InitialEquipment> InitialEquipment { get; }
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
public interface IItemContainer : IDisposable
|
||||
{
|
||||
Item ContainedItem { get; }
|
||||
ItemInstance ContainedItem { get; }
|
||||
Point Location { get; set; }
|
||||
|
||||
void SetContainedItem(Item containedItem);
|
||||
void SetContainedItem(ItemInstance containedItem);
|
||||
void Render();
|
||||
void Update();
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -9,7 +10,7 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
public sealed class Armor : Item
|
||||
{
|
||||
|
||||
public string Type { get; internal set; }
|
||||
}
|
||||
|
||||
public static class ArmorHelper
|
||||
|
25
OpenDiablo2.Common/Models/Item/ItemInstance.cs
Normal file
25
OpenDiablo2.Common/Models/Item/ItemInstance.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
/**
|
||||
* Base Item class, contains common attributes for all item types.
|
||||
**/
|
||||
public class ItemInstance : IItemInstance
|
||||
{
|
||||
public Item Item { get; internal set; }
|
||||
public string Name { get; internal set; }
|
||||
public int Level { get; internal set; }
|
||||
public bool Identified { get; internal set; }
|
||||
|
||||
public ItemInstance(Item item)
|
||||
{
|
||||
Item = item;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
public sealed class Weapon : Item
|
||||
{
|
||||
|
||||
public string WeaponClass { get; internal set; }
|
||||
}
|
||||
|
||||
public static class WeaponHelper
|
||||
@ -19,6 +19,7 @@ namespace OpenDiablo2.Common.Models
|
||||
{
|
||||
Name = row[0],
|
||||
Code = row[2],
|
||||
WeaponClass = row[34],
|
||||
InvFile = row[45]
|
||||
};
|
||||
}
|
||||
|
@ -18,10 +18,33 @@ namespace OpenDiablo2.Common.Models
|
||||
public bool IsTransparent { get; internal set; }
|
||||
public eDrawEffect DrawEffect { get; internal set; }
|
||||
public eWeaponClass WeaponClass { get; internal set; }
|
||||
public string ShieldCode { get; internal set; }
|
||||
public string WeaponCode { get; internal set; }
|
||||
|
||||
// TODO: Move logic somewhere else.
|
||||
// TODO: Consider two hand weapons.
|
||||
public string GetDCCPath(eArmorType armorType)
|
||||
{
|
||||
var result = $"{ResourcePaths.PlayerAnimationBase}\\{COF.Hero.ToToken()}\\{CompositType.ToToken()}\\{COF.Hero.ToToken()}{CompositType.ToToken()}{armorType.ToToken()}{COF.MobMode.ToToken()}{COF.WeaponClass.ToToken()}.dcc";
|
||||
string result = null;
|
||||
var weaponClass = COF.WeaponClass;
|
||||
if(CompositType != eCompositType.RightArm && CompositType != eCompositType.RightHand)
|
||||
{
|
||||
weaponClass = eWeaponClass.HandToHand;
|
||||
}
|
||||
|
||||
if(CompositType == eCompositType.Shield)
|
||||
{
|
||||
result = $"{ResourcePaths.PlayerAnimationBase}\\{COF.Hero.ToToken()}\\{CompositType.ToToken()}\\{COF.Hero.ToToken()}{CompositType.ToToken()}{ShieldCode}{COF.MobMode.ToToken()}{weaponClass.ToToken()}.dcc";
|
||||
}
|
||||
else if (CompositType == eCompositType.RightHand)
|
||||
{
|
||||
result = $"{ResourcePaths.PlayerAnimationBase}\\{COF.Hero.ToToken()}\\{CompositType.ToToken()}\\{COF.Hero.ToToken()}{CompositType.ToToken()}{WeaponCode}{COF.MobMode.ToToken()}{weaponClass.ToToken()}.dcc";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = $"{ResourcePaths.PlayerAnimationBase}\\{COF.Hero.ToToken()}\\{CompositType.ToToken()}\\{COF.Hero.ToToken()}{CompositType.ToToken()}{armorType.ToToken()}{COF.MobMode.ToToken()}{weaponClass.ToToken()}.dcc";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -35,7 +58,7 @@ namespace OpenDiablo2.Common.Models
|
||||
public IEnumerable<COFLayer> Layers { get; private set; }
|
||||
public IEnumerable<eAnimationFrame> AnimationFrames { get; private set; }
|
||||
|
||||
public static MPQCOF Load(Stream stream, Dictionary<string, List<AnimationData>> animations, eHero hero, eWeaponClass weaponClass, eMobMode mobMode)
|
||||
public static MPQCOF Load(Stream stream, Dictionary<string, List<AnimationData>> animations, eHero hero, eWeaponClass weaponClass, eMobMode mobMode, string ShieldCode, string weaponCode)
|
||||
{
|
||||
var result = new MPQCOF
|
||||
{
|
||||
@ -66,6 +89,8 @@ namespace OpenDiablo2.Common.Models
|
||||
layer.DrawEffect = (eDrawEffect)br.ReadByte();
|
||||
layers.Add(layer);
|
||||
layer.WeaponClass = Encoding.ASCII.GetString(br.ReadBytes(4)).Trim('\0').ToWeaponClass();
|
||||
layer.ShieldCode = ShieldCode;
|
||||
layer.WeaponCode = weaponCode;
|
||||
}
|
||||
result.Layers = layers;
|
||||
result.AnimationFrames = br.ReadBytes(framesPerDir).Select(x => (eAnimationFrame)x);
|
||||
|
@ -46,9 +46,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
public int StartingSkill { get; protected set; }
|
||||
public string BaseWeaponClass { get; protected set; }
|
||||
|
||||
public IEnumerable<string> ItemNames { get; }
|
||||
public IEnumerable<string> ItemLocs { get; }
|
||||
public IEnumerable<int> ItemCounts { get; }
|
||||
public List<InitialEquipment> InitialEquipment { get; }
|
||||
|
||||
public HeroTypeConfig(int vitality, int strength, int dexterity, int energy,
|
||||
int health, int mana, int stamina, int manaRegen,
|
||||
@ -59,7 +57,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
int walkFrames, int runFrames, int swingFrames, int spellFrames, int getHitFrames, int bowFrames,
|
||||
int startingSkill,
|
||||
string baseWeaponClass,
|
||||
List<string> itemNames, List<string> itemLocs, List<int> itemCounts)
|
||||
List<InitialEquipment> initialEquipment)
|
||||
{
|
||||
StartingDexterity = dexterity;
|
||||
StartingVitality = vitality;
|
||||
@ -97,12 +95,17 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
StartingSkill = startingSkill;
|
||||
BaseWeaponClass = baseWeaponClass;
|
||||
|
||||
ItemNames = itemNames;
|
||||
ItemLocs = itemLocs;
|
||||
ItemCounts = itemCounts;
|
||||
InitialEquipment = initialEquipment;
|
||||
}
|
||||
}
|
||||
|
||||
public struct InitialEquipment
|
||||
{
|
||||
public string name;
|
||||
public string location;
|
||||
public int count;
|
||||
};
|
||||
|
||||
public static class HeroTypeConfigHelper
|
||||
{
|
||||
public static IHeroTypeConfig ToHeroTypeConfig(this string[] row)
|
||||
@ -134,15 +137,21 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
// 57 58 59 60 61 62
|
||||
// item9 item9loc item9count item10 item10loc item10count
|
||||
|
||||
|
||||
|
||||
List<string> itemNames = new List<string>();
|
||||
List<string> itemLocs = new List<string>();
|
||||
List<int> itemCounts = new List<int>();
|
||||
List<InitialEquipment> initialEquipment = new List<InitialEquipment>();
|
||||
|
||||
for(int i = 33; i <= 60; i+=3)
|
||||
{
|
||||
itemNames.Add(row[i]);
|
||||
itemLocs.Add(row[i + 1]);
|
||||
itemCounts.Add(Convert.ToInt32(row[i + 2]));
|
||||
var item = new InitialEquipment();
|
||||
item.name = row[i];
|
||||
item.location = row[i + 1];
|
||||
item.count = Convert.ToInt32(row[i + 2]);
|
||||
|
||||
initialEquipment.Add(item);
|
||||
}
|
||||
|
||||
return new HeroTypeConfig(
|
||||
@ -175,9 +184,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
bowFrames: Convert.ToInt32(row[29]),
|
||||
startingSkill: Convert.ToInt32(row[31]),
|
||||
baseWeaponClass: row[32],
|
||||
itemNames: itemNames,
|
||||
itemLocs: itemLocs,
|
||||
itemCounts: itemCounts);
|
||||
initialEquipment: initialEquipment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Enums.Mobs;
|
||||
using OpenDiablo2.Common.Interfaces.Mobs;
|
||||
@ -34,6 +35,11 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
public eArmorType ArmorType { get; set; } = eArmorType.Lite; // Temporary
|
||||
public eMobMode MobMode { get; set; } = eMobMode.PlayerTownWalk; // Temporary
|
||||
|
||||
// Remove when we're passing the full inventory. Used for animations.
|
||||
public string ShieldCode { get; set; }
|
||||
public string WeaponCode { get; set; }
|
||||
// ---
|
||||
|
||||
// Player character stats
|
||||
protected Stat Vitality;
|
||||
protected Stat Strength;
|
||||
@ -51,7 +57,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
protected Stat RunVelocity;
|
||||
protected Stat RunDrain;
|
||||
|
||||
|
||||
public Dictionary<String, ItemInstance> Equipment = new Dictionary<string, ItemInstance> ();
|
||||
|
||||
public long Experience { get; protected set; }
|
||||
|
||||
@ -81,6 +87,7 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
|
||||
Experience = experience; // how much total exp do they have
|
||||
|
||||
|
||||
HeroType = herotype;
|
||||
HeroTypeConfig = heroconfig;
|
||||
ExperienceConfig = expconfig;
|
||||
@ -94,6 +101,27 @@ namespace OpenDiablo2.Common.Models.Mobs
|
||||
RefreshDerived();
|
||||
}
|
||||
|
||||
public void UpdateEquipment(string slot, ItemInstance item)
|
||||
{
|
||||
if(Equipment.ContainsKey(slot))
|
||||
{
|
||||
Equipment.Remove(slot);
|
||||
}
|
||||
|
||||
Equipment.Add(slot, item);
|
||||
|
||||
if(item.Item is Weapon)
|
||||
{
|
||||
WeaponClass = ((Weapon)item.Item).WeaponClass.ToWeaponClass();
|
||||
WeaponCode = item.Item.Code;
|
||||
}
|
||||
|
||||
if(item.Item is Armor && slot == "larm") // Shield
|
||||
{
|
||||
ShieldCode = item.Item.Code;
|
||||
}
|
||||
}
|
||||
|
||||
#region Level and Experience
|
||||
public long GetExperienceToLevel()
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models.Mobs;
|
||||
@ -31,39 +32,51 @@ namespace OpenDiablo2.Common.Models
|
||||
public eArmorType ArmorType { get; set; }
|
||||
public eMobMode MobMode { get; set; }
|
||||
public PlayerLocationDetails LocationDetails { get; set; }
|
||||
public string ShieldCode { get; set; }
|
||||
public string WeaponCode { get; set; }
|
||||
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
var result = new List<byte>();
|
||||
var nameBytes = Encoding.UTF8.GetBytes(Name);
|
||||
result.Add((byte)Hero);
|
||||
result.Add((byte)WeaponClass);
|
||||
result.Add((byte)ArmorType);
|
||||
result.Add((byte)MobMode);
|
||||
result.AddRange(BitConverter.GetBytes(nameBytes.Length));
|
||||
result.AddRange(nameBytes);
|
||||
result.AddRange(LocationDetails.GetBytes());
|
||||
result.AddRange(UID.ToByteArray());
|
||||
return result.ToArray();
|
||||
using (var stream = new MemoryStream())
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
writer.Write((byte)Hero);
|
||||
writer.Write((byte)WeaponClass);
|
||||
writer.Write((byte)ArmorType);
|
||||
writer.Write((byte)MobMode);
|
||||
writer.Write(Name);
|
||||
writer.Write(ShieldCode != null ? ShieldCode : "");
|
||||
writer.Write(WeaponCode != null ? WeaponCode : "");
|
||||
writer.Write(LocationDetails.GetBytes());
|
||||
writer.Write(UID.ToByteArray());
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerInfo FromBytes(byte[] data, int offset = 0)
|
||||
{
|
||||
using (var stream = new MemoryStream(data))
|
||||
using (var reader = new BinaryReader(stream))
|
||||
{
|
||||
reader.ReadBytes(offset); // Skip
|
||||
|
||||
var result = new PlayerInfo
|
||||
{
|
||||
Hero = (eHero)data[offset],
|
||||
WeaponClass = (eWeaponClass)data[offset + 1],
|
||||
ArmorType = (eArmorType)data[offset + 2],
|
||||
MobMode = (eMobMode)data[offset + 3]
|
||||
Hero = (eHero)reader.ReadByte(),
|
||||
WeaponClass = (eWeaponClass)reader.ReadByte(),
|
||||
ArmorType = (eArmorType)reader.ReadByte(),
|
||||
MobMode = (eMobMode)reader.ReadByte(),
|
||||
Name = reader.ReadString(),
|
||||
ShieldCode = reader.ReadString(),
|
||||
WeaponCode = reader.ReadString(),
|
||||
LocationDetails = PlayerLocationDetails.FromBytes(reader.ReadBytes(PlayerLocationDetails.SizeInBytes)),
|
||||
UID = new Guid(reader.ReadBytes(16))
|
||||
};
|
||||
var nameLength = BitConverter.ToInt32(data, offset + 4);
|
||||
result.Name = Encoding.UTF8.GetString(data, offset + 8, nameLength);
|
||||
result.LocationDetails = PlayerLocationDetails.FromBytes(data, offset + 8 + nameLength);
|
||||
var uidBytes = new byte[16];
|
||||
Array.Copy(data, offset + 8 + nameLength + PlayerLocationDetails.SizeInBytes, uidBytes, 0, 16);
|
||||
result.UID = new Guid(uidBytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public int SizeInBytes => 8 + Encoding.UTF8.GetByteCount(Name) + PlayerLocationDetails.SizeInBytes + 16;
|
||||
}
|
||||
@ -86,7 +99,9 @@ namespace OpenDiablo2.Common.Models
|
||||
Name = source.Name,
|
||||
WeaponClass = source.WeaponClass,
|
||||
ArmorType = source.ArmorType,
|
||||
MobMode = source.MobMode
|
||||
MobMode = source.MobMode,
|
||||
ShieldCode = source.ShieldCode,
|
||||
WeaponCode = source.WeaponCode
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +87,7 @@
|
||||
<Compile Include="Exceptions\OpenDiablo2Exception.cs" />
|
||||
<Compile Include="Extensions\EnumExtensions.cs" />
|
||||
<Compile Include="Interfaces\Drawing\ICharacterRenderer.cs" />
|
||||
<Compile Include="Interfaces\IItemInstance.cs" />
|
||||
<Compile Include="Interfaces\ICache.cs" />
|
||||
<Compile Include="Interfaces\IItemManager.cs" />
|
||||
<Compile Include="Extensions\MobManagerExtensions.cs" />
|
||||
@ -100,6 +101,7 @@
|
||||
<Compile Include="Interfaces\UI\IPanel.cs" />
|
||||
<Compile Include="Models\AnimationData.cs" />
|
||||
<Compile Include="Models\BitMuncher.cs" />
|
||||
<Compile Include="Models\Item\ItemInstance.cs" />
|
||||
<Compile Include="Models\MPQCOF.cs" />
|
||||
<Compile Include="Models\MPQDCC.cs" />
|
||||
<Compile Include="Models\ItemContainerLayout.cs" />
|
||||
|
@ -40,7 +40,7 @@ namespace OpenDiablo2.Core.GameState_
|
||||
|
||||
public int Seed { get; internal set; }
|
||||
|
||||
public Item SelectedItem { get; internal set; }
|
||||
public ItemInstance SelectedItem { get; internal set; }
|
||||
public object ThreadLocker { get; } = new object();
|
||||
|
||||
public int CameraOffset { get; set; } = 0;
|
||||
@ -288,7 +288,7 @@ namespace OpenDiablo2.Core.GameState_
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void SelectItem(Item item)
|
||||
public void SelectItem(ItemInstance item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
@ -296,7 +296,7 @@ namespace OpenDiablo2.Core.GameState_
|
||||
}
|
||||
else
|
||||
{
|
||||
var cursorsprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(item.InvFile), Palettes.Units);
|
||||
var cursorsprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(item.Item.InvFile), Palettes.Units);
|
||||
|
||||
renderWindow.MouseCursor = renderWindow.LoadCursor(cursorsprite, 0, new Point(cursorsprite.FrameSize.Width / 2, cursorsprite.FrameSize.Height / 2));
|
||||
}
|
||||
|
@ -36,5 +36,10 @@ namespace OpenDiablo2.Core
|
||||
return item;
|
||||
}
|
||||
|
||||
public ItemInstance getItemInstance(string code)
|
||||
{
|
||||
return new ItemInstance(getItem(code));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,8 @@ namespace OpenDiablo2.Core.Map_Engine
|
||||
cr.WeaponClass = info.WeaponClass;
|
||||
cr.Hero = info.Hero;
|
||||
cr.ArmorType = info.ArmorType;
|
||||
cr.ShieldCode = info.ShieldCode;
|
||||
cr.WeaponCode = info.WeaponCode;
|
||||
characterRenderers.Add(cr);
|
||||
cr.ResetAnimationData();
|
||||
}
|
||||
|
@ -63,11 +63,11 @@ namespace OpenDiablo2.Core
|
||||
public MPQDT1 GetMPQDT1(string resourcePath)
|
||||
=> cache.AddOrGetExisting($"DT1::{resourcePath}", () => new MPQDT1(mpqProvider.GetStream(resourcePath)));
|
||||
|
||||
public MPQCOF GetPlayerAnimation(eHero hero, eWeaponClass weaponClass, eMobMode mobMode)
|
||||
public MPQCOF GetPlayerAnimation(eHero hero, eWeaponClass weaponClass, eMobMode mobMode, string shieldCode, string weaponCode)
|
||||
=> cache.AddOrGetExisting($"COF::{hero}::{weaponClass}::{mobMode}", () =>
|
||||
{
|
||||
var path = $"{ResourcePaths.PlayerAnimationBase}\\{hero.ToToken()}\\COF\\{hero.ToToken()}{mobMode.ToToken()}{weaponClass.ToToken()}.cof";
|
||||
return MPQCOF.Load(mpqProvider.GetStream(path), Animations, hero, weaponClass, mobMode);
|
||||
return MPQCOF.Load(mpqProvider.GetStream(path), Animations, hero, weaponClass, mobMode, shieldCode, weaponCode);
|
||||
});
|
||||
|
||||
public MPQDCC GetPlayerDCC(MPQCOF.COFLayer cofLayer, eArmorType armorType, Palette palette)
|
||||
|
@ -70,51 +70,39 @@ namespace OpenDiablo2.Core.UI
|
||||
|
||||
helmContainer = createItemContainer(eItemContainerType.Helm);
|
||||
helmContainer.Location = panelSprite.Location + new Size(135, 5);
|
||||
helmContainer.SetContainedItem(itemManager.getItem("cap"));
|
||||
|
||||
amuletContainer = createItemContainer(eItemContainerType.Amulet);
|
||||
amuletContainer.Location = panelSprite.Location + new Size(209, 34);
|
||||
amuletContainer.SetContainedItem(itemManager.getItem("vip"));
|
||||
|
||||
armorContainer = createItemContainer(eItemContainerType.Armor);
|
||||
armorContainer.Location = panelSprite.Location + new Size(135, 75);
|
||||
armorContainer.SetContainedItem(itemManager.getItem("hla"));
|
||||
|
||||
leftHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
leftHandContainer.Location = panelSprite.Location + new Size(20, 47);
|
||||
leftHandContainer.SetContainedItem(itemManager.getItem("ame"));
|
||||
|
||||
rightHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
rightHandContainer.Location = panelSprite.Location + new Size(253, 47);
|
||||
rightHandContainer.SetContainedItem(itemManager.getItem("paf"));
|
||||
|
||||
secondaryLeftHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
secondaryLeftHandContainer.Location = panelSprite.Location + new Size(24, 45);
|
||||
secondaryLeftHandContainer.SetContainedItem(itemManager.getItem("crs"));
|
||||
|
||||
secondaryRightHandContainer = createItemContainer(eItemContainerType.Weapon);
|
||||
secondaryRightHandContainer.Location = panelSprite.Location + new Size(257, 45);
|
||||
secondaryRightHandContainer.SetContainedItem(itemManager.getItem("kit"));
|
||||
|
||||
beltContainer = createItemContainer(eItemContainerType.Belt);
|
||||
beltContainer.Location = panelSprite.Location + new Size(136, 178);
|
||||
beltContainer.SetContainedItem(itemManager.getItem("vbl"));
|
||||
|
||||
ringtLeftContainer = createItemContainer(eItemContainerType.Ring);
|
||||
ringtLeftContainer.Location = panelSprite.Location + new Size(95, 179);
|
||||
ringtLeftContainer.SetContainedItem(itemManager.getItem("rin"));
|
||||
|
||||
ringtRightContainer = createItemContainer(eItemContainerType.Ring);
|
||||
ringtRightContainer.Location = panelSprite.Location + new Size(209, 179);
|
||||
ringtRightContainer.SetContainedItem(itemManager.getItem("rin"));
|
||||
|
||||
gloveContainer = createItemContainer(eItemContainerType.Glove);
|
||||
gloveContainer.Location = panelSprite.Location + new Size(20, 179);
|
||||
gloveContainer.SetContainedItem(itemManager.getItem("tgl"));
|
||||
|
||||
bootsContainer = createItemContainer(eItemContainerType.Boots);
|
||||
bootsContainer.Location = panelSprite.Location + new Size(251, 178);
|
||||
bootsContainer.SetContainedItem(itemManager.getItem("lbt"));
|
||||
}
|
||||
|
||||
public eButtonType PanelType => eButtonType.MinipanelInventory;
|
||||
|
@ -17,7 +17,7 @@ namespace OpenDiablo2.Core.UI
|
||||
private readonly ItemContainerLayout itemContainerLayout;
|
||||
private readonly IMouseInfoProvider mouseInfoProvider;
|
||||
|
||||
public Item ContainedItem { get; internal set; }
|
||||
public ItemInstance ContainedItem { get; internal set; }
|
||||
|
||||
private readonly Dictionary<eItemContainerType, ISprite> sprites = new Dictionary<eItemContainerType, ISprite>();
|
||||
|
||||
@ -52,13 +52,13 @@ namespace OpenDiablo2.Core.UI
|
||||
this.Size = placeholderSprite.FrameSize; // For all but generic size is equal to the placeholder size. Source: me.
|
||||
}
|
||||
|
||||
public void SetContainedItem(Item containedItem)
|
||||
public void SetContainedItem(ItemInstance containedItem)
|
||||
{
|
||||
ContainedItem = containedItem;
|
||||
|
||||
if (ContainedItem != null)
|
||||
{
|
||||
sprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(this.ContainedItem.InvFile), Palettes.Units, true);
|
||||
sprite = renderWindow.LoadSprite(ResourcePaths.GeneratePathForItem(this.ContainedItem.Item.InvFile), Palettes.Units, true);
|
||||
sprite.Location = new Point(location.X, location.Y + sprite.LocalFrameSize.Height);
|
||||
}
|
||||
}
|
||||
@ -107,8 +107,11 @@ namespace OpenDiablo2.Core.UI
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if(sprite != null)
|
||||
{
|
||||
sprite.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,16 +13,18 @@ namespace OpenDiablo2.GameServer_
|
||||
|
||||
private readonly IMobManager mobManager;
|
||||
private readonly IEngineDataManager engineDataManager;
|
||||
private readonly IItemManager itemManager;
|
||||
|
||||
public int Seed { get; private set; }
|
||||
public IEnumerable<PlayerState> Players => mobManager.Players;
|
||||
|
||||
const double Deg2Rad = Math.PI / 180.0;
|
||||
|
||||
public GameServer(IMobManager mobManager, IEngineDataManager engineDataManager)
|
||||
public GameServer(IMobManager mobManager, IEngineDataManager engineDataManager, IItemManager itemManager)
|
||||
{
|
||||
this.mobManager = mobManager;
|
||||
this.engineDataManager = engineDataManager;
|
||||
this.itemManager = itemManager;
|
||||
}
|
||||
|
||||
public void InitializeNewGame()
|
||||
@ -53,8 +55,9 @@ namespace OpenDiablo2.GameServer_
|
||||
else
|
||||
{
|
||||
log.Error("Error: Hero Config not loaded for '" + heroType.ToString() + "'.");
|
||||
heroConfig = new HeroTypeConfig(10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 9,
|
||||
1, 10, 10, 10, 10, 10, 10, 0, "hth", new List<string>(), new List<string>(), new List<int>());
|
||||
// Do we even need a default?
|
||||
//heroConfig = new HeroTypeConfig(10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 9,
|
||||
// 1, 10, 10, 10, 10, 10, 10, 0, "hth");
|
||||
// TODO: should we have a more robust default hero config?
|
||||
// or should we just fail in some way here?
|
||||
// ... we should probably just fail here
|
||||
@ -63,6 +66,17 @@ namespace OpenDiablo2.GameServer_
|
||||
var newPlayer = new PlayerState(clientHash, playerName, mobManager.GetNextAvailableMobId(), 1, 20.0f, 20.0f, 10, 10, 10, 10, 0, heroType,
|
||||
heroConfig, expConfig);
|
||||
|
||||
// This is probably not the right place to do this.
|
||||
// Only add items with a location set, the other ones go into the inventory - that we do not support yet
|
||||
foreach (var item in heroConfig.InitialEquipment)
|
||||
{
|
||||
if (item.location.Length > 0)
|
||||
{
|
||||
newPlayer.UpdateEquipment(item.location, itemManager.getItemInstance(item.name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mobManager.AddPlayer(newPlayer);
|
||||
return newPlayer.Id;
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ namespace OpenDiablo2.SDL2_
|
||||
public eWeaponClass WeaponClass { get; set; }
|
||||
public eArmorType ArmorType { get; set; }
|
||||
public eMobMode MobMode { get; set; }
|
||||
public string ShieldCode { get; set; }
|
||||
public string WeaponCode { get; set; }
|
||||
|
||||
private readonly IntPtr renderer;
|
||||
|
||||
@ -132,7 +134,7 @@ namespace OpenDiablo2.SDL2_
|
||||
return;
|
||||
}
|
||||
|
||||
animationData = resourceManager.GetPlayerAnimation(Hero, WeaponClass, MobMode);
|
||||
animationData = resourceManager.GetPlayerAnimation(Hero, WeaponClass, MobMode, ShieldCode, WeaponCode);
|
||||
if (animationData == null)
|
||||
throw new OpenDiablo2Exception("Could not locate animation for the character!");
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Text;
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
@ -16,19 +19,25 @@ namespace OpenDiablo2.ServiceBus.Message_Frames.Client
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get => new byte[] { (byte)HeroType }
|
||||
.Concat(BitConverter.GetBytes((UInt16)PlayerName.Length))
|
||||
.Concat(Encoding.UTF8.GetBytes(PlayerName))
|
||||
.ToArray();
|
||||
get
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
using (var writer = new BinaryWriter(stream)) {
|
||||
writer.Write((byte)HeroType);
|
||||
writer.Write(PlayerName);
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
HeroType = (eHero)value[0];
|
||||
var playerNameLen = BitConverter.ToUInt16(value, 1);
|
||||
PlayerName = Encoding.UTF8.GetString(value, 3, value.Length - 3);
|
||||
|
||||
if (PlayerName.Length != playerNameLen)
|
||||
throw new OpenDiablo2Exception("Invalid player length!");
|
||||
using(var stream = new MemoryStream(value))
|
||||
using(var reader = new BinaryReader(stream))
|
||||
{
|
||||
HeroType = (eHero)reader.ReadByte();
|
||||
PlayerName = reader.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user