commit for dealing with conflictstags/0.1.0
| @@ -96,7 +96,7 @@ namespace GameClass.GameObj | |||
| case CanBeginToCharge: | |||
| return ActiveSkillType.CanBeginToCharge; | |||
| case Punish: | |||
| return ActiveSkillType.Publish; | |||
| return ActiveSkillType.Punish; | |||
| default: | |||
| return ActiveSkillType.Null; | |||
| } | |||
| @@ -299,7 +299,7 @@ namespace Gaming | |||
| if (!player.Commandable()) | |||
| return false; | |||
| XY res = new XY // 子弹紧贴人物生成。 | |||
| XY res = player.Position + new XY // 子弹紧贴人物生成。 | |||
| ( | |||
| (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle)), | |||
| (int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle)) | |||
| @@ -49,9 +49,9 @@ namespace Gaming | |||
| { | |||
| if (character.IsGhost() != player.IsGhost() && XY.Distance(player.Position + new XY(player.FacingDirection, player.Radius), character.Position) <= character.Radius) | |||
| { | |||
| AttackManager.BeStunned(character, GameData.TimeOfGhostFainting); | |||
| player.AddScore(GameData.StudentScoreTrickerBeStunned); | |||
| AttackManager.BeStunned(player, GameData.TimeOfStudentFainting); | |||
| AttackManager.BeStunned(character, GameData.TimeOfGhostFaintingWhenCharge); | |||
| player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.TimeOfGhostFaintingWhenCharge)); | |||
| AttackManager.BeStunned(player, GameData.TimeOfStudentFaintingWhenCharge); | |||
| break; | |||
| } | |||
| } | |||
| @@ -115,15 +115,31 @@ namespace Gaming | |||
| { player.BulletOfPlayer = player.OriBulletOfPlayer; }); | |||
| } | |||
| public bool Publish(Character player) | |||
| public bool Punish(Character player) | |||
| { | |||
| return ActiveSkillEffect(player.UseIActiveSkill(ActiveSkillType.Publish), player, () => | |||
| return ActiveSkillEffect(player.UseIActiveSkill(ActiveSkillType.Punish), player, () => | |||
| { | |||
| player.BulletOfPlayer = BulletType.FlyingKnife; | |||
| Debugger.Output(player, "uses flyingknife!"); | |||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | |||
| try | |||
| { | |||
| foreach (Character character in gameMap.GameObjDict[GameObjType.Character]) | |||
| { | |||
| if (player.IsGhost() && XY.Distance(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)); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock(); | |||
| } | |||
| Debugger.Output(player, "uses punishing!"); | |||
| }, | |||
| () => | |||
| { player.BulletOfPlayer = player.OriBulletOfPlayer; }); | |||
| { }); | |||
| } | |||
| public bool SuperFast(Character player) | |||
| @@ -76,7 +76,7 @@ namespace Preparation.Interface | |||
| public BulletType InitBullet => BulletType.Null; | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Publish }); | |||
| public List<ActiveSkillType> ListOfIActiveSkill => new(new ActiveSkillType[] { ActiveSkillType.Punish }); | |||
| public List<PassiveSkillType> ListOfIPassiveSkill => new(new PassiveSkillType[] { }); | |||
| public const int fixSpeed = 0; | |||
| @@ -91,7 +91,7 @@ namespace Preparation.Utility | |||
| SuperFast = 4, | |||
| UseKnife = 5, | |||
| CanBeginToCharge = 6, | |||
| Publish = 7, | |||
| Punish = 7, | |||
| } | |||
| public enum PassiveSkillType | |||
| { | |||
| @@ -117,7 +117,10 @@ namespace Preparation.Utility | |||
| { | |||
| return 0; | |||
| } | |||
| public const int StudentScoreTrickerBeStunned = 25; | |||
| public static int StudentScoreTrickerBeStunned(int time) | |||
| { | |||
| return time; | |||
| } | |||
| public const int StudentScoreRescue = 100; | |||
| public static int StudentScoreTreat(int degree) | |||
| { | |||
| @@ -159,9 +162,14 @@ namespace Preparation.Utility | |||
| /// <summary> | |||
| /// BeginToCharge | |||
| /// </summary> | |||
| public const int TimeOfGhostFainting = 7220;//=AP of Ram | |||
| public const int TimeOfStudentFainting = 2090; | |||
| public const int TimeOfGhostFaintingWhenCharge = 7220; | |||
| public const int TimeOfStudentFaintingWhenCharge = 2090; | |||
| /// <summary> | |||
| /// Punish | |||
| /// </summary> | |||
| public const int TimeOfGhostFaintingWhenPunish = 3070; | |||
| public const int TimeFactorOfGhostFainting = 1000; | |||
| #endregion | |||
| #region 道具相关 | |||
| public const int MinPropTypeNum = 1; | |||
| @@ -12,16 +12,19 @@ namespace Server | |||
| public class ArgumentOptions | |||
| { | |||
| [Option("ip", Required = true, HelpText = "Server listening port")] | |||
| public string ServerIP { get; set; } = "0.0.0.0"; | |||
| [Option('p', "port", Required = true, HelpText = "Server listening port")] | |||
| public ushort ServerPort { get; set; } = 10086; | |||
| public ushort ServerPort { get; set; } = 8888; | |||
| [Option('n', "playerNum", Required = false, HelpText = "The number of players, 1 by defualt")] | |||
| public ushort playerNum { get; set; } = 1; | |||
| [Option('t', "teamCount", Required = false, HelpText = "The number of teams, 1 by defualt")] | |||
| public ushort TeamCount { get; set; } = 1; | |||
| public ushort TeamCount { get; set; } = 2; | |||
| [Option('c', "playerCount", Required = false, HelpText = "The number of players per team, 1 by default")] | |||
| [Option('c', "playerCount", Required = false, HelpText = "The number of players per team, 4 by default")] | |||
| public ushort PlayerCountPerTeam { get; set; } = 4; | |||
| [Option('g', "gameTimeInSecond", Required = false, HelpText = "The time of the game in second, 10 minutes by default")] | |||
| @@ -20,8 +20,12 @@ namespace Server | |||
| protected readonly ArgumentOptions options; | |||
| private HttpSender? httpSender; | |||
| private object gameLock = new(); | |||
| <<<<<<< HEAD | |||
| private int playerNum = 0; | |||
| private int PlayerNum => playerNum; // 注意修改 | |||
| ======= | |||
| public int PlayerNum => options.playerNum; // 注意修改 | |||
| >>>>>>> 9497283ae5076d61510347911d4d9ac16841cef3 | |||
| private MessageToClient currentGameInfo = new(); | |||
| private MessageOfObj currentMapMsg = new(); | |||
| private object newsLock = new(); | |||
| @@ -203,7 +207,7 @@ namespace Server | |||
| } | |||
| private bool ValidPlayerID(long playerID) | |||
| { | |||
| if (0 <= playerID && playerID < options.PlayerCountPerTeam + 1) | |||
| if ((0 <= playerID && playerID < options.PlayerCountPerTeam) || playerID == 4) | |||
| return true; | |||
| return false; | |||
| } | |||
| @@ -277,7 +281,7 @@ namespace Server | |||
| var onConnection = new BoolRes(); | |||
| lock (gameLock) | |||
| { | |||
| if (0 <= request.PlayerId && request.PlayerId < playerNum) // 注意修改 | |||
| if (0 <= request.PlayerId && request.PlayerId < PlayerNum) // 注意修改 | |||
| { | |||
| onConnection.ActSuccess = true; | |||
| Console.WriteLine(onConnection.ActSuccess); | |||
| @@ -332,7 +336,7 @@ namespace Server | |||
| lock (semaDict) | |||
| { | |||
| semaDict.Add(request.PlayerId, temp); | |||
| start = semaDict.Count == playerNum; | |||
| start = semaDict.Count == PlayerNum; | |||
| } | |||
| if (start) StartGame(); | |||
| } | |||
| @@ -428,7 +432,8 @@ namespace Server | |||
| #endif | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| //boolRes.ActSuccess = game.UseProp(gameID, CopyInfo.ToPropType(request.PropType)); | |||
| game.UseProp(gameID, CopyInfo.ToPropType(request.PropType)); | |||
| boolRes.ActSuccess = true; | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| public override Task<BoolRes> ThrowProp(PropMsg request, ServerCallContext context) | |||
| @@ -438,7 +443,8 @@ namespace Server | |||
| #endif | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| //boolRes.ActSuccess = game.ThrowProp(gameID, CopyInfo.ToPropType(request.PropType)); | |||
| game.ThrowProp(gameID, CopyInfo.ToPropType(request.PropType)); | |||
| boolRes.ActSuccess = true; | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| public override Task<BoolRes> UseSkill(SkillMsg request, ServerCallContext context) | |||
| @@ -448,7 +454,7 @@ namespace Server | |||
| #endif | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| //boolRes.ActSuccess = game.UseActiveSkill(gameID, CopyInfo.ToPropType(request.PropType)); | |||
| boolRes.ActSuccess = game.UseActiveSkill(gameID, request.SkillId); | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| @@ -469,7 +475,8 @@ namespace Server | |||
| #endif | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| //boolRes.ActSuccess = game.Rescue(gameID); | |||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||
| boolRes.ActSuccess = game.Rescue(gameID, toGameID); | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| public override Task<BoolRes> StartTreatMate(TreatAndRescueMsg request, ServerCallContext context) | |||
| @@ -479,7 +486,8 @@ namespace Server | |||
| #endif | |||
| BoolRes boolRes = new(); | |||
| var gameID = communicationToGameID[request.PlayerId]; | |||
| //boolRes.ActSuccess = game.Treat(gameID); | |||
| var toGameID = communicationToGameID[request.ToPlayerId]; | |||
| boolRes.ActSuccess = game.Treat(gameID, toGameID); | |||
| return Task.FromResult(boolRes); | |||
| } | |||
| public override Task<BoolRes> StartLearning(IDMsg request, ServerCallContext context) | |||
| @@ -629,7 +637,7 @@ namespace Server | |||
| if (options.Url != DefaultArgumentOptions.Url && options.Token != DefaultArgumentOptions.Token) | |||
| { | |||
| //this.httpSender = new HttpSender(options.Url, options.Token, "PUT"); | |||
| this.httpSender = new HttpSender(options.Url, options.Token, "PUT"); | |||
| } | |||
| } | |||
| } | |||
| @@ -23,10 +23,10 @@ namespace Server | |||
| if (options == null) | |||
| { | |||
| Console.WriteLine("Argument parsing failed!"); | |||
| // return 1; | |||
| return 1; | |||
| } | |||
| // Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); | |||
| Console.WriteLine("Server begins to run: " + options.ServerPort.ToString()); | |||
| try | |||
| { | |||
| @@ -34,7 +34,7 @@ namespace Server | |||
| Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) | |||
| { | |||
| Services = { AvailableService.BindService(gameServer) }, | |||
| Ports = { new ServerPort("0.0.0.0", 8888, ServerCredentials.Insecure) } | |||
| Ports = { new ServerPort(options.ServerIP, options.ServerPort, ServerCredentials.Insecure) } | |||
| }; | |||
| server.Start(); | |||
| @@ -2,7 +2,7 @@ | |||
| "profiles": { | |||
| "Server": { | |||
| "commandName": "Project", | |||
| "commandLineArgs": "-p 8888 -t 2 -c 4" | |||
| "commandLineArgs": "--ip 0.0.0.0\r\n-p 8888\r\n-f playback\r\n-g 600\r\n-b true\r\n-c 4\r\n-t 2\r\n-n 1" | |||
| } | |||
| } | |||
| } | |||
| @@ -1,6 +1,10 @@ | |||
| @echo off | |||
| <<<<<<< HEAD | |||
| start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --port 8888 --teamCount 2 --playerNum 2 --gameTimeInSecond 600 --fileName test | |||
| ======= | |||
| start cmd /k ..\Server\bin\Debug\net6.0\Server.exe --port 8888 --teamCount 2 --playerCount 4 --playerNum 1 --gameTimeInSecond 600 --fileName test | |||
| >>>>>>> 9497283ae5076d61510347911d4d9ac16841cef3 | |||
| ping -n 2 127.0.0.1 > NUL | |||
| @@ -353,3 +353,173 @@ | |||
| | Key3 | 能开启3教的门 |不得分| 能开启3教的门 |不得分| | |||
| | Key5 | 能开启5教的门 |不得分| 能开启3教的门 |不得分| | |||
| | Key6 | 能开启6教的门 |不得分| 能开启3教的门 |不得分| | |||
| ## 游戏数据 | |||
| ### 基本常数 | |||
| ~~~csharp | |||
| public const int numOfStepPerSecond = 20; // 每秒行走的步数 | |||
| public const int frameDuration = 50; // 每帧时长 | |||
| public const int checkInterval = 50; // 检查位置标志、补充子弹的帧时长 | |||
| public const long gameDuration = 600000; // 游戏时长600000ms = 10min | |||
| public const int MinSpeed = 1; // 最小速度 | |||
| public const int MaxSpeed = int.MaxValue; // 最大速度 | |||
| #endregion | |||
| #region 地图相关 | |||
| public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 | |||
| public const int lengthOfMap = 50000; // 地图长度 | |||
| public const int rows = 50; // 行数 | |||
| public const int cols = 50; // 列数 | |||
| public const int numOfBirthPoint = 5; | |||
| public const int numOfGenerator = 9; | |||
| public const int numOfChest = 8; | |||
| public static XY GetCellCenterPos(int x, int y) // 求格子的中心坐标 | |||
| { | |||
| XY ret = new(x * numOfPosGridPerCell + numOfPosGridPerCell / 2, y * numOfPosGridPerCell + numOfPosGridPerCell / 2); | |||
| return ret; | |||
| } | |||
| public static int PosGridToCellX(XY pos) // 求坐标所在的格子的x坐标 | |||
| { | |||
| return pos.x / numOfPosGridPerCell; | |||
| } | |||
| public static int PosGridToCellY(XY pos) // 求坐标所在的格子的y坐标 | |||
| { | |||
| return pos.y / numOfPosGridPerCell; | |||
| } | |||
| public static XY PosGridToCellXY(XY pos) // 求坐标所在的格子的y坐标 | |||
| { | |||
| return new XY(pos.x / numOfPosGridPerCell, pos.y / numOfPosGridPerCell); | |||
| } | |||
| public static bool IsInTheSameCell(XY pos1, XY pos2) | |||
| { | |||
| return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2); | |||
| } | |||
| public static bool ApproachToInteract(XY pos1, XY pos2) | |||
| { | |||
| return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) <= 1 && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2)) <= 1; | |||
| } | |||
| public static bool ApproachToInteractInACross(XY pos1, XY pos2) | |||
| { | |||
| return (Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2)) + Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2))) <= 1; | |||
| } | |||
| ~~~ | |||
| ### 角色相关 | |||
| ~~~csharp | |||
| public const int numOfStudent = 4; | |||
| public const int characterRadius = numOfPosGridPerCell / 2 / 5 * 4; // 人物半径 | |||
| public const int basicTreatSpeed = 100; | |||
| public const int basicFixSpeed = 100; | |||
| public const int basicSpeedOfOpeningOrLocking = 3280; | |||
| public const int basicStudentSpeedOfClimbingThroughWindows = 611; | |||
| public const int basicGhostSpeedOfClimbingThroughWindows = 1270; | |||
| public const int basicSpeedOfOpenChest = 1000; | |||
| public const int basicHp = 3000000; // 初始血量 | |||
| public const int basicMaxGamingAddiction = 60000;//基本完全沉迷时间 | |||
| public const int BeginGamingAddiction = 10003; | |||
| public const int MidGamingAddiction = 30000; | |||
| public const int basicTreatmentDegree = 1500000; | |||
| public const int basicTimeOfRescue = 1000; | |||
| public const int basicMoveSpeed = 1270; // 基本移动速度,单位:s-1 | |||
| public const int characterMaxSpeed = 12000; // 最大速度 | |||
| public const int basicBulletMoveSpeed = 2700; // 基本子弹移动速度,单位:s-1 | |||
| public const double basicConcealment = 1.0; | |||
| public const int basicAlertnessRadius = 30700; | |||
| public const int basicViewRange = 5 * numOfPosGridPerCell; | |||
| public const int maxNumOfPropInPropInventory = 3; | |||
| ~~~ | |||
| ### 得分相关 | |||
| ~~~csharp | |||
| public static int TrickerScoreAttackStudent(int damage) | |||
| { | |||
| return damage * 100 / basicApOfGhost; | |||
| } | |||
| public const int TrickerScoreStudentBeAddicted = 50; | |||
| public const int TrickerScoreStudentBeStunned = 25; | |||
| public const int TrickerScoreStudentDie = 1000; | |||
| public static int StudentScoreFix(int degreeOfFix) | |||
| { | |||
| return degreeOfFix; | |||
| } | |||
| public const int StudentScoreFixed = 25; | |||
| public static int StudentScorePinDown(int timeOfPiningDown) | |||
| { | |||
| return 0; | |||
| } | |||
| public const int StudentScoreTrickerBeStunned = 25; | |||
| public const int StudentScoreRescue = 100; | |||
| public static int StudentScoreTreat(int degree) | |||
| { | |||
| return degree; | |||
| } | |||
| public const int StudentScoreEscape = 1000; | |||
| public const int ScorePropRemainHp = 20; | |||
| public const int ScorePropUseShield = 20; | |||
| public const int ScorePropUseSpear = 20; | |||
| public const int ScorePropAddAp = 10; | |||
| public const int ScorePropAddHp = 50; | |||
| ~~~ | |||
| ### 攻击与子弹相关 | |||
| ~~~csharp | |||
| public const int basicApOfGhost = 1500000; // 捣蛋鬼攻击力 | |||
| public const int MinAP = 0; // 最小攻击力 | |||
| public const int MaxAP = int.MaxValue; // 最大攻击力 | |||
| 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 double basicRemoteAttackRange = 9000; // 基本远程攻击范围 | |||
| public const double basicAttackShortRange = 2700; // 基本近程攻击范围 | |||
| public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围 | |||
| ~~~ | |||
| ### 技能相关 | |||
| ~~~csharp | |||
| public const int maxNumOfSkill = 3; | |||
| public const int commonSkillCD = 30000; // 普通技能标准冷却时间 | |||
| public const int commonSkillTime = 10000; // 普通技能标准持续时间 | |||
| ~~~ | |||
| ### 道具相关 | |||
| ~~~csharp | |||
| public const int MinPropTypeNum = 1; | |||
| public const int MaxPropTypeNum = 10; | |||
| public const int PropRadius = numOfPosGridPerCell / 2; | |||
| public const int PropMoveSpeed = 3000; | |||
| public const int PropMaxMoveDistance = 15 * numOfPosGridPerCell; | |||
| public const long PropProduceTime = 10000; | |||
| public const int PropDuration = 10000; | |||
| public const int ApPropAdd = basicApOfGhost * 12 / 10; | |||
| public const int ApSpearAdd = basicApOfGhost * 6 / 10; | |||
| public const int RemainHpWhenAddLife = 100; | |||
| public const int numOfKeyEachArea = 2; | |||
| public const int numOfPropTypeNotKey = 4; | |||
| public const int numOfTeachingBuilding = 3; | |||
| ~~~ | |||
| ### 物体相关 | |||
| ~~~csharp | |||
| public const int degreeOfFixedGenerator = 10300000; | |||
| public const int degreeOfLockingOrOpeningTheDoor = 10000; | |||
| public const int degreeOfOpeningChest = 10000; | |||
| public const int degreeOfOpenedDoorway = 18000; | |||
| public const int maxNumOfPropInChest = 2; | |||
| public const int numOfGeneratorRequiredForRepair = 7; | |||
| public const int numOfGeneratorRequiredForEmergencyExit = 3; | |||
| ~~~ | |||