baseline: OpenMU upstream b5a0961 (fresh source)
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
// <copyright file="GameConfigurationInitializerBase.cs" company="MUnique">
|
||||
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
||||
// </copyright>
|
||||
|
||||
namespace MUnique.OpenMU.Persistence.Initialization;
|
||||
|
||||
using System.Reflection;
|
||||
using MUnique.OpenMU.AttributeSystem;
|
||||
using MUnique.OpenMU.DataModel.Attributes;
|
||||
using MUnique.OpenMU.DataModel.Configuration;
|
||||
using MUnique.OpenMU.DataModel.Configuration.Items;
|
||||
using MUnique.OpenMU.GameLogic.Attributes;
|
||||
using MUnique.OpenMU.Persistence.Initialization.CharacterClasses;
|
||||
using MUnique.OpenMU.Persistence.Initialization.Version075.Items;
|
||||
using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Maps;
|
||||
|
||||
/// <summary>
|
||||
/// Common base for an initialization of a <see cref="GameConfiguration"/>.
|
||||
/// </summary>
|
||||
public abstract class GameConfigurationInitializerBase : InitializerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameConfigurationInitializerBase"/> class.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="gameConfiguration">The game configuration.</param>
|
||||
protected GameConfigurationInitializerBase(IContext context, GameConfiguration gameConfiguration)
|
||||
: base(context, gameConfiguration)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the option types which are available.
|
||||
/// </summary>
|
||||
protected abstract IEnumerable<ItemOptionType> OptionTypes { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize()
|
||||
{
|
||||
this.GameConfiguration.ExperienceRate = 1.0f;
|
||||
this.GameConfiguration.MinimumMonsterLevelForMasterExperience = 95;
|
||||
this.GameConfiguration.MaximumLevel = 400;
|
||||
this.GameConfiguration.MaximumMasterLevel = 200;
|
||||
this.GameConfiguration.InfoRange = 12;
|
||||
this.GameConfiguration.AreaSkillHitsPlayer = false;
|
||||
this.GameConfiguration.MaximumInventoryMoney = int.MaxValue;
|
||||
this.GameConfiguration.MaximumVaultMoney = int.MaxValue;
|
||||
this.GameConfiguration.PreventExperienceOverflow = false;
|
||||
this.GameConfiguration.ClampMoneyOnPickup = false;
|
||||
this.GameConfiguration.ExcellentItemDropLevelDelta = 25;
|
||||
this.GameConfiguration.RecoveryInterval = 3000;
|
||||
this.GameConfiguration.MaximumLetters = 50;
|
||||
this.GameConfiguration.LetterSendPrice = 1000;
|
||||
this.GameConfiguration.MaximumCharactersPerAccount = 5;
|
||||
this.GameConfiguration.CharacterNameRegex = "^[a-zA-Z0-9]{3,10}$";
|
||||
this.GameConfiguration.MaximumPasswordLength = 20;
|
||||
this.GameConfiguration.MaximumPartySize = 5;
|
||||
this.GameConfiguration.ShouldDropMoney = true;
|
||||
this.GameConfiguration.ItemDropDuration = TimeSpan.FromSeconds(60);
|
||||
this.GameConfiguration.MaximumItemOptionLevelDrop = 3;
|
||||
this.GameConfiguration.DamagePerOneItemDurability = 2000;
|
||||
this.GameConfiguration.DamagePerOnePetDurability = 100000;
|
||||
this.GameConfiguration.HitsPerOneItemDurability = 10000;
|
||||
|
||||
this.GameConfiguration.ExperienceFormula = "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))))";
|
||||
this.GameConfiguration.MasterExperienceFormula = "(505 * level * level * level) + (35278500 * level) + (228045 * level * level)";
|
||||
|
||||
this.AddItemDropGroups();
|
||||
|
||||
this.CreateStatAttributes();
|
||||
this.AddGlobalBaseAttributeValues();
|
||||
|
||||
new SlotTypesInitializer(this.Context, this.GameConfiguration).Initialize();
|
||||
this.CreateItemOptionTypes();
|
||||
this.GameConfiguration.ItemOptions.Add(this.CreateLuckOptionDefinition());
|
||||
this.GameConfiguration.ItemOptions.Add(this.CreateOptionDefinition(Stats.DefenseBase, ItemOptionDefinitionNumbers.DefenseOption));
|
||||
this.GameConfiguration.ItemOptions.Add(this.CreateOptionDefinition(Stats.PhysicalBaseDmg, ItemOptionDefinitionNumbers.PhysicalAttack));
|
||||
this.GameConfiguration.ItemOptions.Add(this.CreateOptionDefinition(Stats.WizardryBaseDmg, ItemOptionDefinitionNumbers.WizardryAttack));
|
||||
this.GameConfiguration.ItemOptions.Add(this.CreateOptionDefinition(Stats.DefenseRatePvm, ItemOptionDefinitionNumbers.DefenseRateOption, 5));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the necessary experience for the specified character level.
|
||||
/// </summary>
|
||||
/// <param name="level">The character level.</param>
|
||||
/// <returns>The calculated necessary experience.</returns>
|
||||
internal static long CalculateNeededExperience(long level)
|
||||
{
|
||||
if (level == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (level < 256)
|
||||
{
|
||||
return 10 * (level + 8) * (level - 1) * (level - 1);
|
||||
}
|
||||
|
||||
return (10 * (level + 8) * (level - 1) * (level - 1)) +
|
||||
(1000 * (level - 247) * (level - 256) * (level - 256));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an item option definition for the specified attribute definition.
|
||||
/// </summary>
|
||||
/// <param name="attributeDefinition">The attribute definition.</param>
|
||||
/// <param name="number">The amount of the item option definition.</param>
|
||||
/// <param name="baseValue">The base value for the item option.</param>
|
||||
/// <returns>The created item option definition.</returns>
|
||||
protected ItemOptionDefinition CreateOptionDefinition(AttributeDefinition attributeDefinition, short number, byte baseValue = 4)
|
||||
{
|
||||
var definition = this.Context.CreateNew<ItemOptionDefinition>();
|
||||
definition.SetGuid(number);
|
||||
definition.Name = attributeDefinition.Designation + " Option";
|
||||
definition.AddChance = 0.25f;
|
||||
definition.AddsRandomly = true;
|
||||
definition.MaximumOptionsPerItem = 1;
|
||||
|
||||
var itemOption = this.Context.CreateNew<IncreasableItemOption>();
|
||||
itemOption.SetGuid(number);
|
||||
itemOption.OptionType =
|
||||
this.GameConfiguration.ItemOptionTypes.FirstOrDefault(o => o == ItemOptionTypes.Option);
|
||||
itemOption.PowerUpDefinition = this.Context.CreateNew<PowerUpDefinition>();
|
||||
itemOption.PowerUpDefinition.TargetAttribute =
|
||||
this.GameConfiguration.Attributes.First(a => a == attributeDefinition);
|
||||
itemOption.PowerUpDefinition.Boost = this.Context.CreateNew<PowerUpDefinitionValue>();
|
||||
itemOption.PowerUpDefinition.Boost.ConstantValue!.Value = baseValue;
|
||||
for (short level = 2; level <= this.MaximumOptionLevel; level++)
|
||||
{
|
||||
var levelDependentOption = this.Context.CreateNew<ItemOptionOfLevel>();
|
||||
levelDependentOption.Level = level;
|
||||
var powerUpDefinition = this.Context.CreateNew<PowerUpDefinition>();
|
||||
powerUpDefinition.TargetAttribute = itemOption.PowerUpDefinition.TargetAttribute;
|
||||
powerUpDefinition.Boost = this.Context.CreateNew<PowerUpDefinitionValue>();
|
||||
powerUpDefinition.Boost.ConstantValue!.Value = level * baseValue;
|
||||
levelDependentOption.PowerUpDefinition = powerUpDefinition;
|
||||
itemOption.LevelDependentOptions.Add(levelDependentOption);
|
||||
}
|
||||
|
||||
definition.PossibleOptions.Add(itemOption);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns the character class home maps.
|
||||
/// Needs to be called after the character classes and maps have been initialized.
|
||||
/// </summary>
|
||||
protected void AssignCharacterClassHomeMaps()
|
||||
{
|
||||
foreach (var characterClass in this.GameConfiguration.CharacterClasses)
|
||||
{
|
||||
byte mapNumber;
|
||||
switch ((CharacterClassNumber)characterClass.Number)
|
||||
{
|
||||
case CharacterClassNumber.FairyElf:
|
||||
case CharacterClassNumber.HighElf:
|
||||
case CharacterClassNumber.MuseElf:
|
||||
mapNumber = Noria.Number;
|
||||
break;
|
||||
case CharacterClassNumber.BloodySummoner:
|
||||
case CharacterClassNumber.Summoner:
|
||||
mapNumber = Elvenland.Number;
|
||||
break;
|
||||
default:
|
||||
mapNumber = Lorencia.Number;
|
||||
break;
|
||||
}
|
||||
|
||||
characterClass.HomeMap = this.GameConfiguration.Maps.First(map => map.Number == mapNumber);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddItemDropGroups()
|
||||
{
|
||||
var moneyDropItemGroup = this.Context.CreateNew<DropItemGroup>();
|
||||
moneyDropItemGroup.SetGuid(1);
|
||||
moneyDropItemGroup.Chance = 0.5;
|
||||
moneyDropItemGroup.ItemType = SpecialItemType.Money;
|
||||
moneyDropItemGroup.Description = "The common money drop item group (50 % drop chance)";
|
||||
this.GameConfiguration.DropItemGroups.Add(moneyDropItemGroup);
|
||||
BaseMapInitializer.RegisterDefaultDropItemGroup(moneyDropItemGroup);
|
||||
|
||||
var randomItemDropItemGroup = this.Context.CreateNew<DropItemGroup>();
|
||||
randomItemDropItemGroup.SetGuid(2);
|
||||
randomItemDropItemGroup.Chance = 0.3;
|
||||
randomItemDropItemGroup.ItemType = SpecialItemType.RandomItem;
|
||||
randomItemDropItemGroup.Description = "The common drop item group for random items (30 % drop chance)";
|
||||
this.GameConfiguration.DropItemGroups.Add(randomItemDropItemGroup);
|
||||
BaseMapInitializer.RegisterDefaultDropItemGroup(randomItemDropItemGroup);
|
||||
|
||||
if (this.OptionTypes.Contains(ItemOptionTypes.Excellent))
|
||||
{
|
||||
var excellentItemDropItemGroup = this.Context.CreateNew<DropItemGroup>();
|
||||
excellentItemDropItemGroup.SetGuid(3);
|
||||
excellentItemDropItemGroup.Chance = 0.0001;
|
||||
excellentItemDropItemGroup.ItemType = SpecialItemType.Excellent;
|
||||
excellentItemDropItemGroup.ItemLevel = 0;
|
||||
excellentItemDropItemGroup.Description =
|
||||
"The common drop item group for random excellent items (0.01 % drop chance)";
|
||||
this.GameConfiguration.DropItemGroups.Add(excellentItemDropItemGroup);
|
||||
BaseMapInitializer.RegisterDefaultDropItemGroup(excellentItemDropItemGroup);
|
||||
}
|
||||
|
||||
var jewelsDropItemGroup = this.Context.CreateNew<DropItemGroup>();
|
||||
jewelsDropItemGroup.SetGuid(4);
|
||||
jewelsDropItemGroup.Chance = 0.001;
|
||||
jewelsDropItemGroup.ItemType = SpecialItemType.Jewel;
|
||||
jewelsDropItemGroup.Description = "The jewels drop item group (0.1 % drop chance)";
|
||||
this.GameConfiguration.DropItemGroups.Add(jewelsDropItemGroup);
|
||||
BaseMapInitializer.RegisterDefaultDropItemGroup(jewelsDropItemGroup);
|
||||
}
|
||||
|
||||
private ItemOptionDefinition CreateLuckOptionDefinition()
|
||||
{
|
||||
var definition = this.Context.CreateNew<ItemOptionDefinition>();
|
||||
definition.SetGuid(ItemOptionDefinitionNumbers.Luck);
|
||||
definition.Name = "Luck";
|
||||
definition.AddChance = 0.25f;
|
||||
definition.AddsRandomly = true;
|
||||
definition.MaximumOptionsPerItem = 1;
|
||||
|
||||
var itemOption = this.Context.CreateNew<IncreasableItemOption>();
|
||||
itemOption.SetGuid(ItemOptionDefinitionNumbers.Luck);
|
||||
itemOption.OptionType =
|
||||
this.GameConfiguration.ItemOptionTypes.FirstOrDefault(o => o == ItemOptionTypes.Luck);
|
||||
itemOption.PowerUpDefinition = this.Context.CreateNew<PowerUpDefinition>();
|
||||
itemOption.PowerUpDefinition.TargetAttribute =
|
||||
this.GameConfiguration.Attributes.FirstOrDefault(a => a == Stats.CriticalDamageChance);
|
||||
itemOption.PowerUpDefinition.Boost = this.Context.CreateNew<PowerUpDefinitionValue>();
|
||||
itemOption.PowerUpDefinition.Boost.ConstantValue!.Value = 0.05f;
|
||||
definition.PossibleOptions.Add(itemOption);
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
private void CreateItemOptionTypes()
|
||||
{
|
||||
foreach (var optionType in this.OptionTypes)
|
||||
{
|
||||
var persistentOptionType = this.Context.CreateNew<ItemOptionType>();
|
||||
persistentOptionType.Description = optionType.Description;
|
||||
persistentOptionType.Id = optionType.Id;
|
||||
persistentOptionType.Name = optionType.Name;
|
||||
persistentOptionType.IsVisible = optionType.IsVisible;
|
||||
this.GameConfiguration.ItemOptionTypes.Add(persistentOptionType);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the stat attributes.
|
||||
/// </summary>
|
||||
private void CreateStatAttributes()
|
||||
{
|
||||
var attributes = typeof(Stats)
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)
|
||||
.Where(p => p.PropertyType == typeof(AttributeDefinition))
|
||||
.Select(p => p.GetValue(typeof(Stats)))
|
||||
.OfType<AttributeDefinition>()
|
||||
.ToList();
|
||||
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
var persistentAttribute = this.Context.CreateNew<AttributeDefinition>(attribute.Id, attribute.Designation, attribute.Description);
|
||||
persistentAttribute.MaximumValue = attribute.MaximumValue;
|
||||
this.GameConfiguration.Attributes.Add(persistentAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the global base attribute values which apply to all characters.
|
||||
/// </summary>
|
||||
private void AddGlobalBaseAttributeValues()
|
||||
{
|
||||
var moneyAmountRate = this.Context.CreateNew<ConstValueAttribute>(1f, Stats.MoneyAmountRate.GetPersistent(this.GameConfiguration));
|
||||
this.GameConfiguration.GlobalBaseAttributeValues.Add(moneyAmountRate);
|
||||
|
||||
var randomExperienceMinMultiplier = this.Context.CreateNew<ConstValueAttribute>(0.8f, Stats.RandomExperienceMinMultiplier.GetPersistent(this.GameConfiguration));
|
||||
this.GameConfiguration.GlobalBaseAttributeValues.Add(randomExperienceMinMultiplier);
|
||||
|
||||
var randomExperienceMaxMultiplier = this.Context.CreateNew<ConstValueAttribute>(1.2f, Stats.RandomExperienceMaxMultiplier.GetPersistent(this.GameConfiguration));
|
||||
this.GameConfiguration.GlobalBaseAttributeValues.Add(randomExperienceMaxMultiplier);
|
||||
|
||||
this.GameConfiguration.GlobalBaseAttributeValues.Add(this.Context.CreateNew<ConstValueAttribute>(1f, Stats.MovementSpeedFactor.GetPersistent(this.GameConfiguration)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user