diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index d9b6363..8494bb1 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -7,6 +7,7 @@ namespace Campofinale.Game.Entities public class EntityMonster : Entity { public string templateId; + public ulong originId; public EntityMonster() { @@ -83,7 +84,7 @@ namespace Campofinale.Game.Entities Type =(int) ObjectTypeIndex.Enemy, }, - + OriginId= originId, Attrs = { GetAttributes() diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index e81d4ef..e2de607 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -3,10 +3,14 @@ using Campofinale.Game.Inventory; using Campofinale.Game.Spawners; using Campofinale.Packets.Sc; using Campofinale.Resource; +using Campofinale.Resource.Dynamic; using MongoDB.Bson.Serialization.Attributes; +using System.Numerics; using System.Text.Json.Serialization; +using static Campofinale.Resource.Dynamic.SpawnerConfig; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; +using static System.Formats.Asn1.AsnWriter; namespace Campofinale.Game { @@ -256,8 +260,6 @@ namespace Campofinale.Game public bool alreadyLoaded = false; [BsonIgnore, JsonIgnore] public List activeScripts = new(); - [BsonIgnore, JsonIgnore] - public List gameSpawners = new(); public int GetCollection(string id) { if (collections.ContainsKey(id)) @@ -354,7 +356,7 @@ namespace Campofinale.Game lv_scene.levelData.npcs.ForEach(en => { - if (en.npcGroupId.Contains("chr") && sceneNumId== 99) return; + if (en.npcGroupId.Contains("chr")) return; EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId) { belongLevelScriptId = en.belongLevelScriptId, @@ -365,22 +367,7 @@ namespace Campofinale.Game entity.defaultHide = en.defaultHide; entities.Add(entity); }); - GetEntityExcludingChar().ForEach(e => - { - if(e is EntityInteractive) - { - // e.spawned = true; - // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); - } - - - }); - GetEntityExcludingChar().FindAll(e=> e is not EntityInteractive).ForEach(e => - { - - // e.spawned = true; - // GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { e })); - }); + UpdateShowEntities(); @@ -389,31 +376,13 @@ namespace Campofinale.Game public void SpawnEntity(Entity en,bool spawnedCheck=true) { - if (!activeScripts.Contains(en.belongLevelScriptId) && en.defaultHide && en.belongLevelScriptId != 0) - { - return; - } - en.spawned = true; - ParamKeyValue targetList=en.properties.Find(p => p.key == "target_list"); - if(targetList!=null) - foreach (Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned == false && targetList.value.valueArray.Any(v=>v.valueBit64== (long)e.levelLogicId))) - { - SpawnEntity(e); - } + en.spawned = true; + GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List() { en })); } public void UpdateShowEntities() { - for (int i = 0; i < gameSpawners.Count; i++) - { - GameSpawner spawner = gameSpawners[i]; - if(spawner != null) - { - spawner.Update(GetOwner()); - } - } - List toSpawn = new(); foreach(Entity e in GetEntityExcludingChar()) { @@ -489,6 +458,34 @@ namespace Campofinale.Game } } - + public void SpawnWaveEnemy(ulong spawnerId, int waveId) + { + LevelSpawnerData data=info().levelData.spawners.Find(s => s.spawnerId == spawnerId); + if (data!=null) + { + SpawnerConfig config = spawnerConfigs.Find(s => s.configId == data.configId); + if (config != null) + { + foreach(var group in config.waveMap[$"{waveId}"].groupMap.Values) + { + foreach (var act in group.actionMap.Values) + { + EnemyLibraryData enemyData = config.enemyLibrary.Find(e=>e.key==act.libraryKey); + if (enemyData != null) + { + entities.Add(new EntityMonster(enemyData.enemyId, enemyData.enemyLevel, ownerId, act.position, act.rotation, sceneNumId) + { + + defaultHide = false, + spawned = false, + belongLevelScriptId = data.belongLevelScriptId + }); + } + + } + } + } + } + } } } diff --git a/Campofinale/Game/Spawners/GameSpawner.cs b/Campofinale/Game/Spawners/GameSpawner.cs deleted file mode 100644 index 0016bab..0000000 --- a/Campofinale/Game/Spawners/GameSpawner.cs +++ /dev/null @@ -1,67 +0,0 @@ -using Campofinale.Game.Entities; -using Campofinale.Resource; -using Campofinale.Resource.Dynamic; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Campofinale.Game.Spawners -{ - public class GameSpawner - { - public Scene scene; - public int curWave = 1; - public int curGroup = 1; - public string configId; - public bool spawned; - - public SpawnerConfig GetConfig() - { - return ResourceManager.spawnerConfigs.Find(s => s.configId == configId); - } - public SpawnerConfig.WaveGroup GetCurrentWaveGroup() - { - return GetConfig().waveMap[$"{curWave}"].groupMap[$"{curGroup}"]; - } - public int GetEnemiesOfCurrentWave() - { - return scene.entities.FindAll(e => e.dependencyGroupId == GetCurrentWaveGroup().groupId).Count; - } - - public void Update(Player player) - { - if (spawned) - { - if (GetEnemiesOfCurrentWave() < 1) - { - if (GetConfig().waveMap.ContainsKey($"{curWave + 1}")) - { - curWave++; - spawned = false; - } - } - } - else - { - - foreach (var item in GetCurrentWaveGroup().actionMap.Values) - { - Logger.Print($"Debug: Spawning {item.libraryKey}"); - scene.entities.Add(new EntityMonster(item.libraryKey, 1, player.roleId, item.position, item.rotation, scene.sceneNumId) - { - dependencyGroupId = GetCurrentWaveGroup().groupId, - defaultHide = false, - spawned = false - }); - - - } - spawned = true; - - } - - } - } -} diff --git a/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs b/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs new file mode 100644 index 0000000..2c6f979 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSceneMonsterSpawnerBeginWave.cs @@ -0,0 +1,24 @@ +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsSceneMonsterSpawnerBeginWave + { + + [Server.Handler(CsMsgId.CsSceneMonsterSpawnerBeginWave)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSceneMonsterSpawnerBeginWave req = packet.DecodeBody(); + session.sceneManager.GetCurScene().SpawnWaveEnemy(req.SpawnerId, req.WaveId); + session.Send(ScMsgId.ScSceneMonsterSpawnerBeginWave, new ScSceneMonsterSpawnerBeginWave() + { + SceneNumId=req.SceneNumId, + SpawnerId=req.SpawnerId, + WaveId=req.WaveId, + }); + + } + + } +} diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 3e98a2f..5ae0b23 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -71,7 +71,7 @@ namespace Campofinale.Packets.Cs State = 4 }; - + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } @@ -122,11 +122,13 @@ namespace Campofinale.Packets.Cs break; case ScriptActionType.StartSpawner: - player.sceneManager.GetCurScene().gameSpawners.Add(new Game.Spawners.GameSpawner() + ScSceneMonsterSpawnerStart start = new() { - configId = action.valueStr[0], - scene= player.sceneManager.GetCurScene() - }); + SceneNumId = player.curSceneNumId, + SpawnerId = action.valueUlong[0], + + }; + player.Send(ScMsgId.ScSceneMonsterSpawnerStart,start); break; case ScriptActionType.AddCharacter: Character chara =player.AddCharacter(action.valueStr[0],(int) action.valueUlong[0],true); diff --git a/Campofinale/Resource/Dynamic/SpawnerConfig.cs b/Campofinale/Resource/Dynamic/SpawnerConfig.cs index d739539..1f2857b 100644 --- a/Campofinale/Resource/Dynamic/SpawnerConfig.cs +++ b/Campofinale/Resource/Dynamic/SpawnerConfig.cs @@ -12,11 +12,17 @@ namespace Campofinale.Resource.Dynamic { public string configId; public Dictionary waveMap = new(); + public List enemyLibrary = new(); - - + public SpawnerConfig() { } + public class EnemyLibraryData + { + public string key; + public string enemyId; + public int enemyLevel; + } public class SpawnerWave { public int waveId; diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 7a0c04b..cae533a 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -534,6 +534,7 @@ namespace Campofinale.Resource public List levelScripts = new(); public List worldWayPointSets = new(); public List factoryRegions = new(); + public List spawners = new(); public void Merge(LevelData other) { this.sceneId = other.sceneId; @@ -544,6 +545,7 @@ namespace Campofinale.Resource this.levelScripts.AddRange(other.levelScripts); this.worldWayPointSets.AddRange(other.worldWayPointSets); this.factoryRegions.AddRange(other.factoryRegions); + this.spawners.AddRange(other.spawners); } public class WorldWayPointSets @@ -551,6 +553,12 @@ namespace Campofinale.Resource public int id; public Dictionary pointIdToIndex = new(); } + public class LevelSpawnerData + { + public ulong spawnerId; + public string configId; + public ulong belongLevelScriptId; + } public class LevelScriptData { public ulong scriptId;