260 lines
11 KiB
C#
260 lines
11 KiB
C#
using GameClass.GameObj;
|
|
using GameClass.GameObj.Map;
|
|
using GameClass.GameObj.Areas;
|
|
using GameEngine;
|
|
using Preparation.Utility;
|
|
using System;
|
|
using System.Threading;
|
|
using Timothy.FrameRateTask;
|
|
|
|
namespace Gaming
|
|
{
|
|
public partial class Game
|
|
{
|
|
private readonly ActionManager actionManager;
|
|
private class ActionManager(Game game, Map gameMap, CharacterManager characterManager)
|
|
{
|
|
private readonly Game game = game;
|
|
private readonly Map gameMap = gameMap;
|
|
private readonly CharacterManager characterManager = characterManager;
|
|
private readonly Random random = new();
|
|
public readonly MoveEngine moveEngine = new(
|
|
gameMap: gameMap,
|
|
OnCollision: (obj, collisionObj, moveVec) =>
|
|
{
|
|
Character ship = (Character)obj;
|
|
return MoveEngine.AfterCollision.MoveMax;
|
|
},
|
|
EndMove: obj =>
|
|
{
|
|
obj.ThreadNum.Release();
|
|
}
|
|
);
|
|
public bool MoveCharacter(Character characterToMove, int moveTimeInMilliseconds, double moveDirection)
|
|
{
|
|
if (moveTimeInMilliseconds < 5)
|
|
{
|
|
ActionManagerLogging.logger.ConsoleLogDebug("Move time is too short");
|
|
return false;
|
|
}
|
|
long stateNum = characterToMove.SetCharacterState(CharacterState.MOVING, characterToMove.CharacterState2);
|
|
if (stateNum == -1)
|
|
{
|
|
ActionManagerLogging.logger.ConsoleLogDebug("Character is not commandable");
|
|
return false;
|
|
}
|
|
new Thread
|
|
(
|
|
() =>
|
|
{
|
|
characterToMove.ThreadNum.WaitOne();
|
|
if (!characterToMove.StartThread(stateNum))
|
|
{
|
|
characterToMove.ThreadNum.Release();
|
|
return;
|
|
}
|
|
moveEngine.MoveObj(characterToMove, moveTimeInMilliseconds, moveDirection, characterToMove.StateNum, characterToMove.Shoes);
|
|
Thread.Sleep(moveTimeInMilliseconds);
|
|
//characterToMove.ResetCharacterState(stateNum);
|
|
}
|
|
)
|
|
{ IsBackground = true }.Start();
|
|
return true;
|
|
}
|
|
public bool KnockBackCharacter(Character characterToMove, double moveDirection)
|
|
{
|
|
long stateNum = characterToMove.SetCharacterState(characterToMove.CharacterState1, CharacterState.KNOCKED_BACK);
|
|
CharacterState tempState = characterToMove.CharacterState2;
|
|
if (stateNum == -1)
|
|
{
|
|
ActionManagerLogging.logger.ConsoleLogDebug("Character can not be knocked back");
|
|
return false;
|
|
}
|
|
new Thread
|
|
(
|
|
() =>
|
|
{
|
|
characterToMove.ThreadNum.WaitOne();
|
|
if (!characterToMove.StartThread(stateNum))
|
|
{
|
|
characterToMove.ThreadNum.Release();
|
|
return;
|
|
}
|
|
moveEngine.MoveObj(characterToMove, GameData.KnockedBackTime, moveDirection, characterToMove.StateNum, GameData.KnockedBackSpeed);
|
|
Thread.Sleep(GameData.KnockedBackTime);
|
|
characterToMove.SetCharacterState(characterToMove.CharacterState1, tempState);
|
|
//characterToMove.ResetCharacterState(stateNum);
|
|
}
|
|
)
|
|
{ IsBackground = true }.Start();
|
|
return true;
|
|
}
|
|
public static bool Stop(Character character)
|
|
{
|
|
lock (character.ActionLock)
|
|
{
|
|
if (character.Commandable())
|
|
{
|
|
character.SetCharacterState(CharacterState.IDLE, character.CharacterState2);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
public bool Produce(Character character)
|
|
{
|
|
E_Resource? Eresource = (E_Resource?)gameMap.OneForInteract(character.Position, GameObjType.ECONOMY_RESOURCE);
|
|
if (Eresource == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (Eresource.HP == 0)
|
|
{
|
|
return false;
|
|
}
|
|
long stateNum = character.SetCharacterState(CharacterState.HARVESTING, character.CharacterState2);
|
|
if (stateNum == -1)
|
|
{
|
|
return false;
|
|
}
|
|
new Thread
|
|
(
|
|
() =>
|
|
{
|
|
character.ThreadNum.WaitOne();
|
|
if (!character.StartThread(stateNum))
|
|
{
|
|
character.ThreadNum.Release();
|
|
return;
|
|
}
|
|
//Eresource.AddProduceNum();
|
|
Thread.Sleep(GameData.CheckInterval);
|
|
new FrameRateTaskExecutor<int>
|
|
(
|
|
loopCondition: () => stateNum == character.StateNum && gameMap.Timer.IsGaming,
|
|
loopToDo: () =>
|
|
{
|
|
if (!Eresource.Produce(GameData.ProduceSpeedPerSecond / GameData.FrameDuration, character))
|
|
{
|
|
//character.ResetShipState(stateNum);
|
|
return false;
|
|
}
|
|
if (Eresource.HP == 0)
|
|
{
|
|
//character.ResetShipState(stateNum);
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
timeInterval: GameData.CheckInterval,
|
|
finallyReturn: () => 0
|
|
).Start();
|
|
character.ThreadNum.Release();
|
|
//Eresource.SubProduceNum();
|
|
}
|
|
)
|
|
{ IsBackground = true }.Start();
|
|
return false;
|
|
}
|
|
public bool Construct(Character character, ConstructionType constructionType)
|
|
{
|
|
Construction? construction = (Construction?)gameMap.OneForInteract(character.Position, GameObjType.CONSTRUCTION);
|
|
if (character.CharacterType != CharacterType.Monkid || character.CharacterType != CharacterType.Pawn)
|
|
{
|
|
return false;
|
|
}
|
|
if (construction == null)
|
|
{
|
|
return false;
|
|
}
|
|
if (construction.HP.IsMaxV())
|
|
{
|
|
return false;
|
|
}
|
|
long stateNum = character.SetCharacterState(CharacterState.CONSTRUCTING, character.CharacterState2);
|
|
if (stateNum == -1)
|
|
{
|
|
return false;
|
|
}
|
|
new Thread
|
|
(
|
|
() =>
|
|
{
|
|
character.ThreadNum.WaitOne();
|
|
if (!character.StartThread(stateNum))
|
|
{
|
|
character.ThreadNum.Release();
|
|
return;
|
|
}
|
|
construction.AddConstructNum();
|
|
Thread.Sleep(GameData.CheckInterval);
|
|
new FrameRateTaskExecutor<int>
|
|
(
|
|
loopCondition: () => stateNum == character.StateNum && gameMap.Timer.IsGaming,
|
|
loopToDo: () =>
|
|
{
|
|
if (!construction.Construct(constructionType, character))
|
|
{
|
|
//character.ResetCharacterState(stateNum);
|
|
return false;
|
|
}
|
|
if (construction.HP.IsMaxV())
|
|
{
|
|
//ship.ResetShipState(stateNum);
|
|
if (!construction.IsActivated)
|
|
{
|
|
switch (construction.ConstructionType)
|
|
{
|
|
case ConstructionType.FARM:
|
|
game.AddFactory(construction.TeamID);
|
|
break;
|
|
case ConstructionType.BARRACKS:
|
|
game.AddBirthPoint(construction.TeamID, construction.Position);
|
|
break;
|
|
}
|
|
construction.IsActivated.Set(true);
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
timeInterval: GameData.CheckInterval,
|
|
finallyReturn: () => 0
|
|
).Start();
|
|
character.ThreadNum.Release();
|
|
construction.SubConstructNum();
|
|
}
|
|
)
|
|
{ IsBackground = true }.Start();
|
|
return false;
|
|
}
|
|
public bool TeamTask(Base team)
|
|
{
|
|
new Thread
|
|
(
|
|
() =>
|
|
{
|
|
while (!gameMap.Timer.IsGaming)
|
|
{
|
|
Thread.Sleep(1);
|
|
}
|
|
new FrameRateTaskExecutor<int>
|
|
(
|
|
loopCondition: () => gameMap.Timer.IsGaming,
|
|
loopToDo: () =>
|
|
{
|
|
team.AddMoney(team.MoneyAddPerSecond / GameData.NumOfStepPerSecond);
|
|
return true;
|
|
},
|
|
timeInterval: GameData.CheckInterval,
|
|
finallyReturn: () => 0
|
|
).Start();
|
|
}
|
|
)
|
|
{ IsBackground = true }.Start();
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|