Skip to content

Commit

Permalink
Merge pull request #453 from TGRCdev/spelf-moods-duplicate-vars
Browse files Browse the repository at this point in the history
Spelf moods now check for duplicate moodvars by default
  • Loading branch information
formlessnameless authored Oct 11, 2024
2 parents 41b0a45 + 283e7c4 commit f55b7fe
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
95 changes: 95 additions & 0 deletions Content.IntegrationTests/Tests/Impstation/Spelfs/MoodTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Content.IntegrationTests;
using Content.Server.Impstation.Spelfs;
using Content.Shared.Dataset;
using Content.Shared.Impstation.Spelfs;
using NUnit.Framework;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;

namespace Content.IntegrationTests.Tests.Impstation.Spelfs;

[TestFixture, TestOf(typeof(SpelfMoodPrototype))]
public sealed class SpelfMoodTests
{
[TestPrototypes]
const string PROTOTYPES = @"
- type: dataset
id: ThreeValueSet
values:
- One
- Two
- Three
- type: spelfMood
id: DuplicateTest
moodName: DuplicateTest
moodDesc: DuplicateTest
allowDuplicateMoodVars: false
moodVars:
a: ThreeValueSet
b: ThreeValueSet
c: ThreeValueSet
- type: spelfMood
id: DuplicateOverlapTest
moodName: DuplicateOverlapTest
moodDesc: DuplicateOverlapTest
allowDuplicateMoodVars: false
moodVars:
a: ThreeValueSet
b: ThreeValueSet
c: ThreeValueSet
d: ThreeValueSet
e: ThreeValueSet
";

[Test]
[Repeat(10)]
public async Task TestDuplicatePrevention()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entMan = server.ResolveDependency<IEntityManager>();
var spelfSystem = entMan.System<SpelfMoodsSystem>();
var protoMan = server.ResolveDependency<IPrototypeManager>();

var dataset = protoMan.Index<DatasetPrototype>("ThreeValueSet");
var moodProto = protoMan.Index<SpelfMoodPrototype>("DuplicateTest");

var datasetSet = dataset.Values.ToHashSet();
var mood = spelfSystem.RollMood(moodProto);
var moodVarSet = mood.MoodVars.Values.ToHashSet();

Assert.That(moodVarSet, Is.EquivalentTo(datasetSet));

await pair.CleanReturnAsync();
}

[Test]
[Repeat(10)]
public async Task TestDuplicateOverlap()
{
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;

var entMan = server.ResolveDependency<IEntityManager>();
var spelfSystem = entMan.System<SpelfMoodsSystem>();
var protoMan = server.ResolveDependency<IPrototypeManager>();

var dataset = protoMan.Index<DatasetPrototype>("ThreeValueSet");
var moodProto = protoMan.Index<SpelfMoodPrototype>("DuplicateOverlapTest");

var datasetSet = dataset.Values.ToHashSet();
var mood = spelfSystem.RollMood(moodProto);
var moodVarSet = mood.MoodVars.Values.ToHashSet();

Assert.That(moodVarSet, Is.EquivalentTo(datasetSet));

await pair.CleanReturnAsync();
}
}
34 changes: 32 additions & 2 deletions Content.Server/Impstation/Spelfs/SpelfMoodSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,38 @@ public SpelfMood RollMood(SpelfMoodPrototype proto)
Conflicts = proto.Conflicts,
};

foreach (var (name, dataset) in proto.MoodVarDatasets)
mood.MoodVars.Add(name, _random.Pick(_proto.Index<DatasetPrototype>(dataset)));
var alreadyChosen = new HashSet<string>();

foreach (var (name, datasetID) in proto.MoodVarDatasets)
{
var dataset = _proto.Index<DatasetPrototype>(datasetID);

if (proto.AllowDuplicateMoodVars)
{
mood.MoodVars.Add(name, _random.Pick(dataset));
continue;
}

var choices = dataset.Values.ToList();
var foundChoice = false;
while (choices.Count > 0)
{
var choice = _random.PickAndTake(choices);
if (alreadyChosen.Contains(choice))
continue;

mood.MoodVars.Add(name, choice);
alreadyChosen.Add(choice);
foundChoice = true;
break;
}

if (!foundChoice)
{
Log.Warning($"Ran out of choices for moodvar \"{name}\" in \"{proto.ID}\"! Picking a duplicate...");
mood.MoodVars.Add(name, _random.Pick(_proto.Index<DatasetPrototype>(dataset)));
}
}

return mood;
}
Expand Down
8 changes: 8 additions & 0 deletions Content.Shared/Impstation/Spelfs/SpelfMoodPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,12 @@ public sealed partial class SpelfMoodPrototype : IPrototype
/// </summary>
[DataField("moodVars", customTypeSerializer: typeof(PrototypeIdValueDictionarySerializer<string, DatasetPrototype>))]
public Dictionary<string, string> MoodVarDatasets = new();

/// <summary>
/// If false, prevents the same variable from being rolled twice when rolling
/// mood variables for this mood. Does not prevent the same mood variable
/// from being present in other moods.
/// </summary>
[DataField("allowDuplicateMoodVars"), ViewVariables(VVAccess.ReadWrite)]
public bool AllowDuplicateMoodVars = false;
}

0 comments on commit f55b7fe

Please sign in to comment.