M Core/NosSmooth.Game/Data/Characters/Character.cs => Core/NosSmooth.Game/Data/Characters/Character.cs +63 -86
@@ 16,89 16,66 @@ namespace NosSmooth.Game.Data.Characters;
/// <summary>
/// Represents the client character.
/// </summary>
-/// <param name="Inventory">The character's inventory with items.</param>
-/// <param name="Family">The family of the character, if any..</param>
-/// <param name="Friends">The friends of the character.</param>
-/// <param name="Skills">The current skill set of the character.</param>
-/// <param name="Group">The group the character is in, if any. Contains pets and partners as well.</param>
-/// <param name="SkillCp">The skill cp amount used for learning new skills.</param>
-/// <param name="Id">The id of the character entity.</param>
-/// <param name="Name">The name of the character entity.</param>
-/// <param name="Position">The position of the character.</param>
-/// <param name="Speed">The movement speed of the character.</param>
-/// <param name="Level">The </param>
-/// <param name="JobLevel">The </param>
-/// <param name="HeroLevel">The </param>
-/// <param name="Direction"></param>
-/// <param name="Hp"></param>
-/// <param name="Mp"></param>
-/// <param name="Faction"></param>
-/// <param name="Size"></param>
-/// <param name="AuthorityType"></param>
-/// <param name="Sex"></param>
-/// <param name="HairStyle"></param>
-/// <param name="HairColor"></param>
-/// <param name="Class"></param>
-/// <param name="Icon"></param>
-/// <param name="Compliment"></param>
-/// <param name="Morph"></param>
-/// <param name="ArenaWinner"></param>
-/// <param name="Invisible"></param>
-/// <param name="Reputation"></param>
-public record Character
-(
- Inventory.Inventory? Inventory = default,
- Family? Family = default,
- IReadOnlyList<Friend>? Friends = default,
- Skills? Skills = default,
- Group? Group = default,
- int? SkillCp = default,
- long Id = default,
- string? Name = default,
- Position? Position = default,
- byte? Speed = default,
- Level? Level = default,
- Level? JobLevel = default,
- Level? HeroLevel = default,
- byte? Direction = default,
- Health? Hp = default,
- Health? Mp = default,
- FactionType? Faction = default,
- short Size = default,
- AuthorityType AuthorityType = default,
- SexType Sex = default,
- HairStyle HairStyle = default,
- HairColor HairColor = default,
- PlayerClass Class = default,
- byte? Icon = default,
- short? Compliment = default,
- Morph? Morph = default,
- bool? ArenaWinner = default,
- bool? Invisible = default,
- long? Reputation = default,
- IReadOnlyList<long>? EffectsVNums = default
-) : Player(
- Id,
- Name,
- Position,
- Speed,
- Level,
- HeroLevel,
- Direction,
- Hp,
- Mp,
- Faction,
- Size,
- AuthorityType,
- Sex,
- HairStyle,
- HairColor,
- Class,
- Icon,
- Compliment,
- Morph,
- ArenaWinner,
- Invisible,
- Reputation,
- EffectsVNums
-);>
\ No newline at end of file
+public class Character : Player
+{
+ /// <summary>
+ /// Gets or sets whether the character can't move.
+ /// </summary>
+ public bool Stunned { get; set; }
+
+ /// <summary>
+ /// Gets or sets the inventory of the character.
+ /// </summary>
+ public Inventory.Inventory? Inventory { get; set; }
+
+ /// <summary>
+ /// Get or sets the friends of the character.
+ /// </summary>
+ public IReadOnlyList<Friend>? Friends { get; set; }
+
+ /// <summary>
+ /// Gets or sets the skills of the player.
+ /// </summary>
+ public Skills? Skills { get; set; }
+
+ /// <summary>
+ /// Gets or sets the group the player is in.
+ /// </summary>
+ public Group? Group { get; set; }
+
+ /// <summary>
+ /// Gets or sets the c skill points.
+ /// </summary>
+ public int? SkillCp { get; set; }
+
+ /// <summary>
+ /// Gets or sets the job level.
+ /// </summary>
+ public Level? JobLevel { get; set; }
+
+ /// <summary>
+ /// Gets or sets the player level.
+ /// </summary>
+ public Level? PlayerLevel { get; set; }
+
+ /// <summary>
+ /// Gets or sets the player level.
+ /// </summary>
+ public Level? HeroLevelStruct { get; set; }
+
+ /// <inheritdoc/>
+ public override short? HeroLevel
+ {
+ get => HeroLevelStruct?.Lvl;
+ set
+ {
+ if (HeroLevelStruct is not null && value is not null)
+ {
+ HeroLevelStruct = HeroLevelStruct with
+ {
+ Lvl = value.Value
+ };
+ }
+ }
+ }
+}<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Characters/Skill.cs => Core/NosSmooth.Game/Data/Characters/Skill.cs +3 -6
@@ 4,6 4,8 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using NosSmooth.Data.Abstractions.Infos;
+
namespace NosSmooth.Game.Data.Characters;
/// <summary>
@@ 11,7 13,7 @@ namespace NosSmooth.Game.Data.Characters;
/// </summary>
/// <param name="SkillVNum">The vnum of the skill.</param>
/// <param name="Level">The level of the skill. Unknown feature.</param>
-public record Skill(long SkillVNum, int? Level = default)
+public record Skill(int SkillVNum, int? Level = default, ISkillInfo? Info = default)
{
/// <summary>
/// Gets the last time this skill was used.
@@ 19,11 21,6 @@ public record Skill(long SkillVNum, int? Level = default)
public DateTimeOffset LastUseTime { get; internal set; }
/// <summary>
- /// Gets the cooldown of the skill.
- /// </summary>
- public TimeSpan? Cooldown { get; internal set; }
-
- /// <summary>
/// Gets whether the skill is on cooldown.
/// </summary>
/// <remarks>
M Core/NosSmooth.Game/Data/Entities/GroundItem.cs => Core/NosSmooth.Game/Data/Entities/GroundItem.cs +37 -8
@@ 4,6 4,7 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using NosSmooth.Data.Abstractions.Infos;
using NosSmooth.Game.Data.Info;
using NosSmooth.Packets.Enums;
@@ 12,14 13,42 @@ namespace NosSmooth.Game.Data.Entities;
/// <summary>
/// The item on the ground.
/// </summary>
-/// <param name="Id">The id of the item entity.</param>
-/// <param name="ItemVNum">The vnum of the dropped item.</param>
-/// <param name="Position">The position of the ground item.</param>
-public record GroundItem(long Id, long ItemVNum, Position? Position) : IEntity
+public class GroundItem : IEntity
{
- /// <inheritdoc />
- public string? Name => null;
+ /// <summary>
+ /// Gets or sets the id of the owner, if any.
+ /// </summary>
+ public long? OwnerId { get; set; }
- /// <inheritdoc />
- public EntityType Type => EntityType.Object;
+ /// <summary>
+ /// Gets or sets the amount of the item on the ground.
+ /// </summary>
+ public int Amount { get; internal set; }
+
+ /// <summary>
+ /// Gets or sets whether the item is for a quest.
+ /// </summary>
+ public bool IsQuestRelated { get; internal set; }
+
+ /// <summary>
+ /// Gets or sets the info about the item, if available.
+ /// </summary>
+ public IItemInfo? ItemInfo { get; internal set; }
+
+ /// <summary>
+ /// Gets the VNum of the npc.
+ /// </summary>
+ public int VNum { get; internal set; }
+
+ /// <inheritdoc/>
+ public long Id { get; set; }
+
+ /// <inheritdoc/>
+ public Position? Position { get; set; }
+
+ /// <inheritdoc/>
+ public EntityType Type
+ {
+ get => EntityType.Object;
+ }
}=
\ No newline at end of file
M Core/NosSmooth.Game/Data/Entities/IEntity.cs => Core/NosSmooth.Game/Data/Entities/IEntity.cs +2 -7
@@ 17,17 17,12 @@ public interface IEntity
/// <summary>
/// Gets the id of the entity.
/// </summary>
- public long Id { get; }
-
- /// <summary>
- /// Gets the name of the entity. May be null if unknown.
- /// </summary>
- public string? Name { get; }
+ public long Id { get; set; }
/// <summary>
/// Gets the position of the entity.
/// </summary>
- public Position? Position { get; }
+ public Position? Position { get; set; }
/// <summary>
/// Gets the type of the entity.
M Core/NosSmooth.Game/Data/Entities/LivingEntity.cs => Core/NosSmooth.Game/Data/Entities/LivingEntity.cs +33 -8
@@ 17,40 17,65 @@ public interface ILivingEntity : IEntity
/// <summary>
/// Gets the speed of the entity. May be null if unknown.
/// </summary>
- public byte? Speed { get; }
+ public int? Speed { get; set; }
+
+ /// <summary>
+ /// Gets or sets whether the player is invisible.
+ /// </summary>
+ public bool? IsInvisible { get; set; }
/// <summary>
/// Gets the level of the entity. May be null if unknown.
/// </summary>
- public ushort? Level { get; }
+ public ushort? Level { get; set; }
/// <summary>
/// Gets the direction the entity is looking. May be null if unknown.
/// </summary>
- public byte? Direction { get; }
+ public byte? Direction { get; set; }
/// <summary>
/// Gets the percentage of the health points of the entity. May be null if unknown.
/// </summary>
- public Health? Hp { get; }
+ public Health? Hp { get; set; }
/// <summary>
/// Gets the percentage of the mana points of the entity. May be null if unknown.
/// </summary>
- public Health? Mp { get; }
+ public Health? Mp { get; set; }
/// <summary>
/// Gets the faction of the entity. May be null if unknown.
/// </summary>
- public FactionType? Faction { get; }
+ public FactionType? Faction { get; set; }
/// <summary>
/// Gets the size of the entity.
/// </summary>
- public short Size { get; }
+ public short Size { get; set; }
/// <summary>
/// Gets the VNums of the effects the entity has.
/// </summary>
- public IReadOnlyList<long>? EffectsVNums { get; }
+ public IReadOnlyList<long>? EffectsVNums { get; set; }
+
+ /// <summary>
+ /// Gets the name of the entity. May be null if unknown.
+ /// </summary>
+ public string? Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets whether the entity is sitting.
+ /// </summary>
+ public bool IsSitting { get; set; }
+
+ /// <summary>
+ /// Gets or sets whether the entity cannot move.
+ /// </summary>
+ public bool CantMove { get; set; }
+
+ /// <summary>
+ /// Gets or sets whether the entity cannot attack.
+ /// </summary>
+ public bool CantAttack { get; set; }
}=
\ No newline at end of file
M Core/NosSmooth.Game/Data/Entities/Monster.cs => Core/NosSmooth.Game/Data/Entities/Monster.cs +57 -26
@@ 4,6 4,7 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using NosSmooth.Data.Abstractions.Infos;
using NosSmooth.Game.Data.Info;
using NosSmooth.Packets.Enums;
@@ 12,33 13,63 @@ namespace NosSmooth.Game.Data.Entities;
/// <summary>
/// Represents nostale monster entity.
/// </summary>
-/// <param name="Id"></param>
-/// <param name="Name"></param>
-/// <param name="Position"></param>
-/// <param name="Speed"></param>
-/// <param name="Level"></param>
-/// <param name="Direction"></param>
-/// <param name="Hp"></param>
-/// <param name="Mp"></param>
-/// <param name="Faction"></param>
-/// <param name="Size"></param>
-/// <param name="MonsterVNum"></param>
-public record Monster
-(
- long Id,
- string? Name,
- Position? Position,
- byte? Speed,
- ushort? Level,
- byte? Direction,
- Health? Hp,
- Health? Mp,
- FactionType? Faction,
- short Size,
- long MonsterVNum,
- IReadOnlyList<long>? EffectsVNums = default
-) : ILivingEntity
+public class Monster : ILivingEntity
{
+ /// <summary>
+ /// Gets or sets the monster info.
+ /// </summary>
+ public IMonsterInfo? MonsterInfo { get; set; }
+
+ /// <summary>
+ /// Gets the VNum of the monster.
+ /// </summary>
+ public int VNum { get; set; }
+
+ /// <inheritdoc/>
+ public long Id { get; set; }
+
+ /// <inheritdoc/>
+ public string? Name { get; set; }
+
+ /// <inheritdoc />
+ public bool IsSitting { get; set; }
+
+ /// <inheritdoc />
+ public bool CantMove { get; set; }
+
+ /// <inheritdoc />
+ public bool CantAttack { get; set; }
+
+ /// <inheritdoc/>
+ public Position? Position { get; set; }
+
/// <inheritdoc/>
public EntityType Type => EntityType.Monster;
+
+ /// <inheritdoc/>
+ public int? Speed { get; set; }
+
+ /// <inheritdoc />
+ public bool? IsInvisible { get; set; }
+
+ /// <inheritdoc/>
+ public ushort? Level { get; set; }
+
+ /// <inheritdoc/>
+ public byte? Direction { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Hp { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Mp { get; set; }
+
+ /// <inheritdoc/>
+ public FactionType? Faction { get; set; }
+
+ /// <inheritdoc/>
+ public short Size { get; set; }
+
+ /// <inheritdoc/>
+ public IReadOnlyList<long>? EffectsVNums { get; set; }
}=
\ No newline at end of file
M Core/NosSmooth.Game/Data/Entities/Npc.cs => Core/NosSmooth.Game/Data/Entities/Npc.cs +58 -1
@@ 4,9 4,66 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using NosSmooth.Game.Data.Info;
+using NosSmooth.Packets.Enums;
+
namespace NosSmooth.Game.Data.Entities;
/// <summary>
/// Represents nostale npc entity.
/// </summary>
-public record Npc();>
\ No newline at end of file
+public class Npc : ILivingEntity
+{
+ /// <summary>
+ /// Gets the VNum of the npc.
+ /// </summary>
+ public int VNum { get; internal set; }
+
+ /// <inheritdoc/>
+ public long Id { get; set; }
+
+ /// <inheritdoc/>
+ public string? Name { get; set; }
+
+ /// <inheritdoc />
+ public bool IsSitting { get; set; }
+
+ /// <inheritdoc />
+ public bool CantMove { get; set; }
+
+ /// <inheritdoc />
+ public bool CantAttack { get; set; }
+
+ /// <inheritdoc/>
+ public Position? Position { get; set; }
+
+ /// <inheritdoc/>
+ public EntityType Type => EntityType.Npc;
+
+ /// <inheritdoc/>
+ public int? Speed { get; set; }
+
+ /// <inheritdoc />
+ public bool? IsInvisible { get; set; }
+
+ /// <inheritdoc/>
+ public ushort? Level { get; set; }
+
+ /// <inheritdoc/>
+ public byte? Direction { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Hp { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Mp { get; set; }
+
+ /// <inheritdoc/>
+ public FactionType? Faction { get; set; }
+
+ /// <inheritdoc/>
+ public short Size { get; set; }
+
+ /// <inheritdoc/>
+ public IReadOnlyList<long>? EffectsVNums { get; set; }
+}<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Entities/Player.cs => Core/NosSmooth.Game/Data/Entities/Player.cs +121 -47
@@ 5,6 5,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using NosSmooth.Game.Data.Info;
+using NosSmooth.Game.Data.Items;
+using NosSmooth.Game.Data.Social;
using NosSmooth.Packets.Enums;
using NosSmooth.Packets.Enums.Players;
@@ 13,56 15,128 @@ namespace NosSmooth.Game.Data.Entities;
/// <summary>
/// Represents nostale player entity.
/// </summary>
-/// <param name="Id">The id of the player.</param>
-/// <param name="Name">The name of the player.</param>
-/// <param name="Position">The position the player is at.</param>
-/// <param name="Speed"></param>
-/// <param name="Level"></param>
-/// <param name="Direction"></param>
-/// <param name="Hp"></param>
-/// <param name="Mp"></param>
-/// <param name="Faction"></param>
-/// <param name="Size"></param>
-/// <param name="AuthorityType"></param>
-/// <param name="Sex"></param>
-/// <param name="HairStyle"></param>
-/// <param name="HairColor"></param>
-/// <param name="Class"></param>
-/// <param name="Icon"></param>
-/// <param name="Compliment"></param>
-/// <param name="Morph"></param>
-/// <param name="ArenaWinner"></param>
-/// <param name="Invisible"></param>
-public record Player
-(
- long Id,
- string? Name = default,
- Position? Position = default,
- byte? Speed = default,
- Level? Level = default,
- Level? HeroLevel = default,
- byte? Direction = default,
- Health? Hp = default,
- Health? Mp = default,
- FactionType? Faction = default,
- short Size = default,
- AuthorityType AuthorityType = default,
- SexType Sex = default,
- HairStyle HairStyle = default,
- HairColor HairColor = default,
- PlayerClass Class = default,
- byte? Icon = default,
- short? Compliment = default,
- Morph? Morph = default,
- bool? ArenaWinner = default,
- bool? Invisible = default,
- long? Reputation = default,
- IReadOnlyList<long>? EffectsVNums = default
-) : ILivingEntity
+public class Player : ILivingEntity
{
+ /// <summary>
+ /// Gets or sets the authority of the player.
+ /// </summary>
+ public AuthorityType Authority { get; set; }
+
+ /// <summary>
+ /// Gets or sets the sex of the player.
+ /// </summary>
+ public SexType Sex { get; set; }
+
+ /// <summary>
+ /// Gets or sets the hairstyle of the player.
+ /// </summary>
+ public HairStyle HairStyle { get; set; }
+
+ /// <summary>
+ /// Gets or sets the hair color of the player.
+ /// </summary>
+ public HairColor HairColor { get; set; }
+
+ /// <summary>
+ /// Gets or sets the class of the player.
+ /// </summary>
+ public PlayerClass Class { get; set; }
+
+ /// <summary>
+ /// Gets or sets the reputation icon. UNKNOWN TODO.
+ /// </summary>
+ public byte? Icon { get; set; }
+
+ /// <summary>
+ /// UNKNOWN TODO.
+ /// </summary>
+ public short? Compliment { get; set; }
+
+ /// <summary>
+ /// Gets or sets the morph used for sps, vehicles and such.
+ /// </summary>
+ public Morph? Morph { get; set; }
+
+ /// <summary>
+ /// Gets or sets whether the player is a champion arena winner.
+ /// </summary>
+ public bool ArenaWinner { get; set; }
+
+ /// <summary>
+ /// Gets or sets the reputation number of the player.
+ /// </summary>
+ public long? Reputation { get; set; }
+
+ /// <summary>
+ /// Gets or sets the visible title of the player.
+ /// </summary>
+ public short Title { get; set; }
+
+ /// <summary>
+ /// Gets or sets the family.
+ /// </summary>
+ public Family? Family { get; set; }
+
+ /// <summary>
+ /// Gets the VNum of the npc.
+ /// </summary>
+ public int VNum { get; set; }
+
+ /// <inheritdoc/>
+ public long Id { get; set; }
+
/// <inheritdoc/>
- ushort? ILivingEntity.Level => Level?.Lvl;
+ public string? Name { get; set; }
+
+ /// <inheritdoc />
+ public bool IsSitting { get; set; }
/// <inheritdoc />
+ public bool CantMove { get; set; }
+
+ /// <inheritdoc />
+ public bool CantAttack { get; set; }
+
+ /// <inheritdoc/>
+ public Position? Position { get; set; }
+
+ /// <inheritdoc/>
public EntityType Type => EntityType.Player;
+
+ /// <inheritdoc/>
+ public int? Speed { get; set; }
+
+ /// <inheritdoc />
+ public bool? IsInvisible { get; set; }
+
+ /// <inheritdoc/>
+ public ushort? Level { get; set; }
+
+ /// <inheritdoc/>
+ public byte? Direction { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Hp { get; set; }
+
+ /// <inheritdoc/>
+ public Health? Mp { get; set; }
+
+ /// <inheritdoc/>
+ public FactionType? Faction { get; set; }
+
+ /// <inheritdoc/>
+ public short Size { get; set; }
+
+ /// <inheritdoc/>
+ public IReadOnlyList<long>? EffectsVNums { get; set; }
+
+ /// <summary>
+ /// Gets or sets the hero level.
+ /// </summary>
+ public virtual short? HeroLevel { get; set; }
+
+ /// <summary>
+ /// Gets or sets the equipment.
+ /// </summary>
+ public Equipment? Equipment { get; set; }
}=
\ No newline at end of file
M Core/NosSmooth.Game/Data/Info/Health.cs => Core/NosSmooth.Game/Data/Info/Health.cs +99 -4
@@ 9,9 9,104 @@ namespace NosSmooth.Game.Data.Info;
/// <summary>
/// Represents the health or mana of an entity.
/// </summary>
-/// <param name="Amount">The current amount of health.</param>
-/// <param name="Maximum">The maximum amount of health.</param>
-public record Health(long Amount, long Maximum)
+public class Health
{
- private decimal Percentage => (decimal)Amount / Maximum;
+ private byte? _percentage;
+ private long? _amount;
+ private long? _maximum;
+
+ /// <summary>
+ /// Gets or sets the percentage of the health.
+ /// </summary>
+ public byte? Percentage
+ {
+ get => _percentage;
+ set
+ {
+ _percentage = value;
+ if (value is null)
+ {
+ return;
+ }
+
+ var maximum = _maximum;
+ if (maximum is not null)
+ {
+ _amount = (long)((value / 100.0) * maximum);
+ return;
+ }
+
+ var amount = _amount;
+ if (amount is not null)
+ {
+ _maximum = (long)(amount / (value / 100.0));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the health amount.
+ /// </summary>
+ public long? Amount
+ {
+ get => _amount;
+ set
+ {
+ _amount = value;
+ if (value is null)
+ {
+ return;
+ }
+
+ var maximum = _maximum;
+ if (maximum is not null)
+ {
+ _percentage = (byte)(((double)value / maximum) * 100);
+ return;
+ }
+
+ var percentage = _percentage;
+ if (percentage is not null)
+ {
+ _maximum = (long)(value / (percentage / 100.0));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the maximum health.
+ /// </summary>
+ public long? Maximum
+ {
+ get => _maximum;
+ set
+ {
+ _maximum = value;
+ if (value is null)
+ {
+ return;
+ }
+
+ var amount = _amount;
+ var percentage = _percentage;
+
+ if (amount is not null)
+ {
+ if (amount > value)
+ {
+ amount = _amount = value;
+ _percentage = 100;
+ return;
+ }
+
+ _percentage = (byte)((amount / (double)value) * 100);
+ return;
+ }
+
+ if (percentage is not null)
+ { // ? would this be correct?
+ _amount = (long)((percentage / 100.0) * value);
+ }
+ }
+ }
}=
\ No newline at end of file
M Core/NosSmooth.Game/Data/Info/Level.cs => Core/NosSmooth.Game/Data/Info/Level.cs +1 -1
@@ 12,4 12,4 @@ namespace NosSmooth.Game.Data.Info;
/// <param name="Lvl">The level.</param>
/// <param name="Xp">Current xp.</param>
/// <param name="XpLoad">Maximum xp of the current level.</param>
-public record Level(ushort Lvl, long Xp, long XpLoad);>
\ No newline at end of file
+public record Level(short Lvl, long Xp, long XpLoad);<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Info/Position.cs => Core/NosSmooth.Game/Data/Info/Position.cs +11 -8
@@ 4,20 4,23 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.Diagnostics.CodeAnalysis;
+
namespace NosSmooth.Game.Data.Info;
/// <summary>
/// Represents nostale position on map.
/// </summary>
-public record Position
+[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313", MessageId = "Parameter names should begin with lower-case letter", Justification = "Standard.")]
+public record struct Position(long X, long Y)
{
/// <summary>
- /// Gets the x coordinate.
- /// </summary>
- public long X { get; internal set; }
-
- /// <summary>
- /// Gets the y coordinate.
+ /// Get the squared distance to the given position.
/// </summary>
- public long Y { get; internal set; }
+ /// <param name="position">The position.</param>
+ /// <returns>The distance squared.</returns>
+ public long DistanceSquared(Position position)
+ {
+ return ((position.X - X) * (position.X - X)) + ((position.Y - Y) * (position.Y - Y));
+ }
}=
\ No newline at end of file
A Core/NosSmooth.Game/Data/Items/Equipment.cs => Core/NosSmooth.Game/Data/Items/Equipment.cs +21 -0
@@ 0,0 1,21 @@
+//
+// Equipment.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace NosSmooth.Game.Data.Items;
+
+public record Equipment
+(
+ Item? Hat,
+ UpgradeableItem? Armor,
+ UpgradeableItem? MainWeapon,
+ UpgradeableItem? SecondaryWeapon,
+ Item? Mask,
+ Item? Fairy,
+ Item? CostumeSuit,
+ Item? CostumeHat,
+ short? WeaponSkin,
+ short? WingSkin
+);<
\ No newline at end of file
A Core/NosSmooth.Game/Data/Items/Fairy.cs => Core/NosSmooth.Game/Data/Items/Fairy.cs +12 -0
@@ 0,0 1,12 @@
+//
+// Fairy.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using NosSmooth.Data.Abstractions.Infos;
+using NosSmooth.Packets.Enums;
+
+namespace NosSmooth.Game.Data.Items;
+
+public record Fairy(int ItemVNum, Element Element, IItemInfo? Info) : Item(ItemVNum, Info);<
\ No newline at end of file
A Core/NosSmooth.Game/Data/Items/Item.cs => Core/NosSmooth.Game/Data/Items/Item.cs +16 -0
@@ 0,0 1,16 @@
+//
+// Item.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using NosSmooth.Data.Abstractions.Infos;
+
+namespace NosSmooth.Game.Data.Items;
+
+/// <summary>
+/// A NosTale item.
+/// </summary>
+/// <param name="ItemVNum"></param>
+/// <param name="Info"></param>
+public record Item(int ItemVNum, IItemInfo? Info);<
\ No newline at end of file
A Core/NosSmooth.Game/Data/Items/UpgradeableItem.cs => Core/NosSmooth.Game/Data/Items/UpgradeableItem.cs +18 -0
@@ 0,0 1,18 @@
+//
+// UpgradeableItem.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using NosSmooth.Data.Abstractions.Infos;
+
+namespace NosSmooth.Game.Data.Items;
+
+/// <summary>
+/// An item that can be upgraded and has rarity, ie. weapon or armor.
+/// </summary>
+/// <param name="ItemVNum">The vnum of the item.</param>
+/// <param name="Info">The information about the item.</param>
+/// <param name="Upgrade">The upgrade (0 - 10).</param>
+/// <param name="Rare">The rare nubmer (0 - 8).</param>
+public record UpgradeableItem(int ItemVNum, IItemInfo? Info, byte? Upgrade, sbyte? Rare) : Item(ItemVNum, Info);<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Maps/Map.cs => Core/NosSmooth.Game/Data/Maps/Map.cs +35 -1
@@ 4,9 4,43 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.Diagnostics.CodeAnalysis;
+using NosSmooth.Data.Abstractions.Infos;
+using NosSmooth.Game.Data.Info;
+
namespace NosSmooth.Game.Data.Maps;
/// <summary>
/// Represents nostale map.
/// </summary>
-public record Map();>
\ No newline at end of file
+public record Map
+(
+ long Id,
+ byte Type,
+ IMapInfo? Info,
+ MapEntities Entities,
+ IReadOnlyList<Portal> Portals
+)
+{
+ /// <summary>
+ /// Gets whether the given position lies on a portal.
+ /// </summary>
+ /// <param name="position">The position.</param>
+ /// <param name="portal">The portal the position is on, if any.</param>
+ /// <returns>Whether there was a portal at the specified position.</returns>
+ public bool IsOnPortal(Position position, [NotNullWhen(true)] out Portal? portal)
+ {
+ foreach (var p in Portals)
+ {
+ // TODO: figure out the distance
+ if (p.Position.DistanceSquared(position) < 3)
+ {
+ portal = p;
+ return true;
+ }
+ }
+
+ portal = null;
+ return false;
+ }
+}<
\ No newline at end of file
A Core/NosSmooth.Game/Data/Maps/MapEntities.cs => Core/NosSmooth.Game/Data/Maps/MapEntities.cs +100 -0
@@ 0,0 1,100 @@
+//
+// MapEntities.cs
+//
+// Copyright (c) František Boháček. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Concurrent;
+using NosSmooth.Game.Data.Entities;
+using NosSmooth.Packets.Enums;
+
+namespace NosSmooth.Game.Data.Maps;
+
+/// <summary>
+/// Thread-safe store for the entities on the map.
+/// </summary>
+public class MapEntities
+{
+ private readonly ConcurrentDictionary<long, IEntity> _entities;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MapEntities"/> class.
+ /// </summary>
+ public MapEntities()
+ {
+ _entities = new ConcurrentDictionary<long, IEntity>();
+ }
+
+ /// <summary>
+ /// Gets the given entity by id.
+ /// </summary>
+ /// <param name="id">The id of the entity.</param>
+ /// <returns>The entity, or null, if not found.</returns>
+ public IEntity? GetEntity(long id)
+ => _entities.GetValueOrDefault(id);
+
+ /// <summary>
+ /// Get the given entity by id.
+ /// </summary>
+ /// <param name="id">The id of the entity.</param>
+ /// <typeparam name="TEntity">The type of the entity.</typeparam>
+ /// <returns>The entity.</returns>
+ /// <exception cref="Exception">If the entity is not of the specified type.</exception>
+ public TEntity? GetEntity<TEntity>(long id)
+ {
+ var entity = GetEntity(id);
+ if (entity is null)
+ {
+ return default;
+ }
+
+ if (entity is TEntity tentity)
+ {
+ return tentity;
+ }
+
+ throw new Exception($"Could not find the entity with the given type {typeof(TEntity)}, was {entity.GetType()}");
+ }
+
+ /// <summary>
+ /// Add the given entity to the entities list.
+ /// </summary>
+ /// <param name="entity">The entity to add.</param>
+ internal void AddEntity(IEntity entity)
+ {
+ _entities.AddOrUpdate(entity.Id, _ => entity, (i, e) => entity);
+ }
+
+ /// <summary>
+ /// .
+ /// </summary>
+ /// <param name="entityId">The id of the entity.</param>
+ /// <param name="createAction">The action to execute on create.</param>
+ /// <param name="updateAction">The action to execute on update.</param>
+ /// <typeparam name="TEntity">The type of the entity.</typeparam>
+ internal void AddOrUpdateEntity<TEntity>
+ (long entityId, Func<long, TEntity> createAction, Func<long, TEntity, TEntity> updateAction)
+ where TEntity : IEntity
+ {
+ _entities.AddOrUpdate
+ (entityId, (key) => createAction(key), (key, entity) => updateAction(key, (TEntity)entity));
+ }
+
+ /// <summary>
+ /// Remove the given entity.
+ /// </summary>
+ /// <param name="entity">The entity to remove.</param>
+ internal void RemoveEntity(IEntity entity)
+ {
+ RemoveEntity(entity.Id);
+ }
+
+ /// <summary>
+ /// Remove the given entity.
+ /// </summary>
+ /// <param name="entityId">The id of the entity to remove.</param>
+ internal void RemoveEntity(long entityId)
+ {
+ _entities.TryRemove(entityId, out _);
+ }
+}<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Maps/Miniland.cs => Core/NosSmooth.Game/Data/Maps/Miniland.cs +18 -1
@@ 4,10 4,27 @@
// Copyright (c) František Boháček. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using NosSmooth.Data.Abstractions.Infos;
+
namespace NosSmooth.Game.Data.Maps;
/// <summary>
/// Represents Miniland map that can contain miniland objects.
/// </summary>
/// <param name="Objects">The objects in the miniland.</param>
-public record Miniland(IReadOnlyList<MinilandObject>? Objects) : Map;>
\ No newline at end of file
+public record Miniland
+(
+ long Id,
+ byte Type,
+ IMapInfo? Info,
+ MapEntities Entities,
+ IReadOnlyList<Portal> Portals,
+ IReadOnlyList<MinilandObject>? Objects
+) : Map
+(
+ Id,
+ Type,
+ Info,
+ Entities,
+ Portals
+);<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Maps/Portal.cs => Core/NosSmooth.Game/Data/Maps/Portal.cs +10 -1
@@ 5,12 5,21 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using NosSmooth.Game.Data.Info;
+using NosSmooth.Packets.Enums;
namespace NosSmooth.Game.Data.Maps;
/// <summary>
/// Represents map portal leading to another map.
/// </summary>
+/// <param name="PortalId">The portal id.</param>
/// <param name="Position">The position of the portal.</param>
/// <param name="TargetMapId">The id of the target map.</param>
-public record Portal(Position Position, long TargetMapId);>
\ No newline at end of file
+public record Portal
+(
+ long PortalId,
+ Position Position,
+ long TargetMapId,
+ PortalType? PortalType,
+ bool IsDisabled
+);<
\ No newline at end of file
M Core/NosSmooth.Game/Data/Social/Family.cs => Core/NosSmooth.Game/Data/Social/Family.cs +8 -1
@@ 12,4 12,11 @@ namespace NosSmooth.Game.Data.Social;
/// <param name="Id">The id of the family.</param>
/// <param name="Name">The name of the family.</param>
/// <param name="Level">The level of the entity.</param>
-public record Family(string? Id, string? Name, byte? Level);>
\ No newline at end of file
+public record Family
+(
+ string? Id,
+ short? Title,
+ string? Name,
+ byte? Level,
+ IReadOnlyList<bool>? Icons
+);<
\ No newline at end of file