|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- using System.Threading;
- using GameClass.GameObj;
- using Preparation.Utility;
- using Preparation.Interface;
- using Timothy.FrameRateTask;
-
- namespace Gaming
- {
- public partial class Game
- {
- private readonly CharacterManager characterManager;
- private class CharacterManager
- {
- readonly Map gameMap;
- public CharacterManager(Map gameMap)
- {
- this.gameMap = gameMap;
- }
-
- public void SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
- {
- lock (player.ActionLock)
- {
- switch (player.PlayerState)
- {
- case PlayerStateType.OpeningTheChest:
- ((Chest)player.WhatInteractingWith!).StopOpen();
- player.ChangePlayerState(value, gameObj);
- break;
- case PlayerStateType.OpeningTheDoorway:
- Doorway doorway = (Doorway)player.WhatInteractingWith!;
- doorway.OpenDegree += gameMap.Timer.nowTime() - doorway.OpenStartTime;
- doorway.OpenStartTime = 0;
- player.ChangePlayerState(value, gameObj);
- break;
- case PlayerStateType.Addicted:
- if (value == PlayerStateType.Rescued)
- player.ChangePlayerStateInOneThread(value, gameObj);
- else
- player.ChangePlayerState(value, gameObj);
- break;
- case PlayerStateType.Rescued:
- if (value == PlayerStateType.Addicted)
- player.ChangePlayerStateInOneThread(value, gameObj);
- else
- player.ChangePlayerState(value, gameObj);
- break;
- default:
- player.ChangePlayerState(value, gameObj);
- break;
- }
- }
- }
-
- public Character? AddPlayer(XY pos, int teamID, int playerID, CharacterType characterType, Character? parent = null)
- {
- Character newPlayer;
-
- if (characterType == CharacterType.Robot)
- {
- newPlayer = new Golem(pos, GameData.characterRadius, parent);
- }
- else newPlayer = (GameData.IsGhost(characterType)) ? new Ghost(pos, GameData.characterRadius, characterType) : new Student(pos, GameData.characterRadius, characterType);
- gameMap.Add(newPlayer);
-
- newPlayer.TeamID = teamID;
- newPlayer.PlayerID = playerID;
- /* #region 人物装弹
- new Thread
- (
- () =>
- {
- while (!gameMap.Timer.IsGaming)
- Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval));
- long lastTime = Environment.TickCount64;
- new FrameRateTaskExecutor<int>(
- loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved,
- loopToDo: () =>
- {
- long nowTime = Environment.TickCount64;
- if (newPlayer.BulletNum == newPlayer.MaxBulletNum)
- lastTime = nowTime;
- else if (nowTime - lastTime >= newPlayer.CD)
- {
- _ = newPlayer.TryAddBulletNum();
- lastTime = nowTime;
- }
- },
- timeInterval: GameData.checkInterval,
- finallyReturn: () => 0
- )
- {
- AllowTimeExceed = true,
- }
- .Start();
- }
- )
- { IsBackground = true }.Start();
- #endregion
- */
- #region BGM,牵制得分更新
- new Thread
- (
- () =>
- {
- while (!gameMap.Timer.IsGaming)
- Thread.Sleep(GameData.checkInterval);
- int TimePinningDown = 0, ScoreAdded = 0;
-
- bool noise = false;
- if (!newPlayer.IsGhost())
- {
- gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
- try
- {
- foreach (Character person in gameMap.GameObjDict[GameObjType.Character])
- {
- if (person.IsGhost())
- {
- if (person.CharacterType == CharacterType.ANoisyPerson)
- {
- noise = true;
- newPlayer.AddBgm(BgmType.GhostIsComing, 1411180);
- newPlayer.AddBgm(BgmType.GeneratorIsBeingFixed, 154991);
- }
- }
- }
- }
- finally
- {
- gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
- }
- }
- new FrameRateTaskExecutor<int>(
- loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved,
- loopToDo: () =>
- {
- gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
- try
- {
- if (newPlayer.IsGhost())
- {
- double bgmVolume = 0;
- foreach (Character person in gameMap.GameObjDict[GameObjType.Character])
- {
- if (!person.IsGhost() && XY.DistanceFloor3(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment))
- {
- if ((double)newPlayer.AlertnessRadius / XY.DistanceFloor3(newPlayer.Position, person.Position) > bgmVolume)
- bgmVolume = newPlayer.AlertnessRadius / XY.DistanceFloor3(newPlayer.Position, person.Position);
- }
- }
- newPlayer.AddBgm(BgmType.StudentIsApproaching, bgmVolume);
- }
- else
- {
- foreach (Character person in gameMap.GameObjDict[GameObjType.Character])
- {
- if (person.IsGhost())
- {
- if (!noise)
- {
- if (XY.DistanceFloor3(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment))
- newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.DistanceFloor3(newPlayer.Position, person.Position));
- else newPlayer.AddBgm(BgmType.GhostIsComing, 0);
- }
- if (newPlayer.CharacterType != CharacterType.Teacher && newPlayer.CharacterType != CharacterType.Robot && !newPlayer.NoHp() && newPlayer.PlayerState != PlayerStateType.Stunned && XY.DistanceFloor3(newPlayer.Position, person.Position) <= GameData.PinningDownRange)
- {
- TimePinningDown += GameData.checkInterval;
- newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded);
- ScoreAdded = GameData.StudentScorePinDown(TimePinningDown);
- }
- else TimePinningDown = ScoreAdded = 0;
- break;
- }
- }
- }
- }
- finally
- {
- gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
- }
-
- if (!noise)
- {
- gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock();
- try
- {
- double bgmVolume = 0;
- foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
- {
- if (XY.DistanceFloor3(newPlayer.Position, generator.Position) <= newPlayer.AlertnessRadius)
- {
- if (generator.NumOfFixing > 0 && (double)newPlayer.AlertnessRadius * generator.DegreeOfRepair / GameData.degreeOfFixedGenerator / XY.DistanceFloor3(newPlayer.Position, generator.Position) > bgmVolume)
- bgmVolume = (double)newPlayer.AlertnessRadius * generator.DegreeOfRepair / GameData.degreeOfFixedGenerator / XY.DistanceFloor3(newPlayer.Position, generator.Position);
- }
- }
- newPlayer.AddBgm(BgmType.GeneratorIsBeingFixed, bgmVolume);
- }
- finally
- {
- gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock();
- }
- }
- },
- 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();
- #endregion
-
- return newPlayer;
- }
-
- public void BeAddictedToGame(Student player, Ghost ghost)
- {
- if (player.CharacterType == CharacterType.Robot)
- {
- ghost.AddScore(GameData.TrickerScoreDestroyRobot);
- Die(player);
- return;
- }
- ghost.AddScore(GameData.TrickerScoreStudentBeAddicted);
- if (player.GamingAddiction > 0)
- {
- if (player.GamingAddiction < GameData.BeginGamingAddiction)
- player.GamingAddiction = GameData.BeginGamingAddiction;
- else if (player.GamingAddiction < GameData.MidGamingAddiction)
- player.GamingAddiction = GameData.MidGamingAddiction;
- else
- {
- ghost.AddScore(GameData.TrickerScoreStudentDie);
- Die(player);
- return;
- }
- }
- SetPlayerState(player, PlayerStateType.Addicted);
- long threadNum = player.StateNum;
- new Thread
- (() =>
- {
- #if DEBUG
- Debugger.Output(player, " is addicted ");
- #endif
- new FrameRateTaskExecutor<int>(
- () => threadNum == player.StateNum && player.GamingAddiction < player.MaxGamingAddiction && gameMap.Timer.IsGaming,
- () =>
- {
- player.GamingAddiction += (player.PlayerState == PlayerStateType.Addicted) ? GameData.frameDuration : 0;
- },
- timeInterval: GameData.frameDuration,
- () =>
- {
- if (player.GamingAddiction == player.MaxGamingAddiction && gameMap.Timer.IsGaming)
- {
- ghost.AddScore(GameData.TrickerScoreStudentDie);
- Die(player);
- }
- return 0;
- }
- )
- .Start();
- }
- )
- { IsBackground = true }.Start();
- }
-
- public bool BeStunned(Character player, int time)
- {
- if (player.PlayerState == PlayerStateType.Stunned || player.NoHp() || player.CharacterType == CharacterType.Robot) return false;
- new Thread
- (() =>
- {
- SetPlayerState(player, PlayerStateType.Stunned);
- long threadNum = player.StateNum;
- Thread.Sleep(time);
- if (threadNum == player.StateNum)
- SetPlayerState(player);
- }
- )
- { IsBackground = true }.Start();
- return true;
- }
-
- public bool TryBeAwed(Student character, Bullet bullet)
- {
- if (character.CanBeAwed())
- {
- if (BeStunned(character, GameData.basicStunnedTimeOfStudent))
- bullet.Parent!.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.basicStunnedTimeOfStudent));
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// 遭受攻击
- /// </summary>
- /// <param name="subHP"></param>
- /// <param name="hasSpear"></param>
- /// <param name="attacker">伤害来源</param>
- /// <returns>人物在受到攻击后死了吗</returns>
- public void BeAttacked(Student student, Bullet bullet)
- {
- #if DEBUG
- Debugger.Output(student, "is being shot!");
- #endif
- if (student.NoHp()) return; // 原来已经死了
- if (!bullet.Parent!.IsGhost()) return;
-
- if (student.CharacterType == CharacterType.StraightAStudent)
- {
- ((WriteAnswers)student.FindIActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation = 0;
- }
- student.SetDegreeOfTreatment0();
- #if DEBUG
- Debugger.Output(bullet, " 's AP is " + bullet.AP.ToString());
- #endif
- if (student.TryUseShield())
- {
- if (bullet.HasSpear)
- {
- int subHp = student.TrySubHp(bullet.AP);
- #if DEBUG
- Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
- #endif
- bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp) + GameData.ScorePropUseSpear);
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
- }
- else return;
- }
- else
- {
- int subHp;
- if (bullet.HasSpear)
- {
- subHp = student.TrySubHp(bullet.AP + GameData.ApSpearAdd);
- #if DEBUG
- Debugger.Output(this, "is being shot with Spear! Now his hp is" + student.HP.ToString());
- #endif
- }
- else
- {
- subHp = student.TrySubHp(bullet.AP);
- #if DEBUG
- Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString());
- #endif
- }
- bullet.Parent.AddScore(GameData.TrickerScoreAttackStudent(subHp));
- bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * subHp));
- }
- if (student.HP <= 0)
- student.TryActivatingLIFE(); // 如果有复活甲
-
- if (student.HP <= 0)
- BeAddictedToGame(student, (Ghost)bullet.Parent);
- else TryBeAwed(student, bullet);
- }
-
- public bool BackSwing(Character player, int time)
- {
- if (time <= 0) return false;
- if (player.PlayerState == PlayerStateType.Swinging || (!player.Commandable() && player.PlayerState != PlayerStateType.TryingToAttack)) return false;
- SetPlayerState(player, PlayerStateType.Swinging);
- long threadNum = player.StateNum;
-
- new Thread
- (() =>
- {
- Thread.Sleep(time);
-
- if (threadNum == player.StateNum)
- {
- SetPlayerState(player);
- }
- }
- )
- { IsBackground = true }.Start();
- return true;
- }
-
- public void Die(Student player)
- {
- #if DEBUG
- Debugger.Output(player, "die.");
- #endif
- if (player.PlayerState == PlayerStateType.Deceased) return;
- player.RemoveFromGame(PlayerStateType.Deceased);
-
- for (int i = 0; i < GameData.maxNumOfPropInPropInventory; i++)
- {
- Prop? prop = player.UseProp(i);
- if (prop != null)
- {
- prop.ReSetPos(player.Position);
- gameMap.Add(prop);
- }
- }
- if (player.CharacterType == CharacterType.Robot)
- {
- var parent = ((Golem)player).Parent;
- if (parent != null && parent.CharacterType == CharacterType.TechOtaku)
- {
- ((SummonGolem)(parent.FindIActiveSkill(ActiveSkillType.SummonGolem))).GolemSummoned = null;
- player.FindIActiveSkill(ActiveSkillType.UseRobot).IsBeingUsed = false;
- }
- return;
- }
- ++gameMap.NumOfDeceasedStudent;
- }
-
- }
- }
- }
|