From 5e68f54c48034f829dde10938e7dfaf8c72dd1e5 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Tue, 10 Jun 2025 21:14:38 +0200 Subject: [PATCH] real enemy drops, improved code etc, i dont remember everything i made LOL --- Campofinale/Game/Entities/Entity.cs | 5 ++ Campofinale/Game/Entities/EntityMonster.cs | 19 ++++++ Campofinale/Game/Inventory/Item.cs | 3 +- Campofinale/Game/MissionSys/GameMission.cs | 25 ++++++++ Campofinale/Game/MissionSys/GameQuest.cs | 24 +++++++ Campofinale/Game/MissionSys/MissionSystem.cs | 31 +--------- Campofinale/Game/SceneManager.cs | 58 ++++++++--------- Campofinale/Http/Dispatch.cs | 14 ++++- .../Cs/HandleCsSceneSetLastSafeZone.cs | 4 +- .../Cs/HandleCsSceneSetLevelScriptActive.cs | 38 +++++++++--- Campofinale/Player.cs | 6 +- Campofinale/Resource/GameEnums.cs | 10 ++- Campofinale/Resource/ResourceManager.cs | 62 ++++++++++++------- .../Resource/Table/WikiEnemyDropTable.cs | 8 +++ 14 files changed, 206 insertions(+), 101 deletions(-) create mode 100644 Campofinale/Game/MissionSys/GameMission.cs create mode 100644 Campofinale/Game/MissionSys/GameQuest.cs create mode 100644 Campofinale/Resource/Table/WikiEnemyDropTable.cs diff --git a/Campofinale/Game/Entities/Entity.cs b/Campofinale/Game/Entities/Entity.cs index 264e3f1..df9363a 100644 --- a/Campofinale/Game/Entities/Entity.cs +++ b/Campofinale/Game/Entities/Entity.cs @@ -1,4 +1,5 @@ using Campofinale.Resource; +using System.Threading; using static Campofinale.Resource.ResourceManager; using static Campofinale.Resource.ResourceManager.LevelScene.LevelData; @@ -41,6 +42,10 @@ namespace Campofinale.Game.Entities public virtual void Heal(double heal) { + } + public virtual void OnDie() + { + } public virtual bool Interact(string eventName, Google.Protobuf.Collections.MapField properties) { diff --git a/Campofinale/Game/Entities/EntityMonster.cs b/Campofinale/Game/Entities/EntityMonster.cs index 8494bb1..08cdc94 100644 --- a/Campofinale/Game/Entities/EntityMonster.cs +++ b/Campofinale/Game/Entities/EntityMonster.cs @@ -1,5 +1,7 @@ using Campofinale.Protocol; using Campofinale.Resource; +using Campofinale.Resource.Table; +using System.Threading; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Entities @@ -97,6 +99,23 @@ namespace Campofinale.Game.Entities }; return proto; } + public override void OnDie() + { + if (!wikiEnemyDropTable.ContainsKey(templateId)) return; + WikiEnemyDropTable table = wikiEnemyDropTable[templateId]; + if (table!=null) + { + table.dropItemIds.ForEach(id => + { + GetOwner().sceneManager.CreateDrop(Position, new RewardTable.ItemBundle() + { + id = id, + count = 1 + }); + }); + } + + } public override void Damage(double dmg) { curHp -= dmg; diff --git a/Campofinale/Game/Inventory/Item.cs b/Campofinale/Game/Inventory/Item.cs index d887947..a35230a 100644 --- a/Campofinale/Game/Inventory/Item.cs +++ b/Campofinale/Game/Inventory/Item.cs @@ -11,6 +11,7 @@ using static Campofinale.Resource.ResourceManager; using Google.Protobuf.Collections; using Campofinale.Packets.Sc; using Campofinale.Protocol; +using CsvHelper.Configuration.Attributes; namespace Campofinale.Game.Inventory { @@ -101,7 +102,7 @@ namespace Campofinale.Game.Inventory GemId = guid, TemplateId= ResourceManager.GetItemTemplateId(id), WeaponId= GetOwner().inventoryManager.items.Find(i=>i.attachGemId==guid)!=null ? GetOwner().inventoryManager.items.Find(i => i.attachGemId == guid).guid: 0, - + }, IsLock = locked } diff --git a/Campofinale/Game/MissionSys/GameMission.cs b/Campofinale/Game/MissionSys/GameMission.cs new file mode 100644 index 0000000..ddc1837 --- /dev/null +++ b/Campofinale/Game/MissionSys/GameMission.cs @@ -0,0 +1,25 @@ +using Campofinale.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.MissionSys +{ + public class GameMission + { + public string missionId; + public MissionState state; + + public GameMission() + { + + } + public GameMission(string id, MissionState state = MissionState.Available) + { + missionId = id; + this.state = state; + } + } +} diff --git a/Campofinale/Game/MissionSys/GameQuest.cs b/Campofinale/Game/MissionSys/GameQuest.cs new file mode 100644 index 0000000..7137bf6 --- /dev/null +++ b/Campofinale/Game/MissionSys/GameQuest.cs @@ -0,0 +1,24 @@ +using Campofinale.Resource; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.MissionSys +{ + public class GameQuest + { + public string questId; + public QuestState state; + public GameQuest() + { + + } + public GameQuest(string id, QuestState state = QuestState.Available) + { + questId = id; + this.state = state; + } + } +} diff --git a/Campofinale/Game/MissionSys/MissionSystem.cs b/Campofinale/Game/MissionSys/MissionSystem.cs index 8b9428d..70f24cb 100644 --- a/Campofinale/Game/MissionSys/MissionSystem.cs +++ b/Campofinale/Game/MissionSys/MissionSystem.cs @@ -266,33 +266,6 @@ namespace Campofinale.Game.MissionSys } } } - public class GameQuest - { - public string questId; - public QuestState state; - public GameQuest() - { - - } - public GameQuest(string id, QuestState state = QuestState.Available) - { - questId = id; - this.state = state; - } - } - public class GameMission - { - public string missionId; - public MissionState state; - - public GameMission() - { - - } - public GameMission(string id, MissionState state = MissionState.Available) - { - missionId = id; - this.state = state; - } - } + + } diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index c90de27..35a1ada 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -90,43 +90,40 @@ namespace Campofinale.Game if (scene != null) { - if(GetEntity(guid) is EntityMonster) + Entity entity = GetEntity(guid); + if (entity != null) { - EntityMonster monster = (EntityMonster)GetEntity(guid); - CreateDrop(monster.Position, new RewardTable.ItemBundle() + entity.OnDie(); + if (killClient) { - id = "item_gem_rarity_3", - count=1 - }); - LevelScene lv_scene = ResourceManager.GetLevelData(GetEntity(guid).sceneNumId); - LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid); - if (d != null) - { - if (!d.respawnable) + ScSceneDestroyEntity destroy = new() { - player.noSpawnAnymore.Add(monster.guid); + Id = guid, + Reason = reason, + SceneNumId = GetEntity(guid).sceneNumId, + }; + player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy); + + } + if (entity is EntityMonster monster) + { + LevelScene lv_scene = ResourceManager.GetLevelData(entity.sceneNumId); + LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid); + if (d != null) + { + if (!d.respawnable) + { + player.noSpawnAnymore.Add(monster.guid); + } } } - } - if (killClient) - { - ScSceneDestroyEntity destroy = new() + if (scenes.Find(s => s.sceneNumId == entity.sceneNumId) != null) { - Id = guid, - Reason = reason, - SceneNumId = GetEntity(guid).sceneNumId, - }; - player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy); - } - if (GetEntity(guid) != null) - { - if(scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId) != null) - { - scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId).entities.Remove(GetEntity(guid)); + scenes.Find(s => s.sceneNumId == entity.sceneNumId).entities.Remove(entity); } + } - } } public void CreateDrop(Vector3f pos,ResourceManager.RewardTable.ItemBundle bundle) @@ -400,8 +397,11 @@ namespace Campofinale.Game { List toSpawn = new(); - foreach(Entity e in GetEntityExcludingChar().FindAll(e=>e.spawned==false)) + List toCheck = GetEntityExcludingChar().FindAll(e => e.spawned == false); + toCheck.Sort((a, b) => a.Position.Distance(GetOwner().position).CompareTo(b.Position.Distance(GetOwner().position))); + foreach (Entity e in toCheck) { + if(e.spawned==false && (GetActiveScript(e.belongLevelScriptId) || e.belongLevelScriptId==0)) { if (!e.defaultHide) diff --git a/Campofinale/Http/Dispatch.cs b/Campofinale/Http/Dispatch.cs index 4a495a7..24d56be 100644 --- a/Campofinale/Http/Dispatch.cs +++ b/Campofinale/Http/Dispatch.cs @@ -122,7 +122,19 @@ namespace Campofinale.Http await ctx.Response.SendAsync(resp); } - + [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/remote_config/get_remote_config/1003/prod-cbt/default/Windows/res_version")] + public static async Task os_windows_res_version(HttpContext ctx) + { + + string resp = "{\"version\": \"2089329-32\", \"kickFlag\": true}"; + + + ctx.Response.StatusCode = 200; + //ctx.Response.ContentLength = resp.Length; + ctx.Response.ContentType = "application/json"; + + await ctx.Response.SendAsync(resp); + } [StaticRoute(HttpServerLite.HttpMethod.GET, "/api/gameBulletin/version")] public static async Task Version(HttpContext ctx) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs index 2095ed7..30c39d0 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLastSafeZone.cs @@ -10,9 +10,7 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneSetLastSafeZone req = packet.DecodeBody(); - - - + } } diff --git a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs index 5b151f7..73ed6b9 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneSetLevelScriptActive.cs @@ -44,20 +44,21 @@ namespace Campofinale.Packets.Cs } else { - /* ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) { - SceneNumId = req.SceneNumId, - ScriptId = req.ScriptId, + sceneScript.state = 2; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, - State = 3 - }; + State = sceneScript.state + }; - if (!session.sceneManager.GetCurScene().activeScripts.Contains(req.ScriptId)) - { - session.sceneManager.GetCurScene().activeScripts.Add(req.ScriptId); session.sceneManager.GetCurScene().UpdateShowEntities(); + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp);*/ } @@ -84,7 +85,24 @@ namespace Campofinale.Packets.Cs session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); } - + + } + else + { + var sceneScript = session.sceneManager.GetCurScene().scripts.Find(s => s.scriptId == req.ScriptId); + if (sceneScript != null) + { + sceneScript.state = 3; + ScSceneLevelScriptStateNotify rsp = new ScSceneLevelScriptStateNotify() + { + SceneNumId = req.SceneNumId, + ScriptId = req.ScriptId, + + State = sceneScript.state + }; + + session.Send(ScMsgId.ScSceneLevelScriptStateNotify, rsp); + } } diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 18a6f1a..4659602 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -81,8 +81,8 @@ namespace Campofinale //Data public string accountId = ""; public string nickname = "Endministrator"; - public ulong roleId= 1; - public Gender gender=Gender.GenFemale; + public ulong roleId = 1; + public Gender gender = Gender.GenFemale; public uint level = 20; public uint xp = 0; // @@ -99,7 +99,7 @@ namespace Campofinale public FactoryManager factoryManager; public MissionSystem missionSystem; public int teamIndex = 0; - public List teams= new List(); + public List teams = new List(); public List mails = new List(); public List unlockedSystems = new(); public List noSpawnAnymore = new(); diff --git a/Campofinale/Resource/GameEnums.cs b/Campofinale/Resource/GameEnums.cs index f53c5f5..e74b912 100644 --- a/Campofinale/Resource/GameEnums.cs +++ b/Campofinale/Resource/GameEnums.cs @@ -1,6 +1,6 @@ namespace Campofinale.Resource { - public enum MissionState : int// TypeDefIndex: 33630 + public enum MissionState { None = 0, Available = 1, @@ -17,6 +17,14 @@ Completed = 3, Failed = 4, } + public enum LevelScriptState + { + None = 0, + Disabled = 1, + Enabled = 2, + Active = 3, + Running = 4 + } public enum InteractiveComponentType { TriggerObserver = 0, diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 97c924e..63ec522 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -54,6 +54,7 @@ namespace Campofinale.Resource public static Dictionary gachaWeaponPoolTable = new(); // public static Dictionary enemyTable = new(); + public static Dictionary wikiEnemyDropTable = new(); public static Dictionary equipTable = new(); public static Dictionary equipSuitTable = new(); public static Dictionary spaceShipCharBehaviourTable = new(); @@ -107,7 +108,6 @@ namespace Campofinale.Resource // TODO: move all tables to the folder sceneAreaTable=JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SceneAreaTable.json")); strIdNumTable = JsonConvert.DeserializeObject(ReadJsonFile("TableCfg/StrIdNumTable.json")); - characterTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/CharacterTable.json")); systemJumpTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SystemJumpTable.json")); settlementBasicDataTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SettlementBasicDataTable.json")); blocMissionTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/BlocMissionTable.json")); @@ -138,15 +138,12 @@ namespace Campofinale.Resource spaceshipRoomInsTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/SpaceshipRoomInsTable.json")); dungeonTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/DungeonTable.json")); equipSuitTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/EquipSuitTable.json")); - levelGradeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/LevelGradeTable.json")); levelShortIdTable = JsonConvert.DeserializeObject>(ReadJsonFile("DynamicAssets/gamedata/gameplayconfig/jsoncfg/LevelShortIdTable.json")); rewardTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/RewardTable.json")); adventureTaskTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/AdventureTaskTable.json")); factoryBuildingTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FactoryBuildingTable.json")); facSTTNodeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FacSTTNodeTable.json")); facSTTLayerTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/FacSTTLayerTable.json")); - itemTypeTable = JsonConvert.DeserializeObject>(ReadJsonFile("TableCfg/ItemTypeTable.json")); - interactiveTable = JsonConvert.DeserializeObject(ReadJsonFile("Json/Interactive/InteractiveTable.json")); LoadInteractiveData(); LoadLevelDatas(); LoadScriptsEvent(); @@ -155,7 +152,7 @@ namespace Campofinale.Resource if (missingResources) { - Logger.PrintWarn("Missing some resources. The gameserver will probably crash."); + Logger.PrintWarn("Some Resources are Missing. The Game server may not work properly."); } } public static List GetAllShortIds() @@ -242,38 +239,55 @@ namespace Campofinale.Resource { Logger.Print("Loading ScriptsEvents"); string directoryPath = @"Json/ScriptEvents"; - string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); - foreach (string json in jsonFiles) + try { - Dictionary events = JsonConvert.DeserializeObject>(ReadJsonFile(json)); - foreach(KeyValuePair e in events) + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) { - if (levelScriptsEvents.ContainsKey(e.Key)) + Dictionary events = JsonConvert.DeserializeObject>(ReadJsonFile(json)); + foreach (KeyValuePair e in events) { - Logger.PrintWarn($"{e.Key} already added, skipping the one in {json}"); + if (levelScriptsEvents.ContainsKey(e.Key)) + { + Logger.PrintWarn($"{e.Key} already added, skipping the one in {json}"); + } + else + { + levelScriptsEvents.Add(e.Key, e.Value); + } + } - else - { - levelScriptsEvents.Add(e.Key,e.Value); - } - + } - + Logger.Print($"Loaded {levelScriptsEvents.Count} ScriptsEvents"); } - Logger.Print($"Loaded {levelScriptsEvents.Count} ScriptsEvents"); + catch (Exception e) + { + Logger.PrintWarn($"No ScriptsEvents folder found in Json."); + } + + } public static void LoadSpawners() { Logger.Print("Loading Spawners"); string directoryPath = @"DynamicAssets\gamedata\spawnerconfig"; - string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); - foreach (string json in jsonFiles) + try { - SpawnerConfig spawner = JsonConvert.DeserializeObject(ReadJsonFile(json)); - spawnerConfigs.Add(spawner); + string[] jsonFiles = Directory.GetFiles(directoryPath, "*.json", SearchOption.AllDirectories); + foreach (string json in jsonFiles) + { + SpawnerConfig spawner = JsonConvert.DeserializeObject(ReadJsonFile(json)); + spawnerConfigs.Add(spawner); + } + Logger.Print($"Loaded {spawnerConfigs.Count} Spawners"); } - Logger.Print($"Loaded {spawnerConfigs.Count} Spawners"); + catch (Exception e) + { + Logger.PrintError($"Error occured when loading SpawnerConfigs: " + e.Message); + } + } public static void LoadLevelDatas() { @@ -302,7 +316,7 @@ namespace Campofinale.Resource catch (Exception ex) { //Logger.PrintError(ex.Message); - Logger.PrintWarn("Missing levelData natural spawns file for scene " + data.mapIdStr + " path: " + path); + Logger.PrintWarn("Missing LevelData natural spawns file for scene " + data.mapIdStr + " path: " + path); } } diff --git a/Campofinale/Resource/Table/WikiEnemyDropTable.cs b/Campofinale/Resource/Table/WikiEnemyDropTable.cs new file mode 100644 index 0000000..6402dc5 --- /dev/null +++ b/Campofinale/Resource/Table/WikiEnemyDropTable.cs @@ -0,0 +1,8 @@ +namespace Campofinale.Resource.Table +{ + [TableCfgType("TableCfg/WikiEnemyDropTable.json", LoadPriority.LOW)] + public class WikiEnemyDropTable + { + public List dropItemIds = new(); + } +}