Browse Source

Merge pull request #239 from shangfengh/new

refactor: 🎨 refactor the struction of code
tags/0.1.0
Shawqeem GitHub 2 years ago
parent
commit
c761e2db73
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 450 additions and 403 deletions
  1. +0
    -1
      logic/Client/StatusBarOfHunter.xaml.cs
  2. +1
    -28
      logic/GameClass/GameObj/Character/Character.Skill.cs
  3. +34
    -11
      logic/GameClass/GameObj/Character/Character.Student.cs
  4. +0
    -16
      logic/GameClass/GameObj/Character/Character.cs
  5. +0
    -250
      logic/GameClass/GameObj/Character/Skill.cs
  6. +1
    -1
      logic/GameClass/GameObj/Map/Generator.cs
  7. +14
    -41
      logic/Gaming/ActionManager.cs
  8. +1
    -1
      logic/Gaming/CharacterManager .cs
  9. +0
    -20
      logic/Gaming/Game.cs
  10. +57
    -1
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  11. +6
    -0
      logic/Gaming/SkillManager/SkillManager.cs
  12. +2
    -0
      logic/Preparation/Interface/ICharacter.cs
  13. +39
    -12
      logic/Preparation/Interface/IOccupation.cs
  14. +286
    -1
      logic/Preparation/Interface/ISkill.cs
  15. +2
    -0
      logic/Preparation/Utility/EnumType.cs
  16. +6
    -12
      logic/Preparation/Utility/GameData.cs
  17. +0
    -1
      logic/Server/GameServer.cs
  18. +1
    -7
      logic/规则Logic.md

+ 0
- 1
logic/Client/StatusBarOfHunter.xaml.cs View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;


+ 1
- 28
logic/GameClass/GameObj/Character/Character.Skill.cs View File

@@ -61,34 +61,7 @@ namespace GameClass.GameObj
this.CanMove = true; this.CanMove = true;
this.score = 0; this.score = 0;
this.buffManager = new BuffManager(); this.buffManager = new BuffManager();
switch (characterType)
{
case CharacterType.Assassin:
this.occupation = new Assassin();
break;
case CharacterType.Robot:
this.occupation = new Robot();
break;
case CharacterType.Teacher:
this.occupation = new Teacher();
break;
case CharacterType.Klee:
this.occupation = new Klee();
break;
case CharacterType.StraightAStudent:
this.occupation = new StraightAStudent();
break;
case CharacterType.ANoisyPerson:
this.occupation = new ANoisyPerson();
break;
case CharacterType.TechOtaku:
this.occupation = new TechOtaku();
break;
case CharacterType.Athlete:
default:
this.occupation = new Athlete();
break;
}
this.occupation = OccupationFactory.FindIOccupation(characterType);
this.MaxHp = this.hp = Occupation.MaxHp; this.MaxHp = this.hp = Occupation.MaxHp;
this.OrgMoveSpeed = this.moveSpeed = Occupation.MoveSpeed; this.OrgMoveSpeed = this.moveSpeed = Occupation.MoveSpeed;
this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet; this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet;


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

@@ -71,16 +71,39 @@ namespace GameClass.GameObj
public int DegreeOfTreatment public int DegreeOfTreatment
{ {
get => degreeOfTreatment; get => degreeOfTreatment;
set
private set
{ {
if (value > 0)
lock (gameObjLock)
degreeOfTreatment = (value < MaxHp - HP) ? value : MaxHp - HP;
else
lock (gameObjLock)
degreeOfTreatment = 0;
degreeOfTreatment = value;
} }
} }
public void SetDegreeOfTreatment0()
{
DegreeOfTreatment = 0;
}
public bool SetDegreeOfTreatment(int value, Student whoTreatYou)
{
if (value <= 0) { degreeOfTreatment = 0; return false; }
if (value >= MaxHp - HP)
{
whoTreatYou.AddScore(GameData.StudentScoreTreat(MaxHp - HP));
HP = MaxHp;
degreeOfTreatment = 0;
return true;
}
if (value >= GameData.basicTreatmentDegree)
{
whoTreatYou.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree));
HP += GameData.basicTreatmentDegree;
DegreeOfTreatment = 0;
return true;
}
DegreeOfTreatment = value;
return false;
}
public bool AddDegreeOfTreatment(int value, Student student)
{
return SetDegreeOfTreatment(value + degreeOfTreatment, student);
}


private int timeOfRescue = 0; private int timeOfRescue = 0;
public int TimeOfRescue public int TimeOfRescue
@@ -99,12 +122,12 @@ namespace GameClass.GameObj


public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType) public Student(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, characterType)
{ {
this.OrgFixSpeed = this.fixSpeed = ((IStudent)Occupation).FixSpeed;
this.TreatSpeed = this.OrgTreatSpeed = ((IStudent)Occupation).TreatSpeed;
this.MaxGamingAddiction = ((IStudent)Occupation).MaxGamingAddiction;
this.OrgFixSpeed = this.fixSpeed = ((IStudentType)Occupation).FixSpeed;
this.TreatSpeed = this.OrgTreatSpeed = ((IStudentType)Occupation).TreatSpeed;
this.MaxGamingAddiction = ((IStudentType)Occupation).MaxGamingAddiction;
} }
} }
public class Golem : Student
public class Golem : Student, IGolem
{ {
private Character? parent; // 主人 private Character? parent; // 主人
public Character? Parent public Character? Parent


+ 0
- 16
logic/GameClass/GameObj/Character/Character.cs View File

@@ -242,22 +242,6 @@ namespace GameClass.GameObj
} }
} }


/// <summary>
/// 尝试加血
/// </summary>
/// <param name="add">欲加量</param>
/// <returns>加操作是否成功</returns>
public bool TryAddHp(int add)
{
if (hp < MaxHp)
{
lock (gameObjLock)
hp = MaxHp > hp + add ? hp + add : MaxHp;
Debugger.Output(this, " hp has added to: " + hp.ToString());
return true;
}
return false;
}
/// <summary> /// <summary>
/// 尝试减血 /// 尝试减血
/// </summary> /// </summary>


+ 0
- 250
logic/GameClass/GameObj/Character/Skill.cs View File

@@ -1,250 +0,0 @@
using Preparation.Interface;
using Preparation.Utility;

namespace GameClass.GameObj
{
public class CanBeginToCharge : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 24 / 30;
public int DurationTime => GameData.commonSkillTime * 5 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class BecomeInvisible : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime * 6 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Punish : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Rouse : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Howl : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 3 / 4;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class JumpyBomb : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD / 2;
public int DurationTime => GameData.commonSkillTime * 3 / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class UseKnife : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2 / 3;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class UseRobot : IActiveSkill
{
public int SkillCD => GameData.frameDuration;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class WriteAnswers : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

private int degreeOfMeditation = 0;
public int DegreeOfMeditation
{
get => degreeOfMeditation;
set
{
lock (commonSkillLock)
{
degreeOfMeditation = value;
}
}
}
public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class SummonGolem : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

private Golem? golemSummoned = null;
public Golem? GolemSummoned
{
get => golemSummoned;
set
{
lock (commonSkillLock)
{
golemSummoned = value;
}
}
}

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class NullSkill : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = false;
}
}

public static class SkillFactory
{
public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType)
{
switch (activeSkillType)
{
case ActiveSkillType.BecomeInvisible:
return new BecomeInvisible();
case ActiveSkillType.UseKnife:
return new UseKnife();
case ActiveSkillType.Howl:
return new Howl();
case ActiveSkillType.CanBeginToCharge:
return new CanBeginToCharge();
case ActiveSkillType.Punish:
return new Punish();
case ActiveSkillType.JumpyBomb:
return new JumpyBomb();
case ActiveSkillType.WriteAnswers:
return new WriteAnswers();
case ActiveSkillType.SummonGolem:
return new SummonGolem();
case ActiveSkillType.UseRobot:
return new UseRobot();
case ActiveSkillType.Rouse:
return new Rouse();
default:
return new NullSkill();
}
}

public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill)
{
switch (ActiveSkill)
{
case BecomeInvisible:
return ActiveSkillType.BecomeInvisible;
case Howl:
return ActiveSkillType.Howl;
case UseKnife:
return ActiveSkillType.UseKnife;
case CanBeginToCharge:
return ActiveSkillType.CanBeginToCharge;
case Punish:
return ActiveSkillType.Punish;
case JumpyBomb:
return ActiveSkillType.JumpyBomb;
case WriteAnswers:
return ActiveSkillType.WriteAnswers;
case SummonGolem:
return ActiveSkillType.SummonGolem;
case UseRobot:
return ActiveSkillType.UseRobot;
case Rouse:
return ActiveSkillType.Rouse;
default:
return ActiveSkillType.Null;
}
}
}
}

+ 1
- 1
logic/GameClass/GameObj/Map/Generator.cs View File

@@ -33,7 +33,7 @@ namespace GameClass.GameObj


public bool Repair(int addDegree, Character character) public bool Repair(int addDegree, Character character)
{ {
if (DegreeOfRepair == GameData.degreeOfFixedGenerator) return false;
if (DegreeOfRepair == GameData.degreeOfFixedGenerator) return true;
int orgDegreeOfRepair = degreeOfRepair; int orgDegreeOfRepair = degreeOfRepair;
DegreeOfRepair += addDegree; DegreeOfRepair += addDegree;
if (DegreeOfRepair > orgDegreeOfRepair) if (DegreeOfRepair > orgDegreeOfRepair)


+ 14
- 41
logic/Gaming/ActionManager.cs View File

@@ -23,8 +23,8 @@ namespace Gaming
{ {
if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty) if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty)
{ {
if (CharacterManager.BeStunned((Character)player, ((Bullet)collisionObj).AP / GameData.timeFactorOfGhostFainting))
player.AddScore(GameData.TrickerScoreStudentBeStunned(((Bullet)collisionObj).AP / GameData.timeFactorOfGhostFainting));
if (CharacterManager.BeStunned((Character)player, GameData.TimeOfStunnedWhenJumpyDumpty))
player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.TimeOfStunnedWhenJumpyDumpty));
gameMap.Remove((GameObj)collisionObj); gameMap.Remove((GameObj)collisionObj);
} }
} }
@@ -68,20 +68,19 @@ namespace Gaming
() => () =>
{ {
new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => player.PlayerState == PlayerStateType.Fixing && gameMap.Timer.IsGaming && generatorForFix.DegreeOfRepair < GameData.degreeOfFixedGenerator,
loopCondition: () => gameMap.Timer.IsGaming && player.PlayerState == PlayerStateType.Fixing,
loopToDo: () => loopToDo: () =>
{ {
generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player);
if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player))
{
player.PlayerState = PlayerStateType.Null;
gameMap.NumOfRepairedGenerators++;
}
}, },
timeInterval: GameData.frameDuration, timeInterval: GameData.frameDuration,
finallyReturn: () => 0 finallyReturn: () => 0
) )
.Start(); .Start();
if (generatorForFix.DegreeOfRepair >= GameData.degreeOfFixedGenerator)
{
gameMap.NumOfRepairedGenerators++;
if (player.PlayerState == PlayerStateType.Fixing) player.PlayerState = PlayerStateType.Null;
}
} }


) )
@@ -146,6 +145,7 @@ 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)
{ {
player.AddScore(GameData.StudentScoreEscape);
++gameMap.NumOfEscapedStudent; ++gameMap.NumOfEscapedStudent;
player.Die(PlayerStateType.Escaped); player.Die(PlayerStateType.Escaped);
return true; return true;
@@ -166,19 +166,6 @@ namespace Gaming
playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position)) playerTreated.HP == playerTreated.MaxHp || !GameData.ApproachToInteract(playerTreated.Position, player.Position))
return false; return false;


if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp)
{
playerTreated.HP = playerTreated.MaxHp;
playerTreated.DegreeOfTreatment = 0;
return false;
}

if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree)
{
playerTreated.HP += GameData.basicTreatmentDegree;
playerTreated.DegreeOfTreatment = 0;
return false;
}
new Thread new Thread
( (
() => () =>
@@ -186,33 +173,19 @@ namespace Gaming
playerTreated.PlayerState = PlayerStateType.Treated; playerTreated.PlayerState = PlayerStateType.Treated;
player.PlayerState = PlayerStateType.Treating; player.PlayerState = PlayerStateType.Treating;
new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && player.PlayerState == PlayerStateType.Treating && gameMap.Timer.IsGaming && playerTreated.HP + playerTreated.DegreeOfTreatment < playerTreated.MaxHp && playerTreated.DegreeOfTreatment < GameData.basicTreatmentDegree && GameData.ApproachToInteract(playerTreated.Position, player.Position),
loopCondition: () => playerTreated.PlayerState == PlayerStateType.Treated && player.PlayerState == PlayerStateType.Treating && gameMap.Timer.IsGaming,
loopToDo: () => loopToDo: () =>
{ {
playerTreated.DegreeOfTreatment += GameData.frameDuration * player.TreatSpeed;
if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player))
playerTreated.PlayerState = PlayerStateType.Null;
}, },
timeInterval: GameData.frameDuration, timeInterval: GameData.frameDuration,
finallyReturn: () => 0 finallyReturn: () => 0
) )

.Start(); .Start();


if (playerTreated.PlayerState == PlayerStateType.Treated) playerTreated.PlayerState = PlayerStateType.Null;
if (player.PlayerState == PlayerStateType.Treating) player.PlayerState = PlayerStateType.Null; if (player.PlayerState == PlayerStateType.Treating) player.PlayerState = PlayerStateType.Null;

if (playerTreated.HP + playerTreated.DegreeOfTreatment >= playerTreated.MaxHp)
{
player.AddScore(GameData.StudentScoreTreat(playerTreated.MaxHp - playerTreated.HP));
playerTreated.HP = playerTreated.MaxHp;
playerTreated.DegreeOfTreatment = 0;
}
else
if (playerTreated.DegreeOfTreatment >= GameData.basicTreatmentDegree)
{
player.AddScore(GameData.StudentScoreTreat(GameData.basicTreatmentDegree));
playerTreated.HP += GameData.basicTreatmentDegree;
playerTreated.DegreeOfTreatment = 0;
}
else if (playerTreated.PlayerState == PlayerStateType.Treated) playerTreated.PlayerState = PlayerStateType.Null;
} }
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
@@ -236,7 +209,7 @@ namespace Gaming
() => () =>
{ {
new FrameRateTaskExecutor<int>( new FrameRateTaskExecutor<int>(
loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && player.PlayerState == PlayerStateType.Rescuing && gameMap.Timer.IsGaming && GameData.ApproachToInteract(playerRescued.Position, player.Position),
loopCondition: () => playerRescued.PlayerState == PlayerStateType.Rescued && player.PlayerState == PlayerStateType.Rescuing && gameMap.Timer.IsGaming,
loopToDo: () => loopToDo: () =>
{ {
playerRescued.TimeOfRescue += GameData.frameDuration; playerRescued.TimeOfRescue += GameData.frameDuration;


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

@@ -328,7 +328,7 @@ namespace Gaming
bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp)); bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp));
bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp)); bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
} }
student.DegreeOfTreatment = 0;
student.SetDegreeOfTreatment0();
if (student.HP <= 0) if (student.HP <= 0)
student.TryActivatingLIFE(); // 如果有复活甲 student.TryActivatingLIFE(); // 如果有复活甲




+ 0
- 20
logic/Gaming/Game.cs View File

@@ -270,26 +270,6 @@ namespace Gaming
else else
return false; return false;
} }
public void AllActiveSkillDisabledTemporarily()
{
if (!gameMap.Timer.IsGaming)
return;
gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{
foreach (var activeSkill in player.Occupation.ListOfIActiveSkill)
{
player.SetTimeUntilActiveSkillAvailable(activeSkill, 0);
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
}
}


public void AllPlayerUsePassiveSkill() public void AllPlayerUsePassiveSkill()
{ {


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

@@ -153,7 +153,7 @@ namespace Gaming
&& gameMap.CanSee(player, character)) && gameMap.CanSee(player, character))
{ {
if (CharacterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish)) if (CharacterManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish))
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.timeFactorOfGhostFainting));
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish));
break; break;
} }
} }
@@ -198,6 +198,62 @@ namespace Gaming
{ }); { });
} }


public bool Encourage(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Encourage), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character character in gameMap.GameObjDict[GameObjType.Character])
{
if ((character.HP < character.MaxHp) && gameMap.CanSee(player, character))
{
player.AddScore(GameData.StudentScoreTreat(character.MaxHp - character.HP));
character.HP = character.MaxHp;
((Student)character).SetDegreeOfTreatment0();
break;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}
Debugger.Output(player, "encourage someone!");
},
() =>
{ });
}

public bool Inspire(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Inspire), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character character in gameMap.GameObjDict[GameObjType.Character])
{
if (gameMap.CanSee(player, character))
{
player.AddScore(GameData.StudentScoreTreat(character.MaxHp - character.HP));
character.AddMoveSpeed(GameData.PropDuration);
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}
Debugger.Output(player, "inspires!");
},
() =>
{ });
}

public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
{ {
lock (activeSkill.ActiveSkillLock) lock (activeSkill.ActiveSkillLock)


+ 6
- 0
logic/Gaming/SkillManager/SkillManager.cs View File

@@ -28,6 +28,12 @@ namespace Gaming
case ActiveSkillType.CanBeginToCharge: case ActiveSkillType.CanBeginToCharge:
CanBeginToCharge(character); CanBeginToCharge(character);
break; break;
case ActiveSkillType.Inspire:
Inspire(character);
break;
case ActiveSkillType.Encourage:
Encourage(character);
break;
case ActiveSkillType.Punish: case ActiveSkillType.Punish:
Punish(character); Punish(character);
break; break;


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

@@ -15,4 +15,6 @@ namespace Preparation.Interface


public bool IsGhost(); public bool IsGhost();
} }
public interface IStudent : ICharacter { }
public interface IGolem : IStudent { }
} }

+ 39
- 12
logic/Preparation/Interface/IOccupation.cs View File

@@ -18,18 +18,18 @@ namespace Preparation.Interface
public int SpeedOfOpenChest { get; } public int SpeedOfOpenChest { get; }
} }


public interface IGhost : IOccupation
public interface IGhostType : IOccupation
{ {
} }


public interface IStudent : IOccupation
public interface IStudentType : IOccupation
{ {
public int FixSpeed { get; } public int FixSpeed { get; }
public int TreatSpeed { get; } public int TreatSpeed { get; }
public int MaxGamingAddiction { get; } public int MaxGamingAddiction { get; }
} }


public class Assassin : IGhost
public class Assassin : IGhostType
{ {
private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 1.1); private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 1.1);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -60,7 +60,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class Klee : IGhost
public class Klee : IGhostType
{ {
private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 155 / 127); private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 155 / 127);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -91,7 +91,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = (int)(GameData.basicSpeedOfOpenChest * 1.1); public int speedOfOpenChest = (int)(GameData.basicSpeedOfOpenChest * 1.1);
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class ANoisyPerson : IGhost
public class ANoisyPerson : IGhostType
{ {
private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 1.07); private const int moveSpeed = (int)(GameData.basicGhostMoveSpeed * 1.07);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -122,7 +122,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = (int)(GameData.basicSpeedOfOpenChest); public int speedOfOpenChest = (int)(GameData.basicSpeedOfOpenChest);
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class Teacher : IStudent
public class Teacher : IStudentType
{ {
private const int moveSpeed = GameData.basicStudentMoveSpeed * 3 / 4; private const int moveSpeed = GameData.basicStudentMoveSpeed * 3 / 4;
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -162,7 +162,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class Athlete : IStudent
public class Athlete : IStudentType
{ {
private const int moveSpeed = GameData.basicStudentMoveSpeed * 40 / 38; private const int moveSpeed = GameData.basicStudentMoveSpeed * 40 / 38;
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -202,7 +202,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class StraightAStudent : IStudent
public class StraightAStudent : IStudentType
{ {
private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.8); private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.8);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -242,7 +242,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class Robot : IStudent
public class Robot : IStudentType
{ {
private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed); private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -282,7 +282,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class TechOtaku : IStudent
public class TechOtaku : IStudentType
{ {
private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.75); private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.75);
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -322,7 +322,7 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }
public class Sunshine : IStudent
public class Sunshine : IStudentType
{ {
private const int moveSpeed = GameData.basicStudentMoveSpeed; private const int moveSpeed = GameData.basicStudentMoveSpeed;
public int MoveSpeed => moveSpeed; public int MoveSpeed => moveSpeed;
@@ -335,7 +335,7 @@ namespace Preparation.Interface


public BulletType InitBullet => BulletType.Null; public BulletType InitBullet => BulletType.Null;


public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Rouse });
public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Rouse, ActiveSkillType.Encourage, ActiveSkillType.Inspire });
public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { }); public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { });


public const int fixSpeed = GameData.basicFixSpeed * 11 / 10; public const int fixSpeed = GameData.basicFixSpeed * 11 / 10;
@@ -362,4 +362,31 @@ namespace Preparation.Interface
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest; public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int SpeedOfOpenChest => speedOfOpenChest; public int SpeedOfOpenChest => speedOfOpenChest;
} }

public static class OccupationFactory
{
public static IOccupation FindIOccupation(CharacterType characterType)
{
switch (characterType)
{
case CharacterType.Assassin:
return new Assassin();
case CharacterType.Robot:
return new Robot();
case CharacterType.Teacher:
return new Teacher();
case CharacterType.Klee:
return new Klee();
case CharacterType.StraightAStudent:
return new StraightAStudent();
case CharacterType.ANoisyPerson:
return new ANoisyPerson();
case CharacterType.TechOtaku:
return new TechOtaku();
case CharacterType.Athlete:
default:
return new Athlete();
}
}
}
} }

+ 286
- 1
logic/Preparation/Interface/ISkill.cs View File

@@ -1,4 +1,7 @@
namespace Preparation.Interface
using Preparation.Interface;
using Preparation.Utility;

namespace Preparation.Interface
{ {
public interface ISkill public interface ISkill
{ {
@@ -13,4 +16,286 @@
public object ActiveSkillLock { get; } public object ActiveSkillLock { get; }
public bool IsBeingUsed { get; set; } public bool IsBeingUsed { get; set; }
} }
}
public class CanBeginToCharge : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 24 / 30;
public int DurationTime => GameData.commonSkillTime * 5 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class BecomeInvisible : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime * 6 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Punish : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Rouse : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Encourage : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Inspire : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Howl : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 3 / 4;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class JumpyBomb : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD / 2;
public int DurationTime => GameData.commonSkillTime * 3 / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class UseKnife : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2 / 3;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class UseRobot : IActiveSkill
{
public int SkillCD => GameData.frameDuration;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class WriteAnswers : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

private int degreeOfMeditation = 0;
public int DegreeOfMeditation
{
get => degreeOfMeditation;
set
{
lock (commonSkillLock)
{
degreeOfMeditation = value;
}
}
}
public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class SummonGolem : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

private IGolem? golemSummoned = null;
public IGolem? GolemSummoned
{
get => golemSummoned;
set
{
lock (commonSkillLock)
{
golemSummoned = value;
}
}
}

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class NullSkill : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = false;
}
}

public static class SkillFactory
{
public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType)
{
switch (activeSkillType)
{
case ActiveSkillType.BecomeInvisible:
return new BecomeInvisible();
case ActiveSkillType.UseKnife:
return new UseKnife();
case ActiveSkillType.Howl:
return new Howl();
case ActiveSkillType.Encourage:
return new Encourage();
case ActiveSkillType.CanBeginToCharge:
return new CanBeginToCharge();
case ActiveSkillType.Punish:
return new Punish();
case ActiveSkillType.JumpyBomb:
return new JumpyBomb();
case ActiveSkillType.WriteAnswers:
return new WriteAnswers();
case ActiveSkillType.SummonGolem:
return new SummonGolem();
case ActiveSkillType.UseRobot:
return new UseRobot();
case ActiveSkillType.Rouse:
return new Rouse();
case ActiveSkillType.Inspire:
return new Inspire();
default:
return new NullSkill();
}
}

public static ActiveSkillType FindActiveSkillType(IActiveSkill ActiveSkill)
{
switch (ActiveSkill)
{
case BecomeInvisible:
return ActiveSkillType.BecomeInvisible;
case Howl:
return ActiveSkillType.Howl;
case UseKnife:
return ActiveSkillType.UseKnife;
case Encourage:
return ActiveSkillType.Encourage;
case CanBeginToCharge:
return ActiveSkillType.CanBeginToCharge;
case Inspire:
return ActiveSkillType.Inspire;
case Punish:
return ActiveSkillType.Punish;
case JumpyBomb:
return ActiveSkillType.JumpyBomb;
case WriteAnswers:
return ActiveSkillType.WriteAnswers;
case SummonGolem:
return ActiveSkillType.SummonGolem;
case UseRobot:
return ActiveSkillType.UseRobot;
case Rouse:
return ActiveSkillType.Rouse;
default:
return ActiveSkillType.Null;
}
}
} }

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

@@ -98,6 +98,8 @@ namespace Preparation.Utility
Howl = 9, Howl = 9,
UseRobot = 10, UseRobot = 10,
Rouse = 11, Rouse = 11,
Encourage = 12,
Inspire = 13,
} }
public enum PassiveSkillType public enum PassiveSkillType
{ {


+ 6
- 12
logic/Preparation/Utility/GameData.cs View File

@@ -84,7 +84,7 @@ namespace Preparation.Utility


public const int basicTreatSpeed = 100; public const int basicTreatSpeed = 100;
public const int basicFixSpeed = 100; public const int basicFixSpeed = 100;
public const int basicSpeedOfOpeningOrLocking = 30;
public const int basicSpeedOfOpeningOrLocking = 40;
public const int basicStudentSpeedOfClimbingThroughWindows = 611; public const int basicStudentSpeedOfClimbingThroughWindows = 611;
public const int basicGhostSpeedOfClimbingThroughWindows = 1270; public const int basicGhostSpeedOfClimbingThroughWindows = 1270;
public const int basicSpeedOfOpenChest = 1000; public const int basicSpeedOfOpenChest = 1000;
@@ -193,23 +193,17 @@ namespace Preparation.Utility
public const int maxNumOfSkill = 3; public const int maxNumOfSkill = 3;
public const int commonSkillCD = 30000; // 普通技能标准冷却时间 public const int commonSkillCD = 30000; // 普通技能标准冷却时间
public const int commonSkillTime = 10000; // 普通技能标准持续时间 public const int commonSkillTime = 10000; // 普通技能标准持续时间
/// <summary>
/// BeginToCharge
/// </summary>

public const int TimeOfGhostFaintingWhenCharge = 7220; public const int TimeOfGhostFaintingWhenCharge = 7220;
public const int TimeOfStudentFaintingWhenCharge = 2090; public const int TimeOfStudentFaintingWhenCharge = 2090;


/// <summary>
/// Punish
/// </summary>
public const int TimeOfGhostFaintingWhenPunish = 3070; public const int TimeOfGhostFaintingWhenPunish = 3070;
public const int timeFactorOfGhostFainting = 250;


/// <summary>
/// Howl
/// </summary>
public const int TimeOfGhostSwingingAfterHowl = 3070; public const int TimeOfGhostSwingingAfterHowl = 3070;
public const int TimeOfStudentFaintingWhenHowl = 6110; public const int TimeOfStudentFaintingWhenHowl = 6110;

public const int TimeOfStunnedWhenJumpyDumpty = 3070;

#endregion #endregion
#region 道具相关 #region 道具相关
public const int PropRadius = numOfPosGridPerCell / 2; public const int PropRadius = numOfPosGridPerCell / 2;
@@ -229,7 +223,7 @@ namespace Preparation.Utility
#endregion #endregion
#region 物体相关 #region 物体相关
public const int degreeOfFixedGenerator = 10300000; public const int degreeOfFixedGenerator = 10300000;
public const int degreeOfLockingOrOpeningTheDoor = 10000;
public const int degreeOfLockingOrOpeningTheDoor = 100000;
public const int degreeOfOpenedChest = 10000; public const int degreeOfOpenedChest = 10000;
public const int degreeOfOpenedDoorway = 18000; public const int degreeOfOpenedDoorway = 18000;
public const int maxNumOfPropInChest = 2; public const int maxNumOfPropInChest = 2;


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

@@ -59,7 +59,6 @@ namespace Server
{ {
game.AllPlayerUsePassiveSkill(); game.AllPlayerUsePassiveSkill();
ReportGame(GameState.GameStart); ReportGame(GameState.GameStart);
game.AllActiveSkillDisabledTemporarily();
flag = false; flag = false;
} }
else ReportGame(GameState.GameRunning); else ReportGame(GameState.GameRunning);


+ 1
- 7
logic/规则Logic.md View File

@@ -196,8 +196,6 @@
- 不加说明,这里“学生”往往包括职业“教师” - 不加说明,这里“学生”往往包括职业“教师”


### 初始状态 ### 初始状态
- 所有玩家可以立刻使用主动技能
- 虽然一开始会接到仍需的冷却时间,但实际上是CD
- 玩家出生点固定且一定为空地 - 玩家出生点固定且一定为空地


### 交互 ### 交互
@@ -231,7 +229,6 @@
- 未开启完成的箱子在下一次需要重新开始开启。 - 未开启完成的箱子在下一次需要重新开始开启。
- 箱子开启后其中道具才可以被观测和拿取 - 箱子开启后其中道具才可以被观测和拿取



## 游戏内Logic底层的枚举类型、类与属性 ## 游戏内Logic底层的枚举类型、类与属性
- 底层实现中的属性,不代表界面全部都需要展示,也可能需要额外展示信息 - 底层实现中的属性,不代表界面全部都需要展示,也可能需要额外展示信息
- 只展示外部需要的属性,部分属性被省略 - 只展示外部需要的属性,部分属性被省略
@@ -288,7 +285,6 @@
- 玩家状态(不可叠加) - 玩家状态(不可叠加)
- Bgm(字典) - Bgm(字典)
- 得分 - 得分
- ~~回血率/原始回血率~~
- 当前子弹类型 - 当前子弹类型
- 原始子弹类型 - 原始子弹类型
- 持有道具 (最多三个)(数组) - 持有道具 (最多三个)(数组)
@@ -310,12 +306,10 @@
### 学生:人物 ### 学生:人物
- 修理电机速度 - 修理电机速度
- 治疗速度 - 治疗速度
- ~~救人速度~~
- ~~自愈次数~~
- 沉迷游戏程度 - 沉迷游戏程度
- 最大沉迷游戏程度 - 最大沉迷游戏程度
- 被治疗程度 - 被治疗程度
- *被救援程度*
- 被救援程度


### 搞蛋鬼:人物 ### 搞蛋鬼:人物


Loading…
Cancel
Save