diff --git a/logic/GameClass/GameObj/BombedBullet.cs b/logic/GameClass/GameObj/Bullet/BombedBullet.cs
similarity index 100%
rename from logic/GameClass/GameObj/BombedBullet.cs
rename to logic/GameClass/GameObj/Bullet/BombedBullet.cs
diff --git a/logic/GameClass/GameObj/Bullet.cs b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
similarity index 51%
rename from logic/GameClass/GameObj/Bullet.cs
rename to logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
index d861351..4eb48cb 100644
--- a/logic/GameClass/GameObj/Bullet.cs
+++ b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
@@ -4,44 +4,48 @@ using System;
namespace GameClass.GameObj
{
- public abstract class Bullet : ObjOfCharacter
+ internal sealed class CommonAttackOfGhost : Bullet
{
- ///
- /// //攻击力
- ///
- public abstract int AP { get; }
- public abstract int Speed { get; }
-
- private readonly bool hasSpear;
- ///
- /// 是否有矛
- ///
- public bool HasSpear => hasSpear;
-
- ///
- /// 与THUAI4不同的一个攻击判定方案,通过这个函数判断爆炸时能否伤害到target
- ///
- /// 被尝试攻击者
- /// 是否可以攻击到
- public abstract bool CanAttack(GameObj target);
-
- protected override bool IgnoreCollideExecutor(IGameObj targetObj)
+ public CommonAttackOfGhost(Character player, int radius = GameData.bulletRadius) :
+ base(player, radius)
+ {
+ }
+ public override double BulletBombRange => 0;
+ public override double BulletAttackRange => GameData.basicAttackShortRange;
+ public override int AP => GameData.basicApOfGhost;
+ public override int Speed => GameData.basicBulletMoveSpeed;
+ public override bool IsToBomb => false;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool CanAttack(GameObj target)
{
- if (targetObj.Type == GameObjType.BirthPoint || targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet)
- return true;
return false;
}
- public Bullet(Character player, int radius) :
- base(player.Position, radius, PlaceType.Null, GameObjType.Bullet)
+
+ public override BulletType TypeOfBullet => BulletType.CommonAttackOfGhost;
+
+ }
+ internal sealed class FlyingKnife : Bullet
+ {
+ public FlyingKnife(Character player, int radius = GameData.bulletRadius) :
+ base(player, radius)
+ {
+ }
+ public override double BulletBombRange => 0;
+ public override double BulletAttackRange => GameData.basicAttackShortRange * 13;
+ public override int AP => GameData.basicApOfGhost / 3 * 7;
+ public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2;
+ public override bool IsToBomb => true;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool CanAttack(GameObj target)
{
- this.CanMove = true;
- this.moveSpeed = this.Speed;
- this.hasSpear = player.HasSpear;
- this.Parent = player;
+ // 圆形攻击范围
+ return XY.Distance(this.Position, target.Position) <= BulletBombRange;
}
- public override bool IsRigid => true; // 默认为true
- public override ShapeType Shape => ShapeType.Circle; // 默认为圆形
- public abstract BulletType TypeOfBullet { get; }
+
+ public override BulletType TypeOfBullet => BulletType.FlyingKnife;
+
}
internal sealed class AtomBomb : Bullet
@@ -50,10 +54,13 @@ namespace GameClass.GameObj
base(player, radius)
{
}
- public const double BulletBombRange = GameData.basicBulletBombRange / 3 * 7;
- public const double BulletAttackRange = GameData.basicAttackRange / 9 * 7;
- public override int AP => GameData.basicAp / 3 * 7;
+ public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 7;
+ public override double BulletAttackRange => GameData.basicAttackShortRange / 9 * 7;
+ public override int AP => GameData.basicApOfGhost / 3 * 7;
public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool IsToBomb => true;
public override bool CanAttack(GameObj target)
{
// 圆形攻击范围
@@ -61,6 +68,7 @@ namespace GameClass.GameObj
}
public override BulletType TypeOfBullet => BulletType.AtomBomb;
+
}
internal sealed class OrdinaryBullet : Bullet // 1倍攻击范围,1倍攻击力,一倍速
@@ -69,10 +77,13 @@ namespace GameClass.GameObj
base(player, radius)
{
}
- public const double BulletBombRange = GameData.basicBulletBombRange / 6 * 5;
- public const double BulletAttackRange = GameData.basicAttackRange / 2;
- public override int AP => GameData.basicAp / 6 * 5;
+ public override double BulletBombRange => GameData.basicBulletBombRange / 6 * 5;
+ public override double BulletAttackRange => GameData.basicAttackShortRange / 2;
+ public override int AP => GameData.basicApOfGhost / 6 * 5;
public override int Speed => GameData.basicBulletMoveSpeed / 6 * 5;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool IsToBomb => true;
public override bool CanAttack(GameObj target)
{
// 圆形攻击范围
@@ -88,10 +99,13 @@ namespace GameClass.GameObj
base(player, radius)
{
}
- public const double BulletBombRange = GameData.basicBulletBombRange / 4 * 2;
- public const double BulletAttackRange = GameData.basicAttackRange;
- public override int AP => (int)(0.5 * GameData.basicAp);
+ public override double BulletBombRange => GameData.basicBulletBombRange / 4 * 2;
+ public override double BulletAttackRange => GameData.basicAttackShortRange;
+ public override int AP => (int)(0.5 * GameData.basicApOfGhost);
public override int Speed => 5 * GameData.basicBulletMoveSpeed / 3;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool IsToBomb => true;
public override bool CanAttack(GameObj target)
{
@@ -108,10 +122,13 @@ namespace GameClass.GameObj
base(player, radius)
{
}
- public const double BulletBombRange = GameData.basicBulletBombRange / 3 * 4;
- public const double BulletAttackRange = 0.1 * GameData.basicAttackRange;
- public override int AP => GameData.basicAp / 3 * 2;
+ public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 4;
+ public override double BulletAttackRange => 0.1 * GameData.basicAttackShortRange;
+ public override int AP => GameData.basicApOfGhost / 3 * 2;
public override int Speed => GameData.basicBulletMoveSpeed / 3;
+ public override int Backswing => GameData.basicBackswing;
+ public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
+ public override bool IsToBomb => true;
public override bool CanAttack(GameObj target)
{
@@ -165,73 +182,5 @@ namespace GameClass.GameObj
public override BulletType TypeOfBullet => BulletType.LineBullet;
}
- public static class BulletFactory
- {
- public static Bullet? GetBullet(Character character)
- {
- Bullet? newBullet = null;
- switch (character.BulletOfPlayer)
- {
- case BulletType.AtomBomb:
- newBullet = new AtomBomb(character);
- break;
- case BulletType.LineBullet:
- newBullet = new LineBullet(character);
- break;
- case BulletType.FastBullet:
- newBullet = new FastBullet(character);
- break;
- case BulletType.OrdinaryBullet:
- newBullet = new OrdinaryBullet(character);
- break;
- default:
- break;
- }
- return newBullet;
- }
- public static int BulletRadius(BulletType bulletType)
- {
- switch (bulletType)
- {
- case BulletType.AtomBomb:
- case BulletType.LineBullet:
- case BulletType.FastBullet:
- case BulletType.OrdinaryBullet:
- default:
- return GameData.bulletRadius;
- }
- }
- public static double BulletAttackRange(BulletType bulletType)
- {
- switch (bulletType)
- {
- case BulletType.AtomBomb:
- return AtomBomb.BulletAttackRange;
- case BulletType.LineBullet:
- return LineBullet.BulletAttackRange;
- case BulletType.FastBullet:
- return FastBullet.BulletAttackRange;
- case BulletType.OrdinaryBullet:
- return OrdinaryBullet.BulletAttackRange;
- default:
- return 0;
- }
- }
- public static double BulletBombRange(BulletType bulletType)
- {
- switch (bulletType)
- {
- case BulletType.AtomBomb:
- return AtomBomb.BulletBombRange;
- case BulletType.LineBullet:
- return LineBullet.BulletBombRange;
- case BulletType.FastBullet:
- return FastBullet.BulletBombRange;
- case BulletType.OrdinaryBullet:
- return OrdinaryBullet.BulletBombRange;
- default:
- return 0;
- }
- }
- }
+
}
diff --git a/logic/GameClass/GameObj/Bullet/Bullet.Student.cs b/logic/GameClass/GameObj/Bullet/Bullet.Student.cs
new file mode 100644
index 0000000..6140d57
--- /dev/null
+++ b/logic/GameClass/GameObj/Bullet/Bullet.Student.cs
@@ -0,0 +1,7 @@
+using Preparation.Interface;
+using Preparation.Utility;
+using System;
+
+namespace GameClass.GameObj
+{
+}
diff --git a/logic/GameClass/GameObj/Bullet/Bullet.cs b/logic/GameClass/GameObj/Bullet/Bullet.cs
new file mode 100644
index 0000000..d0cc2f5
--- /dev/null
+++ b/logic/GameClass/GameObj/Bullet/Bullet.cs
@@ -0,0 +1,89 @@
+using Preparation.Interface;
+using Preparation.Utility;
+using System;
+
+namespace GameClass.GameObj
+{
+ public abstract class Bullet : ObjOfCharacter
+ {
+ ///
+ /// //攻击力
+ ///
+ public abstract double BulletBombRange{ get; }
+ public abstract double BulletAttackRange{ get; }
+ public abstract int AP { get; }
+ public abstract int Speed { get; }
+ public abstract bool IsToBomb { get; }
+ public abstract int Backswing { get; }
+ public abstract int RecoveryFromHit { get; }
+
+ private readonly bool hasSpear;
+ ///
+ /// 是否有矛
+ ///
+ public bool HasSpear => hasSpear;
+
+ ///
+ /// 与THUAI4不同的一个攻击判定方案,通过这个函数判断爆炸时能否伤害到target
+ ///
+ /// 被尝试攻击者
+ /// 是否可以攻击到
+ public abstract bool CanAttack(GameObj target);
+
+ protected override bool IgnoreCollideExecutor(IGameObj targetObj)
+ {
+ if (targetObj.Type == GameObjType.BirthPoint || targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet)
+ return true;
+ return false;
+ }
+ public Bullet(Character player, int radius) :
+ base(player.Position, radius, PlaceType.Null, GameObjType.Bullet)
+ {
+ this.CanMove = true;
+ this.moveSpeed = this.Speed;
+ this.hasSpear = player.HasSpear;
+ this.Parent = player;
+ }
+ public override bool IsRigid => true; // 默认为true
+ public override ShapeType Shape => ShapeType.Circle; // 默认为圆形
+ public abstract BulletType TypeOfBullet { get; }
+ }
+
+ public static class BulletFactory
+ {
+ public static Bullet? GetBullet(Character character)
+ {
+ Bullet? newBullet = null;
+ switch (character.BulletOfPlayer)
+ {
+ case BulletType.AtomBomb:
+ newBullet = new AtomBomb(character);
+ break;
+ case BulletType.LineBullet:
+ newBullet = new LineBullet(character);
+ break;
+ case BulletType.FastBullet:
+ newBullet = new FastBullet(character);
+ break;
+ case BulletType.OrdinaryBullet:
+ newBullet = new OrdinaryBullet(character);
+ break;
+ default:
+ break;
+ }
+ return newBullet;
+ }
+ public static int BulletRadius(BulletType bulletType)
+ {
+ switch (bulletType)
+ {
+ case BulletType.AtomBomb:
+ case BulletType.LineBullet:
+ case BulletType.FastBullet:
+ case BulletType.OrdinaryBullet:
+ default:
+ return GameData.bulletRadius;
+ }
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Character/Character.SkillManager.cs b/logic/GameClass/GameObj/Character/Character.SkillManager.cs
index 36b522f..a9a604f 100644
--- a/logic/GameClass/GameObj/Character/Character.SkillManager.cs
+++ b/logic/GameClass/GameObj/Character/Character.SkillManager.cs
@@ -19,15 +19,18 @@ namespace GameClass.GameObj
{
return commonSkill(this);
}
- private int timeUntilCommonSkillAvailable = 0; // 还剩多少时间可以使用普通技能
- public int TimeUntilCommonSkillAvailable
+
+ private Dictionary TimeUntilActiveSkillAvailable { get; set; }
+
+ public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable)
{
- get => timeUntilCommonSkillAvailable;
- set
+ lock (gameObjLock)
+ if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType))
{
- lock (gameObjLock)
- timeUntilCommonSkillAvailable = value < 0 ? 0 : value;
+ TimeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0;
+ return true;
}
+ return false;
}
readonly CharacterPassiveSkill passiveSkill;
@@ -41,14 +44,14 @@ namespace GameClass.GameObj
{
return this.characterType switch
{
- CharacterType.Assassin => true,
- CharacterType.Vampire => true,
+ this.CharacterType.Assassin => true,
+ this.CharacterType.Vampire => true,
- CharacterType.Null => false,
- CharacterType.RecoverAfterBattle => false,
- CharacterType.SpeedUpWhenLeavingGrass => false,
- CharacterType.PSkill4 => false,
- CharacterType.PSkill5 => false,
+ this.CharacterType.Null => false,
+ this.CharacterType.RecoverAfterBattle => false,
+ this.CharacterType.SpeedUpWhenLeavingGrass => false,
+ this.CharacterType.PSkill4 => false,
+ this.CharacterType.PSkill5 => false,
_ => false,
};
}
@@ -61,19 +64,19 @@ namespace GameClass.GameObj
this.propInventory = null;
this.buffManeger = new BuffManeger();
IPassiveSkill pSkill;
- ICommonSkill cSkill;
+ IActiveSkill cSkill;
switch (characterType)
{
- case CharacterType.Assassin:
- pSkill = new();
+ case this.CharacterType.Assassin:
+ pSkill = null;
break;
- case CharacterType.RecoverAfterBattle:
+ case this.CharacterType.RecoverAfterBattle:
pSkill = new RecoverAfterBattle();
break;
- case CharacterType.SpeedUpWhenLeavingGrass:
+ case this.CharacterType.SpeedUpWhenLeavingGrass:
pSkill = new SpeedUpWhenLeavingGrass();
break;
- case CharacterType.Vampire:
+ case this.CharacterType.Vampire:
pSkill = new Vampire();
break;
default:
@@ -83,7 +86,7 @@ namespace GameClass.GameObj
switch (commonSkillType)
{
case ActiveSkillType.BecomeAssassin:
- cSkill = new BecomeAssassin();
+ cSkill = new BecomeInvisible();
break;
case ActiveSkillType.BecomeVampire:
cSkill = new BecomeVampire();
@@ -102,7 +105,6 @@ namespace GameClass.GameObj
this.hp = cSkill.MaxHp;
this.OrgMoveSpeed = cSkill.MoveSpeed;
this.moveSpeed = cSkill.MoveSpeed;
- this.cd = cSkill.CD;
this.maxBulletNum = cSkill.MaxBulletNum;
this.bulletNum = maxBulletNum;
this.bulletOfPlayer = pSkill.InitBullet;
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index ba2bcb0..2f14ca9 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -2,6 +2,7 @@
using Preparation.Utility;
using System;
using System.Collections.Generic;
+using System.Numerics;
using System.Runtime.InteropServices;
using System.Threading;
@@ -13,26 +14,7 @@ namespace GameClass.GameObj
#region 角色的基本属性及方法,包括与道具的交互方法
- ///
- /// 装弹冷却
- ///
- protected int cd;
- public int CD
- {
- get => cd;
- private
- set
- {
- lock (gameObjLock)
- {
- cd = value;
- Debugger.Output(this, string.Format("'s CD has been set to: {0}.", value));
- }
- }
- }
- public int OrgCD { get; protected set; }
-
- protected int fixSpeed;
+ protected int fixSpeed = 1;
///
/// 修理电机速度
///
@@ -90,7 +72,7 @@ namespace GameClass.GameObj
get => score;
}
- public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer);
+ // public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer);
private double vampire = 0; // 回血率:0-1之间
public double Vampire
@@ -272,16 +254,13 @@ namespace GameClass.GameObj
///
/// 减血量
/// 减操作是否成功
- public bool TrySubHp(int sub)
+ public int TrySubHp(int sub)
{
- if (hp > 0)
- {
+ int previousHp = hp;
lock (gameObjLock)
- hp = 0 >= hp - sub ? 0 : hp - sub;
+ hp = hp >= sub ? 0 : hp - sub;
Debugger.Output(this, " hp has subed to: " + hp.ToString());
- return true;
- }
- return false;
+ return previousHp - hp;
}
/* ///
/// 增加死亡次数
@@ -327,7 +306,7 @@ namespace GameClass.GameObj
///
/// 伤害来源
/// 人物在受到攻击后死了吗
- public bool BeAttack(Bullet bullet)
+ public bool BeAttacked(Bullet bullet)
{
lock (beAttackedLock)
@@ -346,7 +325,7 @@ namespace GameClass.GameObj
}
else
{
- TrySubHp(bullet.AP);
+ bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP)));
}
#if DEBUG
Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}.");
diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs
index eecbabb..fc51880 100644
--- a/logic/GameClass/GameObj/GameObj.cs
+++ b/logic/GameClass/GameObj/GameObj.cs
@@ -171,6 +171,7 @@ namespace GameClass.GameObj
///
/// 依具体类及该方法参数而定,默认为false
protected virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false;
+
bool IMoveable.IgnoreCollide(IGameObj targetObj) => IgnoreCollideExecutor(targetObj);
public GameObj(XY initPos, int initRadius, PlaceType initPlace, GameObjType initType)
{
diff --git a/logic/GameClass/GameObj/Map/MapInfo.cs b/logic/GameClass/GameObj/Map/MapInfo.cs
index 436456e..53b9453 100644
--- a/logic/GameClass/GameObj/Map/MapInfo.cs
+++ b/logic/GameClass/GameObj/Map/MapInfo.cs
@@ -1,7 +1,4 @@
-using Preparation.Utility;
-using Preparation.GameData;
-
-namespace GameClass.GameObj
+namespace GameClass.GameObj
{
public static class MapInfo
{
diff --git a/logic/GameClass/GameObj/Prop.cs b/logic/GameClass/GameObj/Prop.cs
index 2e2e373..8e6dfbc 100644
--- a/logic/GameClass/GameObj/Prop.cs
+++ b/logic/GameClass/GameObj/Prop.cs
@@ -33,6 +33,8 @@ namespace GameClass.GameObj
}
}
+
+
/////
///// 坑人地雷
/////
diff --git a/logic/GameClass/Skill/CommonSkill.cs b/logic/GameClass/Skill/ActiveSkill.cs
similarity index 77%
rename from logic/GameClass/Skill/CommonSkill.cs
rename to logic/GameClass/Skill/ActiveSkill.cs
index 5a8588b..afecdaa 100644
--- a/logic/GameClass/Skill/CommonSkill.cs
+++ b/logic/GameClass/Skill/ActiveSkill.cs
@@ -7,7 +7,7 @@ using Timothy.FrameRateTask;
namespace GameClass.Skill
{
- public class BecomeVampire : ICommonSkill // 化身吸血鬼
+ public class BecomeVampire : IActiveSkill // 化身吸血鬼
{
private const int moveSpeed = GameData.basicMoveSpeed;
public int MoveSpeed => moveSpeed;
@@ -15,22 +15,16 @@ namespace GameClass.Skill
private const int maxHp = (int)(GameData.basicHp / 6 * 9.5);
public int MaxHp => maxHp;
- private const int cd = GameData.basicCD;
- public int CD => cd;
-
- private const int maxBulletNum = GameData.basicBulletNum * 2 / 3;
- public int MaxBulletNum => maxBulletNum;
-
// 以上参数以后再改
public int SkillCD => GameData.commonSkillCD / 3 * 4;
public int DurationTime => GameData.commonSkillTime;
private readonly object commonSkillLock = new object();
- public object CommonSkillLock => commonSkillLock;
+ public object ActiveSkillLock => commonSkillLock;
public bool SkillEffect(Character player)
{
- return CommonSkillFactory.SkillEffect(this, player, () =>
+ return ActiveSkillFactory.SkillEffect(this, player, () =>
{
player.Vampire += 0.5;
Debugger.Output(player, "becomes vampire!");
@@ -42,28 +36,16 @@ namespace GameClass.Skill
});
}
}
- public class BecomeAssassin : ICommonSkill // 化身刺客,隐身
+ public class BecomeInvisible : IActiveSkill
{
- private const int moveSpeed = GameData.basicMoveSpeed / 3 * 5;
- public int MoveSpeed => moveSpeed;
-
- private const int maxHp = (int)(GameData.basicHp / 6 * 7.5);
- public int MaxHp => maxHp;
-
- private const int cd = GameData.basicCD;
- public int CD => cd;
-
- private const int maxBulletNum = GameData.basicBulletNum;
- public int MaxBulletNum => maxBulletNum;
- // 以上参数以后再改
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 6;
private readonly object commonSkillLock = new object();
- public object CommonSkillLock => commonSkillLock;
+ public object ActiveSkillLock => commonSkillLock;
public bool SkillEffect(Character player)
{
- return CommonSkillFactory.SkillEffect(this, player, () =>
+ return ActiveSkillFactory.SkillEffect(this, player, () =>
{
player.IsInvisible = true;
Debugger.Output(player, "uses atombomb!");
@@ -72,7 +54,7 @@ namespace GameClass.Skill
{ player.IsInvisible = false; });
}
}
- public class NuclearWeapon : ICommonSkill // 核武器
+ public class NuclearWeapon : IActiveSkill // 核武器
{
private const int moveSpeed = GameData.basicMoveSpeed / 3 * 4;
public int MoveSpeed => moveSpeed;
@@ -80,19 +62,16 @@ namespace GameClass.Skill
private const int maxHp = GameData.basicHp;
public int MaxHp => maxHp;
- private const int cd = GameData.basicCD;
- public int CD => cd;
-
private const int maxBulletNum = GameData.basicBulletNum * 2 / 3;
public int MaxBulletNum => maxBulletNum;
// 以上参数以后再改
public int SkillCD => GameData.commonSkillCD / 3 * 7;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
- public object CommonSkillLock => commonSkillLock;
+ public object ActiveSkillLock => commonSkillLock;
public bool SkillEffect(Character player)
{
- return CommonSkillFactory.SkillEffect(this, player, () =>
+ return ActiveSkillFactory.SkillEffect(this, player, () =>
{
player.BulletOfPlayer = BulletType.AtomBomb;
Debugger.Output(player, "uses atombomb!");
@@ -101,7 +80,7 @@ namespace GameClass.Skill
{ player.BulletOfPlayer = player.OriBulletOfPlayer; });
}
}
- public class SuperFast : ICommonSkill // 3倍速
+ public class SuperFast : IActiveSkill // 3倍速
{
private const int moveSpeed = GameData.basicMoveSpeed * 4 / 3;
public int MoveSpeed => moveSpeed;
@@ -109,19 +88,16 @@ namespace GameClass.Skill
private const int maxHp = GameData.basicHp / 6 * 4;
public int MaxHp => maxHp;
- private const int cd = GameData.basicCD;
- public int CD => cd;
-
private const int maxBulletNum = GameData.basicBulletNum * 4 / 3;
public int MaxBulletNum => maxBulletNum;
// 以上参数以后再改
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 4;
private readonly object commonSkillLock = new object();
- public object CommonSkillLock => commonSkillLock;
+ public object ActiveSkillLock => commonSkillLock;
public bool SkillEffect(Character player)
{
- return CommonSkillFactory.SkillEffect(this, player, () =>
+ return ActiveSkillFactory.SkillEffect(this, player, () =>
{
player.AddMoveSpeed(this.DurationTime, 3.0);
Debugger.Output(player, "moves very fast!");
@@ -130,7 +106,7 @@ namespace GameClass.Skill
{ });
}
}
- public class NoCommonSkill : ICommonSkill // 这种情况不该发生,定义着以防意外
+ public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外
{
private const int moveSpeed = GameData.basicMoveSpeed;
public int MoveSpeed => moveSpeed;
@@ -138,31 +114,28 @@ namespace GameClass.Skill
private const int maxHp = GameData.basicHp;
public int MaxHp => maxHp;
- private const int cd = GameData.basicCD;
- public int CD => cd;
-
private const int maxBulletNum = GameData.basicBulletNum;
public int MaxBulletNum => maxBulletNum;
// 以上参数以后再改
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime;
private readonly object commonSkillLock = new object();
- public object CommonSkillLock => commonSkillLock;
+ public object ActiveSkillLock => commonSkillLock;
public bool SkillEffect(Character player)
{
return false;
}
}
- public static class CommonSkillFactory
+ public static class ActiveSkillFactory
{
- public static bool SkillEffect(ICommonSkill commonSkill, Character player, Action startSkill, Action endSkill)
+ public static bool SkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill)
{
- lock (commonSkill.CommonSkillLock)
+ lock (activeSkill.ActiveSkillLock)
{
if (player.TimeUntilCommonSkillAvailable == 0)
{
- player.TimeUntilCommonSkillAvailable = commonSkill.SkillCD;
+ player.TimeUntilCommonSkillAvailable = activeSkill.SkillCD;
new Thread
(() =>
{
@@ -175,7 +148,7 @@ namespace GameClass.Skill
},
timeInterval: GameData.frameDuration,
() => 0,
- maxTotalDuration: (long)(commonSkill.DurationTime)
+ maxTotalDuration: (long)(activeSkill.DurationTime)
)
{
AllowTimeExceed = true,
@@ -194,7 +167,7 @@ namespace GameClass.Skill
},
timeInterval: GameData.frameDuration,
() => 0,
- maxTotalDuration: (long)(commonSkill.SkillCD - commonSkill.DurationTime)
+ maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime)
)
{
AllowTimeExceed = true,
diff --git a/logic/GameClass/Skill/ISkill.cs b/logic/GameClass/Skill/ISkill.cs
index a80db89..1735236 100644
--- a/logic/GameClass/Skill/ISkill.cs
+++ b/logic/GameClass/Skill/ISkill.cs
@@ -1,23 +1,29 @@
using GameClass.GameObj;
using Preparation.Utility;
-using System.Threading;
+using System.Collections.Generic;
namespace GameClass.Skill
{
- public interface IPassiveSkill
+ public interface ISkill
+ {
+ }
+ public interface IPassiveSkill: ISkill
{
- public BulletType InitBullet { get; }
public void SkillEffect(Character player);
}
- public interface ICommonSkill
+ public interface IActiveSkill : ISkill
+ {
+ public int SkillCD { get; }
+ public int DurationTime { get; } //技能持续时间
+ public object ActiveSkillLock { get; }
+ public bool SkillEffect(Character player);
+ }
+ public interface ICharacterType
{
public int MoveSpeed { get; }
public int MaxHp { get; }
- public int CD { get; }
- public int MaxBulletNum { get; }
- public bool SkillEffect(Character player);
- public int DurationTime { get; } // 技能持续时间
- public int SkillCD { get; }
- public object CommonSkillLock { get; }
+ public BulletType InitBullet { get; }
+ public List ListOfIActiveSkill { get; }
+ public List ListOfIPassiveSkill { get; }
}
}
diff --git a/logic/GameClass/Skill/Occupation.cs b/logic/GameClass/Skill/Occupation.cs
new file mode 100644
index 0000000..4cb4f65
--- /dev/null
+++ b/logic/GameClass/Skill/Occupation.cs
@@ -0,0 +1,32 @@
+using GameClass.GameObj;
+using System.Threading;
+using Preparation.Interface;
+using Preparation.Utility;
+using System;
+using System.Collections.Generic;
+
+namespace GameClass.Skill
+{
+ public abstract class Occupation
+ {
+ public abstract int MoveSpeed { get; }
+ public abstract int MaxHp { get; }
+ public abstract BulletType InitBullet { get; }
+ public abstract List ListOfIActiveSkill { get; }
+ public abstract List ListOfIPassiveSkill { get; }
+ }
+ public class Assassin : Occupation
+ {
+ private const int moveSpeed = GameData.basicMoveSpeed/380*473;
+ public override int MoveSpeed => moveSpeed;
+
+ private const int maxHp = GameData.basicHp;
+ public override int MaxHp => maxHp;
+
+ public override BulletType InitBullet => BulletType.CommonAttackOfGhost;
+
+ public override List ListOfIActiveSkill => new(new IActiveSkill[]{new BecomeInvisible(),});
+ public override List ListOfIPassiveSkill => new(new IPassiveSkill[] {});
+ }
+
+}
diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs
index 2cb0d5e..6ac60db 100644
--- a/logic/Gaming/ActionManager.cs
+++ b/logic/Gaming/ActionManager.cs
@@ -30,7 +30,7 @@ namespace Gaming
{
foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
{
- if (GameData.IsInTheSameCell(generator.Position, player.Position))
+ if (GameData.ApproachToInteract(generator.Position, player.Position))
{
generatorForFix = generator;
break;
diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs
index c1da35d..21ba15a 100644
--- a/logic/Gaming/AttackManager.cs
+++ b/logic/Gaming/AttackManager.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using GameClass.GameObj;
using Preparation.Utility;
using GameEngine;
+using Preparation.Interface;
namespace Gaming
{
@@ -34,67 +35,80 @@ namespace Gaming
}
);
}
- private void BombOnePlayer(Bullet bullet, Character playerBeingShot)
+ private bool CanBeBombed(Bullet bullet, GameObjType gameObjType)
{
- if (playerBeingShot.BeAttack(bullet))
+ if (gameObjType==GameObjType.Character)return true;
+ return false;
+ }
+ private void BombObj(Bullet bullet, GameObj objBeingShot)
+ {
+ switch (objBeingShot.Type)
{
- playerBeingShot.CanMove = false;
- playerBeingShot.IsResetting = true;
- // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
- // try
- //{
- // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot);
- // }
- // finally
- //{
- // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
- // }
-
- Prop? dropProp = null;
- if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地
- {
- dropProp = playerBeingShot.PropInventory;
- dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell));
- }
- gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
- try
- {
- if (dropProp != null)
- gameMap.GameObjDict[GameObjType.Prop].Add(dropProp);
- }
- finally
- {
- gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
- }
-
- playerBeingShot.Reset();
- ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分
-
- new Thread
- (() =>
+ case GameObjType.Character:
+ Character playerBeingShot= (Character)objBeingShot;
+ if (playerBeingShot.BeAttacked(bullet))
{
-
- Thread.Sleep(GameData.reviveTime);
-
- playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾
-
+ playerBeingShot.CanMove = false;
+ playerBeingShot.IsResetting = true;
// gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
// try
//{
- // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot);
+ // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot);
+ // }
+ // finally
+ //{
+ // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
// }
- // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); }
- if (gameMap.Timer.IsGaming)
+ Prop? dropProp = null;
+ if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地
+ {
+ dropProp = playerBeingShot.PropInventory;
+ dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell));
+ }
+ gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
+ try
{
- playerBeingShot.CanMove = true;
+ if (dropProp != null)
+ gameMap.GameObjDict[GameObjType.Prop].Add(dropProp);
}
- playerBeingShot.IsResetting = false;
+ finally
+ {
+ gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
+ }
+
+ playerBeingShot.Reset();
+ ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分
+
+ /* new Thread
+ (() =>
+ {
+
+ Thread.Sleep(GameData.reviveTime);
+
+ playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾
+
+ // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
+ // try
+ //{
+ // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot);
+ // }
+ // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); }
+
+ if (gameMap.Timer.IsGaming)
+ {
+ playerBeingShot.CanMove = true;
+ }
+ playerBeingShot.IsResetting = false;
+ }
+ )
+ { IsBackground = true }.Start();
+ */
}
- )
- { IsBackground = true }.Start();
+ break;
}
}
+
private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
{
#if DEBUG
@@ -127,6 +141,55 @@ namespace Gaming
gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
}
+ if (!bullet.IsToBomb)
+ {
+ if (objBeingShot==null)
+ {
+ if (bullet.Backswing>0)
+ {
+ bullet.Parent.CanMove=false;
+ bullet.Parent.IsMoving=false;
+
+ new Thread
+ (() =>
+ {
+ Thread.Sleep(bullet.Backswing);
+
+ if (gameMap.Timer.IsGaming)
+ {
+ bullet.Parent.CanMove = true;
+ }
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+ return;
+ }
+
+
+ BombObj(bullet, objBeingShot);
+ if (bullet.RecoveryFromHit>0)
+ {
+ bullet.Parent.CanMove=false;
+ bullet.Parent.IsMoving=false;
+
+ new Thread
+ (() =>
+ {
+
+ Thread.Sleep(bullet.RecoveryFromHit);
+
+ if (gameMap.Timer.IsGaming)
+ {
+ bullet.Parent.CanMove = true;
+ }
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+ return;
+ }
+
/*if (objBeingShot != null)
{
else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。
@@ -136,31 +199,79 @@ namespace Gaming
}*/
// 子弹爆炸会发生的事↓↓↓
- var beAttackedList = new List();
- gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
- try
+ var beAttackedList = new List();
+
+ foreach (var kvp in gameMap.GameObjDict)
{
- foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
+ if (CanBeBombed(bullet, kvp.Key))
{
- if (bullet.CanAttack(player))
+ gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
+ try
{
- beAttackedList.Add(player);
- if (player.ID != bullet.Parent.ID)
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * bullet.AP));
+ foreach (var item in gameMap.GameObjDict[kvp.Key])
+ if (bullet.CanAttack((GameObj)item))
+ {
+ beAttackedList.Add(item);
+ }
+
+ }
+ finally
+ {
+ gameMap.GameObjLockDict[kvp.Key].ExitWriteLock();
}
}
}
- finally
+
+ foreach (GameObj beAttackedObj in beAttackedList)
{
- gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
+ BombObj(bullet, beAttackedObj);
}
-
- foreach (Character beAttackedPlayer in beAttackedList)
+ if (objBeingShot==null)
{
- BombOnePlayer(bullet, beAttackedPlayer);
+ if (bullet.Backswing>0)
+ {
+ bullet.Parent.CanMove=false;
+ bullet.Parent.IsMoving=false;
+
+ new Thread
+ (() =>
+ {
+ Thread.Sleep(bullet.Backswing);
+
+ if (gameMap.Timer.IsGaming)
+ {
+ bullet.Parent.CanMove = true;
+ }
+ }
+ )
+ { IsBackground = true }.Start();
+ }
}
+ else
+ {
+ if (bullet.RecoveryFromHit>0)
+ {
+ bullet.Parent.CanMove=false;
+ bullet.Parent.IsMoving=false;
+
+ new Thread
+ (() =>
+ {
+
+ Thread.Sleep(bullet.RecoveryFromHit);
+
+ if (gameMap.Timer.IsGaming)
+ {
+ bullet.Parent.CanMove = true;
+ }
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+ }
beAttackedList.Clear();
}
+
public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头)
{ // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
if (player == null)
@@ -192,7 +303,7 @@ namespace Gaming
{
gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
}
- moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
+ moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
#if DEBUG
Console.WriteLine($"playerID:{player.ID} successfully attacked!");
#endif
diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs
index 3f55577..56db5c4 100644
--- a/logic/Gaming/Game.cs
+++ b/logic/Gaming/Game.cs
@@ -31,7 +31,7 @@ namespace Gaming
public List TeamList => teamList;
private readonly Map gameMap;
public Map GameMap => gameMap;
- private readonly int numOfTeam;
+ // private readonly int numOfTeam;
public long AddPlayer(PlayerInitInfo playerInitInfo)
{
if (!Team.teamExists(playerInitInfo.teamID))
@@ -57,7 +57,7 @@ namespace Gaming
newPlayer.TeamID = playerInitInfo.teamID;
newPlayer.PlayerID = playerInitInfo.playerID;
- new Thread //人物装弹
+ /*new Thread //人物装弹
(
() =>
{
@@ -85,16 +85,16 @@ namespace Gaming
)
{
AllowTimeExceed = true
- /*MaxTolerantTimeExceedCount = 5,
+ MaxTolerantTimeExceedCount = 5,
TimeExceedAction = exceedTooMuch =>
{
if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!");
- }*/
+ }
}
.Start();
}
)
- { IsBackground = true }.Start();
+ { IsBackground = true }.Start();*/
return newPlayer.ID;
}
@@ -132,7 +132,7 @@ namespace Gaming
if (kvp.Key == GameObjType.Bullet || kvp.Key == GameObjType.Character || kvp.Key == GameObjType.Prop)
{
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
- try
+ try
{
foreach (var item in gameMap.GameObjDict[kvp.Key])
{
@@ -342,7 +342,7 @@ namespace Gaming
gameMap = new Map(mapResource);
// 加入队伍
- this.numOfTeam = numOfTeam;
+ // this.numOfTeam = numOfTeam;
teamList = new List();
for (int i = 0; i < numOfTeam; ++i)
{
diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs
index 3f0d946..2bc4f1b 100644
--- a/logic/Preparation/Utility/EnumType.cs
+++ b/logic/Preparation/Utility/EnumType.cs
@@ -42,7 +42,9 @@ namespace Preparation.Utility
OrdinaryBullet = 1, // 普通子弹
AtomBomb = 2, // 原子弹
FastBullet = 3, // 快速子弹
- LineBullet = 4 // 直线子弹
+ LineBullet = 4, // 直线子弹
+ FlyingKnife = 5, //飞刀
+ CommonAttackOfGhost = 6
}
public enum PropType // 道具类型
{
@@ -66,7 +68,7 @@ namespace Preparation.Utility
public enum ActiveSkillType // 主动技能
{
Null = 0,
- BecomeAssassin = 1,
+ BecomeInvisible = 1,
BecomeVampire = 2,
NuclearWeapon = 3,
SuperFast = 4,
diff --git a/logic/Preparation/Utility/GameData.cs b/logic/Preparation/Utility/GameData.cs
index a01bce8..a296986 100644
--- a/logic/Preparation/Utility/GameData.cs
+++ b/logic/Preparation/Utility/GameData.cs
@@ -1,4 +1,5 @@
-namespace Preparation.Utility
+using System;
+namespace Preparation.Utility
{
public static class GameData
{
@@ -37,19 +38,25 @@
{
return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
}
+ public static bool ApproachToInteract(XY pos1, XY pos2)
+ {
+ return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2))<=1 && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2))<=1;
+ }
#endregion
#region 角色相关
public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径
- public const int basicAp = 3000; // 初始攻击力
- public const int basicHp = 6000; // 初始血量
- public const int basicCD = 3000; // 初始子弹冷却
+ public const int basicApOfGhost = 500; // 初始攻击力
+ public const int basicHp = 1003; // 初始血量
+ public const int basicBackswing = 500;//基本后摇时间
+ public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长
public const int basicBulletNum = 3; // 基本初始子弹量
public const int MinAP = 0; // 最小攻击力
public const int MaxAP = int.MaxValue; // 最大攻击力
- public const double basicAttackRange = 9000; // 基本攻击范围
+ public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围
+ public const double basicAttackShortRange = 2700; // 基本近程攻击范围
public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围
- public const int basicMoveSpeed = 3000; // 基本移动速度,单位:s-1
- public const int basicBulletMoveSpeed = 3000; // 基本子弹移动速度,单位:s-1
+ public const int basicMoveSpeed = 3800; // 基本移动速度,单位:s-1
+ public const int basicBulletMoveSpeed = 5400; // 基本子弹移动速度,单位:s-1
public const int characterMaxSpeed = 12000; // 最大速度
public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分
public const int commonSkillCD = 30000; // 普通技能标准冷却时间
@@ -70,7 +77,7 @@
public const long PropProduceTime = 10000;
public const int PropDuration = 10000;
- public const int degreeOfFixedGenerator = 100;
+ public const int degreeOfFixedGenerator = 2000;
#endregion
#region 游戏帧相关
public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长