Skip to content

Commit

Permalink
Building Fields & Properties
Browse files Browse the repository at this point in the history
  • Loading branch information
EgardA committed Sep 27, 2024
1 parent 8545df8 commit cd4b891
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 0 deletions.
109 changes: 109 additions & 0 deletions source/E2E.Tests/Services/Buildings/BuildingSyncTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Common.Util;
using E2E.Tests.Environment;
using E2E.Tests.Environment.Instance;
using E2E.Tests.Util;
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TaleWorlds.CampaignSystem.Party.PartyComponents;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Settlements.Buildings;
using Xunit.Abstractions;

namespace E2E.Tests.Services.Buildings
{
public class BuildingSyncTests : IDisposable
{
E2ETestEnvironment TestEnvironment { get; }

EnvironmentInstance Server => TestEnvironment.Server;

IEnumerable<EnvironmentInstance> Clients => TestEnvironment.Clients;

private readonly string BuildingId;
private readonly string TownId;
private int newInt = 50;
private float newFloat = 25f;

public BuildingSyncTests(ITestOutputHelper output)
{
TestEnvironment = new E2ETestEnvironment(output);

var building = GameObjectCreator.CreateInitializedObject<Building>();
var town = GameObjectCreator.CreateInitializedObject<Town>();

// Create objects on the server
Assert.True(Server.ObjectManager.AddNewObject(building, out BuildingId));
Assert.True(Server.ObjectManager.AddNewObject(town, out TownId));

// Create objects on all clients
foreach (var client in Clients)
{
Assert.True(client.ObjectManager.AddExisting(BuildingId, building));
Assert.True(client.ObjectManager.AddExisting(TownId, town));
}
}

public void Dispose()
{
TestEnvironment.Dispose();
}

[Fact]
public void Server_Building_Sync()
{
// Arrange
var server = TestEnvironment.Server;

var hitpointsField = AccessTools.Field(typeof(Building), nameof(Building._hitpoints));
var currentLevelField = AccessTools.Field(typeof(Building), nameof(Building._currentLevel));
var isCurrentlyDefaultField = AccessTools.Field(typeof(Building), nameof(Building.IsCurrentlyDefault));
var buildingProgressField = AccessTools.Field(typeof(Building), nameof(Building.BuildingProgress));

// Get field intercept to use on the server to simulate the field changing
var hitpointsIntercept = TestEnvironment.GetIntercept(hitpointsField);
var currentLevelIntercept = TestEnvironment.GetIntercept(currentLevelField);
var isCurrentlyDefaultIntercept = TestEnvironment.GetIntercept(isCurrentlyDefaultField);
var buildingProgressIntercept = TestEnvironment.GetIntercept(buildingProgressField);

// Act
server.Call(() =>
{
Assert.True(server.ObjectManager.TryGetObject<Building>(BuildingId, out var serverBuilding));
Assert.True(server.ObjectManager.TryGetObject<Town>(TownId, out var serverTown));
// Simulate the field changing
hitpointsIntercept.Invoke(null, new object[] { serverBuilding, newFloat });
currentLevelIntercept.Invoke(null, new object[] { serverBuilding, newInt });
isCurrentlyDefaultIntercept.Invoke(null, new object[] { serverBuilding, true });
buildingProgressIntercept.Invoke(null, new object[] { serverBuilding, newFloat });
serverBuilding.Town = serverTown;
Assert.Equal(newFloat, serverBuilding._hitpoints);
Assert.Equal(newInt, serverBuilding._currentLevel);
Assert.True(serverBuilding.IsCurrentlyDefault);
Assert.Equal(newFloat, serverBuilding.BuildingProgress);
Assert.Equal(serverTown, serverBuilding.Town);
});

// Assert
foreach (var client in Clients)
{
Assert.True(client.ObjectManager.TryGetObject<Building>(BuildingId, out var clientBuilding));
Assert.True(client.ObjectManager.TryGetObject<Town>(TownId, out var clientTown));

Assert.Equal(newFloat, clientBuilding._hitpoints);
Assert.Equal(newInt, clientBuilding._currentLevel);
Assert.True(clientBuilding.IsCurrentlyDefault);
Assert.Equal(newFloat, clientBuilding.BuildingProgress);

Assert.Equal(clientTown, clientBuilding.Town);
}
}
}
}
2 changes: 2 additions & 0 deletions source/E2E.Tests/Util/GameObjectCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Party.PartyComponents;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Settlements.Buildings;
using TaleWorlds.CampaignSystem.Settlements.Workshops;
using TaleWorlds.CampaignSystem.Siege;

Expand Down Expand Up @@ -33,6 +34,7 @@ internal class GameObjectCreator
{ typeof(SiegeEvent), new SiegeEventBuilder() },
{ typeof(Workshop), new WorkshopBuilder() },
{ typeof(WorkshopType), new WorkshopTypeBuilder() },
{ typeof(Building), new BuildingBuilder() },
};

public static T CreateInitializedObject<T>()
Expand Down
14 changes: 14 additions & 0 deletions source/E2E.Tests/Util/ObjectBuilders/BuildingBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Settlements.Buildings;

namespace E2E.Tests.Util.ObjectBuilders;
internal class BuildingBuilder : IObjectBuilder
{
public object Build()
{
var town = GameObjectCreator.CreateInitializedObject<Town>();
var buildingType = new BuildingType("testBuildingType");

return new Building(buildingType, town);
}
}
31 changes: 31 additions & 0 deletions source/GameInterface/Services/Buildings/BuildingSync.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using GameInterface.AutoSync;
using HarmonyLib;
using Helpers;
using System;
using System.Collections.Generic;
using System.Text;
using TaleWorlds.CampaignSystem.CampaignBehaviors;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Settlements.Buildings;

namespace GameInterface.Services.Buildings
{
internal class BuildingSync : IAutoSync
{
public BuildingSync(IAutoSyncBuilder autoSyncBuilder)
{
autoSyncBuilder.AddField(AccessTools.Field(typeof(Building), nameof(Building._hitpoints)));

autoSyncBuilder.AddField(AccessTools.Field(typeof(Building), nameof(Building._currentLevel)));

autoSyncBuilder.AddField(AccessTools.Field(typeof(Building), nameof(Building.IsCurrentlyDefault)));
autoSyncBuilder.AddFieldChangeMethod(AccessTools.Method(typeof(BuildingHelper), nameof(BuildingHelper.ChangeDefaultBuilding)));
autoSyncBuilder.AddFieldChangeMethod(AccessTools.Method(typeof(BuildingsCampaignBehavior), nameof(BuildingsCampaignBehavior.BuildDevelopmentsAtGameStart)));

autoSyncBuilder.AddField(AccessTools.Field(typeof(Building), nameof(Building.BuildingProgress)));
autoSyncBuilder.AddFieldChangeMethod(AccessTools.Method(typeof(Town), nameof(Town.TickCurrentBuilding)));

autoSyncBuilder.AddProperty(AccessTools.Property(typeof(Building), nameof(Building.Town)));
}
}
}

0 comments on commit cd4b891

Please sign in to comment.