diff --git a/dependency/proto/MessageType.proto b/dependency/proto/MessageType.proto index 01b42a0..6627e6d 100755 --- a/dependency/proto/MessageType.proto +++ b/dependency/proto/MessageType.proto @@ -62,7 +62,7 @@ enum ButcherBuffType // 屠夫可用的增益效果类型 BBUFFTYPE4 = 4; } -// 特别说明:由于Human阵营和Butcher阵营有显著的隔离,且暂定职业、主动技能和被动效果相互绑定,故不按照THUAI5的方式区分ActiveSkillType和PassiveSkillType,而是选择了按照阵营来给不同阵营赋予不同的职业(及技能)。 +// 特别说明:由于Human阵营和Butcher阵营有显著的隔离,且暂定职业、主动技能和被动效果相互绑定,故不按照THUAI5的方式区分ActiveSkillType和CharacterType,而是选择了按照阵营来给不同阵营赋予不同的职业(及技能)。 enum PlayerType { diff --git a/logic/GameClass/GameObj/Character/Character.SkillManager.cs b/logic/GameClass/GameObj/Character/Character.SkillManager.cs index a4c5ab3..11698e4 100644 --- a/logic/GameClass/GameObj/Character/Character.SkillManager.cs +++ b/logic/GameClass/GameObj/Character/Character.SkillManager.cs @@ -45,15 +45,15 @@ namespace GameClass.GameObj this.buffManeger = new BuffManeger(); IPassiveSkill pSkill; ICommonSkill cSkill; - switch (passiveSkillType) + switch (characterType) { - case this.CharacterType.RecoverAfterBattle: + case CharacterType.RecoverAfterBattle: pSkill = new RecoverAfterBattle(); break; - case this.CharacterType.SpeedUpWhenLeavingGrass: + case CharacterType.SpeedUpWhenLeavingGrass: pSkill = new SpeedUpWhenLeavingGrass(); break; - case this.CharacterType.Vampire: + case CharacterType.Vampire: pSkill = new Vampire(); break; default: @@ -89,7 +89,7 @@ namespace GameClass.GameObj this.OriBulletOfPlayer = pSkill.InitBullet; this.passiveSkill = pSkill.SkillEffect; this.commonSkill = cSkill.SkillEffect; - this.passiveSkillType = passiveSkillType; + this.characterType = characterType; this.commonSkillType = commonSkillType; // UsePassiveSkill(); //创建player时开始被动技能,这一过程也可以放到gamestart时进行 diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs new file mode 100644 index 0000000..096a307 --- /dev/null +++ b/logic/Gaming/AttackManager.cs @@ -0,0 +1,210 @@ +using System; +using System.Threading; +using System.Collections.Generic; +using GameClass.GameObj; +using Preparation.GameData; +using Preparation.Utility; +using GameEngine; + +namespace Gaming +{ + public partial class Game + { + private readonly AttackManager attackManager; + private class AttackManager + { + readonly Map gameMap; + readonly MoveEngine moveEngine; + public AttackManager(Map gameMap) + { + this.gameMap = gameMap; + this.moveEngine = new MoveEngine( + gameMap: gameMap, + OnCollision: (obj, collisionObj, moveVec) => + { + //BulletBomb((Bullet)obj, (GameObj)collisionObj); + return MoveEngine.AfterCollision.Destroyed; }, + EndMove: obj => + { +#if DEBUG + Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); + +#endif + BulletBomb((Bullet)obj, null); } + ); + } + private void BombOnePlayer(Bullet bullet, Character playerBeingShot) + { + if (playerBeingShot.BeAttack(bullet)) + { + playerBeingShot.CanMove = false; + playerBeingShot.IsResetting = true; + // gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); + // try + //{ + // gameMap.GameObjDict[GameObjIdx.Player].Remove(playerBeingShot); + // } + // finally + //{ + // gameMap.GameObjLockDict[GameObjIdx.Player].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[GameObjIdx.Prop].EnterWriteLock(); + try + { + if (dropProp != null) + gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock(); + } + + playerBeingShot.Reset(); + ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 + + new Thread + (() => + { + + Thread.Sleep(GameData.reviveTime); + + playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 + + // gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); + // try + //{ + // gameMap.GameObjDict[GameObjIdx.Player].Add(playerBeingShot); + // } + // finally { gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); } + + if (gameMap.Timer.IsGaming) + { + playerBeingShot.CanMove = true; + } + playerBeingShot.IsResetting = false; + } + ) + { IsBackground = true }.Start(); + } + } + private void BulletBomb(Bullet bullet, GameObj? objBeingShot) + { +#if DEBUG + Debugger.Output(bullet, "bombed!"); +#endif + bullet.CanMove = false; + gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock(); + try + { + foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjIdx.Bullet]) + { + if (_bullet.ID == bullet.ID) + { + gameMap.GameObjLockDict[GameObjIdx.BombedBullet].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.BombedBullet].Add(new BombedBullet(bullet)); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.BombedBullet].ExitWriteLock(); + } + gameMap.GameObjDict[GameObjIdx.Bullet].Remove(_bullet); + break; + } + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock(); + } + + /*if (objBeingShot != null) + { + else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。 + { + new Thread(() => { BulletBomb((Bullet)objBeingShot, null); }) { IsBackground = true }.Start(); + } + }*/ + + // 子弹爆炸会发生的事↓↓↓ + var beAttackedList = new List(); + gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock(); + try + { + foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) + { + if (bullet.CanAttack(player)) + { + beAttackedList.Add(player); + if (player.ID != bullet.Parent.ID) + bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * bullet.AP)); + } + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock(); + } + + foreach (Character beAttackedPlayer in beAttackedList) + { + BombOnePlayer(bullet, beAttackedPlayer); + } + beAttackedList.Clear(); + } + public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头) + { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange + if (player == null) + { +#if DEBUG + Console.WriteLine("the player who will attack is NULL!"); +#endif + return false; + } + + if (player.IsResetting) + return false; + Bullet? bullet = player.RemoteAttack( + new XY // 子弹紧贴人物生成。 + ( + (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle)), + (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle)) + ) + ); + if (bullet != null) + { + bullet.CanMove = true; + gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.Bullet].Add(bullet); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock(); + } + moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms +#if DEBUG + Console.WriteLine($"playerID:{player.ID} successfully attacked!"); +#endif + return true; + } + else + { +#if DEBUG + Console.WriteLine($"playerID:{player.ID} has no bullets so that he can't attack!"); +#endif + return false; + } + } + } +} +} diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs new file mode 100644 index 0000000..1110606 --- /dev/null +++ b/logic/Gaming/Game.cs @@ -0,0 +1,397 @@ +using System; +using System.Threading; +using System.Collections.Generic; +using GameClass.GameObj; +using Preparation.Utility; +using Preparation.GameData; +using Timothy.FrameRateTask; +using Preparation.Interface; + +namespace Gaming +{ + public partial class Game + { + public struct PlayerInitInfo + { + public uint birthPointIndex; + public long teamID; + public long playerID; + public PassiveSkillType passiveSkill; + public ActiveSkillType commonSkill; + public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, PassiveSkillType passiveSkill, ActiveSkillType commonSkill) + { + this.birthPointIndex = birthPointIndex; + this.teamID = teamID; + this.passiveSkill = passiveSkill; + this.commonSkill = commonSkill; + this.playerID = playerID; + } + } + + private readonly List teamList; + public List TeamList => teamList; + private readonly Map gameMap; + public Map GameMap => gameMap; + private readonly int numOfTeam; + public long AddPlayer(PlayerInitInfo playerInitInfo) + { + if (!Team.teamExists(playerInitInfo.teamID)) + /* || !MapInfo.ValidBirthPointIdx(playerInitInfo.birthPointIdx) + || gameMap.BirthPointList[playerInitInfo.birthPointIdx].Parent != null)*/ + return GameObj.invalidID; + + XYPosition pos = gameMap.BirthPointList[playerInitInfo.birthPointIndex].Position; + // Console.WriteLine($"x,y: {pos.x},{pos.y}"); + Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.passiveSkill, playerInitInfo.commonSkill); + gameMap.BirthPointList[playerInitInfo.birthPointIndex].Parent = newPlayer; + gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.Player].Add(newPlayer); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); + } + // Console.WriteLine($"GameObjDict[GameObjIdx.Player] length:{gameMap.GameObjDict[GameObjIdx.Player].Count}"); + teamList[(int)playerInitInfo.teamID].AddPlayer(newPlayer); + newPlayer.TeamID = playerInitInfo.teamID; + newPlayer.PlayerID = playerInitInfo.playerID; + + new Thread //人物装弹 + ( + () => + { + while (!gameMap.Timer.IsGaming) + Thread.Sleep(newPlayer.CD); + long lastTime = Environment.TickCount64; + new FrameRateTaskExecutor( + loopCondition: () => gameMap.Timer.IsGaming, + loopToDo: () => + { + if (!newPlayer.IsResetting) + { + long nowTime = Environment.TickCount64; + if (newPlayer.BulletNum == newPlayer.MaxBulletNum) + lastTime = nowTime; + if (nowTime - lastTime >= newPlayer.CD) + { + _ = newPlayer.TryAddBulletNum(); + lastTime = nowTime; + } + } + }, + timeInterval: GameData.checkInterval, + finallyReturn: () => 0 + ) { + AllowTimeExceed = true + /*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(); + + return newPlayer.ID; + } + public bool StartGame(int milliSeconds) + { + if (gameMap.Timer.IsGaming) + return false; + gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock(); + try + { + foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) + { + player.CanMove = true; + + player.AddShield(GameData.shieldTimeAtBirth); + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock(); + } + + propManager.StartProducing(); + gemManager.StartProducingGem(); + new Thread + ( + () => + { + new FrameRateTaskExecutor + ( + loopCondition: () => gameMap.Timer.IsGaming, + loopToDo: () => + { + foreach (var kvp in gameMap.GameObjDict) // 检查物体位置 + { + if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop || kvp.Key == GameObjIdx.Gem) + { + gameMap.GameObjLockDict[kvp.Key].EnterWriteLock(); + try + { + foreach (var item in gameMap.GameObjDict[kvp.Key]) + { + item.Place = gameMap.GetPlaceType(item.Position); + } + } + finally + { + gameMap.GameObjLockDict[kvp.Key].ExitWriteLock(); + } + } + } + }, + timeInterval: GameData.checkInterval, + finallyReturn: () => 0 + ) + { + AllowTimeExceed = true + }.Start(); + } + ) + { IsBackground = true }.Start(); + // 开始游戏 + if (!gameMap.Timer.StartGame(milliSeconds)) + return false; + + EndGame(); // 游戏结束时要做的事 + + return true; +} + +public void EndGame() +{ + gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); + try + { + foreach (var player in gameMap.GameObjDict[GameObjIdx.Player]) + { + gemManager.UseAllGem((Character)player); + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); + } +} +public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + moveManager.MovePlayer(player, moveTimeInMilliseconds, angle); +#if DEBUG + Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!"); +#endif + } + else + { +#if DEBUG + Console.WriteLine($"PlayerID:{playerID} player does not exists!"); +#endif + } +} +public void Attack(long playerID, double angle) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + _ = attackManager.Attack(player, angle); + } +} +public void UseGem(long playerID, int num = int.MaxValue) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + gemManager.UseGem(player, num); + return; + } +} +public void ThrowGem(long playerID, int moveMilliTime, double angle, int size = 1) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + gemManager.ThrowGem(player, moveMilliTime, angle, size); + return; + } +} +public bool PickGem(long playerID) +{ + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return gemManager.PickGem(player); + } + return false; +} +public void UseProp(long playerID) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + propManager.UseProp(player); + } +} +public void ThrowProp(long playerID, int timeInmillionSeconds, double angle) +{ + if (!gameMap.Timer.IsGaming) + return; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + propManager.ThrowProp(player, timeInmillionSeconds, angle); + } +} +public bool PickProp(long playerID, PropType propType = PropType.Null) +{ + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return propManager.PickProp(player, propType); + } + return false; +} + +public bool UseCommonSkill(long playerID) +{ + if (!gameMap.Timer.IsGaming) + return false; + Character? player = gameMap.FindPlayer(playerID); + if (player != null) + { + return skillManager.UseCommonSkill(player); + } + else + return false; +} + +public void AllPlayerUsePassiveSkill() +{ + if (!gameMap.Timer.IsGaming) + return; + gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); + try + { + foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) + { + skillManager.UsePassiveSkill(player); + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); + } +} + +public void ClearLists(GameObjIdx[] objIdxes) +{ + foreach (var idx in objIdxes) + { + if (idx != GameObjIdx.None) + { + gameMap.GameObjLockDict[idx].EnterWriteLock(); + try + { + gameMap.GameObjDict[idx].Clear(); + } + finally + { + gameMap.GameObjLockDict[idx].ExitWriteLock(); + } + } + } +} +public void ClearAllLists() +{ + foreach (var keyValuePair in gameMap.GameObjDict) + { + if (keyValuePair.Key != GameObjIdx.Map) + { + gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock(); + try + { + if (keyValuePair.Key == GameObjIdx.Player) + { + foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) + { + player.CanMove = false; + } + } + gameMap.GameObjDict[keyValuePair.Key].Clear(); + } + finally + { + gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock(); + } + } + } +} + +public int GetTeamScore(long teamID) +{ + return teamList[(int)teamID].Score; +} +public List GetGameObj() +{ + var gameObjList = new List(); + foreach (var keyValuePair in gameMap.GameObjDict) + { + if (keyValuePair.Key != GameObjIdx.Map) + { + gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock(); + try + { + gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]); + } + finally + { + gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock(); + } + } + } + return gameObjList; +} +public Game(uint[,] mapResource, int numOfTeam) +{ + // if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException(); + + gameMap = new Map(mapResource); + + // 加入队伍 + this.numOfTeam = numOfTeam; + teamList = new List(); + for (int i = 0; i < numOfTeam; ++i) + { + teamList.Add(new Team()); + } + + skillManager = new SkillManager(); + attackManager = new AttackManager(gameMap); + moveManager = new MoveManager(gameMap); + propManager = new PropManager(gameMap); + gemManager = new GemManager(gameMap); +} +} +} diff --git a/logic/Gaming/PropManager.cs b/logic/Gaming/PropManager.cs new file mode 100644 index 0000000..6aad8ce --- /dev/null +++ b/logic/Gaming/PropManager.cs @@ -0,0 +1,246 @@ +using System.Collections.Generic; +using GameClass.GameObj; +using System.Threading; +using Preparation.GameData; +using Preparation.Utility; +using System; +using Timothy.FrameRateTask; +using GameEngine; + +namespace Gaming +{ + public partial class Game + { + private readonly PropManager propManager; + private class PropManager + { + private readonly Map gameMap; + + private MoveEngine moveEngine; + + private bool isProducingProp = false; + + private readonly List availableCellForGenerateProp; + public void StartProducing() + { + if (isProducingProp) + return; + isProducingProp = true; + ProduceProp(); + } + + public void UseProp(Character player) + { + if (player.IsResetting) + return; + Prop? prop = player.UseProp(); + switch (prop?.GetPropType()) + { + case PropType.Spear: + player.AddSpear(GameData.PropDuration); + break; + case PropType.Shield: + player.AddShield(GameData.PropDuration); + break; + case PropType.addLIFE: + player.AddLIFE(GameData.PropDuration); + break; + case PropType.addSpeed: + player.AddMoveSpeed(GameData.PropDuration); + break; + default: + break; + } + } + + /// + /// + /// + /// + /// 若不指定,则自动判断可捡起什么道具 + /// + public bool PickProp(Character player, PropType propType = PropType.Null) + { + if (player.IsResetting) + return false; + Prop? pickProp = null; + if (propType == PropType.Null) // 自动检查有无道具可捡 + { + gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock(); + try + { + foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop]) + { + if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false) + { + pickProp = prop; + } + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock(); + } + } + else + { + gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock(); + try + { + foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop]) + { + if (prop.GetPropType() == propType) + { + if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false) + { + pickProp = prop; + } + } + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock(); + } + } + + if (pickProp != null) + { + // pickProp.CanMove = false; + Prop? dropProp = null; + if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 + { + dropProp = player.PropInventory; + dropProp.SetNewPos(GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell)); + } + player.PropInventory = pickProp; + gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.Prop].Remove(pickProp); + if (dropProp != null) + gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock(); + } + gameMap.GameObjLockDict[GameObjIdx.PickedProp].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.PickedProp].Add(new PickedProp(pickProp)); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.PickedProp].ExitWriteLock(); + } + + return true; + } + else + return false; + } + + public void ThrowProp(Character player, int timeInMilliseconds, double angle) + { + if (!gameMap.Timer.IsGaming) + return; + if (player.IsResetting) // 移动中也能扔,但由于“惯性”,可能初始位置会有点变化 + return; + Prop? prop = player.UseProp(); + if (prop == null) + return; + + prop.CanMove = true; + prop.SetNewPos(player.Position); + gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock(); + try + { + gameMap.GameObjDict[GameObjIdx.Prop].Add(prop); + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock(); + } + timeInMilliseconds = timeInMilliseconds < GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000 ? timeInMilliseconds : GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000; + moveEngine.MoveObj(prop, timeInMilliseconds, angle); + } + private void ProduceProp() + { + int len = availableCellForGenerateProp.Count; + Random r = new Random(Environment.TickCount); + new Thread + ( + () => + { + while (!gameMap.Timer.IsGaming) + Thread.Sleep(1000); + new FrameRateTaskExecutor( + () => gameMap.Timer.IsGaming, + () => + { + int rand = r.Next(0, len); + XYPosition randPos = availableCellForGenerateProp[rand]; + + gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock(); + try + { + switch (r.Next(0, 4)) + { + case 0: + gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddLIFE(randPos)); + break; + case 1: + gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddSpeed(randPos)); + break; + case 2: + gameMap.GameObjDict[GameObjIdx.Prop].Add(new Shield(randPos)); + break; + case 3: + gameMap.GameObjDict[GameObjIdx.Prop].Add(new Spear(randPos)); + break; + default: + break; + } + } + finally + { + gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock(); + } + }, + GameData.PropProduceTime, + () => 0 + ) + .Start(); + } + ) + { IsBackground = true }.Start(); + } + public PropManager(Map gameMap) // 道具不能扔过墙 + { + this.gameMap = gameMap; + this.moveEngine = new MoveEngine( + gameMap: gameMap, + OnCollision: (obj, collision, moveVec) => + { return MoveEngine.AfterCollision.MoveMax; }, + EndMove: obj => + { + // obj.Place = gameMap.GetPlaceType((GameObj)obj); + obj.CanMove = false; + Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); } + ); + availableCellForGenerateProp = new List(); + for (int i = 0; i < gameMap.ProtoGameMap.GetLength(0); i++) + { + for (int j = 0; j < gameMap.ProtoGameMap.GetLength(1); j++) + { + if (gameMap.ProtoGameMap[i, j] == (int)MapInfo.MapInfoObjType.Null) + { + availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j)); + } + } + } + } + } +} +} diff --git a/logic/Gaming/SkillManager.cs b/logic/Gaming/SkillManager.cs new file mode 100644 index 0000000..faed93f --- /dev/null +++ b/logic/Gaming/SkillManager.cs @@ -0,0 +1,21 @@ +using System; +using GameClass.GameObj; + +namespace Gaming +{ + public partial class Game + { + readonly SkillManager skillManager; + private class SkillManager + { + public bool UseCommonSkill(Character character) + { + return character.UseCommonSkill(); + } + public void UsePassiveSkill(Character character) + { + character.UsePassiveSkill(); + } + } + } +} diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index a708e00..a0087f4 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -7,5 +7,6 @@ namespace Preparation.Interface { public long TeamID { get; } public int HP { get; set; } + public double Vampire { get; } } } \ No newline at end of file diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 35c481c..406824e 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -85,10 +85,11 @@ namespace Preparation.Utility { None = 0, Player = 1, - Prop = 2, - Map = 3, - BombedBullet = 4, - PickedProp = 5 + Bullet = 2, + Prop = 3, + Map = 4, + BombedBullet = 5, + PickedProp = 6 } } public enum MapInfoObjType