Browse Source

Merge branch 'eesast:dev' into dev

tags/v0.1.0
DragonAura GitHub 2 years ago
parent
commit
b842d8a10c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 594 additions and 434 deletions
  1. +1
    -0
      docs/CAPI接口(cpp).md
  2. +1
    -0
      docs/GameRules.md
  3. +7
    -1
      docs/版本更新说明.md
  4. +10
    -10
      logic/GameClass/GameObj/Character/Character.Student.cs
  5. +89
    -78
      logic/GameClass/GameObj/Character/Character.cs
  6. +5
    -3
      logic/GameClass/GameObj/Map/Chest.cs
  7. +20
    -6
      logic/GameClass/GameObj/Map/Door.cs
  8. +84
    -55
      logic/GameClass/GameObj/Map/Map.cs
  9. +14
    -0
      logic/GameClass/GameObj/Moveable.cs
  10. +1
    -7
      logic/GameClass/GameObj/Prop/Item.cs
  11. +257
    -175
      logic/Gaming/ActionManager.cs
  12. +20
    -9
      logic/Gaming/AttackManager.cs
  13. +9
    -22
      logic/Gaming/CharacterManager.cs
  14. +1
    -1
      logic/Gaming/Game.cs
  15. +62
    -63
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  16. +2
    -1
      logic/Preparation/Interface/ICharacter.cs
  17. +8
    -0
      logic/Preparation/Utility/EnumType.cs
  18. +1
    -1
      logic/Preparation/Utility/GameData.cs
  19. +2
    -2
      logic/Server/GameServer.cs

+ 1
- 0
docs/CAPI接口(cpp).md View File

@@ -9,6 +9,7 @@

#### 移动
- `std::future<bool> Move(int64_t timeInMilliseconds, double angleInRadian)`:移动,`timeInMilliseconds` 为移动时间,单位毫秒;`angleInRadian` 表示移动方向,单位弧度,使用极坐标,**竖直向下方向为 x 轴,水平向右方向为 y 轴**。因为移动过程中你会受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。
- 5ms 以内的移动指令会被禁止,你不应当使用过小的移动指令
- `std::future<bool> MoveRight(uint32_t timeInMilliseconds)`即向右移动,`MoveLeft`、`MoveDown`、`MoveUp` 同理

#### 使用技能


+ 1
- 0
docs/GameRules.md View File

@@ -305,6 +305,7 @@ $$
- 不可救人
- 无牵制得分
- 不可使用道具(可以捡起和扔道具)
- 不沉迷,击中直接摧毁

#### 技术宅TechOtaku
- 特性


+ 7
- 1
docs/版本更新说明.md View File

@@ -65,4 +65,10 @@

# 5月21日更新
- docs:更新了 游戏机制与平衡性调整更新(基本不变版).pdf
- Klee小炸弹的攻击范围与放射方向调整
- Klee小炸弹的攻击范围与放射方向调整

# 5月22日11:00更新
- fix:修复了开校门的bug

# 5月25日更新
- fix:修复了Semaphore设置错误的问题

+ 10
- 10
logic/GameClass/GameObj/Character/Character.Student.cs View File

@@ -1,6 +1,7 @@
using Preparation.Utility;
using Preparation.Interface;
using System;
using System.Threading;

namespace GameClass.GameObj
{
@@ -108,16 +109,15 @@ namespace GameClass.GameObj
private int timeOfRescue = 0;
public int TimeOfRescue
{
get => timeOfRescue;
set
{
if (value > 0)
lock (gameObjLock)
timeOfRescue = (value < GameData.basicTimeOfRescue) ? value : GameData.basicTimeOfRescue;
else
lock (gameObjLock)
timeOfRescue = 0;
}
get => Interlocked.CompareExchange(ref timeOfRescue, -1, -1);
}
public bool AddTimeOfRescue(int value)
{
return Interlocked.Add(ref timeOfRescue, value) >= GameData.basicTimeOfRescue;
}
public void SetTimeOfRescue(int value)
{
Interlocked.Exchange(ref timeOfRescue, value);
}

public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType)


+ 89
- 78
logic/GameClass/GameObj/Character/Character.cs View File

@@ -418,34 +418,64 @@ namespace GameClass.GameObj
|| playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving);
}
private GameObj? whatInteractingWith = null;
public GameObj? WhatInteractingWith => whatInteractingWith;
public GameObj? WhatInteractingWith
{
get
{
lock (actionLock)
{
return whatInteractingWith;
}
}
}

public bool StartThread(long stateNum, RunningStateType runningState)
{
lock (ActionLock)
{
if (this.StateNum == stateNum)
{
this.runningState = runningState;
return true;
}
}
return false;
}

private long ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
private long ChangePlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
{
//只能被SetPlayerState引用
if (runningState == RunningStateType.RunningSleepily)
{
ThreadNum.Release();
}
runningState = running;
whatInteractingWith = gameObj;
playerState = value;
//Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString());
return ++stateNum;
}

private long ChangePlayerStateInOneThread(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
private long ChangePlayerStateInOneThread(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
{
if (runningState == RunningStateType.RunningSleepily)
{
ThreadNum.Release();
}
runningState = running;
//只能被SetPlayerState引用
whatInteractingWith = gameObj;
playerState = value;
//Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString());
return stateNum;
}


public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null)
public long SetPlayerState(RunningStateType runningState, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null)
{
GameObj? gameObj = (GameObj?)obj;
lock (actionLock)
{
PlayerStateType nowPlayerState = PlayerState;
if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1;
GameObj? lastObj = whatInteractingWith;
switch (nowPlayerState)
{
case PlayerStateType.Escaped:
@@ -454,119 +484,85 @@ namespace GameClass.GameObj

case PlayerStateType.Addicted:
if (value == PlayerStateType.Rescued)
return ChangePlayerStateInOneThread(value, gameObj);
return ChangePlayerStateInOneThread(runningState, value, gameObj);
else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1;
case PlayerStateType.Rescued:
if (value == PlayerStateType.Addicted)
return ChangePlayerStateInOneThread(value, gameObj);
return ChangePlayerStateInOneThread(runningState, value, gameObj);
else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1;

case PlayerStateType.TryingToAttack:
if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1;
case PlayerStateType.Stunned:
case PlayerStateType.Charmed:
if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased
|| value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1;
case PlayerStateType.Swinging:
if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
{
try
{
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
return ChangePlayerState(runningState, value, gameObj);
else return -1;
case PlayerStateType.ClimbingThroughWindows:
if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
{
Window window = (Window)WhatInteractingWith!;
try
{
window.FinishClimbing();
return ChangePlayerState(value, gameObj);
}
finally
{
if (window.Stage.x == 0)
ThreadNum.Release();
else ReSetPos(window.Stage);
}
Window window = (Window)lastObj!;
if (window.Stage.x != 0) ReSetPos(window.Stage);
window.FinishClimbing();
return ChangePlayerState(runningState, value, gameObj);
}
else return -1;

case PlayerStateType.OpeningTheChest:
((Chest)whatInteractingWith!).StopOpen();
return ChangePlayerState(value, gameObj);
if (value == PlayerStateType.Rescued) return -1;
((Chest)lastObj!).StopOpen();
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.OpeningTheDoorway:
try
{
Doorway doorway = (Doorway)whatInteractingWith!;
doorway.StopOpenning();
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
if (value == PlayerStateType.Rescued) return -1;
Doorway doorway = (Doorway)lastObj!;
doorway.StopOpenning();
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.OpeningTheDoor:
Door door = (Door)whatInteractingWith!;
try
if (value == PlayerStateType.Rescued) return -1;
Door door = (Door)lastObj!;
door.StopOpen();
ReleaseTool(door.DoorNum switch
{
door.StopOpen();
ReleaseTool(door.DoorNum switch
{
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
}
);
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
}
);
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.UsingSkill:
{
if (value == PlayerStateType.Rescued) return -1;
switch (CharacterType)
{
case CharacterType.TechOtaku:
{
if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith))
if (typeof(CraftingBench).IsInstanceOfType(lastObj))
{
try
{
((CraftingBench)whatInteractingWith!).StopSkill();
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
((CraftingBench)lastObj!).StopSkill();
return ChangePlayerState(runningState, value, gameObj);
}
else
{
if (value != PlayerStateType.UsingSkill)
((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID;
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
}
}
case CharacterType.Assassin:
@@ -574,14 +570,15 @@ namespace GameClass.GameObj
else
{
TryDeleteInvisible();
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
}
default:
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
}
}
default:
return ChangePlayerState(value, gameObj);
if (value == PlayerStateType.Rescued) return -1;
return ChangePlayerState(runningState, value, gameObj);
}
}
}
@@ -590,19 +587,33 @@ namespace GameClass.GameObj
{
lock (actionLock)
{
runningState = RunningStateType.Null;
whatInteractingWith = null;
playerState = PlayerStateType.Null;
return ++stateNum;
}
}

public bool ResetPlayerState(long state, RunningStateType running = RunningStateType.Null, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null)
{
lock (actionLock)
{
if (state != stateNum) return false;
this.runningState = running;
whatInteractingWith = (GameObj?)obj;
playerState = value;
++stateNum;
return true;
}
}

public bool TryToRemoveFromGame(PlayerStateType playerStateType)
{
lock (actionLock)
{
if (!TryToRemove()) return false;
if (SetPlayerState(RunningStateType.RunningForcibly, playerStateType) == -1) return false;
TryToRemove();
ReSetCanMove(false);
SetPlayerState(playerStateType);
position = GameData.PosWhoDie;
}
return true;


+ 5
- 3
logic/GameClass/GameObj/Map/Chest.cs View File

@@ -1,5 +1,6 @@
using Preparation.Interface;
using Preparation.Utility;
using System;

namespace GameClass.GameObj
{
@@ -22,19 +23,20 @@ namespace GameClass.GameObj
public int OpenStartTime => openStartTime;
private Character? whoOpen = null;
public Character? WhoOpen => whoOpen;
public void Open(int startTime, Character character)
public bool Open(Character character)
{
lock (GameObjReaderWriterLock)
{
openStartTime = startTime;
if (whoOpen != null) return false;
openStartTime = Environment.TickCount;
whoOpen = character;
}
return true;
}
public void StopOpen()
{
lock (GameObjReaderWriterLock)
{
openStartTime = 0;
whoOpen = null;
}
}


+ 20
- 6
logic/GameClass/GameObj/Map/Door.cs View File

@@ -70,8 +70,8 @@ namespace GameClass.GameObj
}
}

private long openStartTime = 0;
public long OpenStartTime
private int openStartTime = 0;
public int OpenStartTime
{
get
{
@@ -86,7 +86,7 @@ namespace GameClass.GameObj
{
if (isOpen) return false;
if (whoLockOrOpen != null) return false;
openStartTime = Environment.TickCount64;
openStartTime = Environment.TickCount;
whoLockOrOpen = character;
return true;
}
@@ -97,7 +97,7 @@ namespace GameClass.GameObj
{
if (whoLockOrOpen != null)
{
if ((Environment.TickCount64 - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking)
if ((Environment.TickCount - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking)
isOpen = true;
whoLockOrOpen = null;
}
@@ -153,9 +153,23 @@ namespace GameClass.GameObj
if (character != null)
{
lock (character.ActionLock)
{
if (character.PlayerState == PlayerStateType.OpeningTheDoor)
character.SetPlayerState();
{
character.ReleaseTool(DoorNum switch
{
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
});
character.SetPlayerStateNaturally();
}
else if (character.PlayerState == PlayerStateType.LockingTheDoor)
{
character.SetPlayerStateNaturally();
}
}
}
}
}
}
}

+ 84
- 55
logic/GameClass/GameObj/Map/Map.cs View File

@@ -75,6 +75,7 @@ namespace GameClass.GameObj
{
if (Interlocked.Increment(ref numOfNoHpStudent) == GameData.numOfStudent)
{
AddScoreFromAddict();
Timer.IsGaming = false;
return;
}
@@ -120,6 +121,10 @@ namespace GameClass.GameObj
GameObjLockDict[GameObjType.EmergencyExit].ExitReadLock();
}
}
private void AddScoreFromAddict()
{

}


private Dictionary<GameObjType, IList<IGameObj>> gameObjDict;
@@ -182,6 +187,26 @@ namespace GameClass.GameObj
}
return player;
}
public Character FindGhost()
{
gameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
int i;
for (i = 0; i < (gameObjDict[GameObjType.Character]).Count - 1; ++i)
{
if (((Character)gameObjDict[GameObjType.Character][i]).IsGhost())
{
return ((Character)gameObjDict[GameObjType.Character][i]);
}
}
return ((Character)gameObjDict[GameObjType.Character][i]);
}
finally
{
gameObjLockDict[GameObjType.Character].ExitReadLock();
}
}
public Character? FindPlayerToAction(long playerID)
{
Character? player = null;
@@ -215,61 +240,7 @@ namespace GameClass.GameObj
}
return player;
}
public bool Remove(GameObj gameObj)
{
GameObj? ToDel = null;
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
foreach (GameObj obj in GameObjDict[gameObj.Type])
{
if (gameObj.ID == obj.ID)
{
ToDel = obj;
break;
}
}
if (ToDel != null)
{
GameObjDict[gameObj.Type].Remove(ToDel);
ToDel.TryToRemove();
}
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
return ToDel != null;
}
public bool RemoveJustFromMap(GameObj gameObj)
{
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
if (GameObjDict[gameObj.Type].Remove(gameObj))
{
gameObj.TryToRemove();
return true;
}
return false;
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
}
public void Add(GameObj gameObj)
{
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
GameObjDict[gameObj.Type].Add(gameObj);
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
}

public GameObj? OneForInteract(XY Pos, GameObjType gameObjType)
{
GameObj? GameObjForInteract = null;
@@ -375,6 +346,7 @@ namespace GameClass.GameObj
}
return GameObjForInteract;
}

public bool CanSee(Character player, GameObj gameObj)
{
if ((gameObj.Type == GameObjType.Character) && ((Character)gameObj).HasInvisible) return false;
@@ -422,6 +394,63 @@ namespace GameClass.GameObj
}
return true;
}

public bool Remove(GameObj gameObj)
{
GameObj? ToDel = null;
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
foreach (GameObj obj in GameObjDict[gameObj.Type])
{
if (gameObj.ID == obj.ID)
{
ToDel = obj;
break;
}
}
if (ToDel != null)
{
GameObjDict[gameObj.Type].Remove(ToDel);
ToDel.TryToRemove();
}
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
return ToDel != null;
}
public bool RemoveJustFromMap(GameObj gameObj)
{
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
if (GameObjDict[gameObj.Type].Remove(gameObj))
{
gameObj.TryToRemove();
return true;
}
return false;
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
}
public void Add(GameObj gameObj)
{
GameObjLockDict[gameObj.Type].EnterWriteLock();
try
{
GameObjDict[gameObj.Type].Add(gameObj);
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
}

public Map(uint[,] mapResource)
{
gameObjDict = new Dictionary<GameObjType, IList<IGameObj>>();


+ 14
- 0
logic/GameClass/GameObj/Moveable.cs View File

@@ -29,6 +29,20 @@ namespace GameClass.GameObj
}
}

protected RunningStateType runningState = RunningStateType.Null;
public RunningStateType RunningState
{
get
{
lock (actionLock) return runningState;
}
set
{
lock (actionLock)
runningState = value;
}
}

public override XY Position
{
get


+ 1
- 7
logic/GameClass/GameObj/Prop/Item.cs View File

@@ -52,13 +52,7 @@ namespace GameClass.GameObj
}
public void TryStopSkill()
{
lock (Parent!.ActionLock)
{
if (Parent!.StateNum == parentStateNum)
{
Parent!.SetPlayerState();
}
}
Parent!.ResetPlayerState(parentStateNum);
}
public override PropType GetPropType() => PropType.CraftingBench;
}


+ 257
- 175
logic/Gaming/ActionManager.cs View File

@@ -1,9 +1,7 @@
using System;
using System.Numerics;
using System.Threading;
using GameClass.GameObj;
using GameEngine;
using Preparation.Interface;
using Preparation.Utility;
using Timothy.FrameRateTask;

@@ -17,17 +15,19 @@ namespace Gaming
public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
{
if (moveTimeInMilliseconds < 5) return false;
long stateNum = playerToMove.SetPlayerState(PlayerStateType.Moving);
long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Moving);
if (stateNum == -1) return false;
new Thread
(
() =>
{
playerToMove.ThreadNum.WaitOne();
if (stateNum != playerToMove.StateNum)
if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively))
{
playerToMove.ThreadNum.Release();
else
moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, stateNum);
return;
}
moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, stateNum);
}
)
{ IsBackground = true }.Start();
@@ -37,22 +37,28 @@ namespace Gaming
public bool MovePlayerWhenStunned(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
{
if (playerToMove.CharacterType == CharacterType.Robot) return false;
long stateNum = playerToMove.SetPlayerState(PlayerStateType.Charmed);
long stateNum = playerToMove.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Charmed);
if (stateNum == -1) return false;
new Thread
(() =>
{
playerToMove.ThreadNum.WaitOne();
if (stateNum != playerToMove.StateNum)
if (!playerToMove.StartThread(stateNum, RunningStateType.RunningActively))
{
playerToMove.ThreadNum.Release();
return;
}
else
{
moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum);
Thread.Sleep(moveTimeInMilliseconds);
lock (playerToMove.ActionLock)
{
if (stateNum == playerToMove.StateNum)
playerToMove.SetPlayerStateNaturally();
lock (playerToMove.ActionLock)
{
if (stateNum == playerToMove.StateNum)
playerToMove.SetPlayerStateNaturally();
}
}
}
}
@@ -67,7 +73,7 @@ namespace Gaming
{
if (player.Commandable())
{
player.SetPlayerState();
player.SetPlayerState(RunningStateType.Null);
return true;
}
}
@@ -79,21 +85,27 @@ namespace Gaming
Generator? generatorForFix = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator);
if (generatorForFix == null) return false;

long stateNum = player.SetPlayerState(PlayerStateType.Fixing);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Fixing);
if (stateNum == -1) return false;

player.ThreadNum.WaitOne();
if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator)
{
player.ThreadNum.Release();
return false;
}

generatorForFix.AddNumOfFixing();
new Thread
(
() =>
{
player.ThreadNum.WaitOne();
if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator)
{
player.ThreadNum.Release();
return;
}
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
player.ThreadNum.Release();
return;
}

generatorForFix.AddNumOfFixing();

Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor<int>(
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
@@ -106,9 +118,11 @@ namespace Gaming
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
player.SetPlayerState();
player.SetPlayerState(RunningStateType.Null);
}
return false;
}
return true;
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
@@ -129,34 +143,27 @@ namespace Gaming
Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
if (doorwayToOpen == null) return false;

long stateNum = player.SetPlayerState(PlayerStateType.OpeningTheDoorway, doorwayToOpen);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoorway, doorwayToOpen);
if (stateNum == -1) return false;
new Thread
(
() =>
{
player.ThreadNum.WaitOne();
lock (player.ActionLock)
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
if (stateNum != player.StateNum)
{
player.ThreadNum.Release();
return;
}
player.ThreadNum.Release();
return;
}
doorwayToOpen.TryToOpen();
Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree);
lock (player.ActionLock)

if (player.ResetPlayerState(stateNum))
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
doorwayToOpen.FinishOpenning();
player.ThreadNum.Release();
}
doorwayToOpen.FinishOpenning();
player.ThreadNum.Release();
}
}

)
{ IsBackground = true }.Start();

@@ -165,14 +172,15 @@ namespace Gaming

public bool Escape(Student player)
{
if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher)
if (player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher)
return false;

Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
if (doorwayForEscape != null && doorwayForEscape.IsOpen())
{
if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
player.AddScore(GameData.StudentScoreEscape);
gameMap.MapEscapeStudent();
player.TryToRemoveFromGame(PlayerStateType.Escaped);
return true;
}
else
@@ -180,9 +188,9 @@ namespace Gaming
EmergencyExit? emergencyExit = (EmergencyExit?)gameMap.OneForInteract(player.Position, GameObjType.EmergencyExit);
if (emergencyExit != null && emergencyExit.IsOpen)
{
if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
player.AddScore(GameData.StudentScoreEscape);
gameMap.MapEscapeStudent();
player.TryToRemoveFromGame(PlayerStateType.Escaped);
return true;
}
return false;
@@ -197,38 +205,88 @@ namespace Gaming
playerTreated = gameMap.StudentForInteract(player.Position);
if (playerTreated == null) return false;
}
if (player == playerTreated || (!player.Commandable()) || playerTreated.PlayerState == PlayerStateType.Treated ||
(!playerTreated.Commandable()) ||
playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position))
else if (!GameData.ApproachToInteract(playerTreated.Position, player.Position)) return false;

if (playerTreated.HP == playerTreated.MaxHp) return false;

long stateNumTreated = playerTreated.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treated);
if (stateNumTreated == -1) return false;

long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Treating);
if (stateNum == -1)
{
lock (playerTreated.ActionLock)
{
if (playerTreated.StateNum == stateNumTreated)
player.SetPlayerStateNaturally();
}
return false;
}

new Thread
(
() =>
{
playerTreated.SetPlayerState(PlayerStateType.Treated);
player.SetPlayerState(PlayerStateType.Treating);
long threadNum = player.StateNum;
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
player.ThreadNum.Release();
lock (playerTreated.ActionLock)
{
if (playerTreated.StateNum == stateNumTreated)
playerTreated.SetPlayerStateNaturally();
}
return;
}

playerTreated.ThreadNum.WaitOne();
if (!playerTreated.StartThread(stateNum, RunningStateType.RunningActively))
{
playerTreated.ThreadNum.Release();
lock (player.ActionLock)
{
if (player.StateNum == stateNum)
player.SetPlayerStateNaturally();
}
player.ThreadNum.Release();
return;
}

Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor<int>(
loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () =>
{
if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player))
playerTreated.SetPlayerState();//
lock (playerTreated.ActionLock)
{
if (playerTreated.StateNum == stateNumTreated)
{
if (playerTreated.AddDegreeOfTreatment(GameData.checkInterval * player.TreatSpeed, player))
{
playerTreated.SetPlayerStateNaturally();
return false;
}
}
else return false;
}
return true;
},
timeInterval: GameData.frameDuration,
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
.Start();
player.ThreadNum.Release();
playerTreated.ThreadNum.Release();
if (player.ResetPlayerState(stateNum))
return;

if (threadNum == player.StateNum) player.SetPlayerState();
else if (playerTreated.PlayerState == PlayerStateType.Treated) playerTreated.SetPlayerState();
playerTreated.ResetPlayerState(stateNumTreated);
}
)
{ IsBackground = true }.Start();
return true;
}

public bool Rescue(Student player, Student? playerRescued = null)
{
if (player.CharacterType == CharacterType.Robot) return false;
@@ -238,69 +296,114 @@ namespace Gaming
playerRescued = gameMap.StudentForInteract(player.Position);
if (playerRescued == null) return false;
}
// else//no need
// if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return false;

long stateNumRescued = playerRescued.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescued);
if (stateNumRescued == -1) return false;

if ((!player.Commandable()) || playerRescued.PlayerState != PlayerStateType.Addicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position))
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescuing);
if (stateNum == -1)
{
playerRescued.ResetPlayerState(stateNumRescued, RunningStateType.RunningForcibly, PlayerStateType.Addicted);
return false;
player.SetPlayerState(PlayerStateType.Rescuing);
playerRescued.SetPlayerState(PlayerStateType.Rescued);
long threadNum = player.StateNum;
}

new Thread
(
() =>
{
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
player.ThreadNum.Release();
playerRescued.ResetPlayerState(stateNumRescued, RunningStateType.RunningForcibly, PlayerStateType.Addicted);
return;
}

playerRescued.ThreadNum.WaitOne();
if (!GameData.ApproachToInteract(playerRescued.Position, player.Position)) return;

if (!playerRescued.StartThread(stateNumRescued, RunningStateType.RunningSleepily))
{
playerRescued.ThreadNum.Release();
if (!player.ResetPlayerState(stateNum))
player.ThreadNum.Release();
return;
}

new FrameRateTaskExecutor<int>(
loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () =>
{
playerRescued.TimeOfRescue += GameData.frameDuration;
lock (playerRescued.ActionLock)
{
if (playerRescued.StateNum == stateNumRescued)
{
if (playerRescued.AddTimeOfRescue(GameData.checkInterval))
{
playerRescued.SetPlayerStateNaturally();
playerRescued.HP = playerRescued.MaxHp / 2;
player.AddScore(GameData.StudentScoreRescue);
return false;
}
}
else return false;
}
return true;
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0,
maxTotalDuration: GameData.basicTimeOfRescue
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
.Start();
playerRescued.SetTimeOfRescue(0);

if (playerRescued.PlayerState == PlayerStateType.Rescued)
{
if (playerRescued.TimeOfRescue >= GameData.basicTimeOfRescue)
{
playerRescued.SetPlayerState();
playerRescued.HP = playerRescued.MaxHp / 2;
player.AddScore(GameData.StudentScoreRescue);
}
else
playerRescued.SetPlayerState(PlayerStateType.Addicted);
}
if (threadNum == player.StateNum) player.SetPlayerState();
playerRescued.TimeOfRescue = 0;
player.ThreadNum.Release();
playerRescued.ThreadNum.Release();
if (player.ResetPlayerState(stateNum)) return;

playerRescued.ResetPlayerState(stateNumRescued, RunningStateType.RunningForcibly, PlayerStateType.Addicted);
}
)
{ IsBackground = true }.Start();

return true;
}

public bool OpenChest(Character player)
{
if ((!player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheChest)
return false;
Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest);
if (chestToOpen == null) return false;

if (chestToOpen == null || chestToOpen.OpenStartTime > 0)
return false;
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheChest, chestToOpen);
if (stateNum == -1) return false;

player.SetPlayerState(PlayerStateType.OpeningTheChest, chestToOpen);
int startTime = gameMap.Timer.nowTime();
chestToOpen.Open(startTime, player);
new Thread
(
() =>
{
player.ThreadNum.WaitOne();
lock (player.ActionLock)
{
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
player.ThreadNum.Release();
return;
}
else
if (!chestToOpen.Open(player))
{
player.ThreadNum.Release();
player.SetPlayerStateNaturally();
return;
}
}

Thread.Sleep(GameData.degreeOfOpenedChest / player.SpeedOfOpenChest);

if (chestToOpen.OpenStartTime == startTime)
if (player.ResetPlayerState(stateNum))
{
player.SetPlayerStateNaturally();
player.ThreadNum.Release();
for (int i = 0; i < GameData.maxNumOfPropInChest; ++i)
{
Gadget prop = chestToOpen.PropInChest[i];
@@ -316,12 +419,13 @@ namespace Gaming

return true;
}

public bool ClimbingThroughWindow(Character player)
{
Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window);
if (windowForClimb == null) return false;

long stateNum = player.SetPlayerState(PlayerStateType.ClimbingThroughWindows, windowForClimb);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.ClimbingThroughWindows, windowForClimb);
if (stateNum == -1) return false;

XY windowToPlayer = new(
@@ -344,43 +448,43 @@ namespace Gaming
() =>
{
player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
{
player.ThreadNum.Release();
}
else
lock (player.ActionLock)
{
if (!windowForClimb.TryToClimb(player))
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
player.ThreadNum.Release();
player.SetPlayerStateNaturally();
return;
}
else
if (!windowForClimb.TryToClimb(player))
{
Thread.Sleep((int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed));
player.SetPlayerStateNaturally();
player.ThreadNum.Release();
return;
}
}

lock (player.ActionLock)
{
if (player.StateNum != stateNum) return;
player.ReSetPos(windowToPlayer + windowForClimb.Position);
windowForClimb.Enter2Stage(windowForClimb.Position - 2 * windowToPlayer);
}
Thread.Sleep((int)((windowToPlayer + windowForClimb.Position - player.Position).Length() * 1000 / player.MoveSpeed));

lock (player.ActionLock)
{
if (!player.StartThread(stateNum, RunningStateType.RunningActively)) return;
player.ReSetPos(windowToPlayer + windowForClimb.Position);
windowForClimb.Enter2Stage(windowForClimb.Position - 2 * windowToPlayer);
}

player.MoveSpeed = player.SpeedOfClimbingThroughWindows;
moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum);
player.MoveSpeed = player.SpeedOfClimbingThroughWindows;
moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum);

Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2));
Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2));

player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed);
player.MoveSpeed = player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed);

lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerState();
windowForClimb.FinishClimbing();
}
}
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
windowForClimb.FinishClimbing();
}
}
}
@@ -389,6 +493,7 @@ namespace Gaming

return true;
}

public bool LockDoor(Character player)
{
if (player.CharacterType == CharacterType.Robot) return false;
@@ -404,7 +509,7 @@ namespace Gaming

if (!player.UseTool(propType)) return false;

long stateNum = player.SetPlayerState(PlayerStateType.LockingTheDoor, doorToLock);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.LockingTheDoor, doorToLock);
if (stateNum == -1)
{
player.ReleaseTool(propType);
@@ -416,47 +521,37 @@ namespace Gaming
() =>
{
player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
player.ReleaseTool(propType);
player.ThreadNum.Release();
return;
}
else
if (!doorToLock.TryLock(player))
{
if (!doorToLock.TryLock(player))
{
player.ReleaseTool(propType);
lock (player.ActionLock)
{
if (stateNum == player.StateNum) player.SetPlayerState();
}
player.ThreadNum.Release();
}
else
{
Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor<int>(
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
loopToDo: () =>
{
if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null)
return false;
doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking;
return true;
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
.Start();
doorToLock.StopLock();
player.ReleaseTool(propType);
lock (player.ActionLock)
{
if (stateNum == player.StateNum) player.SetPlayerStateNaturally();
}
player.ThreadNum.Release();
}
player.ReleaseTool(propType);
player.ResetPlayerState(stateNum);
player.ThreadNum.Release();
return;
}
Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor<int>(
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.LockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
loopToDo: () =>
{
if ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) != null)
return false;
doorToLock.LockDegree += GameData.checkInterval * player.SpeedOfOpeningOrLocking;
return true;
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
.Start();
doorToLock.StopLock();
player.ReleaseTool(propType);
player.ThreadNum.Release();
player.ResetPlayerState(stateNum);
}
)
{ IsBackground = true }.Start();
@@ -479,7 +574,7 @@ namespace Gaming

if (!player.UseTool(propType)) return false;

long stateNum = player.SetPlayerState(PlayerStateType.OpeningTheDoor, doorToLock);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.OpeningTheDoor, doorToLock);
if (stateNum == -1)
{
player.ReleaseTool(propType);
@@ -491,42 +586,29 @@ namespace Gaming
() =>
{
player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
player.ReleaseTool(propType);
player.ThreadNum.Release();
return;
}
else
if (!doorToLock.TryOpen(player))
{
if (!doorToLock.TryOpen(player))
{
player.ReleaseTool(propType);
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
player.ThreadNum.Release();
}
}
}
else
{
Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking);
player.ReleaseTool(propType);
if (player.ResetPlayerState(stateNum))
player.ThreadNum.Release();
return;
}
Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking);

lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
doorToLock.StopOpen();
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
}
}
if (player.ResetPlayerState(stateNum))
{
doorToLock.StopOpen();
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
}

)
{ IsBackground = true }.Start();



+ 20
- 9
logic/Gaming/AttackManager.cs View File

@@ -30,7 +30,7 @@ namespace Gaming
},
EndMove: obj =>
{
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount);
if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty)
BulletBomb((Bullet)obj, null);
obj.ReSetCanMove(false);
@@ -201,6 +201,8 @@ namespace Gaming

public bool Attack(Character player, double angle)
{ // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
if (!player.Commandable()) return false;

Bullet? bullet = player.Attack(angle, gameMap.Timer.nowTime());

if (bullet != null)
@@ -212,14 +214,25 @@ namespace Gaming

if (bullet.CastTime > 0)
{
player.SetPlayerState(PlayerStateType.TryingToAttack);
long threadNum = player.StateNum;
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.TryingToAttack);
if (stateNum == -1)
{
TryRemoveBullet(bullet);
return false;
}

new Thread
(() =>
{
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
TryRemoveBullet(bullet);
player.ThreadNum.Release();
return;
}
new FrameRateTaskExecutor<int>(
loopCondition: () => threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () =>
{
},
@@ -229,13 +242,11 @@ namespace Gaming
)
.Start();

player.ThreadNum.Release();
if (gameMap.Timer.IsGaming)
{
if (threadNum == player.StateNum)
{
player.SetPlayerState();
}
else TryRemoveBullet(bullet);
if (!player.ResetPlayerState(stateNum))
TryRemoveBullet(bullet);
}
}
)


+ 9
- 22
logic/Gaming/CharacterManager.cs View File

@@ -218,11 +218,8 @@ namespace Gaming

public void BeAddictedToGame(Student player, Ghost ghost)
{
long stateNum = player.SetPlayerState(PlayerStateType.Addicted);
if (stateNum == -1)
{
return;
}
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Addicted);
if (stateNum == -1) return;

if (player.CharacterType == CharacterType.Robot)
{
@@ -278,19 +275,18 @@ namespace Gaming
public static long BeStunned(Character player, int time)
{
if (player.CharacterType == CharacterType.Robot) return -1;
long threadNum = player.SetPlayerState(PlayerStateType.Stunned);
if (threadNum == -1) return -1;
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Stunned);
if (stateNum == -1) return -1;
new Thread
(() =>
{
Debugger.Output(player, " is stunned for " + time.ToString());
Thread.Sleep(time);
if (threadNum == player.StateNum)
player.SetPlayerState();
player.ResetPlayerState(stateNum);
}
)
{ IsBackground = true }.Start();
return threadNum;
return stateNum;
}

public bool TryBeAwed(Student character, Bullet bullet)
@@ -378,23 +374,14 @@ namespace Gaming
public bool BackSwing(Character player, int time)
{
if (time <= 0) return false;
long stateNum = player.SetPlayerState(PlayerStateType.Swinging);
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Swinging);
if (stateNum == -1) return false;

new Thread
(() =>
{
player.ThreadNum.WaitOne();
Thread.Sleep(time);

lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.ThreadNum.Release();
player.SetPlayerStateNaturally();
}
}
player.ResetPlayerState(stateNum);
}
)
{ IsBackground = true }.Start();
@@ -428,7 +415,7 @@ namespace Gaming
lock (parent.ActionLock)
{
if (parent.PlayerState == PlayerStateType.UsingSkill)
parent.SetPlayerState();
parent.SetPlayerStateNaturally();
}
}
}


+ 1
- 1
logic/Gaming/Game.cs View File

@@ -225,7 +225,7 @@ namespace Gaming
if (!gameMap.Timer.IsGaming)
return false;
Character? player = gameMap.FindPlayerToAction(playerID);
if (player != null && player.Commandable())
if (player != null)
{
return attackManager.Attack(player, angle);
}


+ 62
- 63
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -93,7 +93,7 @@ namespace Gaming
public static bool BecomeInvisible(Character player)
{
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible);
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill);
if (stateNum == -1)
{
return false;
@@ -106,15 +106,9 @@ namespace Gaming
},
() =>
{
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
}
}
player.ResetPlayerState(stateNum);
}
);
);
}

public static bool UseRobot(Character player, int robotID)
@@ -141,7 +135,7 @@ namespace Gaming
activeSkill.NowPlayerID = robotID;
}
else return false;
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill);
if (stateNum == -1)
{
activeSkill.NowPlayerID = (int)player.PlayerID;
@@ -250,48 +244,48 @@ namespace Gaming
{
CraftingBench craftingBench = new(res, player, num);

long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill, craftingBench);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.UsingSkill, craftingBench);
if (stateNum == -1)
{
((SummonGolem)activeSkill).DeleteGolem(num);
return false;
}

player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
{
((SummonGolem)activeSkill).DeleteGolem(num);
player.ThreadNum.Release();
return false;
}

if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null)
{
((SummonGolem)activeSkill).DeleteGolem(num);
player.ThreadNum.Release();
return false;
}
craftingBench.ParentStateNum = stateNum;
gameMap.Add(craftingBench);

return ActiveSkillEffect(activeSkill, player, () =>
{
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{
((SummonGolem)activeSkill).DeleteGolem(num);
player.ThreadNum.Release();
}
else
{
if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null)
{
((SummonGolem)activeSkill).DeleteGolem(num);
if (player.ResetPlayerState(stateNum))
player.ThreadNum.Release();
}
else
{
craftingBench.ParentStateNum = stateNum;
gameMap.Add(craftingBench);
}
}
},
() =>
{
lock (player.ActionLock)
if (player.ResetPlayerState(stateNum))
{
if (stateNum == player.StateNum)
gameMap.RemoveJustFromMap(craftingBench);
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player);
if (golem == null)
{
gameMap.RemoveJustFromMap(craftingBench);
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player);
if (golem == null)
{
((SummonGolem)activeSkill).AddGolem(num);
}
player.SetPlayerStateNaturally();
player.ThreadNum.Release();
((SummonGolem)activeSkill).AddGolem(num);
}
player.ThreadNum.Release();
}
}
);
@@ -373,34 +367,36 @@ namespace Gaming

public bool HaveTea(Character player, int angle1000)
{
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.UsingSkill);
if (stateNum == -1)
{
return false;
}
player.ThreadNum.WaitOne();

XY res = player.Position + new XY(angle1000 / 1000.0, GameData.distanceOfHaveTea);
Debugger.Output(res.ToString());
if (actionManager.moveEngine.CheckCollision(player, res) != null)
{
player.ThreadNum.Release();
return false;
}
Debugger.Output("NO Collision!");
player.ReSetPos(res);
lock (player.ActionLock)
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.HaveTea), player, () =>
{
if (player.StateNum == stateNum)
player.ThreadNum.WaitOne();

XY res = player.Position + new XY(angle1000 / 1000.0, GameData.distanceOfHaveTea);
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
player.SetPlayerStateNaturally();
player.ThreadNum.Release();
}
else
{
if (actionManager.moveEngine.CheckCollision(player, res) != null)
{
player.ThreadNum.Release();
}
else
{
Debugger.Output("NO Collision!");
player.ReSetPos(res);
player.ThreadNum.Release();
player.ResetPlayerState(stateNum);
Debugger.Output(player, "have tea!");
}
}
}
player.ThreadNum.Release();

return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.HaveTea), player, () =>
{
Debugger.Output(player, "have tea!");
},
() =>
{ });
@@ -416,13 +412,16 @@ namespace Gaming
{
foreach (Character character in gameMap.GameObjDict[GameObjType.Character])
{
if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character))
lock (character.ActionLock)
{
character.SetPlayerState();
character.HP = GameData.RemainHpWhenAddLife;
((Student)character).TimeOfRescue = 0;
player.AddScore(GameData.StudentScoreRescue);
break;
if ((character.PlayerState == PlayerStateType.Addicted) && gameMap.CanSee(player, character))
{
character.SetPlayerStateNaturally();
character.HP = GameData.RemainHpWhenAddLife;
((Student)character).SetTimeOfRescue(0);
player.AddScore(GameData.StudentScoreRescue);
break;
}
}
}
}


+ 2
- 1
logic/Preparation/Interface/ICharacter.cs View File

@@ -15,7 +15,8 @@ namespace Preparation.Interface
public CharacterType CharacterType { get; }
public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType);
public int UpdateBulletNum(int time);
public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null);
public long SetPlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null);
public bool ResetPlayerState(long state, RunningStateType running = RunningStateType.Null, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null);

public bool IsGhost();
}


+ 8
- 0
logic/Preparation/Utility/EnumType.cs View File

@@ -27,6 +27,14 @@ namespace Preparation.Utility
Charmed = 18,
OpeningTheDoor = 19,
}
public enum RunningStateType
{
Null = 0,
Waiting = 1,
RunningActively = 2,
RunningSleepily = 3,
RunningForcibly = 4,
}
public enum GameObjType
{
Null = 0,


+ 1
- 1
logic/Preparation/Utility/GameData.cs View File

@@ -105,7 +105,7 @@ namespace Preparation.Utility
public const int basicTimeOfRescue = 1000;

#if DEBUG
public const int basicStudentMoveSpeed = 3000;// 基本移动速度,单位:s-1
public const int basicStudentMoveSpeed = 9000;// 基本移动速度,单位:s-1
#else
public const int basicStudentMoveSpeed = 3000;
#endif


+ 2
- 2
logic/Server/GameServer.cs View File

@@ -133,7 +133,7 @@ namespace Server
currentGameInfo.ObjMessage.Add(currentMapMsg);
IsSpectatorJoin = false;
}
int time = game.GameMap.Timer.nowTime();
int time = Environment.TickCount;
foreach (GameObj gameObj in gameObjList)
{
MessageOfObj? msg = CopyInfo.Auto(gameObj, time);
@@ -149,7 +149,7 @@ namespace Server
currentNews.Clear();
}
currentGameInfo.GameState = gameState;
currentGameInfo.AllMessage = GetMessageOfAll(time);
currentGameInfo.AllMessage = GetMessageOfAll(game.GameMap.Timer.nowTime());
mwr?.WriteOne(currentGameInfo);
break;
default:


Loading…
Cancel
Save