Browse Source

Merge pull request #565 from eesast/dev

feat:  update balance adjustments
tags/v0.1.0
shangfengh GitHub 2 years ago
parent
commit
eac07875b0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 271 additions and 221 deletions
  1. +59
    -32
      CAPI/cpp/API/include/constants.h
  2. +66
    -45
      CAPI/python/PyAPI/constants.py
  3. +2
    -2
      docs/使用文档.md
  4. +6
    -6
      docs/游戏机制与平衡性调整更新草案.md
  5. +5
    -0
      docs/版本更新说明.md
  6. +1
    -1
      logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
  7. +2
    -2
      logic/GameClass/GameObj/Bullet/Bullet.cs
  8. +1
    -1
      logic/GameClass/GameObj/Character/Character.Skill.cs
  9. +34
    -29
      logic/GameClass/GameObj/Character/Character.cs
  10. +4
    -21
      logic/GameClass/GameObj/GameObj.cs
  11. +9
    -59
      logic/GameClass/GameObj/Moveable.cs
  12. +1
    -1
      logic/GameClass/GameObj/Prop/Gadget.cs
  13. +1
    -1
      logic/GameClass/GameObj/Prop/Item.cs
  14. +4
    -4
      logic/GameEngine/MoveEngine.cs
  15. +55
    -9
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  16. +2
    -0
      logic/Gaming/SkillManager/SkillManager.cs
  17. +1
    -1
      logic/Preparation/Interface/IMoveable.cs
  18. +2
    -2
      logic/Preparation/Interface/IOccupation.cs
  19. +13
    -3
      logic/Preparation/Interface/ISkill.cs
  20. +3
    -2
      logic/Preparation/Utility/GameData.cs

+ 59
- 32
CAPI/cpp/API/include/constants.h View File

@@ -32,10 +32,10 @@ namespace Constants
// 人物属性相关
SCCI int basicEncourageSpeed = 100;
SCCI int basicFixSpeed = 123;
SCCI int basicSpeedOfOpeningOrLocking = 4000;
SCCI int basicSpeedOfOpeningOrLocking = 5000;
SCCI int basicStudentSpeedOfClimbingThroughWindows = 1222;
SCCI int basicTrickerSpeedOfClimbingThroughWindows = 2540;
SCCI int basicSpeedOfOpenChest = 1000;
SCCI int basicSpeedOfOpenChest = 1250;

SCCI int basicHp = 3000000;
SCCI int basicMaxGamingAddiction = 60000;
@@ -138,19 +138,19 @@ namespace Constants
SCCI int moveSpeed = basicStudentSpeed * 9 / 10;
SCCI int maxHp = basicHp * 10;
SCCI int maxAddiction = basicMaxGamingAddiction * 10;
SCCI int fixSpeed = basicFixSpeed * 0;
SCCI int fixSpeed = (int)(basicFixSpeed * 50 / 123);
SCCI int encourageSpeed = basicEncourageSpeed * 8 / 10;
SCCI double concealment = 0.5;
SCCI int alertnessRadius = basicStudentAlertnessRadius / 2;
SCCI int viewRange = basicStudentViewRange * 9 / 10;
SCCI int alertnessRadius = basicStudentAlertnessRadius * 2 / 3;
SCCI int viewRange = basicStudentViewRange * 8 / 10;
SCCI int speedOfOpeningOrLocking = basicSpeedOfOpeningOrLocking;
SCCI int speedOfClimbingThroughWindows = basicStudentSpeedOfClimbingThroughWindows / 2;
SCCI int speedOfClimbingThroughWindows = (int)(basicStudentSpeedOfClimbingThroughWindows * 1000 / 1222);
SCCI int speedOfOpenChest = basicSpeedOfOpenChest;
};

struct StraightAStudent
{
SCCI int moveSpeed = basicStudentSpeed * 96 / 100;
SCCI int moveSpeed = basicStudentSpeed * 24 / 25;
SCCI int maxHp = basicHp * 11 / 10;
SCCI int maxAddiction = basicMaxGamingAddiction * 13 / 10;
SCCI int fixSpeed = basicFixSpeed * 11 / 10;
@@ -165,41 +165,41 @@ namespace Constants

struct Robot
{
SCCI int moveSpeed = basicStudentSpeed;
SCCI int maxHp = basicHp * 0.4;
SCCI int moveSpeed = basicStudentSpeed * 9 / 10;
SCCI int maxHp = basicHp * 0.3;
SCCI int maxAddiction = basicMaxGamingAddiction * 0;
SCCI int fixSpeed = basicFixSpeed;
SCCI int fixSpeed = (int)(basicFixSpeed * 0.7);
SCCI int encourageSpeed = 0;
SCCI double concealment = 1;
SCCI int alertnessRadius = basicStudentAlertnessRadius * 1;
SCCI int viewRange = basicStudentViewRange;
SCCI int speedOfOpeningOrLocking = basicSpeedOfOpeningOrLocking;
SCCI double concealment = 0.8;
SCCI int alertnessRadius = 0;
SCCI int viewRange = 0;
SCCI int speedOfOpeningOrLocking = 0;
SCCI int speedOfClimbingThroughWindows = 1;
SCCI int speedOfOpenChest = basicSpeedOfOpenChest;
SCCI int speedOfOpenChest = basicSpeedOfOpenChest * 4 / 5;
};

struct TechOtaku
{
SCCI int moveSpeed = basicStudentSpeed * 3 / 4;
SCCI int moveSpeed = (int)(basicStudentSpeed * 0.96);
SCCI int maxHp = basicHp * 9 / 10;
SCCI int maxAddiction = basicMaxGamingAddiction * 11 / 10;
SCCI int fixSpeed = basicFixSpeed * 11 / 10;
SCCI int encourageSpeed = basicEncourageSpeed * 9 / 10;
SCCI double concealment = 1;
SCCI int maxAddiction = basicMaxGamingAddiction;
SCCI int fixSpeed = (int)(basicFixSpeed * 0.9);
SCCI int encourageSpeed = basicEncourageSpeed;
SCCI double concealment = 1.1;
SCCI int alertnessRadius = basicStudentAlertnessRadius;
SCCI int viewRange = basicStudentViewRange * 9 / 10;
SCCI int speedOfOpeningOrLocking = basicSpeedOfOpeningOrLocking;
SCCI int speedOfClimbingThroughWindows = basicStudentSpeedOfClimbingThroughWindows * 3 / 4;
SCCI int speedOfOpenChest = basicSpeedOfOpenChest;
SCCI int speedOfClimbingThroughWindows = (int)(basicStudentSpeedOfClimbingThroughWindows * 0.9);
SCCI int speedOfOpenChest = basicSpeedOfOpenChest * 22 / 25;
};

struct Sunshine
{
SCCI int moveSpeed = basicStudentSpeed;
SCCI int maxHp = basicHp * 32 / 30;
SCCI int maxHp = basicHp * 16 / 15;
SCCI int maxAddiction = basicMaxGamingAddiction * 11 / 10;
SCCI int fixSpeed = basicFixSpeed;
SCCI int encourageSpeed = basicEncourageSpeed * 12 / 10;
SCCI int encourageSpeed = basicEncourageSpeed * 6 / 5;
SCCI double concealment = 1;
SCCI int alertnessRadius = basicStudentAlertnessRadius;
SCCI int viewRange = basicStudentViewRange;
@@ -244,7 +244,19 @@ namespace Constants

struct Punish
{
SCCI int skillCD = commonSkillCD * 1;
SCCI int skillCD = commonSkillCD * 3 / 2;
SCCI int durationTime = commonSkillTime * 0;
};

struct SparksNSplash
{
SCCI int skillCD = commonSkillCD * 3 / 2;
SCCI int durationTime = commonSkillTime * 1;
};

struct HaveTea
{
SCCI int skillCD = commonSkillCD * 3;
SCCI int durationTime = commonSkillTime * 0;
};

@@ -292,7 +304,7 @@ namespace Constants

struct UseRobot
{
SCCI int skillCD = commonSkillCD / 300;
SCCI int skillCD = commonSkillCD / 15;
SCCI int durationTime = commonSkillTime * 0;
};

@@ -304,8 +316,8 @@ namespace Constants

struct SummonGolem
{
SCCI int skillCD = commonSkillCD * 1;
SCCI int durationTime = commonSkillTime * 0;
SCCI int skillCD = commonSkillCD * 4 / 3;
SCCI int durationTime = commonSkillTime * 6;
};

struct CommonAttackOfTricker
@@ -331,10 +343,10 @@ namespace Constants
SCCI int Speed = basicBulletMoveSpeed * 25 / 10;
SCCI bool IsRemoteAttack = true;

SCCI int CastTime = basicCastTime * 4 / 5;
SCCI int CastTime = basicCastTime * 6 / 5;
SCCI int Backswing = 0;
SCCI int RecoveryFromHit = 0;
SCCI int cd = basicBackswing / 2;
SCCI int cd = basicBackswing * 3 / 4;
SCCI int maxBulletNum = 1;
};

@@ -347,7 +359,7 @@ namespace Constants
SCCI bool IsRemoteAttack = false;

SCCI int CastTime = (int)BulletAttackRange * 1000 / Speed;
SCCI int Backswing = basicRecoveryFromHit;
SCCI int Backswing = basicBackswing * 3 / 2;
SCCI int RecoveryFromHit = basicRecoveryFromHit;
SCCI int cd = basicCD;
SCCI int maxBulletNum = 1;
@@ -356,10 +368,25 @@ namespace Constants
struct JumpyDumpty
{
SCCI double BulletBombRange = basicBulletBombRange / 2;
SCCI double BulletAttackRange = basicRemoteAttackRange * 2;
SCCI double BulletAttackRange = basicAttackShortRange * 16 / 22;
SCCI int ap = (int)(basicApOfTricker * 0.6);
SCCI int Speed = basicBulletMoveSpeed * 43 / 37;
SCCI bool IsRemoteAttack = false;
};

struct Strike
{
SCCI double BulletBombRange = 0;
SCCI double BulletAttackRange = basicAttackShortRange;
SCCI int ap = basicApOfTricker * 16 / 15;
SCCI int Speed = basicBulletMoveSpeed * 125 / 148;
SCCI bool IsRemoteAttack = false;

SCCI int CastTime = basicCastTime * 16 / 25;
SCCI int Backswing = basicBackswing;
SCCI int RecoveryFromHit = basicRecoveryFromHit;
SCCI int cd = basicBackswing;
SCCI int maxBulletNum = 1;
};
} // namespace Constants
#endif

+ 66
- 45
CAPI/python/PyAPI/constants.py View File

@@ -27,10 +27,10 @@ class Constants(NoInstance):
# 人物属性相关
basicEncourageSpeed = 100
basicLearnSpeed = 123
basicSpeedOfOpeningOrLocking = 4000
basicSpeedOfOpeningOrLocking = 5000
basicStudentSpeedOfClimbingThroughWindows = 1222
basicTrickerSpeedOfClimbingThroughWindows = 2540
basicSpeedOfOpenChest = 1000
basicSpeedOfOpenChest = 1250

basicHp = 3000000
basicMaxGamingAddiction = 60000
@@ -65,8 +65,8 @@ class Constants(NoInstance):

# 道具相关

apPropAdd = basicApOfTricker * 12 / 10
apSpearAdd = basicApOfTricker * 6 / 10
apPropAdd = basicApOfTricker * 12 // 10
apSpearAdd = basicApOfTricker * 6 // 10

# 技能相关
maxNumOfSkill = 3
@@ -85,7 +85,7 @@ class Constants(NoInstance):

addedTimeOfSpeedWhenInspire = 1.6
timeOfAddingSpeedWhenInspire = 6000
addHpWhenEncourage = basicHp / 4
addHpWhenEncourage = basicHp // 4

checkIntervalWhenShowTime = 200
addAddictionPer100msWhenShowTime = 300
@@ -159,14 +159,14 @@ class Teacher:
moveSpeed = (int)(0.9 * Constants.basicStudentSpeed)
maxHp = (int)(10.0 * Constants.basicHp)
maxAddiction = (int)(10.0 * Constants.basicMaxGamingAddiction)
LearnSpeed = (int)(0.0 * Constants.basicLearnSpeed)
LearnSpeed = (int)( Constants.basicLearnSpeed* 50//123)
EncourageSpeed = (int)(0.8 * Constants.basicEncourageSpeed)
concealment = 0.5 * Constants.basicConcealment
alertnessRadius = (int)(0.5 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.9 * Constants.basicStudentViewRange)
alertnessRadius = (int)(Constants.basicStudentAlertnessRadius * 2 // 3)
viewRange = (int)(0.8 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)(
0.5 * Constants.basicStudentSpeedOfClimbingThroughWindows
Constants.basicStudentSpeedOfClimbingThroughWindows* 1000 // 1222
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)

@@ -188,35 +188,33 @@ class StraightAStudent:


class Robot:
moveSpeed = (int)(1.0 * Constants.basicStudentSpeed)
maxHp = (int)(0.4 * Constants.basicHp)
moveSpeed = (int)(0.9 * Constants.basicStudentSpeed)
maxHp = (int)(0.3 * Constants.basicHp)
maxAddiction = (int)(0.0 * Constants.basicMaxGamingAddiction)
LearnSpeed = (int)(1.0 * Constants.basicLearnSpeed)
LearnSpeed = (int)(0.7 * Constants.basicLearnSpeed)
EncourageSpeed = 0
concealment = 1.0 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(1.0 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)(
0.0016 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)
concealment = 0.8 * Constants.basicConcealment
alertnessRadius = (int)(0.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.0 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(0.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = 1
speedOfOpenChest = (int)(0.8 * Constants.basicSpeedOfOpenChest)


class TechOtaku:
moveSpeed = (int)(0.75 * Constants.basicStudentSpeed)
moveSpeed = (int)(0.96 * Constants.basicStudentSpeed)
maxHp = (int)(0.9 * Constants.basicHp)
maxAddiction = (int)(1.1 * Constants.basicMaxGamingAddiction)
LearnSpeed = (int)(1.1 * Constants.basicLearnSpeed)
EncourageSpeed = (int)(0.9 * Constants.basicEncourageSpeed)
concealment = 1.0 * Constants.basicConcealment
maxAddiction = (int)(1.0 * Constants.basicMaxGamingAddiction)
LearnSpeed = (int)(0.9 * Constants.basicLearnSpeed)
EncourageSpeed = (int)(1.0 * Constants.basicEncourageSpeed)
concealment = 1.1 * Constants.basicConcealment
alertnessRadius = (int)(1.0 * Constants.basicStudentAlertnessRadius)
viewRange = (int)(0.9 * Constants.basicStudentViewRange)
speedOfOpeningOrLocking = (int)(1.0 * Constants.basicSpeedOfOpeningOrLocking)
speedOfClimbingThroughWindows = (int)(
0.75 * Constants.basicStudentSpeedOfClimbingThroughWindows
0.9 * Constants.basicStudentSpeedOfClimbingThroughWindows
)
speedOfOpenChest = (int)(1.0 * Constants.basicSpeedOfOpenChest)
speedOfOpenChest = (int)(0.88 * Constants.basicSpeedOfOpenChest)


class Sunshine:
@@ -241,12 +239,22 @@ class CanBeginToCharge:


class BecomeInvisible:
skillCD = (int)(4 * Constants.commonSkillCD / 3)
skillCD = (int)(4 * Constants.commonSkillCD // 3)
durationTime = (int)(Constants.commonSkillTime)


class Punish:
skillCD = (int)(1.0 * Constants.commonSkillCD)
skillCD = (int)(1.5 * Constants.commonSkillCD)
durationTime = (int)(0.0 * Constants.commonSkillTime)


class SparksNSplash:
skillCD = (int)(1.5 * Constants.commonSkillCD)
durationTime = (int)(1.0 * Constants.commonSkillTime)


class HaveTea:
skillCD = (int)(3 * Constants.commonSkillCD)
durationTime = (int)(0.0 * Constants.commonSkillTime)


@@ -271,7 +279,7 @@ class Howl:


class ShowTime:
skillCD = (int)(8 * Constants.commonSkillCD / 3)
skillCD = (int)(8 * Constants.commonSkillCD // 3)
durationTime = (int)(1.0 * Constants.commonSkillTime)


@@ -286,7 +294,7 @@ class UseKnife:


class UseRobot:
skillCD = (int)(0.0017 * Constants.commonSkillCD)
skillCD = (int)(2 * Constants.commonSkillCD // 30)
durationTime = (int)(0.0 * Constants.commonSkillTime)


@@ -296,8 +304,8 @@ class WriteAnswers:


class SummonGolem:
skillCD = (int)(1.0 * Constants.commonSkillCD)
durationTime = (int)(0.0 * Constants.commonSkillTime)
skillCD = (int)(Constants.commonSkillCD * 4 // 3)
durationTime = (int)(6.0 * Constants.commonSkillTime)


class CommonAttackOfTricker:
@@ -306,7 +314,7 @@ class CommonAttackOfTricker:
ap = Constants.basicApOfTricker
Speed = Constants.basicBulletMoveSpeed
IsRemoteAttack = False
CastTime = BulletAttackRange * 1000 / Speed
CastTime = BulletAttackRange * 1000 // Speed
Backswing = Constants.basicBackswing
RecoveryFromHit = Constants.basicRecoveryFromHit
cd = Constants.basicBackswing
@@ -316,32 +324,45 @@ class CommonAttackOfTricker:
class FlyingKnife:
BulletBombRange = 0
BulletAttackRange = Constants.basicRemoteAttackRange * 13
ap = Constants.basicApOfTricker * 4 / 5
Speed = Constants.basicBulletMoveSpeed * 25 / 10
ap = Constants.basicApOfTricker * 4 // 5
Speed = Constants.basicBulletMoveSpeed * 25 // 10
IsRemoteAttack = True
CastTime = Constants.basicCastTime * 4 / 5
CastTime = Constants.basicCastTime * 6 // 5
Backswing = 0
RecoveryFromHit = 0
cd = Constants.basicBackswing / 2
cd = Constants.basicBackswing * 3 // 4
maxBulletNum = 1


class BombBomb:
BulletBombRange = Constants.basicBulletBombRange
BulletAttackRange = Constants.basicAttackShortRange
ap = Constants.basicApOfTricker * 6 / 5
Speed = Constants.basicBulletMoveSpeed * 30 / 37
ap = Constants.basicApOfTricker * 6 // 5
Speed = Constants.basicBulletMoveSpeed * 30 // 37
IsRemoteAttack = False
CastTime = BulletAttackRange * 1000 / Speed
Backswing = Constants.basicRecoveryFromHit
CastTime = BulletAttackRange * 1000 // Speed
Backswing = Constants.basicBackswing * 3 // 2
RecoveryFromHit = Constants.basicRecoveryFromHit
cd = Constants.basicCD
maxBulletNum = 1


class JumpyDumpty:
BulletBombRange = Constants.basicBulletBombRange / 2
BulletAttackRange = Constants.basicRemoteAttackRange * 2
BulletBombRange = Constants.basicBulletBombRange // 2
BulletAttackRange = Constants.basicAttackShortRange * 16 / 22
ap = (int)(Constants.basicApOfTricker * 0.6)
Speed = Constants.basicBulletMoveSpeed * 43 / 37
Speed = Constants.basicBulletMoveSpeed * 43 // 37
IsRemoteAttack = False


class Strike:
BulletBombRange = 0
BulletAttackRange = Constants.basicAttackShortRange
ap = Constants.basicApOfTricker * 16 // 5
Speed = Constants.basicBulletMoveSpeed * 125 // 148
IsRemoteAttack = False
CastTime = Constants.basicCastTime * 16 // 25
Backswing = Constants.basicBackswing
RecoveryFromHit = Constants.basicRecoveryFromHit
cd = Constants.basicBackswing
maxBulletNum = 1

+ 2
- 2
docs/使用文档.md View File

@@ -147,8 +147,8 @@ start python .\CAPI\python\PyAPI\main.py -I 127.0.0.1 -P 8888 -p 0 -d -o -w
| 1 | Athlete |
| 2 | Teacher |
| 3 | StraightAStudent |
| 4 | Robot(目前未实现所有功能) |
| 5 | TechOtaku(目前未实现所有功能) |
| 4 | Robot |
| 5 | TechOtaku |
| 6 | Sunshine |

* 捣蛋鬼


+ 6
- 6
docs/游戏机制与平衡性调整更新草案.md View File

@@ -22,6 +22,7 @@ v1.6
- 增强为“可以攻击未写完的作业”
- 增强为“可以攻击使门被打开(可以重新被锁上)”
- 小炸弹JumpyDumpty
- 攻击距离改为1600
- 小炸弹不受道具增益影响
- 修改为“小炸弹与自己无碰撞体积”
- strike(新增)
@@ -31,7 +32,7 @@ v1.6
| 攻击(子弹)类型 |搞蛋鬼的一般攻击CommonAttackOfTricker|飞刀FlyingKnife | 蹦蹦炸弹BombBomb | 小炸弹JumpyDumpty | strike |
| :--------------------- | :---------------------| :--------------------- | :--------------------- | :--------------------- | :--------------------- |
| 子弹爆炸范围 | 0 | 0 | 2000 | 1000 | 0 |
| 子弹攻击距离 | 2200 | 78000 | 2200 | 4400 | 2000 |
| 子弹攻击距离 | 2200 | 78000 | 2200 | 1600 | 2000 |
| 攻击力 | 1500000 | 1200000 | 1800000 | 900000 | 1600000 |
| 移动速度/s | 7400 | 18500 | 6000 | 8600 | 6250 |
| 前摇(ms) | 297 | 600 | 366 | - | 320 |
@@ -51,7 +52,6 @@ v1.6
- Teacher
- 学习速度由0改为50
- 警戒范围由7500改为10000
- 视野范围由9000降为8000
- 翻窗速度改为1000
- 特质:
- 扣血则得分100×受到伤害/基本伤害(1500000)
@@ -60,7 +60,7 @@ v1.6
- “使用瞬间,在**视野距离/3范围内(不是可视范围)的**翻窗、开锁门、攻击前后摇、**使用技能期间**的捣蛋鬼会被眩晕(3070+**500***已受伤害/基本伤害(1500000))ms”
- 技能喝茶(HaveTea)(新增)
- CD:90s
- 在有队友受过伤的情况下,使用瞬间,向当前方向瞬移3000(可以穿墙),如果会碰撞则失败。
- 使用瞬间,向额外参数/1000.0的角度瞬移3000(可以穿墙),如果会碰撞则失败。
- Robot(新增)
- 无技能
- 特性
@@ -71,14 +71,14 @@ v1.6
- 不可使用道具(可以捡起和扔道具)
- TechOtaku(新增)
- 一名TechOtaku最多可以在场上同时最多拥有3个Robot,无法共享视野
0. SummonGolem
1. SummonGolem
- CD:40s,持续时间:6s
- 在持续时间中,学生进入人物状态进入UsingSpecialSkill(不能移动),进入其他状态会导致制作机器人失败。
- 在持续时间中,学生面前生成道具CraftingBench;学生进入其他状态或该道具被碰撞后,CraftingBench消失且制作机器人失败。
- 持续时间结束后,道具CraftingBench所在位置生成一个Robot,CraftingBench消失
- TechOtaku的Robot的PlayerId = TechOtaku的PlayerId + n×5(一局游戏理论人数),其中1<=n<=3(自己的n为0)
- 新造的Robot的PlayerId的n总是尽量小
1. UseRobot
2. UseRobot
- CD:2s,持续时间:0s
- 输入额外参数PlayerID,切换到要使用的角色。
- 切换到其他角色时,自己进入UsingSkill状态。
@@ -94,7 +94,7 @@ v1.6
| 勉励速度/ms | 80 | 90 | 100 | 120 | 0 | 100 |
| 隐蔽度 | 0.5 | 0.9 | 0.9 | 0.8 | 0.8 | 1.1 |
| 警戒范围 | 10000 | 15000 | 13500 | 15000 | 0 | 15000 |
| 视野范围 | 8000 | 11000 | 9000 | 10000 | 0 | 9000 |
| 视野范围 | 9000 | 11000 | 9000 | 10000 | 0 | 9000 |
| 开锁门速度/ms | 5000 | 5000 | 5000 | 3500 | 0 | 5000 |
| 翻窗速度/ms | 1000 | 1466 | 1018 | 1222 | 1 | 1100 |
| 翻箱速度/ms | 1250 | 1250 | 1250 | 1125 | 1000 | 1100 |


+ 5
- 0
docs/版本更新说明.md View File

@@ -44,5 +44,10 @@
- fix:修复了InSpire会给Tricker加速的问题
- fix:修复了开锁门的bug

# 5月19日15:00更新
- docs:更新了 游戏机制与平衡性调整更新草案.pdf
- hotfix:修复了移动状态设置错误

# 最新更新
- feat:Assassin、Teacher已调整
- docs:更新了 游戏机制与平衡性调整更新草案.pdf

+ 1
- 1
logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs View File

@@ -165,7 +165,7 @@ namespace GameClass.GameObj
ap = (int)(GameData.basicApOfGhost * 0.6);
}
public override double BulletBombRange => GameData.basicBulletBombRange / 2;
public override double AttackDistance => GameData.basicAttackShortRange * 2;
public override double AttackDistance => GameData.basicAttackShortRange * 16 / 22;

public override int Speed => (int)(GameData.basicBulletMoveSpeed * 43 / 37);
public override bool IsRemoteAttack => false;


+ 2
- 2
logic/GameClass/GameObj/Bullet/Bullet.cs View File

@@ -14,7 +14,7 @@ namespace GameClass.GameObj
protected int ap;
public int AP
{
get => Interlocked.CompareExchange(ref ap, 0, 1);
get => Interlocked.CompareExchange(ref ap, 0, 0);
}
public void AddAP(int addAp)
{
@@ -52,7 +52,7 @@ namespace GameClass.GameObj
public Bullet(Character player, int radius, XY Position) :
base(Position, radius, GameObjType.Bullet)
{
this.canMove = true;
this.ReSetCanMove(true);
this.MoveSpeed = this.Speed;
this.hasSpear = player.TryUseSpear();
this.Parent = player;


+ 1
- 1
logic/GameClass/GameObj/Character/Character.Skill.cs View File

@@ -50,7 +50,7 @@ namespace GameClass.GameObj
protected Character(XY initPos, int initRadius, CharacterType characterType) :
base(initPos, initRadius, GameObjType.Character)
{
this.canMove = true;
this.ReSetCanMove(true);
this.score = 0;
this.buffManager = new BuffManager();
this.occupation = OccupationFactory.FindIOccupation(characterType);


+ 34
- 29
logic/GameClass/GameObj/Character/Character.cs View File

@@ -362,8 +362,7 @@ namespace GameClass.GameObj
lock (actionLock)
{
if (playerState == PlayerStateType.Moving)
if (IsMoving == 1) return PlayerStateType.Moving;
else return PlayerStateType.Null;
return (IsMoving) ? PlayerStateType.Moving : PlayerStateType.Null;
return playerState;
}
}
@@ -540,27 +539,41 @@ namespace GameClass.GameObj
ThreadNum.Release();
}
case PlayerStateType.UsingSkill:
if (CharacterType == CharacterType.TechOtaku)
{
if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith))
switch (CharacterType)
{
try
{
((CraftingBench)whatInteractingWith!).StopSkill();
case CharacterType.TechOtaku:
{
if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith))
{
try
{
((CraftingBench)whatInteractingWith!).StopSkill();
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
else
{
if (value != PlayerStateType.UsingSkill)
((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID;
return ChangePlayerState(value, gameObj);
}
}
case CharacterType.Assassin:
if (value == PlayerStateType.Moving) return StateNum;
else
{
TryDeleteInvisible();
return ChangePlayerState(value, gameObj);
}
default:
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
else
{
if (value != PlayerStateType.UsingSkill)
((UseRobot)FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID = (int)playerID;
}
}
return ChangePlayerState(value, gameObj);
default:
return ChangePlayerState(value, gameObj);
}
@@ -581,17 +594,9 @@ namespace GameClass.GameObj
{
lock (actionLock)
{
MoveReaderWriterLock.EnterWriteLock();
try
{
canMove = false;
isRemoved = true;
}
finally
{
MoveReaderWriterLock.ExitWriteLock();
}
playerState = playerStateType;
TryToRemove();
ReSetCanMove(false);
SetPlayerState(playerStateType);
position = GameData.PosWhoDie;
}
}


+ 4
- 21
logic/GameClass/GameObj/GameObj.cs View File

@@ -29,40 +29,23 @@ namespace GameClass.GameObj
protected XY facingDirection = new(1, 0);
public abstract XY FacingDirection { get; }

protected bool canMove;
public abstract bool CanMove { get; }

public abstract bool IsRigid { get; }

public abstract ShapeType Shape { get; }

protected bool isRemoved = false;
public virtual bool IsRemoved
protected int isRemoved = 0;
public bool IsRemoved
{
get
{
gameObjReaderWriterLock.EnterReadLock();
try
{
return isRemoved;
}
finally
{
gameObjReaderWriterLock.ExitReadLock();
}
return (Interlocked.CompareExchange(ref isRemoved, 0, 0) == 1);
}
}
public virtual void TryToRemove()
{
gameObjReaderWriterLock.EnterWriteLock();
try
{
isRemoved = true;
}
finally
{
gameObjReaderWriterLock.ExitWriteLock();
}
Interlocked.Exchange(ref isRemoved, 1);
}

public int Radius { get; }


+ 9
- 59
logic/GameClass/GameObj/Moveable.cs View File

@@ -48,10 +48,10 @@ namespace GameClass.GameObj
}

private int isMoving = 0;
public int IsMoving
public bool IsMoving
{
get => Interlocked.CompareExchange(ref isMoving, 0, 1);
set => Interlocked.Exchange(ref isMoving, value);
get => (Interlocked.CompareExchange(ref isMoving, 0, 0) == 1);
set => Interlocked.Exchange(ref isMoving, value ? 1 : 0);
}

// 移动,改变坐标
@@ -62,15 +62,7 @@ namespace GameClass.GameObj
{
lock (actionLock)
{
moveReaderWriterLock.EnterReadLock();
try
{
if (!canMove || isRemoved) return -1;
}
finally
{
moveReaderWriterLock.ExitReadLock();
}
if (!CanMove || IsRemoved) return -1;
if (stateNo != stateNum) return -1;
facingDirection = moveVec;
this.position += moveVec;
@@ -87,49 +79,15 @@ namespace GameClass.GameObj
}
}

private int canMove;
public override bool CanMove
{
get
{
moveReaderWriterLock.EnterReadLock();
try
{
return canMove;
}
finally
{
moveReaderWriterLock.ExitReadLock();
}
}
get => (Interlocked.CompareExchange(ref canMove, 0, 0) == 1);
}

public void ReSetCanMove(bool value)
{
moveReaderWriterLock.EnterWriteLock();
try
{
canMove = value;
}
finally
{
moveReaderWriterLock.ExitWriteLock();
}
}

public override bool IsRemoved
{
get
{
moveReaderWriterLock.EnterReadLock();
try
{
return isRemoved;
}
finally
{
moveReaderWriterLock.ExitReadLock();
}
}
Interlocked.Exchange(ref canMove, (value ? 1 : 0));
}

public bool IsAvailableForMove // 是否能接收移动指令
@@ -138,15 +96,7 @@ namespace GameClass.GameObj
{
lock (actionLock)
{
moveReaderWriterLock.EnterReadLock();
try
{
return isMoving == 0 && canMove && !isRemoved;
}
finally
{
moveReaderWriterLock.ExitReadLock();
}
return !IsMoving && CanMove && !IsRemoved;
}
}
}
@@ -157,7 +107,7 @@ namespace GameClass.GameObj
/// </summary>
public int MoveSpeed
{
get => Interlocked.CompareExchange(ref moveSpeed, 0, 1);
get => Interlocked.CompareExchange(ref moveSpeed, 0, 0);
set => Interlocked.Exchange(ref moveSpeed, value);
}
/// <summary>


+ 1
- 1
logic/GameClass/GameObj/Prop/Gadget.cs View File

@@ -24,7 +24,7 @@ namespace GameClass.GameObj
public Gadget(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Gadget)
{
this.canMove = false;
this.ReSetCanMove(false);
this.MoveSpeed = GameData.propMoveSpeed;
}
}


+ 1
- 1
logic/GameClass/GameObj/Prop/Item.cs View File

@@ -17,7 +17,7 @@ namespace GameClass.GameObj
public Item(XY initPos, int radius = GameData.propRadius) :
base(initPos, radius, GameObjType.Item)
{
this.canMove = false;
this.ReSetCanMove(false);
this.MoveSpeed = 0;
}
}


+ 4
- 4
logic/GameEngine/MoveEngine.cs View File

@@ -102,7 +102,7 @@ namespace GameEngine
lock (obj.ActionLock)
{
if (!obj.IsAvailableForMove) { EndMove(obj); return; }
obj.IsMoving = 1;
obj.IsMoving = true;
}

new Thread
@@ -139,7 +139,7 @@ namespace GameEngine

if (isEnded)
{
obj.IsMoving = 0;
obj.IsMoving = false;
EndMove(obj);
return;
}
@@ -184,7 +184,7 @@ namespace GameEngine
}
if (isEnded)
{
obj.IsMoving = 0;
obj.IsMoving = false;
EndMove(obj);
return;
}
@@ -224,7 +224,7 @@ namespace GameEngine
}
} while (flag);
}
obj.IsMoving = 0; // 结束移动
obj.IsMoving = false; // 结束移动
EndMove(obj);
}
}


+ 55
- 9
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -13,7 +13,6 @@ namespace Gaming
{
public static bool CanBeginToCharge(Character player)
{

if ((!player.Commandable())) return false;
ActiveSkill skill = player.FindActiveSkill(ActiveSkillType.CanBeginToCharge);
Debugger.Output(player, "can begin to charge!");
@@ -93,19 +92,32 @@ namespace Gaming

public static bool BecomeInvisible(Character player)
{
if ((!player.Commandable())) return false;
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.BecomeInvisible);
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
if (stateNum == -1)
{
return false;
}
return ActiveSkillEffect(activeSkill, player, () =>
{
player.AddScore(GameData.ScoreBecomeInvisible);
player.AddInvisible(activeSkill.DurationTime);
Debugger.Output(player, "become invisible!");
},
() =>
{ });
() =>
{
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
player.SetPlayerStateNaturally();
}
}
}
);
}

public bool UseRobot(Character player, int robotID)
public static bool UseRobot(Character player, int robotID)
{
if ((robotID - player.PlayerID) % GameData.numOfPeople != 0) return false;
if ((robotID - (int)player.PlayerID) / GameData.numOfPeople < 0 || (robotID - (int)player.PlayerID) / GameData.numOfPeople > GameData.maxSummonedGolemNum) return false;
@@ -261,8 +273,7 @@ namespace Gaming
}
craftingBench.ParentStateNum = stateNum;
gameMap.Add(craftingBench);
/*
*/

return ActiveSkillEffect(activeSkill, player, () =>
{
},
@@ -343,8 +354,8 @@ namespace Gaming
|| character.PlayerState == PlayerStateType.ClimbingThroughWindows)
&& XY.DistanceFloor3(character.Position, player.Position) <= player.ViewRange / 3)
{
if (CharacterManager.BeStunned(character, GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP)) > 0)
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP)));
if (CharacterManager.BeStunned(character, GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP) / GameData.basicApOfGhost) > 0)
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenPunish + GameData.factorOfTimeStunnedWhenPunish * (player.MaxHp - player.HP) / GameData.basicApOfGhost));
break;
}
}
@@ -359,6 +370,41 @@ namespace Gaming
{ });
}

public bool HaveTea(Character player, int angle1000)
{
long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill);
if (stateNum == -1)
{
return false;
}
player.ThreadNum.WaitOne();

XY res = player.Position + new XY(angle1000 / 1000.0, GameData.distanceOfHaveTea);
Debugger.Output(res.ToString());
if (actionManager.moveEngine.CheckCollision(player, res) != null)
{
player.ThreadNum.Release();
return false;
}
Debugger.Output("NO Collision!");
player.ReSetPos(res);
lock (player.ActionLock)
{
if (player.StateNum == stateNum)
{
player.SetPlayerStateNaturally();
}
}
player.ThreadNum.Release();

return ActiveSkillEffect(player.FindActiveSkill(ActiveSkillType.HaveTea), player, () =>
{
Debugger.Output(player, "have tea!");
},
() =>
{ });
}

public bool Rouse(Character player)
{
if ((!player.Commandable())) return false;


+ 2
- 0
logic/Gaming/SkillManager/SkillManager.cs View File

@@ -30,6 +30,8 @@ namespace Gaming
return Encourage(character);
case ActiveSkillType.Punish:
return Punish(character);
case ActiveSkillType.HaveTea:
return HaveTea(character, parameter);
case ActiveSkillType.JumpyBomb:
return JumpyBomb(character);
case ActiveSkillType.SparksNSplash:


+ 1
- 1
logic/Preparation/Interface/IMoveable.cs View File

@@ -8,7 +8,7 @@ namespace Preparation.Interface
{
object ActionLock { get; }
public int MoveSpeed { get; }
public int IsMoving { get; set; }
public bool IsMoving { get; set; }
public bool IsRemoved { get; }
public bool IsAvailableForMove { get; }
public long StateNum { get; }


+ 2
- 2
logic/Preparation/Interface/IOccupation.cs View File

@@ -166,7 +166,7 @@ namespace Preparation.Interface

public BulletType InitBullet => BulletType.Null;

public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Punish });
public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Punish, ActiveSkillType.HaveTea });
public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { });

public const int fixSpeed = 50;
@@ -181,7 +181,7 @@ namespace Preparation.Interface
public const int alertnessRadius = GameData.basicStudentAlertnessRadius * 2 / 3;
public int AlertnessRadius => alertnessRadius;

public int viewRange = GameData.basicStudentViewRange * 8 / 10;
public int viewRange = GameData.basicStudentViewRange * 9 / 10;
public int ViewRange => viewRange;

public int speedOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking;


+ 13
- 3
logic/Preparation/Interface/ISkill.cs View File

@@ -34,7 +34,7 @@ namespace Preparation.Interface
{
get
{
return Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1);
return Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 0);
}
set
{
@@ -47,7 +47,7 @@ namespace Preparation.Interface
public int isBeingUsed = 0;//实为bool
public int IsBeingUsed
{
get => Interlocked.CompareExchange(ref isBeingUsed, 0, 1);
get => Interlocked.CompareExchange(ref isBeingUsed, 0, 0);
set => Interlocked.Exchange(ref isBeingUsed, value);
}
}
@@ -70,6 +70,12 @@ namespace Preparation.Interface
public override int DurationTime => 0;
}

public class HaveTea : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD * 3;
public override int DurationTime => 0;
}

public class Rouse : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD * 4;
@@ -163,7 +169,7 @@ namespace Preparation.Interface
private int degreeOfMeditation = 0;
public int DegreeOfMeditation
{
get => Interlocked.CompareExchange(ref degreeOfMeditation, 0, 1);
get => Interlocked.CompareExchange(ref degreeOfMeditation, 0, 0);
set => Interlocked.Exchange(ref degreeOfMeditation, value);
}
}
@@ -245,6 +251,8 @@ namespace Preparation.Interface
return new CanBeginToCharge();
case ActiveSkillType.Punish:
return new Punish();
case ActiveSkillType.HaveTea:
return new HaveTea();
case ActiveSkillType.JumpyBomb:
return new JumpyBomb();
case ActiveSkillType.SparksNSplash:
@@ -284,6 +292,8 @@ namespace Preparation.Interface
return ActiveSkillType.Inspire;
case Punish:
return ActiveSkillType.Punish;
case HaveTea:
return ActiveSkillType.HaveTea;
case JumpyBomb:
return ActiveSkillType.JumpyBomb;
case SparksNSplash:


+ 3
- 2
logic/Preparation/Utility/GameData.cs View File

@@ -214,8 +214,9 @@ namespace Preparation.Utility
public const int timeOfStudentStunnedWhenCharge = 2090;

public const int timeOfGhostStunnedWhenPunish = 3070;
public const int factorOfTimeStunnedWhenPunish = 500 / basicApOfGhost;
public const int factorOfScoreWhenTeacherAttacked = 100;//每个
public const int factorOfTimeStunnedWhenPunish = 500;
public const int factorOfScoreWhenTeacherAttacked = 100;
public const int distanceOfHaveTea = 3000;

public const int timeOfGhostSwingingAfterHowl = 800;
public const int timeOfStudentStunnedWhenHowl = 5500;


Loading…
Cancel
Save