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; + } } } }