Made attributes read-only;
Improved development conditioning; Translations and renames; Refactoring;
This commit is contained in:
parent
d43984a22f
commit
21d6ea62e8
@ -57,8 +57,14 @@ public class AnsiTarget : LogTarget
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
|
||||
public static string Filter(string text)
|
||||
/// <summary>
|
||||
/// Logging keywords to beautify the output.
|
||||
/// It's ugly, I know.
|
||||
/// Changes are welcome - @iamdroppy
|
||||
/// </summary>
|
||||
/// <param name="text">Text to "beautify"</param>
|
||||
/// <returns>Replaced with color changes</returns>
|
||||
public static string Beautify(string text)
|
||||
{
|
||||
return text
|
||||
.Replace("Blizzless", "[dodgerblue1]Blizz[/][deepskyblue2]less[/]", StringComparison.CurrentCultureIgnoreCase)
|
||||
@ -81,7 +87,7 @@ public class AnsiTarget : LogTarget
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
string Cleanup(string x) => Filter(x.Replace("[", "[[").Replace("]", "]]").Replace("$[[/]]$", "[/]").Replace("$[[", "[").Replace("]]$", "]"));
|
||||
string Cleanup(string x) => Beautify(x.Replace("[", "[[").Replace("]", "]]").Replace("$[[/]]$", "[/]").Replace("$[[", "[").Replace("]]$", "]"));
|
||||
|
||||
public override void LogMessage(Logger.Level level, string logger, string message)
|
||||
{
|
||||
|
||||
@ -52,7 +52,7 @@ namespace DiIiS_NA.Core.Logging
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <returns></returns>
|
||||
string Cleanup(string x) => AnsiTarget.Filter(x.Replace("[", "[[").Replace("]", "]]").Replace("$[[/]]$", "[/]").Replace("$[[", "[").Replace("]]$", "]"));
|
||||
string Cleanup(string x) => AnsiTarget.Beautify(x.Replace("[", "[[").Replace("]", "]]").Replace("$[[/]]$", "[/]").Replace("$[[", "[").Replace("]]$", "]"));
|
||||
|
||||
/// <param name="level"></param>
|
||||
private static string SetColor(Logger.Level level, bool withBackground = false)
|
||||
|
||||
@ -11,7 +11,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
public class CommandGroup
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.CreateLogger("CM");
|
||||
private static readonly Logger Logger = LogManager.CreateLogger("Commands");
|
||||
|
||||
public CommandGroupAttribute Attributes { get; private set; }
|
||||
|
||||
@ -37,7 +37,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (!_commands.ContainsKey(attribute))
|
||||
_commands.Add(attribute, method);
|
||||
else
|
||||
Logger.Error("Command '{0}' already exists.", attribute.Name);
|
||||
Logger.Fatal("Command '$[underline white]${0}$[/]$' already exists.", attribute.Name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +62,11 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
// check if the user has enough privileges to access command group.
|
||||
// check if the user has enough privileges to invoke the command.
|
||||
if (invokerClient != null && Attributes.MinUserLevel > invokerClient.Account.UserLevel)
|
||||
#if DEBUG
|
||||
return $"You don't have enough privileges to invoke that command (Min. level: {Attributes.MinUserLevel}).";
|
||||
#else
|
||||
return "You don't have enough privileges to invoke that command.";
|
||||
|
||||
#endif
|
||||
string[] @params = null;
|
||||
CommandAttribute target = null;
|
||||
|
||||
@ -99,13 +102,10 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
[DefaultCommand]
|
||||
public virtual string Fallback(string[] @params = null, BattleClient invokerClient = null)
|
||||
{
|
||||
var output = "Available subcommands: ";
|
||||
foreach (var pair in _commands)
|
||||
{
|
||||
if (pair.Key.Name.Trim() == string.Empty) continue; // skip fallback command.
|
||||
if (invokerClient != null && pair.Key.MinUserLevel > invokerClient.Account.UserLevel) continue;
|
||||
output += pair.Key.Name + ", ";
|
||||
}
|
||||
var output = _commands
|
||||
.Where(pair => pair.Key.Name.Trim() != string.Empty)
|
||||
.Where(pair => invokerClient == null || pair.Key.MinUserLevel <= invokerClient.Account.UserLevel)
|
||||
.Aggregate("Available subcommands: ", (current, pair) => current + (pair.Key.Name + ", "));
|
||||
|
||||
return output.Substring(0, output.Length - 2) + ".";
|
||||
}
|
||||
|
||||
@ -150,21 +150,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
public override string Fallback(string[] parameters = null, BattleClient invokerClient = null)
|
||||
{
|
||||
var output = "Available commands: ";
|
||||
if (invokerClient != null)
|
||||
{
|
||||
foreach (var pair in CommandGroups.Where(pair =>
|
||||
pair.Key.MinUserLevel > invokerClient?.Account.UserLevel))
|
||||
{
|
||||
output += "!" + pair.Key.Name + ": " + pair.Key.Help + "\n\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pair in CommandGroups)
|
||||
{
|
||||
output += "!" + pair.Key.Name + ": " + pair.Key.Help + "\n\n";
|
||||
}
|
||||
}
|
||||
output =
|
||||
invokerClient != null
|
||||
? CommandGroups.Where(pair => pair.Key.MinUserLevel > invokerClient?.Account.UserLevel)
|
||||
.Aggregate(output, (current, pair) => current + ($"{Config.Instance.CommandPrefix}{pair.Key.Name}: {pair.Key.Help}\n\n"))
|
||||
: CommandGroups
|
||||
.Aggregate(output, (current, pair) => current + (($"$[underline green]${Config.Instance.CommandPrefix}{pair.Key.Name}$[/]$: {pair.Key.Help}\n\n")));
|
||||
|
||||
return output + "Type 'help <command>' to get help about a specific command.";
|
||||
}
|
||||
@ -173,10 +164,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
[CommandGroup("help", "usage: help <command>\nType 'commands' to get a list of available commands.")]
|
||||
public class HelpCommandGroup : CommandGroup
|
||||
{
|
||||
public override string Fallback(string[] parameters = null, BattleClient invokerClient = null)
|
||||
{
|
||||
return "usage: help <command>\nType 'commands' to get a list of available commands.";
|
||||
}
|
||||
public override string Fallback(string[] parameters = null, BattleClient invokerClient = null) => "usage: help <command>\nType 'commands' to get a list of available commands.";
|
||||
|
||||
public override string Handle(string parameters, BattleClient invokerClient = null)
|
||||
{
|
||||
@ -189,11 +177,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
var group = @params[0];
|
||||
var command = @params.Count() > 1 ? @params[1] : string.Empty;
|
||||
|
||||
foreach (var pair in CommandGroups)
|
||||
foreach (var pair in CommandGroups.Where(pair => group == pair.Key.Name))
|
||||
{
|
||||
if (group != pair.Key.Name)
|
||||
continue;
|
||||
|
||||
if (command == string.Empty)
|
||||
return pair.Key.Help;
|
||||
|
||||
@ -202,7 +187,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
}
|
||||
|
||||
if (!found)
|
||||
output = string.Format("Unknown command: {0} {1}", group, command);
|
||||
output = $"Unknown command: {group} {command}";
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -19,15 +19,14 @@ using System.Linq;
|
||||
using DiIiS_NA.GameServer.GSSystem.GameSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.ObjectsSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.PlayerSystem;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.Animation;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Fields;
|
||||
using DiIiS_NA.LoginServer.AccountsSystem;
|
||||
using FluentNHibernate.Utils;
|
||||
using static DiIiS_NA.Core.MPQ.FileFormats.GameBalance;
|
||||
using Actor = DiIiS_NA.Core.MPQ.FileFormats.Actor;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
[CommandGroup("powerful", "Makes your character with absurd amount of damage. Useful for testing.", Account.UserLevels.Tester)]
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
[CommandGroup("powerful", "Makes your character with absurd amount of damage. Useful for testing.",
|
||||
Account.UserLevels.Tester)]
|
||||
public class PowerfulCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -50,6 +49,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
attributes[GameAttribute.Damage_Weapon_Delta, 0] = float.MaxValue;
|
||||
attributes[GameAttribute.Damage_Weapon_Min, 0] = float.MaxValue;
|
||||
});
|
||||
|
||||
player.Attributes.BroadcastChangedIfRevealed();
|
||||
return "You are now powerful.";
|
||||
}
|
||||
@ -61,7 +61,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
[DefaultCommand]
|
||||
public string Info(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient?.InGameClient?.Game is not { } game || invokerClient.InGameClient.Player is not { } player || invokerClient.Account is not{} account)
|
||||
if (invokerClient?.InGameClient?.Game is not { } game || invokerClient.InGameClient.Player is not { } player ||
|
||||
invokerClient.Account is not { } account)
|
||||
return "You are not in game.";
|
||||
return GetInfo(account, player, game);
|
||||
}
|
||||
@ -78,7 +79,6 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
};
|
||||
|
||||
if (account.UserLevel >= Account.UserLevels.GM)
|
||||
{
|
||||
foreach (var world in game.Worlds)
|
||||
{
|
||||
info.Add($"World: {world.SNO.ToString()} - {(int)world.SNO}");
|
||||
@ -101,7 +101,6 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
info.Add("");
|
||||
}
|
||||
}
|
||||
|
||||
return string.Join('\n', info);
|
||||
}
|
||||
@ -117,7 +116,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You must be in game to use this command.";
|
||||
|
||||
var unidentified = player.Inventory.GetBackPackItems().Where(i => i.Unidentified).ToArray();
|
||||
int count = unidentified.Length;
|
||||
var count = unidentified.Length;
|
||||
player.StartCasting(60 * 2, new Action(() =>
|
||||
{
|
||||
foreach (var item in unidentified)
|
||||
@ -126,6 +125,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return $"Identified {count} items.";
|
||||
}
|
||||
}
|
||||
|
||||
[CommandGroup("followers", "Manage your followers.", Account.UserLevels.Tester)]
|
||||
public class FollowersCommand : CommandGroup
|
||||
{
|
||||
@ -137,9 +137,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
List<string> followers = new();
|
||||
foreach (var follower in player.Followers.OrderBy(s => s.Value))
|
||||
{
|
||||
followers.Add($"[{follower.Key}] {follower.Value.ToString()}");
|
||||
}
|
||||
|
||||
return string.Join('\n', followers);
|
||||
}
|
||||
@ -152,10 +150,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
var followers = player.Followers.ToArray();
|
||||
// destroy followers
|
||||
foreach (var follower in followers)
|
||||
{
|
||||
player.DestroyFollower(follower.Value);
|
||||
}
|
||||
foreach (var follower in followers) player.DestroyFollower(follower.Value);
|
||||
|
||||
return $"Dismissed {followers.Length} followers.";
|
||||
}
|
||||
@ -254,7 +249,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var actorSNO = 6652; /* zombie */
|
||||
@ -275,32 +270,31 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
*/
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out actorSNO))
|
||||
if (!int.TryParse(@params[0], out actorSNO))
|
||||
actorSNO = 6652;
|
||||
|
||||
|
||||
if (@params.Count() > 1)
|
||||
if (!Int32.TryParse(@params[1], out amount))
|
||||
if (!int.TryParse(@params[1], out amount))
|
||||
amount = 1;
|
||||
if (amount > 100) amount = 100;
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
for (var i = 0; i < amount; i++)
|
||||
{
|
||||
var position = new Vector3D(player.Position.X + (float)RandomHelper.NextDouble() * 20f,
|
||||
player.Position.Y + (float)RandomHelper.NextDouble() * 20f,
|
||||
player.Position.Z);
|
||||
|
||||
var monster = player.World.SpawnMonster((ActorSno)actorSNO, position);
|
||||
|
||||
}
|
||||
|
||||
return $"Spawned {amount} mobs with ActorSNO: {actorSNO}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[CommandGroup("levelup", "Levels your character.\nOptionally specify the number of levels: !levelup [count]", Account.UserLevels.GM)]
|
||||
[CommandGroup("levelup", "Levels your character.\nOptionally specify the number of levels: !levelup [count]",
|
||||
Account.UserLevels.GM)]
|
||||
public class LevelUpCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -310,19 +304,16 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var amount = 1;
|
||||
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out amount))
|
||||
if (!int.TryParse(@params[0], out amount))
|
||||
amount = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
for (var i = 0; i < amount; i++)
|
||||
if (player.Level >= 70)
|
||||
{
|
||||
player.UpdateExp((int)player.Attributes[GameAttribute.Alt_Experience_Next_Lo]);
|
||||
@ -335,13 +326,9 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
player.PlayEffect(Effect.LevelUp, null, false);
|
||||
player.World.PowerManager.RunPower(player, 85954);
|
||||
}
|
||||
}
|
||||
|
||||
player.Toon.GameAccount.NotifyUpdate();
|
||||
if (player.Level >= 70)
|
||||
return $"New paragon level: {player.ParagonLevel}";
|
||||
else
|
||||
return $"New level: {player.Toon.Level}";
|
||||
return player.Level >= 70 ? $"New paragon level: {player.ParagonLevel}" : $"New level: {player.Toon.Level}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -355,7 +342,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
|
||||
@ -378,12 +365,13 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
player.LoadCrafterData();
|
||||
player.Toon.GameAccount.NotifyUpdate();
|
||||
return string.Format("All artisans Unlocked");
|
||||
return "All artisans Unlocked";
|
||||
}
|
||||
}
|
||||
|
||||
[CommandGroup("platinum",
|
||||
"Platinum for your character.\nOptionally specify the number of levels: !platinum [count]", Account.UserLevels.Tester)]
|
||||
"Platinum for your character.\nOptionally specify the number of levels: !platinum [count]",
|
||||
Account.UserLevels.Tester)]
|
||||
public class PlatinumCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -393,16 +381,14 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var amount = 1;
|
||||
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out amount))
|
||||
if (!int.TryParse(@params[0], out amount))
|
||||
amount = 1;
|
||||
}
|
||||
|
||||
|
||||
player.InGameClient.SendMessage(new PlatinumAwardedMessage
|
||||
@ -413,7 +399,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
player.InGameClient.BnetClient.Account.GameAccount.Platinum += amount;
|
||||
|
||||
return string.Format("Platinum test");
|
||||
return "Platinum test";
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,17 +413,18 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
|
||||
player.Inventory.OnBuySharedStashSlots(null);
|
||||
|
||||
return string.Format("Stash Upgraded");
|
||||
return "Stash Upgraded";
|
||||
}
|
||||
}
|
||||
|
||||
[CommandGroup("gold", "Gold for your character.\nOptionally specify the number of gold: !gold [count]", Account.UserLevels.GM)]
|
||||
[CommandGroup("gold", "Gold for your character.\nOptionally specify the number of gold: !gold [count]",
|
||||
Account.UserLevels.GM)]
|
||||
public class GoldCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -447,16 +434,14 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var amount = 1;
|
||||
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out amount))
|
||||
if (!int.TryParse(@params[0], out amount))
|
||||
amount = 1;
|
||||
}
|
||||
|
||||
player.Inventory.AddGoldAmount(amount);
|
||||
|
||||
@ -475,22 +460,17 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var amount = 1;
|
||||
var achiid = 74987243307074;
|
||||
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out amount))
|
||||
if (!int.TryParse(@params[0], out amount))
|
||||
amount = 1;
|
||||
|
||||
//if (!Int32.TryParse(@params[1], out amount))
|
||||
// achiid = 74987243307074;
|
||||
}
|
||||
|
||||
|
||||
player.InGameClient.SendMessage(new PlatinumAchievementAwardedMessage
|
||||
{
|
||||
CurrentPlatinum = 0,
|
||||
@ -499,11 +479,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
});
|
||||
|
||||
|
||||
return string.Format("Achievement test");
|
||||
return "Achievement test";
|
||||
}
|
||||
}
|
||||
|
||||
[CommandGroup("eff", "Platinum for your character.\nOptionally specify the number of levels: !eff [count]", Account.UserLevels.GM)]
|
||||
[CommandGroup("eff", "Platinum for your character.\nOptionally specify the number of levels: !eff [count]",
|
||||
Account.UserLevels.GM)]
|
||||
public class PlayEffectGroup : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -513,16 +494,14 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var id = 1;
|
||||
|
||||
if (@params != null)
|
||||
{
|
||||
if (!Int32.TryParse(@params[0], out id))
|
||||
if (!int.TryParse(@params[0], out id))
|
||||
id = 1;
|
||||
}
|
||||
|
||||
player.PlayEffectGroup(id);
|
||||
|
||||
@ -530,7 +509,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
}
|
||||
}
|
||||
|
||||
[CommandGroup("item", "Spawns an item (with a name or type).\nUsage: item [type <type>|<name>] [amount]", Account.UserLevels.GM)]
|
||||
[CommandGroup("item", "Spawns an item (with a name or type).\nUsage: item [type <type>|<name>] [amount]",
|
||||
Account.UserLevels.GM)]
|
||||
public class ItemCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
@ -540,7 +520,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var name = "Dye_02";
|
||||
@ -556,12 +536,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You need to specify a valid item name!";
|
||||
|
||||
|
||||
if (@params.Count() == 1 || !Int32.TryParse(@params[1], out amount))
|
||||
if (@params.Count() == 1 || !int.TryParse(@params[1], out amount))
|
||||
amount = 1;
|
||||
|
||||
if (amount > 100) amount = 100;
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
for (var i = 0; i < amount; i++)
|
||||
{
|
||||
var position = new Vector3D(player.Position.X + (float)RandomHelper.NextDouble() * 20f,
|
||||
player.Position.Y + (float)RandomHelper.NextDouble() * 20f,
|
||||
@ -572,7 +552,6 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
}
|
||||
|
||||
return $"Spawned {amount} items with name: {name}";
|
||||
|
||||
}
|
||||
|
||||
[Command("type", "Spawns random items of a given type.\nUsage: item type <type> [amount]")]
|
||||
@ -582,7 +561,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
var name = "Dye";
|
||||
@ -599,12 +578,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (type == null)
|
||||
return "The type given is not a valid item type.";
|
||||
|
||||
if (@params.Count() == 1 || !Int32.TryParse(@params[1], out amount))
|
||||
if (@params.Count() == 1 || !int.TryParse(@params[1], out amount))
|
||||
amount = 1;
|
||||
|
||||
if (amount > 100) amount = 100;
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
for (var i = 0; i < amount; i++)
|
||||
{
|
||||
var position = new Vector3D(player.Position.X + (float)RandomHelper.NextDouble() * 20f,
|
||||
player.Position.Y + (float)RandomHelper.NextDouble() * 20f,
|
||||
@ -624,7 +603,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
var player = invokerClient.InGameClient.Player;
|
||||
|
||||
@ -636,11 +615,13 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
var msg = new InventoryDropItemMessage { ItemID = item.DynamicID(player) };
|
||||
player.Inventory.Consume(invokerClient.InGameClient, msg);
|
||||
}
|
||||
|
||||
return $"Dropped {bpItems.Count} Items for you";
|
||||
}
|
||||
}
|
||||
|
||||
[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]
|
||||
@ -651,7 +632,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
var amount = 1;
|
||||
if (@params != null && @params.Any())
|
||||
if (!Int32.TryParse(@params[0], out amount)) amount = 1;
|
||||
if (!int.TryParse(@params[0], out amount))
|
||||
amount = 1;
|
||||
|
||||
amount = amount switch
|
||||
{
|
||||
@ -662,19 +644,21 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
player.World.SpawnRandomEquip(player, player, 11, player.Level, toonClass: player.Toon.Class, canBeUnidentified: false);
|
||||
for (var i = 0; i < amount; i++)
|
||||
player.World.SpawnRandomEquip(player, player, 11, player.Level, toonClass: player.Toon.Class,
|
||||
canBeUnidentified: false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
for (int i = 0; i < amount; i++)
|
||||
player.World.SpawnRandomEquip(player, player, 8, player.Level, toonClass: player.Toon.Class, canBeUnidentified: false);
|
||||
for (var i = 0; i < amount; i++)
|
||||
player.World.SpawnRandomEquip(player, player, 8, player.Level, toonClass: player.Toon.Class,
|
||||
canBeUnidentified: false);
|
||||
}
|
||||
|
||||
return $"Dropped {amount} random equipment.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[CommandGroup("tp", "Transfers your character to another world.")]
|
||||
public class TeleportCommand : CommandGroup
|
||||
{
|
||||
@ -685,12 +669,11 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
if (@params != null && @params.Count() > 0)
|
||||
if (@params != null && @params.Any())
|
||||
{
|
||||
var worldId = 0;
|
||||
Int32.TryParse(@params[0], out worldId);
|
||||
int.TryParse(@params[0], out var worldId);
|
||||
|
||||
if (worldId == 0)
|
||||
return "Invalid arguments. Type 'help tp' to get help.";
|
||||
@ -714,10 +697,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
var scene = scenes[0]; // Parent scene /fasbat
|
||||
|
||||
if (scenes.Count == 2) // What if it's a subscene?
|
||||
{
|
||||
if (scenes[1].ParentChunkID != 0xFFFFFFFF)
|
||||
scene = scenes[1];
|
||||
}
|
||||
|
||||
var levelArea = scene.Specification.SNOLevelAreas[0];
|
||||
|
||||
@ -728,7 +709,6 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
var trigger =
|
||||
invokerClient.InGameClient.Player.World.Game.SideQuestProgress.GlobalQuestTriggers[levelArea];
|
||||
if (trigger.triggerType == QuestStepObjectiveType.EnterLevelArea)
|
||||
{
|
||||
try
|
||||
{
|
||||
trigger.questEvent.Execute(invokerClient.InGameClient.Player.World); // launch a questEvent
|
||||
@ -737,7 +717,6 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var bounty in invokerClient.InGameClient.Player.World.Game.QuestManager.Bounties)
|
||||
bounty.CheckLevelArea(levelArea);
|
||||
@ -758,15 +737,15 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
if (@params.Count() != 1)
|
||||
return "Invalid arguments. Type 'help conversation' to get help.";
|
||||
|
||||
try
|
||||
{
|
||||
var conversation = MPQStorage.Data.Assets[SNOGroup.Conversation][Int32.Parse(@params[0])];
|
||||
invokerClient.InGameClient.Player.Conversations.StartConversation(Int32.Parse(@params[0]));
|
||||
var conversation = MPQStorage.Data.Assets[SNOGroup.Conversation][int.Parse(@params[0])];
|
||||
invokerClient.InGameClient.Player.Conversations.StartConversation(int.Parse(@params[0]));
|
||||
return $"Started conversation {conversation.FileName}";
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -795,8 +774,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
if (@params.Any())
|
||||
{
|
||||
if (!float.TryParse(@params[0], out speedValue) || speedValue < 0 || speedValue > maxSpeed)
|
||||
return ("Invalid speed value. Must be a number between 0 and 2.");
|
||||
if (!float.TryParse(@params[0], out speedValue) || speedValue is < 0 or > maxSpeed)
|
||||
return "Invalid speed value. Must be a number between 0 and 2.";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -830,7 +809,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while ingame.";
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
return "";
|
||||
}
|
||||
@ -841,7 +820,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
try
|
||||
{
|
||||
invokerClient.InGameClient.Game.QuestManager.Advance();
|
||||
return String.Format("Advancing main quest line");
|
||||
return "Advancing main quest line";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -855,7 +834,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
try
|
||||
{
|
||||
invokerClient.InGameClient.Game.QuestManager.SideAdvance();
|
||||
return String.Format("Advancing side quest line");
|
||||
return "Advancing side quest line";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -872,12 +851,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (@params.Count() != 1)
|
||||
return "Invalid arguments. Type 'help text public' to get help.";
|
||||
|
||||
int questId = Int32.Parse(@params[0]);
|
||||
var questId = int.Parse(@params[0]);
|
||||
|
||||
try
|
||||
{
|
||||
invokerClient.InGameClient.Game.QuestManager.LaunchSideQuest(questId, true);
|
||||
return String.Format("Advancing side quest line");
|
||||
return "Advancing side quest line";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -894,13 +873,13 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (@params.Count() != 2)
|
||||
return "Invalid arguments. Type 'help text public' to get help.";
|
||||
|
||||
int eventId = Int32.Parse(@params[0]);
|
||||
int duration = Int32.Parse(@params[1]);
|
||||
var eventId = int.Parse(@params[0]);
|
||||
var duration = int.Parse(@params[1]);
|
||||
|
||||
invokerClient.InGameClient.Game.QuestManager.LaunchQuestTimer(eventId, (float)duration,
|
||||
new Action<int>((q) => { }));
|
||||
|
||||
return String.Format("Message sent.");
|
||||
return "Message sent.";
|
||||
}
|
||||
|
||||
[Command("info", "Retrieves information about quest states.\n Usage: info")]
|
||||
@ -932,84 +911,59 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup actor' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var groupPair in MPQStorage.Data.Assets)
|
||||
{
|
||||
foreach (var pair in groupPair.Value)
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
}
|
||||
foreach (var groupPair in MPQStorage.Data.Assets) matches.AddRange(from pair in groupPair.Value where pair.Value.Name.ToLower().Contains(pattern) select pair.Value);
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Matches:\n" : "No matches found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] [{match.Group}] {match.Name}\n");
|
||||
(current, match) =>
|
||||
$"{current} [{match.SNOId:D6}] [{match.Group}] {match.Name}\n");
|
||||
}
|
||||
|
||||
[Command("actor", "Allows you to search for an actor.\nUsage: lookup actor <pattern>")]
|
||||
public string Actor(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup actor' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Actor])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
var matches = (from pair in MPQStorage.Data.Assets[SNOGroup.Actor] where pair.Value.Name.ToLower().Contains(pattern) select pair.Value).ToList();
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Actor Matches:\n" : "No match found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] {match.Name} ({(match.Data as DiIiS_NA.Core.MPQ.FileFormats.Actor).Type} {(((match.Data as DiIiS_NA.Core.MPQ.FileFormats.Actor).Type == ActorType.Gizmo) ? ((int)(match.Data as DiIiS_NA.Core.MPQ.FileFormats.Actor).TagMap[ActorKeys.GizmoGroup]).ToString() : "")})\n");
|
||||
$"[{match.SNOId:D6}] {match.Name} ({((Actor)match.Data).Type} {(((Actor)match.Data).Type == ActorType.Gizmo ? ((int)((Actor)match.Data).TagMap[ActorKeys.GizmoGroup]).ToString() : "")})\n");
|
||||
}
|
||||
|
||||
[Command("rope", "Allows you to search for an rope.\nUsage: lookup rope <pattern>")]
|
||||
public string Rope(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup actor' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Rope])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
var matches = (from pair in MPQStorage.Data.Assets[SNOGroup.Rope] where pair.Value.Name.ToLower().Contains(pattern) select pair.Value).ToList();
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Rope Matches:\n" : "No match found.",
|
||||
(current, match) => current + $"[{match.SNOId.ToString("D6")}] {match.Name}\n");
|
||||
(current, match) => current + $"[{match.SNOId:D6}] {match.Name}\n");
|
||||
}
|
||||
|
||||
[Command("conv", "Allows you to search for an conversation.\nUsage: lookup conv <pattern>")]
|
||||
public string Conversation(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup actor' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Conversation])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
var matches = (from pair in MPQStorage.Data.Assets[SNOGroup.Conversation] where pair.Value.Name.ToLower().Contains(pattern) select pair.Value).ToList();
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Conversation Matches:\n" : "No match found.",
|
||||
(current, match) => current + $"[{match.SNOId.ToString("D6")}] {match.Name}\n");
|
||||
(current, match) => current + $"[{match.SNOId:D6}] {match.Name}\n");
|
||||
}
|
||||
|
||||
[Command("power", "Allows you to search for a power.\nUsage: lookup power <pattern>")]
|
||||
@ -1017,31 +971,23 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup power' to get help.";
|
||||
|
||||
if (@params[0].ToLower() == "id")
|
||||
{
|
||||
var num = Int32.Parse(@params[1]);
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Power])
|
||||
{
|
||||
if (pair.Value.SNOId == num)
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
var num = int.Parse(@params[1]);
|
||||
matches.AddRange(from pair in MPQStorage.Data.Assets[SNOGroup.Power] where pair.Value.SNOId == num select pair.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var pattern = @params[0].ToLower();
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Power])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
matches.AddRange(from pair in MPQStorage.Data.Assets[SNOGroup.Power] where pair.Value.Name.ToLower().Contains(pattern) select pair.Value);
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "World Matches:\n" : "No match found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] {match.Name} - {(match.Data as World).DynamicWorld}\n");
|
||||
$"[{match.SNOId:D6}] {match.Name} - {((World)match.Data).DynamicWorld}\n");
|
||||
}
|
||||
|
||||
[Command("world",
|
||||
@ -1050,31 +996,27 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup world' to get help.";
|
||||
|
||||
if (@params[0].ToLower() == "id")
|
||||
{
|
||||
var num = Int32.Parse(@params[1]);
|
||||
var num = int.Parse(@params[1]);
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Worlds])
|
||||
{
|
||||
if (pair.Value.SNOId == num)
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var pattern = @params[0].ToLower();
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Worlds])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "World Matches:\n" : "No match found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] {match.Name} - {(match.Data as World).DynamicWorld}\n");
|
||||
$"[{match.SNOId:D6}] {match.Name} - {(match.Data as World).DynamicWorld}\n");
|
||||
}
|
||||
|
||||
[Command("qr", "Show QuestRange of an actor.\nUsage: lookup qr <id>")]
|
||||
@ -1082,20 +1024,18 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup world' to get help.";
|
||||
|
||||
var num = Int32.Parse(@params[0]);
|
||||
string qr_id = "-1";
|
||||
string qr_name = "None";
|
||||
var num = int.Parse(@params[0]);
|
||||
var qr_id = "-1";
|
||||
var qr_name = "None";
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.QuestRange])
|
||||
{
|
||||
if (pair.Value.SNOId == num)
|
||||
{
|
||||
qr_id = pair.Value.SNOId.ToString("D6");
|
||||
qr_name = pair.Value.Name;
|
||||
}
|
||||
}
|
||||
|
||||
return $"[{qr_id}] {qr_name}";
|
||||
}
|
||||
@ -1103,21 +1043,21 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
public static int GetExitBits(Asset scene)
|
||||
{
|
||||
if (scene.Name.Contains("_N_")) return 1;
|
||||
else if (scene.Name.Contains("_S_")) return 2;
|
||||
else if (scene.Name.Contains("_NS_")) return 3;
|
||||
else if (scene.Name.Contains("_E_")) return 4;
|
||||
else if (scene.Name.Contains("_NE_")) return 5;
|
||||
else if (scene.Name.Contains("_SE_")) return 6;
|
||||
else if (scene.Name.Contains("_NSE_")) return 7;
|
||||
else if (scene.Name.Contains("_W_")) return 8;
|
||||
else if (scene.Name.Contains("_NW_")) return 9;
|
||||
else if (scene.Name.Contains("_SW_")) return 10;
|
||||
else if (scene.Name.Contains("_NSW_")) return 11;
|
||||
else if (scene.Name.Contains("_EW_")) return 12;
|
||||
else if (scene.Name.Contains("_NEW_")) return 13;
|
||||
else if (scene.Name.Contains("_SEW_")) return 14;
|
||||
else if (scene.Name.Contains("_NSEW_")) return 15;
|
||||
else return 0;
|
||||
if (scene.Name.Contains("_S_")) return 2;
|
||||
if (scene.Name.Contains("_NS_")) return 3;
|
||||
if (scene.Name.Contains("_E_")) return 4;
|
||||
if (scene.Name.Contains("_NE_")) return 5;
|
||||
if (scene.Name.Contains("_SE_")) return 6;
|
||||
if (scene.Name.Contains("_NSE_")) return 7;
|
||||
if (scene.Name.Contains("_W_")) return 8;
|
||||
if (scene.Name.Contains("_NW_")) return 9;
|
||||
if (scene.Name.Contains("_SW_")) return 10;
|
||||
if (scene.Name.Contains("_NSW_")) return 11;
|
||||
if (scene.Name.Contains("_EW_")) return 12;
|
||||
if (scene.Name.Contains("_NEW_")) return 13;
|
||||
if (scene.Name.Contains("_SEW_")) return 14;
|
||||
if (scene.Name.Contains("_NSEW_")) return 15;
|
||||
return 0;
|
||||
}
|
||||
|
||||
[Command("la", "Allows you to search for a LevelArea.\nUsage: lookup la <pattern>")]
|
||||
@ -1125,19 +1065,17 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup la' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.LevelArea])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "LevelArea Matches:\n" : "No match found.",
|
||||
(current, match) => current + $"[{match.SNOId.ToString("D6")}] {match.Name}\n");
|
||||
(current, match) => current + $"[{match.SNOId:D6}] {match.Name}\n");
|
||||
}
|
||||
|
||||
[Command("sp", "List all Starting Points in world.\nUsage: lookup sp")]
|
||||
@ -1155,19 +1093,17 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup weather' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Weather])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Weather Matches:\n" : "No match found.",
|
||||
(current, match) => current + $"[{match.SNOId.ToString("D6")}] {match.Name}\n");
|
||||
(current, match) => current + $"[{match.SNOId:D6}] {match.Name}\n");
|
||||
}
|
||||
|
||||
[Command("scene", "Allows you to search for a scene.\nUsage: lookup scene <pattern>")]
|
||||
@ -1175,20 +1111,18 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup scene' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.Scene])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Scene Matches:\n" : "No match found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] {match.Name} - {GetExitBits(match)}\n");
|
||||
$"[{match.SNOId:D6}] {match.Name} - {GetExitBits(match)}\n");
|
||||
}
|
||||
|
||||
[Command("eg", "Allows you to search for an EffectGroup.\nUsage: lookup eg <pattern>")]
|
||||
@ -1196,20 +1130,18 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<Asset>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup eg' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
|
||||
foreach (var pair in MPQStorage.Data.Assets[SNOGroup.EffectGroup])
|
||||
{
|
||||
if (pair.Value.Name.ToLower().Contains(pattern))
|
||||
matches.Add(pair.Value);
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "EffectGroup Matches:\n" : "No match found.",
|
||||
(current, match) => current +
|
||||
$"[{match.SNOId.ToString("D6")}] {match.Name} - {GetExitBits(match)}\n");
|
||||
$"[{match.SNOId:D6}] {match.Name} - {GetExitBits(match)}\n");
|
||||
}
|
||||
|
||||
[Command("item", "Allows you to search for an item.\nUsage: lookup item <pattern>")]
|
||||
@ -1217,7 +1149,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
var matches = new List<ItemTable>();
|
||||
|
||||
if (@params.Count() < 1)
|
||||
if (!@params.Any())
|
||||
return "Invalid arguments. Type 'help lookup item' to get help.";
|
||||
|
||||
var pattern = @params[0].ToLower();
|
||||
@ -1228,15 +1160,12 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (data == null || data.Type != BalanceType.Items) continue;
|
||||
|
||||
foreach (var itemDefinition in data.Item)
|
||||
{
|
||||
if (itemDefinition.Name.ToLower().Contains(pattern))
|
||||
matches.Add(itemDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.Aggregate(matches.Count >= 1 ? "Item Matches:\n" : "No match found.",
|
||||
(current, match) => current + $"[{match.SNOActor.ToString("D6")}] {match.Name}\n");
|
||||
}
|
||||
(current, match) => current + $"[{match.SNOActor:D6}] {match.Name}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,7 +117,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem
|
||||
/// <summary>
|
||||
/// Attribute map.
|
||||
/// </summary>
|
||||
public GameAttributeMap Attributes { get; set; } //TODO: this needs to be "private set", but without errors on speed modifications
|
||||
public GameAttributeMap Attributes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Affix list.
|
||||
|
||||
@ -41,7 +41,7 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations.ScriptObjects
|
||||
{
|
||||
try
|
||||
{
|
||||
(World.FindAt(ActorSno._a3dun_keep_bridge, Position, 60.0f) as Door).Open();
|
||||
(World.FindActorAt(ActorSno._a3dun_keep_bridge, Position, 60.0f) as Door).Open();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
@ -43,12 +43,12 @@ namespace DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations.ScriptObjects
|
||||
if (Attributes[GameAttribute.Disabled] == true) return;
|
||||
try
|
||||
{
|
||||
Door waterfall = World.FindAt(ActorSno._caout_oasis_door_aqueduct_a_top, Position, 80.0f) as Door;
|
||||
Door waterfall = World.FindActorAt(ActorSno._caout_oasis_door_aqueduct_a_top, Position, 80.0f) as Door;
|
||||
if (waterfall == null)
|
||||
{
|
||||
Door gate = World.FindAt(ActorSno._caout_oasis_door_aqueduct_a, Position, 80.0f) as Door;
|
||||
Door gate = World.FindActorAt(ActorSno._caout_oasis_door_aqueduct_a, Position, 80.0f) as Door;
|
||||
if (gate == null)
|
||||
(World.FindAt(ActorSno._caout_oasis_cenote_door, Position, 80.0f) as Door).Open();
|
||||
(World.FindActorAt(ActorSno._caout_oasis_cenote_door, Position, 80.0f) as Door).Open();
|
||||
else
|
||||
gate.Open();
|
||||
}
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
using DiIiS_NA.Core.Helpers.Math;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using DiIiS_NA.Core.Helpers.Hash;
|
||||
using DiIiS_NA.Core.Helpers.Math;
|
||||
using DiIiS_NA.Core.Logging;
|
||||
using DiIiS_NA.Core.MPQ;
|
||||
using DiIiS_NA.Core.MPQ.FileFormats;
|
||||
using DiIiS_NA.D3_GameServer.Core.Types.SNO;
|
||||
using DiIiS_NA.GameServer.Core.Types.Math;
|
||||
using DiIiS_NA.GameServer.Core.Types.QuadTrees;
|
||||
@ -7,27 +15,22 @@ using DiIiS_NA.GameServer.Core.Types.SNO;
|
||||
using DiIiS_NA.GameServer.Core.Types.TagMap;
|
||||
using DiIiS_NA.GameServer.GSSystem.ActorSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.ActorSystem.Implementations;
|
||||
using DiIiS_NA.GameServer.GSSystem.ActorSystem.Movement;
|
||||
using DiIiS_NA.GameServer.GSSystem.GameSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.ItemsSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.ObjectsSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.PlayerSystem;
|
||||
using DiIiS_NA.GameServer.GSSystem.PowerSystem;
|
||||
using DiIiS_NA.GameServer.MessageSystem;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.ACD;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.Animation;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.Misc;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Definitions.World;
|
||||
using DiIiS_NA.GameServer.MessageSystem.Message.Fields;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DiIiS_NA.Core.MPQ.FileFormats;
|
||||
using DiIiS_NA.LoginServer.Toons;
|
||||
using Actor = DiIiS_NA.GameServer.GSSystem.ActorSystem.Actor;
|
||||
using Circle = DiIiS_NA.GameServer.Core.Types.Misc.Circle;
|
||||
using Environment = DiIiS_NA.Core.MPQ.FileFormats.Environment;
|
||||
using Monster = DiIiS_NA.GameServer.GSSystem.ActorSystem.Monster;
|
||||
using ResolvedPortalDestination = DiIiS_NA.GameServer.MessageSystem.Message.Fields.ResolvedPortalDestination;
|
||||
|
||||
@ -36,8 +39,8 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public sealed class World : DynamicObject, IRevealable, IUpdateable
|
||||
{
|
||||
static readonly Logger Logger = LogManager.CreateLogger();
|
||||
public readonly Dictionary<World, List<Item>> DbItems = new Dictionary<World, List<Item>>(); //we need this list to delete item_instances from items which have no owner anymore.
|
||||
public readonly Dictionary<ulong, Item> CachedItems = new Dictionary<ulong, Item>();
|
||||
public readonly Dictionary<World, List<Item>> DbItems = new(); //we need this list to delete item_instances from items which have no owner anymore.
|
||||
public readonly Dictionary<ulong, Item> CachedItems = new();
|
||||
|
||||
public int LastCEId = 3000;
|
||||
|
||||
@ -52,30 +55,24 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// SNOHandle for the world.
|
||||
/// </summary>
|
||||
public SNOHandle WorldSNO { get; private set; }
|
||||
public WorldSno SNO
|
||||
{
|
||||
get { return (WorldSno)WorldSNO.Id; }
|
||||
}
|
||||
public WorldSno SNO => (WorldSno)WorldSNO.Id;
|
||||
|
||||
/// <summary>
|
||||
/// QuadTree that contains scenes & actors.
|
||||
/// </summary>
|
||||
private QuadTree _quadTree;
|
||||
public static QuadTree _PvPQuadTree = new QuadTree(new Size(60, 60), 0);
|
||||
public static QuadTree _PvPQuadTree = new(new Size(60, 60), 0);
|
||||
|
||||
public QuadTree QuadTree
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IsPvP ? _PvPQuadTree : _quadTree);
|
||||
}
|
||||
get => (IsPvP ? _PvPQuadTree : _quadTree);
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WorldData loaded from MPQs/DB
|
||||
/// </summary>
|
||||
public DiIiS_NA.Core.MPQ.FileFormats.World worldData = new DiIiS_NA.Core.MPQ.FileFormats.World();
|
||||
public DiIiS_NA.Core.MPQ.FileFormats.World worldData = new();
|
||||
|
||||
/// <summary>
|
||||
/// Destination for portals(on Exit and DungeonStone)
|
||||
@ -92,14 +89,11 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<uint, Scene> _scenes;
|
||||
|
||||
private static readonly ConcurrentDictionary<uint, Scene> _PvPscenes = new ConcurrentDictionary<uint, Scene>();
|
||||
private static readonly ConcurrentDictionary<uint, Scene> _PvPscenes = new();
|
||||
|
||||
public ConcurrentDictionary<uint, Scene> Scenes
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IsPvP ? _PvPscenes : _scenes);
|
||||
}
|
||||
get => (IsPvP ? _PvPscenes : _scenes);
|
||||
set { }
|
||||
}
|
||||
|
||||
@ -108,46 +102,36 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<uint, Actor> _actors;
|
||||
|
||||
public static readonly ConcurrentDictionary<uint, Actor> _PvPActors = new ConcurrentDictionary<uint, Actor>();
|
||||
public static readonly ConcurrentDictionary<uint, Actor> _PvPActors = new();
|
||||
|
||||
public ConcurrentDictionary<uint, Actor> Actors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IsPvP ? _PvPActors : _actors);
|
||||
}
|
||||
get => (IsPvP ? _PvPActors : _actors);
|
||||
set { }
|
||||
}
|
||||
|
||||
public Dictionary<int, WorldSno> PortalOverrides = new Dictionary<int, WorldSno>();
|
||||
public Dictionary<int, WorldSno> PortalOverrides = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of players contained in the world.
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<uint, Player> _players;
|
||||
|
||||
public static readonly ConcurrentDictionary<uint, Player> _PvPPlayers = new ConcurrentDictionary<uint, Player>();
|
||||
public static readonly ConcurrentDictionary<uint, Player> _PvPPlayers = new();
|
||||
|
||||
public ConcurrentDictionary<uint, Player> Players
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IsPvP ? _PvPPlayers : _players);
|
||||
}
|
||||
set { }
|
||||
}
|
||||
public ConcurrentDictionary<uint, Player> Players => (IsPvP ? _PvPPlayers : _players);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the world has players in.
|
||||
/// </summary>
|
||||
public bool HasPlayersIn { get { return Players.Count > 0; } }
|
||||
public bool HasPlayersIn => Players.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new dynamicId for scenes.
|
||||
/// </summary>
|
||||
public uint NewSceneID { get { return IsPvP ? NewPvPSceneID : Game.NewSceneID; } }
|
||||
public uint NewSceneID => IsPvP ? NewPvPSceneID : Game.NewSceneID;
|
||||
|
||||
public bool IsPvP { get { return SNO == WorldSno.pvp_duel_small_multi; } } //PvP_Duel_Small
|
||||
public bool IsPvP => SNO == WorldSno.pvp_duel_small_multi; //PvP_Duel_Small
|
||||
|
||||
public static bool PvPMapLoaded = false;
|
||||
|
||||
@ -164,21 +148,15 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
}
|
||||
|
||||
// Environment
|
||||
public DiIiS_NA.Core.MPQ.FileFormats.Environment Environment
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((DiIiS_NA.Core.MPQ.FileFormats.World)DiIiS_NA.Core.MPQ.MPQStorage.Data.Assets[SNOGroup.Worlds][WorldSNO.Id].Data).Environment;
|
||||
}
|
||||
}
|
||||
public Environment Environment => ((DiIiS_NA.Core.MPQ.FileFormats.World)MPQStorage.Data.Assets[SNOGroup.Worlds][WorldSNO.Id].Data).Environment;
|
||||
|
||||
private static uint _lastPvPObjectID = 10001;
|
||||
private static object obj = new object();
|
||||
private static readonly object _obj = new();
|
||||
public static uint NewActorPvPID
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (obj)
|
||||
lock (_obj)
|
||||
{
|
||||
_lastPvPObjectID++;
|
||||
return _lastPvPObjectID;
|
||||
@ -191,7 +169,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (obj)
|
||||
lock (_obj)
|
||||
{
|
||||
_lastPvPSceneID++;
|
||||
return _lastPvPSceneID;
|
||||
@ -218,14 +196,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
}
|
||||
|
||||
private PowerManager _powerManager;
|
||||
public static PowerManager _PvPPowerManager = new PowerManager();
|
||||
public static PowerManager _PvPPowerManager = new();
|
||||
|
||||
public PowerManager PowerManager { get { return IsPvP ? _PvPPowerManager : _powerManager; } }
|
||||
public PowerManager PowerManager => IsPvP ? _PvPPowerManager : _powerManager;
|
||||
|
||||
private BuffManager _buffManager;
|
||||
public static BuffManager _PvPBuffManager = new BuffManager();
|
||||
public static BuffManager _PvPBuffManager = new();
|
||||
|
||||
public BuffManager BuffManager { get { return IsPvP ? _PvPBuffManager : _buffManager; } }
|
||||
public BuffManager BuffManager => IsPvP ? _PvPBuffManager : _buffManager;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new world for the given game with given snoId.
|
||||
@ -257,8 +235,8 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
if (SNO == WorldSno.x1_bog_01) //Blood Marsh
|
||||
{
|
||||
var worlds = new List<WorldSno>() { WorldSno.x1_catacombs_level01, WorldSno.x1_catacombs_fakeentrance_02, WorldSno.x1_catacombs_fakeentrance_03, WorldSno.x1_catacombs_fakeentrance_04 };
|
||||
var scenes = new List<int>() { 265624, 265655, 265678, 265693 };
|
||||
var worlds = new List<WorldSno> { WorldSno.x1_catacombs_level01, WorldSno.x1_catacombs_fakeentrance_02, WorldSno.x1_catacombs_fakeentrance_03, WorldSno.x1_catacombs_fakeentrance_04 };
|
||||
var scenes = new List<int> { 265624, 265655, 265678, 265693 };
|
||||
foreach (var scene in scenes)
|
||||
{
|
||||
var wld = worlds[FastRandom.Instance.Next(worlds.Count)];
|
||||
@ -283,17 +261,17 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
{
|
||||
foreach (var actor in player.GetActorsInRange().OfType<IUpdateable>()) // get IUpdateable actors in range.
|
||||
{
|
||||
if (actorsToUpdate.Contains(actor as IUpdateable)) // don't let a single actor in range of more than players to get updated more thance per tick /raist.
|
||||
if (actorsToUpdate.Contains(actor)) // don't let a single actor in range of more than players to get updated more thance per tick /raist.
|
||||
continue;
|
||||
|
||||
actorsToUpdate.Add(actor as IUpdateable);
|
||||
actorsToUpdate.Add(actor);
|
||||
}
|
||||
}
|
||||
foreach (var minion in Actors.Values.OfType<Minion>())
|
||||
{
|
||||
if (actorsToUpdate.Contains(minion as IUpdateable))
|
||||
if (actorsToUpdate.Contains(minion))
|
||||
continue;
|
||||
actorsToUpdate.Add(minion as IUpdateable);
|
||||
actorsToUpdate.Add(minion);
|
||||
}
|
||||
foreach (var actor in actorsToUpdate) // trigger the updates.
|
||||
{
|
||||
@ -313,6 +291,49 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
#region message broadcasting
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a message to all players in the world.
|
||||
/// </summary>
|
||||
/// <param name="action">The action that will be invoked to all players</param>
|
||||
/// <exception cref="Exception">If there was an error to broadcast to player.</exception>
|
||||
public void BroadcastOperation(Action<Player> action)
|
||||
{
|
||||
foreach (var player in Players.Values)
|
||||
{
|
||||
if (player == null) continue;
|
||||
try
|
||||
{
|
||||
action(player);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error while broadcasting to player " + player.Name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a message to all players in the world where the <param name="predicate"></param> is true.
|
||||
/// </summary>
|
||||
/// <param name="predicate">Players matching criteria</param>
|
||||
/// <param name="action">The action that will be invoked to all players</param>
|
||||
/// <exception cref="Exception">If there was an error to broadcast to player</exception>
|
||||
public void BroadcastOperation(Func<Player, bool> predicate, Action<Player> action)
|
||||
{
|
||||
foreach (var player in Players.Values.Where(predicate))
|
||||
{
|
||||
if (player == null) continue;
|
||||
try
|
||||
{
|
||||
action(player);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error while broadcasting to player " + player.Name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Scenes are actually laid out in cells with Subscenes filling in certain areas under a Scene.
|
||||
// We can use this design feature to track Actors' current scene and send updates to it and neighboring
|
||||
// scenes instead of distance checking for broadcasting messages. / komiga
|
||||
@ -325,11 +346,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// <param name="actor">The actor.</param>
|
||||
public void BroadcastIfRevealed(Func<Player, GameMessage> message, Actor actor)
|
||||
{
|
||||
foreach (var player in Players.Values)
|
||||
{
|
||||
if (player.RevealedObjects.ContainsKey(actor.GlobalID))
|
||||
player.InGameClient.SendMessage(message(player));
|
||||
}
|
||||
BroadcastOperation(player => player.RevealedObjects.ContainsKey(actor.GlobalID), player => player.InGameClient.SendMessage(message(player)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -338,10 +355,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// <param name="message"></param>
|
||||
public void BroadcastGlobal(Func<Player, GameMessage> message)
|
||||
{
|
||||
foreach (var player in Players.Values)
|
||||
{
|
||||
player.InGameClient.SendMessage(message(player));
|
||||
}
|
||||
BroadcastOperation(player => player.InGameClient.SendMessage(message(player)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -349,9 +363,9 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// </summary>
|
||||
/// <param name="message">The message to broadcast.</param>
|
||||
/// <param name="actor">The actor.</param>
|
||||
public void BroadcastInclusive(Func<Player, GameMessage> message, Actor actor)
|
||||
public void BroadcastInclusive(Func<Player, GameMessage> message, Actor actor, float? radius = null)
|
||||
{
|
||||
var players = actor.GetPlayersInRange();
|
||||
var players = actor.GetPlayersInRange(radius);
|
||||
foreach (var player in players)
|
||||
{
|
||||
player.InGameClient.SendMessage(message(player));
|
||||
@ -404,12 +418,12 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
WorldSizeInFeetY = 5040,
|
||||
snoDungeonFinderSourceWorld = -1
|
||||
});
|
||||
player.InGameClient.SendMessage(new WorldStatusMessage() { WorldID = GlobalID, Field1 = false });
|
||||
player.InGameClient.SendMessage(new WorldStatusMessage { WorldID = GlobalID, Field1 = false });
|
||||
//*
|
||||
player.InGameClient.SendMessage(new WorldSyncedDataMessage()
|
||||
player.InGameClient.SendMessage(new WorldSyncedDataMessage
|
||||
{
|
||||
WorldID = GlobalID,
|
||||
SyncedData = new WorldSyncedData()
|
||||
SyncedData = new WorldSyncedData
|
||||
{
|
||||
SnoWeatherOverride = -1,
|
||||
WeatherIntensityOverride = 0,
|
||||
@ -436,7 +450,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
foreach (var scene in Scenes.Values) scene.Unreveal(player);
|
||||
player.RevealedObjects.Remove(GlobalID);
|
||||
|
||||
player.InGameClient.SendMessage(new WorldStatusMessage() { WorldID = GlobalID, Field1 = true });
|
||||
player.InGameClient.SendMessage(new WorldStatusMessage { WorldID = GlobalID, Field1 = true });
|
||||
player.InGameClient.SendMessage(new PrefetchDataMessage(Opcodes.PrefetchWorldMessage) { SNO = WorldSNO.Id });
|
||||
//player.InGameClient.SendMessage(new WorldDeletedMessage() { WorldID = this.GlobalID });
|
||||
|
||||
@ -560,7 +574,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
UnitAniimStartTime = 0,
|
||||
tAnim = new PlayAnimationMessageSpec[]
|
||||
{
|
||||
new PlayAnimationMessageSpec()
|
||||
new()
|
||||
{
|
||||
Duration = 150,
|
||||
AnimationSNO = monster.AnimationSet.TagMapAnimDefault[animationTag],
|
||||
@ -576,7 +590,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
return monster;
|
||||
}
|
||||
|
||||
private Queue<Queue<Action>> _flippyTimers = new Queue<Queue<Action>>();
|
||||
private Queue<Queue<Action>> _flippyTimers = new();
|
||||
|
||||
private const int FlippyDurationInTicks = 10;
|
||||
private const int FlippyMaxDistanceManhattan = 10; // length of one side of the square around the player where the item will appear
|
||||
@ -592,14 +606,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void PlayPieAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
||||
{
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateDetPathPieWedgeMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathPieWedgeMessage
|
||||
{
|
||||
ann = (int)actor.DynamicID(plr),
|
||||
StartPos = User.Position,
|
||||
FirstTagetPos = User.Position,
|
||||
MoveFlags = 9,
|
||||
AnimTag = 1,
|
||||
PieData = new DPathPieData()
|
||||
PieData = new DPathPieData
|
||||
{
|
||||
Field0 = TargetPosition,
|
||||
Field1 = 1,
|
||||
@ -613,7 +627,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void PlayCircleAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
||||
{
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateDetPathSinMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathSinMessage
|
||||
{
|
||||
ActorID = actor.DynamicID(plr),
|
||||
DPath = 6,
|
||||
@ -625,14 +639,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
Seed = 1,
|
||||
Carry = 1,
|
||||
TargetPostition = TargetPosition,
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
StartPosition = User.Position,
|
||||
MoveFlags = 1,
|
||||
AnimTag = 1,
|
||||
PowerSNO = PowerSNO,
|
||||
Var0Int = 1,
|
||||
Var0Fl = 1f,
|
||||
SinData = new DPathSinData()
|
||||
SinData = new DPathSinData
|
||||
{
|
||||
annOwner = (int)actor.DynamicID(plr),
|
||||
SinIncAccel = 0f,
|
||||
@ -649,28 +663,28 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void PlayZigAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
||||
{
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateFacingMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateFacingMessage
|
||||
{
|
||||
ActorId = actor.DynamicID(plr),
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
TurnImmediately = true
|
||||
}, actor);
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateDetPathSinMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathSinMessage
|
||||
{
|
||||
ActorID = actor.DynamicID(plr),
|
||||
DPath = 5,
|
||||
Seed = 1,
|
||||
Carry = 1,
|
||||
TargetPostition = TargetPosition,
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
StartPosition = User.Position,
|
||||
MoveFlags = 1,
|
||||
AnimTag = 1,
|
||||
PowerSNO = PowerSNO,
|
||||
Var0Int = 1,
|
||||
Var0Fl = 1f,
|
||||
SinData = new DPathSinData()
|
||||
SinData = new DPathSinData
|
||||
{
|
||||
annOwner = (int)actor.DynamicID(plr),
|
||||
SinIncAccel = 0f,
|
||||
@ -687,14 +701,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void PlayReverSpiralAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
||||
{
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateFacingMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateFacingMessage
|
||||
{
|
||||
ActorId = actor.DynamicID(plr),
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
TurnImmediately = true
|
||||
}, actor);
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateDetPathSinMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathSinMessage
|
||||
{
|
||||
ActorID = actor.DynamicID(plr),
|
||||
DPath = 4,
|
||||
@ -706,14 +720,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
Seed = 1,
|
||||
Carry = 1,
|
||||
TargetPostition = TargetPosition,
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
StartPosition = User.Position,
|
||||
MoveFlags = 1,
|
||||
AnimTag = 1,
|
||||
PowerSNO = PowerSNO,
|
||||
Var0Int = 1,
|
||||
Var0Fl = 1f,
|
||||
SinData = new DPathSinData()
|
||||
SinData = new DPathSinData
|
||||
{
|
||||
annOwner = (int)actor.DynamicID(plr),
|
||||
SinIncAccel = 0.2f,
|
||||
@ -730,14 +744,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void PlaySpiralAnimation(Actor actor, Actor User, int PowerSNO, Vector3D TargetPosition)
|
||||
{
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateFacingMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateFacingMessage
|
||||
{
|
||||
ActorId = actor.DynamicID(plr),
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
TurnImmediately = true
|
||||
}, actor);
|
||||
|
||||
BroadcastIfRevealed(plr => new MessageSystem.Message.Definitions.ACD.ACDTranslateDetPathSinMessage
|
||||
BroadcastIfRevealed(plr => new ACDTranslateDetPathSinMessage
|
||||
{
|
||||
ActorID = actor.DynamicID(plr),
|
||||
DPath = 3,
|
||||
@ -749,14 +763,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
Seed = 1,
|
||||
Carry = 1,
|
||||
TargetPostition = TargetPosition,
|
||||
Angle = ActorSystem.Movement.MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
Angle = MovementHelpers.GetFacingAngle(User.Position, TargetPosition),
|
||||
StartPosition = User.Position,
|
||||
MoveFlags = 1,
|
||||
AnimTag = 1,
|
||||
PowerSNO = PowerSNO,
|
||||
Var0Int = 1,
|
||||
Var0Fl = 1f,
|
||||
SinData = new DPathSinData()
|
||||
SinData = new DPathSinData
|
||||
{
|
||||
annOwner = (int)actor.DynamicID(plr),
|
||||
SinIncAccel = 0.2f,
|
||||
@ -773,7 +787,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public Item SpawnRandomEquip(Actor source, Player player, int forceQuality = -1, int forceLevel = -1,
|
||||
GameBalance.ItemTypeTable type = null, bool canBeUnidentified = true, ToonClass toonClass = ToonClass.Unknown)
|
||||
{
|
||||
Logger.Debug("SpawnRandomEquip(): quality {0}", forceQuality);
|
||||
Logger.MethodTrace("SpawnRandomEquip(): quality {0}", forceQuality);
|
||||
if (player != null)
|
||||
{
|
||||
int level = (forceLevel > 0 ? forceLevel : source.Attributes[GameAttribute.Level]);
|
||||
@ -857,7 +871,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
}
|
||||
public void SpawnRandomPotion(Actor source, Player player)
|
||||
{
|
||||
if (player != null && !player.Inventory.HaveEnough(DiIiS_NA.Core.Helpers.Hash.StringHashHelper.HashItemName("HealthPotionBottomless"), 1))
|
||||
if (player != null && !player.Inventory.HaveEnough(StringHashHelper.HashItemName("HealthPotionBottomless"), 1))
|
||||
{
|
||||
var item = ItemGenerator.GenerateRandomPotion(player);
|
||||
if (item == null) return;
|
||||
@ -946,7 +960,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// <returns></returns>
|
||||
public bool HasActorsInGroup(string group)
|
||||
{
|
||||
var groupHash = DiIiS_NA.Core.Helpers.Hash.StringHashHelper.HashItemName(group);
|
||||
var groupHash = StringHashHelper.HashItemName(group);
|
||||
foreach (var actor in Actors.Values)
|
||||
{
|
||||
if (actor.Tags != null)
|
||||
@ -963,7 +977,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public List<Actor> GetActorsInGroup(string group)
|
||||
{
|
||||
List<Actor> matchingActors = new List<Actor>();
|
||||
var groupHash = DiIiS_NA.Core.Helpers.Hash.StringHashHelper.HashItemName(group);
|
||||
var groupHash = StringHashHelper.HashItemName(group);
|
||||
foreach (var actor in Actors.Values)
|
||||
{
|
||||
if (actor.Tags != null)
|
||||
@ -1087,7 +1101,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void AddScene(Scene scene)
|
||||
{
|
||||
if (scene.GlobalID == 0 || HasScene(scene.GlobalID))
|
||||
throw new Exception(String.Format("Scene has an invalid ID or was already present (ID = {0})", scene.GlobalID));
|
||||
throw new Exception($"Scene has an invalid ID or was already present (ID = {scene.GlobalID})");
|
||||
|
||||
Scenes.TryAdd(scene.GlobalID, scene); // add to scenes collection.
|
||||
QuadTree.Insert(scene); // add it to quad-tree too.
|
||||
@ -1100,10 +1114,9 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
public void RemoveScene(Scene scene)
|
||||
{
|
||||
if (scene.GlobalID == 0 || !HasScene(scene.GlobalID))
|
||||
throw new Exception(String.Format("Scene has an invalid ID or was not present (ID = {0})", scene.GlobalID));
|
||||
throw new Exception($"Scene has an invalid ID or was not present (ID = {scene.GlobalID})");
|
||||
|
||||
Scene remotedScene;
|
||||
Scenes.TryRemove(scene.GlobalID, out remotedScene); // remove it from scenes collection.
|
||||
Scenes.TryRemove(scene.GlobalID, out _); // remove it from scenes collection.
|
||||
QuadTree.Remove(scene); // remove from quad-tree too.
|
||||
}
|
||||
|
||||
@ -1114,8 +1127,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// <returns></returns>
|
||||
public Scene GetScene(uint dynamicID)
|
||||
{
|
||||
Scene scene;
|
||||
Scenes.TryGetValue(dynamicID, out scene);
|
||||
Scenes.TryGetValue(dynamicID, out var scene);
|
||||
return scene;
|
||||
}
|
||||
|
||||
@ -1161,10 +1173,9 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
private void RemoveActor(Actor actor)
|
||||
{
|
||||
if (actor.GlobalID == 0 || !Actors.ContainsKey(actor.GlobalID))
|
||||
throw new Exception(String.Format("Actor has an invalid ID or was not present (ID = {0})", actor.GlobalID));
|
||||
throw new Exception($"Actor has an invalid ID or was not present (ID = {actor.GlobalID})");
|
||||
|
||||
Actor removedActor;
|
||||
Actors.TryRemove(actor.GlobalID, out removedActor); // remove it from actors collection.
|
||||
Actors.TryRemove(actor.GlobalID, out _); // remove it from actors collection.
|
||||
QuadTree.Remove(actor); // remove from quad-tree too.
|
||||
|
||||
if (actor.ActorType == ActorType.Player) // if actors is a player, remove it from players collection too.
|
||||
@ -1173,8 +1184,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
public Actor GetActorByGlobalId(uint globalID)
|
||||
{
|
||||
Actor actor;
|
||||
Actors.TryGetValue(globalID, out actor);
|
||||
Actors.TryGetValue(globalID, out var actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
@ -1204,7 +1214,6 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
{
|
||||
if (actor.ActorType == matchType)
|
||||
return actor;
|
||||
else
|
||||
Logger.Warn("Attempted to get actor ID {0} as a {1}, whereas the actor is type {2}",
|
||||
dynamicID, Enum.GetName(typeof(ActorType), matchType), Enum.GetName(typeof(ActorType), actor.ActorType));
|
||||
}
|
||||
@ -1247,37 +1256,42 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// Adds given player to world.
|
||||
/// </summary>
|
||||
/// <param name="player">The player to add.</param>
|
||||
private void AddPlayer(Player player)
|
||||
private bool AddPlayer(Player player)
|
||||
{
|
||||
if (player.GlobalID == 0 || HasPlayer(player.GlobalID))
|
||||
throw new Exception(String.Format("Player has an invalid ID or was already present (ID = {0})", player.GlobalID));
|
||||
if (player == null)
|
||||
throw new Exception($"Player in world {SNO} is null and cannot be removed.");
|
||||
|
||||
Players.TryAdd(player.GlobalID, player); // add it to players collection.
|
||||
if (player.GlobalID == 0 || HasPlayer(player.GlobalID))
|
||||
throw new Exception($"Player has an invalid ID or was already present (ID = {player.GlobalID})");
|
||||
|
||||
return Players.TryAdd(player.GlobalID, player); // add it to players collection.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes given player from world.
|
||||
/// </summary>
|
||||
/// <param name="player"></param>
|
||||
private void RemovePlayer(Player player)
|
||||
private bool RemovePlayer(Player player)
|
||||
{
|
||||
if (player.GlobalID == 0 || !Players.ContainsKey(player.GlobalID))
|
||||
throw new Exception(String.Format("Player has an invalid ID or was not present (ID = {0})", player.GlobalID));
|
||||
if (player == null)
|
||||
throw new Exception($"Player in world {SNO} is null and cannot be removed.");
|
||||
|
||||
Player removedPlayer;
|
||||
Players.TryRemove(player.GlobalID, out removedPlayer); // remove it from players collection.
|
||||
if (player.GlobalID == 0 || !Players.ContainsKey(player.GlobalID))
|
||||
throw new Exception($"Player has an invalid ID or was not present (ID = {player.GlobalID})");
|
||||
|
||||
return Players.TryRemove(player.GlobalID, out _); // remove it from players collection.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns player with given dynamicId.
|
||||
/// Returns player with a given predicate
|
||||
/// </summary>
|
||||
/// <param name="dynamicID">The dynamicId of the player.</param>
|
||||
/// <returns></returns>
|
||||
public Player GetPlayer(uint dynamicID)
|
||||
/// <param name="predicate">Predicate to find player</param>
|
||||
/// <param name="player">Player result</param>
|
||||
/// <returns>Whether the player was found.</returns>
|
||||
public bool TryGetPlayer(Func<Player, bool> predicate, out Player player)
|
||||
{
|
||||
Player player;
|
||||
Players.TryGetValue(dynamicID, out player);
|
||||
return player;
|
||||
player = Players.Values.FirstOrDefault(predicate);
|
||||
return player != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1285,40 +1299,28 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// </summary>
|
||||
/// <param name="dynamicID">The dynamicId of the player.</param>
|
||||
/// <returns><see cref="bool"/></returns>
|
||||
public bool HasPlayer(uint dynamicID)
|
||||
{
|
||||
return Players.ContainsKey(dynamicID);
|
||||
}
|
||||
public bool HasPlayer(uint dynamicID) => Players.ContainsKey(dynamicID);
|
||||
|
||||
/// <summary>
|
||||
/// Returns item with given dynamicId.
|
||||
/// </summary>
|
||||
/// <param name="dynamicID">The dynamicId of the item.</param>
|
||||
/// <returns></returns>
|
||||
public Item GetItem(uint dynamicID)
|
||||
{
|
||||
return (Item)GetActorByGlobalId(dynamicID, ActorType.Item);
|
||||
}
|
||||
public Item GetItem(uint dynamicID) => (Item)GetActorByGlobalId(dynamicID, ActorType.Item);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if world contains a monster with given dynamicId.
|
||||
/// </summary>
|
||||
/// <param name="dynamicID">The dynamicId of the monster.</param>
|
||||
/// <returns><see cref="bool"/></returns>
|
||||
public bool HasMonster(uint dynamicID)
|
||||
{
|
||||
return HasActor(dynamicID, ActorType.Monster);
|
||||
}
|
||||
public bool HasMonster(uint dynamicID) => HasActor(dynamicID, ActorType.Monster);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if world contains an item with given dynamicId.
|
||||
/// </summary>
|
||||
/// <param name="dynamicID">The dynamicId of the item.</param>
|
||||
/// <returns><see cref="bool"/></returns>
|
||||
public bool HasItem(uint dynamicID)
|
||||
{
|
||||
return HasActor(dynamicID, ActorType.Item);
|
||||
}
|
||||
public bool HasItem(uint dynamicID) => HasActor(dynamicID, ActorType.Item);
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1330,17 +1332,14 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// <param name="id">The id of the StartingPoint.</param>
|
||||
/// <returns><see cref="StartingPoint"/></returns>
|
||||
|
||||
public StartingPoint GetStartingPointById(int id)
|
||||
{
|
||||
return Actors.Values.OfType<StartingPoint>().Where(sp => sp.TargetId == id).ToList().FirstOrDefault();
|
||||
}
|
||||
public StartingPoint GetStartingPointById(int id) => Actors.Values.OfType<StartingPoint>().Where(sp => sp.TargetId == id).ToList().FirstOrDefault();
|
||||
|
||||
public Actor FindAt(ActorSno actorSno, Vector3D position, float radius = 3.0f)
|
||||
public Actor FindActorAt(ActorSno actorSno, Vector3D position, float radius = 3.0f)
|
||||
{
|
||||
var proximityCircle = new Circle(position.X, position.Y, radius);
|
||||
var actors = QuadTree.Query<Actor>(proximityCircle);
|
||||
foreach (var actr in actors)
|
||||
if (actr.Attributes[GameAttribute.Disabled] == false && actr.Attributes[GameAttribute.Gizmo_Has_Been_Operated] == false && actr.SNO == actorSno) return actr;
|
||||
foreach (var actor in actors)
|
||||
if (actor.Attributes[GameAttribute.Disabled] == false && actor.Attributes[GameAttribute.Gizmo_Has_Been_Operated] == false && actor.SNO == actorSno) return actor;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1349,10 +1348,13 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the WayPoint</param>
|
||||
/// <returns><see cref="Waypoint"/></returns>
|
||||
public Waypoint GetWayPointById(int id)
|
||||
{
|
||||
return Actors.Values.OfType<Waypoint>().FirstOrDefault(waypoint => waypoint.WaypointId == id);
|
||||
}
|
||||
public Waypoint GetWayPointById(int id) => Actors.Values.OfType<Waypoint>().FirstOrDefault(waypoint => waypoint.WaypointId == id);
|
||||
|
||||
public Waypoint[] GetAllWaypoints() => Actors.Values.OfType<Waypoint>().ToArray();
|
||||
|
||||
public Waypoint[] GetAllWaypointsInWorld(WorldSno worldSno) => Actors.Values.OfType<Waypoint>().Where(waypoint => waypoint.World.SNO == worldSno).ToArray();
|
||||
|
||||
public Waypoint[] GetAllWaypointsInWorld(World world) => Actors.Values.OfType<Waypoint>().Where(waypoint => waypoint.World == world).ToArray();
|
||||
|
||||
#endregion
|
||||
|
||||
@ -1360,8 +1362,27 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
// TODO: Destroy all objects /raist
|
||||
|
||||
Logger.Trace($"$[red]$Destroying$[/]$ World #{GlobalID} $[underline red]${SNO}$[/]$");
|
||||
// TODO: Destroy all objects @iamdroppy - solution below added for testing on 21/01/2023
|
||||
// foreach (var actor in Actors.Values)
|
||||
// try
|
||||
// {
|
||||
// actor.Destroy();
|
||||
// }
|
||||
// catch {}
|
||||
//
|
||||
// foreach (var player in Players.Values)
|
||||
// try
|
||||
// {
|
||||
// player.Destroy();
|
||||
// }
|
||||
// catch{}
|
||||
// foreach (var portal in Portals)
|
||||
// try
|
||||
// {
|
||||
// portal.Destroy();
|
||||
// }
|
||||
// catch{}
|
||||
// TODO: Destroy pre-generated tile set
|
||||
|
||||
worldData = null;
|
||||
@ -1384,18 +1405,15 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
if (s.Parent != null) { scene = s.Parent; }
|
||||
if (s.Subscenes.Count > 0)
|
||||
{
|
||||
foreach (var subscene in s.Subscenes)
|
||||
foreach (var subScene in s.Subscenes.Where(subScene => subScene.Bounds.Contains(location.X, location.Y)))
|
||||
{
|
||||
if (subscene.Bounds.Contains(location.X, location.Y))
|
||||
{
|
||||
scene = subscene;
|
||||
}
|
||||
scene = subScene;
|
||||
}
|
||||
}
|
||||
|
||||
int x = (int)((location.X - scene.Bounds.Left) / 2.5f);
|
||||
int y = (int)((location.Y - scene.Bounds.Top) / 2.5f);
|
||||
int total = (int)((y * scene.NavMesh.SquaresCountX) + x);
|
||||
int total = (y * scene.NavMesh.SquaresCountX) + x;
|
||||
if (total < 0 || total > scene.NavMesh.NavMeshSquareCount)
|
||||
{
|
||||
Logger.Error("Navmesh overflow!");
|
||||
@ -1413,31 +1431,34 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
public float GetZForLocation(Vector3D location, float defaultZ)
|
||||
{
|
||||
foreach (Scene s in Scenes.Values)
|
||||
{
|
||||
if (s.Bounds.Contains(location.X, location.Y))
|
||||
foreach (Scene s in Scenes.Values.Where(s => s.Bounds.Contains(location.X, location.Y)))
|
||||
{
|
||||
Scene scene = s;
|
||||
if (s.Parent != null) { scene = s.Parent; }
|
||||
if (s.Parent != null)
|
||||
{
|
||||
scene = s.Parent;
|
||||
}
|
||||
|
||||
if (s.Subscenes.Count > 0)
|
||||
{
|
||||
foreach (var subscene in s.Subscenes)
|
||||
foreach (var subScene in s.Subscenes)
|
||||
{
|
||||
if (subscene.Bounds.Contains(location.X, location.Y))
|
||||
if (subScene.Bounds.Contains(location.X, location.Y))
|
||||
{
|
||||
scene = subscene;
|
||||
scene = subScene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int x = (int)((location.X - scene.Bounds.Left) / 2.5f);
|
||||
int y = (int)((location.Y - scene.Bounds.Top) / 2.5f);
|
||||
int total = (int)((y * scene.NavMesh.SquaresCountX) + x);
|
||||
int total = (y * scene.NavMesh.SquaresCountX) + x;
|
||||
if (total < 0 || total > scene.NavMesh.NavMeshSquareCount)
|
||||
{
|
||||
Logger.Error("Navmesh overflow!");
|
||||
return defaultZ;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return scene.NavMesh.Squares[total].Z;
|
||||
@ -1447,23 +1468,22 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
return defaultZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return defaultZ;
|
||||
}
|
||||
|
||||
[Obsolete("Isn't used anymore")] // made obsolete by @iamdroppy on 28/01/2023
|
||||
public bool CheckRayPath(Vector3D start, Vector3D destination)
|
||||
{
|
||||
|
||||
var proximity = new RectangleF(start.X - 1f, start.Y - 1f, 2f, 2f);
|
||||
var scenes = QuadTree.Query<Scene>(proximity);
|
||||
if (scenes.Count == 0) return false;
|
||||
|
||||
var scene = scenes[0]; // Parent scene /fasbat
|
||||
|
||||
if (scenes.Count == 2) // What if it's a subscene? /fasbat
|
||||
{
|
||||
if (scenes[1].ParentChunkID != 0xFFFFFFFF)
|
||||
scene = scenes[1];
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1471,7 +1491,7 @@ namespace DiIiS_NA.GameServer.GSSystem.MapSystem
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[World] SNOId: {0} GlobalId: {1} Name: {2}", WorldSNO.Id, GlobalID, WorldSNO.Name);
|
||||
return $"[World] SNOId: {WorldSNO.Id} GlobalId: {GlobalID} Name: {WorldSNO.Name}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1357,7 +1357,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
var world = Game.GetWorld(WorldSno.trout_town);
|
||||
DestroyFollower(ActorSno._leah);
|
||||
AddFollower(world, ActorSno._leah);
|
||||
try { (world.FindAt(ActorSno._trout_tristramfield_field_gate, new Vector3D { X = 1523.13f, Y = 857.71f, Z = 39.26f }, 5.0f) as Door).Open(); } catch { }
|
||||
try { (world.FindActorAt(ActorSno._trout_tristramfield_field_gate, new Vector3D { X = 1523.13f, Y = 857.71f, Z = 39.26f }, 5.0f) as Door).Open(); } catch { }
|
||||
StartConversation(world, 167677);
|
||||
ListenConversation(167677, new Advance());
|
||||
}
|
||||
@ -1405,7 +1405,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
var world = Game.GetWorld(WorldSno.trout_town);
|
||||
DestroyFollower(ActorSno._leah);
|
||||
AddFollower(world, ActorSno._leah);
|
||||
try { (world.FindAt(ActorSno._trout_tristramfield_field_gate, new Vector3D { X = 1444.1f, Y = 786.64f, Z = 39.7f }, 4.0f) as Door).Open(); } catch { }
|
||||
try { (world.FindActorAt(ActorSno._trout_tristramfield_field_gate, new Vector3D { X = 1444.1f, Y = 786.64f, Z = 39.7f }, 4.0f) as Door).Open(); } catch { }
|
||||
SetActorOperable(world, ActorSno._keybox_trout_tristramfield_02, false);
|
||||
SetActorOperable(world, ActorSno._keybox_trout_tristramfield, false);
|
||||
ListenProximity(ActorSno._waypoint, new Advance());
|
||||
|
||||
@ -96,7 +96,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
OnAdvance = new Action(() => { //go through canyon
|
||||
try
|
||||
{
|
||||
Door TDoor = (Game.GetWorld(WorldSno.caout_town).FindAt(ActorSno._a2dun_cald_exit_gate, new Vector3D { X = 2905.62f, Y = 1568.82f, Z = 250.75f }, 6.0f) as Door);
|
||||
Door TDoor = (Game.GetWorld(WorldSno.caout_town).FindActorAt(ActorSno._a2dun_cald_exit_gate, new Vector3D { X = 2905.62f, Y = 1568.82f, Z = 250.75f }, 6.0f) as Door);
|
||||
//ListenProximity(TDoor, )
|
||||
TDoor.Open();
|
||||
} catch { }
|
||||
@ -926,7 +926,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
var world = Game.GetWorld(WorldSno.a2dun_aqd_special_01);
|
||||
Game.AddOnLoadWorldAction(WorldSno.a2dun_aqd_special_01, () =>
|
||||
{
|
||||
(world.FindAt(ActorSno._a2dun_aqd_act_stone_slab_a_01, new Vector3D { X = 175.1f, Y = 62.275f, Z = 50.17f }, 20.0f) as Door).Open();
|
||||
(world.FindActorAt(ActorSno._a2dun_aqd_act_stone_slab_a_01, new Vector3D { X = 175.1f, Y = 62.275f, Z = 50.17f }, 20.0f) as Door).Open();
|
||||
});
|
||||
ListenInteract(ActorSno._a2dun_aqd_act_waterwheel_lever_a_01, 1, new CompleteObjective(0));
|
||||
ListenInteract(ActorSno._a2dun_aqd_act_waterwheel_lever_b_01, 1, new Advance());
|
||||
@ -948,7 +948,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
Open(world, ActorSno._a2dun_aqd_act_stone_slab_a_01);
|
||||
Open(world, ActorSno._a2dun_aqd_special_01_waterfall);
|
||||
Open(world, ActorSno._a2dun_aqd_mainpuzzle_door);
|
||||
(world.FindAt(ActorSno._a2dun_aqd_act_stone_slab_a_01, new Vector3D { X = 80.5f, Y = 155.631f, Z = 50.33f }, 20.0f) as Door).Open();
|
||||
(world.FindActorAt(ActorSno._a2dun_aqd_act_stone_slab_a_01, new Vector3D { X = 80.5f, Y = 155.631f, Z = 50.33f }, 20.0f) as Door).Open();
|
||||
});
|
||||
//try {(this.Game.GetWorld(59486).FindAt(83629, new Vector3D{X = 80.5f, Y = 155.631f, Z = 50.33f}, 20.0f) as Door).Open();} catch {}
|
||||
ListenTeleport(192694, new Advance());
|
||||
@ -1365,7 +1365,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
Objectives = new List<Objective> { Objective.Default() },
|
||||
OnAdvance = new Action(() => { //todo: timed event 115494
|
||||
var world = Game.GetWorld(WorldSno.caout_town);
|
||||
try { (world.FindAt(ActorSno._a2dun_cald_exit_gate, new Vector3D { X = 3135.3f, Y = 1546.1f, Z = 250.545f }, 15.0f) as Door).Open(); } catch { }
|
||||
try { (world.FindActorAt(ActorSno._a2dun_cald_exit_gate, new Vector3D { X = 3135.3f, Y = 1546.1f, Z = 250.545f }, 15.0f) as Door).Open(); } catch { }
|
||||
foreach (var Ashe in world.GetActorsBySNO(ActorSno._asheara))
|
||||
RemoveConversations(Ashe);
|
||||
StartConversation(world, 178852);
|
||||
|
||||
@ -337,7 +337,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
ListenConversation(134266, new Advance());
|
||||
try
|
||||
{
|
||||
Game.GetWorld(WorldSno.a3dun_hub_keep).FindAt(ActorSno._a3dun_hub_drawbridge_01, new Vector3D { X = 127.121f, Y = 353.211f, Z = 0.22f }, 25f).Hidden = true;
|
||||
Game.GetWorld(WorldSno.a3dun_hub_keep).FindActorAt(ActorSno._a3dun_hub_drawbridge_01, new Vector3D { X = 127.121f, Y = 353.211f, Z = 0.22f }, 25f).Hidden = true;
|
||||
var world = Game.GetWorld(WorldSno.a3dun_keep_hub_inn);
|
||||
var NStone = world.GetActorBySNO(ActorSno._a2dun_zolt_black_soulstone);//156328
|
||||
foreach (var atr in world.GetActorsBySNO(ActorSno._leah))
|
||||
@ -653,8 +653,8 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
try
|
||||
{
|
||||
var world = Game.GetWorld(WorldSno.a3dun_crater_st_level04b);
|
||||
(world.FindAt(ActorSno._a3dun_crater_st_demon_chainpylon_fire_mistressofpain, new Vector3D { X = 457.04f, Y = 359.03f, Z = 0.39f }, 20f) as Door).Open();
|
||||
(world.FindAt(ActorSno._a3dun_crater_st_demon_chainpylon_fire_mistressofpain, new Vector3D { X = 356.04f, Y = 267.03f, Z = 0.28f }, 20f) as Door).Open();
|
||||
(world.FindActorAt(ActorSno._a3dun_crater_st_demon_chainpylon_fire_mistressofpain, new Vector3D { X = 457.04f, Y = 359.03f, Z = 0.39f }, 20f) as Door).Open();
|
||||
(world.FindActorAt(ActorSno._a3dun_crater_st_demon_chainpylon_fire_mistressofpain, new Vector3D { X = 356.04f, Y = 267.03f, Z = 0.28f }, 20f) as Door).Open();
|
||||
SetActorOperable(world, ActorSno._a3dun_crater_st_giantdemonheart_mob, false);
|
||||
}
|
||||
catch { }
|
||||
|
||||
@ -166,7 +166,7 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
{
|
||||
if (Game.CurrentQuest == 251355 && Game.CurrentStep == 14)
|
||||
{
|
||||
try { world.FindAt(ActorSno._x1_westm_door_cloister_locked, new Vector3D { X = 555.9f, Y = 403.47f, Z = 10.2f }, 5.0f).Destroy(); } catch { }
|
||||
try { world.FindActorAt(ActorSno._x1_westm_door_cloister_locked, new Vector3D { X = 555.9f, Y = 403.47f, Z = 10.2f }, 5.0f).Destroy(); } catch { }
|
||||
}
|
||||
});
|
||||
ListenKill(ActorSno._x1_skeleton_westmarch_a, 10, new Advance());
|
||||
|
||||
@ -122,31 +122,31 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem
|
||||
NextStep = -1,
|
||||
Objectives = new List<Objective> { Objective.Default() },
|
||||
OnAdvance = new Action(() => { //complete
|
||||
var NephalemWorld = Game.GetWorld(Game.WorldOfPortalNephalem);
|
||||
var nephalem = Game.GetWorld(Game.WorldOfPortalNephalem);
|
||||
ActorSystem.Actor BossOfPortal = null;
|
||||
|
||||
switch (Game.WorldOfPortalNephalem)
|
||||
{
|
||||
default:
|
||||
List<MapSystem.Scene> Scenes = new List<MapSystem.Scene>();
|
||||
foreach (var scene in NephalemWorld.Scenes.Values)
|
||||
List<MapSystem.Scene> scenes = new List<MapSystem.Scene>();
|
||||
foreach (var scene in nephalem.Scenes.Values)
|
||||
{
|
||||
if (!scene.SceneSNO.Name.ToLower().Contains("filler"))
|
||||
Scenes.Add(scene);
|
||||
scenes.Add(scene);
|
||||
}
|
||||
int SceneNum = Scenes.Count - DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 3);
|
||||
Vector3D SSV = Scenes[SceneNum - 1].Position;
|
||||
Vector3D SP = null;
|
||||
int sceneNum = scenes.Count - DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 3);
|
||||
Vector3D SSV = scenes[sceneNum - 1].Position;
|
||||
Vector3D location = null;
|
||||
while (true)
|
||||
{
|
||||
SP = new Vector3D(SSV.X + DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 240), SSV.Y + DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 240), SSV.Z);
|
||||
if (NephalemWorld.CheckLocationForFlag(SP, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk))
|
||||
location = new Vector3D(SSV.X + DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 240), SSV.Y + DiIiS_NA.Core.Helpers.Math.RandomHelper.Next(0, 240), SSV.Z);
|
||||
if (nephalem.CheckLocationForFlag(location, DiIiS_NA.Core.MPQ.FileFormats.Scene.NavCellFlags.AllowWalk))
|
||||
break;
|
||||
}
|
||||
BossOfPortal = NephalemWorld.SpawnMonster(ActorSno._x1_lr_boss_mistressofpain, SP);
|
||||
BossOfPortal = nephalem.SpawnMonster(ActorSno._x1_lr_boss_mistressofpain, location);
|
||||
break;
|
||||
}
|
||||
ActiveArrow(NephalemWorld, BossOfPortal.SNO);
|
||||
ActiveArrow(nephalem, BossOfPortal.SNO);
|
||||
ListenKill(BossOfPortal.SNO, 1, new QuestEvents.SideAdvance());
|
||||
})
|
||||
});
|
||||
|
||||
@ -17,14 +17,14 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem.QuestEvents.Implementations
|
||||
//if (world.Game.Empty) return;
|
||||
//Logger.Trace("SpawnSnakemans event started");
|
||||
var point = new Vector3D { X = 835.331f, Y = 410.121f, Z = 161.842f };
|
||||
var snakemanHandle = new Core.Types.SNO.SNOHandle((int)ActorSno._khamsin_snakeman_melee);
|
||||
var snakemanActor = snakemanHandle.Target as DiIiS_NA.Core.MPQ.FileFormats.Actor;
|
||||
var snakeManHandle = new Core.Types.SNO.SNOHandle((int)ActorSno._khamsin_snakeman_melee);
|
||||
var snakeManActor = snakeManHandle.Target as DiIiS_NA.Core.MPQ.FileFormats.Actor;
|
||||
try
|
||||
{
|
||||
var guard_a = world.FindAt(ActorSno._caldeumguard_cleaver_a, point, 20.0f);
|
||||
Vector3D guard_a_position = guard_a.Position;
|
||||
guard_a.Destroy(); //world.Game.
|
||||
world.Game.WorldGenerator.LoadActor(snakemanHandle,
|
||||
var caldeumGuard = world.FindActorAt(ActorSno._caldeumguard_cleaver_a, point, 20.0f);
|
||||
Vector3D guard_a_position = caldeumGuard.Position;
|
||||
caldeumGuard.Destroy(); //world.Game.
|
||||
world.Game.WorldGenerator.LoadActor(snakeManHandle,
|
||||
new PRTransform()
|
||||
{
|
||||
Quaternion = new Quaternion()
|
||||
@ -35,15 +35,15 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem.QuestEvents.Implementations
|
||||
Vector3D = guard_a_position
|
||||
},
|
||||
world,
|
||||
snakemanActor.TagMap);
|
||||
snakeManActor.TagMap);
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
var guard_b = world.FindAt(ActorSno._caldeumguard_cleaver_a, point, 20.0f);
|
||||
Vector3D guard_b_position = guard_b.Position;
|
||||
guard_b.Destroy();
|
||||
world.Game.WorldGenerator.LoadActor(snakemanHandle,
|
||||
var caldeumGuard = world.FindActorAt(ActorSno._caldeumguard_cleaver_a, point, 20.0f);
|
||||
Vector3D caldeumGuardPosition = caldeumGuard.Position;
|
||||
caldeumGuard.Destroy();
|
||||
world.Game.WorldGenerator.LoadActor(snakeManHandle,
|
||||
new PRTransform()
|
||||
{
|
||||
Quaternion = new Quaternion()
|
||||
@ -51,18 +51,18 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem.QuestEvents.Implementations
|
||||
W = 0.590017f,
|
||||
Vector3D = new Vector3D(0, 0, 0)
|
||||
},
|
||||
Vector3D = guard_b_position
|
||||
Vector3D = caldeumGuardPosition
|
||||
},
|
||||
world,
|
||||
snakemanActor.TagMap);
|
||||
snakeManActor.TagMap);
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
var guard_c = world.FindAt(ActorSno._davydimpostor, point, 20.0f);
|
||||
Vector3D guard_c_position = guard_c.Position;
|
||||
guard_c.Destroy();
|
||||
world.Game.WorldGenerator.LoadActor(snakemanHandle,
|
||||
var davydImpostor = world.FindActorAt(ActorSno._davydimpostor, point, 20.0f);
|
||||
Vector3D davydPosition = davydImpostor.Position;
|
||||
davydImpostor.Destroy();
|
||||
world.Game.WorldGenerator.LoadActor(snakeManHandle,
|
||||
new PRTransform()
|
||||
{
|
||||
Quaternion = new Quaternion()
|
||||
@ -70,10 +70,10 @@ namespace DiIiS_NA.GameServer.GSSystem.QuestSystem.QuestEvents.Implementations
|
||||
W = 0.590017f,
|
||||
Vector3D = new Vector3D(0, 0, 0)
|
||||
},
|
||||
Vector3D = guard_c_position
|
||||
Vector3D = davydPosition
|
||||
},
|
||||
world,
|
||||
snakemanActor.TagMap);
|
||||
snakeManActor.TagMap);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
user.block.title