Wear worn clothes on campus and replace rags at the work morning.

Condition drops from catalog hours only while the person is at school; skip through the night issues the same fresh set as a lived night so the school does not walk in in rags.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 03:49:11 +03:00
co-authored by Cursor
parent af90bb9f9d
commit 1ba739dd9b
20 changed files with 847 additions and 28 deletions
@@ -36,6 +36,7 @@ public class InventoryApiTests(AppHostFixture fixture)
Assert.NotNull(card);
Assert.NotEmpty(card.Worn);
Assert.Contains(card.Worn, item => item.Layers.Count > 0 && item.ColorLabel is { Length: > 0 });
Assert.Contains(card.Worn, item => item.Condition == 1 && item.ConditionLabel == "целая");
Assert.True(card.CarryCapacity > 0);
Assert.True(card.CarryMass <= card.CarryCapacity);
Assert.Contains(card.Carried, item => item.Mass > 0);
@@ -79,6 +80,27 @@ public class InventoryApiTests(AppHostFixture fixture)
Assert.Contains("\"items\"", File.ReadAllText(path), StringComparison.Ordinal);
}
[Fact]
public async Task Card_ConditionLabel_FollowsTheSavedThreshold()
{
using var client = fixture.App.CreateHttpClient("server");
await SchoolApiTests.ResetAsync(client);
var school = await SchoolApiTests.CreateAsync(client, "Ветхая рубашка", Start, seed: 31);
var girl = await FirstGirlTopAsync(client, school.Id);
Assert.Equal("целая", girl.ConditionLabel);
var directory = await SavesDirectoryAsync(client);
var path = Path.Combine(directory, $"{school.Id}.people.json");
SetFirstWornCondition(path, 0.1f);
using var reload = await client.PostAsync("/api/dev/reload-schools", content: null, TestContext.Current.CancellationToken);
reload.EnsureSuccessStatusCode();
var after = await FirstGirlTopAsync(client, school.Id);
Assert.Equal(0.1f, after.Condition, precision: 4);
Assert.Equal("висит лохмотьями", after.ConditionLabel);
}
private static async Task<WornItem> FirstGirlTopAsync(HttpClient client, int schoolId)
{
var page = await client.GetFromJsonAsync<PeoplePage>(
@@ -129,6 +151,26 @@ public class InventoryApiTests(AppHostFixture fixture)
root.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
}
private static void SetFirstWornCondition(string path, float condition)
{
var root = JsonNode.Parse(File.ReadAllText(path))
?? throw new InvalidOperationException("People file parsed to nothing.");
foreach (var person in root["people"]?.AsArray() ?? [])
{
foreach (var item in person?["items"]?.AsArray() ?? [])
{
if (item?["location"]?.GetValue<string>() == "worn")
{
item["condition"] = condition;
}
}
}
File.WriteAllText(
path,
root.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
}
private sealed record SavesDirectoryResponse(string Path);
private sealed record PeoplePage(IReadOnlyList<PersonRow> People);
@@ -146,7 +188,9 @@ public class InventoryApiTests(AppHostFixture fixture)
string Label,
string? Color,
string? ColorLabel,
IReadOnlyList<Layer> Layers);
IReadOnlyList<Layer> Layers,
float Condition,
string ConditionLabel);
private sealed record Layer(string DefName, string Label);