diff --git a/game/territory-autobattler/scenes/game/hex_grid_screen.gd b/game/territory-autobattler/scenes/game/hex_grid_screen.gd index e5a9893..52f009d 100644 --- a/game/territory-autobattler/scenes/game/hex_grid_screen.gd +++ b/game/territory-autobattler/scenes/game/hex_grid_screen.gd @@ -100,6 +100,7 @@ var pending_move_r := 9999 var refresh_prompt_active := false var refresh_request_active := false var units_reload_queued := false +var visible_reload_queued := false func _ready() -> void: @@ -1069,6 +1070,8 @@ func _on_home_request_completed(result: int, response_code: int, _headers: Packe grid_view.set_home_location(q, r) coordinate_label.text = "Home territory assigned at q:%d r:%d | %s" % [q, r, terrain] _load_visible_locations() + _refresh_player_state() + resources_timer.start() func _load_visible_locations() -> void: @@ -1077,6 +1080,10 @@ func _load_visible_locations() -> void: coordinate_label.text = "No auth token available. Visibility was not loaded." return + if visible_request.get_http_client_status() != HTTPClient.STATUS_DISCONNECTED: + visible_reload_queued = true + return + var error: int = visible_request.request( LOCATIONS_BASE_URL + "/api/locations/visible", PackedStringArray([ @@ -1091,16 +1098,19 @@ func _load_visible_locations() -> void: func _on_visible_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void: if result != HTTPRequest.RESULT_SUCCESS: coordinate_label.text = "Visible territory request failed." + _run_queued_visible_reload() return var text: String = body.get_string_from_utf8() if response_code < 200 or response_code >= 300: coordinate_label.text = "Visible territory failed: %s" % text + _run_queued_visible_reload() return var parsed = JSON.parse_string(text) if typeof(parsed) != TYPE_ARRAY: coordinate_label.text = "Locations service returned invalid visibility data." + _run_queued_visible_reload() return var username: String = str(session.get("username", "")) @@ -1108,8 +1118,14 @@ func _on_visible_request_completed(result: int, response_code: int, _headers: Pa grid_view.set_visible_locations(visible_locations, username) _sync_active_building_timer(visible_locations, username) coordinate_label.text = "Visible territory loaded. Sight extends 3 hexes beyond controlled land." - _refresh_player_state() - resources_timer.start() + _run_queued_visible_reload() + + +func _run_queued_visible_reload() -> void: + if not visible_reload_queued: + return + visible_reload_queued = false + call_deferred("_load_visible_locations") func _refresh_player_state() -> void: diff --git a/microservices/LocationsApi/Services/LocationService.cs b/microservices/LocationsApi/Services/LocationService.cs index e5b4c53..5da0ef0 100644 --- a/microservices/LocationsApi/Services/LocationService.cs +++ b/microservices/LocationsApi/Services/LocationService.cs @@ -646,9 +646,14 @@ public class LocationService var destinationQ = worker.DestinationQ.Value; var destinationR = worker.DestinationR.Value; - if (HexDistance(worker.Q, worker.R, destinationQ, destinationR) > 1) + var currentQ = worker.Q; + var currentR = worker.R; + var elapsedSteps = Math.Max(1, (int)Math.Floor((now - worker.MovementCompletesAtUtc!.Value).TotalMinutes) + 1); + var movementBlocked = false; + + while (elapsedSteps > 0 && HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) { - var nextStep = await NextPeasantStepTowardAsync(username, worker.Q, worker.R, destinationQ, destinationR); + var nextStep = await NextPeasantStepTowardAsync(username, currentQ, currentR, destinationQ, destinationR); if (nextStep is null) { await _units.UpdateOneAsync( @@ -660,14 +665,25 @@ public class LocationService .Unset(x => x.MovementStartedAtUtc) .Unset(x => x.MovementCompletesAtUtc) .Set(x => x.UpdatedAtUtc, now)); - continue; + movementBlocked = true; + break; } + currentQ = nextStep.Value.q; + currentR = nextStep.Value.r; + elapsedSteps--; + } + + if (movementBlocked) + continue; + + if (HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) + { await _units.UpdateOneAsync( x => x.Id == worker.Id, Builders.Update - .Set(x => x.Q, nextStep.Value.q) - .Set(x => x.R, nextStep.Value.r) + .Set(x => x.Q, currentQ) + .Set(x => x.R, currentR) .Set(x => x.MovementCompletesAtUtc, now.AddMinutes(1)) .Set(x => x.UpdatedAtUtc, now)); continue; diff --git a/microservices/LocationsApi/Services/ResourceService.cs b/microservices/LocationsApi/Services/ResourceService.cs index 4d7adbf..5f1d6a8 100644 --- a/microservices/LocationsApi/Services/ResourceService.cs +++ b/microservices/LocationsApi/Services/ResourceService.cs @@ -540,9 +540,14 @@ public class ResourceService var destinationQ = worker.DestinationQ.Value; var destinationR = worker.DestinationR.Value; - if (HexDistance(worker.Q, worker.R, destinationQ, destinationR) > 1) + var currentQ = worker.Q; + var currentR = worker.R; + var elapsedSteps = Math.Max(1, (int)Math.Floor((now - worker.MovementCompletesAtUtc!.Value).TotalMinutes) + 1); + var movementBlocked = false; + + while (elapsedSteps > 0 && HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) { - var nextStep = await NextPeasantStepTowardAsync(username, worker.Q, worker.R, destinationQ, destinationR); + var nextStep = await NextPeasantStepTowardAsync(username, currentQ, currentR, destinationQ, destinationR); if (nextStep is null) { await _units.UpdateOneAsync( @@ -554,14 +559,25 @@ public class ResourceService .Unset(x => x.MovementStartedAtUtc) .Unset(x => x.MovementCompletesAtUtc) .Set(x => x.UpdatedAtUtc, now)); - continue; + movementBlocked = true; + break; } + currentQ = nextStep.Value.q; + currentR = nextStep.Value.r; + elapsedSteps--; + } + + if (movementBlocked) + continue; + + if (HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) + { await _units.UpdateOneAsync( x => x.Id == worker.Id, Builders.Update - .Set(x => x.Q, nextStep.Value.q) - .Set(x => x.R, nextStep.Value.r) + .Set(x => x.Q, currentQ) + .Set(x => x.R, currentR) .Set(x => x.MovementCompletesAtUtc, now.AddMinutes(1)) .Set(x => x.UpdatedAtUtc, now)); continue; diff --git a/microservices/LocationsApi/Services/UnitTrainingService.cs b/microservices/LocationsApi/Services/UnitTrainingService.cs index 0dd0837..9df98c2 100644 --- a/microservices/LocationsApi/Services/UnitTrainingService.cs +++ b/microservices/LocationsApi/Services/UnitTrainingService.cs @@ -325,44 +325,57 @@ public class UnitTrainingService var destinationQ = unit.DestinationQ.Value; var destinationR = unit.DestinationR.Value; - if (unit.UnitType == PeasantUnitType && HexDistance(unit.Q, unit.R, destinationQ, destinationR) > 1) + var currentQ = unit.Q; + var currentR = unit.R; + var elapsedSteps = Math.Max(1, (int)Math.Floor((now - unit.MovementCompletesAtUtc!.Value).TotalMinutes) + 1); + var movementBlocked = false; + + while (elapsedSteps > 0 && HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) { - var nextStep = await NextPeasantStepTowardAsync(username, unit.Q, unit.R, destinationQ, destinationR); - if (nextStep is null) + if (unit.UnitType == PeasantUnitType) { - await _units.UpdateOneAsync( - x => x.Id == unit.Id, - Builders.Update - .Set(x => x.Status, "Idle") - .Set(x => x.MovementPerTick, movementPerTick) - .Set(x => x.MovementRemaining, movementPerTick) - .Unset(x => x.DestinationQ) - .Unset(x => x.DestinationR) - .Set(x => x.ClaimOnArrival, false) - .Unset(x => x.MovementStartedAtUtc) - .Unset(x => x.MovementCompletesAtUtc) - .Set(x => x.UpdatedAtUtc, now)); - continue; + var nextStep = await NextPeasantStepTowardAsync(username, currentQ, currentR, destinationQ, destinationR); + if (nextStep is null) + { + await _units.UpdateOneAsync( + x => x.Id == unit.Id, + Builders.Update + .Set(x => x.Status, "Idle") + .Set(x => x.MovementPerTick, movementPerTick) + .Set(x => x.MovementRemaining, movementPerTick) + .Unset(x => x.DestinationQ) + .Unset(x => x.DestinationR) + .Set(x => x.ClaimOnArrival, false) + .Unset(x => x.MovementStartedAtUtc) + .Unset(x => x.MovementCompletesAtUtc) + .Set(x => x.UpdatedAtUtc, now)); + movementBlocked = true; + break; + } + + currentQ = nextStep.Value.q; + currentR = nextStep.Value.r; + } + else + { + var nextStep = NextStepToward(currentQ, currentR, destinationQ, destinationR); + currentQ = nextStep.q; + currentR = nextStep.r; } - await _units.UpdateOneAsync( - x => x.Id == unit.Id, - Builders.Update - .Set(x => x.Q, nextStep.Value.q) - .Set(x => x.R, nextStep.Value.r) - .Set(x => x.MovementCompletesAtUtc, now.AddMinutes(1)) - .Set(x => x.UpdatedAtUtc, now)); - continue; + elapsedSteps--; } - if (unit.UnitType != PeasantUnitType && HexDistance(unit.Q, unit.R, destinationQ, destinationR) > 1) + if (movementBlocked) + continue; + + if (HexDistance(currentQ, currentR, destinationQ, destinationR) > 1) { - var nextStep = NextStepToward(unit.Q, unit.R, destinationQ, destinationR); await _units.UpdateOneAsync( x => x.Id == unit.Id, Builders.Update - .Set(x => x.Q, nextStep.q) - .Set(x => x.R, nextStep.r) + .Set(x => x.Q, currentQ) + .Set(x => x.R, currentR) .Set(x => x.MovementCompletesAtUtc, now.AddMinutes(1)) .Set(x => x.UpdatedAtUtc, now)); continue;