Browse Source

Merge pull request #594 from eesast/dev

fix: 🚑 fix the bug about Semaphore
tags/v0.1.0
shangfengh GitHub 2 years ago
parent
commit
c3fd843cc9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 508 additions and 373 deletions
  1. +1
    -0
      docs/GameRules.md
  2. +7
    -1
      docs/版本更新说明.md
  3. +10
    -10
      logic/GameClass/GameObj/Character/Character.Student.cs
  4. +89
    -78
      logic/GameClass/GameObj/Character/Character.cs
  5. +5
    -3
      logic/GameClass/GameObj/Map/Chest.cs
  6. +20
    -6
      logic/GameClass/GameObj/Map/Door.cs
  7. +14
    -0
      logic/GameClass/GameObj/Moveable.cs
  8. +1
    -7
      logic/GameClass/GameObj/Prop/Item.cs
  9. +260
    -171
      logic/Gaming/ActionManager.cs
  10. +18
    -9
      logic/Gaming/AttackManager.cs
  11. +9
    -22
      logic/Gaming/CharacterManager.cs
  12. +1
    -1
      logic/Gaming/Game.cs
  13. +62
    -63
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  14. +2
    -1
      logic/Preparation/Interface/ICharacter.cs
  15. +8
    -0
      logic/Preparation/Utility/EnumType.cs
  16. +1
    -1
      logic/Server/GameServer.cs

+ 1
- 0
docs/GameRules.md View File

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


#### 技术宅TechOtaku #### 技术宅TechOtaku
- 特性 - 特性


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

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


# 5月21日更新 # 5月21日更新
- docs:更新了 游戏机制与平衡性调整更新(基本不变版).pdf - 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.Utility;
using Preparation.Interface; using Preparation.Interface;
using System; using System;
using System.Threading;


namespace GameClass.GameObj namespace GameClass.GameObj
{ {
@@ -108,16 +109,15 @@ namespace GameClass.GameObj
private int timeOfRescue = 0; private int timeOfRescue = 0;
public int TimeOfRescue 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) 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); || playerState == PlayerStateType.Null || playerState == PlayerStateType.Moving);
} }
private GameObj? whatInteractingWith = null; private GameObj? whatInteractingWith = null;
public GameObj? WhatInteractingWith => whatInteractingWith;
public GameObj? WhatInteractingWith
{
get
{
lock (actionLock)
{
return whatInteractingWith;
}
}
}


private long ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
public bool StartThread(long stateNum, RunningStateType runningState)
{
lock (ActionLock)
{
if (this.StateNum == stateNum)
{
this.runningState = runningState;
return true;
}
}
return false;
}

private long ChangePlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
{ {
//只能被SetPlayerState引用 //只能被SetPlayerState引用
if (runningState == RunningStateType.RunningSleepily)
{
ThreadNum.Release();
}
runningState = running;
whatInteractingWith = gameObj; whatInteractingWith = gameObj;
playerState = value; playerState = value;
//Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString());
return ++stateNum; 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引用 //只能被SetPlayerState引用
whatInteractingWith = gameObj; whatInteractingWith = gameObj;
playerState = value; playerState = value;
//Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString());
return stateNum; 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; GameObj? gameObj = (GameObj?)obj;
lock (actionLock) lock (actionLock)
{ {
PlayerStateType nowPlayerState = PlayerState; PlayerStateType nowPlayerState = PlayerState;
if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1; if (nowPlayerState == value && value != PlayerStateType.UsingSkill) return -1;
GameObj? lastObj = whatInteractingWith;
switch (nowPlayerState) switch (nowPlayerState)
{ {
case PlayerStateType.Escaped: case PlayerStateType.Escaped:
@@ -454,119 +484,85 @@ namespace GameClass.GameObj


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


case PlayerStateType.TryingToAttack: case PlayerStateType.TryingToAttack:
if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null) || value == PlayerStateType.Charmed || value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1; else return -1;
case PlayerStateType.Stunned: case PlayerStateType.Stunned:
case PlayerStateType.Charmed: case PlayerStateType.Charmed:
if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased
|| value == PlayerStateType.Null) || value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
else return -1; else return -1;
case PlayerStateType.Swinging: case PlayerStateType.Swinging:
if (value == PlayerStateType.Addicted if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null) || value == PlayerStateType.Charmed || value == PlayerStateType.Null)
{
try
{
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
return ChangePlayerState(runningState, value, gameObj);
else return -1; else return -1;
case PlayerStateType.ClimbingThroughWindows: case PlayerStateType.ClimbingThroughWindows:
if (value == PlayerStateType.Addicted if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned || value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null) || 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; else return -1;


case PlayerStateType.OpeningTheChest: 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: 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: case PlayerStateType.OpeningTheDoor:
Door door = (Door)whatInteractingWith!;
try
{
door.StopOpen();
ReleaseTool(door.DoorNum switch
{
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
}
);
return ChangePlayerState(value, gameObj);
}
finally
if (value == PlayerStateType.Rescued) return -1;
Door door = (Door)lastObj!;
door.StopOpen();
ReleaseTool(door.DoorNum switch
{ {
ThreadNum.Release();
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
} }
);
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.UsingSkill: case PlayerStateType.UsingSkill:
{ {
if (value == PlayerStateType.Rescued) return -1;
switch (CharacterType) switch (CharacterType)
{ {
case CharacterType.TechOtaku: 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 else
{ {
if (value != PlayerStateType.UsingSkill) if (value != PlayerStateType.UsingSkill)
((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID; ((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID;
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
} }
} }
case CharacterType.Assassin: case CharacterType.Assassin:
@@ -574,14 +570,15 @@ namespace GameClass.GameObj
else else
{ {
TryDeleteInvisible(); TryDeleteInvisible();
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
} }
default: default:
return ChangePlayerState(value, gameObj);
return ChangePlayerState(runningState, value, gameObj);
} }
} }
default: 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) lock (actionLock)
{ {
runningState = RunningStateType.Null;
whatInteractingWith = null; whatInteractingWith = null;
playerState = PlayerStateType.Null; playerState = PlayerStateType.Null;
return ++stateNum; return ++stateNum;
} }
} }


public bool ResetPlayerState(long state)
{
lock (actionLock)
{
if (state != stateNum) return false;
runningState = RunningStateType.Null;
whatInteractingWith = null;
playerState = PlayerStateType.Null;
++stateNum;
return true;
}
}

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


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

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


namespace GameClass.GameObj namespace GameClass.GameObj
{ {
@@ -22,19 +23,20 @@ namespace GameClass.GameObj
public int OpenStartTime => openStartTime; public int OpenStartTime => openStartTime;
private Character? whoOpen = null; private Character? whoOpen = null;
public Character? WhoOpen => whoOpen; public Character? WhoOpen => whoOpen;
public void Open(int startTime, Character character)
public bool Open(Character character)
{ {
lock (GameObjReaderWriterLock) lock (GameObjReaderWriterLock)
{ {
openStartTime = startTime;
if (whoOpen != null) return false;
openStartTime = Environment.TickCount;
whoOpen = character; whoOpen = character;
} }
return true;
} }
public void StopOpen() public void StopOpen()
{ {
lock (GameObjReaderWriterLock) lock (GameObjReaderWriterLock)
{ {
openStartTime = 0;
whoOpen = null; 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 get
{ {
@@ -86,7 +86,7 @@ namespace GameClass.GameObj
{ {
if (isOpen) return false; if (isOpen) return false;
if (whoLockOrOpen != null) return false; if (whoLockOrOpen != null) return false;
openStartTime = Environment.TickCount64;
openStartTime = Environment.TickCount;
whoLockOrOpen = character; whoLockOrOpen = character;
return true; return true;
} }
@@ -97,7 +97,7 @@ namespace GameClass.GameObj
{ {
if (whoLockOrOpen != null) if (whoLockOrOpen != null)
{ {
if ((Environment.TickCount64 - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking)
if ((Environment.TickCount - openStartTime) >= GameData.degreeOfLockingOrOpeningTheDoor / whoLockOrOpen.SpeedOfOpeningOrLocking)
isOpen = true; isOpen = true;
whoLockOrOpen = null; whoLockOrOpen = null;
} }
@@ -153,9 +153,23 @@ namespace GameClass.GameObj
if (character != null) if (character != null)
{ {
lock (character.ActionLock) lock (character.ActionLock)
{
if (character.PlayerState == PlayerStateType.OpeningTheDoor) 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();
}
}
} }
} }
} }
}
}

+ 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 public override XY Position
{ {
get get


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

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


+ 260
- 171
logic/Gaming/ActionManager.cs View File

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


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


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


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

generatorForFix.AddNumOfFixing();
new Thread 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); Thread.Sleep(GameData.checkInterval);
new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming, loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
@@ -106,9 +118,11 @@ namespace Gaming
lock (player.ActionLock) lock (player.ActionLock)
{ {
if (stateNum == player.StateNum) if (stateNum == player.StateNum)
player.SetPlayerState();
player.SetPlayerState(RunningStateType.Null);
} }
return false;
} }
return true;
}, },
timeInterval: GameData.checkInterval, timeInterval: GameData.checkInterval,
finallyReturn: () => 0 finallyReturn: () => 0
@@ -129,34 +143,27 @@ namespace Gaming
Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); Doorway? doorwayToOpen = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
if (doorwayToOpen == null) return false; 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; if (stateNum == -1) return false;
new Thread new Thread
( (
() => () =>
{ {
player.ThreadNum.WaitOne(); 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(); doorwayToOpen.TryToOpen();
Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree); 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(); { IsBackground = true }.Start();


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


public bool Escape(Student player) 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; return false;

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


new Thread 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>( new FrameRateTaskExecutor<int>(
loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () => 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 finallyReturn: () => 0
) )
.Start(); .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(); { IsBackground = true }.Start();
return true; return true;
} }

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


if ((!player.Commandable()) || playerRescued.PlayerState != PlayerStateType.Addicted || !GameData.ApproachToInteract(playerRescued.Position, player.Position))
long stateNumRescued = playerRescued.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescued);
if (stateNumRescued == -1) return false;

long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.Rescuing);
if (stateNum == -1)
{
lock (playerRescued.ActionLock)
{
if (playerRescued.StateNum == stateNumRescued)
player.SetPlayerStateNaturally();
}
return false; return false;
player.SetPlayerState(PlayerStateType.Rescuing);
playerRescued.SetPlayerState(PlayerStateType.Rescued);
long threadNum = player.StateNum;
}


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

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

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

new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () => loopToDo: () =>
{ {
playerRescued.TimeOfRescue += GameData.frameDuration;
lock (playerRescued.ActionLock)
{
if (playerRescued.StateNum == stateNumRescued)
{
if (playerRescued.AddTimeOfRescue(GameData.checkInterval * player.TreatSpeed))
{
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(); .Start();
playerRescued.SetTimeOfRescue(0);


if (playerRescued.PlayerState == PlayerStateType.Rescued)
if (player.ResetPlayerState(stateNum)) return;

lock (playerRescued.ActionLock)
{ {
if (playerRescued.TimeOfRescue >= GameData.basicTimeOfRescue)
if (playerRescued.StateNum == stateNumRescued)
{ {
playerRescued.SetPlayerState();
playerRescued.HP = playerRescued.MaxHp / 2;
player.AddScore(GameData.StudentScoreRescue);
playerRescued.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.Addicted);
return;
} }
else
playerRescued.SetPlayerState(PlayerStateType.Addicted);
} }
if (threadNum == player.StateNum) player.SetPlayerState();
playerRescued.TimeOfRescue = 0;
} }
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();


return true; return true;
} }

public bool OpenChest(Character player) public bool OpenChest(Character player)
{ {
if ((!player.Commandable()) || player.PlayerState == PlayerStateType.OpeningTheChest)
return false;
Chest? chestToOpen = (Chest?)gameMap.OneForInteract(player.Position, GameObjType.Chest); 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 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); 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) for (int i = 0; i < GameData.maxNumOfPropInChest; ++i)
{ {
Gadget prop = chestToOpen.PropInChest[i]; Gadget prop = chestToOpen.PropInChest[i];
@@ -321,7 +433,7 @@ namespace Gaming
Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window); Window? windowForClimb = (Window?)gameMap.OneForInteractInACross(player.Position, GameObjType.Window);
if (windowForClimb == null) return false; 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; if (stateNum == -1) return false;


XY windowToPlayer = new( XY windowToPlayer = new(
@@ -344,43 +456,43 @@ namespace Gaming
() => () =>
{ {
player.ThreadNum.WaitOne(); player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
lock (player.ActionLock)
{ {
player.ThreadNum.Release();
}
else
{
if (!windowForClimb.TryToClimb(player))
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{ {
player.ThreadNum.Release(); 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();
} }
} }
} }
@@ -404,7 +516,7 @@ namespace Gaming


if (!player.UseTool(propType)) return false; 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) if (stateNum == -1)
{ {
player.ReleaseTool(propType); player.ReleaseTool(propType);
@@ -416,47 +528,37 @@ namespace Gaming
() => () =>
{ {
player.ThreadNum.WaitOne(); player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{ {
player.ReleaseTool(propType); player.ReleaseTool(propType);
player.ThreadNum.Release(); 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(); { IsBackground = true }.Start();
@@ -479,7 +581,7 @@ namespace Gaming


if (!player.UseTool(propType)) return false; 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) if (stateNum == -1)
{ {
player.ReleaseTool(propType); player.ReleaseTool(propType);
@@ -491,42 +593,29 @@ namespace Gaming
() => () =>
{ {
player.ThreadNum.WaitOne(); player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
if (!player.StartThread(stateNum, RunningStateType.RunningSleepily))
{ {
player.ReleaseTool(propType); player.ReleaseTool(propType);
player.ThreadNum.Release(); 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(); { IsBackground = true }.Start();




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

@@ -30,7 +30,7 @@ namespace Gaming
}, },
EndMove: obj => 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) if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty)
BulletBomb((Bullet)obj, null); BulletBomb((Bullet)obj, null);
obj.ReSetCanMove(false); obj.ReSetCanMove(false);
@@ -201,6 +201,8 @@ namespace Gaming


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

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


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


if (bullet.CastTime > 0) 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 new Thread
(() => (() =>
{ {
player.ThreadNum.WaitOne();
if (!player.StartThread(stateNum, RunningStateType.RunningActively))
{
TryRemoveBullet(bullet);
return;
}
new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => threadNum == player.StateNum && gameMap.Timer.IsGaming,
loopCondition: () => stateNum == player.StateNum && gameMap.Timer.IsGaming,
loopToDo: () => loopToDo: () =>
{ {
}, },
@@ -231,11 +243,8 @@ namespace Gaming


if (gameMap.Timer.IsGaming) 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) 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) if (player.CharacterType == CharacterType.Robot)
{ {
@@ -278,19 +275,18 @@ namespace Gaming
public static long BeStunned(Character player, int time) public static long BeStunned(Character player, int time)
{ {
if (player.CharacterType == CharacterType.Robot) return -1; 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 new Thread
(() => (() =>
{ {
Debugger.Output(player, " is stunned for " + time.ToString()); Debugger.Output(player, " is stunned for " + time.ToString());
Thread.Sleep(time); Thread.Sleep(time);
if (threadNum == player.StateNum)
player.SetPlayerState();
player.ResetPlayerState(stateNum);
} }
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
return threadNum;
return stateNum;
} }


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


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

lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.ThreadNum.Release();
player.SetPlayerStateNaturally();
}
}
player.ResetPlayerState(stateNum);
} }
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
@@ -428,7 +415,7 @@ namespace Gaming
lock (parent.ActionLock) lock (parent.ActionLock)
{ {
if (parent.PlayerState == PlayerStateType.UsingSkill) 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) if (!gameMap.Timer.IsGaming)
return false; return false;
Character? player = gameMap.FindPlayerToAction(playerID); Character? player = gameMap.FindPlayerToAction(playerID);
if (player != null && player.Commandable())
if (player != null)
{ {
return attackManager.Attack(player, angle); 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) public static bool BecomeInvisible(Character player)
{ {
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible); ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible);
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill);
if (stateNum == -1) if (stateNum == -1)
{ {
return false; 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) public static bool UseRobot(Character player, int robotID)
@@ -141,7 +135,7 @@ namespace Gaming
activeSkill.NowPlayerID = robotID; activeSkill.NowPlayerID = robotID;
} }
else return false; else return false;
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.RunningForcibly, PlayerStateType.UsingSkill);
if (stateNum == -1) if (stateNum == -1)
{ {
activeSkill.NowPlayerID = (int)player.PlayerID; activeSkill.NowPlayerID = (int)player.PlayerID;
@@ -250,48 +244,48 @@ namespace Gaming
{ {
CraftingBench craftingBench = new(res, player, num); 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) if (stateNum == -1)
{ {
((SummonGolem)activeSkill).DeleteGolem(num); ((SummonGolem)activeSkill).DeleteGolem(num);
return false; 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, () => 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) public bool HaveTea(Character player, int angle1000)
{ {
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
long stateNum = player.SetPlayerState(RunningStateType.Waiting, PlayerStateType.UsingSkill);
if (stateNum == -1) if (stateNum == -1)
{ {
return false; 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]) 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 CharacterType CharacterType { get; }
public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType); public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType);
public int UpdateBulletNum(int time); 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);


public bool IsGhost(); public bool IsGhost();
} }


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

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


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

@@ -133,7 +133,7 @@ namespace Server
currentGameInfo.ObjMessage.Add(currentMapMsg); currentGameInfo.ObjMessage.Add(currentMapMsg);
IsSpectatorJoin = false; IsSpectatorJoin = false;
} }
int time = game.GameMap.Timer.nowTime();
int time = Environment.TickCount;
foreach (GameObj gameObj in gameObjList) foreach (GameObj gameObj in gameObjList)
{ {
MessageOfObj? msg = CopyInfo.Auto(gameObj, time); MessageOfObj? msg = CopyInfo.Auto(gameObj, time);


Loading…
Cancel
Save