Browse Source

refactor: 🚧 refactor the fuctions of LockDoor and OpenDoor

tags/v0.1.0
shangfengh 3 years ago
parent
commit
cd65ab8a9e
11 changed files with 328 additions and 84 deletions
  1. +1
    -0
      docs/GameRules.md
  2. +81
    -14
      logic/GameClass/GameObj/Character/Character.cs
  3. +107
    -12
      logic/GameClass/GameObj/Map/Door.cs
  4. +115
    -49
      logic/Gaming/ActionManager.cs
  5. +13
    -2
      logic/Gaming/Game.cs
  6. +1
    -1
      logic/Gaming/PropManager.cs
  7. +3
    -1
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  8. +2
    -1
      logic/Preparation/Utility/EnumType.cs
  9. +2
    -1
      logic/Preparation/Utility/Transformation.cs
  10. +1
    -1
      logic/Server/CopyInfo.cs
  11. +2
    -2
      logic/Server/RpcServices.cs

+ 1
- 0
docs/GameRules.md View File

@@ -316,6 +316,7 @@ $$

### 道具
- 使用钥匙相当于销毁
- 可接受指令状态下能捡起或扔道具,在场上即可使用道具

### 交互
- 被唤醒或被勉励不属于交互状态,翻窗属于交互状态


+ 81
- 14
logic/GameClass/GameObj/Character/Character.cs View File

@@ -341,12 +341,14 @@ namespace GameClass.GameObj
set
{
lock (vampireLock)
{
if (value > 1)
vampire = 1;
else if (value < 0)
vampire = 0;
else
vampire = value;
}
}
}
public double OriVampire { get; protected set; }
@@ -394,7 +396,8 @@ namespace GameClass.GameObj
{
lock (actionLock)
{
return (playerState == PlayerStateType.LockingOrOpeningTheDoor || playerState == PlayerStateType.Fixing || playerState == PlayerStateType.OpeningTheChest);
return (playerState == PlayerStateType.LockingTheDoor || playerState == PlayerStateType.OpeningTheDoor
|| playerState == PlayerStateType.Fixing || playerState == PlayerStateType.OpeningTheChest);
}
}
public bool NullOrMoving()
@@ -465,41 +468,75 @@ namespace GameClass.GameObj
else return -1;

case PlayerStateType.TryingToAttack:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows)
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
return ChangePlayerState(value, gameObj);
else return -1;
case PlayerStateType.Stunned:
case PlayerStateType.Charmed:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows && value != PlayerStateType.Swinging)
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor
&& value != PlayerStateType.Swinging)
return ChangePlayerState(value, gameObj);
else return -1;
case PlayerStateType.Swinging:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows)
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
{
ThreadNum.Release();
return ChangePlayerState(value, gameObj);
try
{
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
else return -1;
case PlayerStateType.ClimbingThroughWindows:
if (value != PlayerStateType.Moving)
if (value != PlayerStateType.Moving && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
{
Window window = (Window)WhatInteractingWith!;
window.FinishClimbing();
if (window.Stage.x == 0)
ThreadNum.Release();
else ReSetPos(window.Stage);
return ChangePlayerState(value, gameObj);
try
{
window.FinishClimbing();
return ChangePlayerState(value, gameObj);
}
finally
{
if (window.Stage.x == 0)
ThreadNum.Release();
else ReSetPos(window.Stage);
}
}
else return -1;

case PlayerStateType.OpeningTheChest:
((Chest)WhatInteractingWith!).StopOpen();
((Chest)whatInteractingWith!).StopOpen();
return ChangePlayerState(value, gameObj);
case PlayerStateType.OpeningTheDoorway:
Doorway doorway = (Doorway)WhatInteractingWith!;
Doorway doorway = (Doorway)whatInteractingWith!;
doorway.StopOpenning();
return ChangePlayerState(value, gameObj);

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
{
ThreadNum.Release();
}
default:
return ChangePlayerState(value, gameObj);
}
@@ -638,6 +675,36 @@ namespace GameClass.GameObj
return new NullProp();
}

public bool UseTool(PropType propType)
{
lock (inventoryLock)
{
for (int indexing = 0; indexing < GameData.maxNumOfPropInPropInventory; ++indexing)
{
if (PropInventory[indexing].GetPropType() == propType && PropInventory[indexing].IsUsable())
{
return ((Tool)PropInventory[indexing]).IsUsed = true;
}
}
}
return false;
}

public void ReleaseTool(PropType propType)
{
lock (inventoryLock)
{
for (int indexing = 0; indexing < GameData.maxNumOfPropInPropInventory; ++indexing)
{
if (PropInventory[indexing].GetPropType() == propType && ((Tool)PropInventory[indexing]).IsUsed)
{
((Tool)PropInventory[indexing]).IsUsed = false;
break;
}
}
}
}

/// <summary>
/// 如果indexing==GameData.maxNumOfPropInPropInventory表明道具栏为满
/// </summary>


+ 107
- 12
logic/GameClass/GameObj/Map/Door.cs View File

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

namespace GameClass.GameObj
{
@@ -32,30 +34,123 @@ namespace GameClass.GameObj
public override bool IsRigid => !isOpen;
public override ShapeType Shape => ShapeType.Square;

private Character? whoLockOrOpen = null;
public Character? WhoLockOrOpen
{
get
{
lock (gameObjLock)
return whoLockOrOpen;
}
}

private bool isOpen = true;
public bool IsOpen
{
get => isOpen;
set
get
{
lock (gameObjLock)
isOpen = value;
return isOpen;
}
}

private int openOrLockDegree = 0;
public int OpenOrLockDegree
private int lockDegree = 0;
public int LockDegree
{
get => openOrLockDegree;
get
{
lock (gameObjLock)
return lockDegree;
}
set
{
if (value > 0)
lock (gameObjLock)
openOrLockDegree = (value > GameData.degreeOfLockingOrOpeningTheDoor) ? GameData.degreeOfLockingOrOpeningTheDoor : value;
else
lock (gameObjLock)
openOrLockDegree = 0;
value = (value > GameData.degreeOfLockingOrOpeningTheDoor) ? GameData.degreeOfLockingOrOpeningTheDoor : value;
lock (gameObjLock)
lockDegree = value;
}
}

private long openStartTime = 0;
public long OpenStartTime
{
get
{
lock (gameObjLock)
return openStartTime;
}
}

public bool TryOpen(Character character)
{
lock (gameObjLock)
{
if (isOpen) return false;
if (whoLockOrOpen != null) return false;
openStartTime = Environment.TickCount64;
whoLockOrOpen = character;
return true;
}
}
public void StopOpen()
{
lock (gameObjLock)
{
if (whoLockOrOpen != null)
{
if (Environment.TickCount64 - openStartTime >= GameData.degreeOfLockingOrOpeningTheDoor)
isOpen = true;
whoLockOrOpen = null;
}
}
}
public void FinishOpen()
{
lock (gameObjLock)
{
isOpen = true;
whoLockOrOpen = null;
}
}

public bool TryLock(Character character)
{
lock (gameObjLock)
{
if (!isOpen) return false;
if (whoLockOrOpen != null) return false;
lockDegree = 0;
whoLockOrOpen = character;
return true;
}
}
public void StopLock()
{
lock (gameObjLock)
{
if (lockDegree >= GameData.degreeOfLockingOrOpeningTheDoor)
isOpen = true;
whoLockOrOpen = null;
}
}
public void FinishLock()
{
lock (gameObjLock)
{
isOpen = false;
whoLockOrOpen = null;
}
}

public void ForceToOpen()
{
Character? character;
lock (gameObjLock)
{
character = whoLockOrOpen;
whoLockOrOpen = null;
isOpen = true;
}
if (character != null) character.SetPlayerState();
}
}
}

+ 115
- 49
logic/Gaming/ActionManager.cs View File

@@ -389,67 +389,133 @@ namespace Gaming

return true;
}
public bool LockOrOpenDoor(Character player)
public bool LockDoor(Character player)
{
if (player.CharacterType == CharacterType.Robot) return false;
Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
if (doorToLock == null) return false;
bool flag = false;
foreach (Gadget prop in player.PropInventory)

PropType propType = doorToLock.DoorNum switch
{
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
};

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

long stateNum = player.SetPlayerState(PlayerStateType.LockingTheDoor, doorToLock);
if (stateNum == -1)
{
switch (prop.GetPropType())
player.ReleaseTool(propType);
return false;
}

new Thread
(
() =>
{
case PropType.Key3:
if (doorToLock.DoorNum == 3)
flag = true;
break;
case PropType.Key5:
if (doorToLock.DoorNum == 5)
flag = true;
break;
case PropType.Key6:
if (doorToLock.DoorNum == 6)
flag = true;
break;
default:
break;
player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
{
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
else
{
if (!doorToLock.TryLock(player))
{
player.ReleaseTool(propType);
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();
if (stateNum == player.StateNum) player.SetPlayerState();
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
}
}
if (flag) break;
}
if (!flag) return false;
)
{ IsBackground = true }.Start();

if (doorToLock.OpenOrLockDegree > 0 || gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character) != null)
return false;
if (!(player.Commandable()) || player.PlayerState == PlayerStateType.LockingOrOpeningTheDoor)
return true;
}

public bool OpenDoor(Character player)
{
if (player.CharacterType == CharacterType.Robot) return false;
Door? doorToLock = (Door?)gameMap.OneForInteract(player.Position, GameObjType.Door);
if (doorToLock == null) return false;

PropType propType = doorToLock.DoorNum switch
{
3 => PropType.Key3,
5 => PropType.Key5,
_ => PropType.Key6,
};

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

long stateNum = player.SetPlayerState(PlayerStateType.OpeningTheDoor, doorToLock);
if (stateNum == -1)
{
player.ReleaseTool(propType);
return false;
}

player.SetPlayerState(PlayerStateType.LockingOrOpeningTheDoor);
long threadNum = player.StateNum;
new Thread
(
() =>
{
new FrameRateTaskExecutor<int>(
loopCondition: () => flag && threadNum == player.StateNum && gameMap.Timer.IsGaming && doorToLock.OpenOrLockDegree < GameData.degreeOfLockingOrOpeningTheDoor,
loopToDo: () =>
{
flag = ((gameMap.PartInTheSameCell(doorToLock.Position, GameObjType.Character)) == null);
doorToLock.OpenOrLockDegree += GameData.frameDuration * player.SpeedOfOpeningOrLocking;
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0
)
.Start();
if (doorToLock.OpenOrLockDegree >= GameData.degreeOfLockingOrOpeningTheDoor)
{
doorToLock.IsOpen = (!doorToLock.IsOpen);
}
if (threadNum == player.StateNum)
player.SetPlayerState();
doorToLock.OpenOrLockDegree = 0;
}
(
() =>
{
player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
{
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
else
{
if (!doorToLock.TryOpen(player))
{
player.ReleaseTool(propType);
player.SetPlayerState();
player.ThreadNum.Release();
}
else
{
Thread.Sleep(GameData.degreeOfLockingOrOpeningTheDoor / player.SpeedOfOpeningOrLocking);

)
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerState();
doorToLock.StopOpen();
player.ReleaseTool(propType);
player.ThreadNum.Release();
}
}
}
}
}
)
{ IsBackground = true }.Start();

return true;


+ 13
- 2
logic/Gaming/Game.cs View File

@@ -197,14 +197,25 @@ namespace Gaming
}
return false;
}
public bool LockOrOpenDoor(long playerID)
public bool LockDoor(long playerID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? player = gameMap.FindPlayerToAction(playerID);
if (player != null)
{
return actionManager.LockOrOpenDoor(player);
return actionManager.LockDoor(player);
}
return false;
}
public bool OpenDoor(long playerID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? player = gameMap.FindPlayerToAction(playerID);
if (player != null)
{
return actionManager.OpenDoor(player);
}
return false;
}


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

@@ -21,7 +21,7 @@ namespace Gaming

public void UseProp(Character player, PropType propType)
{
if (player.IsRemoved || player.CharacterType == CharacterType.Robot)
if (player.CharacterType == CharacterType.Robot || player.IsRemoved)
return;
Gadget prop = player.UseProp(propType);
switch (prop.GetPropType())


+ 3
- 1
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -216,7 +216,9 @@ namespace Gaming
{
if (character.IsGhost() &&
(character.PlayerState == PlayerStateType.TryingToAttack || character.PlayerState == PlayerStateType.Swinging
|| character.PlayerState == PlayerStateType.UsingSkill || character.PlayerState == PlayerStateType.LockingOrOpeningTheDoor || character.PlayerState == PlayerStateType.ClimbingThroughWindows)
|| character.PlayerState == PlayerStateType.UsingSkill
|| character.PlayerState == PlayerStateType.LockingTheDoor || character.PlayerState == PlayerStateType.OpeningTheDoor
|| character.PlayerState == PlayerStateType.ClimbingThroughWindows)
&& gameMap.CanSee(player, character))
{
if (characterManager.BeStunned(character, GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP)) > 0)


+ 2
- 1
logic/Preparation/Utility/EnumType.cs View File

@@ -19,12 +19,13 @@ namespace Preparation.Utility
Rescued = 10,
Stunned = 11,
TryingToAttack = 12,//指前摇
LockingOrOpeningTheDoor = 13,
LockingTheDoor = 13,
OpeningTheChest = 14,
ClimbingThroughWindows = 15,
UsingSkill = 16,
OpeningTheDoorway = 17,
Charmed = 18,
OpeningTheDoor = 19,
}
public enum GameObjType
{


+ 2
- 1
logic/Preparation/Utility/Transformation.cs View File

@@ -107,7 +107,8 @@ namespace Preparation.Utility
return PlayerState.Graduated;
case Preparation.Utility.PlayerStateType.Fixing:
return PlayerState.Learning;
case Preparation.Utility.PlayerStateType.LockingOrOpeningTheDoor:
case Preparation.Utility.PlayerStateType.LockingTheDoor:
case PlayerStateType.OpeningTheDoor:
return PlayerState.Locking;
case Preparation.Utility.PlayerStateType.OpeningTheChest:
return PlayerState.OpeningAChest;


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

@@ -256,7 +256,7 @@ namespace Server
{
X = door.Position.x,
Y = door.Position.y,
Progress = door.OpenOrLockDegree,
Progress = door.LockDegree,
IsOpen = door.IsOpen
}
};


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

@@ -471,7 +471,7 @@ namespace Server
return Task.FromResult(boolRes);
}
var gameID = communicationToGameID[request.PlayerId];
boolRes.ActSuccess = game.LockOrOpenDoor(gameID);
boolRes.ActSuccess = game.OpenDoor(gameID);
return Task.FromResult(boolRes);
}

@@ -487,7 +487,7 @@ namespace Server
return Task.FromResult(boolRes);
}
var gameID = communicationToGameID[request.PlayerId];
boolRes.ActSuccess = game.LockOrOpenDoor(gameID);
boolRes.ActSuccess = game.LockDoor(gameID);
return Task.FromResult(boolRes);
}



Loading…
Cancel
Save