Browse Source

Merge pull request #270 from shangfengh/new

fix: 🚑 fix the bug about interrupting the attack
tags/0.1.0
DragonAura GitHub 2 years ago
parent
commit
8afda4af22
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 48 deletions
  1. +25
    -23
      logic/GameRules.md
  2. +44
    -25
      logic/Gaming/AttackManager.cs

+ 25
- 23
logic/GameRules.md View File

@@ -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。

+ 44
- 25
logic/Gaming/AttackManager.cs View File

@@ -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)


Loading…
Cancel
Save