From 10e791a7a2db3216a67672e4b58156cf68c69ba5 Mon Sep 17 00:00:00 2001 From: Killfrra Date: Mon, 2 May 2022 01:53:22 +0300 Subject: [PATCH] Progress #1407 -- `HandleSpawn` and `Champion` refactor (#1440) I refactored the `HandleSpawn` class and unified the spawning of champions with the spawning of other objects, moving most of the code into the appropriate class. Other changes: - The `NotifyS2C_CreateHero` function now accepts an optional parameter that allows the packet to be wrapped in a vision packet when sent, similar to the `NotifySpawn` function. - The same setting for `NotifySpawn` is now set to false by default. - All comparisons of `userId` with `0` are reduced to the form `<=`. --- .../Packets/Interfaces/IPacketNotifier.cs | 5 +- .../Chatbox/Commands/SpawnCommand.cs | 12 +-- .../AttackableUnits/AI/Champion.cs | 50 ++++++++++++ GameServerLib/GameObjects/GameObject.cs | 2 +- .../Packets/PacketHandlers/HandleSpawn.cs | 76 ------------------- GameServerLib/Players/PlayerManager.cs | 2 + PacketDefinitions420/PacketNotifier.cs | 57 +++++++------- 7 files changed, 84 insertions(+), 120 deletions(-) diff --git a/GameServerCore/Packets/Interfaces/IPacketNotifier.cs b/GameServerCore/Packets/Interfaces/IPacketNotifier.cs index af1eb1b37..3143dcf57 100644 --- a/GameServerCore/Packets/Interfaces/IPacketNotifier.cs +++ b/GameServerCore/Packets/Interfaces/IPacketNotifier.cs @@ -544,7 +544,8 @@ public interface IPacketNotifier /// /// Information about the client which had their hero created. /// User to send the packet to. Set to -1 to broadcast. - void NotifyS2C_CreateHero(ClientInfo clientInfo, int userId = -1); + /// Whether or not to package the packets into a vision packet. + void NotifyS2C_CreateHero(ClientInfo clientInfo, int userId = -1, bool doVision = false); void NotifyS2C_CreateMinionCamp(IMonsterCamp monsterCamp); void NotifyS2C_CreateNeutral(IMonster monster, float time); /// @@ -808,7 +809,7 @@ public interface IPacketNotifier /// UserId to send the packet to. /// Time elapsed since the start of the game /// Whether or not to package the packets into a vision packet. - void NotifySpawn(IGameObject obj, TeamId team, int userId, float gameTime, bool doVision = true); + void NotifySpawn(IGameObject obj, TeamId team, int userId, float gameTime, bool doVision = false); /// /// Sends a packet to the specified player detailing that the spawning (of champions & buildings) that occurs at the start of the game has ended. /// diff --git a/GameServerLib/Chatbox/Commands/SpawnCommand.cs b/GameServerLib/Chatbox/Commands/SpawnCommand.cs index ea9eaf3a8..912cce8cb 100644 --- a/GameServerLib/Chatbox/Commands/SpawnCommand.cs +++ b/GameServerLib/Chatbox/Commands/SpawnCommand.cs @@ -173,18 +173,8 @@ public void SpawnChampForTeam(TeamId team, int userId, string model) c.UpdateMoveOrder(OrderType.Stop); c.LevelUp(); - Game.PacketNotifier.NotifyS2C_CreateHero(clientInfoTemp); - Game.PacketNotifier.NotifyAvatarInfo(clientInfoTemp); Game.ObjectManager.AddObject(c); - Game.PacketNotifier.NotifyEnterLocalVisibilityClient(c, ignoreVision: true); - Game.PacketNotifier.NotifyOnReplication(c, partial: false); - - c.Stats.SetSpellEnabled(13, true); - c.Stats.SetSummonerSpellEnabled(0, true); - c.Stats.SetSummonerSpellEnabled(1, true); - - Game.PacketNotifier.NotifyEnterVisibilityClient(c, 0, true, true); - + ChatCommandManager.SendDebugMsgFormatted(DebugMsgType.INFO, "Spawned Bot" + clientInfoTemp.Name + " as " + c.Model + " with NetID: " + c.NetId + "."); } diff --git a/GameServerLib/GameObjects/AttackableUnits/AI/Champion.cs b/GameServerLib/GameObjects/AttackableUnits/AI/Champion.cs index c2e21fd23..61fe63ea0 100644 --- a/GameServerLib/GameObjects/AttackableUnits/AI/Champion.cs +++ b/GameServerLib/GameObjects/AttackableUnits/AI/Champion.cs @@ -40,6 +40,8 @@ public class Champion : ObjAiBase, IChampion public byte SkillPoints { get; set; } + public override bool SpawnShouldBeHidden => false; + public Champion(Game game, string model, uint playerId, @@ -103,6 +105,54 @@ public override void OnAdded() _game.ObjectManager.AddChampion(this); base.OnAdded(); TalentInventory.Initialize(this); + + var bluePill = _itemManager.GetItemType(_game.Map.MapScript.MapScriptMetadata.RecallSpellItemId); + Inventory.SetExtraItem(7, bluePill); + + // Runes + byte runeItemSlot = 14; + foreach (var rune in RuneList.Runes) + { + var runeItem = _itemManager.GetItemType(rune.Value); + var newRune = Inventory.SetExtraItem(runeItemSlot, runeItem); + Stats.AddModifier(runeItem); + runeItemSlot++; + } + Stats.SetSummonerSpellEnabled(0, true); + Stats.SetSummonerSpellEnabled(1, true); + } + + protected override void OnSpawn(int userId, TeamId team, bool doVision) + { + var peerInfo = _game.PlayerManager.GetClientInfoByChampion(this); + _game.PacketNotifier.NotifyS2C_CreateHero(peerInfo, userId, doVision); + _game.PacketNotifier.NotifyAvatarInfo(peerInfo, userId); + + bool ownChamp = peerInfo.PlayerId == userId; + if (ownChamp) + { + // Buy blue pill + var itemInstance = Inventory.GetItem(7); + _game.PacketNotifier.NotifyBuyItem(userId, this, itemInstance); + + // Set spell levels + foreach (var spell in Spells) + { + var castInfo = spell.Value.CastInfo; + if (castInfo.SpellLevel > 0) + { + // NotifyNPC_UpgradeSpellAns has no effect here + _game.PacketNotifier.NotifyS2C_SetSpellLevel(userId, NetId, castInfo.SpellSlot, castInfo.SpellLevel); + + float currentCD = spell.Value.CurrentCooldown; + float totalCD = spell.Value.GetCooldown(); + if (currentCD > 0) + { + _game.PacketNotifier.NotifyCHAR_SetCooldown(this, castInfo.SpellSlot, currentCD, totalCD, userId); + } + } + } + } } public override void OnRemoved() diff --git a/GameServerLib/GameObjects/GameObject.cs b/GameServerLib/GameObjects/GameObject.cs index 8a96c14d4..0a7298446 100644 --- a/GameServerLib/GameObjects/GameObject.cs +++ b/GameServerLib/GameObjects/GameObject.cs @@ -291,7 +291,7 @@ public virtual void Sync(int userId, TeamId team, bool visible, bool forceSpawn OnSync(userId, team); } } - else if (visible || !SpawnShouldBeHidden) + else if (forceSpawn || visible || !SpawnShouldBeHidden) { OnSpawn(userId, team, visible); SetVisibleForPlayer(userId, visible); diff --git a/GameServerLib/Packets/PacketHandlers/HandleSpawn.cs b/GameServerLib/Packets/PacketHandlers/HandleSpawn.cs index 1370af601..2f5472ed4 100644 --- a/GameServerLib/Packets/PacketHandlers/HandleSpawn.cs +++ b/GameServerLib/Packets/PacketHandlers/HandleSpawn.cs @@ -28,86 +28,10 @@ public HandleSpawn(Game game) private bool _firstSpawn = true; public override bool HandlePacket(int userId, SpawnRequest req) { - var players = _playerManager.GetPlayers(true); - - if (_firstSpawn) - { - _firstSpawn = false; - - var bluePill = _itemManager.GetItemType(_game.Map.MapScript.MapScriptMetadata.RecallSpellItemId); - - foreach (var kv in players) - { - var peerInfo = kv.Item2; - - var itemInstance = peerInfo.Champion.Inventory.SetExtraItem(7, bluePill); - - // Runes - byte runeItemSlot = 14; - foreach (var rune in peerInfo.Champion.RuneList.Runes) - { - var runeItem = _itemManager.GetItemType(rune.Value); - var newRune = peerInfo.Champion.Inventory.SetExtraItem(runeItemSlot, runeItem); - peerInfo.Champion.Stats.AddModifier(runeItem); - runeItemSlot++; - } - - peerInfo.Champion.Stats.SetSummonerSpellEnabled(0, true); - peerInfo.Champion.Stats.SetSummonerSpellEnabled(1, true); - - _game.ObjectManager.AddObject(peerInfo.Champion); - } - } - _logger.Debug("Spawning map"); _game.PacketNotifier.NotifyS2C_StartSpawn(userId); var userInfo = _playerManager.GetPeerInfo(userId); - - foreach (var kv in players) - { - var peerInfo = kv.Item2; - var champ = peerInfo.Champion; - - _game.PacketNotifier.NotifyS2C_CreateHero(peerInfo, userId); - _game.PacketNotifier.NotifyAvatarInfo(peerInfo, userId); - - // Buy blue pill - var itemInstance = peerInfo.Champion.Inventory.GetItem(7); - _game.PacketNotifier.NotifyBuyItem(userId, peerInfo.Champion, itemInstance); - - champ.SetSpawnedForPlayer(userId); - - if (_game.IsRunning) - { - bool ownChamp = peerInfo.PlayerId == userId; - if (ownChamp || champ.IsVisibleForPlayer(userId)) - { - _game.PacketNotifier.NotifyVisibilityChange(champ, userInfo.Team, true, userId); - } - if (ownChamp) - { - // Set spell levels - foreach (var spell in champ.Spells) - { - var castInfo = spell.Value.CastInfo; - if (castInfo.SpellLevel > 0) - { - // NotifyNPC_UpgradeSpellAns has no effect here - _game.PacketNotifier.NotifyS2C_SetSpellLevel(userId, champ.NetId, castInfo.SpellSlot, castInfo.SpellLevel); - - float currentCD = spell.Value.CurrentCooldown; - float totalCD = spell.Value.GetCooldown(); - if (currentCD > 0) - { - _game.PacketNotifier.NotifyCHAR_SetCooldown(champ, castInfo.SpellSlot, currentCD, totalCD, userId); - } - } - } - } - } - } - var om = _game.ObjectManager as ObjectManager; if (_game.IsRunning) { diff --git a/GameServerLib/Players/PlayerManager.cs b/GameServerLib/Players/PlayerManager.cs index 9409d3a8d..958098ba3 100644 --- a/GameServerLib/Players/PlayerManager.cs +++ b/GameServerLib/Players/PlayerManager.cs @@ -66,6 +66,8 @@ public void AddPlayer(KeyValuePair p) c.StopMovement(); c.UpdateMoveOrder(OrderType.Stop); + _game.ObjectManager.AddObject(c); + player.Champion = c; var pair = new Tuple ((uint)player.PlayerId, player); _players.Add(pair); diff --git a/PacketDefinitions420/PacketNotifier.cs b/PacketDefinitions420/PacketNotifier.cs index b58c01d69..216a486e4 100644 --- a/PacketDefinitions420/PacketNotifier.cs +++ b/PacketDefinitions420/PacketNotifier.cs @@ -773,7 +773,7 @@ public void NotifyAvatarInfo(ClientInfo client, int userId = -1) }; } - if (userId < 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacket(avatar.GetBytes(), Channel.CHL_S2C); return; @@ -1026,7 +1026,7 @@ public void NotifyCHAR_SetCooldown(IObjAiBase u, byte slotId, float currentCd, f { cdPacket.IsSummonerSpell = true; // TODO: Verify functionality } - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketVision(u, cdPacket.GetBytes(), Channel.CHL_S2C); } @@ -1144,7 +1144,7 @@ public void NotifyDisplayFloatingText(IFloatingTextData floatTextData, TeamId te Message = floatTextData.Message }; - if (userId == 0) + if (userId <= 0) { if (team != 0) { @@ -1202,7 +1202,7 @@ public void NotifyEnterLocalVisibilityClient(IGameObject o, int userId = 0, bool { var enterLocalVis = ConstructEnterLocalVisibilityClientPacket(o); - if (userId == 0) + if (userId <= 0) { if (ignoreVision) { @@ -1297,7 +1297,7 @@ public void NotifyFXCreateGroup(IParticle particle, int userId = 0) { var fxPacket = ConstructFXCreateGroupPacket(particle); - if (userId == 0) + if (userId <= 0) { // Broadcast only to specific team. if (particle.SpecificTeam != TeamId.TEAM_NEUTRAL) @@ -1394,7 +1394,7 @@ public void NotifyFXLeaveTeamVisibility(IParticle particle, TeamId team, int use fxVisPacket.VisibilityTeam = 1; } - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketTeam(team, fxVisPacket.GetBytes(), Channel.CHL_S2C); } @@ -1414,7 +1414,7 @@ public void NotifyGameStart(int userId = 0) { EnablePause = true }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacket(start.GetBytes(), Channel.CHL_S2C); } @@ -1662,7 +1662,7 @@ public void NotifyS2C_ChangeCharacterData(IAttackableUnit obj, int userId = 0, u } }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketVision(obj, newCharData.GetBytes(), Channel.CHL_S2C); } @@ -2242,7 +2242,7 @@ public void NotifyNPC_SetAutocast(IObjAiBase caster, ISpell spell, byte critSlot CritSlot = critSlot }; - if (critSlot == 0) + if (critSlot <= 0) { autoCast.CritSlot = autoCast.Slot; } @@ -2267,7 +2267,7 @@ public void NotifyNPC_SetAutocast(int userId, IObjAiBase caster, ISpell spell, b CritSlot = critSlot }; - if (critSlot == 0) + if (critSlot <= 0) { autoCast.CritSlot = autoCast.Slot; } @@ -2295,7 +2295,7 @@ public void NotifyOnReplication(IAttackableUnit u, int userId = 0, bool partial } }; var channel = Channel.CHL_LOW_PRIORITY; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketVision(u, us.GetBytes(), channel, PacketFlags.UNSEQUENCED); } @@ -2584,7 +2584,7 @@ public void NotifyS2C_ChangeMissileTarget(ISpellMissile p) /// /// Information about the client which had their hero created. /// User to send the packet to. Set to -1 to broadcast. - public void NotifyS2C_CreateHero(ClientInfo clientInfo, int userId = -1) + public void NotifyS2C_CreateHero(ClientInfo clientInfo, int userId = -1, bool doVision = false) { var champion = clientInfo.Champion; var heroPacket = new S2C_CreateHero() @@ -2604,25 +2604,22 @@ public void NotifyS2C_CreateHero(ClientInfo clientInfo, int userId = -1) Skin = champion.Model, DeathDurationRemaining = champion.RespawnTimer, // TimeSinceDeath + TeamIsOrder = champion.Team == TeamId.TEAM_BLUE, }; - - if (champion.Team == TeamId.TEAM_BLUE) + if (doVision) { - heroPacket.TeamIsOrder = true; + NotifyEnterTeamVision(champion, 0, userId, heroPacket); } - else + else if (userId <= 0) { - heroPacket.TeamIsOrder = false; + _packetHandlerManager.BroadcastPacket(heroPacket.GetBytes(), Channel.CHL_S2C); } - - if (userId < 0) + else { - _packetHandlerManager.BroadcastPacket(heroPacket.GetBytes(), Channel.CHL_S2C); - return; + _packetHandlerManager.SendPacket(userId, heroPacket.GetBytes(), Channel.CHL_S2C); } - - _packetHandlerManager.SendPacket(userId, heroPacket.GetBytes(), Channel.CHL_S2C); } + public void NotifyS2C_CreateMinionCamp(IMonsterCamp monsterCamp) { var packet = new S2C_CreateMinionCamp @@ -2900,7 +2897,7 @@ public void NotifyS2C_OnEnterTeamVisibility(IGameObject o, TeamId team, int user { var enterTeamVis = ConstructOnEnterTeamVisibilityPacket(o, team); - if (userId == 0) + if (userId <= 0) { // TODO: Verify if we should use BroadcastPacketTeam instead. _packetHandlerManager.BroadcastPacket(enterTeamVis.GetBytes(), Channel.CHL_S2C); @@ -2952,7 +2949,7 @@ public void NotifyS2C_OnLeaveTeamVisibility(IGameObject o, TeamId team, int user leaveTeamVis.VisibilityTeam = 1; } - if (userId == 0) + if (userId <= 0) { // TODO: Verify if we should use BroadcastPacketTeam instead. _packetHandlerManager.BroadcastPacket(leaveTeamVis.GetBytes(), Channel.CHL_S2C); @@ -3161,7 +3158,7 @@ public void NotifyS2C_StartSpawn(int userId = 0) BotCountOrder = 0, BotCountChaos = 0 }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacket(start.GetBytes(), Channel.CHL_S2C); } @@ -3499,7 +3496,7 @@ public void NotifySetTeam(IAttackableUnit unit) /// UserId to send the packet to. /// Time elapsed since the start of the game /// Whether or not to package the packets into a vision packet. - public void NotifySpawn(IGameObject obj, TeamId team, int userId, float gameTime, bool doVision = true) + public void NotifySpawn(IGameObject obj, TeamId team, int userId, float gameTime, bool doVision = false) { var spawnPacket = ConstructSpawnPacket(obj, gameTime); if (spawnPacket != null) @@ -3975,7 +3972,7 @@ void NotifyEnterTeamVision(IGameObject obj, TeamId team, int userId = 0, GamePac } }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketTeam(team, visibilityPacket.GetBytes(), Channel.CHL_S2C); _packetHandlerManager.BroadcastPacketTeam(team, healthbarPacket.GetBytes(), Channel.CHL_S2C); @@ -4002,7 +3999,7 @@ void NotifyEnterTeamVision(IGameObject obj, TeamId team, int userId = 0, GamePac packet = ConstructOnEnterTeamVisibilityPacket(obj, team); // Generic visibility packet } }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketTeam(team, packet.GetBytes(), Channel.CHL_S2C); } @@ -4133,7 +4130,7 @@ public void NotifyWaypointGroup(IAttackableUnit u, int userId = 0, bool useTelep Movements = new List() { move } }; - if (userId == 0) + if (userId <= 0) { _packetHandlerManager.BroadcastPacketVision(u, packet.GetBytes(), Channel.CHL_LOW_PRIORITY); }