test: harden Rising Colossus restrictions

This commit is contained in:
Crome696 2026-07-10 16:16:47 +02:00
parent c83fb6fe1d
commit 8eafdd7605
2 changed files with 112 additions and 7 deletions

View file

@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.Reflection;
using Server.Items;
using Server.Mobiles;
using Server.Multis;
using Server.Regions;
using Server.Spells;
using Server.Spells.Mysticism;
using Server.Text;
using Xunit;
namespace Server.Tests.Spells.Mysticism;
@ -143,6 +146,34 @@ public class RisingColossusSpellTests
caster.Delete();
}
[Fact]
public void Serialization_PreservesDispelDifficulty()
{
var caster = NewCaster();
var original = new RisingColossus(caster, 120.0, 120.0);
var deserialized = new RisingColossus(caster, 83.0, 0.0);
try
{
var writer = new BufferWriter(true);
original.Serialize(writer);
var buffer = new byte[writer.Position];
writer.Buffer.AsSpan(0, (int)writer.Position).CopyTo(buffer);
var reader = new BufferReader(buffer);
deserialized.Deserialize(reader);
Assert.Equal(buffer.Length, reader.Position);
Assert.Equal(original.DispelDifficulty, deserialized.DispelDifficulty);
}
finally
{
original.Delete();
deserialized.Delete();
caster.Delete();
}
}
[Fact]
public void CheckCast_RejectsInsufficientSkillManaAndFollowerCapacity()
{
@ -184,14 +215,26 @@ public class RisingColossusSpellTests
}
[Fact]
public void TargetLocation_RejectsHouseLocations()
public void TargetLocation_RejectsHouseLocationsForTargetAndCaster()
{
var caster = NewCaster();
var outside = new Point3D(6200, 500, 0);
var houseLocation = FindSpawnLocation();
var outside = new Point3D(houseLocation.X + 10, houseLocation.Y + 10, houseLocation.Z);
var house = new TestHouse(caster);
house.MoveToWorld(houseLocation, Map.Felucca);
Assert.False(RisingColossusSpell.IsHouseLocation(caster, outside, Map.Felucca));
try
{
Assert.True(RisingColossusSpell.IsHouseLocation(caster, houseLocation, Map.Felucca));
caster.Delete();
caster.MoveToWorld(houseLocation, Map.Felucca);
Assert.True(RisingColossusSpell.IsHouseLocation(caster, outside, Map.Felucca));
}
finally
{
house.Delete();
caster.Delete();
}
}
[Fact]
@ -235,6 +278,41 @@ public class RisingColossusSpellTests
}
}
[Fact]
public void TargetLocation_RejectsCustomNoSummonRegion()
{
var previousExpansion = Core.Expansion;
Core.Expansion = Expansion.SA;
var caster = NewCaster();
AddReagents(caster);
var summonLocation = FindSpawnLocation();
caster.MoveToWorld(new Point3D(summonLocation.X - 1, summonLocation.Y, summonLocation.Z), Map.Felucca);
var region = new NoSummonRegion(summonLocation);
region.Register();
var spell = new TestRisingColossusSpell(caster);
caster.Spell = spell;
spell.State = SpellState.Sequencing;
try
{
Assert.True(RisingColossusSpell.IsNoSummonRegion(summonLocation, Map.Felucca));
spell.Target(summonLocation);
Assert.Equal(100, caster.Mana);
Assert.Equal(0, caster.Followers);
Assert.Equal(10, caster.Backpack.FindItemByType<DaemonBone>().Amount);
Assert.Null(FindSummon(caster));
}
finally
{
region.Unregister();
spell.FinishSequence();
caster.Delete();
Core.Expansion = previousExpansion;
}
}
[Fact]
public void BlockedTarget_DoesNotConsumeResourcesOrCreateSummon()
{
@ -370,6 +448,27 @@ public class RisingColossusSpellTests
SpellRegistry.SpecialMoves.Clear();
}
private sealed class NoSummonRegion : BaseRegion
{
public NoSummonRegion(Point3D location) :
base("Rising Colossus NoSummon Test", Map.Felucca, 1000,
new Rectangle3D(location.X, location.Y, -128, 1, 1, 256))
{
}
public override bool AllowSpawn() => false;
}
private sealed class TestHouse : BaseHouse
{
public TestHouse(Mobile owner) : base(0, owner, 0, 0)
{
}
public override Rectangle2D[] Area => [new Rectangle2D(-2, -2, 5, 5)];
public override Point3D BaseBanLocation => Point3D.Zero;
}
private sealed class TestRisingColossusSpell : RisingColossusSpell
{
public TestRisingColossusSpell(Mobile caster) : base(caster)

View file

@ -44,6 +44,9 @@ public class RisingColossusSpell : MysticSpell, ITargetingSpell<IPoint3D>
return caster.Map != null && Region.Find(caster.Location, caster.Map).IsPartOf<HouseRegion>();
}
internal static bool IsNoSummonRegion(Point3D location, Map map) =>
map == null || !Region.Find(location, map).AllowSpawn();
public override bool CheckCast()
{
if (!base.CheckCast())
@ -70,19 +73,22 @@ public class RisingColossusSpell : MysticSpell, ITargetingSpell<IPoint3D>
var map = Caster.Map;
SpellHelper.GetSurfaceTop(ref point);
var location = new Point3D(point);
if (map?.CanSpawnMobile(point.X, point.Y, point.Z) != true || IsHouseLocation(Caster, new Point3D(point), map))
if (map?.CanSpawnMobile(location) != true ||
IsNoSummonRegion(location, map) ||
IsHouseLocation(Caster, location, map))
{
Caster.SendLocalizedMessage(501942); // That location is blocked.
}
else if (SpellHelper.CheckTown(point, Caster) && CheckSequence())
else if (SpellHelper.CheckTown(location, Caster) && CheckSequence())
{
var mysticism = GetBaseSkill(Caster);
var supportSkill = GetDamageSkill(Caster);
var duration = GetDuration(mysticism, supportSkill);
var summon = new RisingColossus(Caster, mysticism, supportSkill);
if (BaseCreature.Summon(summon, false, Caster, new Point3D(point), 0x656, duration))
if (BaseCreature.Summon(summon, false, Caster, location, 0x656, duration))
{
Effects.SendTargetParticles(summon, 0x3728, 10, 10, 0x13AA, (EffectLayer)255);
}