baseline: OpenMU upstream b5a0961 (fresh source)
This commit is contained in:
51
src/DataModel/AssignableExtensions.cs
Normal file
51
src/DataModel/AssignableExtensions.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
// <copyright file="AssignableExtensions.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Extensions for <see cref="IAssignable{T}"/>.
|
||||
/// </summary>
|
||||
public static class AssignableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigns a collection to another one, resolving the objects to the ones
|
||||
/// which are contained in the given <see cref="GameConfiguration"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the collection elements.</typeparam>
|
||||
/// <param name="collection">The target collection.</param>
|
||||
/// <param name="other">The other collection.</param>
|
||||
/// <param name="gameConfiguration">The game configuration.</param>
|
||||
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other, GameConfiguration gameConfiguration)
|
||||
where T : class
|
||||
{
|
||||
var itemsToRemove = collection.Except(other).ToList();
|
||||
var itemsToAdd = other.Except(collection).ToList();
|
||||
|
||||
itemsToRemove.ForEach(i => collection.Remove(i));
|
||||
itemsToAdd.ForEach(i => collection.Add(
|
||||
gameConfiguration.GetObjectOfConfig(i)
|
||||
?? (i as ICloneable<T>)?.Clone(gameConfiguration)
|
||||
?? (i as ICloneable)?.Clone() as T
|
||||
?? i));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns a collection to another one.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the collection values.</typeparam>
|
||||
/// <param name="collection">The target collection.</param>
|
||||
/// <param name="other">The other collection.</param>
|
||||
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other)
|
||||
where T : struct
|
||||
{
|
||||
var itemsToRemove = collection.Except(other).ToList();
|
||||
var itemsToAdd = other.Except(collection).ToList();
|
||||
|
||||
itemsToRemove.ForEach(i => collection.Remove(i));
|
||||
itemsToAdd.ForEach(collection.Add);
|
||||
}
|
||||
}
|
||||
56
src/DataModel/Attributes/PowerUpDefinition.cs
Normal file
56
src/DataModel/Attributes/PowerUpDefinition.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
// <copyright file="PowerUpDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Attributes;
|
||||
|
||||
using System.Globalization;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The power up definition which describes the boost of an target attribute.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class PowerUpDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the target attribute.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? TargetAttribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the boost.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinitionValue? Boost { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
string value;
|
||||
if (this.Boost?.ConstantValue?.Value > 0)
|
||||
{
|
||||
value = this.Boost.ConstantValue.Value.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (this.Boost?.RelatedValues != null && this.Boost.RelatedValues.Any())
|
||||
{
|
||||
var relation = this.Boost.RelatedValues.First();
|
||||
if (relation.InputOperator == InputOperator.ExponentiateByAttribute)
|
||||
{
|
||||
value = relation.InputOperand + relation.InputOperator.AsString() + new LocalizedString(relation.InputAttribute?.Designation).ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
value = new LocalizedString(relation.InputAttribute?.Designation).ToString() + relation.InputOperator.AsString() + relation.InputOperand;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no value defined, so we assume "0"
|
||||
value = "0";
|
||||
}
|
||||
|
||||
return value + " " + new LocalizedString(this.TargetAttribute?.Designation).ToString();
|
||||
}
|
||||
}
|
||||
40
src/DataModel/Attributes/PowerUpDefinitionValue.cs
Normal file
40
src/DataModel/Attributes/PowerUpDefinitionValue.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// <copyright file="PowerUpDefinitionValue.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Attributes;
|
||||
|
||||
using System.ComponentModel;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The power up definition value which can consist of a constant value and several related values which are all added together to get the result.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class PowerUpDefinitionValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the constant value part of the value.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
[Browsable(false)]
|
||||
public SimpleElement ConstantValue { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the related values.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRelationship> RelatedValues { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum allowable value.
|
||||
/// </summary>
|
||||
public float? MaximumValue { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.ConstantValue?.Value ?? 0} + {string.Join(" + ", this.RelatedValues.Select(v => $"({v})"))}";
|
||||
}
|
||||
}
|
||||
17
src/DataModel/Composition/AggregateRootAttribute.cs
Normal file
17
src/DataModel/Composition/AggregateRootAttribute.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// <copyright file="AggregateRootAttribute.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a class as an aggregate root.
|
||||
/// An instance of an aggregate root is an object which can stand on its own
|
||||
/// and consists of several other objects which are marked with the <see cref="MemberOfAggregateAttribute"/>.
|
||||
/// Example: A car (aggregate root) which consists of several other parts, e.g. engine, wheels, doors etc.
|
||||
/// Properties which are not part of the aggregate will not be marked with the <see cref="MemberOfAggregateAttribute"/>.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class AggregateRootAttribute : Attribute
|
||||
{
|
||||
}
|
||||
13
src/DataModel/Composition/HiddenAtCreationAttribute.cs
Normal file
13
src/DataModel/Composition/HiddenAtCreationAttribute.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
// <copyright file="HiddenAtCreationAttribute.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a property to be hidden on the UI when the object of the declaring type gets created.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class HiddenAtCreationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
14
src/DataModel/Composition/MemberOfAggregateAttribute.cs
Normal file
14
src/DataModel/Composition/MemberOfAggregateAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// <copyright file="MemberOfAggregateAttribute.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a property as a member of an aggregate.
|
||||
/// The declaring type owns the objects of the marked property.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class MemberOfAggregateAttribute : Attribute
|
||||
{
|
||||
}
|
||||
14
src/DataModel/Composition/TransientAttribute.cs
Normal file
14
src/DataModel/Composition/TransientAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// <copyright file="TransientAttribute.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a property as a transient property. That means, that it's not going to get persisted
|
||||
/// and just holds some information at run-time.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class TransientAttribute : Attribute
|
||||
{
|
||||
}
|
||||
106
src/DataModel/Configuration/AreaSkillSettings.cs
Normal file
106
src/DataModel/Configuration/AreaSkillSettings.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
// <copyright file="AreaSkillSettings.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for area skills.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class AreaSkillSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to use a frustum to filter potential targets.
|
||||
/// </summary>
|
||||
public bool UseFrustumFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the frustum at the start.
|
||||
/// </summary>
|
||||
public float FrustumStartWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the frustum at the end.
|
||||
/// </summary>
|
||||
public float FrustumEndWidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the distance.
|
||||
/// </summary>
|
||||
public float FrustumDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to consider the target area coordinate to filter potential targets.
|
||||
/// </summary>
|
||||
public bool UseTargetAreaFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target area diameter.
|
||||
/// </summary>
|
||||
public float TargetAreaDiameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to use deferred hits,
|
||||
/// for skills which take a while to visually arrive at the target.
|
||||
/// </summary>
|
||||
public bool UseDeferredHits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the delay per one distance, when <see cref="UseDeferredHits"/> is active.
|
||||
/// </summary>
|
||||
public TimeSpan DelayPerOneDistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the delay between hits.
|
||||
/// </summary>
|
||||
public TimeSpan DelayBetweenHits { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum number of hits per target.
|
||||
/// </summary>
|
||||
public int MinimumNumberOfHitsPerTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of hits per target.
|
||||
/// </summary>
|
||||
public int MaximumNumberOfHitsPerTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum number of hits per attack, after which subsequent hits have a reduced chance to hit.
|
||||
/// </summary>
|
||||
public int MinimumNumberOfHitsPerAttack { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of hits per attack.
|
||||
/// </summary>
|
||||
public int MaximumNumberOfHitsPerAttack { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hit chance per distance multiplier.
|
||||
/// E.g. when set to 0.9 and the target is 5 steps away,
|
||||
/// the chance to hit is 0.9^5 = 0.59.
|
||||
/// </summary>
|
||||
public float HitChancePerDistanceMultiplier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of projectiles/arrows that are fired.
|
||||
/// When greater than 1, the projectiles are evenly distributed within the frustum.
|
||||
/// Each target can only be hit by projectiles whose paths cross the target's position.
|
||||
/// Default is 1 (single projectile).
|
||||
/// </summary>
|
||||
public int ProjectileCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the effect range of the skill, which is the maximum distance from the target area center.
|
||||
/// </summary>
|
||||
public int EffectRange { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return "Area Skill Settings";
|
||||
}
|
||||
}
|
||||
21
src/DataModel/Configuration/BattleType.cs
Normal file
21
src/DataModel/Configuration/BattleType.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// <copyright file="BattleType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of battle which can be done on a battle zone between two teams.
|
||||
/// </summary>
|
||||
public enum BattleType
|
||||
{
|
||||
/// <summary>
|
||||
/// A normal pvp battle.
|
||||
/// </summary>
|
||||
Normal,
|
||||
|
||||
/// <summary>
|
||||
/// A battle soccer match.
|
||||
/// </summary>
|
||||
Soccer,
|
||||
}
|
||||
63
src/DataModel/Configuration/BattleZoneDefinition.cs
Normal file
63
src/DataModel/Configuration/BattleZoneDefinition.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
// <copyright file="BattleZoneDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a battle zone.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class BattleZoneDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the battle type.
|
||||
/// </summary>
|
||||
public BattleType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of the upper spawn point for the left team.
|
||||
/// </summary>
|
||||
public byte? LeftTeamSpawnPointX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of the upper spawn point for the left team.
|
||||
/// </summary>
|
||||
public byte LeftTeamSpawnPointY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of the upper spawn point for the right team.
|
||||
/// </summary>
|
||||
public byte? RightTeamSpawnPointX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of the upper spawn point for the right team.
|
||||
/// </summary>
|
||||
public byte RightTeamSpawnPointY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the battle ground.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual Rectangle? Ground { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the first goal zone.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual Rectangle? LeftGoal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the second goal zone.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual Rectangle? RightGoal { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Battle Zone ({this.Type})";
|
||||
}
|
||||
}
|
||||
120
src/DataModel/Configuration/CharacterClass.cs
Normal file
120
src/DataModel/Configuration/CharacterClass.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
// <copyright file="CharacterClass.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a character class.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class CharacterClass
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id of a character class.
|
||||
/// This will be used to identify the class when getting created,
|
||||
/// and as identifier to be sent to client.
|
||||
/// </summary>
|
||||
public byte Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the character class.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this character class can get created by the user.
|
||||
/// </summary>
|
||||
public bool CanGetCreated { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level requirement when getting created.
|
||||
/// The level requirement must be fulfilled by another character of the same account.
|
||||
/// </summary>
|
||||
public short LevelRequirementByCreation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the creation allowed flag which is sent to the client in the character list message if this character class is in its <see cref="Account.UnlockedCharacterClasses"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Flag about which characters can be created with this account:
|
||||
/// 1 = Summoner
|
||||
/// 2 = Dark Lord
|
||||
/// 4 = Magic Gladiator
|
||||
/// 8 = Rage Fighter.
|
||||
/// </remarks>
|
||||
public byte CreationAllowedFlag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next generation class, to which a character can upgrade after
|
||||
/// fulfilling certain requirements, like quests.
|
||||
/// </summary>
|
||||
public virtual CharacterClass? NextGenerationClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this class is a master class and therefore can receive master experience for the master tree.
|
||||
/// </summary>
|
||||
public bool IsMasterClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the percent by which the moving level requirement for warping to other maps is reduced.
|
||||
/// </summary>
|
||||
public int LevelWarpRequirementReductionPercent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the fruit calculation strategy.
|
||||
/// </summary>
|
||||
public FruitCalculationStrategy FruitCalculation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the stat attributes.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<StatAttributeDefinition> StatAttributes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute combinations.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRelationship> AttributeCombinations { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base attribute values.
|
||||
/// For example the amount of health a character got without any added stat point.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ConstValueAttribute> BaseAttributeValues { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the home map.
|
||||
/// </summary>
|
||||
public virtual GameMapDefinition? HomeMap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the combo definition for this class and all
|
||||
/// following <see cref="NextGenerationClass"/>es without an explicit combo definition.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual SkillComboDefinition? ComboDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets StatAttributeDefinition corresponding to AttributeDefinition.
|
||||
/// </summary>
|
||||
/// <param name="attributeDefinition">The attribute.</param>
|
||||
/// <returns>The corresponding StatAttributeDefinition.</returns>
|
||||
public StatAttributeDefinition? GetStatAttribute(AttributeDefinition attributeDefinition)
|
||||
{
|
||||
return this.StatAttributes.FirstOrDefault(a => a.Attribute == attributeDefinition);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
61
src/DataModel/Configuration/ChatServerDefinition.cs
Normal file
61
src/DataModel/Configuration/ChatServerDefinition.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// <copyright file="ChatServerDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for the chat server.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class ChatServerDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server identifier.
|
||||
/// </summary>
|
||||
public byte ServerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum connections.
|
||||
/// </summary>
|
||||
public int MaximumConnections { get; set; } = int.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client timeout. When a client did not send any data in this timespan, it's automatically disconnected.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The client timeout.
|
||||
/// </value>
|
||||
public TimeSpan ClientTimeout { get; set; } = TimeSpan.FromMinutes(1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval in which a client clean up takes place.
|
||||
/// For all connected clients it's checked whether or not the <see cref="ClientTimeout"/> has been reached.
|
||||
/// </summary>
|
||||
public TimeSpan ClientCleanUpInterval { get; set; } = TimeSpan.FromMinutes(1);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval in which empty chat rooms are cleaned up.
|
||||
/// </summary>
|
||||
public TimeSpan RoomCleanUpInterval { get; set; } = TimeSpan.FromSeconds(5);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the endpoints of the game server.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ChatServerEndpoint> Endpoints { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[ChatServerDefinition ServerID={this.ServerId}, Description={this.Description}]";
|
||||
}
|
||||
}
|
||||
12
src/DataModel/Configuration/ChatServerEndpoint.cs
Normal file
12
src/DataModel/Configuration/ChatServerEndpoint.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
// <copyright file="ChatServerEndpoint.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an endpoint of a chat server.
|
||||
/// </summary>
|
||||
public class ChatServerEndpoint : ServerEndpoint
|
||||
{
|
||||
}
|
||||
48
src/DataModel/Configuration/ConfigurationUpdate.cs
Normal file
48
src/DataModel/Configuration/ConfigurationUpdate.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
// <copyright file="ConfigurationUpdate.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Describes an applied configuration update.
|
||||
/// Based on this information, the program can decide which updates are need to
|
||||
/// be installed next.
|
||||
/// After a fresh database initialization, an entry exists, so that the maximum
|
||||
/// version can be determined in this case, too.
|
||||
/// </summary>
|
||||
public class ConfigurationUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the version of the update.
|
||||
/// </summary>
|
||||
public int Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the update.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description of the update with further information.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the release date.
|
||||
/// </summary>
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the installation timestamp. If it's <c>null</c>, the update wasn't installed yet.
|
||||
/// </summary>
|
||||
public DateTime? InstalledAt { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"v{this.Version}: {this.Name}";
|
||||
}
|
||||
}
|
||||
21
src/DataModel/Configuration/ConfigurationUpdateState.cs
Normal file
21
src/DataModel/Configuration/ConfigurationUpdateState.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// <copyright file="ConfigurationUpdateState.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Describes the current update state of the configuration.
|
||||
/// </summary>
|
||||
public class ConfigurationUpdateState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the initialization key.
|
||||
/// </summary>
|
||||
public string? InitializationKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the highest <see cref="ConfigurationUpdate.Version"/> which is installed.
|
||||
/// </summary>
|
||||
public int CurrentInstalledVersion { get; set; }
|
||||
}
|
||||
140
src/DataModel/Configuration/ConnectServerDefinition.cs
Normal file
140
src/DataModel/Configuration/ConnectServerDefinition.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
// <copyright file="ConnectServerDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// The definition of a connect server.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class ConnectServerDefinition : IConnectServerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id of this definition.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Guid ConfigurationId => this.Id;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server identifier.
|
||||
/// </summary>
|
||||
public byte ServerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description of the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Will be displayed in the server list in the admin panel as <see cref="IManageableServer.Description"/>.
|
||||
/// </remarks>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client which is expected to connect.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameClientDefinition? Client { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
IGameClientVersion IConnectServerSettings.Client => this.Client ?? throw new InvalidOperationException("ConnectServerDefinition.Client not initialized.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the client should get disconnected when a unknown packet is getting received.
|
||||
/// </summary>
|
||||
public bool DisconnectOnUnknownPacket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum size of the packets which should be received from the client. If this size is exceeded, the client will be disconnected.
|
||||
/// </summary>
|
||||
/// <remarks>DOS protection.</remarks>
|
||||
public byte MaximumReceiveSize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the network port on which the server is listening.
|
||||
/// </summary>
|
||||
public int ClientListenerPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timeout after which clients without activity get disconnected.
|
||||
/// </summary>
|
||||
public TimeSpan Timeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current patch version.
|
||||
/// </summary>
|
||||
public byte[]? CurrentPatchVersion { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
byte[] IConnectServerSettings.CurrentPatchVersion => this.CurrentPatchVersion ?? throw new InvalidOperationException("Patch Version is not initialized");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the patch address.
|
||||
/// </summary>
|
||||
public string PatchAddress { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum connections per ip.
|
||||
/// </summary>
|
||||
public int MaxConnectionsPerAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the <see cref="MaxConnectionsPerAddress"/> should be checked.
|
||||
/// </summary>
|
||||
public bool CheckMaxConnectionsPerAddress { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum connections the connect server should handle.
|
||||
/// </summary>
|
||||
public int MaxConnections { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the listener backlog for the client listener.
|
||||
/// </summary>
|
||||
public int ListenerBacklog { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum FTP requests per connection.
|
||||
/// </summary>
|
||||
public int MaxFtpRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum ip requests per connection.
|
||||
/// </summary>
|
||||
public int MaxIpRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum server list requests per connection.
|
||||
/// </summary>
|
||||
public int MaxServerListRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the defaults.
|
||||
/// </summary>
|
||||
public void InitializeDefaults()
|
||||
{
|
||||
this.DisconnectOnUnknownPacket = true;
|
||||
this.MaximumReceiveSize = 6;
|
||||
this.Timeout = new TimeSpan(0, 1, 0);
|
||||
this.CurrentPatchVersion = new byte[] { 1, 3, 0x2B };
|
||||
this.PatchAddress = "patch.muonline.webzen.com";
|
||||
this.MaxConnectionsPerAddress = 30;
|
||||
this.CheckMaxConnectionsPerAddress = true;
|
||||
this.MaxConnections = 10000;
|
||||
this.ListenerBacklog = 100;
|
||||
this.MaxFtpRequests = 1;
|
||||
this.MaxIpRequests = 5;
|
||||
this.MaxServerListRequests = 20;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Description;
|
||||
}
|
||||
}
|
||||
61
src/DataModel/Configuration/Direction.cs
Normal file
61
src/DataModel/Configuration/Direction.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// <copyright file="Direction.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Direction where an object is looking at.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The directions are named/valued after how they look like due the game client.
|
||||
/// That means, when a character looks to south, it looks straight downwards. Because the map is rotated on the game client, that's actually a corner.
|
||||
/// Since we use the value 0 as 'Undefined' and the original game client uses value 0 as 'West', this has to be considered when communicating with it.
|
||||
/// </remarks>
|
||||
public enum Direction
|
||||
{
|
||||
/// <summary>
|
||||
/// The undefined direction.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the west.
|
||||
/// </summary>
|
||||
West = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the south east.
|
||||
/// </summary>
|
||||
SouthWest = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the south.
|
||||
/// </summary>
|
||||
South = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the south west.
|
||||
/// </summary>
|
||||
SouthEast = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the east.
|
||||
/// </summary>
|
||||
East = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the north east.
|
||||
/// </summary>
|
||||
NorthEast = 6,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the north.
|
||||
/// </summary>
|
||||
North = 7,
|
||||
|
||||
/// <summary>
|
||||
/// The direction looking to the north west.
|
||||
/// </summary>
|
||||
NorthWest = 8,
|
||||
}
|
||||
110
src/DataModel/Configuration/DropItemGroup.cs
Normal file
110
src/DataModel/Configuration/DropItemGroup.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
// <copyright file="DropItemGroup.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Enumeration of special item types.
|
||||
/// </summary>
|
||||
public enum SpecialItemType
|
||||
{
|
||||
/// <summary>
|
||||
/// No special item type.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// The ancient special item type.
|
||||
/// </summary>
|
||||
Ancient,
|
||||
|
||||
/// <summary>
|
||||
/// The excellent special item type.
|
||||
/// </summary>
|
||||
Excellent,
|
||||
|
||||
/// <summary>
|
||||
/// The random item special item type.
|
||||
/// </summary>
|
||||
RandomItem,
|
||||
|
||||
/// <summary>
|
||||
/// The socket item special item type.
|
||||
/// </summary>
|
||||
SocketItem,
|
||||
|
||||
/// <summary>
|
||||
/// The money special item type.
|
||||
/// </summary>
|
||||
Money,
|
||||
|
||||
/// <summary>
|
||||
/// The jewel special item type.
|
||||
/// </summary>
|
||||
Jewel,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Idea: append several "drop item groups" with its certain probability.
|
||||
/// In the drop generator sort all DropItemGroups by its chance.
|
||||
/// Classes which can have DropItemGroups: Maps, Monsters(for example the kundun drops), Players(for quest items).
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class DropItemGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance of the item drop group to apply. From 0.0 to 1.0.
|
||||
/// </summary>
|
||||
public double Chance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum monster level. If <c>null</c>, then it doesn't apply.
|
||||
/// </summary>
|
||||
public byte? MinimumMonsterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum monster level. If <c>null</c>, then it doesn't apply.
|
||||
/// </summary>
|
||||
public byte? MaximumMonsterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a specific monster for which this drop group is valid.
|
||||
/// If <c>null</c>, then it doesn't apply and it's valid for all monsters.
|
||||
/// </summary>
|
||||
/// <remarks>This is required for some quest items which should drop only from specific monsters.</remarks>
|
||||
public virtual MonsterDefinition? Monster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item level which will be assigned to the dropped instance of <see cref="PossibleItems"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Use cases: Quest items (e.g. Broken Sword+1 = Dark Stone), Event Ticket Items, Summoning Orbs, etc. where one item type is used
|
||||
/// for multiple "visible" items.
|
||||
/// </remarks>
|
||||
public byte? ItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the special type of the item.
|
||||
/// </summary>
|
||||
public SpecialItemType ItemType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the possible items which can be dropped.
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemDefinition> PossibleItems { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Description;
|
||||
}
|
||||
}
|
||||
40
src/DataModel/Configuration/DuelArea.cs
Normal file
40
src/DataModel/Configuration/DuelArea.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// <copyright file="DuelArea.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an area where a duel can take place.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class DuelArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the index of the area.
|
||||
/// </summary>
|
||||
public short Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the first player gate to which the player is teleported when he enters the duel.
|
||||
/// </summary>
|
||||
public virtual ExitGate? FirstPlayerGate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the second player gate to which the player is teleported when he enters the duel.
|
||||
/// </summary>
|
||||
public virtual ExitGate? SecondPlayerGate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the gate to which a spectator is teleported when he enters the duel.
|
||||
/// </summary>
|
||||
public virtual ExitGate? SpectatorsGate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Index} - {this.FirstPlayerGate} - {this.SecondPlayerGate}";
|
||||
}
|
||||
}
|
||||
52
src/DataModel/Configuration/DuelConfiguration.cs
Normal file
52
src/DataModel/Configuration/DuelConfiguration.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
// <copyright file="DuelConfiguration.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration for the duel feature.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class DuelConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum score at which the duel will end with a winner.
|
||||
/// </summary>
|
||||
public int MaximumScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the entrance fee for a duel.
|
||||
/// </summary>
|
||||
public int EntranceFee { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum character level to start a duel.
|
||||
/// </summary>
|
||||
public int MinimumCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum spectators per duel room.
|
||||
/// </summary>
|
||||
public int MaximumSpectatorsPerDuelRoom { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exit gate to which all players are ported after the duel has ended.
|
||||
/// If not set, players will be ported to the safezone.
|
||||
/// </summary>
|
||||
public virtual ExitGate? Exit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the available duel areas.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<DuelArea> DuelAreas { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Duel Configuration {this.DuelAreas.Count} Arenas, Exit: {this.Exit}";
|
||||
}
|
||||
}
|
||||
36
src/DataModel/Configuration/EnterGate.cs
Normal file
36
src/DataModel/Configuration/EnterGate.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
// <copyright file="EnterGate.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a gate which a player can enter to move to another <see cref="ExitGate"/>.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class EnterGate : Gate
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the target gate.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual ExitGate? TargetGate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level requirement which the player needs to move through the gate.
|
||||
/// </summary>
|
||||
public short LevelRequirement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of the gate.
|
||||
/// </summary>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{base.ToString()} ({this.Number}) (Level {this.LevelRequirement}) to {this.TargetGate}";
|
||||
}
|
||||
}
|
||||
40
src/DataModel/Configuration/ExitGate.cs
Normal file
40
src/DataModel/Configuration/ExitGate.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// <copyright file="ExitGate.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a gate through which a player enters a map.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ExitGate : Gate
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the direction to which the player looks when he enters the map.
|
||||
/// </summary>
|
||||
public Direction Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the map which will be entered.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameMapDefinition? Map { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is a spawn gate.
|
||||
/// If it's not a spawn gate, it's a target of an <see cref="EnterGate"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is spawn gate; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsSpawnGate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Map?.Name} @ {base.ToString()}";
|
||||
}
|
||||
}
|
||||
26
src/DataModel/Configuration/FruitCalculationStrategy.cs
Normal file
26
src/DataModel/Configuration/FruitCalculationStrategy.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// <copyright file="FruitCalculationStrategy.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The calculation strategy for maximum fruit points.
|
||||
/// </summary>
|
||||
public enum FruitCalculationStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// The default strategy (maximum 127).
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The strategy to calculate the fruits for magic gladiator classes (maximum 100).
|
||||
/// </summary>
|
||||
MagicGladiator = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The strategy to calculate the fruits for dark lord classes (maximum 115).
|
||||
/// </summary>
|
||||
DarkLord = 2,
|
||||
}
|
||||
59
src/DataModel/Configuration/GameClientDefinition.cs
Normal file
59
src/DataModel/Configuration/GameClientDefinition.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
// <copyright file="GameClientDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
using MUnique.OpenMU.Network.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a game client.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class GameClientDefinition : IGameClientVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the season.
|
||||
/// </summary>
|
||||
public byte Season { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the episode.
|
||||
/// </summary>
|
||||
public byte Episode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language.
|
||||
/// </summary>
|
||||
public ClientLanguage Language { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the version which is defined in the client binaries.
|
||||
/// </summary>
|
||||
public byte[]? Version { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
byte[] IGameClientVersion.Version => this.Version ?? throw new InvalidOperationException("Version not initialized.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the serial which is defined in the client binaries.
|
||||
/// </summary>
|
||||
public byte[]? Serial { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
byte[] IGameClientVersion.Serial => this.Serial ?? throw new InvalidOperationException("Serial not initialized.");
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Description;
|
||||
}
|
||||
}
|
||||
308
src/DataModel/Configuration/GameConfiguration.cs
Normal file
308
src/DataModel/Configuration/GameConfiguration.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
// <copyright file="GameConfiguration.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
using MUnique.OpenMU.PlugIns;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the game configuration.
|
||||
/// A game configuration contains the whole configuration of a game, directly or indirectly.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class GameConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum reachable level.
|
||||
/// </summary>
|
||||
public short MaximumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum reachable master level.
|
||||
/// </summary>
|
||||
public short MaximumMasterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the experience rate of the game.
|
||||
/// </summary>
|
||||
public float ExperienceRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master experience rate of the game.
|
||||
/// </summary>
|
||||
public float MasterExperienceRate { get; set; } = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether experience overflow should be prevented.
|
||||
/// When <c>true</c>, if gaining experience would exceed the amount needed for the next level,
|
||||
/// only the necessary experience for the next level is gained, and the overflow is discarded.
|
||||
/// When <c>false</c>, excess experience is applied to subsequent levels (default behavior).
|
||||
/// </summary>
|
||||
public bool PreventExperienceOverflow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum monster level which are required to be killed
|
||||
/// in order to gain master experience for master character classes.
|
||||
/// </summary>
|
||||
public byte MinimumMonsterLevelForMasterExperience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the information range. This defines how far players can see other game objects.
|
||||
/// </summary>
|
||||
public byte InfoRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether area skills hit players.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usually false, during castle siege this might be true.
|
||||
/// </remarks>
|
||||
public bool AreaSkillHitsPlayer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum inventory money value.
|
||||
/// </summary>
|
||||
public int MaximumInventoryMoney { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum vault money value.
|
||||
/// </summary>
|
||||
public int MaximumVaultMoney { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether money pickup should be clamped to the maximum inventory money limit instead of failing when the limit would be exceeded.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When <c>true</c>, if picking up money would exceed the maximum inventory money, the player will receive as much as possible (up to the limit) instead of the pickup failing completely.
|
||||
/// When <c>false</c>, the pickup will fail if it would exceed the maximum (default behavior).
|
||||
/// </remarks>
|
||||
public bool ClampMoneyOnPickup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level delta used to determine the pool of items eligible for excellent drops.
|
||||
/// A monster must be at least this many levels above an item's DropLevel for the item to be eligible as excellent.
|
||||
/// </summary>
|
||||
public byte ExcellentItemDropLevelDelta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the experience formula per level. The variable name for the level is "level".
|
||||
/// </summary>
|
||||
public string? ExperienceFormula { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the experience formula per master level. The variable name for the level is "level".
|
||||
/// </summary>
|
||||
public string? MasterExperienceFormula { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the interval for attribute recoveries. See also MUnique.OpenMU.GameLogic.Attributes.Stats.Regeneration.
|
||||
/// </summary>
|
||||
public int RecoveryInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum numbers of letters a player can have in his inbox.
|
||||
/// </summary>
|
||||
public int MaximumLetters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the price of sending a letter.
|
||||
/// </summary>
|
||||
public int LetterSendPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of characters per account.
|
||||
/// </summary>
|
||||
public byte MaximumCharactersPerAccount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character name regex.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// "^[a-zA-Z0-9]{3,10}$";.
|
||||
/// </remarks>
|
||||
public string? CharacterNameRegex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum length of the password.
|
||||
/// </summary>
|
||||
public int MaximumPasswordLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum size of parties.
|
||||
/// </summary>
|
||||
public byte MaximumPartySize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether if a monster should drop or adds money to the character directly.
|
||||
/// </summary>
|
||||
public bool ShouldDropMoney { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of item drops on the ground.
|
||||
/// </summary>
|
||||
public TimeSpan ItemDropDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum droppable item option level.
|
||||
/// </summary>
|
||||
public byte MaximumItemOptionLevelDrop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the accumulated damage which needs to be done to decrease <see cref="Item.Durability"/> of a defending item by 1.
|
||||
/// </summary>
|
||||
public double DamagePerOneItemDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the accumulated damage which needs to be done to decrease <see cref="Item.Durability"/> of a pet item by 1.
|
||||
/// </summary>
|
||||
public double DamagePerOnePetDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of hits which needs to be done to decrease the <see cref="Item.Durability"/> of an offensive item by 1.
|
||||
/// </summary>
|
||||
public double HitsPerOneItemDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duel configuration.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual DuelConfiguration? DuelConfiguration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the possible jewel mixes.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<JewelMix> JewelMixes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the warp list.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<WarpInfo> WarpList { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drop item groups which can be assigned to maps and characters.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<DropItemGroup> DropItemGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the skills of this game configuration.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<Skill> Skills { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character classes.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<CharacterClass> CharacterClasses { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item definitions.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemDefinition> Items { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item level bonus tables.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemLevelBonusTable> ItemLevelBonusTables { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item slot types.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemSlotType> ItemSlotTypes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item option definitions.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOptionDefinition> ItemOptions { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item option types.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOptionType> ItemOptionTypes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item set groups.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemSetGroup> ItemSetGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item option combination bonuses.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOptionCombinationBonus> ItemOptionCombinationBonuses { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the map definitions.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<GameMapDefinition> Maps { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the monster definitions.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MonsterDefinition> Monsters { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attributes.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeDefinition> Attributes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the magic effects.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MagicEffectDefinition> MagicEffects { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master skill roots.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MasterSkillRoot> MasterSkillRoots { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute combinations.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRelationship> GlobalAttributeCombinations { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base attribute values.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ConstValueAttribute> GlobalBaseAttributeValues { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the plug in configurations.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<PlugInConfiguration> PlugInConfigurations { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the event definitions.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MiniGameDefinition> MiniGameDefinitions { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return "Default Game Configuration";
|
||||
}
|
||||
}
|
||||
115
src/DataModel/Configuration/GameMapDefinition.cs
Normal file
115
src/DataModel/Configuration/GameMapDefinition.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
// <copyright file="GameMapDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Configuration of a map. Contains all information to create an instance of a GameMap.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Some maps have different possible status, for expample the crywolf map:
|
||||
/// 1) Balgass is undeafeated - monsters are not dropping special items
|
||||
/// 2) Balgass is defeated - monsters are dropping special items
|
||||
/// 3) Crywolf event is ongoing - The normal monsters are not there(?), but event monsters.
|
||||
/// For each of this status (<see cref="Discriminator"/>), there exist different terrain maps (safezones are different, etc.).
|
||||
/// To reflect this requirement on this data model, for each status there must be one game map definition.
|
||||
/// The switch between this status and its corresponding game map definitions should be done in game logic.
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class GameMapDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the number of the map.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This number is identifying the map on the client.
|
||||
/// </remarks>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the map.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the terrain data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Content of the *.att file in the original server.
|
||||
/// </remarks>
|
||||
public byte[]? TerrainData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the defined monster spawn areas.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MonsterSpawnArea> MonsterSpawns { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the enter gates, though which the player can move to other maps.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<EnterGate> EnterGates { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the exp multiplier for this map.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The exp multiplier.
|
||||
/// </value>
|
||||
public double ExpMultiplier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the discriminator which allows to identify different map definitions with the same <see cref="Number"/>.
|
||||
/// </summary>
|
||||
public int Discriminator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the game map to which the player will be brought when it died.
|
||||
/// One of the <see cref="ExitGates"/> where <see cref="ExitGate.IsSpawnGate"/> is selected.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameMapDefinition? SafezoneMap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the battle zone.
|
||||
/// This is usually just defined by the Arena map.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual BattleZoneDefinition? BattleZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the spawn gates.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ExitGate> ExitGates { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the DropItemGroup of this map.
|
||||
/// Some maps contain different drops. Examples: land of trials drops ancient items, kanturu drops gemstones.
|
||||
/// </summary>
|
||||
public virtual ICollection<DropItemGroup> DropItemGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the map requirements for player to use this map.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRequirement> MapRequirements { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power ups which are applied to characters which are currently on this map.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<PowerUpDefinition> CharacterPowerUpDefinitions { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Number} - {this.Name}";
|
||||
}
|
||||
}
|
||||
31
src/DataModel/Configuration/GameServerConfiguration.cs
Normal file
31
src/DataModel/Configuration/GameServerConfiguration.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="GameServerConfiguration.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the game server configuration.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class GameServerConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of players which can connect.
|
||||
/// </summary>
|
||||
public short MaximumPlayers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maps which should be hosted on the server.
|
||||
/// </summary>
|
||||
public virtual ICollection<GameMapDefinition> Maps { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Default ({this.MaximumPlayers} players)"; // TODO Add Description field
|
||||
}
|
||||
}
|
||||
61
src/DataModel/Configuration/GameServerDefinition.cs
Normal file
61
src/DataModel/Configuration/GameServerDefinition.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// <copyright file="GameServerDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using System.Globalization;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the configuration of a game server.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
public partial class GameServerDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server identifier.
|
||||
/// </summary>
|
||||
public byte ServerID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the experience rate for the specific server.
|
||||
/// Be aware that this multiplies with the <see cref="MUnique.OpenMU.DataModel.Configuration.GameConfiguration.ExperienceRate"/>.
|
||||
/// </summary>
|
||||
public float ExperienceRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether PVP is enabled on this server.
|
||||
/// </summary>
|
||||
public bool PvpEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server configuration.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameServerConfiguration? ServerConfiguration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the game configuration.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameConfiguration? GameConfiguration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the endpoints of the game server.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<GameServerEndpoint> Endpoints { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "#{0} - {1}", this.ServerID, this.Description);
|
||||
}
|
||||
}
|
||||
22
src/DataModel/Configuration/GameServerEndpoint.cs
Normal file
22
src/DataModel/Configuration/GameServerEndpoint.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
// <copyright file="GameServerEndpoint.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an endpoint of a game server.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class GameServerEndpoint : ServerEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the alternative published network port. It's reported to the connect server instead of the <see cref="ServerEndpoint.NetworkPort"/>, if not <c>0</c>.
|
||||
/// This allows to run a network analyzer program as a proxy, which listens to this <see cref="AlternativePublishedPort"/> and forwards to <see cref="ServerEndpoint.NetworkPort"/>
|
||||
/// without changing the connection address of the game client.
|
||||
/// This may also be useful if you use port forwarding over NAT.
|
||||
/// </summary>
|
||||
public int AlternativePublishedPort { get; set; }
|
||||
}
|
||||
46
src/DataModel/Configuration/Gate.cs
Normal file
46
src/DataModel/Configuration/Gate.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="Gate.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a gate through which a player can exit or enter to other maps.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class Gate : IMapArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner, x-coordinate.
|
||||
/// </summary>
|
||||
public byte X1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner, y-coordinate.
|
||||
/// </summary>
|
||||
public byte Y1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner, x-coordinate.
|
||||
/// </summary>
|
||||
public byte X2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner, y-coordinate.
|
||||
/// </summary>
|
||||
public byte Y2 { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var start = $"({this.X1}, {this.Y1})";
|
||||
if (this.X1 == this.X2 && this.Y1 == this.Y2)
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
return $"{start} - ({this.X2}, {this.Y2})";
|
||||
}
|
||||
}
|
||||
31
src/DataModel/Configuration/IMapArea.cs
Normal file
31
src/DataModel/Configuration/IMapArea.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="IMapArea.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a rectangular area on a map, defined by two corner coordinates.
|
||||
/// </summary>
|
||||
public interface IMapArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the upper-left corner X coordinate.
|
||||
/// </summary>
|
||||
byte X1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper-left corner Y coordinate.
|
||||
/// </summary>
|
||||
byte Y1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom-right corner X coordinate.
|
||||
/// </summary>
|
||||
byte X2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom-right corner Y coordinate.
|
||||
/// </summary>
|
||||
byte Y2 { get; set; }
|
||||
}
|
||||
39
src/DataModel/Configuration/ItemCrafting/ItemCrafting.cs
Normal file
39
src/DataModel/Configuration/ItemCrafting/ItemCrafting.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
// <copyright file="ItemCrafting.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Description of IItemCrafting.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemCrafting
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the number.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Referenced by the client with this number.
|
||||
/// </remarks>
|
||||
public byte Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the item crafting handler class.
|
||||
/// </summary>
|
||||
public string ItemCraftingHandlerClassName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the simple crafting settings.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual SimpleCraftingSettings? SimpleCraftingSettings { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
// <copyright file="ItemCraftingRequiredItem.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
using System.Globalization;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Describes an required item for a crafting.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemCraftingRequiredItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of possible items which are valid for this requirement.
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemDefinition> PossibleItems { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum item level.
|
||||
/// </summary>
|
||||
public byte MinimumItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum item level.
|
||||
/// </summary>
|
||||
public byte MaximumItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required item options.
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemOptionType> RequiredItemOptions { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum amount.
|
||||
/// </summary>
|
||||
public byte MinimumAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum amount.
|
||||
/// </summary>
|
||||
public byte MaximumAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success result.
|
||||
/// </summary>
|
||||
public MixResult SuccessResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the fail result.
|
||||
/// </summary>
|
||||
public MixResult FailResult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the NPC price divisor. For each full division, the percentage gets increased by 1 percent, and the mix price rises.
|
||||
/// </summary>
|
||||
public int NpcPriceDivisor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the add percentage per item.
|
||||
/// </summary>
|
||||
public byte AddPercentage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reference identifier to the corresponding <see cref="ItemCraftingResultItem.Reference"/>.
|
||||
/// If <c>0</c>, no reference exists.
|
||||
/// </summary>
|
||||
public byte Reference { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
string itemName;
|
||||
if (!this.PossibleItems.Any())
|
||||
{
|
||||
itemName = "Random Item";
|
||||
}
|
||||
else
|
||||
{
|
||||
itemName = string.Join(", ", this.PossibleItems.Select(p => p.Name));
|
||||
}
|
||||
|
||||
string amount = this.MinimumAmount == this.MaximumAmount
|
||||
? this.MinimumAmount.ToString(CultureInfo.InvariantCulture)
|
||||
: $"{this.MinimumAmount}~{this.MaximumAmount}";
|
||||
|
||||
string level;
|
||||
if (this.MinimumItemLevel == this.MaximumItemLevel && this.MinimumItemLevel == 0)
|
||||
{
|
||||
level = string.Empty;
|
||||
}
|
||||
else if (this.MinimumItemLevel == this.MaximumItemLevel)
|
||||
{
|
||||
level = $"+{this.MinimumItemLevel}";
|
||||
}
|
||||
else
|
||||
{
|
||||
level = $"+{this.MinimumItemLevel}~{this.MaximumItemLevel}";
|
||||
}
|
||||
|
||||
string options;
|
||||
if (this.RequiredItemOptions.Any())
|
||||
{
|
||||
options = "+" + string.Join("+", this.RequiredItemOptions.Select(o => o.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
options = string.Empty;
|
||||
}
|
||||
|
||||
return $"{amount} x {itemName}{level}{options}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// <copyright file="ItemCraftingResultItem.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the resulting item of a crafting.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemCraftingResultItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item definition.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? ItemDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the random minimum level for a created item.
|
||||
/// </summary>
|
||||
public byte RandomMinimumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the random maximum level for a created item.
|
||||
/// </summary>
|
||||
public byte RandomMaximumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the durability for a created item explicitly.
|
||||
/// </summary>
|
||||
public byte? Durability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reference to the corresponding <see cref="ItemCraftingRequiredItem.Reference"/>.
|
||||
/// If <c>0</c>, no reference exists.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For Item Upping.
|
||||
/// </remarks>
|
||||
public byte Reference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the add level.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For Item Upping.
|
||||
/// </remarks>
|
||||
public byte AddLevel { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
string itemName;
|
||||
if (this.ItemDefinition is null)
|
||||
{
|
||||
itemName = $"Referenced item {this.Reference} will be modified.";
|
||||
}
|
||||
else
|
||||
{
|
||||
itemName = this.ItemDefinition.Name;
|
||||
}
|
||||
|
||||
string level;
|
||||
if (this.RandomMinimumLevel == this.RandomMaximumLevel && this.RandomMinimumLevel == 0)
|
||||
{
|
||||
level = string.Empty;
|
||||
}
|
||||
else if (this.RandomMinimumLevel == this.RandomMaximumLevel)
|
||||
{
|
||||
level = $"+{this.RandomMinimumLevel}";
|
||||
}
|
||||
else
|
||||
{
|
||||
level = $"+{this.RandomMinimumLevel}~{this.RandomMaximumLevel}";
|
||||
}
|
||||
|
||||
return $"{itemName}{level}";
|
||||
}
|
||||
}
|
||||
31
src/DataModel/Configuration/ItemCrafting/MixResult.cs
Normal file
31
src/DataModel/Configuration/ItemCrafting/MixResult.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="MixResult.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
/// <summary>
|
||||
/// Defines what should happen with the required input items when the item crafting finished.
|
||||
/// </summary>
|
||||
public enum MixResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The item will disappear.
|
||||
/// </summary>
|
||||
Disappear = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The item will stay as is.
|
||||
/// </summary>
|
||||
StaysAsIs = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The item will be downgraded to a random level, may lose its skill, and its item option may be reduced by 1 level.
|
||||
/// </summary>
|
||||
ChaosWeaponAndFirstWingsDowngradedRandom = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The item will be downgraded 2 or 3 levels and its item option will be removed.
|
||||
/// </summary>
|
||||
ThirdWingsDowngradedRandom = 3,
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// <copyright file="ResultItemSelection.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the result item selection.
|
||||
/// </summary>
|
||||
public enum ResultItemSelection
|
||||
{
|
||||
/// <summary>
|
||||
/// One random item is selected as result from the result items.
|
||||
/// </summary>
|
||||
Any = 0,
|
||||
|
||||
/// <summary>
|
||||
/// All items are selected as result from the result items.
|
||||
/// </summary>
|
||||
All = 1,
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// <copyright file="SimpleCraftingSettings.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Crafting settings for the simple item crafting handler.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class SimpleCraftingSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the price to do the crafting.
|
||||
/// </summary>
|
||||
public int Money { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the price to do the crafting.
|
||||
/// </summary>
|
||||
public int MoneyPerFinalSuccessPercentage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the NPC price divisor for the sum of crafting items' prices. For each full division, the percentage gets increased by 1 percent, and the mix price rises.
|
||||
/// </summary>
|
||||
/// <remarks>Used for Chaos Weapon and 1st Level Wing craftings.</remarks>
|
||||
public int NpcPriceDivisor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percent.
|
||||
/// </summary>
|
||||
public byte SuccessPercent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum success percent.
|
||||
/// </summary>
|
||||
public byte MaximumSuccessPercent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether multiple crafting at the same time are allowed for this crafting.
|
||||
/// </summary>
|
||||
public bool MultipleAllowed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required items.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemCraftingRequiredItem> RequiredItems { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the result items, which are generated when the crafting succeeded.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemCraftingResultItem> ResultItems { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the result item selection.
|
||||
/// </summary>
|
||||
public ResultItemSelection ResultItemSelect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percentage addition for a item with luck option which gets modified.
|
||||
/// </summary>
|
||||
public int SuccessPercentageAdditionForLuck { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percentage addition for an excellent item which gets modified.
|
||||
/// </summary>
|
||||
public int SuccessPercentageAdditionForExcellentItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percentage addition for an ancient item which gets modified.
|
||||
/// </summary>
|
||||
public int SuccessPercentageAdditionForAncientItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percentage addition for a "380 item" which gets modified.
|
||||
/// </summary>
|
||||
public int SuccessPercentageAdditionForGuardianItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the success percentage addition for a socket item which gets modified.
|
||||
/// </summary>
|
||||
public int SuccessPercentageAdditionForSocketItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance in percent of getting the luck option in the random result item.
|
||||
/// </summary>
|
||||
public byte ResultItemLuckOptionChance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance in percent of getting the skill in the random result item.
|
||||
/// </summary>
|
||||
public byte ResultItemSkillChance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance in percent of getting an excellent option in the random result item.
|
||||
/// </summary>
|
||||
public byte ResultItemExcellentOptionChance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum excellent options in the random result item.
|
||||
/// </summary>
|
||||
public byte ResultItemMaxExcOptionCount { get; set; }
|
||||
}
|
||||
76
src/DataModel/Configuration/ItemDropItemGroup.cs
Normal file
76
src/DataModel/Configuration/ItemDropItemGroup.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
// <copyright file="ItemDropItemGroup.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an effect which is shown in the game, when a <see cref="ItemDropItemGroup"/> is applied.
|
||||
/// </summary>
|
||||
public enum ItemDropEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// No effect.
|
||||
/// </summary>
|
||||
Undefined,
|
||||
|
||||
/// <summary>
|
||||
/// A fireworks is shown at specific coordinates.
|
||||
/// </summary>
|
||||
Fireworks,
|
||||
|
||||
/// <summary>
|
||||
/// A christmas fireworks is shown at specific coordinates.
|
||||
/// </summary>
|
||||
ChristmasFireworks,
|
||||
|
||||
/// <summary>
|
||||
/// A fanfare sound is played.
|
||||
/// </summary>
|
||||
FanfareSound,
|
||||
|
||||
/// <summary>
|
||||
/// A swirl is shown around an object, usually the player which caused the action.
|
||||
/// </summary>
|
||||
Swirl,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="DropItemGroup"/> which acts a definition of possible items when a special item (e.g. Box of Luck) is dropped by the player.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemDropItemGroup : DropItemGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="Item.Level"/> of the source item which was dropped by the player.
|
||||
/// </summary>
|
||||
public byte SourceItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of money, in case <see cref="DropItemGroup.ItemType"/> is <see cref="SpecialItemType.Money"/>.
|
||||
/// </summary>
|
||||
public int MoneyAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum level of the <see cref="DropItemGroup.PossibleItems"/>.
|
||||
/// </summary>
|
||||
public byte MinimumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum level of the <see cref="DropItemGroup.PossibleItems"/>.
|
||||
/// </summary>
|
||||
public byte MaximumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character level which is required to drop this item.
|
||||
/// </summary>
|
||||
public short RequiredCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the effect which should be shown in the game client when this drop group is applied.
|
||||
/// </summary>
|
||||
public ItemDropEffect DropEffect { get; set; }
|
||||
}
|
||||
32
src/DataModel/Configuration/Items/AttributeRequirement.cs
Normal file
32
src/DataModel/Configuration/Items/AttributeRequirement.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
// <copyright file="AttributeRequirement.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a requirement of an attribute with the specified value.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class AttributeRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute which is required.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual AttributeDefinition? Attribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum value the attribute needs to have.
|
||||
/// </summary>
|
||||
public int MinimumValue { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Attribute}: {this.MinimumValue}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// <copyright file="CombinationBonusRequirement.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a requirement of existing item options on the equipped items of a character.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class CombinationBonusRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the required <see cref="ItemOption.OptionType"/>.
|
||||
/// </summary>
|
||||
public virtual ItemOptionType? OptionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required <see cref="ItemOption.SubOptionType"/>.
|
||||
/// </summary>
|
||||
public int SubOptionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum count of options in order to fulfill the requirement.
|
||||
/// </summary>
|
||||
public int MinimumCount { get; set; } = 1;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.OptionType}: SubOption Type {this.SubOptionType}, Min. Count {this.MinimumCount}";
|
||||
}
|
||||
}
|
||||
75
src/DataModel/Configuration/Items/IncreasableItemOption.cs
Normal file
75
src/DataModel/Configuration/Items/IncreasableItemOption.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
// <copyright file="IncreasableItemOption.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using System.Linq;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines by which "level" the option is increased with <see cref="IncreasableItemOption.LevelDependentOptions"/>.
|
||||
/// </summary>
|
||||
public enum LevelType
|
||||
{
|
||||
/// <summary>
|
||||
/// It's increased by the option level.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This one is used by item options which can be increased by separate jewels, e.g. Jewel of Life or Jewel of Harmony.
|
||||
/// </remarks>
|
||||
OptionLevel,
|
||||
|
||||
/// <summary>
|
||||
/// It's increased by the level of the item which has the option.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// As far as I know, this is only required for wing options, e.g. 'Increase max HP +50~125'. That's why <see cref="OptionLevel"/> is the default, too.
|
||||
/// </remarks>
|
||||
ItemLevel,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines an item option which can be increased.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class IncreasableItemOption : ItemOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value which defines by which "level" the option is increased with <see cref="LevelDependentOptions"/>.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the level.
|
||||
/// </value>
|
||||
public LevelType LevelType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value which is considered when randomizing the option to an item.
|
||||
/// </summary>
|
||||
/// <remarks>This is used for Jewel of Harmony options rollout.</remarks>
|
||||
/// <value>The statistical weight.</value>
|
||||
public byte Weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level dependent options for option levels over 1.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOptionOfLevel> LevelDependentOptions { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.PowerUpDefinition != null)
|
||||
{
|
||||
return base.ToString();
|
||||
}
|
||||
|
||||
var firstLevelOption = this.LevelDependentOptions?.OrderBy(l => l.Level).FirstOrDefault();
|
||||
if (firstLevelOption?.PowerUpDefinition != null)
|
||||
{
|
||||
return $"{this.OptionType}: {firstLevelOption.PowerUpDefinition} ({this.Number})";
|
||||
}
|
||||
|
||||
return base.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// <copyright file="ItemBasePowerUpDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an item base power up definition.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemBasePowerUpDefinition
|
||||
{
|
||||
private ConstantElement? _baseValueElement;
|
||||
private float _baseValue;
|
||||
private AggregateType _aggregateType;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target attribute.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? TargetAttribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base value.
|
||||
/// </summary>
|
||||
[Transient]
|
||||
public ConstantElement BaseValueElement => this._baseValueElement ??= new ConstantElement(this.BaseValue, this.AggregateType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bonus per level.
|
||||
/// </summary>
|
||||
public virtual ItemLevelBonusTable? BonusPerLevelTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the additional value to the base value.
|
||||
/// </summary>
|
||||
public float BaseValue
|
||||
{
|
||||
get => this._baseValue;
|
||||
set
|
||||
{
|
||||
this._baseValue = value;
|
||||
this._baseValueElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the aggregate.
|
||||
/// </summary>
|
||||
public AggregateType AggregateType
|
||||
{
|
||||
get => this._aggregateType;
|
||||
set
|
||||
{
|
||||
this._aggregateType = value;
|
||||
this._baseValueElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.BaseValue} {this.TargetAttribute} {this.AggregateType}";
|
||||
}
|
||||
}
|
||||
195
src/DataModel/Configuration/Items/ItemDefinition.cs
Normal file
195
src/DataModel/Configuration/Items/ItemDefinition.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
// <copyright file="ItemDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an item.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the (Sub-)Id of this item. Must be unique in an item group.
|
||||
/// </summary>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item slot where it can get equipped.
|
||||
/// </summary>
|
||||
public virtual ItemSlotType? ItemSlot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of the Item.
|
||||
/// </summary>
|
||||
public byte Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the weight of the Item.
|
||||
/// </summary>
|
||||
public byte Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the item can be dropped by monsters.
|
||||
/// </summary>
|
||||
public bool DropsFromMonsters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance acts as ammunition for another equipped weapon.
|
||||
/// </summary>
|
||||
public bool IsAmmunition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether items of this kind are bound to character.
|
||||
/// That means, it can't be traded, moved to the vault/personal shop or picked up from the ground by other players.
|
||||
/// </summary>
|
||||
public bool IsBoundToCharacter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether items of this kind are quest items.
|
||||
/// Quest items may additionally only be picked up from the ground by a character
|
||||
/// which has an active quest that requires them, even if the character is a member
|
||||
/// of the party which killed the monster that dropped it.
|
||||
/// </summary>
|
||||
public bool IsQuestItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the storage limit per character which is checked on pick-up.
|
||||
/// A value of 0 means, that there is no limit.
|
||||
/// A value 'n' above 0 means, that the inventory of the character can store
|
||||
/// at most 'n' items of this kind.
|
||||
/// </summary>
|
||||
public int StorageLimitPerCharacter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the item.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item drop level, which indicates the minimum monster lvl of which this item can be dropped.
|
||||
/// </summary>
|
||||
public byte DropLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum monster level at which this item can be dropped.
|
||||
/// If no value is set, there is no upper limit.
|
||||
/// </summary>
|
||||
public byte? MaximumDropLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum item level.
|
||||
/// </summary>
|
||||
public byte MaximumItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum durability of this item at Level 0.
|
||||
/// </summary>
|
||||
public byte Durability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item Group (0-15). TODO: Might change item groups to classes, and replace this by it.
|
||||
/// </summary>
|
||||
public byte Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value which defines the worth of an item in zen currency.
|
||||
/// </summary>
|
||||
public int Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the formula to calculate the required experience for a specific pet level.
|
||||
/// Only applies, if this item is actually a trainable pet.
|
||||
/// The variable for the pet level is "level".
|
||||
/// </summary>
|
||||
public string? PetExperienceFormula { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the effect which is applied when this item is consumed.
|
||||
/// Creating a consume handler plugin is not required when this effect definition is set.
|
||||
/// </summary>
|
||||
public virtual MagicEffectDefinition? ConsumeEffect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of sockets an instance of this item can have.
|
||||
/// </summary>
|
||||
public int MaximumSockets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the skill which this items adds to the skill list while wearing or which can be learned by consuming this item.
|
||||
/// TODO: Split these two usages into different properties?.
|
||||
/// </summary>
|
||||
public virtual Skill? Skill { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character classes which are qualified to wear this Item.
|
||||
/// </summary>
|
||||
public virtual ICollection<CharacterClass> QualifiedCharacters { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the possible item set groups.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this we can define a lot of things, for example:
|
||||
/// - double wear bonus of single swords
|
||||
/// - set bonus for defense rate
|
||||
/// - set bonus for defense, if level is greater than 9
|
||||
/// - ancient sets.
|
||||
/// </remarks>
|
||||
public virtual ICollection<ItemSetGroup> PossibleItemSetGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the possible item options.
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemOptionDefinition> PossibleItemOptions { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the requirements for wearing this item.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRequirement> Requirements { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base PowerUps of this item, for example min/max damage for weapons.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemBasePowerUpDefinition> BasePowerUpAttributes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drop item groups (one per possible item level), which are used to
|
||||
/// generate a new item when this item gets dropped by a player.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemDropItemGroup> DropItems { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Name} ({this.Group}, {this.Number}) [{this.Width}x{this.Height}]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name for level.
|
||||
/// </summary>
|
||||
/// <param name="itemLevel">The item level.</param>
|
||||
/// <returns>The name of the item of a certain level.</returns>
|
||||
public string GetNameForLevel(byte itemLevel)
|
||||
{
|
||||
var itemName = this.Name.ToString();
|
||||
if (itemName?.Contains(';') ?? false)
|
||||
{
|
||||
var tokens = itemName.Split(';');
|
||||
if (tokens.Length > itemLevel)
|
||||
{
|
||||
itemName = tokens[itemLevel];
|
||||
}
|
||||
}
|
||||
|
||||
return itemName ?? string.Empty;
|
||||
}
|
||||
}
|
||||
31
src/DataModel/Configuration/Items/ItemLevelBonusTable.cs
Normal file
31
src/DataModel/Configuration/Items/ItemLevelBonusTable.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="ItemLevelBonusTable.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a table of item level related bonus values for <see cref="ItemBasePowerUpDefinition"/>s.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemLevelBonusTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bonus per level.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<LevelBonus> BonusPerLevel { get; protected set; } = null!;
|
||||
}
|
||||
55
src/DataModel/Configuration/Items/ItemOfItemSet.cs
Normal file
55
src/DataModel/Configuration/Items/ItemOfItemSet.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// <copyright file="ItemOfItemSet.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines additional bonus options for this item of a set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Here we can define additional bonus options, like the ancient options (e.g. +5 / +10 Str etc.).
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class ItemOfItemSet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the ancient set discriminator.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only relevant to ancient sets. One item can only be in one ancient set with the same discriminator.
|
||||
/// The original mu online protocol supports up to two different ancient sets per item - with discriminator values 1 and 2.
|
||||
/// E.g. a 'Warrior Leather' set would have a discriminator value of 1, the 'Anonymous Leather' set would have 2.
|
||||
/// </remarks>
|
||||
public int AncientSetDiscriminator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item set group to which this instance belongs.
|
||||
/// </summary>
|
||||
public virtual ItemSetGroup? ItemSetGroup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item's definition for which the bonus should apply.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? ItemDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bonus option.
|
||||
/// </summary>
|
||||
public virtual IncreasableItemOption? BonusOption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string Name => $"{this.ItemSetGroup?.Name} {this.ItemDefinition?.Name}";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return this.BonusOption?.PowerUpDefinition?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
50
src/DataModel/Configuration/Items/ItemOption.cs
Normal file
50
src/DataModel/Configuration/Items/ItemOption.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// <copyright file="ItemOption.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the option of an item.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the number.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This number in combination with the option type is a reference for the client.
|
||||
/// </remarks>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a type of the sub option.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is required for socket options, for example.
|
||||
/// There, it defines the element (fire, water, etc.) of the socket option.
|
||||
/// </remarks>
|
||||
public int SubOptionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the option.
|
||||
/// </summary>
|
||||
public virtual ItemOptionType? OptionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power up definition which should apply when this item is carried.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
[Required]
|
||||
public virtual PowerUpDefinition? PowerUpDefinition { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.OptionType}: {this.PowerUpDefinition} ({this.Number})";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// <copyright file="ItemOptionCombinationBonus.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a bonus which gets granted when the equipped items
|
||||
/// have at least the specified required item options in total.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usage example: The "Socket Package Options" when a character wears socket items with all kind of elemental options.
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class ItemOptionCombinationBonus
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number.
|
||||
/// </summary>
|
||||
public int Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this bonus applies multiple times, for each set of found options.
|
||||
/// </summary>
|
||||
public bool AppliesMultipleTimes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required item options which all have to be fulfilled in order to get the <see cref="Bonus"/>.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<CombinationBonusRequirement> Requirements { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bonus power up.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinition? Bonus { get; set; }
|
||||
}
|
||||
50
src/DataModel/Configuration/Items/ItemOptionDefinition.cs
Normal file
50
src/DataModel/Configuration/Items/ItemOptionDefinition.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// <copyright file="ItemOptionDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// The definition of an item option.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemOptionDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the option, for example "Luck", "Skill", "Normal Option".
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this option adds randomly.
|
||||
/// </summary>
|
||||
public bool AddsRandomly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the add chance if this option adds randomly.
|
||||
/// </summary>
|
||||
public float AddChance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum options per item when it adds randomly by drop.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usually this is 1. But for some options (e.g. excellent) this can be bigger than 1.
|
||||
/// </remarks>
|
||||
public int MaximumOptionsPerItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the possible options.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<IncreasableItemOption> PossibleOptions { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
37
src/DataModel/Configuration/Items/ItemOptionOfLevel.cs
Normal file
37
src/DataModel/Configuration/Items/ItemOptionOfLevel.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// <copyright file="ItemOptionOfLevel.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
|
||||
/// <summary>
|
||||
/// The item option, depending on the specified item level.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemOptionOfLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the level.
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required item level.
|
||||
/// </summary>
|
||||
public int RequiredItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power up definition.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinition? PowerUpDefinition { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Level {this.Level}: {this.PowerUpDefinition}";
|
||||
}
|
||||
}
|
||||
111
src/DataModel/Configuration/Items/ItemOptionType.cs
Normal file
111
src/DataModel/Configuration/Items/ItemOptionType.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
// <copyright file="ItemOptionType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Type of an item option.
|
||||
/// </summary>
|
||||
/// <remarks>For example excellent, option, socket, luck.</remarks>
|
||||
[Cloneable]
|
||||
public partial class ItemOptionType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this item option is visible to other players.
|
||||
/// </summary>
|
||||
public bool IsVisible { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The LHS.</param>
|
||||
/// <param name="rhs">The RHS.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(ItemOptionType? lhs, ItemOptionType? rhs)
|
||||
{
|
||||
if (ReferenceEquals(lhs, rhs))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lhs is null || rhs is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="lhs">The LHS.</param>
|
||||
/// <param name="rhs">The RHS.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(ItemOptionType? lhs, ItemOptionType? rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object" />, is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not ItemOptionType other)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.Id == other.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
85
src/DataModel/Configuration/Items/ItemOptionTypes.cs
Normal file
85
src/DataModel/Configuration/Items/ItemOptionTypes.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
// <copyright file="ItemOptionTypes.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Some standard option types.
|
||||
/// </summary>
|
||||
public static class ItemOptionTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the excellent item option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType Excellent { get; } = new() { Name = "Excellent Option", Id = new Guid("{6487C498-58E0-48E5-B409-35D7598313FC}"), IsVisible = true };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the wing option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType Wing { get; } = new() { Name = "Wing Option", Id = new Guid("{55CB57A7-4FC6-47BB-9FEE-84E6C4EBCE95}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the luck option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType Luck { get; } = new() { Name = "Luck (Critical Damage Chance 5%)", Id = new Guid("{3E3E9BE8-4E16-4F27-A7CF-986D48454D76}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the standard option option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType Option { get; } = new() { Name = "Option", Id = new Guid("{F193F91E-86D7-4456-ADD8-A3667E731303}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the harmony option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType HarmonyOption { get; } = new() { Name = "Jewel of Harmony Option", Id = new Guid("{0CA234F0-4A0F-4FA1-8E07-CFB89C1EC94F}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ancient option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType AncientOption { get; } = new() { Name = "Ancient Option", Id = new Guid("{436D820F-6D50-429D-AF63-BB0F59567DD1}"), IsVisible = true };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ancient bonus option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType AncientBonus { get; } = new() { Name = "Ancient Bonus Option", Id = new Guid("{5E2C10EF-E580-48D5-A48B-0FFCD0678966}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the guardian option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType GuardianOption { get; } = new() { Name = "Guardian Option", Id = new Guid("{4AA95715-1ED3-453D-8D1D-093B281416CA}"), Description = "This option is added by the chaos machine with a jewel of guardian on level 380 items." };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the socket option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType SocketOption { get; } = new() { Name = "Socket Option", Id = new Guid("{AAB309D3-CD97-4F77-AE1B-E9F904102502}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the socket bonus option type.
|
||||
/// </summary>
|
||||
public static ItemOptionType SocketBonusOption { get; } = new() { Name = "Socket Bonus Option", Id = new Guid("{43DA2C68-D6E1-4B94-ADB1-8864D92F8FB9}") };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the blue fenrir option type.
|
||||
/// </summary>
|
||||
/// <remarks>Applies only to the fenrir pet.</remarks>
|
||||
public static ItemOptionType BlueFenrir { get; } = new() { Name = "Blue Fenrir Option", Id = new Guid("{C3ED45BC-5713-494D-A8C8-DC4AFAE56223}"), IsVisible = true };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the black fenrir option type.
|
||||
/// </summary>
|
||||
/// <remarks>Applies only to the fenrir pet.</remarks>
|
||||
public static ItemOptionType BlackFenrir { get; } = new() { Name = "Black Fenrir Option", Id = new Guid("{ED978695-BD3E-46EA-86D8-F8C30EA99B50}"), IsVisible = true };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the gold fenrir option type.
|
||||
/// </summary>
|
||||
/// <remarks>Applies only to the fenrir pet.</remarks>
|
||||
public static ItemOptionType GoldFenrir { get; } = new() { Name = "Gold Fenrir Option", Id = new Guid("{78E6DB0B-AC53-454C-956F-CD2B5467856E}"), IsVisible = true };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dark horse option type.
|
||||
/// </summary>
|
||||
/// <remarks>Applies only to the dark horse pet.</remarks>
|
||||
public static ItemOptionType DarkHorse { get; } = new() { Name = "Dark Horse Option", Id = new Guid("{D2295C44-E458-40F8-8555-87CFD9626616}"), IsVisible = true };
|
||||
}
|
||||
73
src/DataModel/Configuration/Items/ItemSetGroup.cs
Normal file
73
src/DataModel/Configuration/Items/ItemSetGroup.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
// <copyright file="ItemSetGroup.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an item set group. With (partial) completion of the set, additional options are getting applied.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// With this we can define a lot of things, for example:
|
||||
/// - double wear bonus of single swords
|
||||
/// - set bonus for defense rate
|
||||
/// - set bonus for defense, if level is greater than 9
|
||||
/// - ancient sets.
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class ItemSetGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The name.
|
||||
/// </value>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the options of this item set always apply to an item,
|
||||
/// even if the group wasn't explicitly added to the <see cref="Item.ItemSetGroups"/>.
|
||||
/// The minimum item count and the minimum set levels are respected.
|
||||
/// </summary>
|
||||
public bool AlwaysApplies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the items are counted distinctly.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, for the double wear bonus this has to be non-distinct, else we wouldn't get the bonus for wearing two of the same kind of swords.
|
||||
/// </remarks>
|
||||
public bool CountDistinct { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum item count which is needed to get the bonus.
|
||||
/// </summary>
|
||||
public int MinimumItemCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum level which all of the items of the set need to have to get the bonus.
|
||||
/// </summary>
|
||||
public int SetLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the options. If the options depend on the item count, this options need to be ordered correctly.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The order is defined by <see cref="ItemOption.Number"/>.
|
||||
/// </remarks>
|
||||
public virtual ItemOptionDefinition? Options { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the items of this set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Here we can define additional bonus options, like the ancient options (e.g. +5 / +10 Str etc.).
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOfItemSet> Items { get; protected set; } = null!;
|
||||
}
|
||||
25
src/DataModel/Configuration/Items/ItemSlotType.cs
Normal file
25
src/DataModel/Configuration/Items/ItemSlotType.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// <copyright file="ItemSlotType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// The item slot type. Each of this may have one or more actual item slots.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemSlotType
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item slots of this slot type.
|
||||
/// </summary>
|
||||
public virtual ICollection<int> ItemSlots { get; protected set; } = null!;
|
||||
}
|
||||
70
src/DataModel/Configuration/Items/LevelBonus.cs
Normal file
70
src/DataModel/Configuration/Items/LevelBonus.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
// <copyright file="LevelBonus.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a constant bonus, depending on item level.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class LevelBonus
|
||||
{
|
||||
private float _additionalValue;
|
||||
private ConstantElement? _additionalValueElement;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LevelBonus"/> class.
|
||||
/// </summary>
|
||||
public LevelBonus()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LevelBonus"/> class.
|
||||
/// </summary>
|
||||
/// <param name="level">The level.</param>
|
||||
/// <param name="constantValue">The constant value.</param>
|
||||
public LevelBonus(int level, float constantValue)
|
||||
{
|
||||
this.Level = level;
|
||||
this.AdditionalValue = constantValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level of the item.
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the additional value to the base value.
|
||||
/// </summary>
|
||||
public float AdditionalValue
|
||||
{
|
||||
get => this._additionalValue;
|
||||
set
|
||||
{
|
||||
this._additionalValue = value;
|
||||
this._additionalValueElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the element which represents the <see cref="AdditionalValue"/>.
|
||||
/// </summary>
|
||||
/// <param name="aggregateType">Type of the aggregate.</param>
|
||||
/// <returns>The element which represents the <see cref="AdditionalValue"/>.</returns>
|
||||
public IElement GetAdditionalValueElement(AggregateType aggregateType)
|
||||
{
|
||||
return this._additionalValueElement ??= new ConstantElement(this.AdditionalValue, aggregateType);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Level: {this.Level}: {this.AdditionalValue}";
|
||||
}
|
||||
}
|
||||
41
src/DataModel/Configuration/JewelMix.cs
Normal file
41
src/DataModel/Configuration/JewelMix.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// <copyright file="JewelMix.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a jewel mix.
|
||||
/// Some <see cref="SingleJewel"/> can be mixed together to a single <see cref="MixedJewel"/> to save storage place.
|
||||
/// When single jewels are needed again, the client can unmix his <see cref="MixedJewel"/> back to several <see cref="SingleJewel"/>.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class JewelMix
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets gets the number of the mix.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This number is a reference for the client.
|
||||
/// </remarks>
|
||||
public byte Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets gets the single jewel item definition.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? SingleJewel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets gets the mixed jewel item definition.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? MixedJewel { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.SingleJewel?.Name} <> {this.MixedJewel?.Name}";
|
||||
}
|
||||
}
|
||||
30
src/DataModel/Configuration/LevelDependentDamage.cs
Normal file
30
src/DataModel/Configuration/LevelDependentDamage.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
// <copyright file="LevelDependentDamage.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a level-dependent damage.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class LevelDependentDamage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the level belonging to this damage value.
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the damage belonging to this level.
|
||||
/// </summary>
|
||||
public int Damage { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Level {this.Level}: {this.Damage}";
|
||||
}
|
||||
}
|
||||
123
src/DataModel/Configuration/MagicEffectDefinition.cs
Normal file
123
src/DataModel/Configuration/MagicEffectDefinition.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
// <copyright file="MagicEffectDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Magic Effect Definition. It can be an effect from a consumed item, a buff, or the result of an attack skill.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MagicEffectDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the number.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This number is a reference for the game client.
|
||||
/// Negative numbers are for internal usage and their effects are not meant to be exposed to the game client.
|
||||
/// </remarks>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sub type.
|
||||
/// Same sub type = cant stack. Adding a magic effect with the same sub type will cause the existing magic effect to disappear.
|
||||
/// </summary>
|
||||
public byte SubType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the effect change is sent to observers.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Some effects are not externally visible, but only to the player himself.
|
||||
/// </remarks>
|
||||
public bool InformObservers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the effect gets stopped by a death of the player.
|
||||
/// </summary>
|
||||
public bool StopByDeath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the duration of the effect should be sent.
|
||||
/// </summary>
|
||||
public bool SendDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the duration of the effect depends on the target's level.
|
||||
/// </summary>
|
||||
public bool DurationDependsOnTargetLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value by which the effect target's (monster) level should be divided in case <see cref="DurationDependsOnTargetLevel"/> is <c>true</c>.
|
||||
/// </summary>
|
||||
public float MonsterTargetLevelDivisor { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value by which the effect target's (player) level should be divided in case <see cref="DurationDependsOnTargetLevel"/> is <c>true</c>.
|
||||
/// </summary>
|
||||
public float PlayerTargetLevelDivisor { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance of applying the effect, in decimals.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Results in a value of 1.0 if not set.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinitionValue? Chance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance of applying the effect in PvP, in decimals.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Results in the same value as <see cref="Chance"/> if not set.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinitionValue? ChancePvp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration which describes how long the <see cref="PowerUpDefinitions"/> apply, in seconds.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinitionValue? Duration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration which describes how long the <see cref="PowerUpDefinitions"/> apply to PvP, in seconds.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Results in the same value as <see cref="Duration"/> if not set.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual PowerUpDefinitionValue? DurationPvp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power up definitions which are used to create the actual power up element.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<PowerUpDefinition> PowerUpDefinitions { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power up definitions which are used to create the actual power up element for PvP.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Results in the same collection as <see cref="PowerUpDefinitions"/> if not set.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<PowerUpDefinition> PowerUpDefinitionsPvp { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Name} ({this.Number})";
|
||||
}
|
||||
}
|
||||
97
src/DataModel/Configuration/MasterSkillDefinition.cs
Normal file
97
src/DataModel/Configuration/MasterSkillDefinition.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
// <copyright file="MasterSkillDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The definition of a master skill. One skill can have 0-n master skill definitions,
|
||||
/// for example one skill can be used for different character classes at different Rank-Levels at different Roots.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MasterSkillDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the root.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual MasterSkillRoot? Root { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection with the required skills.
|
||||
/// Just one skill (of at least level 10) of this list is required
|
||||
/// to meet the requirements when learning this skill.
|
||||
/// </summary>
|
||||
public virtual ICollection<Skill> RequiredMasterSkills { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rank.
|
||||
/// The rank determines on which level the skill is located.
|
||||
/// A skill at a higher rank can be learned, if there is at least
|
||||
/// one skill of the same tree root at the direct rank below,
|
||||
/// with a level same or greater than 10.
|
||||
/// </summary>
|
||||
public byte Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum level.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Usually it's 20, but for some skills it's 10.
|
||||
/// </remarks>
|
||||
public byte MaximumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum level which is required until the skill gets active.
|
||||
/// It's also the number of master points which are initially required to learn the skill.
|
||||
/// </summary>
|
||||
public byte MinimumLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the formula to calculate the effective value, depending on the level of the master skill.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We use the syntax of MathParser.org.
|
||||
/// To use the level in the formula, use the argument "level".
|
||||
/// </remarks>
|
||||
public string ValueFormula { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the formula to calculate the visible value, depending on the level of the master skill.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We use the syntax of MathParser.org.
|
||||
/// To use the level in the formula, use the argument "level".
|
||||
/// </remarks>
|
||||
public string DisplayValueFormula { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target attribute of a passive skill boost.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? TargetAttribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of how the calculated value is aggregated to the <see cref="TargetAttribute"/>.
|
||||
/// </summary>
|
||||
public AggregateType Aggregation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the replaced skill. If this skill is defined, this master skill replaces it in the skill list.
|
||||
/// The attack damage is also inherited and increased by the damage AND value of the master skill.
|
||||
/// </summary>
|
||||
public virtual Skill? ReplacedSkill { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the <see cref="ValueFormula"/> applies to the duration of the <see cref="ReplacedSkill"/>.
|
||||
/// </summary>
|
||||
public bool ExtendsDuration { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return "Master Skill Definition";
|
||||
}
|
||||
}
|
||||
28
src/DataModel/Configuration/MasterSkillRoot.cs
Normal file
28
src/DataModel/Configuration/MasterSkillRoot.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
// <copyright file="MasterSkillRoot.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The root of a master skill tree. One character can have more than one root.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MasterSkillRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? ToString()
|
||||
{
|
||||
return this.Name.ToString();
|
||||
}
|
||||
}
|
||||
100
src/DataModel/Configuration/MiniGameChangeEvent.cs
Normal file
100
src/DataModel/Configuration/MiniGameChangeEvent.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
// <copyright file="MiniGameChangeEvent.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the kind of targets for the <see cref="MiniGameChangeEvent"/>.
|
||||
/// </summary>
|
||||
public enum KillTarget
|
||||
{
|
||||
/// <summary>
|
||||
/// Any object counts as kill.
|
||||
/// </summary>
|
||||
AnyObject,
|
||||
|
||||
/// <summary>
|
||||
/// Any monster counts as kill.
|
||||
/// </summary>
|
||||
AnyMonster,
|
||||
|
||||
/// <summary>
|
||||
/// A specific monster or destructible, defined by <see cref="MiniGameChangeEvent.TargetDefinition"/> counts as kill.
|
||||
/// </summary>
|
||||
Specific,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An event which changes the mini game to a next phase.
|
||||
/// Defines what the player needs to do to reach it,
|
||||
/// and what happens when the requirements are fulfilled.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MiniGameChangeEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the index to define the order of the event.
|
||||
/// Usually, events are worked through in sequential order.
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description about the event.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the (golden) message which should be shown to the player.
|
||||
/// One placeholder can be used to show the triggering player name.
|
||||
/// </summary>
|
||||
public LocalizedString Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the targets which need to be killed to reach the required <see cref="NumberOfKills"/>.
|
||||
/// </summary>
|
||||
public KillTarget Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum level of the <see cref="Target"/>s,
|
||||
/// if no specific <see cref="TargetDefinition"/> is supplied.
|
||||
/// </summary>
|
||||
public short? MinimumTargetLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of kills which the player(s) have to reach.
|
||||
/// </summary>
|
||||
public short NumberOfKills { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the <see cref="NumberOfKills"/> are meant to be
|
||||
/// a multiple of the players of the game, or not.
|
||||
/// </summary>
|
||||
public bool MultiplyKillsByPlayers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target definition.
|
||||
/// </summary>
|
||||
public virtual MonsterDefinition? TargetDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the optional spawns which will appear when the players reach the goal.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual MonsterSpawnArea? SpawnArea { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the changes which will be applied to the terrain when the player reach the goal.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MiniGameTerrainChange> TerrainChanges { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Index}: {this.Description}";
|
||||
}
|
||||
}
|
||||
155
src/DataModel/Configuration/MiniGameDefinition.cs
Normal file
155
src/DataModel/Configuration/MiniGameDefinition.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
// <copyright file="MiniGameDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Definition for a mini game.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Each game level of a mini game has its own <see cref="MiniGameDefinition"/>.
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class MiniGameDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the mini game.
|
||||
/// </summary>
|
||||
public MiniGameType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the mini game.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description of the mini game.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level of the mini game.
|
||||
/// </summary>
|
||||
public byte GameLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the creation policy of the mini game.
|
||||
/// </summary>
|
||||
public MiniGameMapCreationPolicy MapCreationPolicy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration between opening the mini game map and actually starting the game.
|
||||
/// </summary>
|
||||
public TimeSpan EnterDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the game.
|
||||
/// </summary>
|
||||
public TimeSpan GameDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration after which the game map exists when the game finished.
|
||||
/// </summary>
|
||||
public TimeSpan ExitDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum player count which can enter the game.
|
||||
/// </summary>
|
||||
public int MaximumPlayerCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to save the score as <see cref="MUnique.OpenMU.DataModel.Statistics.MiniGameRankingEntry"/>.
|
||||
/// </summary>
|
||||
public bool SaveRankingStatistics { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether only characters with <see cref="CharacterClass.IsMasterClass"/> = <see langword="true"/> can enter.
|
||||
/// </summary>
|
||||
public bool RequiresMasterClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum character level to which this mini game is available.
|
||||
/// </summary>
|
||||
public int MinimumCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum character level to which this mini game is available.
|
||||
/// </summary>
|
||||
public int MaximumCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum character level for special characters (MG, DL) to which this mini game is available.
|
||||
/// </summary>
|
||||
public int MinimumSpecialCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum character level for special characters (MG, DL) to which this mini game is available.
|
||||
/// </summary>
|
||||
public int MaximumSpecialCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ticket item level which is required to enter the event.
|
||||
/// </summary>
|
||||
public int TicketItemLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the entrance fee which is deducted from the players inventory
|
||||
/// when entering the mini game event.
|
||||
/// </summary>
|
||||
public int EntranceFee { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether player killers are allowed to
|
||||
/// enter the mini game.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if player killers are allowed to enter; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool ArePlayerKillersAllowedToEnter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to allow being in a party during the event.
|
||||
/// </summary>
|
||||
public bool AllowParty { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the entrance gate to the mini game map.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual ExitGate? Entrance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ticket item which is required to enter the mini game.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? TicketItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rewards which are given to the player when the game has been finished successfully.
|
||||
/// Multiple awards per players are possible.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MiniGameReward> Rewards { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the spawn waves of the mini game.
|
||||
/// Overlapping waves are possible.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MiniGameSpawnWave> SpawnWaves { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the mini game change events.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MiniGameChangeEvent> ChangeEvents { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
26
src/DataModel/Configuration/MiniGameMapCreationPolicy.cs
Normal file
26
src/DataModel/Configuration/MiniGameMapCreationPolicy.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// <copyright file="MiniGameMapCreationPolicy.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines how a mini game map is created.
|
||||
/// </summary>
|
||||
public enum MiniGameMapCreationPolicy
|
||||
{
|
||||
/// <summary>
|
||||
/// One map is created per party and game level.
|
||||
/// </summary>
|
||||
OnePerParty,
|
||||
|
||||
/// <summary>
|
||||
/// One map is created for each player.
|
||||
/// </summary>
|
||||
OnePerPlayer,
|
||||
|
||||
/// <summary>
|
||||
/// One map is created and shared for all players.
|
||||
/// </summary>
|
||||
Shared,
|
||||
}
|
||||
125
src/DataModel/Configuration/MiniGameReward.cs
Normal file
125
src/DataModel/Configuration/MiniGameReward.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
// <copyright file="MiniGameReward.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// The success flags of a mini game player.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum MiniGameSuccessFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// No defined flag.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The player submitted the required quest item to the NPC.
|
||||
/// </summary>
|
||||
Winner = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The player is part of the party of a player classified as <see cref="Winner"/>.
|
||||
/// </summary>
|
||||
WinningParty = 1 << 1,
|
||||
|
||||
/// <summary>
|
||||
/// The player is the winner or in the party of a player classified as <see cref="Winner"/>.
|
||||
/// </summary>
|
||||
WinnerOrInWinningParty = 1 << 2,
|
||||
|
||||
/// <summary>
|
||||
/// The player is not the winner and not in the winners party.
|
||||
/// </summary>
|
||||
Loser = 1 << 3,
|
||||
|
||||
/// <summary>
|
||||
/// The player managed to stay alive until the end.
|
||||
/// </summary>
|
||||
Alive = 1 << 4,
|
||||
|
||||
/// <summary>
|
||||
/// The player died during the game.
|
||||
/// </summary>
|
||||
Dead = 1 << 5,
|
||||
|
||||
/// <summary>
|
||||
/// A winner exists in the game.
|
||||
/// </summary>
|
||||
WinnerExists = 1 << 6,
|
||||
|
||||
/// <summary>
|
||||
/// A winner doesn't exist in the game.
|
||||
/// </summary>
|
||||
WinnerNotExists = 1 << 7,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a reward of a <see cref="MiniGameDefinition"/>.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MiniGameReward
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the rank to which this reward is applicable.
|
||||
/// It's applicable, when more than one player can complete the mini game and
|
||||
/// you'd want to give different awards for a differently ranked players.
|
||||
/// </summary>
|
||||
public int? Rank { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the reward type.
|
||||
/// </summary>
|
||||
public MiniGameRewardType RewardType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of the rewards.
|
||||
/// In case of <see cref="MiniGameRewardType.Money"/> it's the amount of money.
|
||||
/// In case of <see cref="MiniGameRewardType.Experience"/> it's the amount of experience.
|
||||
/// In case of <see cref="MiniGameRewardType.Item"/> it's the amount of <see cref="ItemReward"/>.
|
||||
/// </summary>
|
||||
public int RewardAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required success flags for the reward.
|
||||
/// </summary>
|
||||
public MiniGameSuccessFlags RequiredSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="DropItemGroup"/> of this reward, if <see cref="RewardType"/> is <see cref="MiniGameRewardType.Item"/>.
|
||||
/// </summary>
|
||||
public virtual DropItemGroup? ItemReward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the monster/gate/status which needs to be killed during the event, so that this reward applies.
|
||||
/// </summary>
|
||||
public virtual MonsterDefinition? RequiredKill { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
if (this.Rank.HasValue)
|
||||
{
|
||||
result.Append("Rank ").Append(this.Rank.Value).Append(": ");
|
||||
}
|
||||
|
||||
if (this.RequiredSuccess > 0)
|
||||
{
|
||||
result.Append(this.RequiredSuccess).Append(": ");
|
||||
}
|
||||
|
||||
result.Append(this.RewardType.ToString()).Append(" ").Append(this.RewardAmount);
|
||||
|
||||
if (this.ItemReward != null)
|
||||
{
|
||||
result.Append(" ").Append(this.ItemReward.Description);
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
48
src/DataModel/Configuration/MiniGameRewardType.cs
Normal file
48
src/DataModel/Configuration/MiniGameRewardType.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
// <copyright file="MiniGameRewardType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of the <see cref="MiniGameReward"/>.
|
||||
/// </summary>
|
||||
public enum MiniGameRewardType
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined reward type.
|
||||
/// </summary>
|
||||
Undefined,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is money which is added to the character of the player.
|
||||
/// </summary>
|
||||
Money,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is experience which is added to the character of the player.
|
||||
/// </summary>
|
||||
Experience,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is experience which is added to the character of the player,
|
||||
/// which is calculated based on the remaining seconds.
|
||||
/// Reward Value = <see cref="MiniGameReward.RewardAmount"/> * Remaining Seconds.
|
||||
/// </summary>
|
||||
ExperiencePerRemainingSeconds,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is an item.
|
||||
/// </summary>
|
||||
Item,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is an item to be dropped.
|
||||
/// </summary>
|
||||
ItemDrop,
|
||||
|
||||
/// <summary>
|
||||
/// The reward is a score for the mini game.
|
||||
/// </summary>
|
||||
Score,
|
||||
}
|
||||
46
src/DataModel/Configuration/MiniGameSpawnWave.cs
Normal file
46
src/DataModel/Configuration/MiniGameSpawnWave.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="MiniGameSpawnWave.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a spawn wave of a <see cref="MiniGameDefinition"/>.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MiniGameSpawnWave
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the number of the wave, <seealso cref="MonsterSpawnArea.WaveNumber"/>.
|
||||
/// </summary>
|
||||
public byte WaveNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the description about this wave.
|
||||
/// </summary>
|
||||
public LocalizedString Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a message which is shown to the player when the wave starts.
|
||||
/// </summary>
|
||||
public LocalizedString Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the starting time of the wave.
|
||||
/// </summary>
|
||||
public TimeSpan StartTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end time of the wave.
|
||||
/// </summary>
|
||||
public TimeSpan EndTime { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Wave {this.WaveNumber}: {this.Description}";
|
||||
}
|
||||
}
|
||||
55
src/DataModel/Configuration/MiniGameTerrainChange.cs
Normal file
55
src/DataModel/Configuration/MiniGameTerrainChange.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// <copyright file="MiniGameTerrainChange.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a terrain change of the mini game map.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MiniGameTerrainChange
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of terrain attribute which should be added or removed to or from the terrain.
|
||||
/// </summary>
|
||||
public TerrainAttributeType TerrainAttribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to set or to remove the <see cref="TerrainAttribute"/> from the terrain.
|
||||
/// </summary>
|
||||
public bool SetTerrainAttribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether no client update is required.
|
||||
/// </summary>
|
||||
public bool IsClientUpdateRequired { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start value of the X-coordinate of the terrain area.
|
||||
/// </summary>
|
||||
public byte StartX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start value of the Y-coordinate of the terrain area.
|
||||
/// </summary>
|
||||
public byte StartY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end value of the X-coordinate of the terrain area.
|
||||
/// </summary>
|
||||
public byte EndX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the end value of the Y-coordinate of the terrain area.
|
||||
/// </summary>
|
||||
public byte EndY { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{(this.SetTerrainAttribute ? "Set" : "Remove")} Attribute '{this.TerrainAttribute}' from ({this.StartX}, {this.StartY}) to ({this.EndX}, {this.EndY}) {(this.IsClientUpdateRequired ? "with" : "without")} client update";
|
||||
}
|
||||
}
|
||||
41
src/DataModel/Configuration/MiniGameType.cs
Normal file
41
src/DataModel/Configuration/MiniGameType.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// <copyright file="MiniGameType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of a mini game.
|
||||
/// </summary>
|
||||
public enum MiniGameType
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined mini game type.
|
||||
/// </summary>
|
||||
Undefined,
|
||||
|
||||
/// <summary>
|
||||
/// The devil square event.
|
||||
/// </summary>
|
||||
DevilSquare,
|
||||
|
||||
/// <summary>
|
||||
/// The blood castle event.
|
||||
/// </summary>
|
||||
BloodCastle,
|
||||
|
||||
/// <summary>
|
||||
/// The chaos castle event.
|
||||
/// </summary>
|
||||
ChaosCastle,
|
||||
|
||||
/// <summary>
|
||||
/// The illusion temple event.
|
||||
/// </summary>
|
||||
IllusionTemple,
|
||||
|
||||
/// <summary>
|
||||
/// The doppelganger event.
|
||||
/// </summary>
|
||||
Doppelganger,
|
||||
}
|
||||
34
src/DataModel/Configuration/MonsterAttribute.cs
Normal file
34
src/DataModel/Configuration/MonsterAttribute.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
// <copyright file="MonsterAttribute.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The attribute and value of a monster.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Just needed for entity framework, because it does not support the mapping of dictionaries. May be removed in the future.
|
||||
/// </remarks>
|
||||
[Cloneable]
|
||||
public partial class MonsterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute definition.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? AttributeDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
public float Value { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.AttributeDefinition}: {this.Value}";
|
||||
}
|
||||
}
|
||||
349
src/DataModel/Configuration/MonsterDefinition.cs
Normal file
349
src/DataModel/Configuration/MonsterDefinition.cs
Normal file
@@ -0,0 +1,349 @@
|
||||
// <copyright file="MonsterDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Type of the window which will be openend when talking to the npc.
|
||||
/// TODO: Maybe change to a class and do it data-driven.
|
||||
/// </summary>
|
||||
public enum NpcWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// No window defined.
|
||||
/// </summary>
|
||||
Undefined,
|
||||
|
||||
/// <summary>
|
||||
/// A merchant window.
|
||||
/// </summary>
|
||||
Merchant,
|
||||
|
||||
/// <summary>
|
||||
/// Another merchant window.
|
||||
/// </summary>
|
||||
Merchant1,
|
||||
|
||||
/// <summary>
|
||||
/// A storage window.
|
||||
/// </summary>
|
||||
Storage,
|
||||
|
||||
/// <summary>
|
||||
/// A vault storage.
|
||||
/// </summary>
|
||||
VaultStorage,
|
||||
|
||||
/// <summary>
|
||||
/// A chaos machine window.
|
||||
/// </summary>
|
||||
ChaosMachine,
|
||||
|
||||
/// <summary>
|
||||
/// A devil square window.
|
||||
/// </summary>
|
||||
DevilSquare,
|
||||
|
||||
/// <summary>
|
||||
/// A blood castle window.
|
||||
/// </summary>
|
||||
BloodCastle,
|
||||
|
||||
/// <summary>
|
||||
/// The pet trainer window.
|
||||
/// </summary>
|
||||
PetTrainer,
|
||||
|
||||
/// <summary>
|
||||
/// The lahap window.
|
||||
/// </summary>
|
||||
Lahap,
|
||||
|
||||
/// <summary>
|
||||
/// The castle senior window.
|
||||
/// </summary>
|
||||
CastleSeniorNPC,
|
||||
|
||||
/// <summary>
|
||||
/// The elphis refinery window.
|
||||
/// </summary>
|
||||
ElphisRefinery,
|
||||
|
||||
/// <summary>
|
||||
/// The refine stone making window.
|
||||
/// </summary>
|
||||
RefineStoneMaking,
|
||||
|
||||
/// <summary>
|
||||
/// The jewel of harmony option removal window.
|
||||
/// </summary>
|
||||
RemoveJohOption,
|
||||
|
||||
/// <summary>
|
||||
/// The illusion temple window.
|
||||
/// </summary>
|
||||
IllusionTemple,
|
||||
|
||||
/// <summary>
|
||||
/// The chaos card combination window.
|
||||
/// </summary>
|
||||
ChaosCardCombination,
|
||||
|
||||
/// <summary>
|
||||
/// The cherry blossom branches assembly window.
|
||||
/// </summary>
|
||||
CherryBlossomBranchesAssembly,
|
||||
|
||||
/// <summary>
|
||||
/// The seed master window.
|
||||
/// </summary>
|
||||
SeedMaster,
|
||||
|
||||
/// <summary>
|
||||
/// The seed researcher window.
|
||||
/// </summary>
|
||||
SeedResearcher,
|
||||
|
||||
/// <summary>
|
||||
/// The stat reinitializer window.
|
||||
/// </summary>
|
||||
StatReInitializer,
|
||||
|
||||
/// <summary>
|
||||
/// The delgado lucky coin registration window.
|
||||
/// </summary>
|
||||
DelgadoLuckyCoinRegistration,
|
||||
|
||||
/// <summary>
|
||||
/// The doorkeeper titus duel watch window.
|
||||
/// </summary>
|
||||
DoorkeeperTitusDuelWatch,
|
||||
|
||||
/// <summary>
|
||||
/// The lugard doppelganger entry window.
|
||||
/// </summary>
|
||||
LugardDoppelgangerEntry,
|
||||
|
||||
/// <summary>
|
||||
/// The jerint gaion event entry window.
|
||||
/// </summary>
|
||||
JerintGaionEvententry,
|
||||
|
||||
/// <summary>
|
||||
/// The julia warp market server window.
|
||||
/// </summary>
|
||||
JuliaWarpMarketServer,
|
||||
|
||||
/// <summary>
|
||||
/// The guild master window.
|
||||
/// </summary>
|
||||
GuildMaster,
|
||||
|
||||
/// <summary>
|
||||
/// The dialog window which allows to exchange or refine Lucky Item.
|
||||
/// Used by NPC "David".
|
||||
/// </summary>
|
||||
CombineLuckyItem,
|
||||
|
||||
/// <summary>
|
||||
/// The specific npc dialog. The client knows which dialog should be shown.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Npc Numbers: 257, 543, 544, 566, 567, 568, 581.
|
||||
/// Warning: If the game client doesn't have a dialog for this npc, it will crash.
|
||||
/// </remarks>
|
||||
NpcDialog,
|
||||
|
||||
/// <summary>
|
||||
/// The dialog for the legacy quest system.
|
||||
/// </summary>
|
||||
LegacyQuest,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of a non-player-character object.
|
||||
/// </summary>
|
||||
public enum NpcObjectKind
|
||||
{
|
||||
/// <summary>
|
||||
/// The npc is a monster.
|
||||
/// </summary>
|
||||
Monster,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is passive, e.g. a merchant.
|
||||
/// </summary>
|
||||
PassiveNpc,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a guard.
|
||||
/// </summary>
|
||||
Guard,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a trap.
|
||||
/// </summary>
|
||||
Trap,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a gate.
|
||||
/// </summary>
|
||||
Gate,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a statue.
|
||||
/// </summary>
|
||||
Statue,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a soccer ball.
|
||||
/// </summary>
|
||||
SoccerBall,
|
||||
|
||||
/// <summary>
|
||||
/// The npc is a destructible.
|
||||
/// </summary>
|
||||
Destructible,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A definition for a monster (or NPC in general).
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MonsterDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique number of this monster.
|
||||
/// </summary>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the designation of this monster.
|
||||
/// Not relevant for the server, however helpful for debugging/logging.
|
||||
/// </summary>
|
||||
public LocalizedString Designation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the range in which a monster will move randomly?
|
||||
/// It is not used yet. TODO: Find out what it's really good for. Remove, if not needed.
|
||||
/// </summary>
|
||||
public byte MoveRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attack range in which the monster can attack without moving closer to the target.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The attack range.
|
||||
/// </value>
|
||||
public byte AttackRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the view range in which the monster can recognize its targets.
|
||||
/// </summary>
|
||||
public short ViewRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the move delay for each step.
|
||||
/// </summary>
|
||||
public TimeSpan MoveDelay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attack delay, which is the time between attacks.
|
||||
/// </summary>
|
||||
public TimeSpan AttackDelay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the delay which is waited until a died instance respawns.
|
||||
/// </summary>
|
||||
public TimeSpan RespawnDelay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute.
|
||||
/// Not sure what this is.
|
||||
/// Maybe the maximum numbers of concurrent additional attributes / magic effects?
|
||||
/// TODO.
|
||||
/// </summary>
|
||||
public byte Attribute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of maximum item drops after an instance of this monster died.
|
||||
/// </summary>
|
||||
public int NumberOfMaximumItemDrops { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id of the npc window.
|
||||
/// </summary>
|
||||
public NpcWindow NpcWindow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the kind of the object.
|
||||
/// </summary>
|
||||
public NpcObjectKind ObjectKind { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the intelligence type, if this npc/monster uses a specific implementation of an INpcIntelligence.
|
||||
/// </summary>
|
||||
public string? IntelligenceTypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the skill with which this monster is attacking. Also known as "Attack type".
|
||||
/// </summary>
|
||||
/// <remarks>The additional damage of the skill is usually NOT applied; However, magic effects are.</remarks>
|
||||
public virtual Skill? AttackSkill { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the items of the merchant store. Is only relevant for merchant NPCs.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ItemStorage? MerchantStore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item craftings. Is only relevant for crafting NPCs (chaos goblin etc.).
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemCrafting.ItemCrafting> ItemCraftings { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drop item groups.
|
||||
/// Some monsters drop special items. Examples: Kundun has the chance to drop ancient items.
|
||||
/// </summary>
|
||||
public virtual ICollection<DropItemGroup> DropItemGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attributes of this monster.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<MonsterAttribute> Attributes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the quests which can be started through this npc.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<QuestDefinition> Quests { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Attribute default accessor.
|
||||
/// </summary>
|
||||
/// <param name="key">The attribute.</param>
|
||||
/// <returns>The value of the attribute.</returns>
|
||||
public float this[AttributeDefinition key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Attributes.First(a => a.AttributeDefinition == key).Value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Designation} ({this.Number})";
|
||||
}
|
||||
}
|
||||
154
src/DataModel/Configuration/MonsterSpawnArea.cs
Normal file
154
src/DataModel/Configuration/MonsterSpawnArea.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
// <copyright file="MonsterSpawnArea.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Validation;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the trigger when a monster spawns.
|
||||
/// </summary>
|
||||
public enum SpawnTrigger
|
||||
{
|
||||
/// <summary>
|
||||
/// The monster spawns and respawns automatically.
|
||||
/// </summary>
|
||||
Automatic,
|
||||
|
||||
/// <summary>
|
||||
/// The monster spawns automatically during an event.
|
||||
/// </summary>
|
||||
AutomaticDuringEvent,
|
||||
|
||||
/// <summary>
|
||||
/// The monster spawns just once at the beginning of an event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example blood castle gates, statues. Also golden monsters.
|
||||
/// </remarks>
|
||||
OnceAtEventStart,
|
||||
|
||||
/// <summary>
|
||||
/// The monster spawns automatically during a wave of an event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, at devil square different monsters spawn in different waves.
|
||||
/// </remarks>
|
||||
AutomaticDuringWave,
|
||||
|
||||
/// <summary>
|
||||
/// The monster spawns once at the start of a wave of an event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, at devil square there is a wave of bosses, which spawn only once.
|
||||
/// </remarks>
|
||||
OnceAtWaveStart,
|
||||
|
||||
/// <summary>
|
||||
/// The monster spawns manually controlled by the code of an event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example chaos castle enemies, because their number is not known beforehand.
|
||||
/// </remarks>
|
||||
ManuallyForEvent,
|
||||
|
||||
/// <summary>
|
||||
/// The object is wandering between maps. It spawns just at one spawn area
|
||||
/// at the same time.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used for wandering merchants.
|
||||
/// </remarks>
|
||||
Wandering,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a monster spawn area.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class MonsterSpawnArea : IMapArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the monster definition.
|
||||
/// </summary>
|
||||
public virtual MonsterDefinition? MonsterDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the game map.
|
||||
/// </summary>
|
||||
public virtual GameMapDefinition? GameMap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner x coordinate.
|
||||
/// </summary>
|
||||
[LessThanOrEqualTo(nameof(X2))]
|
||||
public byte X1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner y coordinate.
|
||||
/// </summary>
|
||||
[LessThanOrEqualTo(nameof(Y2))]
|
||||
public byte Y1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner x coordinate.
|
||||
/// </summary>
|
||||
public byte X2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner y coordinate.
|
||||
/// </summary>
|
||||
public byte Y2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the looking direction when spawning.
|
||||
/// </summary>
|
||||
public Direction Direction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the quantity of monsters which should spawn in the defined area.
|
||||
/// </summary>
|
||||
public short Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the spawn trigger.
|
||||
/// </summary>
|
||||
public SpawnTrigger SpawnTrigger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the wave to which this spawn area belongs to.
|
||||
/// </summary>
|
||||
public byte WaveNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum health (override) just for this spawn area.
|
||||
/// If <c>null</c>, the default health of the <see cref="MonsterDefinition"/> applies.
|
||||
/// </summary>
|
||||
public int? MaximumHealthOverride { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
var isPoint = this.IsPoint();
|
||||
var result = isPoint
|
||||
? $"{this.MonsterDefinition?.Designation} - Qty: {this.Quantity} @ {this.X1}/{this.Y1}"
|
||||
: $"{this.MonsterDefinition?.Designation} - Qty: {this.Quantity} @ {this.X1}/{this.Y1} to {this.X2}/{this.Y2}";
|
||||
|
||||
if (this.SpawnTrigger == SpawnTrigger.AutomaticDuringWave || this.SpawnTrigger == SpawnTrigger.OnceAtWaveStart)
|
||||
{
|
||||
result += $" - Wave: {this.WaveNumber}";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance is a spawn point.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this instance is point; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsPoint() => this.X1 == this.X2 && this.Y1 == this.Y2;
|
||||
}
|
||||
107
src/DataModel/Configuration/Quests/QuestDefinition.cs
Normal file
107
src/DataModel/Configuration/Quests/QuestDefinition.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
// <copyright file="QuestDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// The definition of a quest.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class QuestDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the NPC which gives the quest.
|
||||
/// </summary>
|
||||
public virtual MonsterDefinition? QuestGiver { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the quest.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the group identifier of the quest.
|
||||
/// </summary>
|
||||
public short Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of the quest which should be unique within the group.
|
||||
/// </summary>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the starting number of the quest which should be unique within the group. It's used as an identifier before a quest is started.
|
||||
/// It's an identifier which is required on the client side to show the correct starting text.
|
||||
/// </summary>
|
||||
public short StartingNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the refuse number of the quest which should be unique within the group. It's used as an identifier after a quest has been refused by the player.
|
||||
/// It's an identifier which is required on the client side to show the correct follow-up text.
|
||||
/// </summary>
|
||||
public short RefuseNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="QuestDefinition"/> is repeatable
|
||||
/// which means if the character can start this quest multiple times even after it already
|
||||
/// completed it once.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if repeatable; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool Repeatable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this quest requires a client action.
|
||||
/// </summary>
|
||||
public bool RequiresClientAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this quest requires a certain amount of money in the characters
|
||||
/// inventory before it can be started.
|
||||
/// </summary>
|
||||
public int RequiredStartMoney { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum character level.
|
||||
/// </summary>
|
||||
public int MinimumCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum character level.
|
||||
/// </summary>
|
||||
public int MaximumCharacterLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the qualified character class. If <c>null</c>, it's valid for all character classes.
|
||||
/// </summary>
|
||||
public virtual CharacterClass? QualifiedCharacter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required monster kills to be able to complete this quest.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<QuestMonsterKillRequirement> RequiredMonsterKills { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the required items which should be in the characters inventory when the
|
||||
/// player requests to complete the quest.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<QuestItemRequirement> RequiredItems { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rewards when completing the quest successfully.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<QuestReward> Rewards { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? ToString()
|
||||
{
|
||||
return this.Name.ToString();
|
||||
}
|
||||
}
|
||||
38
src/DataModel/Configuration/Quests/QuestItemRequirement.cs
Normal file
38
src/DataModel/Configuration/Quests/QuestItemRequirement.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
// <copyright file="QuestItemRequirement.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the required item(s) which should be in the inventory of the character
|
||||
/// when the player requests to complete the quest.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class QuestItemRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the required item.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual ItemDefinition? Item { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drop item group which should be considered when this quest is active and this requirement applies.
|
||||
/// </summary>
|
||||
public virtual DropItemGroup? DropItemGroup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum number of <see cref="Item"/>s.
|
||||
/// </summary>
|
||||
public int MinimumNumber { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.MinimumNumber} x {this.Item?.Name}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// <copyright file="QuestMonsterKillRequirement.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// The monster kill requirement of a <see cref="QuestDefinition"/>.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class QuestMonsterKillRequirement
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the monster which must be killed.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual MonsterDefinition? Monster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minimum number of killed <see cref="Monster"/>s.
|
||||
/// </summary>
|
||||
public int MinimumNumber { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.MinimumNumber}x {this.Monster}";
|
||||
}
|
||||
}
|
||||
72
src/DataModel/Configuration/Quests/QuestReward.cs
Normal file
72
src/DataModel/Configuration/Quests/QuestReward.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
// <copyright file="QuestReward.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the reward of a completed quest.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class QuestReward
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the reward.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The type of the reward.
|
||||
/// </value>
|
||||
public QuestRewardType RewardType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value of the reward. It may have a different meaning, depending on the <see cref="RewardType"/>.
|
||||
/// </summary>
|
||||
public int Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item reward.
|
||||
/// The <see cref="Value"/> contains how often the item is rewarded.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual Item? ItemReward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute reward. It's set when <see cref="RewardType"/> is <see cref="QuestRewardType.Attribute"/>.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? AttributeReward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute reward. It's set when <see cref="RewardType"/> is <see cref="QuestRewardType.Skill"/>.
|
||||
/// </summary>
|
||||
public virtual Skill? SkillReward { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.RewardType == QuestRewardType.Item)
|
||||
{
|
||||
return $"{this.Value} x {this.ItemReward}";
|
||||
}
|
||||
|
||||
if (this.RewardType == QuestRewardType.Skill)
|
||||
{
|
||||
return $"Skill: {this.SkillReward?.Name}";
|
||||
}
|
||||
|
||||
if (this.RewardType == QuestRewardType.Attribute)
|
||||
{
|
||||
return $"Attribute: {this.Value} x {this.AttributeReward}";
|
||||
}
|
||||
|
||||
if (this.RewardType is QuestRewardType.Experience or QuestRewardType.Money or QuestRewardType.LevelUpPoints or QuestRewardType.GensAttribution)
|
||||
{
|
||||
return $"{this.Value} x {this.RewardType}";
|
||||
}
|
||||
|
||||
return $"{this.RewardType}";
|
||||
}
|
||||
}
|
||||
67
src/DataModel/Configuration/Quests/QuestRewardType.cs
Normal file
67
src/DataModel/Configuration/Quests/QuestRewardType.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
// <copyright file="QuestRewardType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the type of the reward of a quest.
|
||||
/// </summary>
|
||||
public enum QuestRewardType
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined quest reward. Rewards nothing.
|
||||
/// </summary>
|
||||
Undefined,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards additional <see cref="Character.Experience"/>.
|
||||
/// </summary>
|
||||
Experience,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards additional money to the characters inventory.
|
||||
/// </summary>
|
||||
Money,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards an item one or more times.
|
||||
/// </summary>
|
||||
Item,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards gens attribution points.
|
||||
/// </summary>
|
||||
GensAttribution,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards additional <see cref="Character.LevelUpPoints"/>.
|
||||
/// </summary>
|
||||
LevelUpPoints,
|
||||
|
||||
/// <summary>
|
||||
/// When completing the quest, the <see cref="Character.CharacterClass"/> evolves from the first to the second generation.
|
||||
/// </summary>
|
||||
CharacterEvolutionFirstToSecond,
|
||||
|
||||
/// <summary>
|
||||
/// When completing the quest, the <see cref="Character.CharacterClass"/> evolves from the second to the third generation (master classes).
|
||||
/// </summary>
|
||||
CharacterEvolutionSecondToThird,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards an additional attribute with the specified value.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, it could mean to add an attribute "Completed Marlon Quest" or "Combo Skill Available" which could
|
||||
/// further be a requirement for skills etc. With the the definition of an attribute, we have maximum flexibility.
|
||||
/// </remarks>
|
||||
Attribute,
|
||||
|
||||
/// <summary>
|
||||
/// The completed quest rewards an additional skill, if not yet learned.
|
||||
/// </summary>
|
||||
Skill,
|
||||
}
|
||||
45
src/DataModel/Configuration/Rectangle.cs
Normal file
45
src/DataModel/Configuration/Rectangle.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
// <copyright file="Rectangle.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a rectangle.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class Rectangle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner, x-coordinate.
|
||||
/// </summary>
|
||||
public byte X1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the upper left corner, y-coordinate.
|
||||
/// </summary>
|
||||
public byte Y1 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner, x-coordinate.
|
||||
/// </summary>
|
||||
public byte X2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom right corner, y-coordinate.
|
||||
/// </summary>
|
||||
public byte Y2 { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.X1 == this.X2 && this.Y1 == this.Y2)
|
||||
{
|
||||
return $"{this.X1} / {this.Y1}";
|
||||
}
|
||||
|
||||
return $"{this.X1} / {this.Y1} to {this.X2} / {this.Y2}";
|
||||
}
|
||||
}
|
||||
43
src/DataModel/Configuration/ServerEndpoint.cs
Normal file
43
src/DataModel/Configuration/ServerEndpoint.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// <copyright file="ServerEndpoint.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an endpoint of a server.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ServerEndpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerEndpoint"/> class.
|
||||
/// </summary>
|
||||
protected ServerEndpoint()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the network port on which the server is listening.
|
||||
/// </summary>
|
||||
public int NetworkPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client which is expected to connect.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameClientDefinition? Client { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Client: {this.Client?.Description}; Port: {this.NetworkPort}";
|
||||
}
|
||||
}
|
||||
332
src/DataModel/Configuration/Skill.cs
Normal file
332
src/DataModel/Configuration/Skill.cs
Normal file
@@ -0,0 +1,332 @@
|
||||
// <copyright file="Skill.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the damage type of a skill.
|
||||
/// </summary>
|
||||
public enum DamageType
|
||||
{
|
||||
/// <summary>
|
||||
/// No damage type.
|
||||
/// </summary>
|
||||
None = -1,
|
||||
|
||||
/// <summary>
|
||||
/// The physical damage type.
|
||||
/// </summary>
|
||||
Physical = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The wizardry damage type.
|
||||
/// </summary>
|
||||
Wizardry = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The curse damage type.
|
||||
/// </summary>
|
||||
Curse = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The summoned monster damage type.
|
||||
/// </summary>
|
||||
SummonedMonster = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The damage of the fenrir pet.
|
||||
/// </summary>
|
||||
Fenrir = 4,
|
||||
|
||||
/// <summary>
|
||||
/// All damage types.
|
||||
/// </summary>
|
||||
All = 5,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The skill types.
|
||||
/// </summary>
|
||||
public enum SkillType
|
||||
{
|
||||
/// <summary>
|
||||
/// The skill hits its target directly.
|
||||
/// </summary>
|
||||
DirectHit = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The castle siege special skill.
|
||||
/// </summary>
|
||||
CastleSiegeSpecial = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Same as <see cref="DirectHit"/> but only appliable during castle siege event.
|
||||
/// </summary>
|
||||
CastleSiegeSkill = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Area skill damage, which automatically hit all targets in its target area. No declaration of hits by the client.
|
||||
/// </summary>
|
||||
AreaSkillAutomaticHits = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Area skill damage, but the hits have to be declared by the client.
|
||||
/// </summary>
|
||||
AreaSkillExplicitHits = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Area skill, which only hits the explicit target. No declaration of hits by the client.
|
||||
/// </summary>
|
||||
AreaSkillExplicitTarget = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The buff skill type. Applies magic effects on players.
|
||||
/// </summary>
|
||||
Buff = 10,
|
||||
|
||||
/// <summary>
|
||||
/// The regeneration skill type. Regenerates the target attribute of the defined effect.
|
||||
/// </summary>
|
||||
Regeneration = 11,
|
||||
|
||||
/// <summary>
|
||||
/// The passive boost skill type. Applies boosts to the player who has learned this skill, without the need to be casted.
|
||||
/// </summary>
|
||||
PassiveBoost = 20,
|
||||
|
||||
/// <summary>
|
||||
/// The skill type for monster summoning.
|
||||
/// </summary>
|
||||
SummonMonster = 30,
|
||||
|
||||
/// <summary>
|
||||
/// Other skill type.
|
||||
/// </summary>
|
||||
Other = 40,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines how the target(s) of a skill are determined.
|
||||
/// </summary>
|
||||
public enum SkillTarget
|
||||
{
|
||||
/// <summary>
|
||||
/// The target selection is undefined.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The skill target is stated explicitly.
|
||||
/// </summary>
|
||||
Explicit = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The targets are implicitly all party member which are in view range of the attacker.
|
||||
/// </summary>
|
||||
ImplicitParty = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The targets are implicitly all players which are in <see cref="Skill.ImplicitTargetRange"/> of the attacker.
|
||||
/// </summary>
|
||||
ImplicitPlayersInRange = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The targets are implicitly all non-player-characters in <see cref="Skill.ImplicitTargetRange"/> of the attacker.
|
||||
/// </summary>
|
||||
ImplicitNpcsInRange = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The targets are implicitly all objects in <see cref="Skill.ImplicitTargetRange"/> of the attacker.
|
||||
/// </summary>
|
||||
ImplicitAllInRange = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The primary target is stated explicitly, additional targets are all objects in the <see cref="Skill.ImplicitTargetRange"/> of the primary target.
|
||||
/// </summary>
|
||||
ExplicitWithImplicitInRange = 6,
|
||||
|
||||
/// <summary>
|
||||
/// The skill target is only the own player implicitly.
|
||||
/// </summary>
|
||||
ImplicitPlayer = 7,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines how a skill is restricted to specific targets.
|
||||
/// </summary>
|
||||
public enum SkillTargetRestriction
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined restriction. Skill can be applied to all possible entities (players, NPCs, etc.).
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The skill can only be applied to the executor.
|
||||
/// </summary>
|
||||
Self = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The skill can only be applied to the executor or its party members.
|
||||
/// </summary>
|
||||
Party = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The skill can only be applied to players (and summoned monsters of a player).
|
||||
/// </summary>
|
||||
Player = 3,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines a skill.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class Skill
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the skill number.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The client is referencing skills by this number.
|
||||
/// </remarks>
|
||||
public short Number { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attack damage. Only relevant for attack skills.
|
||||
/// </summary>
|
||||
public int AttackDamage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the requirements to execute the skill.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRequirement> Requirements { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attributes which values will be consumed by executing this skill.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRequirement> ConsumeRequirements { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute relationships which are applied during damage calculations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, horse skill:
|
||||
/// * new AttributeRelationship(Stats.SkillBaseDamageBonus, 1.0f / 10, Stats.TotalStrength)
|
||||
/// * new AttributeRelationship(Stats.SkillBaseDamageBonus, 1.0f / 5, Stats.TotalLeadership)
|
||||
/// * new AttributeRelationship(Stats.SkillBaseDamageBonus, 10, Stats.HorseLevel).
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<AttributeRelationship> AttributeRelationships { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum range between executor of the skill and the target object.
|
||||
/// </summary>
|
||||
public short Range { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the damage.
|
||||
/// </summary>
|
||||
public DamageType DamageType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the skill.
|
||||
/// </summary>
|
||||
public SkillType SkillType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="SkillTarget"/> which defines how the target(s) of a skill are determined.
|
||||
/// </summary>
|
||||
public SkillTarget Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the range for automatic targeting of additional target.
|
||||
/// Has only effect if greater than <c>0</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Possible use cases: Additional hits for the "Fireburst" or "Deathstab" skills. They use direct targeting, but also hit nearby enemies.
|
||||
/// </remarks>
|
||||
public short ImplicitTargetRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the target restriction.
|
||||
/// </summary>
|
||||
public SkillTargetRestriction TargetRestriction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the skill moves the attacker to the target.
|
||||
/// </summary>
|
||||
/// <remarks>Used by dark knight weapon skills, e.g. Slash.</remarks>
|
||||
public bool MovesToTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the skill moves the target.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used by dark knight weapon physical attack skills, e.g. Slash. The target gets pushed around randomly.
|
||||
/// This is not a use case for the lightning skill, since resistances play a role there.
|
||||
/// </remarks>
|
||||
public bool MovesTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the elemental modifier target attribute.
|
||||
/// If this is set, hitting the target (successfully or not) may apply additional effects.
|
||||
/// A value of <c>255</c> means, the target is immune to effects of this element.
|
||||
/// </summary>
|
||||
public virtual AttributeDefinition? ElementalModifierTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the elemental modifier resistance should be ignored, which means the skill uses a specific logic.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not all skills have magic effects corresponding to their element,
|
||||
/// e.g. Pollution (book of lagle, lightning) has a 100% chance iceing effect.
|
||||
/// Other skills have magic effects which may or may not be related to their element, but which apply regardless of resistance,
|
||||
/// e.g. Explosion (book of samut, fire) and Requiem (book of neil, wind) have 100% bleeding effects.
|
||||
/// </remarks>
|
||||
public bool SkipElementalModifier { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the magic effect definition. It will be applied for buff skills.
|
||||
/// </summary>
|
||||
public virtual MagicEffectDefinition? MagicEffectDef { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character classes which are qualified to learn and use this skill.
|
||||
/// </summary>
|
||||
public virtual ICollection<CharacterClass> QualifiedCharacters { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master skill definition. Only relevant for master skills.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual MasterSkillDefinition? MasterDefinition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the area skill settings.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual AreaSkillSettings? AreaSkillSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of hits per attack.
|
||||
/// </summary>
|
||||
public short NumberOfHitsPerAttack { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? ToString()
|
||||
{
|
||||
return this.Name.ToString();
|
||||
}
|
||||
}
|
||||
36
src/DataModel/Configuration/SkillComboDefinition.cs
Normal file
36
src/DataModel/Configuration/SkillComboDefinition.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
// <copyright file="SkillComboDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Definition for a skill combo sequence.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class SkillComboDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the combo sequence.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum time until the final step has to be done.
|
||||
/// </summary>
|
||||
public TimeSpan MaximumCompletionTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the steps of the combo sequence.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<SkillComboStep> Steps { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? ToString()
|
||||
{
|
||||
return this.Name.ToString();
|
||||
}
|
||||
}
|
||||
36
src/DataModel/Configuration/SkillComboStep.cs
Normal file
36
src/DataModel/Configuration/SkillComboStep.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
// <copyright file="SkillComboStep.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Definition for one step for one skill of a combo sequence.
|
||||
/// There can be multiple steps with the same <see cref="Order"/> but different skills.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class SkillComboStep
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the order for the step in the sequence.
|
||||
/// </summary>
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this step is a final step which ends the combo.
|
||||
/// </summary>
|
||||
public bool IsFinalStep { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the skill of this step.
|
||||
/// </summary>
|
||||
public virtual Skill? Skill { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Order} - {this.Skill}";
|
||||
}
|
||||
}
|
||||
64
src/DataModel/Configuration/StatAttributeDefinition.cs
Normal file
64
src/DataModel/Configuration/StatAttributeDefinition.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
// <copyright file="StatAttributeDefinition.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a stat attribute, which may be increasable by the player.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class StatAttributeDefinition
|
||||
{
|
||||
private AttributeDefinition? attribute = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StatAttributeDefinition"/> class.
|
||||
/// </summary>
|
||||
public StatAttributeDefinition()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StatAttributeDefinition" /> class.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The attribute.</param>
|
||||
/// <param name="baseValue">The base value.</param>
|
||||
/// <param name="increasableByPlayer">if set to <c>true</c> it is increasable by the player.</param>
|
||||
public StatAttributeDefinition(AttributeDefinition attribute, float baseValue, bool increasableByPlayer)
|
||||
{
|
||||
this.attribute = attribute;
|
||||
this.BaseValue = baseValue;
|
||||
this.IncreasableByPlayer = increasableByPlayer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attribute definition of this stat attribute.
|
||||
/// </summary>
|
||||
#pragma warning disable S2292 // When this would be an auto property, it would lead to a virtual member call in the constructor.
|
||||
public virtual AttributeDefinition? Attribute
|
||||
#pragma warning restore S2292
|
||||
{
|
||||
get { return this.attribute; }
|
||||
set { this.attribute = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base value, which is the initial value without an increase of the player.
|
||||
/// </summary>
|
||||
public float BaseValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this stat is increasable by the player in any way.
|
||||
/// </summary>
|
||||
public bool IncreasableByPlayer { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Attribute}: {this.BaseValue}";
|
||||
}
|
||||
}
|
||||
84
src/DataModel/Configuration/SystemConfiguration.cs
Normal file
84
src/DataModel/Configuration/SystemConfiguration.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
// <copyright file="SystemConfiguration.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Properties;
|
||||
using MUnique.OpenMU.Network;
|
||||
|
||||
/// <summary>
|
||||
/// System-wide configuration values.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
[Cloneable]
|
||||
[Display(ResourceType = typeof(Resources), Name = nameof(Resources.SystemConfiguration_Name), Description = nameof(Resources.SystemConfiguration_Description))]
|
||||
public partial class SystemConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the ip resolver.
|
||||
/// </summary>
|
||||
[Display(
|
||||
Order = 1,
|
||||
Name = nameof(Resources.SystemConfiguration_IpResolver_Name),
|
||||
Description = nameof(Resources.SystemConfiguration_IpResolver_Description),
|
||||
GroupName = nameof(Resources.SystemConfiguration_IpResolver_Name),
|
||||
ResourceType = typeof(Resources))]
|
||||
public IpResolverType IpResolver { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ip resolver parameter, when <see cref="IpResolverType.Custom"/>
|
||||
/// is used.
|
||||
/// </summary>
|
||||
[Display(
|
||||
Order = 2,
|
||||
Name = nameof(Resources.SystemConfiguration_IpResolverParameter_Name),
|
||||
Description = nameof(Resources.SystemConfiguration_IpResolverParameter_Description),
|
||||
GroupName = nameof(Resources.SystemConfiguration_IpResolver_Name),
|
||||
ResourceType = typeof(Resources))]
|
||||
public string? IpResolverParameter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to automatically start
|
||||
/// the listeners of the servers when the server process starts.
|
||||
/// Only applicable to the All-In-One Startup. The distributed processes
|
||||
/// always start their listeners automatically.
|
||||
/// </summary>
|
||||
[Display(
|
||||
Order = 3,
|
||||
Name = nameof(Resources.SystemConfiguration_AutoStart_Name),
|
||||
Description = nameof(Resources.SystemConfiguration_AutoStart_Description),
|
||||
ResourceType = typeof(Resources))]
|
||||
public bool AutoStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to automatically update the
|
||||
/// database schema when the server process starts.
|
||||
/// Only applicable to the All-In-One Startup. In a distributed deployment,
|
||||
/// the user must start the update manually over the admin panel.
|
||||
/// </summary>
|
||||
[Display(
|
||||
Order = 4,
|
||||
Name = nameof(Resources.SystemConfiguration_AutoUpdateSchema_Name),
|
||||
Description = nameof(Resources.SystemConfiguration_AutoUpdateSchema_Description),
|
||||
ResourceType = typeof(Resources))]
|
||||
public bool AutoUpdateSchema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the user can enter commands in
|
||||
/// the console of the All-In-One Startup process.
|
||||
/// </summary>
|
||||
[Display(
|
||||
Order = 5,
|
||||
Name = nameof(Resources.SystemConfiguration_ReadConsoleInput_Name),
|
||||
Description = nameof(Resources.SystemConfiguration_ReadConsoleInput_Description),
|
||||
ResourceType = typeof(Resources))]
|
||||
public bool ReadConsoleInput { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return "System Configuration";
|
||||
}
|
||||
}
|
||||
36
src/DataModel/Configuration/TerrainAttributeType.cs
Normal file
36
src/DataModel/Configuration/TerrainAttributeType.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
// <copyright file="TerrainAttributeType.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the attribute which should be set/unset.
|
||||
/// </summary>
|
||||
public enum TerrainAttributeType
|
||||
{
|
||||
/// <summary>
|
||||
/// The coordinate is a safezone.
|
||||
/// </summary>
|
||||
Safezone = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The coordinate is occupied by a character.
|
||||
/// </summary>
|
||||
Character = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The coordinate is blocked and can’t be passed by a character.
|
||||
/// </summary>
|
||||
Blocked = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The coordinate is blocked, because there is no ground and can’t be passed by a character.
|
||||
/// </summary>
|
||||
NoGround = 8,
|
||||
|
||||
/// <summary>
|
||||
/// The coordinate is blocked by water and can’t be passed by a character.
|
||||
/// </summary>
|
||||
Water = 16,
|
||||
}
|
||||
46
src/DataModel/Configuration/WarpInfo.cs
Normal file
46
src/DataModel/Configuration/WarpInfo.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="WarpInfo.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// Defines a warp list entry.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class WarpInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the index.
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public LocalizedString Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the warp costs.
|
||||
/// </summary>
|
||||
public int Costs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level requirement which a character needs to fulfill so that it can warp to the <see cref="Gate"/>.
|
||||
/// </summary>
|
||||
public int LevelRequirement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the gate.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual ExitGate? Gate { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string? ToString()
|
||||
{
|
||||
return this.Name.ToString();
|
||||
}
|
||||
}
|
||||
57
src/DataModel/CultureHelper.cs
Normal file
57
src/DataModel/CultureHelper.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// <copyright file="CultureHelper.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel;
|
||||
|
||||
using System.Globalization;
|
||||
using System.Resources;
|
||||
using Nito.Disposables;
|
||||
using Nito.Disposables.Internals;
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for culture related operations.
|
||||
/// </summary>
|
||||
public static class CultureHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the temporary culture for the current thread.
|
||||
/// Should be disposed after usage to revert to the previous culture.
|
||||
/// Should not be used between async calls.
|
||||
/// </summary>
|
||||
/// <param name="cultureInfo">The culture information.</param>
|
||||
/// <returns>A disposable to revert to the previous culture.</returns>
|
||||
public static IDisposable SetTemporaryCulture(CultureInfo cultureInfo)
|
||||
{
|
||||
var oldUiCulture = CultureInfo.CurrentUICulture;
|
||||
var oldCulture = CultureInfo.CurrentCulture;
|
||||
CultureInfo.CurrentUICulture = cultureInfo;
|
||||
CultureInfo.CurrentCulture = cultureInfo;
|
||||
|
||||
return Disposable.Create(() =>
|
||||
{
|
||||
CultureInfo.CurrentUICulture = oldUiCulture;
|
||||
CultureInfo.CurrentCulture = oldCulture;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the available cultures for a specific resource.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResources">The type of the resources.</typeparam>
|
||||
/// <returns>An enumeration of <see cref="CultureInfo.TwoLetterISOLanguageName"/> of available cultures of the given resource type.</returns>
|
||||
public static IEnumerable<CultureInfo> GetAvailableCultures<TResources>()
|
||||
{
|
||||
var resourceManager = new ResourceManager(typeof(TResources));
|
||||
|
||||
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
|
||||
var result = cultures
|
||||
.Except([CultureInfo.InvariantCulture])
|
||||
.Where(culture => culture is { IsNeutralCulture: true, TwoLetterISOLanguageName: "en" }
|
||||
|| !object.Equals(resourceManager.GetResourceSet(culture, true, false), null))
|
||||
.WhereNotNull()
|
||||
.ToList();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
155
src/DataModel/Entities/Account.cs
Normal file
155
src/DataModel/Entities/Account.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
// <copyright file="Account.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using System.ComponentModel;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The state of an account.
|
||||
/// </summary>
|
||||
public enum AccountState
|
||||
{
|
||||
/// <summary>
|
||||
/// Normal player account.
|
||||
/// </summary>
|
||||
Normal,
|
||||
|
||||
/// <summary>
|
||||
/// Spectator account, invisible to players and monsters.
|
||||
/// </summary>
|
||||
Spectator,
|
||||
|
||||
/// <summary>
|
||||
/// Game Master account.
|
||||
/// </summary>
|
||||
GameMaster,
|
||||
|
||||
/// <summary>
|
||||
/// Game Master account, invisible to players and monsters.
|
||||
/// </summary>
|
||||
GameMasterInvisible,
|
||||
|
||||
/// <summary>
|
||||
/// Banned account.
|
||||
/// </summary>
|
||||
Banned,
|
||||
|
||||
/// <summary>
|
||||
/// Temporarily banned account.
|
||||
/// </summary>
|
||||
TemporarilyBanned,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The account of a player.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
public class Account
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique login name.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string LoginName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hash of the password, preferrably of BCrypt.
|
||||
/// </summary>
|
||||
public string PasswordHash { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the security code which is used to confirm character deletion and guild kicks.
|
||||
/// </summary>
|
||||
public string SecurityCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the e mail address.
|
||||
/// </summary>
|
||||
public string EMail { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the iso code (ISO 639-2/3) of the preferred language of the player.
|
||||
/// </summary>
|
||||
[DefaultValue("en")]
|
||||
public string LanguageIsoCode { get; set; } = "en";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time until which the chat ban is in effect.
|
||||
/// </summary>
|
||||
public DateTime? ChatBanUntil { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the unlocked character classes which are locked by default.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Some classes are only available when the player reached a certain level before, or when he paid for some unlock ticket.
|
||||
/// </remarks>
|
||||
[HiddenAtCreation]
|
||||
public virtual ICollection<CharacterClass> UnlockedCharacterClasses { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the registration date.
|
||||
/// </summary>
|
||||
public DateTime RegistrationDate { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the state.
|
||||
/// </summary>
|
||||
public AccountState State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timezone of the player, difference to UTC.
|
||||
/// </summary>
|
||||
public short TimeZone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vault password.
|
||||
/// </summary>
|
||||
[HiddenAtCreation]
|
||||
public string VaultPassword { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vault.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
[HiddenAtCreation]
|
||||
public virtual ItemStorage? Vault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is vault extended.
|
||||
/// </summary>
|
||||
public bool IsVaultExtended { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this instance is a template account
|
||||
/// and therefore read-only within the game server.
|
||||
/// </summary>
|
||||
public bool IsTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the characters.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
[HiddenAtCreation]
|
||||
public virtual ICollection<Character> Characters { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the stat attributes which are applied across all characters of the account.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note, that it's not possible to add stat attribute with the same
|
||||
/// attribute definition to the <see cref="Account.Attributes"/> and the <see cref="Character.Attributes"/>.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<StatAttribute> Attributes { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.LoginName;
|
||||
}
|
||||
}
|
||||
46
src/DataModel/Entities/AppearanceData.cs
Normal file
46
src/DataModel/Entities/AppearanceData.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="AppearanceData.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The appearance data of a character.
|
||||
/// </summary>
|
||||
public class AppearanceData : IAppearanceData
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when the appearance of the player changed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This never happens in this implementation.
|
||||
/// </remarks>
|
||||
public event EventHandler? AppearanceChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character class.
|
||||
/// </summary>
|
||||
public virtual CharacterClass? CharacterClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character status.
|
||||
/// </summary>
|
||||
public CharacterStatus CharacterStatus { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public CharacterPose Pose { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool FullAncientSetEquipped { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the equipped items.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemAppearance> EquippedItems { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
IEnumerable<ItemAppearance> IAppearanceData.EquippedItems => this.EquippedItems;
|
||||
}
|
||||
271
src/DataModel/Entities/Character.cs
Normal file
271
src/DataModel/Entities/Character.cs
Normal file
@@ -0,0 +1,271 @@
|
||||
// <copyright file="Character.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// The hero state of a player. Given enough time, the state converges to <see cref="Normal"/>.
|
||||
/// </summary>
|
||||
public enum HeroState
|
||||
{
|
||||
/// <summary>
|
||||
/// The character is new.
|
||||
/// </summary>
|
||||
New,
|
||||
|
||||
/// <summary>
|
||||
/// The character is a hero.
|
||||
/// </summary>
|
||||
Hero,
|
||||
|
||||
/// <summary>
|
||||
/// The character is a hero, but the hero state is almost gone.
|
||||
/// </summary>
|
||||
LightHero,
|
||||
|
||||
/// <summary>
|
||||
/// The normal state.
|
||||
/// </summary>
|
||||
Normal,
|
||||
|
||||
/// <summary>
|
||||
/// The character killed another character, and has a kill warning.
|
||||
/// </summary>
|
||||
PlayerKillWarning,
|
||||
|
||||
/// <summary>
|
||||
/// The character killed two characters, and has some restrictions.
|
||||
/// </summary>
|
||||
PlayerKiller1stStage,
|
||||
|
||||
/// <summary>
|
||||
/// The character killed more than two characters, and has hard restrictions.
|
||||
/// </summary>
|
||||
PlayerKiller2ndStage,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Character Status of a player.
|
||||
/// </summary>
|
||||
public enum CharacterStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The character is normal.
|
||||
/// </summary>
|
||||
Normal = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The character is banned.
|
||||
/// </summary>
|
||||
Banned = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The character is a GameMaster (have mu logo on the head).
|
||||
/// </summary>
|
||||
GameMaster = 32,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character pose.
|
||||
/// </summary>
|
||||
public enum CharacterPose : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// The character is standing (normal).
|
||||
/// </summary>
|
||||
Standing = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The character is sitting on an object.
|
||||
/// </summary>
|
||||
Sitting = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The character is leaning towards something (wall etc).
|
||||
/// </summary>
|
||||
Leaning = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The character is hanging on something.
|
||||
/// </summary>
|
||||
Hanging = 4,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character of a player.
|
||||
/// </summary>
|
||||
public class Character
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character class.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual CharacterClass? CharacterClass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character slot in the account.
|
||||
/// </summary>
|
||||
public byte CharacterSlot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the create date.
|
||||
/// </summary>
|
||||
public DateTime CreateDate { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the experience.
|
||||
/// </summary>
|
||||
public long Experience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master experience.
|
||||
/// </summary>
|
||||
public long MasterExperience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remaining level up points which can be spent on increasable stat attributes.
|
||||
/// </summary>
|
||||
public int LevelUpPoints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the master level up points which can be spent on master skills.
|
||||
/// </summary>
|
||||
public int MasterLevelUpPoints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current game map.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual GameMapDefinition? CurrentMap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of its map position.
|
||||
/// </summary>
|
||||
public byte PositionX { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of its map position.
|
||||
/// </summary>
|
||||
public byte PositionY { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the player kill count.
|
||||
/// </summary>
|
||||
public int PlayerKillCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the remaining seconds for the current hero state, when the player state is not normal.
|
||||
/// </summary>
|
||||
public int StateRemainingSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the hero state.
|
||||
/// </summary>
|
||||
public HeroState State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the character status.
|
||||
/// </summary>
|
||||
public CharacterStatus CharacterStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pose.
|
||||
/// </summary>
|
||||
public CharacterPose Pose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the used fruit points.
|
||||
/// </summary>
|
||||
public int UsedFruitPoints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the used negative fruit points.
|
||||
/// </summary>
|
||||
public int UsedNegFruitPoints { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of inventory extensions.
|
||||
/// </summary>
|
||||
public int InventoryExtensions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the key configuration, which is set by the client and just saved as is.
|
||||
/// </summary>
|
||||
public byte[]? KeyConfiguration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration of the mu helper, which is set by the client and just saved as is.
|
||||
/// </summary>
|
||||
public byte[]? MuHelperConfiguration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the personal store.
|
||||
/// </summary>
|
||||
public string? StoreName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this character has it's store opened.
|
||||
/// </summary>
|
||||
public bool IsStoreOpened { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the stat attributes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note, that it's not possible to add stat attribute with the same
|
||||
/// attribute definition to the <see cref="Account.Attributes"/> and the <see cref="Character.Attributes"/>.
|
||||
/// </remarks>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<StatAttribute> Attributes { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the letters.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual IList<LetterHeader> Letters { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the learned skills.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<SkillEntry> LearnedSkills { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the inventory.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ItemStorage? Inventory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the drop item groups.
|
||||
/// </summary>
|
||||
public virtual ICollection<DropItemGroup> DropItemGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the quest states.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<CharacterQuestState> QuestStates { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
46
src/DataModel/Entities/CharacterQuestState.cs
Normal file
46
src/DataModel/Entities/CharacterQuestState.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
// <copyright file="CharacterQuestState.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the progress state of a started quest.
|
||||
/// It's only possible to have one quest of the same group active.
|
||||
/// </summary>
|
||||
public class CharacterQuestState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the group.
|
||||
/// </summary>
|
||||
public short Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the game client action was performed.
|
||||
/// </summary>
|
||||
public bool ClientActionPerformed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the last finished quest of the <see cref="Group"/>.
|
||||
/// </summary>
|
||||
public virtual QuestDefinition? LastFinishedQuest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active quest.
|
||||
/// </summary>
|
||||
public virtual QuestDefinition? ActiveQuest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the requirement states for the current <see cref="ActiveQuest"/>.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<QuestMonsterKillRequirementState> RequirementStates { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"#{this.Group}, Last finished: '{this.LastFinishedQuest?.Name}', Active: '{this.ActiveQuest?.Name}'";
|
||||
}
|
||||
}
|
||||
28
src/DataModel/Entities/Guild.cs
Normal file
28
src/DataModel/Entities/Guild.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
// <copyright file="Guild.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// A guild is a group of players who like to play together.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
public class Guild : OpenMU.Interfaces.Guild
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the members.
|
||||
/// </summary>
|
||||
public virtual ICollection<GuildMember> Members { get; protected set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Name ?? "<Guild>";
|
||||
}
|
||||
}
|
||||
44
src/DataModel/Entities/GuildMember.cs
Normal file
44
src/DataModel/Entities/GuildMember.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
// <copyright file="GuildMember.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a guild member.
|
||||
/// </summary>
|
||||
public class GuildMember
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GuildMember"/> class.
|
||||
/// </summary>
|
||||
public GuildMember()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GuildMember"/> class.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
public GuildMember(Guid id)
|
||||
{
|
||||
this.Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier. Should be the same id as the character id to which it belongs.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the guild identifier to which the member belongs.
|
||||
/// </summary>
|
||||
public Guid GuildId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status of the member.
|
||||
/// </summary>
|
||||
public GuildPosition Status { get; set; }
|
||||
}
|
||||
43
src/DataModel/Entities/IAppearanceData.cs
Normal file
43
src/DataModel/Entities/IAppearanceData.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
// <copyright file="IAppearanceData.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The interface for the appearance data.
|
||||
/// </summary>
|
||||
public interface IAppearanceData
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs when the appearance of the player changed.
|
||||
/// </summary>
|
||||
event EventHandler? AppearanceChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the character class.
|
||||
/// </summary>
|
||||
CharacterClass? CharacterClass { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the character status.
|
||||
/// </summary>
|
||||
CharacterStatus CharacterStatus { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current pose.
|
||||
/// </summary>
|
||||
CharacterPose Pose { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a full ancient set is equipped.
|
||||
/// </summary>
|
||||
bool FullAncientSetEquipped { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the equipped items.
|
||||
/// </summary>
|
||||
IEnumerable<ItemAppearance> EquippedItems { get; }
|
||||
}
|
||||
226
src/DataModel/Entities/Item.cs
Normal file
226
src/DataModel/Entities/Item.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
// <copyright file="Item.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using System.Globalization;
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
using MUnique.OpenMU.DataModel.Properties;
|
||||
|
||||
/// <summary>
|
||||
/// The item.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class Item
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item slot in the <see cref="ItemStorage"/>.
|
||||
/// </summary>
|
||||
public byte ItemSlot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item definition.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual ItemDefinition? Definition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the currently remaining durability.
|
||||
/// </summary>
|
||||
public double Durability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level of the item.
|
||||
/// </summary>
|
||||
public byte Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this item instance provides the weapon skill while being equipped.
|
||||
/// </summary>
|
||||
public bool HasSkill { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item options.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<ItemOptionLink> ItemOptions { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the applied item set groups (Ancient Set).
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemOfItemSet> ItemSetGroups { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the socket count. This limits the amount of socket options in the <see cref="ItemOptions"/>.
|
||||
/// </summary>
|
||||
public int SocketCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the price which was set by the player for his personal store.
|
||||
/// </summary>
|
||||
public int? StorePrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pet experience.
|
||||
/// Only applies, if this item is actually a trainable pet.
|
||||
/// </summary>
|
||||
public int PetExperience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Assigns the values of another item to this item.
|
||||
/// </summary>
|
||||
/// <param name="otherItem">The other item.</param>
|
||||
public void AssignValues(Item otherItem)
|
||||
{
|
||||
this.Definition = otherItem.Definition;
|
||||
this.Durability = otherItem.Durability;
|
||||
this.Level = otherItem.Level;
|
||||
this.HasSkill = otherItem.HasSkill;
|
||||
this.SocketCount = otherItem.SocketCount;
|
||||
this.PetExperience = otherItem.PetExperience;
|
||||
if (otherItem.ItemOptions != null && otherItem.ItemOptions.Any())
|
||||
{
|
||||
this.ItemOptions.Clear();
|
||||
foreach (var option in otherItem.ItemOptions)
|
||||
{
|
||||
this.ItemOptions.Add(this.CloneItemOptionLink(option));
|
||||
}
|
||||
}
|
||||
|
||||
if (otherItem.ItemSetGroups != null && otherItem.ItemSetGroups.Any())
|
||||
{
|
||||
this.ItemSetGroups.Clear();
|
||||
foreach (var setGroup in otherItem.ItemSetGroups)
|
||||
{
|
||||
this.ItemSetGroups.Add(setGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append("Slot ").Append(this.ItemSlot).Append(": ");
|
||||
|
||||
if (this.ItemOptions.Any(o => o.ItemOption?.OptionType == ItemOptionTypes.Excellent))
|
||||
{
|
||||
stringBuilder.Append("Excellent ");
|
||||
}
|
||||
|
||||
var ancientSet = this.ItemSetGroups.FirstOrDefault(s => s.AncientSetDiscriminator != 0)?.ItemSetGroup;
|
||||
if (ancientSet != null)
|
||||
{
|
||||
stringBuilder.Append(ancientSet.Name).Append(" ");
|
||||
}
|
||||
|
||||
var itemName = this.Definition?.GetNameForLevel(this.Level);
|
||||
|
||||
stringBuilder.Append(itemName);
|
||||
if (this.Level > 0)
|
||||
{
|
||||
stringBuilder.Append("+").Append(this.Level);
|
||||
}
|
||||
|
||||
foreach (var option in this.ItemOptions
|
||||
.Where(o => o.ItemOption?.OptionType != ItemOptionTypes.Luck)
|
||||
.OrderBy(o => o.ItemOption?.OptionType == ItemOptionTypes.Option))
|
||||
{
|
||||
var levelOption = option.ItemOption?.LevelDependentOptions.FirstOrDefault(o => o.Level == (option.ItemOption.LevelType == LevelType.ItemLevel ? this.Level : option.Level));
|
||||
var powerUpDefinition = levelOption?.PowerUpDefinition ?? option.ItemOption?.PowerUpDefinition;
|
||||
if (powerUpDefinition is not null)
|
||||
{
|
||||
stringBuilder.Append("+").Append(powerUpDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.HasSkill)
|
||||
{
|
||||
stringBuilder.Append("+Skill");
|
||||
}
|
||||
|
||||
if (this.ItemOptions.Any(opt => opt.ItemOption?.OptionType == ItemOptionTypes.Luck))
|
||||
{
|
||||
stringBuilder.Append("+Luck");
|
||||
}
|
||||
|
||||
if (this.SocketCount > 0)
|
||||
{
|
||||
stringBuilder.Append("+").Append(this.SocketCount).Append("S");
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents this item, using the specified culture for localization.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture to use for localization.</param>
|
||||
/// <returns>The localized string.</returns>
|
||||
public string ToString(CultureInfo culture)
|
||||
{
|
||||
using var cultureHelper = CultureHelper.SetTemporaryCulture(culture);
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(Resources.Slot).Append(" ").Append(this.ItemSlot).Append(": ");
|
||||
|
||||
if (this.ItemOptions.Any(o => o.ItemOption?.OptionType == ItemOptionTypes.Excellent))
|
||||
{
|
||||
stringBuilder.Append(Resources.Excellent).Append(" ");
|
||||
}
|
||||
|
||||
var ancientSet = this.ItemSetGroups.FirstOrDefault(s => s.AncientSetDiscriminator != 0)?.ItemSetGroup;
|
||||
if (ancientSet != null)
|
||||
{
|
||||
stringBuilder.Append(ancientSet.Name.ToString()).Append(" ");
|
||||
}
|
||||
|
||||
var itemName = this.Definition?.GetNameForLevel(this.Level);
|
||||
|
||||
stringBuilder.Append(itemName);
|
||||
if (this.Level > 0)
|
||||
{
|
||||
stringBuilder.Append("+").Append(this.Level);
|
||||
}
|
||||
|
||||
foreach (var option in this.ItemOptions
|
||||
.Where(o => o.ItemOption?.OptionType != ItemOptionTypes.Luck)
|
||||
.OrderBy(o => o.ItemOption?.OptionType == ItemOptionTypes.Option))
|
||||
{
|
||||
var levelOption = option.ItemOption?.LevelDependentOptions.FirstOrDefault(o => o.Level == (option.ItemOption.LevelType == LevelType.ItemLevel ? this.Level : option.Level));
|
||||
var powerUpDefinition = levelOption?.PowerUpDefinition ?? option.ItemOption?.PowerUpDefinition;
|
||||
if (powerUpDefinition is not null)
|
||||
{
|
||||
stringBuilder.Append("+").Append(powerUpDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.HasSkill)
|
||||
{
|
||||
stringBuilder.Append("+").Append(Resources.Skill);
|
||||
}
|
||||
|
||||
if (this.ItemOptions.Any(opt => opt.ItemOption?.OptionType == ItemOptionTypes.Luck))
|
||||
{
|
||||
stringBuilder.Append("+").Append(Resources.Luck);
|
||||
}
|
||||
|
||||
if (this.SocketCount > 0)
|
||||
{
|
||||
stringBuilder.Append("+").Append(this.SocketCount).Append(Resources.SocketAbbreviation);
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clones the item option link.
|
||||
/// </summary>
|
||||
/// <param name="link">The link.</param>
|
||||
/// <returns>The cloned item option link.</returns>
|
||||
protected virtual ItemOptionLink CloneItemOptionLink(ItemOptionLink link)
|
||||
{
|
||||
return link.Clone();
|
||||
}
|
||||
}
|
||||
33
src/DataModel/Entities/ItemAppearance.cs
Normal file
33
src/DataModel/Entities/ItemAppearance.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
// <copyright file="ItemAppearance.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// Appearance of an item.
|
||||
/// </summary>
|
||||
public class ItemAppearance
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item slot.
|
||||
/// </summary>
|
||||
public byte ItemSlot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the definition of the item.
|
||||
/// </summary>
|
||||
public virtual ItemDefinition? Definition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level.
|
||||
/// </summary>
|
||||
public byte Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visible options.
|
||||
/// </summary>
|
||||
public virtual ICollection<ItemOptionType> VisibleOptions { get; protected set; } = null!;
|
||||
}
|
||||
62
src/DataModel/Entities/ItemOptionLink.cs
Normal file
62
src/DataModel/Entities/ItemOptionLink.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
// <copyright file="ItemOptionLink.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
|
||||
/// <summary>
|
||||
/// This class defines a link between the item and the concrete item option which the actual item instance possess.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemOptionLink
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the item option.
|
||||
/// Link to <see cref="ItemDefinition.PossibleItemOptions"/>, <see cref="ItemOptionDefinition.PossibleOptions"/>.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual IncreasableItemOption? ItemOption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level.
|
||||
/// </summary>
|
||||
public int Level { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the index of the option. This is required when the options are sorted, e.g. for socket options.
|
||||
/// </summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clones this instance.
|
||||
/// </summary>
|
||||
/// <returns>The cloned instance.</returns>
|
||||
public virtual ItemOptionLink Clone()
|
||||
{
|
||||
var link = new ItemOptionLink();
|
||||
link.AssignValues(this);
|
||||
return link;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns the values.
|
||||
/// </summary>
|
||||
/// <param name="otherLink">The other link.</param>
|
||||
public void AssignValues(ItemOptionLink otherLink)
|
||||
{
|
||||
this.ItemOption = otherLink.ItemOption;
|
||||
this.Level = otherLink.Level;
|
||||
this.Index = otherLink.Index;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
var powerUpDefinition = this.ItemOption?.LevelDependentOptions?.FirstOrDefault(ldo => ldo.Level == this.Level)?.PowerUpDefinition
|
||||
?? this.ItemOption?.PowerUpDefinition;
|
||||
return powerUpDefinition?.ToString() ?? "empty";
|
||||
}
|
||||
}
|
||||
31
src/DataModel/Entities/ItemStorage.cs
Normal file
31
src/DataModel/Entities/ItemStorage.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
// <copyright file="ItemStorage.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.Annotations;
|
||||
|
||||
/// <summary>
|
||||
/// A storage where items can be stored.
|
||||
/// </summary>
|
||||
[Cloneable]
|
||||
public partial class ItemStorage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the items which are stored.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual ICollection<Item> Items { get; protected set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the money which is stored.
|
||||
/// </summary>
|
||||
public int Money { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Items?.Count ?? 0} Items, {this.Money} Money";
|
||||
}
|
||||
}
|
||||
52
src/DataModel/Entities/LetterBody.cs
Normal file
52
src/DataModel/Entities/LetterBody.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
// <copyright file="LetterBody.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// The body of a letter.
|
||||
/// </summary>
|
||||
[AggregateRoot]
|
||||
public class LetterBody
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the header.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual LetterHeader? Header { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the message.
|
||||
/// </summary>
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rotation of the sender character.
|
||||
/// </summary>
|
||||
public byte Rotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the animation of the sender character.
|
||||
/// </summary>
|
||||
public byte Animation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the sender appearance data.
|
||||
/// </summary>
|
||||
[MemberOfAggregate]
|
||||
public virtual AppearanceData? SenderAppearance { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Header}";
|
||||
}
|
||||
}
|
||||
29
src/DataModel/Entities/QuestMonsterKillRequirementState.cs
Normal file
29
src/DataModel/Entities/QuestMonsterKillRequirementState.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
// <copyright file="QuestMonsterKillRequirementState.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using MUnique.OpenMU.DataModel.Configuration.Quests;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps the progress of the <see cref="QuestDefinition.RequiredMonsterKills"/> of the currently active quest.
|
||||
/// </summary>
|
||||
public class QuestMonsterKillRequirementState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the requirement for which this state is kept.
|
||||
/// </summary>
|
||||
public virtual QuestMonsterKillRequirement? Requirement { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the monster kill count for this <see cref="Requirement"/>.
|
||||
/// </summary>
|
||||
public int KillCount { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.KillCount}/{this.Requirement?.MinimumNumber} {this.Requirement?.Monster}";
|
||||
}
|
||||
}
|
||||
110
src/DataModel/Entities/SkillEntry.cs
Normal file
110
src/DataModel/Entities/SkillEntry.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
// <copyright file="SkillEntry.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel.Entities;
|
||||
|
||||
using System.ComponentModel;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// An actual entry of a skill in the characters skill list.
|
||||
/// </summary>
|
||||
public class SkillEntry : INotifyPropertyChanged
|
||||
{
|
||||
private int level;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a property changed.
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the skill definition.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public virtual Skill? Skill { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the level of the skill, primarily master skill level.
|
||||
/// </summary>
|
||||
public int Level
|
||||
{
|
||||
get => this.level;
|
||||
|
||||
set
|
||||
{
|
||||
if (this.level != value)
|
||||
{
|
||||
this.level = value;
|
||||
this.OnPropertyChanged(nameof(this.Level));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the power up element of this skill of this player. It is a "cached" element which will be created on demand and can be applied multiple times.
|
||||
/// </summary>
|
||||
[Transient]
|
||||
public (AttributeDefinition Target, IElement BuffPowerUp)[]? PowerUps { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the PvP power up element of this skill of this player. It is a "cached" element which will be created on demand and can be applied multiple times.
|
||||
/// </summary>
|
||||
[Transient]
|
||||
public (AttributeDefinition Target, IElement BuffPowerUp)[]? PowerUpsPvp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the <see cref="PowerUps"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is an IElement, because the duration can be dependent from the player attributes.
|
||||
/// </remarks>
|
||||
[Transient]
|
||||
public IElement? PowerUpDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the duration of the <see cref="PowerUps"/> for PvP.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is an IElement, because the duration can be dependent from the player attributes.
|
||||
/// </remarks>
|
||||
[Transient]
|
||||
public IElement? PowerUpDurationPvp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance of applying the <see cref="PowerUps"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is an IElement, because the duration can be dependent from the player attributes.
|
||||
/// </remarks>
|
||||
[Transient]
|
||||
public IElement? PowerUpChance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the chance of applying the <see cref="PowerUps"/> for PvP.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It is an IElement, because the duration can be dependent from the player attributes.
|
||||
/// </remarks>
|
||||
[Transient]
|
||||
public IElement? PowerUpChancePvp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the attributes, if this skill has attribute relationships.
|
||||
/// </summary>
|
||||
[Transient]
|
||||
public IAttributeSystem? Attributes { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Skill?.Name}{(this.Level > 0 ? ", Level: " + this.Level : string.Empty)}";
|
||||
}
|
||||
|
||||
private void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
50
src/DataModel/Error.cs
Normal file
50
src/DataModel/Error.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// <copyright file="Error.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.DataModel;
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// Static class which offers convenience methods to throw exceptions.
|
||||
/// </summary>
|
||||
public static class Error
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an <see cref="InvalidOperationException"/> because of on uninitialized property.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object whose property is not initialized.</param>
|
||||
/// <param name="propertyName">The property name.</param>
|
||||
/// <returns>The created <see cref="InvalidOperationException"/>.</returns>
|
||||
public static Exception NotInitializedProperty(object parent, [CallerMemberName] string propertyName = "")
|
||||
{
|
||||
return new InvalidOperationException($"Property '{propertyName}' of {parent} is not initialized yet.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and throws an <see cref="InvalidOperationException"/> because of on uninitialized property.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object whose property is not initialized.</param>
|
||||
/// <param name="propertyName">The property name.</param>
|
||||
[DoesNotReturn]
|
||||
public static void ThrowNotInitializedProperty(this object parent, string propertyName)
|
||||
{
|
||||
throw new InvalidOperationException($"Property '{propertyName}' of {parent} is not initialized yet.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and throws an <see cref="InvalidOperationException"/> if <paramref name="propertyIsNull"/> is <see langword="true"/>.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent object whose property is not initialized.</param>
|
||||
/// <param name="propertyIsNull">The flag, if the property is null.</param>
|
||||
/// <param name="propertyName">The property name.</param>
|
||||
public static void ThrowNotInitializedProperty(this object parent, [DoesNotReturnIf(true)] bool propertyIsNull, string propertyName)
|
||||
{
|
||||
if (propertyIsNull)
|
||||
{
|
||||
throw new InvalidOperationException($"Property '{propertyName}' of {parent} is not initialized yet.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user