Files
abysmal-isle/Scripts/SubSystem/Cellar.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

1376 lines
28 KiB
C#

#region Header
// Vorspire _,-'/-'/ Cellar.cs
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2019 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # The MIT License (MIT) #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Server.ContextMenus;
using Server.Gumps;
using Server.Mobiles;
using Server.Multis;
using Server.Regions;
using VitaNex;
using VitaNex.SuperGumps;
using VitaNex.SuperGumps.UI;
using VitaNex.Targets;
#endregion
namespace Server.Items
{
// Initially separated by a factor of 100 to leave insertion spaces, feel free to use any slots in between.
// After adding a new entry, create the style info for it below and register it like the others.
public enum CellarStyle
{
None = 0,
Grass = 100,
Dirt = 200,
FlagStone = 300,
SandFlagStone = 301,
Stone = 400,
DarkStone = 500,
SandStone = 501,
Marble = 600,
Brick = 601,
Timber = 700,
Crystal = 701,
Jade = 702,
Dungeon = 900,
Blood = 1000
}
public static class CellarStyles
{
public static List<CellarStyleInfo> Styles { get; private set; }
public static CellarStyleInfo GetInfo(this CellarStyle style)
{
return Styles.FirstOrDefault(s => s.Style == style);
}
static CellarStyles()
{
Styles = new List<CellarStyleInfo>();
var dirt = new CellarStyleInfo(CellarStyle.Dirt, "Dirt");
dirt.SetFloor(12788, 12789, 12790, 12791, 12792, 12793, 12794, 12795);
dirt.SetWall(3215, 3216, 3217, 3218);
dirt.SetStairs(17621, 2212);
Styles.Add(dirt);
var grass = new CellarStyleInfo(CellarStyle.Grass, "Grass");
grass.SetFloor(6013, 6014, 6015, 6016, 6017);
grass.SetWall(3215, 3216, 3217, 3218);
grass.SetStairs(17621, 2213);
Styles.Add(grass);
var dungeon = new CellarStyleInfo(CellarStyle.Dungeon, "Dungeon");
dungeon.SetFloor(1339, 1340, 1341, 1342, 1343);
dungeon.SetWall(1955);
dungeon.SetStairs(17621, 1956);
Styles.Add(dungeon);
var flags = new CellarStyleInfo(CellarStyle.FlagStone, "Flagstone");
flags.SetFloor(1276, 1277, 1278, 1279);
flags.SetWall(1872);
flags.SetStairs(17621, 1873);
Styles.Add(flags);
var sandFlags = new CellarStyleInfo(CellarStyle.SandFlagStone, "Sand Flagstone");
sandFlags.SetFloor(1327, 1328, 1329, 1330);
sandFlags.SetWall(1900);
sandFlags.SetStairs(17621, 1901);
Styles.Add(sandFlags);
var sand = new CellarStyleInfo(CellarStyle.SandStone, "Sand Stone");
sand.SetFloor(1181, 1182, 1183, 1184);
sand.SetWall(1900);
sand.SetStairs(17621, 1901);
Styles.Add(sand);
var stone = new CellarStyleInfo(CellarStyle.Stone, "Stone");
stone.SetFloor(1305, 1306, 1307, 1308);
stone.SetWall(1822);
stone.SetStairs(17621, 1823);
Styles.Add(stone);
var darkStone = new CellarStyleInfo(CellarStyle.DarkStone, "Dark Stone");
darkStone.SetFloor(1313, 1314, 1315, 1316);
darkStone.SetWall(1928);
darkStone.SetStairs(17621, 1929);
Styles.Add(darkStone);
var marble = new CellarStyleInfo(CellarStyle.Marble, "Marble");
marble.SetFloor(1297, 1298, 1299, 1300);
marble.SetWall(1801);
marble.SetStairs(17621, 1802);
Styles.Add(marble);
var brick = new CellarStyleInfo(CellarStyle.Brick, "Brick");
brick.SetFloor(1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257);
brick.SetWall(1822);
brick.SetStairs(17621, 1823);
Styles.Add(brick);
var timber = new CellarStyleInfo(CellarStyle.Timber, "Timber");
timber.SetFloor(1193, 1194, 1195, 1196);
timber.SetWall(1848);
timber.SetStairs(17621, 1849);
Styles.Add(timber);
var crystal = new CellarStyleInfo(CellarStyle.Crystal, "Crystal");
crystal.SetFloor(13751, 13752, 13753, 13754, 13755, 13756, 13757);
crystal.SetWall(13778);
crystal.SetStairs(17621, 13780);
Styles.Add(crystal);
var jade = new CellarStyleInfo(CellarStyle.Jade, "Jade");
jade.SetFloor(16815, 16815, 16816, 16817);
jade.SetWall(19207);
jade.SetStairs(17621, 19205);
Styles.Add(jade);
var blood = new CellarStyleInfo(CellarStyle.Blood, "Blood");
blood.SetFloor(2760);
blood.SetWall(8700);
blood.SetStairs(17621, 1979);
Styles.Add(blood);
}
public static CellarStyle ResolveOldID(int itemID)
{
switch (itemID)
{
case 0x177D:
return CellarStyle.Grass;
case 0x31F4:
return CellarStyle.Dirt;
case 0x04FF:
return CellarStyle.FlagStone;
case 0x051A:
return CellarStyle.Stone;
case 0x0521:
return CellarStyle.DarkStone;
case 0x04B8:
return CellarStyle.Timber;
default:
return CellarStyle.None;
}
}
}
public sealed class CellarStyleInfo
{
public CellarStyle Style { get; private set; }
public string Name { get; private set; }
public int[] FloorTiles { get; set; }
public int[] WallTiles { get; set; }
public int StairsDown { get; set; }
public int StairsUp { get; set; }
public CellarStyleInfo(CellarStyle style, string name)
{
Style = style;
Name = name;
FloorTiles = new int[0];
WallTiles = new int[0];
}
public void SetStairs(int down, int up)
{
StairsDown = down;
StairsUp = up;
}
public void SetFloor(params int[] itemIDs)
{
FloorTiles = itemIDs ?? new int[0];
}
public void SetWall(params int[] itemIDs)
{
WallTiles = itemIDs ?? new int[0];
}
}
public interface ICellarComponent
{
bool Deleted { get; }
Point3D Offset { get; set; }
Point3D Location { get; set; }
Map Map { get; set; }
void Delete();
}
public sealed class CellarStairs : AddonComponent, ICellarComponent, ISecurable
{
private SecureLevel _Level = SecureLevel.Anyone;
[CommandProperty(AccessLevel.Counselor, true)]
public CellarStairs Link { get; set; }
[CommandProperty(AccessLevel.Counselor)]
public SecureLevel Level
{
get
{
if (Link != null && _Level != Link._Level)
{
_Level = Link._Level;
}
return _Level;
}
set
{
if (_Level == value)
{
return;
}
_Level = value;
if (Link != null)
{
Link._Level = _Level;
}
}
}
public CellarStairs(int itemID)
: base(itemID)
{
Movable = false;
//UpdateItemData();
}
public CellarStairs(Serial serial)
: base(serial)
{
//UpdateItemData();
}
/*
private void UpdateItemData()
{
var data = ItemData;
var flags = data.Flags;
flags &= ~TileFlag.Impassable;
flags &= ~TileFlag.Wall;
flags |= TileFlag.Surface;
flags |= TileFlag.Bridge;
flags |= TileFlag.NoShoot;
ItemData = new ItemData(Name, flags, data.Weight, data.Quality, data.Quantity, data.Value, data.Height);
}
*/
public void LinkWith(CellarStairs other)
{
if (Link == other || other == null || other == this)
{
return;
}
other.Link = this;
Link = other;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
SetSecureLevelEntry.AddTo(from, this, list);
}
public override void OnDoubleClick(Mobile m)
{
if (Link != null && !Link.Deleted && Link.Map != null && Link.Map != Map.Internal && Link.Location != Point3D.Zero &&
m.Region.IsPartOf(Region.Find(GetWorldLocation(), Map)) && this.CheckDoubleClick(m, true, true, 3))
{
m.MoveToWorld(Link.Location, Link.Map);
}
}
public override bool OnMoveOver(Mobile m)
{
var house = BaseHouse.FindHouseAt(this);
if (house == null || house.CheckSecureAccess(m, this) == SecureAccessResult.Inaccessible)
{
return false;
}
if (Link != null && !Link.Deleted && Link.Map != null && Link.Map != Map.Internal && Link.Location != Point3D.Zero &&
m != null && !m.Deleted)
{
m.MoveToWorld(Link.Location, Link.Map);
}
return false;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(3);
switch (version)
{
case 0:
{
writer.WriteFlag(_Level);
writer.Write(Link);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
_Level = reader.ReadFlag<SecureLevel>();
var link = reader.ReadItem<CellarStairs>();
if (Link == null || Link.Deleted)
{
Link = link;
}
}
break;
}
}
}
public sealed class CellarFloor : AddonComponent, ICellarComponent
{
private CellarAddon Cellar { get; set; }
public CellarFloor(int itemID)
: base(itemID)
{
Name = "Cellar Floor";
Movable = false;
//UpdateItemData();
}
public CellarFloor(Serial serial)
: base(serial)
{
//UpdateItemData();
}
/*
private void UpdateItemData()
{
var data = ItemData;
var flags = data.Flags;
flags &= ~TileFlag.Impassable;
flags &= ~TileFlag.Wall;
flags |= TileFlag.Surface;
ItemData = new ItemData(Name, flags, data.Weight, data.Quality, data.Quantity, data.Value, data.Height);
}
*/
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.SetVersion(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.GetVersion();
}
}
public sealed class CellarWall : AddonComponent, ICellarComponent
{
private CellarAddon Cellar { get; set; }
public CellarWall(int itemID)
: base(itemID)
{
Name = "Cellar Wall";
Movable = false;
//UpdateItemData();
}
public CellarWall(Serial serial)
: base(serial)
{
//UpdateItemData();
}
/*
private void UpdateItemData()
{
var data = ItemData;
var flags = data.Flags;
flags &= ~TileFlag.Surface;
flags |= TileFlag.Impassable;
flags |= TileFlag.NoShoot;
flags |= TileFlag.Wall;
ItemData = new ItemData(Name, flags, data.Weight, data.Quality, data.Quantity, data.Value, data.Height);
}
*/
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.SetVersion(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.GetVersion();
}
}
public class CellarAddon : BaseAddon
{
protected sealed class CellarPlaceholder : AddonComponent, ICellarComponent
{
public CellarPlaceholder(int itemID)
: base(itemID)
{
Name = "Cellar Placeholder";
Movable = false;
}
public CellarPlaceholder(Serial serial)
: base(serial)
{ }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.SetVersion(0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
reader.GetVersion();
}
}
public static List<CellarAddon> Cellars { get; private set; }
static CellarAddon()
{
Cellars = new List<CellarAddon>();
}
public static void Configure()
{
EventSink.ServerStarted += () =>
{
var i = Cellars.Count;
while (--i >= 0)
{
Cellars[i].InvalidateComponents();
}
};
CommandUtility.Register(
"Cellar",
AccessLevel.Counselor,
e =>
{
var house = BaseHouse.FindHouseAt(e.Mobile);
if (house == null)
{
e.Mobile.SendMessage("You must be inside a house to use that command.");
return;
}
#if ServUO
var cellar = house.Addons.Keys.OfType<CellarAddon>().FirstOrDefault();
#else
var cellar = house.Addons.OfType<CellarAddon>().FirstOrDefault();
#endif
if (cellar == null)
{
e.Mobile.SendMessage("This house does not have a cellar.");
return;
}
e.Mobile.SendGump(new PropertiesGump(e.Mobile, cellar));
});
}
public static bool CanPlace(Mobile m, Point3D p, out BaseHouse house, bool message = true)
{
house = null;
if (m == null || p == Point3D.Zero)
{
return false;
}
var r = m.Region.GetRegion<HouseRegion>();
if (r == null || r.House == null || r.House.Deleted || r.House.Map == null || r.House.Map == Map.Internal)
{
if (message)
{
m.SendMessage(0x22, "You must be inside a house to build a cellar.");
}
return false;
}
house = r.House;
#if ServUO
if (house.Addons.Keys.OfType<CellarAddon>().Any())
#else
if (house.Addons.OfType<CellarAddon>().Any())
#endif
{
if (message)
{
m.SendMessage(0x22, "There is already a cellar in this house.");
}
return false;
}
if (!house.Region.Contains(p))
{
if (message)
{
m.SendMessage(0x22, "You may only build a cellar inside a house.");
}
return false;
}
// 10z allows for the ground floor tile height, house foundation surface tops are typically z + 7
if (Math.Abs(house.Z - p.Z) > 10)
{
if (message)
{
m.SendMessage(0x22, "You may only build a cellar on the first floor of a house.");
}
return false;
}
if (m.AccessLevel >= AccessLevel.GameMaster)
{
return true;
}
if (!house.IsOwner(m))
{
if (message)
{
m.SendMessage(0x22, "Only the house owner may build a cellar.");
}
return false;
}
if (!house.Map.CanFit(p.X, p.Y, p.Z, 20, true, false, true))
{
if (message)
{
m.SendMessage(0x22, "The cellar can't be built here because something is blocking the location.");
}
return false;
}
return true;
}
public override BaseAddonDeed Deed { get { return new CellarDeed(_Style); } }
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public CellarStyle Style
{
get { return _Style; }
set
{
if (_Style == value)
{
return;
}
_Style = value;
if (_Style != CellarStyle.None)
{
UpdateComponents();
}
}
}
public void UpdateComponents()
{
var info = _Style.GetInfo();
if (info == null)
{
return;
}
if (_FloorTiles.Count == 0 || _WallTiles.Count == 0)
{
if (House == null)
{
House = BaseHouse.FindHouseAt(_Placeholder as Item ?? this);
}
if (House != null)
{
ClearComponents(true);
GenerateComponents();
}
}
foreach (var s in _FloorTiles.Where(s => s != null && !s.Deleted))
{
s.ItemID = info.FloorTiles.GetRandom();
}
foreach (var s in _WallTiles.Where(s => s != null && !s.Deleted))
{
s.ItemID = info.WallTiles.GetRandom();
}
if (StairsDown != null)
{
StairsDown.ItemID = info.StairsDown;
}
if (StairsUp != null)
{
StairsUp.ItemID = info.StairsUp;
}
}
[CommandProperty(AccessLevel.Counselor, true)]
public BaseHouse House { get; private set; }
[CommandProperty(AccessLevel.Counselor, true)]
public CellarStairs StairsDown { get; private set; }
[CommandProperty(AccessLevel.Counselor, true)]
public CellarStairs StairsUp { get; private set; }
private CellarPlaceholder _Placeholder;
private List<CellarFloor> _FloorTiles;
private List<CellarWall> _WallTiles;
private CellarStyle _Style;
private bool _Chopping;
[Constructable]
public CellarAddon()
: this(CellarStyle.Dirt)
{ }
[Constructable]
public CellarAddon(CellarStyle style)
{
_Style = style;
_FloorTiles = new List<CellarFloor>();
_WallTiles = new List<CellarWall>();
_Placeholder = AddComponent(new CellarPlaceholder(0xF39), Point3D.Zero);
Cellars.Add(this);
}
public CellarAddon(Serial serial)
: base(serial)
{
Cellars.Add(this);
}
public override void OnChop(Mobile m)
{
if (House == null || House.Deleted)
{
House = BaseHouse.FindHouseAt(this);
}
if (House == null || House.Deleted || _Chopping || !(m is PlayerMobile))
{
return;
}
if (!House.IsOwner(m))
{
m.SendMessage(0x22, "Only the house owner may demolish the cellar.");
return;
}
_Chopping = true;
ConfirmDialogGump g = null;
g = new ConfirmDialogGump((PlayerMobile)m)
{
Title = "Demolish Cellar?",
Html =
String.Format(
"Demolishing this cellar will cause all contents to be moved to {0}.\nClick OK to to demolish this cellar.",
House is HouseFoundation ? "the moving crate" : "the cellar entrance").WrapUOHtmlColor(Color.OrangeRed),
AcceptHandler = b =>
{
g = null;
_Chopping = false;
Demolish(m);
},
CancelHandler = b => _Chopping = false
};
g.Send();
Timer.DelayCall(
TimeSpan.FromSeconds(10.0),
() =>
{
if (g == null || !g.IsOpen)
{
return;
}
m.SendMessage(0x22, "Your time to select an option has expired and the demolition has been cancelled.");
g.Close(true);
_Chopping = false;
});
}
public override void Delete()
{
Demolish(null);
}
public override void OnDelete()
{
base.OnDelete();
Cellars.Remove(this);
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
Cellars.Remove(this);
}
public void Demolish(Mobile m)
{
if (StairsDown == null || StairsUp == null)
{
return;
}
if (House == null || House.Deleted)
{
House = BaseHouse.FindHouseAt(this);
}
var loc = StairsDown.Location;
var map = StairsDown.Map;
if (House != null)
{
House.Region.Area.Select(r => new Rectangle3D(r.Start.ToPoint3D(Region.MinZ + 1), r.End.ToPoint3D(House.Z - 20)))
.ForEach(
r =>
{
var entities = r.GetEntities(map);
entities.RemoveAll(
e =>
e == null || e == this || e.Deleted || e == House || e == House.Sign || e == House.MovingCrate ||
e.Z >= House.Z - 20 || e == StairsDown || e == StairsUp || e == _Placeholder || Components.Exists(c => c == e) ||
e is ICellarComponent /* || House.Statics.Contains(e)*/);
entities.OfType<Mobile>().ForEach(
e =>
{
e.MoveToWorld(House.BanLocation, House.Map);
entities.Remove(e);
});
entities.OfType<IAddon>().ForEach(
e =>
{
var d = e.Deed;
if (d != null)
{
((IEntity)e).Delete();
entities.Add(d);
}
entities.Remove((IEntity)e);
});
entities.OfType<Item>().ForEach(
e =>
{
if (!e.Movable && !e.IsLockedDown && !e.IsSecure)
{
return;
}
if (m != null)
{
if (e.IsSecure)
{
House.ReleaseSecure(m, e);
}
if (e.IsLockedDown)
{
House.Release(m, e);
}
}
else
{
if (e.IsSecure)
{
e.IsSecure = e.IsLockedDown = false;
e.Movable = !(e is BaseAddonContainer);
e.SetLastMoved();
var c = House.Secures.Count;
while (--c >= 0)
{
if (c >= House.Secures.Count)
{
continue;
}
#if ServUO
var si = House.Secures[c];
#else
var si = House.Secures[c] as SecureInfo;
#endif
if (si == null || si.Item == e)
{
House.Secures.RemoveAt(c);
}
}
}
if (e.IsLockedDown)
{
e.IsLockedDown = false;
e.SetLastMoved();
House.LockDowns.Remove(e);
}
}
if (House is HouseFoundation)
{
House.DropToMovingCrate(e);
}
else
{
e.MoveToWorld(loc, map);
}
entities.Remove(e);
});
entities.Free(true);
});
}
ClearComponents(false);
if (m != null)
{
base.OnChop(m);
}
else
{
base.Delete();
}
if (House != null)
{
House.Addons.Remove(this);
House = null;
}
}
public override void OnMapChange()
{
base.OnMapChange();
if (!World.Loading && Map != null && Map != Map.Internal)
{
GenerateComponents();
}
}
public override void OnLocationChange(Point3D oldLoc)
{
base.OnLocationChange(oldLoc);
if (!World.Loading && Map != null && Map != Map.Internal)
{
GenerateComponents();
}
}
public void ClearComponents(bool holdPlace)
{
var comp = Components.Where(c => c != null && !c.Deleted).ToArray();
_FloorTiles.Free(true);
_WallTiles.Free(true);
Components.Free(true);
foreach (var c in comp)
{
c.Addon = null;
c.Delete();
}
if (holdPlace)
{
_Placeholder = _Placeholder ?? AddComponent(new CellarPlaceholder(0xF39), Point3D.Zero);
}
}
protected TComponent AddComponent<TComponent>(TComponent c, Point3D o) where TComponent : AddonComponent
{
AddComponent(c, o.X, o.Y, o.Z);
return c;
}
public void GenerateComponents()
{
if (Deleted || Map == null || Map == Map.Internal || Location == Point3D.Zero)
{
return;
}
if (House == null || House.Deleted)
{
House = BaseHouse.FindHouseAt(this);
}
if (House == null || House.Deleted || House.Area == null || House.Area.Length == 0 || _Placeholder == null ||
_Placeholder.Deleted)
{
House = null;
return;
}
if (_Style == CellarStyle.None)
{
_Style = CellarStyle.Dirt;
}
var p = _Placeholder.Location;
var o = _Placeholder.Offset;
Components.Remove(_Placeholder);
_Placeholder.Addon = null;
_Placeholder.Delete();
_Placeholder = null;
var s = Style.GetInfo();
AddComponent(StairsDown = new CellarStairs(s.StairsDown), o);
var floorPoints = new List<Point2D>();
var wallPoints = new List<Point2D>();
foreach (var r in House.Region.Area)
{
floorPoints.AddRange(r.EnumeratePoints2D().Not(floorPoints.Contains));
}
floorPoints.ForEach(
f =>
{
var points = new[]
{
f.Clone2D(-1, -1), //nw
f.Clone2D(0, -1), //n
f.Clone2D(1, -1), //ne
f.Clone2D(1), //e
f.Clone2D(1, 1), //se
f.Clone2D(0, 1), //s
f.Clone2D(-1, 1), //sw
f.Clone2D(-1) //w
};
wallPoints.AddRange(points.Not(floorPoints.Contains).Not(wallPoints.Contains));
});
foreach (var fp in floorPoints.Select(fp => fp.ToPoint3D(Region.MinZ + 1).Clone3D(-p.X, -p.Y, -p.Z)))
{
_FloorTiles.Add(AddComponent(new CellarFloor(s.FloorTiles.GetRandom()), fp));
}
foreach (var wp in wallPoints.Select(wp => wp.ToPoint3D(Region.MinZ + 1).Clone3D(-p.X, -p.Y, -p.Z)))
{
_WallTiles.Add(AddComponent(new CellarWall(s.WallTiles.GetRandom()), wp));
}
AddComponent(StairsUp = new CellarStairs(s.StairsUp), p.ToPoint3D(Region.MinZ + 1).Clone3D(-p.X, -p.Y, -p.Z));
StairsDown.LinkWith(StairsUp);
#if ServUO
House.Addons[this] = House.Owner;
#else
if (!House.Addons.Contains(this))
{
House.Addons.Add(this);
}
#endif
}
private void InvalidateComponents()
{
if (Deleted || Map == null || Map == Map.Internal)
{
return;
}
if (StairsDown == null || StairsUp == null)
{
var stairs = Components.OfType<CellarStairs>().OrderByDescending(s => s.Z).ToArray();
if (stairs.Length > 1)
{
StairsDown = stairs.First();
StairsUp = stairs.Last();
StairsDown.Link = StairsUp;
StairsUp.Link = StairsDown;
}
}
else if (StairsDown.Link == null || StairsUp.Link == null)
{
StairsDown.Link = StairsUp;
StairsUp.Link = StairsDown;
}
if (_Style == CellarStyle.None)
{
var tiles = new Queue<AddonComponent>(Components);
while (_Style == CellarStyle.None && tiles.Count > 0)
{
var floor = tiles.Dequeue();
if (floor != null)
{
_Style = CellarStyles.ResolveOldID(floor.ItemID);
}
}
tiles.Clear();
}
if (_Style == CellarStyle.None)
{
_Style = CellarStyle.Dirt;
}
UpdateComponents();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.Write(_Placeholder);
writer.WriteItemList(_FloorTiles);
writer.WriteItemList(_WallTiles);
writer.WriteFlag(_Style);
writer.Write(House);
writer.Write(StairsDown);
writer.Write(StairsUp);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
_Placeholder = reader.ReadItem<CellarPlaceholder>();
_FloorTiles = reader.ReadStrongItemList<CellarFloor>();
_WallTiles = reader.ReadStrongItemList<CellarWall>();
_Style = reader.ReadFlag<CellarStyle>();
House = reader.ReadItem<BaseHouse>();
StairsDown = reader.ReadItem<CellarStairs>();
StairsUp = reader.ReadItem<CellarStairs>();
}
break;
}
}
}
public class CellarDeed : BaseAddonDeed
{
public override BaseAddon Addon { get { return new CellarAddon(Style); } }
[CommandProperty(AccessLevel.Counselor, AccessLevel.GameMaster)]
public CellarStyle Style { get; set; }
[Constructable]
public CellarDeed()
: this(CellarStyle.None)
{ }
[Constructable]
public CellarDeed(CellarStyle style)
{
Style = style;
Name = "Cellar Deed";
LootType = LootType.Blessed;
}
public CellarDeed(Serial serial)
: base(serial)
{ }
public override void OnSingleClick(Mobile m)
{
base.OnSingleClick(m);
if (Style != CellarStyle.None)
{
LabelTo(m, "[Floor: {0}]", Style.ToString().SpaceWords());
}
}
public override void OnDoubleClick(Mobile m)
{
if (!this.CheckDoubleClick(m, true, false, 2, true) || !(m is PlayerMobile))
{
return;
}
if (Style == CellarStyle.None)
{
new CellarFloorSelector((PlayerMobile)m, this).Send();
}
else
{
BeginTarget(m, Style);
}
}
public void BeginTarget(Mobile m, CellarStyle style)
{
if (m == null || m.Deleted || !this.CheckDoubleClick(m, false, false, 2, true)) //soft dclick check
{
return;
}
m.SendMessage("Pick a place for your cellar stairs.");
GenericSelectTarget<IPoint3D>.Begin(m, (tm, to) => EndTarget(tm, style, to), OnTargetFail, -1, true);
}
public void EndTarget(Mobile m, CellarStyle style, IPoint3D p)
{
BaseHouse house;
var loc = p.Clone3D();
if (!CellarAddon.CanPlace(m, loc, out house))
{
return;
}
Style = style;
var addon = Addon;
addon.MoveToWorld(loc, m.Map);
/*if (house is TownHouse)
{
var th = (TownHouse)house;
if (th.ForSaleSign != null)
{
var z = addon.Components.Min(c => c.Z - 1);
if (th.ForSaleSign.MinZ > z)
{
th.ForSaleSign.MinZ = z;
}
}
}*/
Delete();
}
protected void OnTargetFail(Mobile m)
{ }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
writer.WriteFlag(Style);
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
Style = reader.ReadFlag<CellarStyle>();
break;
}
}
}
public sealed class CellarFloorSelector : MenuGump
{
public CellarDeed Deed { get; set; }
public CellarFloorSelector(PlayerMobile user, CellarDeed deed)
: base(user)
{
Deed = deed;
Modal = true;
CanClose = true;
CanDispose = true;
}
protected override void CompileOptions(MenuGumpOptions list)
{
CellarStyles.Styles.ForEach(s => list.AppendEntry(new ListGumpEntry(s.Name, b => Select(s), HighlightHue)));
base.CompileOptions(list);
}
public override void CompileEntryLayout(
SuperGumpLayout layout,
int length,
int index,
int pIndex,
int yOffset,
ListGumpEntry entry)
{
base.CompileEntryLayout(layout, length, index, pIndex, yOffset, entry);
layout.Replace(
"button/list/select/" + index,
() =>
{
var info = CellarStyles.Styles.FirstOrDefault(s => s.Name == entry.Label);
if (info != null && info.Style != CellarStyle.None)
{
AddButton(20, yOffset + 5, 1895, 1896, b => SelectEntry(b, entry));
AddItem(10, yOffset - 5, info.FloorTiles.GetRandom());
}
else
{
AddButton(15, yOffset, 4006, 4007, b => SelectEntry(b, entry));
}
});
}
public void Select(CellarStyleInfo info)
{
if (info != null)
{
User.SendMessage("You have chosen {0}.", info.Name);
if (Deed != null && info.Style != CellarStyle.None)
{
Deed.BeginTarget(User, info.Style);
}
}
Close();
}
}
}