Browse Source

Merge pull request #583 from shangfengh/new

fix: 🐛 fix the bug about numOfNoHpStudent
tags/v0.1.0
Changli Tang GitHub 2 years ago
parent
commit
95f844a3eb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 86 deletions
  1. +8
    -2
      docs/版本更新说明.md
  2. +6
    -4
      logic/GameClass/GameObj/Character/Character.cs
  3. +2
    -2
      logic/GameClass/GameObj/GameObj.cs
  4. +64
    -62
      logic/GameClass/GameObj/Map/Map.cs
  5. +4
    -4
      logic/Gaming/ActionManager.cs
  6. +15
    -12
      logic/Gaming/CharacterManager.cs

+ 8
- 2
docs/版本更新说明.md View File

@@ -52,6 +52,12 @@
- docs:更新了 游戏机制与平衡性调整更新草案.pdf
- feat:游戏机制与平衡性调整已完成

# 5月20日更新
# 5月20日18:00更新
- docs:更新了 游戏机制与平衡性调整更新(基本不变版).pdf
- fix:修复了Pubnish技能眩晕时长的错误
- fix:修复了Pubnish技能眩晕时长的错误

# 5月20日23:30更新
- fix:修复了学习已经完成的作业会卡死的问题

# 5月21日更新
- fix:修复了游戏结束判定的bug

+ 6
- 4
logic/GameClass/GameObj/Character/Character.cs View File

@@ -455,13 +455,13 @@ namespace GameClass.GameObj
case PlayerStateType.Addicted:
if (value == PlayerStateType.Rescued)
return ChangePlayerStateInOneThread(value, gameObj);
else if (value == PlayerStateType.Null)
else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased)
return ChangePlayerState(value, gameObj);
else return -1;
case PlayerStateType.Rescued:
if (value == PlayerStateType.Addicted)
return ChangePlayerStateInOneThread(value, gameObj);
else if (value == PlayerStateType.Null)
else if (value == PlayerStateType.Null || value == PlayerStateType.Deceased)
return ChangePlayerState(value, gameObj);
else return -1;

@@ -590,15 +590,17 @@ namespace GameClass.GameObj
}
}

public void RemoveFromGame(PlayerStateType playerStateType)
public bool TryToRemoveFromGame(PlayerStateType playerStateType)
{
lock (actionLock)
{
TryToRemove();
if (!TryToRemove()) return false;
Debugger.Output(this, "TryToRemove");
ReSetCanMove(false);
SetPlayerState(playerStateType);
position = GameData.PosWhoDie;
}
return true;
}
#endregion



+ 2
- 2
logic/GameClass/GameObj/GameObj.cs View File

@@ -43,9 +43,9 @@ namespace GameClass.GameObj
return (Interlocked.CompareExchange(ref isRemoved, 0, 0) == 1);
}
}
public virtual void TryToRemove()
public virtual bool TryToRemove()
{
Interlocked.Exchange(ref isRemoved, 1);
return Interlocked.Exchange(ref isRemoved, 1) == 0;
}

public int Radius { get; }


+ 64
- 62
logic/GameClass/GameObj/Map/Map.cs View File

@@ -11,58 +11,14 @@ namespace GameClass.GameObj
private readonly Dictionary<uint, XY> birthPointList; // 出生点列表
public Dictionary<uint, XY> BirthPointList => birthPointList;

private readonly object lockForNum = new();
private void WhenStudentNumChange()
{
if (numOfDeceasedStudent + numOfEscapedStudent == GameData.numOfStudent)
{
Timer.IsGaming = false;
return;
}

if (GameData.numOfStudent - numOfDeceasedStudent - numOfEscapedStudent == 1)
{
GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character player in GameObjDict[GameObjType.Character])
if (player.PlayerState == PlayerStateType.Addicted)
{
Timer.IsGaming = false;
break;
}
}
finally
{
GameObjLockDict[GameObjType.Character].ExitReadLock();
}
if (Timer.IsGaming)
{
GameObjLockDict[GameObjType.EmergencyExit].EnterWriteLock();
try
{
foreach (EmergencyExit emergencyExit in GameObjDict[GameObjType.EmergencyExit])
if (emergencyExit.CanOpen)
{
emergencyExit.IsOpen = true;
break;
}
}
finally
{
GameObjLockDict[GameObjType.EmergencyExit].ExitWriteLock();
}
}
}
}
private uint numOfRepairedGenerators = 0;
public uint NumOfRepairedGenerators
{
get => Interlocked.CompareExchange(ref numOfDeceasedStudent, 0, 0);
get => Interlocked.CompareExchange(ref numOfRepairedGenerators, 0, 0);
}
public void AddNumOfRepairedGenerators()
{
uint value = Interlocked.Increment(ref numOfDeceasedStudent);
uint value = Interlocked.Increment(ref numOfRepairedGenerators);
if (value == GameData.numOfGeneratorRequiredForEmergencyExit)
{
GameObjLockDict[GameObjType.EmergencyExit].EnterWriteLock();
@@ -93,33 +49,79 @@ namespace GameClass.GameObj
}
}
}

private uint numOfDeceasedStudent = 0;
public uint NumOfDeceasedStudent
{
get => numOfDeceasedStudent;
set
{
lock (lockForNum)
{
numOfDeceasedStudent = value;
WhenStudentNumChange();
}
}
get => Interlocked.CompareExchange(ref numOfDeceasedStudent, 0, 0);
}
private uint numOfEscapedStudent = 0;
public uint NumOfEscapedStudent
{
get => numOfEscapedStudent;
set
get => Interlocked.CompareExchange(ref numOfEscapedStudent, 0, 0);
}
private uint numOfNoHpStudent = 0;
public uint NumOfNoHpStudent
{
get => Interlocked.CompareExchange(ref numOfNoHpStudent, 0, 0);
}
private uint numOfRemovedStudent = 0;
public uint NumOfRemovedStudent
{
get => Interlocked.CompareExchange(ref numOfRemovedStudent, 0, 0);
}

public void MapEscapeStudent()
{
if (Interlocked.Increment(ref numOfNoHpStudent) == GameData.numOfStudent)
{
lock (lockForNum)
{
numOfEscapedStudent = value;
WhenStudentNumChange();
}
Timer.IsGaming = false;
return;
}
Interlocked.Increment(ref numOfEscapedStudent);
if (Interlocked.Increment(ref numOfRemovedStudent) == GameData.numOfStudent - 1)
OpenEmergencyExit();
}
public void MapDieStudent()
{
if (Interlocked.Increment(ref numOfNoHpStudent) == GameData.numOfStudent)
{
Timer.IsGaming = false;
return;
}
Interlocked.Increment(ref numOfDeceasedStudent);
if (Interlocked.Increment(ref numOfRemovedStudent) == GameData.numOfStudent - 1)
OpenEmergencyExit();
}
public void MapAddictStudent()
{
if (Interlocked.Increment(ref numOfNoHpStudent) == GameData.numOfStudent)
Timer.IsGaming = false;
}
public void MapRescueStudent()
{
Interlocked.Decrement(ref numOfNoHpStudent);
}

private void OpenEmergencyExit()
{
GameObjLockDict[GameObjType.EmergencyExit].EnterReadLock();
try
{
foreach (EmergencyExit emergencyExit in GameObjDict[GameObjType.EmergencyExit])
if (emergencyExit.CanOpen)
{
emergencyExit.IsOpen = true;
break;
}
}
finally
{
GameObjLockDict[GameObjType.EmergencyExit].ExitReadLock();
}
}


private Dictionary<GameObjType, IList<IGameObj>> gameObjDict;
public Dictionary<GameObjType, IList<IGameObj>> GameObjDict => gameObjDict;
private Dictionary<GameObjType, ReaderWriterLockSlim> gameObjLockDict;


+ 4
- 4
logic/Gaming/ActionManager.cs View File

@@ -163,8 +163,8 @@ namespace Gaming
if (doorwayForEscape != null && doorwayForEscape.IsOpen())
{
player.AddScore(GameData.StudentScoreEscape);
++gameMap.NumOfEscapedStudent;
player.RemoveFromGame(PlayerStateType.Escaped);
gameMap.MapEscapeStudent();
player.TryToRemoveFromGame(PlayerStateType.Escaped);
return true;
}
else
@@ -173,8 +173,8 @@ namespace Gaming
if (emergencyExit != null && emergencyExit.IsOpen)
{
player.AddScore(GameData.StudentScoreEscape);
++gameMap.NumOfEscapedStudent;
player.RemoveFromGame(PlayerStateType.Escaped);
gameMap.MapEscapeStudent();
player.TryToRemoveFromGame(PlayerStateType.Escaped);
return true;
}
return false;


+ 15
- 12
logic/Gaming/CharacterManager.cs View File

@@ -218,13 +218,18 @@ namespace Gaming

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

if (player.CharacterType == CharacterType.Robot)
{
ghost.AddScore(GameData.TrickerScoreDestroyRobot);
Die(player);
return;
}
ghost.AddScore(GameData.TrickerScoreStudentBeAddicted);
if (player.GamingAddiction > 0)
{
if (player.GamingAddiction < GameData.BeginGamingAddiction)
@@ -238,16 +243,16 @@ namespace Gaming
return;
}
}
player.SetPlayerState(PlayerStateType.Addicted);
long threadNum = player.StateNum;
ghost.AddScore(GameData.TrickerScoreStudentBeAddicted);

gameMap.MapAddictStudent();
new Thread
(() =>
{
#if DEBUG
Debugger.Output(player, " is addicted ");
#endif
new FrameRateTaskExecutor<int>(
() => threadNum == player.StateNum && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming,
() => stateNum == player.StateNum && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming,
() =>
{
player.GamingAddiction += (player.PlayerState == PlayerStateType.Addicted) ? GameData.frameDuration : 0;
@@ -255,6 +260,7 @@ namespace Gaming
timeInterval: GameData.frameDuration,
() =>
{
gameMap.MapRescueStudent();
if (player.GamingAddiction == player.MaxGamingAddiction && gameMap.Timer.IsGaming)
{
ghost.AddScore(GameData.TrickerScoreStudentDie);
@@ -397,11 +403,9 @@ namespace Gaming

public void Die(Student player)
{
#if DEBUG
Debugger.Output(player, "die.");
#endif
if (player.PlayerState == PlayerStateType.Deceased) return;
player.RemoveFromGame(PlayerStateType.Deceased);

if (!player.TryToRemoveFromGame(PlayerStateType.Deceased)) return;

for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++)
{
@@ -430,9 +434,8 @@ namespace Gaming
}
return;
}
++gameMap.NumOfDeceasedStudent;
gameMap.MapDieStudent();
}

}
}
}

Loading…
Cancel
Save