Core/Players: Introduce configurable allied race starting level and fix default level selection for pandaren death knights
Port From (https://github.com/TrinityCore/TrinityCore/commit/bff8f2ff4ebc4144a2c1c31a65b78a1f0ed3f973)
This commit is contained in:
@@ -991,6 +991,11 @@ namespace Framework.Constants
|
|||||||
Factional = 0x40
|
Factional = 0x40
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ChrRacesFlag
|
||||||
|
{
|
||||||
|
AlliedRace = 0x80000
|
||||||
|
}
|
||||||
|
|
||||||
public enum ChrSpecializationFlag
|
public enum ChrSpecializationFlag
|
||||||
{
|
{
|
||||||
Caster = 0x01,
|
Caster = 0x01,
|
||||||
|
|||||||
@@ -1346,6 +1346,7 @@ namespace Framework.Constants
|
|||||||
SkipCinematics,
|
SkipCinematics,
|
||||||
SocketTimeoutTime,
|
SocketTimeoutTime,
|
||||||
SocketTimeoutTimeActive,
|
SocketTimeoutTimeActive,
|
||||||
|
StartAlliedRaceLevel,
|
||||||
StartAllExplored,
|
StartAllExplored,
|
||||||
StartAllRep,
|
StartAllRep,
|
||||||
StartAllSpells,
|
StartAllSpells,
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace Game.Chat
|
|||||||
byte oldLevel = (byte)target.GetLevel();
|
byte oldLevel = (byte)target.GetLevel();
|
||||||
|
|
||||||
// set starting level
|
// set starting level
|
||||||
uint startLevel = (uint)(target.GetClass() != Class.Deathknight ? WorldConfig.GetIntValue(WorldCfg.StartPlayerLevel) : WorldConfig.GetIntValue(WorldCfg.StartDeathKnightPlayerLevel));
|
uint startLevel = target.GetStartLevel(target.GetRace(), target.GetClass());
|
||||||
|
|
||||||
target._ApplyAllLevelScaleItemMods(false);
|
target._ApplyAllLevelScaleItemMods(false);
|
||||||
target.SetLevel(startLevel);
|
target.SetLevel(startLevel);
|
||||||
|
|||||||
@@ -265,6 +265,8 @@ namespace Game.DataStorage
|
|||||||
public sbyte FemaleTextureFallbackRaceID;
|
public sbyte FemaleTextureFallbackRaceID;
|
||||||
public sbyte FemaleTextureFallbackSex;
|
public sbyte FemaleTextureFallbackSex;
|
||||||
public sbyte UnalteredVisualCustomizationRaceID;
|
public sbyte UnalteredVisualCustomizationRaceID;
|
||||||
|
|
||||||
|
public ChrRacesFlag GetFlags() { return (ChrRacesFlag)Flags; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ChrSpecializationRecord
|
public sealed class ChrSpecializationRecord
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ using Game.Spells;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Framework.Dynamic;
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -231,35 +232,7 @@ namespace Game.Entities
|
|||||||
SetInventorySlotCount(InventorySlots.DefaultSize);
|
SetInventorySlotCount(InventorySlots.DefaultSize);
|
||||||
|
|
||||||
// set starting level
|
// set starting level
|
||||||
uint start_level = WorldConfig.GetUIntValue(WorldCfg.StartPlayerLevel);
|
SetLevel((uint)GetStartLevel(createInfo.RaceId, createInfo.ClassId, createInfo.TemplateSet));
|
||||||
if (GetClass() == Class.Deathknight)
|
|
||||||
start_level = WorldConfig.GetUIntValue(WorldCfg.StartDeathKnightPlayerLevel);
|
|
||||||
else if (GetClass() == Class.DemonHunter)
|
|
||||||
start_level = WorldConfig.GetUIntValue(WorldCfg.StartDemonHunterPlayerLevel);
|
|
||||||
|
|
||||||
if (createInfo.TemplateSet.HasValue)
|
|
||||||
{
|
|
||||||
if (GetSession().HasPermission(RBACPermissions.UseCharacterTemplates))
|
|
||||||
{
|
|
||||||
CharacterTemplate charTemplate = Global.CharacterTemplateDataStorage.GetCharacterTemplate(createInfo.TemplateSet.Value);
|
|
||||||
if (charTemplate != null)
|
|
||||||
{
|
|
||||||
if (charTemplate.Level > start_level)
|
|
||||||
start_level = charTemplate.Level;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Log.outWarn(LogFilter.Cheat, "Account: {0} (IP: {1}) tried to use a character template without given permission. Possible cheating attempt.", GetSession().GetAccountId(), GetSession().GetRemoteAddress());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetSession().HasPermission(RBACPermissions.UseStartGmLevel))
|
|
||||||
{
|
|
||||||
uint gm_level = WorldConfig.GetUIntValue(WorldCfg.StartGmLevel);
|
|
||||||
if (gm_level > start_level)
|
|
||||||
start_level = gm_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLevel(start_level);
|
|
||||||
|
|
||||||
InitRunes();
|
InitRunes();
|
||||||
|
|
||||||
@@ -1877,6 +1850,41 @@ namespace Game.Entities
|
|||||||
mapId = 0;
|
mapId = 0;
|
||||||
return new WorldLocation(mapId, info.PositionX, info.PositionY, info.PositionZ, 0);
|
return new WorldLocation(mapId, info.PositionX, info.PositionY, info.PositionZ, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint GetStartLevel(Race race, Class playerClass, Optional<uint> characterTemplateId = default)
|
||||||
|
{
|
||||||
|
uint startLevel = WorldConfig.GetUIntValue(WorldCfg.StartPlayerLevel);
|
||||||
|
if (CliDB.ChrRacesStorage.LookupByKey(race).GetFlags().HasFlag(ChrRacesFlag.AlliedRace))
|
||||||
|
startLevel = WorldConfig.GetUIntValue(WorldCfg.StartAlliedRaceLevel);
|
||||||
|
|
||||||
|
if (playerClass == Class.Deathknight)
|
||||||
|
{
|
||||||
|
if (race == Race.PandarenAlliance || race == Race.PandarenHorde)
|
||||||
|
startLevel = Math.Max(WorldConfig.GetUIntValue(WorldCfg.StartAlliedRaceLevel), startLevel);
|
||||||
|
else
|
||||||
|
startLevel = Math.Max(WorldConfig.GetUIntValue(WorldCfg.StartDeathKnightPlayerLevel), startLevel);
|
||||||
|
}
|
||||||
|
else if (playerClass == Class.DemonHunter)
|
||||||
|
startLevel = Math.Max(WorldConfig.GetUIntValue(WorldCfg.StartDemonHunterPlayerLevel), startLevel);
|
||||||
|
|
||||||
|
if (characterTemplateId.HasValue)
|
||||||
|
{
|
||||||
|
if (GetSession().HasPermission(RBACPermissions.UseCharacterTemplates))
|
||||||
|
{
|
||||||
|
CharacterTemplate charTemplate = Global.CharacterTemplateDataStorage.GetCharacterTemplate(characterTemplateId.Value);
|
||||||
|
if (charTemplate != null)
|
||||||
|
startLevel = Math.Max(charTemplate.Level, startLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Log.outWarn(LogFilter.Cheat, $"Account: {GetSession().GetAccountId()} (IP: {GetSession().GetRemoteAddress()}) tried to use a character template without given permission. Possible cheating attempt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetSession().HasPermission(RBACPermissions.UseStartGmLevel))
|
||||||
|
startLevel = Math.Max(WorldConfig.GetUIntValue(WorldCfg.StartGmLevel), startLevel);
|
||||||
|
|
||||||
|
return startLevel;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool IsUnderWater()
|
public override bool IsUnderWater()
|
||||||
{
|
{
|
||||||
return IsInWater() &&
|
return IsInWater() &&
|
||||||
|
|||||||
@@ -408,12 +408,12 @@ namespace Game
|
|||||||
Values[WorldCfg.StartPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
Values[WorldCfg.StartPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
Values[WorldCfg.StartDeathKnightPlayerLevel] = GetDefaultValue("StartDeathKnightPlayerLevel", 55);
|
Values[WorldCfg.StartDeathKnightPlayerLevel] = GetDefaultValue("StartDeathKnightPlayerLevel", 8);
|
||||||
if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] < 1)
|
if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] < 1)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.ServerLoading, "StartDeathKnightPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 55.",
|
Log.outError(LogFilter.ServerLoading, "StartDeathKnightPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 1.",
|
||||||
Values[WorldCfg.StartDeathKnightPlayerLevel], Values[WorldCfg.MaxPlayerLevel]);
|
Values[WorldCfg.StartDeathKnightPlayerLevel], Values[WorldCfg.MaxPlayerLevel]);
|
||||||
Values[WorldCfg.StartDeathKnightPlayerLevel] = 55;
|
Values[WorldCfg.StartDeathKnightPlayerLevel] = 1;
|
||||||
}
|
}
|
||||||
else if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel])
|
else if ((int)Values[WorldCfg.StartDeathKnightPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel])
|
||||||
{
|
{
|
||||||
@@ -422,12 +422,12 @@ namespace Game
|
|||||||
Values[WorldCfg.StartDeathKnightPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
Values[WorldCfg.StartDeathKnightPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
Values[WorldCfg.StartDemonHunterPlayerLevel] = GetDefaultValue("StartDemonHunterPlayerLevel", 98);
|
Values[WorldCfg.StartDemonHunterPlayerLevel] = GetDefaultValue("StartDemonHunterPlayerLevel", 8);
|
||||||
if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] < 98)
|
if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] < 1)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.ServerLoading, "StartDemonHunterPlayerLevel ({0}) must be in range 98..MaxPlayerLevel({1}). Set to 98.",
|
Log.outError(LogFilter.ServerLoading, "StartDemonHunterPlayerLevel ({0}) must be in range 1..MaxPlayerLevel({1}). Set to 1.",
|
||||||
Values[WorldCfg.StartDemonHunterPlayerLevel], Values[WorldCfg.MaxPlayerLevel]);
|
Values[WorldCfg.StartDemonHunterPlayerLevel], Values[WorldCfg.MaxPlayerLevel]);
|
||||||
Values[WorldCfg.StartDemonHunterPlayerLevel] = 98;
|
Values[WorldCfg.StartDemonHunterPlayerLevel] = 1;
|
||||||
}
|
}
|
||||||
else if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel])
|
else if ((int)Values[WorldCfg.StartDemonHunterPlayerLevel] > (int)Values[WorldCfg.MaxPlayerLevel])
|
||||||
{
|
{
|
||||||
@@ -436,6 +436,18 @@ namespace Game
|
|||||||
Values[WorldCfg.StartDemonHunterPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
Values[WorldCfg.StartDemonHunterPlayerLevel] = Values[WorldCfg.MaxPlayerLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Values[WorldCfg.StartAlliedRaceLevel] = GetDefaultValue("StartAlliedRacePlayerLevel", 10);
|
||||||
|
if ((int)Values[WorldCfg.StartAlliedRaceLevel] < 1)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.ServerLoading, $"StartDemonHunterPlayerLevel ({Values[WorldCfg.StartAlliedRaceLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to 1.");
|
||||||
|
Values[WorldCfg.StartAlliedRaceLevel] = 1;
|
||||||
|
}
|
||||||
|
else if ((int)Values[WorldCfg.StartAlliedRaceLevel] > (int)Values[WorldCfg.MaxPlayerLevel])
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.ServerLoading, $"StartDemonHunterPlayerLevel ({Values[WorldCfg.StartAlliedRaceLevel]}) must be in range 1..MaxPlayerLevel({Values[WorldCfg.MaxPlayerLevel]}). Set to {Values[WorldCfg.MaxPlayerLevel]}.");
|
||||||
|
Values[WorldCfg.StartAlliedRaceLevel] = Values[WorldCfg.MaxPlayerLevel];
|
||||||
|
}
|
||||||
|
|
||||||
Values[WorldCfg.StartPlayerMoney] = GetDefaultValue("StartPlayerMoney", 0);
|
Values[WorldCfg.StartPlayerMoney] = GetDefaultValue("StartPlayerMoney", 0);
|
||||||
if ((int)Values[WorldCfg.StartPlayerMoney] < 0)
|
if ((int)Values[WorldCfg.StartPlayerMoney] < 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -843,9 +843,9 @@ StartPlayerLevel = 1
|
|||||||
# StartDeathKnightPlayerLevel
|
# StartDeathKnightPlayerLevel
|
||||||
# Description: Starting level for death knights after creation.
|
# Description: Starting level for death knights after creation.
|
||||||
# Range: 1-MaxPlayerLevel
|
# Range: 1-MaxPlayerLevel
|
||||||
# Default: 10
|
# Default: 8
|
||||||
|
|
||||||
StartDeathKnightPlayerLevel = 10
|
StartDeathKnightPlayerLevel = 8
|
||||||
|
|
||||||
#
|
#
|
||||||
# StartDemonHunterPlayerLevel
|
# StartDemonHunterPlayerLevel
|
||||||
@@ -855,6 +855,14 @@ StartDeathKnightPlayerLevel = 10
|
|||||||
|
|
||||||
StartDemonHunterPlayerLevel = 8
|
StartDemonHunterPlayerLevel = 8
|
||||||
|
|
||||||
|
#
|
||||||
|
# StartAlliedRacePlayerLevel
|
||||||
|
# Description: Staring level for allied races after creation.
|
||||||
|
# Range: 1-MaxPlayerLevel
|
||||||
|
# Default: 10
|
||||||
|
|
||||||
|
StartAlliedRacePlayerLevel = 10
|
||||||
|
|
||||||
#
|
#
|
||||||
# StartPlayerMoney
|
# StartPlayerMoney
|
||||||
# Description: Amount of money (in Copper) that a character has after creation.
|
# Description: Amount of money (in Copper) that a character has after creation.
|
||||||
|
|||||||
Reference in New Issue
Block a user