Browse Source

Merge pull request #192 from shangfengh/new

feat:  add the judgment of the end ofthe Game, and implement Skills "CanBeginToCharge" and "Punish" again
tags/0.1.0
Shawqeem GitHub 2 years ago
parent
commit
4e3f3ccafe
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 294 additions and 76 deletions
  1. +15
    -4
      logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
  2. +55
    -7
      logic/GameClass/GameObj/Character/Skill.cs
  3. +58
    -0
      logic/GameClass/GameObj/Map/Map.cs
  4. +9
    -1
      logic/GameClass/GameObj/Map/MapGameTimer.cs
  5. +10
    -0
      logic/Gaming/ActionManager.cs
  6. +13
    -7
      logic/Gaming/AttackManager.cs
  7. +7
    -44
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  8. +1
    -1
      logic/Preparation/Interface/IOccupation.cs
  9. +1
    -0
      logic/Preparation/Interface/ISkill.cs
  10. +1
    -1
      logic/Preparation/Interface/ITimer.cs
  11. +7
    -5
      logic/Preparation/Utility/GameData.cs
  12. +2
    -0
      logic/Server/CopyInfo.cs
  13. +115
    -6
      logic/规则Logic.md

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

@@ -37,8 +37,14 @@ namespace GameClass.GameObj
}
public override bool CanBeBombed(GameObjType gameObjType)
{
if (gameObjType == GameObjType.Character) return true;
return false;
switch (gameObjType)
{
case GameObjType.Character:
case GameObjType.Generator:
return true;
default:
return false;
}
}
public override BulletType TypeOfBullet => BulletType.CommonAttackOfGhost;

@@ -76,8 +82,13 @@ namespace GameClass.GameObj
}
public override bool CanBeBombed(GameObjType gameObjType)
{
if (gameObjType == GameObjType.Character) return true;
return false;
switch (gameObjType)
{
case GameObjType.Character:
return true;
default:
return false;
}
}

public override BulletType TypeOfBullet => BulletType.FlyingKnife;


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

@@ -5,61 +5,103 @@ namespace GameClass.GameObj
{
public class BecomeVampire : IActiveSkill // 化身吸血鬼
{
public int SkillCD => GameData.commonSkillCD / 3 * 4;
public int SkillCD => GameData.commonSkillCD * 4 / 3;
public int DurationTime => GameData.commonSkillTime;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}
public class CanBeginToCharge : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD / 5;
public int DurationTime => GameData.commonSkillTime / 10 * 6;
public int DurationTime => GameData.commonSkillTime * 6 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class BecomeInvisible : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 6;
public int DurationTime => GameData.commonSkillTime * 6 / 10;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class Punish : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 6;
public int DurationTime => 0;

private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class NuclearWeapon : IActiveSkill // 核武器
{
public int SkillCD => GameData.commonSkillCD / 3 * 7;
public int SkillCD => GameData.commonSkillCD * 7 / 3;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class UseKnife : IActiveSkill
{
public int SkillCD => GameData.commonSkillCD / 3 * 2;
public int SkillCD => GameData.commonSkillCD * 2 / 3;
public int DurationTime => GameData.commonSkillTime / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class SuperFast : IActiveSkill // 3倍速
{
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 4;
public int DurationTime => GameData.commonSkillTime * 4 / 10;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = value;
}
}

public class NullSkill : IActiveSkill
@@ -68,6 +110,12 @@ namespace GameClass.GameObj
public int DurationTime => GameData.commonSkillTime;
private readonly object commonSkillLock = new object();
public object ActiveSkillLock => commonSkillLock;

public bool isBeingUsed = false;
public bool IsBeingUsed
{
get => isBeingUsed; set => isBeingUsed = false;
}
}

public static class SkillFactory


+ 58
- 0
logic/GameClass/GameObj/Map/Map.cs View File

@@ -21,7 +21,9 @@ namespace GameClass.GameObj
set
{
lock (lockForNum)
{
numOfRepairedGenerators = value;
}
}
}
private uint numOfDeceasedStudent = 0;
@@ -31,7 +33,13 @@ namespace GameClass.GameObj
set
{
lock (lockForNum)
{
numOfDeceasedStudent = value;
if (numOfDeceasedStudent + numOfEscapedStudent == GameData.numOfStudent)
{
Timer.IsGaming = false;
}
}
}
}
private uint numOfEscapedStudent = 0;
@@ -41,7 +49,13 @@ namespace GameClass.GameObj
set
{
lock (lockForNum)
{
numOfEscapedStudent = value;
if (numOfDeceasedStudent + numOfEscapedStudent == GameData.numOfStudent)
{
Timer.IsGaming = false;
}
}
}
}

@@ -235,6 +249,50 @@ namespace GameClass.GameObj
}
return GameObjForInteract;
}
public bool CanSee(XY pos1, XY pos2, int viewRange)
{
XY del = pos1 - pos2;
if (del * del > viewRange * viewRange) return false;
if (del.x > del.y)
{
if (GetPlaceType(pos1) == PlaceType.Grass && GetPlaceType(pos2) == PlaceType.Grass)
{
for (int x = GameData.PosGridToCellX(pos1) + GameData.numOfPosGridPerCell; x < GameData.PosGridToCellX(pos2); x += GameData.numOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (x / del.x)) != PlaceType.Grass)
return false;
}
}
else
{
for (int x = GameData.PosGridToCellX(pos1) + GameData.numOfPosGridPerCell; x < GameData.PosGridToCellX(pos2); x += GameData.numOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (x / del.x)) == PlaceType.Wall)
return false;
}
}
}
else
{
if (GetPlaceType(pos1) == PlaceType.Grass && GetPlaceType(pos2) == PlaceType.Grass)
{
for (int y = GameData.PosGridToCellY(pos1) + GameData.numOfPosGridPerCell; y < GameData.PosGridToCellY(pos2); y += GameData.numOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (y / del.y)) != PlaceType.Grass)
return false;
}
}
else
{
for (int y = GameData.PosGridToCellY(pos1) + GameData.numOfPosGridPerCell; y < GameData.PosGridToCellY(pos2); y += GameData.numOfPosGridPerCell)
{
if (GetPlaceType(pos1 + del * (y / del.y)) == PlaceType.Wall)
return false;
}
}
}
return true;
}
public Map(uint[,] mapResource)
{
gameObjDict = new Dictionary<GameObjType, IList<IGameObj>>();


+ 9
- 1
logic/GameClass/GameObj/Map/MapGameTimer.cs View File

@@ -11,7 +11,15 @@ namespace GameClass.GameObj
public class GameTimer : ITimer
{
private bool isGaming = false;
public bool IsGaming => isGaming;
public bool IsGaming
{
get => isGaming;
set
{
lock (isGamingLock)
isGaming = value;
}
}

readonly object isGamingLock = new();



+ 10
- 0
logic/Gaming/ActionManager.cs View File

@@ -15,6 +15,15 @@ namespace Gaming
{

// 人物移动
private void SkillWhenMove(Character player, IGameObj collisionObj)
{
if (player.UseIActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost())
{
if (AttackManager.BeStunned((Character)collisionObj, GameData.TimeOfGhostFaintingWhenCharge))
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenCharge));
AttackManager.BeStunned(player, GameData.TimeOfStudentFaintingWhenCharge);
}
}
public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
{
if (!playerToMove.Commandable()) return false;
@@ -479,6 +488,7 @@ namespace Gaming
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
{
SkillWhenMove((Character)obj, collisionObj);
//if (collisionObj is Mine)
//{
// ActivateMine((Character)obj, (Mine)collisionObj);


+ 13
- 7
logic/Gaming/AttackManager.cs View File

@@ -71,8 +71,9 @@ namespace Gaming
{ IsBackground = true }.Start();
}

public static void BeStunned(Character player, int time)
public static bool BeStunned(Character player, int time)
{
if (player.PlayerState == PlayerStateType.Stunned || player.NoHp()) return false;
new Thread
(() =>
{
@@ -83,6 +84,7 @@ namespace Gaming
}
)
{ IsBackground = true }.Start();
return true;
}

private void Die(Character player)
@@ -134,20 +136,24 @@ namespace Gaming

if ((!(((Character)objBeingShot).IsGhost())) && bullet.Parent.IsGhost())
{
Student oneBeAttacked = (Student)objBeingShot;
if (oneBeAttacked.BeAttacked(bullet))
Student whoBeAttacked = (Student)objBeingShot;
if (whoBeAttacked.BeAttacked(bullet))
{
BeAddictedToGame(oneBeAttacked, (Ghost)bullet.Parent);
BeAddictedToGame(whoBeAttacked, (Ghost)bullet.Parent);
}
if (oneBeAttacked.CanBeAwed())
if (whoBeAttacked.CanBeAwed())
{
bullet.Parent.AddScore(GameData.TrickerScoreStudentBeStunned);
BeStunned(oneBeAttacked, GameData.basicStunnedTimeOfStudent);
if (BeStunned(whoBeAttacked, GameData.basicStunnedTimeOfStudent))
bullet.Parent.AddScore(GameData.TrickerScoreStudentBeStunned);
}
}
// if (((Character)objBeingShot).IsGhost() && !bullet.Parent.IsGhost() && bullet.TypeOfBullet == BulletType.Ram)
// BeStunned((Character)objBeingShot, bullet.AP);
break;
case GameObjType.Generator:
if (bullet.CanBeBombed(GameObjType.Generator))
((Generator)objBeingShot).DegreeOfRepair -= bullet.AP * GameData.factorDamageGenerator;
break;
default:
break;
}


+ 7
- 44
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -36,49 +36,10 @@ namespace Gaming
return ActiveSkillEffect(skill, player, () =>
{
player.AddMoveSpeed(skill.DurationTime, 3.0);
new Thread
(
() =>
{
new FrameRateTaskExecutor<int>(
loopCondition: () => player.Commandable() && gameMap.Timer.IsGaming,
loopToDo: () =>
{
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character character in gameMap.GameObjDict[GameObjType.Character])
{
if (character.IsGhost() != player.IsGhost() && Math.Max(XY.Distance(player.Position, character.Position), XY.Distance(player.Position + new XY(player.FacingDirection, player.Radius), character.Position)) <= character.Radius + player.Radius + GameData.tolerancesLength)
{
AttackManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenCharge);
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenCharge));
AttackManager.BeStunned(player, GameData.TimeOfStudentFaintingWhenCharge);
break;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}
},
timeInterval: GameData.frameDuration,
finallyReturn: () => 0,
maxTotalDuration: skill.DurationTime
)

.Start();
}

)
{ IsBackground = true }.Start();
//See SkillWhenMove in ActionManager
},
() =>
{
double tempVam = player.Vampire - 0.5;
player.Vampire = tempVam < player.OriVampire ? player.OriVampire : tempVam;
});
{ });
}


@@ -125,10 +86,10 @@ namespace Gaming
{
foreach (Character character in gameMap.GameObjDict[GameObjType.Character])
{
if (player.IsGhost() && XY.Distance(player.Position, character.Position) <= player.ViewRange)
if (player.IsGhost() && gameMap.CanSee(player.Position, character.Position, player.ViewRange))
{
AttackManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.TimeFactorOfGhostFainting);
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.TimeFactorOfGhostFainting));
if (AttackManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.TimeFactorOfGhostFainting))
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenPunish + (player.MaxHp - player.HP) / GameData.TimeFactorOfGhostFainting));
break;
}
}
@@ -167,6 +128,7 @@ namespace Gaming
(() =>
{
startSkill();
activeSkill.IsBeingUsed = true;
new FrameRateTaskExecutor<int>(
() => !player.IsResetting,
() =>
@@ -184,6 +146,7 @@ namespace Gaming
.Start();

endSkill();
activeSkill.IsBeingUsed = false;
Debugger.Output(player, "return to normal.");

new FrameRateTaskExecutor<int>(


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

@@ -97,7 +97,7 @@ namespace Preparation.Interface
public int timeOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking;
public int TimeOfOpeningOrLocking => timeOfOpeningOrLocking;

public int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows * 9 / 10;
public int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows / 2;
public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows;

public int timeOfOpenChest = GameData.basicSpeedOfOpenChest;


+ 1
- 0
logic/Preparation/Interface/ISkill.cs View File

@@ -11,5 +11,6 @@
public int SkillCD { get; }
public int DurationTime { get; } //技能持续时间
public object ActiveSkillLock { get; }
public bool IsBeingUsed { get; set; }
}
}

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

@@ -3,7 +3,7 @@ namespace Preparation.Interface
{
public interface ITimer
{
bool IsGaming { get; }
bool IsGaming { get; set; }
public bool StartGame(int timeInMilliseconds);
}
}

+ 7
- 5
logic/Preparation/Utility/GameData.cs View File

@@ -46,7 +46,7 @@ namespace Preparation.Utility
{
return pos.y / numOfPosGridPerCell;
}
public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的y坐标
public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的xy坐标
{
return new XY(pos.x / numOfPosGridPerCell, pos.y / numOfPosGridPerCell);
}
@@ -90,7 +90,7 @@ namespace Preparation.Utility
public const int characterMaxSpeed = 12000; // 最大速度

public const double basicConcealment = 1.0;
public const int basicAlertnessRadius = 30700;
public const int basicAlertnessRadius = 10700;
public const int basicViewRange = 5 * numOfPosGridPerCell;
public const int maxNumOfPropInPropInventory = 3;

@@ -148,7 +148,10 @@ namespace Preparation.Utility
public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力
public const int MinAP = 0; // 最小攻击力
public const int MaxAP = int.MaxValue; // 最大攻击力
public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1

public const int factorDamageGenerator = 2;//子弹对电机的破坏=factorDamageGenerator*AP;
public const int bulletRadius = 200; // 默认子弹半径
public const int basicBulletNum = 3; // 基本初始子弹量

public const int basicCD = 3000; // 初始子弹冷却
public const int basicCastTime = 500;//基本前摇时间
@@ -156,8 +159,7 @@ namespace Preparation.Utility
public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长
public const int basicStunnedTimeOfStudent = 4130;

public const int bulletRadius = 200; // 默认子弹半径
public const int basicBulletNum = 3; // 基本初始子弹量
public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1
public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围
public const double basicAttackShortRange = 2700; // 基本近程攻击范围
public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围


+ 2
- 0
logic/Server/CopyInfo.cs View File

@@ -184,6 +184,8 @@ namespace Server
{
case Protobuf.StudentType.Athlete:
return Preparation.Utility.CharacterType.Athlete;
case StudentType._2:
return Preparation.Utility.CharacterType.Teacher;
default:
return Preparation.Utility.CharacterType.Null;
}


+ 115
- 6
logic/规则Logic.md View File

@@ -363,7 +363,6 @@
{
private const int moveSpeed = GameData.basicMoveSpeed * 473 / 380;
private const int maxHp = GameData.basicHp;
public const int maxBulletNum = 1;

public BulletType InitBullet => BulletType.CommonAttackOfGhost;

@@ -378,17 +377,124 @@
public int timeOfOpenChest = GameData.basicSpeedOfOpenChest;
}
~~~
- 普通攻击为 CommonAttackOfGhost
~~~csharp
public CommonAttackOfGhost...
{
public override double BulletBombRange => 0;
public override double BulletAttackRange => GameData.basicAttackShortRange;
public int ap = GameData.basicApOfGhost;
public override int Speed => GameData.basicBulletMoveSpeed;
public override bool IsToBomb => false;

public override int CastTime => GameData.basicCastTime;
public override int Backswing => GameData.basicBackswing;
public override int RecoveryFromHit => GameData.basicRecoveryFromHit;
public const int cd = GameData.basicBackswing;
public override bool CanBeBombed(GameObjType gameObjType)
{
switch (gameObjType)
{
case GameObjType.Character:
case GameObjType.Generator:
return true;
default:
return false;
}
}
}
~~~
- 主动技能
- 隐身
~~~csharp
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => GameData.commonSkillTime / 10 * 6;
~~~
在DurationTime时间内玩家隐身
- 使用飞刀
~~~csharp
public int SkillCD => GameData.commonSkillCD* 2 / 3 ;
public int DurationTime => GameData.commonSkillTime / 10;
~~~
在DurationTime时间内,攻击类型变为飞刀
~~~csharp
internal sealed class FlyingKnife : Bullet
{
public override double BulletBombRange => 0;
public override double BulletAttackRange => GameData.basicRemoteAttackRange * 13;
public int ap = GameData.basicApOfGhost * 4 / 5;
public override int Speed => GameData.basicBulletMoveSpeed * 2;
public override bool IsToBomb => false;

public override int CastTime => GameData.basicCastTime;
public override int Backswing => GameData.basicBackswing * 2 / 5;
public override int RecoveryFromHit => GameData.basicBackswing * 3 / 4;
public const int cd = GameData.basicBackswing * 2 / 5 + 100;

public override bool CanBeBombed(GameObjType gameObjType)
{
if (gameObjType == GameObjType.Character) return true;
return false;
}
}
~~~

### 学生(&老师)

#### 运动员
~~~csharp
private const int moveSpeed = GameData.basicMoveSpeed * 40 / 38;
private const int maxHp = GameData.basicHp * 32 / 30;
public const int maxBulletNum = 0;
public BulletType InitBullet => BulletType.Null;

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

public const int fixSpeed = GameData.basicFixSpeed * 6 / 10;
int treatSpeed = GameData.basicTreatSpeed * 8 / 10;

public const double concealment = GameData.basicConcealment * 0.9;
int alertnessRadius = (int)(GameData.basicAlertnessRadius * 0.9);
int viewRange = (int)(GameData.basicViewRange * 1.1);
int timeOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking * 12 / 10;
int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows * 12 / 10;
int timeOfOpenChest = GameData.basicSpeedOfOpenChest;
~~~
- 主动技能
- 冲撞
~~~csharp
public int SkillCD => GameData.commonSkillCD / 5;
public int DurationTime => GameData.commonSkillTime * 6 / 10;
~~~
在DurationTime内,速度变为三倍,期间撞到捣蛋鬼,会导致捣蛋鬼眩晕7.22s,学生眩晕2.09s

#### 教师
~~~csharp
private const int moveSpeed = GameData.basicMoveSpeed * 3 / 4;
int maxHp = GameData.basicHp * 10;
int maxBulletNum = 0;
BulletType InitBullet => BulletType.Null;

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

public const int fixSpeed = 0;
int treatSpeed = GameData.basicTreatSpeed;
double concealment = GameData.basicConcealment * 0.5;
int alertnessRadius = GameData.basicAlertnessRadius / 2;
int viewRange = GameData.basicViewRange * 9 / 10;
int timeOfOpeningOrLocking = GameData.basicSpeedOfOpeningOrLocking;
int speedOfClimbingThroughWindows = GameData.basicStudentSpeedOfClimbingThroughWindows /2;
int timeOfOpenChest = GameData.basicSpeedOfOpenChest;
~~~
- 主动技能
- 惩罚
~~~csharp
public int SkillCD => GameData.commonSkillCD;
public int DurationTime => 0;
~~~
使用瞬间,在视野范围内的捣蛋鬼会被眩晕(3070+ 玩家损失的血量 / 1000)ms,

## 游戏数据

@@ -426,7 +532,7 @@
{
return pos.y / numOfPosGridPerCell;
}
public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的y坐标
public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的Xy坐标
{
return new XY(pos.x / numOfPosGridPerCell, pos.y / numOfPosGridPerCell);
}
@@ -456,7 +562,7 @@
public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1

public const double basicConcealment = 1.0;
public const int basicAlertnessRadius = 30700;
public const int basicAlertnessRadius = 10700;
public const int basicViewRange = 5 * numOfPosGridPerCell;
public const int maxNumOfPropInPropInventory = 3;
~~~
@@ -500,14 +606,17 @@
public const int MinAP = 0; // 最小攻击力
public const int MaxAP = int.MaxValue; // 最大攻击力

public const int factorDamageGenerator = 2;//子弹对电机的破坏=factorDamageGenerator*AP;
public const int bulletRadius = 200; // 默认子弹半径
public const int basicBulletNum = 3; // 基本初始子弹量

public const int basicCD = 3000; // 初始子弹冷却
public const int basicCastTime = 500;//基本前摇时间
public const int basicBackswing = 818;//基本后摇时间
public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长
public const int basicStunnedTimeOfStudent = 4130;

public const int bulletRadius = 200; // 默认子弹半径
public const int basicBulletNum = 3; // 基本初始子弹量
public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1
public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围
public const double basicAttackShortRange = 2700; // 基本近程攻击范围
public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围
@@ -526,7 +635,7 @@
public const int PropRadius = numOfPosGridPerCell / 2;
public const int PropMoveSpeed = 3000;
public const int PropMaxMoveDistance = 15 * numOfPosGridPerCell;
public const long PropProduceTime = 10000;
public const long PropProduceTime = 20000;
public const int PropDuration = 10000;

public const int ApPropAdd = basicApOfGhost * 12 / 10;


Loading…
Cancel
Save