diff --git a/docs/游戏机制与平衡性调整更新草案.md b/docs/游戏机制与平衡性调整更新草案.md index b178d45..f08ff94 100644 --- a/docs/游戏机制与平衡性调整更新草案.md +++ b/docs/游戏机制与平衡性调整更新草案.md @@ -54,10 +54,10 @@ v1.6 - 视野范围由9000降为8000 - 翻窗速度改为1000 - 特质: - - 扣血则得分50×受到伤害/基本伤害(1500000) + - 扣血则得分100×受到伤害/基本伤害(1500000) - 技能惩罚(Punish)改为 - CD:45s - - “使用瞬间,在**视野距离/4范围内(不是可视范围)的**翻窗、开锁门、攻击前后摇、**使用技能期间**的捣蛋鬼会被眩晕(3070+**500***已受伤害/基本伤害(1500000))ms” + - “使用瞬间,在**视野距离/3范围内(不是可视范围)的**翻窗、开锁门、攻击前后摇、**使用技能期间**的捣蛋鬼会被眩晕(3070+**500***已受伤害/基本伤害(1500000))ms” - 技能喝茶(HaveTea)(新增) - CD:90s - 在有队友受过伤的情况下,使用瞬间,向当前方向瞬移3000(可以穿墙),如果会碰撞则失败。 diff --git a/docs/版本更新说明.md b/docs/版本更新说明.md index 1f21808..7dc7e94 100644 --- a/docs/版本更新说明.md +++ b/docs/版本更新说明.md @@ -38,8 +38,11 @@ - feat:Robot可用 - hotfix: 修复了移动相关的bug -# 最新更新 +# 5月19日13:00更新 - feat:TechOtaku可用 - feat:Klee、Idol已调整 - fix:修复了InSpire会给Tricker加速的问题 -- fix:修复了开锁门的bug \ No newline at end of file +- fix:修复了开锁门的bug + +# 最新更新 +- docs:更新了 游戏机制与平衡性调整更新草案.pdf \ No newline at end of file diff --git a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs index 1642a41..72a0ee7 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs @@ -8,20 +8,48 @@ namespace GameClass.GameObj public CommonAttackOfGhost(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { + ap = GameData.basicApOfGhost; } public override double BulletBombRange => 0; public override double AttackDistance => GameData.basicAttackShortRange; - public int ap = GameData.basicApOfGhost; - public override int AP + public override int Speed => GameData.basicBulletMoveSpeed; + public override bool IsRemoteAttack => false; + + public override int CastTime => (int)AttackDistance * 1000 / Speed; + public override int Backswing => GameData.basicBackswing; + public override int RecoveryFromHit => GameData.basicRecoveryFromHit; + public const int cd = GameData.basicBackswing; + public override int CD => cd; + public const int maxBulletNum = 1; + public override int MaxBulletNum => maxBulletNum; + + public override bool CanAttack(GameObj target) { - get => ap; - set + return false; + } + public override bool CanBeBombed(GameObjType gameObjType) + { + switch (gameObjType) { - lock (gameObjLock) - ap = value; + case GameObjType.Character: + return true; + default: + return false; } } - public override int Speed => GameData.basicBulletMoveSpeed; + public override BulletType TypeOfBullet => BulletType.CommonAttackOfGhost; + } + + internal sealed class Strike : Bullet + { + public Strike(Character player, XY pos, int radius = GameData.bulletRadius) : + base(player, radius, pos) + { + ap = GameData.basicApOfGhost * 16 / 15; + } + public override double BulletBombRange => 0; + public override double AttackDistance => GameData.basicAttackShortRange * 20 / 22; + public override int Speed => GameData.basicBulletMoveSpeed * 625 / 740; public override bool IsRemoteAttack => false; public override int CastTime => (int)AttackDistance * 1000 / Speed; @@ -41,12 +69,13 @@ namespace GameClass.GameObj switch (gameObjType) { case GameObjType.Character: + case GameObjType.Generator: return true; default: return false; } } - public override BulletType TypeOfBullet => BulletType.CommonAttackOfGhost; + public override BulletType TypeOfBullet => BulletType.Strike; } internal sealed class FlyingKnife : Bullet @@ -54,19 +83,11 @@ namespace GameClass.GameObj public FlyingKnife(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { + ap = GameData.basicApOfGhost * 4 / 5; } public override double BulletBombRange => 0; public override double AttackDistance => GameData.basicRemoteAttackRange * 13; - public int ap = GameData.basicApOfGhost * 4 / 5; - public override int AP - { - get => ap; - set - { - lock (gameObjLock) - ap = value; - } - } + public override int Speed => GameData.basicBulletMoveSpeed * 25 / 10; public override bool IsRemoteAttack => true; @@ -102,19 +123,11 @@ namespace GameClass.GameObj { public BombBomb(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { + ap = (int)(GameData.basicApOfGhost * 6.0 / 5); } public override double BulletBombRange => GameData.basicBulletBombRange; public override double AttackDistance => GameData.basicAttackShortRange; - public int ap = (int)(GameData.basicApOfGhost * 6.0 / 5); - public override int AP - { - get => ap; - set - { - lock (gameObjLock) - ap = value; - } - } + public override int Speed => (int)(GameData.basicBulletMoveSpeed * 30 / 37); public override bool IsRemoteAttack => false; @@ -149,19 +162,11 @@ namespace GameClass.GameObj { public JumpyDumpty(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { + ap = (int)(GameData.basicApOfGhost * 0.6); } public override double BulletBombRange => GameData.basicBulletBombRange / 2; public override double AttackDistance => GameData.basicAttackShortRange * 2; - public int ap = (int)(GameData.basicApOfGhost * 0.6); - public override int AP - { - get => ap; - set - { - lock (gameObjLock) - ap = value; - } - } + public override int Speed => (int)(GameData.basicBulletMoveSpeed * 43 / 37); public override bool IsRemoteAttack => false; diff --git a/logic/GameClass/GameObj/Bullet/Bullet.cs b/logic/GameClass/GameObj/Bullet/Bullet.cs index 470d191..fa25353 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.cs @@ -1,5 +1,6 @@ using Preparation.Interface; using Preparation.Utility; +using System.Threading; namespace GameClass.GameObj { @@ -10,7 +11,16 @@ namespace GameClass.GameObj /// public abstract double BulletBombRange { get; } public abstract double AttackDistance { get; } - public abstract int AP { get; set; } + protected int ap; + public int AP + { + get => Interlocked.CompareExchange(ref ap, 0, 1); + } + public void AddAP(int addAp) + { + Interlocked.Add(ref ap, addAp); + } + public abstract int Speed { get; } public abstract bool IsRemoteAttack { get; } public abstract int CastTime { get; } diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index e5f9071..6855120 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -106,7 +106,7 @@ namespace GameClass.GameObj ); Bullet? bullet = BulletFactory.GetBullet(this, res, this.bulletOfPlayer); if (bullet == null) return null; - bullet.AP += TryAddAp() ? GameData.ApPropAdd : 0; + if (TryAddAp()) bullet.AddAP(GameData.ApPropAdd); facingDirection = new(angle, bullet.AttackDistance); return bullet; } @@ -361,7 +361,9 @@ namespace GameClass.GameObj { lock (actionLock) { - if (playerState == PlayerStateType.Moving && IsMoving == 1) return PlayerStateType.Moving; + if (playerState == PlayerStateType.Moving) + if (IsMoving == 1) return PlayerStateType.Moving; + else return PlayerStateType.Null; return playerState; } } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 2960c5c..04acc9f 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -555,7 +555,7 @@ namespace Gaming if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty) { - if (characterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0) + if (CharacterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0) player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty)); gameMap.Remove((GameObj)collisionObj); } @@ -563,9 +563,9 @@ namespace Gaming case GameObjType.Character: if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && ((Character)collisionObj).IsGhost()) { - if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) + if (CharacterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge)); - characterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge); + CharacterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge); } break; case GameObjType.Item: diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs index 614d6bf..54cd0be 100644 --- a/logic/Gaming/CharacterManager.cs +++ b/logic/Gaming/CharacterManager.cs @@ -240,7 +240,7 @@ namespace Gaming { IsBackground = true }.Start(); } - public long BeStunned(Character player, int time) + public static long BeStunned(Character player, int time) { if (player.CharacterType == CharacterType.Robot) return -1; long threadNum = player.SetPlayerState(PlayerStateType.Stunned); @@ -324,6 +324,11 @@ namespace Gaming #endif } bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp)); + if (student.CharacterType == CharacterType.Teacher) + { + student.AddScore(subHp * GameData.factorOfScoreWhenTeacherAttacked / GameData.basicApOfGhost); + } + bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp)); } if (student.HP <= 0) diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index 7df2ef1..5f05c6b 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -310,7 +310,7 @@ namespace Gaming { if (!character.IsGhost() && !character.NoHp() && XY.DistanceFloor3(character.Position, player.Position) <= player.ViewRange) { - if (characterManager.BeStunned(character, GameData.timeOfStudentStunnedWhenHowl) > 0) + if (CharacterManager.BeStunned(character, GameData.timeOfStudentStunnedWhenHowl) > 0) player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStudentStunnedWhenHowl)); } } @@ -341,9 +341,9 @@ namespace Gaming || character.PlayerState == PlayerStateType.UsingSkill || character.PlayerState == PlayerStateType.LockingTheDoor || character.PlayerState == PlayerStateType.OpeningTheDoor || character.PlayerState == PlayerStateType.ClimbingThroughWindows) - && gameMap.CanSee(player, character)) + && XY.DistanceFloor3(character.Position, player.Position) <= player.ViewRange / 3) { - if (characterManager.BeStunned(character, GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP)) > 0) + if (CharacterManager.BeStunned(character, GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP)) > 0) player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP))); break; } diff --git a/logic/Preparation/Interface/IOccupation.cs b/logic/Preparation/Interface/IOccupation.cs index 7d21a67..4d8e606 100644 --- a/logic/Preparation/Interface/IOccupation.cs +++ b/logic/Preparation/Interface/IOccupation.cs @@ -130,7 +130,7 @@ namespace Preparation.Interface private const int maxHp = GameData.basicHp * 12 / 10; public int MaxHp => maxHp; - public BulletType InitBullet => BulletType.CommonAttackOfGhost; + public BulletType InitBullet => BulletType.Strike; public List ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Howl }); public List ListOfIPassiveSkill => new(new PassiveSkillType[] { }); diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index b06f1a0..c8fa69d 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -66,7 +66,7 @@ namespace Preparation.Interface public class Punish : ActiveSkill { - public override int SkillCD => GameData.commonSkillCD; + public override int SkillCD => GameData.commonSkillCD * 45 / 30; public override int DurationTime => 0; } diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 2d7329b..1fff97d 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -59,7 +59,7 @@ namespace Preparation.Utility CommonAttackOfGhost = 2, JumpyDumpty = 3, BombBomb = 4, - // Ram = 7, + Strike = 8, } public enum PropType // 道具类型 {//numOfPropSpecies 见Gamedata @@ -106,6 +106,7 @@ namespace Preparation.Utility Inspire = 13, ShowTime = 14, SparksNSplash = 15, + HaveTea = 16, } public enum PassiveSkillType { diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs index 2d3ccbe..b24dbd1 100644 --- a/logic/Preparation/Utility/GameData.cs +++ b/logic/Preparation/Utility/GameData.cs @@ -205,7 +205,7 @@ namespace Preparation.Utility public const double basicAttackShortRange = 2200; // 基本近程攻击范围 public const double basicBulletBombRange = 2000; // 基本子弹爆炸范围 #endregion - #region 技能相关 + #region 技能、特性相关 public const int maxNumOfSkill = 3; public const int commonSkillCD = 30000; // 普通技能标准冷却时间 public const int commonSkillTime = 10000; // 普通技能标准持续时间 @@ -214,7 +214,8 @@ namespace Preparation.Utility public const int timeOfStudentStunnedWhenCharge = 2090; public const int timeOfGhostStunnedWhenPunish = 3070; - public const int factorOfTimeStunnedWhenPunish = 300 / basicApOfGhost; + public const int factorOfTimeStunnedWhenPunish = 500 / basicApOfGhost; + public const int factorOfScoreWhenTeacherAttacked = 100;//每个 public const int timeOfGhostSwingingAfterHowl = 800; public const int timeOfStudentStunnedWhenHowl = 5500;