Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,41 @@
using System;
using Server;
using Server.Gumps;
using Server.Engines.XmlSpawner2;
namespace Server.Items
{
[Flipable( 0x1E5E, 0x1E5F )]
public class QuestLeadersBoard : Item
{
public QuestLeadersBoard( Serial serial ) : base( serial )
{
}
[Constructable]
public QuestLeadersBoard() : base( 0x1e5e )
{
Movable = false;
Name = "Quest Leaders Board";
}
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new XmlQuestLeaders.TopQuestPlayersGump( XmlAttach.FindAttachment(from,typeof(XmlQuestPoints)) as XmlQuestPoints) );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using Server;
using System.Collections;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class QuestLeadersStone: Item
{
[Constructable]
public QuestLeadersStone() : base( 0xED4)
{
Movable = false;
Visible = false;
Name = "Quest LeaderboardSave Stone";
// is there already another?
ArrayList dlist = new ArrayList();
foreach( Item i in World.Items.Values)
{
if(i is QuestLeadersStone && i != this)
{
dlist.Add(i);
}
}
foreach(Item d in dlist)
{
d.Delete();
}
}
public QuestLeadersStone( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile m )
{
if( m != null && m.AccessLevel >= AccessLevel.Administrator)
{
CommandEventArgs e = new CommandEventArgs(m, "", "", new string[0]);
XmlQuestLeaders.QuestLeaderboardSave_OnCommand(e);
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
XmlQuestLeaders.QuestLBSSerialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
XmlQuestLeaders.QuestLBSDeserialize( reader );
int version = reader.ReadInt();
// version 0
}
}
}

View File

@@ -0,0 +1,417 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Engines.XmlSpawner2;
//
// XmlLogGump
// modified from RC0 BOBGump.cs
//
namespace Server.Gumps
{
public class XMLQuestLogGump : Gump
{
private Mobile m_From;
private List<object> m_List;
private int m_Page;
private const int LabelColor = 0x7FFF;
public int GetIndexForPage( int page )
{
int index = 0;
while ( page-- > 0 )
index += GetCountForIndex( index );
return index;
}
public int GetCountForIndex( int index )
{
int slots = 0;
int count = 0;
List<object> list = m_List;
for ( int i = index; i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
int add;
add = 1;
if ( (slots + add) > 10 )
break;
slots += add;
++count;
}
return count;
}
public XMLQuestLogGump( Mobile from ) : this( from, 0, null )
{
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || m_From == null) return;
switch ( info.ButtonID )
{
case 0: // EXIT
{
break;
}
case 2: // Previous page
{
if ( m_Page > 0 )
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page - 1, m_List ) );
return;
}
case 3: // Next page
{
if ( GetIndexForPage( m_Page + 1 ) < m_List.Count )
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page + 1, m_List ) );
break;
}
case 10: // Top players
{
// if this player has an XmlQuestPoints attachment, find it
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m_From,typeof(XmlQuestPoints));
m_From.CloseGump(typeof(XmlQuestLeaders.TopQuestPlayersGump));
m_From.SendGump(new XmlQuestLeaders.TopQuestPlayersGump(p));
break;
}
default:
{
if ( info.ButtonID >= 2000 )
{
int index = info.ButtonID - 2000;
if ( index < 0 || index >= m_List.Count )
break;
if(m_List[index] is IXmlQuest)
{
IXmlQuest o = m_List[index] as IXmlQuest;
if(o != null && !o.Deleted){
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page, null ) );
m_From.CloseGump( typeof( XmlQuestStatusGump ) );
m_From.SendGump( new XmlQuestStatusGump(o, o.TitleString, 320, 0, true) );
}
}
}
break;
}
}
}
public XMLQuestLogGump( Mobile from, int page, List<object> list ) : base( 12, 24 )
{
if(from == null) return;
from.CloseGump( typeof( XMLQuestLogGump ) );
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(from, typeof(XmlQuestPoints));
m_From = from;
m_Page = page;
if ( list == null )
{
// make a new list based on the number of items in the book
int nquests = 0;
list = new List<object>( );
// find all quest items in the players pack
if(from.Backpack != null)
{
Item [] packquestitems = from.Backpack.FindItemsByType(typeof(IXmlQuest));
if (packquestitems != null)
{
nquests += packquestitems.Length;
for ( int i = 0; i < packquestitems.Length; ++i )
{
if(packquestitems[i] != null && !packquestitems[i].Deleted && !(packquestitems[i].Parent is XmlQuestBook))
list.Add( packquestitems[i] );
}
}
// find any questbooks they might have
Item [] questbookitems = from.Backpack.FindItemsByType(typeof(XmlQuestBook));
if(questbookitems != null)
{
for ( int j = 0; j < questbookitems.Length; ++j )
{
Item [] questitems = ((XmlQuestBook)questbookitems[j]).FindItemsByType(typeof(IXmlQuest));
if(questitems != null)
{
nquests += questitems.Length;
for ( int i = 0; i < questitems.Length; ++i )
{
list.Add( questitems[i] );
}
}
}
}
// find any completed quests on the XmlQuestPoints attachment
if(p != null && p.QuestList != null)
{
// add all completed quests
foreach(XmlQuestPoints.QuestEntry q in p.QuestList)
{
list.Add(q);
}
}
}
}
m_List = list;
int index = GetIndexForPage( page );
int count = GetCountForIndex( index );
int tableIndex = 0;
int width = 600;
width = 766;
X = (824 - width) / 2;
int xoffset = 20;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddImageTiled( 58 - xoffset, 64, 36, 352, 200 ); // open
AddImageTiled( 96 - xoffset, 64, 163, 352, 1416 ); // name
AddImageTiled( 261 - xoffset, 64, 55, 352, 200 ); // type
AddImageTiled( 308 - xoffset, 64, 85, 352, 1416 ); // status
AddImageTiled( 395 - xoffset, 64, 116, 352, 200 ); // expires
AddImageTiled( 511 - xoffset, 64, 42, 352, 1416 ); // points
AddImageTiled( 555 - xoffset, 64, 175, 352, 200 ); // completed
AddImageTiled( 734 - xoffset, 64, 42, 352, 1416 ); // repeated
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
AddImageTiled( 24, 94 + (tableIndex * 32), 489, 2, 2624 );
++tableIndex;
}
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
AddHtmlLocalized( 375, 25, 200, 30, 1046026, LabelColor, false, false ); // Quest Log
AddHtmlLocalized( 63 - xoffset, 45, 200, 32, 1072837, LabelColor, false, false ); // Current Points:
AddHtml( 243 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Available Credits:","FFFFFF"), false, false ); // Your Reward Points:
AddHtml( 453 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Rank:","FFFFFF"), false, false ); // Rank
AddHtml( 600 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Quests Completed:","FFFFFF"), false, false ); // Quests completed
if(p != null)
{
int pcolor = 53;
AddLabel(170 - xoffset, 45, pcolor, p.Points.ToString());
AddLabel(350 - xoffset, 45, pcolor, p.Credits.ToString());
AddLabel(500 - xoffset, 45, pcolor, p.Rank.ToString());
AddLabel(720 - xoffset, 45, pcolor, p.QuestsCompleted.ToString());
}
AddHtmlLocalized( 63 - xoffset, 64, 200, 32, 3000362, LabelColor, false, false ); // Open
AddHtmlLocalized( 147 - xoffset, 64, 200, 32, 3005104, LabelColor, false, false ); // Name
AddHtmlLocalized( 270 - xoffset, 64, 200, 32, 1062213, LabelColor, false, false ); // Type
AddHtmlLocalized( 326 - xoffset, 64, 200, 32, 3000132, LabelColor, false, false ); // Status
AddHtmlLocalized( 429 - xoffset, 64, 200, 32, 1062465, LabelColor, false, false ); // Expires
AddHtml( 514 - xoffset, 64, 200, 32, XmlSimpleGump.Color("Points","FFFFFF"), false, false ); // Points
AddHtml( 610 - xoffset, 64, 200, 32, XmlSimpleGump.Color("Next Available","FFFFFF"), false, false ); // Next Available
//AddHtmlLocalized( 610 - xoffset, 64, 200, 32, 1046033, LabelColor, false, false ); // Completed
AddHtmlLocalized( 738 - xoffset, 64, 200, 32, 3005020, LabelColor, false, false ); // Repeat
AddButton( 675 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 710 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
AddButton( 113 - xoffset, 416, 0xFA8, 0xFAA, 10, GumpButtonType.Reply, 0 );
AddHtml( 150 - xoffset, 416, 200, 32, XmlSimpleGump.Color("Top Players","FFFFFF"), false, false ); // Top players gump
tableIndex = 0;
if ( page > 0 )
{
AddButton( 225, 416, 4014, 4016, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 260, 416, 150, 20, 1011067, LabelColor, false, false ); // Previous page
}
if ( GetIndexForPage( page + 1 ) < list.Count )
{
AddButton( 375, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 410, 416, 150, 20, 1011066, LabelColor, false, false ); // Next page
}
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
if ( obj is IXmlQuest )
{
IXmlQuest e = (IXmlQuest)obj;
int y = 96 + (tableIndex++ * 32);
AddButton( 60 - xoffset, y + 2, 0xFAB, 0xFAD, 2000 + i, GumpButtonType.Reply, 0 ); // open gump
int color;
if(!e.IsValid)
{
color = 33;
}
else
if(e.IsCompleted)
{
color = 67;
}
else
{
color = 5;
}
AddLabel( 100 - xoffset, y, color, (string)e.Name );
//AddHtmlLocalized( 315, y, 200, 32, e.IsCompleted ? 1049071 : 1049072, htmlcolor, false, false ); // Completed/Incomplete
AddLabel( 315 - xoffset, y, color, e.IsCompleted ? "Completed" : "In Progress" );
// indicate the expiration time
if(e.IsValid)
{
// do a little parsing of the expiration string to fit it in the space
string substring = e.ExpirationString;
if(e.ExpirationString.IndexOf("Expires in") >= 0)
{
substring = e.ExpirationString.Substring(11);
}
AddLabel( 400 - xoffset, y, color, (string)substring );
}
else
{
AddLabel( 400 - xoffset, y, color, "No longer valid" );
}
if(e.PartyEnabled)
{
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
}
else
{
AddLabel( 270 - xoffset, y, color, "Solo" );
}
AddLabel( 515 - xoffset, y, color, e.Difficulty.ToString() );
}
else
if(obj is XmlQuestPoints.QuestEntry)
{
XmlQuestPoints.QuestEntry e = (XmlQuestPoints.QuestEntry)obj;
int y = 96 + (tableIndex++ * 32);
int color = 67;
AddLabel( 100 - xoffset, y, color, (string)e.Name );
AddLabel( 315 - xoffset, y, color, "Completed" );
if(e.PartyEnabled)
{
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
}
else
{
AddLabel( 270 - xoffset, y, color, "Solo" );
}
AddLabel( 515 - xoffset, y, color, e.Difficulty.ToString() );
//AddLabel( 560 - xoffset, y, color, e.WhenCompleted.ToString() );
// determine when the quest can be done again by looking for an xmlquestattachment with the same name
XmlQuestAttachment qa = (XmlQuestAttachment)XmlAttach.FindAttachment(from, typeof(XmlQuestAttachment), e.Name);
if(qa != null)
{
if(qa.Expiration == TimeSpan.Zero)
{
AddLabel( 560 - xoffset, y, color, "Not Repeatable" );
}
else
{
DateTime nexttime = DateTime.UtcNow + qa.Expiration;
AddLabel( 560 - xoffset, y, color, nexttime.ToString() );
}
}
else
{
// didnt find one so it can be done again
AddLabel( 560 - xoffset, y, color, "Available Now" );
}
AddLabel( 741 - xoffset, y, color, e.TimesCompleted.ToString() );
}
}
}
}
}

View File

@@ -0,0 +1,229 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.XmlSpawner2;
/*
** QuestRewardGump
** ArteGordon
** updated 9/18/05
**
** Gives out rewards based on the XmlQuestReward reward list entries and the players Credits that are accumulated through quests with the XmlQuestPoints attachment.
** The Gump supports Item, Mobile, and Attachment type rewards.
*/
namespace Server.Gumps
{
public class QuestRewardGump : Gump
{
private List<XmlQuestPointsRewards> Rewards;
private int y_inc = 35;
private int x_creditoffset = 350;
private int x_pointsoffset = 480;
private int maxItemsPerPage = 9;
private int viewpage;
public QuestRewardGump( Mobile from, int page ) : base( 20, 30 )
{
from.CloseGump(typeof(QuestRewardGump));
// determine the gump size based on the number of rewards
Rewards = XmlQuestPointsRewards.RewardsList;
viewpage = page;
int height = maxItemsPerPage*y_inc + 120;
int width = x_pointsoffset+110;
/*
if(Rewards != null && Rewards.Count > 0)
{
height = Rewards.Count*y_inc + 120;
}
*/
AddBackground( 0, 0, width, height, 0xDAC );
AddHtml( 40, 20, 350, 50, "Rewards Available for Purchase with QuestPoints Credits", false, false );
int qcredits = XmlQuestPoints.GetCredits(from);
AddLabel( 400, 20, 0, String.Format("Available Credits: {0}", qcredits ));
int qpoints = XmlQuestPoints.GetPoints(from);
//AddButton( 30, height - 35, 0xFB7, 0xFB9, 0, GumpButtonType.Reply, 0 );
//AddLabel( 70, height - 35, 0, "Close" );
// put the page buttons in the lower right corner
if(Rewards != null && Rewards.Count > 0)
{
AddLabel( width - 165, height - 35, 0, String.Format("Page: {0}/{1}", viewpage+1, (int)(Rewards.Count/maxItemsPerPage)+1));
// page up and down buttons
AddButton( width - 55, height - 35, 0x15E0, 0x15E4, 13, GumpButtonType.Reply, 0 );
AddButton( width - 35, height - 35, 0x15E2, 0x15E6, 12, GumpButtonType.Reply, 0 );
}
AddLabel( 70, 50, 40, "Reward" );
AddLabel( x_creditoffset, 50, 40, "Credits" );
AddLabel( x_pointsoffset, 50, 40, "Min Points" );
// display the items with their selection buttons
if(Rewards != null)
{
int y = 50;
for(int i = 0; i < Rewards.Count; i++)
{
if((int)(i/maxItemsPerPage) != viewpage) continue;
XmlQuestPointsRewards r = Rewards[i];
if(r == null) continue;
y += y_inc;
int texthue = 0;
// display the item
if(r.MinPoints > qpoints || r.Cost > qcredits)
{
texthue = 33;
}
else
{
// add the selection button
AddButton( 30, y, 0xFA5, 0xFA7, 1000+i, GumpButtonType.Reply, 0 );
}
// display the name
AddLabel( 70, y+3, texthue, r.Name);
// display the cost
AddLabel( x_creditoffset, y+3, texthue, r.Cost.ToString() );
// display the item
if(r.ItemID > 0)
AddItem(x_creditoffset+60, y+r.yOffset, r.ItemID, r.ItemHue);
// display the min points requirement
AddLabel( x_pointsoffset, y+3, texthue, r.MinPoints.ToString() );
}
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null || Rewards == null) return;
Mobile from = state.Mobile;
switch ( info.ButtonID )
{
case 12:
// page up
int nitems = 0;
if(Rewards != null)
nitems = Rewards.Count;
int page = viewpage+1;
if(page > (int)(nitems/maxItemsPerPage))
{
page = (int)(nitems/maxItemsPerPage);
}
state.Mobile.SendGump( new QuestRewardGump( state.Mobile, page));
break;
case 13:
// page down
page = viewpage-1;
if(page < 0)
{
page = 0;
}
state.Mobile.SendGump( new QuestRewardGump( state.Mobile, page));
break;
default:
{
if(info.ButtonID >= 1000)
{
int selection = info.ButtonID - 1000;
if(selection < Rewards.Count)
{
XmlQuestPointsRewards r = Rewards[selection];
// check the price
if(XmlQuestPoints.HasCredits(from, r.Cost, r.MinPoints))
{
// create an instance of the reward type
object o = null;
try
{
o = Activator.CreateInstance( r.RewardType , r.RewardArgs);
}
catch {}
bool received = true;
if(o is Item)
{
// and give them the item
from.AddToBackpack((Item)o);
}
else if(o is Mobile)
{
// if it is controllable then set the buyer as master. Note this does not check for control slot limits.
if(o is BaseCreature)
{
BaseCreature b = o as BaseCreature;
b.Controlled = true;
b.ControlMaster = from;
}
((Mobile)o).MoveToWorld(from.Location, from.Map);
}
else if(o is XmlAttachment)
{
XmlAttachment a = o as XmlAttachment;
XmlAttach.AttachTo(from, a);
}
else
{
from.SendMessage(33, "unable to create {0}.", r.RewardType.Name);
received = false;
}
// complete the transaction
if(received)
{
// charge them
if(XmlQuestPoints.TakeCredits(from, r.Cost))
{
from.SendMessage("You have purchased {0} for {1} credits.", r.Name, r.Cost);
}
else
{
if(o is Item)
((Item)o).Delete();
else if(o is Mobile)
((Mobile)o).Delete();
else if(o is XmlAttachment)
((XmlAttachment)o).Delete();
}
}
}
else
{
from.SendMessage("Insufficient Credits for {0}.", r.Name);
}
from.SendGump(new QuestRewardGump(from, viewpage));
}
}
break;
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using Server.Gumps;
/*
** QuestRewardStone
** used to open the QuestPointsRewardGump that allows players to purchase rewards with their XmlQuestPoints Credits.
*/
namespace Server.Items
{
public class QuestRewardStone : Item
{
[Constructable]
public QuestRewardStone() : base( 0xED4 )
{
Movable = false;
Name = "a Quest Points Reward Stone";
}
public QuestRewardStone( Serial serial ) : base( serial )
{
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m.Player )
{
if ( !m.InRange( this.Location, 2 ) )
m.CloseGump( typeof( QuestRewardGump ) );
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
if ( from.InRange( GetWorldLocation(), 2 ) )
{
from.SendGump( new QuestRewardGump( from, 0 ) );
}
else
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
}
}
}

View File

@@ -0,0 +1,341 @@
using System;
using Server;
using Server.Network;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
//
// XmlPlayerQuestGump
//
namespace Server.Gumps
{
public class XmlPlayerQuestGump : Gump
{
private PlayerMobile m_From;
private IXmlQuest m_QuestItem;
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || sender == null || sender.Mobile == null) return;
// read the text entries for the search criteria
TextRelay tr = info.GetTextEntry( 100 ); // quest name
if(tr != null)
m_QuestItem.Name = tr.Text.Trim();
tr = info.GetTextEntry( 102 ); // title
if(tr != null)
m_QuestItem.TitleString = tr.Text.Trim();
tr = info.GetTextEntry( 103 ); // notestring
if(tr != null)
m_QuestItem.NoteString = tr.Text;
tr = info.GetTextEntry( 200 ); // objectives
if(tr != null)
m_QuestItem.Objective1 = tr.Text.Trim();
tr = info.GetTextEntry( 201 );
if(tr != null)
m_QuestItem.Objective2 = tr.Text.Trim();
tr = info.GetTextEntry( 202 );
if(tr != null)
m_QuestItem.Objective3 = tr.Text.Trim();
tr = info.GetTextEntry( 203 );
if (tr != null)
m_QuestItem.Objective4 = tr.Text.Trim();
tr = info.GetTextEntry( 204 );
if(tr != null)
m_QuestItem.Objective5 = tr.Text.Trim();
tr = info.GetTextEntry( 205 );
if(tr != null && tr.Text != null && tr.Text.Length > 0) // descriptions
m_QuestItem.Description1 = tr.Text.Trim();
else
m_QuestItem.Description1 = null;
tr = info.GetTextEntry( 206 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description2 = tr.Text.Trim();
else
m_QuestItem.Description2 = null;
tr = info.GetTextEntry( 207 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description3 = tr.Text.Trim();
else
m_QuestItem.Description3 = null;
tr = info.GetTextEntry( 208 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description4 = tr.Text.Trim();
else
m_QuestItem.Description4 = null;
tr = info.GetTextEntry( 209 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description5 = tr.Text.Trim();
else
m_QuestItem.Description5 = null;
tr = info.GetTextEntry( 210 ); // expiration
if(tr != null && tr.Text != null && tr.Text.Length > 0){
try{m_QuestItem.Expiration = double.Parse(tr.Text.Trim());} catch{}
}
// check all of the check boxes
m_QuestItem.PartyEnabled = info.IsSwitched(300);
m_QuestItem.CanSeeReward = info.IsSwitched(301);
// refresh the time created
m_QuestItem.TimeCreated = DateTime.UtcNow;
switch ( info.ButtonID )
{
case 0: // Okay
{
break;
}
case 1: // Select Reward
{
sender.Mobile.Target = new RewardTarget(m_QuestItem);
break;
}
case 2: // Select Reward Return
{
sender.Mobile.Target = new ReturnTarget(m_QuestItem);
break;
}
}
}
public XmlPlayerQuestGump( PlayerMobile from, IXmlQuest questitem ) : base( 12, 140 )
{
from.CloseGump( typeof( XmlPlayerQuestGump ) );
if(from == null || from.Deleted || questitem == null || questitem.Deleted) return;
m_From = from;
m_QuestItem = questitem;
int width = 600;
//width = 516;
X = (624 - width) / 2;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
// add the Quest Title
AddLabel( width/2 - 50, 15, 0x384, "Player Quest Maker" );
int y = 35;
// add the Quest Name
AddLabel( 28, y, 0x384, "Quest Name" );
string name = questitem.Name;
if(name != null)
{
name = name.Substring(4);
}
AddImageTiled( 26, y + 20, 232, 20, 0xBBC );
AddTextEntry( 26, y + 20, 250, 20, 0, 100, name );
// add the Quest Title
AddLabel( 328, y, 0x384, "Quest Title" );
AddImageTiled( 306, y + 20, 232, 20, 0xBBC );
AddTextEntry( 306, y + 20, 230, 20, 0, 102, questitem.TitleString );
y += 50;
// add the Quest Text
AddLabel( 28, y, 0x384, "Quest Text" );
AddImageTiled( 26, y + 20, 532, 80, 0xBBC );
AddTextEntry( 26, y + 20, 530, 80, 0, 103, questitem.NoteString );
y += 110;
// add the Quest Expiration
AddLabel( 28, y, 0x384, "Expiration" );
AddLabel( 98, y + 20, 0x384, "Hours" );
AddImageTiled( 26, y + 20, 52, 20, 0xBBC );
AddTextEntry( 26, y + 20, 50, 20, 0, 210, questitem.Expiration.ToString() );
y += 50;
// add the Quest Objectives
AddLabel( 28, y, 0x384, "Quest Objectives" );
AddImageTiled( 26, y + 20, 252, 19, 0xBBC );
AddTextEntry( 26, y + 20, 250, 19, 0, 200, questitem.Objective1 );
AddImageTiled( 26, y + 40, 252, 19, 0xBBC );
AddTextEntry( 26, y + 40, 250, 19, 0, 201, questitem.Objective2 );
AddImageTiled( 26, y + 60, 252, 19, 0xBBC );
AddTextEntry( 26, y + 60, 250, 19, 0, 202, questitem.Objective3 );
AddImageTiled( 26, y + 80, 252, 19, 0xBBC );
AddTextEntry( 26, y + 80, 250, 19, 0, 203, questitem.Objective4 );
AddImageTiled( 26, y + 100, 252, 19, 0xBBC );
AddTextEntry( 26, y + 100, 250, 19, 0, 204, questitem.Objective5 );
// add the Quest Objectives
AddLabel( 328, y, 0x384, "Objective Descriptions" );
AddImageTiled( 306, y + 20, 252, 19, 0xBBC );
AddTextEntry( 306, y + 20, 250, 19, 0, 205, questitem.Description1 );
AddImageTiled( 306, y + 40, 252, 19, 0xBBC );
AddTextEntry( 306, y + 40, 250, 19, 0, 206, questitem.Description2 );
AddImageTiled( 306, y + 60, 252, 19, 0xBBC );
AddTextEntry( 306, y + 60, 250, 19, 0, 207, questitem.Description3 );
AddImageTiled( 306, y + 80, 252, 19, 0xBBC );
AddTextEntry( 306, y + 80, 250, 19, 0, 208, questitem.Description4 );
AddImageTiled( 306, y + 100, 252, 19, 0xBBC );
AddTextEntry( 306, y + 100, 250, 19, 0, 209, questitem.Description5 );
y += 130;
// party enable toggle
AddCheck( 25, y, 0xD2, 0xD3, questitem.PartyEnabled, 300);
AddLabel( 48, y, 0x384, "PartyEnabled" );
y += 20;
// can see toggle
AddCheck( 25, y, 0xD2, 0xD3, questitem.CanSeeReward, 301);
AddLabel( 48, y, 0x384, "CanSeeReward" );
// select reward button
AddButton( 225, y+3, 2103, 2103, 1, GumpButtonType.Reply, 0 );
AddLabel( 245, y, 0x384, "Select Reward" );
// select reward button
AddButton( 375, y+3, 2103, 2103, 2, GumpButtonType.Reply, 0 );
AddLabel( 395, y, 0x384, "Select Return Container" );
AddButton( 45, 416, 2130, 2129, 0, GumpButtonType.Reply, 0 ); // Okay button
//AddButton( 375 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
//AddHtmlLocalized( 410 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
}
private class RewardTarget : Target
{
IXmlQuest m_QuestItem;
public RewardTarget(IXmlQuest questitem) : base ( 30, true, TargetFlags.None )
{
m_QuestItem = questitem;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(m_QuestItem == null || m_QuestItem.Deleted) return;
// first check to see if you are too far from the return container. This is to avoid exploits involving targeting a container
// then using the return reward feature as a free transport of items back to that container
if(m_QuestItem.ReturnContainer != null && !m_QuestItem.ReturnContainer.Deleted)
{
Point3D returnloc;
if(m_QuestItem.ReturnContainer.Parent == null)
{
returnloc = m_QuestItem.ReturnContainer.Location;
} else
if(m_QuestItem.ReturnContainer.RootParent != null)
{
returnloc = ((IEntity)m_QuestItem.ReturnContainer.RootParent).Location;
} else
{
from.SendMessage("Invalid container location");
return;
}
if(!Utility.InRange( returnloc, from.Location, 10))
{
// out of range
from.SendMessage("Too far away from the reward return container");
return;
}
}
// try to add the item as the reward item
if(m_QuestItem.PlayerMade && (from != null) && !from.Deleted && (from is PlayerMobile) &&
(from == m_QuestItem.Creator) && (from == m_QuestItem.Owner) && (targeted is Item) &&
!(targeted is IXmlQuest))
{
Item i = targeted as Item;
// make sure the target item is in the oweners backpack
if(i != null && !i.Deleted && i.RootParent == m_QuestItem.Owner)
{
m_QuestItem.RewardItem = i;
m_QuestItem.AutoReward = true;
} else
{
from.SendMessage("Targeted item must be in the owners pack");
}
}
}
}
private class ReturnTarget : Target
{
IXmlQuest m_QuestItem;
public ReturnTarget(IXmlQuest questitem) : base ( 30, true, TargetFlags.None )
{
m_QuestItem = questitem;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(m_QuestItem == null || m_QuestItem.Deleted) return;
// try to add the item as the reward item
if(m_QuestItem.PlayerMade && (from != null) && !from.Deleted && (from is PlayerMobile) &&
(from == m_QuestItem.Creator) && (from == m_QuestItem.Owner) && targeted is Container)
{
Container i = targeted as Container;
// make sure the target item is in the oweners backpack
if(i != null && !i.Deleted )
{
m_QuestItem.ReturnContainer = i;
from.SendMessage("Reward return container set");
} else
{
from.SendMessage("Targeted item must be a valid container");
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.IO;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestAttachment : XmlAttachment
{
private DateTime m_DataValue;
public DateTime Date { get { return m_DataValue; } set { m_DataValue = value; } }
// These are the various ways in which the message attachment can be constructed.
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
// Other overloads could be defined to handle other types of arguments
// a serial constructor is REQUIRED
public XmlQuestAttachment(ASerial serial)
: base(serial)
{
}
[Attachable]
public XmlQuestAttachment(string name)
{
Name = name;
Date = DateTime.UtcNow;
}
[Attachable]
public XmlQuestAttachment(string name, double expiresin)
{
Name = name;
Date = DateTime.UtcNow;
Expiration = TimeSpan.FromMinutes(expiresin);
}
[Attachable]
public XmlQuestAttachment(string name, DateTime value, double expiresin)
{
Name = name;
Date = value;
Expiration = TimeSpan.FromMinutes(expiresin);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
// version 0
writer.Write(m_DataValue);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
// version 0
m_DataValue = reader.ReadDateTime();
}
public override string OnIdentify(Mobile from)
{
if (from.AccessLevel == AccessLevel.Player) return null;
if (Expiration > TimeSpan.Zero)
{
return String.Format("Quest '{2}' Completed {0} expires in {1} mins", Date, Expiration.TotalMinutes, Name);
}
else
{
return String.Format("Quest '{1}' Completed {0}", Date, Name);
}
}
}
}

View File

@@ -0,0 +1,279 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using System.IO;
using System.Collections.Generic;
using Server.Targeting;
using Server.Engines.PartySystem;
using System.Data;
using System.Xml;
/*
** XmlQuestBook class
**
*/
namespace Server.Items
{
[Flipable( 0x1E5E, 0x1E5F )]
public class PlayerQuestBoard : XmlQuestBook
{
public override bool IsDecoContainer
{
get { return false; }
}
public PlayerQuestBoard( Serial serial ) : base( serial )
{
}
[Constructable]
public PlayerQuestBoard() : base( 0x1e5e )
{
Movable = false;
Name = "Player Quest Board";
LiftOverride = true; // allow players to store books in it
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class XmlQuestBook : Container
{
private PlayerMobile m_Owner;
private bool m_Locked;
[CommandProperty( AccessLevel.GameMaster )]
public PlayerMobile Owner
{ get{ return m_Owner; }
set { m_Owner = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Locked
{ get{ return m_Locked; }
set { m_Locked = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsCompleted
{ get{
Item [] questitems = this.FindItemsByType(typeof(IXmlQuest));
if(questitems == null || questitems.Length <= 0)
return false;
for ( int i = 0; i < questitems.Length; ++i )
{
IXmlQuest q = questitems[i] as IXmlQuest;
// check completion and validity status of all quests held in the book
if(q == null || q.Deleted || !q.IsValid || !q.IsCompleted) return false;
}
return true;
}
}
public XmlQuestBook( Serial serial ) : base( serial )
{
}
[Constructable]
public XmlQuestBook(int itemid) : this( )
{
ItemID = itemid;
}
[Constructable]
public XmlQuestBook() : base( 0x2259 )
{
//LootType = LootType.Blessed;
Name = "QuestBook";
Hue = 100;
}
public override void OnDoubleClick( Mobile from )
{
if(!(from is PlayerMobile)) return;
if(from.AccessLevel >= AccessLevel.GameMaster)
{
base.OnDoubleClick(from);
}
from.SendGump( new XmlQuestBookGump( (PlayerMobile)from, this ) );
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if(dropped is IXmlQuest && !Locked)
{
return base.OnDragDrop(from,dropped);
} else
{
return false;
}
}
private void CheckOwnerFlag()
{
if(Owner != null && !Owner.Deleted)
{
// need to check to see if any other questtoken items are owned
// search the Owners top level pack for an xmlquest
List<Item> list = XmlQuest.FindXmlQuest(Owner);
if(list == null || list.Count == 0)
{
// if none remain then flag the ower as having none
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,false);
}
}
}
public virtual void Invalidate()
{
if(Owner != null)
{
Owner.SendMessage(String.Format("{0} Quests invalidated - '{1}' removed", TotalItems,Name));
}
this.Delete();
}
public override void OnItemLifted(Mobile from, Item item)
{
base.OnItemLifted(from,item);
if(from is PlayerMobile && Owner == null)
{
Owner = from as PlayerMobile;
LootType = LootType.Blessed;
// flag the owner as carrying a questtoken assuming the book contains quests and then confirm it with CheckOwnerFlag
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,true);
CheckOwnerFlag();
}
}
#if(NEWPARENT)
public override void OnAdded(IEntity parent)
#else
public override void OnAdded(object parent)
#endif
{
base.OnAdded(parent);
if(parent != null && parent is Container)
{
// find the parent of the container
// note, the only valid additions are to the player pack. Anything else is invalid. This is to avoid exploits involving storage or transfer of questtokens
object from = ((Container)parent).Parent;
// check to see if it can be added
if(from != null && from is PlayerMobile)
{
// if it was not owned then allow it to go anywhere
if(Owner == null)
{
Owner = from as PlayerMobile;
LootType = LootType.Blessed;
// could also bless all of the quests inside as well but not actually necessary since blessed containers retain their
// contents whether blessed or not, and when dropped the questtokens will be blessed
// flag the owner as carrying a questtoken
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,true);
CheckOwnerFlag();
} else
if(from as PlayerMobile != Owner || parent is BankBox)
{
// tried to give it to another player or placed it in the players bankbox. try to return it to the owners pack
Owner.AddToBackpack(this);
}
} else
{
if(Owner != null)
{
// try to return it to the owners pack
Owner.AddToBackpack(this);
}
// allow placement into npcs or drop on their corpses when owner is null
else
if(!(from is Mobile) && !(parent is Corpse))
{
// in principle this should never be reached
// invalidate the token
CheckOwnerFlag();
Invalidate();
}
}
}
}
public override void OnDelete()
{
base.OnDelete();
CheckOwnerFlag();
}
public override bool OnDroppedToWorld(Mobile from,Point3D point)
{
bool returnvalue = base.OnDroppedToWorld(from,point);
from.SendGump( new XmlConfirmDeleteGump(from,this));
//CheckOwnerFlag();
//Invalidate();
return false;
//return returnvalue;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Owner);
writer.Write( m_Locked);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
this.m_Owner = reader.ReadMobile() as PlayerMobile;
this.m_Locked = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,308 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Engines.XmlSpawner2;
//
// XmlQuestBookGump
// modified from RC0 BOBGump.cs
//
namespace Server.Gumps
{
public class XmlQuestBookGump : Gump
{
private PlayerMobile m_From;
private XmlQuestBook m_Book;
private ArrayList m_List;
private int m_Page;
private const int LabelColor = 0x7FFF;
public int GetIndexForPage( int page )
{
int index = 0;
while ( page-- > 0 )
index += GetCountForIndex( index );
return index;
}
public int GetCountForIndex( int index )
{
int slots = 0;
int count = 0;
ArrayList list = m_List;
for ( int i = index; i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
int add;
add = 1;
if ( (slots + add) > 10 )
break;
slots += add;
++count;
}
return count;
}
public XmlQuestBookGump( PlayerMobile from, XmlQuestBook book ) : this( from, book, 0, null )
{
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || m_From == null) return;
switch ( info.ButtonID )
{
case 0: // EXIT
{
break;
}
case 2: // Previous page
{
if ( m_Page > 0 )
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page - 1, m_List ) );
return;
}
case 3: // Next page
{
if ( GetIndexForPage( m_Page + 1 ) < m_List.Count )
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page + 1, m_List ) );
break;
}
default:
{
if ( info.ButtonID >= 2000 )
{
int index = info.ButtonID - 2000;
if ( index < 0 || index >= m_List.Count )
break;
if(m_List[index] is IXmlQuest)
{
IXmlQuest o = m_List[index] as IXmlQuest;
if(o != null && !o.Deleted){
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page, null ) );
m_From.CloseGump( typeof( XmlQuestStatusGump ) );
m_From.SendGump( new XmlQuestStatusGump(o, o.TitleString, 320, 0, true) );
}
}
} else
if ( info.ButtonID >= 1000 )
{
int index = info.ButtonID - 1000;
if ( index < 0 || index >= m_List.Count )
break;
// allow quests to be dropped from books that are either in the world or in the players backpack
if ( m_Book.IsChildOf( m_From.Backpack ) || (m_Book.Parent == null))
{
// move the item from the book to the players backpack
Item item = m_List[index] as Item;
if ( item != null && !item.Deleted)
{
m_From.AddToBackpack( item );
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page, null ) );
}
else
{
m_From.SendMessage( "Internal error. The quest could not be retrieved." );
}
}
}
break;
}
}
}
public XmlQuestBookGump( PlayerMobile from, XmlQuestBook book, int page, ArrayList list ) : base( 12, 24 )
{
from.CloseGump( typeof( XmlQuestBookGump ) );
m_From = from;
m_Book = book;
m_Page = page;
if ( list == null )
{
// make a new list based on the number of items in the book
int nquests = 0;
Item [] questitems = book.FindItemsByType(typeof(IXmlQuest));
if(questitems != null)
nquests = questitems.Length;
list = new ArrayList( nquests );
for ( int i = 0; i < nquests; ++i )
{
list.Add( questitems[i] );
}
}
m_List = list;
int index = GetIndexForPage( page );
int count = GetCountForIndex( index );
int tableIndex = 0;
int width = 600;
width = 516;
X = (624 - width) / 2;
int xoffset = 0;
if(m_Book.Locked)
xoffset = 20;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddImageTiled( 58 - xoffset, 64, 36, 352, 200 ); // open
AddImageTiled( 96 - xoffset, 64, 163, 352, 1416 ); // name
AddImageTiled( 261 - xoffset, 64, 55, 352, 200 ); // type
AddImageTiled( 308 - xoffset, 64, 85, 352, 1416 ); // status
AddImageTiled( 395 - xoffset, 64, 116, 352, 200 ); // expires
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
AddImageTiled( 24, 94 + (tableIndex * 32), 489, 2, 2624 );
++tableIndex;
}
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
AddHtmlLocalized( 224, 32, 200, 32, 1046026, LabelColor, false, false ); // Quest Log
AddHtmlLocalized( 63 - xoffset, 64, 200, 32, 3000362, LabelColor, false, false ); // Open
AddHtmlLocalized( 147 - xoffset, 64, 200, 32, 3005104, LabelColor, false, false ); // Name
AddHtmlLocalized( 270 - xoffset, 64, 200, 32, 1062213, LabelColor, false, false ); // Type
AddHtmlLocalized( 326 - xoffset, 64, 200, 32, 3000132, LabelColor, false, false ); // Status
AddHtmlLocalized( 429 - xoffset, 64, 200, 32, 1062465, LabelColor, false, false ); // Expires
AddButton( 375 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 410 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
if(!m_Book.Locked)
AddHtmlLocalized( 26, 64, 50, 32, 1062212, LabelColor, false, false ); // Drop
tableIndex = 0;
if ( page > 0 )
{
AddButton( 75, 416, 4014, 4016, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 110, 416, 150, 20, 1011067, LabelColor, false, false ); // Previous page
}
if ( GetIndexForPage( page + 1 ) < list.Count )
{
AddButton( 225, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 260, 416, 150, 20, 1011066, LabelColor, false, false ); // Next page
}
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
if ( obj is IXmlQuest )
{
IXmlQuest e = (IXmlQuest)obj;
int y = 96 + (tableIndex++ * 32);
if(!m_Book.Locked)
AddButton( 35, y + 2, 5602, 5606, 1000 + i, GumpButtonType.Reply, 0 ); // drop
AddButton( 60 - xoffset, y + 2, 0xFAB, 0xFAD, 2000 + i, GumpButtonType.Reply, 0 ); // open gump
int color;
if(!e.IsValid)
{
color = 33;
} else
if(e.IsCompleted)
{
color = 67;
} else
{
color = 5;
}
AddLabel( 100 - xoffset, y, color, (string)e.Name );
//AddHtmlLocalized( 315, y, 200, 32, e.IsCompleted ? 1049071 : 1049072, htmlcolor, false, false ); // Completed/Incomplete
AddLabel( 315 - xoffset, y, color, e.IsCompleted ? "Completed" : "In Progress" );
// indicate the expiration time
if(e.IsValid){
// do a little parsing of the expiration string to fit it in the space
string substring = e.ExpirationString;
if(e.ExpirationString.IndexOf("Expires in") >= 0)
{
substring = e.ExpirationString.Substring(11);
}
AddLabel( 400 - xoffset, y, color, (string)substring );
} else
{
AddLabel( 400 - xoffset, y, color, "No longer valid" );
}
if(e.PartyEnabled){
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
} else {
AddLabel( 270 - xoffset, y, color, "Solo" );
}
}
}
}
}
}

View File

@@ -0,0 +1,702 @@
using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
/*
** Changelog
**
** 3/25/04
** added party status information
** 3/23/04
** changed bottom border location in the quest status gump for 3dclient compatibility
*/
namespace Server.Gumps
{
public class XmlConfirmDeleteGump : Gump
{
Item m_Item;
Mobile m_From;
public XmlConfirmDeleteGump(Mobile from, Item item) : base ( 0, 0 )
{
m_Item = item;
m_From = from;
Closable = false;
Dragable = true;
AddPage( 0 );
AddBackground( 10, 185, 200, 130, 5054 );
if(item is XmlQuestBook)
{
AddLabel( 20, 190, 33, String.Format("Delete this questbook?") );
AddLabel( 20, 210, 33, String.Format("{0} quest(s) will be lost.", item.TotalItems) );
AddLabel( 20, 230, 53, item.Name );
}
else if(item is IXmlQuest)
{
AddLabel( 20, 210, 33, String.Format("Delete this quest?") );
AddLabel( 20, 230, 53, item.Name );
}
else
{
AddLabel( 20, 210, 33, String.Format("Delete this item?") );
AddLabel( 20, 230, 53, item.Name );
}
AddRadio( 35, 255, 9721, 9724, false, 1 ); // accept/yes radio
AddRadio( 135, 255, 9721, 9724, true, 2 ); // decline/no radio
AddHtmlLocalized(72, 255, 200, 30, 1049016, 0x7fff , false , false ); // Yes
AddHtmlLocalized(172, 255, 200, 30, 1049017, 0x7fff , false , false ); // No
AddButton( 80, 289, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
int radiostate = -1;
if(info.Switches.Length > 0)
{
radiostate = info.Switches[0];
}
switch(info.ButtonID)
{
default:
{
if(radiostate == 1 && m_Item != null )
{ // accept
if(m_Item is IXmlQuest)
{
((IXmlQuest)m_Item).Invalidate();
}
else
if(m_Item is XmlQuestBook)
{
((XmlQuestBook)m_Item).Invalidate();
}
else
{
m_Item.Delete();
}
}
else
if(m_From != null && m_Item != null && !m_Item.Deleted)
{
m_From.AddToBackpack(m_Item);
}
break;
}
}
}
}
public class XmlSimpleGump : Gump
{
public static string Color( string text, string color )
{
return String.Format( "<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text );
}
private int m_gumptype;
private object m_invoker;
private BaseXmlSpawner.KeywordTag m_keywordtag;
private XmlGumpCallback m_gumpcallback;
private List<GumpSelection> gumpSelections = new List<GumpSelection>();
private class GumpSelection
{
public string Selection;
public string Response;
public int GumpItemType; // 1=textentry
public GumpSelection(string s, string r)
{
Selection = s;
Response = r;
}
}
void LocalAddHtml(string text, int x, int y, int width, int height, int color, bool background, bool scrollbar)
{
if (text == null) return;
// check for cliloc specification
if (text.StartsWith("#"))
{
int cliloc = 0;
if(int.TryParse(text.Substring(1, text.Length - 1), out cliloc))
AddHtmlLocalized(x, y, width, height, cliloc, color, background, scrollbar);
}
else
{
try
{
string colorstring = String.Format("{0:X}",color);
AddHtml(x, y, width, height, XmlSimpleGump.Color(text, colorstring), background, scrollbar);
}
catch { }
}
}
private string ParseGumpText(string text)
{
string maintext = text;
// format for multiple selection specifications is
// maintext ; selection0 ; response0 ; selection1 ; response1 ....
string [] args = text.Split(';');
// the first arg is the maintext
if(args.Length > 0)
{
maintext = args[0];
// fill the selection and responses with the remaining args
for(int i = 1;i<args.Length;i += 2)
{
GumpSelection s = new GumpSelection("","");
if(i < args.Length) s.Selection = args[i].Trim();
if(i+1 < args.Length) s.Response = args[i+1].Trim();
gumpSelections.Add(s);
}
}
return maintext;
}
public XmlSimpleGump( object invoker, string gumptext, string gumptitle, int gumptype, BaseXmlSpawner.KeywordTag tag, Mobile from) : this( invoker, gumptext, gumptitle, gumptype, tag, from, null)
{
}
public XmlSimpleGump( object invoker, string gumptext, string gumptitle, int gumptype, BaseXmlSpawner.KeywordTag tag, Mobile from, XmlGumpCallback gumpcallback) : base( 0, 0 )
{
string maintext = gumptext;
int nselections = 0;
int height = 400;
int width = 369;
Closable = false;
Dragable = true;
m_gumptype = gumptype;
m_invoker = invoker;
m_keywordtag = tag;
m_gumpcallback = gumpcallback;
AddPage( 0 );
// for the multiple selection gump, parse the gumptext for selections and responses
if(gumptype == 4)
{
maintext = ParseGumpText(gumptext);
nselections = gumpSelections.Count;
height = height + nselections*40;
}
if(gumptype == 5)
{
maintext = ParseGumpText(gumptext);
nselections = gumpSelections.Count;
// the maintext in this case is a width,height specifier so parse it
string [] args = maintext.Split(',');
if(args != null && args.Length>1)
{
int.TryParse(args[0].Trim(), out width);
int.TryParse(args[1].Trim(), out height);
}
}
AddImageTiled( 54, 33, width, height, 2624 );
AddAlphaRegion( 54, 33, width, height );
AddImageTiled( width + 47, 39, 44, height-11, 203 );
AddImageTiled( 58, 39, 29, height - 10, 10460 ); // left hand border
AddImageTiled( width + 43, 37, 31, height - 11, 10460 ); // right hand border
AddImageTiled( 40, 38, 17, height - 9, 9263 ); // leftmost border
//AddImageTiled( 94, 25, width - 27, 15, 10304 ); // top border
AddImageTiled( 40, 25, width + 48, 15, 10304 ); // top border
AddImageTiled( 40, height + 27, width + 46, 16, 10304 ); // bottom border
if(gumptype != 5)
{
AddImage( width + 61, 9, 10441); // dragon borders
AddImage( 6, 25, 10421 );
AddImage( 34, 12, 10420 );
AddImage( -10, height - 86, 10402 );
AddImage( 56, 150, 10411 );
AddImage( 136, 84, 96 ); // divider
AddImage( width + 3, 57, 1417); // quest icons
AddImage( width + 12, 66, 5576);
AddButton( width - 31, height - 8, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
}
else
{
AddButton( width + 70, 25, 0x138b, 0x138b, 0, GumpButtonType.Reply, 0 ); // closegump button
}
if(gumptitle != null && gumptitle.Length > 0 && gumptype != 5)
{ // display the title if it is there
AddImage( 156, 126, 2103 ); // bullet
LocalAddHtml(gumptitle, 174, 121, 200, 40, 0x00FF42, false, false);
}
if(gumptype == 0)
{ // simple message gump
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
} else
if(gumptype == 1)
{ // Yes/no type gump
AddRadio( 101, height - 45, 9721, 9724, true, 1 ); // accept/yes radio
AddRadio( 101, height - 11, 9721, 9724, false, 2 ); // decline/no radio
AddHtmlLocalized(137, height - 41, 200, 30, 1049016, 0x7fff , false , false ); // Yes
AddHtmlLocalized(137, height - 7, 200, 30, 1049017, 0x7fff , false , false ); // No
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 2)
{ // reply type gump
AddImageTiled( 134, height - 7, 159, 23, 0x52 );
AddImageTiled( 135, height - 6, 157, 21, 0xBBC );
AddHtmlLocalized(105, height - 7, 200, 30, 3002006, 0x7fff , false , false ); // Say:
AddTextEntry( 135, height - 7, 150, 21, 0, 99, null );
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 3)
{ // Quest type gump
AddImage( 97, 49, 9005 ); // quest ribbon
AddRadio( 101, height - 45, 9721, 9724, true, 1 ); // accept/yes radio
AddRadio( 101, height - 11, 9721, 9724, false, 2 ); // decline/no radio
AddHtmlLocalized( 139, 59, 200, 30, 1046013, 0x7fff, false , false ); // Quest Offer
AddHtmlLocalized(137, height - 41, 200, 30, 1049011, 0x7fff , false , false ); // I accept!
AddHtmlLocalized(137, height - 7, 200, 30, 1049012, 0x7fff , false , false ); // No thanks, I decline.
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 4)
{ // multiple selection type gump
// parse the gump text to get the selections and responses
for(int i=0;i < gumpSelections.Count; i++)
{
int y = 360 + i*40;
AddRadio( 101, y, 9721, 9724, i==0 ? true: false, i ); // accept/yes radio
AddHtml( 137, y+4, 250, 40, XmlSimpleGump.Color( gumpSelections[i].Selection, "FFFFFF" ), false, false );
}
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 5)
{
// parse the gump text to get the selections and responses
for(int i=0;i < gumpSelections.Count; i++)
{
string selection = gumpSelections[i].Selection;
string response = gumpSelections[i].Response;
int gx = 0;
int gy = 0;
int gwidth = 0;
int gheight = 0;
string label = null;
string [] args = null;
int gumpid = 0;
int color = 0;
if(selection != null)
{
args = selection.Split(',');
}
// process the gumpitem specifications
if(args.Length > 1)
{
for(int j=0;j<args.Length;j++)
{
args[j] = args[j].Trim();
}
if(args[0].ToLower() == "button")
{
// syntax is button,gumpid,x,y
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
int buttonid = 1000 + i;
// add the button
AddButton( gx, gy, gumpid, gumpid, buttonid, GumpButtonType.Reply, 0 );
}
}
else
if(args[0].ToLower() == "label")
{
// syntax is label,x,y,label[,color]
if(args.Length > 3)
{
int.TryParse(args[1], out gx);
int.TryParse(args[2], out gy);
label = args[3];
}
// set the default label color
color = 0x384;
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the label
AddLabel( gx, gy, color, label );
}
else
if(args[0].ToLower() == "html")
{
// reparse the specification to allow for the possibility of commas in the html text
args = selection.Split(new char[] {','},6);
color = 0xEFEF5A;
// syntax is html,x,y,width,height,text[,hue] * hue has to be in HEX format, ex: 0xFF00AA (lenght of 8 mandatory!)
if(args.Length > 5)
{
int.TryParse(args[1].Trim(), out gx);
int.TryParse(args[2].Trim(), out gy);
int.TryParse(args[3].Trim(), out gwidth);
int.TryParse(args[4].Trim(), out gheight);
if(args.Length>6 && args[5].StartsWith("0x") && args[5].Trim().Length==8)
{
if(!int.TryParse(args[5].Trim().Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color))
color=0xEFEF5A;
label = args[6];
}
else
label = args[5];
}
// add the html area
//AddHtml( gx, gy, gwidth, gheight, label, false, true );
LocalAddHtml(label, gx, gy, gwidth, gheight, color, false, true);
}
else
if(args[0].ToLower() == "textentry")
{
gumpSelections[i].GumpItemType = 1;
// syntax is textentry,x,y,width,height[,textcolor][,text]
if(args.Length > 4)
{
int.TryParse(args[1].Trim(), out gx);
int.TryParse(args[2].Trim(), out gy);
int.TryParse(args[3].Trim(), out gwidth);
int.TryParse(args[4].Trim(), out gheight);
}
if(args.Length > 5)
{
label = args[5];
}
// set the default textentry color
color = 0x384;
if(args.Length > 6)
{
int.TryParse(args[6], out color);
}
AddTextEntry( gx, gy, gwidth, gheight, color, i, label );
}
else
if(args[0].ToLower() == "radio")
{
int gumpid1 = 0;
int gumpid2 = 0;
// syntax is radio,gumpid1,gumpid2,x,y[,initialstate]
if(args.Length > 4)
{
int.TryParse(args[1].Trim(), out gumpid1);
int.TryParse(args[2].Trim(), out gumpid2);
int.TryParse(args[3].Trim(), out gx);
int.TryParse(args[4].Trim(), out gy);
}
bool initial = false;
if(args.Length > 5)
{
bool.TryParse(args[5], out initial);
}
AddRadio( gx, gy, gumpid1, gumpid2, initial, i);
}
else
if(args[0].ToLower() == "image")
{
// syntax is image,gumpid,x,y[,hue]
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the image
AddImage( gx, gy, gumpid, color );
}
}
else
if(args[0].ToLower() == "imagetiled")
{
// syntax is imagetiled,gumpid,x,y,width,height
if(args.Length > 5)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
int.TryParse(args[4], out gwidth);
int.TryParse(args[5], out gheight);
// add the image
AddImageTiled( gx, gy, gwidth, gheight, gumpid );
}
}
else
if(args[0].ToLower() == "item")
{
// syntax is item,itemid,x,y[,hue]
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the image
AddItem( gx, gy, gumpid, color );
}
}
}
}
}
}
public override void OnResponse( Server.Network.NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
Mobile from = state.Mobile;
if(m_gumpcallback != null)
{
if(info.ButtonID == 0)
{
m_gumpcallback( from, m_invoker, String.Empty);
}
else
{
switch (m_gumptype)
{
case 0: // simple acknowledgement gump
m_gumpcallback(from, m_invoker, "done");
break;
case 1: // yes/no gump
if (info.Switches != null && info.Switches.Length > 0)
{
if (info.Switches[0] == 1)
{
m_gumpcallback(from, m_invoker, "yes");
}
else
{
m_gumpcallback(from, m_invoker, "no");
}
}
break;
case 2: // text entry gump
TextRelay entry = info.GetTextEntry(99);
if (entry != null && entry.Text.Length > 0)
{
// return the response string
m_gumpcallback(from, m_invoker, entry.Text);
}
break;
case 3: // accept/decline gump
if (info.Switches != null && info.Switches.Length > 0)
{
if (info.Switches[0] == 1)
{
from.SendLocalizedMessage(1049019); // You have accepted the Quest.
m_gumpcallback(from, m_invoker, "accept");
}
else
{
from.SendLocalizedMessage(1049018); // You have declined the Quest.
m_gumpcallback(from, m_invoker, "decline");
}
}
break;
case 4: // multiple option gump
if (info.Switches != null && info.Switches.Length > 0)
{
int select = info.Switches[0];
if (select >= 0 && select < gumpSelections.Count)
{
// return the response string for that selection
m_gumpcallback(from, m_invoker, gumpSelections[select].Response);
}
}
break;
case 5:
string buttonresponse = String.Empty;
string radioresponse = String.Empty;
string textresponse = String.Empty;
if (info.ButtonID >= 1000)
{
int select = info.ButtonID - 1000;
// get the gump response associated with the button
if (select >= 0 && select < gumpSelections.Count)
{
// return the response string for that selection
buttonresponse = gumpSelections[select].Response;
}
}
if (info.Switches != null && info.Switches.Length > 0)
{
int radiostate = info.Switches[0];
if (radiostate >= 0 && radiostate < gumpSelections.Count)
{
radioresponse = gumpSelections[radiostate].Response;
}
}
// check for any textentries
for (int j = 0; j < gumpSelections.Count; j++)
{
if (gumpSelections[j].GumpItemType == 1)
{
try
{
TextRelay te = info.GetTextEntry(j);
if (te != null && te.Text.Length > 0)
{
textresponse += te.Text + " ";
}
}
catch { }
}
}
// build the composite reponse string
string responsestring = null;
if (buttonresponse != null && buttonresponse.Length > 0)
{
responsestring = buttonresponse;
}
if (radioresponse != null && radioresponse.Length > 0)
{
responsestring += " " + radioresponse;
}
if (textresponse != null && textresponse.Length > 0)
{
responsestring += " " + textresponse;
}
m_gumpcallback(from, m_invoker, responsestring);
break;
}
}
}
// get rid of any temporary gump keyword tokens
if(m_invoker is XmlSpawner)
((XmlSpawner)m_invoker).DeleteTag(m_keywordtag);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,690 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
namespace Server.Gumps
{
public class XmlQuestStatusGump : Gump
{
public static string Color(string text, string color)
{
return String.Format("<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text);
}
public void DisplayQuestStatus(int x, int y, string objectivestr, string statestr, bool status, string descriptionstr)
{
if (objectivestr != null && objectivestr.Length > 0)
{
// look for special keywords
string[] arglist = BaseXmlSpawner.ParseString(objectivestr, 5, ",");
int targetcount = 1;
bool foundkill = false;
bool foundcollect = false;
bool foundgive = false;
bool foundescort = false;
string name = null;
string mobname = null;
string type = null;
string status_str;
string text = null;
string typestr;
bool checkprop;
if (arglist.Length > 0)
switch (arglist[0])
{
case "GIVE":
// format for the objective string will be GIVE,mobname,itemtype[,count][,proptest]
if (arglist.Length > 2)
{
mobname = arglist[1];
//name = arglist[2];
type = arglist[2];
}
XmlQuest.CheckArgList(arglist, 3, null, out typestr, out targetcount, out checkprop, out status_str);
foundgive = true;
break;
case "GIVENAMED":
// format for the objective string will be GIVENAMED,mobname,itemname[,type][,count][,proptest]
if (arglist.Length > 2)
{
mobname = arglist[1];
name = arglist[2];
}
XmlQuest.CheckArgList(arglist, 3, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundgive = true;
break;
case "KILL":
// format for the objective string will be KILL,mobtype[,count][,proptest]
if (arglist.Length > 1)
{
//name = arglist[1];
type = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
foundkill = true;
break;
case "KILLNAMED":
// format for the objective string KILLNAMED,mobname[,type][,count][,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundkill = true;
break;
case "COLLECT":
// format for the objective string will be COLLECT,itemtype[,count][,proptest]
if (arglist.Length > 1)
{
//name = arglist[1];
type = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
foundcollect = true;
break;
case "COLLECTNAMED":
// format for the objective string will be COLLECTNAMED,itemname[,itemtype][,count][,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundcollect = true;
break;
case "ESCORT":
// format for the objective string will be ESCORT,mobname[,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
foundescort = true;
break;
}
if (foundkill)
{
// get the current kill status
int killed = 0;
try
{
killed = int.Parse(statestr);
}
catch { }
int remaining = targetcount - killed;
if (remaining < 0) remaining = 0;
// report the kill task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "mob";
text = String.Format("Kill {0} {1}(s) named {2} ({3} left)", targetcount, type, name, remaining);
}
else
text = String.Format("Kill {0} {1}(s) ({2} left)", targetcount, type, remaining);
}
}
else
if (foundescort)
{
// get the current escort status
int escorted = 0;
try
{
escorted = int.Parse(statestr);
}
catch { }
int remaining = targetcount - escorted;
if (remaining < 0) remaining = 0;
// report the escort task objective status
if (descriptionstr != null)
text = descriptionstr;
else
text = String.Format("Escort {0}", name);
}
else
if (foundcollect)
{
// get the current collection status
int collected = 0;
try
{
collected = int.Parse(statestr);
}
catch { }
int remaining = targetcount - collected;
if (remaining < 0) remaining = 0;
// report the collect task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "mob";
text = String.Format("Collect {0} {1}(s) named {2} ({3} left)", targetcount, type, name, remaining);
}
else
text = String.Format("Collect {0} {1}(s) ({2} left)", targetcount, type, remaining);
}
}
else
if (foundgive)
{
// get the current give status
int collected = 0;
try
{
collected = int.Parse(statestr);
}
catch { }
int remaining = targetcount - collected;
if (remaining < 0) remaining = 0;
// report the collect task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "item";
text = String.Format("Give {0} {1}(s) named {2} to {3} ({4} left)", targetcount, type, name, mobname, remaining);
}
else
text = String.Format("Give {0} {1}(s) to {2} ({3} left)", targetcount, type, mobname, remaining);
}
}
else
{
// just report the objectivestring
text = objectivestr;
}
AddHtml(x, y, 223, 35, XmlSimpleGump.Color(text, "EFEF5A"), false, false);
if (status)
{
AddImage(x - 20, y + 3, 0x939); // bullet
AddHtmlLocalized(x + 222, y, 225, 37, 1046033, 0xff42, false, false); // Complete
}
else
{
AddImage(x - 20, y + 3, 0x938); // bullet
AddHtmlLocalized(x + 222, y, 225, 37, 1046034, 0x7fff, false, false); // Incomplete
}
}
}
private IXmlQuest m_questitem;
private string m_gumptitle;
private int m_X;
private int m_Y;
private bool m_solid;
private int m_screen;
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle)
: this(questitem, gumptitle, 0, 0, false, 0)
{
}
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid)
: this(questitem, gumptitle, X, Y, solid, 0)
{
}
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid, int screen)
: base(X, Y)
{
Closable = true;
Dragable = true;
m_X = X;
m_Y = Y;
m_solid = solid;
m_questitem = questitem;
m_gumptitle = gumptitle;
m_screen = screen;
AddPage(0);
if (!solid)
{
AddImageTiled(54, 33, 369, 400, 2624);
AddAlphaRegion(54, 33, 369, 400);
}
else
{
AddBackground(54, 33, 369, 400, 5054);
}
AddImageTiled(416, 39, 44, 389, 203);
// AddButton( 338, 392, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
AddHtmlLocalized(139, 59, 200, 30, 1046026, 0x7fff, false, false); // Quest Log
AddImage(97, 49, 9005); // quest ribbon
AddImageTiled(58, 39, 29, 390, 10460); // left hand border
AddImageTiled(412, 37, 31, 389, 10460); // right hand border
AddImage(430, 9, 10441);
AddImageTiled(40, 38, 17, 391, 9263);
AddImage(6, 25, 10421);
AddImage(34, 12, 10420);
AddImageTiled(94, 25, 342, 15, 10304); // top border
AddImageTiled(40, 414, 415, 16, 10304); // bottom border
AddImage(-10, 314, 10402);
AddImage(56, 150, 10411);
AddImage(136, 84, 96);
AddImage(372, 57, 1417);
AddImage(381, 66, 5576);
// add the status and journal tabs
AddImageTiled(90, 34, 322, 5, 0x145E); // top border
int tab1 = 0x138F;
int tab2 = 0x138E;
if (screen == 1)
{
tab1 = 0x138E;
tab2 = 0x138F;
}
AddButton(100, 18, tab1, tab2, 900, GumpButtonType.Reply, 0);
AddLabel(115, 17, 0, "Status");
AddButton(189, 18, tab2, tab1, 901, GumpButtonType.Reply, 0);
AddLabel(205, 17, 0, "Journal");
if (screen == 1)
{
// display the journal
if (questitem.Journal != null && questitem.Journal.Count > 0)
{
string journaltext = null;
for (int i = 0; i < questitem.Journal.Count; i++)
{
journaltext += "<u>";
journaltext += questitem.Journal[i].EntryID;
journaltext += ":</u><br>";
journaltext += questitem.Journal[i].EntryText;
journaltext += "<br><br>";
}
AddHtml(100, 90, 270, 300, journaltext, true, true);
}
// add the add journal entry button
AddButton(300, 49, 0x99C, 0x99D, 952, GumpButtonType.Reply, 0);
//AddButton(300, 49, 0x159E, 0x159D, 952, GumpButtonType.Reply, 0);
}
else
{
if (gumptitle != null && gumptitle.Length > 0)
{ // display the title if it is there
AddImage(146, 91, 2103); // bullet
AddHtml(164, 86, 200, 30, XmlSimpleGump.Color(gumptitle, "00FF42"), false, false);
}
if (questitem.NoteString != null && questitem.NoteString.Length > 0)
{ // display the note string if it is there
AddHtml(100, 106, 270, 80, questitem.NoteString, true, true);
}
DisplayQuestStatus(130, 192, questitem.Objective1, questitem.State1, questitem.Completed1, questitem.Description1);
DisplayQuestStatus(130, 224, questitem.Objective2, questitem.State2, questitem.Completed2, questitem.Description2);
DisplayQuestStatus(130, 256, questitem.Objective3, questitem.State3, questitem.Completed3, questitem.Description3);
DisplayQuestStatus(130, 288, questitem.Objective4, questitem.State4, questitem.Completed4, questitem.Description4);
DisplayQuestStatus(130, 320, questitem.Objective5, questitem.State5, questitem.Completed5, questitem.Description5);
//if(questitem.HasCollect){
AddButton(100, 350, 0x2A4E, 0x2A3A, 700, GumpButtonType.Reply, 0);
AddLabel(135, 356, 0x384, "Collect");
//}
if ((questitem.RewardItem != null && !questitem.RewardItem.Deleted))
{
m_questitem.CheckRewardItem();
if (questitem.RewardItem.Amount > 1)
{
AddLabel(230, 356, 55, String.Format("Reward: {0} ({1})", questitem.RewardItem.GetType().Name,
questitem.RewardItem.Amount));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.Weight * questitem.RewardItem.Amount));
}
else
if (questitem.RewardItem is Container)
{
AddLabel(230, 356, 55, String.Format("Reward: {0} ({1} items)", questitem.RewardItem.GetType().Name,
questitem.RewardItem.TotalItems));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.TotalWeight + questitem.RewardItem.Weight));
}
else
{
AddLabel(230, 356, 55, String.Format("Reward: {0}", questitem.RewardItem.GetType().Name));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.Weight));
}
AddImageTiled(330, 373, 81, 40, 200);
AddItem(340, 376, questitem.RewardItem.ItemID);
}
if (questitem.RewardAttachment != null && !questitem.RewardAttachment.Deleted)
{
AddLabel(230, 339, 55, String.Format("Bonus: {0}", questitem.RewardAttachment.GetType().Name));
}
if ((questitem.RewardItem != null && !questitem.RewardItem.Deleted) || (questitem.RewardAttachment != null && !questitem.RewardAttachment.Deleted))
{
if (questitem.CanSeeReward)
{
AddButton(400, 380, 2103, 2103, 800, GumpButtonType.Reply, 0);
}
}
// indicate any status info
XmlQuest.VerifyObjectives(questitem);
if (questitem.Status != null)
{
AddLabel(100, 392, 33, questitem.Status);
}
else
// indicate the expiration time
if (questitem.IsValid)
{
//AddHtmlLocalized(150, 400, 50, 37, 1046033, 0xf0000 , false , false ); // Expires
AddHtml(130, 392, 200, 37, XmlSimpleGump.Color(questitem.ExpirationString, "00FF42"), false, false);
}
else
if (questitem.AlreadyDone)
{
if (!questitem.Repeatable)
{
AddLabel(100, 392, 33, "Already done - cannot be repeated");
}
else
{
List<XmlAttachment> a = XmlAttach.FindAttachments(questitem.Owner, typeof(XmlQuestAttachment), questitem.Name);
if (a != null && a.Count > 0)
{
AddLabel(100, 392, 33, String.Format("Repeatable in {0}", a[0].Expiration));
}
else
{
AddLabel(150, 392, 33, "Already done - ???");
}
}
}
else
{
//AddHtml( 150, 384, 200, 37, XmlSimpleGump.Color( "No longer valid", "00FF42" ), false, false );
AddLabel(150, 392, 33, "No longer valid");
}
if (XmlQuest.QuestPointsEnabled)
{
AddHtml(250, 40, 200, 30, XmlSimpleGump.Color(String.Format("Difficulty Level {0}", questitem.Difficulty), "00FF42"), false, false);
}
if (questitem.PartyEnabled)
{
AddHtml(250, 55, 200, 30, XmlSimpleGump.Color("Party Quest", "00FF42"), false, false);
if (questitem.PartyRange >= 0)
{
AddHtml(250, 70, 200, 30, XmlSimpleGump.Color(String.Format("Party Range {0}", questitem.PartyRange), "00FF42"), false, false);
}
else
{
AddHtml(250, 70, 200, 30, XmlSimpleGump.Color("No Range Limit", "00FF42"), false, false);
}
}
else
{
AddHtml(250, 55, 200, 30, XmlSimpleGump.Color("Solo Quest", "00FF42"), false, false);
}
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info == null || state == null || state.Mobile == null || state.Mobile.Deleted || m_questitem == null || m_questitem.Deleted)
return;
switch (info.ButtonID)
{
case 700:
state.Mobile.Target = new XmlQuest.GetCollectTarget(m_questitem);
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, m_screen));
break;
case 800:
if(!m_questitem.CanSeeReward) return;
if (m_questitem.RewardItem != null || m_questitem.RewardAttachment != null)
{
// open a new status gump
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, m_screen));
}
// display the reward item
if (m_questitem.RewardItem != null)
{
// show the contents of the xmlquest pack
if (m_questitem.Pack != null)
m_questitem.Pack.DisplayTo(state.Mobile);
}
// identify the reward attachment
if (m_questitem.RewardAttachment != null)
{
//state.Mobile.SendMessage("{0}",m_questitem.RewardAttachment.OnIdentify(state.Mobile));
state.Mobile.CloseGump(typeof(DisplayAttachmentGump));
state.Mobile.SendGump(new DisplayAttachmentGump(state.Mobile, m_questitem.RewardAttachment.OnIdentify(state.Mobile)));
}
break;
case 900:
// open a new status gump with status display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 0));
break;
case 901:
// open a new status gump with journal display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
break;
case 952:
// open a new status gump with journal display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
// and open the journal entry editing gump
// only allow this to be used if the questholder is theirs
if (m_questitem.Owner == state.Mobile)
{
state.Mobile.SendGump(new JournalEntryGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid));
}
break;
}
}
public class JournalEntryGump : Gump
{
private IXmlQuest m_questitem;
private string m_gumptitle;
private int m_X, m_Y;
private bool m_solid;
public JournalEntryGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid)
: base(X, Y)
{
if (questitem == null || questitem.Deleted)
return;
m_questitem = questitem;
m_gumptitle = gumptitle;
m_X = X;
m_Y = Y;
m_solid = solid;
AddPage(0);
//AddBackground(0, 0, 260, 354, 5054);
//AddAlphaRegion(20, 0, 220, 354);
AddImage(0, 0, 0x24AE); // left top scroll
AddImage(114, 0, 0x24AF); // middle top scroll
AddImage(170, 0, 0x24B0); // right top scroll
AddImageTiled(0, 140, 114, 100, 0x24B1); // left middle scroll
AddImageTiled(114, 140, 114, 100, 0x24B2); // middle middle scroll
AddImageTiled(170, 140, 114, 100, 0x24B3); // right middle scroll
AddImage(0, 210, 0x24B4); // left bottom scroll
AddImage(114, 210, 0x24B5); // middle bottom scroll
AddImage(170, 210, 0x24B6); // right bottom scroll
//AddImageTiled(23, 40, 214, 290, 0x52);
//AddImageTiled(24, 41, 213, 281, 0xBBC);
// OK button
AddButton(25, 327, 0xFB7, 0xFB9, 1, GumpButtonType.Reply, 0);
// Close button
AddButton(230, 327, 0xFB1, 0xFB3, 0, GumpButtonType.Reply, 0);
// Edit button
//AddButton(100, 325, 0xEF, 0xEE, 2, GumpButtonType.Reply, 0);
string str = null;
int entrynumber = 0;
if (questitem.Journal != null && questitem.Journal.Count > 0)
{
entrynumber = questitem.Journal.Count;
}
string m_entryid = "Personal entry #" + entrynumber;
// entryid text entry area
//AddImageTiled(23, 0, 214, 23, 0x52);
//AddImageTiled(24, 1, 213, 21, 0xBBC);
AddTextEntry(35, 5, 200, 21, 0, 1, m_entryid);
// main text entry area
AddTextEntry(35, 40, 200, 271, 0, 0, str);
// editing text entry areas
// background for text entry area
/*
AddImageTiled(23, 275, 214, 23, 0x52);
AddImageTiled(24, 276, 213, 21, 0xBBC);
AddImageTiled(23, 300, 214, 23, 0x52);
AddImageTiled(24, 301, 213, 21, 0xBBC);
AddTextEntry(35, 275, 200, 21, 0, 1, null);
AddTextEntry(35, 300, 200, 21, 0, 2, null);
*/
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info == null || state == null || state.Mobile == null) return;
if (m_questitem == null || m_questitem.Deleted)
return;
bool update_entry = false;
//bool edit_entry = false;
switch (info.ButtonID)
{
case 0: // Close
{
update_entry = false;
break;
}
case 1: // Okay
{
update_entry = true;
break;
}
case 2: // Edit
{
//edit_entry = true;
break;
}
default:
update_entry = true;
break;
}
if (update_entry)
{
string entrytext = null;
string entryid = null;
TextRelay entry = info.GetTextEntry(0);
if (entry != null)
{
entrytext = entry.Text;
}
entry = info.GetTextEntry(1);
if (entry != null)
{
entryid = entry.Text;
}
m_questitem.AddJournalEntry = entryid + ":" + entrytext;
}
// open a new journal gump
state.Mobile.CloseGump(typeof(XmlQuestStatusGump));
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
}
}
private class DisplayAttachmentGump : Gump
{
public DisplayAttachmentGump(Mobile from, string text)
: base(0, 0)
{
// prepare the page
AddPage(0);
AddBackground(0, 0, 400, 150, 5054);
AddAlphaRegion(0, 0, 400, 150);
AddLabel(20, 2, 55, "Quest Attachment Description");
AddHtml(20, 20, 360, 110, text, true, true);
}
}
}
}

View File

@@ -0,0 +1,749 @@
#define FACTIONS
using System;
using System.IO;
using System.Xml;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Targeting;
using Server.Gumps;
using System.Text;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestLeaders
{
private static TimeSpan m_QuestLeaderboardSaveInterval = TimeSpan.FromMinutes(15); // default time interval between quest leaderboard saves
private static string m_QuestLeaderboardSaveDirectory = "Leaderboard"; // default directory for saving quest leaderboard xml information
private static int m_QuestLeaderboardSaveRanks = 20; // number of ranked players to save to the quest leaderboard. 0 means save all players.
private static QuestLeaderboardTimer m_QuestLeaderboardTimer;
private static string m_QuestLeaderboardFile;
private static List<XmlQuestLeaders.QuestRankEntry> QuestRankList = new List<XmlQuestLeaders.QuestRankEntry>();
private static bool needsupdate = true;
public class QuestRankEntry : IComparable<XmlQuestLeaders.QuestRankEntry>
{
public Mobile Quester;
public int Rank;
public XmlQuestPoints QuestPointsAttachment;
public QuestRankEntry(Mobile m, XmlQuestPoints attachment)
{
Quester = m;
QuestPointsAttachment = attachment;
}
public int CompareTo( QuestRankEntry p )
{
if(p.QuestPointsAttachment == null || QuestPointsAttachment == null) return 0;
// break points ties with quests completed (more quests means higher rank)
if(p.QuestPointsAttachment.Points - QuestPointsAttachment.Points == 0)
{
// if kills are the same then compare previous rank
if(p.QuestPointsAttachment.QuestsCompleted - QuestPointsAttachment.QuestsCompleted == 0)
{
return p.QuestPointsAttachment.Rank - QuestPointsAttachment.Rank;
}
return p.QuestPointsAttachment.QuestsCompleted - QuestPointsAttachment.QuestsCompleted;
}
return p.QuestPointsAttachment.Points - QuestPointsAttachment.Points;
}
}
private static void RefreshQuestRankList()
{
if(needsupdate && QuestRankList != null)
{
QuestRankList.Sort();
int rank = 0;
//int prevpoints = 0;
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// bump the rank for every change in point level
// this means that people with the same points score will have the same rank
/*
if(p.QuestPointsAttachment.Points != prevpoints)
{
rank++;
}
prevpoints = p.QuestPointsAttachment.Points;
*/
// bump the rank for every successive player in the list. Players with the same points total will be
// ordered by quests completed
rank++;
p.Rank = rank;
}
needsupdate = false;
}
}
public static int GetQuestRanking(Mobile m)
{
if(QuestRankList == null || m == null) return 0;
RefreshQuestRankList();
// go through the sorted list and calculate rank
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// found the person?
if(p.Quester == m)
{
return p.Rank;
}
}
// rank 0 means unranked
return 0;
}
public static void UpdateQuestRanking(Mobile m, XmlQuestPoints attachment)
{
if(QuestRankList == null) QuestRankList = new List<XmlQuestLeaders.QuestRankEntry>();
// flag the rank list for updating on the next attempt to retrieve a rank
needsupdate = true;
bool found = false;
// rank the entries
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// found a match
if(p != null && p.Quester == m)
{
// update the entry with the new points value
p.QuestPointsAttachment = attachment;
found = true;
break;
}
}
// a new entry so add it
if(!found)
{
QuestRankList.Add(new QuestRankEntry(m, attachment));
}
}
public static void Initialize()
{
CommandSystem.Register( "QuestLeaderboardSave", AccessLevel.Administrator, new CommandEventHandler( QuestLeaderboardSave_OnCommand ) );
CommandSystem.Register( "QuestRanking", AccessLevel.Player, new CommandEventHandler( QuestRanking_OnCommand ) );
}
[Usage( "QuestRanking" )]
[Description( "Displays the top players in quest points" )]
public static void QuestRanking_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
// if this player has an XmlQuestPoints attachment, find it
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(e.Mobile,typeof(XmlQuestPoints));
e.Mobile.CloseGump(typeof(TopQuestPlayersGump));
e.Mobile.SendGump(new TopQuestPlayersGump(p));
}
public static void WriteQuestLeaderboardXml(string filename, int nranks)
{
string dirname = Path.Combine( m_QuestLeaderboardSaveDirectory, filename );
StreamWriter sw = new StreamWriter( dirname );
XmlTextWriter xf = new XmlTextWriter( sw );
if(xf == null)
{
Console.WriteLine("Error: unable to save XML quest leaderboard to {0}", dirname);
return;
}
xf.Formatting = Formatting.Indented;
xf.WriteStartDocument( true );
xf.WriteStartElement( "QuestLeaderboard" );
if(nranks > 0)
xf.WriteAttributeString( "nentries", nranks.ToString() );
else
xf.WriteAttributeString( "nentries", QuestRankList.Count.ToString() );
// go through the sorted list and display the top ranked players
for(int i= 0; i<QuestRankList.Count;i++)
{
if(nranks > 0 && i >= nranks) break;
QuestRankEntry r = QuestRankList[i];
XmlQuestPoints a = r.QuestPointsAttachment;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null)
guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
// write out the entry information
xf.WriteStartElement( "Entry" );
xf.WriteAttributeString( "number", i.ToString() );
xf.WriteStartElement( "Player" );
xf.WriteString( r.Quester.Name );
xf.WriteEndElement();
xf.WriteStartElement( "Guild" );
xf.WriteString( guildname );
xf.WriteEndElement();
#if(FACTIONS)
xf.WriteStartElement( "Faction" );
xf.WriteString( factionname );
xf.WriteEndElement();
#endif
xf.WriteStartElement( "Points" );
xf.WriteString( a.Points.ToString() );
xf.WriteEndElement();
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
xf.WriteStartElement( "Quests" );
xf.WriteString( quests );
xf.WriteEndElement();
xf.WriteStartElement( "Rank" );
xf.WriteString( a.Rank.ToString() );
xf.WriteEndElement();
xf.WriteStartElement( "Change" );
xf.WriteString( a.DeltaRank.ToString() );
xf.WriteEndElement();
xf.WriteStartElement( "Duration" );
xf.WriteString( timeranked.ToString() );
xf.WriteEndElement();
// end the entry
xf.WriteEndElement();
}
}
xf.WriteEndElement();
xf.Close();
}
public static void WriteQuestLeaderboardHtml(string filename, int nranks)
{
string dirname = Path.Combine( m_QuestLeaderboardSaveDirectory, filename );
StreamWriter sw = new StreamWriter( dirname );
if(sw == null)
{
Console.WriteLine("Error: unable to save HTML quest leaderboard to {0}", dirname);
return;
}
sw.WriteLine("<TABLE border=\"1\" summary=\"This table gives quest leaderboard stats\"> ");
sw.WriteLine( "<CAPTION><B>Quest Leaderboard</B></CAPTION>");
#if(FACTIONS)
sw.WriteLine( "<TR><TH><TH>Player Name<TH>Guild<TH>Faction<TH>Points<TH>Quests<TH>Rank<TH>Change<TH>Time at current rank");
#else
sw.WriteLine( "<TR><TH><TH>Player Name<TH>Guild<TH>Points<TH>Quests<TH>Rank<TH>Change<TH>Time at current rank");
#endif
// go through the sorted list and display the top ranked players
for(int i= 0; i<QuestRankList.Count;i++)
{
if(nranks > 0 && i >= nranks) break;
QuestRankEntry r = QuestRankList[i];
XmlQuestPoints a = r.QuestPointsAttachment;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null)
guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
#if(FACTIONS)
// write out the entry information
sw.WriteLine( "<TR><TH><TD>{0}<TD>{1}<TD>{2}<TD>{3}<TD>{4}<TD>{5}<TD>{6}<TD>{7}",
r.Quester.Name,
guildname,
factionname,
a.Points,
quests,
a.Rank,
a.DeltaRank,
timeranked
);
#else
// write out the entry information
sw.WriteLine( "<TR><TH><TD>{0}<TD>{1}<TD>{2}<TD>{3}<TD>{4}<TD>{5}<TD>{6}",
r.Quester.Name,
guildname,
a.Points,
quests,
a.Rank,
a.DeltaRank,
timeranked
);
#endif
}
}
sw.WriteLine( "</TABLE>");
sw.Close();
}
public static void WriteQuestLeaderboard(string filename, int nranks)
{
if(QuestRankList == null) return;
// force an update of the quest leaderboard rankings
needsupdate = true;
RefreshQuestRankList();
if ( !Directory.Exists( m_QuestLeaderboardSaveDirectory ) )
Directory.CreateDirectory( m_QuestLeaderboardSaveDirectory );
WriteQuestLeaderboardXml(filename + ".xml", nranks);
WriteQuestLeaderboardHtml(filename + ".html", nranks);
}
[Usage( "QuestLeaderboardSave [filename [minutes[nentries]]][off]" )]
[Description( "Periodically save .xml quest leaderboard information to the specified file" )]
public static void QuestLeaderboardSave_OnCommand( CommandEventArgs e )
{
if(e.Arguments.Length > 0)
{
if(m_QuestLeaderboardTimer != null) m_QuestLeaderboardTimer.Stop();
if(e.Arguments[0].ToLower() != "off")
{
m_QuestLeaderboardFile = e.Arguments[0];
if(e.Arguments.Length > 1)
{
try
{
m_QuestLeaderboardSaveInterval = TimeSpan.FromMinutes(double.Parse(e.Arguments[1]));
}
catch{}
}
if(e.Arguments.Length > 2)
{
try
{
m_QuestLeaderboardSaveRanks = int.Parse(e.Arguments[2]);
}
catch{}
}
m_QuestLeaderboardTimer = new QuestLeaderboardTimer(m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval, m_QuestLeaderboardSaveRanks);
m_QuestLeaderboardTimer.Start();
}
}
if(m_QuestLeaderboardTimer != null && m_QuestLeaderboardTimer.Running)
{
e.Mobile.SendMessage("Quest Leaderboard is saving to {0} every {1} minutes. Nranks = {2}",
m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval.TotalMinutes, m_QuestLeaderboardSaveRanks);
}
else
{
e.Mobile.SendMessage("Quest Leaderboard saving is off.");
}
}
public static void QuestLBSSerialize( GenericWriter writer )
{
// version
writer.Write( (int) 0 );
// version 0
if(m_QuestLeaderboardTimer != null && m_QuestLeaderboardTimer.Running)
{
writer.Write((bool)true);
}
else
writer.Write((bool)false);
writer.Write(m_QuestLeaderboardSaveInterval);
writer.Write(m_QuestLeaderboardSaveRanks);
writer.Write(m_QuestLeaderboardFile);
}
public static void QuestLBSDeserialize(GenericReader reader)
{
int version = reader.ReadInt();
switch(version)
{
case 0:
bool running = reader.ReadBool();
m_QuestLeaderboardSaveInterval = reader.ReadTimeSpan();
m_QuestLeaderboardSaveRanks = reader.ReadInt();
m_QuestLeaderboardFile = reader.ReadString();
if(running)
{
if(m_QuestLeaderboardTimer != null) m_QuestLeaderboardTimer.Stop();
m_QuestLeaderboardTimer = new QuestLeaderboardTimer(m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval, m_QuestLeaderboardSaveRanks);
m_QuestLeaderboardTimer.Start();
}
break;
}
}
// added the duration timer that begins on spawning
private class QuestLeaderboardTimer : Timer
{
private string m_filename;
private int m_nranks;
public QuestLeaderboardTimer( string filename, TimeSpan delay, int nranks ) : base( delay, delay )
{
m_filename = filename;
m_nranks = nranks;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
WriteQuestLeaderboard(m_filename, m_nranks);
}
}
public class TopQuestPlayersGump : Gump
{
private XmlQuestPoints m_attachment;
public TopQuestPlayersGump(XmlQuestPoints attachment) : base( 0,0)
{
if(QuestRankList == null) return;
m_attachment = attachment;
int numberToDisplay = 20;
int height = numberToDisplay*20 + 65;
// prepare the page
AddPage( 0 );
int width = 740;
#if(FACTIONS)
width = 790;
#endif
AddBackground( 0, 0, width, height, 5054 );
AddAlphaRegion( 0, 0, width, height );
AddImageTiled( 20, 20, width - 40, height - 45, 0xBBC );
AddLabel( 20, 2, 55, "Top Quest Player Rankings" );
// guild filter
AddLabel( 40, height - 20, 55, "Filter by Guild" );
string filter = null;
if(m_attachment != null)
filter = m_attachment.guildFilter;
AddImageTiled( 140, height - 20, 160, 19, 0xBBC );
AddTextEntry( 140, height - 20, 160, 19, 0, 200, filter );
AddButton( 20, height - 20, 0x15E1, 0x15E5, 200, GumpButtonType.Reply, 0 );
// name filter
AddLabel( 340, height - 20, 55, "Filter by Name" ); //
string nfilter = null;
if(m_attachment != null)
nfilter = m_attachment.nameFilter;
AddImageTiled( 440, height - 20, 160, 19, 0xBBC );
AddTextEntry( 440, height - 20, 160, 19, 0, 100, nfilter );
AddButton( 320, height - 20, 0x15E1, 0x15E5, 100, GumpButtonType.Reply, 0 );
RefreshQuestRankList();
int xloc = 23;
AddLabel( xloc, 20, 0, "Name" );
xloc += 177;
AddLabel( xloc, 20, 0, "Guild" );
#if(FACTIONS)
xloc += 35;
AddLabel( xloc, 20, 0, "Faction" );
xloc += 15;
#endif
xloc += 50;
AddLabel( xloc, 20, 0, "Points" );
xloc += 50;
AddLabel( xloc, 20, 0, "Quests" );
xloc += 50;
//AddLabel( xloc, 20, 0, "" );
xloc += 70;
AddLabel( xloc, 20, 0, "Rank" );
xloc += 45;
AddLabel( xloc, 20, 0, "Change" );
xloc += 45;
AddLabel( xloc, 20, 0, "Time at Rank" );
// go through the sorted list and display the top ranked players
int y = 40;
int count = 0;
for(int i= 0; i<QuestRankList.Count;i++)
{
if(count >= numberToDisplay) break;
QuestRankEntry r = QuestRankList[i];
if(r == null) continue;
XmlQuestPoints a = r.QuestPointsAttachment;
if(a == null) continue;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null) guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
// check for guild filter
if(m_attachment != null && m_attachment.guildFilter != null && m_attachment.guildFilter.Length > 0)
{
// parse the comma separated list
string [] args = m_attachment.guildFilter.Split(',');
if(args != null)
{
bool found = false;
foreach(string arg in args)
{
if(arg != null && guildname == arg.Trim())
{
found = true;
break;
}
}
if(!found) continue;
}
}
// check for name filter
if(m_attachment != null && m_attachment.nameFilter != null && m_attachment.nameFilter.Length > 0)
{
// parse the comma separated list
string [] args = m_attachment.nameFilter.Split(',');
if(args != null)
{
bool found = false;
foreach(string arg in args)
{
if(arg != null && r.Quester.Name != null && (r.Quester.Name.ToLower().IndexOf(arg.Trim().ToLower()) >= 0))
{
found = true;
break;
}
}
if(!found) continue;
}
}
count++;
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
int days = (int)timeranked.TotalDays;
int hours = (int)(timeranked.TotalHours - days*24);
int mins = (int)(timeranked.TotalMinutes - ((int)timeranked.TotalHours)*60);
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
xloc = 23;
AddLabel( xloc, y, 0, r.Quester.Name ?? String.Empty );
xloc += 177;
AddLabel( xloc, y, 0, guildname ?? String.Empty );
#if(FACTIONS)
xloc += 35;
AddLabelCropped( xloc, y, 60, 21, 0, factionname ?? String.Empty );
xloc += 15;
#endif
xloc += 50;
AddLabel( xloc, y, 0, a.Points.ToString() );
xloc += 50;
AddLabel( xloc, y, 0, quests ?? String.Empty );
xloc += 50;
//AddLabel( xloc, y, 0, "" );
xloc += 70;
AddLabel( xloc, y, 0, a.Rank.ToString() );
string label=null;
if(days > 0)
label += String.Format("{0} days ",days);
if(hours > 0)
label += String.Format("{0} hours ",hours);
if(mins > 0)
label += String.Format("{0} mins",mins);
if(label == null)
{
label = "just changed";
}
string deltalabel = a.DeltaRank.ToString();
int deltahue = 0;
if(a.DeltaRank > 0)
{
deltalabel = String.Format("+{0}",a.DeltaRank);
deltahue = 68;
}
else if(a.DeltaRank < 0)
{
deltahue = 33;
}
xloc += 50;
AddLabel( xloc, y, deltahue, deltalabel );
xloc += 40;
AddLabel( xloc, y, 0, label);
y += 20;
}
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(state == null || state.Mobile == null || info == null) return;
// Get the current name
if(m_attachment != null)
{
TextRelay entry = info.GetTextEntry( 200 );
if(entry != null)
m_attachment.guildFilter = entry.Text;
entry = info.GetTextEntry( 100 );
if(entry != null)
m_attachment.nameFilter = entry.Text;
}
switch(info.ButtonID)
{
case 100:
case 200:
{
// redisplay the gump
state.Mobile.SendGump(new TopQuestPlayersGump(m_attachment));
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,380 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Gumps;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestPoints : XmlAttachment
{
private int m_Points;
private int m_Completed;
private int m_Credits;
private List<XmlQuestPoints.QuestEntry> m_QuestList = new List<XmlQuestPoints.QuestEntry>();
private DateTime m_WhenRanked;
private int m_Rank;
private int m_DeltaRank;
public string guildFilter;
public string nameFilter;
public List<XmlQuestPoints.QuestEntry> QuestList { get{ return m_QuestList; } set { m_QuestList = value; }}
[CommandProperty( AccessLevel.GameMaster )]
public int Rank { get{ return m_Rank; } set { m_Rank = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int DeltaRank { get{ return m_DeltaRank; } set { m_DeltaRank = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public DateTime WhenRanked { get{ return m_WhenRanked; } set { m_WhenRanked = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Points { get{ return m_Points; } set { m_Points = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Credits { get{ return m_Credits; } set { m_Credits = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int QuestsCompleted { get{ return m_Completed; } set { m_Completed = value; } }
public class QuestEntry
{
public Mobile Quester;
public string Name;
public DateTime WhenCompleted;
public DateTime WhenStarted;
public int Difficulty;
public bool PartyEnabled;
public int TimesCompleted = 1;
public QuestEntry()
{
}
public QuestEntry(Mobile m, IXmlQuest quest)
{
Quester = m;
if(quest != null)
{
WhenStarted = quest.TimeCreated;
WhenCompleted = DateTime.UtcNow;
Difficulty = quest.Difficulty;
Name = quest.Name;
}
}
public virtual void Serialize( GenericWriter writer )
{
writer.Write( (int) 0 ); // version
writer.Write(Quester);
writer.Write(Name);
writer.Write(WhenCompleted);
writer.Write(WhenStarted);
writer.Write(Difficulty);
writer.Write(TimesCompleted);
writer.Write(PartyEnabled);
}
public virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
switch(version)
{
case 0:
Quester = reader.ReadMobile();
Name = reader.ReadString();
WhenCompleted = reader.ReadDateTime();
WhenStarted = reader.ReadDateTime();
Difficulty = reader.ReadInt();
TimesCompleted = reader.ReadInt();
PartyEnabled = reader.ReadBool();
break;
}
}
public static void AddQuestEntry(Mobile m, IXmlQuest quest)
{
if(m == null || quest == null) return;
// get the XmlQuestPoints attachment from the mobile
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p == null) return;
// look through the list of quests and see if it is one that has already been done
if(p.QuestList == null) p.QuestList = new List<XmlQuestPoints.QuestEntry>();
bool found = false;
foreach(QuestEntry e in p.QuestList)
{
if(e.Name == quest.Name)
{
// found a match, so just change the number and dates
e.TimesCompleted++;
e.WhenStarted = quest.TimeCreated;
e.WhenCompleted = DateTime.UtcNow;
// and update the difficulty and party status
e.Difficulty = quest.Difficulty;
e.PartyEnabled = quest.PartyEnabled;
found = true;
break;
}
}
if(!found)
{
// add a new entry
p.QuestList.Add(new QuestEntry(m, quest));
}
}
}
public XmlQuestPoints(ASerial serial) : base(serial)
{
}
[Attachable]
public XmlQuestPoints()
{
}
public static new void Initialize()
{
CommandSystem.Register( "QuestPoints", AccessLevel.Player, new CommandEventHandler( CheckQuestPoints_OnCommand ) );
CommandSystem.Register( "QuestLog", AccessLevel.Player, new CommandEventHandler( QuestLog_OnCommand ) );
}
[Usage( "QuestPoints" )]
[Description( "Displays the players quest points and ranking" )]
public static void CheckQuestPoints_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
string msg = null;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(e.Mobile, typeof(XmlQuestPoints));
if(p != null)
{
msg = p.OnIdentify(e.Mobile);
}
if(msg != null)
e.Mobile.SendMessage(msg);
}
[Usage( "QuestLog" )]
[Description( "Displays players quest history" )]
public static void QuestLog_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
e.Mobile.CloseGump(typeof(XMLQuestLogGump));
e.Mobile.SendGump(new XMLQuestLogGump(e.Mobile));
}
public static void GiveQuestPoints(Mobile from, IXmlQuest quest)
{
if(from == null || quest == null) return;
// find the XmlQuestPoints attachment
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(from, typeof(XmlQuestPoints));
// if doesnt have one yet, then add it
if(p == null)
{
p = new XmlQuestPoints();
XmlAttach.AttachTo(from, p);
}
// if you wanted to scale the points given based on party size, karma, fame, etc.
// this would be the place to do it
int points = quest.Difficulty;
// update the questpoints attachment information
p.Points += points;
p.Credits += points;
p.QuestsCompleted++;
if(from != null)
{
from.SendMessage("You have received {0} quest points!",points);
}
// add the completed quest to the quest list
QuestEntry.AddQuestEntry(from, quest);
// update the overall ranking list
XmlQuestLeaders.UpdateQuestRanking(from, p);
}
public static int GetCredits(Mobile m)
{
int val = 0;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
val = p.Credits;
}
return val;
}
public static int GetPoints(Mobile m)
{
int val = 0;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
val = p.Points;
}
return val;
}
public static bool HasCredits(Mobile m, int credits, int minpoints)
{
if(m == null || m.Deleted) return false;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
if(p.Credits >= credits && p.Points >= minpoints)
{
return true;
}
}
return false;
}
public static bool TakeCredits(Mobile m, int credits)
{
if(m == null || m.Deleted) return false;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
if(p.Credits >= credits)
{
p.Credits -= credits;
return true;
}
}
return false;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write( (int) 0 );
// version 0
writer.Write(m_Points);
writer.Write(m_Credits);
writer.Write(m_Completed);
writer.Write(m_Rank);
writer.Write(m_DeltaRank);
writer.Write(m_WhenRanked);
// save the quest history
if(QuestList != null)
{
writer.Write((int)QuestList.Count);
foreach(QuestEntry e in QuestList)
{
e.Serialize(writer);
}
}
else
{
writer.Write((int)0);
}
// need this in order to rebuild the rankings on deser
if(AttachedTo is Mobile)
writer.Write(AttachedTo as Mobile);
else
writer.Write((Mobile)null);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch(version)
{
case 0:
m_Points = reader.ReadInt();
m_Credits = reader.ReadInt();
m_Completed = reader.ReadInt();
m_Rank = reader.ReadInt();
m_DeltaRank = reader.ReadInt();
m_WhenRanked = reader.ReadDateTime();
int nquests = reader.ReadInt();
if(nquests > 0)
{
QuestList = new List<XmlQuestPoints.QuestEntry>(nquests);
for(int i = 0; i< nquests;i++)
{
QuestEntry e = new QuestEntry();
e.Deserialize(reader);
QuestList.Add(e);
}
}
// get the owner of this in order to rebuild the rankings
Mobile quester = reader.ReadMobile();
// rebuild the ranking list
// if they have never made a kill, then dont rank
if(quester != null && QuestsCompleted > 0)
{
XmlQuestLeaders.UpdateQuestRanking(quester, this);
}
break;
}
}
public override string OnIdentify(Mobile from)
{
return String.Format("Quest Points Status:\nTotal Quest Points = {0}\nTotal Quests Completed = {1}\nQuest Credits Available = {2}",Points, QuestsCompleted, Credits);
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
/*
** XmlQuestPointsRewards
** ArteGordon
** updated 9/18/05
**
** this class lets you specify rewards that can be purchased for XmlQuestPoints quest Credits.
** The items will be displayed in the QuestPointsRewardGump that is opened by the QuestPointsRewardStone
*/
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestPointsRewards
{
public int Cost; // cost of the reward in credits
public Type RewardType; // this will be used to create an instance of the reward
public string Name; // used to describe the reward in the gump
public int ItemID; // used for display purposes
public int ItemHue;
public int yOffset;
public object [] RewardArgs; // arguments passed to the reward constructor
public int MinPoints; // the minimum points requirement for the reward
private static List<XmlQuestPointsRewards> PointsRewardList = new List<XmlQuestPointsRewards>();
public static List<XmlQuestPointsRewards> RewardsList { get { return PointsRewardList; } }
public XmlQuestPointsRewards(int minpoints, Type reward, string name, int cost, int id, int hue, int yoffset, object[] args)
{
RewardType = reward;
Cost = cost;
ItemID = id;
ItemHue = hue;
Name = name;
RewardArgs = args;
MinPoints = minpoints;
yOffset = yoffset;
}
public static void Initialize()
{
// these are items as rewards. Note that the args list must match a constructor for the reward type specified.
PointsRewardList.Add( new XmlQuestPointsRewards( 1000, typeof(PowerScroll), "105 Smithing powerscroll", 1000, 0x14F0, 0, 5, new object[] { SkillName.Blacksmith, 105 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 2000, typeof(PowerScroll), "110 Smithing powerscroll", 2000, 0x14F0, 0x22, 5, new object[] { SkillName.Blacksmith, 110 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 4000, typeof(PowerScroll), "115 Smithing powerscroll", 4000, 0x14F0, 0x44, 5, new object[] { SkillName.Blacksmith, 115 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 500, typeof(AncientSmithyHammer), "+20 Ancient Smithy Hammer, 50 uses", 500, 0x13E4, 0, 5, new object[] { 20, 50 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 200, typeof(ColoredAnvil), "Colored Anvil", 400, 0xFAF, 0, 5, null ));
PointsRewardList.Add( new XmlQuestPointsRewards( 100, typeof(PowderOfTemperament), "Powder Of Temperament, 10 uses", 300, 4102, 0, 5, new object[] { 10 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 100, typeof(LeatherGlovesOfMining), "+20 Leather Gloves Of Mining", 200, 0x13c6, 0, 5, new object[] { 20 }));
// this is an example of adding a mobile as a reward
PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(RidableLlama),"Ridable Llama", 1, 0x20f6, 0, -15, null));
// this is an example of adding an attachment as a reward
//PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(XmlEnemyMastery), "+200% Balron Mastery for 1 day", 2, 0, 0, 0, new object[] { "Balron", 50, 200, 1440.0 }));
//PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(XmlStr), "+20 Strength for 1 day", 10, 0, new object[] { 20, 86400.0 }));
}
}
}

File diff suppressed because it is too large Load Diff