diff --git a/src/AttributeSystem/ComposableAttribute.cs b/src/AttributeSystem/ComposableAttribute.cs index 0f27f78f37..bafd2661cb 100644 --- a/src/AttributeSystem/ComposableAttribute.cs +++ b/src/AttributeSystem/ComposableAttribute.cs @@ -105,6 +105,17 @@ public void RemoveElement(IElement element) } } + /// + /// Removes all elements from the composition. + /// + public void RemoveAllElements() + { + while (this._elementList.FirstOrDefault() is { } element) + { + this._elementList.Remove(element); + } + } + private float GetAndCacheValue() { // Aggregate a copy-on-write snapshot, so a concurrent AddElement/RemoveElement (e.g. an expiring diff --git a/src/AttributeSystem/ConstValueAttribute.cs b/src/AttributeSystem/ConstValueAttribute.cs index 038d864a53..44e41a0e70 100644 --- a/src/AttributeSystem/ConstValueAttribute.cs +++ b/src/AttributeSystem/ConstValueAttribute.cs @@ -16,10 +16,12 @@ public class ConstValueAttribute : IAttribute /// /// The value. /// The definition. - public ConstValueAttribute(float value, AttributeDefinition definition) + /// The aggregate type. + public ConstValueAttribute(float value, AttributeDefinition definition, AggregateType aggregateType = AggregateType.AddRaw) { this.Value = value; this._definition = definition; + this.AggregateType = aggregateType; } /// @@ -57,11 +59,11 @@ public virtual AttributeDefinition Definition public float Value { get; protected set; } /// - public AggregateType AggregateType => AggregateType.AddRaw; + public AggregateType AggregateType { get; protected set; } /// public override string ToString() { - return $"{this.Definition.Designation}: {this.Value}"; + return $"{this.Definition.Designation}: {this.Value} ({this.AggregateType})"; } } \ No newline at end of file diff --git a/src/GameLogic/Attributes/Stats.cs b/src/GameLogic/Attributes/Stats.cs index 3e7c69bfa0..5dabae4096 100644 --- a/src/GameLogic/Attributes/Stats.cs +++ b/src/GameLogic/Attributes/Stats.cs @@ -1173,7 +1173,31 @@ public class Stats /// Gets the shield recovery everywhere attribute definition. /// By default, shield recovery is limited to the safezone only. With this attribute (value >= 1), recovery works everywhere on a map. /// - public static AttributeDefinition ShieldRecoveryEverywhere { get; } = new(new Guid("3D0A78FF-CCD4-442E-8B4E-64E5082ABD78"), "Is Shield Recovery Active Everwhere", "By default, shield recovery is limited to the safezone only. With this attribute (value >= 1), recovery works everywhere on a map."); + public static AttributeDefinition ShieldRecoveryEverywhere { get; } = new(new Guid("3D0A78FF-CCD4-442E-8B4E-64E5082ABD78"), "Shield Recovery Active Everywhere", "By default, shield recovery is limited to the safezone only. With this attribute (value >= 1), recovery works everywhere on a map."); + + /// + /// Gets the is shield recovery active attribute definition. + /// + public static AttributeDefinition IsShieldRecoveryActive { get; } = new(new Guid("8F2C4D7E-B1A9-4E3F-9C5D-2A1B7E8F3C4D"), "Is Shield Recovery Active", string.Empty); + + /// + /// Gets the shield recovery hiatus (in seconds) attribute definition. + /// + /// + /// Must be equal or greater than .HiatusThreshold for shield to regenerate. See . + /// + public static AttributeDefinition ShieldRecoveryHiatus { get; } = new(new Guid("5A7E2B9C-3D1F-4A8E-B6C2-1E7D4A9F2B3C"), "Shield Recovery Hiatus", "The seconds since when shield recovery was last interrupted, either by leaving a safezone, the shield being damaged or maxing out."); + + /// + /// Gets the shield recovery ramp factor attribute definition. + /// + /// + /// The factor by which shield recovery increases. Rises linearly with . Original range is [2,3]. + /// + public static AttributeDefinition ShieldRecoveryRampFactor { get; } = new(new Guid("C3E8F1A7-4B9D-4C5E-8A2F-3D6E1C9B5A7F"), "Shield Recovery Ramp Factor", "The factor by which shield recovery increases. Rises linearly with the uninterrupted shield recovery duration.") + { + MaximumValue = 3, + }; /// /// Gets the ability usage reduction attribute definition. Value ranges from 0 (no reduction) to 1 (full reduction). @@ -1437,7 +1461,12 @@ public class Stats /// /// Gets the attribute which defines if the character is located in a safezone of a game map. /// - public static AttributeDefinition IsInSafezone { get; } = new(new Guid("82044DF9-F528-4AD6-9AAA-6FEAA4C786E7"), "Flag, if the character is located in a safezone of a game map", "Characters at the safezone recover additional health and shield."); + public static AttributeDefinition IsInSafezone { get; } = new(new Guid("82044DF9-F528-4AD6-9AAA-6FEAA4C786E7"), "Flag, if the character is located in a safezone of a game map", "Characters at the safezone recover shield and additional ability."); + + /// + /// Gets the attribute which defines if the character is in a resting state: sitting, leaning or hanging. + /// + public static AttributeDefinition IsResting { get; } = new(new Guid("7A4E2D9F-B1C3-48F5-9D2E-1A6F8C3E5B7D"), "Flag, if the character is resting (sitting, leaning or hanging)", "Characters resting recover additional health and mana."); /// /// Gets the attribute which defines if the character is located on an underwater game map. @@ -1588,13 +1617,43 @@ public static IEnumerable AfterMonsterKillRegenerationAttributes } } - private static Regeneration ManaRegeneration { get; } = new(ManaRecoveryMultiplier, MaximumMana, CurrentMana, ManaRecoveryAbsolute); + /// + /// Gets the mana regeneration. + /// + public static Regeneration ManaRegeneration { get; } = new(ManaRecoveryMultiplier, MaximumMana, CurrentMana, ManaRecoveryAbsolute) + { + IntervalResting = TimeSpan.FromSeconds(5), + }; - private static Regeneration HealthRegeneration { get; } = new(HealthRecoveryMultiplier, MaximumHealth, CurrentHealth, HealthRecoveryAbsolute); + /// + /// Gets the health regeneration. + /// + public static Regeneration HealthRegeneration { get; } = new(HealthRecoveryMultiplier, MaximumHealth, CurrentHealth, HealthRecoveryAbsolute) + { + Interval = TimeSpan.FromSeconds(7), + IntervalResting = TimeSpan.FromSeconds(5), + }; - private static Regeneration AbilityRegeneration { get; } = new(AbilityRecoveryMultiplier, MaximumAbility, CurrentAbility, AbilityRecoveryAbsolute); + /// + /// Gets the ability regeneration. + /// + public static Regeneration AbilityRegeneration { get; } = new(AbilityRecoveryMultiplier, MaximumAbility, CurrentAbility, AbilityRecoveryAbsolute); - private static Regeneration ShieldRegeneration { get; } = new(ShieldRecoveryMultiplier, MaximumShield, CurrentShield, ShieldRecoveryAbsolute); + /// + /// Gets the shield regeneration. + /// + /// + /// Shield recovery is only possible at safe zone, except the character has a specific attribute which has the effect that it's recovered everywhere. + /// This attribute is usually provided by level 380 armor with a Guardian Option. + /// Also, shield has a penalty (hiatus) period before the recovery starts, after which it increases linearly (see ). + /// + public static Regeneration ShieldRegeneration { get; } = new(ShieldRecoveryMultiplier, MaximumShield, CurrentShield, ShieldRecoveryAbsolute) + { + Interval = TimeSpan.FromSeconds(1), + IntervalResting = TimeSpan.FromSeconds(1), + EnablerAttribute = IsShieldRecoveryActive, + HiatusAttribute = ShieldRecoveryHiatus, + }; private static Regeneration ManaRegenerationAfterMonsterKill { get; } = new(ManaAfterMonsterKillMultiplier, MaximumMana, CurrentMana, ManaAfterMonsterKillAbsolute); @@ -1613,8 +1672,8 @@ public class Regeneration { /// /// Initializes a new instance of the class. - /// At regeneration the value of * is getting added to - /// , until the value of is reached. + /// At regeneration the value of ( * ) + + /// is getting added to , until the value of is reached. /// /// The regeneration multiplier. /// The maximum attribute. @@ -1647,5 +1706,36 @@ public Regeneration(AttributeDefinition regenerationMultiplier, AttributeDefinit /// Gets the current attribute. /// public AttributeDefinition CurrentAttribute { get; } + + /// + /// Gets the interval at which the attribute would complete a full regeneration cycle. + /// + /// + /// Originally, the game had different regeneration cycles depending on attributes and the player's state (). + /// To avoid having different timers each with a regeneration interval, we run just one set to . + /// Then, we apply a compensation factor which is the ratio between elapsed time and . + /// This way we can mimic original regeneration over time while still keeping it configurable. + /// + public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(3); + + /// + /// Gets the interval at which the attribute would complete a full regeneration cycle when the player is resting (). + /// + public TimeSpan IntervalResting { get; init; } = TimeSpan.FromSeconds(3); + + /// + /// Gets the attribute which gates the regeneration, if it exists. + /// + public AttributeDefinition? EnablerAttribute { get; init; } + + /// + /// Gets the attribute which keeps the regeneration hiatus duration, if it exists. + /// + public AttributeDefinition? HiatusAttribute { get; init; } + + /// + /// Gets the hiatus threshold (in seconds) against wich is checked to allow the regeneration. + /// + public int HiatusThreshold { get; init; } = 10; } } diff --git a/src/GameLogic/Player.cs b/src/GameLogic/Player.cs index 9c4d32c357..3e7f51a51e 100644 --- a/src/GameLogic/Player.cs +++ b/src/GameLogic/Player.cs @@ -24,7 +24,6 @@ namespace MUnique.OpenMU.GameLogic; using MUnique.OpenMU.GameLogic.Views.Guild; using MUnique.OpenMU.GameLogic.Views.Inventory; using MUnique.OpenMU.GameLogic.Views.MuHelper; -using MUnique.OpenMU.GameLogic.Views.Pet; using MUnique.OpenMU.GameLogic.Views.Quest; using MUnique.OpenMU.GameLogic.Views.World; using MUnique.OpenMU.Interfaces; @@ -77,6 +76,14 @@ public class Player : AsyncDisposable, IBucketMapObserver, IAttackable, IAttacke private DateTime _lastRegenerate = DateTime.UtcNow; + private Dictionary _lastRegeneration = new() + { + [Stats.ManaRegeneration] = DateTime.UtcNow, + [Stats.HealthRegeneration] = DateTime.UtcNow, + [Stats.AbilityRegeneration] = DateTime.UtcNow, + [Stats.ShieldRegeneration] = DateTime.UtcNow, + }; + private GameMap? _currentMap; private IDisposable? _accountLoggingScope; @@ -240,8 +247,7 @@ public CharacterPose Pose set { - var character = this._selectedCharacter; - if (character is null || character.Pose == this.Pose) + if (this._selectedCharacter is not { } character || character.Pose == value) { return; } @@ -876,28 +882,42 @@ public async Task RegenerateAsync() { try { - var attributes = this.Attributes; - if (attributes is null) + if (this.Attributes is not { } attributes) { return; } - foreach (var r in Stats.IntervalRegenerationAttributes.Where(r => - attributes[r.RegenerationMultiplier] > 0 || attributes[r.AbsoluteAttribute] > 0)) + var now = DateTime.UtcNow; + foreach (var r in Stats.IntervalRegenerationAttributes) { - if (r.CurrentAttribute == Stats.CurrentShield && !this.IsAtSafezone() && - attributes[Stats.ShieldRecoveryEverywhere] < 1) + if ((r.EnablerAttribute is { } enabler && attributes[enabler] < 1) + || (r.HiatusAttribute is { } hiatus && attributes[hiatus] < r.HiatusThreshold)) { - // Shield recovery is only possible at safe-zone, except the character has a specific attribute which has the effect that it's recovered everywhere. - // This attribute is usually provided by level 380 armor and a Guardian Option. + this._lastRegeneration[r] = now; continue; } + var factor = 0f; + var interval = r.Interval; + if (attributes[Stats.IsResting] > 0) + { + interval = r.IntervalResting; + + if (r.CurrentAttribute == Stats.CurrentMana) + { + // Mana recovery while resting is on top of regular recovery + factor += (float)((now - this._lastRegeneration[r]) / r.Interval); + } + } + + factor += (float)((now - this._lastRegeneration[r]) / interval); + attributes[r.CurrentAttribute] = Math.Min( attributes[r.CurrentAttribute] + - ((attributes[r.MaximumAttribute] * attributes[r.RegenerationMultiplier]) + - attributes[r.AbsoluteAttribute]), + (((attributes[r.MaximumAttribute] * attributes[r.RegenerationMultiplier]) + attributes[r.AbsoluteAttribute]) * factor), attributes[r.MaximumAttribute]); + + this._lastRegeneration[r] = now; } await this.RegenerateHeroStateAsync().ConfigureAwait(false); @@ -1202,6 +1222,17 @@ internal async ValueTask AfterKilledPlayerAsync(Player killedPlayer) await this.ForEachWorldObserverAsync(o => o.UpdateCharacterHeroStateAsync(this), true).ConfigureAwait(false); } + /// + /// Sets the current values of the regeneration attributes to their maximum values. + /// + internal void SetReclaimableAttributesToMaximum() + { + foreach (var regeneration in Stats.IntervalRegenerationAttributes) + { + this.Attributes![regeneration.CurrentAttribute] = this.Attributes[regeneration.MaximumAttribute]; + } + } + /// /// Sets the current map without raising the enter/leave map events, when the player is /// removed from the game. @@ -1594,7 +1625,7 @@ private async ValueTask OnPlayerEnteredWorldAsync() this.AddMissingStatAttributes(); this.Attributes = new ItemAwareAttributeSystem(this.Account!, selectedCharacter, this.GameContext.Configuration); - this.Attributes[Stats.NearbyPartyMemberCount] = 0; + this.Attributes[Stats.IsResting] = 0; this.LogInvalidInventoryItems(); this._storages.CreateForCharacter(selectedCharacter); @@ -1669,17 +1700,6 @@ private void SetReclaimableAttributesBeforeEnterGame() this.Attributes[Stats.CurrentHealth] = Math.Min(this.Attributes[Stats.CurrentHealth], this.Attributes[Stats.MaximumHealth]); } - /// - /// Sets the current values of the regeneration attributes to their maximum values. - /// - internal void SetReclaimableAttributesToMaximum() - { - foreach (var regeneration in Stats.IntervalRegenerationAttributes) - { - this.Attributes![regeneration.CurrentAttribute] = this.Attributes[regeneration.MaximumAttribute]; - } - } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "Catching all Exceptions.")] private async void OnAttributeValueChanged(object? sender, IAttribute attribute) { diff --git a/src/GameLogic/PlugIns/PeriodicTasks/ShieldRecoveryHiatusPlugIn.cs b/src/GameLogic/PlugIns/PeriodicTasks/ShieldRecoveryHiatusPlugIn.cs new file mode 100644 index 0000000000..b5730be7ba --- /dev/null +++ b/src/GameLogic/PlugIns/PeriodicTasks/ShieldRecoveryHiatusPlugIn.cs @@ -0,0 +1,75 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.GameLogic.PlugIns; + +using System; +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.GameLogic.Attributes; +using MUnique.OpenMU.GameLogic.NPC; +using MUnique.OpenMU.PlugIns; + +/// +/// Updates and resets the shield recovery hiatus attribute. +/// +[PlugIn] +[Display(Name = nameof(PlugInResources.ShieldRecoveryHiatusPlugIn_Name), Description = nameof(PlugInResources.ShieldRecoveryHiatusPlugIn_Description), ResourceType = typeof(PlugInResources))] +[Guid("7B4A9E2D-C1F5-48E3-A6B2-1E7D4C8F3A5B")] +public class ShieldRecoveryHiatusPlugIn : IPeriodicTaskPlugIn, IAttackableMovedPlugIn, IAttackableGotHitPlugIn +{ + /// + public async ValueTask ExecuteTaskAsync(GameContext gameContext) + { + await gameContext.ForEachPlayerAsync(player => + { + if (player.SelectedCharacter != null + && !player.PlayerState.CurrentState.IsDisconnectedOrFinished() + && player.Attributes is { } attributes + && attributes[Stats.MaximumShield] > 0) + { + attributes.AddElement(new SimpleElement(1, AggregateType.AddRaw), Stats.ShieldRecoveryHiatus); + } + + return Task.CompletedTask; + }).ConfigureAwait(false); + } + + /// + public void ForceStart() + { + // do nothing. + } + + /// + public void AttackableGotHit(IAttackable attackable, IAttacker attacker, HitInfo hitInfo) + { + var defender = attackable as Player ?? (attackable as Monster)?.SummonedBy; + var attackerPlayer = attacker as Player ?? (attacker as Monster)?.SummonedBy; + if (defender is null || attackerPlayer is null || defender == attackerPlayer || defender.Attributes is not { } attributes) + { + return; + } + + if (attributes[Stats.MaximumShield] > 0 && hitInfo is { ShieldDamage: > 0 }) + { + attributes.GetComposableAttribute(Stats.ShieldRecoveryHiatus)?.RemoveAllElements(); + } + } + + /// + public void AttackableMoved(IAttackable attackable) + { + if (attackable is not Player player || player.Attributes is not { } attributes) + { + return; + } + + if (attributes[Stats.MaximumShield] > 0 && + (attributes[Stats.IsShieldRecoveryActive] < 1 || attributes[Stats.CurrentShield] == attributes[Stats.MaximumShield])) + { + attributes.GetComposableAttribute(Stats.ShieldRecoveryHiatus)?.RemoveAllElements(); + } + } +} \ No newline at end of file diff --git a/src/GameLogic/PlugIns/UpdateIsInSafezoneAfterPlayerMoved.cs b/src/GameLogic/PlugIns/UpdateIsInSafezoneAfterPlayerMoved.cs index ca09af0346..c8958bf84f 100644 --- a/src/GameLogic/PlugIns/UpdateIsInSafezoneAfterPlayerMoved.cs +++ b/src/GameLogic/PlugIns/UpdateIsInSafezoneAfterPlayerMoved.cs @@ -9,7 +9,8 @@ namespace MUnique.OpenMU.GameLogic.PlugIns; using MUnique.OpenMU.PlugIns; /// -/// Updates the . For example, this activates the automatic health and shield recover. +/// Updates the and attributes. +/// For example, these activate or increase shield, ability, health and mana recoveries. /// [PlugIn] [Display(Name = nameof(PlugInResources.UpdateIsInSafezoneAfterPlayerMoved_Name), Description = nameof(PlugInResources.UpdateIsInSafezoneAfterPlayerMoved_Description), ResourceType = typeof(PlugInResources))] @@ -22,6 +23,7 @@ public void AttackableMoved(IAttackable attackable) if (attackable is Player player) { player.Attributes?.SetStatAttribute(Stats.IsInSafezone, attackable.IsAtSafezone() ? 1.0f : 0.0f); + player.Attributes?.SetStatAttribute(Stats.IsResting, 0.0f); } } } \ No newline at end of file diff --git a/src/GameLogic/Properties/PlugInResources.Designer.cs b/src/GameLogic/Properties/PlugInResources.Designer.cs index dc41811fa6..4f8c0eb696 100644 --- a/src/GameLogic/Properties/PlugInResources.Designer.cs +++ b/src/GameLogic/Properties/PlugInResources.Designer.cs @@ -2501,6 +2501,24 @@ public static string SetStatChatCommandPlugIn_Name { } } + /// + /// Looks up a localized string similar to Updates and resets the shield recovery hiatus attribute.. + /// + public static string ShieldRecoveryHiatusPlugIn_Description { + get { + return ResourceManager.GetString("ShieldRecoveryHiatusPlugIn_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shield Recovery Hiatus. + /// + public static string ShieldRecoveryHiatusPlugIn_Name { + get { + return ResourceManager.GetString("ShieldRecoveryHiatusPlugIn_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Handles the chat command '/fireworks <x> <y>'. Shows an fireworks effect at the specified coordinates.. /// diff --git a/src/GameLogic/Properties/PlugInResources.resx b/src/GameLogic/Properties/PlugInResources.resx index 26953515c4..105249bd0b 100644 --- a/src/GameLogic/Properties/PlugInResources.resx +++ b/src/GameLogic/Properties/PlugInResources.resx @@ -177,6 +177,12 @@ Updates the state of the self defense system. + + Shield Recovery Hiatus + + + Updates and resets the shield recovery hiatus attribute. + Show Message To All When Player Entered World diff --git a/src/GameServer/MessageHandler/AnimationHandlerPlugIn.cs b/src/GameServer/MessageHandler/AnimationHandlerPlugIn.cs index 491caf8f81..567d6935dc 100644 --- a/src/GameServer/MessageHandler/AnimationHandlerPlugIn.cs +++ b/src/GameServer/MessageHandler/AnimationHandlerPlugIn.cs @@ -7,6 +7,7 @@ namespace MUnique.OpenMU.GameServer.MessageHandler; using System.Runtime.InteropServices; using MUnique.OpenMU.DataModel.Entities; using MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.GameLogic.Attributes; using MUnique.OpenMU.GameLogic.Views.World; using MUnique.OpenMU.Network.Packets.ClientToServer; using MUnique.OpenMU.PlugIns; @@ -47,6 +48,11 @@ public async ValueTask HandlePacketAsync(Player player, Memory packet) _ => default, }; + if (player.Pose > CharacterPose.Standing) + { + player.Attributes?.SetStatAttribute(Stats.IsResting, 1.0f); + } + await player.ForEachWorldObserverAsync(p => p.ShowAnimationAsync(player, animation, null, rotation), false).ConfigureAwait(false); } } \ No newline at end of file diff --git a/src/Persistence/BasicModel/ConstValueAttribute.Generated.cs b/src/Persistence/BasicModel/ConstValueAttribute.Generated.cs index 5597321094..872e0c9602 100644 --- a/src/Persistence/BasicModel/ConstValueAttribute.Generated.cs +++ b/src/Persistence/BasicModel/ConstValueAttribute.Generated.cs @@ -21,8 +21,8 @@ public partial class ConstValueAttribute : MUnique.OpenMU.AttributeSystem.ConstV { /// - public ConstValueAttribute(System.Single value, MUnique.OpenMU.AttributeSystem.AttributeDefinition definition) - : base(value, definition) + public ConstValueAttribute(System.Single value, MUnique.OpenMU.AttributeSystem.AttributeDefinition definition, MUnique.OpenMU.AttributeSystem.AggregateType aggregateType) + : base(value, definition, aggregateType) { } diff --git a/src/Persistence/EntityFramework/EntityDataContext.cs b/src/Persistence/EntityFramework/EntityDataContext.cs index 73c227137a..dd05e4ef71 100644 --- a/src/Persistence/EntityFramework/EntityDataContext.cs +++ b/src/Persistence/EntityFramework/EntityDataContext.cs @@ -74,7 +74,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(); modelBuilder.Entity().Apply(); - modelBuilder.Entity().Apply(); + modelBuilder.Entity(); modelBuilder.Entity().Apply(); modelBuilder.Entity().Apply(); modelBuilder.Entity().Apply(); diff --git a/src/Persistence/EntityFramework/Extensions/ModelBuilder/AttributeExtensions.cs b/src/Persistence/EntityFramework/Extensions/ModelBuilder/AttributeExtensions.cs index a6c32d15dd..1e2c88312b 100644 --- a/src/Persistence/EntityFramework/Extensions/ModelBuilder/AttributeExtensions.cs +++ b/src/Persistence/EntityFramework/Extensions/ModelBuilder/AttributeExtensions.cs @@ -12,15 +12,6 @@ namespace MUnique.OpenMU.Persistence.EntityFramework.Extensions.ModelBuilder; /// internal static class AttributeExtensions { - /// - /// Applies the settings for the entity. - /// - /// The builder. - public static void Apply(this EntityTypeBuilder builder) - { - builder.Ignore(c => c.AggregateType); - } - /// /// Applies the settings for the entity. /// diff --git a/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.Designer.cs b/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.Designer.cs new file mode 100644 index 0000000000..3e27000668 --- /dev/null +++ b/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.Designer.cs @@ -0,0 +1,5820 @@ +// +using System; +using MUnique.OpenMU.Persistence.EntityFramework; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace MUnique.OpenMU.Persistence.EntityFramework.Migrations +{ + [DbContext(typeof(EntityDataContext))] + [Migration("20260819100503_AddConstValueAttributeAggregateType")] + partial class AddConstValueAttributeAggregateType + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChatBanUntil") + .HasColumnType("timestamp with time zone"); + + b.Property("EMail") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsBot") + .HasColumnType("boolean"); + + b.Property("IsTemplate") + .HasColumnType("boolean"); + + b.Property("IsVaultExtended") + .HasColumnType("boolean"); + + b.Property("LanguageIsoCode") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(3) + .HasColumnType("character varying(3)") + .HasDefaultValue("en"); + + b.Property("LoginName") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("text"); + + b.Property("RegistrationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SecurityCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimeZone") + .HasColumnType("smallint"); + + b.Property("VaultId") + .HasColumnType("uuid"); + + b.Property("VaultPassword") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("LoginName") + .IsUnique(); + + b.HasIndex("VaultId") + .IsUnique(); + + b.ToTable("Account", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AccountCharacterClass", b => + { + b.Property("AccountId") + .HasColumnType("uuid"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.HasKey("AccountId", "CharacterClassId"); + + b.HasIndex("CharacterClassId"); + + b.ToTable("AccountCharacterClass", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.Property("FullAncientSetEquipped") + .HasColumnType("boolean"); + + b.Property("Pose") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CharacterClassId"); + + b.ToTable("AppearanceData", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AreaSkillSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DelayBetweenHits") + .HasColumnType("interval"); + + b.Property("DelayPerOneDistance") + .HasColumnType("interval"); + + b.Property("EffectRange") + .HasColumnType("integer"); + + b.Property("FrustumDistance") + .HasColumnType("real"); + + b.Property("FrustumEndWidth") + .HasColumnType("real"); + + b.Property("FrustumStartWidth") + .HasColumnType("real"); + + b.Property("HitChancePerDistanceMultiplier") + .HasColumnType("real"); + + b.Property("MaximumNumberOfHitsPerAttack") + .HasColumnType("integer"); + + b.Property("MaximumNumberOfHitsPerTarget") + .HasColumnType("integer"); + + b.Property("MinimumNumberOfHitsPerAttack") + .HasColumnType("integer"); + + b.Property("MinimumNumberOfHitsPerTarget") + .HasColumnType("integer"); + + b.Property("ProjectileCount") + .HasColumnType("integer"); + + b.Property("TargetAreaDiameter") + .HasColumnType("real"); + + b.Property("UseDeferredHits") + .HasColumnType("boolean"); + + b.Property("UseFrustumFilter") + .HasColumnType("boolean"); + + b.Property("UseTargetAreaFilter") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("AreaSkillSettings", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Designation") + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("MaximumValue") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("AttributeDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRelationship", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AggregateType") + .HasColumnType("integer"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("InputAttributeId") + .HasColumnType("uuid"); + + b.Property("InputOperand") + .HasColumnType("real"); + + b.Property("InputOperator") + .HasColumnType("integer"); + + b.Property("OperandAttributeId") + .HasColumnType("uuid"); + + b.Property("PowerUpDefinitionValueId") + .HasColumnType("uuid"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.Property("TargetAttributeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CharacterClassId"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("InputAttributeId"); + + b.HasIndex("OperandAttributeId"); + + b.HasIndex("PowerUpDefinitionValueId"); + + b.HasIndex("SkillId"); + + b.HasIndex("TargetAttributeId"); + + b.ToTable("AttributeRelationship", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRequirement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttributeId") + .HasColumnType("uuid"); + + b.Property("GameMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("MinimumValue") + .HasColumnType("integer"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.Property("SkillId1") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("AttributeId"); + + b.HasIndex("GameMapDefinitionId"); + + b.HasIndex("ItemDefinitionId"); + + b.HasIndex("SkillId"); + + b.HasIndex("SkillId1"); + + b.ToTable("AttributeRequirement", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GroundId") + .HasColumnType("uuid"); + + b.Property("LeftGoalId") + .HasColumnType("uuid"); + + b.Property("LeftTeamSpawnPointX") + .HasColumnType("smallint"); + + b.Property("LeftTeamSpawnPointY") + .HasColumnType("smallint"); + + b.Property("RightGoalId") + .HasColumnType("uuid"); + + b.Property("RightTeamSpawnPointX") + .HasColumnType("smallint"); + + b.Property("RightTeamSpawnPointY") + .HasColumnType("smallint"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GroundId") + .IsUnique(); + + b.HasIndex("LeftGoalId") + .IsUnique(); + + b.HasIndex("RightGoalId") + .IsUnique(); + + b.ToTable("BattleZoneDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Buff", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MagicEffectDefinitionId") + .HasColumnType("uuid"); + + b.Property("MaximumLevel") + .HasColumnType("integer"); + + b.Property("MinimumLevel") + .HasColumnType("integer"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MagicEffectDefinitionId") + .IsUnique(); + + b.HasIndex("MonsterDefinitionId"); + + b.ToTable("Buff", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttackRespawnAreaId") + .HasColumnType("uuid"); + + b.Property("CastleSiegeMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("CrownHoldTimeSeconds") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(30); + + b.Property("DefenseRespawnAreaId") + .HasColumnType("uuid"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("GateBuyPrice") + .HasColumnType("integer"); + + b.Property("GateRepairCostPerHealthPoint") + .HasColumnType("integer"); + + b.Property("GuildScoreCastleSiege") + .HasColumnType("integer"); + + b.Property("GuildScoreCastleSiegeMembers") + .HasColumnType("integer"); + + b.Property("LandOfTrialsMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("MaxAttackingGuilds") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(3); + + b.Property("ParticipantRewardMinSeconds") + .HasColumnType("integer"); + + b.Property("RegisterMinLevel") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(200); + + b.Property("RegisterMinMembers") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(20); + + b.Property("RepairCostPerUpgradeLevel") + .HasColumnType("integer"); + + b.Property("RewardItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("SignOfLordItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("SignOfLordItemLevel") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((byte)3); + + b.Property("StatueBuyPrice") + .HasColumnType("integer"); + + b.Property("StatueRepairCostPerHealthPoint") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AttackRespawnAreaId") + .IsUnique(); + + b.HasIndex("CastleSiegeMapDefinitionId"); + + b.HasIndex("DefenseRespawnAreaId") + .IsUnique(); + + b.HasIndex("LandOfTrialsMapDefinitionId"); + + b.HasIndex("RewardItemDefinitionId"); + + b.HasIndex("SignOfLordItemDefinitionId"); + + b.ToTable("CastleSiegeConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsHuntZoneEnabled") + .HasColumnType("boolean"); + + b.Property("IsOccupied") + .HasColumnType("boolean"); + + b.Property("OwnerGuildId") + .HasColumnType("uuid"); + + b.Property("TaxChaos") + .HasColumnType("smallint"); + + b.Property("TaxHunt") + .HasColumnType("integer"); + + b.Property("TaxStore") + .HasColumnType("smallint"); + + b.Property("TributeMoney") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("OwnerGuildId"); + + b.ToTable("CastleSiegeData", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeGuildRegistration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GuildId") + .HasColumnType("uuid"); + + b.Property("GuildName") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("Marks") + .HasColumnType("integer"); + + b.Property("RegistrationOrder") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.ToTable("CastleSiegeGuildRegistration", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeNpcDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId") + .HasColumnType("uuid"); + + b.Property("DefaultSide") + .HasColumnType("smallint"); + + b.Property("Direction") + .HasColumnType("integer"); + + b.Property("InstanceId") + .HasColumnType("smallint"); + + b.Property("IsPersistedToDatabase") + .HasColumnType("boolean"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("SpawnX") + .HasColumnType("smallint"); + + b.Property("SpawnY") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeConfigurationId"); + + b.HasIndex("MonsterDefinitionId", "InstanceId"); + + b.ToTable("CastleSiegeNpcDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeNpcState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CastleSiegeDataId") + .HasColumnType("uuid"); + + b.Property("CurrentHp") + .HasColumnType("integer"); + + b.Property("DefenseLevel") + .HasColumnType("smallint"); + + b.Property("InstanceId") + .HasColumnType("smallint"); + + b.Property("LifeLevel") + .HasColumnType("smallint"); + + b.Property("MonsterNumber") + .HasColumnType("smallint"); + + b.Property("RegenLevel") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeDataId"); + + b.HasIndex("MonsterNumber", "InstanceId") + .IsUnique(); + + b.ToTable("CastleSiegeNpcState", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeStateScheduleEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId") + .HasColumnType("uuid"); + + b.Property("DayOfWeek") + .HasColumnType("integer"); + + b.Property("Hour") + .HasColumnType("smallint"); + + b.Property("Minute") + .HasColumnType("smallint"); + + b.Property("State") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeConfigurationId"); + + b.ToTable("CastleSiegeStateScheduleEntry", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeUpgradeDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId") + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId1") + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId2") + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId3") + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId4") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("smallint"); + + b.Property("RequiredJewelOfGuardianCount") + .HasColumnType("integer"); + + b.Property("RequiredZen") + .HasColumnType("integer"); + + b.Property("Value") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeConfigurationId"); + + b.HasIndex("CastleSiegeConfigurationId1"); + + b.HasIndex("CastleSiegeConfigurationId2"); + + b.HasIndex("CastleSiegeConfigurationId3"); + + b.HasIndex("CastleSiegeConfigurationId4"); + + b.ToTable("CastleSiegeUpgradeDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeZoneDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId") + .HasColumnType("uuid"); + + b.Property("CastleSiegeConfigurationId1") + .HasColumnType("uuid"); + + b.Property("X1") + .HasColumnType("smallint"); + + b.Property("X2") + .HasColumnType("smallint"); + + b.Property("Y1") + .HasColumnType("smallint"); + + b.Property("Y2") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeConfigurationId"); + + b.HasIndex("CastleSiegeConfigurationId1"); + + b.ToTable("CastleSiegeZoneDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("uuid"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.Property("CharacterSlot") + .HasColumnType("smallint"); + + b.Property("CharacterStatus") + .HasColumnType("integer"); + + b.Property("CreateDate") + .HasColumnType("timestamp with time zone"); + + b.Property("CurrentMapId") + .HasColumnType("uuid"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("InventoryExtensions") + .HasColumnType("integer"); + + b.Property("InventoryId") + .HasColumnType("uuid"); + + b.Property("IsStoreOpened") + .HasColumnType("boolean"); + + b.Property("KeyConfiguration") + .HasColumnType("bytea"); + + b.Property("LevelUpPoints") + .HasColumnType("integer"); + + b.Property("MasterExperience") + .HasColumnType("bigint"); + + b.Property("MasterLevelUpPoints") + .HasColumnType("integer"); + + b.Property("MuHelperConfiguration") + .HasColumnType("bytea"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("PlayerKillCount") + .HasColumnType("integer"); + + b.Property("Pose") + .HasColumnType("smallint"); + + b.Property("PositionX") + .HasColumnType("smallint"); + + b.Property("PositionY") + .HasColumnType("smallint"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("StateRemainingSeconds") + .HasColumnType("integer"); + + b.Property("StoreName") + .HasColumnType("text"); + + b.Property("UsedFruitPoints") + .HasColumnType("integer"); + + b.Property("UsedNegFruitPoints") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("CharacterClassId"); + + b.HasIndex("CurrentMapId"); + + b.HasIndex("InventoryId") + .IsUnique(); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Character", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CanGetCreated") + .HasColumnType("boolean"); + + b.Property("ComboDefinitionId") + .HasColumnType("uuid"); + + b.Property("CreationAllowedFlag") + .HasColumnType("smallint"); + + b.Property("FruitCalculation") + .HasColumnType("integer"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("HomeMapId") + .HasColumnType("uuid"); + + b.Property("IsMasterClass") + .HasColumnType("boolean"); + + b.Property("LevelRequirementByCreation") + .HasColumnType("smallint"); + + b.Property("LevelWarpRequirementReductionPercent") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NextGenerationClassId") + .HasColumnType("uuid"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("ComboDefinitionId") + .IsUnique(); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("HomeMapId"); + + b.HasIndex("NextGenerationClassId"); + + b.ToTable("CharacterClass", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterDropItemGroup", b => + { + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("DropItemGroupId") + .HasColumnType("uuid"); + + b.HasKey("CharacterId", "DropItemGroupId"); + + b.HasIndex("DropItemGroupId"); + + b.ToTable("CharacterDropItemGroup", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterQuestState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ActiveQuestId") + .HasColumnType("uuid"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("ClientActionPerformed") + .HasColumnType("boolean"); + + b.Property("Group") + .HasColumnType("smallint"); + + b.Property("LastFinishedQuestId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ActiveQuestId"); + + b.HasIndex("CharacterId"); + + b.HasIndex("LastFinishedQuestId"); + + b.ToTable("CharacterQuestState", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ClientCleanUpInterval") + .HasColumnType("interval"); + + b.Property("ClientTimeout") + .HasColumnType("interval"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("MaximumConnections") + .HasColumnType("integer"); + + b.Property("RoomCleanUpInterval") + .HasColumnType("interval"); + + b.Property("ServerId") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.ToTable("ChatServerDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerEndpoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChatServerDefinitionId") + .HasColumnType("uuid"); + + b.Property("ClientId") + .HasColumnType("uuid"); + + b.Property("NetworkPort") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChatServerDefinitionId"); + + b.HasIndex("ClientId"); + + b.ToTable("ChatServerEndpoint", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CombinationBonusRequirement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ItemOptionCombinationBonusId") + .HasColumnType("uuid"); + + b.Property("MinimumCount") + .HasColumnType("integer"); + + b.Property("OptionTypeId") + .HasColumnType("uuid"); + + b.Property("SubOptionType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ItemOptionCombinationBonusId"); + + b.HasIndex("OptionTypeId"); + + b.ToTable("CombinationBonusRequirement", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConfigurationUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("InstalledAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Version") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("ConfigurationUpdate", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConfigurationUpdateState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CurrentInstalledVersion") + .HasColumnType("integer"); + + b.Property("InitializationKey") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ConfigurationUpdateState", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConnectServerDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CheckMaxConnectionsPerAddress") + .HasColumnType("boolean"); + + b.Property("ClientId") + .HasColumnType("uuid"); + + b.Property("ClientListenerPort") + .HasColumnType("integer"); + + b.Property("CurrentPatchVersion") + .HasColumnType("bytea"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisconnectOnUnknownPacket") + .HasColumnType("boolean"); + + b.Property("ListenerBacklog") + .HasColumnType("integer"); + + b.Property("MaxConnections") + .HasColumnType("integer"); + + b.Property("MaxConnectionsPerAddress") + .HasColumnType("integer"); + + b.Property("MaxFtpRequests") + .HasColumnType("integer"); + + b.Property("MaxIpRequests") + .HasColumnType("integer"); + + b.Property("MaxServerListRequests") + .HasColumnType("integer"); + + b.Property("MaximumReceiveSize") + .HasColumnType("smallint"); + + b.Property("PatchAddress") + .IsRequired() + .HasColumnType("text"); + + b.Property("ServerId") + .HasColumnType("smallint"); + + b.Property("Timeout") + .HasColumnType("interval"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ConnectServerDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConstValueAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AggregateType") + .HasColumnType("integer"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.Property("DefinitionId") + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Value") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("CharacterClassId"); + + b.HasIndex("DefinitionId"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ConstValueAttribute", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Chance") + .HasColumnType("double precision"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("ItemLevel") + .HasColumnType("smallint"); + + b.Property("ItemType") + .HasColumnType("integer"); + + b.Property("MaximumMonsterLevel") + .HasColumnType("smallint"); + + b.Property("MinimumMonsterLevel") + .HasColumnType("smallint"); + + b.Property("MonsterId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("MonsterId"); + + b.ToTable("DropItemGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroupItemDefinition", b => + { + b.Property("DropItemGroupId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("DropItemGroupId", "ItemDefinitionId"); + + b.HasIndex("ItemDefinitionId"); + + b.ToTable("DropItemGroupItemDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DuelConfigurationId") + .HasColumnType("uuid"); + + b.Property("FirstPlayerGateId") + .HasColumnType("uuid"); + + b.Property("Index") + .HasColumnType("smallint"); + + b.Property("SecondPlayerGateId") + .HasColumnType("uuid"); + + b.Property("SpectatorsGateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("DuelConfigurationId"); + + b.HasIndex("FirstPlayerGateId"); + + b.HasIndex("SecondPlayerGateId"); + + b.HasIndex("SpectatorsGateId"); + + b.ToTable("DuelArea", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EntranceFee") + .HasColumnType("integer"); + + b.Property("ExitId") + .HasColumnType("uuid"); + + b.Property("MaximumScore") + .HasColumnType("integer"); + + b.Property("MaximumSpectatorsPerDuelRoom") + .HasColumnType("integer"); + + b.Property("MinimumCharacterLevel") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ExitId"); + + b.ToTable("DuelConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.EnterGate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GameMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("LevelRequirement") + .HasColumnType("smallint"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("TargetGateId") + .HasColumnType("uuid"); + + b.Property("X1") + .HasColumnType("smallint"); + + b.Property("X2") + .HasColumnType("smallint"); + + b.Property("Y1") + .HasColumnType("smallint"); + + b.Property("Y2") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("GameMapDefinitionId"); + + b.HasIndex("TargetGateId"); + + b.ToTable("EnterGate", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Direction") + .HasColumnType("integer"); + + b.Property("IsSpawnGate") + .HasColumnType("boolean"); + + b.Property("MapId") + .HasColumnType("uuid"); + + b.Property("X1") + .HasColumnType("smallint"); + + b.Property("X2") + .HasColumnType("smallint"); + + b.Property("Y1") + .HasColumnType("smallint"); + + b.Property("Y2") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("MapId"); + + b.ToTable("ExitGate", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Friend", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Accepted") + .HasColumnType("boolean"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("FriendId") + .HasColumnType("uuid"); + + b.Property("RequestOpen") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasAlternateKey("CharacterId", "FriendId"); + + b.ToTable("Friend", "friend"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameClientDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Episode") + .HasColumnType("smallint"); + + b.Property("Language") + .HasColumnType("integer"); + + b.Property("Season") + .HasColumnType("smallint"); + + b.Property("Serial") + .HasColumnType("bytea"); + + b.Property("Version") + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.ToTable("GameClientDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AreaSkillHitsPlayer") + .HasColumnType("boolean"); + + b.Property("CastleSiegeConfigurationId") + .HasColumnType("uuid"); + + b.Property("CharacterNameRegex") + .HasColumnType("text"); + + b.Property("ClampMoneyOnPickup") + .HasColumnType("boolean"); + + b.Property("DamagePerOneItemDurability") + .HasColumnType("double precision"); + + b.Property("DamagePerOnePetDurability") + .HasColumnType("double precision"); + + b.Property("DuelConfigurationId") + .HasColumnType("uuid"); + + b.Property("ExcellentItemDropLevelDelta") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((byte)25); + + b.Property("ExperienceFormula") + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("if(level == 0, 0, if(level < 256, 10 * (level + 8) * (level - 1) * (level - 1), (10 * (level + 8) * (level - 1) * (level - 1)) + (1000 * (level - 247) * (level - 256) * (level - 256))))"); + + b.Property("ExperienceRate") + .HasColumnType("real"); + + b.Property("HitsPerOneItemDurability") + .HasColumnType("double precision"); + + b.Property("InfoRange") + .HasColumnType("smallint"); + + b.Property("ItemDropDuration") + .ValueGeneratedOnAdd() + .HasColumnType("interval") + .HasDefaultValue(new TimeSpan(0, 0, 1, 0, 0)); + + b.Property("LetterSendPrice") + .HasColumnType("integer"); + + b.Property("MasterExperienceFormula") + .ValueGeneratedOnAdd() + .HasColumnType("text") + .HasDefaultValue("(505 * level * level * level) + (35278500 * level) + (228045 * level * level)"); + + b.Property("MasterExperienceRate") + .HasColumnType("real"); + + b.Property("MaximumCharactersPerAccount") + .HasColumnType("smallint"); + + b.Property("MaximumInventoryMoney") + .HasColumnType("integer"); + + b.Property("MaximumItemOptionLevelDrop") + .HasColumnType("smallint"); + + b.Property("MaximumLetters") + .HasColumnType("integer"); + + b.Property("MaximumLevel") + .HasColumnType("smallint"); + + b.Property("MaximumMasterLevel") + .HasColumnType("smallint"); + + b.Property("MaximumPartySize") + .HasColumnType("smallint"); + + b.Property("MaximumPasswordLength") + .HasColumnType("integer"); + + b.Property("MaximumVaultMoney") + .HasColumnType("integer"); + + b.Property("MinimumMonsterLevelForMasterExperience") + .HasColumnType("smallint"); + + b.Property("PreventExperienceOverflow") + .HasColumnType("boolean"); + + b.Property("RecoveryInterval") + .HasColumnType("integer"); + + b.Property("ShouldDropMoney") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CastleSiegeConfigurationId") + .IsUnique(); + + b.HasIndex("DuelConfigurationId") + .IsUnique(); + + b.ToTable("GameConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BattleZoneId") + .HasColumnType("uuid"); + + b.Property("Discriminator") + .HasColumnType("integer"); + + b.Property("ExpMultiplier") + .HasColumnType("double precision"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("SafezoneMapId") + .HasColumnType("uuid"); + + b.Property("TerrainData") + .HasColumnType("bytea"); + + b.HasKey("Id"); + + b.HasIndex("BattleZoneId") + .IsUnique(); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("SafezoneMapId"); + + b.ToTable("GameMapDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinitionDropItemGroup", b => + { + b.Property("GameMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("DropItemGroupId") + .HasColumnType("uuid"); + + b.HasKey("GameMapDefinitionId", "DropItemGroupId"); + + b.HasIndex("DropItemGroupId"); + + b.ToTable("GameMapDefinitionDropItemGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MaximumPlayers") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.ToTable("GameServerConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfigurationGameMapDefinition", b => + { + b.Property("GameServerConfigurationId") + .HasColumnType("uuid"); + + b.Property("GameMapDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("GameServerConfigurationId", "GameMapDefinitionId"); + + b.HasIndex("GameMapDefinitionId"); + + b.ToTable("GameServerConfigurationGameMapDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExperienceRate") + .HasColumnType("real"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("PvpEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(true); + + b.Property("ServerConfigurationId") + .HasColumnType("uuid"); + + b.Property("ServerID") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("ServerConfigurationId"); + + b.ToTable("GameServerDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerEndpoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AlternativePublishedPort") + .HasColumnType("integer"); + + b.Property("ClientId") + .HasColumnType("uuid"); + + b.Property("GameServerDefinitionId") + .HasColumnType("uuid"); + + b.Property("NetworkPort") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("GameServerDefinitionId"); + + b.ToTable("GameServerEndpoint", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllianceGuildId") + .HasColumnType("uuid"); + + b.Property("HostilityId") + .HasColumnType("uuid"); + + b.Property("Logo") + .HasColumnType("bytea"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("character varying(8)"); + + b.Property("Notice") + .HasColumnType("text"); + + b.Property("Score") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AllianceGuildId"); + + b.HasIndex("HostilityId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Guild", "guild"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GuildMember", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("GuildId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildMember", "guild"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ItemOptionDefinitionId") + .HasColumnType("uuid"); + + b.Property("LevelType") + .HasColumnType("integer"); + + b.Property("Number") + .HasColumnType("integer"); + + b.Property("OptionTypeId") + .HasColumnType("uuid"); + + b.Property("PowerUpDefinitionId") + .HasColumnType("uuid"); + + b.Property("SubOptionType") + .HasColumnType("integer"); + + b.Property("Weight") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("ItemOptionDefinitionId"); + + b.HasIndex("OptionTypeId"); + + b.HasIndex("PowerUpDefinitionId") + .IsUnique(); + + b.ToTable("IncreasableItemOption", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DefinitionId") + .HasColumnType("uuid"); + + b.Property("Durability") + .HasColumnType("double precision"); + + b.Property("HasSkill") + .HasColumnType("boolean"); + + b.Property("ItemSlot") + .HasColumnType("smallint"); + + b.Property("ItemStorageId") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("smallint"); + + b.Property("PetExperience") + .HasColumnType("integer"); + + b.Property("SocketCount") + .HasColumnType("integer"); + + b.Property("StorePrice") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("DefinitionId"); + + b.HasIndex("ItemStorageId"); + + b.ToTable("Item", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AppearanceDataId") + .HasColumnType("uuid"); + + b.Property("DefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemSlot") + .HasColumnType("smallint"); + + b.Property("Level") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AppearanceDataId"); + + b.HasIndex("DefinitionId"); + + b.ToTable("ItemAppearance", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearanceItemOptionType", b => + { + b.Property("ItemAppearanceId") + .HasColumnType("uuid"); + + b.Property("ItemOptionTypeId") + .HasColumnType("uuid"); + + b.HasKey("ItemAppearanceId", "ItemOptionTypeId"); + + b.HasIndex("ItemOptionTypeId"); + + b.ToTable("ItemAppearanceItemOptionType", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemBasePowerUpDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AggregateType") + .HasColumnType("integer"); + + b.Property("BaseValue") + .HasColumnType("real"); + + b.Property("BonusPerLevelTableId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("TargetAttributeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("BonusPerLevelTableId"); + + b.HasIndex("ItemDefinitionId"); + + b.HasIndex("TargetAttributeId"); + + b.ToTable("ItemBasePowerUpDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCrafting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ItemCraftingHandlerClassName") + .IsRequired() + .HasColumnType("text"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("SimpleCraftingSettingsId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MonsterDefinitionId"); + + b.HasIndex("SimpleCraftingSettingsId") + .IsUnique(); + + b.ToTable("ItemCrafting", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddPercentage") + .HasColumnType("smallint"); + + b.Property("FailResult") + .HasColumnType("integer"); + + b.Property("MaximumAmount") + .HasColumnType("smallint"); + + b.Property("MaximumItemLevel") + .HasColumnType("smallint"); + + b.Property("MinimumAmount") + .HasColumnType("smallint"); + + b.Property("MinimumItemLevel") + .HasColumnType("smallint"); + + b.Property("NpcPriceDivisor") + .HasColumnType("integer"); + + b.Property("Reference") + .HasColumnType("smallint"); + + b.Property("SimpleCraftingSettingsId") + .HasColumnType("uuid"); + + b.Property("SuccessResult") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SimpleCraftingSettingsId"); + + b.ToTable("ItemCraftingRequiredItem", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItemItemDefinition", b => + { + b.Property("ItemCraftingRequiredItemId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("ItemCraftingRequiredItemId", "ItemDefinitionId"); + + b.HasIndex("ItemDefinitionId"); + + b.ToTable("ItemCraftingRequiredItemItemDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItemItemOptionType", b => + { + b.Property("ItemCraftingRequiredItemId") + .HasColumnType("uuid"); + + b.Property("ItemOptionTypeId") + .HasColumnType("uuid"); + + b.HasKey("ItemCraftingRequiredItemId", "ItemOptionTypeId"); + + b.HasIndex("ItemOptionTypeId"); + + b.ToTable("ItemCraftingRequiredItemItemOptionType", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingResultItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddLevel") + .HasColumnType("smallint"); + + b.Property("Durability") + .HasColumnType("smallint"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("RandomMaximumLevel") + .HasColumnType("smallint"); + + b.Property("RandomMinimumLevel") + .HasColumnType("smallint"); + + b.Property("Reference") + .HasColumnType("smallint"); + + b.Property("SimpleCraftingSettingsId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ItemDefinitionId"); + + b.HasIndex("SimpleCraftingSettingsId"); + + b.ToTable("ItemCraftingResultItem", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ConsumeEffectId") + .HasColumnType("uuid"); + + b.Property("DropLevel") + .HasColumnType("smallint"); + + b.Property("DropsFromMonsters") + .HasColumnType("boolean"); + + b.Property("Durability") + .HasColumnType("smallint"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Group") + .HasColumnType("smallint"); + + b.Property("Height") + .HasColumnType("smallint"); + + b.Property("IsAmmunition") + .HasColumnType("boolean"); + + b.Property("IsBoundToCharacter") + .HasColumnType("boolean"); + + b.Property("IsQuestItem") + .HasColumnType("boolean"); + + b.Property("ItemSlotId") + .HasColumnType("uuid"); + + b.Property("MaximumDropLevel") + .HasColumnType("smallint"); + + b.Property("MaximumItemLevel") + .HasColumnType("smallint"); + + b.Property("MaximumSockets") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("PetExperienceFormula") + .HasColumnType("text"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.Property("StorageLimitPerCharacter") + .HasColumnType("integer"); + + b.Property("Value") + .HasColumnType("integer"); + + b.Property("Width") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("ConsumeEffectId"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("ItemSlotId"); + + b.HasIndex("SkillId"); + + b.ToTable("ItemDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionCharacterClass", b => + { + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.HasKey("ItemDefinitionId", "CharacterClassId"); + + b.HasIndex("CharacterClassId"); + + b.ToTable("ItemDefinitionCharacterClass", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionItemOptionDefinition", b => + { + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemOptionDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("ItemDefinitionId", "ItemOptionDefinitionId"); + + b.HasIndex("ItemOptionDefinitionId"); + + b.ToTable("ItemDefinitionItemOptionDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionItemSetGroup", b => + { + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemSetGroupId") + .HasColumnType("uuid"); + + b.HasKey("ItemDefinitionId", "ItemSetGroupId"); + + b.HasIndex("ItemSetGroupId"); + + b.ToTable("ItemDefinitionItemSetGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Chance") + .HasColumnType("double precision"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DropEffect") + .HasColumnType("integer"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemLevel") + .HasColumnType("smallint"); + + b.Property("ItemType") + .HasColumnType("integer"); + + b.Property("MaximumLevel") + .HasColumnType("smallint"); + + b.Property("MaximumMonsterLevel") + .HasColumnType("smallint"); + + b.Property("MinimumLevel") + .HasColumnType("smallint"); + + b.Property("MinimumMonsterLevel") + .HasColumnType("smallint"); + + b.Property("MoneyAmount") + .HasColumnType("integer"); + + b.Property("MonsterId") + .HasColumnType("uuid"); + + b.Property("RequiredCharacterLevel") + .HasColumnType("smallint"); + + b.Property("SourceItemLevel") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("ItemDefinitionId"); + + b.HasIndex("MonsterId"); + + b.ToTable("ItemDropItemGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroupItemDefinition", b => + { + b.Property("ItemDropItemGroupId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("ItemDropItemGroupId", "ItemDefinitionId"); + + b.HasIndex("ItemDefinitionId"); + + b.ToTable("ItemDropItemGroupItemDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemItemOfItemSet", b => + { + b.Property("ItemId") + .HasColumnType("uuid"); + + b.Property("ItemOfItemSetId") + .HasColumnType("uuid"); + + b.HasKey("ItemId", "ItemOfItemSetId"); + + b.HasIndex("ItemOfItemSetId"); + + b.ToTable("ItemItemOfItemSet", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemLevelBonusTable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ItemLevelBonusTable", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOfItemSet", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AncientSetDiscriminator") + .HasColumnType("integer"); + + b.Property("BonusOptionId") + .HasColumnType("uuid"); + + b.Property("ItemDefinitionId") + .HasColumnType("uuid"); + + b.Property("ItemSetGroupId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("BonusOptionId"); + + b.HasIndex("ItemDefinitionId"); + + b.HasIndex("ItemSetGroupId"); + + b.ToTable("ItemOfItemSet", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Number") + .HasColumnType("integer"); + + b.Property("OptionTypeId") + .HasColumnType("uuid"); + + b.Property("PowerUpDefinitionId") + .HasColumnType("uuid"); + + b.Property("SubOptionType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("OptionTypeId"); + + b.HasIndex("PowerUpDefinitionId") + .IsUnique(); + + b.ToTable("ItemOption", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionCombinationBonus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AppliesMultipleTimes") + .HasColumnType("boolean"); + + b.Property("BonusId") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Number") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("BonusId") + .IsUnique(); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ItemOptionCombinationBonus", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddChance") + .HasColumnType("real"); + + b.Property("AddsRandomly") + .HasColumnType("boolean"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("MaximumOptionsPerItem") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ItemOptionDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionLink", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("ItemId") + .HasColumnType("uuid"); + + b.Property("ItemOptionId") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ItemId"); + + b.HasIndex("ItemOptionId"); + + b.ToTable("ItemOptionLink", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionOfLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IncreasableItemOptionId") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("PowerUpDefinitionId") + .HasColumnType("uuid"); + + b.Property("RequiredItemLevel") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IncreasableItemOptionId"); + + b.HasIndex("PowerUpDefinitionId") + .IsUnique(); + + b.ToTable("ItemOptionOfLevel", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("IsVisible") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ItemOptionType", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSetGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AlwaysApplies") + .HasColumnType("boolean"); + + b.Property("CountDistinct") + .HasColumnType("boolean"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("MinimumItemCount") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("OptionsId") + .HasColumnType("uuid"); + + b.Property("SetLevel") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("OptionsId"); + + b.ToTable("ItemSetGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSlotType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("RawItemSlots") + .HasColumnType("text") + .HasColumnName("ItemSlots") + .HasJsonPropertyName("itemSlots"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("ItemSlotType", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Money") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("ItemStorage", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.JewelMix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("MixedJewelId") + .HasColumnType("uuid"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("SingleJewelId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("MixedJewelId"); + + b.HasIndex("SingleJewelId"); + + b.ToTable("JewelMix", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterBody", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Animation") + .HasColumnType("smallint"); + + b.Property("HeaderId") + .HasColumnType("uuid"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Rotation") + .HasColumnType("smallint"); + + b.Property("SenderAppearanceId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("HeaderId"); + + b.HasIndex("SenderAppearanceId") + .IsUnique(); + + b.ToTable("LetterBody", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterHeader", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("LetterDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ReadFlag") + .HasColumnType("boolean"); + + b.Property("ReceiverId") + .HasColumnType("uuid"); + + b.Property("SenderName") + .HasColumnType("text"); + + b.Property("Subject") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ReceiverId"); + + b.ToTable("LetterHeader", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LevelBonus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AdditionalValue") + .HasColumnType("real"); + + b.Property("ItemLevelBonusTableId") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ItemLevelBonusTableId"); + + b.ToTable("LevelBonus", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChanceId") + .HasColumnType("uuid"); + + b.Property("ChancePvpId") + .HasColumnType("uuid"); + + b.Property("DurationDependsOnTargetLevel") + .HasColumnType("boolean"); + + b.Property("DurationId") + .HasColumnType("uuid"); + + b.Property("DurationPvpId") + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("InformObservers") + .HasColumnType("boolean"); + + b.Property("MonsterTargetLevelDivisor") + .HasColumnType("real"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("PlayerTargetLevelDivisor") + .HasColumnType("real"); + + b.Property("SendDuration") + .HasColumnType("boolean"); + + b.Property("StopByDeath") + .HasColumnType("boolean"); + + b.Property("SubType") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("ChanceId") + .IsUnique(); + + b.HasIndex("ChancePvpId") + .IsUnique(); + + b.HasIndex("DurationId") + .IsUnique(); + + b.HasIndex("DurationPvpId") + .IsUnique(); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("MagicEffectDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Aggregation") + .HasColumnType("integer"); + + b.Property("DisplayValueFormula") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExtendsDuration") + .HasColumnType("boolean"); + + b.Property("MaximumLevel") + .HasColumnType("smallint"); + + b.Property("MinimumLevel") + .HasColumnType("smallint"); + + b.Property("Rank") + .HasColumnType("smallint"); + + b.Property("ReplacedSkillId") + .HasColumnType("uuid"); + + b.Property("RootId") + .HasColumnType("uuid"); + + b.Property("TargetAttributeId") + .HasColumnType("uuid"); + + b.Property("ValueFormula") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ReplacedSkillId"); + + b.HasIndex("RootId"); + + b.HasIndex("TargetAttributeId"); + + b.ToTable("MasterSkillDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinitionSkill", b => + { + b.Property("MasterSkillDefinitionId") + .HasColumnType("uuid"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.HasKey("MasterSkillDefinitionId", "SkillId"); + + b.HasIndex("SkillId"); + + b.ToTable("MasterSkillDefinitionSkill", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillRoot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("MasterSkillRoot", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameChangeEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("MiniGameDefinitionId") + .HasColumnType("uuid"); + + b.Property("MinimumTargetLevel") + .HasColumnType("smallint"); + + b.Property("MultiplyKillsByPlayers") + .HasColumnType("boolean"); + + b.Property("NumberOfKills") + .HasColumnType("smallint"); + + b.Property("SpawnAreaId") + .HasColumnType("uuid"); + + b.Property("Target") + .HasColumnType("integer"); + + b.Property("TargetDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MiniGameDefinitionId"); + + b.HasIndex("SpawnAreaId") + .IsUnique(); + + b.HasIndex("TargetDefinitionId"); + + b.ToTable("MiniGameChangeEvent", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AllowParty") + .HasColumnType("boolean"); + + b.Property("ArePlayerKillersAllowedToEnter") + .HasColumnType("boolean"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("EnterDuration") + .HasColumnType("interval"); + + b.Property("EntranceFee") + .HasColumnType("integer"); + + b.Property("EntranceId") + .HasColumnType("uuid"); + + b.Property("ExitDuration") + .HasColumnType("interval"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("GameDuration") + .HasColumnType("interval"); + + b.Property("GameLevel") + .HasColumnType("smallint"); + + b.Property("MapCreationPolicy") + .HasColumnType("integer"); + + b.Property("MaximumCharacterLevel") + .HasColumnType("integer"); + + b.Property("MaximumPlayerCount") + .HasColumnType("integer"); + + b.Property("MaximumSpecialCharacterLevel") + .HasColumnType("integer"); + + b.Property("MinimumCharacterLevel") + .HasColumnType("integer"); + + b.Property("MinimumSpecialCharacterLevel") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("RequiresMasterClass") + .HasColumnType("boolean"); + + b.Property("SaveRankingStatistics") + .HasColumnType("boolean"); + + b.Property("TicketItemId") + .HasColumnType("uuid"); + + b.Property("TicketItemLevel") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EntranceId"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("TicketItemId"); + + b.ToTable("MiniGameDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameRankingEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("GameInstanceId") + .HasColumnType("uuid"); + + b.Property("MiniGameId") + .HasColumnType("uuid"); + + b.Property("Rank") + .HasColumnType("integer"); + + b.Property("Score") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId"); + + b.HasIndex("MiniGameId"); + + b.ToTable("MiniGameRankingEntry", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameReward", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ItemRewardId") + .HasColumnType("uuid"); + + b.Property("MiniGameDefinitionId") + .HasColumnType("uuid"); + + b.Property("Rank") + .HasColumnType("integer"); + + b.Property("RequiredKillId") + .HasColumnType("uuid"); + + b.Property("RequiredSuccess") + .HasColumnType("integer"); + + b.Property("RewardAmount") + .HasColumnType("integer"); + + b.Property("RewardType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ItemRewardId"); + + b.HasIndex("MiniGameDefinitionId"); + + b.HasIndex("RequiredKillId"); + + b.ToTable("MiniGameReward", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameSpawnWave", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("EndTime") + .HasColumnType("interval"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("MiniGameDefinitionId") + .HasColumnType("uuid"); + + b.Property("StartTime") + .HasColumnType("interval"); + + b.Property("WaveNumber") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("MiniGameDefinitionId"); + + b.ToTable("MiniGameSpawnWave", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameTerrainChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("EndX") + .HasColumnType("smallint"); + + b.Property("EndY") + .HasColumnType("smallint"); + + b.Property("IsClientUpdateRequired") + .HasColumnType("boolean"); + + b.Property("MiniGameChangeEventId") + .HasColumnType("uuid"); + + b.Property("SetTerrainAttribute") + .HasColumnType("boolean"); + + b.Property("StartX") + .HasColumnType("smallint"); + + b.Property("StartY") + .HasColumnType("smallint"); + + b.Property("TerrainAttribute") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("MiniGameChangeEventId"); + + b.ToTable("MiniGameTerrainChange", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttributeDefinitionId") + .HasColumnType("uuid"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("Value") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("AttributeDefinitionId"); + + b.HasIndex("MonsterDefinitionId"); + + b.ToTable("MonsterAttribute", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttackDelay") + .HasColumnType("interval"); + + b.Property("AttackRange") + .HasColumnType("smallint"); + + b.Property("AttackSkillId") + .HasColumnType("uuid"); + + b.Property("Attribute") + .HasColumnType("smallint"); + + b.Property("Designation") + .IsRequired() + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("IntelligenceTypeName") + .HasColumnType("text"); + + b.Property("MerchantStoreId") + .HasColumnType("uuid"); + + b.Property("MoveDelay") + .HasColumnType("interval"); + + b.Property("MoveRange") + .HasColumnType("smallint"); + + b.Property("NpcWindow") + .HasColumnType("integer"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("NumberOfMaximumItemDrops") + .HasColumnType("integer"); + + b.Property("ObjectKind") + .HasColumnType("integer"); + + b.Property("RespawnDelay") + .HasColumnType("interval"); + + b.Property("ViewRange") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("AttackSkillId"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("MerchantStoreId") + .IsUnique(); + + b.ToTable("MonsterDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinitionDropItemGroup", b => + { + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("DropItemGroupId") + .HasColumnType("uuid"); + + b.HasKey("MonsterDefinitionId", "DropItemGroupId"); + + b.HasIndex("DropItemGroupId"); + + b.ToTable("MonsterDefinitionDropItemGroup", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterSpawnArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Direction") + .HasColumnType("integer"); + + b.Property("GameMapId") + .HasColumnType("uuid"); + + b.Property("MaximumHealthOverride") + .HasColumnType("integer"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("Quantity") + .HasColumnType("smallint"); + + b.Property("SpawnTrigger") + .HasColumnType("integer"); + + b.Property("WaveNumber") + .HasColumnType("smallint"); + + b.Property("X1") + .HasColumnType("smallint"); + + b.Property("X2") + .HasColumnType("smallint"); + + b.Property("Y1") + .HasColumnType("smallint"); + + b.Property("Y2") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("GameMapId"); + + b.HasIndex("MonsterDefinitionId"); + + b.ToTable("MonsterSpawnArea", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PlugInConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CustomConfiguration") + .HasColumnType("text"); + + b.Property("CustomPlugInSource") + .HasColumnType("text"); + + b.Property("ExternalAssemblyName") + .HasColumnType("text"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("TypeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.ToTable("PlugInConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("BoostId") + .HasColumnType("uuid"); + + b.Property("GameMapDefinitionId") + .HasColumnType("uuid"); + + b.Property("MagicEffectDefinitionId") + .HasColumnType("uuid"); + + b.Property("MagicEffectDefinitionId1") + .HasColumnType("uuid"); + + b.Property("TargetAttributeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("BoostId") + .IsUnique(); + + b.HasIndex("GameMapDefinitionId"); + + b.HasIndex("MagicEffectDefinitionId"); + + b.HasIndex("MagicEffectDefinitionId1"); + + b.HasIndex("TargetAttributeId"); + + b.ToTable("PowerUpDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AggregateType") + .HasColumnType("integer"); + + b.Property("MaximumValue") + .HasColumnType("real"); + + b.Property("Value") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.ToTable("PowerUpDefinitionValue", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Group") + .HasColumnType("smallint"); + + b.Property("MaximumCharacterLevel") + .HasColumnType("integer"); + + b.Property("MinimumCharacterLevel") + .HasColumnType("integer"); + + b.Property("MonsterDefinitionId") + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("QualifiedCharacterId") + .HasColumnType("uuid"); + + b.Property("QuestGiverId") + .HasColumnType("uuid"); + + b.Property("RefuseNumber") + .HasColumnType("smallint"); + + b.Property("Repeatable") + .HasColumnType("boolean"); + + b.Property("RequiredStartMoney") + .HasColumnType("integer"); + + b.Property("RequiresClientAction") + .HasColumnType("boolean"); + + b.Property("StartingNumber") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.HasIndex("MonsterDefinitionId"); + + b.HasIndex("QualifiedCharacterId"); + + b.HasIndex("QuestGiverId"); + + b.ToTable("QuestDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestItemRequirement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("DropItemGroupId") + .HasColumnType("uuid"); + + b.Property("ItemId") + .HasColumnType("uuid"); + + b.Property("MinimumNumber") + .HasColumnType("integer"); + + b.Property("QuestDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("DropItemGroupId"); + + b.HasIndex("ItemId"); + + b.HasIndex("QuestDefinitionId"); + + b.ToTable("QuestItemRequirement", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestMonsterKillRequirement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MinimumNumber") + .HasColumnType("integer"); + + b.Property("MonsterId") + .HasColumnType("uuid"); + + b.Property("QuestDefinitionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MonsterId"); + + b.HasIndex("QuestDefinitionId"); + + b.ToTable("QuestMonsterKillRequirement", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestMonsterKillRequirementState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CharacterQuestStateId") + .HasColumnType("uuid"); + + b.Property("KillCount") + .HasColumnType("integer"); + + b.Property("RequirementId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CharacterQuestStateId"); + + b.HasIndex("RequirementId"); + + b.ToTable("QuestMonsterKillRequirementState", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestReward", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttributeRewardId") + .HasColumnType("uuid"); + + b.Property("ItemRewardId") + .HasColumnType("uuid"); + + b.Property("QuestDefinitionId") + .HasColumnType("uuid"); + + b.Property("RewardType") + .HasColumnType("integer"); + + b.Property("SkillRewardId") + .HasColumnType("uuid"); + + b.Property("Value") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AttributeRewardId"); + + b.HasIndex("ItemRewardId") + .IsUnique(); + + b.HasIndex("QuestDefinitionId"); + + b.HasIndex("SkillRewardId"); + + b.ToTable("QuestReward", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Rectangle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("X1") + .HasColumnType("smallint"); + + b.Property("X2") + .HasColumnType("smallint"); + + b.Property("Y1") + .HasColumnType("smallint"); + + b.Property("Y2") + .HasColumnType("smallint"); + + b.HasKey("Id"); + + b.ToTable("Rectangle", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SimpleCraftingSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MaximumSuccessPercent") + .HasColumnType("smallint"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("MoneyPerFinalSuccessPercentage") + .HasColumnType("integer"); + + b.Property("MultipleAllowed") + .HasColumnType("boolean"); + + b.Property("NpcPriceDivisor") + .HasColumnType("integer"); + + b.Property("ResultItemExcellentOptionChance") + .HasColumnType("smallint"); + + b.Property("ResultItemLuckOptionChance") + .HasColumnType("smallint"); + + b.Property("ResultItemMaxExcOptionCount") + .HasColumnType("smallint"); + + b.Property("ResultItemSelect") + .HasColumnType("integer"); + + b.Property("ResultItemSkillChance") + .HasColumnType("smallint"); + + b.Property("SuccessPercent") + .HasColumnType("smallint"); + + b.Property("SuccessPercentageAdditionForAncientItem") + .HasColumnType("integer"); + + b.Property("SuccessPercentageAdditionForExcellentItem") + .HasColumnType("integer"); + + b.Property("SuccessPercentageAdditionForGuardianItem") + .HasColumnType("integer"); + + b.Property("SuccessPercentageAdditionForLuck") + .HasColumnType("integer"); + + b.Property("SuccessPercentageAdditionForSocketItem") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("SimpleCraftingSettings", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AreaSkillSettingsId") + .HasColumnType("uuid"); + + b.Property("AttackDamage") + .HasColumnType("integer"); + + b.Property("DamageType") + .HasColumnType("integer"); + + b.Property("ElementalModifierTargetId") + .HasColumnType("uuid"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("ImplicitTargetRange") + .HasColumnType("smallint"); + + b.Property("MagicEffectDefId") + .HasColumnType("uuid"); + + b.Property("MasterDefinitionId") + .HasColumnType("uuid"); + + b.Property("MovesTarget") + .HasColumnType("boolean"); + + b.Property("MovesToTarget") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Number") + .HasColumnType("smallint"); + + b.Property("NumberOfHitsPerAttack") + .HasColumnType("smallint"); + + b.Property("Range") + .HasColumnType("smallint"); + + b.Property("SkillType") + .HasColumnType("integer"); + + b.Property("SkipElementalModifier") + .HasColumnType("boolean"); + + b.Property("Target") + .HasColumnType("integer"); + + b.Property("TargetRestriction") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AreaSkillSettingsId") + .IsUnique(); + + b.HasIndex("ElementalModifierTargetId"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("MagicEffectDefId"); + + b.HasIndex("MasterDefinitionId") + .IsUnique(); + + b.ToTable("Skill", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillCharacterClass", b => + { + b.Property("SkillId") + .HasColumnType("uuid"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.HasKey("SkillId", "CharacterClassId"); + + b.HasIndex("CharacterClassId"); + + b.ToTable("SkillCharacterClass", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("MaximumCompletionTime") + .HasColumnType("interval"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("SkillComboDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboStep", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("IsFinalStep") + .HasColumnType("boolean"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("SkillComboDefinitionId") + .HasColumnType("uuid"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("SkillComboDefinitionId"); + + b.HasIndex("SkillId"); + + b.ToTable("SkillComboStep", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("SkillId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("CharacterId"); + + b.HasIndex("SkillId"); + + b.ToTable("SkillEntry", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.StatAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AccountId") + .HasColumnType("uuid"); + + b.Property("CharacterId") + .HasColumnType("uuid"); + + b.Property("DefinitionId") + .HasColumnType("uuid"); + + b.Property("Value") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("CharacterId"); + + b.HasIndex("DefinitionId"); + + b.ToTable("StatAttribute", "data"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.StatAttributeDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AttributeId") + .HasColumnType("uuid"); + + b.Property("BaseValue") + .HasColumnType("real"); + + b.Property("CharacterClassId") + .HasColumnType("uuid"); + + b.Property("IncreasableByPlayer") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AttributeId"); + + b.HasIndex("CharacterClassId"); + + b.ToTable("StatAttributeDefinition", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SystemConfiguration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AutoStart") + .HasColumnType("boolean"); + + b.Property("AutoUpdateSchema") + .HasColumnType("boolean"); + + b.Property("IpResolver") + .HasColumnType("integer"); + + b.Property("IpResolverParameter") + .HasColumnType("text"); + + b.Property("ReadConsoleInput") + .HasColumnType("boolean"); + + b.Property("TimeZoneId") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("SystemConfiguration", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.WarpInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Costs") + .HasColumnType("integer"); + + b.Property("GameConfigurationId") + .HasColumnType("uuid"); + + b.Property("GateId") + .HasColumnType("uuid"); + + b.Property("Index") + .HasColumnType("integer"); + + b.Property("LevelRequirement") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GameConfigurationId"); + + b.HasIndex("GateId"); + + b.ToTable("WarpInfo", "config"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", "RawVault") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", "VaultId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawVault"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AccountCharacterClass", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", "Account") + .WithMany("JoinedUnlockedCharacterClasses") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "CharacterClass") + .WithMany() + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("CharacterClass"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "RawCharacterClass") + .WithMany() + .HasForeignKey("CharacterClassId"); + + b.Navigation("RawCharacterClass"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawAttributes") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRelationship", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", null) + .WithMany("RawAttributeCombinations") + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawGlobalAttributeCombinations") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawInputAttribute") + .WithMany() + .HasForeignKey("InputAttributeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawOperandAttribute") + .WithMany() + .HasForeignKey("OperandAttributeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", null) + .WithMany("RawRelatedValues") + .HasForeignKey("PowerUpDefinitionValueId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", null) + .WithMany("RawAttributeRelationships") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawTargetAttribute") + .WithMany() + .HasForeignKey("TargetAttributeId"); + + b.Navigation("RawInputAttribute"); + + b.Navigation("RawOperandAttribute"); + + b.Navigation("RawTargetAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRequirement", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawAttribute") + .WithMany() + .HasForeignKey("AttributeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", null) + .WithMany("RawMapRequirements") + .HasForeignKey("GameMapDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", null) + .WithMany("RawRequirements") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", null) + .WithMany("RawConsumeRequirements") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", null) + .WithMany("RawRequirements") + .HasForeignKey("SkillId1") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Rectangle", "RawGround") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", "GroundId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Rectangle", "RawLeftGoal") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", "LeftGoalId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Rectangle", "RawRightGoal") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", "RightGoalId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawGround"); + + b.Navigation("RawLeftGoal"); + + b.Navigation("RawRightGoal"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Buff", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "RawMagicEffectDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.Buff", "MagicEffectDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", null) + .WithMany("RawBuffs") + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawMagicEffectDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeZoneDefinition", "RawAttackRespawnArea") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", "AttackRespawnAreaId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawCastleSiegeMapDefinition") + .WithMany() + .HasForeignKey("CastleSiegeMapDefinitionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeZoneDefinition", "RawDefenseRespawnArea") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", "DefenseRespawnAreaId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawLandOfTrialsMapDefinition") + .WithMany() + .HasForeignKey("LandOfTrialsMapDefinitionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawRewardItemDefinition") + .WithMany() + .HasForeignKey("RewardItemDefinitionId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawSignOfLordItemDefinition") + .WithMany() + .HasForeignKey("SignOfLordItemDefinitionId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("RawAttackRespawnArea"); + + b.Navigation("RawCastleSiegeMapDefinition"); + + b.Navigation("RawDefenseRespawnArea"); + + b.Navigation("RawLandOfTrialsMapDefinition"); + + b.Navigation("RawRewardItemDefinition"); + + b.Navigation("RawSignOfLordItemDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeData", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", null) + .WithMany() + .HasForeignKey("OwnerGuildId") + .OnDelete(DeleteBehavior.SetNull); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeGuildRegistration", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", null) + .WithMany() + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeNpcDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawNpcDefinitions") + .HasForeignKey("CastleSiegeConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawMonsterDefinition") + .WithMany() + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("RawMonsterDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeNpcState", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeData", null) + .WithMany("RawNpcStates") + .HasForeignKey("CastleSiegeDataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeStateScheduleEntry", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawStateSchedule") + .HasForeignKey("CastleSiegeConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeUpgradeDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawGateDefenseUpgrades") + .HasForeignKey("CastleSiegeConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawGateLifeUpgrades") + .HasForeignKey("CastleSiegeConfigurationId1") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_CastleSiegeUpgradeDefinition_CastleSiegeConfiguration_Cast~1"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawStatueDefenseUpgrades") + .HasForeignKey("CastleSiegeConfigurationId2") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_CastleSiegeUpgradeDefinition_CastleSiegeConfiguration_Cast~2"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawStatueLifeUpgrades") + .HasForeignKey("CastleSiegeConfigurationId3") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_CastleSiegeUpgradeDefinition_CastleSiegeConfiguration_Cast~3"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawStatueRegenUpgrades") + .HasForeignKey("CastleSiegeConfigurationId4") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_CastleSiegeUpgradeDefinition_CastleSiegeConfiguration_Cast~4"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeZoneDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawAttackMachineZones") + .HasForeignKey("CastleSiegeConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", null) + .WithMany("RawDefenseMachineZones") + .HasForeignKey("CastleSiegeConfigurationId1") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_CastleSiegeZoneDefinition_CastleSiegeConfiguration_CastleS~1"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", null) + .WithMany("RawCharacters") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "RawCharacterClass") + .WithMany() + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawCurrentMap") + .WithMany() + .HasForeignKey("CurrentMapId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", "RawInventory") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", "InventoryId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawCharacterClass"); + + b.Navigation("RawCurrentMap"); + + b.Navigation("RawInventory"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboDefinition", "RawComboDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "ComboDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawCharacterClasses") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawHomeMap") + .WithMany() + .HasForeignKey("HomeMapId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "RawNextGenerationClass") + .WithMany() + .HasForeignKey("NextGenerationClassId"); + + b.Navigation("RawComboDefinition"); + + b.Navigation("RawHomeMap"); + + b.Navigation("RawNextGenerationClass"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterDropItemGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", "Character") + .WithMany("JoinedDropItemGroups") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "DropItemGroup") + .WithMany() + .HasForeignKey("DropItemGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + + b.Navigation("DropItemGroup"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterQuestState", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", "RawActiveQuest") + .WithMany() + .HasForeignKey("ActiveQuestId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", null) + .WithMany("RawQuestStates") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", "RawLastFinishedQuest") + .WithMany() + .HasForeignKey("LastFinishedQuestId"); + + b.Navigation("RawActiveQuest"); + + b.Navigation("RawLastFinishedQuest"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerEndpoint", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerDefinition", null) + .WithMany("RawEndpoints") + .HasForeignKey("ChatServerDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameClientDefinition", "RawClient") + .WithMany() + .HasForeignKey("ClientId"); + + b.Navigation("RawClient"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CombinationBonusRequirement", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionCombinationBonus", null) + .WithMany("RawRequirements") + .HasForeignKey("ItemOptionCombinationBonusId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", "RawOptionType") + .WithMany() + .HasForeignKey("OptionTypeId"); + + b.Navigation("RawOptionType"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConnectServerDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameClientDefinition", "RawClient") + .WithMany() + .HasForeignKey("ClientId"); + + b.Navigation("RawClient"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConstValueAttribute", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "CharacterClass") + .WithMany("RawBaseAttributeValues") + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawDefinition") + .WithMany() + .HasForeignKey("DefinitionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", "GameConfiguration") + .WithMany("RawGlobalBaseAttributeValues") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("CharacterClass"); + + b.Navigation("GameConfiguration"); + + b.Navigation("RawDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawDropItemGroups") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawMonster") + .WithMany() + .HasForeignKey("MonsterId"); + + b.Navigation("RawMonster"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroupItemDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "DropItemGroup") + .WithMany("JoinedPossibleItems") + .HasForeignKey("DropItemGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany() + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DropItemGroup"); + + b.Navigation("ItemDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelArea", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", null) + .WithMany("RawDuelAreas") + .HasForeignKey("DuelConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawFirstPlayerGate") + .WithMany() + .HasForeignKey("FirstPlayerGateId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawSecondPlayerGate") + .WithMany() + .HasForeignKey("SecondPlayerGateId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawSpectatorsGate") + .WithMany() + .HasForeignKey("SpectatorsGateId"); + + b.Navigation("RawFirstPlayerGate"); + + b.Navigation("RawSecondPlayerGate"); + + b.Navigation("RawSpectatorsGate"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawExit") + .WithMany() + .HasForeignKey("ExitId"); + + b.Navigation("RawExit"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.EnterGate", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", null) + .WithMany("RawEnterGates") + .HasForeignKey("GameMapDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawTargetGate") + .WithMany() + .HasForeignKey("TargetGateId"); + + b.Navigation("RawTargetGate"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawMap") + .WithMany("RawExitGates") + .HasForeignKey("MapId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawMap"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", "RawCastleSiegeConfiguration") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", "CastleSiegeConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", "RawDuelConfiguration") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", "DuelConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawCastleSiegeConfiguration"); + + b.Navigation("RawDuelConfiguration"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", "RawBattleZone") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "BattleZoneId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawMaps") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawSafezoneMap") + .WithMany() + .HasForeignKey("SafezoneMapId"); + + b.Navigation("RawBattleZone"); + + b.Navigation("RawSafezoneMap"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinitionDropItemGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "DropItemGroup") + .WithMany() + .HasForeignKey("DropItemGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "GameMapDefinition") + .WithMany("JoinedDropItemGroups") + .HasForeignKey("GameMapDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DropItemGroup"); + + b.Navigation("GameMapDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfigurationGameMapDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "GameMapDefinition") + .WithMany() + .HasForeignKey("GameMapDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfiguration", "GameServerConfiguration") + .WithMany("JoinedMaps") + .HasForeignKey("GameServerConfigurationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GameMapDefinition"); + + b.Navigation("GameServerConfiguration"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", "RawGameConfiguration") + .WithMany() + .HasForeignKey("GameConfigurationId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfiguration", "RawServerConfiguration") + .WithMany() + .HasForeignKey("ServerConfigurationId"); + + b.Navigation("RawGameConfiguration"); + + b.Navigation("RawServerConfiguration"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerEndpoint", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameClientDefinition", "RawClient") + .WithMany() + .HasForeignKey("ClientId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerDefinition", null) + .WithMany("RawEndpoints") + .HasForeignKey("GameServerDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawClient"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", "RawAllianceGuild") + .WithMany() + .HasForeignKey("AllianceGuildId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", "RawHostility") + .WithMany() + .HasForeignKey("HostilityId"); + + b.Navigation("RawAllianceGuild"); + + b.Navigation("RawHostility"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GuildMember", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", null) + .WithMany("RawMembers") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", "Character") + .WithMany() + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Character"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", null) + .WithMany("RawPossibleOptions") + .HasForeignKey("ItemOptionDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", "RawOptionType") + .WithMany() + .HasForeignKey("OptionTypeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", "RawPowerUpDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", "PowerUpDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawOptionType"); + + b.Navigation("RawPowerUpDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawDefinition") + .WithMany() + .HasForeignKey("DefinitionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", "RawItemStorage") + .WithMany("RawItems") + .HasForeignKey("ItemStorageId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawDefinition"); + + b.Navigation("RawItemStorage"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearance", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", null) + .WithMany("RawEquippedItems") + .HasForeignKey("AppearanceDataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawDefinition") + .WithMany() + .HasForeignKey("DefinitionId"); + + b.Navigation("RawDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearanceItemOptionType", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearance", "ItemAppearance") + .WithMany("JoinedVisibleOptions") + .HasForeignKey("ItemAppearanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", "ItemOptionType") + .WithMany() + .HasForeignKey("ItemOptionTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemAppearance"); + + b.Navigation("ItemOptionType"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemBasePowerUpDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemLevelBonusTable", "RawBonusPerLevelTable") + .WithMany() + .HasForeignKey("BonusPerLevelTableId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", null) + .WithMany("RawBasePowerUpAttributes") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawTargetAttribute") + .WithMany() + .HasForeignKey("TargetAttributeId"); + + b.Navigation("RawBonusPerLevelTable"); + + b.Navigation("RawTargetAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCrafting", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", null) + .WithMany("RawItemCraftings") + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.SimpleCraftingSettings", "RawSimpleCraftingSettings") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCrafting", "SimpleCraftingSettingsId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawSimpleCraftingSettings"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItem", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.SimpleCraftingSettings", null) + .WithMany("RawRequiredItems") + .HasForeignKey("SimpleCraftingSettingsId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItemItemDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItem", "ItemCraftingRequiredItem") + .WithMany("JoinedPossibleItems") + .HasForeignKey("ItemCraftingRequiredItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany() + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemCraftingRequiredItem"); + + b.Navigation("ItemDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItemItemOptionType", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItem", "ItemCraftingRequiredItem") + .WithMany("JoinedRequiredItemOptions") + .HasForeignKey("ItemCraftingRequiredItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", "ItemOptionType") + .WithMany() + .HasForeignKey("ItemOptionTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemCraftingRequiredItem"); + + b.Navigation("ItemOptionType"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingResultItem", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawItemDefinition") + .WithMany() + .HasForeignKey("ItemDefinitionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.SimpleCraftingSettings", null) + .WithMany("RawResultItems") + .HasForeignKey("SimpleCraftingSettingsId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawItemDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "RawConsumeEffect") + .WithMany() + .HasForeignKey("ConsumeEffectId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItems") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSlotType", "RawItemSlot") + .WithMany() + .HasForeignKey("ItemSlotId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawSkill") + .WithMany() + .HasForeignKey("SkillId"); + + b.Navigation("RawConsumeEffect"); + + b.Navigation("RawItemSlot"); + + b.Navigation("RawSkill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionCharacterClass", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "CharacterClass") + .WithMany() + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany("JoinedQualifiedCharacters") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CharacterClass"); + + b.Navigation("ItemDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionItemOptionDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany("JoinedPossibleItemOptions") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", "ItemOptionDefinition") + .WithMany() + .HasForeignKey("ItemOptionDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemDefinition"); + + b.Navigation("ItemOptionDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinitionItemSetGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany("JoinedPossibleItemSetGroups") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSetGroup", "ItemSetGroup") + .WithMany() + .HasForeignKey("ItemSetGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemDefinition"); + + b.Navigation("ItemSetGroup"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", null) + .WithMany("RawDropItems") + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawMonster") + .WithMany() + .HasForeignKey("MonsterId"); + + b.Navigation("RawMonster"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroupItemDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "ItemDefinition") + .WithMany() + .HasForeignKey("ItemDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroup", "ItemDropItemGroup") + .WithMany("JoinedPossibleItems") + .HasForeignKey("ItemDropItemGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ItemDefinition"); + + b.Navigation("ItemDropItemGroup"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemItemOfItemSet", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", "Item") + .WithMany("JoinedItemSetGroups") + .HasForeignKey("ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOfItemSet", "ItemOfItemSet") + .WithMany() + .HasForeignKey("ItemOfItemSetId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("ItemOfItemSet"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemLevelBonusTable", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemLevelBonusTables") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOfItemSet", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", "RawBonusOption") + .WithMany() + .HasForeignKey("BonusOptionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawItemDefinition") + .WithMany() + .HasForeignKey("ItemDefinitionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSetGroup", "RawItemSetGroup") + .WithMany("RawItems") + .HasForeignKey("ItemSetGroupId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawBonusOption"); + + b.Navigation("RawItemDefinition"); + + b.Navigation("RawItemSetGroup"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOption", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", "RawOptionType") + .WithMany() + .HasForeignKey("OptionTypeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", "RawPowerUpDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOption", "PowerUpDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawOptionType"); + + b.Navigation("RawPowerUpDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionCombinationBonus", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", "RawBonus") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionCombinationBonus", "BonusId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemOptionCombinationBonuses") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawBonus"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemOptions") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionLink", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", null) + .WithMany("RawItemOptions") + .HasForeignKey("ItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", "RawItemOption") + .WithMany() + .HasForeignKey("ItemOptionId"); + + b.Navigation("RawItemOption"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionOfLevel", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", null) + .WithMany("RawLevelDependentOptions") + .HasForeignKey("IncreasableItemOptionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", "RawPowerUpDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionOfLevel", "PowerUpDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawPowerUpDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionType", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemOptionTypes") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSetGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemSetGroups") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", "RawOptions") + .WithMany() + .HasForeignKey("OptionsId"); + + b.Navigation("RawOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSlotType", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawItemSlotTypes") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.JewelMix", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawJewelMixes") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawMixedJewel") + .WithMany() + .HasForeignKey("MixedJewelId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawSingleJewel") + .WithMany() + .HasForeignKey("SingleJewelId"); + + b.Navigation("RawMixedJewel"); + + b.Navigation("RawSingleJewel"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterBody", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterHeader", "RawHeader") + .WithMany() + .HasForeignKey("HeaderId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", "RawSenderAppearance") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterBody", "SenderAppearanceId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawHeader"); + + b.Navigation("RawSenderAppearance"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LetterHeader", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", "Receiver") + .WithMany("RawLetters") + .HasForeignKey("ReceiverId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Receiver"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.LevelBonus", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemLevelBonusTable", null) + .WithMany("RawBonusPerLevel") + .HasForeignKey("ItemLevelBonusTableId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", "RawChance") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "ChanceId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", "RawChancePvp") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "ChancePvpId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", "RawDuration") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "DurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", "RawDurationPvp") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "DurationPvpId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawMagicEffects") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawChance"); + + b.Navigation("RawChancePvp"); + + b.Navigation("RawDuration"); + + b.Navigation("RawDurationPvp"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawReplacedSkill") + .WithMany() + .HasForeignKey("ReplacedSkillId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillRoot", "RawRoot") + .WithMany() + .HasForeignKey("RootId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawTargetAttribute") + .WithMany() + .HasForeignKey("TargetAttributeId"); + + b.Navigation("RawReplacedSkill"); + + b.Navigation("RawRoot"); + + b.Navigation("RawTargetAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinitionSkill", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinition", "MasterSkillDefinition") + .WithMany("JoinedRequiredMasterSkills") + .HasForeignKey("MasterSkillDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "Skill") + .WithMany() + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MasterSkillDefinition"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillRoot", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawMasterSkillRoots") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameChangeEvent", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", null) + .WithMany("RawChangeEvents") + .HasForeignKey("MiniGameDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterSpawnArea", "RawSpawnArea") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameChangeEvent", "SpawnAreaId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawTargetDefinition") + .WithMany() + .HasForeignKey("TargetDefinitionId"); + + b.Navigation("RawSpawnArea"); + + b.Navigation("RawTargetDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawEntrance") + .WithMany() + .HasForeignKey("EntranceId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawMiniGameDefinitions") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawTicketItem") + .WithMany() + .HasForeignKey("TicketItemId"); + + b.Navigation("RawEntrance"); + + b.Navigation("RawTicketItem"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameRankingEntry", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", "RawCharacter") + .WithMany() + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", "RawMiniGame") + .WithMany() + .HasForeignKey("MiniGameId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawCharacter"); + + b.Navigation("RawMiniGame"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameReward", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "RawItemReward") + .WithMany() + .HasForeignKey("ItemRewardId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", null) + .WithMany("RawRewards") + .HasForeignKey("MiniGameDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawRequiredKill") + .WithMany() + .HasForeignKey("RequiredKillId"); + + b.Navigation("RawItemReward"); + + b.Navigation("RawRequiredKill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameSpawnWave", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", null) + .WithMany("RawSpawnWaves") + .HasForeignKey("MiniGameDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameTerrainChange", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameChangeEvent", null) + .WithMany("RawTerrainChanges") + .HasForeignKey("MiniGameChangeEventId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterAttribute", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawAttributeDefinition") + .WithMany() + .HasForeignKey("AttributeDefinitionId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", null) + .WithMany("RawAttributes") + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawAttributeDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawAttackSkill") + .WithMany() + .HasForeignKey("AttackSkillId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawMonsters") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", "RawMerchantStore") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "MerchantStoreId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawAttackSkill"); + + b.Navigation("RawMerchantStore"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinitionDropItemGroup", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "DropItemGroup") + .WithMany() + .HasForeignKey("DropItemGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "MonsterDefinition") + .WithMany("JoinedDropItemGroups") + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DropItemGroup"); + + b.Navigation("MonsterDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterSpawnArea", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", "RawGameMap") + .WithMany("RawMonsterSpawns") + .HasForeignKey("GameMapId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawMonsterDefinition") + .WithMany() + .HasForeignKey("MonsterDefinitionId"); + + b.Navigation("RawGameMap"); + + b.Navigation("RawMonsterDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PlugInConfiguration", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawPlugInConfigurations") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", "RawBoost") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinition", "BoostId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", null) + .WithMany("RawCharacterPowerUpDefinitions") + .HasForeignKey("GameMapDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", null) + .WithMany("RawPowerUpDefinitions") + .HasForeignKey("MagicEffectDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", null) + .WithMany("RawPowerUpDefinitionsPvp") + .HasForeignKey("MagicEffectDefinitionId1") + .OnDelete(DeleteBehavior.Cascade) + .HasConstraintName("FK_PowerUpDefinition_MagicEffectDefinition_MagicEffectDefinit~1"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawTargetAttribute") + .WithMany() + .HasForeignKey("TargetAttributeId"); + + b.Navigation("RawBoost"); + + b.Navigation("RawTargetAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", null) + .WithMany("RawQuests") + .HasForeignKey("MonsterDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "RawQualifiedCharacter") + .WithMany() + .HasForeignKey("QualifiedCharacterId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawQuestGiver") + .WithMany() + .HasForeignKey("QuestGiverId"); + + b.Navigation("RawQualifiedCharacter"); + + b.Navigation("RawQuestGiver"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestItemRequirement", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", "RawDropItemGroup") + .WithMany() + .HasForeignKey("DropItemGroupId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", "RawItem") + .WithMany() + .HasForeignKey("ItemId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", null) + .WithMany("RawRequiredItems") + .HasForeignKey("QuestDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawDropItemGroup"); + + b.Navigation("RawItem"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestMonsterKillRequirement", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", "RawMonster") + .WithMany() + .HasForeignKey("MonsterId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", null) + .WithMany("RawRequiredMonsterKills") + .HasForeignKey("QuestDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawMonster"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestMonsterKillRequirementState", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterQuestState", null) + .WithMany("RawRequirementStates") + .HasForeignKey("CharacterQuestStateId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestMonsterKillRequirement", "RawRequirement") + .WithMany() + .HasForeignKey("RequirementId"); + + b.Navigation("RawRequirement"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestReward", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawAttributeReward") + .WithMany() + .HasForeignKey("AttributeRewardId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", "RawItemReward") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestReward", "ItemRewardId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", null) + .WithMany("RawRewards") + .HasForeignKey("QuestDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawSkillReward") + .WithMany() + .HasForeignKey("SkillRewardId"); + + b.Navigation("RawAttributeReward"); + + b.Navigation("RawItemReward"); + + b.Navigation("RawSkillReward"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AreaSkillSettings", "RawAreaSkillSettings") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "AreaSkillSettingsId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawElementalModifierTarget") + .WithMany() + .HasForeignKey("ElementalModifierTargetId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawSkills") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", "RawMagicEffectDef") + .WithMany() + .HasForeignKey("MagicEffectDefId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinition", "RawMasterDefinition") + .WithOne() + .HasForeignKey("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "MasterDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawAreaSkillSettings"); + + b.Navigation("RawElementalModifierTarget"); + + b.Navigation("RawMagicEffectDef"); + + b.Navigation("RawMasterDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillCharacterClass", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", "CharacterClass") + .WithMany() + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "Skill") + .WithMany("JoinedQualifiedCharacters") + .HasForeignKey("SkillId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CharacterClass"); + + b.Navigation("Skill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboStep", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboDefinition", null) + .WithMany("RawSteps") + .HasForeignKey("SkillComboDefinitionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawSkill") + .WithMany() + .HasForeignKey("SkillId"); + + b.Navigation("RawSkill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillEntry", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", null) + .WithMany("RawLearnedSkills") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", "RawSkill") + .WithMany() + .HasForeignKey("SkillId"); + + b.Navigation("RawSkill"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.StatAttribute", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", null) + .WithMany("RawAttributes") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", null) + .WithMany("RawAttributes") + .HasForeignKey("CharacterId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawDefinition") + .WithMany() + .HasForeignKey("DefinitionId"); + + b.Navigation("RawDefinition"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.StatAttributeDefinition", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", "RawAttribute") + .WithMany() + .HasForeignKey("AttributeId"); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", null) + .WithMany("RawStatAttributes") + .HasForeignKey("CharacterClassId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("RawAttribute"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.WarpInfo", b => + { + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", null) + .WithMany("RawWarpList") + .HasForeignKey("GameConfigurationId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", "RawGate") + .WithMany() + .HasForeignKey("GateId"); + + b.Navigation("RawGate"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", b => + { + b.Navigation("JoinedUnlockedCharacterClasses"); + + b.Navigation("RawAttributes"); + + b.Navigation("RawCharacters"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", b => + { + b.Navigation("RawEquippedItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeConfiguration", b => + { + b.Navigation("RawAttackMachineZones"); + + b.Navigation("RawDefenseMachineZones"); + + b.Navigation("RawGateDefenseUpgrades"); + + b.Navigation("RawGateLifeUpgrades"); + + b.Navigation("RawNpcDefinitions"); + + b.Navigation("RawStateSchedule"); + + b.Navigation("RawStatueDefenseUpgrades"); + + b.Navigation("RawStatueLifeUpgrades"); + + b.Navigation("RawStatueRegenUpgrades"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CastleSiegeData", b => + { + b.Navigation("RawNpcStates"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", b => + { + b.Navigation("JoinedDropItemGroups"); + + b.Navigation("RawAttributes"); + + b.Navigation("RawLearnedSkills"); + + b.Navigation("RawLetters"); + + b.Navigation("RawQuestStates"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", b => + { + b.Navigation("RawAttributeCombinations"); + + b.Navigation("RawBaseAttributeValues"); + + b.Navigation("RawStatAttributes"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterQuestState", b => + { + b.Navigation("RawRequirementStates"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerDefinition", b => + { + b.Navigation("RawEndpoints"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", b => + { + b.Navigation("JoinedPossibleItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", b => + { + b.Navigation("RawDuelAreas"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", b => + { + b.Navigation("RawAttributes"); + + b.Navigation("RawCharacterClasses"); + + b.Navigation("RawDropItemGroups"); + + b.Navigation("RawGlobalAttributeCombinations"); + + b.Navigation("RawGlobalBaseAttributeValues"); + + b.Navigation("RawItemLevelBonusTables"); + + b.Navigation("RawItemOptionCombinationBonuses"); + + b.Navigation("RawItemOptionTypes"); + + b.Navigation("RawItemOptions"); + + b.Navigation("RawItemSetGroups"); + + b.Navigation("RawItemSlotTypes"); + + b.Navigation("RawItems"); + + b.Navigation("RawJewelMixes"); + + b.Navigation("RawMagicEffects"); + + b.Navigation("RawMaps"); + + b.Navigation("RawMasterSkillRoots"); + + b.Navigation("RawMiniGameDefinitions"); + + b.Navigation("RawMonsters"); + + b.Navigation("RawPlugInConfigurations"); + + b.Navigation("RawSkills"); + + b.Navigation("RawWarpList"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", b => + { + b.Navigation("JoinedDropItemGroups"); + + b.Navigation("RawCharacterPowerUpDefinitions"); + + b.Navigation("RawEnterGates"); + + b.Navigation("RawExitGates"); + + b.Navigation("RawMapRequirements"); + + b.Navigation("RawMonsterSpawns"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfiguration", b => + { + b.Navigation("JoinedMaps"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerDefinition", b => + { + b.Navigation("RawEndpoints"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", b => + { + b.Navigation("RawMembers"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", b => + { + b.Navigation("RawLevelDependentOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Item", b => + { + b.Navigation("JoinedItemSetGroups"); + + b.Navigation("RawItemOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemAppearance", b => + { + b.Navigation("JoinedVisibleOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemCraftingRequiredItem", b => + { + b.Navigation("JoinedPossibleItems"); + + b.Navigation("JoinedRequiredItemOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDefinition", b => + { + b.Navigation("JoinedPossibleItemOptions"); + + b.Navigation("JoinedPossibleItemSetGroups"); + + b.Navigation("JoinedQualifiedCharacters"); + + b.Navigation("RawBasePowerUpAttributes"); + + b.Navigation("RawDropItems"); + + b.Navigation("RawRequirements"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemDropItemGroup", b => + { + b.Navigation("JoinedPossibleItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemLevelBonusTable", b => + { + b.Navigation("RawBonusPerLevel"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionCombinationBonus", b => + { + b.Navigation("RawRequirements"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemOptionDefinition", b => + { + b.Navigation("RawPossibleOptions"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemSetGroup", b => + { + b.Navigation("RawItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ItemStorage", b => + { + b.Navigation("RawItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MagicEffectDefinition", b => + { + b.Navigation("RawPowerUpDefinitions"); + + b.Navigation("RawPowerUpDefinitionsPvp"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MasterSkillDefinition", b => + { + b.Navigation("JoinedRequiredMasterSkills"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameChangeEvent", b => + { + b.Navigation("RawTerrainChanges"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MiniGameDefinition", b => + { + b.Navigation("RawChangeEvents"); + + b.Navigation("RawRewards"); + + b.Navigation("RawSpawnWaves"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.MonsterDefinition", b => + { + b.Navigation("JoinedDropItemGroups"); + + b.Navigation("RawAttributes"); + + b.Navigation("RawBuffs"); + + b.Navigation("RawItemCraftings"); + + b.Navigation("RawQuests"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.PowerUpDefinitionValue", b => + { + b.Navigation("RawRelatedValues"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.QuestDefinition", b => + { + b.Navigation("RawRequiredItems"); + + b.Navigation("RawRequiredMonsterKills"); + + b.Navigation("RawRewards"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SimpleCraftingSettings", b => + { + b.Navigation("RawRequiredItems"); + + b.Navigation("RawResultItems"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Skill", b => + { + b.Navigation("JoinedQualifiedCharacters"); + + b.Navigation("RawAttributeRelationships"); + + b.Navigation("RawConsumeRequirements"); + + b.Navigation("RawRequirements"); + }); + + modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.SkillComboDefinition", b => + { + b.Navigation("RawSteps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.cs b/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.cs new file mode 100644 index 0000000000..27f4e29ad8 --- /dev/null +++ b/src/Persistence/EntityFramework/Migrations/20260819100503_AddConstValueAttributeAggregateType.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace MUnique.OpenMU.Persistence.EntityFramework.Migrations +{ + /// + public partial class AddConstValueAttributeAggregateType : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "AggregateType", + schema: "config", + table: "ConstValueAttribute", + type: "integer", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AggregateType", + schema: "config", + table: "ConstValueAttribute"); + } + } +} diff --git a/src/Persistence/EntityFramework/Migrations/EntityDataContextModelSnapshot.cs b/src/Persistence/EntityFramework/Migrations/EntityDataContextModelSnapshot.cs index b56b2c4b77..2004f716a5 100644 --- a/src/Persistence/EntityFramework/Migrations/EntityDataContextModelSnapshot.cs +++ b/src/Persistence/EntityFramework/Migrations/EntityDataContextModelSnapshot.cs @@ -1176,6 +1176,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("uuid"); + b.Property("AggregateType") + .HasColumnType("integer"); + b.Property("CharacterClassId") .HasColumnType("uuid"); diff --git a/src/Persistence/EntityFramework/Model/ConstValueAttribute.Generated.cs b/src/Persistence/EntityFramework/Model/ConstValueAttribute.Generated.cs index 4325178a06..eeb064b245 100644 --- a/src/Persistence/EntityFramework/Model/ConstValueAttribute.Generated.cs +++ b/src/Persistence/EntityFramework/Model/ConstValueAttribute.Generated.cs @@ -23,8 +23,8 @@ internal partial class ConstValueAttribute : MUnique.OpenMU.AttributeSystem.Cons { /// - public ConstValueAttribute(System.Single value, MUnique.OpenMU.AttributeSystem.AttributeDefinition definition) - : base(value, definition) + public ConstValueAttribute(System.Single value, MUnique.OpenMU.AttributeSystem.AttributeDefinition definition, MUnique.OpenMU.AttributeSystem.AggregateType aggregateType) + : base(value, definition, aggregateType) { } diff --git a/src/Persistence/EntityFramework/Model/ExtendedTypes.Custom.cs b/src/Persistence/EntityFramework/Model/ExtendedTypes.Custom.cs index 624270cb25..2d15057ca2 100644 --- a/src/Persistence/EntityFramework/Model/ExtendedTypes.Custom.cs +++ b/src/Persistence/EntityFramework/Model/ExtendedTypes.Custom.cs @@ -98,6 +98,13 @@ public ConstValueAttribute() get => base.Value; set => base.Value = value; } + + /// + public new AggregateType AggregateType + { + get => base.AggregateType; + set => base.AggregateType = value; + } } /// diff --git a/src/Persistence/Initialization/CharacterClasses/CharacterClassHelper.cs b/src/Persistence/Initialization/CharacterClasses/CharacterClassHelper.cs index 839cb0d667..52060fb7e6 100644 --- a/src/Persistence/Initialization/CharacterClasses/CharacterClassHelper.cs +++ b/src/Persistence/Initialization/CharacterClasses/CharacterClassHelper.cs @@ -200,9 +200,10 @@ public static AttributeRelationship CreateConditionalRelationship(IContext conte /// The game configuration. /// The value. /// The attribute. + /// The aggregate type. /// The constant value attribute. - public static ConstValueAttribute CreateConstValueAttribute(IContext context, GameConfiguration gameConfiguration, float value, AttributeDefinition attribute) + public static ConstValueAttribute CreateConstValueAttribute(IContext context, GameConfiguration gameConfiguration, float value, AttributeDefinition attribute, AggregateType aggregateType = AggregateType.AddRaw) { - return context.CreateNew(value, attribute.GetPersistent(gameConfiguration)); + return context.CreateNew(value, attribute.GetPersistent(gameConfiguration), aggregateType); } } \ No newline at end of file diff --git a/src/Persistence/Initialization/CharacterClasses/CharacterClassInitialization.cs b/src/Persistence/Initialization/CharacterClasses/CharacterClassInitialization.cs index d2caf067f0..7b85676e79 100644 --- a/src/Persistence/Initialization/CharacterClasses/CharacterClassInitialization.cs +++ b/src/Persistence/Initialization/CharacterClasses/CharacterClassInitialization.cs @@ -84,9 +84,9 @@ private AttributeRelationship CreateConditionalRelationship(AttributeDefinition return CharacterClassHelper.CreateConditionalRelationship(this.Context, this.GameConfiguration, targetAttribute, conditionalAttribute, sourceAttribute, aggregateType); } - private ConstValueAttribute CreateConstValueAttribute(float value, AttributeDefinition attribute) + private ConstValueAttribute CreateConstValueAttribute(float value, AttributeDefinition attribute, AggregateType aggregateType = AggregateType.AddRaw) { - return CharacterClassHelper.CreateConstValueAttribute(this.Context, this.GameConfiguration, value, attribute); + return CharacterClassHelper.CreateConstValueAttribute(this.Context, this.GameConfiguration, value, attribute, aggregateType); } private void AddCommonAttributeRelationships(ICollection attributeRelationships) @@ -122,12 +122,9 @@ private void AddCommonAttributeRelationships(ICollection attributeRelationships.Add(this.CreateAttributeRelationship(Stats.MaximumMana, 1, Stats.SwellLifeManaIncrease, aggregateType: AggregateType.Multiplicate)); attributeRelationships.Add(this.CreateAttributeRelationship(Stats.IncreaseBlockBonus, 1, Stats.DefenseRatePvm, aggregateType: AggregateType.Multiplicate)); - // If two weapons are equipped (DK, MG, Sum, RF) we subtract the half of the sum of the speeds again from the attack speed - attributeRelationships.Add(this.CreateAttributeRelationship(Stats.AreTwoWeaponsEquipped, 1, Stats.EquippedWeaponCount)); - var tempSpeed = this.Context.CreateNew(Guid.NewGuid(), "Temp Half weapon attack speed", string.Empty); - this.GameConfiguration.Attributes.Add(tempSpeed); - attributeRelationships.Add(this.CreateAttributeRelationship(tempSpeed, -0.5f, Stats.AttackSpeedByWeapon)); - attributeRelationships.Add(this.CreateConditionalRelationship(Stats.AttackSpeedAny, Stats.AreTwoWeaponsEquipped, tempSpeed)); + // If two weapons are equipped (DK, MG, Sum, RF) we average the weapon attack speed + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.AreTwoWeaponsEquipped, 1, Stats.EquippedWeaponCount, InputOperator.Maximum)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.AttackSpeedByWeapon, 0.5f, Stats.AreTwoWeaponsEquipped, InputOperator.ExponentiateByAttribute, AggregateType.Multiplicate)); var tempDefense = this.Context.CreateNew(Guid.NewGuid(), "Temp Defense Bonus multiplier with Shield", string.Empty); this.GameConfiguration.Attributes.Add(tempDefense); @@ -138,12 +135,12 @@ private void AddCommonAttributeRelationships(ICollection attributeRelationships.Add(this.CreateConditionalRelationship(Stats.DefenseFinal, Stats.IsShieldEquipped, Stats.BonusDefenseWithShield, AggregateType.AddFinal)); attributeRelationships.Add(this.CreateConditionalRelationship(Stats.DefenseRatePvm, Stats.IsShieldEquipped, Stats.BonusDefenseRateWithShield, AggregateType.AddFinal)); - var tempInnovDefDec = this.Context.CreateNew(Guid.NewGuid(), "Temp Innovation defense decrement", string.Empty); - this.GameConfiguration.Attributes.Add(tempInnovDefDec); - attributeRelationships.Add(this.CreateAttributeRelationship(tempInnovDefDec, -1, Stats.InnovationDefDecrement)); - attributeRelationships.Add(this.CreateAttributeRelationship(Stats.DefenseDecrement, 1, tempInnovDefDec, InputOperator.Add, AggregateType.Multiplicate)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.DefenseDecrement, -1, Stats.InnovationDefDecrement)); + + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.HealthRecoveryMultiplier, 0.03f, Stats.IsResting)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.ManaRecoveryMultiplier, 0.03f, Stats.IsResting)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.AbilityRecoveryAbsolute, 3, Stats.IsInSafezone)); - attributeRelationships.Add(this.CreateAttributeRelationship(Stats.HealthRecoveryMultiplier, 0.01f, Stats.IsInSafezone)); if (this.UseClassicPvp) { attributeRelationships.Add(this.CreateAttributeRelationship(Stats.DefenseRatePvp, 1, Stats.DefenseRatePvm)); @@ -151,7 +148,10 @@ private void AddCommonAttributeRelationships(ICollection } else { - attributeRelationships.Add(this.CreateAttributeRelationship(Stats.ShieldRecoveryMultiplier, 0.01f, Stats.IsInSafezone)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.IsShieldRecoveryActive, 1, Stats.IsInSafezone)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.IsShieldRecoveryActive, 1, Stats.ShieldRecoveryEverywhere)); + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.ShieldRecoveryRampFactor, 1f / 15f, Stats.ShieldRecoveryHiatus)); // (3 - 2) / (25 - 10) + attributeRelationships.Add(this.CreateAttributeRelationship(Stats.ShieldRecoveryMultiplier, 1, Stats.ShieldRecoveryRampFactor, aggregateType: AggregateType.Multiplicate)); } attributeRelationships.Add(this.CreateAttributeRelationship(Stats.MaximumGuildSize, 0.1f, Stats.Level)); @@ -160,7 +160,7 @@ private void AddCommonAttributeRelationships(ICollection private void AddCommonBaseAttributeValues(ICollection baseAttributeValues, bool isMaster) { - baseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 27.5f, Stats.ManaRecoveryMultiplier)); + baseAttributeValues.Add(this.CreateConstValueAttribute(0.037f, Stats.ManaRecoveryMultiplier)); baseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.DamageReceiveDecrement)); baseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.AttackDamageIncrease)); baseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.ExperienceRate)); @@ -184,7 +184,9 @@ private void AddCommonBaseAttributeValues(ICollection baseA if (!this.UseClassicPvp) { - baseAttributeValues.Add(this.CreateConstValueAttribute(0.01f, Stats.ShieldRecoveryMultiplier)); + baseAttributeValues.Add(this.CreateConstValueAttribute(100, Stats.ShieldRecoveryMultiplier)); + baseAttributeValues.Add(this.CreateConstValueAttribute(1f / 75000, Stats.ShieldRecoveryMultiplier, AggregateType.Multiplicate)); // 1 / (30 * 100 * 25) + baseAttributeValues.Add(this.CreateConstValueAttribute(4f / 3f, Stats.ShieldRecoveryRampFactor)); // y=mx+b: m=1/15, y=2, x=10 => b=4/3 } } diff --git a/src/Persistence/Initialization/CharacterClasses/ClassDarkKnight.cs b/src/Persistence/Initialization/CharacterClasses/ClassDarkKnight.cs index 9a2a72c7ee..e7cb931c5a 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassDarkKnight.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassDarkKnight.cs @@ -43,7 +43,9 @@ protected CharacterClass CreateDarkKnight(CharacterClassNumber number, string na result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentMana, 20, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); this.AddDoubleWieldAttributeRelationships(result.AttributeCombinations); diff --git a/src/Persistence/Initialization/CharacterClasses/ClassDarkLord.cs b/src/Persistence/Initialization/CharacterClasses/ClassDarkLord.cs index 1cdb51defe..c7a1b40d78 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassDarkLord.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassDarkLord.cs @@ -13,13 +13,6 @@ namespace MUnique.OpenMU.Persistence.Initialization.CharacterClasses; /// internal partial class CharacterClassInitialization { - private CharacterClass CreateLordEmperor() - { - var result = this.CreateDarkLord(CharacterClassNumber.LordEmperor, "Lord Emperor", true, null, false); - result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); - return result; - } - private CharacterClass CreateDarkLord(CharacterClassNumber number, string name, bool isMaster, CharacterClass? nextGenerationClass, bool canGetCreated) { var energyMinus15 = this.Context.CreateNew(Guid.NewGuid(), "TotalEnergy minus 15", "TotalEnergy minus 15"); @@ -48,7 +41,9 @@ private CharacterClass CreateDarkLord(CharacterClassNumber number, string name, result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentMana, 40, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); @@ -128,8 +123,10 @@ private CharacterClass CreateDarkLord(CharacterClassNumber number, string name, result.BaseAttributeValues.Add(this.CreateConstValueAttribute(38, Stats.MaximumMana)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(48.5f, Stats.MaximumHealth)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(2, Stats.SkillMultiplier)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.PetDurationIncrease)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeed, AggregateType.Maximum)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeedUnderwater, AggregateType.Maximum)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(180, Stats.RavenMinimumDamage)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(200, Stats.RavenMaximumDamage)); @@ -141,4 +138,11 @@ private CharacterClass CreateDarkLord(CharacterClassNumber number, string name, return result; } + + private CharacterClass CreateLordEmperor() + { + var result = this.CreateDarkLord(CharacterClassNumber.LordEmperor, "Lord Emperor", true, null, false); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); + return result; + } } \ No newline at end of file diff --git a/src/Persistence/Initialization/CharacterClasses/ClassDarkWizard.cs b/src/Persistence/Initialization/CharacterClasses/ClassDarkWizard.cs index 5d6ec2807e..d073b79c67 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassDarkWizard.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassDarkWizard.cs @@ -42,9 +42,10 @@ protected CharacterClass CreateDarkWizard(CharacterClassNumber number, string na result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentHealth, 60, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentMana, 60, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); - result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); @@ -111,7 +112,7 @@ protected CharacterClass CreateDarkWizard(CharacterClassNumber number, string na result.BaseAttributeValues.Add(this.CreateConstValueAttribute(30, Stats.MaximumHealth)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.SkillMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f, Stats.WizardryAttackDamageIncrease)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.WizardryBaseDmgIncrease)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0, Stats.NovaStageDamage)); // placeholder value diff --git a/src/Persistence/Initialization/CharacterClasses/ClassFairyElf.cs b/src/Persistence/Initialization/CharacterClasses/ClassFairyElf.cs index b79df65532..5c94445873 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassFairyElf.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassFairyElf.cs @@ -47,7 +47,9 @@ protected CharacterClass CreateFairyElf(CharacterClassNumber number, string name result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.AmmunitionAmount, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); @@ -119,7 +121,7 @@ protected CharacterClass CreateFairyElf(CharacterClassNumber number, string name result.BaseAttributeValues.Add(this.CreateConstValueAttribute(39, Stats.MaximumHealth)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(6, Stats.MaximumMana)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.SkillMultiplier)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); this.AddCommonBaseAttributeValues(result.BaseAttributeValues, isMaster); diff --git a/src/Persistence/Initialization/CharacterClasses/ClassMagicGladiator.cs b/src/Persistence/Initialization/CharacterClasses/ClassMagicGladiator.cs index 930c9b1f5f..38f759978d 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassMagicGladiator.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassMagicGladiator.cs @@ -46,7 +46,9 @@ protected CharacterClass CreateMagicGladiator(CharacterClassNumber number, strin result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentMana, 60, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); this.AddDoubleWieldAttributeRelationships(result.AttributeCombinations); @@ -122,9 +124,11 @@ protected CharacterClass CreateMagicGladiator(CharacterClassNumber number, strin result.BaseAttributeValues.Add(this.CreateConstValueAttribute(7, Stats.MaximumMana)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(2, Stats.SkillMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f, Stats.WizardryAttackDamageIncrease)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.WizardryBaseDmgIncrease)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0, Stats.IsOneHandedSwordEquipped)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeed, AggregateType.Maximum)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeedUnderwater, AggregateType.Maximum)); this.AddCommonBaseAttributeValues(result.BaseAttributeValues, isMaster); diff --git a/src/Persistence/Initialization/CharacterClasses/ClassRageFighter.cs b/src/Persistence/Initialization/CharacterClasses/ClassRageFighter.cs index 0dc2a10b46..1c87ea25d0 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassRageFighter.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassRageFighter.cs @@ -13,13 +13,6 @@ namespace MUnique.OpenMU.Persistence.Initialization.CharacterClasses; /// internal partial class CharacterClassInitialization { - private CharacterClass CreateFistMaster() - { - var result = this.CreateRageFighter(CharacterClassNumber.FistMaster, "Fist Master", true, null, false); - result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); - return result; - } - private CharacterClass CreateRageFighter(CharacterClassNumber number, string name, bool isMaster, CharacterClass? nextGenerationClass, bool canGetCreated) { var result = this.Context.CreateNew(); @@ -45,7 +38,9 @@ private CharacterClass CreateRageFighter(CharacterClassNumber number, string nam result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentShield, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); this.AddDoubleWieldAttributeRelationships(result.AttributeCombinations); @@ -101,10 +96,19 @@ private CharacterClass CreateRageFighter(CharacterClassNumber number, string nam result.BaseAttributeValues.Add(this.CreateConstValueAttribute(7, Stats.MaximumMana)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.5f, Stats.SkillMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.5f, Stats.VitalitySkillMultiplier)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeed, AggregateType.Maximum)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(MovementSpeedConstants.RunningGearMovementSpeed, Stats.MovementSpeedUnderwater, AggregateType.Maximum)); this.AddCommonBaseAttributeValues(result.BaseAttributeValues, isMaster); return result; } + + private CharacterClass CreateFistMaster() + { + var result = this.CreateRageFighter(CharacterClassNumber.FistMaster, "Fist Master", true, null, false); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); + return result; + } } \ No newline at end of file diff --git a/src/Persistence/Initialization/CharacterClasses/ClassSummoner.cs b/src/Persistence/Initialization/CharacterClasses/ClassSummoner.cs index 6942934780..2c0e3ec5c8 100644 --- a/src/Persistence/Initialization/CharacterClasses/ClassSummoner.cs +++ b/src/Persistence/Initialization/CharacterClasses/ClassSummoner.cs @@ -13,18 +13,6 @@ namespace MUnique.OpenMU.Persistence.Initialization.CharacterClasses; /// internal partial class CharacterClassInitialization { - private CharacterClass CreateBloodySummoner(CharacterClass dimensionMaster) - { - return this.CreateSummoner(CharacterClassNumber.BloodySummoner, "Bloody Summoner", false, dimensionMaster, false); - } - - private CharacterClass CreateDimensionMaster() - { - var result = this.CreateSummoner(CharacterClassNumber.DimensionMaster, "Dimension Master", true, null, false); - result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); - return result; - } - private CharacterClass CreateSummoner(CharacterClassNumber number, string name, bool isMaster, CharacterClass? nextGenerationClass, bool canGetCreated) { var statsDefense = this.Context.CreateNew(Guid.NewGuid(), "Stats defense", string.Empty); @@ -59,7 +47,9 @@ private CharacterClass CreateSummoner(CharacterClassNumber number, string name, result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentAbility, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.CurrentShield, 1, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsInSafezone, 1, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.IsResting, 0, false)); result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.Resets, 0, false)); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.NearbyPartyMemberCount, 0, false)); this.AddCommonAttributeRelationships(result.AttributeCombinations); @@ -150,7 +140,7 @@ private CharacterClass CreateSummoner(CharacterClassNumber number, string name, result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.SkillMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f, Stats.WizardryAttackDamageIncrease)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f, Stats.CurseAttackDamageIncrease)); - result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1.0f / 33f, Stats.AbilityRecoveryMultiplier)); + result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0.03f, Stats.AbilityRecoveryMultiplier)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(1, Stats.WizardryBaseDmgIncrease)); result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0, Stats.BerserkerManaMultiplier)); // placeholder value result.BaseAttributeValues.Add(this.CreateConstValueAttribute(0, Stats.BerserkerHealthDecrement)); // placeholder value @@ -161,4 +151,16 @@ private CharacterClass CreateSummoner(CharacterClassNumber number, string name, return result; } + + private CharacterClass CreateBloodySummoner(CharacterClass dimensionMaster) + { + return this.CreateSummoner(CharacterClassNumber.BloodySummoner, "Bloody Summoner", false, dimensionMaster, false); + } + + private CharacterClass CreateDimensionMaster() + { + var result = this.CreateSummoner(CharacterClassNumber.DimensionMaster, "Dimension Master", true, null, false); + result.StatAttributes.Add(this.CreateStatAttributeDefinition(Stats.MasterLevel, 0, false)); + return result; + } } \ No newline at end of file diff --git a/src/Persistence/Initialization/GameConfigurationInitializerBase.cs b/src/Persistence/Initialization/GameConfigurationInitializerBase.cs index 1d966d76c6..b2d78ef966 100644 --- a/src/Persistence/Initialization/GameConfigurationInitializerBase.cs +++ b/src/Persistence/Initialization/GameConfigurationInitializerBase.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // @@ -272,15 +272,16 @@ private void CreateStatAttributes() /// private void AddGlobalBaseAttributeValues() { - var moneyAmountRate = this.Context.CreateNew(1f, Stats.MoneyAmountRate.GetPersistent(this.GameConfiguration)); + var moneyAmountRate = this.Context.CreateNew(1f, Stats.MoneyAmountRate.GetPersistent(this.GameConfiguration), AggregateType.AddRaw); this.GameConfiguration.GlobalBaseAttributeValues.Add(moneyAmountRate); - var randomExperienceMinMultiplier = this.Context.CreateNew(0.8f, Stats.RandomExperienceMinMultiplier.GetPersistent(this.GameConfiguration)); + var randomExperienceMinMultiplier = this.Context.CreateNew(0.8f, Stats.RandomExperienceMinMultiplier.GetPersistent(this.GameConfiguration), AggregateType.AddRaw); this.GameConfiguration.GlobalBaseAttributeValues.Add(randomExperienceMinMultiplier); - var randomExperienceMaxMultiplier = this.Context.CreateNew(1.2f, Stats.RandomExperienceMaxMultiplier.GetPersistent(this.GameConfiguration)); + var randomExperienceMaxMultiplier = this.Context.CreateNew(1.2f, Stats.RandomExperienceMaxMultiplier.GetPersistent(this.GameConfiguration), AggregateType.AddRaw); this.GameConfiguration.GlobalBaseAttributeValues.Add(randomExperienceMaxMultiplier); - this.GameConfiguration.GlobalBaseAttributeValues.Add(this.Context.CreateNew(1f, Stats.MovementSpeedFactor.GetPersistent(this.GameConfiguration))); + var movementSpeedFactor = this.Context.CreateNew(1f, Stats.MovementSpeedFactor.GetPersistent(this.GameConfiguration), AggregateType.AddRaw); + this.GameConfiguration.GlobalBaseAttributeValues.Add(movementSpeedFactor); } } diff --git a/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn075.cs b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn075.cs new file mode 100644 index 0000000000..0dba65d0b0 --- /dev/null +++ b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn075.cs @@ -0,0 +1,30 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes and reworks some regeneration attributes (health, mana, ability). +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("F079402E-F557-423C-B376-80A1B87D842D")] +public class RegenerationsRefactorPlugIn075 : RegenerationsRefactorPlugInBase +{ + /// + public override UpdateVersion Version => UpdateVersion.RegenerationsRefactor075; + + /// + public override string DataInitializationKey => Version075.DataInitialization.Id; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + } +} diff --git a/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn095d.cs b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn095d.cs new file mode 100644 index 0000000000..8bf8a15c6b --- /dev/null +++ b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugIn095d.cs @@ -0,0 +1,55 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.GameLogic.Attributes; +using MUnique.OpenMU.Persistence.Initialization; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes and reworks some regeneration attributes (health, mana, ability). It also adds default running (and fast swimming) speed for tier 2 chars (MG). +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("A7C2E9F4-5B1D-4E8A-9C6F-3D2B7A1E5F90")] +public class RegenerationsRefactorPlugIn095D : RegenerationsRefactorPlugInBase +{ + /// + /// The plug in description. + /// + internal new const string PlugInDescription = "This update fixes and reworks some regeneration attributes (health, mana, ability). It also adds default running (and fast swimming) speed for tier 2 chars (MG)."; + + /// + public override UpdateVersion Version => UpdateVersion.RegenerationsRefactorSeason6; + + /// + public override string DataInitializationKey => Version095d.DataInitialization.Id; + + /// + public override string Description => PlugInDescription; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + + var movementSpeed = Stats.MovementSpeed.GetPersistent(gameConfiguration); + var movementSpeedUnderwater = Stats.MovementSpeedUnderwater.GetPersistent(gameConfiguration); + + gameConfiguration.CharacterClasses.ForEach(charClass => + { + // Add default movement speeds for tier 2 chars + if (charClass.Number == 12 || charClass.Number == 13) // MG classes + { + charClass.BaseAttributeValues.Add(context.CreateNew(MovementSpeedConstants.RunningGearMovementSpeed, movementSpeed, AggregateType.Maximum)); + charClass.BaseAttributeValues.Add(context.CreateNew(MovementSpeedConstants.RunningGearMovementSpeed, movementSpeedUnderwater, AggregateType.Maximum)); + } + }); + } +} diff --git a/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInBase.cs b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInBase.cs new file mode 100644 index 0000000000..6df7612862 --- /dev/null +++ b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInBase.cs @@ -0,0 +1,181 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.GameLogic.Attributes; + +/// +/// This update fixes and reworks some regeneration attributes (health, mana, ability). +/// +public abstract class RegenerationsRefactorPlugInBase : UpdatePlugInBase +{ + /// + /// The plug in name. + /// + internal const string PlugInName = "Regenerations Refactor"; + + /// + /// The plug in description. + /// + internal const string PlugInDescription = "This update fixes and reworks some regeneration attributes (health, mana, ability)."; + + /// + public override string Name => PlugInName; + + /// + public override string Description => PlugInDescription; + + /// + public override bool IsMandatory => true; + + /// + public override DateTime CreatedAt => new(2026, 8, 26, 16, 0, 0, DateTimeKind.Utc); + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + // Create new Stats + var isResting = context.CreateNew(Stats.IsResting.Id, Stats.IsResting.Designation, Stats.IsResting.Description); + gameConfiguration.Attributes.Add(isResting); + + var areTwoWeaponsEquipped = Stats.AreTwoWeaponsEquipped.GetPersistent(gameConfiguration); + var equippedWeaponCount = Stats.EquippedWeaponCount.GetPersistent(gameConfiguration); + var attackSpeedByWeapon = Stats.AttackSpeedByWeapon.GetPersistent(gameConfiguration); + var innovationDefDecrement = Stats.InnovationDefDecrement.GetPersistent(gameConfiguration); + var defenseDecrement = Stats.DefenseDecrement.GetPersistent(gameConfiguration); + + var healthRecoveryMultiplier = Stats.HealthRecoveryMultiplier.GetPersistent(gameConfiguration); + var manaRecoveryMultiplier = Stats.ManaRecoveryMultiplier.GetPersistent(gameConfiguration); + var abilityRecoveryMultiplier = Stats.AbilityRecoveryMultiplier.GetPersistent(gameConfiguration); + var abilityRecoveryAbsolute = Stats.AbilityRecoveryAbsolute.GetPersistent(gameConfiguration); + var isInSafezone = Stats.IsInSafezone.GetPersistent(gameConfiguration); + var nearbyPartyMemberCount = Stats.NearbyPartyMemberCount.GetPersistent(gameConfiguration); + + gameConfiguration.CharacterClasses.ForEach(charClass => + { + var attrCombos = charClass.AttributeCombinations; + + // Remove temp attack speed combos + var tempAttackSpeeds = gameConfiguration.Attributes.Where(a => a.Designation == "Temp Half weapon attack speed"); + if (tempAttackSpeeds.Any()) + { + if (attrCombos.FirstOrDefault(ac => ac.TargetAttribute == areTwoWeaponsEquipped) is { } equippedWeaponCountToAreTwoWeaponsEquipped) + { + equippedWeaponCountToAreTwoWeaponsEquipped.InputOperator = InputOperator.Maximum; + } + + AttributeDefinition? classTempAttackSpeed = null; + if (attrCombos.FirstOrDefault(ac => tempAttackSpeeds.Contains(ac.TargetAttribute)) is { } attrCombo1) + { + attrCombos.Remove(attrCombo1); + classTempAttackSpeed = attrCombo1.TargetAttribute; + } + + if (attrCombos.FirstOrDefault(ac => tempAttackSpeeds.Contains(ac.InputAttribute)) is { } attrCombo2) + { + attrCombos.Remove(attrCombo2); + } + + if (classTempAttackSpeed is not null) + { + gameConfiguration.Attributes.Remove(classTempAttackSpeed); + } + } + + var areTwoWeaponsEquippedToAttackSpeedByWeapon = context.CreateNew( + attackSpeedByWeapon, + 0.5f, + areTwoWeaponsEquipped, + InputOperator.ExponentiateByAttribute, + default(AttributeDefinition?), + AggregateType.Multiplicate); + + charClass.AttributeCombinations.Add(areTwoWeaponsEquippedToAttackSpeedByWeapon); + + // Remove temp innovation defense decrement combos + var tempInnovationDefDecrements = gameConfiguration.Attributes.Where(a => a.Designation == "Temp Innovation defense decrement"); + if (tempInnovationDefDecrements.Any()) + { + AttributeDefinition? classTempInnovationDefDecrement = null; + if (attrCombos.FirstOrDefault(ac => tempInnovationDefDecrements.Contains(ac.InputAttribute)) is { } attrCombo) + { + attrCombos.Remove(attrCombo); + classTempInnovationDefDecrement = attrCombo.InputAttribute; + } + + if (attrCombos.FirstOrDefault(ac => ac.InputAttribute == innovationDefDecrement && ac.InputOperand == -1) is { } innovationDefDecrementToTempInnovDefDec) + { + innovationDefDecrementToTempInnovDefDec.TargetAttribute = defenseDecrement; + } + + if (classTempInnovationDefDecrement is not null) + { + gameConfiguration.Attributes.Remove(classTempInnovationDefDecrement); + } + } + + // Add new attribute combinations + var isRestingToHealthRecoveryMultiplier = context.CreateNew( + healthRecoveryMultiplier, + 0.03f, + isResting, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.AddRaw); + + var isRestingToManaRecoveryMultiplier = context.CreateNew( + manaRecoveryMultiplier, + 0.03f, + isResting, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.AddRaw); + + var isInSafezoneToAbilityRecoveryAbsolute = context.CreateNew( + abilityRecoveryAbsolute, + 3f, + isInSafezone, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.AddRaw); + + charClass.AttributeCombinations.Add(isRestingToHealthRecoveryMultiplier); + charClass.AttributeCombinations.Add(isRestingToManaRecoveryMultiplier); + charClass.AttributeCombinations.Add(isInSafezoneToAbilityRecoveryAbsolute); + + // Remove recovery multiplier combos + if (attrCombos.FirstOrDefault(ac => ac.InputAttribute == isInSafezone && ac.TargetAttribute == healthRecoveryMultiplier) is { } isInSafezoneToHealthRecoveryMultiplier) + { + attrCombos.Remove(isInSafezoneToHealthRecoveryMultiplier); + } + + // Change common base attribute values (ConstValueAttribute) + if (charClass.BaseAttributeValues.FirstOrDefault(bav => bav.Definition == manaRecoveryMultiplier) is { } baseManaRecoveryMultiplier) + { + charClass.BaseAttributeValues.Remove(baseManaRecoveryMultiplier); + } + + charClass.BaseAttributeValues.Add(context.CreateNew(0.037f, manaRecoveryMultiplier, AggregateType.AddRaw)); + + // Create new StatAttributDefinitions + charClass.StatAttributes.Add(context.CreateNew(isResting, 0, false)); + charClass.StatAttributes.Add(context.CreateNew(nearbyPartyMemberCount, 0, false)); + + // Change base ability recovery multiplier + if (charClass.Number != 4 && charClass.Number != 6 && charClass.Number != 7) // DK classes + { + if (charClass.BaseAttributeValues.FirstOrDefault(bav => bav.Definition == abilityRecoveryMultiplier) is { } baseAbilityRecoveryMultiplier) + { + charClass.BaseAttributeValues.Remove(baseAbilityRecoveryMultiplier); + } + + charClass.BaseAttributeValues.Add(context.CreateNew(0.03f, abilityRecoveryMultiplier, AggregateType.AddRaw)); + } + }); + } +} diff --git a/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInSeason6.cs b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInSeason6.cs new file mode 100644 index 0000000000..9ee506d8bc --- /dev/null +++ b/src/Persistence/Initialization/Updates/RegenerationsRefactorPlugInSeason6.cs @@ -0,0 +1,127 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.GameLogic.Attributes; +using MUnique.OpenMU.Persistence.Initialization.Skills; +using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes and reworks some regeneration attributes (health, shield, mana, ability). It also adds default running (and fast swimming) speed for tier 2 chars (MG, DL, RF). +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("E6A3B9F1-7C4D-48E2-A5B8-1F9D3C6E2A7B")] +public class RegenerationsRefactorPlugInSeason6 : RegenerationsRefactorPlugInBase +{ + /// + /// The plug in description. + /// + internal new const string PlugInDescription = "This update fixes and reworks some regeneration attributes (health, shield, mana, ability). It also adds default running (and fast swimming) speed for tier 2 chars (MG, DL, RF)."; + + /// + public override UpdateVersion Version => UpdateVersion.RegenerationsRefactorSeason6; + + /// + public override string DataInitializationKey => DataInitialization.Id; + + /// + public override string Description => PlugInDescription; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + + // Create new Stats + var isShieldRecoveryActive = context.CreateNew(Stats.IsShieldRecoveryActive.Id, Stats.IsShieldRecoveryActive.Designation, Stats.IsShieldRecoveryActive.Description); + gameConfiguration.Attributes.Add(isShieldRecoveryActive); + var shieldRecoveryHiatus = context.CreateNew(Stats.ShieldRecoveryHiatus.Id, Stats.ShieldRecoveryHiatus.Designation, Stats.ShieldRecoveryHiatus.Description); + gameConfiguration.Attributes.Add(shieldRecoveryHiatus); + var shieldRecoveryRampFactor = context.CreateNew(Stats.ShieldRecoveryRampFactor.Id, Stats.ShieldRecoveryRampFactor.Designation, Stats.ShieldRecoveryRampFactor.Description); + shieldRecoveryRampFactor.MaximumValue = 3; + gameConfiguration.Attributes.Add(shieldRecoveryRampFactor); + + var shieldRecoveryMultiplier = Stats.ShieldRecoveryMultiplier.GetPersistent(gameConfiguration); + var shieldRecoveryEverywhere = Stats.ShieldRecoveryEverywhere.GetPersistent(gameConfiguration); + + var movementSpeed = Stats.MovementSpeed.GetPersistent(gameConfiguration); + var movementSpeedUnderwater = Stats.MovementSpeedUnderwater.GetPersistent(gameConfiguration); + + gameConfiguration.CharacterClasses.ForEach(charClass => + { + var attrCombos = charClass.AttributeCombinations; + + // Add new attribute combinations + var shieldRecoveryEverywhereToIsShieldRecoveryActive = context.CreateNew( + isShieldRecoveryActive, + 1f, + shieldRecoveryEverywhere, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.AddRaw); + + var shieldRecoveryHiatusToShieldRecoveryRampFactor = context.CreateNew( + shieldRecoveryRampFactor, + 1f / 15f, + shieldRecoveryHiatus, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.AddRaw); + + var shieldRecoveryRampFactorToShieldRecoveryMultiplier = context.CreateNew( + shieldRecoveryMultiplier, + 1f, + shieldRecoveryRampFactor, + InputOperator.Multiply, + default(AttributeDefinition?), + AggregateType.Multiplicate); + + charClass.AttributeCombinations.Add(shieldRecoveryEverywhereToIsShieldRecoveryActive); + charClass.AttributeCombinations.Add(shieldRecoveryHiatusToShieldRecoveryRampFactor); + charClass.AttributeCombinations.Add(shieldRecoveryRampFactorToShieldRecoveryMultiplier); + + // Change common base attribute values (ConstValueAttribute) + charClass.BaseAttributeValues.Add(context.CreateNew(4f / 3f, shieldRecoveryRampFactor, AggregateType.AddRaw)); + + if (charClass.BaseAttributeValues.FirstOrDefault(bav => bav.Definition == shieldRecoveryMultiplier) is { } baseShieldRecoveryMultiplier) + { + charClass.BaseAttributeValues.Remove(baseShieldRecoveryMultiplier); + } + + charClass.BaseAttributeValues.Add(context.CreateNew(100, shieldRecoveryMultiplier, AggregateType.AddRaw)); + charClass.BaseAttributeValues.Add(context.CreateNew(1f / 75000, shieldRecoveryMultiplier, AggregateType.Multiplicate)); + + // Add default movement speeds for tier 2 chars + if (charClass.Number == 16 || charClass.Number == 17 // DL classes + || charClass.Number == 12 || charClass.Number == 13 // MG classes + || charClass.Number == 24 || charClass.Number == 25) // RF classes + { + charClass.BaseAttributeValues.Add(context.CreateNew(MovementSpeedConstants.RunningGearMovementSpeed, movementSpeed, AggregateType.Maximum)); + charClass.BaseAttributeValues.Add(context.CreateNew(MovementSpeedConstants.RunningGearMovementSpeed, movementSpeedUnderwater, AggregateType.Maximum)); + } + }); + + // Update master skills + if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.SdRecoverySpeedInc)?.MasterDefinition is { } sdRecoverySpeedInc) + { + sdRecoverySpeedInc.ValueFormula = $"1 + {SkillsInitializer.FormulaRecoveryIncrease120}"; + sdRecoverySpeedInc.TargetAttribute = shieldRecoveryMultiplier; + sdRecoverySpeedInc.Aggregation = AggregateType.Multiplicate; + } + + if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.IncreaseSdRecoveryRate)?.MasterDefinition is { } increaseSdRecoveryRate) + { + increaseSdRecoveryRate.ValueFormula = $"1 + {SkillsInitializer.FormulaRecoveryIncrease120}"; + increaseSdRecoveryRate.TargetAttribute = shieldRecoveryMultiplier; + increaseSdRecoveryRate.Aggregation = AggregateType.Multiplicate; + } + } +} diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index 21e0ccdb0b..4527d520e9 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -529,4 +529,19 @@ public enum UpdateVersion /// The version of the . /// ConfigureCastleSiegeParticipation = 104, + + /// + /// The version of the . + /// + RegenerationsRefactor075 = 105, + + /// + /// The version of the . + /// + RegenerationsRefactor095d = 106, + + /// + /// The version of the . + /// + RegenerationsRefactorSeason6 = 107, } diff --git a/src/Persistence/Initialization/VersionSeasonSix/GameConfigurationInitializer.cs b/src/Persistence/Initialization/VersionSeasonSix/GameConfigurationInitializer.cs index d95ae5595e..d6a480b5a7 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/GameConfigurationInitializer.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/GameConfigurationInitializer.cs @@ -1,4 +1,4 @@ -// +// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // @@ -53,7 +53,7 @@ public override void Initialize() this.GameConfiguration.ItemOptions.Add(this.CreateOptionDefinition(Stats.CurseBaseDmg, ItemOptionDefinitionNumbers.CurseAttack)); var maximumAllianceSizeDef = Stats.MaximumAllianceSize.GetPersistent(this.GameConfiguration); - var maximumAllianceSizeValue = this.Context.CreateNew(5f, maximumAllianceSizeDef); + var maximumAllianceSizeValue = this.Context.CreateNew(5f, maximumAllianceSizeDef, AggregateType.AddRaw); this.GameConfiguration.GlobalBaseAttributeValues.Add(maximumAllianceSizeValue); new CharacterClassInitialization(this.Context, this.GameConfiguration).Initialize(); diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/GuardianOptions.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/GuardianOptions.cs index 0ececa34fb..83482c452b 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/GuardianOptions.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/GuardianOptions.cs @@ -79,7 +79,7 @@ private void CreateHelmOption() definition.AddsRandomly = false; definition.PossibleOptions.Add(this.CreateOption(ItemGroups.Helm, Stats.DefenseRatePvp, 10, AggregateType.AddRaw, ItemOptionDefinitionNumbers.GuardianOption1)); - definition.PossibleOptions.Add(this.CreateOption(ItemGroups.Helm, Stats.ShieldRecoveryMultiplier, 20, AggregateType.AddRaw, ItemOptionDefinitionNumbers.GuardianOption2)); // 20 absolute, need test + definition.PossibleOptions.Add(this.CreateOption(ItemGroups.Helm, Stats.ShieldRecoveryMultiplier, 20, AggregateType.AddRaw, ItemOptionDefinitionNumbers.GuardianOption2)); } private void CreateGlovesOption() diff --git a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs index 70c537a203..7ba9bcfb83 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs @@ -769,7 +769,7 @@ private void InitializeMasterSkillData() this.AddPassiveMasterSkillDefinition(SkillNumber.AutomaticManaRecInc, Stats.ManaRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease181, Formula181, 2, 1, SkillNumber.Undefined, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.PoisonResistanceInc, Stats.PoisonResistance, AggregateType.AddRaw, Formula120, Formula120, 2, 1); this.AddPassiveMasterSkillDefinition(SkillNumber.DurabilityReduction2, Stats.ItemDurationIncrease, AggregateType.Multiplicate, Formula1204, 3, 1, SkillNumber.DurabilityReduction1); - this.AddMasterSkillDefinition(SkillNumber.SdRecoverySpeedInc, SkillNumber.MaximumSDincrease, SkillNumber.Undefined, 1, 3, SkillNumber.Undefined, 20, Formula120); + this.AddPassiveMasterSkillDefinition(SkillNumber.SdRecoverySpeedInc, Stats.ShieldRecoveryMultiplier, AggregateType.Multiplicate, $"1 + {FormulaRecoveryIncrease120}", Formula120, 3, 1, SkillNumber.MaximumSDincrease, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.AutomaticHpRecInc, Stats.HealthRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease120, Formula120, 3, 1, SkillNumber.AutomaticManaRecInc, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.LightningResistanceInc, Stats.LightningResistance, AggregateType.AddRaw, Formula120, Formula120, 2, 1, requiredSkill1: SkillNumber.PoisonResistanceInc); this.AddPassiveMasterSkillDefinition(SkillNumber.DefenseIncrease, Stats.DefenseBase, AggregateType.AddFinal, Formula6020, 4, 1); @@ -919,7 +919,7 @@ private void InitializeMasterSkillData() this.AddPassiveMasterSkillDefinition(SkillNumber.IncreaseManaRecoveryRate, Stats.ManaRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease181, Formula181, 2, 1, SkillNumber.Undefined, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.IncreasePoisonResistance, Stats.PoisonResistance, AggregateType.AddRaw, Formula120Value, Formula120, 2, 1); this.AddPassiveMasterSkillDefinition(SkillNumber.DurabilityReduction2FistMaster, Stats.ItemDurationIncrease, AggregateType.Multiplicate, Formula1204, 3, 1, SkillNumber.DurabilityReduction1FistMaster); - this.AddPassiveMasterSkillDefinition(SkillNumber.IncreaseSdRecoveryRate, Stats.ShieldRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease120, Formula120, 3, 1, SkillNumber.IncreaseMaximumSd, SkillNumber.Undefined, 20); + this.AddPassiveMasterSkillDefinition(SkillNumber.IncreaseSdRecoveryRate, Stats.ShieldRecoveryMultiplier, AggregateType.Multiplicate, $"1 + {FormulaRecoveryIncrease120}", Formula120, 3, 1, SkillNumber.IncreaseMaximumSd, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.IncreaseHpRecoveryRate, Stats.HealthRecoveryMultiplier, AggregateType.AddRaw, FormulaRecoveryIncrease120, Formula120, 3, 1, SkillNumber.IncreaseManaRecoveryRate, SkillNumber.Undefined, 20); this.AddPassiveMasterSkillDefinition(SkillNumber.IncreaseLightningResistance, Stats.LightningResistance, AggregateType.AddRaw, Formula120Value, Formula120, 3, 1, requiredSkill1: SkillNumber.IncreasePoisonResistance); this.AddPassiveMasterSkillDefinition(SkillNumber.IncreasesDefense, Stats.DefenseBase, AggregateType.AddFinal, Formula3371, 4, 1);