#W# Added Knives TownHouses. Also wrote my own static house system that is configured with a cfg file.

This commit is contained in:
WarrentyExpired 2026-08-24 19:15:14 -04:00
parent 3132211847
commit dc5e0577fd
31 changed files with 7009 additions and 11 deletions

View file

@ -0,0 +1,69 @@
using System;
using System.Collections;
using Server;
using Server.Network;
namespace Knives.TownHouses
{
public class Errors
{
private static ArrayList s_ErrorLog = new ArrayList();
private static ArrayList s_Checked = new ArrayList();
public static ArrayList ErrorLog{ get{ return s_ErrorLog; } }
public static ArrayList Checked{ get{ return s_Checked; } }
public static void Initialize()
{
RUOVersion.AddCommand("TownHouseErrors", AccessLevel.Counselor, new TownHouseCommandHandler(OnErrors));
RUOVersion.AddCommand("the", AccessLevel.Counselor, new TownHouseCommandHandler(OnErrors));
EventSink.Login += new LoginEventHandler( OnLogin );
}
private static void OnErrors( CommandInfo e )
{
if ( e.ArgString == null || e.ArgString == "" )
new ErrorsGump( e.Mobile );
else
Report( e.ArgString + " - " + e.Mobile.Name );
}
private static void OnLogin( LoginEventArgs e )
{
if ( e.Mobile.AccessLevel != AccessLevel.Player
&& s_ErrorLog.Count != 0
&& !s_Checked.Contains( e.Mobile ) )
new ErrorsNotifyGump( e.Mobile );
}
public static void Report( string error )
{
s_ErrorLog.Add( String.Format( "<B>{0}</B><BR>{1}<BR>", DateTime.Now, error ) );
s_Checked.Clear();
Notify();
}
private static void Notify()
{
foreach( NetState state in NetState.Instances )
{
if ( state.Mobile == null )
continue;
if ( state.Mobile.AccessLevel != AccessLevel.Player )
Notify( state.Mobile );
}
}
public static void Notify( Mobile m )
{
if ( m.HasGump( typeof( ErrorsGump ) ) )
new ErrorsGump( m );
else
new ErrorsNotifyGump( m );
}
}
}

View file

@ -0,0 +1,55 @@
using System;
using Server;
namespace Knives.TownHouses
{
public class ErrorsGump : GumpPlusLight
{
public ErrorsGump( Mobile m ) : base( m, 100, 100 )
{
Errors.Checked.Add(m);
m.CloseGump( typeof( ErrorsGump ) );
}
protected override void BuildGump()
{
int width = 400;
int y = 10;
AddHtml(0, y, width, "<CENTER>TownHouse Errors");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddButton(width - 20, y, 0x5689, 0x5689, "Help", new GumpCallback(Help));
string str = HTML.Black;
foreach( string text in Errors.ErrorLog )
str += text;
AddHtml( 20, y+=25, width-40, 200, str, true, true );
y += 200;
if ( Owner.AccessLevel >= AccessLevel.Administrator )
{
AddButton( width/2-30, y+=10, 0x98B, 0x98B, "Clear", new GumpCallback( ClearLog ) );
AddHtml( width/2-23, y+3, 51, "<CENTER>Clear");
}
AddBackgroundZero(0, 0, width, y + 40, 0x1400);
}
private void Help()
{
NewGump();
new InfoGump( Owner, 300, 300, HTML.White + " Errors reported by either the TownHouse system or other staff members! Administrators have the power to clear this list. All staff members can report an error using the [TownHouseErrors command.", true );
}
private void ClearLog()
{
Errors.ErrorLog.Clear();
NewGump();
}
}
}

View file

@ -0,0 +1,24 @@
using System;
using Server;
namespace Knives.TownHouses
{
public class ErrorsNotifyGump : GumpPlusLight
{
public ErrorsNotifyGump( Mobile m ) : base( m, 250, 100 )
{
m.CloseGump( typeof( ErrorsNotifyGump ) );
}
protected override void BuildGump()
{
AddButton( 0, 0, 0x1590, 0x1590, "Errors", new GumpCallback( Errors ) );
AddItem(20, 20, 0x22C4);
}
private void Errors()
{
new ErrorsGump( Owner );
}
}
}

View file

@ -0,0 +1,23 @@
using System;
using Server;
using Server.Gumps;
namespace Knives.TownHouses
{
public class BackgroundPlus : GumpBackground
{
private bool c_Override;
public bool Override{ get{ return c_Override; } set{ c_Override = value; } }
public BackgroundPlus( int x, int y, int width, int height, int back ) : base( x, y, width, height, back )
{
c_Override = true;
}
public BackgroundPlus( int x, int y, int width, int height, int back, bool over ) : base( x, y, width, height, back )
{
c_Override = over;
}
}
}

View file

@ -0,0 +1,37 @@
using System;
using Server;
using Server.Gumps;
namespace Knives.TownHouses
{
public class ButtonPlus : GumpButton
{
private string c_Name;
private object c_Callback;
private object c_Param;
public string Name{ get{ return c_Name; } }
public ButtonPlus( int x, int y, int normalID, int pressedID, int buttonID, string name, GumpCallback back ) : base( x, y, normalID, pressedID, buttonID, GumpButtonType.Reply, 0 )
{
c_Name = name;
c_Callback = back;
c_Param = "";
}
public ButtonPlus( int x, int y, int normalID, int pressedID, int buttonID, string name, GumpStateCallback back, object param ) : base( x, y, normalID, pressedID, buttonID, GumpButtonType.Reply, 0 )
{
c_Name = name;
c_Callback = back;
c_Param = param;
}
public void Invoke()
{
if ( c_Callback is GumpCallback )
((GumpCallback)c_Callback)();
else if ( c_Callback is GumpStateCallback )
((GumpStateCallback)c_Callback)( c_Param );
}
}
}

View file

@ -0,0 +1,261 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Network;
namespace Knives.TownHouses
{
public delegate void GumpStateCallback(object obj);
public delegate void GumpCallback();
public abstract class GumpPlusLight : Gump
{
public static void RefreshGump(Mobile m, Type type)
{
if (m.NetState == null)
return;
foreach (Gump g in m.NetState.Gumps)
if (g is GumpPlusLight && g.GetType() == type)
{
m.CloseGump(type);
((GumpPlusLight)g).NewGump();
return;
}
}
private Mobile c_Owner;
private Hashtable c_Buttons, c_Fields;
public Mobile Owner{ get{ return c_Owner; } }
public GumpPlusLight( Mobile m, int x, int y ) : base( x, y )
{
c_Owner = m;
c_Buttons = new Hashtable();
c_Fields = new Hashtable();
Timer.DelayCall(TimeSpan.FromSeconds(0), new TimerCallback(NewGump));
}
public void Clear()
{
Entries.Clear();
c_Buttons.Clear();
c_Fields.Clear();
}
public virtual void NewGump()
{
NewGump( true );
}
public void NewGump( bool clear )
{
if ( clear )
Clear();
BuildGump();
c_Owner.SendGump( this );
}
public void SameGump()
{
c_Owner.SendGump( this );
}
protected abstract void BuildGump();
private int UniqueButton()
{
int random = 0;
do
{
random = Utility.Random( 20000 );
}while( c_Buttons[random] != null );
return random;
}
private int UniqueTextId()
{
int random = 0;
do
{
random = Utility.Random(20000);
} while (c_Buttons[random] != null);
return random;
}
public void AddBackgroundZero(int x, int y, int width, int height, int back)
{
AddBackgroundZero(x, y, width, height, back, true);
}
public void AddBackgroundZero(int x, int y, int width, int height, int back, bool over)
{
BackgroundPlus plus = new BackgroundPlus(x, y, width, height, back, over);
Entries.Insert(0, plus);
}
public new void AddBackground(int x, int y, int width, int height, int back)
{
AddBackground(x, y, width, height, back, true);
}
public void AddBackground(int x, int y, int width, int height, int back, bool over)
{
BackgroundPlus plus = new BackgroundPlus(x, y, width, height, back, over);
Add(plus);
}
public void AddButton(int x, int y, int id, GumpCallback callback)
{
AddButton(x, y, id, id, "None", callback);
}
public void AddButton(int x, int y, int id, GumpStateCallback callback, object arg)
{
AddButton(x, y, id, id, "None", callback, arg);
}
public void AddButton(int x, int y, int id, string name, GumpCallback callback)
{
AddButton(x, y, id, id, name, callback);
}
public void AddButton(int x, int y, int id, string name, GumpStateCallback callback, object arg)
{
AddButton(x, y, id, id, name, callback, arg);
}
public void AddButton(int x, int y, int up, int down, GumpCallback callback)
{
AddButton(x, y, up, down, "None", callback);
}
public void AddButton(int x, int y, int up, int down, string name, GumpCallback callback)
{
int id = UniqueButton();
ButtonPlus button = new ButtonPlus( x, y, up, down, id, name, callback );
Add( button );
c_Buttons[id] = button;
}
public void AddButton( int x, int y, int up, int down, GumpStateCallback callback, object arg )
{
AddButton( x, y, up, down, "None", callback, arg );
}
public void AddButton( int x, int y, int up, int down, string name, GumpStateCallback callback, object arg )
{
int id = UniqueButton();
ButtonPlus button = new ButtonPlus( x, y, up, down, id, name, callback, arg );
Add( button );
c_Buttons[id] = button;
}
public void AddHtml(int x, int y, int width, string text)
{
AddHtml(x, y, width, 21, HTML.White + text, false, false, true, false);
}
public void AddHtml(int x, int y, int width, string text, bool over)
{
AddHtml(x, y, width, 21, HTML.White + text, false, false, over, false);
}
public void AddHtml(int x, int y, int width, int height, string text, bool back, bool scroll)
{
AddHtml(x, y, width, height, HTML.White + text, back, scroll, false);
}
public void AddHtml(int x, int y, int width, int height, string text, bool back, bool scroll, bool over, bool useBlackTextOutline = false)
{
HtmlPlus html = new HtmlPlus(x, y, width, height, HTML.White + text, back, scroll, over);
Add(html);
}
public void AddTextField(int x, int y, int width, int height, int color, int back, string name, string text)
{
int id = UniqueTextId();
AddImageTiled(x, y, width, height, back);
base.AddTextEntry(x, y, width, height, color, id, text);
c_Fields[id] = name;
c_Fields[name] = text;
}
public string GetTextField( string name )
{
if ( c_Fields[name] == null )
return "";
return c_Fields[name].ToString();
}
public int GetTextFieldInt(string name)
{
return Utility.ToInt32(GetTextField(name));
}
protected virtual void OnClose()
{
}
public override void OnResponse( NetState state, RelayInfo info )
{
string name = "";
try
{
if (info.ButtonID == -5)
{
NewGump();
return;
}
foreach (TextRelay t in info.TextEntries)
c_Fields[c_Fields[t.EntryID].ToString()] = t.Text;
if (info.ButtonID == 0)
OnClose();
if (c_Buttons[info.ButtonID] == null || !(c_Buttons[info.ButtonID] is ButtonPlus))
return;
name = ((ButtonPlus)c_Buttons[info.ButtonID]).Name;
((ButtonPlus)c_Buttons[info.ButtonID]).Invoke();
}
catch (Exception e)
{
Errors.Report("An error occured during a gump response. More information can be found on the console.");
if (name != "")
Console.WriteLine("{0} gump name triggered an error.", name);
Console.WriteLine(e.Message);
Console.WriteLine(e.Source);
Console.WriteLine(e.StackTrace);
}
}
}
}

View file

@ -0,0 +1,20 @@
using System;
using Server;
namespace Knives.TownHouses
{
public class HTML
{
public static string White{ get { return "<BASEFONT Color=#FBFBFB>"; } }
public static string Red{ get { return "<BASEFONT COLOR=#FF0000>"; } }
public static string AshRed{ get { return "<BASEFONT COLOR=#FF9999>"; } }
public static string Green{ get { return "<BASEFONT COLOR=#00FF00>"; } }
public static string Blue{ get { return "<BASEFONT COLOR=#0000FF>"; } }
public static string Gray{ get { return "<BASEFONT COLOR=#999999>"; } }
public static string DarkGray{ get { return "<BASEFONT COLOR=#222222>"; } }
public static string Black{ get { return "<BASEFONT COLOR=#111111>"; } }
public static string Yellow{ get { return "<BASEFONT COLOR=#FFFF00>"; } }
public static string Purple{ get { return "<BASEFONT COLOR=#990099>"; } }
public static string LightPurple{ get { return "<BASEFONT COLOR=#CC00FF>"; } }
}
}

View file

@ -0,0 +1,23 @@
using System;
using Server;
using Server.Gumps;
namespace Knives.TownHouses
{
public class HtmlPlus : GumpHtml
{
private bool c_Override;
public bool Override{ get{ return c_Override; } set{ c_Override = value; } }
public HtmlPlus( int x, int y, int width, int height, string text, bool back, bool scroll ) : base( x, y, width, height, text, back, scroll )
{
c_Override = true;
}
public HtmlPlus( int x, int y, int width, int height, string text, bool back, bool scroll, bool over ) : base( x, y, width, height, text, back, scroll )
{
c_Override = over;
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using Server;
using Server.Gumps;
namespace Knives.TownHouses
{
public class InfoGump : GumpPlusLight
{
private int c_Width, c_Height;
private string c_Text;
private bool c_Scroll;
public InfoGump( Mobile m, int width, int height, string text, bool scroll ) : base( m, 100, 100 )
{
c_Width = width;
c_Height = height;
c_Text= text;
c_Scroll = scroll;
NewGump();
}
protected override void BuildGump()
{
AddBackground( 0, 0, c_Width, c_Height, 3600 );
AddHtml( 20, 20, c_Width-40, c_Height-40, HTML.White + c_Text, false, c_Scroll );
}
}
}

View file

@ -0,0 +1,117 @@
using System;
using Server;
namespace Knives.TownHouses
{
public class ContractConfirmGump : GumpPlusLight
{
private RentalContract c_Contract;
public ContractConfirmGump( Mobile m, RentalContract rc ) : base( m, 100, 100 )
{
m.CloseGump( typeof( ContractConfirmGump ) );
c_Contract = rc;
}
protected override void BuildGump()
{
int width = 300;
int y = 0;
if ( c_Contract.RentalClient == null )
AddHtml( 0, y+5, width, HTML.Black + "<CENTER>Rent this House?");
else
AddHtml( 0, y+5, width, HTML.Black + "<CENTER>Rental Agreement");
string text = String.Format( " I, {0}, agree to rent this property from {1} for the sum of {2} every {3}. " +
"The funds for this payment will be taken directly from my bank. In the case where " +
"I cannot pay this fee, the property will return to {1}. I may cancel this agreement at any time by " +
"demolishing the property. {1} may also cancel this agreement at any time by either demolishing their " +
"property or canceling the contract, in which case your security deposit will be returned.",
c_Contract.RentalClient == null ? "_____" : c_Contract.RentalClient.Name,
c_Contract.RentalMaster.Name,
c_Contract.Free ? 0 : c_Contract.Price,
c_Contract.PriceTypeShort.ToLower() );
text += "<BR> Here is some more info reguarding this property:<BR>";
text += String.Format( "<CENTER>Lockdowns: {0}<BR>", c_Contract.Locks );
text += String.Format( "Secures: {0}<BR>", c_Contract.Secures );
text += String.Format( "Floors: {0}<BR>", (c_Contract.MaxZ-c_Contract.MinZ < 200) ? (c_Contract.MaxZ-c_Contract.MinZ)/20+1 : 1 );
text += String.Format( "Space: {0} cubic units", c_Contract.CalcVolume() );
AddHtml( 40, y+=30, width-60, 200, HTML.Black + text, false, true );
y += 200;
if ( c_Contract.RentalClient == null )
{
AddHtml( 60, y+=20, 60, HTML.Black + "Preview");
AddButton( 40, y+3, 0x837, 0x838, "Preview", new GumpCallback( Preview ) );
bool locsec = c_Contract.ValidateLocSec();
if ( Owner != c_Contract.RentalMaster && locsec )
{
AddHtml( width-100, y, 60, HTML.Black + "Accept");
AddButton( width-60, y+3, 0x232C, 0x232D, "Accept", new GumpCallback( Accept ) );
}
else
AddImage( width-60, y-10, 0x232C );
if ( !locsec )
Owner.SendMessage( (Owner == c_Contract.RentalMaster ? "You don't have the lockdowns or secures available for this contract." : "The owner of this contract cannot rent this property at this time.") );
}
else
{
if ( Owner == c_Contract.RentalMaster )
{
AddHtml( 60, y+=20, 100, HTML.Black + "Cancel Contract");
AddButton( 40, y+3, 0x837, 0x838, "Cancel Contract", new GumpCallback( CancelContract ) );
}
else
AddImage( width-60, y+=20, 0x232C );
}
AddBackgroundZero( 0, 0, width, y+23, 0x24A4 );
}
protected override void OnClose()
{
c_Contract.ClearPreview();
}
private void Preview()
{
c_Contract.ShowAreaPreview(Owner);
NewGump();
}
private void CancelContract()
{
if ( Owner == c_Contract.RentalClient )
c_Contract.House.Delete();
else
c_Contract.Delete();
}
private void Accept()
{
if ( !c_Contract.ValidateLocSec() )
{
Owner.SendMessage( "The owner of this contract cannot rent this property at this time." );
return;
}
c_Contract.Purchase( Owner );
if ( !c_Contract.Owned )
return;
c_Contract.Visible = true;
c_Contract.RentalClient = Owner;
c_Contract.RentalClient.AddToBackpack( new RentalContractCopy( c_Contract ) );
}
}
}

View file

@ -0,0 +1,560 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Knives.TownHouses
{
public class ContractSetupGump : GumpPlusLight
{
public enum Page { Blocks, Floors, Sign, LocSec, Length, Price }
public enum TargetType { SignLoc, MinZ, MaxZ, BlockOne, BlockTwo }
private RentalContract c_Contract;
private Page c_Page;
public ContractSetupGump( Mobile m, RentalContract contract ) : base( m, 50, 50 )
{
m.CloseGump( typeof( ContractSetupGump ) );
c_Contract = contract;
}
protected override void BuildGump()
{
int width = 300;
int y = 0;
switch( c_Page )
{
case Page.Blocks: BlocksPage(width, ref y); break;
case Page.Floors: FloorsPage(width, ref y); break;
case Page.Sign: SignPage(width, ref y); break;
case Page.LocSec: LocSecPage(width, ref y); break;
case Page.Length: LengthPage(width, ref y); break;
case Page.Price: PricePage(width, ref y); break;
}
AddBackgroundZero(0, 0, width, y+40, 3600);
}
private void BlocksPage(int width, ref int y)
{
if ( c_Contract == null )
return;
c_Contract.ShowAreaPreview( Owner );
AddHtml( 0, y+=10, width, "<CENTER>Create the Area");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
y+=25;
if ( !General.HasOtherContract( c_Contract.ParentHouse, c_Contract ) )
{
AddHtml( 60, y, 90, "Entire House");
AddButton( 30, y, c_Contract.EntireHouse ? 0xD3 : 0xD2, "Entire House", new GumpCallback(EntireHouse ));
}
if ( !c_Contract.EntireHouse )
{
AddHtml( 170, y, 70, "Add Area");
AddButton( 240, y, 0x15E1, 0x15E5, "Add Area", new GumpCallback( AddBlock ) );
AddHtml( 170, y+=20, 70, "Clear All");
AddButton( 240, y, 0x15E1, 0x15E5, "Clear All", new GumpCallback( ClearBlocks ) );
}
string helptext = String.Format( " Welcome to the rental contract setup menu! To begin, you must " +
"first create the area which you wish to sell. As seen above, there are two ways to do this: " +
"rent the entire house, or parts of it. As you create the area, a simple preview will show you exactly " +
"what area you've selected so far. You can make all sorts of odd shapes by using multiple areas!" );
AddHtml( 10, y+=35, width-20, 170, helptext, false, false );
y += 170;
if ( c_Contract.EntireHouse || c_Contract.Blocks.Count != 0 )
{
AddHtml( width-60, y+=20, 60, "Next");
AddButton( width-30, y, 0x15E1, 0x15E5, "Next", new GumpStateCallback( ChangePage ), (int)c_Page + ( c_Contract.EntireHouse ? 4 : 1 ) );
}
}
private void FloorsPage(int width, ref int y)
{
AddHtml( 0, y+=10, width, "<CENTER>Floors");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddHtml( 40, y+=25, 80, "Base Floor");
AddButton( 110, y, 0x15E1, 0x15E5, "Base Floor", new GumpCallback( MinZSelect ) );
AddHtml( 160, y, 80, "Top Floor");
AddButton( 230, y, 0x15E1, 0x15E5, "Top Floor", new GumpCallback( MaxZSelect ) );
AddHtml( 100, y+=25, 100, String.Format( "{0} total floor{1}", c_Contract.Floors > 10 ? "1" : "" + c_Contract.Floors, c_Contract.Floors == 1 || c_Contract.Floors > 10 ? "" : "s" ));
string helptext = String.Format( " Now you will need to target the floors you wish to rent out. " +
"If you only want one floor, you can skip targeting the top floor. Everything within the base " +
"and highest floor will come with the rental, and the more floors, the higher the cost later on." );
AddHtml( 10, y+=35, width-20, 120, helptext, false, false );
y += 120;
AddHtml( 30, y+=20, 80, "Previous");
AddButton( 10, y, 0x15E3, 0x15E7, "Previous", new GumpStateCallback( ChangePage ), (int)c_Page-1 );
if ( c_Contract.MinZ != short.MinValue )
{
AddHtml( width-60, y, 60, "Next");
AddButton( width-30, y, 0x15E1, 0x15E5, "Next", new GumpStateCallback( ChangePage ), (int)c_Page+1 );
}
}
private void SignPage(int width, ref int y)
{
if ( c_Contract == null )
return;
c_Contract.ShowSignPreview();
AddHtml( 0, y+=10, width, "<CENTER>Their Sign Location");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddHtml( 100, y+=25, 80, "Set Location");
AddButton( 180, y, 0x15E1, 0x15E5, "Sign Loc", new GumpCallback( SignLocSelect ) );
string helptext = String.Format( " With this sign, the rentee will have all the powers an owner has " +
"over their area. If they use this power to demolish their rental unit, they have broken their " +
"contract and will not receive their security deposit. They can also ban you from their rental home!" );
AddHtml( 10, y+=35, width-20, 110, helptext, false, false );
y += 110;
AddHtml( 30, y+=20, 80, "Previous");
AddButton( 10, y, 0x15E3, 0x15E7, "Previous", new GumpStateCallback( ChangePage ), (int)c_Page-1 );
if ( c_Contract.SignLoc != Point3D.Zero )
{
AddHtml( width-60, y, 60, "Next");
AddButton( width-30, y, 0x15E1, 0x15E5, "Next", new GumpStateCallback( ChangePage ), (int)c_Page+1 );
}
}
private void LocSecPage(int width, ref int y)
{
AddHtml( 0, y+=10, width, "<CENTER>Lockdowns and Secures");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddHtml(0, y += 25, width, "<CENTER>Suggest Secures");
AddButton(width / 2 - 70, y + 3, 0x2716, "Suggest LocSec", new GumpCallback(SuggestLocSec));
AddButton(width / 2 + 60, y + 3, 0x2716, "Suggest LocSec", new GumpCallback(SuggestLocSec));
AddHtml(30, y += 25, width / 2 - 20, "<DIV ALIGN=RIGHT>Secures (Max: " + (General.RemainingSecures(c_Contract.ParentHouse) + c_Contract.Secures) + ")");
AddTextField( width/2+50, y, 50, 20, 0x480, 0xBBC, "Secures", c_Contract.Secures.ToString() );
AddButton(width / 2 + 25, y + 3, 0x2716, "Secures", new GumpCallback(Secures));
AddHtml(30, y += 20, width / 2 - 20, "<DIV ALIGN=RIGHT>Lockdowns (Max: " + (General.RemainingLocks(c_Contract.ParentHouse) + c_Contract.Locks) + ")");
AddTextField( width/2+50, y, 50, 20, 0x480, 0xBBC, "Lockdowns", c_Contract.Locks.ToString() );
AddButton(width / 2 + 25, y + 3, 0x2716, "Lockdowns", new GumpCallback(Lockdowns));
string helptext = String.Format( " Without giving storage, this wouldn't be much of a home! Here you give them lockdowns " +
"and secures from your own home. Use the suggest button for an idea of how much you should give. Be very careful when " +
"renting your property: if you use too much storage you begin to use storage you reserved for your clients. " +
"You will receive a 48 hour warning when this happens, but after that the contract disappears!" );
AddHtml( 10, y+=35, width-20, 180, helptext, false, false );
y += 180;
AddHtml( 30, y+=20, 80, "Previous");
AddButton( 10, y, 0x15E3, 0x15E7, "Previous", new GumpStateCallback( ChangePage ), (int)c_Page-1 );
if ( c_Contract.Locks != 0 && c_Contract.Secures != 0 )
{
AddHtml( width-60, y, 60, "Next");
AddButton( width-30, y, 0x15E1, 0x15E5, "Next", new GumpStateCallback( ChangePage ), (int)c_Page+1 );
}
}
private void LengthPage(int width, ref int y)
{
AddHtml( 0, y+=10, width, "<CENTER>Time Period");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddHtml( 120, y+=25, 50, c_Contract.PriceType);
AddButton( 170, y+8, 0x985, "LengthUp", new GumpCallback( LengthUp ) );
AddButton( 170, y-2, 0x983, "LengthDown", new GumpCallback( LengthDown ) );
string helptext = String.Format( " Every {0} the bank will automatically transfer the rental cost from them to you. " +
"By using the arrows, you can cycle through other time periods to something better fitting your needs.", c_Contract.PriceTypeShort.ToLower() );
AddHtml( 10, y+=35, width-20, 100, helptext, false, false );
y += 100;
AddHtml( 30, y+=20, 80, "Previous");
AddButton( 10, y, 0x15E3, 0x15E7, "Previous", new GumpStateCallback( ChangePage ), (int)c_Page - ( c_Contract.EntireHouse ? 4 : 1 ) );
AddHtml( width-60, y, 60, "Next");
AddButton( width-30, y, 0x15E1, 0x15E5, "Next", new GumpStateCallback( ChangePage ), (int)c_Page+1 );
}
private void PricePage(int width, ref int y)
{
AddHtml( 0, y+=10, width, "<CENTER>Charge Per Period");
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
AddHtml(0, y += 25, width, "<CENTER>Free");
AddButton(width / 2 - 80, y, c_Contract.Free ? 0xD3 : 0xD2, "Free", new GumpCallback(Free));
AddButton(width / 2 + 60, y, c_Contract.Free ? 0xD3 : 0xD2, "Free", new GumpCallback(Free));
if ( !c_Contract.Free )
{
AddHtml( 0, y+=25, width/2-20, "<DIV ALIGN=RIGHT>Per " + c_Contract.PriceTypeShort);
AddTextField( width/2+20, y, 70, 20, 0x480, 0xBBC, "Price", c_Contract.Price.ToString() );
AddButton(width / 2 - 5, y + 3, 0x2716, "Price", new GumpCallback(Price));
AddHtml( 0, y+=20, width, "<CENTER>Suggest");
AddButton(width / 2 - 70, y + 3, 0x2716, "Suggest", new GumpCallback(SuggestPrice));
AddButton(width / 2 + 60, y + 3, 0x2716, "Suggest", new GumpCallback(SuggestPrice));
}
string helptext = String.Format( " Now you can finalize the contract by including your price per {0}. " +
"Once you finalize, the only way you can modify it is to dump it and start a new contract! By " +
"using the suggest button, a price will automatically be figured based on the following:<BR>", c_Contract.PriceTypeShort );
helptext += String.Format( "<CENTER>Volume: {0}<BR>", c_Contract.CalcVolume() );
helptext += String.Format( "Cost per unit: {0} gold</CENTER>", General.SuggestionFactor );
helptext += "<br> You may also give this space away for free using the option above.";
AddHtml( 10, y+=35, width-20, 150, helptext, false, true );
y += 150;
AddHtml( 30, y+=20, 80, "Previous");
AddButton( 10, y, 0x15E3, 0x15E7, "Previous", new GumpStateCallback( ChangePage ), (int)c_Page-1 );
if ( c_Contract.Price != 0 )
{
AddHtml( width-70, y, 60, "Finalize");
AddButton( width-30, y, 0x15E1, 0x15E5, "Finalize", new GumpCallback( FinalizeSetup ) );
}
}
protected override void OnClose()
{
c_Contract.ClearPreview();
}
private void SuggestPrice()
{
if ( c_Contract == null )
return;
c_Contract.Price = c_Contract.CalcVolume()*General.SuggestionFactor;
if ( c_Contract.RentByTime == TimeSpan.FromDays( 1 ) )
c_Contract.Price /= 60;
if ( c_Contract.RentByTime == TimeSpan.FromDays( 7 ) )
c_Contract.Price = (int)((double)c_Contract.Price/8.57);
if ( c_Contract.RentByTime == TimeSpan.FromDays( 30 ) )
c_Contract.Price /= 2;
NewGump();
}
private void SuggestLocSec()
{
int price = c_Contract.CalcVolume()*General.SuggestionFactor;
c_Contract.Secures = price/75;
c_Contract.Locks = c_Contract.Secures/2;
c_Contract.FixLocSec();
NewGump();
}
private void Price()
{
c_Contract.Price = GetTextFieldInt("Price");
Owner.SendMessage("Price set!");
NewGump();
}
private void Secures()
{
c_Contract.Secures = GetTextFieldInt("Secures");
Owner.SendMessage("Secures set!");
NewGump();
}
private void Lockdowns()
{
c_Contract.Locks = GetTextFieldInt("Lockdowns");
Owner.SendMessage("Lockdowns set!");
NewGump();
}
private void ChangePage(object obj)
{
if ( c_Contract == null || !(obj is int) )
return;
c_Contract.ClearPreview();
c_Page = (Page)(int)obj;
NewGump();
}
private void EntireHouse()
{
if ( c_Contract == null || c_Contract.ParentHouse == null )
return;
c_Contract.EntireHouse = !c_Contract.EntireHouse;
c_Contract.ClearPreview();
if ( c_Contract.EntireHouse )
{
ArrayList list = new ArrayList();
bool once = false;
foreach (Rectangle3D rect in RUOVersion.RegionArea(c_Contract.ParentHouse.Region))
{
list.Add(new Rectangle2D(new Point2D(rect.Start.X, rect.Start.Y), new Point2D(rect.End.X, rect.End.Y)));
if (once)
continue;
if (rect.Start.Z >= rect.End.Z)
{
c_Contract.MinZ = rect.End.Z;
c_Contract.MaxZ = rect.Start.Z;
}
else
{
c_Contract.MinZ = rect.Start.Z;
c_Contract.MaxZ = rect.End.Z;
}
once = true;
}
c_Contract.Blocks = list;
}
else
{
c_Contract.Blocks.Clear();
c_Contract.MinZ = short.MinValue;
c_Contract.MaxZ = short.MinValue;
}
NewGump();
}
private void SignLocSelect()
{
Owner.Target = new InternalTarget( this, c_Contract, TargetType.SignLoc );
}
private void MinZSelect()
{
Owner.SendMessage( "Target the base floor for your rental area." );
Owner.Target = new InternalTarget( this, c_Contract, TargetType.MinZ );
}
private void MaxZSelect()
{
Owner.SendMessage( "Target the highest floor for your rental area." );
Owner.Target = new InternalTarget( this, c_Contract, TargetType.MaxZ );
}
private void LengthUp()
{
if ( c_Contract == null )
return;
c_Contract.NextPriceType();
if ( c_Contract.RentByTime == TimeSpan.FromDays( 0 ) )
c_Contract.RentByTime = TimeSpan.FromDays( 1 );
NewGump();
}
private void LengthDown()
{
if ( c_Contract == null )
return;
c_Contract.PrevPriceType();
if ( c_Contract.RentByTime == TimeSpan.FromDays( 0 ) )
c_Contract.RentByTime = TimeSpan.FromDays( 30 );
NewGump();
}
private void Free()
{
c_Contract.Free = !c_Contract.Free;
NewGump();
}
private void AddBlock()
{
Owner.SendMessage( "Target the north western corner." );
Owner.Target = new InternalTarget( this, c_Contract, TargetType.BlockOne );
}
private void ClearBlocks()
{
if ( c_Contract == null )
return;
c_Contract.Blocks.Clear();
c_Contract.ClearPreview();
NewGump();
}
private void FinalizeSetup()
{
if ( c_Contract == null )
return;
if ( c_Contract.Price == 0 )
{
Owner.SendMessage( "You can't rent the area for 0 gold!" );
NewGump();
return;
}
c_Contract.Completed = true;
c_Contract.BanLoc = c_Contract.ParentHouse.Region.GoLocation;
if ( c_Contract.EntireHouse )
{
Point3D point = c_Contract.ParentHouse.Sign.Location;
c_Contract.SignLoc = new Point3D( point.X, point.Y, point.Z-5 );
c_Contract.Secures = Core.AOS ? c_Contract.ParentHouse.GetAosMaxSecures() : c_Contract.ParentHouse.MaxSecures;
c_Contract.Locks = Core.AOS ? c_Contract.ParentHouse.GetAosMaxLockdowns() : c_Contract.ParentHouse.MaxLockDowns;
}
Owner.SendMessage( "You have finalized this rental contract. Now find someone to sign it!" );
}
private class InternalTarget : Target
{
private ContractSetupGump c_Gump;
private RentalContract c_Contract;
private TargetType c_Type;
private Point3D c_BoundOne;
public InternalTarget( ContractSetupGump gump, RentalContract contract, TargetType type ) : this( gump, contract, type, Point3D.Zero ){}
public InternalTarget( ContractSetupGump gump, RentalContract contract, TargetType type, Point3D point ) : base( 20, true, TargetFlags.None )
{
c_Gump = gump;
c_Contract = contract;
c_Type = type;
c_BoundOne = point;
}
protected override void OnTarget( Mobile m, object o )
{
IPoint3D point = (IPoint3D)o;
if ( c_Contract == null || c_Contract.ParentHouse == null )
return;
if ( !c_Contract.ParentHouse.Region.Contains( new Point3D( point.X, point.Y, point.Z ) ) )
{
m.SendMessage( "You must target within the home." );
m.Target = new InternalTarget( c_Gump, c_Contract, c_Type, c_BoundOne );
return;
}
switch( c_Type )
{
case TargetType.SignLoc:
c_Contract.SignLoc = new Point3D( point.X, point.Y, point.Z );
c_Contract.ShowSignPreview();
c_Gump.NewGump();
break;
case TargetType.MinZ:
if (!c_Contract.ParentHouse.Region.Contains(new Point3D(point.X, point.Y, point.Z)))
m.SendMessage( "That isn't within your house." );
else if ( c_Contract.HasContractedArea( point.Z ) )
m.SendMessage( "That area is already taken by another rental contract." );
else
{
c_Contract.MinZ = point.Z;
if ( c_Contract.MaxZ < c_Contract.MinZ+19 )
c_Contract.MaxZ = point.Z+19;
}
c_Contract.ShowFloorsPreview(m);
c_Gump.NewGump();
break;
case TargetType.MaxZ:
if ( !c_Contract.ParentHouse.Region.Contains(new Point3D(point.X, point.Y, point.Z)) )
m.SendMessage( "That isn't within your house." );
else if ( c_Contract.HasContractedArea( point.Z ) )
m.SendMessage( "That area is already taken by another rental contract." );
else
{
c_Contract.MaxZ = point.Z+19;
if ( c_Contract.MinZ > c_Contract.MaxZ )
c_Contract.MinZ = point.Z;
}
c_Contract.ShowFloorsPreview(m);
c_Gump.NewGump();
break;
case TargetType.BlockOne:
m.SendMessage( "Now target the south eastern corner." );
m.Target = new InternalTarget( c_Gump, c_Contract, TargetType.BlockTwo, new Point3D( point.X, point.Y, point.Z ) );
break;
case TargetType.BlockTwo:
Rectangle2D rect = TownHouseSetupGump.FixRect( new Rectangle2D( c_BoundOne, new Point3D( point.X+1, point.Y+1, point.Z ) ) );
if ( c_Contract.HasContractedArea( rect, point.Z ) )
m.SendMessage( "That area is already taken by another rental contract." );
else
{
c_Contract.Blocks.Add( rect );
c_Contract.ShowAreaPreview( m );
}
c_Gump.NewGump();
break;
}
}
protected override void OnTargetCancel( Mobile m, TargetCancelType cancelType )
{
c_Gump.NewGump();
}
}
}
}

View file

@ -0,0 +1,63 @@
using System;
using Server;
namespace Knives.TownHouses
{
public class TownHouseConfirmGump : GumpPlusLight
{
private TownHouseSign c_Sign;
private bool c_Items;
public TownHouseConfirmGump( Mobile m, TownHouseSign sign ) : base( m, 100, 100 )
{
c_Sign = sign;
}
protected override void BuildGump()
{
int width = 200;
int y = 0;
AddHtml( 0, y+=10, width, String.Format( "<CENTER>{0} this House?", c_Sign.RentByTime == TimeSpan.Zero ? "Purchase" : "Rent" ));
AddImage(width / 2 - 100, y + 2, 0x39);
AddImage(width / 2 + 70, y + 2, 0x3B);
if ( c_Sign.RentByTime == TimeSpan.Zero )
AddHtml( 0, y+=25, width, String.Format( "<CENTER>{0}: {1}", "Price", c_Sign.Free ? "Free" : "" + c_Sign.Price ));
else if ( c_Sign.RecurRent )
AddHtml( 0, y+=25, width, String.Format( "<CENTER>{0}: {1}", "Recurring " + c_Sign.PriceType, c_Sign.Price ));
else
AddHtml( 0, y+=25, width, String.Format( "<CENTER>{0}: {1}", "One " + c_Sign.PriceTypeShort, c_Sign.Price ));
if ( c_Sign.KeepItems )
{
AddHtml( 0, y+=20, width, "<CENTER>Cost of Items: " + c_Sign.ItemsPrice);
AddButton( 20, y, c_Items ? 0xD3 : 0xD2, "Items", new GumpCallback( Items ) );
}
AddHtml(0, y += 20, width, "<CENTER>Lockdowns: " + c_Sign.Locks);
AddHtml( 0, y+=20, width, "<CENTER>Secures: " + c_Sign.Secures);
AddButton( 10, y+=25, 0xFB1, 0xFB3, "Cancel", new GumpCallback( Cancel ) );
AddButton( width-40, y, 0xFB7, 0xFB9, "Confirm", new GumpCallback( Confirm ) );
AddBackgroundZero(0, 0, width, y+40, 3600);
}
private void Items()
{
c_Items = !c_Items;
NewGump();
}
private void Cancel()
{
}
private void Confirm()
{
c_Sign.Purchase( Owner, c_Items );
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,202 @@
using System;
using System.Collections;
using Server;
using Server.Multis;
using Server.Gumps;
namespace Knives.TownHouses
{
public class TownHousesGump : GumpPlusLight
{
public enum ListPage { Town, House }
public static void Initialize()
{
RUOVersion.AddCommand("TownHouses", AccessLevel.Counselor, new TownHouseCommandHandler(OnHouses));
}
private static void OnHouses(CommandInfo info)
{
new TownHousesGump(info.Mobile);
}
private ListPage c_ListPage;
private int c_Page;
public TownHousesGump(Mobile m)
: base(m, 100, 100)
{
m.CloseGump(typeof(TownHousesGump));
}
protected override void BuildGump()
{
int width = 400;
int y = 0;
AddHtml(0, y += 10, width, "<CENTER>TownHouses Main Menu");
AddImage(width / 2 - 120, y + 2, 0x39);
AddImage(width / 2 + 90, y + 2, 0x3B);
int pp = 10;
if (c_Page != 0)
AddButton(width / 2 - 10, y += 25, 0x25E4, 0x25E5, "Page Down", new GumpCallback(PageDown));
ArrayList list = new ArrayList();
if(c_ListPage == ListPage.Town)
list = new ArrayList(TownHouseSign.AllSigns);
else
foreach(Item item in World.Items.Values)
if(item is BaseHouse)
list.Add(item);
list.Sort(new InternalSort());
AddHtml(0, y += 20, width, "<CENTER>" + (c_ListPage == ListPage.Town ? "TownHouses" : "Houses") + " Count: " + list.Count);
AddHtml(0, y += 25, width, "<CENTER>TownHouses / Houses");
AddButton(width / 2 - 100, y + 3, c_ListPage == ListPage.Town ? 0x939 : 0x2716, "Page", new GumpStateCallback(Page), ListPage.Town);
AddButton(width / 2 + 90, y + 3, c_ListPage == ListPage.House ? 0x939 : 0x2716, "Page", new GumpStateCallback(Page), ListPage.House);
TownHouseSign sign = null;
BaseHouse house = null;
y += 5;
for (int i = c_Page * pp; i < (c_Page + 1) * pp && i < list.Count; ++i)
{
if (c_ListPage == ListPage.Town)
{
sign = (TownHouseSign)list[i];
AddHtml(30, y += 20, width / 2 - 20, "<DIV ALIGN=LEFT>" + sign.Name);
AddButton(15, y + 3, 0x2716, "TownHouse Menu", new GumpStateCallback(TownHouseMenu), sign);
if (sign.House != null && sign.House.Owner != null)
{
AddHtml(width / 2, y, width / 2 - 40, "<DIV ALIGN=RIGHT>" + sign.House.Owner.RawName);
AddButton(width - 30, y + 3, 0x2716, "House Menu", new GumpStateCallback(HouseMenu), sign.House);
}
}
else
{
house = (BaseHouse)list[i];
AddHtml(30, y += 20, width / 2 - 20, "<DIV ALIGN=LEFT>" + house.Name);
AddButton(15, y + 3, 0x2716, "Goto", new GumpStateCallback(Goto), house);
if (house.Owner != null)
{
AddHtml(width / 2, y, width / 2 - 40, "<DIV ALIGN=RIGHT>" + house.Owner.RawName);
AddButton(width - 30, y + 3, 0x2716, "House Menu", new GumpStateCallback(HouseMenu), house);
}
}
}
if (pp * (c_Page + 1) < list.Count)
AddButton(width / 2 - 10, y += 25, 0x25E8, 0x25E9, "Page Up", new GumpCallback(PageUp));
if (c_ListPage == ListPage.Town)
{
AddHtml(0, y += 35, width, "<CENTER>Add New TownHouse");
AddButton(width / 2 - 80, y + 3, 0x2716, "New", new GumpCallback(New));
AddButton(width / 2 + 70, y + 3, 0x2716, "New", new GumpCallback(New));
}
AddBackgroundZero(0, 0, width, y + 40, 3600);
}
private void TownHouseMenu(object obj)
{
if (!(obj is TownHouseSign))
return;
NewGump();
new TownHouseSetupGump(Owner, (TownHouseSign)obj);
}
private void Page(object obj)
{
c_ListPage = (ListPage)obj;
NewGump();
}
private void Goto(object obj)
{
if (!(obj is BaseHouse))
return;
Owner.Location = ((BaseHouse)obj).BanLocation;
Owner.Map = ((BaseHouse)obj).Map;
NewGump();
}
private void HouseMenu(object obj)
{
if (!(obj is BaseHouse))
return;
NewGump();
Owner.SendGump(new HouseGumpAOS((HouseGumpPageAOS)0, Owner, (BaseHouse)obj));
}
private void New()
{
TownHouseSign sign = new TownHouseSign();
Owner.AddToBackpack(sign);
Owner.SendMessage("A new sign is now in your backpack. It will move on it's own during setup, but if you don't complete setup you may want to delete it.");
NewGump();
new TownHouseSetupGump(Owner, sign);
}
private void PageUp()
{
c_Page++;
NewGump();
}
private void PageDown()
{
c_Page--;
NewGump();
}
private class InternalSort : IComparer
{
public InternalSort()
{
}
public int Compare(object x, object y)
{
if (x == null && y == null)
return 0;
if (x is TownHouseSign)
{
TownHouseSign a = (TownHouseSign)x;
TownHouseSign b = (TownHouseSign)y;
return Insensitive.Compare(a.Name, b.Name);
}
else
{
BaseHouse a = (BaseHouse)x;
BaseHouse b = (BaseHouse)y;
if (a.Owner == null && b.Owner != null)
return -1;
if (a.Owner != null && b.Owner == null)
return 1;
return Insensitive.Compare(a.Owner.RawName, b.Owner.RawName);
}
}
}
}
}