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
|
||||
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
|
||||
Log(Level.MethodTrace, $"$[darkolivegreen3_2]${methodName}()$[/]$: " + message, null);
|
||||
#endif
|
||||
|
||||
@ -13,23 +13,17 @@ namespace DiIiS_NA.Core.Storage
|
||||
private static Object _globalSessionLock = new object();
|
||||
private Object _sessionLock = new object();
|
||||
private IStatelessSession _gameSession = null;
|
||||
private readonly Logger Logger = LogManager.CreateLogger("DB");
|
||||
private readonly Logger Logger = LogManager.CreateLogger(nameof(GameDBSession));
|
||||
|
||||
public GameDBSession()
|
||||
{
|
||||
lock (_globalSessionLock)
|
||||
{
|
||||
this._gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
_gameSession = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
}
|
||||
}
|
||||
|
||||
private IStatelessSession GameSession
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._gameSession;
|
||||
}
|
||||
}
|
||||
private IStatelessSession GameSession => _gameSession;
|
||||
|
||||
public void SessionSave(Object obj)
|
||||
{
|
||||
@ -39,7 +33,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
session.Insert(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -74,7 +68,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
session.Update(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -109,7 +103,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
session.Delete(obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -157,7 +151,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
return session.Query<T>().ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -189,7 +183,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
return session.QueryOver<T>().Where(predicate).List().ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -221,7 +215,7 @@ namespace DiIiS_NA.Core.Storage
|
||||
{
|
||||
try
|
||||
{
|
||||
using (IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession())
|
||||
using IStatelessSession session = AccountDataBase.SessionProvider.SessionFactory.OpenStatelessSession();
|
||||
return (T)session.QueryOver<T>().Where(predicate).List().FirstOrDefault();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@ -24,18 +24,29 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
|
||||
{
|
||||
if (!type.IsSubclassOf(typeof(CommandGroup))) continue;
|
||||
|
||||
var attributes = (CommandGroupAttribute[])type.GetCustomAttributes(typeof(CommandGroupAttribute), true);
|
||||
if (attributes.Length == 0) continue;
|
||||
|
||||
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))
|
||||
Logger.Warn("There exists an already registered command group named '{0}'.", groupAttribute.Name);
|
||||
|
||||
var commandGroup = (CommandGroup)Activator.CreateInstance(type);
|
||||
if (commandGroup != null)
|
||||
{
|
||||
commandGroup.Register(groupAttribute);
|
||||
CommandGroups.Add(groupAttribute, commandGroup);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warn("Failed to create an instance of command group '{0}'.", groupAttribute.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -4,8 +4,7 @@ using DiIiS_NA.LoginServer.Battle;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]",
|
||||
Account.UserLevels.Owner)]
|
||||
[CommandGroup("drop", "Drops an epic item for your class.\nOptionally specify the number of items: !drop [1-20]", Account.UserLevels.Owner)]
|
||||
public class DropCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -29,16 +28,16 @@ public class DropCommand : CommandGroup
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
catch
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return $"Dropped {amount} random equipment.";
|
||||
return $"Dropped {amount} random epic equipment.";
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,19 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
set => Set(nameof(CommandPrefix), value);
|
||||
}
|
||||
|
||||
public static CommandsConfig Instance = new();
|
||||
public string DisabledGroups
|
||||
{
|
||||
get => GetString(nameof(DisabledGroups), "");
|
||||
set => Set(nameof(DisabledGroups), value);
|
||||
}
|
||||
|
||||
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") { }
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,41 +113,24 @@ namespace DiIiS_NA.GameServer.Core.Types.Math
|
||||
return ((x * x) + (y * y)) + (z * z);
|
||||
}
|
||||
|
||||
public static bool operator ==(Vector3D a, Vector3D b)
|
||||
{
|
||||
if (ReferenceEquals(null, a))
|
||||
return ReferenceEquals(null, b);
|
||||
return a.Equals(b);
|
||||
}
|
||||
public static bool operator ==(Vector3D a, Vector3D b) => a?.Equals(b) ?? ReferenceEquals(null, b);
|
||||
|
||||
public static bool operator !=(Vector3D a, Vector3D b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
public static bool operator !=(Vector3D a, Vector3D b) => !(a == b);
|
||||
|
||||
public static bool operator >(Vector3D a, Vector3D b)
|
||||
{
|
||||
if (ReferenceEquals(null, a))
|
||||
return !ReferenceEquals(null, b);
|
||||
return a.X > b.X
|
||||
return ReferenceEquals(null, a)
|
||||
? !ReferenceEquals(null, b)
|
||||
: a.X > b.X
|
||||
&& a.Y > b.Y
|
||||
&& a.Z > b.Z;
|
||||
}
|
||||
|
||||
public static Vector3D operator +(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
}
|
||||
public static Vector3D operator +(Vector3D a, Vector3D b) => new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||
|
||||
public static Vector3D operator -(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
}
|
||||
public static Vector3D operator -(Vector3D a, Vector3D b) => new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||
|
||||
public static bool operator <(Vector3D a, Vector3D b)
|
||||
{
|
||||
return !(a > b);
|
||||
}
|
||||
public static bool operator <(Vector3D a, Vector3D b) => !(a > 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;
|
||||
if (v != null)
|
||||
{
|
||||
return System.Math.Abs(X - v.X) < 0.0001
|
||||
&& System.Math.Abs(Y - v.Y) < 0.0001
|
||||
&& System.Math.Abs(Z - v.Z) < 0.0001;
|
||||
return System.Math.Abs(X - v.X) < Globals.FLOAT_TOLERANCE
|
||||
&& System.Math.Abs(Y - v.Y) < Globals.FLOAT_TOLERANCE
|
||||
&& System.Math.Abs(Z - v.Z) < Globals.FLOAT_TOLERANCE;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -20690,7 +20690,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
||||
ActorSno._p73_fallenlunatic_a_nonspawner,
|
||||
};
|
||||
// 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._a1dun_caves_nephalem_altar_volume,
|
||||
@ -20713,7 +20713,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
||||
ActorSno._p43_ad_valor_bloodstone_volume,
|
||||
};
|
||||
// all 'door' actors
|
||||
private static readonly ActorSno[] doors = new ActorSno[]
|
||||
private static readonly ActorSno[] _doors = new ActorSno[]
|
||||
{
|
||||
ActorSno._trdun_cath_wooddoor_a,
|
||||
ActorSno._door_intactc_caout_towns,
|
||||
@ -21156,7 +21156,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
||||
ActorSno._kanai_cube_uber_fx,
|
||||
};
|
||||
// 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_zkplans,
|
||||
@ -21168,7 +21168,7 @@ namespace DiIiS_NA.D3_GameServer.Core.Types.SNO
|
||||
ActorSno._x1_adventuremode_hubbantertrigger,
|
||||
};
|
||||
#endregion
|
||||
public static readonly ActorSno[] nephalemPortalBosses = new ActorSno[]
|
||||
public static readonly ActorSno[] NephalemPortalBosses = new ActorSno[]
|
||||
{
|
||||
ActorSno._x1_lr_boss_mistressofpain,
|
||||
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)
|
||||
{
|
||||
return adventureModeActors.Contains(actorSno);
|
||||
return AdventureModeActors.Contains(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)
|
||||
{
|
||||
return doors.Contains(actorSno) || barricades.Contains(actorSno);
|
||||
return _doors.Contains(actorSno) || barricades.Contains(actorSno);
|
||||
}
|
||||
|
||||
public static bool IsWoodwraithOrWasp(this ActorSno actorSno)
|
||||
|
||||
@ -50,11 +50,5 @@ namespace DiIiS_NA.D3_GameServer.GSSystem.ActorSystem.Implementations.Artisans
|
||||
base.OnCraft(player);
|
||||
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()
|
||||
{
|
||||
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;
|
||||
//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;
|
||||
|
||||
@ -1256,7 +1256,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GameSystem
|
||||
GameAccountId = new GameAccountHandle() { ID = (uint)joinedPlayer.Toon.GameAccount.BnetEntityId.Low, Program = 0x00004433, Region = 1 },
|
||||
ToonName = joinedPlayer.Toon.Name,
|
||||
Team = 0x00000002,
|
||||
Class = joinedPlayer.ClassSNO,
|
||||
Class = joinedPlayer.ClassSno,
|
||||
snoActorPortrait = joinedPlayer.Toon.DBToon.Cosmetic4,
|
||||
Level = joinedPlayer.Toon.Level,
|
||||
AltLevel = (ushort)joinedPlayer.Toon.ParagonLevel,
|
||||
|
||||
@ -386,8 +386,8 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
||||
RandomSpawnInWorldWithLevelArea(world, ActorSno._x1_deathmaiden_unique_fire_a);
|
||||
break;
|
||||
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;
|
||||
world.SpawnMonster(ActorSno._waypoint, new Vector3D(Scene0Pos.X + 149.0907f, Scene0Pos.Y + 106.7075f, Scene0Pos.Z));
|
||||
Vector3D sceneOfPos = world.GetSceneBySnoId(78824).Position;
|
||||
world.SpawnMonster(ActorSno._waypoint, new Vector3D(sceneOfPos.X + 149.0907f, sceneOfPos.Y + 106.7075f, sceneOfPos.Z));
|
||||
break;
|
||||
case WorldSno.x1_westm_graveyard_deathorb:
|
||||
FilterWaypoints(world);
|
||||
@ -402,9 +402,9 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
||||
break;
|
||||
case WorldSno.trout_town: //mercenary
|
||||
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)
|
||||
{
|
||||
@ -419,17 +419,17 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
||||
}
|
||||
foreach (var door in world.GetActorsBySNO(ActorSno._house_door_trout_newtristram))
|
||||
door.Destroy();
|
||||
if (Game.CurrentAct == 3000)
|
||||
if (Game.CurrentActEnum == ActEnum.OpenWorld)
|
||||
{
|
||||
var TownDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town);
|
||||
TownDoor.Attributes[GameAttribute.Team_Override] = 2;
|
||||
TownDoor.Attributes[GameAttribute.Untargetable] = true;
|
||||
TownDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false;
|
||||
TownDoor.Attributes[GameAttribute.Operatable] = false;
|
||||
TownDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false;
|
||||
TownDoor.Attributes[GameAttribute.Disabled] = true;
|
||||
TownDoor.Attributes[GameAttribute.Immunity] = true;
|
||||
TownDoor.Attributes.BroadcastChangedIfRevealed();
|
||||
var townDoor = world.GetActorBySNO(ActorSno._trout_newtristram_gate_town);
|
||||
townDoor.Attributes[GameAttribute.Team_Override] = 2;
|
||||
townDoor.Attributes[GameAttribute.Untargetable] = true;
|
||||
townDoor.Attributes[GameAttribute.NPC_Is_Operatable] = false;
|
||||
townDoor.Attributes[GameAttribute.Operatable] = false;
|
||||
townDoor.Attributes[GameAttribute.Operatable_Story_Gizmo] = false;
|
||||
townDoor.Attributes[GameAttribute.Disabled] = true;
|
||||
townDoor.Attributes[GameAttribute.Immunity] = true;
|
||||
townDoor.Attributes.BroadcastChangedIfRevealed();
|
||||
}
|
||||
break;
|
||||
case WorldSno.a1trdun_level04: //Cathedral Level 2
|
||||
@ -504,10 +504,12 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
||||
zoltunGhost.Attributes.BroadcastChangedIfRevealed();
|
||||
break;
|
||||
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;
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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();
|
||||
else scenes = scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList();
|
||||
Vector3D SSV = scenes.PickRandom().Position;
|
||||
scenes = levelArea != -1
|
||||
? scenes.Where(sc => sc.Specification.SNOLevelAreas[0] == levelArea && !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList()
|
||||
: scenes.Where(sc => !sc.SceneSNO.Name.ToLower().Contains("filler")).ToList();
|
||||
Vector3D randomScene = scenes.PickRandom().Position;
|
||||
Vector3D startingPoint = null;
|
||||
|
||||
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))
|
||||
break;
|
||||
}
|
||||
@ -1591,7 +1594,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
|
||||
{
|
||||
bool busy = false;
|
||||
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;
|
||||
break;
|
||||
|
||||
@ -552,8 +552,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ItemsSystem
|
||||
if (ratio > 1f) ratio = 1f;
|
||||
Attributes[GameAttribute.Block_Amount_Item_Min] +=
|
||||
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, 0]);
|
||||
Attributes[GameAttribute.Block_Amount_Item_Delta] += Math.Abs(scaleCapDelta * ratio - Attributes[GameAttribute.Block_Amount_Item_Delta, 0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,16 +590,13 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
public Actor SpawnMonster(ActorSno monsterSno, Vector3D position)
|
||||
{
|
||||
if (monsterSno == ActorSno.__NONE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (monsterSno == ActorSno.__NONE) return null;
|
||||
Logger.MethodTrace($"Spawning monster {monsterSno} at {position}");
|
||||
var monster = ActorFactory.Create(this, monsterSno, new TagMap());
|
||||
if (monster != null)
|
||||
{
|
||||
if (monster == null) return null;
|
||||
|
||||
monster.EnterWorld(position);
|
||||
if (monster.AnimationSet != null)
|
||||
{
|
||||
if (monster.AnimationSet == null) return monster;
|
||||
var animationTag = new[] { AnimationSetKeys.Spawn, AnimationSetKeys.Spawn2 }.FirstOrDefault(x => monster.AnimationSet.TagMapAnimDefault.ContainsKey(x));
|
||||
|
||||
if (animationTag != null)
|
||||
@ -622,8 +619,6 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
}, monster);
|
||||
}
|
||||
}
|
||||
}
|
||||
return monster;
|
||||
}
|
||||
|
||||
@ -640,19 +635,21 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
player.GroundItems[item.GlobalID] = item; // FIXME: Hacky. /komiga
|
||||
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
|
||||
{
|
||||
ann = (int)actor.DynamicID(plr),
|
||||
StartPos = User.Position,
|
||||
FirstTagetPos = User.Position,
|
||||
StartPos = user.Position,
|
||||
FirstTagetPos = user.Position,
|
||||
MoveFlags = 9,
|
||||
AnimTag = 1,
|
||||
PieData = new DPathPieData
|
||||
{
|
||||
Field0 = TargetPosition,
|
||||
Field0 = targetPosition,
|
||||
Field1 = 1,
|
||||
Field2 = 1,
|
||||
Field3 = 1
|
||||
|
||||
@ -2395,7 +2395,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
var rem = new List<uint>();
|
||||
foreach (var fol in Followers.Where(f =>
|
||||
Math.Abs(World.GetActorByGlobalId(f.Key).Attributes[GameAttribute.Summoned_By_SNO] -
|
||||
oldSNOSkill) < 0.001))
|
||||
oldSNOSkill) < Globals.FLOAT_TOLERANCE))
|
||||
rem.Add(fol.Key);
|
||||
foreach (var rm in rem)
|
||||
DestroyFollowerById(rm);
|
||||
@ -2914,13 +2914,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
//*
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
var trainHelper = artisanTrainHelpers[CurrentArtisan.Value];
|
||||
var trainHelper = _artisanTrainHelpers[CurrentArtisan.Value];
|
||||
if (trainHelper.HasMaxLevel)
|
||||
return;
|
||||
|
||||
@ -2947,7 +2947,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
if (trainHelper.Criteria is not null)
|
||||
GrantCriteria(trainHelper.Criteria.Value);
|
||||
|
||||
if (artisanTrainHelpers.All(x => x.Value.HasMaxLevel))
|
||||
if (_artisanTrainHelpers.All(x => x.Value.HasMaxLevel))
|
||||
GrantCriteria(74987249993545);
|
||||
|
||||
client.SendMessage(new CrafterLevelUpMessage
|
||||
@ -2966,13 +2966,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
public void UnlockTransmog(int transmogGBID)
|
||||
{
|
||||
if (learnedTransmogs.Contains(transmogGBID)) return;
|
||||
if (_learnedTransmogs.Contains(transmogGBID)) return;
|
||||
InGameClient.SendMessage(new UnlockTransmogMessage() { TransmogGBID = transmogGBID });
|
||||
|
||||
Logger.Trace("Learning transmog #{0}", transmogGBID);
|
||||
learnedTransmogs.Add(transmogGBID);
|
||||
mystic_data.LearnedRecipes = SerializeBytes(learnedTransmogs);
|
||||
World.Game.GameDbSession.SessionUpdate(mystic_data);
|
||||
_learnedTransmogs.Add(transmogGBID);
|
||||
_mysticData.LearnedRecipes = SerializeBytes(_learnedTransmogs);
|
||||
World.Game.GameDbSession.SessionUpdate(_mysticData);
|
||||
|
||||
LoadCrafterData();
|
||||
}
|
||||
@ -3067,7 +3067,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
foreach (var timed_out in TimedActions.Where(t => t.TimedOut).ToList())
|
||||
TimedActions.Remove(timed_out);
|
||||
|
||||
// Check the Killstreaks
|
||||
// Check the kill streaks
|
||||
ExpBonusData.Check(0);
|
||||
ExpBonusData.Check(1);
|
||||
|
||||
@ -3165,27 +3165,29 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
#region Necromancer summons
|
||||
|
||||
var switchertobool = false;
|
||||
var switchertoboolTwo = false;
|
||||
ActiveSkillSavedData NowSkillGolem = null;
|
||||
var switcherToBool = false;
|
||||
var switcherToBool2 = false;
|
||||
ActiveSkillSavedData nowSkillGolen = null;
|
||||
foreach (var skill in SkillSet.ActiveSkills)
|
||||
if (skill.snoSkill == 453801)
|
||||
switchertobool = true;
|
||||
switcherToBool = true;
|
||||
foreach (var skill in SkillSet.ActiveSkills)
|
||||
if (skill.snoSkill == 451537)
|
||||
{
|
||||
switchertoboolTwo = true;
|
||||
NowSkillGolem = skill;
|
||||
switcherToBool2 = true;
|
||||
nowSkillGolen = skill;
|
||||
}
|
||||
|
||||
ActiveSkeletons = switchertobool;
|
||||
EnableGolem = switchertoboolTwo;
|
||||
ActiveSkeletons = switcherToBool;
|
||||
EnableGolem = switcherToBool2;
|
||||
|
||||
|
||||
var Killer = new PowerContext();
|
||||
Killer.User = this;
|
||||
Killer.World = World;
|
||||
Killer.PowerSNO = -1;
|
||||
var killer = new PowerContext
|
||||
{
|
||||
User = this,
|
||||
World = World,
|
||||
PowerSNO = -1
|
||||
};
|
||||
|
||||
if (ActiveSkeletons)
|
||||
{
|
||||
@ -3255,8 +3257,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
{
|
||||
PetId = ActiveGolem.GlobalID
|
||||
});
|
||||
Killer.Target = ActiveGolem;
|
||||
(ActiveGolem as Minion).Kill(Killer);
|
||||
killer.Target = ActiveGolem;
|
||||
(ActiveGolem as Minion).Kill(killer);
|
||||
}
|
||||
|
||||
ActiveGolem = null;
|
||||
@ -3386,20 +3388,14 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
#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];
|
||||
var Rune_B = Attributes[GameAttribute.Rune_B, PowerSNO];
|
||||
var Rune_C = Attributes[GameAttribute.Rune_C, PowerSNO];
|
||||
var Rune_D = Attributes[GameAttribute.Rune_D, PowerSNO];
|
||||
var Rune_E = Attributes[GameAttribute.Rune_E, PowerSNO];
|
||||
|
||||
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;
|
||||
if (Attributes[GameAttribute.Rune_A, powerSno] > 0) return runeA;
|
||||
if (Attributes[GameAttribute.Rune_B, powerSno] > 0) return runeB;
|
||||
if (Attributes[GameAttribute.Rune_C, powerSno] > 0) return runeC;
|
||||
if (Attributes[GameAttribute.Rune_D, powerSno] > 0) return runeD;
|
||||
if (Attributes[GameAttribute.Rune_E, powerSno] > 0) return runeE;
|
||||
return none;
|
||||
}
|
||||
|
||||
#region enter, leave, reveal handling
|
||||
@ -3410,11 +3406,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
public void RevealScenesToPlayer()
|
||||
{
|
||||
//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)
|
||||
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.
|
||||
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
|
||||
{
|
||||
if (!scene.IsRevealedToPlayer(this) || scenes_around.Contains(scene))
|
||||
if (!scene.IsRevealedToPlayer(this) || scenesAround.Contains(scene))
|
||||
continue;
|
||||
|
||||
if (scene.Parent !=
|
||||
@ -3444,9 +3440,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
/// </summary>
|
||||
public void RevealActorsToPlayer()
|
||||
{
|
||||
var Range = 200f;
|
||||
var range = 200f;
|
||||
if (InGameClient.Game.CurrentEncounter.Activated)
|
||||
Range = 360f;
|
||||
range = 360f;
|
||||
|
||||
var specialWorlds = new WorldSno[]
|
||||
{
|
||||
@ -3457,9 +3453,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
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.
|
||||
continue;
|
||||
@ -3482,7 +3478,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
foreach (var actor in World.Actors.Values) // unreveal far actors
|
||||
{
|
||||
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;
|
||||
|
||||
actor.Unreveal(this);
|
||||
@ -3549,7 +3545,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
world.Reveal(this);
|
||||
Unreveal(this);
|
||||
|
||||
if (_CurrentHPValue == -1f)
|
||||
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||
DefaultQueryProximityRadius = 60;
|
||||
|
||||
InGameClient.SendMessage(new EnterWorldMessage()
|
||||
@ -3580,7 +3576,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
break;
|
||||
}
|
||||
|
||||
if (_CurrentHPValue == -1f)
|
||||
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||
AddPercentageHP(100);
|
||||
|
||||
DefaultQueryProximityRadius = 100;
|
||||
@ -3750,7 +3746,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
AllBuffs.Clear();
|
||||
BetweenWorlds = false;
|
||||
|
||||
if (Math.Abs(_CurrentHPValue - (-1)) > 0.0001)
|
||||
if (Math.Abs(_CurrentHPValue - (-1)) > Globals.FLOAT_TOLERANCE)
|
||||
{
|
||||
Attributes[GameAttribute.Hitpoints_Cur] = _CurrentHPValue;
|
||||
Attributes[GameAttribute.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue;
|
||||
@ -3850,7 +3846,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
}
|
||||
|
||||
/// <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>
|
||||
public void UpdateHeroState()
|
||||
{
|
||||
@ -3940,7 +3936,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
//removing tomb
|
||||
try
|
||||
{
|
||||
GetObjectsInRange<Headstone>(100.0f).Where(h => h.playerIndex == PlayerIndex).First().Destroy();
|
||||
GetObjectsInRange<Headstone>(100.0f).First(h => h.playerIndex == PlayerIndex).Destroy();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -3949,8 +3945,8 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Teleport(spawnPosition);
|
||||
World.BuffManager.AddBuff(this, this, new ActorGhostedBuff());
|
||||
|
||||
var old_skills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList();
|
||||
foreach (var skill in old_skills)
|
||||
var oldSkills = SkillSet.ActiveSkills.Select(s => s.snoSkill).ToList();
|
||||
foreach (var skill in oldSkills)
|
||||
{
|
||||
var power = PowerLoader.CreateImplementationForPowerSNO(skill);
|
||||
if (power != null && power.EvalTag(PowerKeys.SynergyPower) != -1)
|
||||
@ -3998,13 +3994,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
get
|
||||
{
|
||||
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)
|
||||
baseStrength = Toon.HeroTable.Strength + (Level - 1) * 3;
|
||||
else
|
||||
baseStrength = Toon.HeroTable.Strength + (Level - 1);
|
||||
|
||||
return baseStrength;
|
||||
return baseStrength * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4015,17 +4010,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity)
|
||||
return Toon.HeroTable.Dexterity + (Level - 1) * 3;
|
||||
else
|
||||
return Toon.HeroTable.Dexterity + (Level - 1);
|
||||
var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.DexterityParagonMultiplier : GameServerConfig.Instance.DexterityMultiplier;
|
||||
|
||||
return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Dexterity
|
||||
? Toon.HeroTable.Dexterity + (Level - 1) * 3 * multiplier
|
||||
: Toon.HeroTable.Dexterity + (Level - 1) * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
public float TotalDexterity =>
|
||||
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 =>
|
||||
Attributes[GameAttribute.Vitality] + Inventory.GetItemBonus(GameAttribute.Vitality_Item);
|
||||
@ -4034,10 +4030,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence)
|
||||
return Toon.HeroTable.Intelligence + (Level - 1) * 3;
|
||||
else
|
||||
return Toon.HeroTable.Intelligence + (Level - 1);
|
||||
var multiplier = ParagonLevel > 0 ? GameServerConfig.Instance.IntelligenceParagonMultiplier : GameServerConfig.Instance.IntelligenceMultiplier;
|
||||
return Toon.HeroTable.CoreAttribute == GameBalance.PrimaryAttribute.Intelligence
|
||||
? Toon.HeroTable.Intelligence + (Level - 1) * 3 * multiplier
|
||||
: Toon.HeroTable.Intelligence + (Level - 1) * multiplier;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4325,15 +4321,15 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
if (query.Count == 0)
|
||||
{
|
||||
//returns empty data
|
||||
var hireling_empty = new HirelingInfo
|
||||
var emptyHireling = new HirelingInfo
|
||||
{
|
||||
HirelingIndex = type, GbidName = 0x0000, Dead = false, Skill1SNOId = -1, Skill2SNOId = -1,
|
||||
Skill3SNOId = -1, Skill4SNOId = -1, annItems = -1
|
||||
};
|
||||
return hireling_empty;
|
||||
return emptyHireling;
|
||||
}
|
||||
|
||||
var hireling_full = new HirelingInfo
|
||||
return new HirelingInfo
|
||||
{
|
||||
HirelingIndex = type,
|
||||
GbidName = 0x0000,
|
||||
@ -4344,14 +4340,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Skill4SNOId = query.First().Skill4SNOId,
|
||||
annItems = -1
|
||||
};
|
||||
return hireling_full;
|
||||
}
|
||||
|
||||
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>();
|
||||
foreach (var recid in recparts) ret.Add(Convert.ToInt32(recid, 10));
|
||||
foreach (var part in parts) ret.Add(Convert.ToInt32(part, 10));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4380,34 +4375,35 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
public void LearnRecipe(ArtisanType? artisan, int recipe)
|
||||
{
|
||||
Logger.Trace("Learning recipe #{0}, Artisan type: {1}", recipe, artisan);
|
||||
|
||||
/*var query = this.World.Game.GameDBSession.SessionQuerySingle<DBCraft>(
|
||||
dbi =>
|
||||
dbi.DBGameAccount.Id == this.Toon.GameAccount.PersistentID &&
|
||||
dbi.Artisan == artisan &&
|
||||
dbi.isHardcore == this.World.Game.IsHardcore);*/
|
||||
if (artisan == ArtisanType.Blacksmith)
|
||||
switch (artisan)
|
||||
{
|
||||
learnedBlacksmithRecipes.Add(recipe);
|
||||
blacksmith_data.LearnedRecipes = SerializeBytes(learnedBlacksmithRecipes);
|
||||
World.Game.GameDbSession.SessionUpdate(blacksmith_data);
|
||||
case ArtisanType.Blacksmith:
|
||||
_learnedBlacksmithRecipes.Add(recipe);
|
||||
_blacksmithData.LearnedRecipes = SerializeBytes(_learnedBlacksmithRecipes);
|
||||
World.Game.GameDbSession.SessionUpdate(_blacksmithData);
|
||||
UpdateAchievementCounter(404, 1, 0);
|
||||
}
|
||||
else if (artisan == ArtisanType.Jeweler)
|
||||
{
|
||||
learnedJewelerRecipes.Add(recipe);
|
||||
jeweler_data.LearnedRecipes = SerializeBytes(learnedJewelerRecipes);
|
||||
World.Game.GameDbSession.SessionUpdate(jeweler_data);
|
||||
break;
|
||||
case ArtisanType.Jeweler:
|
||||
_learnedJewelerRecipes.Add(recipe);
|
||||
_jewelerData.LearnedRecipes = SerializeBytes(_learnedJewelerRecipes);
|
||||
World.Game.GameDbSession.SessionUpdate(_jewelerData);
|
||||
UpdateAchievementCounter(404, 1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
LoadCrafterData();
|
||||
}
|
||||
|
||||
public bool RecipeAvailable(GameBalance.RecipeTable recipe_definition)
|
||||
public bool RecipeAvailable(GameBalance.RecipeTable recipeDefinition)
|
||||
{
|
||||
if (recipe_definition.Flags == 0) return true;
|
||||
return learnedBlacksmithRecipes.Contains(recipe_definition.Hash) ||
|
||||
learnedJewelerRecipes.Contains(recipe_definition.Hash);
|
||||
if (recipeDefinition.Flags == 0) return true;
|
||||
return _learnedBlacksmithRecipes.Contains(recipeDefinition.Hash) || _learnedJewelerRecipes.Contains(recipeDefinition.Hash);
|
||||
}
|
||||
|
||||
public PlayerBannerMessage GetPlayerBanner()
|
||||
@ -4420,69 +4416,69 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
return new PlayerBannerMessage() { PlayerBanner = playerBanner };
|
||||
}
|
||||
|
||||
private List<int> learnedBlacksmithRecipes = new();
|
||||
private List<int> learnedJewelerRecipes = new();
|
||||
private List<int> learnedTransmogs = new();
|
||||
private List<int> _learnedBlacksmithRecipes = new();
|
||||
private List<int> _learnedJewelerRecipes = new();
|
||||
private List<int> _learnedTransmogs = new();
|
||||
|
||||
private DBCraft blacksmith_data = null;
|
||||
private DBCraft jeweler_data = null;
|
||||
private DBCraft mystic_data = null;
|
||||
private Dictionary<ArtisanType, ArtisanTrainHelper> artisanTrainHelpers = new();
|
||||
private DBCraft _blacksmithData = null;
|
||||
private DBCraft _jewelerData = null;
|
||||
private DBCraft _mysticData = null;
|
||||
private readonly Dictionary<ArtisanType, ArtisanTrainHelper> _artisanTrainHelpers = new();
|
||||
|
||||
public void LoadCrafterData()
|
||||
{
|
||||
if (blacksmith_data == null)
|
||||
if (_blacksmithData == null)
|
||||
{
|
||||
var craft_data =
|
||||
World.Game.GameDbSession.SessionQueryWhere<DBCraft>(dbc =>
|
||||
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.isSeasoned == World.Game.IsSeasoned);
|
||||
jeweler_data = craft_data.Single(dbc =>
|
||||
_jewelerData = craft_data.Single(dbc =>
|
||||
dbc.Artisan == "Jeweler" && dbc.isHardcore == World.Game.IsHardcore &&
|
||||
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.isSeasoned == World.Game.IsSeasoned);
|
||||
|
||||
artisanTrainHelpers[ArtisanType.Blacksmith] =
|
||||
new ArtisanTrainHelper(blacksmith_data, ArtisanType.Blacksmith);
|
||||
artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(jeweler_data, ArtisanType.Jeweler);
|
||||
artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(mystic_data, ArtisanType.Mystic);
|
||||
_artisanTrainHelpers[ArtisanType.Blacksmith] =
|
||||
new ArtisanTrainHelper(_blacksmithData, ArtisanType.Blacksmith);
|
||||
_artisanTrainHelpers[ArtisanType.Jeweler] = new ArtisanTrainHelper(_jewelerData, ArtisanType.Jeweler);
|
||||
_artisanTrainHelpers[ArtisanType.Mystic] = new ArtisanTrainHelper(_mysticData, ArtisanType.Mystic);
|
||||
}
|
||||
|
||||
|
||||
var blacksmith = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||
? BlacksmithUnlocked == false && blacksmith_data.Level < 1 ? 1 : blacksmith_data.Level
|
||||
: blacksmith_data.Level)
|
||||
? BlacksmithUnlocked == false && _blacksmithData.Level < 1 ? 1 : _blacksmithData.Level
|
||||
: _blacksmithData.Level)
|
||||
.SetCooldownEnd(0)
|
||||
.AddRangeRecipes(UnserializeBytes(blacksmith_data.LearnedRecipes))
|
||||
.AddRangeRecipes(UnserializeBytes(_blacksmithData.LearnedRecipes))
|
||||
.Build();
|
||||
learnedBlacksmithRecipes = UnserializeBytes(blacksmith_data.LearnedRecipes);
|
||||
_learnedBlacksmithRecipes = UnserializeBytes(_blacksmithData.LearnedRecipes);
|
||||
var jeweler = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||
? JewelerUnlocked == false && jeweler_data.Level < 1 ? 1 : jeweler_data.Level
|
||||
: jeweler_data.Level)
|
||||
? JewelerUnlocked == false && _jewelerData.Level < 1 ? 1 : _jewelerData.Level
|
||||
: _jewelerData.Level)
|
||||
.SetCooldownEnd(0)
|
||||
.AddRangeRecipes(UnserializeBytes(jeweler_data.LearnedRecipes))
|
||||
.AddRangeRecipes(UnserializeBytes(_jewelerData.LearnedRecipes))
|
||||
.Build();
|
||||
learnedJewelerRecipes = UnserializeBytes(jeweler_data.LearnedRecipes);
|
||||
_learnedJewelerRecipes = UnserializeBytes(_jewelerData.LearnedRecipes);
|
||||
var mystic = D3.ItemCrafting.CrafterData.CreateBuilder()
|
||||
.SetLevel(InGameClient.Game.CurrentAct == 3000
|
||||
? MysticUnlocked == false && mystic_data.Level < 1 ? 1 : mystic_data.Level
|
||||
: mystic_data.Level)
|
||||
? MysticUnlocked == false && _mysticData.Level < 1 ? 1 : _mysticData.Level
|
||||
: _mysticData.Level)
|
||||
.SetCooldownEnd(0)
|
||||
.Build();
|
||||
|
||||
var transmog = D3.ItemCrafting.CrafterSavedData.CreateBuilder()
|
||||
.SetTransmogData(D3.GameBalance.BitPackedGbidArray.CreateBuilder()
|
||||
.SetBitfield(ByteString.CopyFrom(mystic_data.LearnedRecipes)))
|
||||
.SetBitfield(ByteString.CopyFrom(_mysticData.LearnedRecipes)))
|
||||
//.AddRangeUnlockedTransmogs(this.UnserializeBytes(mystic_data.LearnedRecipes))
|
||||
.Build();
|
||||
learnedTransmogs = UnserializeBytes(mystic_data.LearnedRecipes);
|
||||
_learnedTransmogs = UnserializeBytes(_mysticData.LearnedRecipes);
|
||||
|
||||
if (BlacksmithUnlocked || InGameClient.Game.CurrentAct == 3000)
|
||||
InGameClient.SendMessage(new GenericBlobMessage(Opcodes.CraftingDataBlacksmithInitialMessage)
|
||||
@ -4503,27 +4499,26 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
public void LoadCurrencyData()
|
||||
{
|
||||
var bloodShards = 0;
|
||||
bloodShards = Toon.GameAccount.BloodShards;
|
||||
var bloodShards = Toon.GameAccount.BloodShards; // TODO: is this needed? @iamdroppy
|
||||
Inventory.UpdateCurrencies();
|
||||
}
|
||||
|
||||
public void LoadMailData()
|
||||
{
|
||||
var mail_data =
|
||||
var mailData =
|
||||
World.Game.GameDbSession.SessionQueryWhere<DBMail>(dbm =>
|
||||
dbm.DBToon.Id == Toon.PersistentID && dbm.Claimed == false);
|
||||
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)
|
||||
.SetAccountFrom(Toon.D3EntityID)
|
||||
.SetMailId(mail.Id)
|
||||
.SetTitle(mail.Title)
|
||||
.SetBody(mail.Body);
|
||||
if (mail.ItemGBID != -1)
|
||||
mail_row.SetAttachments(D3.Items.MailAttachments.CreateBuilder()
|
||||
mailRow.SetAttachments(D3.Items.MailAttachments.CreateBuilder()
|
||||
.SetItems(D3.Items.ItemList.CreateBuilder()
|
||||
.AddItems(D3.Items.SavedItem.CreateBuilder()
|
||||
.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()
|
||||
{
|
||||
MailContents = D3.GameMessage.MailContents.CreateBuilder()
|
||||
.SetAppendMessages(false)
|
||||
.SetMails(mails)
|
||||
.Build();
|
||||
|
||||
InGameClient.SendMessage(new MailDigestMessage() { MailContents = mail_contents });
|
||||
.Build()
|
||||
});
|
||||
}
|
||||
|
||||
//*/
|
||||
@ -4578,10 +4574,10 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
public void LoadShownTutorials()
|
||||
{
|
||||
var tutorials = new List<byte>();
|
||||
tutorials.Add(64);
|
||||
for (var i = 0; i < 15; i++)
|
||||
tutorials.Add(0);
|
||||
// var tutorials = new List<byte>();
|
||||
// tutorials.Add(64);
|
||||
// for (var i = 0; i < 15; i++)
|
||||
// tutorials.Add(0);
|
||||
var seenTutorials = Toon.GameAccount.DBGameAccount.SeenTutorials;
|
||||
|
||||
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() });
|
||||
}
|
||||
|
||||
private List<ulong> _unlockedAchievements = new();
|
||||
private List<ulong> _unlockedCriterias = new();
|
||||
private readonly List<ulong> _unlockedAchievements = 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 BlocksInARow = 0;
|
||||
public int DodgesInARow { get; set; } = 0;
|
||||
public int BlocksInARow { get; set; }= 0;
|
||||
|
||||
public void GrantAchievement(ulong id)
|
||||
{
|
||||
@ -4606,20 +4602,20 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
_unlockedAchievements.Add(id);
|
||||
try
|
||||
{
|
||||
var Achievement = AchievementSystem.AchievementManager.GetAchievementById(id);
|
||||
long Platinum = -1;
|
||||
foreach (var attr in Achievement.AttributesList)
|
||||
var achievement = AchievementSystem.AchievementManager.GetAchievementById(id);
|
||||
long platinum = -1;
|
||||
foreach (var attr in achievement.AttributesList)
|
||||
if (attr.Key == "Reward Currency Quantity")
|
||||
Platinum = long.Parse(attr.Value);
|
||||
platinum = long.Parse(attr.Value);
|
||||
InGameClient.SendMessage(new MessageSystem.Message.Definitions.Platinum.PlatinumAchievementAwardedMessage
|
||||
{
|
||||
CurrentPlatinum = InGameClient.BnetClient.Account.GameAccount.Platinum,
|
||||
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();
|
||||
}
|
||||
|
||||
@ -4633,33 +4629,33 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
public void AddAchievementCounter(ulong id, uint count)
|
||||
{
|
||||
lock (AchievementCounters)
|
||||
lock (_achievementCounters)
|
||||
{
|
||||
if (!AchievementCounters.ContainsKey(id))
|
||||
AchievementCounters.Add(id, count);
|
||||
if (!_achievementCounters.ContainsKey(id))
|
||||
_achievementCounters.Add(id, count);
|
||||
else
|
||||
AchievementCounters[id] += count;
|
||||
_achievementCounters[id] += count;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckAchievementCounters()
|
||||
{
|
||||
lock (AchievementCounters)
|
||||
lock (_achievementCounters)
|
||||
{
|
||||
foreach (var counter in AchievementCounters)
|
||||
foreach (var counter in _achievementCounters)
|
||||
{
|
||||
if (counter.Value == 0) continue;
|
||||
UpdateSingleAchievementCounter(counter.Key, counter.Value);
|
||||
}
|
||||
|
||||
AchievementCounters.Clear();
|
||||
_achievementCounters.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void GrantCriteria(ulong id)
|
||||
{
|
||||
if (_unlockedCriterias.Contains(id)) return;
|
||||
_unlockedCriterias.Add(id);
|
||||
if (_unlockCriteria.Contains(id)) return;
|
||||
_unlockCriteria.Add(id);
|
||||
try
|
||||
{
|
||||
GameServer.ClientSystem.GameServer.GSBackend.GrantCriteria(Toon.GameAccount.PersistentID, id);
|
||||
@ -4824,13 +4820,13 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
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;
|
||||
CastResult = result;
|
||||
Attributes[GameAttribute.Looping_Animation_Start_Time] = World.Game.TickCounter;
|
||||
Attributes[GameAttribute.Looping_Animation_End_Time] = World.Game.TickCounter + durationTicks;
|
||||
CastingSnoPower = skillsno;
|
||||
CastingSnoPower = skillSno;
|
||||
if (CastingSnoPower != -1)
|
||||
{
|
||||
Attributes[GameAttribute.Buff_Icon_Start_Tick0, CastingSnoPower] = World.Game.TickCounter;
|
||||
@ -4882,7 +4878,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
#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
|
||||
{
|
||||
@ -4910,7 +4906,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
public int SecondaryResourceID => (int)Toon.HeroTable.SecondaryResource;
|
||||
|
||||
[Obsolete]
|
||||
[Obsolete("Not used anymore. Should it be removed?")]
|
||||
public bool IsInTown
|
||||
{
|
||||
get
|
||||
@ -4945,7 +4941,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
(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 */
|
||||
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 */
|
||||
};
|
||||
|
||||
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,
|
||||
//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
|
||||
|
||||
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
|
||||
Attributes[GameAttribute.Hitpoints_Cur] = Attributes[GameAttribute.Hitpoints_Max_Total];
|
||||
// set resources to max as well
|
||||
@ -5165,8 +5159,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Level++;
|
||||
Attributes[GameAttribute.Level]++;
|
||||
Toon.LevelUp();
|
||||
if (World.Game.MonsterLevel + 1 ==
|
||||
Attributes[GameAttribute.Level]) //if this is suitable level to update
|
||||
if (World.Game.MonsterLevel + 1 == Attributes[GameAttribute.Level]) //if this is suitable level to update
|
||||
World.Game.UpdateLevel(Attributes[GameAttribute.Level]);
|
||||
|
||||
InGameClient.SendMessage(new PlayerLevel()
|
||||
@ -5326,7 +5319,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
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];
|
||||
var itemList = GetItemsInRange(radius);
|
||||
foreach (var item in itemList)
|
||||
@ -5501,12 +5494,11 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
item.Destroy();
|
||||
}
|
||||
|
||||
else if (item.ItemDefinition.Name == "p1_normal_rifts_Orb" ||
|
||||
item.ItemDefinition.Name == "p1_tiered_rifts_Orb")
|
||||
else if (item.ItemDefinition.Name is "p1_normal_rifts_Orb" or "p1_tiered_rifts_Orb")
|
||||
{
|
||||
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)
|
||||
{
|
||||
plr.InGameClient.SendMessage(new FloatDataMessage(Opcodes.DunggeonFinderProgressGlyphPickUp)
|
||||
@ -5630,7 +5622,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
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.Is_Loot_Run_Boss] = true;
|
||||
boss.Attributes.BroadcastChangedIfRevealed();
|
||||
@ -5658,23 +5650,26 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
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;
|
||||
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;
|
||||
AddHP(quantity, GuidingLight);
|
||||
AddHP(quantity, guidingLight);
|
||||
}
|
||||
|
||||
public override void AddHP(float quantity, bool guidingLight = false)
|
||||
{
|
||||
if (Dead) return;
|
||||
if (quantity == 0) return;
|
||||
if (quantity > 0)
|
||||
switch (quantity)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
case > 0:
|
||||
{
|
||||
if (Attributes[GameAttribute.Hitpoints_Cur] < Attributes[GameAttribute.Hitpoints_Max_Total])
|
||||
{
|
||||
@ -5706,14 +5701,16 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Type = FloatingNumberMessage.FloatType.Green
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
default:
|
||||
Attributes[GameAttribute.Hitpoints_Cur] = Math.Max(
|
||||
Attributes[GameAttribute.Hitpoints_Cur] + quantity,
|
||||
0);
|
||||
|
||||
Attributes.BroadcastChangedIfRevealed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5731,9 +5728,9 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
#region Resource Generate/Use
|
||||
|
||||
private int _DisciplineSpent = 0;
|
||||
private int _HatredSpent = 0;
|
||||
private int _WrathSpent = 0;
|
||||
private int _disciplineSpent = 0;
|
||||
private int _hatredSpent = 0;
|
||||
private int _wrathSpent = 0;
|
||||
|
||||
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
|
||||
amount *= 1.35f;
|
||||
|
||||
_ModifyResourceAttribute(PrimaryResourceID, amount);
|
||||
ModifyResourceAttribute(PrimaryResourceID, amount);
|
||||
}
|
||||
|
||||
public void UsePrimaryResource(float amount, bool tick = false)
|
||||
@ -5757,28 +5754,28 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
amount = amount * (1f - DecreaseUseResourcePercent);
|
||||
if (Toon.Class == ToonClass.Crusader)
|
||||
{
|
||||
_WrathSpent += (int)amount;
|
||||
_wrathSpent += (int)amount;
|
||||
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
|
||||
if (!tick && World.BuffManager.HasBuff<CrusaderLawsOfHope.LawsShieldBuff>(this))
|
||||
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))
|
||||
World.BuffManager.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(this).wrathBlast = true;
|
||||
}
|
||||
|
||||
if (Toon.Class == ToonClass.DemonHunter)
|
||||
{
|
||||
_HatredSpent += (int)amount;
|
||||
_hatredSpent += (int)amount;
|
||||
|
||||
if (_HatredSpent >= 150 && _DisciplineSpent >= 50)
|
||||
if (_hatredSpent >= 150 && _disciplineSpent >= 50)
|
||||
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)
|
||||
@ -5813,12 +5810,12 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
if (SkillSet.HasPassive(205398) && Attributes[GameAttribute.Hitpoints_Cur] <
|
||||
Attributes[GameAttribute.Hitpoints_Max_Total] * 0.35f) //Relentless (Barbarian)
|
||||
amount *= 0.25f;
|
||||
_ModifyResourceAttribute(PrimaryResourceID, -amount);
|
||||
ModifyResourceAttribute(PrimaryResourceID, -amount);
|
||||
}
|
||||
|
||||
public void GenerateSecondaryResource(float amount)
|
||||
{
|
||||
_ModifyResourceAttribute(SecondaryResourceID, amount);
|
||||
ModifyResourceAttribute(SecondaryResourceID, amount);
|
||||
}
|
||||
|
||||
public void UseSecondaryResource(float amount)
|
||||
@ -5833,18 +5830,18 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
if (Toon.Class == ToonClass.DemonHunter)
|
||||
{
|
||||
_DisciplineSpent += (int)amount;
|
||||
_disciplineSpent += (int)amount;
|
||||
|
||||
if (_HatredSpent >= 150 && _DisciplineSpent >= 50)
|
||||
if (_hatredSpent >= 150 && _disciplineSpent >= 50)
|
||||
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;
|
||||
var current = Attributes[GameAttribute.Resource_Cur, resourceID];
|
||||
@ -5857,7 +5854,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Attributes[GameAttribute.Resource_Cur, resourceID] + amount,
|
||||
0f);
|
||||
|
||||
if (current == Attributes[GameAttribute.Resource_Cur, resourceID]) return;
|
||||
if (Math.Abs(current - Attributes[GameAttribute.Resource_Cur, resourceID]) < Globals.FLOAT_TOLERANCE) return;
|
||||
|
||||
Attributes.BroadcastChangedIfRevealed();
|
||||
}
|
||||
|
||||
@ -266,9 +266,9 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
}, Target);
|
||||
|
||||
if (Context?.User != null)
|
||||
if (Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 247640] - 1) < 0.001 ||
|
||||
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249963] - 1) < 0.001 ||
|
||||
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 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) < Globals.FLOAT_TOLERANCE ||
|
||||
Math.Abs(Context.User.Attributes[GameAttribute.Item_Power_Passive, 249954] - 1) < Globals.FLOAT_TOLERANCE ||
|
||||
(float)FastRandom.Instance.NextDouble() < 0.1f ||
|
||||
Target.World.SNO == WorldSno.a1dun_random_level01)
|
||||
switch ((int)DeathDamageType.HitEffect)
|
||||
@ -1066,7 +1066,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
{
|
||||
//death implementation
|
||||
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.StopCasting();
|
||||
Target.World.BuffManager.RemoveAllBuffs(Target, false);
|
||||
|
||||
@ -24,25 +24,22 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
public class HitPayload : Payload
|
||||
{
|
||||
public static readonly Logger Logger = LogManager.CreateLogger();
|
||||
public float TotalDamage;
|
||||
public DamageType DominantDamageType;
|
||||
public Dictionary<DamageType, float> ElementDamages;
|
||||
public bool IsCriticalHit;
|
||||
public bool IsDodged;
|
||||
public bool IsWeaponDamage;
|
||||
public float TotalDamage { get; set; }
|
||||
public DamageType DominantDamageType { get; set; }
|
||||
public Dictionary<DamageType, float> ElementDamages { get; set; }
|
||||
public bool IsCriticalHit { get; set; }
|
||||
public bool IsDodged { get; set; }
|
||||
public bool IsWeaponDamage { get; set; }
|
||||
|
||||
public bool Successful = false;
|
||||
public bool Blocked = false;
|
||||
public bool Successful { get; set; }
|
||||
public bool Blocked { get; set; }
|
||||
|
||||
public bool AutomaticHitEffects = true;
|
||||
public Action<DeathPayload> OnDeath = null;
|
||||
|
||||
private bool WaitTo(TickTimer timer)
|
||||
{
|
||||
while (timer.TimedOut != true)
|
||||
{
|
||||
|
||||
}
|
||||
while (timer.TimedOut != true) ;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -144,7 +141,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
if (criticalHit)
|
||||
{
|
||||
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())
|
||||
(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)
|
||||
{
|
||||
case Player:
|
||||
case Player plr:
|
||||
if (IsWeaponDamage)
|
||||
{
|
||||
var plr = Context.User as Player;
|
||||
TotalDamage = TotalDamage * (1 + (plr.PrimaryAttribute / 100f));
|
||||
if (FastRandom.Instance.NextDouble() < Context.GetProcCoefficient())
|
||||
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())
|
||||
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;
|
||||
|
||||
if (plr.SkillSet.HasPassive(155725))
|
||||
@ -239,12 +235,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
|
||||
if (criticalHit)
|
||||
{
|
||||
plr.AddTimedAction(1f, new Action<int>((q) => plr.World.BuffManager.RemoveBuffs(plr, 155715)));
|
||||
plr.AddTimedAction(2f, new Action<int>((q) =>
|
||||
plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 155715));
|
||||
plr.AddTimedAction(2f, _ =>
|
||||
{
|
||||
if (plr.SkillSet.HasPassive(155715))
|
||||
plr.World.BuffManager.AddBuff(plr, plr, new SharpshooterBuff());
|
||||
}));
|
||||
});
|
||||
}
|
||||
break;
|
||||
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.GetFirstBuff<CrusaderAkaratChampion.AkaratBuff>(plr).CDRActive)
|
||||
if (FastRandom.Instance.NextDouble() < 0.5f * Context.GetProcCoefficient())
|
||||
foreach (var cdBuff in plr.World.BuffManager.GetBuffs<CooldownBuff>(plr))
|
||||
if (!(cdBuff.TargetPowerSNO == 269032)) //do not CDR AkaratChampionBuff
|
||||
cdBuff.Reduce(60);
|
||||
foreach (var cooldownBuff in plr.World.BuffManager.GetBuffs<CooldownBuff>(plr))
|
||||
if (cooldownBuff.TargetPowerSNO != 269032) //do not CDR AkaratChampionBuff
|
||||
cooldownBuff.Reduce(60);
|
||||
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];
|
||||
|
||||
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();
|
||||
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
plr.World.BuffManager.AddBuff(plr, Target, new KnockbackBuff(3f));
|
||||
plr.World.BuffManager.AddBuff(plr, monster, new KnockbackBuff(3f));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Minion:
|
||||
var mn = Context.User as Minion;
|
||||
case Minion mn:
|
||||
TotalDamage *= (1 + (mn.PrimaryAttribute / 100f));
|
||||
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 || mn is CorpseSpiderQueen))
|
||||
if (mstr.SkillSet.HasPassive(209041) && mn is CorpseSpider or CorpseSpiderQueen)
|
||||
mstr.World.BuffManager.AddBuff(mstr, mstr, new VisionQuestBuff());
|
||||
|
||||
if (mn.SNO == ActorSno._dh_companion_spider)
|
||||
@ -438,12 +431,18 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
}
|
||||
|
||||
|
||||
if (Target is Player playerTarget) //check for passives here (incoming damage)
|
||||
switch (Target)
|
||||
{
|
||||
//check for passives here (incoming damage)
|
||||
case Player playerTarget:
|
||||
{
|
||||
if (!playerTarget.Attributes[GameAttribute.Cannot_Dodge] && FastRandom.Instance.NextDouble() < playerTarget.DodgeChance)
|
||||
IsDodged = true;
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.Monk) //Monk defensive passives
|
||||
switch (playerTarget.Toon.Class)
|
||||
{
|
||||
//Monk defensive passives
|
||||
case ToonClass.Monk:
|
||||
{
|
||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||
|
||||
@ -459,9 +458,10 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
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;
|
||||
}
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.Barbarian) //Barb defensive passives
|
||||
//Barb defensive passives
|
||||
case ToonClass.Barbarian:
|
||||
{
|
||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||
|
||||
@ -471,9 +471,10 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
|
||||
if (playerTarget.SkillSet.HasPassive(205398) && (playerTarget.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage) < (playerTarget.Attributes[GameAttribute.Hitpoints_Max_Total] * 0.2f)) //Relentless (barbarian)
|
||||
TotalDamage *= 0.5f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.Wizard) //Wizard defensive passives
|
||||
//Wizard defensive passives
|
||||
case ToonClass.Wizard:
|
||||
{
|
||||
if (playerTarget.SkillSet.HasPassive(208471)) //GlassCannon (Wizard)
|
||||
TotalDamage *= 1.1f;
|
||||
@ -498,21 +499,25 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
cdBuff.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.WitchDoctor) //Witch Doctor defensive passives
|
||||
break;
|
||||
}
|
||||
//Witch Doctor defensive passives
|
||||
case ToonClass.WitchDoctor:
|
||||
{
|
||||
if (playerTarget.SkillSet.HasPassive(217968)) //JungleFortitude (WD)
|
||||
TotalDamage *= 0.85f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.DemonHunter) //DH defensive passives
|
||||
//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;
|
||||
}
|
||||
|
||||
if (playerTarget.Toon.Class == ToonClass.Crusader) //Crusader defensive passives
|
||||
//Crusader defensive passives
|
||||
case ToonClass.Crusader:
|
||||
{
|
||||
TotalDamage *= 0.7f; //Class damage reduction bonus
|
||||
|
||||
@ -532,11 +537,15 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
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;
|
||||
}
|
||||
else if (Target is Minion { Master: Player playerOwner }) //check for passives here (incoming damage, minions)
|
||||
//check for passives here (incoming damage, minions)
|
||||
case Minion { Master: Player playerOwner }:
|
||||
{
|
||||
var plr = playerOwner;
|
||||
|
||||
@ -549,26 +558,22 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
TotalDamage *= 0.85f;
|
||||
|
||||
TotalDamage *= 0.1f; //hack for unkillable minions
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float ReductionFromResistance(float resistance, int attackerLevel)
|
||||
{
|
||||
return 1f - (resistance / ((5 * attackerLevel) + resistance));
|
||||
}
|
||||
private static float ReductionFromResistance(float resistance, int attackerLevel) => 1f - (resistance / ((5 * attackerLevel) + resistance));
|
||||
|
||||
private static float ReductionFromArmor(float armor, int attackerLevel)
|
||||
{
|
||||
return 1f - (armor / ((50 * attackerLevel) + armor));
|
||||
}
|
||||
private static float ReductionFromArmor(float armor, int attackerLevel) => 1f - (armor / ((50 * attackerLevel) + armor));
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -625,12 +630,12 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
|
||||
else if (plr.Toon.Class == ToonClass.DemonHunter) //Awareness
|
||||
{
|
||||
plr.AddTimedAction(1f, new Action<int>((q) => plr.World.BuffManager.RemoveBuffs(plr, 324770)));
|
||||
plr.AddTimedAction(2f, new Action<int>((q) =>
|
||||
plr.AddTimedAction(1f, _ => plr.World.BuffManager.RemoveBuffs(plr, 324770));
|
||||
plr.AddTimedAction(2f, _ =>
|
||||
{
|
||||
if (plr.SkillSet.HasPassive(324770))
|
||||
plr.World.BuffManager.AddBuff(plr, plr, new AwarenessBuff());
|
||||
}));
|
||||
});
|
||||
}
|
||||
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)
|
||||
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)
|
||||
{
|
||||
@ -703,19 +707,17 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
hireling.AddHP(hireling.Attributes[GameAttribute.Hitpoints_On_Hit]);
|
||||
}
|
||||
|
||||
|
||||
// floating damage number
|
||||
if (Target.World != null)
|
||||
// make player damage red, all other damage white
|
||||
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),
|
||||
Number = TotalDamage,
|
||||
// make player damage red, all other damage white
|
||||
Type = IsCriticalHit ?
|
||||
(Target is Player) ? FloatingNumberMessage.FloatType.RedCritical : FloatingNumberMessage.FloatType.Golden
|
||||
:
|
||||
(Target is Player) ? FloatingNumberMessage.FloatType.Red : FloatingNumberMessage.FloatType.White
|
||||
Type = type
|
||||
}, 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
|
||||
int overridenSound = Context.EvalTag(PowerKeys.HitsoundOverride);
|
||||
int hitsound = overridenSound != -1 ? overridenSound : 1;
|
||||
if (hitsound > 0)
|
||||
Target.PlayEffect(Effect.Hit, hitsound);
|
||||
int hitSound = overridenSound != -1 ? overridenSound : 1;
|
||||
if (hitSound > 0)
|
||||
Target.PlayEffect(Effect.Hit, hitSound);
|
||||
}
|
||||
}
|
||||
|
||||
// update hp
|
||||
float new_hp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f);
|
||||
Target.Attributes[GameAttribute.Hitpoints_Cur] = new_hp;
|
||||
float newHp = Math.Max(Target.Attributes[GameAttribute.Hitpoints_Cur] - TotalDamage, 0f);
|
||||
Target.Attributes[GameAttribute.Hitpoints_Cur] = newHp;
|
||||
Target.Attributes.BroadcastChangedIfRevealed();
|
||||
|
||||
//thorns
|
||||
@ -766,21 +768,23 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Payloads
|
||||
*/
|
||||
|
||||
// if hp=0 do death
|
||||
if (new_hp <= 0f)
|
||||
if (newHp <= 0f)
|
||||
{
|
||||
var deathload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot);
|
||||
deathload.AutomaticHitEffects = AutomaticHitEffects;
|
||||
var deathPayload = new DeathPayload(Context, DominantDamageType, Target, Target.HasLoot)
|
||||
{
|
||||
AutomaticHitEffects = AutomaticHitEffects
|
||||
};
|
||||
|
||||
if (deathload.Successful)
|
||||
if (deathPayload.Successful)
|
||||
{
|
||||
Target.Dead = true;
|
||||
try
|
||||
{
|
||||
if (OnDeath != null && AutomaticHitEffects)
|
||||
OnDeath(deathload);
|
||||
OnDeath(deathPayload);
|
||||
}
|
||||
catch { }
|
||||
deathload.Apply();
|
||||
deathPayload.Apply();
|
||||
}
|
||||
}
|
||||
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))
|
||||
{
|
||||
float BackSpeed = Target.WalkSpeed;
|
||||
float backSpeed = Target.WalkSpeed;
|
||||
Target.WalkSpeed = 0f;
|
||||
TickTimer Timeout = new SecondsTickTimer(Target.World.Game, 0.3f);
|
||||
var Boom = Task<bool>.Factory.StartNew(() => WaitTo(Timeout));
|
||||
Boom.ContinueWith(delegate
|
||||
TickTimer timeout = new SecondsTickTimer(Target.World.Game, 0.3f);
|
||||
var boom = Task<bool>.Factory.StartNew(() => WaitTo(timeout));
|
||||
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)
|
||||
{
|
||||
if (Math.Abs(angle - (-1)) < 0.0001)
|
||||
if (Math.Abs(angle - -1) < Globals.FLOAT_TOLERANCE)
|
||||
angle = (float)(Rand.NextDouble() * (Math.PI * 2));
|
||||
if (timeout == null)
|
||||
{
|
||||
if (_defaultEffectTimeout == null)
|
||||
_defaultEffectTimeout = new SecondsTickTimer(World.Game, 2f); // default timeout of 2 seconds for now
|
||||
|
||||
_defaultEffectTimeout ??= new SecondsTickTimer(World.Game, 2f);
|
||||
timeout = _defaultEffectTimeout;
|
||||
}
|
||||
|
||||
var actor = new EffectActor(this, actorSNO, position);
|
||||
actor.Timeout = timeout;
|
||||
actor.Spawn(angle);
|
||||
//187359
|
||||
return actor;
|
||||
}
|
||||
|
||||
|
||||
@ -11,35 +11,54 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
||||
{
|
||||
public class SkillSet
|
||||
{
|
||||
public ToonClass @Class;
|
||||
public Toon Toon { get; private set; }
|
||||
public Player Player { get; private set; }
|
||||
public ToonClass ToonClass { get; }
|
||||
public Toon Toon { get; }
|
||||
public Player Player { get; }
|
||||
|
||||
public ActiveSkillSavedData[] ActiveSkills;
|
||||
public HotbarButtonData[] HotBarSkills;
|
||||
public int[] PassiveSkills;
|
||||
public ActiveSkillSavedData[] ActiveSkills { get; }
|
||||
public HotbarButtonData[] HotBarSkills { get; }
|
||||
public int[] PassiveSkills { get; }
|
||||
|
||||
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;
|
||||
var dbToon = player.Toon.DBToon;
|
||||
// var dbToon = player.Toon.DBToon;
|
||||
var dbActiveSkills = player.Toon.DBActiveSkills;
|
||||
ActiveSkills = new ActiveSkillSavedData[6] {
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill0,
|
||||
snoRune = dbActiveSkills.Rune0 },
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill1,
|
||||
snoRune = dbActiveSkills.Rune1 },
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill2,
|
||||
snoRune = dbActiveSkills.Rune2 },
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill3,
|
||||
snoRune = dbActiveSkills.Rune3 },
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill4,
|
||||
snoRune = dbActiveSkills.Rune4 },
|
||||
new ActiveSkillSavedData { snoSkill = dbActiveSkills.Skill5,
|
||||
snoRune = dbActiveSkills.Rune5 },
|
||||
ActiveSkills = new ActiveSkillSavedData[6]
|
||||
{
|
||||
new()
|
||||
{
|
||||
snoSkill = dbActiveSkills.Skill0,
|
||||
snoRune = dbActiveSkills.Rune0
|
||||
},
|
||||
new()
|
||||
{
|
||||
snoSkill = dbActiveSkills.Skill1,
|
||||
snoRune = dbActiveSkills.Rune1
|
||||
},
|
||||
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] {
|
||||
@ -51,18 +70,18 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
||||
//}
|
||||
|
||||
HotBarSkills = new HotbarButtonData[6] {
|
||||
new HotbarButtonData { 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 HotbarButtonData { 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 HotbarButtonData { 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[0].snoSkill, ItemAnn = ActiveSkills[0].snoRune, ItemGBId = -1, RuneType = -1 }, // left-click
|
||||
new() { SNOSkill = ActiveSkills[1].snoSkill, ItemAnn = ActiveSkills[1].snoRune, ItemGBId = -1, RuneType = -1 }, // right-click
|
||||
new() { SNOSkill = ActiveSkills[2].snoSkill, ItemAnn = ActiveSkills[2].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-1
|
||||
new() { SNOSkill = ActiveSkills[3].snoSkill, ItemAnn = ActiveSkills[3].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-2
|
||||
new() { SNOSkill = ActiveSkills[4].snoSkill, ItemAnn = ActiveSkills[4].snoRune, ItemGBId = -1, RuneType = -1 }, // bar-3
|
||||
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)
|
||||
{
|
||||
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;
|
||||
switch (hotBarIndex)
|
||||
{
|
||||
@ -119,31 +138,12 @@ namespace DiIiS_NA.GameServer.GSSystem.SkillsSystem
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasPassive(int passiveId)
|
||||
{
|
||||
if (PassiveSkills.Contains(passiveId))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public bool HasPassive(int passiveId) => PassiveSkills.Contains(passiveId);
|
||||
|
||||
public bool HasSkill(int skillId)
|
||||
{
|
||||
return ActiveSkills.Any(s => s.snoSkill == skillId);
|
||||
}
|
||||
public bool HasSkill(int skillId) => ActiveSkills.Any(s => s.snoSkill == skillId);
|
||||
|
||||
public bool HasSkillWithRune(int skillId, int runeId)
|
||||
{
|
||||
return ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId);
|
||||
}
|
||||
public bool HasSkillWithRune(int skillId, int runeId) => ActiveSkills.Any(s => s.snoSkill == skillId && s.snoRune == runeId);
|
||||
|
||||
|
||||
public bool HasItemPassiveProc(int passiveId)
|
||||
{
|
||||
if ((float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId])
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public bool HasItemPassiveProc(int passiveId) => (float)FastRandom.Instance.NextDouble() < Player.Attributes[GameAttribute.Item_Power_Passive, passiveId];
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,14 @@ namespace DiIiS_NA.GameServer
|
||||
set => Set(nameof(CoreActive), value);
|
||||
}
|
||||
|
||||
public bool IWServer
|
||||
{
|
||||
get => GetBoolean(nameof(IWServer), true);
|
||||
set => Set(nameof(IWServer), value);
|
||||
}
|
||||
|
||||
#region Game Mods
|
||||
|
||||
/// <summary>
|
||||
/// Rate of experience gain.
|
||||
/// </summary>
|
||||
@ -101,12 +109,6 @@ namespace DiIiS_NA.GameServer
|
||||
set => Set(nameof(RateMonsterDMG), value);
|
||||
}
|
||||
|
||||
public bool IWServer
|
||||
{
|
||||
get => GetBoolean(nameof(IWServer), true);
|
||||
set => Set(nameof(IWServer), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Percentage that a unique, legendary, set or special item created is unidentified
|
||||
/// </summary>
|
||||
@ -197,6 +199,79 @@ namespace DiIiS_NA.GameServer
|
||||
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();
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@ using System.Configuration;
|
||||
|
||||
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,
|
||||
BadRequest = 400,
|
||||
NotFound = 404,
|
||||
InternalServerError = 500
|
||||
InternalServerError = 500,
|
||||
BadGateway = 502
|
||||
}
|
||||
|
||||
public class HttpHelper
|
||||
|
||||
@ -12,6 +12,7 @@ using DiIiS_NA.REST.Data.Authentication;
|
||||
using DiIiS_NA.REST.JSON;
|
||||
using DiIiS_NA.LoginServer.AccountsSystem;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Web;
|
||||
using DiIiS_NA.GameServer.MessageSystem;
|
||||
@ -41,26 +42,19 @@ namespace DiIiS_NA.REST
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
||||
Logger.Debug($"$[yellow]$REST Request: $[/]$ {httpRequest.Method} {httpRequest.Path}");
|
||||
if (httpRequest.Path == "200")
|
||||
{
|
||||
|
||||
}
|
||||
else if (httpRequest.Path.Contains("/client/alert"))
|
||||
{
|
||||
switch (httpRequest.Method)
|
||||
{
|
||||
case "GET":
|
||||
default:
|
||||
HandleInfoRequest(httpRequest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (httpRequest.Path.Contains("/battlenet/login"))
|
||||
{
|
||||
switch (httpRequest.Method)
|
||||
{
|
||||
case "GET":
|
||||
default:
|
||||
HandleConnectRequest(httpRequest);
|
||||
break;
|
||||
@ -69,30 +63,34 @@ namespace DiIiS_NA.REST
|
||||
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();
|
||||
}
|
||||
|
||||
public void HandleConnectRequest(HttpHeader request)
|
||||
void HandleConnectRequest(HttpHeader request)
|
||||
{
|
||||
SendResponse(HttpCode.OK, SessionManager.Instance.GetFormInput());
|
||||
}
|
||||
|
||||
public void HandleInfoRequest(HttpHeader request)
|
||||
void HandleInfoRequest(HttpHeader request)
|
||||
{
|
||||
SendResponseHtml(HttpCode.OK, "Welcome to BlizzLess.Net" +
|
||||
"\nBuild " + Program.Build +
|
||||
"\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)
|
||||
{
|
||||
AsyncWrite(HttpHelper.CreateResponse(code, JSON.Json.CreateString(response)));
|
||||
@ -107,7 +105,8 @@ namespace DiIiS_NA.REST
|
||||
{
|
||||
AsyncRead();
|
||||
}
|
||||
public void HandleLoginRequest(HttpHeader request)
|
||||
|
||||
void HandleLoginRequest(HttpHeader request)
|
||||
{
|
||||
LogonData loginForm = Json.CreateObject<LogonData>(request.Content);
|
||||
LogonResult loginResult = new LogonResult();
|
||||
|
||||
Loading…
Reference in New Issue
user.block.title