Browse Source

fix: 🐛 make SafeValues classs

dev
shangfengh 2 years ago
parent
commit
e4bea8433e
21 changed files with 107 additions and 108 deletions
  1. +1
    -1
      logic/Client/MainWindow.xaml.cs
  2. +5
    -5
      logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
  3. +4
    -3
      logic/GameClass/GameObj/Bullet/Bullet.cs
  4. +2
    -2
      logic/GameClass/GameObj/Character/Character.Skill.cs
  5. +2
    -2
      logic/GameClass/GameObj/Character/Character.cs
  6. +2
    -1
      logic/GameClass/GameObj/GameObj.cs
  7. +2
    -1
      logic/GameClass/GameObj/Map/Chest.cs
  8. +3
    -2
      logic/GameClass/GameObj/Map/Door.cs
  9. +2
    -3
      logic/GameClass/GameObj/Map/Map.cs
  10. +4
    -2
      logic/GameClass/GameObj/Moveable.cs
  11. +2
    -2
      logic/GameClass/GameObj/Prop/Gadget.cs
  12. +2
    -2
      logic/GameClass/GameObj/Prop/Item.cs
  13. +4
    -4
      logic/GameEngine/MoveEngine.cs
  14. +2
    -2
      logic/Gaming/ActionManager.cs
  15. +2
    -2
      logic/Gaming/AttackManager.cs
  16. +3
    -36
      logic/Gaming/CharacterManager.cs
  17. +2
    -2
      logic/Gaming/Game.cs
  18. +2
    -2
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  19. +1
    -1
      logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs
  20. +2
    -1
      logic/Preparation/Interface/ISkill.cs
  21. +58
    -32
      logic/Preparation/Utility/SafeValue.cs

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

@@ -844,7 +844,7 @@ namespace Client
} }
foreach (var obj in listOfButcher) foreach (var obj in listOfButcher)
{ {
if (!isDataFixed[obj.PlayerId])
if (obj.PlayerId < GameData.numOfStudent && !isDataFixed[obj.PlayerId])
{ {
IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType));
int j = 0; int j = 0;


+ 5
- 5
logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs View File

@@ -8,7 +8,7 @@ namespace GameClass.GameObj
public CommonAttackOfGhost(Character player, XY pos, int radius = GameData.bulletRadius) : public CommonAttackOfGhost(Character player, XY pos, int radius = GameData.bulletRadius) :
base(player, radius, pos) base(player, radius, pos)
{ {
AP.Set(GameData.basicApOfGhost);
AP.SetReturnOri(GameData.basicApOfGhost);
} }
public override double BulletBombRange => 0; public override double BulletBombRange => 0;
public override double AttackDistance => GameData.basicAttackShortRange; public override double AttackDistance => GameData.basicAttackShortRange;
@@ -45,7 +45,7 @@ namespace GameClass.GameObj
public Strike(Character player, XY pos, int radius = GameData.bulletRadius) : public Strike(Character player, XY pos, int radius = GameData.bulletRadius) :
base(player, radius, pos) base(player, radius, pos)
{ {
AP.Set(GameData.basicApOfGhost * 16 / 15);
AP.SetReturnOri(GameData.basicApOfGhost * 16 / 15);
} }
public override double BulletBombRange => 0; public override double BulletBombRange => 0;
public override double AttackDistance => GameData.basicAttackShortRange * 20 / 22; public override double AttackDistance => GameData.basicAttackShortRange * 20 / 22;
@@ -83,7 +83,7 @@ namespace GameClass.GameObj
public FlyingKnife(Character player, XY pos, int radius = GameData.bulletRadius) : public FlyingKnife(Character player, XY pos, int radius = GameData.bulletRadius) :
base(player, radius, pos) base(player, radius, pos)
{ {
AP.Set(GameData.basicApOfGhost * 4 / 5);
AP.SetReturnOri(GameData.basicApOfGhost * 4 / 5);
} }
public override double BulletBombRange => 0; public override double BulletBombRange => 0;
public override double AttackDistance => GameData.basicRemoteAttackRange * 13; public override double AttackDistance => GameData.basicRemoteAttackRange * 13;
@@ -123,7 +123,7 @@ namespace GameClass.GameObj
{ {
public BombBomb(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) public BombBomb(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos)
{ {
AP.Set((int)(GameData.basicApOfGhost * 6.0 / 5));
AP.SetReturnOri((int)(GameData.basicApOfGhost * 6.0 / 5));
} }
public override double BulletBombRange => GameData.basicBulletBombRange; public override double BulletBombRange => GameData.basicBulletBombRange;
public override double AttackDistance => GameData.basicAttackShortRange; public override double AttackDistance => GameData.basicAttackShortRange;
@@ -163,7 +163,7 @@ namespace GameClass.GameObj
{ {
public JumpyDumpty(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) public JumpyDumpty(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos)
{ {
AP.Set((int)(GameData.basicApOfGhost * 0.6));
AP.SetReturnOri((int)(GameData.basicApOfGhost * 0.6));
} }
public override double BulletBombRange => GameData.basicBulletBombRange / 2; public override double BulletBombRange => GameData.basicBulletBombRange / 2;
public override double AttackDistance => GameData.basicAttackShortRange * 18 / 22; public override double AttackDistance => GameData.basicAttackShortRange * 18 / 22;


+ 4
- 3
logic/GameClass/GameObj/Bullet/Bullet.cs View File

@@ -11,7 +11,8 @@ namespace GameClass.GameObj
/// </summary> /// </summary>
public abstract double BulletBombRange { get; } public abstract double BulletBombRange { get; }
public abstract double AttackDistance { get; } public abstract double AttackDistance { get; }
public AtomicInt AP { get; }
private AtomicInt ap = new(0);
public AtomicInt AP { get => ap; }
public abstract int Speed { get; } public abstract int Speed { get; }
public abstract bool IsRemoteAttack { get; } public abstract bool IsRemoteAttack { get; }
public abstract int CastTime { get; } public abstract int CastTime { get; }
@@ -43,8 +44,8 @@ namespace GameClass.GameObj
public Bullet(Character player, int radius, XY Position) : public Bullet(Character player, int radius, XY Position) :
base(Position, radius, GameObjType.Bullet) base(Position, radius, GameObjType.Bullet)
{ {
this.CanMove.Set(true);
this.MoveSpeed.Set(this.Speed);
this.CanMove.SetReturnOri(true);
this.MoveSpeed.SetReturnOri(this.Speed);
this.hasSpear = player.TryUseSpear(); this.hasSpear = player.TryUseSpear();
this.Parent = player; this.Parent = player;
} }


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

@@ -31,12 +31,12 @@ namespace GameClass.GameObj
protected Character(XY initPos, int initRadius, CharacterType characterType) : protected Character(XY initPos, int initRadius, CharacterType characterType) :
base(initPos, initRadius, GameObjType.Character) base(initPos, initRadius, GameObjType.Character)
{ {
this.CanMove.Set(true);
this.CanMove.SetReturnOri(true);
this.score = 0; this.score = 0;
this.buffManager = new BuffManager(); this.buffManager = new BuffManager();
this.occupation = OccupationFactory.FindIOccupation(characterType); this.occupation = OccupationFactory.FindIOccupation(characterType);
this.HP = new(Occupation.MaxHp); this.HP = new(Occupation.MaxHp);
this.MoveSpeed.Set(this.orgMoveSpeed = Occupation.MoveSpeed);
this.MoveSpeed.SetReturnOri(this.orgMoveSpeed = Occupation.MoveSpeed);
this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet; this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet;
this.concealment = Occupation.Concealment; this.concealment = Occupation.Concealment;
this.alertnessRadius = Occupation.AlertnessRadius; this.alertnessRadius = Occupation.AlertnessRadius;


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

@@ -459,7 +459,7 @@ namespace GameClass.GameObj
{ {
if (SetPlayerState(RunningStateType.RunningForcibly, playerStateType) == -1) return false; if (SetPlayerState(RunningStateType.RunningForcibly, playerStateType) == -1) return false;
TryToRemove(); TryToRemove();
CanMove.Set(false);
CanMove.SetReturnOri(false);
position = GameData.PosWhoDie; position = GameData.PosWhoDie;
} }
return true; return true;
@@ -604,7 +604,7 @@ namespace GameClass.GameObj
} }


public void AddMoveSpeed(int buffTime, double add = 1.0) => buffManager.AddMoveSpeed(add, buffTime, newVal => public void AddMoveSpeed(int buffTime, double add = 1.0) => buffManager.AddMoveSpeed(add, buffTime, newVal =>
{ MoveSpeed.Set(newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed); },
{ MoveSpeed.SetReturnOri(newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed); },
OrgMoveSpeed); OrgMoveSpeed);
public bool HasFasterSpeed => buffManager.HasFasterSpeed; public bool HasFasterSpeed => buffManager.HasFasterSpeed;




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

@@ -30,7 +30,8 @@ namespace GameClass.GameObj


public abstract ShapeType Shape { get; } public abstract ShapeType Shape { get; }


public AtomicBool IsRemoved { get; } = new AtomicBool(false);
private AtomicBool isRemoved = new(false);
public AtomicBool IsRemoved { get => isRemoved; }
public virtual bool TryToRemove() public virtual bool TryToRemove()
{ {
return IsRemoved.TrySet(true); return IsRemoved.TrySet(true);


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

@@ -19,6 +19,7 @@ namespace GameClass.GameObj
private readonly Gadget[] propInChest = new Gadget[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; private readonly Gadget[] propInChest = new Gadget[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() };
public Gadget[] PropInChest => propInChest; public Gadget[] PropInChest => propInChest;


public LongProgressContinuously OpenProgress { get; } = new LongProgressContinuously();
private LongProgressByTime openProgress = new LongProgressByTime();
public LongProgressByTime OpenProgress { get => openProgress; }
} }
} }

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

@@ -46,7 +46,8 @@ namespace GameClass.GameObj
} }
} }


public AtomicInt LockDegree { get; } = new AtomicInt(0);
private AtomicInt lockDegree = new AtomicInt(0);
public AtomicInt LockDegree { get => lockDegree; }


private long openStartTime = 0; private long openStartTime = 0;
public long OpenStartTime public long OpenStartTime
@@ -97,7 +98,7 @@ namespace GameClass.GameObj
{ {
if (!isOpen) return false; if (!isOpen) return false;
if (whoLockOrOpen != null) return false; if (whoLockOrOpen != null) return false;
LockDegree.Set(0);
LockDegree.SetReturnOri(0);
whoLockOrOpen = character; whoLockOrOpen = character;
return true; return true;
} }


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

@@ -26,7 +26,7 @@ namespace GameClass.GameObj
{ {
Random r = new Random(Environment.TickCount); Random r = new Random(Environment.TickCount);
EmergencyExit emergencyExit = (EmergencyExit)(GameObjDict[GameObjType.EmergencyExit][r.Next(0, GameObjDict[GameObjType.EmergencyExit].Count)]); EmergencyExit emergencyExit = (EmergencyExit)(GameObjDict[GameObjType.EmergencyExit][r.Next(0, GameObjDict[GameObjType.EmergencyExit].Count)]);
emergencyExit.CanOpen.Set(true);
emergencyExit.CanOpen.SetReturnOri(true);
Preparation.Utility.Debugger.Output(emergencyExit, emergencyExit.Position.ToString()); Preparation.Utility.Debugger.Output(emergencyExit, emergencyExit.Position.ToString());
} }
finally finally
@@ -41,7 +41,7 @@ namespace GameClass.GameObj
try try
{ {
foreach (Doorway doorway in GameObjDict[GameObjType.Doorway]) foreach (Doorway doorway in GameObjDict[GameObjType.Doorway])
doorway.PowerSupply.Set(true);
doorway.PowerSupply.SetReturnOri(true);
} }
finally finally
{ {
@@ -228,7 +228,6 @@ namespace GameClass.GameObj
{ {
if (person.CharacterType == CharacterType.TechOtaku) if (person.CharacterType == CharacterType.TechOtaku)
{ {
Debugger.Output(person, person.PlayerID.ToString());
foreach (Character character in gameObjDict[GameObjType.Character]) foreach (Character character in gameObjDict[GameObjType.Character])
{ {
if (((UseRobot)person.FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID == character.PlayerID) if (((UseRobot)person.FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID == character.PlayerID)


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

@@ -94,14 +94,16 @@ namespace GameClass.GameObj
} }
} }


public AtomicBool CanMove { get; }
private AtomicBool canMove = new(false);
public AtomicBool CanMove { get => canMove; }


public bool IsAvailableForMove => !IsMoving && CanMove && !IsRemoved; // 是否能接收移动指令 public bool IsAvailableForMove => !IsMoving && CanMove && !IsRemoved; // 是否能接收移动指令


/// <summary> /// <summary>
/// 移动速度 /// 移动速度
/// </summary> /// </summary>
public AtomicInt MoveSpeed { get; }
private AtomicInt moveSpeed = new(0);
public AtomicInt MoveSpeed { get => moveSpeed; }
/// <summary> /// <summary>
/// 原初移动速度 /// 原初移动速度
/// </summary> /// </summary>


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

@@ -24,8 +24,8 @@ namespace GameClass.GameObj
public Gadget(XY initPos, int radius = GameData.propRadius) : public Gadget(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Gadget) base(initPos, radius, GameObjType.Gadget)
{ {
this.CanMove.Set(false);
this.MoveSpeed.Set(GameData.propMoveSpeed);
this.CanMove.SetReturnOri(false);
this.MoveSpeed.SetReturnOri(GameData.propMoveSpeed);
} }
} }
public abstract class Tool : Gadget public abstract class Tool : Gadget


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

@@ -17,8 +17,8 @@ namespace GameClass.GameObj
public Item(XY initPos, int radius = GameData.propRadius) : public Item(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Item) base(initPos, radius, GameObjType.Item)
{ {
this.CanMove.Set(false);
this.MoveSpeed.Set(0);
this.CanMove.SetReturnOri(false);
this.MoveSpeed.SetReturnOri(0);
} }
} }




+ 4
- 4
logic/GameEngine/MoveEngine.cs View File

@@ -102,7 +102,7 @@ namespace GameEngine
lock (obj.ActionLock) lock (obj.ActionLock)
{ {
if (!obj.IsAvailableForMove) { EndMove(obj); return; } if (!obj.IsAvailableForMove) { EndMove(obj); return; }
obj.IsMoving.Set(true);
obj.IsMoving.SetReturnOri(true);
} }


new Thread new Thread
@@ -139,7 +139,7 @@ namespace GameEngine


if (isEnded) if (isEnded)
{ {
obj.IsMoving.Set(false);
obj.IsMoving.SetReturnOri(false);
EndMove(obj); EndMove(obj);
return; return;
} }
@@ -184,7 +184,7 @@ namespace GameEngine
} }
if (isEnded) if (isEnded)
{ {
obj.IsMoving.Set(false);
obj.IsMoving.SetReturnOri(false);
EndMove(obj); EndMove(obj);
return; return;
} }
@@ -224,7 +224,7 @@ namespace GameEngine
} }
} while (flag); } while (flag);
} }
obj.IsMoving.Set(false); // 结束移动
obj.IsMoving.SetReturnOri(false); // 结束移动
EndMove(obj); EndMove(obj);
} }
} }


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

@@ -450,12 +450,12 @@ namespace Gaming
player.ReSetPos(windowToPlayer + windowForClimb.Position); player.ReSetPos(windowToPlayer + windowForClimb.Position);
} }


player.MoveSpeed.Set(player.SpeedOfClimbingThroughWindows);
player.MoveSpeed.SetReturnOri(player.SpeedOfClimbingThroughWindows);
moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum); moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum);


Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2)); Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2));


player.MoveSpeed.Set(player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed));
player.MoveSpeed.SetReturnOri(player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed));


lock (player.ActionLock) lock (player.ActionLock)
{ {


+ 2
- 2
logic/Gaming/AttackManager.cs View File

@@ -33,7 +33,7 @@ namespace Gaming
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty) if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty)
BulletBomb((Bullet)obj, null); BulletBomb((Bullet)obj, null);
obj.CanMove.Set(false);
obj.CanMove.SetReturnOri(false);
} }
); );
this.characterManager = characterManager; this.characterManager = characterManager;
@@ -89,7 +89,7 @@ namespace Gaming
{ {
if (gameMap.Remove(bullet)) if (gameMap.Remove(bullet))
{ {
bullet.CanMove.Set(false);
bullet.CanMove.SetReturnOri(false);
if (bullet.BulletBombRange > 0) if (bullet.BulletBombRange > 0)
{ {
BombedBullet bombedBullet = new(bullet); BombedBullet bombedBullet = new(bullet);


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

@@ -57,41 +57,8 @@ namespace Gaming
} }
gameMap.Add(newPlayer); gameMap.Add(newPlayer);


newPlayer.TeamID.Set(teamID);
newPlayer.PlayerID.Set(playerID);
/* #region 人物装弹
new Thread
(
() =>
{
while (!gameMap.Timer.IsGaming)
Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval));
long lastTime = Environment.TickCount64;
new FrameRateTaskExecutor<int>(
loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved,
loopToDo: () =>
{
long nowTime = Environment.TickCount64;
if (newPlayer.BulletNum == newPlayer.MaxBulletNum)
lastTime = nowTime;
else if (nowTime - lastTime >= newPlayer.CD)
{
_ = newPlayer.TryAddBulletNum();
lastTime = nowTime;
}
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
{
AllowTimeExceed = true,
}
.Start();
}
)
{ IsBackground = true }.Start();
#endregion
*/
newPlayer.TeamID.SetReturnOri(teamID);
newPlayer.PlayerID.SetReturnOri(playerID);
#region BGM,牵制得分更新 #region BGM,牵制得分更新
new Thread new Thread
( (
@@ -311,7 +278,7 @@ namespace Gaming


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




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

@@ -84,7 +84,7 @@ namespace Gaming
else else
{ {
#if DEBUG #if DEBUG
Console.WriteLine($"PlayerID:{playerID} player does not exists!");
Console.WriteLine($"playerID:{playerID} player does not exists!");
#endif #endif
return false; return false;


@@ -326,7 +326,7 @@ namespace Gaming
{ {
foreach (Character player in gameMap.GameObjDict[GameObjType.Character]) foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{ {
player.CanMove.Set(false);
player.CanMove.SetReturnOri(false);
} }
} }
gameMap.GameObjDict[keyValuePair.Key].Clear(); gameMap.GameObjDict[keyValuePair.Key].Clear();


+ 2
- 2
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -196,7 +196,7 @@ namespace Gaming
} }
if (homingMissile != null) if (homingMissile != null)
{ {
homingMissile.CanMove.Set(true);
homingMissile.CanMove.SetReturnOri(true);
attackManager.moveEngine.MoveObj(homingMissile, GameData.checkIntervalWhenSparksNSplash - 1, (whoAttacked.Position - homingMissile.Position).Angle(), ++homingMissile.StateNum); attackManager.moveEngine.MoveObj(homingMissile, GameData.checkIntervalWhenSparksNSplash - 1, (whoAttacked.Position - homingMissile.Position).Angle(), ++homingMissile.StateNum);
} }
}, },
@@ -227,7 +227,7 @@ namespace Gaming
if (generator.Repair(((WriteAnswers)activeSkill).DegreeOfMeditation, player)) if (generator.Repair(((WriteAnswers)activeSkill).DegreeOfMeditation, player))
gameMap.AddNumOfRepairedGenerators(); gameMap.AddNumOfRepairedGenerators();
Debugger.Output(player, "uses WriteAnswers in" + generator.ToString() + "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString()); Debugger.Output(player, "uses WriteAnswers in" + generator.ToString() + "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString());
((WriteAnswers)activeSkill).DegreeOfMeditation.Set(0);
((WriteAnswers)activeSkill).DegreeOfMeditation.SetReturnOri(0);
} }
}, },
() => () =>


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

@@ -26,7 +26,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束
() => () =>
{ {
if (player.Commandable() && player.PlayerState != PlayerStateType.Fixing) activeSkill.DegreeOfMeditation.Add(learningDegree * GameData.frameDuration); if (player.Commandable() && player.PlayerState != PlayerStateType.Fixing) activeSkill.DegreeOfMeditation.Add(learningDegree * GameData.frameDuration);
else activeSkill.DegreeOfMeditation.Set(0);
else activeSkill.DegreeOfMeditation.SetReturnOri(0);
//Debugger.Output(player, "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString()); //Debugger.Output(player, "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString());
}, },
timeInterval: GameData.frameDuration, timeInterval: GameData.frameDuration,


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

@@ -174,7 +174,8 @@ namespace Preparation.Interface
public override int SkillCD => GameData.commonSkillCD; public override int SkillCD => GameData.commonSkillCD;
public override int DurationTime => 0; public override int DurationTime => 0;


public AtomicInt DegreeOfMeditation { get; } = new(0);
private AtomicInt degreeOfMeditation = new(0);
public AtomicInt DegreeOfMeditation { get => degreeOfMeditation; }
} }


public class SummonGolem : ActiveSkill public class SummonGolem : ActiveSkill


+ 58
- 32
logic/Preparation/Utility/SafeValue.cs View File

@@ -5,7 +5,7 @@ namespace Preparation.Utility
{ {
//理论上结构体最好不可变,这里采用了可变结构。 //理论上结构体最好不可变,这里采用了可变结构。
//其对应属性不应当有set访问器,避免不安全的=赋值 //其对应属性不应当有set访问器,避免不安全的=赋值
public struct AtomicInt
public class AtomicInt
{ {
private int v; private int v;
public AtomicInt(int x) public AtomicInt(int x)
@@ -15,18 +15,17 @@ namespace Preparation.Utility
public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString(); public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString();
public int Get() => Interlocked.CompareExchange(ref v, -1, -1); public int Get() => Interlocked.CompareExchange(ref v, -1, -1);
public static implicit operator int(AtomicInt aint) => Interlocked.CompareExchange(ref aint.v, -1, -1); public static implicit operator int(AtomicInt aint) => Interlocked.CompareExchange(ref aint.v, -1, -1);
public int Set(int value) => Interlocked.Exchange(ref v, value);
/// <returns>返回操作前的值</returns>
public int SetReturnOri(int value) => Interlocked.Exchange(ref v, value);
public int Add(int x) => Interlocked.Add(ref v, x); public int Add(int x) => Interlocked.Add(ref v, x);
public int Sub(int x) => Interlocked.Add(ref v, -x); public int Sub(int x) => Interlocked.Add(ref v, -x);
public int Inc() => Interlocked.Increment(ref v); public int Inc() => Interlocked.Increment(ref v);
public int Dec() => Interlocked.Decrement(ref v); public int Dec() => Interlocked.Decrement(ref v);

public void CompareExchange(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
/// <returns>返回操作前的值</returns> /// <returns>返回操作前的值</returns>
public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
} }
public struct AtomicLong

public class AtomicLong
{ {
private long v; private long v;
public AtomicLong(long x) public AtomicLong(long x)
@@ -36,18 +35,17 @@ namespace Preparation.Utility
public override string ToString() => Interlocked.Read(ref v).ToString(); public override string ToString() => Interlocked.Read(ref v).ToString();
public long Get() => Interlocked.Read(ref v); public long Get() => Interlocked.Read(ref v);
public static implicit operator long(AtomicLong aint) => Interlocked.Read(ref aint.v); public static implicit operator long(AtomicLong aint) => Interlocked.Read(ref aint.v);
public long Set(long value) => Interlocked.Exchange(ref v, value);
/// <returns>返回操作前的值</returns>
public long SetReturnOri(long value) => Interlocked.Exchange(ref v, value);
public long Add(long x) => Interlocked.Add(ref v, x); public long Add(long x) => Interlocked.Add(ref v, x);
public long Sub(long x) => Interlocked.Add(ref v, -x); public long Sub(long x) => Interlocked.Add(ref v, -x);
public long Inc() => Interlocked.Increment(ref v); public long Inc() => Interlocked.Increment(ref v);
public long Dec() => Interlocked.Decrement(ref v); public long Dec() => Interlocked.Decrement(ref v);

public void CompareExchange(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
/// <returns>返回操作前的值</returns> /// <returns>返回操作前的值</returns>
public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
} }
public struct AtomicBool

public class AtomicBool
{ {
private int v;//v==0为false,v==1为true private int v;//v==0为false,v==1为true
public AtomicBool(bool x) public AtomicBool(bool x)
@@ -57,36 +55,34 @@ namespace Preparation.Utility
public override string ToString() => (Interlocked.CompareExchange(ref v, -2, -2) == 0) ? "false" : "true"; public override string ToString() => (Interlocked.CompareExchange(ref v, -2, -2) == 0) ? "false" : "true";
public bool Get() => (Interlocked.CompareExchange(ref v, -1, -1) != 0); public bool Get() => (Interlocked.CompareExchange(ref v, -1, -1) != 0);
public static implicit operator bool(AtomicBool abool) => (Interlocked.CompareExchange(ref abool.v, -1, -1) != 0); public static implicit operator bool(AtomicBool abool) => (Interlocked.CompareExchange(ref abool.v, -1, -1) != 0);

public bool Set(bool value) => (Interlocked.Exchange(ref v, value ? 1 : 0) != 0);

/// <returns>返回操作前的值</returns>
public bool SetReturnOri(bool value) => (Interlocked.Exchange(ref v, value ? 1 : 0) != 0);
/// <returns>赋值前的值是否与将赋予的值不相同</returns> /// <returns>赋值前的值是否与将赋予的值不相同</returns>
public bool TrySet(bool value) public bool TrySet(bool value)
{ {
return (Interlocked.CompareExchange(ref v, value ? 1 : 0, value ? 0 : 1) ^ (value ? 1 : 0)) != 0; return (Interlocked.CompareExchange(ref v, value ? 1 : 0, value ? 0 : 1) ^ (value ? 1 : 0)) != 0;
} }

public bool And(bool x) => Interlocked.And(ref v, x ? 1 : 0) != 0; public bool And(bool x) => Interlocked.And(ref v, x ? 1 : 0) != 0;
public bool Or(bool x) => Interlocked.Or(ref v, x ? 1 : 0) != 0; public bool Or(bool x) => Interlocked.Or(ref v, x ? 1 : 0) != 0;
} }


/// <summary> /// <summary>
/// 一个能记录Start后完成多少进度的进度条(long),
/// 根据时间推算Start后完成多少进度的进度条(long)。
/// 只允许Start时修改needTime(请确保大于0); /// 只允许Start时修改needTime(请确保大于0);
/// 支持TrySet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零; /// 支持TrySet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零;
/// 不支持暂停
/// 通过原子操作实现。
/// </summary> /// </summary>
public struct LongProgressContinuously
public class LongProgressByTime
{ {
private long endT = long.MaxValue; private long endT = long.MaxValue;
private long needT; private long needT;


public LongProgressContinuously(long needTime)
public LongProgressByTime(long needTime)
{ {
if (needTime <= 0) Debugger.Output("Bug:LongProgressContinuously.needTime (" + needTime.ToString() + ") is less than 0.");
if (needTime <= 0) Debugger.Output("Bug:LongProgressByTime.needTime (" + needTime.ToString() + ") is less than 0.");
this.needT = needTime; this.needT = needTime;
} }
public LongProgressContinuously()
public LongProgressByTime()
{ {
this.needT = long.MaxValue; this.needT = long.MaxValue;
} }
@@ -118,7 +114,7 @@ namespace Preparation.Utility
/// <summary> /// <summary>
/// <0则表明未开始 /// <0则表明未开始
/// </summary> /// </summary>
public static implicit operator long(LongProgressContinuously pLong) => pLong.GetProgress();
public static implicit operator long(LongProgressByTime pLong) => pLong.GetProgress();


/// <summary> /// <summary>
/// GetProgressDouble<0则表明未开始 /// GetProgressDouble<0则表明未开始
@@ -134,13 +130,13 @@ namespace Preparation.Utility
{ {
if (needTime <= 0) if (needTime <= 0)
{ {
Debugger.Output("Warning:Start LongProgressContinuously with the needTime (" + needTime.ToString() + ") which is less than 0.");
Debugger.Output("Warning:Start LongProgressByTime with the needTime (" + needTime.ToString() + ") which is less than 0.");
return false; return false;
} }
//规定只有Start可以修改needT,且需要先访问endTime,从而避免锁(某种程度上endTime可以认为是needTime的锁) //规定只有Start可以修改needT,且需要先访问endTime,从而避免锁(某种程度上endTime可以认为是needTime的锁)
if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false;
if (needTime <= 2) Debugger.Output("Warning:the field of LongProgressContinuously is " + needTime.ToString() + ",which is too small.");
Interlocked.Exchange(ref this.needT, needTime);
if (needTime <= 2) Debugger.Output("Warning:the field of LongProgressByTime is " + needTime.ToString() + ",which is too small.");
Interlocked.Exchange(ref needT, needTime);
return true; return true;
} }
public bool Start() public bool Start()
@@ -149,7 +145,13 @@ namespace Preparation.Utility
if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false;
return true; return true;
} }
/// <summary>
/// 使进度条强制终止清零
/// </summary>
public void Set0() => Interlocked.Exchange(ref endT, long.MaxValue); public void Set0() => Interlocked.Exchange(ref endT, long.MaxValue);
/// <summary>
/// 使未完成的进度条终止清零
/// </summary>
public bool TrySet0() public bool TrySet0()
{ {
if (Environment.TickCount64 < Interlocked.CompareExchange(ref endT, -2, -2)) if (Environment.TickCount64 < Interlocked.CompareExchange(ref endT, -2, -2))
@@ -162,10 +164,34 @@ namespace Preparation.Utility
//增加其他新的写操作可能导致不安全 //增加其他新的写操作可能导致不安全
} }


/*
/// <summary>
/// 记录(不是根据时间)完成多少进度的进度条(long)。
/// </summary>
public struct IntProgressByAdding
{
private int completedProgress = -1;
private int requiredProgress;
public IntProgressByAdding(int completedProgress, int requiredProgress)
{
this.completedProgress = completedProgress;
this.requiredProgress = requiredProgress;
}
public IntProgressByAdding(int requiredProgress)
{
this.requiredProgress = requiredProgress;
}
public IntProgressByAdding()
{
this.requiredProgress=int.MaxValue;
}
}
*/

/// <summary> /// <summary>
/// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0) /// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0)
/// </summary> /// </summary>
public struct IntWithVariableRange
public class IntWithVariableRange
{ {
private int v; private int v;
private int maxV; private int maxV;
@@ -310,7 +336,7 @@ namespace Preparation.Utility
/// <summary> /// <summary>
/// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0) /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0)
/// </summary> /// </summary>
public struct LongWithVariableRange
public class LongWithVariableRange
{ {
private long v; private long v;
private long maxV; private long maxV;
@@ -319,7 +345,7 @@ namespace Preparation.Utility
{ {
if (maxValue < 0) if (maxValue < 0)
{ {
Debugger.Output("Warning:Try to set LongWithVariableRange.maxValue to " + maxValue.ToString() + ".");
Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + ".");
maxValue = 0; maxValue = 0;
} }
v = value < maxValue ? value : maxValue; v = value < maxValue ? value : maxValue;
@@ -332,7 +358,7 @@ namespace Preparation.Utility
{ {
if (maxValue < 0) if (maxValue < 0)
{ {
Debugger.Output("Warning:Try to set LongWithVariableRange.maxValue to " + maxValue.ToString() + ".");
Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + ".");
maxValue = 0; maxValue = 0;
} }
v = this.maxV = maxValue; v = this.maxV = maxValue;
@@ -455,7 +481,7 @@ namespace Preparation.Utility
/// <summary> /// <summary>
/// 一个保证在[0,maxNum],每CDms自动更新的可变int,支持可变的CD、maxNum(请确保大于0) /// 一个保证在[0,maxNum],每CDms自动更新的可变int,支持可变的CD、maxNum(请确保大于0)
/// </summary> /// </summary>
public struct IntNumUpdateByCD
public class IntNumUpdateByCD
{ {
private int num; private int num;
private int maxNum; private int maxNum;
@@ -623,9 +649,9 @@ namespace Preparation.Utility
{ {
lock (numLock) lock (numLock)
{ {
if (cd <= 0) Debugger.Output("Bug:Set IntNumUpdateByCD.cd to " + cd.ToString() + ".");
if (cd <= 0) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + ".");
this.cd = cd; this.cd = cd;
} }
} }
} }
}
}

Loading…
Cancel
Save