## Summary `BaseCreature` stored the pet owner (`ControlMaster`) and the summoner (`SummonMaster`) in two fields. Every flow that manages pets kept them in step by hand: summon, transfer, stable, claim, ball of summoning and GM obey. They now share one `_master` field, and the two properties read it through the Controlled and Summoned flags: ```csharp ControlMaster => Controlled ? master : null SummonMaster => Controlled && !Summoned ? null : master ``` Every existing reader keeps its meaning: - `ControlMaster` is still "the owner". - `SummonMaster` is still "the summoner, controlled or not". Blade spirits, energy vortexes, clones, undead minions and enraged creatures (a summon master without `Summoned`) never become visible through `ControlMaster`, so the ungated readers (ML notoriety, aggressor entries and similar) behave as before. - Setting `SummonMaster` on a plain pet does nothing, instead of quietly replacing the owner. - `SetControlMaster` now keeps both masters in step, so the hand-written `SummonMaster` copies are removed from ball of summoning, GM obey, pet transfer, auto-stable and claim, the animal trainer's stable and claim, and jail stabling. ## Serialization BaseCreature moves to v24 with one serialized master (slot 15); the old `SummonMaster` slot is dropped. - `MigrateFrom(V23Content)` resolves absent fields through the same default-value methods the live reader uses. - A save that carried both masters (a summon traded before ownership followed transfers) resolves to the owner. Legacy pre-codegen streams follow the same rule. Requires `ModernUO.Serialization.Generator` 4.2.0 (#2671). `UOContent.Tests` was still on 4.1.0 and is bumped to match. ## Test plan - [x] `MasterShapes_RoundTrip`: controlled pet, controlled summon, energy vortex, enraged creature - [x] `SummonMaster_OnPlainPet_KeepsTheOwner`: owner and follower counts unchanged - [x] `LegacyV22Stream_DifferingMasters_OwnerWins` - [x] `V23Stream_MigratesToOneMaster_AndDefaultsAbsentFields`: both master slots -> owner; flags past bit 32; absent fields take class defaults - [x] UOContent.Tests (1168 passed, 2 skipped) and Server.Tests (907) green
27 lines
1.4 KiB
XML
27 lines
1.4 KiB
XML
<Project Sdk="Microsoft.NET.Sdk">
|
|
<PropertyGroup>
|
|
<IsPackable>false</IsPackable>
|
|
<Configurations>Debug;Release;Analyze</Configurations>
|
|
</PropertyGroup>
|
|
<ItemGroup>
|
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
|
|
<PackageReference Include="xunit" Version="2.9.3" />
|
|
<PackageReference Include="xunit.runner.visualstudio" Version="4.0.0">
|
|
<PrivateAssets>all</PrivateAssets>
|
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
</PackageReference>
|
|
<PackageReference Include="xunit.SkippableFact" Version="1.5.85" />
|
|
<PackageReference Include="ModernUO.Serialization.Generator" Version="4.2.0" PrivateAssets="all" />
|
|
<ProjectReference Include="..\Server\Server.csproj" />
|
|
<ProjectReference Include="..\UOContent\UOContent.csproj" />
|
|
<ProjectReference Include="..\Server.Tests\Server.Tests.csproj" />
|
|
<DataFiles Include="$(SolutionDir)\Distribution\Data\**" />
|
|
</ItemGroup>
|
|
<ItemGroup>
|
|
<None Include="Tests/Engines/Spawners/Fixtures/*.bin" CopyToOutputDirectory="PreserveNewest" />
|
|
<AdditionalFiles Include="Migrations/*.v*.json" />
|
|
</ItemGroup>
|
|
<Target Name="CopyData" AfterTargets="AfterBuild">
|
|
<Copy SourceFiles="@(DataFiles)" DestinationFolder="$(OutDir)\Data\%(RecursiveDir)" />
|
|
</Target>
|
|
</Project>
|