Skip to content

Commit a566c04

Browse files
authored
Merge pull request #178 from lch24/dev
lei le
2 parents cf16bca + c391e47 commit a566c04

3 files changed

Lines changed: 33 additions & 32 deletions

File tree

docs/规则.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585

8686
| 属性 | 初始值 | 上限 |
8787
|:----:|:------:|:----:|
88-
| 血量 (HP) | 100 | 300 |
88+
| 血量 (HP) | 1000 | 3000 |
8989
| 防御力 (Robust) | 20 | 50 |
9090
| 仓储 (Storage) | 5 | 150 |
9191
| 效率 (Efficiency) | 1 | 2 |
@@ -99,11 +99,11 @@
9999
**算力产出**:基础 1 点/秒,每个已占领算力中心 +2 点/秒
100100

101101
**被攻击**
102-
-7 分钟工厂处于**无敌状态**,不受任何伤害
102+
-30 秒工厂处于**无敌状态**,不受任何伤害
103103
- 实际伤害 = `Max(ATK − Robust, 1)`
104104
- 攻击方获得 `伤害量` 分(等于工厂实际损失的血量)
105105
- 工厂被攻击后进入 1s 停摆(CanProduce 和 CanRecruit 均为 false)
106-
- 工厂被摧毁(HP=0):攻击方获得 **1000**
106+
- 工厂被摧毁(HP=0):攻击方获得 **20000**
107107

108108
### 市场
109109

@@ -202,7 +202,7 @@
202202
| **对敌方角色造成伤害** | 伤害量 × 20 |
203203
| **击杀敌方角色** | 角色造价 × 40(Drone=2000, Robot=2000, Car=2000) |
204204
| **对敌方工厂造成伤害** | 伤害量(工厂实际损失血量) |
205-
| **摧毁敌方工厂** | 1000 |
205+
| **摧毁敌方工厂** | 20000 |
206206

207207
- 买入商品会消耗队伍分数
208208
- 游戏结束(10 分钟)或所有队伍工厂被摧毁时结算

logic/Gaming/CharacterManager.cs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ private sealed class CharacterManager(Game game, Map gameMap)
2222
private readonly Game game = game;
2323
private readonly Map map = gameMap;
2424
private readonly ConcurrentDictionary<long, ConcurrentDictionary<long, Character>> teamCharacters = new(); // key: TeamID -> (PlayerID -> Character)
25+
private readonly ConcurrentDictionary<long, object> teamRecruitLocks = new(); // 防止同一队伍并发创建角色导致出生点重叠
2526

2627
public Character CreateCharacter(long teamId, long playerId, CharacterType type)
2728
{
@@ -51,33 +52,33 @@ public bool RecruitCharacter(long teamId, long playerId, CharacterType type, XY
5152
LogicLogging.logger.LogWarning($"Factory for Team {teamId} cannot recruit at this time.");
5253
return false;
5354
}
54-
var teamDict = teamCharacters.GetOrAdd(teamId, _ => new ConcurrentDictionary<long, Character>());
55-
if (teamDict.Count >= GameData.MaxCharactersPerTeam)
56-
{
57-
LogicLogging.logger.LogWarning($"Team {teamId} has reached the maximum character limit ({GameData.MaxCharactersPerTeam}). Cannot recruit more.");
58-
return false;
59-
}
60-
if (teamDict.ContainsKey(playerId))
61-
{
62-
LogicLogging.logger.LogWarning($"Team {teamId} already has an alive character for Player {playerId}. Cannot recruit.");
63-
return false;
64-
}
65-
if (teamCharacters.TryGetValue(teamId, out var dict) && dict.Count >= GameData.MaxCharactersPerTeam)
66-
{
67-
LogicLogging.logger.LogWarning($"Team {teamId} has reached the maximum character limit ({GameData.MaxCharactersPerTeam}). Cannot recruit more.");
68-
return false;
69-
}
7055
var occ = OccupationFactory.FindIOccupation(type);
7156
int cost = occ.Cost;
72-
if (factory.ComputingPower.Get() < cost)
57+
58+
var teamLock = teamRecruitLocks.GetOrAdd(teamId, _ => new object());
59+
lock (teamLock)
7360
{
74-
LogicLogging.logger.LogWarning($"Not enough computing power for Team {teamId} to recruit character. Required: {cost}, Available: {factory.ComputingPower.Get()}");
75-
return false;
61+
var teamDict = teamCharacters.GetOrAdd(teamId, _ => new ConcurrentDictionary<long, Character>());
62+
if (teamDict.Count >= GameData.MaxCharactersPerTeam)
63+
{
64+
LogicLogging.logger.LogWarning($"Team {teamId} has reached the maximum character limit ({GameData.MaxCharactersPerTeam}). Cannot recruit more.");
65+
return false;
66+
}
67+
if (teamDict.ContainsKey(playerId))
68+
{
69+
LogicLogging.logger.LogWarning($"Team {teamId} already has an alive character for Player {playerId}. Cannot recruit.");
70+
return false;
71+
}
72+
if (factory.ComputingPower.Get() < cost)
73+
{
74+
LogicLogging.logger.LogWarning($"Not enough computing power for Team {teamId} to recruit character. Required: {cost}, Available: {factory.ComputingPower.Get()}");
75+
return false;
76+
}
77+
factory.ComputingPower.SubRNow(cost);
78+
var ch = CreateCharacter(teamId, playerId, type);
79+
ActivateCharacter(teamId, playerId, birthPos);
80+
return true;
7681
}
77-
factory.ComputingPower.SubRNow(cost);
78-
var ch = CreateCharacter(teamId, playerId, type);
79-
ActivateCharacter(teamId, playerId, birthPos);
80-
return true;
8182
}
8283

8384
public bool ActivateCharacter(long teamId, long playerId, XY pos)
@@ -154,8 +155,8 @@ private bool IsPositionColliding(Character ch, XY pos)
154155
// 在基准位置附近按环形搜索一个非碰撞点
155156
private bool TryFindNearbyFreePosition(Character ch, XY center, out XY result)
156157
{
157-
// 从工厂半径 + 角色半径开始,保证与工厂外部至少间隔1
158-
int startDist = GameData.FactoryRadius + ch.Radius + 1;
158+
// 工厂外至少两个格子的缓冲区,确保角色不会卡在工厂边缘
159+
int startDist = GameData.FactoryRadius + GameData.NumOfPosGridPerCell * 2;
159160
int maxDist = GameData.NumOfPosGridPerCell * 5; // 最多搜索 5 个格子的半径
160161
int distStep = Math.Max(1, GameData.NumOfPosGridPerCell / 8);
161162
int angleStepDeg = 15;

logic/Preparation/Utility/GameData.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ public static class GameData
3737

3838
public const int ResourceHP = 500; // 资源血量
3939

40-
public const int FactoryScore = 1000;
40+
public const int FactoryScore = 20000;
4141
public const int FactoryDisableTimeMs = 10_00;
42-
public const int FactoryInvulnerableTimeMs = 7 * 60 * 1000; // 前7分钟工厂不掉血
42+
public const int FactoryInvulnerableTimeMs = 30 * 1000; // 前30秒工厂不掉血
4343

4444
// Score multipliers for combat
4545
public const int CharacterDamageScoreMultiplier = 20;
4646
public const int CharacterKillScoreMultiplier = 40;
4747

48-
public const int FactoryHP = 100;
48+
public const int FactoryHP = 1000;
4949
public const int FactoryStorage = 5;
5050
public const int FactoryRobust = 20;
5151
public const int FactoryEfficiency = 1;

0 commit comments

Comments
 (0)