From 6933e26548142ea850a1c284ea577b8d289ccf48 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 26 Nov 2022 23:53:08 +0800
Subject: [PATCH 1/5] build: :construction_worker: add map and character
TAT
---
logic/.gitignore | 3 +
logic/GameClass/GameClass.csproj | 13 ++
.../GameObj/Character.BuffManager.cs | 172 ++++++++++++++++++
.../GameObj/Character.SkillManager.cs | 51 ++++++
logic/GameClass/GameObj/Map/Map.cs | 156 ++++++++++++++++
logic/GameClass/GameObj/Map/MapGameTimer.cs | 32 ++++
logic/GameClass/GameObj/Map/MapInfo.cs | 77 ++++++++
logic/GameClass/GameObj/Map/Wall.cs | 19 ++
logic/GameClass/GameObj/OutOfBoundBlock.cs | 20 ++
logic/GameEngine/MoveEngine.cs | 2 +-
logic/Gaming/Gaming.csproj | 14 ++
logic/Preparation/GameData/GameData.cs | 2 +
logic/Preparation/Interface/IOutOfBound.cs | 8 +
logic/Preparation/Preparation.csproj | 11 ++
logic/Preparation/Utility/EnumType.cs | 15 +-
logic/logic.sln | 30 +++
16 files changed, 622 insertions(+), 3 deletions(-)
create mode 100644 logic/GameClass/GameClass.csproj
create mode 100644 logic/GameClass/GameObj/Character.BuffManager.cs
create mode 100644 logic/GameClass/GameObj/Character.SkillManager.cs
create mode 100644 logic/GameClass/GameObj/Map/Map.cs
create mode 100644 logic/GameClass/GameObj/Map/MapGameTimer.cs
create mode 100644 logic/GameClass/GameObj/Map/MapInfo.cs
create mode 100644 logic/GameClass/GameObj/Map/Wall.cs
create mode 100644 logic/GameClass/GameObj/OutOfBoundBlock.cs
create mode 100644 logic/Gaming/Gaming.csproj
create mode 100644 logic/Preparation/Interface/IOutOfBound.cs
create mode 100644 logic/Preparation/Preparation.csproj
diff --git a/logic/.gitignore b/logic/.gitignore
index ec116cb..762b4b5 100644
--- a/logic/.gitignore
+++ b/logic/.gitignore
@@ -399,3 +399,6 @@ FodyWeavers.xsd
#THUAI playback file
*.thuaipb
+
+Client/
+CSharpInterface/
diff --git a/logic/GameClass/GameClass.csproj b/logic/GameClass/GameClass.csproj
new file mode 100644
index 0000000..de8abd4
--- /dev/null
+++ b/logic/GameClass/GameClass.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ enable
+
+
+
+
+
+
+
+
diff --git a/logic/GameClass/GameObj/Character.BuffManager.cs b/logic/GameClass/GameObj/Character.BuffManager.cs
new file mode 100644
index 0000000..b580e9e
--- /dev/null
+++ b/logic/GameClass/GameObj/Character.BuffManager.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Preparation.Utility;
+using Preparation.GameData;
+
+namespace GameClass.GameObj
+{
+ public partial class Character
+ {
+ private readonly BuffManeger buffManeger;
+ ///
+ /// 角色携带的buff管理器
+ ///
+ private class BuffManeger
+ {
+ [StructLayout(LayoutKind.Explicit, Size = 8)]
+ private struct BuffValue // buff参数联合体类型,可能是int或double
+ {
+ [FieldOffset(0)]
+ public int iValue;
+ [FieldOffset(0)]
+ public double lfValue;
+
+ public BuffValue(int intValue)
+ {
+ this.lfValue = 0.0;
+ this.iValue = intValue;
+ }
+ public BuffValue(double longFloatValue)
+ {
+ this.iValue = 0;
+ this.lfValue = longFloatValue;
+ }
+ }
+
+ ///
+ /// buff列表
+ ///
+ private readonly LinkedList[] buffList;
+ private readonly object[] buffListLock;
+
+ private void AddBuff(BuffValue bf, int buffTime, BuffType buffType, Action ReCalculateFunc)
+ {
+ new Thread
+ (
+ () =>
+ {
+ LinkedListNode buffNode;
+ lock (buffListLock[(int)buffType])
+ {
+ buffNode = buffList[(int)buffType].AddLast(bf);
+ }
+ ReCalculateFunc();
+ Thread.Sleep(buffTime);
+ try
+ {
+ lock (buffListLock[(int)buffType])
+ {
+ buffList[(int)buffType].Remove(buffNode);
+ }
+ }
+ catch
+ {
+ }
+ ReCalculateFunc();
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+
+ private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal)
+ {
+ double times = 1.0;
+ lock (buffListLock[(int)buffType])
+ {
+ foreach (var add in buffList[(int)buffType])
+ {
+ times *= add.lfValue;
+ }
+ }
+ return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal);
+ }
+
+ public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)));
+ public bool HasFasterSpeed
+ {
+ get {
+ lock (buffListLock[(int)BuffType.AddSpeed])
+ {
+ return buffList[(int)BuffType.AddSpeed].Count != 0;
+ }
+ }
+ }
+
+ public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () =>
+ {});
+ public bool HasShield
+ {
+ get {
+ lock (buffListLock[(int)BuffType.Shield])
+ {
+ return buffList[(int)BuffType.Shield].Count != 0;
+ }
+ }
+ }
+
+ public void AddLIFE(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLIFE, () =>
+ {});
+ public bool HasLIFE
+ {
+ get {
+ lock (buffListLock[(int)BuffType.AddLIFE])
+ {
+ return buffList[(int)BuffType.AddLIFE].Count != 0;
+ }
+ }
+ }
+ public bool TryActivatingLIFE()
+ {
+ if (HasLIFE)
+ {
+ lock (buffListLock[(int)BuffType.AddLIFE])
+ {
+ buffList[(int)BuffType.AddLIFE].Clear();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () =>
+ {});
+ public bool HasSpear
+ {
+ get {
+ lock (buffListLock[(int)BuffType.Spear])
+ {
+ return buffList[(int)BuffType.Spear].Count != 0;
+ }
+ }
+ }
+ ///
+ /// 清除所有buff
+ ///
+ public void ClearAll()
+ {
+ for (int i = 0; i < buffList.Length; ++i)
+ {
+ lock (buffListLock[i])
+ {
+ buffList[i].Clear();
+ }
+ }
+ }
+
+ public BuffManeger()
+ {
+ var buffTypeArray = Enum.GetValues(typeof(BuffType));
+ buffList = new LinkedList[buffTypeArray.Length];
+ buffListLock = new object[buffList.Length];
+ int i = 0;
+ foreach (BuffType type in buffTypeArray)
+ {
+ buffList[i] = new LinkedList();
+ buffListLock[i++] = new object();
+ }
+ }
+ }
+}
+}
diff --git a/logic/GameClass/GameObj/Character.SkillManager.cs b/logic/GameClass/GameObj/Character.SkillManager.cs
new file mode 100644
index 0000000..2bd8c5f
--- /dev/null
+++ b/logic/GameClass/GameObj/Character.SkillManager.cs
@@ -0,0 +1,51 @@
+using Preparation.Utility;
+using System.Collections.Generic;
+using System;
+
+namespace GameClass.GameObj
+{
+ public partial class Character
+ {
+ private delegate bool CharacterActiveSkill(Character player); // 返回值:是否成功释放了技能
+ private delegate void CharacterPassiveSkill(Character player);
+ private readonly CharacterActiveSkill commonSkill;
+ private readonly ActiveSkillType commonSkillType;
+ public ActiveSkillType CommonSkillType => commonSkillType;
+
+ private readonly CharacterType passiveSkillType;
+ public CharacterType PassiveSkillType => passiveSkillType;
+ public bool UseCommonSkill()
+ {
+ return commonSkill(this);
+ }
+ private int timeUntilCommonSkillAvailable = 0; // 还剩多少时间可以使用普通技能
+ public int TimeUntilCommonSkillAvailable
+ {
+ get => timeUntilCommonSkillAvailable;
+ set {
+ lock (gameObjLock)
+ timeUntilCommonSkillAvailable = value < 0 ? 0 : value;
+ }
+ }
+
+ readonly CharacterPassiveSkill passiveSkill;
+ public void UsePassiveSkill()
+ {
+ passiveSkill(this);
+ return;
+ }
+ public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType passiveSkillType, ActiveSkillType commonSkillType) :
+ base(initPos, initRadius, initPlace, GameObjType.Character)
+ {
+ this.CanMove = true;
+ this.score = 0;
+ this.propInventory = null;
+ this.buffManeger = new BuffManeger();
+
+ // UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行
+ // 这可以放在AddPlayer中做
+
+ Debugger.Output(this, "constructed!");
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs
new file mode 100644
index 0000000..c382099
--- /dev/null
+++ b/logic/GameClass/GameObj/Map/Map.cs
@@ -0,0 +1,156 @@
+using System.Collections.Generic;
+using System.Threading;
+using Preparation.Interface;
+using Preparation.Utility;
+using Preparation.GameData;
+using System;
+
+namespace GameClass.GameObj
+{
+ public partial class Map : IMap
+ {
+
+ private readonly Dictionary birthPointList; // 出生点列表
+ public Dictionary BirthPointList => birthPointList;
+
+ private Dictionary> gameObjDict;
+ public Dictionary> GameObjDict => gameObjDict;
+ private Dictionary gameObjLockDict;
+ public Dictionary GameObjLockDict => gameObjLockDict;
+
+ public readonly uint[,] ProtoGameMap;
+ public PlaceType GetPlaceType(GameObj obj)
+ {
+ try
+ {
+ uint type = ProtoGameMap[obj.Position.x / GameData.numOfPosGridPerCell, obj.Position.y / GameData.numOfPosGridPerCell];
+ if (type == 2)
+ return PlaceType.Grass1;
+ else if (type == 3)
+ return PlaceType.Grass2;
+ else if (type == 4)
+ return PlaceType.Grass3;
+ else
+ return PlaceType.Land; // 其他情况均返回land
+ }
+ catch
+ {
+ return PlaceType.Land;
+ }
+ }
+
+ public PlaceType GetPlaceType(XY pos)
+ {
+ try
+ {
+ switch (ProtoGameMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell])
+ {
+ case 2:
+ return PlaceType.Grass1;
+ case 3:
+ return PlaceType.Grass2;
+ case 4:
+ return PlaceType.Grass3;
+ default:
+ return PlaceType.Land;
+ }
+ }
+ catch
+ {
+ return PlaceType.Land;
+ }
+ }
+
+ public bool IsOutOfBound(IGameObj obj)
+ {
+ return obj.Position.x >= GameData.lengthOfMap - obj.Radius || obj.Position.x <= obj.Radius || obj.Position.y >= GameData.lengthOfMap - obj.Radius || obj.Position.y <= obj.Radius;
+ }
+ public IOutOfBound GetOutOfBound(XY pos)
+ {
+ return new OutOfBoundBlock(pos);
+ }
+
+ public Character? FindPlayer(long playerID)
+ {
+ Character? player = null;
+ gameObjLockDict[GameObjIdx.Player].EnterReadLock();
+ try
+ {
+ foreach (Character person in gameObjDict[GameObjIdx.Player])
+ {
+ if (playerID == person.ID)
+ {
+ player = person;
+ break;
+ }
+ }
+ }
+ finally
+ {
+ gameObjLockDict[GameObjIdx.Player].ExitReadLock();
+ }
+ return player;
+ }
+ public Map(uint[,] mapResource)
+ {
+ gameObjDict = new Dictionary>();
+ gameObjLockDict = new Dictionary();
+ foreach (GameObjIdx idx in Enum.GetValues(typeof(GameObjIdx)))
+ {
+ if (idx != GameObjIdx.None)
+ {
+ gameObjDict.Add(idx, new List());
+ gameObjLockDict.Add(idx, new ReaderWriterLockSlim());
+ }
+ }
+
+ ProtoGameMap = new uint[mapResource.GetLength(0), mapResource.GetLength(1)];
+ Array.Copy(mapResource, ProtoGameMap, mapResource.Length);
+
+ birthPointList = new Dictionary(GameData.numOfBirthPoint);
+
+ // 将出生点插入
+ for (int i = 0; i < GameData.rows; ++i)
+ {
+ for (int j = 0; j < GameData.cols; ++j)
+ {
+ switch (mapResource[i, j])
+ {
+ case (uint)MapInfoObjType.Wall:
+ {
+ GameObjLockDict[GameObjIdx.Map].EnterWriteLock();
+ try
+ {
+ GameObjDict[GameObjIdx.Map].Add(new Wall(GameData.GetCellCenterPos(i, j)));
+ }
+ finally
+ {
+ GameObjLockDict[GameObjIdx.Map].ExitWriteLock();
+ }
+ break;
+ }
+ case (uint)MapInfoObjType.BirthPoint1:
+ case (uint)MapInfoObjType.BirthPoint2:
+ case (uint)MapInfoObjType.BirthPoint3:
+ case (uint)MapInfoObjType.BirthPoint4:
+ case (uint)MapInfoObjType.BirthPoint5:
+ {
+ BirthPoint newBirthPoint = new BirthPoint(GameData.GetCellCenterPos(i, j));
+ birthPointList.Add(MapInfo.BirthPointEnumToIdx((MapInfoObjType)mapResource[i, j]), newBirthPoint);
+ GameObjLockDict[GameObjIdx.Map].EnterWriteLock();
+ try
+ {
+ GameObjDict[GameObjIdx.Map].Add(newBirthPoint);
+ }
+ finally
+ {
+ GameObjLockDict[GameObjIdx.Map].ExitWriteLock();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Map/MapGameTimer.cs b/logic/GameClass/GameObj/Map/MapGameTimer.cs
new file mode 100644
index 0000000..f03500a
--- /dev/null
+++ b/logic/GameClass/GameObj/Map/MapGameTimer.cs
@@ -0,0 +1,32 @@
+using System.Threading;
+using Preparation.Interface;
+
+namespace GameClass.GameObj
+{
+ public partial class Map
+ {
+ // xfgg说:爱因斯坦说,每个坐标系都有与之绑定的时钟,(x, y, z, ict) 构成四维时空坐标,在洛伦兹变换下满足矢量性(狗头)
+ private readonly GameTimer timer = new();
+ public ITimer Timer => timer;
+ public class GameTimer : ITimer
+ {
+ private bool isGaming = false;
+ public bool IsGaming => isGaming;
+
+ readonly object isGamingLock = new();
+
+ public bool StartGame(int timeInMilliseconds)
+ {
+ lock (isGamingLock)
+ {
+ if (isGaming)
+ return false;
+ isGaming = true;
+ }
+ Thread.Sleep(timeInMilliseconds);
+ isGaming = false;
+ return true;
+ }
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Map/MapInfo.cs b/logic/GameClass/GameObj/Map/MapInfo.cs
new file mode 100644
index 0000000..20d0c66
--- /dev/null
+++ b/logic/GameClass/GameObj/Map/MapInfo.cs
@@ -0,0 +1,77 @@
+using Preparation.Utility;
+using Preparation.GameData;
+
+namespace GameClass.GameObj
+{
+ public static class MapInfo
+ {
+ ///
+ /// 检测物体在哪;不能返回invisible。
+ ///
+ ///
+ ///
+
+ public static uint BirthPointEnumToIdx(MapInfoObjType birthPointEnum)
+ {
+ uint tmp = (uint)birthPointEnum;
+ // if (tmp < 5 || tmp > 12) throw new Exception("The parameter of BirthPointEnumToIdx is not a valid birth point enumeration value!");
+ return tmp - 5;
+ }
+ ///
+ /// 50*50
+ /// 1:Wall; 2:Grass1; 3:Grass2 ; 4:Grass3 ; 5~12:BirthPoint ; 13:GemWell
+ ///
+ public static uint[,] defaultMap = new uint[,] {
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 1, 1, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 13, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 13, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 13, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+ };
+ }
+}
diff --git a/logic/GameClass/GameObj/Map/Wall.cs b/logic/GameClass/GameObj/Map/Wall.cs
new file mode 100644
index 0000000..b91e537
--- /dev/null
+++ b/logic/GameClass/GameObj/Map/Wall.cs
@@ -0,0 +1,19 @@
+using Preparation.Utility;
+using Preparation.GameData;
+
+namespace GameClass.GameObj
+{
+ ///
+ /// 墙体
+ ///
+ public class Wall : GameObj
+ {
+ public Wall(XY initPos) :
+ base(initPos, GameData.numOfPosGridPerCell / 2, PlaceType.Land, GameObjType.Wall)
+ {
+ this.CanMove = false;
+ }
+ public override bool IsRigid => true;
+ public override ShapeType Shape => ShapeType.Square;
+ }
+}
diff --git a/logic/GameClass/GameObj/OutOfBoundBlock.cs b/logic/GameClass/GameObj/OutOfBoundBlock.cs
new file mode 100644
index 0000000..9ac2a84
--- /dev/null
+++ b/logic/GameClass/GameObj/OutOfBoundBlock.cs
@@ -0,0 +1,20 @@
+using Preparation.Interface;
+using Preparation.Utility;
+
+namespace GameClass.GameObj
+{
+ ///
+ /// 逻辑墙
+ ///
+ public class OutOfBoundBlock : GameObj, IOutOfBound
+ {
+ public OutOfBoundBlock(XY initPos) :
+ base(initPos, int.MaxValue, PlaceType.Land, GameObjType.OutOfBoundBlock)
+ {
+ this.CanMove = false;
+ }
+
+ public override bool IsRigid => true;
+ public override ShapeType Shape => ShapeType.Square;
+ }
+}
diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs
index c7e07d3..f596c4e 100644
--- a/logic/GameEngine/MoveEngine.cs
+++ b/logic/GameEngine/MoveEngine.cs
@@ -64,7 +64,7 @@ namespace GameEngine
(
() =>
{
- if (!obj.IsAvailable&&gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况
+ if (!obj.IsAvailable && gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况
return;
lock (obj.MoveLock)
obj.IsMoving = true;
diff --git a/logic/Gaming/Gaming.csproj b/logic/Gaming/Gaming.csproj
new file mode 100644
index 0000000..5d635c7
--- /dev/null
+++ b/logic/Gaming/Gaming.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net6.0
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/logic/Preparation/GameData/GameData.cs b/logic/Preparation/GameData/GameData.cs
index 0903b6d..0be6c40 100644
--- a/logic/Preparation/GameData/GameData.cs
+++ b/logic/Preparation/GameData/GameData.cs
@@ -33,6 +33,8 @@ namespace Preparation.GameData
{
return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
}
+
+ public static int numOfBirthPoint = 5;
#endregion
#region 角色相关
///
diff --git a/logic/Preparation/Interface/IOutOfBound.cs b/logic/Preparation/Interface/IOutOfBound.cs
new file mode 100644
index 0000000..28219ce
--- /dev/null
+++ b/logic/Preparation/Interface/IOutOfBound.cs
@@ -0,0 +1,8 @@
+
+namespace Preparation.Interface
+{
+ public interface IOutOfBound : IGameObj
+ {
+ // 接口不定义内容,为引擎使用
+ }
+}
diff --git a/logic/Preparation/Preparation.csproj b/logic/Preparation/Preparation.csproj
new file mode 100644
index 0000000..4dd34fc
--- /dev/null
+++ b/logic/Preparation/Preparation.csproj
@@ -0,0 +1,11 @@
+
+
+
+ Library
+ net6.0
+
+
+ enable
+
+
+
diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs
index b21ff5e..35c481c 100644
--- a/logic/Preparation/Utility/EnumType.cs
+++ b/logic/Preparation/Utility/EnumType.cs
@@ -35,8 +35,6 @@ namespace Preparation.Utility
Grass1 = 3,
Grass2 = 4,
Grass3 = 5,
- Grass4 = 6,
- Grass5 = 7,
}
public enum BulletType // 子弹类型
{
@@ -93,3 +91,16 @@ namespace Preparation.Utility
PickedProp = 5
}
}
+public enum MapInfoObjType
+{
+ Null = 0,
+ Wall = 1,
+ Grass1 = 2,
+ Grass2 = 3,
+ Grass3 = 4,
+ BirthPoint1 = 5,
+ BirthPoint2 = 6,
+ BirthPoint3 = 7,
+ BirthPoint4 = 8,
+ BirthPoint5 = 9,
+}
\ No newline at end of file
diff --git a/logic/logic.sln b/logic/logic.sln
index 51f61b6..a233cfa 100644
--- a/logic/logic.sln
+++ b/logic/logic.sln
@@ -5,6 +5,16 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameClass", "GameClass\GameClass.csproj", "{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameEngine", "GameEngine\GameEngine.csproj", "{91448D70-61C3-499F-9B27-979E16DC9E64}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gaming", "Gaming\Gaming.csproj", "{BE9E3584-93C0-4E0F-8DAC-967CF4792709}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MapGenerator", "MapGenerator\MapGenerator.csproj", "{9BC673F1-14B1-4203-944D-474BD0F64EDC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preparation", "Preparation\Preparation.csproj", "{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +25,26 @@ Global
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91448D70-61C3-499F-9B27-979E16DC9E64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91448D70-61C3-499F-9B27-979E16DC9E64}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91448D70-61C3-499F-9B27-979E16DC9E64}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91448D70-61C3-499F-9B27-979E16DC9E64}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
From 86c1f407fc5f9e1259ca6e13e3e037902b63ced7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 10 Dec 2022 14:15:23 +0000
Subject: [PATCH 2/5] chore(deps): update dependency google.protobuf.tools to
v3.21.11
---
dependency/proto/Protos.csproj | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dependency/proto/Protos.csproj b/dependency/proto/Protos.csproj
index d03c1fe..e053d1f 100755
--- a/dependency/proto/Protos.csproj
+++ b/dependency/proto/Protos.csproj
@@ -15,7 +15,7 @@
-
+
From 2d7b7bd3c4d15e14e90aba52ab577662f215a85e Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Wed, 14 Dec 2022 00:41:55 +0800
Subject: [PATCH 3/5] feat: :sparkles: add prop, Bullet, and skill
---
logic/.gitignore | 2 -
logic/GameClass/GameObj/BombedBullet.cs | 20 ++
logic/GameClass/GameObj/Bullet.cs | 238 ++++++++++++++++++
.../GameObj/Character.BuffManager.cs | 172 -------------
.../GameObj/Character.SkillManager.cs | 51 ----
.../Character/Character.BuffManager.cs | 176 +++++++++++++
.../Character/Character.SkillManager.cs | 101 ++++++++
.../GameObj/{ => Character}/Character.cs | 80 ++++--
logic/GameClass/GameObj/GameObj.cs | 28 ++-
logic/GameClass/GameObj/ObjOfCharacter.cs | 3 +-
logic/GameClass/GameObj/PickedProp.cs | 24 ++
logic/GameClass/GameObj/Prop.cs | 125 +++++++++
logic/GameClass/GameObj/Team.cs | 3 +-
logic/GameClass/Skill/CommonSkill.cs | 219 ++++++++++++++++
logic/GameClass/Skill/ISkill.cs | 23 ++
logic/GameClass/Skill/PassiveSkill.cs | 152 +++++++++++
logic/GameEngine/MoveEngine.cs | 163 ++++++------
logic/Gaming/MoveManager.cs | 3 +-
logic/Preparation/GameData/GameData.cs | 12 +-
logic/Preparation/Utility/XY.cs | 2 +-
logic/logic.sln | 32 +--
21 files changed, 1250 insertions(+), 379 deletions(-)
create mode 100644 logic/GameClass/GameObj/BombedBullet.cs
create mode 100644 logic/GameClass/GameObj/Bullet.cs
delete mode 100644 logic/GameClass/GameObj/Character.BuffManager.cs
delete mode 100644 logic/GameClass/GameObj/Character.SkillManager.cs
create mode 100644 logic/GameClass/GameObj/Character/Character.BuffManager.cs
create mode 100644 logic/GameClass/GameObj/Character/Character.SkillManager.cs
rename logic/GameClass/GameObj/{ => Character}/Character.cs (92%)
create mode 100644 logic/GameClass/GameObj/PickedProp.cs
create mode 100644 logic/GameClass/GameObj/Prop.cs
create mode 100644 logic/GameClass/Skill/CommonSkill.cs
create mode 100644 logic/GameClass/Skill/ISkill.cs
create mode 100644 logic/GameClass/Skill/PassiveSkill.cs
diff --git a/logic/.gitignore b/logic/.gitignore
index 762b4b5..a9bdd24 100644
--- a/logic/.gitignore
+++ b/logic/.gitignore
@@ -400,5 +400,3 @@ FodyWeavers.xsd
#THUAI playback file
*.thuaipb
-Client/
-CSharpInterface/
diff --git a/logic/GameClass/GameObj/BombedBullet.cs b/logic/GameClass/GameObj/BombedBullet.cs
new file mode 100644
index 0000000..749049c
--- /dev/null
+++ b/logic/GameClass/GameObj/BombedBullet.cs
@@ -0,0 +1,20 @@
+using Preparation.Utility;
+
+namespace GameClass.GameObj
+{
+ // 为方便界面组做子弹爆炸特效,现引入“爆炸中的子弹”,在每帧发送给界面组
+ public sealed class BombedBullet : GameObj
+ {
+ public override ShapeType Shape => ShapeType.Circle;
+ public override bool IsRigid => false;
+ public long MappingID { get; }
+ public Bullet bulletHasBombed;
+ public BombedBullet(Bullet bullet) :
+ base(bullet.Position, bullet.Radius, bullet.Place, GameObjType.BombedBullet)
+ {
+ this.bulletHasBombed = bullet;
+ this.MappingID = bullet.ID;
+ this.FacingDirection = bullet.FacingDirection;
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Bullet.cs b/logic/GameClass/GameObj/Bullet.cs
new file mode 100644
index 0000000..0b56056
--- /dev/null
+++ b/logic/GameClass/GameObj/Bullet.cs
@@ -0,0 +1,238 @@
+using Preparation.GameData;
+using Preparation.Interface;
+using Preparation.Utility;
+using System;
+
+namespace GameClass.GameObj
+{
+ public abstract class Bullet : ObjOfCharacter
+ {
+ ///
+ /// //攻击力
+ ///
+ 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)
+ {
+ 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; }
+ }
+
+ internal sealed class AtomBomb : Bullet
+ {
+ public AtomBomb(Character player, int radius = GameData.bulletRadius) :
+ 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 int Speed => GameData.basicBulletMoveSpeed / 3 * 2;
+ public override bool CanAttack(GameObj target)
+ {
+ // 圆形攻击范围
+ return XY.Distance(this.Position, target.Position) <= BulletBombRange;
+ }
+
+ public override BulletType TypeOfBullet => BulletType.AtomBomb;
+ }
+
+ internal sealed class OrdinaryBullet : Bullet // 1倍攻击范围,1倍攻击力,一倍速
+ {
+ public OrdinaryBullet(Character player, int radius = GameData.bulletRadius) :
+ 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 int Speed => GameData.basicBulletMoveSpeed / 6 * 5;
+ public override bool CanAttack(GameObj target)
+ {
+ // 圆形攻击范围
+ return XY.Distance(this.Position, target.Position) <= BulletBombRange;
+ }
+
+ public override BulletType TypeOfBullet => BulletType.OrdinaryBullet;
+ }
+
+ internal sealed class FastBullet : Bullet // 1倍攻击范围,0.2倍攻击力,2倍速
+ {
+ public FastBullet(Character player, int radius = GameData.bulletRadius) :
+ 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 int Speed => 5 * GameData.basicBulletMoveSpeed / 3;
+
+ public override bool CanAttack(GameObj target)
+ {
+ // 圆形攻击范围
+ return XY.Distance(this.Position, target.Position) <= BulletBombRange;
+ }
+
+ public override BulletType TypeOfBullet => BulletType.FastBullet;
+ }
+
+ internal sealed class LineBullet : Bullet // 直线爆炸,宽度1格,长度为2倍爆炸范围
+ {
+ public LineBullet(Character player, int radius = GameData.bulletRadius) :
+ 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 int Speed => GameData.basicBulletMoveSpeed / 3;
+
+ public override bool CanAttack(GameObj target)
+ {
+ double FacingAngle = Math.Atan2(this.FacingDirection.y, this.FacingDirection.x);
+ if (Math.Abs(FacingAngle - Math.PI / 2) < 1e-2)
+ {
+ if (target.Position.y - this.Position.y > BulletBombRange)
+ return false;
+ if (target.Position.x < this.Position.x + GameData.numOfPosGridPerCell / 2 && target.Position.x > this.Position.x - GameData.numOfPosGridPerCell / 2)
+ return true;
+ return false;
+ }
+ else if (Math.Abs(FacingAngle - Math.PI * 3 / 2) < 1e-2)
+ {
+ if (target.Position.y - this.Position.y < -BulletBombRange)
+ return false;
+ if (target.Position.x < this.Position.x + GameData.numOfPosGridPerCell / 2 && target.Position.x > this.Position.x - GameData.numOfPosGridPerCell / 2)
+ return true;
+ return false;
+ }
+ else if (Math.Abs(FacingAngle) < 1e-2)
+ {
+ if (target.Position.x - this.Position.x > BulletBombRange)
+ return false;
+ if (target.Position.y < this.Position.y + GameData.numOfPosGridPerCell / 2 && target.Position.y > this.Position.y - GameData.numOfPosGridPerCell / 2)
+ return true;
+ return false;
+ }
+ else if (Math.Abs(FacingAngle - Math.PI) < 1e-2)
+ {
+ if (target.Position.x - this.Position.x < -BulletBombRange)
+ return false;
+ if (target.Position.y < this.Position.y + GameData.numOfPosGridPerCell / 2 && target.Position.y > this.Position.y - GameData.numOfPosGridPerCell / 2)
+ return true;
+ return false;
+ }
+ double vertical = Math.Tan(FacingAngle + Math.PI / 2);
+ bool posValue = vertical * Math.Cos(FacingAngle) - Math.Sin(FacingAngle) > 0;
+ double dist;
+ dist = vertical * (target.Position.x - this.Position.x) - (target.Position.y - this.Position.y) / Math.Sqrt(1 + vertical * vertical);
+ if (Math.Abs(dist) > BulletBombRange)
+ return false;
+ else if (dist < 0 && posValue) // 位于直线两侧
+ return false;
+ vertical = Math.Tan(FacingAngle);
+ dist = Math.Abs(vertical * (target.Position.x - this.Position.x) - (target.Position.y - this.Position.y)) / Math.Sqrt(1 + vertical * vertical);
+ if (dist > GameData.numOfPosGridPerCell / 2)
+ return false;
+ return true;
+ }
+
+ 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/Character.BuffManager.cs b/logic/GameClass/GameObj/Character.BuffManager.cs
deleted file mode 100644
index b580e9e..0000000
--- a/logic/GameClass/GameObj/Character.BuffManager.cs
+++ /dev/null
@@ -1,172 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-using System.Threading;
-using Preparation.Utility;
-using Preparation.GameData;
-
-namespace GameClass.GameObj
-{
- public partial class Character
- {
- private readonly BuffManeger buffManeger;
- ///
- /// 角色携带的buff管理器
- ///
- private class BuffManeger
- {
- [StructLayout(LayoutKind.Explicit, Size = 8)]
- private struct BuffValue // buff参数联合体类型,可能是int或double
- {
- [FieldOffset(0)]
- public int iValue;
- [FieldOffset(0)]
- public double lfValue;
-
- public BuffValue(int intValue)
- {
- this.lfValue = 0.0;
- this.iValue = intValue;
- }
- public BuffValue(double longFloatValue)
- {
- this.iValue = 0;
- this.lfValue = longFloatValue;
- }
- }
-
- ///
- /// buff列表
- ///
- private readonly LinkedList[] buffList;
- private readonly object[] buffListLock;
-
- private void AddBuff(BuffValue bf, int buffTime, BuffType buffType, Action ReCalculateFunc)
- {
- new Thread
- (
- () =>
- {
- LinkedListNode buffNode;
- lock (buffListLock[(int)buffType])
- {
- buffNode = buffList[(int)buffType].AddLast(bf);
- }
- ReCalculateFunc();
- Thread.Sleep(buffTime);
- try
- {
- lock (buffListLock[(int)buffType])
- {
- buffList[(int)buffType].Remove(buffNode);
- }
- }
- catch
- {
- }
- ReCalculateFunc();
- }
- )
- { IsBackground = true }.Start();
- }
-
- private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal)
- {
- double times = 1.0;
- lock (buffListLock[(int)buffType])
- {
- foreach (var add in buffList[(int)buffType])
- {
- times *= add.lfValue;
- }
- }
- return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal);
- }
-
- public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)));
- public bool HasFasterSpeed
- {
- get {
- lock (buffListLock[(int)BuffType.AddSpeed])
- {
- return buffList[(int)BuffType.AddSpeed].Count != 0;
- }
- }
- }
-
- public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () =>
- {});
- public bool HasShield
- {
- get {
- lock (buffListLock[(int)BuffType.Shield])
- {
- return buffList[(int)BuffType.Shield].Count != 0;
- }
- }
- }
-
- public void AddLIFE(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLIFE, () =>
- {});
- public bool HasLIFE
- {
- get {
- lock (buffListLock[(int)BuffType.AddLIFE])
- {
- return buffList[(int)BuffType.AddLIFE].Count != 0;
- }
- }
- }
- public bool TryActivatingLIFE()
- {
- if (HasLIFE)
- {
- lock (buffListLock[(int)BuffType.AddLIFE])
- {
- buffList[(int)BuffType.AddLIFE].Clear();
- }
- return true;
- }
- return false;
- }
-
- public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () =>
- {});
- public bool HasSpear
- {
- get {
- lock (buffListLock[(int)BuffType.Spear])
- {
- return buffList[(int)BuffType.Spear].Count != 0;
- }
- }
- }
- ///
- /// 清除所有buff
- ///
- public void ClearAll()
- {
- for (int i = 0; i < buffList.Length; ++i)
- {
- lock (buffListLock[i])
- {
- buffList[i].Clear();
- }
- }
- }
-
- public BuffManeger()
- {
- var buffTypeArray = Enum.GetValues(typeof(BuffType));
- buffList = new LinkedList[buffTypeArray.Length];
- buffListLock = new object[buffList.Length];
- int i = 0;
- foreach (BuffType type in buffTypeArray)
- {
- buffList[i] = new LinkedList();
- buffListLock[i++] = new object();
- }
- }
- }
-}
-}
diff --git a/logic/GameClass/GameObj/Character.SkillManager.cs b/logic/GameClass/GameObj/Character.SkillManager.cs
deleted file mode 100644
index 2bd8c5f..0000000
--- a/logic/GameClass/GameObj/Character.SkillManager.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Preparation.Utility;
-using System.Collections.Generic;
-using System;
-
-namespace GameClass.GameObj
-{
- public partial class Character
- {
- private delegate bool CharacterActiveSkill(Character player); // 返回值:是否成功释放了技能
- private delegate void CharacterPassiveSkill(Character player);
- private readonly CharacterActiveSkill commonSkill;
- private readonly ActiveSkillType commonSkillType;
- public ActiveSkillType CommonSkillType => commonSkillType;
-
- private readonly CharacterType passiveSkillType;
- public CharacterType PassiveSkillType => passiveSkillType;
- public bool UseCommonSkill()
- {
- return commonSkill(this);
- }
- private int timeUntilCommonSkillAvailable = 0; // 还剩多少时间可以使用普通技能
- public int TimeUntilCommonSkillAvailable
- {
- get => timeUntilCommonSkillAvailable;
- set {
- lock (gameObjLock)
- timeUntilCommonSkillAvailable = value < 0 ? 0 : value;
- }
- }
-
- readonly CharacterPassiveSkill passiveSkill;
- public void UsePassiveSkill()
- {
- passiveSkill(this);
- return;
- }
- public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType passiveSkillType, ActiveSkillType commonSkillType) :
- base(initPos, initRadius, initPlace, GameObjType.Character)
- {
- this.CanMove = true;
- this.score = 0;
- this.propInventory = null;
- this.buffManeger = new BuffManeger();
-
- // UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行
- // 这可以放在AddPlayer中做
-
- Debugger.Output(this, "constructed!");
- }
- }
-}
diff --git a/logic/GameClass/GameObj/Character/Character.BuffManager.cs b/logic/GameClass/GameObj/Character/Character.BuffManager.cs
new file mode 100644
index 0000000..9b2f724
--- /dev/null
+++ b/logic/GameClass/GameObj/Character/Character.BuffManager.cs
@@ -0,0 +1,176 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Preparation.Utility;
+using Preparation.GameData;
+
+namespace GameClass.GameObj
+{
+ public partial class Character
+ {
+ private readonly BuffManeger buffManeger;
+ ///
+ /// 角色携带的buff管理器
+ ///
+ private class BuffManeger
+ {
+ [StructLayout(LayoutKind.Explicit, Size = 8)]
+ private struct BuffValue // buff参数联合体类型,可能是int或double
+ {
+ [FieldOffset(0)]
+ public int iValue;
+ [FieldOffset(0)]
+ public double lfValue;
+
+ public BuffValue(int intValue)
+ {
+ this.lfValue = 0.0;
+ this.iValue = intValue;
+ }
+ public BuffValue(double longFloatValue)
+ {
+ this.iValue = 0;
+ this.lfValue = longFloatValue;
+ }
+ }
+
+ ///
+ /// buff列表
+ ///
+ private readonly LinkedList[] buffList;
+ private readonly object[] buffListLock;
+
+ private void AddBuff(BuffValue bf, int buffTime, BuffType buffType, Action ReCalculateFunc)
+ {
+ new Thread
+ (
+ () =>
+ {
+ LinkedListNode buffNode;
+ lock (buffListLock[(int)buffType])
+ {
+ buffNode = buffList[(int)buffType].AddLast(bf);
+ }
+ ReCalculateFunc();
+ Thread.Sleep(buffTime);
+ try
+ {
+ lock (buffListLock[(int)buffType])
+ {
+ buffList[(int)buffType].Remove(buffNode);
+ }
+ }
+ catch
+ {
+ }
+ ReCalculateFunc();
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+
+ private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal)
+ {
+ double times = 1.0;
+ lock (buffListLock[(int)buffType])
+ {
+ foreach (var add in buffList[(int)buffType])
+ {
+ times *= add.lfValue;
+ }
+ }
+ return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal);
+ }
+
+ public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)));
+ public bool HasFasterSpeed
+ {
+ get
+ {
+ lock (buffListLock[(int)BuffType.AddSpeed])
+ {
+ return buffList[(int)BuffType.AddSpeed].Count != 0;
+ }
+ }
+ }
+
+ public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () =>
+ { });
+ public bool HasShield
+ {
+ get
+ {
+ lock (buffListLock[(int)BuffType.Shield])
+ {
+ return buffList[(int)BuffType.Shield].Count != 0;
+ }
+ }
+ }
+
+ public void AddLIFE(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLIFE, () =>
+ { });
+ public bool HasLIFE
+ {
+ get
+ {
+ lock (buffListLock[(int)BuffType.AddLIFE])
+ {
+ return buffList[(int)BuffType.AddLIFE].Count != 0;
+ }
+ }
+ }
+ public bool TryActivatingLIFE()
+ {
+ if (HasLIFE)
+ {
+ lock (buffListLock[(int)BuffType.AddLIFE])
+ {
+ buffList[(int)BuffType.AddLIFE].Clear();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () =>
+ { });
+ public bool HasSpear
+ {
+ get
+ {
+ lock (buffListLock[(int)BuffType.Spear])
+ {
+ return buffList[(int)BuffType.Spear].Count != 0;
+ }
+ }
+ }
+ ///
+ /// 清除所有buff
+ ///
+ public void ClearAll()
+ {
+ for (int i = 0; i < buffList.Length; ++i)
+ {
+ lock (buffListLock[i])
+ {
+ buffList[i].Clear();
+ }
+ }
+ }
+
+ public BuffManeger()
+ {
+ var buffTypeArray = Enum.GetValues(typeof(BuffType));
+ buffList = new LinkedList[buffTypeArray.Length];
+ buffListLock = new object[buffList.Length];
+ int i = 0;
+ foreach (BuffType type in buffTypeArray)
+ {
+ buffList[i] = new LinkedList();
+ buffListLock[i++] = new object();
+ }
+ }
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Character/Character.SkillManager.cs b/logic/GameClass/GameObj/Character/Character.SkillManager.cs
new file mode 100644
index 0000000..a4c5ab3
--- /dev/null
+++ b/logic/GameClass/GameObj/Character/Character.SkillManager.cs
@@ -0,0 +1,101 @@
+using GameClass.Skill;
+using Preparation.Utility;
+using System.Collections.Generic;
+using System;
+
+namespace GameClass.GameObj
+{
+ public partial class Character
+ {
+ private delegate bool CharacterActiveSkill(Character player); // 返回值:是否成功释放了技能
+ private delegate void CharacterPassiveSkill(Character player);
+ private readonly CharacterActiveSkill commonSkill;
+ private readonly ActiveSkillType commonSkillType;
+ public ActiveSkillType CommonSkillType => commonSkillType;
+
+ private readonly CharacterType characterType;
+ public CharacterType CharacterType => characterType;
+ public bool UseCommonSkill()
+ {
+ return commonSkill(this);
+ }
+ private int timeUntilCommonSkillAvailable = 0; // 还剩多少时间可以使用普通技能
+ public int TimeUntilCommonSkillAvailable
+ {
+ get => timeUntilCommonSkillAvailable;
+ set
+ {
+ lock (gameObjLock)
+ timeUntilCommonSkillAvailable = value < 0 ? 0 : value;
+ }
+ }
+
+ readonly CharacterPassiveSkill passiveSkill;
+ public void UsePassiveSkill()
+ {
+ passiveSkill(this);
+ return;
+ }
+ public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType, ActiveSkillType commonSkillType) :
+ base(initPos, initRadius, initPlace, GameObjType.Character)
+ {
+ this.CanMove = true;
+ this.score = 0;
+ this.propInventory = null;
+ this.buffManeger = new BuffManeger();
+ IPassiveSkill pSkill;
+ ICommonSkill cSkill;
+ switch (passiveSkillType)
+ {
+ case this.CharacterType.RecoverAfterBattle:
+ pSkill = new RecoverAfterBattle();
+ break;
+ case this.CharacterType.SpeedUpWhenLeavingGrass:
+ pSkill = new SpeedUpWhenLeavingGrass();
+ break;
+ case this.CharacterType.Vampire:
+ pSkill = new Vampire();
+ break;
+ default:
+ pSkill = new NoPassiveSkill();
+ break;
+ }
+ switch (commonSkillType)
+ {
+ case ActiveSkillType.BecomeAssassin:
+ cSkill = new BecomeAssassin();
+ break;
+ case ActiveSkillType.BecomeVampire:
+ cSkill = new BecomeVampire();
+ break;
+ case ActiveSkillType.NuclearWeapon:
+ cSkill = new NuclearWeapon();
+ break;
+ case ActiveSkillType.SuperFast:
+ cSkill = new SuperFast();
+ break;
+ default:
+ cSkill = new NoCommonSkill();
+ break;
+ }
+ this.MaxHp = cSkill.MaxHp;
+ 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;
+ this.OriBulletOfPlayer = pSkill.InitBullet;
+ this.passiveSkill = pSkill.SkillEffect;
+ this.commonSkill = cSkill.SkillEffect;
+ this.passiveSkillType = passiveSkillType;
+ this.commonSkillType = commonSkillType;
+
+ // UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行
+ // 这可以放在AddPlayer中做
+
+ Debugger.Output(this, "constructed!");
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
similarity index 92%
rename from logic/GameClass/GameObj/Character.cs
rename to logic/GameClass/GameObj/Character/Character.cs
index 9631793..ba7e617 100644
--- a/logic/GameClass/GameObj/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -11,9 +11,8 @@ namespace GameClass.GameObj
{
private readonly object beAttackedLock = new();
-#region 角色的基本属性及方法,包括与道具的交互方法
- /*
- //THUAI5子弹
+ #region 角色的基本属性及方法,包括与道具的交互方法
+
///
/// 装弹冷却
///
@@ -21,8 +20,9 @@ namespace GameClass.GameObj
public int CD
{
get => cd;
- private
- set {
+ private
+ set
+ {
lock (gameObjLock)
{
cd = value;
@@ -35,13 +35,14 @@ namespace GameClass.GameObj
public int MaxBulletNum => maxBulletNum; // 人物最大子弹数
protected int bulletNum;
public int BulletNum => bulletNum; // 目前持有的子弹数
- */
+
public int MaxHp { get; protected set; } // 最大血量
protected int hp;
public int HP
{
get => hp;
- set {
+ set
+ {
lock (gameObjLock)
hp = value <= MaxHp ? value : MaxHp;
}
@@ -55,13 +56,31 @@ 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
{
get => vampire;
- set {
+ set
+ {
+ if (value > 1)
+ lock (gameObjLock)
+ vampire = 1;
+ else if (value < 0)
+ lock (gameObjLock)
+ vampire = 0;
+ else
+ lock (gameObjLock)
+ vampire = value;
+ }
+ }
+ private double oriVampire = 0;
+ public double OriVampire
+ {
+ get => oriVampire;
+ set
+ {
if (value > 1)
lock (gameObjLock)
vampire = 1;
@@ -73,26 +92,27 @@ namespace GameClass.GameObj
vampire = value;
}
}
- private double OriVampire { get; }
- /*
+
public readonly BulletType OriBulletOfPlayer;
private BulletType bulletOfPlayer;
public BulletType BulletOfPlayer
{
get => bulletOfPlayer;
- set {
+ set
+ {
lock (gameObjLock)
bulletOfPlayer = value;
}
}
- */
+
private Prop? propInventory;
public Prop? PropInventory // 持有的道具
{
get => propInventory;
- set {
+ set
+ {
lock (gameObjLock)
{
propInventory = value;
@@ -122,7 +142,8 @@ namespace GameClass.GameObj
public bool IsModifyingProp
{
get => isModifyingProp;
- set {
+ set
+ {
lock (gameObjLock)
{
isModifyingProp = value;
@@ -137,14 +158,15 @@ namespace GameClass.GameObj
public bool IsInvisible
{
get => isInvisible;
- set {
+ set
+ {
lock (gameObjLock)
{
isInvisible = value;
}
}
}
- /*
+
///
/// 进行一次远程攻击
///
@@ -196,7 +218,7 @@ namespace GameClass.GameObj
return false;
}
}
- */
+
///
/// 尝试加血
///
@@ -265,7 +287,7 @@ namespace GameClass.GameObj
Debugger.Output(this, " 's score has been subed to: " + score.ToString());
}
}
- /*
+
///
/// 遭受攻击
///
@@ -326,7 +348,7 @@ namespace GameClass.GameObj
return hp <= 0;
}
}
- */
+
///
/// 角色所属队伍ID
///
@@ -334,7 +356,8 @@ namespace GameClass.GameObj
public long TeamID
{
get => teamID;
- set {
+ set
+ {
lock (gameObjLock)
{
teamID = value;
@@ -346,7 +369,8 @@ namespace GameClass.GameObj
public long PlayerID
{
get => playerID;
- set {
+ set
+ {
lock (gameObjLock)
{
playerID = value;
@@ -360,16 +384,17 @@ namespace GameClass.GameObj
public string Message
{
get => message;
- set {
+ set
+ {
lock (gameObjLock)
{
message = value;
}
}
}
-#endregion
+ #endregion
-#region 角色拥有的buff相关属性、方法
+ #region 角色拥有的buff相关属性、方法
public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManeger.AddMoveSpeed(add, buffTime, newVal =>
{ MoveSpeed = newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed; },
OrgMoveSpeed);
@@ -387,7 +412,8 @@ namespace GameClass.GameObj
private Array buffTypeArray = Enum.GetValues(typeof(BuffType));
public Dictionary Buff
{
- get {
+ get
+ {
Dictionary buff = new Dictionary();
foreach (BuffType type in buffTypeArray)
{
@@ -420,7 +446,7 @@ namespace GameClass.GameObj
hp = MaxHp;
}
}
-#endregion
+ #endregion
public override void Reset() // 要加锁吗?
{
_ = AddDeathCount();
diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs
index 27f2abd..b2732d1 100644
--- a/logic/GameClass/GameObj/GameObj.cs
+++ b/logic/GameClass/GameObj/GameObj.cs
@@ -29,8 +29,9 @@ namespace GameClass.GameObj
public XY Position
{
get => position;
- protected
- set {
+ protected
+ set
+ {
lock (gameObjLock)
{
position = value;
@@ -43,7 +44,8 @@ namespace GameClass.GameObj
public XY FacingDirection
{
get => facingDirection;
- set {
+ set
+ {
lock (gameObjLock)
facingDirection = value;
}
@@ -54,7 +56,8 @@ namespace GameClass.GameObj
public bool CanMove
{
get => canMove;
- set {
+ set
+ {
lock (gameObjLock)
{
canMove = value;
@@ -66,7 +69,8 @@ namespace GameClass.GameObj
public bool IsMoving
{
get => isMoving;
- set {
+ set
+ {
lock (gameObjLock)
{
isMoving = value;
@@ -78,7 +82,8 @@ namespace GameClass.GameObj
public bool IsResetting
{
get => isResetting;
- set {
+ set
+ {
lock (gameObjLock)
{
isResetting = value;
@@ -92,7 +97,8 @@ namespace GameClass.GameObj
public PlaceType Place
{
get => place;
- set {
+ set
+ {
lock (gameObjLock)
{
place = value;
@@ -106,7 +112,8 @@ namespace GameClass.GameObj
public int MoveSpeed
{
get => moveSpeed;
- set {
+ set
+ {
lock (gameObjLock)
{
moveSpeed = value;
@@ -120,8 +127,9 @@ namespace GameClass.GameObj
public int OrgMoveSpeed
{
get => orgMoveSpeed;
- protected
- set {
+ protected
+ set
+ {
orgMoveSpeed = value;
}
}
diff --git a/logic/GameClass/GameObj/ObjOfCharacter.cs b/logic/GameClass/GameObj/ObjOfCharacter.cs
index a09c6e5..140bab4 100644
--- a/logic/GameClass/GameObj/ObjOfCharacter.cs
+++ b/logic/GameClass/GameObj/ObjOfCharacter.cs
@@ -12,7 +12,8 @@ namespace GameClass.GameObj
public ICharacter? Parent
{
get => parent;
- set {
+ set
+ {
lock (gameObjLock)
{
parent = value;
diff --git a/logic/GameClass/GameObj/PickedProp.cs b/logic/GameClass/GameObj/PickedProp.cs
new file mode 100644
index 0000000..f825062
--- /dev/null
+++ b/logic/GameClass/GameObj/PickedProp.cs
@@ -0,0 +1,24 @@
+using Preparation.Utility;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace GameClass.GameObj
+{
+ // 为方便界面组做道具拾起特效,现引入“被捡起的道具”,在每帧发送给界面组
+ public class PickedProp : GameObj
+ {
+ public override ShapeType Shape => ShapeType.Circle;
+ public override bool IsRigid => false;
+ public long MappingID { get; }
+ public Prop PropHasPicked;
+ public PickedProp(Prop prop) :
+ base(prop.Position, prop.Radius, prop.Place, GameObjType.PickedProp)
+ {
+ this.PropHasPicked = prop;
+ this.MappingID = prop.ID;
+ }
+ }
+}
diff --git a/logic/GameClass/GameObj/Prop.cs b/logic/GameClass/GameObj/Prop.cs
new file mode 100644
index 0000000..1aaba6f
--- /dev/null
+++ b/logic/GameClass/GameObj/Prop.cs
@@ -0,0 +1,125 @@
+using Preparation.Interface;
+using Preparation.Utility;
+using Preparation.GameData;
+
+namespace GameClass.GameObj
+{
+ public abstract class Prop : ObjOfCharacter
+ {
+ protected bool laid = false;
+ public bool Laid => laid; // 道具是否放置在地图上
+
+ public override bool IsRigid => true;
+
+ protected override bool IgnoreCollideExecutor(IGameObj targetObj)
+ {
+ if (targetObj.Type == GameObjType.BirthPoint || targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet || targetObj.Type == GameObjType.Character)
+ return true;
+ return false;
+ }
+
+ public override ShapeType Shape => ShapeType.Square;
+
+ public abstract PropType GetPropType();
+
+ public Prop(XY initPos, int radius = GameData.PropRadius) :
+ base(initPos, radius, PlaceType.Land, GameObjType.Prop)
+ {
+ this.CanMove = false;
+ this.moveSpeed = GameData.PropMoveSpeed;
+ }
+ public void SetNewPos(XY pos)
+ {
+ this.Position = pos;
+ }
+ }
+ ///
+ /// 增益道具
+ ///
+ public abstract class BuffProp : Prop
+ {
+ public BuffProp(XY initPos) :
+ base(initPos)
+ {
+ }
+ }
+ /////
+ ///// 坑人地雷
+ /////
+ // public abstract class DebuffMine : Prop
+ //{
+ // public DebuffMine(XYPosition initPos) : base(initPos) { }
+ // }
+ #region 所有增益道具
+ ///
+ /// 增加速度
+ ///
+ public sealed class AddSpeed : BuffProp
+ {
+ public AddSpeed(XY initPos) :
+ base(initPos)
+ {
+ }
+ public override PropType GetPropType() => PropType.addSpeed;
+ }
+ ///
+ /// 复活甲
+ ///
+ public sealed class AddLIFE : BuffProp
+ {
+ public AddLIFE(XY initPos) :
+ base(initPos)
+ {
+ }
+ public override PropType GetPropType() => PropType.addLIFE;
+ }
+ ///
+ /// 护盾
+ ///
+ public sealed class Shield : BuffProp
+ {
+ public Shield(XY initPos) :
+ base(initPos)
+ {
+ }
+ public override PropType GetPropType() => PropType.Shield;
+ }
+ ///
+ /// 矛
+ ///
+ public sealed class Spear : BuffProp
+ {
+ public Spear(XY initPos) :
+ base(initPos)
+ {
+ }
+ public override PropType GetPropType() => PropType.Spear;
+ }
+ #endregion
+ // #region 所有坑人地雷
+ /////
+ ///// 减速
+ /////
+ // public sealed class MinusSpeed : DebuffMine
+ //{
+ // public MinusSpeed(XYPosition initPos) : base(initPos) { }
+ // public override PropType GetPropType() => PropType.minusSpeed;
+ // }
+ /////
+ ///// 减少攻击力
+ /////
+ // public sealed class MinusAP : DebuffMine
+ //{
+ // public MinusAP(XYPosition initPos) : base(initPos) { }
+ // public override PropType GetPropType() => PropType.minusAP;
+ // }
+ /////
+ ///// 增加冷却
+ /////
+ // public sealed class AddCD : DebuffMine
+ //{
+ // public AddCD(XYPosition initPos) : base(initPos) { }
+ // public override PropType GetPropType() => PropType.addCD;
+ // }
+ // #endregion
+}
diff --git a/logic/GameClass/GameObj/Team.cs b/logic/GameClass/GameObj/Team.cs
index 281ea82..625c68e 100644
--- a/logic/GameClass/GameObj/Team.cs
+++ b/logic/GameClass/GameObj/Team.cs
@@ -13,7 +13,8 @@ namespace GameClass.GameObj
private readonly List playerList;
public int Score
{
- get {
+ get
+ {
int score = 0;
foreach (var player in playerList)
score += player.Score;
diff --git a/logic/GameClass/Skill/CommonSkill.cs b/logic/GameClass/Skill/CommonSkill.cs
new file mode 100644
index 0000000..5933c19
--- /dev/null
+++ b/logic/GameClass/Skill/CommonSkill.cs
@@ -0,0 +1,219 @@
+using GameClass.GameObj;
+using System.Threading;
+using Preparation.Interface;
+using Preparation.Utility;
+using Preparation.GameData;
+using System;
+using Timothy.FrameRateTask;
+
+namespace GameClass.Skill
+{
+ public class BecomeVampire : ICommonSkill //化身吸血鬼
+ {
+ private const int moveSpeed = GameData.basicMoveSpeed;
+ public int MoveSpeed => moveSpeed;
+
+ 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 bool SkillEffect(Character player)
+ {
+ return CommonSkillFactory.SkillEffect(this, player, () =>
+ {
+ player.Vampire += 0.5;
+ Debugger.Output(player, "becomes vampire!");
+ },
+ () =>
+ {
+ double tempVam = player.Vampire - 0.5;
+ player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam;
+ });
+ }
+ }
+ public class BecomeAssassin : ICommonSkill //化身刺客,隐身
+ {
+ 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 bool SkillEffect(Character player)
+ {
+ return CommonSkillFactory.SkillEffect(this, player, () =>
+ {
+ player.IsInvisible = true;
+ Debugger.Output(player, "uses atombomb!");
+ },
+ () => { player.IsInvisible = false; });
+ }
+ }
+ public class NuclearWeapon : ICommonSkill //核武器
+ {
+ private const int moveSpeed = GameData.basicMoveSpeed / 3 * 4;
+ public int MoveSpeed => moveSpeed;
+
+ 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 bool SkillEffect(Character player)
+ {
+ return CommonSkillFactory.SkillEffect(this, player, () =>
+ {
+ player.BulletOfPlayer = BulletType.AtomBomb;
+ Debugger.Output(player, "uses atombomb!");
+ },
+ () => { player.BulletOfPlayer = player.OriBulletOfPlayer; });
+ }
+ }
+ public class SuperFast : ICommonSkill //3倍速
+ {
+ private const int moveSpeed = GameData.basicMoveSpeed * 4 / 3;
+ public int MoveSpeed => moveSpeed;
+
+ 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 bool SkillEffect(Character player)
+ {
+ return CommonSkillFactory.SkillEffect(this, player, () =>
+ {
+ player.AddMoveSpeed(this.DurationTime, 3.0);
+ Debugger.Output(player, "moves very fast!");
+ },
+ () => { });
+ }
+ }
+ public class NoCommonSkill : ICommonSkill //这种情况不该发生,定义着以防意外
+ {
+ private const int moveSpeed = GameData.basicMoveSpeed;
+ public int MoveSpeed => moveSpeed;
+
+ 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 bool SkillEffect(Character player)
+ {
+ return false;
+ }
+ }
+
+ public static class CommonSkillFactory
+ {
+ public static bool SkillEffect(ICommonSkill commonSkill, Character player, Action startSkill, Action endSkill)
+ {
+ lock (commonSkill.CommonSkillLock)
+ {
+ if (player.TimeUntilCommonSkillAvailable == 0)
+ {
+ player.TimeUntilCommonSkillAvailable = commonSkill.SkillCD;
+ new Thread
+ (() =>
+ {
+ startSkill();
+ new FrameRateTaskExecutor
+ (
+ () => !player.IsResetting,
+ () =>
+ {
+ player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
+ },
+ timeInterval: GameData.frameDuration,
+ () => 0,
+ maxTotalDuration: (long)(commonSkill.DurationTime)
+ )
+ {
+ AllowTimeExceed = true,
+ MaxTolerantTimeExceedCount = ulong.MaxValue,
+ }.Start();
+
+ endSkill();
+ Debugger.Output(player, "return to normal.");
+
+ new FrameRateTaskExecutor
+ (
+ () => player.TimeUntilCommonSkillAvailable > 0 && !player.IsResetting,
+ () =>
+ {
+ player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
+ },
+ timeInterval: GameData.frameDuration,
+ () => 0,
+ maxTotalDuration: (long)(commonSkill.SkillCD - commonSkill.DurationTime)
+ )
+ {
+ AllowTimeExceed = true,
+ MaxTolerantTimeExceedCount = ulong.MaxValue,
+ }.Start();
+
+ player.TimeUntilCommonSkillAvailable = 0;
+ Debugger.Output(player, "CommonSkill is ready.");
+ }
+ )
+ { IsBackground = true }.Start();
+
+ return true;
+ }
+ else
+ {
+ Debugger.Output(player, "CommonSkill is cooling down!");
+ return false;
+ }
+ }
+ }
+ }
+}
diff --git a/logic/GameClass/Skill/ISkill.cs b/logic/GameClass/Skill/ISkill.cs
new file mode 100644
index 0000000..e947001
--- /dev/null
+++ b/logic/GameClass/Skill/ISkill.cs
@@ -0,0 +1,23 @@
+using GameClass.GameObj;
+using Preparation.Utility;
+using System.Threading;
+
+namespace GameClass.Skill
+{
+ public interface IPassiveSkill
+ {
+ public BulletType InitBullet { get; }
+ public void SkillEffect(Character player);
+ }
+ public interface ICommonSkill
+ {
+ 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; }
+ }
+}
diff --git a/logic/GameClass/Skill/PassiveSkill.cs b/logic/GameClass/Skill/PassiveSkill.cs
new file mode 100644
index 0000000..bd8b209
--- /dev/null
+++ b/logic/GameClass/Skill/PassiveSkill.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Threading;
+using GameClass.GameObj;
+using Preparation.GameData;
+using Preparation.Interface;
+using Preparation.Utility;
+using Timothy.FrameRateTask;
+
+namespace GameClass.Skill //被动技能开局时就释放,持续到游戏结束
+{
+ public class RecoverAfterBattle : IPassiveSkill //脱战回血,普通子弹
+ {
+ private readonly BulletType initBullet = BulletType.OrdinaryBullet;
+ public BulletType InitBullet => initBullet;
+ //以上参数以后再改
+ public void SkillEffect(Character player)
+ {
+ const int recoverDegree = 5; //每帧回复血量
+ int nowHP = player.HP;
+ int lastHP = nowHP;
+ long waitTime = 0;
+ const long interval = 10000; //每隔interval时间不受伤害,角色即开始回血
+ new Thread
+ (
+ () =>
+ {
+ new FrameRateTaskExecutor
+ (
+ () => true,
+ () =>
+ {
+ lastHP = nowHP; //lastHP等于上一帧的HP
+ nowHP = player.HP; //nowHP更新为这一帧的HP
+ if (lastHP > nowHP) //这一帧扣血了
+ {
+ waitTime = 0;
+ }
+ else if (waitTime < interval)
+ {
+ waitTime += GameData.frameDuration;
+ }
+
+ if (waitTime >= interval) //回复时,每帧(50ms)回复5,即1s回复100。
+ player.TryAddHp(recoverDegree);
+ },
+ timeInterval: GameData.frameDuration,
+ () => 0,
+ maxTotalDuration: GameData.gameDuration
+ )
+ {
+ AllowTimeExceed = true,
+ MaxTolerantTimeExceedCount = ulong.MaxValue,
+ TimeExceedAction = b =>
+ {
+ if (b) Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");
+
+#if DEBUG
+ else
+ {
+ Console.WriteLine("Debug info: passive skill time exceeds for once.");
+ }
+#endif
+ }
+ }.Start();
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+ }
+ public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速
+ {
+ private readonly BulletType initBullet = BulletType.FastBullet;
+ public BulletType InitBullet => initBullet;
+ //以上参数以后再改
+ public void SkillEffect(Character player)
+ {
+ PlaceType nowPlace = player.Place;
+ PlaceType lastPlace = nowPlace;
+ bool speedup = false;
+ const int SpeedUpTime = 2000; //加速时间:2s
+ new Thread
+ (
+ () =>
+ {
+ new FrameRateTaskExecutor
+ (
+ () => true,
+ () =>
+ {
+ lastPlace = nowPlace;
+ nowPlace = player.Place;
+ if ((lastPlace == PlaceType.Grass1 || lastPlace == PlaceType.Grass2 || lastPlace == PlaceType.Grass3) && nowPlace == PlaceType.Land)
+ {
+ if (!speedup)
+ {
+ new Thread(() =>
+ {
+ speedup = true;
+ player.AddMoveSpeed(SpeedUpTime, 3.0);
+ speedup = false;
+ })
+ { IsBackground = true }.Start();
+ }
+ }
+ },
+ timeInterval: GameData.frameDuration,
+ () => 0,
+ maxTotalDuration: GameData.gameDuration
+ )
+ {
+ AllowTimeExceed = true,
+ MaxTolerantTimeExceedCount = ulong.MaxValue,
+ TimeExceedAction = b =>
+ {
+ if (b) Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");
+
+#if DEBUG
+ else
+ {
+ Console.WriteLine("Debug info: passive skill time exceeds for once.");
+ }
+#endif
+ }
+ }.Start();
+ }
+ )
+ { IsBackground = true }.Start();
+ }
+ }
+ public class Vampire : IPassiveSkill //被动就是吸血,普通子弹
+ {
+ private readonly BulletType initBullet = BulletType.LineBullet;
+ public BulletType InitBullet => initBullet;
+ //以上参数以后再改
+ public void SkillEffect(Character player)
+ {
+ player.OriVampire = 0.5;
+ player.Vampire = player.OriVampire;
+ }
+ }
+
+ public class NoPassiveSkill : IPassiveSkill //没技能,这种情况不应该发生,先定义着以防意外
+ {
+ private readonly BulletType initBullet = BulletType.OrdinaryBullet;
+ public BulletType InitBullet => initBullet;
+ //以上参数以后再改
+ public void SkillEffect(Character player)
+ {
+
+ }
+ }
+}
diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs
index f596c4e..f717f57 100644
--- a/logic/GameEngine/MoveEngine.cs
+++ b/logic/GameEngine/MoveEngine.cs
@@ -66,65 +66,28 @@ namespace GameEngine
{
if (!obj.IsAvailable && gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况
return;
- lock (obj.MoveLock)
- obj.IsMoving = true;
-
- double moveVecLength = 0.0;
- double deltaLen = moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength))); // 转向,并用deltaLen存储行走的误差
- IGameObj? collisionObj = null;
- bool isDestroyed = false;
- new FrameRateTaskExecutor(
- () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting,
- () =>
- {
- moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond;
-
- // 越界情况处理:如果越界,则与越界方块碰撞
- bool flag; // 循环标志
- do
- {
- flag = false;
- collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength));
- if (collisionObj == null)
- break;
+ lock (obj.MoveLock)
+ obj.IsMoving = true;
- switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
+ double moveVecLength = 0.0;
+ double deltaLen = moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength))); // 转向,并用deltaLen存储行走的误差
+ IGameObj? collisionObj = null;
+ bool isDestroyed = false;
+ new FrameRateTaskExecutor(
+ () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting,
+ () =>
{
- case AfterCollision.ContinueCheck:
- flag = true;
- break;
- case AfterCollision.Destroyed:
- Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
- isDestroyed = true;
- return false;
- case AfterCollision.MoveMax:
- MoveMax(obj, new XY(direction, moveVecLength));
- moveVecLength = 0;
- break;
- }
- } while (flag);
+ moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond;
- deltaLen += moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength)));
-
- return true;
- },
- GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond,
- () =>
- {
- int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond);
- bool flag;
- do
- {
- flag = false;
- if (!isDestroyed)
- {
- moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
- if ((collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength))) == null)
- {
- obj.Move(new XY(direction, moveVecLength));
- }
- else
+ // 越界情况处理:如果越界,则与越界方块碰撞
+ bool flag; // 循环标志
+ do
{
+ flag = false;
+ collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength));
+ if (collisionObj == null)
+ break;
+
switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
{
case AfterCollision.ContinueCheck:
@@ -133,43 +96,81 @@ namespace GameEngine
case AfterCollision.Destroyed:
Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
isDestroyed = true;
- break;
+ return false;
case AfterCollision.MoveMax:
MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0;
break;
}
+ } while (flag);
+
+ deltaLen += moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength)));
+
+ return true;
+ },
+ GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond,
+ () =>
+ {
+ int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond);
+ bool flag;
+ do
+ {
+ flag = false;
+ if (!isDestroyed)
+ {
+ moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
+ if ((collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength))) == null)
+ {
+ obj.Move(new XY(direction, moveVecLength));
+ }
+ else
+ {
+ switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
+ {
+ case AfterCollision.ContinueCheck:
+ flag = true;
+ break;
+ case AfterCollision.Destroyed:
+ Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
+ isDestroyed = true;
+ break;
+ case AfterCollision.MoveMax:
+ MoveMax(obj, new XY(direction, moveVecLength));
+ moveVecLength = 0;
+ break;
+ }
+ }
+ }
+ } while (flag);
+ if (leftTime > 0)
+ {
+ Thread.Sleep(leftTime); // 多移动的在这里补回来
}
- }
- } while (flag);
- if (leftTime > 0)
+ lock (obj.MoveLock)
+ obj.IsMoving = false; // 结束移动
+ EndMove(obj);
+ return 0;
+ },
+ maxTotalDuration: moveTime
+ )
{
- Thread.Sleep(leftTime); // 多移动的在这里补回来
- }
- lock (obj.MoveLock)
- obj.IsMoving = false; // 结束移动
- EndMove(obj);
- return 0;
- },
- maxTotalDuration: moveTime
- ) {
- AllowTimeExceed = true,
- MaxTolerantTimeExceedCount = ulong.MaxValue,
- TimeExceedAction = b =>
- {
- if (b)
- Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!");
+ AllowTimeExceed = true,
+ MaxTolerantTimeExceedCount = ulong.MaxValue,
+ TimeExceedAction = b =>
+ {
+ if (b)
+ Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!");
#if DEBUG
- else
- {
- Console.WriteLine("Debug info: Object moving time exceed for once.");
- }
+ else
+ {
+ Console.WriteLine("Debug info: Object moving time exceed for once.");
+ }
#endif
+ }
+ }.Start();
}
- }.Start();
- }
).Start();
+ }
}
}
-}
diff --git a/logic/Gaming/MoveManager.cs b/logic/Gaming/MoveManager.cs
index 7c15aa6..d9ad560 100644
--- a/logic/Gaming/MoveManager.cs
+++ b/logic/Gaming/MoveManager.cs
@@ -54,7 +54,8 @@ namespace Gaming
// ActivateMine((Character)obj, (Mine)collisionObj);
// return MoveEngine.AfterCollision.ContinueCheck;
//}
- return MoveEngine.AfterCollision.MoveMax; },
+ return MoveEngine.AfterCollision.MoveMax;
+ },
EndMove: obj =>
{
// Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
diff --git a/logic/Preparation/GameData/GameData.cs b/logic/Preparation/GameData/GameData.cs
index 0be6c40..d0ad358 100644
--- a/logic/Preparation/GameData/GameData.cs
+++ b/logic/Preparation/GameData/GameData.cs
@@ -4,7 +4,7 @@ namespace Preparation.GameData
{
public static class GameData
{
-#region 基本常数与常方法
+ #region 基本常数与常方法
public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数
public const int numOfStepPerSecond = 20; // 每秒行走的步数
public const int lengthOfMap = 50000; // 地图长度
@@ -35,8 +35,8 @@ namespace Preparation.GameData
}
public static int numOfBirthPoint = 5;
-#endregion
-#region 角色相关
+ #endregion
+ #region 角色相关
///
/// 玩家相关
///
@@ -71,9 +71,9 @@ namespace Preparation.GameData
public const long GemProduceTime = 10000;
public const long PropProduceTime = 10000;
public const int PropDuration = 10000;
-#endregion
-#region 游戏帧相关
+ #endregion
+ #region 游戏帧相关
public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长
-#endregion
+ #endregion
}
}
diff --git a/logic/Preparation/Utility/XY.cs b/logic/Preparation/Utility/XY.cs
index d1b62e1..8f4a29f 100644
--- a/logic/Preparation/Utility/XY.cs
+++ b/logic/Preparation/Utility/XY.cs
@@ -21,7 +21,7 @@ namespace Preparation.Utility
{
return "(" + x.ToString() + "," + y.ToString() + ")";
}
- public static int operator*(XY v1, XY v2)
+ public static int operator *(XY v1, XY v2)
{
return (v1.x * v2.x) + (v1.y * v2.y);
}
diff --git a/logic/logic.sln b/logic/logic.sln
index 6d419a1..a030118 100644
--- a/logic/logic.sln
+++ b/logic/logic.sln
@@ -5,23 +5,17 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}"
EndProject
-<<<<<<< HEAD
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameClass", "GameClass\GameClass.csproj", "{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameEngine", "GameEngine\GameEngine.csproj", "{91448D70-61C3-499F-9B27-979E16DC9E64}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gaming", "Gaming\Gaming.csproj", "{BE9E3584-93C0-4E0F-8DAC-967CF4792709}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MapGenerator", "MapGenerator\MapGenerator.csproj", "{9BC673F1-14B1-4203-944D-474BD0F64EDC}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preparation", "Preparation\Preparation.csproj", "{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}"
-=======
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientTest", "ClientTest\ClientTest.csproj", "{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Protos", "..\dependency\proto\Protos.csproj", "{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}"
->>>>>>> 9f4b5ac18b94330559cd560708f4100ae913260e
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameEngine", "GameEngine\GameEngine.csproj", "{C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameEngine", "GameEngine\GameEngine.csproj", "{1D1D07F3-C332-4407-AC1B-EAD73F8BB3F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -33,28 +27,18 @@ Global
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D033B809-2FB7-4340-B8B4-DDA30D6CA6FF}.Release|Any CPU.Build.0 = Release|Any CPU
-<<<<<<< HEAD
{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39D838F6-2B84-49E1-9CAF-1DFF22960B5D}.Release|Any CPU.Build.0 = Release|Any CPU
- {91448D70-61C3-499F-9B27-979E16DC9E64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {91448D70-61C3-499F-9B27-979E16DC9E64}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {91448D70-61C3-499F-9B27-979E16DC9E64}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {91448D70-61C3-499F-9B27-979E16DC9E64}.Release|Any CPU.Build.0 = Release|Any CPU
{BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE9E3584-93C0-4E0F-8DAC-967CF4792709}.Release|Any CPU.Build.0 = Release|Any CPU
- {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {9BC673F1-14B1-4203-944D-474BD0F64EDC}.Release|Any CPU.Build.0 = Release|Any CPU
{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3DC4A37-8A83-40CC-AE47-68E70064C9DB}.Release|Any CPU.Build.0 = Release|Any CPU
-=======
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C98717-DD4F-45B8-B0F0-C217E7E2B5D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -63,14 +47,10 @@ Global
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9ADA1EF8-DF2F-4C2E-9DE2-BC94DF89B44D}.Release|Any CPU.Build.0 = Release|Any CPU
-<<<<<<< HEAD
->>>>>>> 9f4b5ac18b94330559cd560708f4100ae913260e
-=======
- {C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {C7A82045-5EE5-46E8-AD0C-04103EFEAF7E}.Release|Any CPU.Build.0 = Release|Any CPU
->>>>>>> 3fa94addd0e0b62765b62c0788f217f7cf25b7c1
+ {1D1D07F3-C332-4407-AC1B-EAD73F8BB3F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D1D07F3-C332-4407-AC1B-EAD73F8BB3F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D1D07F3-C332-4407-AC1B-EAD73F8BB3F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D1D07F3-C332-4407-AC1B-EAD73F8BB3F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
From fec0b558b065198abcd31bbb40754aa7cd95663d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 14 Dec 2022 00:20:24 +0000
Subject: [PATCH 4/5] chore(deps): update doozyx/clang-format-lint-action
action to v0.15
---
.github/workflows/format.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index 5357743..ee67952 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -5,7 +5,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- - uses: DoozyX/clang-format-lint-action@v0.14
+ - uses: DoozyX/clang-format-lint-action@v0.15
with:
source: '.'
extensions: 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx,i,ixx,ipp,i++'
From ad33cfb95a097d73d6f74929acd184e15ab613e9 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 14 Dec 2022 00:21:52 +0000
Subject: [PATCH 5/5] chore(deps): update dependency google.protobuf to
v3.21.11
---
dependency/proto/Protos.csproj | 2 +-
logic/ClientTest/ClientTest.csproj | 2 +-
logic/Server/Server.csproj | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dependency/proto/Protos.csproj b/dependency/proto/Protos.csproj
index e053d1f..a32336c 100755
--- a/dependency/proto/Protos.csproj
+++ b/dependency/proto/Protos.csproj
@@ -14,7 +14,7 @@
-->
-
+
diff --git a/logic/ClientTest/ClientTest.csproj b/logic/ClientTest/ClientTest.csproj
index 075a2ce..4f85f0f 100644
--- a/logic/ClientTest/ClientTest.csproj
+++ b/logic/ClientTest/ClientTest.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/logic/Server/Server.csproj b/logic/Server/Server.csproj
index 969fa35..93ee7eb 100644
--- a/logic/Server/Server.csproj
+++ b/logic/Server/Server.csproj
@@ -9,7 +9,7 @@
-
+