fix: 🚑 fix the bug about interrupting the attack
tags/0.1.0
| @@ -1,5 +1,5 @@ | |||
| # 规则 | |||
| V4.3 | |||
| V4.4 | |||
| - [规则](#规则) | |||
| - [简则](#简则) | |||
| - [地图](#地图) | |||
| @@ -78,11 +78,10 @@ V4.3 | |||
| 8. 翻窗 | |||
| ### 攻击 | |||
| - 无论近战远程均产生bullet表示攻击 | |||
| - 攻击类型CommonAttackOfGhost攻击未写完的作业,会造成对应攻击力的损坏 | |||
| - 捣蛋鬼攻击交互状态或前后摇的学生,将使学生眩晕4.3s | |||
| | 攻击类型 |搞蛋鬼的一般攻击CommonAttackOfGhost| 飞刀FlyingKnife | 蹦蹦炸弹BombBomb | 小炸弹JumpyDumpty | | |||
| | 攻击(子弹)类型 |搞蛋鬼的一般攻击CommonAttackOfGhost| 飞刀FlyingKnife | 蹦蹦炸弹BombBomb | 小炸弹JumpyDumpty | | |||
| | :------------ | :--------------------- | :--------------------- | :--------------------- | :--------------------- | | |||
| | 子弹爆炸范围 | 0 | 0 | 1000 | 500 | | |||
| | 子弹攻击距离 | 1100 | 39000 | 1100 | 2200 | | |||
| @@ -103,13 +102,14 @@ V4.3 | |||
| - 每张地图都有10间教室,学生需要完成其中的**7间**教室的作业,才可以开启任意校门。 | |||
| - 开启校门所需时间为18秒,开启的进度不清空 | |||
| - 当**3间**教室的作业完成时,隐藏校门在3-5个刷新点之一随机显现;当只剩1名学生时,隐藏校门自动打开。 | |||
| - 从开启的校门或隐藏校门离开是学生终极目标 | |||
| #### 勉励 | |||
| - 当达到被勉励程度达到1500000或者最大学习毅力与当前学习毅力的差值时,勉励完成,学生毅力增加对应被勉励程度。 | |||
| - 当被勉励程度达到当前损失的毅力值或1500000时,勉励完成,学生毅力增加对应被勉励程度。 | |||
| - 勉励中断时,被勉励程度保留;遭到攻击时被勉励程度清空 | |||
| #### 沉迷与唤醒 | |||
| - 当学生学习毅力归零时,学生原地进入沉迷状态,每毫秒增加1沉迷度 | |||
| - 学习毅力归零时,学生原地进入沉迷状态,每毫秒增加1沉迷度 | |||
| - 唤醒需要时间1秒,之后学习毅力恢复至1/2。沉迷程度不清空。 | |||
| - 进入沉迷状态时,如果学生原沉迷程度在(0,该玩家最大沉迷度/3)中,沉迷程度直接变为其最大沉迷度/3;原沉迷程度在[其最大沉迷度/3,其最大沉迷度x2/3)中,沉迷程度直接变为其最大沉迷度x2/3;原沉迷程度大于其最大沉迷度x2/3,从游戏中出局; | |||
| - 当学生沉迷程度达到其最大沉迷程度时,从游戏中出局 | |||
| @@ -128,8 +128,8 @@ V4.3 | |||
| ### 信息相关 | |||
| - Bgm (在structures.h/.py中的student类或Tricker类中作为其属性) | |||
| 1. 不详的感觉(dangerAlert):如果捣蛋鬼进入(学生的警戒半径/捣蛋鬼的隐蔽度)的距离,则学生的dangerAlert=(int)(警戒半径/二者距离) | |||
| 2. 期待搞事的感觉(trickDesire):如果有学生进入(捣蛋鬼的警戒半径/学生的隐蔽度)的距离,则捣蛋鬼trickDesire=(警戒半径/可被发觉的最近的学生距离) | |||
| 3. 学习的声音(classVolume): 警戒半径内有人学习时,捣蛋鬼classVolume=(警戒半径x学习进度百分比)/二者距离 | |||
| 2. 期待搞事的感觉(trickDesire):如果有学生进入(捣蛋鬼的警戒半径/学生的隐蔽度)的距离,则捣蛋鬼trickDesire=(int)(警戒半径/可被发觉的最近的学生距离) | |||
| 3. 学习的声音(classVolume): 警戒半径内有人学习时,捣蛋鬼classVolume=(int)((警戒半径x学习进度百分比)/二者距离) | |||
| - 可以向其他每一个队友发送不超过256字节的信息 | |||
| ### 可视范围 | |||
| @@ -137,8 +137,9 @@ V4.3 | |||
| - 对于在从草地中的物体,物体与玩家连线上均为草地方可见 | |||
| ### 道具 | |||
| - 玩家最多同时拥有三个道具 | |||
| - 可以捡起与自己处于同一个格子(cell)的道具,或将道具扔在原地 | |||
| - 玩家同时最多拥有三个道具 | |||
| - 可以捡起与自己处于同一个格子(cell)的道具 | |||
| - 可将道具扔在玩家位置 | |||
| | 道具 | 对学生增益 | 学生得分条件 | 对搞蛋鬼增益 | 搞蛋鬼得分条件 | | |||
| | :-------- | :-------------------------------------- | :-----------------| :-------------------------------------- |:-----------------| | |||
| @@ -284,61 +285,62 @@ V4.3 | |||
| ## 细则 | |||
| ### 特殊说明 | |||
| - 不加说明,这里“学生”往往包括职业“教师” | |||
| - 不加说明,这里“学生”往往包括职业“教师” | |||
| ### 移动 | |||
| - 不鼓励选手面向地图编程,因为移动过程中你可以受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。 | |||
| ### 人物 | |||
| - 被唤醒或被勉励不属于交互状态,翻窗属于交互状态 | |||
| - EndAllAction()及Move指令调用数总和一帧内不超过10次 | |||
| ### 初始状态 | |||
| - 玩家出生点固定且一定为空地 | |||
| - 玩家出生点固定且一定为空地 | |||
| ### 道具 | |||
| - 使用钥匙相当于销毁 | |||
| - 使用钥匙相当于销毁 | |||
| ### 交互 | |||
| - 在指令仍在进行时,重复发出同一类型的交互指令是无效的,你需要先发出Stop指令终止进行的指令 | |||
| - 实际上唤醒或勉励不同的人是有效的 | |||
| - 被唤醒或被勉励不属于交互状态,翻窗属于交互状态 | |||
| ### 学习与毕业 | |||
| - 隐藏校门与校门对于人有碰撞体积 | |||
| - 一个校门同时最多可以由一人开启 | |||
| - 隐藏校门与校门对于人有碰撞体积 | |||
| ### 攻击 | |||
| - 每次学生受到攻击后会损失对应子弹的攻击力的学习毅力 | |||
| - 无论近战远程均产生bullet表示攻击 | |||
| - 前摇期间攻击被打断时,子弹消失。 | |||
| - 此处,前摇指 从播放攻击动作开始 攻击者不能交互 的时间 | |||
| - 每次学生受到攻击后会损失对应子弹的攻击力的学习毅力 | |||
| - 此处,前摇指 从播放攻击动作开始 攻击者不能交互 的时间 | |||
| ### 沉迷与唤醒 | |||
| - 在被救时沉迷度不增加 | |||
| - 不能两人同时唤醒一个人 | |||
| - 在被救时沉迷度不增加 | |||
| ### 门 | |||
| - 每个教学区都有2把钥匙 | |||
| - 一扇门只允许同时一个人开锁门 | |||
| - 开锁门未完成前,门状态表现为原来的状态 | |||
| - 开锁门未完成前,门状态表现为原来的状态 | |||
| - 开锁门进度中断后清空 | |||
| ### 窗 | |||
| - 攻击可以穿过窗,道具可以在窗上 | |||
| - 翻越窗户是一种交互行为,翻窗一共有两个过程 | |||
| - 跳上窗:从当前位置到窗边缘中点,位置瞬移,时间=距离/爬窗速度。中断时,停留在原位置 | |||
| - 爬窗:从窗一侧边缘中点到另一侧格子中心,位置渐移,时间=距离/爬窗速度。中断时,停留在另一侧格子中心 | |||
| - 通常情况下捣蛋鬼翻越窗户的速度高于学生。 | |||
| - 攻击可以穿过窗,道具可以在窗上 | |||
| - 有人正在翻越窗户时,其他玩家均不可以翻越该窗户。 | |||
| - 通常情况下捣蛋鬼翻越窗户的速度高于学生。 | |||
| ### 箱子 | |||
| - 地图上有8个箱子 | |||
| - 同一时刻只允许一人进行开启 | |||
| - 同一时刻只允许一人进行开启 | |||
| - 未开启完成的箱子在下一次需要重新开始开启。 | |||
| - 箱子开启后其中道具才可以被观测和拿取 | |||
| - 箱子开启后其中道具才可以被观测和拿取 | |||
| - 箱子道具不刷新 | |||
| ### 得分 | |||
| - 眩晕或毅力值归零时无牵制得分 | |||
| - 眩晕或毅力值归零时无牵制得分 | |||
| ### 信息相关 | |||
| - Bgm在没有符合条件的情况下,值为0。 | |||
| @@ -64,6 +64,29 @@ namespace Gaming | |||
| } | |||
| } | |||
| public bool TryRemoveBullet(Bullet bullet) | |||
| { | |||
| bullet.CanMove = false; | |||
| if (gameMap.Remove(bullet)) | |||
| { | |||
| if (bullet.BulletBombRange > 0) | |||
| { | |||
| BombedBullet bombedBullet = new(bullet); | |||
| gameMap.Add(bombedBullet); | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(GameData.frameDuration * 5); | |||
| gameMap.RemoveJustFromMap(bombedBullet); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| return true; | |||
| } | |||
| else return false; | |||
| } | |||
| private void BulletBomb(Bullet bullet, GameObj? objBeingShot) | |||
| { | |||
| #if DEBUG | |||
| @@ -72,11 +95,10 @@ namespace Gaming | |||
| else | |||
| Debugger.Output(bullet, "bombed without objBeingShot"); | |||
| #endif | |||
| bullet.CanMove = false; | |||
| if (!TryRemoveBullet(bullet)) return; | |||
| if (bullet.BulletBombRange == 0) | |||
| { | |||
| gameMap.Remove(bullet); | |||
| if (objBeingShot == null) | |||
| { | |||
| characterManager.BackSwing((Character)bullet.Parent, bullet.Backswing); | |||
| @@ -88,20 +110,6 @@ namespace Gaming | |||
| return; | |||
| } | |||
| if (gameMap.Remove(bullet)) | |||
| { | |||
| BombedBullet bombedBullet = new(bullet); | |||
| gameMap.Add(bombedBullet); | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(GameData.frameDuration * 5); | |||
| gameMap.RemoveJustFromMap(bombedBullet); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| /*if (objBeingShot != null) | |||
| { | |||
| else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。 | |||
| @@ -178,24 +186,35 @@ namespace Gaming | |||
| bullet.CanMove = true; | |||
| gameMap.Add(bullet); | |||
| moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| if (bullet.CastTime > 0) | |||
| { | |||
| characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | |||
| if (bullet.IsRemoteAttack) | |||
| { | |||
| new Thread | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.CastTime); | |||
| if (player.PlayerState == PlayerStateType.TryingToAttack) | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => player.PlayerState == PlayerStateType.TryingToAttack && gameMap.Timer.IsGaming, | |||
| loopToDo: () => | |||
| { | |||
| }, | |||
| timeInterval: GameData.checkInterval, | |||
| finallyReturn: () => 0, | |||
| maxTotalDuration: bullet.CastTime | |||
| ) | |||
| .Start(); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| characterManager.SetPlayerState(player); | |||
| if (player.PlayerState == PlayerStateType.TryingToAttack) | |||
| { | |||
| characterManager.SetPlayerState(player); | |||
| } | |||
| else TryRemoveBullet(bullet); | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| } | |||
| if (bullet != null) | |||