Improvement world bosses;
Command to open all doors; Do not show logs of colors
This commit is contained in:
parent
b95ab45e62
commit
8c9dc3c9d5
@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace DiIiS_NA.Core.Logging
|
||||
@ -24,48 +25,55 @@ namespace DiIiS_NA.Core.Logging
|
||||
/// <param name="reset">Reset log file on application startup?</param>
|
||||
public FileTarget(string fileName, Logger.Level minLevel, Logger.Level maxLevel, bool includeTimeStamps, bool reset = false)
|
||||
{
|
||||
this.MinimumLevel = minLevel;
|
||||
this.MaximumLevel = maxLevel;
|
||||
this.IncludeTimeStamps = includeTimeStamps;
|
||||
this._fileName = fileName;
|
||||
this._fileTimestamp = DateTime.Now.ToString("yyyyMMdd_HHmm");
|
||||
this._filePath = string.Format("{0}/{1}/{2}", LogConfig.Instance.LoggingRoot, this._fileTimestamp, _fileName);
|
||||
this._fileIndex = 0;
|
||||
MinimumLevel = minLevel;
|
||||
MaximumLevel = maxLevel;
|
||||
IncludeTimeStamps = includeTimeStamps;
|
||||
_fileName = fileName;
|
||||
_fileTimestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm");
|
||||
_filePath = $"{LogConfig.Instance.LoggingRoot}/{_fileTimestamp}/{_fileName}";
|
||||
_fileIndex = 0;
|
||||
|
||||
if (!Directory.Exists(LogConfig.Instance.LoggingRoot)) // create logging directory if it does not exist yet.
|
||||
Directory.CreateDirectory(LogConfig.Instance.LoggingRoot);
|
||||
|
||||
if (!Directory.Exists(string.Format("{0}/{1}", LogConfig.Instance.LoggingRoot, this._fileTimestamp))) // create logging directory if it does not exist yet.
|
||||
Directory.CreateDirectory(string.Format("{0}/{1}", LogConfig.Instance.LoggingRoot, this._fileTimestamp));
|
||||
if (!Directory.Exists($"{LogConfig.Instance.LoggingRoot}/{_fileTimestamp}")) // create logging directory if it does not exist yet.
|
||||
Directory.CreateDirectory($"{LogConfig.Instance.LoggingRoot}/{_fileTimestamp}");
|
||||
|
||||
this._fileStream = new FileStream(_filePath, reset ? FileMode.Create : FileMode.Append, FileAccess.Write, FileShare.Read); // init the file stream.
|
||||
this._logStream = new StreamWriter(this._fileStream) { AutoFlush = true }; // init the stream writer.
|
||||
this.TaskQueue = new ConcurrentQueue<Action>();
|
||||
this.LoggerThread = new Thread(this.CheckQueue) { Name = "Logger", IsBackground = true };
|
||||
this.LoggerThread.Start();
|
||||
_fileStream = new FileStream(_filePath, reset ? FileMode.Create : FileMode.Append, FileAccess.Write, FileShare.Read); // init the file stream.
|
||||
_logStream = new StreamWriter(_fileStream) { AutoFlush = true }; // init the stream writer.
|
||||
TaskQueue = new ConcurrentQueue<Action>();
|
||||
LoggerThread = new Thread(CheckQueue) { Name = "Logger", IsBackground = true };
|
||||
LoggerThread.Start();
|
||||
}
|
||||
|
||||
public void CheckQueue()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Action action = null;
|
||||
if (this.TaskQueue.TryDequeue(out action))
|
||||
if (TaskQueue.TryDequeue(out var action))
|
||||
action.Invoke();
|
||||
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace the colors from AnsiColor so they do not appear in the log file.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
private string NoColors(string message) => Regex.Replace(message, @"\$\[[\w\W\d\s_\-\/]+\]\$", "");
|
||||
|
||||
/// <param name="level">Log level.</param>
|
||||
/// <param name="logger">Source of the log message.</param>
|
||||
/// <param name="message">Log message.</param>
|
||||
public override void LogMessage(Logger.Level level, string logger, string message)
|
||||
{
|
||||
this.TaskQueue.Enqueue(() =>
|
||||
TaskQueue.Enqueue(() =>
|
||||
{
|
||||
var timeStamp = this.IncludeTimeStamps ? "[" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + "] " : "";
|
||||
if (!this._disposed) // make sure we're not disposed.
|
||||
message = NoColors(message);
|
||||
var timeStamp = IncludeTimeStamps ? "[" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + "] " : "";
|
||||
if (!_disposed) // make sure we're not disposed.
|
||||
{
|
||||
/*
|
||||
if (this._fileStream.Length >= 20971520) //20 MB limit
|
||||
@ -77,9 +85,9 @@ namespace DiIiS_NA.Core.Logging
|
||||
}
|
||||
//*/
|
||||
if (level > Logger.Level.ChatMessage)
|
||||
this._logStream.WriteLine(string.Format("{0}[{1}] [{2}]: {3}", timeStamp, level.ToString().PadLeft(5), logger, message));
|
||||
_logStream.WriteLine($"{timeStamp}[{level.ToString(),5}] [{logger}]: {message}");
|
||||
else
|
||||
this._logStream.WriteLine(string.Format("{0}{1}", timeStamp, message));
|
||||
_logStream.WriteLine($"{timeStamp}{message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -90,12 +98,13 @@ namespace DiIiS_NA.Core.Logging
|
||||
/// <param name="exception">Exception to be included with log message.</param>
|
||||
public override void LogException(Logger.Level level, string logger, string message, Exception exception)
|
||||
{
|
||||
this.TaskQueue.Enqueue(() =>
|
||||
TaskQueue.Enqueue(() =>
|
||||
{
|
||||
var timeStamp = this.IncludeTimeStamps ? "[" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + "] " : "";
|
||||
if (!this._disposed) // make sure we're not disposed.
|
||||
message = NoColors(message);
|
||||
var timeStamp = IncludeTimeStamps ? "[" + DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + "] " : "";
|
||||
if (!_disposed) // make sure we're not disposed.
|
||||
{
|
||||
this._logStream.WriteLine(
|
||||
_logStream.WriteLine(
|
||||
$"{timeStamp}[{level.ToString(),5}] [{logger}]: {message} - [Exception] {exception}");
|
||||
}
|
||||
});
|
||||
@ -109,23 +118,23 @@ namespace DiIiS_NA.Core.Logging
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this); // Take object out the finalization queue to prevent finalization code for it from executing a second time.
|
||||
GC.SuppressFinalize(this); // Take object out the finalization queue to prevent finalization code for it from executing (~FileTarget).
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this._disposed) return; // if already disposed, just return
|
||||
if (_disposed) return; // if already disposed, just return
|
||||
|
||||
if (disposing) // only dispose managed resources if we're called from directly or in-directly from user code.
|
||||
{
|
||||
this._logStream.Close();
|
||||
this._logStream.Dispose();
|
||||
this._fileStream.Close();
|
||||
this._fileStream.Dispose();
|
||||
_logStream.Close();
|
||||
_logStream.Dispose();
|
||||
_fileStream.Close();
|
||||
_fileStream.Dispose();
|
||||
}
|
||||
|
||||
this._logStream = null;
|
||||
this._fileStream = null;
|
||||
_logStream = null;
|
||||
_fileStream = null;
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ using DiIiS_NA.LoginServer.Battle;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations;
|
||||
using DiIiS_NA.GameServer.GSSystem.GameSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.ObjectsSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.PlayerSystem;
|
||||
@ -25,6 +26,74 @@ using Actor = DiIiS_NA.Core.MPQ.FileFormats.Actor;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
[CommandGroup("doors", "Information about all doors in the vicinity. This is useful for testing purposes.. Useful for testing.", Account.UserLevels.Tester)]
|
||||
public class OpenDoorCommand : CommandGroup
|
||||
{
|
||||
[Command("all", "Activate all doors. This is useful for testing purposes.\nUsage: !open all", Account.UserLevels.Tester)]
|
||||
public string OpenAllDoors(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient?.InGameClient?.Player is not { } player)
|
||||
return "You are not in game.";
|
||||
var world = player.World;
|
||||
var openedDoors = world.OpenAllDoors();
|
||||
if (openedDoors.Length == 0)
|
||||
return "No doors found.";
|
||||
return $"Opened {openedDoors.Length} doors: {string.Join(", ", openedDoors.Select(d => (int)d.SNO + " - " + d.SNO))}";
|
||||
}
|
||||
|
||||
[Command("near", "Activate all nearby doors in the vicinity. This is useful for testing purposes.\nUsage: !open near [distance:50]", Account.UserLevels.Tester)]
|
||||
public string OpenAllDoorsNear(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient?.InGameClient?.Player is not { } player)
|
||||
return "You are not in game.";
|
||||
var world = player.World;
|
||||
|
||||
var distance = 50f;
|
||||
|
||||
if (@params.Length > 0)
|
||||
{
|
||||
if (!float.TryParse(@params[0], out distance) || distance < 1)
|
||||
return "Invalid distance. Distance must be greater than 1.";
|
||||
}
|
||||
|
||||
var openedDoors = player.OpenNearDoors(distance);
|
||||
if (openedDoors.Length == 0)
|
||||
return "No doors found.";
|
||||
return $"Opened {openedDoors.Count()} in a distance of {distance:0.0000} doors: {string.Join(", ", openedDoors)}";
|
||||
}
|
||||
|
||||
[Command("info", "Retrieve all world doors in proximity, sorted in descending order.\nUsage: !open info [distance:50]", Account.UserLevels.Tester)]
|
||||
public string InfoDoorsNear(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient?.InGameClient?.Player is not { } player)
|
||||
return "You are not in game.";
|
||||
var world = player.World;
|
||||
var distance = 50f;
|
||||
|
||||
if (@params.Length > 0)
|
||||
{
|
||||
if (!float.TryParse(@params[0], out distance) || distance < 1)
|
||||
return "Invalid distance. Distance must be greater than 1.";
|
||||
}
|
||||
|
||||
var doors = player.GetNearDoors(distance);
|
||||
if (doors.Length == 0)
|
||||
return "No doors found.";
|
||||
return $"{doors.Length} doors in a distance of {distance:0.0000} doors: \n{string.Join("\n", doors.Select(s=>
|
||||
{
|
||||
var position = player.Position;
|
||||
return s.Position.DistanceSquared(ref position) + " distance - [" + (int)s.SNO + "] " + s.SNO;;
|
||||
}))}";
|
||||
}
|
||||
|
||||
[DefaultCommand()]
|
||||
public string DefaultCommand(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
return "!doors all - Activate all doors. This is useful for testing purposes.\n" +
|
||||
"!doors near [distance:50] - Activate all nearby doors in the vicinity. This is useful for testing purposes.\n" +
|
||||
"!doors info [distance:50] - Retrieve all world doors in proximity, sorted in descending order.";
|
||||
}
|
||||
}
|
||||
[CommandGroup("powerful", "Makes your character with absurd amount of damage. Useful for testing.",
|
||||
Account.UserLevels.Tester)]
|
||||
public class PowerfulCommand : CommandGroup
|
||||
|
||||
@ -133,7 +133,25 @@ namespace DiIiS_NA.GameServer
|
||||
get => GetInt(nameof(ResurrectionCharges), 3);
|
||||
set => Set(nameof(ResurrectionCharges), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boss Health Multiplier
|
||||
/// </summary>
|
||||
public float BossHealthMultiplier
|
||||
{
|
||||
get => GetFloat(nameof(BossHealthMultiplier), 6f);
|
||||
set => Set(nameof(BossHealthMultiplier), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Boss Damage Multiplier
|
||||
/// </summary>
|
||||
public float BossDamageMultiplier
|
||||
{
|
||||
get => GetFloat(nameof(BossDamageMultiplier), 3f);
|
||||
set => Set(nameof(BossDamageMultiplier), value);
|
||||
}
|
||||
|
||||
public static Config Instance { get; } = new();
|
||||
|
||||
private Config() : base("Game-Server")
|
||||
|
||||
@ -104,7 +104,7 @@ namespace DiIiS_NA.GameServer.Core.Types.Math
|
||||
/// </summary>
|
||||
/// <param name="point">the second <see cref="Vector3" /></param>
|
||||
/// <returns>the distance squared between the vectors</returns>
|
||||
public float DistanceSquared(ref Vector3D point)
|
||||
public float DistanceSquared(ref Vector3D point) // todo: remove ref
|
||||
{
|
||||
float x = point.X - X,
|
||||
y = point.Y - Y,
|
||||
@ -183,8 +183,6 @@ namespace DiIiS_NA.GameServer.Core.Types.Math
|
||||
|
||||
public override string ToString() => $"X:{X:F4}, Y:{Y:F4} Z:{Z:F4}";
|
||||
|
||||
public bool IsNear(Vector3D other, float distance) => DistanceSquared(ref other) < distance * distance;
|
||||
|
||||
public bool IsNearSquared(Vector3D other, float distanceSquared) => DistanceSquared(ref other) < distanceSquared;
|
||||
public bool IsNear(Vector3D other, float distance) => DistanceSquared(ref other) < distance;
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations
|
||||
public sealed class Boss : Monster
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.CreateLogger(nameof(Boss));
|
||||
|
||||
public Boss(MapSystem.World world, ActorSno sno, TagMap tags)
|
||||
: base(world, sno, tags)
|
||||
{
|
||||
@ -77,106 +78,113 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations
|
||||
//this.Attributes[GameAttribute.Immune_To_Charm] = true;
|
||||
Attributes[GameAttribute.using_Bossbar] = true;
|
||||
Attributes[GameAttribute.InBossEncounter] = true;
|
||||
Attributes[GameAttribute.Hitpoints_Max] *= 4f;
|
||||
Attributes[GameAttribute.Damage_Weapon_Min, 0] *= 3f;
|
||||
Attributes[GameAttribute.Damage_Weapon_Delta, 0] *= 3f;
|
||||
Attributes[GameAttribute.Hitpoints_Max] *= Config.Instance.BossHealthMultiplier;
|
||||
Attributes[GameAttribute.Damage_Weapon_Min, 0] *= Config.Instance.BossDamageMultiplier;
|
||||
Attributes[GameAttribute.Damage_Weapon_Delta, 0] *= Config.Instance.BossDamageMultiplier;
|
||||
Attributes[GameAttribute.Hitpoints_Cur] = Attributes[GameAttribute.Hitpoints_Max_Total];
|
||||
Attributes[GameAttribute.TeamID] = 10;
|
||||
|
||||
|
||||
WalkSpeed *= 0.5f;
|
||||
MonsterBrain monsterBrain = (Brain as MonsterBrain);
|
||||
switch (sno)
|
||||
if (Brain is MonsterBrain monsterBrain)
|
||||
{
|
||||
case ActorSno._diablo: //Diablo
|
||||
//(Brain as MonsterBrain).RemovePresetPower(30592);
|
||||
//(Brain as MonsterBrain).AddPresetPower(136189); //[136189] Diablo_ClawRip
|
||||
monsterBrain.AddPresetPower(136223); //Diablo_RingOfFire
|
||||
monsterBrain.AddPresetPower(136226); //Diablo_HellSpikes
|
||||
;
|
||||
switch (sno)
|
||||
{
|
||||
case ActorSno._diablo: //Diablo
|
||||
//(Brain as MonsterBrain).RemovePresetPower(30592);
|
||||
//(Brain as MonsterBrain).AddPresetPower(136189); //[136189] Diablo_ClawRip
|
||||
monsterBrain.AddPresetPower(136223); //Diablo_RingOfFire
|
||||
monsterBrain.AddPresetPower(136226); //Diablo_HellSpikes
|
||||
;
|
||||
|
||||
/*
|
||||
[199476] Diablo_StompAndStun
|
||||
[219598] Diablo_Teleport
|
||||
[167560] Diablo_LightningBreath_v2
|
||||
[185997] Diablo_ExpandingFireRing
|
||||
[169212] Diablo_Smash_Puny_Destructible
|
||||
[136828] Diablo_CurseOfAnguish
|
||||
[136829] Diablo_CurseOfPain
|
||||
[136830] Diablo_CurseOfHate
|
||||
[136831] Diablo_CurseOfDestruction
|
||||
|
||||
[439719] Diablo_LightningBreath_LR_TerrorDemon_Clone
|
||||
[214831] Diablo_FireMeteor
|
||||
[161174] Diablo_CorruptionShield
|
||||
[136219] Diablo_LightningBreath
|
||||
[136223] Diablo_RingOfFire
|
||||
[136226] Diablo_HellSpikes
|
||||
|
||||
[214668] Diablo_GetHit
|
||||
|
||||
[136237] Diablo_ShadowVanish
|
||||
[136281] Diablo_ShadowClones
|
||||
[142582] Diablo_ShadowVanish_Charge
|
||||
[136849] Diablo_ShadowVanish_Grab
|
||||
|
||||
[141865] Diablo_Phase1Buff
|
||||
[136850] Diablo_Phase2Buff
|
||||
[136852] Diablo_Phase3Buff
|
||||
[478072] Diablo_StompAndStunMB313
|
||||
|
||||
[478410] Diablo_LightningBreath_Turret_MB313
|
||||
[195816] Diablo_Charge
|
||||
[428985] Diablo_LightningBreath_LR_TerrorDemon
|
||||
[376396] Uber_Gluttony_Gas_Cloud_Diablo
|
||||
[375473] Uber_SkeletonKing_Summon_Skeleton_Diablo
|
||||
[375493] Uber_Maghda_Summon_Beserker_Diablo
|
||||
[365978] Uber_Diablo_StompAndStun
|
||||
[375537] Uber_Despair_SummonMinion_Diablo
|
||||
[375929] UberDiablo_MirrorImage
|
||||
[376039] Uber_Despair_TeleportEnrage_Diablo
|
||||
[376043] Uber_ZoltunKulle_SlowTime_Diablo
|
||||
[376056] Uber_Despair_Volley_Diablo
|
||||
[375439] x1_Uber_Diablo_HellSpikes
|
||||
[375904] Diablo_LightningBreath_Uber
|
||||
[375905] Diablo_ClawRip_Uber
|
||||
[375907] Diablo_RingOfFire_Uber
|
||||
[375908] Diablo_ExpandingFireRing_Uber
|
||||
|
||||
[453765] p43_d1_Diablo_ClawRip
|
||||
|
||||
[328715] x1_Malthael_Diablo_AIState
|
||||
[334760] x1_Malthael_Diablo_TeleportFireNovaLightning
|
||||
|
||||
|
||||
*/
|
||||
break;
|
||||
case ActorSno._skeletonking://Leoric King
|
||||
monsterBrain.RemovePresetPower(30592);
|
||||
monsterBrain.AddPresetPower(30496);
|
||||
monsterBrain.AddPresetPower(30504);
|
||||
monsterBrain.AddPresetPower(73824);
|
||||
monsterBrain.AddPresetPower(79334);
|
||||
break;
|
||||
case ActorSno._butcher://Butcher
|
||||
monsterBrain.AddPresetPower(83008);
|
||||
break;
|
||||
case ActorSno._belial_trueform://Belial (small)
|
||||
HasLoot = false;
|
||||
break;
|
||||
case ActorSno._belial://Belial (big)
|
||||
monsterBrain.AddPresetPower(152540);
|
||||
break;
|
||||
case ActorSno._maghda://Maghda
|
||||
monsterBrain.AddPresetPower(131744); //summon berserker
|
||||
//(Brain as MonsterBrain).AddPresetPower(131745); //mothDust
|
||||
monsterBrain.AddPresetPower(131749); //teleport
|
||||
break;
|
||||
case ActorSno._gluttony://Gluttony
|
||||
monsterBrain.AddPresetPower(93676); //gas cloud
|
||||
monsterBrain.AddPresetPower(211292); //slime spawn
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/*
|
||||
[199476] Diablo_StompAndStun
|
||||
[219598] Diablo_Teleport
|
||||
[167560] Diablo_LightningBreath_v2
|
||||
[185997] Diablo_ExpandingFireRing
|
||||
[169212] Diablo_Smash_Puny_Destructible
|
||||
[136828] Diablo_CurseOfAnguish
|
||||
[136829] Diablo_CurseOfPain
|
||||
[136830] Diablo_CurseOfHate
|
||||
[136831] Diablo_CurseOfDestruction
|
||||
|
||||
[439719] Diablo_LightningBreath_LR_TerrorDemon_Clone
|
||||
[214831] Diablo_FireMeteor
|
||||
[161174] Diablo_CorruptionShield
|
||||
[136219] Diablo_LightningBreath
|
||||
[136223] Diablo_RingOfFire
|
||||
[136226] Diablo_HellSpikes
|
||||
|
||||
[214668] Diablo_GetHit
|
||||
|
||||
[136237] Diablo_ShadowVanish
|
||||
[136281] Diablo_ShadowClones
|
||||
[142582] Diablo_ShadowVanish_Charge
|
||||
[136849] Diablo_ShadowVanish_Grab
|
||||
|
||||
[141865] Diablo_Phase1Buff
|
||||
[136850] Diablo_Phase2Buff
|
||||
[136852] Diablo_Phase3Buff
|
||||
[478072] Diablo_StompAndStunMB313
|
||||
|
||||
[478410] Diablo_LightningBreath_Turret_MB313
|
||||
[195816] Diablo_Charge
|
||||
[428985] Diablo_LightningBreath_LR_TerrorDemon
|
||||
[376396] Uber_Gluttony_Gas_Cloud_Diablo
|
||||
[375473] Uber_SkeletonKing_Summon_Skeleton_Diablo
|
||||
[375493] Uber_Maghda_Summon_Beserker_Diablo
|
||||
[365978] Uber_Diablo_StompAndStun
|
||||
[375537] Uber_Despair_SummonMinion_Diablo
|
||||
[375929] UberDiablo_MirrorImage
|
||||
[376039] Uber_Despair_TeleportEnrage_Diablo
|
||||
[376043] Uber_ZoltunKulle_SlowTime_Diablo
|
||||
[376056] Uber_Despair_Volley_Diablo
|
||||
[375439] x1_Uber_Diablo_HellSpikes
|
||||
[375904] Diablo_LightningBreath_Uber
|
||||
[375905] Diablo_ClawRip_Uber
|
||||
[375907] Diablo_RingOfFire_Uber
|
||||
[375908] Diablo_ExpandingFireRing_Uber
|
||||
|
||||
[453765] p43_d1_Diablo_ClawRip
|
||||
|
||||
[328715] x1_Malthael_Diablo_AIState
|
||||
[334760] x1_Malthael_Diablo_TeleportFireNovaLightning
|
||||
|
||||
|
||||
*/
|
||||
break;
|
||||
case ActorSno._skeletonking: //Leoric King
|
||||
monsterBrain.RemovePresetPower(30592);
|
||||
monsterBrain.AddPresetPower(30496);
|
||||
monsterBrain.AddPresetPower(30504);
|
||||
monsterBrain.AddPresetPower(73824);
|
||||
monsterBrain.AddPresetPower(79334);
|
||||
break;
|
||||
case ActorSno._butcher: //Butcher
|
||||
monsterBrain.AddPresetPower(83008);
|
||||
break;
|
||||
case ActorSno._belial_trueform: //Belial (small)
|
||||
HasLoot = false;
|
||||
break;
|
||||
case ActorSno._belial: //Belial (big)
|
||||
monsterBrain.AddPresetPower(152540);
|
||||
break;
|
||||
case ActorSno._maghda: //Maghda
|
||||
monsterBrain.AddPresetPower(131744); //summon berserker
|
||||
//(Brain as MonsterBrain).AddPresetPower(131745); //mothDust
|
||||
monsterBrain.AddPresetPower(131749); //teleport
|
||||
break;
|
||||
case ActorSno._gluttony: //Gluttony
|
||||
monsterBrain.AddPresetPower(93676); //gas cloud
|
||||
monsterBrain.AddPresetPower(211292); //slime spawn
|
||||
break;
|
||||
default:
|
||||
Logger.Warn($"Unhandled boss type {sno}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error($"Boss $[underline red]${GetType().Name}$[/]$ ({sno}) has no monster brain!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ using System.Threading.Tasks;
|
||||
namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations
|
||||
{
|
||||
[HandledSNO(ActorSno._caout_stingingwinds_khamsin_gate)]
|
||||
class Door : Gizmo
|
||||
public class Door : Gizmo
|
||||
{
|
||||
public bool isOpened = false;
|
||||
public Portal NearestPortal = null;
|
||||
@ -75,12 +75,13 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations
|
||||
|
||||
public void Open()
|
||||
{
|
||||
Logger.MethodTrace($"Opening door $[underline green]${SNO}$[/]$ in world $[underline green]{World.SNO}$[/]$");
|
||||
World.BroadcastIfRevealed(plr => new PlayAnimationMessage
|
||||
{
|
||||
ActorID = DynamicID(plr),
|
||||
AnimReason = 5,
|
||||
UnitAniimStartTime = 0,
|
||||
tAnim = new PlayAnimationMessageSpec[]
|
||||
tAnim = new[]
|
||||
{
|
||||
new PlayAnimationMessageSpec()
|
||||
{
|
||||
@ -115,8 +116,8 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations
|
||||
TickerSystem.TickTimer Timeout = new TickerSystem.SecondsTickTimer(World.Game, 1.8f);
|
||||
if (NearestPortal != null)
|
||||
{
|
||||
var Boom = Task<bool>.Factory.StartNew(() => WaitToSpawn(Timeout));
|
||||
Boom.ContinueWith(delegate
|
||||
var nearestPortalOpen = Task<bool>.Factory.StartNew(() => WaitToSpawn(Timeout));
|
||||
nearestPortalOpen.ContinueWith(delegate
|
||||
{
|
||||
NearestPortal.SetVisible(true);
|
||||
foreach (var plr in World.Players.Values)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@ -1495,5 +1496,21 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
{
|
||||
return $"[World] SNOId: {WorldSNO.Id} GlobalId: {GlobalID} Name: {WorldSNO.Name}";
|
||||
}
|
||||
|
||||
public ImmutableArray<Door> GetAllDoors() =>
|
||||
Actors.Select(a => a.Value).Where(a => a is Door).Cast<Door>().ToImmutableArray();
|
||||
public ImmutableArray<Door> OpenAllDoors()
|
||||
{
|
||||
List<Door> openedDoors = new();
|
||||
var doors = GetAllDoors();
|
||||
|
||||
foreach (var door in doors)
|
||||
{
|
||||
openedDoors.Add(door);
|
||||
door.Open();
|
||||
}
|
||||
|
||||
return openedDoors.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
using System;
|
||||
//Blizzless Project 2022
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
//Blizzless Project 2022
|
||||
using System.Linq;
|
||||
//Blizzless Project 2022
|
||||
@ -6181,4 +6182,23 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Attributes[GameAttribute.Hitpoints_Total_From_Level] = Attributes[GameAttribute.Hitpoints_Max_Total];
|
||||
Attributes.BroadcastChangedIfRevealed();
|
||||
}
|
||||
|
||||
public ImmutableArray<Door> GetNearDoors(float distance = 50f)
|
||||
{
|
||||
var doors = World.GetAllDoors();
|
||||
List<Door> doorList = doors.Where(door => door.Position.IsNear(Position, distance)).ToList();
|
||||
return doorList.ToImmutableArray();
|
||||
}
|
||||
|
||||
public ImmutableArray<Door> OpenNearDoors(float distance = 50f)
|
||||
{
|
||||
List<Door> openedDoors = new();
|
||||
foreach (var door in GetNearDoors(distance))
|
||||
{
|
||||
openedDoors.Add(door);
|
||||
door.Open();
|
||||
}
|
||||
|
||||
return openedDoors.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
@ -1070,7 +1070,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
|
||||
});
|
||||
|
||||
ListenKill(ActorSno._skeletonking_shield_skeleton, 4, new Advance());
|
||||
ListenKill(ActorSno._skeletonking_shield_skeleton, 1, new Advance());
|
||||
}
|
||||
});
|
||||
|
||||
@ -1082,11 +1082,8 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
Objectives = new List<Objective> { Objective.Default() },
|
||||
OnAdvance = () =>
|
||||
{ //take crown on Leoric's head
|
||||
Game.AddOnLoadWorldAction(WorldSno.a1trdun_king_level08, () =>
|
||||
{
|
||||
Open(Game.GetWorld(WorldSno.a1trdun_king_level08), ActorSno._trdun_cath_gate_b_skeletonking);
|
||||
});
|
||||
//Open(this.Game.GetWorld(73261), 172645);
|
||||
|
||||
OpenAll(this.Game.GetWorld(WorldSno.a1trdun_king_level08));
|
||||
ListenInteract(ActorSno._skeletonkinggizmo, 1, new Advance());
|
||||
}
|
||||
});
|
||||
@ -1111,6 +1108,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
Objectives = new List<Objective> { Objective.Default() },
|
||||
OnAdvance = () =>
|
||||
{ //go to fallen star room
|
||||
Open(Game.GetWorld(WorldSno.a1trdun_king_level08), ActorSno._trdun_cath_gate_b_skeletonking);
|
||||
Game.CurrentEncounter.Activated = false;
|
||||
ListenTeleport(117411, new Advance());
|
||||
Game.AddOnLoadWorldAction(WorldSno.a1trdun_king_level08, () =>
|
||||
|
||||
@ -181,6 +181,13 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
(actor as Door).Open();
|
||||
return true;
|
||||
}
|
||||
|
||||
//opening all doors
|
||||
protected void OpenAll(World world)
|
||||
{
|
||||
foreach (var actor in world.Actors.Select(s=>s.Value).Where(t=>t is Door).Cast<Door>())
|
||||
(actor).Open();
|
||||
}
|
||||
|
||||
protected bool OpenAll(World world, ActorSno sno)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
user.block.title