Browse Source

Merge pull request #550 from shangfengh/new

refactor: 🚧 refactor the skill fuction
tags/v0.1.0
Changli Tang GitHub 2 years ago
parent
commit
a0bbe2f09f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 211 additions and 261 deletions
  1. +2
    -2
      logic/Client/MainWindow.xaml.cs
  2. +10
    -17
      logic/GameClass/GameObj/Character/Character.Skill.cs
  3. +1
    -1
      logic/GameClass/GameObj/GameObj.cs
  4. +6
    -1
      logic/GameClass/GameObj/Map/Door.cs
  5. +2
    -3
      logic/GameClass/GameObj/Map/Map.cs
  6. +3
    -3
      logic/GameClass/GameObj/Moveable.cs
  7. +2
    -2
      logic/GameClass/GameObj/Prop/Gadget.cs
  8. +1
    -1
      logic/GameClass/GameObj/Prop/Item.cs
  9. +11
    -5
      logic/Gaming/ActionManager.cs
  10. +3
    -3
      logic/Gaming/CharacterManager.cs
  11. +1
    -1
      logic/Gaming/PropManager.cs
  12. +40
    -35
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  13. +1
    -1
      logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs
  14. +1
    -1
      logic/Preparation/Interface/IMoveable.cs
  15. +7
    -7
      logic/Preparation/Interface/IOccupation.cs
  16. +108
    -167
      logic/Preparation/Interface/ISkill.cs
  17. +6
    -4
      logic/Preparation/Utility/GameData.cs
  18. +6
    -7
      logic/Server/CopyInfo.cs

+ 2
- 2
logic/Client/MainWindow.xaml.cs View File

@@ -833,7 +833,7 @@ namespace Client
int i = 0;
foreach (var skill in occupation.ListOfIActiveSkill)
{
var iActiveSkill = SkillFactory.FindIActiveSkill(skill);
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD;
++i;
}
@@ -848,7 +848,7 @@ namespace Client
int j = 0;
foreach (var skill in occupation1.ListOfIActiveSkill)
{
var iActiveSkill = SkillFactory.FindIActiveSkill(skill);
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD;
++j;
}


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

@@ -11,37 +11,32 @@ namespace GameClass.GameObj
private readonly IOccupation occupation;
public IOccupation Occupation => occupation;

private Dictionary<ActiveSkillType, int> timeUntilActiveSkillAvailable = new();
public Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable => timeUntilActiveSkillAvailable;
private Dictionary<ActiveSkillType, ActiveSkill> activeSkillDictionary = new();
public Dictionary<ActiveSkillType, ActiveSkill> ActiveSkillDictionary => activeSkillDictionary;

private Dictionary<ActiveSkillType, IActiveSkill> iActiveSkillDictionary = new();
public Dictionary<ActiveSkillType, IActiveSkill> IActiveSkillDictionary => iActiveSkillDictionary;

public IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType)
public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType)
{
if (Occupation.ListOfIActiveSkill.Contains(activeSkillType))
{
return IActiveSkillDictionary[activeSkillType];
return ActiveSkillDictionary[activeSkillType];
}
return new NullSkill();
}

public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable)
{
if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType))
if (Occupation.ListOfIActiveSkill.Contains(activeSkillType))
{
lock (gameObjLock)
this.timeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0;
ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0;
return true;
}
return false;
}
public bool AddTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int addTimeUntilActiveSkillAvailable)
{
if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType))
if (Occupation.ListOfIActiveSkill.Contains(activeSkillType))
{
lock (gameObjLock)
this.timeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable[activeSkillType] + addTimeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable[activeSkillType] + addTimeUntilActiveSkillAvailable : 0;
ActiveSkillDictionary[activeSkillType].TimeUntilActiveSkillAvailable += addTimeUntilActiveSkillAvailable;
return true;
}
return false;
@@ -72,12 +67,10 @@ namespace GameClass.GameObj

foreach (var activeSkill in this.Occupation.ListOfIActiveSkill)
{
this.IActiveSkillDictionary.Add(activeSkill, SkillFactory.FindIActiveSkill(activeSkill));
this.TimeUntilActiveSkillAvailable.Add(activeSkill, 0);
this.ActiveSkillDictionary.Add(activeSkill, SkillFactory.FindActiveSkill(activeSkill));
}

// UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行
// 这可以放在AddPlayer中做
// UsePassiveSkill(); //这一过程放到gamestart时进行

Debugger.Output(this, "constructed!");
}


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

@@ -9,7 +9,7 @@ namespace GameClass.GameObj
/// </summary>
public abstract class GameObj : IGameObj
{
private ReaderWriterLockSlim gameObjReaderWriterLock = new();
private readonly ReaderWriterLockSlim gameObjReaderWriterLock = new();
public ReaderWriterLockSlim GameObjReaderWriterLock => gameObjReaderWriterLock;
protected readonly object gameObjLock = new();
public object GameLock => gameObjLock;


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

@@ -150,7 +150,12 @@ namespace GameClass.GameObj
whoLockOrOpen = null;
isOpen = true;
}
if (character != null) character.SetPlayerState();
if (character != null)
{
lock (character.ActionLock)
if (character.PlayerState == PlayerStateType.OpeningTheDoor)
character.SetPlayerState();
}
}
}
}

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

@@ -193,13 +193,12 @@ namespace GameClass.GameObj
{
if (playerID == person.ID)
{
if (person.CharacterType == CharacterType.TechOtaku && person.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed)
if (person.CharacterType == CharacterType.TechOtaku)
{
Debugger.Output(person, person.PlayerID.ToString());
foreach (Character character in gameObjDict[GameObjType.Character])
{
Debugger.Output(character, character.PlayerID.ToString());
if (person.PlayerID + GameData.numOfPeople == character.PlayerID)
if (((UseRobot)person.FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID == character.PlayerID)
{
player = character;
break;


+ 3
- 3
logic/GameClass/GameObj/Moveable.cs View File

@@ -162,13 +162,13 @@ namespace GameClass.GameObj
}
}

protected long moveSpeed;
protected int moveSpeed;
/// <summary>
/// 移动速度
/// </summary>
public long MoveSpeed
public int MoveSpeed
{
get => Interlocked.Read(ref moveSpeed);
get => Interlocked.CompareExchange(ref moveSpeed, 0, 1);
set => Interlocked.Exchange(ref moveSpeed, value);
}
/// <summary>


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

@@ -21,11 +21,11 @@ namespace GameClass.GameObj
public abstract bool IsUsable();
public abstract PropType GetPropType();

public Gadget(XY initPos, int radius = GameData.PropRadius) :
public Gadget(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Gadget)
{
this.canMove = false;
this.MoveSpeed = GameData.PropMoveSpeed;
this.MoveSpeed = GameData.propMoveSpeed;
}
}
public abstract class Tool : Gadget


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

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

public abstract PropType GetPropType();

public Item(XY initPos, int radius = GameData.PropRadius) :
public Item(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Item)
{
this.canMove = false;


+ 11
- 5
logic/Gaming/ActionManager.cs View File

@@ -26,7 +26,7 @@ namespace Gaming
gameMap.Remove((GameObj)collisionObj);
}
}
if (player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost())
if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost())
{
if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0)
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge));
@@ -117,7 +117,7 @@ namespace Gaming
if (generatorForFix.Repair(player.FixSpeed * GameData.frameDuration, player))
gameMap.NumOfRepairedGenerators++;
if (generatorForFix.DegreeOfRepair == GameData.degreeOfFixedGenerator)
player.SetPlayerState();
player.SetPlayerState();//Num == player.StateNum
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0
@@ -215,7 +215,7 @@ namespace Gaming
loopToDo: () =>
{
if (playerTreated.AddDegreeOfTreatment(GameData.frameDuration * player.TreatSpeed, player))
playerTreated.SetPlayerState();
playerTreated.SetPlayerState();//
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0
@@ -426,7 +426,10 @@ namespace Gaming
if (!doorToLock.TryLock(player))
{
player.ReleaseTool(propType);
player.SetPlayerState();
lock (player.ActionLock)
{
if (stateNum == player.StateNum) player.SetPlayerState();
}
player.ThreadNum.Release();
}
else
@@ -495,7 +498,10 @@ namespace Gaming
if (!doorToLock.TryOpen(player))
{
player.ReleaseTool(propType);
player.SetPlayerState();
lock (player.ActionLock)
{
if (stateNum == player.StateNum) player.SetPlayerState();
}
player.ThreadNum.Release();
}
else


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

@@ -284,7 +284,7 @@ namespace Gaming

if (student.CharacterType == CharacterType.StraightAStudent)
{
((WriteAnswers)student.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0;
((WriteAnswers)student.FindActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0;
}
student.SetDegreeOfTreatment0();

@@ -382,8 +382,8 @@ namespace Gaming
var parent = ((Golem)player).Parent;
if (parent != null && parent.CharacterType == CharacterType.TechOtaku)
{
((SummonGolem)(parent.FindIActiveSkill(ActiveSkillType.SummonGolem))).GolemSummoned = null;
player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false;
((SummonGolem)(parent.FindActiveSkill(ActiveSkillType.SummonGolem))).DeleteGolem((int)(player.PlayerID - parent.PlayerID) / GameData.numOfPeople - 1);
//player.FindActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false;
}
return;
}


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

@@ -107,7 +107,7 @@ namespace Gaming

if (pickProp.GetPropType() != PropType.Null)
{
gameMap.Remove(pickProp);
gameMap.RemoveJustFromMap(pickProp);
//gameMap.Add(new Item(pickProp));
return true;
}


+ 40
- 35
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -15,7 +15,7 @@ namespace Gaming
{

if ((!player.Commandable())) return false;
IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.CanBeginToCharge);
ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.CanBeginToCharge);
Debugger.Output(player, "can begin to charge!");


@@ -31,7 +31,7 @@ namespace Gaming
public bool ShowTime(Character player)
{
if ((!player.Commandable())) return false;
IActiveSkill skill = player.FindIActiveSkill(ActiveSkillType.ShowTime);
ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.ShowTime);

return ActiveSkillEffect(skill, player, () =>
{
@@ -93,7 +93,7 @@ namespace Gaming
public static bool BecomeInvisible(Character player)
{
if ((!player.Commandable())) return false;
IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.BecomeInvisible);
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible);
return ActiveSkillEffect(activeSkill, player, () =>
{
player.AddScore(GameData.ScoreBecomeInvisible);
@@ -106,20 +106,21 @@ namespace Gaming

public bool UseRobot(Character player)
{
IGolem? golem = (IGolem?)(((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned);
if ((!player.Commandable()) || ((SummonGolem)player.FindIActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false;
/*
IGolem? golem = (IGolem?)(((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned);
if ((!player.Commandable()) || ((SummonGolem)player.FindActiveSkill(ActiveSkillType.SummonGolem)).GolemSummoned == null) return false;
Debugger.Output(player, "use robot!");
IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.UseRobot);
IActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.UseRobot);
activeSkill.IsBeingUsed = (activeSkill.IsBeingUsed) ? false : true;
if (activeSkill.IsBeingUsed) player.SetPlayerState(PlayerStateType.UsingSkill);
else player.SetPlayerState();
else player.SetPlayerState();*/
return true;
}

public static bool JumpyBomb(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.JumpyBomb), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.JumpyBomb), player, () =>
{
player.BulletOfPlayer = BulletType.BombBomb;
Debugger.Output(player, "uses jumpybomb!");
@@ -131,7 +132,7 @@ namespace Gaming
public bool WriteAnswers(Character player)
{
if ((!player.Commandable())) return false;
IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.WriteAnswers);
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.WriteAnswers);
return ActiveSkillEffect(activeSkill, player, () =>
{
Generator? generator = (Generator?)gameMap.OneForInteract(player.Position, GameObjType.Generator);
@@ -149,25 +150,30 @@ namespace Gaming

public bool SummonGolem(Character player)
{
if ((!player.Commandable())) return false;
IActiveSkill activeSkill = player.FindIActiveSkill(ActiveSkillType.SummonGolem);
if (((SummonGolem)activeSkill).GolemSummoned != null) return false;
XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2);
if (actionManager.moveEngine.CheckCollision(player, res) != null)
return false;
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player);
if (golem == null) return false;
((SummonGolem)activeSkill).GolemSummoned = golem;
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem);
long num = ((SummonGolem)activeSkill).AddGolem();
if (num >= GameData.maxSummonedGolemNum) return false;
num = (num + 1) * GameData.numOfPeople + player.PlayerID;

/* if ((!player.Commandable())) return false;
XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2);
if (actionManager.moveEngine.CheckCollision(player, res) != null)
return false;
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player);
if (golem == null) return false;
((SummonGolem)activeSkill).GolemSummoned = golem;
*/
return ActiveSkillEffect(activeSkill, player, () =>
{
},
() =>
{ });

}

public static bool UseKnife(Character player)
{
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.UseKnife), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.UseKnife), player, () =>
{
player.BulletOfPlayer = BulletType.FlyingKnife;
Debugger.Output(player, "uses flyingknife!");
@@ -179,7 +185,7 @@ namespace Gaming
public bool Howl(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Howl), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Howl), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
@@ -207,7 +213,7 @@ namespace Gaming
public bool Punish(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Punish), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Punish), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
@@ -240,7 +246,7 @@ namespace Gaming
public bool Rouse(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Rouse), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Rouse), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
@@ -270,7 +276,7 @@ namespace Gaming
public bool Encourage(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Encourage), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Encourage), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
@@ -299,7 +305,7 @@ namespace Gaming
public bool Inspire(Character player)
{
if ((!player.Commandable())) return false;
return ActiveSkillEffect(player.FindIActiveSkill(ActiveSkillType.Inspire), player, () =>
return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.Inspire), player, () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
@@ -323,24 +329,23 @@ namespace Gaming
{ });
}

public static bool ActiveSkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
public static bool ActiveSkillEffect(ActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
{
lock (activeSkill.ActiveSkillLock)
lock (activeSkill.ActiveSkillUseLock)
{
ActiveSkillType activeSkillType = SkillFactory.FindActiveSkillType(activeSkill);
if (player.TimeUntilActiveSkillAvailable[activeSkillType] == 0)
if (activeSkill.TimeUntilActiveSkillAvailable == 0)
{
player.SetTimeUntilActiveSkillAvailable(activeSkillType, activeSkill.SkillCD);
activeSkill.TimeUntilActiveSkillAvailable = activeSkill.SkillCD;
new Thread
(() =>
{
startSkill();
activeSkill.IsBeingUsed = true;
activeSkill.IsBeingUsed = 1;
new FrameRateTaskExecutor<int>(
() => !player.IsRemoved,
() =>
{
player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
() => 0,
@@ -353,14 +358,14 @@ namespace Gaming
.Start();

endSkill();
activeSkill.IsBeingUsed = false;
activeSkill.IsBeingUsed = 0;
Debugger.Output(player, "return to normal.");

new FrameRateTaskExecutor<int>(
loopCondition: () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsRemoved,
loopCondition: () => activeSkill.TimeUntilActiveSkillAvailable > 0,
loopToDo: () =>
{
player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration);
activeSkill.TimeUntilActiveSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0
@@ -371,7 +376,7 @@ namespace Gaming
}
.Start();

player.SetTimeUntilActiveSkillAvailable(activeSkillType, 0);
activeSkill.TimeUntilActiveSkillAvailable = 0;
Debugger.Output(player, "ActiveSkill is ready.");
}
)


+ 1
- 1
logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs View File

@@ -15,7 +15,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束
public void Meditate(Character player)
{
const int learningDegree = GameData.basicFixSpeed / 4;
WriteAnswers activeSkill = (WriteAnswers)player.FindIActiveSkill(ActiveSkillType.WriteAnswers);
WriteAnswers activeSkill = (WriteAnswers)player.FindActiveSkill(ActiveSkillType.WriteAnswers);
new Thread
(
() =>


+ 1
- 1
logic/Preparation/Interface/IMoveable.cs View File

@@ -7,7 +7,7 @@ namespace Preparation.Interface
public interface IMoveable : IGameObj
{
object ActionLock { get; }
public long MoveSpeed { get; }
public int MoveSpeed { get; }
public bool IsMoving { get; set; }
public bool IsRemoved { get; }
public bool IsAvailableForMove { get; }


+ 7
- 7
logic/Preparation/Interface/IOccupation.cs View File

@@ -315,13 +315,13 @@ namespace Preparation.Interface
}
public class TechOtaku : IStudentType
{
private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 0.75);
private const int moveSpeed = (int)(GameData.basicStudentMoveSpeed * 288 / 300);
public int MoveSpeed => moveSpeed;

private const int maxHp = (int)(GameData.basicHp * 0.9);
public int MaxHp => maxHp;

private const int maxGamingAddiction = (int)(GameData.basicMaxGamingAddiction * 1.1);
private const int maxGamingAddiction = (int)(GameData.basicMaxGamingAddiction);
public int MaxGamingAddiction => maxGamingAddiction;

public BulletType InitBullet => BulletType.Null;
@@ -329,13 +329,13 @@ namespace Preparation.Interface
public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.SummonGolem, ActiveSkillType.UseRobot });
public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { });

public const int fixSpeed = (int)(GameData.basicFixSpeed * 1.1);
public const int fixSpeed = (int)(GameData.basicFixSpeed * 110 / 123);
public int FixSpeed => fixSpeed;

public const int treatSpeed = GameData.basicTreatSpeed * 9 / 10;
public const int treatSpeed = GameData.basicTreatSpeed;
public int TreatSpeed => treatSpeed;

public const double concealment = GameData.basicConcealment;
public const double concealment = GameData.basicConcealment * 1.1;
public double Concealment => concealment;

public const int alertnessRadius = (int)(GameData.basicStudentAlertnessRadius);
@@ -347,10 +347,10 @@ namespace Preparation.Interface
public int speedOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking;
public int SpeedOfOpeningOrLocking => speedOfOpeningOrLocking;

public int speedOfClimbingThroughWindows = (int)(GameData.basicStudentSpeedOfClimbingThroughWindows * 3 / 4);
public int speedOfClimbingThroughWindows = (int)(GameData.basicStudentSpeedOfClimbingThroughWindows * 1100 / 1222);
public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows;

public int speedOfOpenChest = GameData.basicSpeedOfOpenChest;
public int speedOfOpenChest = GameData.basicSpeedOfOpenChest * 1100 / 1250;
public int SpeedOfOpenChest => speedOfOpenChest;
}
public class Sunshine : IStudentType


+ 108
- 167
logic/Preparation/Interface/ISkill.cs View File

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

namespace Preparation.Interface
{
@@ -13,241 +14,181 @@ namespace Preparation.Interface
{
public int SkillCD { get; }
public int DurationTime { get; } //技能持续时间
public object ActiveSkillLock { get; }
public bool IsBeingUsed { get; set; }
public object ActiveSkillUseLock { get; }
public int IsBeingUsed { get; set; }
}
public class CanBeginToCharge : IActiveSkill

public abstract class ActiveSkill : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 2;
public int DurationTime => GameData.commonSkillTime * 3 / 10;
public abstract int SkillCD { get; }
public abstract int DurationTime { get; }

private readonly object activeSkillUseLock = new();
public object ActiveSkillUseLock => activeSkillUseLock;

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

public bool isBeingUsed = false;
public bool IsBeingUsed
private int timeUntilActiveSkillAvailable = 0;
public int TimeUntilActiveSkillAvailable
{
get => isBeingUsed; set => isBeingUsed = value;
get => Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1);
set
{
if (value < 0) value = 0;
else if (value > SkillCD) value = SkillCD;
Interlocked.Exchange(ref timeUntilActiveSkillAvailable, value);
}
}
}

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

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

public bool isBeingUsed = false;
public bool IsBeingUsed
public int isBeingUsed = 0;//实为bool
public int IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
get => Interlocked.CompareExchange(ref isBeingUsed, 0, 1);
set => Interlocked.Exchange(ref isBeingUsed, value);
}
}

public class Punish : IActiveSkill
public class CanBeginToCharge : ActiveSkill
{
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 override int SkillCD => GameData.commonSkillCD * 2;
public override int DurationTime => GameData.commonSkillTime * 3 / 10;
}

public class Rouse : IActiveSkill
public class BecomeInvisible : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 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 override int SkillCD => GameData.commonSkillCD * 4 / 3;
public override int DurationTime => GameData.commonSkillTime;
}

public class Encourage : IActiveSkill
public class Punish : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 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 override int SkillCD => GameData.commonSkillCD;
public override int DurationTime => 0;
}

public class Inspire : IActiveSkill
public class Rouse : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 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 override int SkillCD => GameData.commonSkillCD * 4;
public override int DurationTime => 0;
}

public class Howl : IActiveSkill
public class Encourage : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 25 / 30;
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 override int SkillCD => GameData.commonSkillCD * 4;
public override int DurationTime => 0;
}

public class ShowTime : IActiveSkill
public class Inspire : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 8 / 3;
public int DurationTime => GameData.commonSkillTime;
public override int SkillCD => GameData.commonSkillCD * 4;
public override int DurationTime => 0;
}

private readonly object commonSkillLock = new();
public object ActiveSkillLock => commonSkillLock;
public class Howl : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD * 25 / 30;
public override int DurationTime => 0;
}

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
public class ShowTime : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD * 8 / 3;
public override int DurationTime => GameData.commonSkillTime;
}

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

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
public class UseKnife : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD;
public override int DurationTime => GameData.commonSkillTime / 10;
}

public class UseKnife : IActiveSkill
public class UseRobot : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;
public override int SkillCD => GameData.commonSkillCD / 300;
public override int DurationTime => 0;

public bool isBeingUsed = false;
public bool IsBeingUsed
private int nowPlayerID;
public int NowPlayerID
{
get => isBeingUsed; set => isBeingUsed = value;
get => Interlocked.CompareExchange(ref nowPlayerID, 0, 1);
set => Interlocked.Exchange(ref nowPlayerID, value);
}
}

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

public bool isBeingUsed = false;
public bool IsBeingUsed
private int degreeOfMeditation = 0;
public int DegreeOfMeditation
{
get => isBeingUsed; set => isBeingUsed = value;
get => Interlocked.CompareExchange(ref degreeOfMeditation, 0, 1);
set => Interlocked.Exchange(ref degreeOfMeditation, value);
}
}

public class WriteAnswers : IActiveSkill
public class SummonGolem : ActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;
public override int SkillCD => GameData.commonSkillCD * 4 / 3;
public override int DurationTime => 6;

private int degreeOfMeditation = 0;
public int DegreeOfMeditation
private bool[] golemIDArray = new bool[GameData.maxSummonedGolemNum] { false, false, false };
public bool[] GolemIDArray
{
get => degreeOfMeditation;
set
get
{
lock (commonSkillLock)
{
degreeOfMeditation = value;
}
lock (SkillLock) { return golemIDArray; }
}
}
public bool isBeingUsed = false;
public bool IsBeingUsed
private int nowPtr = 0;
public int NowPtr
{
get => isBeingUsed; set => isBeingUsed = value;
get
{
lock (SkillLock) { return nowPtr; }
}
}
}

public class SummonGolem : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD * 4 / 3;
public int DurationTime => 6;
private readonly object commonSkillLock = new();
public object ActiveSkillLock => commonSkillLock;

private IGolem? golemSummoned = null;
public IGolem? GolemSummoned
public int AddGolem()
{
get => golemSummoned;
set
lock (SkillLock)
{
lock (commonSkillLock)
{
golemSummoned = value;
}
if (nowPtr == GameData.maxSummonedGolemNum) return GameData.maxSummonedGolemNum;
int num = nowPtr;
golemIDArray[nowPtr] = true;
while ((++nowPtr) < GameData.maxSummonedGolemNum && golemIDArray[nowPtr]) ;
return num;
}
}

public bool isBeingUsed = false;
public bool IsBeingUsed
public void DeleteGolem(int num)
{
get => isBeingUsed; set => isBeingUsed = value;
lock (SkillLock)
{
golemIDArray[num] = false;
if (num < nowPtr)
{
nowPtr = num;
}
}
}
}

public class NullSkill : IActiveSkill
public class NullSkill : ActiveSkill
{
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 override int SkillCD => GameData.commonSkillCD;
public override int DurationTime => GameData.commonSkillTime;
}

public static class SkillFactory
{
public static IActiveSkill FindIActiveSkill(ActiveSkillType activeSkillType)
public static ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType)
{
switch (activeSkillType)
{


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

@@ -92,10 +92,10 @@ namespace Preparation.Utility

public const int basicTreatSpeed = 100;
public const int basicFixSpeed = 123;
public const int basicSpeedOfOpeningOrLocking = 4000;
public const int basicSpeedOfOpeningOrLocking = 5000;
public const int basicStudentSpeedOfClimbingThroughWindows = 1222;
public const int basicGhostSpeedOfClimbingThroughWindows = 2540;
public const int basicSpeedOfOpenChest = 1000;
public const int basicSpeedOfOpenChest = 1250;

public const int basicHp = 3000000; // 初始血量
public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间
@@ -228,10 +228,12 @@ namespace Preparation.Utility

public const int checkIntervalWhenShowTime = 200;
public const int addAddictionPer100msWhenShowTime = 300;

public const int maxSummonedGolemNum = 3;
#endregion
#region 道具相关
public const int PropRadius = numOfPosGridPerCell / 2;
public const int PropMoveSpeed = 3000;
public const int propRadius = characterRadius;
public const int propMoveSpeed = 3000;
public const int PropMaxMoveDistance = 15 * numOfPosGridPerCell;
public const long PropProduceTime = 20000;
public const int PropDuration = 10000;


+ 6
- 7
logic/Server/CopyInfo.cs View File

@@ -80,9 +80,9 @@ namespace Server
}
};

foreach (var keyValue in player.TimeUntilActiveSkillAvailable)
msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value);
for (int i = 0; i < GameData.maxNumOfSkill - player.TimeUntilActiveSkillAvailable.Count; ++i)
foreach (var keyValue in player.ActiveSkillDictionary)
msg.StudentMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable);
for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i)
msg.StudentMessage.TimeUntilSkillAvailable.Add(-1);

foreach (var value in player.PropInventory)
@@ -121,10 +121,9 @@ namespace Server
BulletType = Transformation.ToBulletType((Preparation.Utility.BulletType)player.BulletOfPlayer)
}
};

foreach (var keyValue in player.TimeUntilActiveSkillAvailable)
msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value);
for (int i = 0; i < GameData.maxNumOfSkill - player.TimeUntilActiveSkillAvailable.Count; ++i)
foreach (var keyValue in player.ActiveSkillDictionary)
msg.TrickerMessage.TimeUntilSkillAvailable.Add(keyValue.Value.TimeUntilActiveSkillAvailable);
for (int i = 0; i < GameData.maxNumOfSkill - player.ActiveSkillDictionary.Count; ++i)
msg.TrickerMessage.TimeUntilSkillAvailable.Add(-1);

foreach (var value in player.PropInventory)


Loading…
Cancel
Save