| @@ -1,5 +1,5 @@ | |||||
| # 规则 | # 规则 | ||||
| V3.9 | |||||
| V4.0 | |||||
| - [规则](#规则) | - [规则](#规则) | ||||
| - [简则](#简则) | - [简则](#简则) | ||||
| - [地图](#地图) | - [地图](#地图) | ||||
| @@ -42,17 +42,17 @@ V3.9 | |||||
| - [门](#门-1) | - [门](#门-1) | ||||
| - [窗](#窗-1) | - [窗](#窗-1) | ||||
| - [箱子](#箱子-1) | - [箱子](#箱子-1) | ||||
| - [信息获取](#信息获取) | |||||
| - [得分](#得分-1) | |||||
| ## 简则 | ## 简则 | ||||
| ### 地图 | ### 地图 | ||||
| - 地图为矩形区域,地图上的游戏对象坐标为(x, y),且x和y均为整数。 | |||||
| - 地图为矩形区域,游戏对象坐标为(x, y),x和y均为整数。 | |||||
| - **x坐标轴正方向竖直向下,y坐标轴正方向水平向右**; | - **x坐标轴正方向竖直向下,y坐标轴正方向水平向右**; | ||||
| - **极坐标以x坐标轴为极轴,角度逆时针为正方向**。 | - **极坐标以x坐标轴为极轴,角度逆时针为正方向**。 | ||||
| - 地图由50 * 50个格子构成,其中每个格子代表1000 * 1000的正方形。每个格子的编号(CellX,CellY)可以计算得到: | - 地图由50 * 50个格子构成,其中每个格子代表1000 * 1000的正方形。每个格子的编号(CellX,CellY)可以计算得到: | ||||
| - $$CellX=\frac{x}{1000},CellY=\frac{y}{1000}$$ | - $$CellX=\frac{x}{1000},CellY=\frac{y}{1000}$$ | ||||
| - 地图上格子有自己的区域类型:陆地、墙、草地、教室、校门、隐藏校门、门、窗、箱子 | |||||
| - 格子有对应区域类型:陆地、墙、草地、教室、校门、隐藏校门、门、窗、箱子 | |||||
| ### 人物 | ### 人物 | ||||
| - 人物半径为800 | - 人物半径为800 | ||||
| @@ -125,10 +125,11 @@ V3.9 | |||||
| - 开箱后将有2个随机道具掉落在玩家位置。 | - 开箱后将有2个随机道具掉落在玩家位置。 | ||||
| ### 信息相关 | ### 信息相关 | ||||
| 1. 不详的感觉(dangerAlert):捣蛋鬼进入(学生的警戒半径/捣蛋鬼的隐蔽度)时,学生收到;捣蛋鬼距离学生越近,Bgm音量越大。bgmVolume=(警戒半径/二者距离) | |||||
| 2. 期待搞事的感觉(trickDesire):学生进入(捣蛋鬼的警戒半径/学生的隐蔽度)时,捣蛋鬼收到;捣蛋鬼距离学生越近,Bgm音量越大。bgmVolume=(警戒半径/可被发觉的最近的学生距离) | |||||
| 3. 学习的声音(classVolume): 捣蛋鬼警戒半径内有人学习时收到;bgmVolume=(警戒半径x学习进度百分比)/二者距离 | |||||
| 4. 可以向其他每一个队友发送不超过256字节的信息 | |||||
| - Bgm | |||||
| 1. 不详的感觉(dangerAlert):捣蛋鬼进入(学生的警戒半径/捣蛋鬼的隐蔽度)时,学生收到;捣蛋鬼距离学生越近,Bgm音量越大。bgmVolume=(警戒半径/二者距离) | |||||
| 2. 期待搞事的感觉(trickDesire):学生进入(捣蛋鬼的警戒半径/学生的隐蔽度)时,捣蛋鬼收到;捣蛋鬼距离学生越近,Bgm音量越大。bgmVolume=(警戒半径/可被发觉的最近的学生距离) | |||||
| 3. 学习的声音(classVolume): 捣蛋鬼警戒半径内有人学习时收到;bgmVolume=(警戒半径x学习进度百分比)/二者距离 | |||||
| - 可以向其他每一个队友发送不超过256字节的信息 | |||||
| ### 可视范围 | ### 可视范围 | ||||
| - 小于视野半径,且受限于墙和草地 | - 小于视野半径,且受限于墙和草地 | ||||
| @@ -155,14 +156,14 @@ V3.9 | |||||
| - 对学生造成伤害时,得伤害*100/基本伤害(1500000)分。 | - 对学生造成伤害时,得伤害*100/基本伤害(1500000)分。 | ||||
| - 对作业造成破坏时,每破坏n%的作业,得n分 | - 对作业造成破坏时,每破坏n%的作业,得n分 | ||||
| - 使学生进入沉迷状态时,得50分。 | |||||
| - 使学生进入眩晕状态时,得20*眩晕时长(/s)分。 | |||||
| - 使学生沉迷时,得50分。 | |||||
| - 使学生眩晕时,得20*眩晕时长(/s)分。 | |||||
| - 每淘汰一个学生,得1000分 | - 每淘汰一个学生,得1000分 | ||||
| ### 学生 | ### 学生 | ||||
| - 学生每完成n%的作业,得2n分 | - 学生每完成n%的作业,得2n分 | ||||
| - 学生与捣蛋鬼处于小于5000的距离认为在牵制状态,得(牵制时长(ms)*0.00369)分 | |||||
| - 使捣蛋鬼进入眩晕状态时,得20*眩晕时长(/s)分。 | |||||
| - 学生与捣蛋鬼处于小于5000的距离认为正在牵制,得(牵制时长(ms)*0.00369)分 | |||||
| - 使捣蛋鬼眩晕时,得20*眩晕时长(/s)分。 | |||||
| - 成功唤醒一名同学,得100分 | - 成功唤醒一名同学,得100分 | ||||
| - 成功勉励一名同学,得50*勉励程度/基本勉励程度(1500000)分 | - 成功勉励一名同学,得50*勉励程度/基本勉励程度(1500000)分 | ||||
| - 毕业,得1000分 | - 毕业,得1000分 | ||||
| @@ -250,7 +251,8 @@ V3.9 | |||||
| - 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇的捣蛋鬼会被眩晕(3070)ms, | - 使用瞬间,在可视范围内的使用技能状态中、攻击前后摇的捣蛋鬼会被眩晕(3070)ms, | ||||
| - 通过眩晕获得对应得分 | - 通过眩晕获得对应得分 | ||||
| - 特性 | - 特性 | ||||
| - 教师无法获得牵制得分 | |||||
| - 无法获得牵制得分 | |||||
| - 无法毕业 | |||||
| #### 学霸 | #### 学霸 | ||||
| - 特性 | - 特性 | ||||
| @@ -334,5 +336,5 @@ V3.9 | |||||
| - 箱子开启后其中道具才可以被观测和拿取 | - 箱子开启后其中道具才可以被观测和拿取 | ||||
| - 箱子道具不刷新 | - 箱子道具不刷新 | ||||
| ### 信息获取 | |||||
| - 查询对应物体状态时物体不存在则返回false | |||||
| ### 得分 | |||||
| - 眩晕或毅力值归零时无牵制得分 | |||||
| @@ -122,7 +122,7 @@ namespace Gaming | |||||
| public bool Escape(Student player) | public bool Escape(Student player) | ||||
| { | { | ||||
| if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot) | |||||
| if (!(player.Commandable()) || player.CharacterType == CharacterType.Robot || player.CharacterType == CharacterType.Teacher) | |||||
| return false; | return false; | ||||
| Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway); | ||||
| if (doorwayForEscape != null && doorwayForEscape.IsOpen()) | if (doorwayForEscape != null && doorwayForEscape.IsOpen()) | ||||
| @@ -6,7 +6,6 @@ using Preparation.Utility; | |||||
| using GameEngine; | using GameEngine; | ||||
| using Preparation.Interface; | using Preparation.Interface; | ||||
| using Timothy.FrameRateTask; | using Timothy.FrameRateTask; | ||||
| using System.Numerics; | |||||
| namespace Gaming | namespace Gaming | ||||
| { | { | ||||
| @@ -85,8 +84,6 @@ namespace Gaming | |||||
| return; | return; | ||||
| } | } | ||||
| Debugger.Output(bullet, bullet.TypeOfBullet.ToString()); | |||||
| BombObj(bullet, objBeingShot); | BombObj(bullet, objBeingShot); | ||||
| characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); | characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); | ||||
| return; | return; | ||||
| @@ -105,6 +102,7 @@ namespace Gaming | |||||
| if (bullet.TypeOfBullet == BulletType.BombBomb && objBeingShot != null) | if (bullet.TypeOfBullet == BulletType.BombBomb && objBeingShot != null) | ||||
| { | { | ||||
| bullet.Parent.BulletOfPlayer = BulletType.JumpyDumpty; | bullet.Parent.BulletOfPlayer = BulletType.JumpyDumpty; | ||||
| Debugger.Output(bullet.Parent, bullet.Parent.CharacterType.ToString() + " " + bullet.Parent.BulletNum.ToString()); | |||||
| Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI / 2.0); | Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI / 2.0); | ||||
| Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI * 3.0 / 2.0); | Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI * 3.0 / 2.0); | ||||
| } | } | ||||
| @@ -146,15 +144,11 @@ namespace Gaming | |||||
| characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); | characterManager.BackSwing((Character?)bullet.Parent, bullet.RecoveryFromHit); | ||||
| } | } | ||||
| public bool Attack(Character? player, double angle) | |||||
| public bool Attack(Character player, double angle) | |||||
| { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | ||||
| if (player == null) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| if (player.BulletOfPlayer == BulletType.Null || !player.Commandable()) | |||||
| if (player.BulletOfPlayer == BulletType.Null) | |||||
| return false; | return false; | ||||
| Debugger.Output(player, player.CharacterType.ToString() + "Attack in " + player.BulletOfPlayer.ToString()); | |||||
| XY res = player.Position + new XY // 子弹紧贴人物生成。 | XY res = player.Position + new XY // 子弹紧贴人物生成。 | ||||
| ( | ( | ||||
| @@ -166,7 +160,7 @@ namespace Gaming | |||||
| if (bullet != null) | if (bullet != null) | ||||
| { | { | ||||
| Debugger.Output(player, "Attack in" + bullet.ToString()); | |||||
| Debugger.Output(player, "Attack in " + bullet.ToString()); | |||||
| bullet.AP += player.TryAddAp() ? GameData.ApPropAdd : 0; | bullet.AP += player.TryAddAp() ? GameData.ApPropAdd : 0; | ||||
| bullet.CanMove = true; | bullet.CanMove = true; | ||||
| gameMap.Add(bullet); | gameMap.Add(bullet); | ||||
| @@ -141,8 +141,7 @@ namespace Gaming | |||||
| bgmVolume = newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position); | bgmVolume = newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position); | ||||
| } | } | ||||
| } | } | ||||
| if (bgmVolume > 0) | |||||
| newPlayer.AddBgm(BgmType.StudentIsApproaching, bgmVolume); | |||||
| newPlayer.AddBgm(BgmType.StudentIsApproaching, bgmVolume); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -152,7 +151,7 @@ namespace Gaming | |||||
| { | { | ||||
| if (!noise && XY.Distance(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment)) | if (!noise && XY.Distance(newPlayer.Position, person.Position) <= (newPlayer.AlertnessRadius / person.Concealment)) | ||||
| newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position)); | newPlayer.AddBgm(BgmType.GhostIsComing, (double)newPlayer.AlertnessRadius / XY.Distance(newPlayer.Position, person.Position)); | ||||
| if (newPlayer.CharacterType != CharacterType.Teacher && XY.Distance(newPlayer.Position, person.Position) <= GameData.PinningDownRange) | |||||
| if (newPlayer.CharacterType != CharacterType.Teacher && !newPlayer.NoHp() && newPlayer.PlayerState != PlayerStateType.Stunned && XY.Distance(newPlayer.Position, person.Position) <= GameData.PinningDownRange) | |||||
| { | { | ||||
| TimePinningDown += GameData.checkInterval; | TimePinningDown += GameData.checkInterval; | ||||
| newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); | newPlayer.AddScore(GameData.StudentScorePinDown(TimePinningDown) - ScoreAdded); | ||||
| @@ -220,7 +220,7 @@ namespace Gaming | |||||
| if (!gameMap.Timer.IsGaming) | if (!gameMap.Timer.IsGaming) | ||||
| return false; | return false; | ||||
| Character? player = gameMap.FindPlayerToAction(playerID); | Character? player = gameMap.FindPlayerToAction(playerID); | ||||
| if (player != null) | |||||
| if (player != null && player.Commandable()) | |||||
| { | { | ||||
| return attackManager.Attack(player, angle); | return attackManager.Attack(player, angle); | ||||
| } | } | ||||
| @@ -12,6 +12,8 @@ namespace Preparation.Interface | |||||
| public double Vampire { get; } | public double Vampire { get; } | ||||
| public PlayerStateType PlayerState { get; } | public PlayerStateType PlayerState { get; } | ||||
| public BulletType BulletOfPlayer { get; set; } | public BulletType BulletOfPlayer { get; set; } | ||||
| public CharacterType CharacterType { get; } | |||||
| public int BulletNum { get; } | |||||
| public bool IsGhost(); | public bool IsGhost(); | ||||
| } | } | ||||