From 4abb9d0bb5cf097c846df02565b30776e6fd3b61 Mon Sep 17 00:00:00 2001 From: AlessandroCH Date: Fri, 8 Aug 2025 18:00:09 +0200 Subject: [PATCH] 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();