This commit is contained in:
Bandwidth
2026-04-26 17:28:23 +02:00
parent 9590629795
commit fda01dd93c
2 changed files with 84 additions and 2 deletions

View File

@@ -479,6 +479,10 @@ public class LobbyActor : IDisposable
ProcessCastVote(player, m, ref ack); ProcessCastVote(player, m, ref ack);
break; break;
case TaskStart m:
ProcessTaskStart(player, m, ref ack);
break;
case TaskComplete m: case TaskComplete m:
ProcessTaskComplete(player, m, ref ack); ProcessTaskComplete(player, m, ref ack);
break; break;
@@ -1083,6 +1087,59 @@ public class LobbyActor : IDisposable
CheckWinConditions(); CheckWinConditions();
} }
private void ProcessTaskStart(Player player, TaskStart message, ref Ack ack)
{
// Same gating as TaskComplete: must be Playing, no meeting, must be crew.
if (_phase != GamePhase.Playing || _currentMeeting != null)
{
ack.Success = false;
ack.Error = "Nelze začít task";
return;
}
if (player.State != PlayerState.Alive)
{
ack.Success = false;
ack.Error = "Mrtví hráči nemohou provádět tasky";
return;
}
if (player.Role == PlayerRole.Impostor)
{
ack.Success = false;
ack.Error = "Impostoři nemohou dělat tasky";
return;
}
// Validate the task belongs to this player and isn't already done.
var task = player.Tasks.FirstOrDefault(t => t.TaskId == message.TaskId);
if (task == null || player.CompletedTaskIds.Contains(message.TaskId))
{
ack.Success = false;
ack.Error = "Neznámý nebo již dokončený task";
return;
}
// Distance check (same threshold as TryCompleteTask uses).
var distance = player.Position.DistanceTo(task.Location);
if (distance > _config.TaskStartDistanceM)
{
ack.Success = false;
ack.Error = $"Příliš daleko od tasku ({distance:F1}m)";
return;
}
player.CurrentTaskId = message.TaskId;
var evt = CreateEvent("TaskStarted", player.ClientUuid, new TaskStartedPayload
{
ClientUuid = player.ClientUuid,
TaskId = message.TaskId
});
PersistAndBroadcast(evt);
}
private void ProcessTaskComplete(Player player, TaskComplete message, ref Ack ack) private void ProcessTaskComplete(Player player, TaskComplete message, ref Ack ack)
{ {
if (_phase != GamePhase.Playing || _currentMeeting != null) if (_phase != GamePhase.Playing || _currentMeeting != null)
@@ -1554,6 +1611,18 @@ public class LobbyActor : IDisposable
_logger.LogInformation("Stanice opravena: {Station} by {Player}", station.Name, player.DisplayName); _logger.LogInformation("Stanice opravena: {Station} by {Player}", station.Name, player.DisplayName);
// Broadcast that this station's repair started so other clients can
// surface "1/2 stations active" coaching during multi-station
// (meltdown) sabotage. Without this, only the meltdown countdown
// is visible - players don't know whether anyone else is helping.
var startedEvt = CreateEvent("RepairStarted", player.ClientUuid, new RepairStartedPayload
{
SabotageId = _currentSabotage.SabotageId,
StationId = station.StationId,
PlayerId = player.ClientUuid
});
PersistAndBroadcast(startedEvt);
// Zkontroluj zda je sabotáž kompletně opravena // Zkontroluj zda je sabotáž kompletně opravena
CheckSabotageRepairComplete(player.ClientUuid, station.StationId); CheckSabotageRepairComplete(player.ClientUuid, station.StationId);
} }

View File

@@ -733,6 +733,12 @@ public class PlayerEjectedPayload
public PlayerRole Role { get; set; } public PlayerRole Role { get; set; }
} }
public class TaskStartedPayload
{
public required string ClientUuid { get; set; }
public required string TaskId { get; set; }
}
public class TaskCompletedPayload public class TaskCompletedPayload
{ {
public required string ClientUuid { get; set; } public required string ClientUuid { get; set; }
@@ -793,6 +799,13 @@ public class RepairStartedPayload
public required string PlayerId { get; set; } public required string PlayerId { get; set; }
} }
public class RepairStartedPayload
{
public required string SabotageId { get; set; }
public required string StationId { get; set; }
public required string PlayerId { get; set; }
}
public class RepairStoppedPayload public class RepairStoppedPayload
{ {
public required string SabotageId { get; set; } public required string SabotageId { get; set; }