Changelog:
GameServerConfig.cs and Player.cs: - StrengthMultiplier / StrengthParagonMultipler - DexterityMultiplier / DexterityParagonMultiplier - IntelligenceMultiplier / IntelligenceParagonMultiplier - VitalityMultiplier / VitalityParagonMultiplier CommandManager.cs and CommandsConfig.cs: - Added a command group disable parameter (DisabledGroups). A ranking system should be added later on. RestSession.cs and Http.cs: - Added battlenet login POST and GET; - If no page is found on DEBUG, it returns 502 (Bad GW - if on NAT it could be useful for stopping bots of retrying connection with the server) otherwise returns 404 Others: !drop minor changes Cleanups
This commit is contained in:
parent
3d123f409f
commit
6657f17730
@ -107,7 +107,7 @@ namespace DiIiS_NA.Core.Logging
|
|||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var fileName = Path.GetFileName(filePath);
|
var fileName = Path.GetFileName(filePath);
|
||||||
Log(Level.MethodTrace, $"$[underline white]${fileName}:{lineNumber}$[/]$ $[darkolivegreen3_2]${methodName}()$[/]$: $[black on white]$" + message + "$[/]$", null);
|
Log(Level.MethodTrace, $"$[underline white]${fileName}:{lineNumber}$[/]$ $[darkolivegreen3_2]${methodName}()$[/]$: " + message, null);
|
||||||
#else
|
#else
|
||||||
Log(Level.MethodTrace, $"$[darkolivegreen3_2]${methodName}()$[/]$: " + message, null);
|
Log(Level.MethodTrace, $"$[darkolivegreen3_2]${methodName}()$[/]$: " + message, null);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -13,23 +13,17 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
private static Object _globalSessionLock = new object();
|
private static Object _globalSessionLock = new object();
|
||||||
private Object _sessionLock = new object();
|
private Object _sessionLock = new object();
|
||||||
private IStatelessSession _gameSession = null;
|
private IStatelessSession _gameSession = null;
|
||||||
private readonly Logger Logger = LogManager.CreateLogger("DB");
|
private readonly Logger Logger = LogManager.CreateLogger(nameof(GameDBSession));
|
||||||
|
|
||||||
public GameDBSession()
|
public GameDBSession()
|
||||||
{
|
{
|
||||||
lock (_globalSessionLock)
|
lock (_globalSessionLock)
|
||||||
{
|
{
|
||||||
this._gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
_gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IStatelessSession GameSession
|
private IStatelessSession GameSession => _gameSession;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._gameSession;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SessionSave(Object obj)
|
public void SessionSave(Object obj)
|
||||||
{
|
{
|
||||||
@ -39,8 +33,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
session.Insert(obj);
|
session.Insert(obj);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -74,8 +68,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
session.Update(obj);
|
session.Update(obj);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -109,8 +103,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
session.Delete(obj);
|
session.Delete(obj);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -157,8 +151,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
return session.Query<T>().ToList();
|
return session.Query<T>().ToList();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -189,8 +183,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
return session.QueryOver<T>().Where(predicate).List().ToList();
|
return session.QueryOver<T>().Where(predicate).List().ToList();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -221,8 +215,8 @@ namespace DiIiS_NA.Core.Storage
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||||
return (T)session.QueryOver<T>().Where(predicate).List().FirstOrDefault();
|
return (T)session.QueryOver<T>().Where(predicate).List().FirstOrDefault();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -24,17 +24,28 @@ namespace DiIiS_NA.GameServer.CommandManager
|
|||||||
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
||||||
{
|
{
|
||||||
if (!type.IsSubclassOf(typeof(CommandGroup))) continue;
|
if (!type.IsSubclassOf(typeof(CommandGroup))) continue;
|
||||||
|
|
||||||
var attributes = (CommandGroupAttribute[])type.GetCustomAttributes(typeof(CommandGroupAttribute), true);
|
var attributes = (CommandGroupAttribute[])type.GetCustomAttributes(typeof(CommandGroupAttribute), true);
|
||||||
if (attributes.Length == 0) continue;
|
if (attributes.Length == 0) continue;
|
||||||
|
|
||||||
var groupAttribute = attributes[0];
|
var groupAttribute = attributes[0];
|
||||||
|
if (groupAttribute.Name == null) continue;
|
||||||
|
if (CommandsConfig.Instance.DisabledGroupsData.Contains(groupAttribute.Name))
|
||||||
|
{
|
||||||
|
Logger.Trace($"Command group {groupAttribute.Name} is disabled.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (CommandGroups.ContainsKey(groupAttribute))
|
if (CommandGroups.ContainsKey(groupAttribute))
|
||||||
Logger.Warn("There exists an already registered command group named '{0}'.", groupAttribute.Name);
|
Logger.Warn("There exists an already registered command group named '{0}'.", groupAttribute.Name);
|
||||||
|
|
||||||
var commandGroup = (CommandGroup)Activator.CreateInstance(type);
|
var commandGroup = (CommandGroup)Activator.CreateInstance(type);
|
||||||
commandGroup.Register(groupAttribute);
|
if (commandGroup != null)
|
||||||
CommandGroups.Add(groupAttribute, commandGroup);
|
{
|
||||||
|
commandGroup.Register(groupAttribute);
|
||||||
|
CommandGroups.Add(groupAttribute, commandGroup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Warn("Failed to create an instance of command group '{0}'.", groupAttribute.Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,7 @@ using DiIiS_NA.LoginServer.Battle;
|
|||||||
|
|
||||||
namespace DiIiS_NA.GameServer.CommandManager;
|
namespace DiIiS_NA.GameServer.CommandManager;
|
||||||
|
|
||||||
[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]",
|
[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]", Account.UserLevels.Owner)]
|
||||||
Account.UserLevels.Owner)]
|
|
||||||
public class DropCommand : CommandGroup
|
public class DropCommand : CommandGroup
|
||||||
{
|
{
|
||||||
[DefaultCommand]
|
[DefaultCommand]
|
||||||
@ -29,16 +28,16 @@ public class DropCommand : CommandGroup
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (var i = 0; i < amount; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
player.World.SpawnRandomEquip(player, player, 11, player.Level, toonClass: player.Toon.Class,
|
player.World.SpawnRandomEquip(player, player, 11, /*player.Level,*/ toonClass: player.Toon.Class,
|
||||||
canBeUnidentified: false);
|
canBeUnidentified: false);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
for (var i = 0; i < amount; i++)
|
for (var i = 0; i < amount; i++)
|
||||||
player.World.SpawnRandomEquip(player, player, 8, player.Level, toonClass: player.Toon.Class,
|
player.World.SpawnRandomEquip(player, player, 8, /*player.Level,*/ toonClass: player.Toon.Class,
|
||||||
canBeUnidentified: false);
|
canBeUnidentified: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"Dropped {amount} random equipment.";
|
return $"Dropped {amount} random epic equipment.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,8 +13,20 @@ namespace DiIiS_NA.GameServer.CommandManager
|
|||||||
get => GetString(nameof(CommandPrefix), "!")[0];
|
get => GetString(nameof(CommandPrefix), "!")[0];
|
||||||
set => Set(nameof(CommandPrefix), value);
|
set => Set(nameof(CommandPrefix), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DisabledGroups
|
||||||
|
{
|
||||||
|
get => GetString(nameof(DisabledGroups), "");
|
||||||
|
set => Set(nameof(DisabledGroups), value);
|
||||||
|
}
|
||||||
|
|
||||||
public static CommandsConfig Instance = new();
|
public string[] DisabledGroupsData
|
||||||
|
=> DisabledGroups
|
||||||
|
.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(s=>s.Replace(CommandPrefix.ToString(), ""))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
public static readonly CommandsConfig Instance = new();
|
||||||
private CommandsConfig() : base("Commands") { }
|
private CommandsConfig() : base("Commands") { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,41 +113,24 @@ namespace DiIiS_NA.GameServer.Core.Types.Math
|
|||||||
return ((x * x) + (y * y)) + (z * z);
|
return ((x * x) + (y * y)) + (z * z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(Vector3D a, Vector3D b)
|
public static bool operator ==(Vector3D a, Vector3D b) => a?.Equals(b) ?? ReferenceEquals(null, b);
|
||||||
{
|
|
||||||
if (ReferenceEquals(null, a))
|
|
||||||
return ReferenceEquals(null, b);
|
|
||||||
return a.Equals(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(Vector3D a, Vector3D b)
|
public static bool operator !=(Vector3D a, Vector3D b) => !(a == b);
|
||||||
{
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >(Vector3D a, Vector3D b)
|
public static bool operator >(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(null, a))
|
return ReferenceEquals(null, a)
|
||||||
return !ReferenceEquals(null, b);
|
? !ReferenceEquals(null, b)
|
||||||
return a.X > b.X
|
: a.X > b.X
|
||||||
&& a.Y > b.Y
|
&& a.Y > b.Y
|
||||||
&& a.Z > b.Z;
|
&& a.Z > b.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3D operator +(Vector3D a, Vector3D b)
|
public static Vector3D operator +(Vector3D a, Vector3D b) => new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||||
{
|
|
||||||
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3D operator -(Vector3D a, Vector3D b)
|
public static Vector3D operator -(Vector3D a, Vector3D b) => new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||||
{
|
|
||||||
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator <(Vector3D a, Vector3D b)
|
public static bool operator <(Vector3D a, Vector3D b) => !(a > b);
|
||||||
{
|
|
||||||
return !(a > b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator >=(Vector3D a, Vector3D b)
|
public static bool operator >=(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
@ -174,9 +157,9 @@ namespace DiIiS_NA.GameServer.Core.Types.Math
|
|||||||
var v = o as Vector3D;
|
var v = o as Vector3D;
|
||||||
if (v != null)
|
if (v != null)
|
||||||
{
|
{
|
||||||
return System.Math.Abs(X - v.X) < 0.0001
|
return System.Math.Abs(X - v.X) < Globals.FLOAT_TOLERANCE
|
||||||
&& System.Math.Abs(Y - v.Y) < 0.0001
|
&& System.Math.Abs(Y - v.Y) < Globals.FLOAT_TOLERANCE
|
||||||
&& System.Math.Abs(Z - v.Z) < 0.0001;
|
&& System.Math.Abs(Z - v.Z) < Globals.FLOAT_TOLERANCE;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20690,7 +20690,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
|||||||
ActorSno._p73_fallenlunatic_a_nonspawner,
|
ActorSno._p73_fallenlunatic_a_nonspawner,
|
||||||
};
|
};
|
||||||
// all '_vo' and 'voiceo' actors except 'voodoomask` and and cosmetic pets
|
// all '_vo' and 'voiceo' actors except 'voodoomask` and and cosmetic pets
|
||||||
private static readonly ActorSno[] soundActors = new ActorSno[]
|
private static readonly ActorSno[] _soundActors = new ActorSno[]
|
||||||
{
|
{
|
||||||
ActorSno._lustmissle_volume,
|
ActorSno._lustmissle_volume,
|
||||||
ActorSno._a1dun_caves_nephalem_altar_volume,
|
ActorSno._a1dun_caves_nephalem_altar_volume,
|
||||||
@ -20713,7 +20713,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
|||||||
ActorSno._p43_ad_valor_bloodstone_volume,
|
ActorSno._p43_ad_valor_bloodstone_volume,
|
||||||
};
|
};
|
||||||
// all 'door' actors
|
// all 'door' actors
|
||||||
private static readonly ActorSno[] doors = new ActorSno[]
|
private static readonly ActorSno[] _doors = new ActorSno[]
|
||||||
{
|
{
|
||||||
ActorSno._trdun_cath_wooddoor_a,
|
ActorSno._trdun_cath_wooddoor_a,
|
||||||
ActorSno._door_intactc_caout_towns,
|
ActorSno._door_intactc_caout_towns,
|
||||||
@ -21156,7 +21156,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
|||||||
ActorSno._kanai_cube_uber_fx,
|
ActorSno._kanai_cube_uber_fx,
|
||||||
};
|
};
|
||||||
// all 'adventuremode' actors
|
// all 'adventuremode' actors
|
||||||
private static readonly ActorSno[] adventureModeActors = new ActorSno[]
|
private static readonly ActorSno[] AdventureModeActors = new ActorSno[]
|
||||||
{
|
{
|
||||||
ActorSno._x1_lore_adventuremode_zknephalem,
|
ActorSno._x1_lore_adventuremode_zknephalem,
|
||||||
ActorSno._x1_lore_adventuremode_zkplans,
|
ActorSno._x1_lore_adventuremode_zkplans,
|
||||||
@ -21168,7 +21168,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
|||||||
ActorSno._x1_adventuremode_hubbantertrigger,
|
ActorSno._x1_adventuremode_hubbantertrigger,
|
||||||
};
|
};
|
||||||
#endregion
|
#endregion
|
||||||
public static readonly ActorSno[] nephalemPortalBosses = new ActorSno[]
|
public static readonly ActorSno[] NephalemPortalBosses = new ActorSno[]
|
||||||
{
|
{
|
||||||
ActorSno._x1_lr_boss_mistressofpain,
|
ActorSno._x1_lr_boss_mistressofpain,
|
||||||
ActorSno._x1_lr_boss_angel_corrupt_a,
|
ActorSno._x1_lr_boss_angel_corrupt_a,
|
||||||
@ -21227,17 +21227,17 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
|||||||
|
|
||||||
public static bool IsAdventureModeActor(this ActorSno actorSno)
|
public static bool IsAdventureModeActor(this ActorSno actorSno)
|
||||||
{
|
{
|
||||||
return adventureModeActors.Contains(actorSno);
|
return AdventureModeActors.Contains(actorSno);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsTargetable(this ActorSno actorSno)
|
public static bool IsTargetable(this ActorSno actorSno)
|
||||||
{
|
{
|
||||||
return !spawners.Contains(actorSno) && !soundActors.Contains(actorSno);
|
return !spawners.Contains(actorSno) && !_soundActors.Contains(actorSno);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsDoorOrBarricade(this ActorSno actorSno)
|
public static bool IsDoorOrBarricade(this ActorSno actorSno)
|
||||||
{
|
{
|
||||||
return doors.Contains(actorSno) || barricades.Contains(actorSno);
|
return _doors.Contains(actorSno) || barricades.Contains(actorSno);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsWoodwraithOrWasp(this ActorSno actorSno)
|
public static bool IsWoodwraithOrWasp(this ActorSno actorSno)
|
||||||
|
|||||||
@ -50,11 +50,5 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.ActorSystem.Implementations.Artisans
|
|||||||
base.OnCraft(player);
|
base.OnCraft(player);
|
||||||
player.CurrentArtisan = ArtisanType.Nephalem;
|
player.CurrentArtisan = ArtisanType.Nephalem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Reveal(Player player)
|
|
||||||
{
|
|
||||||
|
|
||||||
return base.Reveal(player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,7 +88,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem
|
|||||||
public void UpdateStats()
|
public void UpdateStats()
|
||||||
{
|
{
|
||||||
var monsterLevels = (GameBalance)DiIiS_NA.Core.MPQ.MPQStorage.Data.Assets[SNOGroup.GameBalance][19760].Data;
|
var monsterLevels = (GameBalance)DiIiS_NA.Core.MPQ.MPQStorage.Data.Assets[SNOGroup.GameBalance][19760].Data;
|
||||||
bool fullHp = (Math.Abs(Attributes[GameAttribute.Hitpoints_Cur] - Attributes[GameAttribute.Hitpoints_Max_Total]) < 0.001);
|
bool fullHp = (Math.Abs(Attributes[GameAttribute.Hitpoints_Cur] - Attributes[GameAttribute.Hitpoints_Max_Total]) < Globals.FLOAT_TOLERANCE);
|
||||||
Attributes[GameAttribute.Level] = World.Game.MonsterLevel;
|
Attributes[GameAttribute.Level] = World.Game.MonsterLevel;
|
||||||
//this.Attributes[GameAttribute.Hitpoints_Max] = (int)monsterLevels.MonsterLevel[this.World.Game.MonsterLevel - 1].HPMin * (int)this.HPMultiplier * (int)this.World.Game.HPModifier;
|
//this.Attributes[GameAttribute.Hitpoints_Max] = (int)monsterLevels.MonsterLevel[this.World.Game.MonsterLevel - 1].HPMin * (int)this.HPMultiplier * (int)this.World.Game.HPModifier;
|
||||||
int monsterLevel = 1;
|
int monsterLevel = 1;
|
||||||
|
|||||||
@ -1256,7 +1256,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem
|
|||||||
GameAccountId = new GameAccountHandle() { ID = (uint)joinedPlayer.Toon.GameAccount.BnetEntityId.Low, Program = 0x00004433, Region = 1 },
|
GameAccountId = new GameAccountHandle() { ID = (uint)joinedPlayer.Toon.GameAccount.BnetEntityId.Low, Program = 0x00004433, Region = 1 },
|
||||||
ToonName = joinedPlayer.Toon.Name,
|
ToonName = joinedPlayer.Toon.Name,
|
||||||
Team = 0x00000002,
|
Team = 0x00000002,
|
||||||
Class = joinedPlayer.ClassSNO,
|
Class = joinedPlayer.ClassSno,
|
||||||
snoActorPortrait = joinedPlayer.Toon.DBToon.Cosmetic4,
|
snoActorPortrait = joinedPlayer.Toon.DBToon.Cosmetic4,
|
||||||
Level = joinedPlayer.Toon.Level,
|
Level = joinedPlayer.Toon.Level,
|
||||||
AltLevel = (ushort)joinedPlayer.Toon.ParagonLevel,
|
AltLevel = (ushort)joinedPlayer.Toon.ParagonLevel,
|
||||||
|
|||||||
@ -386,8 +386,8 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
RandomSpawnInWorldWithLevelArea(world, ActorSno._x1_deathmaiden_unique_fire_a);
|
RandomSpawnInWorldWithLevelArea(world, ActorSno._x1_deathmaiden_unique_fire_a);
|
||||||
break;
|
break;
|
||||||
case WorldSno.trdun_leoric_level03: //Setting portal to the third floor of the Agony's Halls near the entrance to the Butcher.
|
case WorldSno.trdun_leoric_level03: //Setting portal to the third floor of the Agony's Halls near the entrance to the Butcher.
|
||||||
Vector3D Scene0Pos = world.GetSceneBySnoId(78824).Position;
|
Vector3D sceneOfPos = world.GetSceneBySnoId(78824).Position;
|
||||||
world.SpawnMonster(ActorSno._waypoint, new Vector3D(Scene0Pos.X + 149.0907f, Scene0Pos.Y + 106.7075f, Scene0Pos.Z));
|
world.SpawnMonster(ActorSno._waypoint, new Vector3D(sceneOfPos.X + 149.0907f, sceneOfPos.Y + 106.7075f, sceneOfPos.Z));
|
||||||
break;
|
break;
|
||||||
case WorldSno.x1_westm_graveyard_deathorb:
|
case WorldSno.x1_westm_graveyard_deathorb:
|
||||||
FilterWaypoints(world);
|
FilterWaypoints(world);
|
||||||
@ -402,9 +402,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
break;
|
break;
|
||||||
case WorldSno.trout_town: //mercenary
|
case WorldSno.trout_town: //mercenary
|
||||||
var templar = world.GetActorBySNO(ActorSno._templar);
|
var templar = world.GetActorBySNO(ActorSno._templar);
|
||||||
var hasmalth = world.GetActorBySNO(ActorSno._x1_malthael_npc);
|
var hasMalthaelNpc = world.GetActorBySNO(ActorSno._x1_malthael_npc);
|
||||||
|
|
||||||
if (hasmalth == null)
|
if (hasMalthaelNpc == null)
|
||||||
{
|
{
|
||||||
ActorSystem.Implementations.Hirelings.MalthaelHireling malthaelHire = new ActorSystem.Implementations.Hirelings.MalthaelHireling(world, ActorSno._x1_malthael_npc_nocollision, templar.Tags)
|
ActorSystem.Implementations.Hirelings.MalthaelHireling malthaelHire = new ActorSystem.Implementations.Hirelings.MalthaelHireling(world, ActorSno._x1_malthael_npc_nocollision, templar.Tags)
|
||||||
{
|
{
|
||||||
@ -419,17 +419,17 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
}
|
}
|
||||||
foreach (var door in world.GetActorsBySNO(ActorSno._house_door_trout_newtristram))
|
foreach (var door in world.GetActorsBySNO(ActorSno._house_door_trout_newtristram))
|
||||||
door.Destroy();
|
door.Destroy();
|
||||||
if (Game.CurrentAct == 3000)
|
if (Game.CurrentActEnum == ActEnum.OpenWorld)
|
||||||
{
|
{
|
||||||
var TownDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town);
|
var townDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town);
|
||||||
TownDoor.Attributes[GameAttribute.Team_Override] = 2;
|
townDoor.Attributes[GameAttribute.Team_Override] = 2;
|
||||||
TownDoor.Attributes[GameAttribute.Untargetable] = true;
|
townDoor.Attributes[GameAttribute.Untargetable] = true;
|
||||||
TownDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false;
|
townDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false;
|
||||||
TownDoor.Attributes[GameAttribute.Operatable] = false;
|
townDoor.Attributes[GameAttribute.Operatable] = false;
|
||||||
TownDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false;
|
townDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false;
|
||||||
TownDoor.Attributes[GameAttribute.Disabled] = true;
|
townDoor.Attributes[GameAttribute.Disabled] = true;
|
||||||
TownDoor.Attributes[GameAttribute.Immunity] = true;
|
townDoor.Attributes[GameAttribute.Immunity] = true;
|
||||||
TownDoor.Attributes.BroadcastChangedIfRevealed();
|
townDoor.Attributes.BroadcastChangedIfRevealed();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WorldSno.a1trdun_level04: //Cathedral Level 2
|
case WorldSno.a1trdun_level04: //Cathedral Level 2
|
||||||
@ -504,10 +504,12 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
zoltunGhost.Attributes.BroadcastChangedIfRevealed();
|
zoltunGhost.Attributes.BroadcastChangedIfRevealed();
|
||||||
break;
|
break;
|
||||||
case WorldSno.a3dun_ruins_frost_city_a_02:
|
case WorldSno.a3dun_ruins_frost_city_a_02:
|
||||||
foreach (var waypoint in world.GetActorsBySNO(ActorSno._waypoint)) waypoint.Destroy();
|
foreach (var waypoint in world.GetActorsBySNO(ActorSno._waypoint))
|
||||||
|
waypoint.Destroy();
|
||||||
break;
|
break;
|
||||||
case WorldSno.p43_ad_oldtristram:
|
case WorldSno.p43_ad_oldtristram:
|
||||||
foreach (var waypoint in world.GetActorsBySNO(ActorSno._trout_oldtristram_exit_gate)) waypoint.Destroy();
|
foreach (var waypoint in world.GetActorsBySNO(ActorSno._trout_oldtristram_exit_gate))
|
||||||
|
waypoint.Destroy();
|
||||||
break;
|
break;
|
||||||
case WorldSno.x1_tristram_adventure_mode_hub:
|
case WorldSno.x1_tristram_adventure_mode_hub:
|
||||||
|
|
||||||
@ -561,14 +563,15 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
public void RandomSpawnInWorldWithLevelArea(World world, ActorSno monsterSno, int levelArea = -1)
|
public void RandomSpawnInWorldWithLevelArea(World world, ActorSno monsterSno, int levelArea = -1)
|
||||||
{
|
{
|
||||||
List<Scene> scenes = world.Scenes.Values.ToList();
|
List<Scene> scenes = world.Scenes.Values.ToList();
|
||||||
if (levelArea != -1) scenes = scenes.Where(sc => sc.Specification.SNOLevelAreas[0] == levelArea && !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList();
|
scenes = levelArea != -1
|
||||||
else scenes = scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList();
|
? scenes.Where(sc => sc.Specification.SNOLevelAreas[0] == levelArea && !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList()
|
||||||
Vector3D SSV = scenes.PickRandom().Position;
|
: scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList();
|
||||||
|
Vector3D randomScene = scenes.PickRandom().Position;
|
||||||
Vector3D startingPoint = null;
|
Vector3D startingPoint = null;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
startingPoint = new Vector3D(SSV.X + RandomHelper.Next(0, 240), SSV.Y + RandomHelper.Next(0, 240), SSV.Z);
|
startingPoint = new Vector3D(randomScene.X + RandomHelper.Next(0, 240), randomScene.Y + RandomHelper.Next(0, 240), randomScene.Z);
|
||||||
if (world.CheckLocationForFlag(startingPoint, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk))
|
if (world.CheckLocationForFlag(startingPoint, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1591,7 +1594,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
|||||||
{
|
{
|
||||||
bool busy = false;
|
bool busy = false;
|
||||||
foreach (var chunk in world.worldData.SceneParams.SceneChunks)
|
foreach (var chunk in world.worldData.SceneParams.SceneChunks)
|
||||||
if (Math.Abs(chunk.PRTransform.Vector3D.X - x) < 0.001 & Math.Abs(chunk.PRTransform.Vector3D.Y - y) < 0.001)
|
if (Math.Abs(chunk.PRTransform.Vector3D.X - x) < Globals.FLOAT_TOLERANCE & Math.Abs(chunk.PRTransform.Vector3D.Y - y) < Globals.FLOAT_TOLERANCE)
|
||||||
{
|
{
|
||||||
busy = true;
|
busy = true;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -552,8 +552,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ItemsSystem
|
|||||||
if (ratio > 1f) ratio = 1f;
|
if (ratio > 1f) ratio = 1f;
|
||||||
Attributes[GameAttribute.Block_Amount_Item_Min] +=
|
Attributes[GameAttribute.Block_Amount_Item_Min] +=
|
||||||
Math.Abs(scaleCapMin * ratio - Attributes[GameAttribute.Block_Amount_Item_Min, 0]);
|
Math.Abs(scaleCapMin * ratio - Attributes[GameAttribute.Block_Amount_Item_Min, 0]);
|
||||||
Attributes[GameAttribute.Block_Amount_Item_Delta] += Math.Abs(scaleCapDelta * ratio -
|
Attributes[GameAttribute.Block_Amount_Item_Delta] += Math.Abs(scaleCapDelta * ratio - Attributes[GameAttribute.Block_Amount_Item_Delta, 0]);
|
||||||
Attributes[GameAttribute.Block_Amount_Item_Delta, 0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -590,41 +590,36 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
|||||||
|
|
||||||
public Actor SpawnMonster(ActorSno monsterSno, Vector3D position)
|
public Actor SpawnMonster(ActorSno monsterSno, Vector3D position)
|
||||||
{
|
{
|
||||||
if (monsterSno == ActorSno.__NONE)
|
if (monsterSno == ActorSno.__NONE) return null;
|
||||||
{
|
Logger.MethodTrace($"Spawning monster {monsterSno} at {position}");
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var monster = ActorFactory.Create(this, monsterSno, new TagMap());
|
var monster = ActorFactory.Create(this, monsterSno, new TagMap());
|
||||||
if (monster != null)
|
if (monster == null) return null;
|
||||||
|
|
||||||
|
monster.EnterWorld(position);
|
||||||
|
if (monster.AnimationSet == null) return monster;
|
||||||
|
var animationTag = new[] { AnimationSetKeys.Spawn, AnimationSetKeys.Spawn2 }.FirstOrDefault(x => monster.AnimationSet.TagMapAnimDefault.ContainsKey(x));
|
||||||
|
|
||||||
|
if (animationTag != null)
|
||||||
{
|
{
|
||||||
monster.EnterWorld(position);
|
monster.World.BroadcastIfRevealed(plr => new PlayAnimationMessage
|
||||||
if (monster.AnimationSet != null)
|
{
|
||||||
{
|
ActorID = monster.DynamicID(plr),
|
||||||
var animationTag = new[] { AnimationSetKeys.Spawn, AnimationSetKeys.Spawn2 }.FirstOrDefault(x => monster.AnimationSet.TagMapAnimDefault.ContainsKey(x));
|
AnimReason = 5,
|
||||||
|
UnitAniimStartTime = 0,
|
||||||
|
tAnim = new PlayAnimationMessageSpec[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Duration = 150,
|
||||||
|
AnimationSNO = monster.AnimationSet.TagMapAnimDefault[animationTag],
|
||||||
|
PermutationIndex = 0,
|
||||||
|
Speed = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (animationTag != null)
|
}, monster);
|
||||||
{
|
|
||||||
monster.World.BroadcastIfRevealed(plr => new PlayAnimationMessage
|
|
||||||
{
|
|
||||||
ActorID = monster.DynamicID(plr),
|
|
||||||
AnimReason = 5,
|
|
||||||
UnitAniimStartTime = 0,
|
|
||||||
tAnim = new PlayAnimationMessageSpec[]
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Duration = 150,
|
|
||||||
AnimationSNO = monster.AnimationSet.TagMapAnimDefault[animationTag],
|
|
||||||
PermutationIndex = 0,
|
|
||||||
Speed = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, monster);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return monster;
|
return monster;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Queue<Queue<Action>> _flippyTimers = new();
|
private Queue<Queue<Action>> _flippyTimers = new();
|
||||||
@ -640,19 +635,21 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
|||||||
player.GroundItems[item.GlobalID] = item; // FIXME: Hacky. /komiga
|
player.GroundItems[item.GlobalID] = item; // FIXME: Hacky. /komiga
|
||||||
DropItem(source, null, item);
|
DropItem(source, null, item);
|
||||||
}
|
}
|
||||||
public void PlayPieAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
|
||||||
|
[Obsolete("Isn't used anymore. Is it useful?")]
|
||||||
|
public void PlayPieAnimation(Actor actor, Actor user, int powerSNO, Vector3D targetPosition)
|
||||||
{
|
{
|
||||||
|
|
||||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathPieWedgeMessage
|
BroadcastIfRevealed(plr => new ACDTranslateDetPathPieWedgeMessage
|
||||||
{
|
{
|
||||||
ann = (int)actor.DynamicID(plr),
|
ann = (int)actor.DynamicID(plr),
|
||||||
StartPos = User.Position,
|
StartPos = user.Position,
|
||||||
FirstTagetPos = User.Position,
|
FirstTagetPos = user.Position,
|
||||||
MoveFlags = 9,
|
MoveFlags = 9,
|
||||||
AnimTag = 1,
|
AnimTag = 1,
|
||||||
PieData = new DPathPieData
|
PieData = new DPathPieData
|
||||||
{
|
{
|
||||||
Field0 = TargetPosition,
|
Field0 = targetPosition,
|
||||||
Field1 = 1,
|
Field1 = 1,
|
||||||
Field2 = 1,
|
Field2 = 1,
|
||||||
Field3 = 1
|
Field3 = 1
|
||||||
|
|||||||
@ -2395,7 +2395,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
var rem = new List<uint>();
|
var rem = new List<uint>();
|
||||||
foreach (var fol in Followers.Where(f =>
|
foreach (var fol in Followers.Where(f =>
|
||||||
Math.Abs(World.GetActorByGlobalId(f.Key).Attributes[GameAttribute.Summoned_By_SNO] -
|
Math.Abs(World.GetActorByGlobalId(f.Key).Attributes[GameAttribute.Summoned_By_SNO] -
|
||||||
oldSNOSkill) < 0.001))
|
oldSNOSkill) < Globals.FLOAT_TOLERANCE))
|
||||||
rem.Add(fol.Key);
|
rem.Add(fol.Key);
|
||||||
foreach (var rm in rem)
|
foreach (var rm in rem)
|
||||||
DestroyFollowerById(rm);
|
DestroyFollowerById(rm);
|
||||||
@ -2914,13 +2914,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
//*
|
//*
|
||||||
private void TrainArtisan(GameClient client, RequestTrainArtisanMessage message)
|
private void TrainArtisan(GameClient client, RequestTrainArtisanMessage message)
|
||||||
{
|
{
|
||||||
if (CurrentArtisan == null || !artisanTrainHelpers.ContainsKey(CurrentArtisan.Value))
|
if (CurrentArtisan == null || !_artisanTrainHelpers.ContainsKey(CurrentArtisan.Value))
|
||||||
{
|
{
|
||||||
Logger.Warn("Training for artisan {} is not supported", CurrentArtisan);
|
Logger.Warn("Training for artisan {} is not supported", CurrentArtisan);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var trainHelper = artisanTrainHelpers[CurrentArtisan.Value];
|
var trainHelper = _artisanTrainHelpers[CurrentArtisan.Value];
|
||||||
if (trainHelper.HasMaxLevel)
|
if (trainHelper.HasMaxLevel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2947,7 +2947,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
if (trainHelper.Criteria is not null)
|
if (trainHelper.Criteria is not null)
|
||||||
GrantCriteria(trainHelper.Criteria.Value);
|
GrantCriteria(trainHelper.Criteria.Value);
|
||||||
|
|
||||||
if (artisanTrainHelpers.All(x => x.Value.HasMaxLevel))
|
if (_artisanTrainHelpers.All(x => x.Value.HasMaxLevel))
|
||||||
GrantCriteria(74987249993545);
|
GrantCriteria(74987249993545);
|
||||||
|
|
||||||
client.SendMessage(new CrafterLevelUpMessage
|
client.SendMessage(new CrafterLevelUpMessage
|
||||||
@ -2966,13 +2966,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public void UnlockTransmog(int transmogGBID)
|
public void UnlockTransmog(int transmogGBID)
|
||||||
{
|
{
|
||||||
if (learnedTransmogs.Contains(transmogGBID)) return;
|
if (_learnedTransmogs.Contains(transmogGBID)) return;
|
||||||
InGameClient.SendMessage(new UnlockTransmogMessage() { TransmogGBID = transmogGBID });
|
InGameClient.SendMessage(new UnlockTransmogMessage() { TransmogGBID = transmogGBID });
|
||||||
|
|
||||||
Logger.Trace("Learning transmog #{0}", transmogGBID);
|
Logger.Trace("Learning transmog #{0}", transmogGBID);
|
||||||
learnedTransmogs.Add(transmogGBID);
|
_learnedTransmogs.Add(transmogGBID);
|
||||||
mystic_data.LearnedRecipes = SerializeBytes(learnedTransmogs);
|
_mysticData.LearnedRecipes = SerializeBytes(_learnedTransmogs);
|
||||||
World.Game.GameDbSession.SessionUpdate(mystic_data);
|
World.Game.GameDbSession.SessionUpdate(_mysticData);
|
||||||
|
|
||||||
LoadCrafterData();
|
LoadCrafterData();
|
||||||
}
|
}
|
||||||
@ -3067,7 +3067,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
foreach (var timed_out in TimedActions.Where(t => t.TimedOut).ToList())
|
foreach (var timed_out in TimedActions.Where(t => t.TimedOut).ToList())
|
||||||
TimedActions.Remove(timed_out);
|
TimedActions.Remove(timed_out);
|
||||||
|
|
||||||
// Check the Killstreaks
|
// Check the kill streaks
|
||||||
ExpBonusData.Check(0);
|
ExpBonusData.Check(0);
|
||||||
ExpBonusData.Check(1);
|
ExpBonusData.Check(1);
|
||||||
|
|
||||||
@ -3165,27 +3165,29 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
#region Necromancer summons
|
#region Necromancer summons
|
||||||
|
|
||||||
var switchertobool = false;
|
var switcherToBool = false;
|
||||||
var switchertoboolTwo = false;
|
var switcherToBool2 = false;
|
||||||
ActiveSkillSavedData NowSkillGolem = null;
|
ActiveSkillSavedData nowSkillGolen = null;
|
||||||
foreach (var skill in SkillSet.ActiveSkills)
|
foreach (var skill in SkillSet.ActiveSkills)
|
||||||
if (skill.snoSkill == 453801)
|
if (skill.snoSkill == 453801)
|
||||||
switchertobool = true;
|
switcherToBool = true;
|
||||||
foreach (var skill in SkillSet.ActiveSkills)
|
foreach (var skill in SkillSet.ActiveSkills)
|
||||||
if (skill.snoSkill == 451537)
|
if (skill.snoSkill == 451537)
|
||||||
{
|
{
|
||||||
switchertoboolTwo = true;
|
switcherToBool2 = true;
|
||||||
NowSkillGolem = skill;
|
nowSkillGolen = skill;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveSkeletons = switchertobool;
|
ActiveSkeletons = switcherToBool;
|
||||||
EnableGolem = switchertoboolTwo;
|
EnableGolem = switcherToBool2;
|
||||||
|
|
||||||
|
|
||||||
var Killer = new PowerContext();
|
var killer = new PowerContext
|
||||||
Killer.User = this;
|
{
|
||||||
Killer.World = World;
|
User = this,
|
||||||
Killer.PowerSNO = -1;
|
World = World,
|
||||||
|
PowerSNO = -1
|
||||||
|
};
|
||||||
|
|
||||||
if (ActiveSkeletons)
|
if (ActiveSkeletons)
|
||||||
{
|
{
|
||||||
@ -3255,8 +3257,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
{
|
{
|
||||||
PetId = ActiveGolem.GlobalID
|
PetId = ActiveGolem.GlobalID
|
||||||
});
|
});
|
||||||
Killer.Target = ActiveGolem;
|
killer.Target = ActiveGolem;
|
||||||
(ActiveGolem as Minion).Kill(Killer);
|
(ActiveGolem as Minion).Kill(killer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActiveGolem = null;
|
ActiveGolem = null;
|
||||||
@ -3386,20 +3388,14 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public T RuneSelect<T>(int PowerSNO, T none, T runeA, T runeB, T runeC, T runeD, T runeE)
|
public T RuneSelect<T>(int powerSno, T none, T runeA, T runeB, T runeC, T runeD, T runeE)
|
||||||
{
|
{
|
||||||
var Rune_A = Attributes[GameAttribute.Rune_A, PowerSNO];
|
if (Attributes[GameAttribute.Rune_A, powerSno] > 0) return runeA;
|
||||||
var Rune_B = Attributes[GameAttribute.Rune_B, PowerSNO];
|
if (Attributes[GameAttribute.Rune_B, powerSno] > 0) return runeB;
|
||||||
var Rune_C = Attributes[GameAttribute.Rune_C, PowerSNO];
|
if (Attributes[GameAttribute.Rune_C, powerSno] > 0) return runeC;
|
||||||
var Rune_D = Attributes[GameAttribute.Rune_D, PowerSNO];
|
if (Attributes[GameAttribute.Rune_D, powerSno] > 0) return runeD;
|
||||||
var Rune_E = Attributes[GameAttribute.Rune_E, PowerSNO];
|
if (Attributes[GameAttribute.Rune_E, powerSno] > 0) return runeE;
|
||||||
|
return none;
|
||||||
if (Rune_A > 0) return runeA;
|
|
||||||
else if (Rune_B > 0) return runeB;
|
|
||||||
else if (Rune_C > 0) return runeC;
|
|
||||||
else if (Rune_D > 0) return runeD;
|
|
||||||
else if (Rune_E > 0) return runeE;
|
|
||||||
else return none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region enter, leave, reveal handling
|
#region enter, leave, reveal handling
|
||||||
@ -3410,11 +3406,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
public void RevealScenesToPlayer()
|
public void RevealScenesToPlayer()
|
||||||
{
|
{
|
||||||
//List<Scene> scenes_around = this.GetScenesInRegion(DefaultQueryProximityLenght * 2);
|
//List<Scene> scenes_around = this.GetScenesInRegion(DefaultQueryProximityLenght * 2);
|
||||||
var scenes_around = World.Scenes.Values.ToList();
|
var scenesAround = World.Scenes.Values.ToList();
|
||||||
if (!World.worldData.DynamicWorld)
|
if (!World.worldData.DynamicWorld)
|
||||||
scenes_around = GetScenesInRegion(DefaultQueryProximityLenght * 3);
|
scenesAround = GetScenesInRegion(DefaultQueryProximityLenght * 3);
|
||||||
|
|
||||||
foreach (var scene in scenes_around) // reveal scenes in player's proximity.
|
foreach (var scene in scenesAround) // reveal scenes in player's proximity.
|
||||||
{
|
{
|
||||||
if (scene.IsRevealedToPlayer(this)) // if the actors is already revealed skip it.
|
if (scene.IsRevealedToPlayer(this)) // if the actors is already revealed skip it.
|
||||||
continue; // if the scene is already revealed, skip it.
|
continue; // if the scene is already revealed, skip it.
|
||||||
@ -3428,7 +3424,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
foreach (var scene in World.Scenes.Values) // unreveal far scenes
|
foreach (var scene in World.Scenes.Values) // unreveal far scenes
|
||||||
{
|
{
|
||||||
if (!scene.IsRevealedToPlayer(this) || scenes_around.Contains(scene))
|
if (!scene.IsRevealedToPlayer(this) || scenesAround.Contains(scene))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (scene.Parent !=
|
if (scene.Parent !=
|
||||||
@ -3444,9 +3440,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void RevealActorsToPlayer()
|
public void RevealActorsToPlayer()
|
||||||
{
|
{
|
||||||
var Range = 200f;
|
var range = 200f;
|
||||||
if (InGameClient.Game.CurrentEncounter.Activated)
|
if (InGameClient.Game.CurrentEncounter.Activated)
|
||||||
Range = 360f;
|
range = 360f;
|
||||||
|
|
||||||
var specialWorlds = new WorldSno[]
|
var specialWorlds = new WorldSno[]
|
||||||
{
|
{
|
||||||
@ -3457,9 +3453,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
WorldSno.a1trdun_level05_templar
|
WorldSno.a1trdun_level05_templar
|
||||||
};
|
};
|
||||||
|
|
||||||
var actors_around = specialWorlds.Contains(World.SNO) ? World.Actors.Values.ToList() : GetActorsInRange(Range);
|
var actorsAround = specialWorlds.Contains(World.SNO) ? World.Actors.Values.ToList() : GetActorsInRange(range);
|
||||||
|
|
||||||
foreach (var actor in actors_around) // reveal actors in player's proximity.
|
foreach (var actor in actorsAround) // reveal actors in player's proximity.
|
||||||
{
|
{
|
||||||
if (actor is Player) // if the actors is already revealed, skip it.
|
if (actor is Player) // if the actors is already revealed, skip it.
|
||||||
continue;
|
continue;
|
||||||
@ -3482,7 +3478,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
foreach (var actor in World.Actors.Values) // unreveal far actors
|
foreach (var actor in World.Actors.Values) // unreveal far actors
|
||||||
{
|
{
|
||||||
if ((actor is Player && (!World.IsPvP || actor == this)) ||
|
if ((actor is Player && (!World.IsPvP || actor == this)) ||
|
||||||
actors_around.Contains(actor)) // if the actors is already revealed, skip it.
|
actorsAround.Contains(actor)) // if the actors is already revealed, skip it.
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
actor.Unreveal(this);
|
actor.Unreveal(this);
|
||||||
@ -3549,7 +3545,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
world.Reveal(this);
|
world.Reveal(this);
|
||||||
Unreveal(this);
|
Unreveal(this);
|
||||||
|
|
||||||
if (_CurrentHPValue == -1f)
|
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||||
DefaultQueryProximityRadius = 60;
|
DefaultQueryProximityRadius = 60;
|
||||||
|
|
||||||
InGameClient.SendMessage(new EnterWorldMessage()
|
InGameClient.SendMessage(new EnterWorldMessage()
|
||||||
@ -3580,7 +3576,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_CurrentHPValue == -1f)
|
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||||
AddPercentageHP(100);
|
AddPercentageHP(100);
|
||||||
|
|
||||||
DefaultQueryProximityRadius = 100;
|
DefaultQueryProximityRadius = 100;
|
||||||
@ -3750,7 +3746,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
AllBuffs.Clear();
|
AllBuffs.Clear();
|
||||||
BetweenWorlds = false;
|
BetweenWorlds = false;
|
||||||
|
|
||||||
if (Math.Abs(_CurrentHPValue - (-1)) > 0.0001)
|
if (Math.Abs(_CurrentHPValue - (-1)) > Globals.FLOAT_TOLERANCE)
|
||||||
{
|
{
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] = _CurrentHPValue;
|
Attributes[GameAttribute.Hitpoints_Cur] = _CurrentHPValue;
|
||||||
Attributes[GameAttribute.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue;
|
Attributes[GameAttribute.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue;
|
||||||
@ -3850,7 +3846,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows hero state message to be sent when hero's some property get's updated.
|
/// Allows hero state message to be sent when hero's some property gets updated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void UpdateHeroState()
|
public void UpdateHeroState()
|
||||||
{
|
{
|
||||||
@ -3940,7 +3936,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
//removing tomb
|
//removing tomb
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GetObjectsInRange<Headstone>(100.0f).Where(h => h.playerIndex == PlayerIndex).First().Destroy();
|
GetObjectsInRange<Headstone>(100.0f).First(h => h.playerIndex == PlayerIndex).Destroy();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -3949,8 +3945,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
Teleport(spawnPosition);
|
Teleport(spawnPosition);
|
||||||
World.BuffManager.AddBuff(this, this, new ActorGhostedBuff());
|
World.BuffManager.AddBuff(this, this, new ActorGhostedBuff());
|
||||||
|
|
||||||
var old_skills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList();
|
var oldSkills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList();
|
||||||
foreach (var skill in old_skills)
|
foreach (var skill in oldSkills)
|
||||||
{
|
{
|
||||||
var power = PowerLoader.CreateImplementationForPowerSNO(skill);
|
var power = PowerLoader.CreateImplementationForPowerSNO(skill);
|
||||||
if (power != null && power.EvalTag(PowerKeys.SynergyPower) != -1)
|
if (power != null && power.EvalTag(PowerKeys.SynergyPower) != -1)
|
||||||
@ -3998,13 +3994,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
var baseStrength = 0.0f;
|
var baseStrength = 0.0f;
|
||||||
|
var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.StrengthParagonMultiplier : GameServerConfig.Instance.StrengthMultiplier;
|
||||||
|
baseStrength = Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Strength
|
||||||
|
? Toon.HeroTable.Strength + (Level - 1) * 3
|
||||||
|
: Toon.HeroTable.Strength + (Level - 1);
|
||||||
|
|
||||||
if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Strength)
|
return baseStrength * multiplier;
|
||||||
baseStrength = Toon.HeroTable.Strength + (Level - 1) * 3;
|
|
||||||
else
|
|
||||||
baseStrength = Toon.HeroTable.Strength + (Level - 1);
|
|
||||||
|
|
||||||
return baseStrength;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4015,17 +4010,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity)
|
var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.DexterityParagonMultiplier : GameServerConfig.Instance.DexterityMultiplier;
|
||||||
return Toon.HeroTable.Dexterity + (Level - 1) * 3;
|
|
||||||
else
|
return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity
|
||||||
return Toon.HeroTable.Dexterity + (Level - 1);
|
? Toon.HeroTable.Dexterity + (Level - 1) * 3 * multiplier
|
||||||
|
: Toon.HeroTable.Dexterity + (Level - 1) * multiplier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float TotalDexterity =>
|
public float TotalDexterity =>
|
||||||
Attributes[GameAttribute.Dexterity] + Inventory.GetItemBonus(GameAttribute.Dexterity_Item);
|
Attributes[GameAttribute.Dexterity] + Inventory.GetItemBonus(GameAttribute.Dexterity_Item);
|
||||||
|
|
||||||
public float Vitality => Toon.HeroTable.Vitality + (Level - 1) * 2;
|
public float Vitality => Toon.HeroTable.Vitality + (Level - 1) * 2 * (ParagonLevel > 0 ? GameServerConfig.Instance.VitalityParagonMultiplier : GameServerConfig.Instance.VitalityMultiplier);
|
||||||
|
|
||||||
public float TotalVitality =>
|
public float TotalVitality =>
|
||||||
Attributes[GameAttribute.Vitality] + Inventory.GetItemBonus(GameAttribute.Vitality_Item);
|
Attributes[GameAttribute.Vitality] + Inventory.GetItemBonus(GameAttribute.Vitality_Item);
|
||||||
@ -4034,10 +4030,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence)
|
var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.IntelligenceParagonMultiplier : GameServerConfig.Instance.IntelligenceMultiplier;
|
||||||
return Toon.HeroTable.Intelligence + (Level - 1) * 3;
|
return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence
|
||||||
else
|
? Toon.HeroTable.Intelligence + (Level - 1) * 3 * multiplier
|
||||||
return Toon.HeroTable.Intelligence + (Level - 1);
|
: Toon.HeroTable.Intelligence + (Level - 1) * multiplier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4325,15 +4321,15 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
if (query.Count == 0)
|
if (query.Count == 0)
|
||||||
{
|
{
|
||||||
//returns empty data
|
//returns empty data
|
||||||
var hireling_empty = new HirelingInfo
|
var emptyHireling = new HirelingInfo
|
||||||
{
|
{
|
||||||
HirelingIndex = type, GbidName = 0x0000, Dead = false, Skill1SNOId = -1, Skill2SNOId = -1,
|
HirelingIndex = type, GbidName = 0x0000, Dead = false, Skill1SNOId = -1, Skill2SNOId = -1,
|
||||||
Skill3SNOId = -1, Skill4SNOId = -1, annItems = -1
|
Skill3SNOId = -1, Skill4SNOId = -1, annItems = -1
|
||||||
};
|
};
|
||||||
return hireling_empty;
|
return emptyHireling;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hireling_full = new HirelingInfo
|
return new HirelingInfo
|
||||||
{
|
{
|
||||||
HirelingIndex = type,
|
HirelingIndex = type,
|
||||||
GbidName = 0x0000,
|
GbidName = 0x0000,
|
||||||
@ -4344,14 +4340,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
Skill4SNOId = query.First().Skill4SNOId,
|
Skill4SNOId = query.First().Skill4SNOId,
|
||||||
annItems = -1
|
annItems = -1
|
||||||
};
|
};
|
||||||
return hireling_full;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<int> Unserialize(string data)
|
private List<int> Unserialize(string data)
|
||||||
{
|
{
|
||||||
var recparts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
var parts = data.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
var ret = new List<int>();
|
var ret = new List<int>();
|
||||||
foreach (var recid in recparts) ret.Add(Convert.ToInt32(recid, 10));
|
foreach (var part in parts) ret.Add(Convert.ToInt32(part, 10));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4380,34 +4375,35 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
public void LearnRecipe(ArtisanType? artisan, int recipe)
|
public void LearnRecipe(ArtisanType? artisan, int recipe)
|
||||||
{
|
{
|
||||||
Logger.Trace("Learning recipe #{0}, Artisan type: {1}", recipe, artisan);
|
Logger.Trace("Learning recipe #{0}, Artisan type: {1}", recipe, artisan);
|
||||||
|
|
||||||
/*var query = this.World.Game.GameDBSession.SessionQuerySingle<DBCraft>(
|
/*var query = this.World.Game.GameDBSession.SessionQuerySingle<DBCraft>(
|
||||||
dbi =>
|
dbi =>
|
||||||
dbi.DBGameAccount.Id == this.Toon.GameAccount.PersistentID &&
|
dbi.DBGameAccount.Id == this.Toon.GameAccount.PersistentID &&
|
||||||
dbi.Artisan == artisan &&
|
dbi.Artisan == artisan &&
|
||||||
dbi.isHardcore == this.World.Game.IsHardcore);*/
|
dbi.isHardcore == this.World.Game.IsHardcore);*/
|
||||||
if (artisan == ArtisanType.Blacksmith)
|
switch (artisan)
|
||||||
{
|
{
|
||||||
learnedBlacksmithRecipes.Add(recipe);
|
case ArtisanType.Blacksmith:
|
||||||
blacksmith_data.LearnedRecipes = SerializeBytes(learnedBlacksmithRecipes);
|
_learnedBlacksmithRecipes.Add(recipe);
|
||||||
World.Game.GameDbSession.SessionUpdate(blacksmith_data);
|
_blacksmithData.LearnedRecipes = SerializeBytes(_learnedBlacksmithRecipes);
|
||||||
UpdateAchievementCounter(404, 1, 0);
|
World.Game.GameDbSession.SessionUpdate(_blacksmithData);
|
||||||
}
|
UpdateAchievementCounter(404, 1, 0);
|
||||||
else if (artisan == ArtisanType.Jeweler)
|
break;
|
||||||
{
|
case ArtisanType.Jeweler:
|
||||||
learnedJewelerRecipes.Add(recipe);
|
_learnedJewelerRecipes.Add(recipe);
|
||||||
jeweler_data.LearnedRecipes = SerializeBytes(learnedJewelerRecipes);
|
_jewelerData.LearnedRecipes = SerializeBytes(_learnedJewelerRecipes);
|
||||||
World.Game.GameDbSession.SessionUpdate(jeweler_data);
|
World.Game.GameDbSession.SessionUpdate(_jewelerData);
|
||||||
UpdateAchievementCounter(404, 1, 1);
|
UpdateAchievementCounter(404, 1, 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadCrafterData();
|
LoadCrafterData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RecipeAvailable(GameBalance.RecipeTable recipe_definition)
|
public bool RecipeAvailable(GameBalance.RecipeTable recipeDefinition)
|
||||||
{
|
{
|
||||||
if (recipe_definition.Flags == 0) return true;
|
if (recipeDefinition.Flags == 0) return true;
|
||||||
return learnedBlacksmithRecipes.Contains(recipe_definition.Hash) ||
|
return _learnedBlacksmithRecipes.Contains(recipeDefinition.Hash) || _learnedJewelerRecipes.Contains(recipeDefinition.Hash);
|
||||||
learnedJewelerRecipes.Contains(recipe_definition.Hash);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerBannerMessage GetPlayerBanner()
|
public PlayerBannerMessage GetPlayerBanner()
|
||||||
@ -4420,69 +4416,69 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
return new PlayerBannerMessage() { PlayerBanner = playerBanner };
|
return new PlayerBannerMessage() { PlayerBanner = playerBanner };
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<int> learnedBlacksmithRecipes = new();
|
private List<int> _learnedBlacksmithRecipes = new();
|
||||||
private List<int> learnedJewelerRecipes = new();
|
private List<int> _learnedJewelerRecipes = new();
|
||||||
private List<int> learnedTransmogs = new();
|
private List<int> _learnedTransmogs = new();
|
||||||
|
|
||||||
private DBCraft blacksmith_data = null;
|
private DBCraft _blacksmithData = null;
|
||||||
private DBCraft jeweler_data = null;
|
private DBCraft _jewelerData = null;
|
||||||
private DBCraft mystic_data = null;
|
private DBCraft _mysticData = null;
|
||||||
private Dictionary<ArtisanType, ArtisanTrainHelper> artisanTrainHelpers = new();
|
private readonly Dictionary<ArtisanType, ArtisanTrainHelper> _artisanTrainHelpers = new();
|
||||||
|
|
||||||
public void LoadCrafterData()
|
public void LoadCrafterData()
|
||||||
{
|
{
|
||||||
if (blacksmith_data == null)
|
if (_blacksmithData == null)
|
||||||
{
|
{
|
||||||
var craft_data =
|
var craft_data =
|
||||||
World.Game.GameDbSession.SessionQueryWhere<DBCraft>(dbc =>
|
World.Game.GameDbSession.SessionQueryWhere<DBCraft>(dbc =>
|
||||||
dbc.DBGameAccount.Id == Toon.GameAccount.PersistentID);
|
dbc.DBGameAccount.Id == Toon.GameAccount.PersistentID);
|
||||||
|
|
||||||
blacksmith_data = craft_data.Single(dbc =>
|
_blacksmithData = craft_data.Single(dbc =>
|
||||||
dbc.Artisan == "Blacksmith" && dbc.isHardcore == World.Game.IsHardcore &&
|
dbc.Artisan == "Blacksmith" && dbc.isHardcore == World.Game.IsHardcore &&
|
||||||
dbc.isSeasoned == World.Game.IsSeasoned);
|
dbc.isSeasoned == World.Game.IsSeasoned);
|
||||||
jeweler_data = craft_data.Single(dbc =>
|
_jewelerData = craft_data.Single(dbc =>
|
||||||
dbc.Artisan == "Jeweler" && dbc.isHardcore == World.Game.IsHardcore &&
|
dbc.Artisan == "Jeweler" && dbc.isHardcore == World.Game.IsHardcore &&
|
||||||
dbc.isSeasoned == World.Game.IsSeasoned);
|
dbc.isSeasoned == World.Game.IsSeasoned);
|
||||||
mystic_data = craft_data.Single(dbc =>
|
_mysticData = craft_data.Single(dbc =>
|
||||||
dbc.Artisan == "Mystic" && dbc.isHardcore == World.Game.IsHardcore &&
|
dbc.Artisan == "Mystic" && dbc.isHardcore == World.Game.IsHardcore &&
|
||||||
dbc.isSeasoned == World.Game.IsSeasoned);
|
dbc.isSeasoned == World.Game.IsSeasoned);
|
||||||
|
|
||||||
artisanTrainHelpers[ArtisanType.Blacksmith] =
|
_artisanTrainHelpers[ArtisanType.Blacksmith] =
|
||||||
new ArtisanTrainHelper(blacksmith_data, ArtisanType.Blacksmith);
|
new ArtisanTrainHelper(_blacksmithData, ArtisanType.Blacksmith);
|
||||||
artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(jeweler_data, ArtisanType.Jeweler);
|
_artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(_jewelerData, ArtisanType.Jeweler);
|
||||||
artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(mystic_data, ArtisanType.Mystic);
|
_artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(_mysticData, ArtisanType.Mystic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var blacksmith = D3.ItemCrafting.CrafterData.CreateBuilder()
|
var blacksmith = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||||
? BlacksmithUnlocked == false && blacksmith_data.Level < 1 ? 1 : blacksmith_data.Level
|
? BlacksmithUnlocked == false && _blacksmithData.Level < 1 ? 1 : _blacksmithData.Level
|
||||||
: blacksmith_data.Level)
|
: _blacksmithData.Level)
|
||||||
.SetCooldownEnd(0)
|
.SetCooldownEnd(0)
|
||||||
.AddRangeRecipes(UnserializeBytes(blacksmith_data.LearnedRecipes))
|
.AddRangeRecipes(UnserializeBytes(_blacksmithData.LearnedRecipes))
|
||||||
.Build();
|
.Build();
|
||||||
learnedBlacksmithRecipes = UnserializeBytes(blacksmith_data.LearnedRecipes);
|
_learnedBlacksmithRecipes = UnserializeBytes(_blacksmithData.LearnedRecipes);
|
||||||
var jeweler = D3.ItemCrafting.CrafterData.CreateBuilder()
|
var jeweler = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||||
? JewelerUnlocked == false && jeweler_data.Level < 1 ? 1 : jeweler_data.Level
|
? JewelerUnlocked == false && _jewelerData.Level < 1 ? 1 : _jewelerData.Level
|
||||||
: jeweler_data.Level)
|
: _jewelerData.Level)
|
||||||
.SetCooldownEnd(0)
|
.SetCooldownEnd(0)
|
||||||
.AddRangeRecipes(UnserializeBytes(jeweler_data.LearnedRecipes))
|
.AddRangeRecipes(UnserializeBytes(_jewelerData.LearnedRecipes))
|
||||||
.Build();
|
.Build();
|
||||||
learnedJewelerRecipes = UnserializeBytes(jeweler_data.LearnedRecipes);
|
_learnedJewelerRecipes = UnserializeBytes(_jewelerData.LearnedRecipes);
|
||||||
var mystic = D3.ItemCrafting.CrafterData.CreateBuilder()
|
var mystic = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||||
? MysticUnlocked == false && mystic_data.Level < 1 ? 1 : mystic_data.Level
|
? MysticUnlocked == false && _mysticData.Level < 1 ? 1 : _mysticData.Level
|
||||||
: mystic_data.Level)
|
: _mysticData.Level)
|
||||||
.SetCooldownEnd(0)
|
.SetCooldownEnd(0)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var transmog = D3.ItemCrafting.CrafterSavedData.CreateBuilder()
|
var transmog = D3.ItemCrafting.CrafterSavedData.CreateBuilder()
|
||||||
.SetTransmogData(D3.GameBalance.BitPackedGbidArray.CreateBuilder()
|
.SetTransmogData(D3.GameBalance.BitPackedGbidArray.CreateBuilder()
|
||||||
.SetBitfield(ByteString.CopyFrom(mystic_data.LearnedRecipes)))
|
.SetBitfield(ByteString.CopyFrom(_mysticData.LearnedRecipes)))
|
||||||
//.AddRangeUnlockedTransmogs(this.UnserializeBytes(mystic_data.LearnedRecipes))
|
//.AddRangeUnlockedTransmogs(this.UnserializeBytes(mystic_data.LearnedRecipes))
|
||||||
.Build();
|
.Build();
|
||||||
learnedTransmogs = UnserializeBytes(mystic_data.LearnedRecipes);
|
_learnedTransmogs = UnserializeBytes(_mysticData.LearnedRecipes);
|
||||||
|
|
||||||
if (BlacksmithUnlocked || InGameClient.Game.CurrentAct == 3000)
|
if (BlacksmithUnlocked || InGameClient.Game.CurrentAct == 3000)
|
||||||
InGameClient.SendMessage(new GenericBlobMessage(Opcodes.CraftingDataBlacksmithInitialMessage)
|
InGameClient.SendMessage(new GenericBlobMessage(Opcodes.CraftingDataBlacksmithInitialMessage)
|
||||||
@ -4503,27 +4499,26 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public void LoadCurrencyData()
|
public void LoadCurrencyData()
|
||||||
{
|
{
|
||||||
var bloodShards = 0;
|
var bloodShards = Toon.GameAccount.BloodShards; // TODO: is this needed? @iamdroppy
|
||||||
bloodShards = Toon.GameAccount.BloodShards;
|
|
||||||
Inventory.UpdateCurrencies();
|
Inventory.UpdateCurrencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadMailData()
|
public void LoadMailData()
|
||||||
{
|
{
|
||||||
var mail_data =
|
var mailData =
|
||||||
World.Game.GameDbSession.SessionQueryWhere<DBMail>(dbm =>
|
World.Game.GameDbSession.SessionQueryWhere<DBMail>(dbm =>
|
||||||
dbm.DBToon.Id == Toon.PersistentID && dbm.Claimed == false);
|
dbm.DBToon.Id == Toon.PersistentID && dbm.Claimed == false);
|
||||||
var mails = D3.Items.Mails.CreateBuilder();
|
var mails = D3.Items.Mails.CreateBuilder();
|
||||||
foreach (var mail in mail_data)
|
foreach (var mail in mailData)
|
||||||
{
|
{
|
||||||
var mail_row = D3.Items.Mail.CreateBuilder()
|
var mailRow = D3.Items.Mail.CreateBuilder()
|
||||||
.SetAccountTo(Toon.D3EntityID)
|
.SetAccountTo(Toon.D3EntityID)
|
||||||
.SetAccountFrom(Toon.D3EntityID)
|
.SetAccountFrom(Toon.D3EntityID)
|
||||||
.SetMailId(mail.Id)
|
.SetMailId(mail.Id)
|
||||||
.SetTitle(mail.Title)
|
.SetTitle(mail.Title)
|
||||||
.SetBody(mail.Body);
|
.SetBody(mail.Body);
|
||||||
if (mail.ItemGBID != -1)
|
if (mail.ItemGBID != -1)
|
||||||
mail_row.SetAttachments(D3.Items.MailAttachments.CreateBuilder()
|
mailRow.SetAttachments(D3.Items.MailAttachments.CreateBuilder()
|
||||||
.SetItems(D3.Items.ItemList.CreateBuilder()
|
.SetItems(D3.Items.ItemList.CreateBuilder()
|
||||||
.AddItems(D3.Items.SavedItem.CreateBuilder()
|
.AddItems(D3.Items.SavedItem.CreateBuilder()
|
||||||
.SetId(D3.OnlineService.ItemId.CreateBuilder().SetIdLow(0).SetIdHigh(0x3C000002517A294))
|
.SetId(D3.OnlineService.ItemId.CreateBuilder().SetIdLow(0).SetIdHigh(0x3C000002517A294))
|
||||||
@ -4542,15 +4537,16 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
mails.AddMailsProp(mail_row);
|
mails.AddMailsProp(mailRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mail_contents = D3.GameMessage.MailContents.CreateBuilder()
|
InGameClient.SendMessage(new MailDigestMessage()
|
||||||
.SetAppendMessages(false)
|
{
|
||||||
.SetMails(mails)
|
MailContents = D3.GameMessage.MailContents.CreateBuilder()
|
||||||
.Build();
|
.SetAppendMessages(false)
|
||||||
|
.SetMails(mails)
|
||||||
InGameClient.SendMessage(new MailDigestMessage() { MailContents = mail_contents });
|
.Build()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//*/
|
//*/
|
||||||
@ -4578,10 +4574,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public void LoadShownTutorials()
|
public void LoadShownTutorials()
|
||||||
{
|
{
|
||||||
var tutorials = new List<byte>();
|
// var tutorials = new List<byte>();
|
||||||
tutorials.Add(64);
|
// tutorials.Add(64);
|
||||||
for (var i = 0; i < 15; i++)
|
// for (var i = 0; i < 15; i++)
|
||||||
tutorials.Add(0);
|
// tutorials.Add(0);
|
||||||
var seenTutorials = Toon.GameAccount.DBGameAccount.SeenTutorials;
|
var seenTutorials = Toon.GameAccount.DBGameAccount.SeenTutorials;
|
||||||
|
|
||||||
var state = D3.GameMessage.TutorialState.CreateBuilder()
|
var state = D3.GameMessage.TutorialState.CreateBuilder()
|
||||||
@ -4590,13 +4586,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
InGameClient.SendMessage(new GenericBlobMessage(Opcodes.TutorialStateMessage) { Data = state.ToByteArray() });
|
InGameClient.SendMessage(new GenericBlobMessage(Opcodes.TutorialStateMessage) { Data = state.ToByteArray() });
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ulong> _unlockedAchievements = new();
|
private readonly List<ulong> _unlockedAchievements = new();
|
||||||
private List<ulong> _unlockedCriterias = new();
|
private readonly List<ulong> _unlockCriteria = new();
|
||||||
|
|
||||||
private Dictionary<ulong, uint> AchievementCounters = new();
|
private readonly Dictionary<ulong, uint> _achievementCounters = new();
|
||||||
|
|
||||||
public int DodgesInARow = 0;
|
public int DodgesInARow { get; set; } = 0;
|
||||||
public int BlocksInARow = 0;
|
public int BlocksInARow { get; set; }= 0;
|
||||||
|
|
||||||
public void GrantAchievement(ulong id)
|
public void GrantAchievement(ulong id)
|
||||||
{
|
{
|
||||||
@ -4606,20 +4602,20 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
_unlockedAchievements.Add(id);
|
_unlockedAchievements.Add(id);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var Achievement = AchievementSystem.AchievementManager.GetAchievementById(id);
|
var achievement = AchievementSystem.AchievementManager.GetAchievementById(id);
|
||||||
long Platinum = -1;
|
long platinum = -1;
|
||||||
foreach (var attr in Achievement.AttributesList)
|
foreach (var attr in achievement.AttributesList)
|
||||||
if (attr.Key == "Reward Currency Quantity")
|
if (attr.Key == "Reward Currency Quantity")
|
||||||
Platinum = long.Parse(attr.Value);
|
platinum = long.Parse(attr.Value);
|
||||||
InGameClient.SendMessage(new MessageSystem.Message.Definitions.Platinum.PlatinumAchievementAwardedMessage
|
InGameClient.SendMessage(new MessageSystem.Message.Definitions.Platinum.PlatinumAchievementAwardedMessage
|
||||||
{
|
{
|
||||||
CurrentPlatinum = InGameClient.BnetClient.Account.GameAccount.Platinum,
|
CurrentPlatinum = InGameClient.BnetClient.Account.GameAccount.Platinum,
|
||||||
idAchievement = id,
|
idAchievement = id,
|
||||||
PlatinumIncrement = Platinum
|
PlatinumIncrement = platinum
|
||||||
});
|
});
|
||||||
if (Platinum > 0)
|
if (platinum > 0)
|
||||||
{
|
{
|
||||||
InGameClient.BnetClient.Account.GameAccount.Platinum += (int)Platinum;
|
InGameClient.BnetClient.Account.GameAccount.Platinum += (int)platinum;
|
||||||
Inventory.UpdateCurrencies();
|
Inventory.UpdateCurrencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4633,33 +4629,33 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public void AddAchievementCounter(ulong id, uint count)
|
public void AddAchievementCounter(ulong id, uint count)
|
||||||
{
|
{
|
||||||
lock (AchievementCounters)
|
lock (_achievementCounters)
|
||||||
{
|
{
|
||||||
if (!AchievementCounters.ContainsKey(id))
|
if (!_achievementCounters.ContainsKey(id))
|
||||||
AchievementCounters.Add(id, count);
|
_achievementCounters.Add(id, count);
|
||||||
else
|
else
|
||||||
AchievementCounters[id] += count;
|
_achievementCounters[id] += count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckAchievementCounters()
|
public void CheckAchievementCounters()
|
||||||
{
|
{
|
||||||
lock (AchievementCounters)
|
lock (_achievementCounters)
|
||||||
{
|
{
|
||||||
foreach (var counter in AchievementCounters)
|
foreach (var counter in _achievementCounters)
|
||||||
{
|
{
|
||||||
if (counter.Value == 0) continue;
|
if (counter.Value == 0) continue;
|
||||||
UpdateSingleAchievementCounter(counter.Key, counter.Value);
|
UpdateSingleAchievementCounter(counter.Key, counter.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
AchievementCounters.Clear();
|
_achievementCounters.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GrantCriteria(ulong id)
|
public void GrantCriteria(ulong id)
|
||||||
{
|
{
|
||||||
if (_unlockedCriterias.Contains(id)) return;
|
if (_unlockCriteria.Contains(id)) return;
|
||||||
_unlockedCriterias.Add(id);
|
_unlockCriteria.Add(id);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GameServer.ClientSystem.GameServer.GSBackend.GrantCriteria(Toon.GameAccount.PersistentID, id);
|
GameServer.ClientSystem.GameServer.GSBackend.GrantCriteria(Toon.GameAccount.PersistentID, id);
|
||||||
@ -4824,13 +4820,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public int CastingSnoPower = -1;
|
public int CastingSnoPower = -1;
|
||||||
|
|
||||||
public void StartCasting(int durationTicks, Action result, int skillsno = -1)
|
public void StartCasting(int durationTicks, Action result, int skillSno = -1)
|
||||||
{
|
{
|
||||||
IsCasting = true;
|
IsCasting = true;
|
||||||
CastResult = result;
|
CastResult = result;
|
||||||
Attributes[GameAttribute.Looping_Animation_Start_Time] = World.Game.TickCounter;
|
Attributes[GameAttribute.Looping_Animation_Start_Time] = World.Game.TickCounter;
|
||||||
Attributes[GameAttribute.Looping_Animation_End_Time] = World.Game.TickCounter + durationTicks;
|
Attributes[GameAttribute.Looping_Animation_End_Time] = World.Game.TickCounter + durationTicks;
|
||||||
CastingSnoPower = skillsno;
|
CastingSnoPower = skillSno;
|
||||||
if (CastingSnoPower != -1)
|
if (CastingSnoPower != -1)
|
||||||
{
|
{
|
||||||
Attributes[GameAttribute.Buff_Icon_Start_Tick0, CastingSnoPower] = World.Game.TickCounter;
|
Attributes[GameAttribute.Buff_Icon_Start_Tick0, CastingSnoPower] = World.Game.TickCounter;
|
||||||
@ -4882,7 +4878,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
#region generic properties
|
#region generic properties
|
||||||
|
|
||||||
public int ClassSNO => Toon.Gender == 0 ? Toon.HeroTable.SNOMaleActor : Toon.HeroTable.SNOFemaleActor;
|
public int ClassSno => Toon.Gender == 0 ? Toon.HeroTable.SNOMaleActor : Toon.HeroTable.SNOFemaleActor;
|
||||||
|
|
||||||
public int AdditionalLootItems
|
public int AdditionalLootItems
|
||||||
{
|
{
|
||||||
@ -4910,7 +4906,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public int SecondaryResourceID => (int)Toon.HeroTable.SecondaryResource;
|
public int SecondaryResourceID => (int)Toon.HeroTable.SecondaryResource;
|
||||||
|
|
||||||
[Obsolete]
|
[Obsolete("Not used anymore. Should it be removed?")]
|
||||||
public bool IsInTown
|
public bool IsInTown
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -4945,7 +4941,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
(Attributes[GameAttribute.Resource_Max_Percent_Bonus, resourceId] + 1), 0);
|
(Attributes[GameAttribute.Resource_Max_Percent_Bonus, resourceId] + 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<long> LevelBorders = new()
|
public static readonly List<long> LevelBorders = new()
|
||||||
{
|
{
|
||||||
0, 280, 2700, 4500, 6600, 9000, 11700, 14000, 16500, 19200, 22100, /* Level 0-10 */
|
0, 280, 2700, 4500, 6600, 9000, 11700, 14000, 16500, 19200, 22100, /* Level 0-10 */
|
||||||
25200, 28500, 32000, 35700, 39600, 43700, 48000, 52500, 57200, 62100, /* Level 11-20 */
|
25200, 28500, 32000, 35700, 39600, 43700, 48000, 52500, 57200, 62100, /* Level 11-20 */
|
||||||
@ -4958,7 +4954,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
100000000 /* Level 61-70 */
|
100000000 /* Level 61-70 */
|
||||||
};
|
};
|
||||||
|
|
||||||
public static List<long> ParagonLevelBorders = new()
|
public static readonly List<long> ParagonLevelBorders = new()
|
||||||
{
|
{
|
||||||
//7200000,8640000,10800000,11520000,12960000,14400000,15840000,17280000,18720000,20160000,21600000,23040000,24480000,25920000,27360000,
|
//7200000,8640000,10800000,11520000,12960000,14400000,15840000,17280000,18720000,20160000,21600000,23040000,24480000,25920000,27360000,
|
||||||
//28800000,30240000,31680000,33120000,34560000,36000000,37440000,38880000,40320,41760000,43200000,41760000,43200000,44640000,46080000,
|
//28800000,30240000,31680000,33120000,34560000,36000000,37440000,38880000,40320,41760000,43200000,41760000,43200000,44640000,46080000,
|
||||||
@ -5141,9 +5137,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
});
|
});
|
||||||
Conversations.StartConversation(0x0002A777); //LevelUp Conversation
|
Conversations.StartConversation(0x0002A777); //LevelUp Conversation
|
||||||
|
|
||||||
Attributes[GameAttribute.Alt_Experience_Next_Lo] =
|
Attributes[GameAttribute.Alt_Experience_Next_Lo] += (int)ParagonLevelBorders[Attributes[GameAttribute.Alt_Level]];
|
||||||
Attributes[GameAttribute.Alt_Experience_Next_Lo] +
|
|
||||||
(int)ParagonLevelBorders[Attributes[GameAttribute.Alt_Level]];
|
|
||||||
// On level up, health is set to max
|
// On level up, health is set to max
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] = Attributes[GameAttribute.Hitpoints_Max_Total];
|
Attributes[GameAttribute.Hitpoints_Cur] = Attributes[GameAttribute.Hitpoints_Max_Total];
|
||||||
// set resources to max as well
|
// set resources to max as well
|
||||||
@ -5165,8 +5159,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
Level++;
|
Level++;
|
||||||
Attributes[GameAttribute.Level]++;
|
Attributes[GameAttribute.Level]++;
|
||||||
Toon.LevelUp();
|
Toon.LevelUp();
|
||||||
if (World.Game.MonsterLevel + 1 ==
|
if (World.Game.MonsterLevel + 1 == Attributes[GameAttribute.Level]) //if this is suitable level to update
|
||||||
Attributes[GameAttribute.Level]) //if this is suitable level to update
|
|
||||||
World.Game.UpdateLevel(Attributes[GameAttribute.Level]);
|
World.Game.UpdateLevel(Attributes[GameAttribute.Level]);
|
||||||
|
|
||||||
InGameClient.SendMessage(new PlayerLevel()
|
InGameClient.SendMessage(new PlayerLevel()
|
||||||
@ -5326,7 +5319,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public void VacuumPickupHealthOrb(float radius = -1)
|
public void VacuumPickupHealthOrb(float radius = -1)
|
||||||
{
|
{
|
||||||
if (Math.Abs(radius - -1) < 0.001)
|
if (Math.Abs(radius - -1) < Globals.FLOAT_TOLERANCE)
|
||||||
radius = Attributes[GameAttribute.Gold_PickUp_Radius];
|
radius = Attributes[GameAttribute.Gold_PickUp_Radius];
|
||||||
var itemList = GetItemsInRange(radius);
|
var itemList = GetItemsInRange(radius);
|
||||||
foreach (var item in itemList)
|
foreach (var item in itemList)
|
||||||
@ -5501,12 +5494,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
item.Destroy();
|
item.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (item.ItemDefinition.Name == "p1_normal_rifts_Orb" ||
|
else if (item.ItemDefinition.Name is "p1_normal_rifts_Orb" or "p1_tiered_rifts_Orb")
|
||||||
item.ItemDefinition.Name == "p1_tiered_rifts_Orb")
|
|
||||||
{
|
{
|
||||||
if (InGameClient.Game.ActiveNephalemTimer && InGameClient.Game.ActiveNephalemKilledMobs == false)
|
if (InGameClient.Game.ActiveNephalemTimer && InGameClient.Game.ActiveNephalemKilledMobs == false)
|
||||||
{
|
{
|
||||||
InGameClient.Game.ActiveNephalemProgress += 15f;
|
InGameClient.Game.ActiveNephalemProgress += 15f * GameServerConfig.Instance.NephalemRiftProgressMultiplier;
|
||||||
foreach (var plr in InGameClient.Game.Players.Values)
|
foreach (var plr in InGameClient.Game.Players.Values)
|
||||||
{
|
{
|
||||||
plr.InGameClient.SendMessage(new FloatDataMessage(Opcodes.DunggeonFinderProgressGlyphPickUp)
|
plr.InGameClient.SendMessage(new FloatDataMessage(Opcodes.DunggeonFinderProgressGlyphPickUp)
|
||||||
@ -5630,7 +5622,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
public Actor SpawnNephalemBoss(World world)
|
public Actor SpawnNephalemBoss(World world)
|
||||||
{
|
{
|
||||||
var boss = world.SpawnMonster(ActorSnoExtensions.nephalemPortalBosses.PickRandom(), Position);
|
var boss = world.SpawnMonster(ActorSnoExtensions.NephalemPortalBosses.PickRandom(), Position);
|
||||||
boss.Attributes[GameAttribute.Bounty_Objective] = true;
|
boss.Attributes[GameAttribute.Bounty_Objective] = true;
|
||||||
boss.Attributes[GameAttribute.Is_Loot_Run_Boss] = true;
|
boss.Attributes[GameAttribute.Is_Loot_Run_Boss] = true;
|
||||||
boss.Attributes.BroadcastChangedIfRevealed();
|
boss.Attributes.BroadcastChangedIfRevealed();
|
||||||
@ -5658,62 +5650,67 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPercentageHP(int percentage, bool GuidingLight = false)
|
public void AddPercentageHP(int percentage, bool guidingLight = false)
|
||||||
{
|
{
|
||||||
var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100;
|
var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100;
|
||||||
AddHP(quantity, GuidingLight);
|
AddHP(quantity, guidingLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddPercentageHP(float percentage, bool GuidingLight = false)
|
public void AddPercentageHP(float percentage, bool guidingLight = false)
|
||||||
{
|
{
|
||||||
var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100;
|
var quantity = percentage * Attributes[GameAttribute.Hitpoints_Max_Total] / 100;
|
||||||
AddHP(quantity, GuidingLight);
|
AddHP(quantity, guidingLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddHP(float quantity, bool guidingLight = false)
|
public override void AddHP(float quantity, bool guidingLight = false)
|
||||||
{
|
{
|
||||||
if (Dead) return;
|
if (Dead) return;
|
||||||
if (quantity == 0) return;
|
switch (quantity)
|
||||||
if (quantity > 0)
|
|
||||||
{
|
{
|
||||||
if (Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total])
|
case 0:
|
||||||
|
return;
|
||||||
|
case > 0:
|
||||||
{
|
{
|
||||||
if (Toon.Class == ToonClass.Barbarian)
|
if (Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total])
|
||||||
if (SkillSet.HasPassive(205217))
|
|
||||||
quantity += 0.01f * Attributes[GameAttribute.Health_Globe_Bonus_Health];
|
|
||||||
|
|
||||||
if (guidingLight) //Monk -> Guiding Light
|
|
||||||
{
|
{
|
||||||
var missingHP =
|
if (Toon.Class == ToonClass.Barbarian)
|
||||||
(Attributes[GameAttribute.Hitpoints_Max_Total] - Attributes[GameAttribute.Hitpoints_Cur]) /
|
if (SkillSet.HasPassive(205217))
|
||||||
Attributes[GameAttribute.Hitpoints_Max_Total];
|
quantity += 0.01f * Attributes[GameAttribute.Health_Globe_Bonus_Health];
|
||||||
if (missingHP > 0.05f)
|
|
||||||
if (!World.BuffManager.HasBuff<GuidingLightBuff>(this))
|
if (guidingLight) //Monk -> Guiding Light
|
||||||
World.BuffManager.AddBuff(this, this,
|
{
|
||||||
new GuidingLightBuff(Math.Min(missingHP, 0.3f),
|
var missingHP =
|
||||||
TickTimer.WaitSeconds(World.Game, 10.0f)));
|
(Attributes[GameAttribute.Hitpoints_Max_Total] - Attributes[GameAttribute.Hitpoints_Cur]) /
|
||||||
|
Attributes[GameAttribute.Hitpoints_Max_Total];
|
||||||
|
if (missingHP > 0.05f)
|
||||||
|
if (!World.BuffManager.HasBuff<GuidingLightBuff>(this))
|
||||||
|
World.BuffManager.AddBuff(this, this,
|
||||||
|
new GuidingLightBuff(Math.Min(missingHP, 0.3f),
|
||||||
|
TickTimer.WaitSeconds(World.Game, 10.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Attributes[GameAttribute.Hitpoints_Cur] = Math.Min(
|
||||||
|
Attributes[GameAttribute.Hitpoints_Cur] + quantity,
|
||||||
|
Attributes[GameAttribute.Hitpoints_Max_Total]);
|
||||||
|
|
||||||
|
Attributes.BroadcastChangedIfRevealed();
|
||||||
|
InGameClient.SendMessage(new FloatingNumberMessage
|
||||||
|
{
|
||||||
|
ActorID = DynamicID(this),
|
||||||
|
Number = quantity,
|
||||||
|
Type = FloatingNumberMessage.FloatType.Green
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] = Math.Min(
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Attributes[GameAttribute.Hitpoints_Cur] = Math.Max(
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] + quantity,
|
Attributes[GameAttribute.Hitpoints_Cur] + quantity,
|
||||||
Attributes[GameAttribute.Hitpoints_Max_Total]);
|
0);
|
||||||
|
|
||||||
Attributes.BroadcastChangedIfRevealed();
|
Attributes.BroadcastChangedIfRevealed();
|
||||||
InGameClient.SendMessage(new FloatingNumberMessage
|
break;
|
||||||
{
|
|
||||||
ActorID = DynamicID(this),
|
|
||||||
Number = quantity,
|
|
||||||
Type = FloatingNumberMessage.FloatType.Green
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] = Math.Max(
|
|
||||||
Attributes[GameAttribute.Hitpoints_Cur] + quantity,
|
|
||||||
0);
|
|
||||||
|
|
||||||
Attributes.BroadcastChangedIfRevealed();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5731,9 +5728,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
#region Resource Generate/Use
|
#region Resource Generate/Use
|
||||||
|
|
||||||
private int _DisciplineSpent = 0;
|
private int _disciplineSpent = 0;
|
||||||
private int _HatredSpent = 0;
|
private int _hatredSpent = 0;
|
||||||
private int _WrathSpent = 0;
|
private int _wrathSpent = 0;
|
||||||
|
|
||||||
public void GeneratePrimaryResource(float amount)
|
public void GeneratePrimaryResource(float amount)
|
||||||
{
|
{
|
||||||
@ -5745,7 +5742,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
if (World.BuffManager.HasBuff<GuardiansPathBuff>(this)) //Monk -> The Guardian's Path 2H
|
if (World.BuffManager.HasBuff<GuardiansPathBuff>(this)) //Monk -> The Guardian's Path 2H
|
||||||
amount *= 1.35f;
|
amount *= 1.35f;
|
||||||
|
|
||||||
_ModifyResourceAttribute(PrimaryResourceID, amount);
|
ModifyResourceAttribute(PrimaryResourceID, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UsePrimaryResource(float amount, bool tick = false)
|
public void UsePrimaryResource(float amount, bool tick = false)
|
||||||
@ -5757,28 +5754,28 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
amount = amount * (1f - DecreaseUseResourcePercent);
|
amount = amount * (1f - DecreaseUseResourcePercent);
|
||||||
if (Toon.Class == ToonClass.Crusader)
|
if (Toon.Class == ToonClass.Crusader)
|
||||||
{
|
{
|
||||||
_WrathSpent += (int)amount;
|
_wrathSpent += (int)amount;
|
||||||
if (!tick && SkillSet.HasPassive(310775)) //Wrathful passive
|
if (!tick && SkillSet.HasPassive(310775)) //Wrathful passive
|
||||||
AddHP(_WrathSpent * 15f * Attributes[GameAttribute.Level]);
|
AddHP(_wrathSpent * 15f * Attributes[GameAttribute.Level]);
|
||||||
|
|
||||||
//Laws of Hope -> Faith's reward
|
//Laws of Hope -> Faith's reward
|
||||||
if (!tick && World.BuffManager.HasBuff<CrusaderLawsOfHope.LawsShieldBuff>(this))
|
if (!tick && World.BuffManager.HasBuff<CrusaderLawsOfHope.LawsShieldBuff>(this))
|
||||||
if (World.BuffManager.GetFirstBuff<CrusaderLawsOfHope.LawsShieldBuff>(this).HealPerWrath)
|
if (World.BuffManager.GetFirstBuff<CrusaderLawsOfHope.LawsShieldBuff>(this).HealPerWrath)
|
||||||
AddHP(_WrathSpent * 15f * Attributes[GameAttribute.Level]);
|
AddHP(_wrathSpent * 15f * Attributes[GameAttribute.Level]);
|
||||||
|
|
||||||
if (_WrathSpent >= 20) //Akarat Champion -> Fire Starter
|
if (_wrathSpent >= 20) //Akarat Champion -> Fire Starter
|
||||||
if (!tick && World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(this))
|
if (!tick && World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(this))
|
||||||
World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(this).wrathBlast = true;
|
World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(this).wrathBlast = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Toon.Class == ToonClass.DemonHunter)
|
if (Toon.Class == ToonClass.DemonHunter)
|
||||||
{
|
{
|
||||||
_HatredSpent += (int)amount;
|
_hatredSpent += (int)amount;
|
||||||
|
|
||||||
if (_HatredSpent >= 150 && _DisciplineSpent >= 50)
|
if (_hatredSpent >= 150 && _disciplineSpent >= 50)
|
||||||
GrantAchievement(74987243307068);
|
GrantAchievement(74987243307068);
|
||||||
|
|
||||||
AddTimedAction(6f, new Action<int>((q) => _HatredSpent -= (int)amount));
|
AddTimedAction(6f, new Action<int>((q) => _hatredSpent -= (int)amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Toon.Class == ToonClass.Barbarian)
|
if (Toon.Class == ToonClass.Barbarian)
|
||||||
@ -5813,12 +5810,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
if (SkillSet.HasPassive(205398) && Attributes[GameAttribute.Hitpoints_Cur] <
|
if (SkillSet.HasPassive(205398) && Attributes[GameAttribute.Hitpoints_Cur] <
|
||||||
Attributes[GameAttribute.Hitpoints_Max_Total] * 0.35f) //Relentless (Barbarian)
|
Attributes[GameAttribute.Hitpoints_Max_Total] * 0.35f) //Relentless (Barbarian)
|
||||||
amount *= 0.25f;
|
amount *= 0.25f;
|
||||||
_ModifyResourceAttribute(PrimaryResourceID, -amount);
|
ModifyResourceAttribute(PrimaryResourceID, -amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenerateSecondaryResource(float amount)
|
public void GenerateSecondaryResource(float amount)
|
||||||
{
|
{
|
||||||
_ModifyResourceAttribute(SecondaryResourceID, amount);
|
ModifyResourceAttribute(SecondaryResourceID, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UseSecondaryResource(float amount)
|
public void UseSecondaryResource(float amount)
|
||||||
@ -5833,18 +5830,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
|
|
||||||
if (Toon.Class == ToonClass.DemonHunter)
|
if (Toon.Class == ToonClass.DemonHunter)
|
||||||
{
|
{
|
||||||
_DisciplineSpent += (int)amount;
|
_disciplineSpent += (int)amount;
|
||||||
|
|
||||||
if (_HatredSpent >= 150 && _DisciplineSpent >= 50)
|
if (_hatredSpent >= 150 && _disciplineSpent >= 50)
|
||||||
GrantAchievement(74987243307068);
|
GrantAchievement(74987243307068);
|
||||||
|
|
||||||
AddTimedAction(6f, new Action<int>((q) => _DisciplineSpent -= (int)amount));
|
AddTimedAction(6f, new Action<int>((q) => _disciplineSpent -= (int)amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ModifyResourceAttribute(SecondaryResourceID, -amount);
|
ModifyResourceAttribute(SecondaryResourceID, -amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _ModifyResourceAttribute(int resourceID, float amount)
|
private void ModifyResourceAttribute(int resourceID, float amount)
|
||||||
{
|
{
|
||||||
if (resourceID == -1 || amount == 0) return;
|
if (resourceID == -1 || amount == 0) return;
|
||||||
var current = Attributes[GameAttribute.Resource_Cur, resourceID];
|
var current = Attributes[GameAttribute.Resource_Cur, resourceID];
|
||||||
@ -5857,7 +5854,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
|||||||
Attributes[GameAttribute.Resource_Cur, resourceID] + amount,
|
Attributes[GameAttribute.Resource_Cur, resourceID] + amount,
|
||||||
0f);
|
0f);
|
||||||
|
|
||||||
if (current == Attributes[GameAttribute.Resource_Cur, resourceID]) return;
|
if (Math.Abs(current - Attributes[GameAttribute.Resource_Cur, resourceID]) < Globals.FLOAT_TOLERANCE) return;
|
||||||
|
|
||||||
Attributes.BroadcastChangedIfRevealed();
|
Attributes.BroadcastChangedIfRevealed();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -266,9 +266,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
}, Target);
|
}, Target);
|
||||||
|
|
||||||
if (Context?.User != null)
|
if (Context?.User != null)
|
||||||
if (Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 247640] - 1) < 0.001 ||
|
if (Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 247640] - 1) < Globals.FLOAT_TOLERANCE ||
|
||||||
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249963] - 1) < 0.001 ||
|
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249963] - 1) < Globals.FLOAT_TOLERANCE ||
|
||||||
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 1) < 0.001 ||
|
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 1) < Globals.FLOAT_TOLERANCE ||
|
||||||
(float)FastRandom.Instance.NextDouble() < 0.1f ||
|
(float)FastRandom.Instance.NextDouble() < 0.1f ||
|
||||||
Target.World.SNO == WorldSno.a1dun_random_level01)
|
Target.World.SNO == WorldSno.a1dun_random_level01)
|
||||||
switch ((int)DeathDamageType.HitEffect)
|
switch ((int)DeathDamageType.HitEffect)
|
||||||
@ -1066,7 +1066,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
{
|
{
|
||||||
//death implementation
|
//death implementation
|
||||||
Player player = (Player)Target;
|
Player player = (Player)Target;
|
||||||
if (Math.Abs(player.Attributes[GameAttribute.Item_Power_Passive, 248629] - 1) < 0.001)
|
if (Math.Abs(player.Attributes[GameAttribute.Item_Power_Passive, 248629] - 1) < Globals.FLOAT_TOLERANCE)
|
||||||
player.PlayEffectGroup(248680);
|
player.PlayEffectGroup(248680);
|
||||||
player.StopCasting();
|
player.StopCasting();
|
||||||
Target.World.BuffManager.RemoveAllBuffs(Target, false);
|
Target.World.BuffManager.RemoveAllBuffs(Target, false);
|
||||||
|
|||||||
@ -24,25 +24,22 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
public class HitPayload : Payload
|
public class HitPayload : Payload
|
||||||
{
|
{
|
||||||
public static readonly Logger Logger = LogManager.CreateLogger();
|
public static readonly Logger Logger = LogManager.CreateLogger();
|
||||||
public float TotalDamage;
|
public float TotalDamage { get; set; }
|
||||||
public DamageType DominantDamageType;
|
public DamageType DominantDamageType { get; set; }
|
||||||
public Dictionary<DamageType, float> ElementDamages;
|
public Dictionary<DamageType, float> ElementDamages { get; set; }
|
||||||
public bool IsCriticalHit;
|
public bool IsCriticalHit { get; set; }
|
||||||
public bool IsDodged;
|
public bool IsDodged { get; set; }
|
||||||
public bool IsWeaponDamage;
|
public bool IsWeaponDamage { get; set; }
|
||||||
|
|
||||||
public bool Successful = false;
|
public bool Successful { get; set; }
|
||||||
public bool Blocked = false;
|
public bool Blocked { get; set; }
|
||||||
|
|
||||||
public bool AutomaticHitEffects = true;
|
public bool AutomaticHitEffects = true;
|
||||||
public Action<DeathPayload> OnDeath = null;
|
public Action<DeathPayload> OnDeath = null;
|
||||||
|
|
||||||
private bool WaitTo(TickTimer timer)
|
private bool WaitTo(TickTimer timer)
|
||||||
{
|
{
|
||||||
while (timer.TimedOut != true)
|
while (timer.TimedOut != true) ;
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +141,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
if (criticalHit)
|
if (criticalHit)
|
||||||
{
|
{
|
||||||
TotalDamage *= (1f + Context.User.Attributes[GameAttribute.Crit_Damage_Percent]);
|
TotalDamage *= (1f + Context.User.Attributes[GameAttribute.Crit_Damage_Percent]);
|
||||||
if (Context.User is Player && (Context.User as Player).Toon.Class == ToonClass.Wizard && Context.User.Attributes[GameAttribute.Resource_On_Crit, 1] > 0)
|
if (Context.User is Player player && player.Toon.Class == ToonClass.Wizard && player.Attributes[GameAttribute.Resource_On_Crit, 1] > 0)
|
||||||
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
||||||
(Context.User as Player).GeneratePrimaryResource(Context.User.Attributes[GameAttribute.Resource_On_Crit, 1]);
|
(Context.User as Player).GeneratePrimaryResource(Context.User.Attributes[GameAttribute.Resource_On_Crit, 1]);
|
||||||
}
|
}
|
||||||
@ -170,10 +167,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
|
|
||||||
switch (Context.User)
|
switch (Context.User)
|
||||||
{
|
{
|
||||||
case Player:
|
case Player plr:
|
||||||
if (IsWeaponDamage)
|
if (IsWeaponDamage)
|
||||||
{
|
{
|
||||||
var plr = Context.User as Player;
|
|
||||||
TotalDamage = TotalDamage * (1 + (plr.PrimaryAttribute / 100f));
|
TotalDamage = TotalDamage * (1 + (plr.PrimaryAttribute / 100f));
|
||||||
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
||||||
plr.GeneratePrimaryResource(plr.Attributes[GameAttribute.Resource_On_Hit]);
|
plr.GeneratePrimaryResource(plr.Attributes[GameAttribute.Resource_On_Hit]);
|
||||||
@ -224,7 +220,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
||||||
plr.GenerateSecondaryResource(1f);
|
plr.GenerateSecondaryResource(1f);
|
||||||
|
|
||||||
if (plr.SkillSet.HasPassive(155721) && Target.Attributes[GameAttribute.Slow] == true)
|
if (plr.SkillSet.HasPassive(155721) && Target.Attributes[GameAttribute.Slow])
|
||||||
TotalDamage *= 1.20f;
|
TotalDamage *= 1.20f;
|
||||||
|
|
||||||
if (plr.SkillSet.HasPassive(155725))
|
if (plr.SkillSet.HasPassive(155725))
|
||||||
@ -239,12 +235,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
|
|
||||||
if (criticalHit)
|
if (criticalHit)
|
||||||
{
|
{
|
||||||
plr.AddTimedAction(1f, new Action<int>((q) => plr.World.BuffManager.RemoveBuffs(plr, 155715)));
|
plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 155715));
|
||||||
plr.AddTimedAction(2f, new Action<int>((q) =>
|
plr.AddTimedAction(2f, _ =>
|
||||||
{
|
{
|
||||||
if (plr.SkillSet.HasPassive(155715))
|
if (plr.SkillSet.HasPassive(155715))
|
||||||
plr.World.BuffManager.AddBuff(plr, plr, new SharpshooterBuff());
|
plr.World.BuffManager.AddBuff(plr, plr, new SharpshooterBuff());
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ToonClass.Wizard:
|
case ToonClass.Wizard:
|
||||||
@ -373,17 +369,17 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
if (plr.World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(plr)) //AkaratChampion -> Rally
|
if (plr.World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(plr)) //AkaratChampion -> Rally
|
||||||
if (plr.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(plr).CDRActive)
|
if (plr.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(plr).CDRActive)
|
||||||
if (FastRandom.Instance.NextDouble() < 0.5f * Context.GetProcCoefficient())
|
if (FastRandom.Instance.NextDouble() < 0.5f * Context.GetProcCoefficient())
|
||||||
foreach (var cdBuff in plr.World.BuffManager.GetBuffs<CooldownBuff>(plr))
|
foreach (var cooldownBuff in plr.World.BuffManager.GetBuffs<CooldownBuff>(plr))
|
||||||
if (!(cdBuff.TargetPowerSNO == 269032)) //do not CDR AkaratChampionBuff
|
if (cooldownBuff.TargetPowerSNO != 269032) //do not CDR AkaratChampionBuff
|
||||||
cdBuff.Reduce(60);
|
cooldownBuff.Reduce(60);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Target is Monster)
|
if (Target is Monster monster)
|
||||||
{
|
{
|
||||||
TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Monster_Type, (Target as Monster).MonsterType];
|
TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Monster_Type, monster.MonsterType];
|
||||||
|
|
||||||
if ((Target as Monster).Quality > 0)
|
if (monster.Quality > 0)
|
||||||
TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Elites];
|
TotalDamage *= 1 + plr.Attributes[GameAttribute.Damage_Percent_Bonus_Vs_Elites];
|
||||||
|
|
||||||
if (attackPayload.Targets.Actors.Count == 1 && !(attackPayload.Context is Buff) && attackPayload.AutomaticHitEffects)
|
if (attackPayload.Targets.Actors.Count == 1 && !(attackPayload.Context is Buff) && attackPayload.AutomaticHitEffects)
|
||||||
@ -391,40 +387,37 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
float procCoeff = Context.GetProcCoefficient();
|
float procCoeff = Context.GetProcCoefficient();
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Fear_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Fear_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffFeared(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffFeared(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Stun_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Stun_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffStunned(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffStunned(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Blind_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Blind_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffBlind(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffBlind(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Freeze_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Freeze_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffFrozen(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffFrozen(TickTimer.WaitSeconds(plr.World.Game, 1.5f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Chill_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Chill_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffChilled(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffChilled(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Slow_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Slow_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new DebuffSlowed(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f)));
|
plr.World.BuffManager.AddBuff(plr, monster, new DebuffSlowed(0.3f, TickTimer.WaitSeconds(plr.World.Game, 2f)));
|
||||||
|
|
||||||
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Knockback_Proc_Chance] * procCoeff)
|
if (FastRandom.Instance.NextDouble() < plr.Attributes[GameAttribute.On_Hit_Knockback_Proc_Chance] * procCoeff)
|
||||||
plr.World.BuffManager.AddBuff(plr, Target, new KnockbackBuff(3f));
|
plr.World.BuffManager.AddBuff(plr, monster, new KnockbackBuff(3f));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Minion:
|
case Minion mn:
|
||||||
var mn = Context.User as Minion;
|
|
||||||
TotalDamage *= (1 + (mn.PrimaryAttribute / 100f));
|
TotalDamage *= (1 + (mn.PrimaryAttribute / 100f));
|
||||||
TotalDamage *= mn.Master.Attributes[GameAttribute.Attacks_Per_Second_Total];
|
TotalDamage *= mn.Master.Attributes[GameAttribute.Attacks_Per_Second_Total];
|
||||||
|
|
||||||
if (mn.Master is Player)
|
if (mn.Master is Player mstr)
|
||||||
{
|
{
|
||||||
var mstr = mn.Master as Player;
|
if (mstr.SkillSet.HasPassive(209041) && mn is CorpseSpider or CorpseSpiderQueen)
|
||||||
|
|
||||||
if (mstr.SkillSet.HasPassive(209041) && (mn is CorpseSpider || mn is CorpseSpiderQueen))
|
|
||||||
mstr.World.BuffManager.AddBuff(mstr, mstr, new VisionQuestBuff());
|
mstr.World.BuffManager.AddBuff(mstr, mstr, new VisionQuestBuff());
|
||||||
|
|
||||||
if (mn.SNO == ActorSno._dh_companion_spider)
|
if (mn.SNO == ActorSno._dh_companion_spider)
|
||||||
@ -438,137 +431,149 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (Target is Player playerTarget) //check for passives here (incoming damage)
|
switch (Target)
|
||||||
{
|
{
|
||||||
if (!playerTarget.Attributes[GameAttribute.Cannot_Dodge] && FastRandom.Instance.NextDouble() < playerTarget.DodgeChance)
|
//check for passives here (incoming damage)
|
||||||
IsDodged = true;
|
case Player playerTarget:
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.Monk) //Monk defensive passives
|
|
||||||
{
|
{
|
||||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
if (!playerTarget.Attributes[GameAttribute.Cannot_Dodge] && FastRandom.Instance.NextDouble() < playerTarget.DodgeChance)
|
||||||
|
IsDodged = true;
|
||||||
|
|
||||||
if (playerTarget.World.BuffManager.HasBuff<TempestRush.TempestEffect>(playerTarget)) //Tempest rush -> Slipstream
|
switch (playerTarget.Toon.Class)
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<TempestRush.TempestEffect>(playerTarget)._slipStream)
|
|
||||||
TotalDamage *= 0.8f;
|
|
||||||
|
|
||||||
if (playerTarget.World.BuffManager.HasBuff<Epiphany.EpiphanyBuff>(playerTarget)) //Epiphany -> Desert Shroud
|
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<Epiphany.EpiphanyBuff>(playerTarget).DesertShroud)
|
|
||||||
TotalDamage *= 0.5f;
|
|
||||||
|
|
||||||
if (IsDodged) //Mantra of Evasion -> Backlash
|
|
||||||
if (playerTarget.World.BuffManager.HasBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget))
|
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget).Backlash)
|
|
||||||
playerTarget.World.BuffManager.GetFirstBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget).BacklashTrigger = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.Barbarian) //Barb defensive passives
|
|
||||||
{
|
|
||||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
|
||||||
|
|
||||||
if (playerTarget.SkillSet.HasPassive(205491) && PowerMath.Distance2D(Context.User.Position, playerTarget.Position) > 6f) //Superstition (barbarian)
|
|
||||||
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
|
||||||
playerTarget.GeneratePrimaryResource(2f);
|
|
||||||
|
|
||||||
if (playerTarget.SkillSet.HasPassive(205398) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) < (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.2f)) //Relentless (barbarian)
|
|
||||||
TotalDamage *= 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.Wizard) //Wizard defensive passives
|
|
||||||
{
|
|
||||||
if (playerTarget.SkillSet.HasPassive(208471)) //GlassCannon (Wizard)
|
|
||||||
TotalDamage *= 1.1f;
|
|
||||||
|
|
||||||
if (playerTarget.SkillSet.HasPassive(208547) && TotalDamage > (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.15f)) //Illusionist (Wizard)
|
|
||||||
{
|
{
|
||||||
foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs<CooldownBuff>(playerTarget))
|
//Monk defensive passives
|
||||||
if (cdBuff.TargetPowerSNO == 1769 || cdBuff.TargetPowerSNO == 168344)
|
case ToonClass.Monk:
|
||||||
cdBuff.Remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerTarget.SkillSet.HasPassive(208474) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) //UnstableAnomaly (wizard)
|
|
||||||
{
|
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<UnstableAnomalyCooldownBuff>(playerTarget) == null)
|
|
||||||
{
|
{
|
||||||
playerTarget.AddPercentageHP(45);
|
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||||
playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new UnstableAnomalyCooldownBuff());
|
|
||||||
playerTarget.World.PowerManager.RunPower(playerTarget, 30796);
|
if (playerTarget.World.BuffManager.HasBuff<TempestRush.TempestEffect>(playerTarget)) //Tempest rush -> Slipstream
|
||||||
playerTarget.GenerateSecondaryResource(25f);
|
if (playerTarget.World.BuffManager.GetFirstBuff<TempestRush.TempestEffect>(playerTarget)._slipStream)
|
||||||
foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs<CooldownBuff>(playerTarget))
|
TotalDamage *= 0.8f;
|
||||||
if (cdBuff.TargetPowerSNO == 30796)
|
|
||||||
cdBuff.Remove();
|
if (playerTarget.World.BuffManager.HasBuff<Epiphany.EpiphanyBuff>(playerTarget)) //Epiphany -> Desert Shroud
|
||||||
|
if (playerTarget.World.BuffManager.GetFirstBuff<Epiphany.EpiphanyBuff>(playerTarget).DesertShroud)
|
||||||
|
TotalDamage *= 0.5f;
|
||||||
|
|
||||||
|
if (IsDodged) //Mantra of Evasion -> Backlash
|
||||||
|
if (playerTarget.World.BuffManager.HasBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget))
|
||||||
|
if (playerTarget.World.BuffManager.GetFirstBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget).Backlash)
|
||||||
|
playerTarget.World.BuffManager.GetFirstBuff<MantraOfEvasionPassive.MantraOfEvasionBuff>(playerTarget).BacklashTrigger = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
//Barb defensive passives
|
||||||
}
|
case ToonClass.Barbarian:
|
||||||
|
{
|
||||||
|
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.WitchDoctor) //Witch Doctor defensive passives
|
if (playerTarget.SkillSet.HasPassive(205491) && PowerMath.Distance2D(Context.User.Position, playerTarget.Position) > 6f) //Superstition (barbarian)
|
||||||
{
|
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
||||||
if (playerTarget.SkillSet.HasPassive(217968)) //JungleFortitude (WD)
|
playerTarget.GeneratePrimaryResource(2f);
|
||||||
TotalDamage *= 0.85f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.DemonHunter) //DH defensive passives
|
if (playerTarget.SkillSet.HasPassive(205398) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) < (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.2f)) //Relentless (barbarian)
|
||||||
{
|
TotalDamage *= 0.5f;
|
||||||
if (playerTarget.SkillSet.HasPassive(210801) && playerTarget.World.BuffManager.GetFirstBuff<BroodingCooldownBuff>(playerTarget) == null) //Brooding (DH)
|
break;
|
||||||
playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new BroodingCooldownBuff());
|
}
|
||||||
}
|
//Wizard defensive passives
|
||||||
|
case ToonClass.Wizard:
|
||||||
|
{
|
||||||
|
if (playerTarget.SkillSet.HasPassive(208471)) //GlassCannon (Wizard)
|
||||||
|
TotalDamage *= 1.1f;
|
||||||
|
|
||||||
if (playerTarget.Toon.Class == ToonClass.Crusader) //Crusader defensive passives
|
if (playerTarget.SkillSet.HasPassive(208547) && TotalDamage > (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.15f)) //Illusionist (Wizard)
|
||||||
{
|
|
||||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
|
||||||
|
|
||||||
if (playerTarget.SkillSet.HasPassive(310626)) //Vigilant
|
|
||||||
if (DominantDamageType != DamageType.Physical)
|
|
||||||
TotalDamage *= 0.95f;
|
|
||||||
|
|
||||||
if (playerTarget.World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget)) //AkaratChampion resurrect once
|
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget).resurrectActive)
|
|
||||||
if ((playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0)
|
|
||||||
{
|
{
|
||||||
playerTarget.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget).resurrectActive = false;
|
foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs<CooldownBuff>(playerTarget))
|
||||||
playerTarget.AddPercentageHP(100);
|
if (cdBuff.TargetPowerSNO == 1769 || cdBuff.TargetPowerSNO == 168344)
|
||||||
|
cdBuff.Remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playerTarget.World.BuffManager.HasBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget)) //Protect the Innocent
|
if (playerTarget.SkillSet.HasPassive(208474) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0) //UnstableAnomaly (wizard)
|
||||||
if (!playerTarget.World.BuffManager.GetFirstBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget).Primary)
|
{
|
||||||
if (playerTarget.World.BuffManager.GetFirstBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget).Redirect)
|
if (playerTarget.World.BuffManager.GetFirstBuff<UnstableAnomalyCooldownBuff>(playerTarget) == null)
|
||||||
TotalDamage *= 0.8f;
|
{
|
||||||
|
playerTarget.AddPercentageHP(45);
|
||||||
|
playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new UnstableAnomalyCooldownBuff());
|
||||||
|
playerTarget.World.PowerManager.RunPower(playerTarget, 30796);
|
||||||
|
playerTarget.GenerateSecondaryResource(25f);
|
||||||
|
foreach (var cdBuff in playerTarget.World.BuffManager.GetBuffs<CooldownBuff>(playerTarget))
|
||||||
|
if (cdBuff.TargetPowerSNO == 30796)
|
||||||
|
cdBuff.Remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Witch Doctor defensive passives
|
||||||
|
case ToonClass.WitchDoctor:
|
||||||
|
{
|
||||||
|
if (playerTarget.SkillSet.HasPassive(217968)) //JungleFortitude (WD)
|
||||||
|
TotalDamage *= 0.85f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//DH defensive passives
|
||||||
|
case ToonClass.DemonHunter:
|
||||||
|
{
|
||||||
|
if (playerTarget.SkillSet.HasPassive(210801) && playerTarget.World.BuffManager.GetFirstBuff<BroodingCooldownBuff>(playerTarget) == null) //Brooding (DH)
|
||||||
|
playerTarget.World.BuffManager.AddBuff(playerTarget, playerTarget, new BroodingCooldownBuff());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Crusader defensive passives
|
||||||
|
case ToonClass.Crusader:
|
||||||
|
{
|
||||||
|
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||||
|
|
||||||
|
if (playerTarget.SkillSet.HasPassive(310626)) //Vigilant
|
||||||
|
if (DominantDamageType != DamageType.Physical)
|
||||||
|
TotalDamage *= 0.95f;
|
||||||
|
|
||||||
|
if (playerTarget.World.BuffManager.HasBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget)) //AkaratChampion resurrect once
|
||||||
|
if (playerTarget.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget).resurrectActive)
|
||||||
|
if ((playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) <= 0)
|
||||||
|
{
|
||||||
|
playerTarget.World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(playerTarget).resurrectActive = false;
|
||||||
|
playerTarget.AddPercentageHP(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playerTarget.World.BuffManager.HasBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget)) //Protect the Innocent
|
||||||
|
if (!playerTarget.World.BuffManager.GetFirstBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget).Primary)
|
||||||
|
if (playerTarget.World.BuffManager.GetFirstBuff<CrusaderLawsOfJustice.LawsResBuff>(playerTarget).Redirect)
|
||||||
|
TotalDamage *= 0.8f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TotalDamage *= 0.1f;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
//check for passives here (incoming damage, minions)
|
||||||
|
case Minion { Master: Player playerOwner }:
|
||||||
|
{
|
||||||
|
var plr = playerOwner;
|
||||||
|
|
||||||
TotalDamage *= 0.1f;
|
var masterArmor = plr.Attributes[GameAttribute.Armor_Total];
|
||||||
}
|
var attackLevel = attackPayload.Context.User.Attributes[GameAttribute.Level];
|
||||||
else if (Target is Minion { Master: Player playerOwner }) //check for passives here (incoming damage, minions)
|
|
||||||
{
|
|
||||||
var plr = playerOwner;
|
|
||||||
|
|
||||||
var masterArmor = plr.Attributes[GameAttribute.Armor_Total];
|
TotalDamage *= ReductionFromArmor(masterArmor, attackLevel);
|
||||||
var attackLevel = attackPayload.Context.User.Attributes[GameAttribute.Level];
|
|
||||||
|
|
||||||
TotalDamage *= ReductionFromArmor(masterArmor, attackLevel);
|
if (plr.SkillSet.HasPassive(217968)) //JungleFortitude (WD)
|
||||||
|
TotalDamage *= 0.85f;
|
||||||
|
|
||||||
if (plr.SkillSet.HasPassive(217968)) //JungleFortitude (WD)
|
TotalDamage *= 0.1f; //hack for unkillable minions
|
||||||
TotalDamage *= 0.85f;
|
break;
|
||||||
|
}
|
||||||
TotalDamage *= 0.1f; //hack for unkillable minions
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float ReductionFromResistance(float resistance, int attackerLevel)
|
private static float ReductionFromResistance(float resistance, int attackerLevel) => 1f - (resistance / ((5 * attackerLevel) + resistance));
|
||||||
{
|
|
||||||
return 1f - (resistance / ((5 * attackerLevel) + resistance));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float ReductionFromArmor(float armor, int attackerLevel)
|
private static float ReductionFromArmor(float armor, int attackerLevel) => 1f - (armor / ((50 * attackerLevel) + armor));
|
||||||
{
|
|
||||||
return 1f - (armor / ((50 * attackerLevel) + armor));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckItemProcs(Player user)
|
private void CheckItemProcs(Player user)
|
||||||
{
|
{
|
||||||
if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 247724] - 1) < 0.001 && FastRandom.Instance.NextDouble() < 0.2)
|
if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 247724] - 1) < Globals.FLOAT_TOLERANCE && FastRandom.Instance.NextDouble() < 0.2)
|
||||||
{
|
{
|
||||||
user.PlayEffectGroup(247770);
|
user.PlayEffectGroup(247770);
|
||||||
}
|
}
|
||||||
if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 245741] - 1) < 0.001 && FastRandom.Instance.NextDouble() < 0.2)
|
if (Math.Abs(user.Attributes[GameAttribute.Item_Power_Passive, 245741] - 1) < Globals.FLOAT_TOLERANCE && FastRandom.Instance.NextDouble() < 0.2)
|
||||||
{
|
{
|
||||||
user.PlayEffectGroup(245747);
|
user.PlayEffectGroup(245747);
|
||||||
}
|
}
|
||||||
@ -625,12 +630,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
|
|
||||||
else if (plr.Toon.Class == ToonClass.DemonHunter) //Awareness
|
else if (plr.Toon.Class == ToonClass.DemonHunter) //Awareness
|
||||||
{
|
{
|
||||||
plr.AddTimedAction(1f, new Action<int>((q) => plr.World.BuffManager.RemoveBuffs(plr, 324770)));
|
plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 324770));
|
||||||
plr.AddTimedAction(2f, new Action<int>((q) =>
|
plr.AddTimedAction(2f, _ =>
|
||||||
{
|
{
|
||||||
if (plr.SkillSet.HasPassive(324770))
|
if (plr.SkillSet.HasPassive(324770))
|
||||||
plr.World.BuffManager.AddBuff(plr, plr, new AwarenessBuff());
|
plr.World.BuffManager.AddBuff(plr, plr, new AwarenessBuff());
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -675,12 +680,11 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Target.World != null)
|
Target.World?.BuffManager?.SendTargetPayload(Target, this);
|
||||||
Target.World.BuffManager.SendTargetPayload(Target, this);
|
|
||||||
if (Context.User != null)
|
if (Context.User != null)
|
||||||
Target.World.BuffManager.SendTargetPayload(Context.User, this);
|
Target.World?.BuffManager?.SendTargetPayload(Context.User, this);
|
||||||
|
|
||||||
if (Target == null || Target.World == null) return; //in case Target was killed in OnPayload
|
if (Target?.World == null) return; //in case Target was killed in OnPayload
|
||||||
|
|
||||||
if (Context.User is Player player)
|
if (Context.User is Player player)
|
||||||
{
|
{
|
||||||
@ -702,20 +706,18 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
if (hireling.Attributes[GameAttribute.Hitpoints_On_Hit] > 0)
|
if (hireling.Attributes[GameAttribute.Hitpoints_On_Hit] > 0)
|
||||||
hireling.AddHP(hireling.Attributes[GameAttribute.Hitpoints_On_Hit]);
|
hireling.AddHP(hireling.Attributes[GameAttribute.Hitpoints_On_Hit]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// floating damage number
|
// make player damage red, all other damage white
|
||||||
if (Target.World != null)
|
var type = Target is Player ?
|
||||||
|
IsCriticalHit ? FloatingNumberMessage.FloatType.RedCritical : FloatingNumberMessage.FloatType.Red :
|
||||||
|
IsCriticalHit ? FloatingNumberMessage.FloatType.Golden : FloatingNumberMessage.FloatType.White;
|
||||||
|
if (Target.World is { } world)
|
||||||
{
|
{
|
||||||
Target.World.BroadcastIfRevealed(plr => new FloatingNumberMessage
|
world.BroadcastIfRevealed(plr => new FloatingNumberMessage
|
||||||
{
|
{
|
||||||
ActorID = Target.DynamicID(plr),
|
ActorID = Target.DynamicID(plr),
|
||||||
Number = TotalDamage,
|
Number = TotalDamage,
|
||||||
// make player damage red, all other damage white
|
Type = type
|
||||||
Type = IsCriticalHit ?
|
|
||||||
(Target is Player) ? FloatingNumberMessage.FloatType.RedCritical : FloatingNumberMessage.FloatType.Golden
|
|
||||||
:
|
|
||||||
(Target is Player) ? FloatingNumberMessage.FloatType.Red : FloatingNumberMessage.FloatType.White
|
|
||||||
}, Target);
|
}, Target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,15 +739,15 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
{
|
{
|
||||||
// play override hitsound if any, otherwise just default to playing metal weapon hit for now
|
// play override hitsound if any, otherwise just default to playing metal weapon hit for now
|
||||||
int overridenSound = Context.EvalTag(PowerKeys.HitsoundOverride);
|
int overridenSound = Context.EvalTag(PowerKeys.HitsoundOverride);
|
||||||
int hitsound = overridenSound != -1 ? overridenSound : 1;
|
int hitSound = overridenSound != -1 ? overridenSound : 1;
|
||||||
if (hitsound > 0)
|
if (hitSound > 0)
|
||||||
Target.PlayEffect(Effect.Hit, hitsound);
|
Target.PlayEffect(Effect.Hit, hitSound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update hp
|
// update hp
|
||||||
float new_hp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f);
|
float newHp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f);
|
||||||
Target.Attributes[GameAttribute.Hitpoints_Cur] = new_hp;
|
Target.Attributes[GameAttribute.Hitpoints_Cur] = newHp;
|
||||||
Target.Attributes.BroadcastChangedIfRevealed();
|
Target.Attributes.BroadcastChangedIfRevealed();
|
||||||
|
|
||||||
//thorns
|
//thorns
|
||||||
@ -766,21 +768,23 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// if hp=0 do death
|
// if hp=0 do death
|
||||||
if (new_hp <= 0f)
|
if (newHp <= 0f)
|
||||||
{
|
{
|
||||||
var deathload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot);
|
var deathPayload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot)
|
||||||
deathload.AutomaticHitEffects = AutomaticHitEffects;
|
{
|
||||||
|
AutomaticHitEffects = AutomaticHitEffects
|
||||||
|
};
|
||||||
|
|
||||||
if (deathload.Successful)
|
if (deathPayload.Successful)
|
||||||
{
|
{
|
||||||
Target.Dead = true;
|
Target.Dead = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (OnDeath != null && AutomaticHitEffects)
|
if (OnDeath != null && AutomaticHitEffects)
|
||||||
OnDeath(deathload);
|
OnDeath(deathPayload);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
deathload.Apply();
|
deathPayload.Apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (AutomaticHitEffects && Target.World != null && Target is not Player)
|
else if (AutomaticHitEffects && Target.World != null && Target is not Player)
|
||||||
@ -800,13 +804,13 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
|||||||
{
|
{
|
||||||
if (Target.IsRevealedToPlayer(plr))
|
if (Target.IsRevealedToPlayer(plr))
|
||||||
{
|
{
|
||||||
float BackSpeed = Target.WalkSpeed;
|
float backSpeed = Target.WalkSpeed;
|
||||||
Target.WalkSpeed = 0f;
|
Target.WalkSpeed = 0f;
|
||||||
TickTimer Timeout = new SecondsTickTimer(Target.World.Game, 0.3f);
|
TickTimer timeout = new SecondsTickTimer(Target.World.Game, 0.3f);
|
||||||
var Boom = Task<bool>.Factory.StartNew(() => WaitTo(Timeout));
|
var boom = Task<bool>.Factory.StartNew(() => WaitTo(timeout));
|
||||||
Boom.ContinueWith(delegate
|
boom.ContinueWith(_ =>
|
||||||
{
|
{
|
||||||
Target.WalkSpeed = BackSpeed;
|
Target.WalkSpeed = backSpeed;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,20 +178,17 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem
|
|||||||
|
|
||||||
public EffectActor SpawnEffect(ActorSno actorSNO, Vector3D position, float angle = 0, TickTimer timeout = null)
|
public EffectActor SpawnEffect(ActorSno actorSNO, Vector3D position, float angle = 0, TickTimer timeout = null)
|
||||||
{
|
{
|
||||||
if (Math.Abs(angle - (-1)) < 0.0001)
|
if (Math.Abs(angle - -1) < Globals.FLOAT_TOLERANCE)
|
||||||
angle = (float)(Rand.NextDouble() * (Math.PI * 2));
|
angle = (float)(Rand.NextDouble() * (Math.PI * 2));
|
||||||
if (timeout == null)
|
if (timeout == null)
|
||||||
{
|
{
|
||||||
if (_defaultEffectTimeout == null)
|
_defaultEffectTimeout ??= new SecondsTickTimer(World.Game, 2f);
|
||||||
_defaultEffectTimeout = new SecondsTickTimer(World.Game, 2f); // default timeout of 2 seconds for now
|
|
||||||
|
|
||||||
timeout = _defaultEffectTimeout;
|
timeout = _defaultEffectTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor = new EffectActor(this, actorSNO, position);
|
var actor = new EffectActor(this, actorSNO, position);
|
||||||
actor.Timeout = timeout;
|
actor.Timeout = timeout;
|
||||||
actor.Spawn(angle);
|
actor.Spawn(angle);
|
||||||
//187359
|
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,35 +11,54 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
|||||||
{
|
{
|
||||||
public class SkillSet
|
public class SkillSet
|
||||||
{
|
{
|
||||||
public ToonClass @Class;
|
public ToonClass ToonClass { get; }
|
||||||
public Toon Toon { get; private set; }
|
public Toon Toon { get; }
|
||||||
public Player Player { get; private set; }
|
public Player Player { get; }
|
||||||
|
|
||||||
public ActiveSkillSavedData[] ActiveSkills;
|
public ActiveSkillSavedData[] ActiveSkills { get; }
|
||||||
public HotbarButtonData[] HotBarSkills;
|
public HotbarButtonData[] HotBarSkills { get; }
|
||||||
public int[] PassiveSkills;
|
public int[] PassiveSkills { get; }
|
||||||
|
|
||||||
protected static readonly Logger Logger = LogManager.CreateLogger();
|
protected static readonly Logger Logger = LogManager.CreateLogger();
|
||||||
|
|
||||||
public SkillSet(Player player, ToonClass @class, Toon toon)
|
public SkillSet(Player player, ToonClass toonClass, Toon toon)
|
||||||
{
|
{
|
||||||
@Class = @class;
|
ToonClass = toonClass;
|
||||||
Player = player;
|
Player = player;
|
||||||
var dbToon = player.Toon.DBToon;
|
// var dbToon = player.Toon.DBToon;
|
||||||
var dbActiveSkills = player.Toon.DBActiveSkills;
|
var dbActiveSkills = player.Toon.DBActiveSkills;
|
||||||
ActiveSkills = new ActiveSkillSavedData[6] {
|
ActiveSkills = new ActiveSkillSavedData[6]
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill0,
|
{
|
||||||
snoRune = dbActiveSkills.Rune0 },
|
new()
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill1,
|
{
|
||||||
snoRune = dbActiveSkills.Rune1 },
|
snoSkill = dbActiveSkills.Skill0,
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill2,
|
snoRune = dbActiveSkills.Rune0
|
||||||
snoRune = dbActiveSkills.Rune2 },
|
},
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill3,
|
new()
|
||||||
snoRune = dbActiveSkills.Rune3 },
|
{
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill4,
|
snoSkill = dbActiveSkills.Skill1,
|
||||||
snoRune = dbActiveSkills.Rune4 },
|
snoRune = dbActiveSkills.Rune1
|
||||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill5,
|
},
|
||||||
snoRune = dbActiveSkills.Rune5 },
|
new()
|
||||||
|
{
|
||||||
|
snoSkill = dbActiveSkills.Skill2,
|
||||||
|
snoRune = dbActiveSkills.Rune2
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
snoSkill = dbActiveSkills.Skill3,
|
||||||
|
snoRune = dbActiveSkills.Rune3
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
snoSkill = dbActiveSkills.Skill4,
|
||||||
|
snoRune = dbActiveSkills.Rune4
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
snoSkill = dbActiveSkills.Skill5,
|
||||||
|
snoRune = dbActiveSkills.Rune5
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
PassiveSkills = new int[4] {
|
PassiveSkills = new int[4] {
|
||||||
@ -51,18 +70,18 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
HotBarSkills = new HotbarButtonData[6] {
|
HotBarSkills = new HotbarButtonData[6] {
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[0].snoSkill, ItemAnn = ActiveSkills[0].snoRune, ItemGBId = -1, RuneType = -1 }, // left-click
|
new() { SNOSkill = ActiveSkills[0].snoSkill, ItemAnn = ActiveSkills[0].snoRune, ItemGBId = -1, RuneType = -1 }, // left-click
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[1].snoSkill, ItemAnn = ActiveSkills[1].snoRune, ItemGBId = -1, RuneType = -1 }, // right-click
|
new() { SNOSkill = ActiveSkills[1].snoSkill, ItemAnn = ActiveSkills[1].snoRune, ItemGBId = -1, RuneType = -1 }, // right-click
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[2].snoSkill, ItemAnn = ActiveSkills[2].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-1
|
new() { SNOSkill = ActiveSkills[2].snoSkill, ItemAnn = ActiveSkills[2].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-1
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[3].snoSkill, ItemAnn = ActiveSkills[3].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-2
|
new() { SNOSkill = ActiveSkills[3].snoSkill, ItemAnn = ActiveSkills[3].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-2
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[4].snoSkill, ItemAnn = ActiveSkills[4].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-3
|
new() { SNOSkill = ActiveSkills[4].snoSkill, ItemAnn = ActiveSkills[4].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-3
|
||||||
new HotbarButtonData { SNOSkill = ActiveSkills[5].snoSkill, ItemAnn = ActiveSkills[5].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-4
|
new() { SNOSkill = ActiveSkills[5].snoSkill, ItemAnn = ActiveSkills[5].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-4
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSkills(int hotBarIndex, int SNOSkill, int SNORune, Toon toon)
|
public void UpdateSkills(int hotBarIndex, int SNOSkill, int SNORune, Toon toon)
|
||||||
{
|
{
|
||||||
Logger.Debug("Update index {0} skill {1} rune {2}", hotBarIndex, SNOSkill, SNORune);
|
Logger.MethodTrace(string.Format("Update index {0} skill {1} rune {2}", hotBarIndex, SNOSkill, SNORune));
|
||||||
var dbActiveSkills = Player.Toon.DBActiveSkills;
|
var dbActiveSkills = Player.Toon.DBActiveSkills;
|
||||||
switch (hotBarIndex)
|
switch (hotBarIndex)
|
||||||
{
|
{
|
||||||
@ -119,31 +138,12 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasPassive(int passiveId)
|
public bool HasPassive(int passiveId) => PassiveSkills.Contains(passiveId);
|
||||||
{
|
|
||||||
if (PassiveSkills.Contains(passiveId))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasSkill(int skillId)
|
public bool HasSkill(int skillId) => ActiveSkills.Any(s => s.snoSkill == skillId);
|
||||||
{
|
|
||||||
return ActiveSkills.Any(s => s.snoSkill == skillId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasSkillWithRune(int skillId, int runeId)
|
public bool HasSkillWithRune(int skillId, int runeId) => ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId);
|
||||||
{
|
|
||||||
return ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId);
|
public bool HasItemPassiveProc(int passiveId) => (float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId];
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool HasItemPassiveProc(int passiveId)
|
|
||||||
{
|
|
||||||
if ((float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId])
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,14 @@ namespace DiIiS_NA.GameServer
|
|||||||
get => GetBoolean(nameof(CoreActive), true);
|
get => GetBoolean(nameof(CoreActive), true);
|
||||||
set => Set(nameof(CoreActive), value);
|
set => Set(nameof(CoreActive), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IWServer
|
||||||
|
{
|
||||||
|
get => GetBoolean(nameof(IWServer), true);
|
||||||
|
set => Set(nameof(IWServer), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Game Mods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rate of experience gain.
|
/// Rate of experience gain.
|
||||||
@ -100,12 +108,6 @@ namespace DiIiS_NA.GameServer
|
|||||||
get => GetFloat(nameof(RateMonsterDMG), 1);
|
get => GetFloat(nameof(RateMonsterDMG), 1);
|
||||||
set => Set(nameof(RateMonsterDMG), value);
|
set => Set(nameof(RateMonsterDMG), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IWServer
|
|
||||||
{
|
|
||||||
get => GetBoolean(nameof(IWServer), true);
|
|
||||||
set => Set(nameof(IWServer), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Percentage that a unique, legendary, set or special item created is unidentified
|
/// Percentage that a unique, legendary, set or special item created is unidentified
|
||||||
@ -196,7 +198,80 @@ namespace DiIiS_NA.GameServer
|
|||||||
get => GetBoolean(nameof(UnlockAllWaypoints), false);
|
get => GetBoolean(nameof(UnlockAllWaypoints), false);
|
||||||
set => Set(nameof(UnlockAllWaypoints), value);
|
set => Set(nameof(UnlockAllWaypoints), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Strength multiplier when you're not a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float StrengthMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(StrengthMultiplier), 1f);
|
||||||
|
set => Set(nameof(StrengthMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Strength multiplier when you're a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float StrengthParagonMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(StrengthParagonMultiplier), 1f);
|
||||||
|
set => Set(nameof(StrengthParagonMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dexterity multiplier when you're not a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float DexterityMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(DexterityMultiplier), 1f);
|
||||||
|
set => Set(nameof(DexterityMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dexterity multiplier when you're a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float DexterityParagonMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(DexterityParagonMultiplier), 1f);
|
||||||
|
set => Set(nameof(DexterityParagonMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intelligence multiplier when you're not a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float IntelligenceMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(IntelligenceMultiplier), 1f);
|
||||||
|
set => Set(nameof(IntelligenceMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intelligence multiplier when you're a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float IntelligenceParagonMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(IntelligenceParagonMultiplier), 1f);
|
||||||
|
set => Set(nameof(IntelligenceParagonMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vitality multiplier when you're not a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float VitalityMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(VitalityMultiplier), 1f);
|
||||||
|
set => Set(nameof(VitalityMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vitality multiplier when you're a paragon.
|
||||||
|
/// </summary>
|
||||||
|
public float VitalityParagonMultiplier
|
||||||
|
{
|
||||||
|
get => GetFloat(nameof(VitalityParagonMultiplier), 1f);
|
||||||
|
set => Set(nameof(VitalityParagonMultiplier), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
public static GameServerConfig Instance { get; } = new();
|
public static GameServerConfig Instance { get; } = new();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,8 @@ using System.Configuration;
|
|||||||
|
|
||||||
namespace DiIiS_NA
|
namespace DiIiS_NA
|
||||||
{
|
{
|
||||||
public static class Extensions
|
internal static class Globals
|
||||||
{
|
{
|
||||||
|
public const float FLOAT_TOLERANCE = 0.0001f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +30,8 @@ namespace DiIiS_NA.REST.Http
|
|||||||
Found = 302,
|
Found = 302,
|
||||||
BadRequest = 400,
|
BadRequest = 400,
|
||||||
NotFound = 404,
|
NotFound = 404,
|
||||||
InternalServerError = 500
|
InternalServerError = 500,
|
||||||
|
BadGateway = 502
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HttpHelper
|
public class HttpHelper
|
||||||
|
|||||||
@ -12,6 +12,7 @@ using DiIiS_NA.REST.Data.Authentication;
|
|||||||
using DiIiS_NA.REST.JSON;
|
using DiIiS_NA.REST.JSON;
|
||||||
using DiIiS_NA.LoginServer.AccountsSystem;
|
using DiIiS_NA.LoginServer.AccountsSystem;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using DiIiS_NA.GameServer.MessageSystem;
|
using DiIiS_NA.GameServer.MessageSystem;
|
||||||
@ -41,26 +42,19 @@ namespace DiIiS_NA.REST
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Info($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
Logger.Debug($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
||||||
if (httpRequest.Path == "200")
|
if (httpRequest.Path == "200")
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (httpRequest.Path.Contains("/client/alert"))
|
else if (httpRequest.Path.Contains("/client/alert"))
|
||||||
{
|
{
|
||||||
switch (httpRequest.Method)
|
HandleInfoRequest(httpRequest);
|
||||||
{
|
|
||||||
case "GET":
|
|
||||||
default:
|
|
||||||
HandleInfoRequest(httpRequest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (httpRequest.Path.Contains("/battlenet/login"))
|
||||||
{
|
{
|
||||||
switch (httpRequest.Method)
|
switch (httpRequest.Method)
|
||||||
{
|
{
|
||||||
case "GET":
|
|
||||||
default:
|
default:
|
||||||
HandleConnectRequest(httpRequest);
|
HandleConnectRequest(httpRequest);
|
||||||
break;
|
break;
|
||||||
@ -69,30 +63,34 @@ namespace DiIiS_NA.REST
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Logger.Info($"$[red]$[404] REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
||||||
|
SendResponseHtml(HttpCode.NotFound, "404 Not Found");
|
||||||
|
#else
|
||||||
|
// sends 502 Bad Gateway to the client to prevent the client from trying to connect to the server again - in case it's a crawler or bad bot.
|
||||||
|
Logger.Info($"$[red]$[404/502] REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
||||||
|
SendResponseHtml(HttpCode.BadGateway, "502 Bad Gateway");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AsyncRead();
|
AsyncRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleConnectRequest(HttpHeader request)
|
void HandleConnectRequest(HttpHeader request)
|
||||||
{
|
{
|
||||||
SendResponse(HttpCode.OK, SessionManager.Instance.GetFormInput());
|
SendResponse(HttpCode.OK, SessionManager.Instance.GetFormInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleInfoRequest(HttpHeader request)
|
void HandleInfoRequest(HttpHeader request)
|
||||||
{
|
{
|
||||||
SendResponseHtml(HttpCode.OK, "Welcome to BlizzLess.Net" +
|
SendResponseHtml(HttpCode.OK, "Welcome to BlizzLess.Net" +
|
||||||
"\nBuild " + Program.Build +
|
"\nBuild " + Program.Build +
|
||||||
"\nSupport: 2.7.4");
|
"\nSupport: 2.7.4");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] StringToByteArray(string hex)
|
|
||||||
{
|
|
||||||
return Enumerable.Range(0, hex.Length)
|
|
||||||
.Where(x => x % 2 == 0)
|
|
||||||
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
|
|
||||||
.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendResponse<T>(HttpCode code, T response)
|
void SendResponse<T>(HttpCode code, T response)
|
||||||
{
|
{
|
||||||
AsyncWrite(HttpHelper.CreateResponse(code, JSON.Json.CreateString(response)));
|
AsyncWrite(HttpHelper.CreateResponse(code, JSON.Json.CreateString(response)));
|
||||||
@ -107,7 +105,8 @@ namespace DiIiS_NA.REST
|
|||||||
{
|
{
|
||||||
AsyncRead();
|
AsyncRead();
|
||||||
}
|
}
|
||||||
public void HandleLoginRequest(HttpHeader request)
|
|
||||||
|
void HandleLoginRequest(HttpHeader request)
|
||||||
{
|
{
|
||||||
LogonData loginForm = Json.CreateObject<LogonData>(request.Content);
|
LogonData loginForm = Json.CreateObject<LogonData>(request.Content);
|
||||||
LogonResult loginResult = new LogonResult();
|
LogonResult loginResult = new LogonResult();
|
||||||
|
|||||||
Loading…
Reference in New Issue
user.block.title