From 58cbef023ebea117b96b5d6ed3464ccadb237789 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 21 Sep 2017 11:44:36 +1000 Subject: [PATCH] Add EntitySpawned/EntityDespawned events. --- MCGalaxy/Entity/Entities.cs | 41 ++++++++++------------- MCGalaxy/Events/EntityEvents.cs | 39 +++++++++++++++++++-- MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs | 14 ++++++++ 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/MCGalaxy/Entity/Entities.cs b/MCGalaxy/Entity/Entities.cs index eddbe55da..c51012f0e 100644 --- a/MCGalaxy/Entity/Entities.cs +++ b/MCGalaxy/Entity/Entities.cs @@ -14,6 +14,7 @@ permissions and limitations under the Licenses. */ using System; using System.Text; +using MCGalaxy.Events.EntityEvents; using MCGalaxy.Games; using MCGalaxy.Network; using MCGalaxy.Maths; @@ -84,20 +85,12 @@ namespace MCGalaxy { Orientation rot, string possession = "") { byte id = p == dst ? Entities.SelfID : p.id; - if (!ServerConfig.TablistGlobal) - TabList.Add(dst, p, id); - if (!Server.zombie.Running || !p.Game.Infected) { - SpawnRaw(dst, id, p.SkinName, p.color + p.truename + possession, p.Model, p.Pos, p.Rot); - return; - } + string name = p.color + p.truename + possession; + string skin = p.SkinName, model = p.Model; + OnEntitySpawnedEvent.Call(p, ref name, ref skin, ref model, dst); - string name = p.truename, skinName = p.SkinName; - if (ZSConfig.ZombieName.Length > 0 && !dst.Game.Aka) { - name = ZSConfig.ZombieName; skinName = name; - } - - string model = p == dst ? p.Model : ZSConfig.ZombieModel; - SpawnRaw(dst, id, skinName, Colors.red + name + possession, model, p.Pos, p.Rot); + SpawnRaw(dst, id, skin, name, model, p.Pos, p.Rot); + if (!ServerConfig.TablistGlobal) TabList.Add(dst, p, id); } /// Spawns this player to all other players, and spawns all others players to this player. @@ -133,15 +126,15 @@ namespace MCGalaxy { internal static void Spawn(Player dst, PlayerBot b) { string name = Chat.Format(b.color + b.DisplayName, dst, true, false); if (b.DisplayName.CaselessEq("empty")) name = ""; - string skin = Chat.Format(b.SkinName, dst, true, false); - - SpawnRaw(dst, b.id, skin, name, b.Model, b.Pos, b.Rot); - if (ServerConfig.TablistBots) - TabList.Add(dst, b); + string skin = Chat.Format(b.SkinName, dst, true, false), model = b.Model; + + OnEntitySpawnedEvent.Call(b, ref name, ref skin, ref model, dst); + SpawnRaw(dst, b.id, skin, name, model, b.Pos, b.Rot); + if (ServerConfig.TablistBots) TabList.Add(dst, b); } - public static void SpawnRaw(Player dst, byte id, string skin, string name, - string model, Position pos, Orientation rot) { + static void SpawnRaw(Player dst, byte id, string skin, string name, + string model, Position pos, Orientation rot) { // NOTE: Fix for standard clients if (id == Entities.SelfID) pos.Y -= 22; name = Colors.Cleanup(name, dst.hasTextColors); @@ -163,16 +156,16 @@ namespace MCGalaxy { } internal static void Despawn(Player dst, Player other) { + OnEntityDespawnedEvent.Call(other, dst); byte id = other == dst ? SelfID : other.id; dst.Send(Packet.RemoveEntity(id)); - if (!ServerConfig.TablistGlobal) - TabList.Remove(dst, other); + if (!ServerConfig.TablistGlobal) TabList.Remove(dst, other); } internal static void Despawn(Player dst, PlayerBot b) { + OnEntityDespawnedEvent.Call(b, dst); dst.Send(Packet.RemoveEntity(b.id)); - if (ServerConfig.TablistBots) - TabList.Remove(dst, b); + if (ServerConfig.TablistBots) TabList.Remove(dst, b); } #endregion diff --git a/MCGalaxy/Events/EntityEvents.cs b/MCGalaxy/Events/EntityEvents.cs index 16fb032e7..906b502ed 100644 --- a/MCGalaxy/Events/EntityEvents.cs +++ b/MCGalaxy/Events/EntityEvents.cs @@ -42,8 +42,43 @@ namespace MCGalaxy.Events.EntityEvents { public sealed class OnTabListEntryRemovedEvent : IEvent { public static void Call(Entity entity, Player dst) { - if (handlers.Count == 0) return; - CallCommon(pl => pl(entity, dst)); + IEvent[] items = handlers.Items; + // Don't use CallCommon, because this event is called very frequently + // and want to avoid lots of pointless temp mem allocations + for (int i = 0; i < items.Length; i++) { + try { items[i].method(entity, dst); } + catch (Exception ex) { LogHandlerException(ex, items[i]); } + } + } + } + + public delegate void OnEntitySpawned(Entity entity, ref string name, ref string skin, ref string model, Player dst); + /// Called when an entity is being spawned to someone. + public sealed class OnEntitySpawnedEvent : IEvent { + + public static void Call(Entity entity, ref string name, ref string skin, ref string model, Player dst) { + IEvent[] items = handlers.Items; + // Can't use CallCommon because we need to pass arguments by ref + for (int i = 0; i < items.Length; i++) { + try { + items[i].method(entity, ref name, ref skin, ref model, dst); + } catch (Exception ex) { + LogHandlerException(ex, items[i]); + } + } + } + } + + public delegate void OnEntityDespawned(Entity entity, Player dst); + /// Called when an entity is being despawned from someone. + public sealed class OnEntityDespawnedEvent : IEvent { + + public static void Call(Entity entity, Player dst) { + IEvent[] items = handlers.Items; + for (int i = 0; i < items.Length; i++) { + try { items[i].method(entity, dst); } + catch (Exception ex) { LogHandlerException(ex, items[i]); } + } } } } diff --git a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs index 3c84e8633..e585f7020 100644 --- a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs +++ b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs @@ -30,6 +30,7 @@ namespace MCGalaxy.Games.ZS { public ZSGame Game; public override void Load(bool startup) { + OnEntitySpawnedEvent.Register(HandleEntitySpawned, Priority.High); OnTabListEntryAddedEvent.Register(HandleTabListEntryAdded, Priority.High); OnMoneyChangedEvent.Register(HandleMoneyChanged, Priority.High); OnPlayerConnectEvent.Register(HandlePlayerConnect, Priority.High); @@ -41,6 +42,7 @@ namespace MCGalaxy.Games.ZS { } public override void Unload(bool shutdown) { + OnEntitySpawnedEvent.Unregister(HandleEntitySpawned); OnTabListEntryAddedEvent.Unregister(HandleTabListEntryAdded); OnMoneyChangedEvent.Unregister(HandleMoneyChanged); OnPlayerConnectEvent.Unregister(HandlePlayerConnect); @@ -74,6 +76,18 @@ namespace MCGalaxy.Games.ZS { HUD.UpdateTertiary(p); } + void HandleEntitySpawned(Entity entity, ref string name, ref string skin, ref string model, Player dst) { + Player p = entity as Player; + if (p == null || !p.Game.Infected) return; + + name = p.truename; + if (ZSConfig.ZombieName.Length > 0 && !dst.Game.Aka) { + name = ZSConfig.ZombieName; skin = name; + } + name = Colors.red + name; + model = p == dst ? p.Model : ZSConfig.ZombieModel; + } + void HandlePlayerConnect(Player p) { if (!ZSConfig.SetMainLevel) return; Player.Message(p, "Zombie Survival is running! Type %T/ZS go %Sto join.");