added global item config
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
using ActionBlocks.Game.Core;
|
||||
using ActionBlocks.Game.Items;
|
||||
using static ActionBlocks.Game.Tests.TestHelpers;
|
||||
|
||||
namespace ActionBlocks.Game.Tests;
|
||||
|
||||
public class ConfigTests
|
||||
{
|
||||
private static GameSettings WithItems(params (string Id, ItemSettings Item)[] items) =>
|
||||
new() { Items = items.ToDictionary(i => i.Id, i => i.Item, StringComparer.OrdinalIgnoreCase) };
|
||||
|
||||
private static ItemContext Context(PlayerGame target, double now) => new(target, target, new Random(3), now);
|
||||
|
||||
[Fact]
|
||||
public void Empty_settings_keep_the_built_in_defaults()
|
||||
{
|
||||
var registry = ItemRegistry.FromSettings(new GameSettings());
|
||||
|
||||
Assert.Equal(6, registry.All.Count);
|
||||
Assert.All(registry.All, i => Assert.Equal(1.0 / 6, registry.Share(i.Id), 6));
|
||||
Assert.Equal(4, registry.Get("blind")!.DurationSeconds);
|
||||
Assert.Equal(8, registry.Get("transform")!.DurationSeconds);
|
||||
Assert.Null(registry.Get("nuke")!.DurationSeconds);
|
||||
Assert.Empty(new GameSettings().Validate());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Configured_durations_change_the_effect_length()
|
||||
{
|
||||
var registry = ItemRegistry.FromSettings(WithItems(
|
||||
("blind", new ItemSettings { DurationSeconds = 2 }),
|
||||
("transform", new ItemSettings { DurationSeconds = 3 })));
|
||||
var target = CreatePlayer("b");
|
||||
target.Start();
|
||||
|
||||
registry.Get("blind")!.Apply(Context(target, 10));
|
||||
registry.Get("transform")!.Apply(Context(target, 10));
|
||||
|
||||
target.Update(0.01, 11.9);
|
||||
Assert.True(target.IsInvisible);
|
||||
target.Update(0.01, 12.1);
|
||||
Assert.False(target.IsInvisible);
|
||||
Assert.True(target.IsTransformed);
|
||||
target.Update(0.01, 13.1);
|
||||
Assert.False(target.IsTransformed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Only_items_with_weight_spawn()
|
||||
{
|
||||
var settings = WithItems(
|
||||
("add_line", new ItemSettings { Weight = 0 }),
|
||||
("clear_line", new ItemSettings { Weight = 0 }),
|
||||
("nuke", new ItemSettings { Weight = 0 }),
|
||||
("swap", new ItemSettings { Weight = 0 }),
|
||||
("transform", new ItemSettings { Weight = 0 }));
|
||||
var spawner = new ItemSpawner(ItemRegistry.FromSettings(settings), 1, new Random(1));
|
||||
|
||||
var items = Enumerable.Range(0, 50).SelectMany(_ => spawner.Decorate(PieceType.T).Items!).ToHashSet();
|
||||
|
||||
Assert.Equal(["blind"], items);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Weights_split_the_item_chance()
|
||||
{
|
||||
var settings = WithItems(
|
||||
("add_line", new ItemSettings { Weight = 3 }),
|
||||
("nuke", new ItemSettings { Weight = 1 }),
|
||||
("clear_line", new ItemSettings { Weight = 0 }),
|
||||
("swap", new ItemSettings { Weight = 0 }),
|
||||
("blind", new ItemSettings { Weight = 0 }),
|
||||
("transform", new ItemSettings { Weight = 0 }));
|
||||
var registry = ItemRegistry.FromSettings(settings);
|
||||
var random = new Random(7);
|
||||
|
||||
var picks = Enumerable.Range(0, 4000).Select(_ => registry.PickRandom(random).Id).ToList();
|
||||
|
||||
Assert.Equal(0.75, registry.Share("add_line"));
|
||||
Assert.Equal(0.25, registry.Share("nuke"));
|
||||
Assert.InRange(picks.Count(p => p == "add_line") / 4000.0, 0.72, 0.78);
|
||||
Assert.Equal(4000, picks.Count(p => p is "add_line" or "nuke"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void All_weights_zero_means_no_items()
|
||||
{
|
||||
var settings = new GameSettings
|
||||
{
|
||||
Items = ItemRegistry.Default.All.ToDictionary(i => i.Id, _ => new ItemSettings { Weight = 0 }),
|
||||
};
|
||||
var spawner = new ItemSpawner(ItemRegistry.FromSettings(settings), 1, new Random(1));
|
||||
|
||||
Assert.Empty(settings.Validate());
|
||||
Assert.False(spawner.Decorate(PieceType.T).HasItem);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Item_ids_are_case_insensitive()
|
||||
{
|
||||
var settings = new GameSettings { Items = new() { ["Blind"] = new ItemSettings { DurationSeconds = 2 } } };
|
||||
|
||||
Assert.Empty(settings.Validate());
|
||||
Assert.Equal(2, ItemRegistry.FromSettings(settings).Get("blind")!.DurationSeconds);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Missing_items_keep_weight_one()
|
||||
{
|
||||
var registry = ItemRegistry.FromSettings(WithItems(("nuke", new ItemSettings { Weight = 5 })));
|
||||
|
||||
Assert.Equal(0.5, registry.Share("nuke"));
|
||||
Assert.Equal(0.1, registry.Share("blind"), 6);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_reports_every_problem()
|
||||
{
|
||||
var settings = WithItems(
|
||||
("add_line", new ItemSettings { Weight = -1 }),
|
||||
("blind", new ItemSettings { DurationSeconds = 0 }),
|
||||
("nuke", new ItemSettings { DurationSeconds = 5 }),
|
||||
("laser", new ItemSettings { Weight = 1 })) with { ItemSpawnChance = 1.5 };
|
||||
|
||||
var errors = settings.Validate();
|
||||
|
||||
Assert.Equal(5, errors.Count);
|
||||
Assert.Contains(errors, e => e.StartsWith("ItemSpawnChance"));
|
||||
Assert.Contains(errors, e => e.StartsWith("Items.add_line.Weight"));
|
||||
Assert.Contains(errors, e => e.StartsWith("Items.blind.DurationSeconds"));
|
||||
Assert.Contains(errors, e => e.StartsWith("Items.nuke: this item acts instantly"));
|
||||
Assert.Contains(errors, e => e.StartsWith("Items.laser: unknown item"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user