From 0e16292c38d88bc10223f8b99ab52e67d3710f5d Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sun, 5 Nov 2023 19:13:20 +0800 Subject: [PATCH 1/7] perf: :zap: apply Atomic --- logic/GameClass/GameObj/Areas/Construction.cs | 10 ++++- logic/GameClass/GameObj/Areas/Resource.cs | 42 ++----------------- logic/GameClass/GameObj/Areas/Wormhole.cs | 5 +-- logic/GameClass/GameObj/Team.cs | 22 ++++------ logic/Preparation/Interface/IWormhole.cs | 3 +- 5 files changed, 23 insertions(+), 59 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs index b49697da..04e1d96c 100644 --- a/logic/GameClass/GameObj/Areas/Construction.cs +++ b/logic/GameClass/GameObj/Areas/Construction.cs @@ -5,11 +5,19 @@ namespace GameClass.GameObj.Areas; public class Construction : Immovable { - public LongInTheVariableRange HP => throw new NotImplementedException(); + public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(0); public override bool IsRigid => constructionType == ConstructionType.Community; public override ShapeType Shape => ShapeType.Square; private ConstructionType constructionType = ConstructionType.Null; public ConstructionType ConstructionType => constructionType; + public AtomicInt ConstructNum { get; } = new AtomicInt(0); + public bool Construct(int constructSpeed, ConstructionType constructionType, Ship ship) + { + if (this.constructionType != ConstructionType.Null && this.HP > 0) + return false; + this.constructionType = constructionType; + return HP.AddV(constructSpeed) > 0; + } public Construction(XY initPos) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Construction) { diff --git a/logic/GameClass/GameObj/Areas/Resource.cs b/logic/GameClass/GameObj/Areas/Resource.cs index 07c7c96a..2953439a 100644 --- a/logic/GameClass/GameObj/Areas/Resource.cs +++ b/logic/GameClass/GameObj/Areas/Resource.cs @@ -6,48 +6,14 @@ namespace GameClass.GameObj.Areas; public class Resource : Immovable { - public LongInTheVariableRange HP => throw new NotImplementedException(); + public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(GameData.ResourceHP); public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Square; - private int producingNum = 0; - public int ProducingNum - { - get => Interlocked.CompareExchange(ref producingNum, 0, 0); - } - public void AddProducingNum() - { - Interlocked.Increment(ref producingNum); - } - public void SubProducingNum() - { - Interlocked.Decrement(ref producingNum); - } + public AtomicInt ProduceNum { get; } = new AtomicInt(0); public bool Produce(int produceSpeed, Ship ship) { - long orgHP, value; - lock (gameObjLock) - { - if (HP == 0) - { - return false; - } - orgHP = HP.GetValue(); - HP.SubV(produceSpeed); - if (HP > HP.GetMaxV()) - { - HP.SetV(HP.GetMaxV()); - } - else if (HP < 0) - { - HP.SetV(0); - } - value = HP.GetValue(); - } - if (value < orgHP) - { - if (value == 0) return true; - } - return false; + // TODO: Add Money + return HP.SubV(produceSpeed) > 0; } public Resource(XY initPos) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Resource) diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs index 83ddda46..3606d39f 100644 --- a/logic/GameClass/GameObj/Areas/Wormhole.cs +++ b/logic/GameClass/GameObj/Areas/Wormhole.cs @@ -7,9 +7,8 @@ namespace GameClass.GameObj.Areas; public class Wormhole : Immovable, IWormhole { - public LongInTheVariableRange HP => throw new NotImplementedException(); - public List Entrance => throw new NotImplementedException(); - public List Content => throw new NotImplementedException(); + public LongInTheVariableRange HP = new LongInTheVariableRange(GameData.WormholeHP); + public List Grids => throw new NotImplementedException(); public override bool IsRigid => HP > GameData.WormholeHP / 2; public override ShapeType Shape => ShapeType.Square; public Wormhole(XY initPos) diff --git a/logic/GameClass/GameObj/Team.cs b/logic/GameClass/GameObj/Team.cs index b08385e0..f6e5f59c 100644 --- a/logic/GameClass/GameObj/Team.cs +++ b/logic/GameClass/GameObj/Team.cs @@ -17,16 +17,8 @@ public class Team private readonly Dictionary birthPointList; public Dictionary BirthPointList => birthPointList; private Home home; - private long score = 0; - public long Score - { - get => Interlocked.Read(ref score); - } - private long totalScore; - public long TotalScore - { - get => Interlocked.Read(ref totalScore); - } + public AtomicLong Money { get; } = new AtomicLong(0); + public AtomicLong Score { get; } = new AtomicLong(0); public Ship? GetShip(long shipID) { foreach (Ship ship in shipList) @@ -58,14 +50,14 @@ public bool AddShip(Ship ship) shipList.Add(ship); return true; } - public void AddScore(long add) + public void AddMoney(long add) { - Interlocked.Add(ref score, add); - Interlocked.Add(ref totalScore, add); + Money.Add(add); + Score.Add(add); } - public void SubScore(long sub) + public void SubMoney(long sub) { - Interlocked.Add(ref score, -sub); + Money.Sub(sub); } public void SetHome(Home home) { diff --git a/logic/Preparation/Interface/IWormhole.cs b/logic/Preparation/Interface/IWormhole.cs index e46d6dbf..b5ce16cc 100644 --- a/logic/Preparation/Interface/IWormhole.cs +++ b/logic/Preparation/Interface/IWormhole.cs @@ -5,7 +5,6 @@ namespace Preparation.Interface { public interface IWormhole : IGameObj { - public List Entrance { get; } - public List Content { get; } + public List Grids { get; } } } From bf7c6e40eb8aad36fadcdeb8ae29074148abf983 Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sat, 18 Nov 2023 19:47:49 +0800 Subject: [PATCH 2/7] feat: :sparkles: specify some areas use Atomic --- logic/GameClass/GameObj/Areas/Construction.cs | 27 +++++++++++++++++-- logic/GameClass/GameObj/Areas/Home.cs | 12 +++++---- logic/GameClass/GameObj/Areas/Wormhole.cs | 2 +- logic/Preparation/Interface/IHome.cs | 4 +-- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs index 04e1d96c..d80a4315 100644 --- a/logic/GameClass/GameObj/Areas/Construction.cs +++ b/logic/GameClass/GameObj/Areas/Construction.cs @@ -13,9 +13,32 @@ public class Construction : Immovable public AtomicInt ConstructNum { get; } = new AtomicInt(0); public bool Construct(int constructSpeed, ConstructionType constructionType, Ship ship) { - if (this.constructionType != ConstructionType.Null && this.HP > 0) + if (constructionType == ConstructionType.Null) + { return false; - this.constructionType = constructionType; + } + if (this.constructionType != ConstructionType.Null && this.constructionType != constructionType && this.HP > 0) + { + return false; + } + if (this.constructionType == ConstructionType.Null || this.HP == 0) + { + this.constructionType = constructionType; + switch (constructionType) + { + case ConstructionType.Community: + HP.SetMaxV(GameData.CommunityHP); + break; + case ConstructionType.Factory: + HP.SetMaxV(GameData.FactoryHP); + break; + case ConstructionType.Fort: + HP.SetMaxV(GameData.FortHP); + break; + default: + break; + } + } return HP.AddV(constructSpeed) > 0; } public Construction(XY initPos) diff --git a/logic/GameClass/GameObj/Areas/Home.cs b/logic/GameClass/GameObj/Areas/Home.cs index 369477bc..584b030b 100644 --- a/logic/GameClass/GameObj/Areas/Home.cs +++ b/logic/GameClass/GameObj/Areas/Home.cs @@ -6,17 +6,19 @@ namespace GameClass.GameObj.Areas; public class Home : Immovable, IHome { - public AtomicLong TeamID => throw new NotImplementedException(); - public LongInTheVariableRange HP => throw new NotImplementedException(); - public long Score => throw new NotImplementedException(); + private long teamID; + public long TeamID => teamID; + public LongInTheVariableRange HP => new LongInTheVariableRange(GameData.HomeHP); + public AtomicLong Score => new AtomicLong(0); public override bool IsRigid => false; public override ShapeType Shape => ShapeType.Square; public void AddScore(long add) { - throw new NotImplementedException(); + Score.Add(add); } - public Home(XY initPos) + public Home(XY initPos, long teamID) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Home) { + this.teamID = teamID; } } diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs index 3606d39f..f2ea8f2f 100644 --- a/logic/GameClass/GameObj/Areas/Wormhole.cs +++ b/logic/GameClass/GameObj/Areas/Wormhole.cs @@ -8,7 +8,7 @@ namespace GameClass.GameObj.Areas; public class Wormhole : Immovable, IWormhole { public LongInTheVariableRange HP = new LongInTheVariableRange(GameData.WormholeHP); - public List Grids => throw new NotImplementedException(); + public List Grids => null; public override bool IsRigid => HP > GameData.WormholeHP / 2; public override ShapeType Shape => ShapeType.Square; public Wormhole(XY initPos) diff --git a/logic/Preparation/Interface/IHome.cs b/logic/Preparation/Interface/IHome.cs index 02857a37..bd5f93c9 100644 --- a/logic/Preparation/Interface/IHome.cs +++ b/logic/Preparation/Interface/IHome.cs @@ -4,9 +4,9 @@ namespace Preparation.Interface { public interface IHome { - public AtomicLong TeamID { get; } + public long TeamID { get; } public LongInTheVariableRange HP { get; } - public long Score { get; } + public AtomicLong Score { get; } public void AddScore(long add); } } From 194d1a156103e89118679496a09a3e07fbb6e0f4 Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sat, 18 Nov 2023 20:05:57 +0800 Subject: [PATCH 3/7] fix: :bug: fix teamID of Home --- logic/GameClass/GameObj/Areas/AreaFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/GameClass/GameObj/Areas/AreaFactory.cs b/logic/GameClass/GameObj/Areas/AreaFactory.cs index 3e6fc797..61c8a641 100644 --- a/logic/GameClass/GameObj/Areas/AreaFactory.cs +++ b/logic/GameClass/GameObj/Areas/AreaFactory.cs @@ -6,7 +6,7 @@ public static class AreaFactory { public static Immovable GetArea(XY pos, PlaceType placeType) => placeType switch { - PlaceType.Home => new Home(pos), + PlaceType.Home => new Home(pos, pos.y > GameData.MapRows / 2 ? 1 : 0), PlaceType.Ruin => new Ruin(pos), PlaceType.Shadow => new Shadow(pos), PlaceType.Asteroid => new Asteroid(pos), From e229b8a17f9cf420efda1e6bd8f8f2cc9d3a946d Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sat, 18 Nov 2023 20:41:27 +0800 Subject: [PATCH 4/7] fix: :bug: fix producenum of resource --- logic/GameClass/GameObj/Areas/Construction.cs | 8 ++++++++ logic/GameClass/GameObj/Areas/Resource.cs | 8 ++++++++ logic/Gaming/ActionManager.cs | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs index d80a4315..e8461998 100644 --- a/logic/GameClass/GameObj/Areas/Construction.cs +++ b/logic/GameClass/GameObj/Areas/Construction.cs @@ -41,6 +41,14 @@ public bool Construct(int constructSpeed, ConstructionType constructionType, Shi } return HP.AddV(constructSpeed) > 0; } + public void AddConstructNum(int add = 1) + { + ConstructNum.Add(add); + } + public void SubConstructNum(int sub = 1) + { + ConstructNum.Sub(sub); + } public Construction(XY initPos) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Construction) { diff --git a/logic/GameClass/GameObj/Areas/Resource.cs b/logic/GameClass/GameObj/Areas/Resource.cs index 2953439a..d0875586 100644 --- a/logic/GameClass/GameObj/Areas/Resource.cs +++ b/logic/GameClass/GameObj/Areas/Resource.cs @@ -15,6 +15,14 @@ public bool Produce(int produceSpeed, Ship ship) // TODO: Add Money return HP.SubV(produceSpeed) > 0; } + public void AddProduceNum(int add = 1) + { + ProduceNum.Add(add); + } + public void SubProduceNum(int sub = 1) + { + ProduceNum.Sub(sub); + } public Resource(XY initPos) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Resource) { diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 394b46cd..1080b265 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -114,7 +114,7 @@ public bool Produce(Ship ship) ship.ThreadNum.Release(); return; } - resource.AddProducingNum(); + resource.AddProduceNum(); Thread.Sleep(GameData.CheckInterval); new FrameRateTaskExecutor ( @@ -132,7 +132,7 @@ public bool Produce(Ship ship) finallyReturn: () => 0 ).Start(); ship.ThreadNum.Release(); - resource.SubProducingNum(); + resource.SubProduceNum(); } ) { IsBackground = true }.Start(); From ea8ceea358d749f7cf3db75ac08603a374b470cf Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sat, 18 Nov 2023 22:23:02 +0800 Subject: [PATCH 5/7] feat: :sparkles: no longer use AreaFactory remove the use of AreaFactory since it does not fit Home & Wormhole --- logic/GameClass/GameObj/Areas/AreaFactory.cs | 4 +- logic/GameClass/GameObj/Areas/Wormhole.cs | 6 ++- logic/GameClass/GameObj/Map/Map.cs | 49 +++++++++++++++++++- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/AreaFactory.cs b/logic/GameClass/GameObj/Areas/AreaFactory.cs index 61c8a641..49e93de3 100644 --- a/logic/GameClass/GameObj/Areas/AreaFactory.cs +++ b/logic/GameClass/GameObj/Areas/AreaFactory.cs @@ -6,13 +6,13 @@ public static class AreaFactory { public static Immovable GetArea(XY pos, PlaceType placeType) => placeType switch { - PlaceType.Home => new Home(pos, pos.y > GameData.MapRows / 2 ? 1 : 0), + //PlaceType.Home => new Home(pos), PlaceType.Ruin => new Ruin(pos), PlaceType.Shadow => new Shadow(pos), PlaceType.Asteroid => new Asteroid(pos), PlaceType.Resource => new Resource(pos), PlaceType.Construction => new Construction(pos), - PlaceType.Wormhole => new Wormhole(pos), + //PlaceType.Wormhole => new Wormhole(pos), _ => new NullArea(pos) }; public static OutOfBoundBlock GetOutOfBoundBlock(XY pos) => new(pos); diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs index f2ea8f2f..76665c9a 100644 --- a/logic/GameClass/GameObj/Areas/Wormhole.cs +++ b/logic/GameClass/GameObj/Areas/Wormhole.cs @@ -8,11 +8,13 @@ namespace GameClass.GameObj.Areas; public class Wormhole : Immovable, IWormhole { public LongInTheVariableRange HP = new LongInTheVariableRange(GameData.WormholeHP); - public List Grids => null; + private List grids = new(); + public List Grids => grids; public override bool IsRigid => HP > GameData.WormholeHP / 2; public override ShapeType Shape => ShapeType.Square; - public Wormhole(XY initPos) + public Wormhole(XY initPos, List grids) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Wormhole) { + this.grids = grids; } } \ No newline at end of file diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index 5a09727d..ff2507ec 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -3,6 +3,8 @@ using Preparation.Interface; using Preparation.Utility; using System; +using GameClass.GameObj.Areas; +using System.Linq; namespace GameClass.GameObj { @@ -286,11 +288,56 @@ public Map(uint[,] mapResource) } protoGameMap = new uint[mapResource.GetLength(0), mapResource.GetLength(1)]; Array.Copy(mapResource, protoGameMap, mapResource.Length); + long teamID = 0; for (int i = 0; i < GameData.MapRows; ++i) { for (int j = 0; j < GameData.MapCols; ++j) { - Add(Areas.AreaFactory.GetArea(GameData.GetCellCenterPos(i, j), (PlaceType)mapResource[i, j])); + bool hasWormhole = false; + switch (mapResource[i, j]) + { + case (uint)PlaceType.Resource: + Add(new Resource(GameData.GetCellCenterPos(i, j))); + break; + case (uint)PlaceType.Construction: + Add(new Construction(GameData.GetCellCenterPos(i, j))); + break; + case (uint)PlaceType.Wormhole: + foreach (Wormhole wormhole in GameObjDict[GameObjType.Wormhole].Cast()) + { + if (wormhole.Grids.Contains(new XY(i, j))) + { + hasWormhole = true; + break; + } + else + { + foreach (XY xy in wormhole.Grids) + { + if (Math.Abs(xy.x - i) <= 1 && Math.Abs(xy.y - j) <= 1) + { + wormhole.Grids.Add(new XY(i, j)); + hasWormhole = true; + break; + } + } + if (hasWormhole) + { + break; + } + } + } + if (!hasWormhole) + { + List grids = new(); + grids.Add(new XY(i, j)); + Add(new Wormhole(GameData.GetCellCenterPos(i, j), grids)); + } + break; + case (uint)PlaceType.Home: + Add(new Home(GameData.GetCellCenterPos(i, j), teamID++)); + break; + } } } } From def9fa429d875c372b361cfdb9acd175f472f618 Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sun, 19 Nov 2023 00:11:16 +0800 Subject: [PATCH 6/7] feat: :sparkles: add construct --- logic/GameClass/GameObj/Areas/Construction.cs | 2 +- logic/Gaming/ActionManager.cs | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs index e8461998..39070846 100644 --- a/logic/GameClass/GameObj/Areas/Construction.cs +++ b/logic/GameClass/GameObj/Areas/Construction.cs @@ -5,7 +5,7 @@ namespace GameClass.GameObj.Areas; public class Construction : Immovable { - public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(0); + public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(0, GameData.CommunityHP); public override bool IsRigid => constructionType == ConstructionType.Community; public override ShapeType Shape => ShapeType.Square; private ConstructionType constructionType = ConstructionType.Null; diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 1080b265..9604a37a 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -140,9 +140,54 @@ public bool Produce(Ship ship) } public bool Construct(Ship ship) { + Construction? construction = (Construction?)gameMap.OneForInteract(ship.Position, GameObjType.Construction); + if (construction == null) + { + return false; + } + if (construction.HP == construction.HP.GetMaxV()) + { + return false; + } + long stateNum = ship.SetShipState(RunningStateType.Waiting, ShipStateType.Constructing); + if (stateNum == -1) + { + return false; + } + new Thread + ( + () => + { + ship.ThreadNum.WaitOne(); + if (!ship.StartThread(stateNum, RunningStateType.RunningActively)) + { + ship.ThreadNum.Release(); + return; + } + construction.AddConstructNum(); + Thread.Sleep(GameData.CheckInterval); + new FrameRateTaskExecutor + ( + loopCondition: () => stateNum == ship.StateNum && gameMap.Timer.IsGaming, + loopToDo: () => + { + if (construction.HP == construction.HP.GetMaxV()) + { + ship.ResetShipState(stateNum); + return false; + } + return true; + }, + timeInterval: GameData.CheckInterval, + finallyReturn: () => 0 + ).Start(); + ship.ThreadNum.Release(); + construction.SubConstructNum(); + } + ) + { IsBackground = true }.Start(); return false; } - } } } From f91e97daead25fec282452accd65887c4d366c5c Mon Sep 17 00:00:00 2001 From: Panxuc Date: Sun, 19 Nov 2023 00:48:30 +0800 Subject: [PATCH 7/7] feat: :sparkles: add wormhole related --- logic/GameClass/GameObj/Areas/Wormhole.cs | 13 +++++ logic/GameClass/GameObj/Map/Map.cs | 26 ++++++++- logic/GameClass/GameObj/Ship.cs | 3 + logic/Gaming/ActionManager.cs | 70 ++++++++++++++++++++++- 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs index 76665c9a..4b6c84cb 100644 --- a/logic/GameClass/GameObj/Areas/Wormhole.cs +++ b/logic/GameClass/GameObj/Areas/Wormhole.cs @@ -12,6 +12,19 @@ public class Wormhole : Immovable, IWormhole public List Grids => grids; public override bool IsRigid => HP > GameData.WormholeHP / 2; public override ShapeType Shape => ShapeType.Square; + public AtomicInt RepairNum { get; } = new AtomicInt(0); + public bool Repair(int constructSpeed, Ship ship) + { + return HP.AddV(constructSpeed) > 0; + } + public void AddRepairNum(int add = 1) + { + RepairNum.Add(add); + } + public void SubRepairNum(int sub = 1) + { + RepairNum.Sub(sub); + } public Wormhole(XY initPos, List grids) : base(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Wormhole) { diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index ff2507ec..14fadab4 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -96,10 +96,30 @@ public IOutOfBound GetOutOfBound(XY pos) { foreach (GameObj gameObj in GameObjDict[gameObjType]) { - if (GameData.ApproachToInteract(gameObj.Position, Pos)) + if (gameObjType == GameObjType.Wormhole) { - GameObjForInteract = gameObj; - break; + bool flag = false; + foreach (XY xy in ((Wormhole)gameObj).Grids) + { + if (GameData.ApproachToInteract(xy, Pos)) + { + GameObjForInteract = gameObj; + flag = true; + break; + } + } + if (flag) + { + break; + } + } + else + { + if (GameData.ApproachToInteract(gameObj.Position, Pos)) + { + GameObjForInteract = gameObj; + break; + } } } } diff --git a/logic/GameClass/GameObj/Ship.cs b/logic/GameClass/GameObj/Ship.cs index 0a640fa3..e835bf21 100644 --- a/logic/GameClass/GameObj/Ship.cs +++ b/logic/GameClass/GameObj/Ship.cs @@ -65,6 +65,9 @@ public override bool IgnoreCollideExecutor(IGameObj targetObj) public IWeapon WeaponModule => weapon; #endregion + public int ProduceSpeed => producer.ProduceSpeed; + public int ConstructSpeed => constructor.ConstructSpeed; + private GameObj? whatInteractingWith = null; public GameObj? WhatInteractingWith { diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 9604a37a..1ae3e768 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -109,6 +109,12 @@ public bool Produce(Ship ship) () => { ship.ThreadNum.WaitOne(); + if (!resource.Produce(ship.ProduceSpeed, ship)) + { + ship.ThreadNum.Release(); + ship.ResetShipState(stateNum); + return; + } if (!ship.StartThread(stateNum, RunningStateType.RunningActively)) { ship.ThreadNum.Release(); @@ -138,7 +144,7 @@ public bool Produce(Ship ship) { IsBackground = true }.Start(); return false; } - public bool Construct(Ship ship) + public bool Construct(Ship ship, ConstructionType constructionType) { Construction? construction = (Construction?)gameMap.OneForInteract(ship.Position, GameObjType.Construction); if (construction == null) @@ -159,6 +165,12 @@ public bool Construct(Ship ship) () => { ship.ThreadNum.WaitOne(); + if (!construction.Construct(ship.ConstructSpeed, constructionType, ship)) + { + ship.ThreadNum.Release(); + ship.ResetShipState(stateNum); + return; + } if (!ship.StartThread(stateNum, RunningStateType.RunningActively)) { ship.ThreadNum.Release(); @@ -188,6 +200,62 @@ public bool Construct(Ship ship) { IsBackground = true }.Start(); return false; } + public bool Repair(Ship ship) + { + Wormhole? wormhole = (Wormhole?)gameMap.OneForInteract(ship.Position, GameObjType.Wormhole); + if (wormhole == null) + { + return false; + } + if (wormhole.HP == wormhole.HP.GetMaxV()) + { + return false; + } + long stateNum = ship.SetShipState(RunningStateType.Waiting, ShipStateType.Constructing); + if (stateNum == -1) + { + return false; + } + new Thread + ( + () => + { + ship.ThreadNum.WaitOne(); + if (!wormhole.Repair(ship.ConstructSpeed, ship)) + { + ship.ThreadNum.Release(); + ship.ResetShipState(stateNum); + return; + } + if (!ship.StartThread(stateNum, RunningStateType.RunningActively)) + { + ship.ThreadNum.Release(); + return; + } + wormhole.AddRepairNum(); + Thread.Sleep(GameData.CheckInterval); + new FrameRateTaskExecutor + ( + loopCondition: () => stateNum == ship.StateNum && gameMap.Timer.IsGaming, + loopToDo: () => + { + if (wormhole.HP == wormhole.HP.GetMaxV()) + { + ship.ResetShipState(stateNum); + return false; + } + return true; + }, + timeInterval: GameData.CheckInterval, + finallyReturn: () => 0 + ).Start(); + ship.ThreadNum.Release(); + wormhole.SubRepairNum(); + } + ) + { IsBackground = true }.Start(); + return false; + } } } }