From 99a7aceee2213d0c8f0ecd38b6c5ebb3919aed16 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Thu, 7 Aug 2025 01:45:49 +0200 Subject: [PATCH 01/14] some factory components (not finished) --- .../Factory/Components/FComponentBattle.cs | 23 ++++++++++++ .../Factory/Components/FComponentCache.cs | 21 +++++++++++ .../Components/FComponentFormulaMan.cs | 20 +++++++++++ .../Components/FComponentPortManager.cs | 13 ++++++- .../Factory/Components/FComponentProducer.cs | 20 +++++++++++ Campofinale/Game/Factory/FactoryManager.cs | 35 ++++++++++++++++--- 6 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 Campofinale/Game/Factory/Components/FComponentBattle.cs create mode 100644 Campofinale/Game/Factory/Components/FComponentCache.cs create mode 100644 Campofinale/Game/Factory/Components/FComponentFormulaMan.cs create mode 100644 Campofinale/Game/Factory/Components/FComponentProducer.cs diff --git a/Campofinale/Game/Factory/Components/FComponentBattle.cs b/Campofinale/Game/Factory/Components/FComponentBattle.cs new file mode 100644 index 0000000..82d44e8 --- /dev/null +++ b/Campofinale/Game/Factory/Components/FComponentBattle.cs @@ -0,0 +1,23 @@ +using Campofinale.Resource; +using static Campofinale.Game.Factory.FactoryNode; + +namespace Campofinale.Game.Factory.Components +{ + public class FComponentBattle : FComponent + { + public int EnergyCurrent=100; + public FComponentBattle(uint id) : base(id, FCComponentType.Battle) + { + } + + public override void SetComponentInfo(ScdFacCom proto) + { + proto.Battle = new() + { + EnergyCurrent=100, + EnergyMax=100, + InOverloading=false + }; + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentCache.cs b/Campofinale/Game/Factory/Components/FComponentCache.cs new file mode 100644 index 0000000..a88b7ca --- /dev/null +++ b/Campofinale/Game/Factory/Components/FComponentCache.cs @@ -0,0 +1,21 @@ +using Campofinale.Resource; +using static Campofinale.Game.Factory.FactoryNode; + +namespace Campofinale.Game.Factory.Components +{ + public class FComponentCache : FComponent + { + + public FComponentCache(uint id) : base(id, FCComponentType.Cache) + { + } + + public override void SetComponentInfo(ScdFacCom proto) + { + proto.Cache = new() + { + + }; + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs new file mode 100644 index 0000000..e4ecbbc --- /dev/null +++ b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs @@ -0,0 +1,20 @@ +using Campofinale.Resource; +using static Campofinale.Game.Factory.FactoryNode; + +namespace Campofinale.Game.Factory.Components +{ + public class FComponentFormulaMan : FComponent + { + public FComponentFormulaMan(uint id) : base(id, FCComponentType.FormulaMan) + { + } + + public override void SetComponentInfo(ScdFacCom proto) + { + proto.FormulaMan = new() + { + + }; + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentPortManager.cs b/Campofinale/Game/Factory/Components/FComponentPortManager.cs index 43e473d..615605b 100644 --- a/Campofinale/Game/Factory/Components/FComponentPortManager.cs +++ b/Campofinale/Game/Factory/Components/FComponentPortManager.cs @@ -35,7 +35,18 @@ namespace Campofinale.Game.Factory.Components }); } } - + public FComponentPortManager(uint id, int size) : base(id, FCComponentType.PortManager) + { + for (int i = 0; i < size; i++) + { + ports.Add(new FPort() + { + index = i, + ownerComId = 0, + touchComId = 0 + }); + } + } public override void SetComponentInfo(ScdFacCom proto) { proto.PortManager = new(); diff --git a/Campofinale/Game/Factory/Components/FComponentProducer.cs b/Campofinale/Game/Factory/Components/FComponentProducer.cs new file mode 100644 index 0000000..d8ac236 --- /dev/null +++ b/Campofinale/Game/Factory/Components/FComponentProducer.cs @@ -0,0 +1,20 @@ +using Campofinale.Resource; +using static Campofinale.Game.Factory.FactoryNode; + +namespace Campofinale.Game.Factory.Components +{ + public class FComponentProducer : FComponent + { + public FComponentProducer(uint id) : base(id, FCComponentType.Producer) + { + } + + public override void SetComponentInfo(ScdFacCom proto) + { + proto.Producer = new() + { + + }; + } + } +} diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index d62ae5d..d9fe989 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -721,6 +721,19 @@ namespace Campofinale.Game.Factory case FCNodeType.PowerDiffuser: components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); break; + case FCNodeType.Battle: + components.Add(new FComponentBattle(chapter.nextCompV()).Init()); + break; + case FCNodeType.Producer: + + components.Add(new FComponentPortManager(chapter.nextCompV(), 3).Init()); + components.Add(new FComponentPortManager(chapter.nextCompV(), 3).Init()); + components.Add(new FComponentProducer(chapter.nextCompV()).Init()); + components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); + components.Add(new FComponentCache(chapter.nextCompV()).Init()); + components.Add(new FComponentCache(chapter.nextCompV()).Init()); + components.Add(new FComponentCache(chapter.nextCompV()).Init()); + break; case FCNodeType.TravelPole: components.Add(new FComponentTravelPole(chapter.nextCompV()).Init()); break; @@ -783,12 +796,16 @@ namespace Campofinale.Game.Factory } else { - EntityInteractive e = new(interactiveFacWrapperTable[templateId].interactiveTemplateId, player.roleId, worldPosition, direction, sceneNumId, guid); - e.InitDefaultProperties(); - e.SetPropValue(nodeId, "factory_inst_id"); + if (interactiveFacWrapperTable.ContainsKey(templateId)) + { + EntityInteractive e = new(interactiveFacWrapperTable[templateId].interactiveTemplateId, player.roleId, worldPosition, direction, sceneNumId, guid); + e.InitDefaultProperties(); + e.SetPropValue(nodeId, "factory_inst_id"); - player.sceneManager.GetCurScene().entities.Add(e); - player.sceneManager.GetCurScene().SpawnEntity(e); + player.sceneManager.GetCurScene().entities.Add(e); + player.sceneManager.GetCurScene().SpawnEntity(e); + } + } } @@ -829,6 +846,14 @@ namespace Campofinale.Game.Factory { case FCComponentType.PowerPole: return FCComponentPos.PowerPole; + case FCComponentType.TravelPole: + return FCComponentPos.TravelPole; + case FCComponentType.Battle: + return FCComponentPos.Battle1; + case FCComponentType.Producer: + return FCComponentPos.Producer; + case FCComponentType.FormulaMan: + return FCComponentPos.FormulaMan; } return FCComponentPos.Invalid; } From 34a904442d2100e85083a9ce6179bc7ab8fc5bee Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 02:04:38 +0200 Subject: [PATCH 02/14] many stuff --- Campofinale/Database/DatabaseManager.cs | 3 + Campofinale/Game/Factory/BlockCalculator.cs | 119 +++ .../NodeBuildingBehaviour.cs | 21 + .../NodeBuilding_Producer.cs | 102 ++ .../Factory/Components/FComponentBattle.cs | 2 +- .../Components/FComponentBoxConveyor.cs | 33 + .../Factory/Components/FComponentCache.cs | 85 +- .../Components/FComponentFormulaMan.cs | 18 +- .../Components/FComponentPortManager.cs | 25 + .../Factory/Components/FComponentProducer.cs | 11 +- Campofinale/Game/Factory/FComponent.cs | 108 +++ Campofinale/Game/Factory/FactoryChapter.cs | 635 +++++++++++++ Campofinale/Game/Factory/FactoryManager.cs | 878 +----------------- Campofinale/Game/Factory/FactoryNode.cs | 522 +++++++++++ Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs | 32 +- Campofinale/Packets/Cs/HandleCsPing.cs | 20 +- .../Packets/Sc/PacketScFactoryOpRet.cs | 51 + Campofinale/Resource/ResourceManager.cs | 159 +++- .../Table/FactoryMachineCraftTable.cs | 52 ++ Campofinale/Server.cs | 2 +- 20 files changed, 2000 insertions(+), 878 deletions(-) create mode 100644 Campofinale/Game/Factory/BlockCalculator.cs create mode 100644 Campofinale/Game/Factory/BuildingsBehaviour/NodeBuildingBehaviour.cs create mode 100644 Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs create mode 100644 Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs create mode 100644 Campofinale/Game/Factory/FComponent.cs create mode 100644 Campofinale/Game/Factory/FactoryChapter.cs create mode 100644 Campofinale/Game/Factory/FactoryNode.cs create mode 100644 Campofinale/Resource/Table/FactoryMachineCraftTable.cs diff --git a/Campofinale/Database/DatabaseManager.cs b/Campofinale/Database/DatabaseManager.cs index e769373..9235701 100644 --- a/Campofinale/Database/DatabaseManager.cs +++ b/Campofinale/Database/DatabaseManager.cs @@ -4,6 +4,8 @@ using MongoDB.Bson; using System.Reflection; using static Campofinale.Game.Factory.FactoryNode; using Campofinale.Game.Inventory; +using Campofinale.Game.Factory; +using Campofinale.Game.Factory.BuildingsBehaviour; namespace Campofinale.Database { @@ -66,6 +68,7 @@ namespace Campofinale.Database BsonSerializer.RegisterSerializer(typeof(Dictionary), new CustomDictionarySerializer()); RegisterSubclasses(); + RegisterSubclasses(); Logger.Print("Connecting to MongoDB..."); try { diff --git a/Campofinale/Game/Factory/BlockCalculator.cs b/Campofinale/Game/Factory/BlockCalculator.cs new file mode 100644 index 0000000..b5e01bf --- /dev/null +++ b/Campofinale/Game/Factory/BlockCalculator.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Game.Factory +{ + public class BlockCalculator + { + public static int CalculateTotalBlocks(List points) + { + if (points == null || points.Count < 2) + return 0; + + HashSet> blocks = new HashSet>(); + + for (int i = 0; i < points.Count - 1; i++) + { + Vector3f p1 = points[i]; + Vector3f p2 = points[i + 1]; + + AddBlocksForLineSegment3D(p1, p2, blocks); + } + + return blocks.Count; + } + + private static void AddBlocksForLineSegment3D(Vector3f p1, Vector3f p2, HashSet> blocks) + { + int x0 = (int)Math.Floor(p1.x); + int y0 = (int)Math.Floor(p1.y); + int z0 = (int)Math.Floor(p1.z); + int x1 = (int)Math.Floor(p2.x); + int y1 = (int)Math.Floor(p2.y); + int z1 = (int)Math.Floor(p2.z); + + // Algoritmo di Bresenham 3D + int dx = Math.Abs(x1 - x0); + int dy = Math.Abs(y1 - y0); + int dz = Math.Abs(z1 - z0); + int sx = x0 < x1 ? 1 : -1; + int sy = y0 < y1 ? 1 : -1; + int sz = z0 < z1 ? 1 : -1; + + // Decision variables + if (dx >= dy && dx >= dz) + { + int err1 = 2 * dy - dx; + int err2 = 2 * dz - dx; + for (int i = 0; i < dx; i++) + { + blocks.Add(Tuple.Create(x0, y0, z0)); + if (err1 > 0) + { + y0 += sy; + err1 -= 2 * dx; + } + if (err2 > 0) + { + z0 += sz; + err2 -= 2 * dx; + } + err1 += 2 * dy; + err2 += 2 * dz; + x0 += sx; + } + } + else if (dy >= dx && dy >= dz) + { + int err1 = 2 * dx - dy; + int err2 = 2 * dz - dy; + for (int i = 0; i < dy; i++) + { + blocks.Add(Tuple.Create(x0, y0, z0)); + if (err1 > 0) + { + x0 += sx; + err1 -= 2 * dy; + } + if (err2 > 0) + { + z0 += sz; + err2 -= 2 * dy; + } + err1 += 2 * dx; + err2 += 2 * dz; + y0 += sy; + } + } + else // dz è la dimensione dominante + { + int err1 = 2 * dy - dz; + int err2 = 2 * dx - dz; + for (int i = 0; i < dz; i++) + { + blocks.Add(Tuple.Create(x0, y0, z0)); + if (err1 > 0) + { + y0 += sy; + err1 -= 2 * dz; + } + if (err2 > 0) + { + x0 += sx; + err2 -= 2 * dz; + } + err1 += 2 * dy; + err2 += 2 * dx; + z0 += sz; + } + } + + // Aggiungi l'ultimo punto + blocks.Add(Tuple.Create(x1, y1, z1)); + } + } +} diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuildingBehaviour.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuildingBehaviour.cs new file mode 100644 index 0000000..f024b38 --- /dev/null +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuildingBehaviour.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.Factory.BuildingsBehaviour +{ + public class NodeBuildingBehaviour + { + public virtual void Update(FactoryChapter chapter, FactoryNode node) + { + + } + //Executed the first time when created a node that use the specific behaviour + public virtual void Init(FactoryChapter chapter, FactoryNode node) + { + + } + } +} diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs new file mode 100644 index 0000000..9397b80 --- /dev/null +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs @@ -0,0 +1,102 @@ +using Campofinale.Game.Factory.Components; +using Campofinale.Protocol; +using Campofinale.Resource; +using Campofinale.Resource.Table; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Campofinale.Resource; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Game.Factory.BuildingsBehaviour +{ + public class NodeBuilding_Producer : NodeBuildingBehaviour + { + public uint inputCacheId = 0; + public uint outputCacheId = 0; + public uint producerId = 0; + public int currentProgress = 0; + public override void Init(FactoryChapter chapter, FactoryNode node) + { + FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); + FComponentCache cache2 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheOut1).Init(); + FComponentProducer producer = (FComponentProducer)new FComponentProducer(chapter.nextCompV()).Init(); + node.components.Add(producer); + node.components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); + node.components.Add(cache1); + node.components.Add(cache2); + inputCacheId = cache1.compId; + outputCacheId = cache2.compId; + producerId = producer.compId; + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3,cache1).Init()); + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3, cache2).Init()); + } + public override void Update(FactoryChapter chapter, FactoryNode node) + { + + if (node.powered) + { + FComponentProducer producer = node.GetComponent(producerId); + FComponentCache inCache = node.GetComponent(inputCacheId); + FComponentCache outCache = node.GetComponent(outputCacheId); + FactoryMachineCraftTable craftingRecipe = null; + string recipe = ResourceManager.FindFactoryMachineCraftIdUsingCacheItems(inCache.items); + producer.formulaId = recipe; + ResourceManager.factoryMachineCraftTable.TryGetValue(producer.formulaId, out craftingRecipe); + + if (craftingRecipe != null) + { + producer.inBlock = outCache.IsFull(); + if (craftingRecipe.CacheHaveItems(inCache) && !outCache.IsFull()) + { + producer.inProduce = true; + + producer.lastFormulaId = recipe; + producer.progress += craftingRecipe.totalProgress/craftingRecipe.progressRound; + currentProgress++; + if (currentProgress >= craftingRecipe.progressRound) + { + currentProgress = 0; + List toConsume = craftingRecipe.GetIngredients(); + inCache.ConsumeItems(toConsume); + craftingRecipe.outcomes.ForEach(e => + { + e.group.ForEach(i => + { + outCache.AddItem(i.id, i.count); + }); + + }); + } + } + else + { + producer.inBlock = false; + producer.inProduce = false; + producer.progress = 0; + } + } + else + { + producer.inBlock = false; + producer.inProduce = false; + producer.progress = 0; + } + } + /* ScFactoryModifyChapterComponents update = new() + { + ChapterId = chapter.chapterId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, + + }; + + foreach (var comp in node.components) + { + update.Components.Add(comp.ToProto()); + } + chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterComponents, update);*/ + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentBattle.cs b/Campofinale/Game/Factory/Components/FComponentBattle.cs index 82d44e8..f48cd53 100644 --- a/Campofinale/Game/Factory/Components/FComponentBattle.cs +++ b/Campofinale/Game/Factory/Components/FComponentBattle.cs @@ -6,7 +6,7 @@ namespace Campofinale.Game.Factory.Components public class FComponentBattle : FComponent { public int EnergyCurrent=100; - public FComponentBattle(uint id) : base(id, FCComponentType.Battle) + public FComponentBattle(uint id) : base(id, FCComponentType.Battle, FCComponentPos.Battle1) { } diff --git a/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs new file mode 100644 index 0000000..cd64c4b --- /dev/null +++ b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs @@ -0,0 +1,33 @@ +using Campofinale.Resource; +using static Campofinale.Game.Factory.FactoryNode; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Game.Factory.Components +{ + public class FComponentBoxConveyor : FComponent + { + public long lastPopTms = 0; + public List items = new(); + public FComponentBoxConveyor(uint id) : base(id, FCComponentType.BoxConveyor,FCComponentPos.BoxConveyor) + { + } + + public override void SetComponentInfo(ScdFacCom proto) + { + if (items == null) + { + items = new List(); + } + proto.BoxConveyor = new() + { + LastPopTms = lastPopTms, + + }; + items.ForEach(item => + { + proto.BoxConveyor.Items.Add(item.ToFactoryItemProto()); + }); + + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentCache.cs b/Campofinale/Game/Factory/Components/FComponentCache.cs index a88b7ca..3b347f1 100644 --- a/Campofinale/Game/Factory/Components/FComponentCache.cs +++ b/Campofinale/Game/Factory/Components/FComponentCache.cs @@ -1,21 +1,100 @@ using Campofinale.Resource; using static Campofinale.Game.Factory.FactoryNode; +using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Factory.Components { public class FComponentCache : FComponent { - - public FComponentCache(uint id) : base(id, FCComponentType.Cache) + + public List items = new(); + public FComponentCache(uint id,FCComponentPos pos) : base(id, FCComponentType.Cache,pos) { } - + public int GetItemCount(string id) + { + int count = 0; + ItemCount item = items.Find(i=>i.id == id); + if (item != null) + { + count += item.count; + } + return count; + } public override void SetComponentInfo(ScdFacCom proto) { + if(items.Count < 1) + { + //Add 1 empty item as default + items.Add(new ItemCount()); + } proto.Cache = new() { + Items = + { + }, + Size=items.Count, }; + items.ForEach(item => + { + proto.Cache.Items.Add(item.ToFactoryItemProto()); + }); + } + + public void ConsumeItems(List toConsume) + { + foreach (var consume in toConsume) + { + ItemCount item = items.Find(i => i.id == consume.id); + if (item != null) + { + item.count-=consume.count; + if(item.count < 1) + { + item.count = 0; + item.id = ""; + } + } + } + } + + public bool IsFull() + { + int maxItems = items.Count * 100; + int count = 0; + foreach (var item in items) + { + count += item.count; + }; + return count>=maxItems; + } + + public void AddItem(string id, int count) + { + int remaining = count; + foreach (var item in items) + { + int space = 100-item.count; + if (item.id==id) + { + if (space >= remaining) + { + item.count +=remaining; + remaining = 0; + } + else + { + item.count += space; + remaining -= space; + } + } + else if(item.id.Length < 1) + { + item.id = id; + item.count = remaining; + } + } } } } diff --git a/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs index e4ecbbc..17868d9 100644 --- a/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs +++ b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs @@ -5,6 +5,8 @@ namespace Campofinale.Game.Factory.Components { public class FComponentFormulaMan : FComponent { + public string currentGroup = "group_grinder_normal"; + public string currentMode = "normal"; public FComponentFormulaMan(uint id) : base(id, FCComponentType.FormulaMan) { } @@ -13,7 +15,21 @@ namespace Campofinale.Game.Factory.Components { proto.FormulaMan = new() { - + CurrentGroup = currentGroup, + CurrentMode = currentMode, + FormulaIds = { + "grinder_iron_powder_1", + "grinder_quartz_powder_1", + "grinder_originium_powder_1", + "grinder_carbon_powder_1", + "grinder_crystal_powder_1", + "grinder_plant_moss_powder_1_1", + "grinder_plant_moss_powder_2_1", + "grinder_plant_moss_powder_3_1", + "grinder_plant_bbflower_powder_1_1", + "grinder_plant_grass_powder_1_1", + "grinder_plant_grass_powder_2_1" + } }; } } diff --git a/Campofinale/Game/Factory/Components/FComponentPortManager.cs b/Campofinale/Game/Factory/Components/FComponentPortManager.cs index 615605b..fa83d87 100644 --- a/Campofinale/Game/Factory/Components/FComponentPortManager.cs +++ b/Campofinale/Game/Factory/Components/FComponentPortManager.cs @@ -47,8 +47,33 @@ namespace Campofinale.Game.Factory.Components }); } } + public FComponentPortManager(uint id, int size, FComponentCache cache) : base(id, FCComponentType.PortManager) + { + if( cache.customPos == FCComponentPos.CacheIn1 || + cache.customPos == FCComponentPos.CacheIn2 || + cache.customPos == FCComponentPos.CacheIn3 || + cache.customPos == FCComponentPos.CacheIn4) + { + customPos = FCComponentPos.PortInManager; + } + else + { + customPos = FCComponentPos.PortOutManager; + } + + for (int i = 0; i < size; i++) + { + ports.Add(new FPort() + { + index = i, + ownerComId = cache.compId, + touchComId = 0 + }); + } + } public override void SetComponentInfo(ScdFacCom proto) { + proto.PortManager = new(); foreach(FPort port in ports) { diff --git a/Campofinale/Game/Factory/Components/FComponentProducer.cs b/Campofinale/Game/Factory/Components/FComponentProducer.cs index d8ac236..4452420 100644 --- a/Campofinale/Game/Factory/Components/FComponentProducer.cs +++ b/Campofinale/Game/Factory/Components/FComponentProducer.cs @@ -5,15 +5,24 @@ namespace Campofinale.Game.Factory.Components { public class FComponentProducer : FComponent { + public string formulaId = ""; + public string lastFormulaId = ""; + public bool inProduce, inBlock; + public long progress; public FComponentProducer(uint id) : base(id, FCComponentType.Producer) { + } public override void SetComponentInfo(ScdFacCom proto) { proto.Producer = new() { - + FormulaId=formulaId, + InBlock=inBlock, + CurrentProgress=progress, + InProduce=inProduce, + LastFormulaId=lastFormulaId }; } } diff --git a/Campofinale/Game/Factory/FComponent.cs b/Campofinale/Game/Factory/FComponent.cs new file mode 100644 index 0000000..4f5ffca --- /dev/null +++ b/Campofinale/Game/Factory/FComponent.cs @@ -0,0 +1,108 @@ +using Campofinale.Game.Factory.Components; +using Campofinale.Resource; +using MongoDB.Bson.Serialization.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Campofinale.Game.Factory +{ + [BsonDiscriminator(Required = true)] + [BsonKnownTypes(typeof(FComponentSelector))] + + public class FComponent + { + public class FCompInventory + { + public ScdFacComInventory ToProto() + { + return new ScdFacComInventory() + { + + }; + } + } + public uint compId; + public FCComponentType type; + public FCompInventory inventory; + public FCComponentPos customPos = FCComponentPos.Invalid; + public FComponent(uint id, FCComponentType t, FCComponentPos custom= FCComponentPos.Invalid) + { + this.compId = id; + this.type = t; + this.customPos = custom; + } + public FCComponentPos GetComPos() + { + if(customPos == FCComponentPos.Invalid) + { + switch (type) + { + case FCComponentType.PowerPole: + return FCComponentPos.PowerPole; + case FCComponentType.TravelPole: + return FCComponentPos.TravelPole; + case FCComponentType.Battle: + return FCComponentPos.Battle1; + case FCComponentType.Producer: + return FCComponentPos.Producer; + case FCComponentType.FormulaMan: + return FCComponentPos.FormulaMan; + case FCComponentType.BusLoader: + return FCComponentPos.BusLoader; + case FCComponentType.StablePower: + return FCComponentPos.StablePower; + case FCComponentType.Selector: + return FCComponentPos.Selector; + case FCComponentType.PowerSave: + return FCComponentPos.PowerSave; + default: + return FCComponentPos.Invalid; + } + } + + return customPos; + } + public ScdFacCom ToProto() + { + ScdFacCom proto = new ScdFacCom() + { + ComponentType = (int)type, + ComponentId = compId, + + }; + SetComponentInfo(proto); + return proto; + } + + public virtual void SetComponentInfo(ScdFacCom proto) + { + if (inventory != null) + { + proto.Inventory = inventory.ToProto(); + } + else if (type == FCComponentType.PowerPole) + { + proto.PowerPole = new() + { + + }; + } + } + + public virtual FComponent Init() + { + switch (type) + { + case FCComponentType.Inventory: + inventory = new(); + break; + default: + break; + } + return this; + } + } +} diff --git a/Campofinale/Game/Factory/FactoryChapter.cs b/Campofinale/Game/Factory/FactoryChapter.cs new file mode 100644 index 0000000..e25563b --- /dev/null +++ b/Campofinale/Game/Factory/FactoryChapter.cs @@ -0,0 +1,635 @@ +using Campofinale.Game.Factory.Components; +using Campofinale.Game.Inventory; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; +using Campofinale.Resource.Table; +using Newtonsoft.Json; +using System.Xml.Linq; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Game.Factory +{ + public class FactoryChapter + { + public string chapterId; + public ulong ownerId; + public List nodes = new(); + public uint v = 1; + public uint compV = 0; + public int bandwidth = 200; + + public ScFactorySyncChapter ToProto() + { + ScFactorySyncChapter chapter = new() + { + ChapterId = chapterId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Blackboard = new() + { + Power = new() + { + PowerGen = 0, + PowerSaveMax = 0, + PowerSaveCurrent = 0, + PowerCost = 0 + }, + InventoryNodeId = 1 + }, + Statistic = new() + { + LastDay = new() + { + + }, + Other = new() + { + InPowerBuilding = 1 + } + }, + PinBoard = new() + { + Cards = + { + + }, + + }, + }; + chapter.Blackboard.Power.PowerSaveCurrent = bandwidth; + domainDataTable[chapterId].levelGroup.ForEach(levelGroup => + { + int grade = GetOwner().sceneManager.GetScene(GetSceneNumIdFromLevelData(levelGroup)).grade; + LevelGradeInfo sceneGrade = ResourceManager.levelGradeTable[levelGroup].grades.Find(g => g.grade == grade); + if (sceneGrade != null) + { + chapter.Blackboard.Power.PowerGen += sceneGrade.bandwidth; + chapter.Blackboard.Power.PowerSaveMax += sceneGrade.bandwidth; + + var scene = new ScdFactorySyncScene() + { + SceneId = GetSceneNumIdFromLevelData(levelGroup), + + Bandwidth = new() + { + Current = 0, + Max = sceneGrade.bandwidth, + TravelPoleMax = sceneGrade.travelPoleLimit, + + BattleCurrent = 0, + BattleMax = sceneGrade.battleBuildingLimit, + }, + Settlements = + { + + }, + + Panels = + { + + } + }; + int index = 0; + LevelScene scen = GetLevelData(GetSceneNumIdFromLevelData(levelGroup)); + foreach (var reg in scen.levelData.factoryRegions) + { + foreach (var area in reg.areas) + { + var lvData = area.levelData.Find(l => l.level == grade); + if (lvData == null) + { + lvData = area.levelData.Last(); + } + if (lvData.levelBounds.Count > 0) + { + var bounds = lvData.levelBounds[0]; + scene.Panels.Add(new ScdFactorySyncScenePanel() + { + Index = index, + Level = lvData.level, + MainMesh = + { + new ScdRectInt() + { + X=(int)bounds.start.x, + Z=(int)bounds.start.z, + Y=(int)bounds.start.y, + W=(int)bounds.size.x, + H=(int)bounds.size.y, + L=(int)bounds.size.z, + } + } + }); + index++; + } + + } + } + chapter.Scenes.Add(scene); + } + + }); + try + { + nodes.ForEach(node => + { + chapter.Nodes.Add(node.ToProto()); + }); + } + catch(Exception e) + { + + } + + chapter.Maps.AddRange(GetMaps()); + return chapter; + } + public List GetMaps() + { + List maps = new(); + string levelId = domainDataTable[chapterId].levelGroup[0]; + string mapId = GetLevelData(GetSceneNumIdFromLevelData(levelId)).mapIdStr; + maps.Add(new ScdFactorySyncMap() + { + MapId = ResourceManager.strIdNumTable.chapter_map_id.dic[mapId], + Wires = + { + GetWires() + } + }); + return maps; + } + + public List GetWires() + { + List wires = new(); + HashSet<(ulong, ulong)> addedConnections = new(); + ulong i = 0; + + foreach (FactoryNode node in nodes) + { + foreach (var conn in node.connectedComps) + { + ulong compA = conn.Key; + ulong compB = conn.Value; + + var key = (compA, compB); + + if (!addedConnections.Contains(key)) + { + wires.Add(new ScdFactorySyncMapWire() + { + Index = i, + FromComId = compA, + ToComId = compB + }); + + addedConnections.Add(key); + i++; + } + } + } + + return wires; + } + + + public void Update() + { + try + { + UpdatePowerGrid(nodes); + foreach (FactoryNode node in nodes) + { + try + { + node.Update(this); + } + catch (Exception e) + { + Logger.PrintError($"Error occured while updating nodeId {node.nodeId}: {e.Message}"); + } + + } + } + catch (Exception e) + { + + } + + } + public List GetNodesInRange(Vector3f pos, float range) + { + return nodes.FindAll(n => n.position.Distance(pos) <= range); + } + + public void ExecOp(CsFactoryOp op, ulong seq) + { + + switch (op.OpType) + { + case FactoryOpType.Place: + CreateNode(op, seq); + break; + case FactoryOpType.MoveNode: + MoveNode(op, seq); + break; + case FactoryOpType.Dismantle: + DismantleNode(op, seq); + break; + case FactoryOpType.AddConnection: + AddConnection(op, seq); + break; + case FactoryOpType.MoveItemBagToCache: + MoveItemBagToCache(op, seq); + break; + case FactoryOpType.ChangeProducerMode: + ChangeProducerMode(op, seq); + break; + case FactoryOpType.EnableNode: + EnableNode(op, seq); + break; + case FactoryOpType.PlaceConveyor: + PlaceConveyor(op, seq); + break; + case FactoryOpType.DismantleBoxConveyor: + DismantleBoxConveyor(op, seq); + break; + case FactoryOpType.SetTravelPoleDefaultNext: + FactoryNode travelNode = GetNodeByCompId(op.SetTravelPoleDefaultNext.ComponentId); + travelNode.GetComponent().defaultNext = op.SetTravelPoleDefaultNext.DefaultNext; + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, travelNode)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); + break; + default: + break; + } + + } + public void DismantleBoxConveyor(CsFactoryOp op, ulong seq) + { + var dismantle = op.DismantleBoxConveyor; + + FactoryNode nodeRem = nodes.Find(n => n.nodeId == dismantle.NodeId); + if (nodeRem != null) + { + RemoveConnectionsToNode(nodeRem, nodes); + nodes.Remove(nodeRem); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, nodeRem.nodeId)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), nodeRem.nodeId, op), seq); + } + else + { + ScFactoryOpRet ret = new() + { + RetCode = FactoryOpRetCode.Fail, + + }; + GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); + } + } + public void EnableNode(CsFactoryOp op, ulong seq) + { + var enableNode = op.EnableNode; + FactoryNode node = nodes.Find(n => n.nodeId == enableNode.NodeId); + if(node!= null) + { + node.deactive = !enableNode.Enable; + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); + } + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); + } + public void ChangeProducerMode(CsFactoryOp op, ulong seq) + { + var changeMode = op.ChangeProducerMode; + FactoryNode node = nodes.Find(n=>n.nodeId == changeMode.NodeId); + if(node != null) + { + FComponentFormulaMan formula = node.GetComponent(); + if (formula != null) + { + formula.currentMode = changeMode.ToMode; //test, not sure + } + + } + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); + + } + public void MoveItemBagToCache(CsFactoryOp op, ulong seq) + { + var move = op.MoveItemBagToCache; + FComponentCache cacheComp = GetCompById(move.ComponentId); + if (cacheComp != null) + { + Item gridItem = null; + GetOwner().inventoryManager.items.bag.TryGetValue(move.GridIndex, out gridItem); + if (gridItem != null) + { + if(cacheComp.items[move.CacheGridIndex].id == "" || cacheComp.items[move.CacheGridIndex].id == gridItem.id) + { + int canAdd = 100 - cacheComp.items[move.CacheGridIndex].count; + + if (canAdd >= gridItem.amount) + { + cacheComp.items[move.CacheGridIndex].id = gridItem.id; + cacheComp.items[move.CacheGridIndex].count += gridItem.amount; + GetOwner().inventoryManager.items.bag.Remove(move.GridIndex); + GetOwner().inventoryManager.items.UpdateBagInventoryPacket(); + } + else + { + cacheComp.items[move.CacheGridIndex].id = gridItem.id; + cacheComp.items[move.CacheGridIndex].count += canAdd; + gridItem.amount-=canAdd; + GetOwner().inventoryManager.items.UpdateBagInventoryPacket(); + } + } + } + + } + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); + } + + public void MoveNode(CsFactoryOp op, ulong seq) + { + var move = op.MoveNode; + FactoryNode node = nodes.Find(n => n.nodeId == move.NodeId); + if (node != null) + { + node.direction = new Vector3f(move.Direction); + node.position = new Vector3f(move.Position); + node.worldPosition = new Vector3f(move.InteractiveParam.Position); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId, op), seq); + node.SendEntity(GetOwner(), chapterId); + } + else + { + ScFactoryOpRet ret = new() + { + RetCode = FactoryOpRetCode.Fail, + }; + GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); + } + } + public void DismantleNode(CsFactoryOp op, ulong seq) + { + var dismantle = op.Dismantle; + + FactoryNode nodeRem = nodes.Find(n => n.nodeId == dismantle.NodeId); + if (nodeRem != null) + { + RemoveConnectionsToNode(nodeRem, nodes); + nodes.Remove(nodeRem); + GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() + { + ChapterId = chapterId, + MapId = nodeRem.mapId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Wires = + { + GetWires() + } + }); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, nodeRem.nodeId)); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), nodeRem.nodeId, op), seq); + } + else + { + ScFactoryOpRet ret = new() + { + RetCode = FactoryOpRetCode.Fail, + + }; + GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); + } + } + public void RemoveConnectionsToNode(FactoryNode nodeRem, List allNodes) + { + // Ottieni tutti i compId del nodo da rimuovere + HashSet remCompIds = nodeRem.components.Select(c => (ulong)c.compId).ToHashSet(); + + foreach (var node in allNodes) + { + node.connectedComps.RemoveAll(conn => + remCompIds.Contains(conn.Key) || remCompIds.Contains(conn.Value)); + } + } + + + public uint nextCompV() + { + compV++; + return compV; + } + public FComponent GetCompById(ulong compId) + { + foreach (FactoryNode node in nodes) + { + if (node.components.Find(c => c.compId == compId) != null) + { + return node.components.Find(c => c.compId == compId); + } + } + return null; + } + public FComponent GetCompById(ulong compId) where FComponent : class + { + foreach (FactoryNode node in nodes) + { + if (node.components.Find(c => c.compId == compId) != null) + { + return node.components.Find(c => c.compId == compId && c is FComponent) as FComponent; + } + } + return null; + } + public FactoryNode GetNodeByCompId(ulong compId) + { + foreach (FactoryNode node in nodes) + { + if (node.components.Find(c => c.compId == compId) != null) + { + return node; + } + } + return null; + } + private void AddConnection(CsFactoryOp op, ulong seq) + { + FComponent nodeFrom = GetCompById(op.AddConnection.FromComId); + FComponent nodeTo = GetCompById(op.AddConnection.ToComId); + + if (nodeFrom != null && nodeTo != null) + { + GetNodeByCompId(nodeFrom.compId).connectedComps.Add(new(nodeFrom.compId, nodeTo.compId)); + GetNodeByCompId(nodeTo.compId).connectedComps.Add(new(nodeTo.compId, nodeFrom.compId)); + GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() + { + ChapterId = chapterId, + MapId = GetNodeByCompId(nodeFrom.compId).mapId, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Wires = + { + GetWires() + } + }); + var wire = GetWires().Find(w => + (w.FromComId == op.AddConnection.FromComId && w.ToComId == op.AddConnection.ToComId) || + (w.FromComId == op.AddConnection.ToComId && w.ToComId == op.AddConnection.FromComId)); + + if (wire != null) + { + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), (uint)wire.Index, op), seq); + } + else + { + // Facoltativo: log di errore + Console.WriteLine($"[WARN] Connessione non trovata tra {op.AddConnection.FromComId} e {op.AddConnection.ToComId}"); + } + + } + + } + void ResetAllPower(List allNodes) + { + foreach (var node in allNodes) + node.powered = false; + } + void UpdatePowerGrid(List allNodes) + { + ResetAllPower(allNodes); + + HashSet visited = new(); + + foreach (var node in allNodes) + { + if (node.templateId.Contains("hub") || node.templateId == "power_diffuser_1") + { + //if(node.forcePowerOn) + if (node.templateId == "power_diffuser_1") + { + //Check inside factory region + + } + else + { + PropagatePowerFrom(node, visited); + } + + } + } + } + void PropagatePowerFrom(FactoryNode node, HashSet visited) + { + if (visited.Contains(node.nodeId)) + return; + + visited.Add(node.nodeId); + node.powered = true; + if (node.templateId == "power_diffuser_1") + { + //get builds in area test + List nodes = GetNodesInRange(node.position, 15); + foreach (FactoryNode propagateNode in nodes) + { + if (propagateNode.GetComponent() == null) + { + propagateNode.powered = true; + } + } + } + if (node.GetComponent() != null) + foreach (var connectedCompId in node.connectedComps) + { + FactoryNode connectedNode = GetNodeByCompId(connectedCompId.Value); + if (connectedNode != null) + { + PropagatePowerFrom(connectedNode, visited); + } + } + } + public void PlaceConveyor(CsFactoryOp op, ulong seq) + { + var placeConveyor = op.PlaceConveyor; + Logger.Print($"'PlaceConveyor': {JsonConvert.SerializeObject(placeConveyor)}"); + v++; + uint nodeId = v; + List points = new(); + foreach(var point in placeConveyor.Points) + { + points.Add(new Vector3f(point)); + } + FactoryNode node = new() + { + nodeId = nodeId, + templateId = placeConveyor.TemplateId, + mapId = placeConveyor.MapId, + sceneNumId = GetOwner().sceneManager.GetCurScene().sceneNumId, + nodeType = FCNodeType.BoxConveyor, + position = new Vector3f(placeConveyor.Points[0]), + direction = new(), + directionIn = new Vector3f(placeConveyor.DirectionIn), + directionOut = new Vector3f(placeConveyor.DirectionOut), + worldPosition = null, + points = points, + guid = GetOwner().random.NextRand(), + }; + + node.InitComponents(this); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); + nodes.Add(node); + + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), nodeId, op), seq); + } + private void CreateNode(CsFactoryOp op, ulong seq) + { + v++; + uint nodeId = v; + CsdFactoryOpPlace place = op.Place; + FactoryBuildingTable table = ResourceManager.factoryBuildingTable[place.TemplateId]; + FactoryNode node = new() + { + nodeId = nodeId, + templateId = place.TemplateId, + mapId = place.MapId, + sceneNumId = GetOwner().sceneManager.GetCurScene().sceneNumId, + nodeType = table.GetNodeType(), + position = new Vector3f(place.Position), + direction = new Vector3f(place.Direction), + worldPosition = new Vector3f(place.InteractiveParam.Position), + guid = GetOwner().random.NextRand(), + + }; + + node.InitComponents(this); + GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); + nodes.Add(node); + node.SendEntity(GetOwner(), chapterId); + + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId, op), seq); + + } + + public FactoryChapter(string chapterId, ulong ownerId) + { + this.ownerId = ownerId; + this.chapterId = chapterId; + FactoryNode node = new() + { + nodeId = v, + templateId = "__inventory__", + nodeType = FCNodeType.Inventory, + mapId = 0, + deactive = true, + guid = GetOwner().random.NextRand() + }; + node.InitComponents(this); + nodes.Add(node); + } + public Player GetOwner() + { + return Server.clients.Find(c => c.roleId == ownerId); + } + } +} diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index d9fe989..e902f83 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -1,15 +1,12 @@ using Campofinale.Database; using Campofinale.Game.Entities; using Campofinale.Game.Factory.Components; +using Campofinale.Network; using Campofinale.Packets.Sc; using Campofinale.Protocol; using Campofinale.Resource; -using Campofinale.Resource.Table; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; -using System.Linq; -using System.Numerics; -using System.Xml.Linq; using static Campofinale.Resource.ResourceManager; namespace Campofinale.Game.Factory @@ -19,6 +16,7 @@ namespace Campofinale.Game.Factory public Player player; public List chapters = new(); public ObjectId _id; + public class FactoryData { public ulong roleId; @@ -71,854 +69,52 @@ namespace Campofinale.Game.Factory player.Send(ScMsgId.ScFactoryOpRet, ret, seq); } } + public void SendFactoryHsSync() + { + if (!player.Initialized) return; + long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + + ScFactoryHsSync hs = new() + { + Tms = curtimestamp, + CcList = + { + }, + Blackboard = GetChapter(player.GetCurrentChapter()).ToProto().Blackboard, + ChapterId = player.GetCurrentChapter(), + }; + foreach (var node in GetChapter(player.GetCurrentChapter()).nodes) + { + + if (node != null) + { + if (node.position.DistanceXZ(player.position) < 150) + { + node.components.ForEach(c => + { + hs.CcList.Add(c.ToProto()); + }); + } + + } + } + player.Send(ScMsgId.ScFactoryHsSync, hs); + } public void Update() { + if (!player.Initialized) return; foreach (FactoryChapter chapter in chapters) { chapter.Update(); } + } public FactoryChapter GetChapter(string id) { return chapters.Find(c=>c.chapterId==id); } } - public class FactoryChapter - { - public string chapterId; - public ulong ownerId; - public List nodes=new(); - public uint v = 1; - public uint compV = 0; - public int bandwidth = 200; - - public ScFactorySyncChapter ToProto() - { - ScFactorySyncChapter chapter = new() - { - ChapterId = chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, - Blackboard = new() - { - Power = new() - { - PowerGen = 0, - PowerSaveMax = 0, - PowerSaveCurrent = 0, - PowerCost = 0 - }, - InventoryNodeId = 1 - }, - Statistic = new() - { - LastDay = new() - { - - }, - Other = new() - { - InPowerBuilding = 1 - } - }, - PinBoard = new() - { - Cards = - { - - }, - - }, - }; - chapter.Blackboard.Power.PowerSaveCurrent = bandwidth; - domainDataTable[chapterId].levelGroup.ForEach(levelGroup => - { - int grade = GetOwner().sceneManager.GetScene(GetSceneNumIdFromLevelData(levelGroup)).grade; - LevelGradeInfo sceneGrade = ResourceManager.levelGradeTable[levelGroup].grades.Find(g=>g.grade==grade); - if (sceneGrade != null) - { - chapter.Blackboard.Power.PowerGen += sceneGrade.bandwidth; - chapter.Blackboard.Power.PowerSaveMax += sceneGrade.bandwidth; - - var scene = new ScdFactorySyncScene() - { - SceneId = GetSceneNumIdFromLevelData(levelGroup), - - Bandwidth = new() - { - Current = 0, - Max = sceneGrade.bandwidth, - TravelPoleMax = sceneGrade.travelPoleLimit, - - BattleCurrent = 0, - BattleMax = sceneGrade.battleBuildingLimit, - }, - Settlements = - { - - }, - - Panels = - { - - } - }; - int index = 0; - LevelScene scen = GetLevelData(GetSceneNumIdFromLevelData(levelGroup)); - foreach (var reg in scen.levelData.factoryRegions) - { - foreach (var area in reg.areas) - { - var lvData = area.levelData.Find(l=>l.level==grade); - if (lvData == null) - { - lvData = area.levelData.Last(); - } - if (lvData.levelBounds.Count > 0) - { - var bounds = lvData.levelBounds[0]; - scene.Panels.Add(new ScdFactorySyncScenePanel() - { - Index = index, - Level = lvData.level, - MainMesh = - { - new ScdRectInt() - { - X=(int)bounds.start.x, - Z=(int)bounds.start.z, - Y=(int)bounds.start.y, - W=(int)bounds.size.x, - H=(int)bounds.size.y, - L=(int)bounds.size.z, - } - } - }); - index++; - } - - } - } - chapter.Scenes.Add(scene); - } - - }); - nodes.ForEach(node => - { - chapter.Nodes.Add(node.ToProto()); - }); - chapter.Maps.AddRange(GetMaps()); - return chapter; - } - public List GetMaps() - { - List maps = new(); - string levelId = domainDataTable[chapterId].levelGroup[0]; - string mapId = GetLevelData(GetSceneNumIdFromLevelData(levelId)).mapIdStr; - maps.Add(new ScdFactorySyncMap() - { - MapId = ResourceManager.strIdNumTable.chapter_map_id.dic[mapId], - Wires = - { - GetWires() - } - }); - return maps; - } - - public List GetWires() - { - List wires = new(); - HashSet<(ulong, ulong)> addedConnections = new(); // evita doppioni esatti - ulong i = 0; - - foreach (FactoryNode node in nodes) - { - foreach (var conn in node.connectedComps) - { - ulong compA = conn.Key; - ulong compB = conn.Value; - - var key = (compA, compB); - - if (!addedConnections.Contains(key)) - { - wires.Add(new ScdFactorySyncMapWire() - { - Index = i, - FromComId = compA, - ToComId = compB - }); - - addedConnections.Add(key); - i++; - } - } - } - - return wires; - } - - - public void Update() - { - try - { - UpdatePowerGrid(nodes); - foreach (FactoryNode node in nodes) - { - node.Update(this); - } - } - catch (Exception e) - { - - } - - } - public List GetNodesInRange(Vector3f pos,float range) - { - return nodes.FindAll(n => n.position.Distance(pos) <= range); - } - - public void ExecOp(CsFactoryOp op, ulong seq) - { - - switch (op.OpType) - { - case FactoryOpType.Place: - CreateNode(op, seq); - break; - case FactoryOpType.MoveNode: - MoveNode(op, seq); - break; - case FactoryOpType.Dismantle: - DismantleNode(op, seq); - break; - case FactoryOpType.AddConnection: - AddConnection(op, seq); - break; - case FactoryOpType.SetTravelPoleDefaultNext: - FactoryNode travelNode = GetNodeByCompId(op.SetTravelPoleDefaultNext.ComponentId); - travelNode.GetComponent().defaultNext = op.SetTravelPoleDefaultNext.DefaultNext; - GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, travelNode)); - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); - break; - default: - break; - } - - } - public void MoveNode(CsFactoryOp op, ulong seq) - { - var move = op.MoveNode; - FactoryNode node = nodes.Find(n => n.nodeId == move.NodeId); - if (node != null) - { - node.direction = new Vector3f(move.Direction); - node.position = new Vector3f(move.Position); - node.worldPosition = new Vector3f(move.InteractiveParam.Position); - GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId, op), seq); - node.SendEntity(GetOwner(), chapterId); - } - else - { - ScFactoryOpRet ret = new() - { - RetCode = FactoryOpRetCode.Fail, - }; - GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); - } - } - public void DismantleNode(CsFactoryOp op, ulong seq) - { - var dismantle = op.Dismantle; - - FactoryNode nodeRem = nodes.Find(n => n.nodeId == dismantle.NodeId); - if (nodeRem != null) - { - RemoveConnectionsToNode(nodeRem, nodes); - nodes.Remove(nodeRem); - GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() - { - ChapterId = chapterId, - MapId = nodeRem.mapId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, - Wires = - { - GetWires() - } - }); - GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, nodeRem.nodeId)); - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), nodeRem.nodeId, op), seq); - } - else - { - ScFactoryOpRet ret = new() - { - RetCode = FactoryOpRetCode.Fail, - - }; - GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); - } - } - public void RemoveConnectionsToNode(FactoryNode nodeRem, List allNodes) - { - // Ottieni tutti i compId del nodo da rimuovere - HashSet remCompIds = nodeRem.components.Select(c => (ulong)c.compId).ToHashSet(); - - foreach (var node in allNodes) - { - node.connectedComps.RemoveAll(conn => - remCompIds.Contains(conn.Key) || remCompIds.Contains(conn.Value)); - } - } - - - public uint nextCompV() - { - compV++; - return compV; - } - public FactoryNode.FComponent GetCompById(ulong compId) - { - foreach(FactoryNode node in nodes) - { - if (node.components.Find(c => c.compId == compId) != null) - { - return node.components.Find(c => c.compId == compId); - } - } - return null; - } - public FactoryNode GetNodeByCompId(ulong compId) - { - foreach (FactoryNode node in nodes) - { - if (node.components.Find(c => c.compId == compId) != null) - { - return node; - } - } - return null; - } - private void AddConnection(CsFactoryOp op,ulong seq) - { - FactoryNode.FComponent nodeFrom = GetCompById(op.AddConnection.FromComId); - FactoryNode.FComponent nodeTo = GetCompById(op.AddConnection.ToComId); - - if(nodeFrom!=null && nodeTo != null) - { - GetNodeByCompId(nodeFrom.compId).connectedComps.Add(new(nodeFrom.compId, nodeTo.compId)); - GetNodeByCompId(nodeTo.compId).connectedComps.Add(new(nodeTo.compId, nodeFrom.compId)); - GetOwner().Send(ScMsgId.ScFactoryModifyChapterMap, new ScFactoryModifyChapterMap() - { - ChapterId = chapterId, - MapId = GetNodeByCompId(nodeFrom.compId).mapId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, - Wires = - { - GetWires() - } - }); - var wire = GetWires().Find(w => - (w.FromComId == op.AddConnection.FromComId && w.ToComId == op.AddConnection.ToComId) || - (w.FromComId == op.AddConnection.ToComId && w.ToComId == op.AddConnection.FromComId)); - - if (wire != null) - { - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), (uint)wire.Index, op), seq); - } - else - { - // Facoltativo: log di errore - Console.WriteLine($"[WARN] Connessione non trovata tra {op.AddConnection.FromComId} e {op.AddConnection.ToComId}"); - } - - } - - } - void ResetAllPower(List allNodes) - { - foreach (var node in allNodes) - node.powered = false; - } - void UpdatePowerGrid(List allNodes) - { - ResetAllPower(allNodes); - - HashSet visited = new(); - - foreach (var node in allNodes) - { - if (node.templateId.Contains("hub") || node.templateId == "power_diffuser_1") - { - //if(node.forcePowerOn) - if(node.templateId== "power_diffuser_1") - { - //Check inside factory region - - } - else - { - PropagatePowerFrom(node, visited); - } - - } - } - } - void PropagatePowerFrom(FactoryNode node, HashSet visited) - { - if (visited.Contains(node.nodeId)) - return; - - visited.Add(node.nodeId); - node.powered = true; - if(node.templateId == "power_diffuser_1") - { - //get builds in area test - List nodes=GetNodesInRange(node.position, 15); - foreach(FactoryNode propagateNode in nodes) - { - if (propagateNode.GetComponent() == null) - { - propagateNode.powered = true; - } - } - } - if (node.GetComponent() != null) - foreach (var connectedCompId in node.connectedComps) - { - FactoryNode connectedNode = GetNodeByCompId(connectedCompId.Value); - if (connectedNode != null) - { - PropagatePowerFrom(connectedNode, visited); - } - } - } - private void CreateNode(CsFactoryOp op, ulong seq) - { - v++; - uint nodeId = v; - CsdFactoryOpPlace place = op.Place; - FactoryBuildingTable table = ResourceManager.factoryBuildingTable[place.TemplateId]; - FactoryNode node = new() - { - nodeId = nodeId, - templateId = place.TemplateId, - mapId = place.MapId, - sceneNumId = GetOwner().sceneManager.GetCurScene().sceneNumId, - nodeType = table.GetNodeType(), - position = new Vector3f(place.Position), - direction = new Vector3f(place.Direction), - worldPosition = new Vector3f(place.InteractiveParam.Position), - guid = GetOwner().random.NextRand(), - - }; - - node.InitComponents(this); - GetOwner().Send(new PacketScFactoryModifyChapterNodes(GetOwner(), chapterId, node)); - nodes.Add(node); - node.SendEntity(GetOwner(), chapterId); - - GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId,op),seq); - - } - - public FactoryChapter(string chapterId,ulong ownerId) - { - this.ownerId = ownerId; - this.chapterId = chapterId; - FactoryNode node = new() - { - nodeId = v, - templateId= "__inventory__", - nodeType=FCNodeType.Inventory, - mapId=0, - deactive=true, - guid = GetOwner().random.NextRand() - }; - node.InitComponents(this); - nodes.Add(node); - } - public Player GetOwner() - { - return Server.clients.Find(c => c.roleId == ownerId); - } - } - public class FactoryNode - { - public uint nodeId; - public FCNodeType nodeType; - public string templateId; - public Vector3f position=new(); - public Vector3f direction = new(); - public Vector3f worldPosition = new(); - public string instKey=""; - public bool deactive = false; - public int mapId; - public int sceneNumId; - public bool forcePowerOn = false; - public List components = new(); - [BsonIgnore] - public bool powered = false; - [BsonIgnore] - public bool lastPowered = false; - public List connectedComps = new(); - public ulong guid; - - public class ConnectedComp - { - public ulong Key; - public ulong Value; - public ConnectedComp(ulong key, ulong value) - { - this.Key = key; - this.Value = value; - } - } - public void Update(FactoryChapter chapter) - { - LevelScene scen = GetLevelData(sceneNumId); - if (lastPowered != powered) - { - lastPowered = powered; - chapter.GetOwner().Send(new PacketScFactoryModifyChapterNodes(chapter.GetOwner(), chapter.chapterId, this)); - } - - } - public bool InPower() - { - if (forcePowerOn) - { - return true; - } - return powered; - } - public FComponent GetComponent() where FComponent : class - { - return components.Find(c => c is FComponent) as FComponent; - } - public FMesh GetMesh() - { - FMesh mesh = new FMesh(); - - if (ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table)) - { - float width = table.range.width - 1; - float height = table.range.height - 1; - float depth = table.range.depth-1; - - Vector3f p1_final = new Vector3f(); - Vector3f p2_final = new Vector3f(); - - switch (direction.y) - { - case 0f: - case 360f: - default: - p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z); - p2_final = p1_final + new Vector3f(width, height, depth); - break; - - case 90f: - // Rotazione 90°: Larghezza e profondità si scambiano. - // Il mesh parte da 'position' ma si estende su assi diversi. - p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z - width); - p2_final = p1_final + new Vector3f(depth, height, width); - break; - - case 180f: - // Rotazione 180°: Larghezza e profondità mantengono i loro valori - // ma il mesh si estende in direzioni negative. - p1_final = position + new Vector3f(table.range.x - width, table.range.y, table.range.z - depth); - p2_final = p1_final + new Vector3f(width, height, depth); - break; - - case 270f: - // Rotazione 270°: Larghezza e profondità si scambiano. - // Il mesh si estende in direzioni diverse rispetto alla rotazione di 90°. - p1_final = position + new Vector3f(table.range.x - depth, table.range.y, table.range.z); - p2_final = p1_final + new Vector3f(depth, height, width); - break; - } - - mesh.points.Add(p1_final); - mesh.points.Add(p2_final); - } - - return mesh; - } - - - public ScdFacNode ToProto() - { - ScdFacNode node = new ScdFacNode() - { - InstKey = instKey, - NodeId=nodeId, - TemplateId=templateId, - StableId= GetStableId(), - IsDeactive= deactive, - - Power = new() - { - InPower= InPower(), - NeedInPower=true, - }, - - NodeType=(int)nodeType, - Transform = new() - { - Position = position.ToProtoScd(), - Direction=direction.ToProtoScd(), - MapId=mapId, - - - } - }; - if(templateId!="__inventory__") - { - node.Transform.Mesh = GetMesh().ToProto(); - node.Transform.Position = position.ToProtoScd(); - node.Transform.WorldPosition = worldPosition.ToProto(); - node.Transform.WorldRotation = direction.ToProto(); - node.InteractiveObject = new() - { - ObjectId=guid, - }; - node.Flag = 0; - node.InstKey = ""; - } - foreach(FComponent comp in components) - { - node.Components.Add(comp.ToProto()); - node.ComponentPos.Add((int)comp.GetComPos(), comp.compId); - } - - return node; - } - public uint GetStableId() - { - return 10000+nodeId; - } - public FCComponentType GetMainCompType() - { - string nodeTypeName = nodeType.ToString(); - if (Enum.TryParse(nodeTypeName, out FCComponentType fromName)) - { - return fromName; - } - return FCComponentType.Invalid; - } - public void InitComponents(FactoryChapter chapter) - { - switch (nodeType) - { - case FCNodeType.PowerPole: - components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); - break; - case FCNodeType.PowerDiffuser: - components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); - break; - case FCNodeType.Battle: - components.Add(new FComponentBattle(chapter.nextCompV()).Init()); - break; - case FCNodeType.Producer: - - components.Add(new FComponentPortManager(chapter.nextCompV(), 3).Init()); - components.Add(new FComponentPortManager(chapter.nextCompV(), 3).Init()); - components.Add(new FComponentProducer(chapter.nextCompV()).Init()); - components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); - components.Add(new FComponentCache(chapter.nextCompV()).Init()); - components.Add(new FComponentCache(chapter.nextCompV()).Init()); - components.Add(new FComponentCache(chapter.nextCompV()).Init()); - break; - case FCNodeType.TravelPole: - components.Add(new FComponentTravelPole(chapter.nextCompV()).Init()); - break; - case FCNodeType.Hub: - components.Add(new FComponentSelector(chapter.nextCompV()).Init()); - components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); - components.Add(new FComponentPowerSave(chapter.nextCompV()).Init()); - components.Add(new FComponentStablePower(chapter.nextCompV()).Init()); - components.Add(new FComponentBusLoader(chapter.nextCompV()).Init()); - components.Add(new FComponentPortManager(chapter.nextCompV(),GetComponent().compId).Init()); - forcePowerOn = true; - break; - case FCNodeType.SubHub: - components.Add(new FComponentSubHub(chapter.nextCompV()).Init()); - components.Add(new FComponentSelector(chapter.nextCompV()).Init()); - components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); - components.Add(new FComponentPowerSave(chapter.nextCompV()).Init()); - components.Add(new FComponentStablePower(chapter.nextCompV()).Init()); - components.Add(new FComponentBusLoader(chapter.nextCompV()).Init()); - components.Add(new FComponentPortManager(chapter.nextCompV(), GetComponent().compId).Init()); - forcePowerOn = true; - break; - default: - components.Add(new FComponent(chapter.nextCompV(), GetMainCompType()).Init()); - break; - } - - } - - public void SendEntity(Player player, string chapterId) - { - Entity exist = player.sceneManager.GetCurScene().entities.Find(e => e.guid == guid); - if (exist != null) - { - exist.Position = worldPosition; - exist.Rotation = direction; - ScMoveObjectMove move = new() - { - ServerNotify = true, - MoveInfo = - { - new MoveObjectMoveInfo() - { - Objid = guid, - SceneNumId=sceneNumId, - MotionInfo = new() - { - Position=exist.Position.ToProto(), - Rotation=exist.Rotation.ToProto(), - Speed=new Vector() - { - - }, - State=MotionState.MotionNone - } - } - } - }; - player.Send(ScMsgId.ScMoveObjectMove, move); - } - else - { - if (interactiveFacWrapperTable.ContainsKey(templateId)) - { - EntityInteractive e = new(interactiveFacWrapperTable[templateId].interactiveTemplateId, player.roleId, worldPosition, direction, sceneNumId, guid); - e.InitDefaultProperties(); - e.SetPropValue(nodeId, "factory_inst_id"); - - player.sceneManager.GetCurScene().entities.Add(e); - player.sceneManager.GetCurScene().SpawnEntity(e); - } - - } - - } - - [BsonDiscriminator(Required = true)] - [BsonKnownTypes(typeof(FComponentSelector))] - - public class FComponent - { - public class FCompInventory - { - public ScdFacComInventory ToProto() - { - return new ScdFacComInventory() - { - - }; - } - } - public uint compId; - public FCComponentType type; - public FCompInventory inventory; - - public FComponent(uint id, FCComponentType t) - { - this.compId = id; - this.type = t; - } - public FCComponentPos GetComPos() - { - - string compTypeName = type.ToString(); - if (Enum.TryParse(compTypeName, out FCComponentPos fromName)) - { - return fromName; - } - switch (type) - { - case FCComponentType.PowerPole: - return FCComponentPos.PowerPole; - case FCComponentType.TravelPole: - return FCComponentPos.TravelPole; - case FCComponentType.Battle: - return FCComponentPos.Battle1; - case FCComponentType.Producer: - return FCComponentPos.Producer; - case FCComponentType.FormulaMan: - return FCComponentPos.FormulaMan; - } - return FCComponentPos.Invalid; - } - public ScdFacCom ToProto() - { - ScdFacCom proto = new ScdFacCom() - { - ComponentType = (int)type, - ComponentId = compId, - - }; - SetComponentInfo(proto); - return proto; - } - - public virtual void SetComponentInfo(ScdFacCom proto) - { - if (inventory != null) - { - proto.Inventory = inventory.ToProto(); - } - else if (type == FCComponentType.PowerPole) - { - proto.PowerPole = new() - { - - }; - } - } - - public virtual FComponent Init() - { - switch (type) - { - case FCComponentType.Inventory: - inventory = new(); - break; - default: - break; - } - return this; - } - } - public class FMesh - { - public FCMeshType type; - public List points=new(); - public ScdFacMesh ToProto() - { - ScdFacMesh m = new ScdFacMesh() - { - MeshType = (int)type - }; - foreach (Vector3f p in points) - { - m.Points.Add(new ScdVec3Int() - { - X = (int)p.x, - Y = (int)p.y, - Z = (int)p.z - }); - } - return m; - } - } - } + + } diff --git a/Campofinale/Game/Factory/FactoryNode.cs b/Campofinale/Game/Factory/FactoryNode.cs new file mode 100644 index 0000000..349232a --- /dev/null +++ b/Campofinale/Game/Factory/FactoryNode.cs @@ -0,0 +1,522 @@ +using Campofinale.Game.Entities; +using Campofinale.Game.Factory.Components; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource.Table; +using Campofinale.Resource; +using MongoDB.Bson.Serialization.Attributes; +using static Campofinale.Resource.ResourceManager; +using Campofinale.Game.Factory.BuildingsBehaviour; +using static Campofinale.Resource.ResourceManager.FactoryBuildingTable; +using Newtonsoft.Json; +using System.Drawing; + +namespace Campofinale.Game.Factory +{ + public class FactoryNode + { + public uint nodeId; + public FCNodeType nodeType; + public string templateId; + public Vector3f position = new(); + public Vector3f direction = new(); + public Vector3f worldPosition = new(); + + public Vector3f directionIn; + public Vector3f directionOut; + public string instKey = ""; + public bool deactive = false; + public int mapId; + public int sceneNumId; + public bool forcePowerOn = false; + public List components = new(); + //Conveyor only + public List points; + public bool powered = false; + public bool lastPowered = false; + public List connectedComps = new(); + public ulong guid; + public NodeBuildingBehaviour nodeBehaviour; + public class ConnectedComp + { + public ulong Key; + public ulong Value; + public ConnectedComp(ulong key, ulong value) + { + this.Key = key; + this.Value = value; + } + } + public void Update(FactoryChapter chapter) + { + LevelScene scen = GetLevelData(sceneNumId); + if (lastPowered != powered) + { + lastPowered = powered; + chapter.GetOwner().Send(new PacketScFactoryModifyChapterNodes(chapter.GetOwner(), chapter.chapterId, this)); + } + if (nodeBehaviour != null) + { + nodeBehaviour.Update(chapter,this); + } + foreach(var comp in components.FindAll(c=> c is FComponentPortManager)) + { + UpdatePortManager(chapter, (FComponentPortManager)comp); + } + } + public void UpdatePortManager(FactoryChapter chapter,FComponentPortManager manager) + { + if (ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table)) + { + List ports = new(); + if (manager.customPos == FCComponentPos.PortOutManager) + { + ports = GetTransformedPorts(table.outputPorts); + List conveyors = chapter.nodes.FindAll(n => n.points != null); + foreach (var port in ports) + { + Vector3f front = port.GetFront(); + FactoryNode node = conveyors.Find(c => + c.nodeType == FCNodeType.BoxConveyor && + c.points.Any(p => p.x == front.x && p.y == front.y && p.z == front.z)); + var compPort = manager.ports.Find(p => p.index == port.index); + if (compPort != null) + { + if (node != null) + { + compPort.touchComId = node.GetComponent().compId; + } + else + { + compPort.touchComId = 0; + } + } + + } + //Output items + foreach (var port in manager.ports) + { + FComponentBoxConveyor output = chapter.GetCompById(port.touchComId); + FComponentCache outputCache = chapter.GetCompById(port.ownerComId); + FactoryNode conveyorNode = chapter.GetNodeByCompId(port.touchComId); + if(outputCache!=null && output != null && conveyorNode != null) + { + bool did = false; + outputCache.items.ForEach(i => + { + if (!did && i.count > 0) + { + ItemCount add = new ItemCount() + { + id = i.id, + count = 1, + + }; + + + if (conveyorNode.AddConveyorItem(i)) + { + did = true; + outputCache.ConsumeItems(new List() { add }); + } + + } + }); + } + } + + } + else + { + ports = GetTransformedPorts(table.inputPorts); + List conveyors = chapter.nodes.FindAll(n => n.points != null); + foreach (var port in ports) + { + Vector3f back = port.GetBack(); + FactoryNode node = conveyors.Find(c => + c.nodeType == FCNodeType.BoxConveyor && + c.points.Any(p => p.x == back.x && p.y == back.y && p.z == back.z)); + var compPort = manager.ports.Find(p => p.index == port.index); + + if (compPort != null) + { + if (node != null) + { + compPort.touchComId = node.GetComponent().compId; + } + else + { + compPort.touchComId = 0; + } + } + + } + } + + } + + } + + private bool AddConveyorItem(ItemCount i) + { + int length=BlockCalculator.CalculateTotalBlocks(points); + FComponentBoxConveyor conveyorComp = GetComponent(); + if (conveyorComp != null) + { + if(conveyorComp.items.Count < length) + { + conveyorComp.items.Add(i); + int size = BlockCalculator.CalculateTotalBlocks(points) - 1; + conveyorComp.lastPopTms = i.tms; + return true; + } + } + return false; + } + + public bool InPower() + { + if (forcePowerOn) + { + return true; + } + return lastPowered; + } + public FComponent GetComponent() where FComponent : class + { + return components.Find(c => c is FComponent) as FComponent; + } + public FComponent GetComponent(uint compid) where FComponent : class + { + return components.Find(c => c is FComponent && c.compId==compid) as FComponent; + } + public List GetTransformedPorts(List originalPorts) + { + List transformedPorts = new List(); + + if (originalPorts == null || originalPorts.Count == 0) + return transformedPorts; + + // Ottieni la posizione e rotazione base dall'oggetto + FMesh mesh = GetMesh(); + if (mesh.points.Count < 2) + return transformedPorts; + + Vector3f objectPosition = mesh.points[0]; + float objectRotationY = direction.y % 360f; + + // Ottieni le dimensioni originali + FactoryBuildingTable table; + if (!ResourceManager.factoryBuildingTable.TryGetValue(templateId, out table)) + return transformedPorts; + + float width = table.range.width - 1; + float depth = table.range.depth - 1; + + foreach (FacPort originalPort in originalPorts) + { + FacPort transformedPort = new FacPort + { + index = originalPort.index, + isOutput = originalPort.isOutput, + isPipe = originalPort.isPipe, + trans = new FacPort.FacPortTrans() + }; + + Vector3f originalPos = originalPort.trans.position; + Vector3f transformedPos = objectPosition; + + switch ((int)objectRotationY) + { + case 0: + transformedPos += originalPos; + break; + + case 90: + transformedPos += new Vector3f(originalPos.z, originalPos.y, width - originalPos.x); + break; + + case 180: + transformedPos += new Vector3f(width - originalPos.x, originalPos.y, depth - originalPos.z); + break; + + case 270: + transformedPos += new Vector3f(depth - originalPos.z, originalPos.y, originalPos.x); + break; + } + + transformedPort.trans.position = transformedPos; + + // Rotazione della porta + transformedPort.trans.rotation = new Vector3f( + originalPort.trans.rotation.x, + (originalPort.trans.rotation.y + objectRotationY) % 360f, + originalPort.trans.rotation.z + ); + + transformedPorts.Add(transformedPort); + } + + return transformedPorts; + } + + public FMesh GetMesh() + { + FMesh mesh = new FMesh(); + if(points != null) + { + points.ForEach(p => + { + mesh.points.Add(p); + }); + mesh.type = FCMeshType.Line; + return mesh; + } + if (ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table)) + { + float width = table.range.width - 1; + float height = table.range.height - 1; + float depth = table.range.depth - 1; + + Vector3f p1_final = new Vector3f(); + Vector3f p2_final = new Vector3f(); + + switch (direction.y) + { + case 0f: + case 360f: + default: + p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z); + p2_final = p1_final + new Vector3f(width, height, depth); + break; + + case 90f: + p1_final = position + new Vector3f(table.range.x, table.range.y, table.range.z - width); + p2_final = p1_final + new Vector3f(depth, height, width); + break; + + case 180f: + p1_final = position + new Vector3f(table.range.x - width, table.range.y, table.range.z - depth); + p2_final = p1_final + new Vector3f(width, height, depth); + break; + + case 270f: + p1_final = position + new Vector3f(table.range.x - depth, table.range.y, table.range.z); + p2_final = p1_final + new Vector3f(depth, height, width); + break; + } + + mesh.points.Add(p1_final); + mesh.points.Add(p2_final); + } + + return mesh; + } + + + public ScdFacNode ToProto() + { + ScdFacNode node = new ScdFacNode() + { + InstKey = instKey, + NodeId = nodeId, + TemplateId = templateId, + StableId = GetStableId(), + IsDeactive = deactive, + + Power = new() + { + InPower = InPower(), + NeedInPower = true, + }, + + NodeType = (int)nodeType, + Transform = new() + { + Position = position.ToProtoScd(), + Direction = direction.ToProtoScd(), + MapId = mapId, + + } + }; + + if (templateId != "__inventory__") + { + if(nodeType != FCNodeType.BoxConveyor) + { + node.Transform.Mesh = GetMesh().ToProto(); + node.Transform.Position = position.ToProtoScd(); + node.Transform.WorldPosition = worldPosition.ToProto(); + node.Transform.WorldRotation = direction.ToProto(); + node.InteractiveObject = new() + { + ObjectId = guid, + }; + node.Flag = 0; + node.InstKey = ""; + } + else + { + node.Transform.Mesh = GetMesh().ToProto(); + node.Transform.Position = position.ToProtoScd(); + node.Transform.WorldPosition = null; + node.Transform.WorldRotation = null; + node.InteractiveObject =null; + node.Transform.BcPortIn = new() + { + Direction = directionIn.ToProtoScd(), + Position = points[0].ToProtoScd() + }; + node.Transform.BcPortOut = new() + { + Direction = directionOut.ToProtoScd(), + Position = points[points.Count-1].ToProtoScd() + }; + node.Flag = 0; + node.InstKey = ""; + } + + } + + foreach (FComponent comp in components) + { + node.Components.Add(comp.ToProto()); + node.ComponentPos.Add((int)comp.GetComPos(), comp.compId); + } + + return node; + } + public uint GetStableId() + { + return 10000 + nodeId; + } + public FCComponentType GetMainCompType() + { + string nodeTypeName = nodeType.ToString(); + if (Enum.TryParse(nodeTypeName, out FCComponentType fromName)) + { + return fromName; + } + return FCComponentType.Invalid; + } + public void InitComponents(FactoryChapter chapter) + { + switch (nodeType) + { + case FCNodeType.PowerPole: + components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); + break; + case FCNodeType.PowerDiffuser: + components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); + break; + case FCNodeType.Battle: + components.Add(new FComponentBattle(chapter.nextCompV()).Init()); + break; + case FCNodeType.Producer: + nodeBehaviour=new NodeBuilding_Producer(); + nodeBehaviour.Init(chapter, this); + break; + case FCNodeType.BoxConveyor: + components.Add(new FComponentBoxConveyor(chapter.nextCompV()).Init()); + break; + case FCNodeType.TravelPole: + components.Add(new FComponentTravelPole(chapter.nextCompV()).Init()); + break; + case FCNodeType.Hub: + components.Add(new FComponentSelector(chapter.nextCompV()).Init()); + components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); + components.Add(new FComponentPowerSave(chapter.nextCompV()).Init()); + components.Add(new FComponentStablePower(chapter.nextCompV()).Init()); + components.Add(new FComponentBusLoader(chapter.nextCompV()).Init()); + components.Add(new FComponentPortManager(chapter.nextCompV(), GetComponent().compId).Init()); + forcePowerOn = true; + break; + case FCNodeType.SubHub: + components.Add(new FComponentSubHub(chapter.nextCompV()).Init()); + components.Add(new FComponentSelector(chapter.nextCompV()).Init()); + components.Add(new FComponentPowerPole(chapter.nextCompV()).Init()); + components.Add(new FComponentPowerSave(chapter.nextCompV()).Init()); + components.Add(new FComponentStablePower(chapter.nextCompV()).Init()); + components.Add(new FComponentBusLoader(chapter.nextCompV()).Init()); + components.Add(new FComponentPortManager(chapter.nextCompV(), GetComponent().compId).Init()); + forcePowerOn = true; + break; + default: + components.Add(new FComponent(chapter.nextCompV(), GetMainCompType()).Init()); + break; + } + + } + + public void SendEntity(Player player, string chapterId) + { + Entity exist = player.sceneManager.GetCurScene().entities.Find(e => e.guid == guid); + if (exist != null) + { + exist.Position = worldPosition; + exist.Rotation = direction; + ScMoveObjectMove move = new() + { + ServerNotify = true, + MoveInfo = + { + new MoveObjectMoveInfo() + { + Objid = guid, + SceneNumId=sceneNumId, + MotionInfo = new() + { + Position=exist.Position.ToProto(), + Rotation=exist.Rotation.ToProto(), + Speed=new Vector() + { + + }, + State=MotionState.MotionNone + } + } + } + }; + player.Send(ScMsgId.ScMoveObjectMove, move); + } + else + { + if (interactiveFacWrapperTable.ContainsKey(templateId)) + { + EntityInteractive e = new(interactiveFacWrapperTable[templateId].interactiveTemplateId, player.roleId, worldPosition, direction, sceneNumId, guid); + e.InitDefaultProperties(); + e.SetPropValue(nodeId, "factory_inst_id"); + + player.sceneManager.GetCurScene().entities.Add(e); + player.sceneManager.GetCurScene().SpawnEntity(e); + } + + } + + } + + + public class FMesh + { + public FCMeshType type; + public List points = new(); + public ScdFacMesh ToProto() + { + ScdFacMesh m = new ScdFacMesh() + { + MeshType = (int)type + }; + foreach (Vector3f p in points) + { + m.Points.Add(new ScdVec3Int() + { + X = (int)p.x, + Y = (int)p.y, + Z = (int)p.z + }); + } + return m; + } + } + } +} diff --git a/Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs b/Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs index 853efe5..51a565d 100644 --- a/Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs +++ b/Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs @@ -1,4 +1,5 @@ -using Campofinale.Network; +using Campofinale.Game.Factory; +using Campofinale.Network; using Campofinale.Protocol; namespace Campofinale.Packets.Cs @@ -10,14 +11,33 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsFactoryHsFb req = packet.DecodeBody(); - long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + + List comps = new(); - ScFactoryHs hs = new() + foreach (var id in req.NodeIdList) { - - + FactoryNode node=session.factoryManager.GetChapter(req.ChapterId).nodes.Find(n=>n.nodeId == id); + if (node != null) + { + node.components.ForEach(c => + { + comps.Add(c.ToProto()); + }); + } + } + + long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + ScFactoryHsSync hs = new() + { + Tms = curtimestamp, + CcList = + { + comps, + }, + Blackboard = session.factoryManager.GetChapter(req.ChapterId).ToProto().Blackboard, + ChapterId=req.ChapterId, }; - session.Send(ScMsgId.ScFactoryHs, hs); + session.Send(ScMsgId.ScFactoryHsSync, hs,packet.csHead.UpSeqid); } diff --git a/Campofinale/Packets/Cs/HandleCsPing.cs b/Campofinale/Packets/Cs/HandleCsPing.cs index f3cccf3..7fa8e39 100644 --- a/Campofinale/Packets/Cs/HandleCsPing.cs +++ b/Campofinale/Packets/Cs/HandleCsPing.cs @@ -17,25 +17,7 @@ namespace Campofinale.Packets.Cs ClientTs = req.ClientTs, ServerTs = (ulong)curtimestamp, })); - /*ScFactoryHsSync s = new() - { - Blackboard = new() - { - InventoryNodeId = 0, - Power = new() - { - - } - }, - CcList = - { - - }, - Tms = curtimestamp / 1000, - ChapterId = session.GetCurrentChapter() - }; - - session.Send(ScMessageId.ScFactoryHsSync,s);*/ + session.factoryManager.SendFactoryHsSync(); //Logger.Print("Server: " + curtimestamp + " client: " + req.ClientTs); } diff --git a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs index 0dcb19c..edec84a 100644 --- a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs +++ b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs @@ -42,6 +42,20 @@ namespace Campofinale.Packets.Sc }; } + if (op.OpType == FactoryOpType.DismantleBoxConveyor) + { + proto.DismantleBoxConveyor = new() + { + + }; + } + if (op.OpType == FactoryOpType.ChangeProducerMode) + { + proto.ChangeProducerMode = new() + { + + }; + } if (op.OpType == FactoryOpType.SetTravelPoleDefaultNext) { proto.SetTravelPoleDefaultNext = new() @@ -49,9 +63,46 @@ namespace Campofinale.Packets.Sc }; } + if (op.OpType == FactoryOpType.EnableNode) + { + proto.EnableNode = new() + { + + }; + } + + if (op.OpType == FactoryOpType.MoveItemBagToCache) + { + proto.MoveItemBagToCache = new() + { + + }; + } proto.Index=op.Index; SetData(ScMsgId.ScFactoryOpRet, proto); } + public PacketScFactoryOpRet(Player client, List val, CsFactoryOp op) + { + ScFactoryOpRet proto = new ScFactoryOpRet() + { + RetCode = FactoryOpRetCode.Ok, + OpType = op.OpType, + + }; + + if (op.OpType == FactoryOpType.PlaceConveyor) + { + proto.PlaceConveyor = new() + { + NodeId = + { + val + } + }; + } + proto.Index = op.Index; + SetData(ScMsgId.ScFactoryOpRet, proto); + } } } diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index 37d0b90..ce0a66f 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -69,6 +69,7 @@ namespace Campofinale.Resource public static DialogIdTable dialogIdTable = new();// public static Dictionary levelShortIdTable = new(); public static Dictionary factoryBuildingTable = new(); + public static Dictionary factoryMachineCraftTable = new(); public static Dictionary facSTTNodeTable = new(); public static Dictionary facSTTLayerTable = new(); public static Dictionary itemTypeTable = new(); // @@ -339,12 +340,55 @@ namespace Campofinale.Resource { return strIdNumTable.item_id.dic[item_id]; } + + public static string FindFactoryMachineCraftIdUsingCacheItems(List items) + { + // Estrae solo gli ID degli items in input e li ordina + var inputItemIds = items.Select(item => item.id).OrderBy(id => id).ToList(); + + foreach (var recipe in factoryMachineCraftTable.Values.ToList()) + { + // Raccoglie tutti gli ID degli ingredienti della ricetta + var recipeItemIds = new List(); + foreach (var ingr in recipe.ingredients) + { + recipeItemIds.AddRange(ingr.group.Select(item => item.id)); + } + + // Ordina gli ID degli ingredienti della ricetta + var sortedRecipeItemIds = recipeItemIds.OrderBy(id => id).ToList(); + + // Confronta le due liste di ID (ignorando le quantità) + if (inputItemIds.SequenceEqual(sortedRecipeItemIds)) + { + return recipe.id; // Trovata corrispondenza + } + } + + return ""; // Nessuna corrispondenza trovata + } + public class InteractiveData { public string id; public Dictionary propertyKeyToIdMap = new(); public List saveProperties = new(); } + public class ItemCount + { + public int count; + public string id = ""; + public long tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + + public ScdFactorySyncItem ToFactoryItemProto() + { + return new ScdFactorySyncItem() + { + Count = count, + Id = id, + }; + } + } public class FactoryBuildingTable { public int bandwidth; @@ -354,15 +398,107 @@ namespace Campofinale.Resource public int powerConsume; public FacBuildingType type; public FBuildingRange range; + public List outputPorts = new(); + public List inputPorts = new(); + public class FacPort + { + public int index; + public int isOutput; + public bool isPipe; + public FacPortTrans trans = new(); + public Vector3f GetBack() + { + float angleY = trans.rotation.y % 360f; + + Vector3f offset; + + switch ((int)angleY) + { + default: + case 360: + case 0: + offset = new Vector3f(0, 0, -1); + break; + case 90: + offset = new Vector3f(-1, 0, 0); + break; + case 180: + offset = new Vector3f(0, 0, 1); + break; + case 270: + offset = new Vector3f(1, 0, 0); + break; + } + + return trans.position + offset; + } + public Vector3f GetFront() + { + float angleY = trans.rotation.y % 360f; + + Vector3f offset=new(); + + switch ((int)angleY) + { + default: + case 360: + case 0: + offset = new Vector3f(0, 0, 1); + break; + case 90: + offset = new Vector3f(1, 0, 0); + break; + case 180: + offset = new Vector3f(0, 0, -1); + break; + case 270: + offset = new Vector3f(-1, 0, 0); + break; + } + + return trans.position + offset; + } + + public class FacPortTrans + { + public Vector3f position=new(); + public Vector3f rotation = new(); + } + } public FCNodeType GetNodeType() { - string nodeTypeName = type.ToString(); - if (Enum.TryParse(nodeTypeName, out FCNodeType fromName)) + switch (type) { - return fromName; + case FacBuildingType.Battle: + return FCNodeType.Battle; + case FacBuildingType.Hub: + return FCNodeType.Hub; + case FacBuildingType.SubHub: + return FCNodeType.SubHub; + case FacBuildingType.MachineCrafter: + return FCNodeType.Producer; + case FacBuildingType.PowerPort: + return FCNodeType.PowerPort; + case FacBuildingType.PowerPole: + return FCNodeType.PowerPole; + case FacBuildingType.PowerDiffuser: + return FCNodeType.PowerDiffuser; + case FacBuildingType.TravelPole: + return FCNodeType.TravelPole; + case FacBuildingType.Medic: + return FCNodeType.HealTower; + case FacBuildingType.Unloader: + return FCNodeType.BusUnloader; + case FacBuildingType.Loader: + return FCNodeType.BusLoader; + case FacBuildingType.Miner: + return FCNodeType.Collector; + case FacBuildingType.Storager: + return FCNodeType.DepositBox; + default: + return FCNodeType.Invalid; } - return FCNodeType.Invalid; } public struct FBuildingRange { @@ -978,7 +1114,20 @@ namespace Campofinale.Resource public float x; public float y; public float z; - + + public override bool Equals(object obj) + { + if (obj is Vector3f v) + { + return x == v.x && y == v.y && z == v.z; + } + return false; + } + + public override int GetHashCode() + { + return HashCode.Combine(x, y, z); + } public Vector3f() { diff --git a/Campofinale/Resource/Table/FactoryMachineCraftTable.cs b/Campofinale/Resource/Table/FactoryMachineCraftTable.cs new file mode 100644 index 0000000..5cf914c --- /dev/null +++ b/Campofinale/Resource/Table/FactoryMachineCraftTable.cs @@ -0,0 +1,52 @@ +using Campofinale.Game.Factory.Components; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Resource.Table +{ + [TableCfgType("TableCfg/FactoryMachineCraftTable.json", LoadPriority.LOW)] + public class FactoryMachineCraftTable + { + public string id; + public string machineId; + public int progressRound; + public long totalProgress; + public int signal; + public List ingredients = new(); + public List outcomes = new(); + + public bool CacheHaveItems(FComponentCache inCache) + { + bool enough = true; + ingredients.ForEach(i => + { + i.group.ForEach(item => + { + if(inCache.GetItemCount(item.id) < item.count) + { + enough = false; + + } + }); + }); + return enough; + } + + internal List GetIngredients() + { + List items = new(); + ingredients.ForEach(i => + { + i.group.ForEach(item => + { + items.Add(item); + }); + }); + return items; + } + + public class FactoryMachineCraftIngredient + { + public List group = new(); + } + } +} diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 4f2b587..06b5c39 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -59,7 +59,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.6"; + public static string ServerVersion = "1.1.7-dev"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true; From eb63e350a789d9a9ee8c854d1e3a7f380bf8f2e2 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 02:06:19 +0200 Subject: [PATCH 03/14] default 1 scene grade --- Campofinale/Game/SceneManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index c000be1..e8bbe01 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -267,7 +267,7 @@ namespace Campofinale.Game public List activeScripts = new(); public List scripts = new(); - public int grade = 0; + public int grade = 1; public int GetCollection(string id) { From c92afab33fcb7102c5d6eb060a783a0d6f7ea004 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 02:08:07 +0200 Subject: [PATCH 04/14] scene grade send correctly on self scene info --- Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs index fbb5069..f54189c 100644 --- a/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs +++ b/Campofinale/Packets/Sc/PacketScSelfSceneInfo.cs @@ -22,7 +22,7 @@ namespace Campofinale.Packets.Sc TeamType = CharBagTeamType.Main }, - SceneGrade = 4, + SceneGrade = session.sceneManager.GetCurScene().grade, Detail = new() { From ff7332fdaf2371f41e430b373238869c622bfe0f Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 02:08:32 +0200 Subject: [PATCH 05/14] set to grade 1 if grade is 0 on scene load --- Campofinale/Game/SceneManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index e8bbe01..799dc2a 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -311,6 +311,10 @@ namespace Campofinale.Game } public void Load() { + if (grade == 0) + { + grade = 1; + } Unload(); LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId); From 4abb9d0bb5cf097c846df02565b30776e6fd3b61 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 18:00:09 +0200 Subject: [PATCH 06/14] working conveyors and implemented furnace build --- Campofinale/Game/Factory/BlockCalculator.cs | 2 +- .../NodeBuilding_Producer.cs | 57 +++++---- .../NodeBuilding_ProducerFurnace.cs | 115 ++++++++++++++++++ .../Components/FComponentBoxConveyor.cs | 3 + .../Components/FComponentFormulaMan.cs | 22 ++-- Campofinale/Game/Factory/FactoryNode.cs | 100 ++++++++++++--- Campofinale/Packets/Cs/HandleCsLogin.cs | 3 +- Campofinale/Resource/ResourceManager.cs | 12 +- .../Table/FactoryMachineCraftTable.cs | 1 + 9 files changed, 252 insertions(+), 63 deletions(-) create mode 100644 Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs diff --git a/Campofinale/Game/Factory/BlockCalculator.cs b/Campofinale/Game/Factory/BlockCalculator.cs index b5e01bf..a77b7f3 100644 --- a/Campofinale/Game/Factory/BlockCalculator.cs +++ b/Campofinale/Game/Factory/BlockCalculator.cs @@ -9,7 +9,7 @@ namespace Campofinale.Game.Factory { public class BlockCalculator { - public static int CalculateTotalBlocks(List points) + public static float CalculateTotalBlocks(List points) { if (points == null || points.Count < 2) return 0; diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs index 9397b80..f690108 100644 --- a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading.Tasks; using Campofinale.Resource; using static Campofinale.Resource.ResourceManager; +using System.Xml.Linq; namespace Campofinale.Game.Factory.BuildingsBehaviour { @@ -20,18 +21,30 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour public int currentProgress = 0; public override void Init(FactoryChapter chapter, FactoryNode node) { - FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); - FComponentCache cache2 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheOut1).Init(); - FComponentProducer producer = (FComponentProducer)new FComponentProducer(chapter.nextCompV()).Init(); - node.components.Add(producer); - node.components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); - node.components.Add(cache1); - node.components.Add(cache2); - inputCacheId = cache1.compId; - outputCacheId = cache2.compId; - producerId = producer.compId; - node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3,cache1).Init()); - node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3, cache2).Init()); + FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); + FComponentCache cache2 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheOut1).Init(); + FComponentProducer producer = (FComponentProducer)new FComponentProducer(chapter.nextCompV()).Init(); + node.components.Add(producer); + node.components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); + node.components.Add(cache1); + node.components.Add(cache2); + inputCacheId = cache1.compId; + outputCacheId = cache2.compId; + producerId = producer.compId; + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3, cache1).Init()); + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 3, cache2).Init()); + } + public string GetFormulaGroupId(string templateId) + { + FactoryMachineCraftTable table = factoryMachineCraftTable.Values.ToList().Find(r => r.machineId == templateId); + if (table != null) + { + return table.formulaGroupId; + } + else + { + return ""; + } } public override void Update(FactoryChapter chapter, FactoryNode node) { @@ -41,8 +54,12 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour FComponentProducer producer = node.GetComponent(producerId); FComponentCache inCache = node.GetComponent(inputCacheId); FComponentCache outCache = node.GetComponent(outputCacheId); + FComponentFormulaMan formulaManager = node.GetComponent(); + + if (formulaManager == null) return; + formulaManager.currentGroup = GetFormulaGroupId(node.templateId); FactoryMachineCraftTable craftingRecipe = null; - string recipe = ResourceManager.FindFactoryMachineCraftIdUsingCacheItems(inCache.items); + string recipe = ResourceManager.FindFactoryMachineCraftIdUsingCacheItems(inCache.items,formulaManager.currentGroup); producer.formulaId = recipe; ResourceManager.factoryMachineCraftTable.TryGetValue(producer.formulaId, out craftingRecipe); @@ -73,7 +90,6 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour } else { - producer.inBlock = false; producer.inProduce = false; producer.progress = 0; } @@ -85,18 +101,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.progress = 0; } } - /* ScFactoryModifyChapterComponents update = new() - { - ChapterId = chapter.chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, - - }; - - foreach (var comp in node.components) - { - update.Components.Add(comp.ToProto()); - } - chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterComponents, update);*/ + } } } diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs new file mode 100644 index 0000000..8c2d01c --- /dev/null +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs @@ -0,0 +1,115 @@ +using Campofinale.Game.Factory.Components; +using Campofinale.Protocol; +using Campofinale.Resource; +using Campofinale.Resource.Table; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Campofinale.Resource; +using static Campofinale.Resource.ResourceManager; +using System.Xml.Linq; + +namespace Campofinale.Game.Factory.BuildingsBehaviour +{ + public class NodeBuilding_ProducerFurnace : NodeBuildingBehaviour + { + public uint inputCacheId = 0; + public uint outputCacheId = 0; + public uint inputCacheIdFluid = 0; + public uint outputCacheIdFluid = 0; + public uint producerId = 0; + public int currentProgress = 0; + public override void Init(FactoryChapter chapter, FactoryNode node) + { + FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); + FComponentCache cache2 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheOut1).Init(); + FComponentCache cache3 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheFluidIn1).Init(); + FComponentCache cache4 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheFluidOut1).Init(); + FComponentProducer producer = (FComponentProducer)new FComponentProducer(chapter.nextCompV()).Init(); + node.components.Add(producer); + node.components.Add(new FComponentFormulaMan(chapter.nextCompV()).Init()); + node.components.Add(cache1); + node.components.Add(cache2); + node.components.Add(cache3); + node.components.Add(cache4); + inputCacheId = cache1.compId; + outputCacheId = cache2.compId; + inputCacheIdFluid = cache3.compId; + outputCacheIdFluid = cache4.compId; + producerId = producer.compId; + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 4, cache1).Init()); + node.components.Add(new FComponentPortManager(chapter.nextCompV(), 4, cache2).Init()); + } + public string GetFormulaGroupId(string templateId) + { + FactoryMachineCraftTable table = factoryMachineCraftTable.Values.ToList().Find(r => r.machineId == templateId); + if (table != null) + { + return table.formulaGroupId; + } + else + { + return ""; + } + } + public override void Update(FactoryChapter chapter, FactoryNode node) + { + + if (node.powered) + { + FComponentProducer producer = node.GetComponent(producerId); + FComponentCache inCache = node.GetComponent(inputCacheId); + FComponentCache outCache = node.GetComponent(outputCacheId); + FComponentFormulaMan formulaManager = node.GetComponent(); + + if (formulaManager == null) return; + formulaManager.currentGroup = GetFormulaGroupId(node.templateId); + FactoryMachineCraftTable craftingRecipe = null; + string recipe = ResourceManager.FindFactoryMachineCraftIdUsingCacheItems(inCache.items,formulaManager.currentGroup); + producer.formulaId = recipe; + ResourceManager.factoryMachineCraftTable.TryGetValue(producer.formulaId, out craftingRecipe); + + if (craftingRecipe != null) + { + producer.inBlock = outCache.IsFull(); + if (craftingRecipe.CacheHaveItems(inCache) && !outCache.IsFull()) + { + producer.inProduce = true; + + producer.lastFormulaId = recipe; + producer.progress += craftingRecipe.totalProgress/craftingRecipe.progressRound; + currentProgress++; + if (currentProgress >= craftingRecipe.progressRound) + { + currentProgress = 0; + List toConsume = craftingRecipe.GetIngredients(); + inCache.ConsumeItems(toConsume); + craftingRecipe.outcomes.ForEach(e => + { + e.group.ForEach(i => + { + outCache.AddItem(i.id, i.count); + }); + + }); + } + } + else + { + producer.inProduce = false; + producer.progress = 0; + } + } + else + { + producer.inBlock = false; + producer.inProduce = false; + producer.progress = 0; + } + } + + } + } +} diff --git a/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs index cd64c4b..c204911 100644 --- a/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs +++ b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs @@ -10,14 +10,17 @@ namespace Campofinale.Game.Factory.Components public List items = new(); public FComponentBoxConveyor(uint id) : base(id, FCComponentType.BoxConveyor,FCComponentPos.BoxConveyor) { + lastPopTms=DateTime.UtcNow.ToUnixTimestampMilliseconds(); } + public override void SetComponentInfo(ScdFacCom proto) { if (items == null) { items = new List(); } + proto.BoxConveyor = new() { LastPopTms = lastPopTms, diff --git a/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs index 17868d9..993892c 100644 --- a/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs +++ b/Campofinale/Game/Factory/Components/FComponentFormulaMan.cs @@ -1,5 +1,5 @@ using Campofinale.Resource; -using static Campofinale.Game.Factory.FactoryNode; + namespace Campofinale.Game.Factory.Components { @@ -7,28 +7,24 @@ namespace Campofinale.Game.Factory.Components { public string currentGroup = "group_grinder_normal"; public string currentMode = "normal"; + public List formulaIds = new(); public FComponentFormulaMan(uint id) : base(id, FCComponentType.FormulaMan) { } - + public List GetFormulaIds() + { + List ids = ResourceManager.factoryMachineCraftTable.Where(i => i.Value.formulaGroupId == currentGroup).Select(i => i.Value.id).ToList(); + return ids; + } public override void SetComponentInfo(ScdFacCom proto) { + formulaIds = GetFormulaIds(); proto.FormulaMan = new() { CurrentGroup = currentGroup, CurrentMode = currentMode, FormulaIds = { - "grinder_iron_powder_1", - "grinder_quartz_powder_1", - "grinder_originium_powder_1", - "grinder_carbon_powder_1", - "grinder_crystal_powder_1", - "grinder_plant_moss_powder_1_1", - "grinder_plant_moss_powder_2_1", - "grinder_plant_moss_powder_3_1", - "grinder_plant_bbflower_powder_1_1", - "grinder_plant_grass_powder_1_1", - "grinder_plant_grass_powder_2_1" + formulaIds } }; } diff --git a/Campofinale/Game/Factory/FactoryNode.cs b/Campofinale/Game/Factory/FactoryNode.cs index 349232a..bd653fa 100644 --- a/Campofinale/Game/Factory/FactoryNode.cs +++ b/Campofinale/Game/Factory/FactoryNode.cs @@ -10,6 +10,7 @@ using Campofinale.Game.Factory.BuildingsBehaviour; using static Campofinale.Resource.ResourceManager.FactoryBuildingTable; using Newtonsoft.Json; using System.Drawing; +using Campofinale.Game.Inventory; namespace Campofinale.Game.Factory { @@ -55,14 +56,27 @@ namespace Campofinale.Game.Factory lastPowered = powered; chapter.GetOwner().Send(new PacketScFactoryModifyChapterNodes(chapter.GetOwner(), chapter.chapterId, this)); } - if (nodeBehaviour != null) + if (nodeBehaviour != null && !deactive) { nodeBehaviour.Update(chapter,this); } - foreach(var comp in components.FindAll(c=> c is FComponentPortManager)) + foreach (var comp in components.FindAll(c => c is FComponentPortManager)) { - UpdatePortManager(chapter, (FComponentPortManager)comp); + var portmanager = (FComponentPortManager)comp; + if (portmanager.customPos != FCComponentPos.PortOutManager) + { + UpdatePortManager(chapter, portmanager); + } } + foreach (var comp in components.FindAll(c => c is FComponentPortManager)) + { + var portmanager = (FComponentPortManager)comp; + if (portmanager.customPos == FCComponentPos.PortOutManager) + { + UpdatePortManager(chapter, portmanager); + } + } + } public void UpdatePortManager(FactoryChapter chapter,FComponentPortManager manager) { @@ -99,7 +113,7 @@ namespace Campofinale.Game.Factory FComponentBoxConveyor output = chapter.GetCompById(port.touchComId); FComponentCache outputCache = chapter.GetCompById(port.ownerComId); FactoryNode conveyorNode = chapter.GetNodeByCompId(port.touchComId); - if(outputCache!=null && output != null && conveyorNode != null) + if (outputCache != null && output != null && conveyorNode != null) { bool did = false; outputCache.items.ForEach(i => @@ -109,22 +123,20 @@ namespace Campofinale.Game.Factory ItemCount add = new ItemCount() { id = i.id, - count = 1, - + count = 1 }; - - - if (conveyorNode.AddConveyorItem(i)) + + if (conveyorNode.AddConveyorItem(add)) { did = true; outputCache.ConsumeItems(new List() { add }); } - + } }); } } - + } else { @@ -137,7 +149,7 @@ namespace Campofinale.Game.Factory c.nodeType == FCNodeType.BoxConveyor && c.points.Any(p => p.x == back.x && p.y == back.y && p.z == back.z)); var compPort = manager.ports.Find(p => p.index == port.index); - + if (compPort != null) { if (node != null) @@ -151,24 +163,65 @@ namespace Campofinale.Game.Factory } } + + //Input items + foreach (var port in manager.ports) + { + FComponentBoxConveyor input = chapter.GetCompById(port.touchComId); + FComponentCache inputCache = chapter.GetCompById(port.ownerComId); + FactoryNode conveyorNode = chapter.GetNodeByCompId(port.touchComId); + if (inputCache != null && input != null && conveyorNode != null) + { + bool did = false; + ItemCount toRemove = null; + foreach (var item in input.items) + { + if (!did && item.count > 0 && item.IsItemAtConveyorEnd(BlockCalculator.CalculateTotalBlocks(conveyorNode.points))) + { + + if (!inputCache.IsFull()) + { + did = true; + toRemove = item; + inputCache.AddItem(item.id, item.count); + break; + } + + } + } + if(toRemove!=null) + input.items.Remove(toRemove); + + } + } } - } } private bool AddConveyorItem(ItemCount i) { - int length=BlockCalculator.CalculateTotalBlocks(points); + float length=BlockCalculator.CalculateTotalBlocks(points); FComponentBoxConveyor conveyorComp = GetComponent(); if (conveyorComp != null) { - if(conveyorComp.items.Count < length) + if(conveyorComp.items.Count < (int)length) { - conveyorComp.items.Add(i); - int size = BlockCalculator.CalculateTotalBlocks(points) - 1; - conveyorComp.lastPopTms = i.tms; - return true; + long timestamp = i.tms - conveyorComp.lastPopTms; + if(timestamp >= 2000) + { + conveyorComp.items.Add(i); + i.tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + conveyorComp.lastPopTms = i.tms; + Logger.Print("Spawning item in conveyor: " + conveyorComp.lastPopTms); + return true; + } + else + { + return false; + } + + } } return false; @@ -413,7 +466,14 @@ namespace Campofinale.Game.Factory components.Add(new FComponentBattle(chapter.nextCompV()).Init()); break; case FCNodeType.Producer: - nodeBehaviour=new NodeBuilding_Producer(); + if (templateId == "grinder_1") + { + nodeBehaviour = new NodeBuilding_Producer(); + }else if (templateId == "furnance_1") + { + nodeBehaviour = new NodeBuilding_ProducerFurnace(); + } + if(nodeBehaviour!=null) nodeBehaviour.Init(chapter, this); break; case FCNodeType.BoxConveyor: diff --git a/Campofinale/Packets/Cs/HandleCsLogin.cs b/Campofinale/Packets/Cs/HandleCsLogin.cs index 412ee09..db853ec 100644 --- a/Campofinale/Packets/Cs/HandleCsLogin.cs +++ b/Campofinale/Packets/Cs/HandleCsLogin.cs @@ -89,7 +89,8 @@ namespace Campofinale.Packets.Cs IsFirstLogin = false, IsReconnect=false, LastRecvUpSeqid = packet.csHead.UpSeqid, - + ServerTimeZone=2, + ServerTime=DateTime.UtcNow.ToUnixTimestampMilliseconds(), }; byte[] encKey = GenerateRandomBytes(32); string serverPublicKeyPem = req.ClientPublicKey.ToStringUtf8(); diff --git a/Campofinale/Resource/ResourceManager.cs b/Campofinale/Resource/ResourceManager.cs index ce0a66f..44ae964 100644 --- a/Campofinale/Resource/ResourceManager.cs +++ b/Campofinale/Resource/ResourceManager.cs @@ -341,12 +341,12 @@ namespace Campofinale.Resource return strIdNumTable.item_id.dic[item_id]; } - public static string FindFactoryMachineCraftIdUsingCacheItems(List items) + public static string FindFactoryMachineCraftIdUsingCacheItems(List items, string group) { // Estrae solo gli ID degli items in input e li ordina var inputItemIds = items.Select(item => item.id).OrderBy(id => id).ToList(); - foreach (var recipe in factoryMachineCraftTable.Values.ToList()) + foreach (var recipe in factoryMachineCraftTable.Values.ToList().FindAll(r=>r.formulaGroupId==group)) { // Raccoglie tutti gli ID degli ingredienti della ricetta var recipeItemIds = new List(); @@ -386,8 +386,16 @@ namespace Campofinale.Resource { Count = count, Id = id, + Tms = tms }; } + public bool IsItemAtConveyorEnd(float conveyorSize) + { + long spawnTms = tms; + long endTms = spawnTms + (long)(2000 * conveyorSize); + long cur = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + return cur > endTms; + } } public class FactoryBuildingTable { diff --git a/Campofinale/Resource/Table/FactoryMachineCraftTable.cs b/Campofinale/Resource/Table/FactoryMachineCraftTable.cs index 5cf914c..880d691 100644 --- a/Campofinale/Resource/Table/FactoryMachineCraftTable.cs +++ b/Campofinale/Resource/Table/FactoryMachineCraftTable.cs @@ -11,6 +11,7 @@ namespace Campofinale.Resource.Table public int progressRound; public long totalProgress; public int signal; + public string formulaGroupId; public List ingredients = new(); public List outcomes = new(); From 388a71df7f520ec2e9f0890b00f7b9e1026e8337 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 19:06:50 +0200 Subject: [PATCH 07/14] CsSceneRest --- Campofinale/Commands/Handlers/CommandHeal.cs | 17 ++--------- .../NodeBuilding_ProducerFurnace.cs | 2 +- Campofinale/Packets/Cs/HandleCsSceneRest.cs | 28 +++++++++++++++++++ Campofinale/Player.cs | 19 +++++++++++++ 4 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 Campofinale/Packets/Cs/HandleCsSceneRest.cs diff --git a/Campofinale/Commands/Handlers/CommandHeal.cs b/Campofinale/Commands/Handlers/CommandHeal.cs index 992c2b2..60c049d 100644 --- a/Campofinale/Commands/Handlers/CommandHeal.cs +++ b/Campofinale/Commands/Handlers/CommandHeal.cs @@ -10,21 +10,8 @@ namespace Campofinale.Commands.Handlers [Server.Command("heal", "Revives/Heals your team characters", true)] public static void Handle(Player sender, string cmd, string[] args, Player target) { - target.GetCurTeam().ForEach(chara => - { - chara.curHp = chara.CalcAttributes()[AttributeType.MaxHp].val; - ScCharSyncStatus state = new ScCharSyncStatus() - { - Objid=chara.guid, - IsDead=chara.curHp < 1, - BattleInfo = new() - { - Hp=chara.curHp, - Ultimatesp=chara.ultimateSp - } - }; - target.Send(ScMsgId.ScCharSyncStatus, state); - }); + target.RestTeam(); + target.Send(ScMsgId.ScSceneRevival, new ScSceneRevival() { diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs index 8c2d01c..b9f82c0 100644 --- a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs @@ -80,7 +80,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.lastFormulaId = recipe; producer.progress += craftingRecipe.totalProgress/craftingRecipe.progressRound; - currentProgress++; + currentProgress++; if (currentProgress >= craftingRecipe.progressRound) { currentProgress = 0; diff --git a/Campofinale/Packets/Cs/HandleCsSceneRest.cs b/Campofinale/Packets/Cs/HandleCsSceneRest.cs new file mode 100644 index 0000000..ad7f36e --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSceneRest.cs @@ -0,0 +1,28 @@ +using Campofinale.Network; +using Campofinale.Packets.Sc; +using Campofinale.Protocol; +using Campofinale.Resource; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsSceneRest + { + + [Server.Handler(CsMsgId.CsSceneRest)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSceneRest req = packet.DecodeBody(); + + ScSceneRevival revival = new() + { + + }; + session.RestTeam(); + session.sceneManager.LoadCurrentTeamEntities(); + session.Send(ScMsgId.ScSceneRevival, revival, packet.csHead.UpSeqid); + session.Send(new PacketScSelfSceneInfo(session, SelfInfoReasonType.SlrReviveRest)); + + } + + } +} diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index ebce970..86db04e 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -759,5 +759,24 @@ namespace Campofinale } } + + public void RestTeam() + { + GetCurTeam().ForEach(chara => + { + chara.curHp = chara.CalcAttributes()[AttributeType.MaxHp].val; + ScCharSyncStatus state = new ScCharSyncStatus() + { + Objid = chara.guid, + IsDead = chara.curHp < 1, + BattleInfo = new() + { + Hp = chara.curHp, + Ultimatesp = chara.ultimateSp + } + }; + Send(ScMsgId.ScCharSyncStatus, state); + }); + } } } From 96048df57cb993ca9e5c582bcf50c45c3f268b51 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 23:05:37 +0200 Subject: [PATCH 08/14] CsSceneRest fix, teleport improvements, cache max item amount now is 50 --- .../Factory/Components/FComponentCache.cs | 4 +- Campofinale/Game/Factory/FactoryChapter.cs | 74 +++++++++++-- Campofinale/Game/Factory/FactoryManager.cs | 1 + Campofinale/Game/Factory/FactoryNode.cs | 15 ++- Campofinale/Game/SceneManager.cs | 14 ++- .../Packets/Cs/HandleCsCharPotentialUnlock.cs | 1 + .../Packets/Cs/HandleCsGachaTenPullReq.cs | 101 ------------------ .../Packets/Cs/HandleCsMoveObjectMove.cs | 1 + .../Packets/Cs/HandleCsSceneRepatriate.cs | 3 + Campofinale/Packets/Cs/HandleCsSceneRest.cs | 2 +- .../Packets/Cs/HandleCsSceneTeleport.cs | 8 +- .../Packets/Cs/HandleCsSceneTeleportFinish.cs | 19 ++++ .../Sc/PacketScFactoryModifyChapterNodes.cs | 4 +- .../Packets/Sc/PacketScFactoryOpRet.cs | 4 + 14 files changed, 126 insertions(+), 125 deletions(-) create mode 100644 Campofinale/Packets/Cs/HandleCsSceneTeleportFinish.cs diff --git a/Campofinale/Game/Factory/Components/FComponentCache.cs b/Campofinale/Game/Factory/Components/FComponentCache.cs index 3b347f1..e76407d 100644 --- a/Campofinale/Game/Factory/Components/FComponentCache.cs +++ b/Campofinale/Game/Factory/Components/FComponentCache.cs @@ -61,7 +61,7 @@ namespace Campofinale.Game.Factory.Components public bool IsFull() { - int maxItems = items.Count * 100; + int maxItems = items.Count * 50; int count = 0; foreach (var item in items) { @@ -75,7 +75,7 @@ namespace Campofinale.Game.Factory.Components int remaining = count; foreach (var item in items) { - int space = 100-item.count; + int space = 50-item.count; if (item.id==id) { if (space >= remaining) diff --git a/Campofinale/Game/Factory/FactoryChapter.cs b/Campofinale/Game/Factory/FactoryChapter.cs index e25563b..7ce8b26 100644 --- a/Campofinale/Game/Factory/FactoryChapter.cs +++ b/Campofinale/Game/Factory/FactoryChapter.cs @@ -24,7 +24,7 @@ namespace Campofinale.Game.Factory ScFactorySyncChapter chapter = new() { ChapterId = chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Blackboard = new() { Power = new() @@ -40,11 +40,12 @@ namespace Campofinale.Game.Factory { LastDay = new() { - + }, Other = new() { - InPowerBuilding = 1 + InPowerBuilding = nodes.FindAll(n=>n.lastPowered==true).Count, + } }, PinBoard = new() @@ -75,7 +76,7 @@ namespace Campofinale.Game.Factory Current = 0, Max = sceneGrade.bandwidth, TravelPoleMax = sceneGrade.travelPoleLimit, - + BattleCurrent = 0, BattleMax = sceneGrade.battleBuildingLimit, }, @@ -152,10 +153,12 @@ namespace Campofinale.Game.Factory maps.Add(new ScdFactorySyncMap() { MapId = ResourceManager.strIdNumTable.chapter_map_id.dic[mapId], + Wires = { GetWires() - } + }, + }); return maps; } @@ -181,7 +184,8 @@ namespace Campofinale.Game.Factory { Index = i, FromComId = compA, - ToComId = compB + ToComId = compB, + }); addedConnections.Add(key); @@ -243,6 +247,9 @@ namespace Campofinale.Game.Factory case FactoryOpType.MoveItemBagToCache: MoveItemBagToCache(op, seq); break; + case FactoryOpType.MoveItemCacheToBag: + MoveItemCacheToBag(op, seq); + break; case FactoryOpType.ChangeProducerMode: ChangeProducerMode(op, seq); break; @@ -255,6 +262,9 @@ namespace Campofinale.Game.Factory case FactoryOpType.DismantleBoxConveyor: DismantleBoxConveyor(op, seq); break; + case FactoryOpType.UseHealTowerPoint: + //TODO + break; case FactoryOpType.SetTravelPoleDefaultNext: FactoryNode travelNode = GetNodeByCompId(op.SetTravelPoleDefaultNext.ComponentId); travelNode.GetComponent().defaultNext = op.SetTravelPoleDefaultNext.DefaultNext; @@ -283,7 +293,7 @@ namespace Campofinale.Game.Factory ScFactoryOpRet ret = new() { RetCode = FactoryOpRetCode.Fail, - + }; GetOwner().Send(ScMsgId.ScFactoryOpRet, ret, seq); } @@ -315,6 +325,49 @@ namespace Campofinale.Game.Factory GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); } + public void MoveItemCacheToBag(CsFactoryOp op, ulong seq) + { + var move = op.MoveItemCacheToBag; + FComponentCache cacheComp = GetCompById(move.ComponentId); + if (cacheComp != null) + { + ItemCount cacheItem = cacheComp.items[move.CacheGridIndex]; + Item gridItem = null; + GetOwner().inventoryManager.items.bag.TryGetValue(move.GridIndex, out gridItem); + if (gridItem == null) + { + GetOwner().inventoryManager.items.bag.Add(move.GridIndex, new Item(ownerId,cacheItem.id,cacheItem.count)); + cacheItem.id = ""; + cacheItem.count = 0; + + } + else + { + if(gridItem.id == cacheItem.id) + { + int availableSpace = 50 - gridItem.amount; + if(cacheItem.count > availableSpace) + { + gridItem.amount += availableSpace; + cacheItem.count-= availableSpace; + } + else + { + gridItem.amount += cacheItem.count; + cacheItem.id = ""; + cacheItem.count = 0; + } + } + else + { + //TODO Swap + } + + } + } + GetOwner().inventoryManager.items.UpdateBagInventoryPacket(); + GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), 0, op), seq); + } public void MoveItemBagToCache(CsFactoryOp op, ulong seq) { var move = op.MoveItemBagToCache; @@ -327,7 +380,7 @@ namespace Campofinale.Game.Factory { if(cacheComp.items[move.CacheGridIndex].id == "" || cacheComp.items[move.CacheGridIndex].id == gridItem.id) { - int canAdd = 100 - cacheComp.items[move.CacheGridIndex].count; + int canAdd = 50 - cacheComp.items[move.CacheGridIndex].count; if (canAdd >= gridItem.amount) { @@ -385,7 +438,7 @@ namespace Campofinale.Game.Factory { ChapterId = chapterId, MapId = nodeRem.mapId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Wires = { GetWires() @@ -468,7 +521,7 @@ namespace Campofinale.Game.Factory { ChapterId = chapterId, MapId = GetNodeByCompId(nodeFrom.compId).mapId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Wires = { GetWires() @@ -552,7 +605,6 @@ namespace Campofinale.Game.Factory public void PlaceConveyor(CsFactoryOp op, ulong seq) { var placeConveyor = op.PlaceConveyor; - Logger.Print($"'PlaceConveyor': {JsonConvert.SerializeObject(placeConveyor)}"); v++; uint nodeId = v; List points = new(); diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index e902f83..5d6eb69 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -72,6 +72,7 @@ namespace Campofinale.Game.Factory public void SendFactoryHsSync() { if (!player.Initialized) return; + if (player.GetCurrentChapter() == "") return; long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); ScFactoryHsSync hs = new() diff --git a/Campofinale/Game/Factory/FactoryNode.cs b/Campofinale/Game/Factory/FactoryNode.cs index bd653fa..0b9c58e 100644 --- a/Campofinale/Game/Factory/FactoryNode.cs +++ b/Campofinale/Game/Factory/FactoryNode.cs @@ -78,6 +78,15 @@ namespace Campofinale.Game.Factory } } + public FactoryBuildingTable GetBuildingTable() + { + ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table); + if (table == null) + { + table = new FactoryBuildingTable(); + } + return table; + } public void UpdatePortManager(FactoryChapter chapter,FComponentPortManager manager) { if (ResourceManager.factoryBuildingTable.TryGetValue(templateId, out FactoryBuildingTable table)) @@ -213,7 +222,6 @@ namespace Campofinale.Game.Factory conveyorComp.items.Add(i); i.tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(); conveyorComp.lastPopTms = i.tms; - Logger.Print("Spawning item in conveyor: " + conveyorComp.lastPopTms); return true; } else @@ -250,7 +258,6 @@ namespace Campofinale.Game.Factory if (originalPorts == null || originalPorts.Count == 0) return transformedPorts; - // Ottieni la posizione e rotazione base dall'oggetto FMesh mesh = GetMesh(); if (mesh.points.Count < 2) return transformedPorts; @@ -258,7 +265,6 @@ namespace Campofinale.Game.Factory Vector3f objectPosition = mesh.points[0]; float objectRotationY = direction.y % 360f; - // Ottieni le dimensioni originali FactoryBuildingTable table; if (!ResourceManager.factoryBuildingTable.TryGetValue(templateId, out table)) return transformedPorts; @@ -300,7 +306,6 @@ namespace Campofinale.Game.Factory transformedPort.trans.position = transformedPos; - // Rotazione della porta transformedPort.trans.rotation = new Vector3f( originalPort.trans.rotation.x, (originalPort.trans.rotation.y + objectRotationY) % 360f, @@ -381,6 +386,8 @@ namespace Campofinale.Game.Factory { InPower = InPower(), NeedInPower = true, + PowerCost= GetBuildingTable().bandwidth, + PowerCostShow= GetBuildingTable().bandwidth, }, NodeType = (int)nodeType, diff --git a/Campofinale/Game/SceneManager.cs b/Campofinale/Game/SceneManager.cs index 799dc2a..b185c34 100644 --- a/Campofinale/Game/SceneManager.cs +++ b/Campofinale/Game/SceneManager.cs @@ -27,8 +27,18 @@ namespace Campofinale.Game } public void Update() { - if (GetCurScene()!=null) - GetCurScene().UpdateShowEntities(); + if (GetCurScene() != null) + { + try + { + GetCurScene().UpdateShowEntities(); + } + catch(Exception e) + { + + } + } + } public Entity GetEntity(ulong guid) { diff --git a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs index 6ca8531..121ea0e 100644 --- a/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs +++ b/Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs @@ -15,6 +15,7 @@ namespace Campofinale.Packets.Cs Character character = session.chars.Find(c => c.guid == req.CharObjId); if (character != null) { + character.potential=req.Level; //TODO consume Item ID diff --git a/Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs b/Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs index 407d1b5..41e7f26 100644 --- a/Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs +++ b/Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs @@ -19,107 +19,6 @@ namespace Campofinale.Packets.Cs CsGachaTenPullReq req = packet.DecodeBody(); session.gachaManager.upSeqId = packet.csHead.UpSeqid; session.gachaManager.DoGacha(req.GachaPoolId, 10); - /* Random rng = new Random(); - List chars = new List(); - const double prob6Star = 0.008; // 0.8% - const double prob5Star = 0.08; // 8% - const double fiftyfifty = 0.50; // 50% - GachaCharPoolTable table = ResourceManager.gachaCharPoolTable[req.GachaPoolId]; - GachaCharPoolContentTable content = ResourceManager.gachaCharPoolContentTable[req.GachaPoolId]; - int sixstarcount = 0; - int fivestarcount = 0; - List fiveStars = content.list.FindAll(c => c.starLevel == 5); - List sixStars = content.list.FindAll(c => c.starLevel == 6); - int fiveStarGuaranteedIndex = new Random().Next(9); - for (int i=0; i < 10; i++) - { - double roll = rng.NextDouble(); - double fifty = rng.NextDouble(); - - if (roll < prob6Star) - { - sixstarcount++; - - if (table.upCharIds.Count > 0) - { - if (fifty >= fiftyfifty) - { - chars.Add(ResourceManager.characterTable[table.upCharIds[0]].charId); - } - else - { - chars.Add(sixStars[new Random().Next(sixStars.Count - 1)].charId); - } - - } - else - { - chars.Add(sixStars[new Random().Next(sixStars.Count - 1)].charId); - } - } - else if (roll < prob6Star + prob5Star || fiveStarGuaranteedIndex == i) - { - fivestarcount++; - if(table.upCharIds.Count > 1) - { - if(fifty >= fiftyfifty) - { - chars.Add(ResourceManager.characterTable[table.upCharIds[1]].charId); - } - else - { - chars.Add(fiveStars[new Random().Next(fiveStars.Count - 1)].charId); - } - - } - else - { - chars.Add(fiveStars[new Random().Next(fiveStars.Count-1)].charId); - } - - } - else - { - chars.Add(ResourceManager.characterTable.Values.ToList().FindAll(c=>c.rarity == 4)[new Random().Next(ResourceManager.characterTable.Values.ToList().FindAll(c => c.rarity == 4).Count - 1)].charId); - } - - } - ScGachaSyncPullResult result = new ScGachaSyncPullResult() - { - GachaPoolId=req.GachaPoolId, - GachaType=req.GachaType, - - OriResultIds = - { - }, - Star5GotCount= fivestarcount, - Star6GotCount= sixstarcount, - FinalResults = - { - - }, - UpGotCount= fivestarcount+ sixstarcount, - - }; - foreach(string ch in chars) - { - bool exist = session.chars.Find(c => c.id == ch) != null; - result.OriResultIds.Add(ch); - result.FinalResults.Add(new ScdGachaFinalResult() - { - IsNew= !exist, - ItemId=ch, - - }); - } - - - //session.Send(Packet.EncodePacket((int)CsMessageId.CsGachaTenPullReq, req)); - - session.Send(ScMessageId.ScGachaSyncPullResult, result); */ - // session.Send(CsMessageId.CsGachaEnd, new Empty()); - // session.Send(ScMessageId.ScGachaBegin, new Empty()); - } } diff --git a/Campofinale/Packets/Cs/HandleCsMoveObjectMove.cs b/Campofinale/Packets/Cs/HandleCsMoveObjectMove.cs index dafe2a2..276a787 100644 --- a/Campofinale/Packets/Cs/HandleCsMoveObjectMove.cs +++ b/Campofinale/Packets/Cs/HandleCsMoveObjectMove.cs @@ -12,6 +12,7 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsMoveObjectMove req = packet.DecodeBody(); + if (session.sceneLoadState != Player.SceneLoadState.OK) return; foreach (var moveInfo in req.MoveInfo) { diff --git a/Campofinale/Packets/Cs/HandleCsSceneRepatriate.cs b/Campofinale/Packets/Cs/HandleCsSceneRepatriate.cs index 75b40ad..d6e2917 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneRepatriate.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneRepatriate.cs @@ -1,5 +1,7 @@ using Campofinale.Network; +using Campofinale.Packets.Sc; using Campofinale.Protocol; +using Campofinale.Resource; namespace Campofinale.Packets.Cs { @@ -30,6 +32,7 @@ namespace Campofinale.Packets.Cs } // Not correctly fixed, need to find the issue - SuikoAkari // No idea how pass_through_data is used, it's not part of the packet sent by the official server + session.Send(new PacketScSelfSceneInfo(session, SelfInfoReasonType.SlrReviveRest)); session.Send(ScMsgId.ScSceneRepatriate, new ScSceneRepatriate() { SceneNumId = session.savedSaveZone.sceneNumId, diff --git a/Campofinale/Packets/Cs/HandleCsSceneRest.cs b/Campofinale/Packets/Cs/HandleCsSceneRest.cs index ad7f36e..00649a8 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneRest.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneRest.cs @@ -12,7 +12,7 @@ namespace Campofinale.Packets.Cs public static void Handle(Player session, CsMsgId cmdId, Packet packet) { CsSceneRest req = packet.DecodeBody(); - + if (session.sceneLoadState == Player.SceneLoadState.Loading) return; ScSceneRevival revival = new() { diff --git a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs index b4c77b6..6a85ee1 100644 --- a/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs +++ b/Campofinale/Packets/Cs/HandleCsSceneTeleport.cs @@ -1,6 +1,7 @@ using Campofinale.Network; using Campofinale.Protocol; using Campofinale.Utils; +using static Campofinale.Resource.ResourceManager; namespace Campofinale.Packets.Cs { @@ -15,7 +16,7 @@ namespace Campofinale.Packets.Cs if (session.curSceneNumId != req.SceneNumId) { session.EnterScene(req.SceneNumId, new Resource.ResourceManager.Vector3f(req.Position), new Resource.ResourceManager.Vector3f(req.Rotation)); - /* ScSceneTeleport t = new() + ScSceneTeleport t = new() { TeleportReason = req.TeleportReason, PassThroughData = req.PassThroughData, @@ -23,7 +24,7 @@ namespace Campofinale.Packets.Cs Rotation = req.Rotation, SceneNumId = req.SceneNumId, }; - session.Send(ScMsgId.ScSceneTeleport, t);*/ + session.Send(ScMsgId.ScSceneTeleport, t); } else { @@ -41,6 +42,9 @@ namespace Campofinale.Packets.Cs TpUuid= (ulong)id }; session.curSceneNumId = t.SceneNumId; + session.position = new Vector3f(req.Position); + session.rotation = new Vector3f(req.Rotation); + session.sceneLoadState = Player.SceneLoadState.Loading; session.Send(ScMsgId.ScSceneTeleport, t); } diff --git a/Campofinale/Packets/Cs/HandleCsSceneTeleportFinish.cs b/Campofinale/Packets/Cs/HandleCsSceneTeleportFinish.cs new file mode 100644 index 0000000..110a647 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsSceneTeleportFinish.cs @@ -0,0 +1,19 @@ +using Campofinale.Network; +using Campofinale.Protocol; +using Campofinale.Utils; +using static Campofinale.Resource.ResourceManager; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsSceneTeleportFinish + { + + [Server.Handler(CsMsgId.CsSceneTeleportFinish)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsSceneTeleportFinish req = packet.DecodeBody(); + session.sceneLoadState=Player.SceneLoadState.OK; + } + + } +} diff --git a/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs b/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs index d34a9d9..85a3409 100644 --- a/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs +++ b/Campofinale/Packets/Sc/PacketScFactoryModifyChapterNodes.cs @@ -11,7 +11,7 @@ namespace Campofinale.Packets.Sc ScFactoryModifyChapterNodes edit = new() { ChapterId = chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds()/1000, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Nodes = { node.ToProto() @@ -24,7 +24,7 @@ namespace Campofinale.Packets.Sc ScFactoryModifyChapterNodes edit = new() { ChapterId = chapterId, - Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds() / 1000, + Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), RemoveNodes = { nodeId diff --git a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs index edec84a..d406b6f 100644 --- a/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs +++ b/Campofinale/Packets/Sc/PacketScFactoryOpRet.cs @@ -78,6 +78,10 @@ namespace Campofinale.Packets.Sc }; } + if(op.OpType == FactoryOpType.MoveItemCacheToBag) + { + proto.MoveItemCacheToBag = new(); + } proto.Index=op.Index; SetData(ScMsgId.ScFactoryOpRet, proto); } From f210746859e22b9b3dbb769d64048645b2338711 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sat, 9 Aug 2025 17:41:24 +0200 Subject: [PATCH 09/14] improvements --- Campofinale/Campofinale.csproj | 4 - .../NodeBuilding_Producer.cs | 15 +- .../NodeBuilding_ProducerFurnace.cs | 15 +- .../Components/FComponentBoxConveyor.cs | 3 +- Campofinale/Game/Factory/FComponent.cs | 3 + Campofinale/Game/Factory/FactoryChapter.cs | 65 +++-- Campofinale/Game/Factory/FactoryManager.cs | 22 +- Campofinale/Game/Factory/FactoryNode.cs | 15 +- Campofinale/Game/Inventory/Item.cs | 1 - .../Packets/Sc/PacketScFactoryHsSync.cs | 31 +++ Campofinale/Server.cs | 2 +- Dotfuscator1.xml | 229 ------------------ 12 files changed, 123 insertions(+), 282 deletions(-) create mode 100644 Campofinale/Packets/Sc/PacketScFactoryHsSync.cs delete mode 100644 Dotfuscator1.xml diff --git a/Campofinale/Campofinale.csproj b/Campofinale/Campofinale.csproj index 5cc10f4..113136d 100644 --- a/Campofinale/Campofinale.csproj +++ b/Campofinale/Campofinale.csproj @@ -21,15 +21,11 @@ - - - - diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs index f690108..333a907 100644 --- a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_Producer.cs @@ -18,7 +18,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour public uint inputCacheId = 0; public uint outputCacheId = 0; public uint producerId = 0; - public int currentProgress = 0; + public long timestampFinish = 0; public override void Init(FactoryChapter chapter, FactoryNode node) { FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); @@ -71,11 +71,14 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.inProduce = true; producer.lastFormulaId = recipe; - producer.progress += craftingRecipe.totalProgress/craftingRecipe.progressRound; - currentProgress++; - if (currentProgress >= craftingRecipe.progressRound) + if (timestampFinish == 0) { - currentProgress = 0; + timestampFinish = DateTime.UtcNow.ToUnixTimestampMilliseconds() + 1000 * craftingRecipe.progressRound; + } + producer.progress = (DateTime.UtcNow.ToUnixTimestampMilliseconds()/timestampFinish)* craftingRecipe.totalProgress; + if (DateTime.UtcNow.ToUnixTimestampMilliseconds() >= timestampFinish) + { + timestampFinish= DateTime.UtcNow.ToUnixTimestampMilliseconds()+1000* craftingRecipe.progressRound; List toConsume = craftingRecipe.GetIngredients(); inCache.ConsumeItems(toConsume); craftingRecipe.outcomes.ForEach(e => @@ -92,6 +95,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour { producer.inProduce = false; producer.progress = 0; + timestampFinish = 0; } } else @@ -99,6 +103,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.inBlock = false; producer.inProduce = false; producer.progress = 0; + timestampFinish = 0; } } diff --git a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs index b9f82c0..a9bf040 100644 --- a/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs +++ b/Campofinale/Game/Factory/BuildingsBehaviour/NodeBuilding_ProducerFurnace.cs @@ -20,7 +20,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour public uint inputCacheIdFluid = 0; public uint outputCacheIdFluid = 0; public uint producerId = 0; - public int currentProgress = 0; + public long timestampFinish = 0; public override void Init(FactoryChapter chapter, FactoryNode node) { FComponentCache cache1 = (FComponentCache)new FComponentCache(chapter.nextCompV(), FCComponentPos.CacheIn1).Init(); @@ -79,11 +79,14 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.inProduce = true; producer.lastFormulaId = recipe; - producer.progress += craftingRecipe.totalProgress/craftingRecipe.progressRound; - currentProgress++; - if (currentProgress >= craftingRecipe.progressRound) + if (timestampFinish == 0) { - currentProgress = 0; + timestampFinish = DateTime.UtcNow.ToUnixTimestampMilliseconds() + 1000 * craftingRecipe.progressRound; + } + producer.progress = (DateTime.UtcNow.ToUnixTimestampMilliseconds() / timestampFinish) * craftingRecipe.totalProgress; + if (DateTime.UtcNow.ToUnixTimestampMilliseconds() >= timestampFinish) + { + timestampFinish = DateTime.UtcNow.ToUnixTimestampMilliseconds() + 1000 * craftingRecipe.progressRound; List toConsume = craftingRecipe.GetIngredients(); inCache.ConsumeItems(toConsume); craftingRecipe.outcomes.ForEach(e => @@ -100,6 +103,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour { producer.inProduce = false; producer.progress = 0; + timestampFinish = 0; } } else @@ -107,6 +111,7 @@ namespace Campofinale.Game.Factory.BuildingsBehaviour producer.inBlock = false; producer.inProduce = false; producer.progress = 0; + timestampFinish = 0; } } diff --git a/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs index c204911..c63d964 100644 --- a/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs +++ b/Campofinale/Game/Factory/Components/FComponentBoxConveyor.cs @@ -13,7 +13,6 @@ namespace Campofinale.Game.Factory.Components lastPopTms=DateTime.UtcNow.ToUnixTimestampMilliseconds(); } - public override void SetComponentInfo(ScdFacCom proto) { if (items == null) @@ -26,8 +25,10 @@ namespace Campofinale.Game.Factory.Components LastPopTms = lastPopTms, }; + items.ForEach(item => { + if(item!=null) proto.BoxConveyor.Items.Add(item.ToFactoryItemProto()); }); diff --git a/Campofinale/Game/Factory/FComponent.cs b/Campofinale/Game/Factory/FComponent.cs index 4f5ffca..89058d3 100644 --- a/Campofinale/Game/Factory/FComponent.cs +++ b/Campofinale/Game/Factory/FComponent.cs @@ -1,6 +1,7 @@ using Campofinale.Game.Factory.Components; using Campofinale.Resource; using MongoDB.Bson.Serialization.Attributes; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; @@ -104,5 +105,7 @@ namespace Campofinale.Game.Factory } return this; } + + } } diff --git a/Campofinale/Game/Factory/FactoryChapter.cs b/Campofinale/Game/Factory/FactoryChapter.cs index 7ce8b26..7a461d3 100644 --- a/Campofinale/Game/Factory/FactoryChapter.cs +++ b/Campofinale/Game/Factory/FactoryChapter.cs @@ -18,24 +18,59 @@ namespace Campofinale.Game.Factory public uint v = 1; public uint compV = 0; public int bandwidth = 200; + public FactoryBlackboard blackboard = new(); + public class FactoryBlackboard + { + public uint inventoryNodeId=1; + public FacBbPower power = new(); + public class FacBbPower + { + public long powerGen; + public long powerSaveMax; + public long powerSaveCurrent; + public long powerCost; + public bool isStopByPower; + } + public ScdFactorySyncBlackboard ToProto() + { + return new ScdFactorySyncBlackboard() + { + InventoryNodeId = inventoryNodeId, + Power = new() + { + IsStopByPower=power.isStopByPower, + PowerCost=power.powerCost, + PowerGen=power.powerGen, + PowerSaveCurrent=power.powerSaveCurrent, + PowerSaveMax=power.powerSaveMax, + } + }; + } + + public ScdFactoryHsBb ToProtoHsBb() + { + return new ScdFactoryHsBb() + { + Power = new() + { + IsStopByPower = power.isStopByPower, + PowerSaveCurrent = power.powerSaveCurrent, + PowerSaveMax = power.powerSaveMax, + + }, + + }; + } + } public ScFactorySyncChapter ToProto() { + blackboard = new(); ScFactorySyncChapter chapter = new() { ChapterId = chapterId, Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), - Blackboard = new() - { - Power = new() - { - PowerGen = 0, - PowerSaveMax = 0, - PowerSaveCurrent = 0, - PowerCost = 0 - }, - InventoryNodeId = 1 - }, + Blackboard = new(), Statistic = new() { LastDay = new() @@ -57,15 +92,15 @@ namespace Campofinale.Game.Factory }, }; - chapter.Blackboard.Power.PowerSaveCurrent = bandwidth; + blackboard.power.powerSaveCurrent = bandwidth; domainDataTable[chapterId].levelGroup.ForEach(levelGroup => { int grade = GetOwner().sceneManager.GetScene(GetSceneNumIdFromLevelData(levelGroup)).grade; LevelGradeInfo sceneGrade = ResourceManager.levelGradeTable[levelGroup].grades.Find(g => g.grade == grade); if (sceneGrade != null) { - chapter.Blackboard.Power.PowerGen += sceneGrade.bandwidth; - chapter.Blackboard.Power.PowerSaveMax += sceneGrade.bandwidth; + blackboard.power.powerGen += sceneGrade.bandwidth; + blackboard.power.powerSaveMax += sceneGrade.bandwidth; var scene = new ScdFactorySyncScene() { @@ -141,7 +176,7 @@ namespace Campofinale.Game.Factory { } - + chapter.Blackboard = blackboard.ToProto(); chapter.Maps.AddRange(GetMaps()); return chapter; } diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index 5d6eb69..dbaa245 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -73,33 +73,19 @@ namespace Campofinale.Game.Factory { if (!player.Initialized) return; if (player.GetCurrentChapter() == "") return; - long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); - - ScFactoryHsSync hs = new() - { - Tms = curtimestamp, - CcList = - { - }, - Blackboard = GetChapter(player.GetCurrentChapter()).ToProto().Blackboard, - ChapterId = player.GetCurrentChapter(), - }; + List nodeUpdateList = new(); foreach (var node in GetChapter(player.GetCurrentChapter()).nodes) { if (node != null) { - if (node.position.DistanceXZ(player.position) < 150) + if (node.position.DistanceXZ(player.position) < 150 && node.nodeType != FCNodeType.BoxConveyor) { - node.components.ForEach(c => - { - hs.CcList.Add(c.ToProto()); - }); + nodeUpdateList.Add(node); } - } } - player.Send(ScMsgId.ScFactoryHsSync, hs); + player.Send(new PacketScFactoryHsSync(player,GetChapter(player.GetCurrentChapter()), nodeUpdateList)); } public void Update() { diff --git a/Campofinale/Game/Factory/FactoryNode.cs b/Campofinale/Game/Factory/FactoryNode.cs index 0b9c58e..d469806 100644 --- a/Campofinale/Game/Factory/FactoryNode.cs +++ b/Campofinale/Game/Factory/FactoryNode.cs @@ -11,6 +11,7 @@ using static Campofinale.Resource.ResourceManager.FactoryBuildingTable; using Newtonsoft.Json; using System.Drawing; using Campofinale.Game.Inventory; +using System.Numerics; namespace Campofinale.Game.Factory { @@ -135,7 +136,7 @@ namespace Campofinale.Game.Factory count = 1 }; - if (conveyorNode.AddConveyorItem(add)) + if (conveyorNode.AddConveyorItem(chapter,add)) { did = true; outputCache.ConsumeItems(new List() { add }); @@ -199,7 +200,7 @@ namespace Campofinale.Game.Factory } } if(toRemove!=null) - input.items.Remove(toRemove); + conveyorNode.RemoveConveyorItem(chapter,toRemove); } } @@ -208,7 +209,14 @@ namespace Campofinale.Game.Factory } - private bool AddConveyorItem(ItemCount i) + private void RemoveConveyorItem(FactoryChapter chapter,ItemCount toRemove) + { + FComponentBoxConveyor conveyorComp = GetComponent(); + conveyorComp.items.Remove(toRemove); + chapter.GetOwner().Send(new PacketScFactoryHsSync(chapter.GetOwner(), chapter, new List() { this})); + } + + private bool AddConveyorItem(FactoryChapter chapter,ItemCount i) { float length=BlockCalculator.CalculateTotalBlocks(points); FComponentBoxConveyor conveyorComp = GetComponent(); @@ -222,6 +230,7 @@ namespace Campofinale.Game.Factory conveyorComp.items.Add(i); i.tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(); conveyorComp.lastPopTms = i.tms; + chapter.GetOwner().Send(new PacketScFactoryHsSync(chapter.GetOwner(), chapter, new List() { this })); return true; } else diff --git a/Campofinale/Game/Inventory/Item.cs b/Campofinale/Game/Inventory/Item.cs index a35230a..a219079 100644 --- a/Campofinale/Game/Inventory/Item.cs +++ b/Campofinale/Game/Inventory/Item.cs @@ -11,7 +11,6 @@ using static Campofinale.Resource.ResourceManager; using Google.Protobuf.Collections; using Campofinale.Packets.Sc; using Campofinale.Protocol; -using CsvHelper.Configuration.Attributes; namespace Campofinale.Game.Inventory { diff --git a/Campofinale/Packets/Sc/PacketScFactoryHsSync.cs b/Campofinale/Packets/Sc/PacketScFactoryHsSync.cs new file mode 100644 index 0000000..3d4286d --- /dev/null +++ b/Campofinale/Packets/Sc/PacketScFactoryHsSync.cs @@ -0,0 +1,31 @@ +using Campofinale.Game.Factory; +using Campofinale.Network; +using Campofinale.Protocol; +using System.Numerics; + +namespace Campofinale.Packets.Sc +{ + public class PacketScFactoryHsSync : Packet + { + + public PacketScFactoryHsSync(Player client, FactoryChapter chapter, List nodes) { + + long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds(); + ScFactoryHsSync hs = new() + { + Tms = curtimestamp, + Blackboard = chapter.blackboard.ToProto(), + ChapterId = chapter.chapterId, + }; + nodes.ForEach(node => + { + node.components.ForEach(c => + { + hs.CcList.Add(c.ToProto()); + }); + }); + SetData(ScMsgId.ScFactoryHsSync, hs); + } + + } +} diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 06b5c39..b5ea2ba 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -152,7 +152,7 @@ namespace Campofinale try { clients.ForEach(client => { if (client != null) client.Update(); }); - Thread.Sleep(1000); + Thread.Sleep(250); } catch (Exception ex) { diff --git a/Dotfuscator1.xml b/Dotfuscator1.xml deleted file mode 100644 index 44bfed3..0000000 --- a/Dotfuscator1.xml +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 460bfe527c5baae9f933789b3f994828652da010 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Sat, 9 Aug 2025 19:00:11 +0200 Subject: [PATCH 10/14] cleaning code --- Campofinale/Game/Factory/BlockCalculator.cs | 7 ++---- Campofinale/Game/Factory/FactoryManager.cs | 3 +-- Campofinale/Game/Inventory/Item.cs | 10 ++++++-- Campofinale/Player.cs | 28 --------------------- Campofinale/Server.cs | 2 +- 5 files changed, 12 insertions(+), 38 deletions(-) diff --git a/Campofinale/Game/Factory/BlockCalculator.cs b/Campofinale/Game/Factory/BlockCalculator.cs index a77b7f3..ba4b72b 100644 --- a/Campofinale/Game/Factory/BlockCalculator.cs +++ b/Campofinale/Game/Factory/BlockCalculator.cs @@ -9,7 +9,7 @@ namespace Campofinale.Game.Factory { public class BlockCalculator { - public static float CalculateTotalBlocks(List points) + public static int CalculateTotalBlocks(List points) { if (points == null || points.Count < 2) return 0; @@ -36,7 +36,6 @@ namespace Campofinale.Game.Factory int y1 = (int)Math.Floor(p2.y); int z1 = (int)Math.Floor(p2.z); - // Algoritmo di Bresenham 3D int dx = Math.Abs(x1 - x0); int dy = Math.Abs(y1 - y0); int dz = Math.Abs(z1 - z0); @@ -44,7 +43,6 @@ namespace Campofinale.Game.Factory int sy = y0 < y1 ? 1 : -1; int sz = z0 < z1 ? 1 : -1; - // Decision variables if (dx >= dy && dx >= dz) { int err1 = 2 * dy - dx; @@ -89,7 +87,7 @@ namespace Campofinale.Game.Factory y0 += sy; } } - else // dz è la dimensione dominante + else { int err1 = 2 * dy - dz; int err2 = 2 * dx - dz; @@ -112,7 +110,6 @@ namespace Campofinale.Game.Factory } } - // Aggiungi l'ultimo punto blocks.Add(Tuple.Create(x1, y1, z1)); } } diff --git a/Campofinale/Game/Factory/FactoryManager.cs b/Campofinale/Game/Factory/FactoryManager.cs index dbaa245..81f4e51 100644 --- a/Campofinale/Game/Factory/FactoryManager.cs +++ b/Campofinale/Game/Factory/FactoryManager.cs @@ -76,10 +76,9 @@ namespace Campofinale.Game.Factory List nodeUpdateList = new(); foreach (var node in GetChapter(player.GetCurrentChapter()).nodes) { - if (node != null) { - if (node.position.DistanceXZ(player.position) < 150 && node.nodeType != FCNodeType.BoxConveyor) + if (node.position.DistanceXZ(player.position) < 150 && node.nodeBehaviour!=null) { nodeUpdateList.Add(node); } diff --git a/Campofinale/Game/Inventory/Item.cs b/Campofinale/Game/Inventory/Item.cs index a219079..13afaa9 100644 --- a/Campofinale/Game/Inventory/Item.cs +++ b/Campofinale/Game/Inventory/Item.cs @@ -140,14 +140,15 @@ namespace Campofinale.Game.Inventory Inst = new() { InstId = guid, - + Equip = new() { - + EquipCharId = GetOwner().chars.Find(c => c.IsEquipped(guid)) != null ? GetOwner().chars.Find(c => c.IsEquipped(guid)).guid : 0, Equipid = guid, Templateid = ResourceManager.GetItemTemplateId(id), + }, IsLock = locked } @@ -240,6 +241,7 @@ namespace Campofinale.Game.Inventory }; GetOwner().Send(ScMsgId.ScWeaponAddExp, levelUp); + GetOwner().Send(new PacketScSyncWallet(GetOwner())); } } @@ -257,6 +259,10 @@ namespace Campofinale.Game.Inventory return false; case ItemValuableDepotType.MissionItem: return true; + case ItemValuableDepotType.Factory: + return false; + case ItemValuableDepotType.CommercialItem: + return false; default: return false; } diff --git a/Campofinale/Player.cs b/Campofinale/Player.cs index 86db04e..e85cf9b 100644 --- a/Campofinale/Player.cs +++ b/Campofinale/Player.cs @@ -312,24 +312,6 @@ namespace Campofinale teams.Add(new Team()); teams.Add(new Team()); bitsetManager.Load(new Dictionary>()); - /*mails.Add(new Mail() - { - expireTime=DateTime.UtcNow.AddDays(30).Ticks, - sendTime=DateTime.UtcNow.Ticks, - claimed=false, - guid=random.Next(), - owner=roleId, - isRead=false, - content=new Mail_Content() - { - content= "Welcome to Campofinale, Join our Discord for help: https://discord.gg/5uJGJJEFHa", - senderName="SuikoAkari", - title="Welcome", - templateId="", - } - - });*/ - spaceshipManager.Load(); } @@ -348,8 +330,6 @@ namespace Campofinale } else { - //sceneManager.UnloadCurrent(false); - //sceneManager.LoadCurrent(); sceneLoadState = SceneLoadState.Loading; Send(new PacketScEnterSceneNotify(this, curSceneNumId)); } @@ -370,7 +350,6 @@ namespace Campofinale } public SceneLoadState sceneLoadState=0; - // public bool LoadFinish = true; public void EnterScene(int sceneNumId, Vector3f pos, Vector3f rot, PassThroughData passThroughData = null) { // if (!LoadFinish) return; @@ -573,15 +552,10 @@ namespace Campofinale { } - - - - Disconnect(); } public void Kick(CODE code, string optionalMsg="") { - Send(ScMsgId.ScNtfErrorCode, new ScNtfErrorCode() { Details = optionalMsg, @@ -606,8 +580,6 @@ namespace Campofinale Logger.Print($"{nickname} Disconnected"); socket.Disconnect(false); } - - } public void Save() { diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index b5ea2ba..e707f8c 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -67,7 +67,7 @@ namespace Campofinale public static Dispatch? dispatch; public static ConfigFile? config; public static List csMessageToHide = new() { CsMsgId.CsMoveObjectMove, CsMsgId.CsBattleOp,CsMsgId.CsPing }; - public static List scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing,ScMsgId.ScObjectEnterView }; + public static List scMessageToHide = new() { ScMsgId.ScMoveObjectMove, ScMsgId.ScPing,ScMsgId.ScObjectEnterView,ScMsgId.ScFactoryHsSync }; public void Start(ConfigFile config) { { From 69d832d376b9683ba66997f09da929e0ab35ce93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=E7=B4=85=20=E7=81=AF?= Date: Wed, 20 Aug 2025 22:39:06 +0200 Subject: [PATCH 11/14] item bag set item lock --- .../Packets/Cs/HandleCsItemBagSetItemLock.cs | 34 +++++++++++++++++++ Campofinale/Program.cs | 7 ++-- 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 Campofinale/Packets/Cs/HandleCsItemBagSetItemLock.cs diff --git a/Campofinale/Packets/Cs/HandleCsItemBagSetItemLock.cs b/Campofinale/Packets/Cs/HandleCsItemBagSetItemLock.cs new file mode 100644 index 0000000..8c33136 --- /dev/null +++ b/Campofinale/Packets/Cs/HandleCsItemBagSetItemLock.cs @@ -0,0 +1,34 @@ +using Campofinale.Game.Char; +using Campofinale.Game.Inventory; +using Campofinale.Network; +using Campofinale.Protocol; + +namespace Campofinale.Packets.Cs +{ + public class HandleCsItemBagSetItemLock + { + [Server.Handler(CsMsgId.CsItemBagSetItemLock)] + public static void Handle(Player session, CsMsgId cmdId, Packet packet) + { + CsItemBagSetItemLock req = packet.DecodeBody(); + + foreach (var info in req.LockInfoList) + { + Item item = session.inventoryManager.items.items.Find(i=>i.guid==info.InstId); + if (item != null) + { + item.locked = info.IsLock; + } + } + ScItemBagSetItemLock rsp = new() + { + LockInfoList = + { + req.LockInfoList, + } + }; + session.Send(ScMsgId.ScItemBagSetItemLock, rsp); + } + + } +} diff --git a/Campofinale/Program.cs b/Campofinale/Program.cs index 78e50ad..00b5597 100644 --- a/Campofinale/Program.cs +++ b/Campofinale/Program.cs @@ -13,7 +13,7 @@ class Program static void Main(string[] args) { StartServer(args); - //FakeClientTester(); + //FakeClientTester(); } public static byte[] ConcatenateByteArrays(byte[] array1, byte[] array2) { @@ -22,7 +22,7 @@ class Program private static void FakeClientTester() { // - string serverIp = "beyond-cn.hypergryph.com"; + string serverIp = "beyond-ric.gryphline.com"; int serverPort = 30000; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); @@ -32,7 +32,8 @@ class Program socket.Connect(new IPEndPoint(ipAddress, serverPort)); - socket.Send(Packet.EncodePacket((int)CsMsgId.CsLogin,new CsLogin() { ClientVersion="0.5.5",Uid= "", Token= "", Env=EnvType.Prod,PlatformId=ClientPlatformType.Windows,Area=AreaType.Oversea,ClientResVersion="", LoginToken= "" }.ToByteArray())); + socket.Send(Packet.EncodePacket((int)CsMsgId.CsLogin,new CsLogin() { ClientVersion="0.5.5",Uid= "", Token= "", Env=EnvType.Prod,PlatformId=ClientPlatformType.Windows,Area=AreaType.Oversea,ClientResVersion="", LoginToken= "" }.ToByteArray())); + //socket.Send(Packet.EncodePacket((int)CsMsgId.CsFriendListSync, new CsFriendListSync() { }.ToByteArray())); while (true) { byte[] buffer = new byte[3]; From b125394b79e8968269a9db5c6e9fdc1be7f559b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=E7=B4=85=20=E7=81=AF?= Date: Wed, 20 Aug 2025 23:28:08 +0200 Subject: [PATCH 12/14] 1.1.7 ready --- Campofinale/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index e707f8c..2963a4b 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -59,7 +59,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.7-dev"; + public static string ServerVersion = "1.1.7"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true; From c2ba13b5f767673acd0d2716ca3a7923600d6f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=E7=B4=85=20=E7=81=AF?= Date: Wed, 20 Aug 2025 23:29:37 +0200 Subject: [PATCH 13/14] 1.1.8-dev start --- Campofinale/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 2963a4b..717e9fe 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -59,7 +59,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.7"; + public static string ServerVersion = "1.1.8-dev"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true; From 68f93eb80d66e7734c3e32b9590421102cad83d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BF=A0=E7=B4=85=20=E7=81=AF?= Date: Wed, 20 Aug 2025 23:30:18 +0200 Subject: [PATCH 14/14] revert --- Campofinale/Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Campofinale/Server.cs b/Campofinale/Server.cs index 717e9fe..2963a4b 100644 --- a/Campofinale/Server.cs +++ b/Campofinale/Server.cs @@ -59,7 +59,7 @@ namespace Campofinale public delegate void HandlerDelegate(Player sender, string command, string[] args, Player target); } public static List clients = new List(); - public static string ServerVersion = "1.1.8-dev"; + public static string ServerVersion = "1.1.7"; public static bool Initialized = false; public static bool showLogs = true; public static bool showWarningLogs = true;