#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.

This commit is contained in:
WarrentyExpired 2026-08-06 11:06:05 -04:00
parent b51c58f514
commit 3045c83799
3512 changed files with 627673 additions and 0 deletions

View file

@ -0,0 +1,779 @@
using System;
using Server;
namespace Server.Items
{
public class GrimmochJournal1 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day One :",
"",
"'Tis a grand sight, this",
"primeval tomb, I agree",
"with Tavara on that.",
"And we've a good crew",
"here, they've strong",
"backs and a good"
),
new BookPageInfo
(
"attitude. I'm a bit",
"concerned by those",
"that worked as guides",
"for us, however. All",
"seemed well enough",
"until we revealed the",
"immense stone doors",
"of the tomb structure"
),
new BookPageInfo
(
"itself. Seemed to send",
"a shiver up their",
"spines and get them all",
"stirred up with",
"whispering. I'll",
"watch the lot of them",
"with a close eye, but",
"I'm confident we won't"
),
new BookPageInfo
(
"have any real",
"problems on the dig.",
"I'm especially proud to",
"see Thomas standing",
"out - he was a good",
"hire, despite the",
"warnings from his",
"previous employers."
),
new BookPageInfo
(
"He's drummed up the",
"workers into a",
"furious pace - we've",
"nearly halved the",
"estimate on the",
"timeline for",
"excavating the Tomb's",
"entrance."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal1() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal1( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal2 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Two :",
"",
"We managed to dig out",
"the last of the",
"remaining rubble",
"today, revealing the",
"entirety of the giant",
"stone doors that sealed"
),
new BookPageInfo
(
"ol' Khal Ankur and",
"his folk up ages ago.",
"Actually getting them",
"open was another",
"matter altogether,",
"however. As the",
"workers set to the",
"task with picks and"
),
new BookPageInfo
(
"crowbars, I could have",
"sworn I saw Lysander",
"Gathenwale fiddling",
"with something in that",
"musty old tome of his.",
" I've no great",
"knowledge of things",
"magical, but the way"
),
new BookPageInfo
(
"his hand moved over",
"that book, and the look",
"of concentration on his",
"face as he whispered",
"something to himself",
"looked like every",
"description of an",
"incantation I've ever"
),
new BookPageInfo
(
"heard. The strange",
"thing is, this set of",
"doors that an entire",
"crew of excavators",
"was laboring over for",
"hours, right when",
"Gathenwale finishes",
"with his mumbling..."
),
new BookPageInfo
(
"well, I swore the doors",
"just gave open at the",
"exact moment he",
"spoke his last bit of",
"whisper and shut the",
"tome tight in his",
"hands. When he",
"looked up, it was"
),
new BookPageInfo
(
"almost as if he was",
"expecting the doors to",
"be open, rather than",
"shocked that they'd",
"finally given way."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal2() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal2( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal3 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Three - Day Five:",
"",
"I might have",
"written too hastily in",
"my first entry - this",
"place doesn't seem too",
"bent on giving up any",
"secrets. Though the"
),
new BookPageInfo
(
"main antechamber is",
"open to us, the main",
"exit hall is blocked by",
"yet another pile of",
"rubble. Doesn't look a",
"bit like anything",
"caused by a quake or",
"instability in the"
),
new BookPageInfo
(
"stonework... I swear it",
"looks as if someone",
"actually piled the",
"stones up themselves,",
"some time after the",
"tomb was built. The",
"stones aren't of the",
"same set nor quality"
),
new BookPageInfo
(
"of the carved work",
"that surrounds them",
"- if anything, they",
"resemble the grade of",
"common rock we saw",
"in great quantities on",
"the trip here. Which",
"makes it feel all the"
),
new BookPageInfo
(
"more like someone",
"hauled them in and",
"deliberately covered",
"this passage. But then",
"why not decorate them",
"in the same ornate",
"manner as the rest of",
"the stone in this"
),
new BookPageInfo
(
"place? Lysander",
"wouldn't hear a word",
"of what I had to say -",
"to him, it was a quake",
"some time in the",
"history of the tomb,",
"and that was it, shut",
"up and move on. So I"
),
new BookPageInfo
(
"shut up, and got back",
"to work."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal3() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal3( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal6 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Six :",
"",
"The camp was",
"attacked last night by",
"a pack of, well, I don't",
"have a clue. I've never",
"seen the like of these",
"beasts anywhere."
),
new BookPageInfo
(
"Huge things, with",
"fangs the size of your",
"forefinger, covered in",
"hair and with the",
"strangest arched back",
"I've ever seen. And so",
"many of them. We",
"were forced back into"
),
new BookPageInfo
(
"the Tomb for the",
"night, just to keep our",
"hides on us. And",
"today Gathenwale",
"practically orders us",
"all to move the entire",
"exterior camp into the",
"Tomb. Now, I don't"
),
new BookPageInfo
(
"disagree that we'd be",
"well off to use the",
"place as a point of",
"fortification... but I",
"don't like it one bit, in",
"any case. I don't like",
"the look of this place,",
"nor the sound of it."
),
new BookPageInfo
(
"The way the wind",
"gets into the",
"passageways,",
"whistling up the",
"strangest noises.",
"Deep, sustained echoes",
"of the wind, not so",
"much flute-like as..."
),
new BookPageInfo
(
"well, it sounds",
"ridiculous. In any",
"case, we've set to work",
"moving the bulk of the",
"exterior camp into the",
"main antechamber, so",
"there's no use moaning",
"about it now."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal6() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal6( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal7 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Seven - Day Ten:",
"",
"I cannot stand this",
"place, I cannot bear it.",
"I've got to get out.",
"Something evil lurks",
"in this ancient place,",
"something best left"
),
new BookPageInfo
(
"alone. I hear them,",
"yet none of the others",
"do. And yet they",
"must. Hands, claws,",
"scratching at stone,",
"the awful scratching",
"and the piteous cries",
"that sound almost like"
),
new BookPageInfo
(
"laughter. I can hear",
"them above even the",
"cracks of the",
"workmen's picks, and",
"at night they are all I",
"can hear. And yet the",
"others hear nothing.",
"We must leave this"
),
new BookPageInfo
(
"place, we must.",
"Three workers have",
"gone missing - Tavara",
"expects they've",
"abandoned us - and I",
"count them lucky if",
"they have. I don't care",
"what the others say,"
),
new BookPageInfo
(
"we must leave this",
"place. We must do as",
"those before and pile",
"up the stones, block all",
"access to this primeval",
"crypt, seal it up again",
"for all eternity."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal7() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal7( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal11 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Eleven - Day",
"Thirteen :",
"",
"Lysander is gone, and",
"two more workers",
"with him. Good",
"riddance to the first.",
"He knows something."
),
new BookPageInfo
(
"He heard them too, I",
"know he did - and yet",
"he scowled at me",
"when I mentioned",
"them. I cannot stop",
"the noise in my head,",
"the scratching, the",
"clawing tears at my"
),
new BookPageInfo
(
"senses. What is it?",
"What does Lysander",
"seek that I can only",
"turn from? Where",
"has he gone? The",
"only answer to my",
"questions comes as",
"laughter from behind"
),
new BookPageInfo
(
"the stones."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal11() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal11( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal14 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Fourteen - Day",
"Sixteen :",
"",
"We are lost... we are",
"lost... all is lost. The",
"dead are piled up at",
"my feet. Bergen and I",
"somehow managed in"
),
new BookPageInfo
(
"the madness to piece",
"together a barricade,",
"barring access to the",
"camp antechamber.",
"He knows as well as I",
"that we cannot hold it",
"forever. The dead",
"come. They took"
),
new BookPageInfo
(
"Lysander before our",
"eyes. I pity the soul",
"of even such a",
"madman - no one",
"should die in such a",
"manner. And yet so",
"many have. We're",
"trapped here in this"
),
new BookPageInfo
(
"horror. So many have",
"died, and for what?",
"What curse have we",
"stumbled upon? I",
"cannot bear it, the",
"moaning, wailing cries",
"of the dead. Poor",
"Thomas, cut to pieces"
),
new BookPageInfo
(
"by their blades. We",
"had only an hour to",
"properly bury those",
"we could, before the",
"undead legions struck",
"again. I cannot go on...",
"I cannot go on."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal14() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal14( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal17 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Seventeen - Day",
"Twenty-Two :",
"",
"The fighting never",
"ceases... the blood",
"never stops flowing,",
"like a river through",
"the bloated corpses of"
),
new BookPageInfo
(
"the dead. And yet",
"there are still more.",
"Always more, with",
"the red fire gleaming",
"in their eyes. My",
"arm aches, I've taken",
"to the sword as my",
"bow seems to do little"
),
new BookPageInfo
(
"good... the dull ache in",
"my arm... so many",
"swings, cleaving a",
"mountain of decaying",
"flesh. And Thomas...",
"he was there, in the",
"thick of it... Thomas",
"was beside me..."
),
new BookPageInfo
(
"his face cleaved in",
"twain - and yet beside",
"me, fighting with us",
"against the horde until",
"he was cut down once",
"again. And I swear I",
"see him even now,",
"there in the dark"
),
new BookPageInfo
(
"corner of the",
"antechamber, his eyes",
"flickering in the last",
"dying embers of the",
"fire... and he stares at",
"me, and a scream fills",
"the vault - whether",
"his or mine, I can no"
),
new BookPageInfo
(
"longer tell."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal17() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal17( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class GrimmochJournal23 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"The daily journal of Grimmoch Drummel", "Grimmoch",
new BookPageInfo
(
"Day Twenty-Three :",
"",
"We no longer bury the",
"dead."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public GrimmochJournal23() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public GrimmochJournal23( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,539 @@
using System;
using Server;
namespace Server.Items
{
public class LysanderNotebook1 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day One :",
"",
"At last, it stands",
"before me. The doors",
"of Thy Sanctum will",
"open to me now, after",
"all these years of",
"searching. I give"
),
new BookPageInfo
(
"myself unto Thee,",
"Khal Ankur, I have",
"come for Thy secrets",
"and I will kneel",
"prostrate before Thee.",
" Blessed are the",
"Keepers, praise unto",
"Thee, a thousand"
),
new BookPageInfo
(
"fortunes in the night."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook1() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook1( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class LysanderNotebook2 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day Two:",
"",
"The woman, Tavara",
"Sewel, is unbearable.",
"Her entire demeanor",
"sickens me. I would",
"take her life for Thee",
"now, my Lord. But I"
),
new BookPageInfo
(
"cannot alert the",
"others. Progress is",
"made too slowly, I",
"cannot stand this",
"perpetual waiting.",
"Today I knelt down",
"with the workers,",
"tossing stones and dirt"
),
new BookPageInfo
(
"aside with my very",
"hands as they dug at",
"the last of the rubble",
"covering the entrance",
"to Thy Sanctum. The",
"Sewel woman was",
"shocked at my",
"demeanor, dirtying"
),
new BookPageInfo
(
"my robes, on my",
"knees in the muck as I",
"clawed at the rocks.",
"She thought I did this",
"for those sickly",
"scholars, or for her,",
"or for what she",
"laughably calls 'The"
),
new BookPageInfo
(
"Gift of Discovery', of",
"learning. As if I did",
"not know what I went",
"to find! I come for",
"Thee, Master. Soon",
"shall I receive Thy",
"gifts, Thy blessings.",
"Patience, eternal"
),
new BookPageInfo
(
"patience. I must take",
"my lessons well. I",
"have learned from",
"Thee, Master, I have."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook2() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook2( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class LysanderNotebook3 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day Three - Day Six:",
"",
"What are these Beasts",
"that dare to defy our",
"presence here? Hast",
"Thou sent them,",
"Master? To tear",
"apart these foolish"
),
new BookPageInfo
(
"ones that accompany",
"me? That repugnant",
"pustule, Drummel, put",
"forth his absurd little",
"theories as to the",
"nature of the Beasts",
"that attacked our",
"camp, but I'll have"
),
new BookPageInfo
(
"none of his words. He",
"asks too many",
"questions. He is a",
"taint upon the grounds",
"of Thy Sanctum,",
"Master - I will deal",
"with him after the",
"Sewel woman."
),
new BookPageInfo
(
"Speaking of Sewel, I",
"have convinced that",
"empty-headed harlot",
"that we should move",
"our encampment",
"within the",
"antechamber. She",
"thinks I worry for"
),
new BookPageInfo
(
"her safety. I come",
"for thee, Master. I",
"make my camp in Thy",
"chambers. I sleep",
"under Thy roof. I can",
"feel Thine presence",
"even now. Soon,",
"Master. Soon."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook3() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook3( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class LysanderNotebook7 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day Seven :",
"",
"The Sewel woman",
"pratters on endlessly.",
"And she dares to",
"speak Thy Name,",
"Master! I wish so",
"vehemently to take a"
),
new BookPageInfo
(
"knife to that little",
"neck of hers. She",
"struts around the",
"chambers of Thy",
"Sanctum with her",
"repugnant airs, her",
"scholarly conjecture",
"on this or that. That I"
),
new BookPageInfo
(
"could peel the skin",
"from her face and",
"show her how vile and",
"ugly she truly is, how",
"unworthy of entrance",
"to Thy Sanctum. I",
"must take her,",
"Master. I must rend"
),
new BookPageInfo
(
"that little wench to",
"pieces. I ask this gift",
"of Thee, that I might",
"cleanse Thy Sanctum",
"of her presence. Give",
"me the Sewel woman",
"and I shall show you",
"my mastery of Death,"
),
new BookPageInfo
(
"Master. I shall cut",
"her to bits and scatter",
"them before the",
"others as a warning.",
"I cannot stand her",
"presence, I cannot",
"abide it. And",
"Drummel! He is a"
),
new BookPageInfo
(
"pustule that must be",
"lanced, a sickness that",
"I must cure by blade",
"and fire. Not a trace",
"of him will be left",
"when I'm done with",
"him. Praises to Thee,",
"Master. I shall honor"
),
new BookPageInfo
(
"Thee with many",
"sacrifices, soon",
"enough."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook7() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook7( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class LysanderNotebook8 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day Eight - Day Ten :",
"",
"Have you taken them,",
"Master? They could",
"not have found a way",
"past the stones that",
"block our path! The",
"three workers, My"
),
new BookPageInfo
(
"Master, where have",
"they gone? Curses",
"upon them! I'll cut",
"them all to pieces if",
"they show their faces",
"again, then burn the",
"rest alive upon a pyre,",
"for all to see, as a"
),
new BookPageInfo
(
"warning of Thy",
"Power. How could",
"they have gotten past",
"me? I sleep against",
"the very walls, to",
"hear Thy Words, to",
"feel Thy Breath. I",
"can find no egress"
),
new BookPageInfo
(
"from the chambers",
"that the Sewel woman",
"does not know of nor",
"have men working at",
"excavating. Where",
"have they gone,",
"Master? Have you",
"taken them, or do they"
),
new BookPageInfo
(
"truly flee from Thy",
"Presence? I will kill",
"them if they show",
"their faces again.",
"Give me Strength, my",
"Master, to let them",
"live a while longer,",
"until they have"
),
new BookPageInfo
(
"fulfilled their",
"purpose and I kneel",
"before Thee, covered",
"in their blood."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook8() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook8( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class LysanderNotebook11 : BaseBook
{
public static readonly BookContent Content = new BookContent
(
"Lysander's Notebook", "L. Gathenwale",
new BookPageInfo
(
"Day Eleven - Day",
"Thirteen:",
"",
"I come for Thee, my",
"Master. I come! The",
"way is clear, I have",
"found Thy path and",
"washed it in the blood"
),
new BookPageInfo
(
"of the two workers",
"that caught sight of",
"me. Ah, how sweet it",
"was to cut them open,",
"to see the blood pour",
"out in great torrents, to",
"stand in it, to revel in",
"it. If only I had time"
),
new BookPageInfo
(
"for the Sewel woman.",
"But there will be time",
"enough for her. I",
"have learned Thy",
"Patience, Master. I",
"come for Thee. I walk",
"Thy halls in penance,",
"my last steps in this"
),
new BookPageInfo
(
"repulsive living",
"frame. I come for",
"Thee and Thy Gifts,",
"my Master. Glory",
"Unto Thee, Khal",
"Ankur, Keeper of the",
"Seventh Death,",
"Master, Leader of the"
),
new BookPageInfo
(
"Chosen, the Khaldun.",
"Praises in Thy",
"Name, Master of Life",
"and Death, Lord of All.",
" Khal Ankur, Master,",
"Prophet, I join Thy",
"ranks this night, a",
"member of the"
),
new BookPageInfo
(
"Khaldun at last!"
)
);
public override BookContent DefaultContent{ get{ return Content; } }
[Constructable]
public LysanderNotebook11() : base( Utility.Random( 0xFF1, 2 ), false )
{
}
public LysanderNotebook11( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int)0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,211 @@
using System;
using Server;
using Server.Items;
namespace Server.Commands
{
public class GenKhaldun
{
private static int m_Count;
public static void Initialize()
{
CommandSystem.Register( "GenKhaldun", AccessLevel.Administrator, new CommandEventHandler( GenKhaldun_OnCommand ) );
}
public static bool FindMorphItem( int x, int y, int z, int inactiveItemID, int activeItemID )
{
IPooledEnumerable eable = Map.Felucca.GetItemsInRange( new Point3D( x, y, z ), 0 );
foreach ( Item item in eable )
{
if ( item is MorphItem && item.Z == z && ((MorphItem)item).InactiveItemID == inactiveItemID && ((MorphItem)item).ActiveItemID == activeItemID )
{
eable.Free();
return true;
}
}
eable.Free();
return false;
}
public static bool FindEffectController( int x, int y, int z )
{
IPooledEnumerable eable = Map.Felucca.GetItemsInRange( new Point3D( x, y, z ), 0 );
foreach ( Item item in eable )
{
if ( item is EffectController && item.Z == z )
{
eable.Free();
return true;
}
}
eable.Free();
return false;
}
public static Item TryCreateItem( int x, int y, int z, Item srcItem )
{
IPooledEnumerable eable = Map.Felucca.GetItemsInBounds( new Rectangle2D( x, y, 1, 1 ) );
foreach ( Item item in eable )
{
if ( item.GetType() == srcItem.GetType() )
{
eable.Free();
srcItem.Delete();
return item;
}
}
eable.Free();
srcItem.MoveToWorld( new Point3D( x, y, z ), Map.Felucca );
m_Count++;
return srcItem;
}
public static void CreateMorphItem( int x, int y, int z, int inactiveItemID, int activeItemID, int range )
{
if ( FindMorphItem( x, y, z, inactiveItemID, activeItemID ) )
return;
MorphItem item = new MorphItem( inactiveItemID, activeItemID, range, 3 );
item.MoveToWorld( new Point3D( x, y, z ), Map.Felucca );
m_Count++;
}
public static void CreateApproachLight( int x, int y, int z, int off, int on, LightType light )
{
if ( FindMorphItem( x, y, z, off, on ) )
return;
MorphItem item = new MorphItem( off, on, 2, 3 );
item.Light = light;
item.MoveToWorld( new Point3D( x, y, z ), Map.Felucca );
m_Count++;
}
public static void CreateSoundEffect( int x, int y, int z, int sound, int range )
{
if ( FindEffectController( x, y, z ) )
return;
EffectController item = new EffectController();
item.SoundID = sound;
item.TriggerType = EffectTriggerType.InRange;
item.TriggerRange = range;
item.MoveToWorld( new Point3D( x, y, z ), Map.Felucca );
m_Count++;
}
public static void CreateBigTeleporterItem( int x, int y, bool reverse )
{
if ( FindMorphItem( x, y, 0, reverse ? 0x17DC : 0x17EE, reverse ? 0x17EE : 0x17DC ) )
return;
MorphItem item = new MorphItem( reverse ? 0x17DC : 0x17EE, reverse ? 0x17EE : 0x17DC, 1, 3 );
item.MoveToWorld( new Point3D( x, y, 0 ), Map.Felucca );
m_Count++;
}
public static void GenKhaldun_OnCommand( CommandEventArgs e )
{
m_Count = 0;
// Generate Morph Items
CreateMorphItem( 5459, 1416, 0, 0x1D0, 0x1, 1 );
CreateMorphItem( 5460, 1416, 0, 0x1D0, 0x1, 1 );
CreateMorphItem( 5459, 1416, 0, 0x1, 0x53D, 1 );
CreateMorphItem( 5460, 1416, 0, 0x1, 0x53B, 1 );
CreateMorphItem( 5459, 1425, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5459, 1426, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5459, 1427, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5460, 1425, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5460, 1426, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5460, 1427, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5461, 1427, 0, 0x1, 0x53B, 2 );
CreateMorphItem( 5460, 1422, 0, 0x1, 0x544, 2 );
CreateMorphItem( 5460, 1419, 0, 0x1, 0x545, 2 );
CreateMorphItem( 5460, 1420, 0, 0x1, 0x545, 2 );
CreateMorphItem( 5460, 1423, 0, 0x1, 0x545, 2 );
CreateMorphItem( 5460, 1424, 0, 0x1, 0x545, 2 );
CreateMorphItem( 5461, 1426, 0, 0x1, 0x545, 2 );
CreateMorphItem( 5460, 1417, 0, 0x1, 0x546, 1 );
CreateMorphItem( 5460, 1418, 0, 0x1, 0x546, 2 );
CreateMorphItem( 5460, 1421, 0, 0x1, 0x546, 2 );
CreateMorphItem( 5461, 1425, 0, 0x1, 0x548, 2 );
CreateMorphItem( 5459, 1420, 0, 0x1, 0x54A, 2 );
CreateMorphItem( 5459, 1421, 0, 0x1, 0x54A, 2 );
CreateMorphItem( 5459, 1423, 0, 0x1, 0x54A, 2 );
CreateMorphItem( 5459, 1418, 0, 0x1, 0x54B, 2 );
CreateMorphItem( 5459, 1422, 0, 0x1, 0x54B, 2 );
CreateMorphItem( 5459, 1417, 0, 0x1, 0x54C, 1 );
CreateMorphItem( 5459, 1419, 0, 0x1, 0x54C, 2 );
CreateMorphItem( 5459, 1424, 0, 0x1, 0x54C, 2 );
CreateMorphItem( 5458, 1426, 0, 0x1, 0x1D1, 2 );
CreateMorphItem( 5459, 1427, 0, 0x1, 0x1E3, 2 );
CreateMorphItem( 5458, 1425, 3, 0x1, 0x1E4, 2 );
CreateMorphItem( 5458, 1427, 6, 0x1, 0x1E5, 2 );
CreateMorphItem( 5461, 1427, 0, 0x1, 0x1E8, 2 );
CreateMorphItem( 5460, 1427, 0, 0x1, 0x1E9, 2 );
CreateMorphItem( 5458, 1425, 0, 0x1, 0x1EA, 2 );
CreateMorphItem( 5458, 1427, 0, 0x1, 0x1EA, 2 );
CreateMorphItem( 5458, 1427, 3, 0x1, 0x1EA, 2 );
// Generate Approach Lights
CreateApproachLight( 5393, 1417, 0, 0x1857, 0x1858, LightType.Circle150 );
CreateApproachLight( 5393, 1420, 0, 0x1857, 0x1858, LightType.Circle150 );
CreateApproachLight( 5395, 1421, 0, 0x1857, 0x1858, LightType.Circle150 );
CreateApproachLight( 5396, 1417, 0, 0x1857, 0x1858, LightType.Circle150 );
CreateApproachLight( 5397, 1419, 0, 0x1857, 0x1858, LightType.Circle150 );
CreateApproachLight( 5441, 1393, 5, 0x1F2B, 0x19BB, LightType.Circle225 );
CreateApproachLight( 5446, 1393, 5, 0x1F2B, 0x19BB, LightType.Circle225 );
// Generate Sound Effects
CreateSoundEffect( 5425, 1489, 5, 0x102, 1 );
CreateSoundEffect( 5425, 1491, 5, 0x102, 1 );
CreateSoundEffect( 5449, 1499, 10, 0xF5, 1 );
CreateSoundEffect( 5451, 1499, 10, 0xF5, 1 );
CreateSoundEffect( 5453, 1499, 10, 0xF5, 1 );
CreateSoundEffect( 5524, 1367, 0, 0x102, 1 );
CreateSoundEffect( 5450, 1370, 0, 0x220, 2 );
CreateSoundEffect( 5450, 1372, 0, 0x220, 2 );
CreateSoundEffect( 5460, 1416, 0, 0x244, 2 );
CreateSoundEffect( 5483, 1439, 5, 0x14, 3 );
// Generate Big Teleporter
CreateBigTeleporterItem( 5387, 1325, true );
CreateBigTeleporterItem( 5388, 1326, true );
CreateBigTeleporterItem( 5388, 1325, false );
CreateBigTeleporterItem( 5387, 1326, false );
// Generate Central Khaldun entrance
DisappearingRaiseSwitch sw = TryCreateItem( 5459, 1426, 10, new DisappearingRaiseSwitch() ) as DisappearingRaiseSwitch;
RaiseSwitch lv = TryCreateItem( 5403, 1359, 0, new RaiseSwitch() ) as RaiseSwitch;
RaisableItem stone = TryCreateItem( 5403, 1360, 0, new RaisableItem( 0x788, 10, 0x477, 0x475, TimeSpan.FromMinutes( 1.5 ) ) ) as RaisableItem;
RaisableItem door = TryCreateItem( 5524, 1367, 0, new RaisableItem( 0x1D0, 20, 0x477, 0x475, TimeSpan.FromMinutes( 5.0 ) ) ) as RaisableItem;
sw.RaisableItem = stone;
lv.RaisableItem = door;
e.Mobile.SendMessage( String.Format( "{0} dynamic Khaldun item{1} generated.", m_Count, m_Count == 1 ? "" : "s" ) );
}
}
}

View file

@ -0,0 +1,108 @@
using System;
namespace Server.Items
{
public class KhaldunPitTeleporter : Item
{
private bool m_Active;
private Point3D m_PointDest;
private Map m_MapDest;
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get { return m_Active; }
set { m_Active = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D PointDest
{
get { return m_PointDest; }
set { m_PointDest = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Map MapDest
{
get { return m_MapDest; }
set { m_MapDest = value; }
}
public override int LabelNumber{ get{ return 1016511; } } // the floor of the cavern seems to have collapsed here - a faint light is visible at the bottom of the pit
[Constructable]
public KhaldunPitTeleporter() : this( new Point3D( 5451, 1374, 0 ), Map.Felucca )
{
}
[Constructable]
public KhaldunPitTeleporter( Point3D pointDest, Map mapDest ) : base( 0x053B )
{
Movable = false;
Hue = 1;
m_Active = true;
m_PointDest = pointDest;
m_MapDest = mapDest;
}
public KhaldunPitTeleporter( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile m )
{
if ( !m_Active )
return;
Map map = m_MapDest;
if ( map == null || map == Map.Internal )
map = m.Map;
Point3D p = m_PointDest;
if ( p == Point3D.Zero )
p = m.Location;
if ( m.InRange( this, 3 ) )
{
Server.Mobiles.BaseCreature.TeleportPets( m, m_PointDest, m_MapDest );
m.MoveToWorld( m_PointDest, m_MapDest );
}
else
{
m.SendLocalizedMessage( 1019045 ); // I can't reach that.
}
}
public override void OnDoubleClickDead( Mobile m )
{
OnDoubleClick( m );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 ); // version
writer.Write( m_Active );
writer.Write( m_PointDest );
writer.Write( m_MapDest );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Active = reader.ReadBool();
m_PointDest = reader.ReadPoint3D();
m_MapDest = reader.ReadMap();
}
}
}

View file

@ -0,0 +1,131 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
public class GrimmochDrummel : BaseCreature
{
public override bool ClickTitle{ get{ return false; } }
public override bool ShowFameTitle{ get{ return false; } }
public override bool DeleteCorpseOnDeath{ get{ return true; } }
[Constructable]
public GrimmochDrummel() : base( AIType.AI_Archer, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Title = "the Cursed";
Hue = 0x8596;
Body = 0x190;
Name = "Grimmoch Drummel";
HairItemID = 0x204A; //Krisna
Bow bow = new Bow();
bow.Movable = false;
AddItem( bow );
AddItem( new Boots( 0x8A4 ) );
AddItem( new BodySash( 0x8A4 ) );
Backpack backpack = new Backpack();
backpack.Movable = false;
AddItem( backpack );
LeatherGloves gloves = new LeatherGloves();
LeatherChest chest = new LeatherChest();
gloves.Hue = 0x96F;
chest.Hue = 0x96F;
AddItem( gloves );
AddItem( chest );
SetStr( 111, 120 );
SetDex( 151, 160 );
SetInt( 41, 50 );
SetHits( 180, 207 );
SetMana( 0 );
SetDamage( 13, 16 );
SetResistance( ResistanceType.Physical, 35, 45 );
SetResistance( ResistanceType.Fire, 25, 30 );
SetResistance( ResistanceType.Cold, 45, 55 );
SetResistance( ResistanceType.Poison, 30, 40 );
SetResistance( ResistanceType.Energy, 20, 25 );
SetSkill( SkillName.Archery, 90.1, 110.0 );
SetSkill( SkillName.Swords, 60.1, 70.0 );
SetSkill( SkillName.Tactics, 90.1, 100.0 );
SetSkill( SkillName.MagicResist, 60.1, 70.0 );
SetSkill( SkillName.Anatomy, 90.1, 100.0 );
Fame = 5000;
Karma = -1000;
PackItem( new Arrow( 40 ) );
if ( 3 > Utility.Random( 100 ) )
PackItem( new FireHorn() );
if ( 1 > Utility.Random( 3 ) )
PackItem( Loot.RandomGrimmochJournal() );
}
public override int GetIdleSound()
{
return 0x178;
}
public override int GetAngerSound()
{
return 0x1AC;
}
public override int GetDeathSound()
{
return 0x27E;
}
public override int GetHurtSound()
{
return 0x177;
}
public override bool OnBeforeDeath()
{
Gold gold = new Gold( Utility.RandomMinMax( 190, 230 ) );
gold.MoveToWorld( Location, Map );
Container pack = this.Backpack;
if ( pack != null )
{
pack.Movable = true;
pack.MoveToWorld( Location, Map );
}
Effects.SendLocationEffect( Location, Map, 0x376A, 10, 1 );
return true;
}
public override bool AlwaysMurderer{ get{ return true; } }
public GrimmochDrummel( Serial serial ) : base( serial )
{
}
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,132 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
public class LysanderGathenwale : BaseCreature
{
public override bool ClickTitle{ get{ return false; } }
public override bool ShowFameTitle{ get{ return false; } }
public override bool DeleteCorpseOnDeath{ get{ return true; } }
[Constructable]
public LysanderGathenwale() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Title = "the Cursed";
Hue = 0x8838;
Body = 0x190;
Name = "Lysander Gathenwale";
AddItem( new Boots( 0x599 ) );
AddItem( new Cloak( 0x96F ) );
Spellbook spellbook = new Spellbook();
RingmailGloves gloves = new RingmailGloves();
StuddedChest chest = new StuddedChest();
PlateArms arms = new PlateArms();
spellbook.Hue = 0x599;
gloves.Hue = 0x599;
chest.Hue = 0x96F;
arms.Hue = 0x599;
AddItem( spellbook );
AddItem( gloves );
AddItem( chest );
AddItem( arms );
SetStr( 111, 120 );
SetDex( 71, 80 );
SetInt( 121, 130 );
SetHits( 180, 207 );
SetMana( 227, 265 );
SetDamage( 5, 13 );
SetResistance( ResistanceType.Physical, 35, 45 );
SetResistance( ResistanceType.Fire, 25, 30 );
SetResistance( ResistanceType.Cold, 50, 60 );
SetResistance( ResistanceType.Poison, 25, 35 );
SetResistance( ResistanceType.Energy, 25, 35 );
SetSkill( SkillName.Wrestling, 80.1, 90.0 );
SetSkill( SkillName.Tactics, 90.1, 100.0 );
SetSkill( SkillName.MagicResist, 80.1, 90.0 );
SetSkill( SkillName.Magery, 90.1, 100.0 );
SetSkill( SkillName.EvalInt, 95.1, 100.0 );
SetSkill( SkillName.Meditation, 90.1, 100.0 );
Fame = 5000;
Karma = -10000;
Item reags = Loot.RandomReagent();
reags.Amount = 30;
PackItem( reags );
}
public override int GetIdleSound()
{
return 0x1CE;
}
public override int GetAngerSound()
{
return 0x1AC;
}
public override int GetDeathSound()
{
return 0x182;
}
public override int GetHurtSound()
{
return 0x28D;
}
public override void GenerateLoot()
{
AddLoot( LootPack.MedScrolls, 2 );
}
public override bool OnBeforeDeath()
{
if ( !base.OnBeforeDeath() )
return false;
if ( Backpack != null )
Backpack.Destroy();
if ( Utility.Random( 3 ) == 0 )
{
BaseBook notebook = Loot.RandomLysanderNotebook();
notebook.MoveToWorld( Location, Map );
}
Effects.SendLocationEffect( Location, Map, 0x376A, 10, 1 );
return true;
}
public override bool AlwaysMurderer{ get{ return true; } }
public LysanderGathenwale( Serial serial ) : base( serial )
{
}
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,111 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
public class MorgBergen : BaseCreature
{
public override bool ClickTitle{ get{ return false; } }
public override bool ShowFameTitle{ get{ return false; } }
public override bool DeleteCorpseOnDeath{ get{ return true; } }
[Constructable]
public MorgBergen() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Title = "the Cursed";
Hue = 0x8596;
Body = 0x190;
Name = "Morg Bergen";
AddItem( new ShortPants( 0x59C ) );
Bardiche bardiche = new Bardiche();
LeatherGloves gloves = new LeatherGloves();
LeatherArms arms = new LeatherArms();
bardiche.Hue = 0x96F; bardiche.Movable = false;
gloves.Hue = 0x96F;
arms.Hue = 0x96F;
AddItem( bardiche );
AddItem( gloves );
AddItem( arms );
SetStr( 111, 120 );
SetDex( 111, 120 );
SetInt( 51, 60 );
SetHits( 180, 207 );
SetMana( 0 );
SetDamage( 9, 17 );
SetDamageType( ResistanceType.Physical, 40 );
SetDamageType( ResistanceType.Cold, 60 );
SetResistance( ResistanceType.Physical, 35, 45 );
SetResistance( ResistanceType.Fire, 25, 30 );
SetResistance( ResistanceType.Cold, 50, 60 );
SetResistance( ResistanceType.Poison, 25, 35 );
SetResistance( ResistanceType.Energy, 25, 35 );
SetSkill( SkillName.Swords, 90.1, 100.0 );
SetSkill( SkillName.Tactics, 90.1, 100.0 );
SetSkill( SkillName.MagicResist, 80.1, 90.0 );
SetSkill( SkillName.Anatomy, 90.1, 100.0 );
Fame = 5000;
Karma = -1000;
}
public override int GetIdleSound()
{
return 0x1CE;
}
public override int GetAngerSound()
{
return 0x263;
}
public override int GetDeathSound()
{
return 0x1D1;
}
public override int GetHurtSound()
{
return 0x25E;
}
public override bool OnBeforeDeath()
{
Gold gold = new Gold( Utility.RandomMinMax( 190, 230 ) );
gold.MoveToWorld( Location, Map );
Effects.SendLocationEffect( Location, Map, 0x376A, 10, 1 );
return true;
}
public override bool AlwaysMurderer{ get{ return true; } }
public MorgBergen( Serial serial ) : base( serial )
{
}
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,120 @@
using System;
using Server.Items;
namespace Server.Mobiles
{
public class TavaraSewel : BaseCreature
{
public override bool ClickTitle{ get{ return false; } }
public override bool ShowFameTitle{ get{ return false; } }
public override bool DeleteCorpseOnDeath{ get{ return true; } }
[Constructable]
public TavaraSewel () : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Title = "the Cursed";
Hue = 0x8838;
Female = true;
Body = 0x191;
Name = "Tavara Sewel";
AddItem( new Kilt( 0x59C ) );
AddItem( new Sandals( 0x599 ) );
Kryss kryss = new Kryss();
Buckler buckler = new Buckler();
RingmailGloves gloves = new RingmailGloves();
FemalePlateChest chest = new FemalePlateChest();
kryss.Hue = 0x96F; kryss.Movable = false;
buckler.Hue = 0x96F; buckler.Movable = false;
gloves.Hue = 0x599;
chest.Hue = 0x96F;
AddItem( kryss );
AddItem( buckler );
AddItem( gloves );
AddItem( chest );
SetStr( 111, 120 );
SetDex( 111, 120 );
SetInt( 111, 120 );
SetHits( 180, 207 );
SetStam( 126, 150 );
SetMana( 0 );
SetDamage( 13, 16 );
SetResistance( ResistanceType.Physical, 25, 30 );
SetResistance( ResistanceType.Fire, 25, 30 );
SetResistance( ResistanceType.Cold, 50, 60 );
SetResistance( ResistanceType.Poison, 25, 35 );
SetResistance( ResistanceType.Energy, 25, 35 );
SetSkill( SkillName.Fencing, 90.1, 100.0 );
SetSkill( SkillName.Tactics, 90.1, 100.0 );
SetSkill( SkillName.MagicResist, 80.1, 90.0 );
SetSkill( SkillName.Anatomy, 90.1, 100.0 );
Fame = 5000;
Karma = -1000;
}
public override int GetIdleSound()
{
return 0x27F;
}
public override int GetAngerSound()
{
return 0x258;
}
public override int GetDeathSound()
{
return 0x25B;
}
public override int GetHurtSound()
{
return 0x257;
}
public override bool OnBeforeDeath()
{
Gold gold = new Gold( Utility.RandomMinMax( 190, 230 ) );
gold.MoveToWorld( Location, Map );
if ( Utility.Random( 3 ) == 0 )
{
BaseBook journal = Loot.RandomTavarasJournal();
journal.MoveToWorld( Location, Map );
}
Effects.SendLocationEffect( Location, Map, 0x376A, 10, 1 );
return true;
}
public override bool AlwaysMurderer{ get{ return true; } }
public TavaraSewel( Serial serial ) : base( serial )
{
}
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,793 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public enum PuzzleChestCylinder
{
None = 0xE73,
LightBlue = 0x186F,
Blue = 0x186A,
Green = 0x186B,
Orange = 0x186C,
Purple = 0x186D,
Red = 0x186E,
DarkBlue = 0x1869,
Yellow = 0x1870
}
public class PuzzleChestSolution
{
public const int Length = 5;
private PuzzleChestCylinder[] m_Cylinders = new PuzzleChestCylinder[Length];
public PuzzleChestCylinder[] Cylinders{ get{ return m_Cylinders; } }
public PuzzleChestCylinder First{ get{ return m_Cylinders[0]; } set{ m_Cylinders[0] = value; } }
public PuzzleChestCylinder Second{ get{ return m_Cylinders[1]; } set{ m_Cylinders[1] = value; } }
public PuzzleChestCylinder Third{ get{ return m_Cylinders[2]; } set{ m_Cylinders[2] = value; } }
public PuzzleChestCylinder Fourth{ get{ return m_Cylinders[3]; } set{ m_Cylinders[3] = value; } }
public PuzzleChestCylinder Fifth{ get{ return m_Cylinders[4]; } set{ m_Cylinders[4] = value; } }
public static PuzzleChestCylinder RandomCylinder()
{
switch ( Utility.Random( 8 ) )
{
case 0: return PuzzleChestCylinder.LightBlue;
case 1: return PuzzleChestCylinder.Blue;
case 2: return PuzzleChestCylinder.Green;
case 3: return PuzzleChestCylinder.Orange;
case 4: return PuzzleChestCylinder.Purple;
case 5: return PuzzleChestCylinder.Red;
case 6: return PuzzleChestCylinder.DarkBlue;
default: return PuzzleChestCylinder.Yellow;
}
}
public PuzzleChestSolution()
{
for ( int i = 0; i < m_Cylinders.Length; i++ ) {
m_Cylinders[i] = RandomCylinder();
}
}
public PuzzleChestSolution( PuzzleChestCylinder first, PuzzleChestCylinder second, PuzzleChestCylinder third, PuzzleChestCylinder fourth, PuzzleChestCylinder fifth )
{
First = first;
Second = second;
Third = third;
Fourth = fourth;
Fifth = fifth;
}
public PuzzleChestSolution( PuzzleChestSolution solution )
{
for ( int i = 0; i < m_Cylinders.Length; i++ ) {
m_Cylinders[i] = solution.m_Cylinders[i];
}
}
public bool Matches( PuzzleChestSolution solution, out int cylinders, out int colors )
{
cylinders = 0;
colors = 0;
bool[] matchesSrc = new bool[solution.m_Cylinders.Length];
bool[] matchesDst = new bool[solution.m_Cylinders.Length];
for ( int i = 0; i < m_Cylinders.Length; i++ )
{
if ( m_Cylinders[i] == solution.m_Cylinders[i] )
{
cylinders++;
matchesSrc[i] = true;
matchesDst[i] = true;
}
}
for ( int i = 0; i < m_Cylinders.Length; i++ )
{
if ( !matchesSrc[i] )
{
for ( int j = 0; j < solution.m_Cylinders.Length; j++ )
{
if ( m_Cylinders[i] == solution.m_Cylinders[j] && !matchesDst[j] )
{
colors++;
matchesDst[j] = true;
}
}
}
}
return cylinders == m_Cylinders.Length;
}
public virtual void Serialize( GenericWriter writer )
{
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_Cylinders.Length );
for ( int i = 0; i < m_Cylinders.Length; i++ )
{
writer.Write( (int) m_Cylinders[i] );
}
}
public PuzzleChestSolution( GenericReader reader )
{
int version = reader.ReadEncodedInt();
int length = reader.ReadEncodedInt();
for ( int i = 0; ; i++ )
{
if ( i < length )
{
PuzzleChestCylinder cylinder = (PuzzleChestCylinder) reader.ReadInt();
if ( i < m_Cylinders.Length )
m_Cylinders[i] = cylinder;
}
else if ( i < m_Cylinders.Length )
{
m_Cylinders[i] = RandomCylinder();
}
else
{
break;
}
}
}
}
public class PuzzleChestSolutionAndTime : PuzzleChestSolution
{
private DateTime m_When;
public DateTime When{ get{ return m_When; } }
public PuzzleChestSolutionAndTime( DateTime when, PuzzleChestSolution solution ) : base( solution )
{
m_When = when;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteDeltaTime( m_When );
}
public PuzzleChestSolutionAndTime( GenericReader reader ) : base( reader )
{
int version = reader.ReadEncodedInt();
m_When = reader.ReadDeltaTime();
}
}
public abstract class PuzzleChest : BaseTreasureChest
{
public const int HintsCount = 3;
public readonly TimeSpan CleanupTime = TimeSpan.FromHours( 1.0 );
private PuzzleChestSolution m_Solution;
private PuzzleChestCylinder[] m_Hints = new PuzzleChestCylinder[HintsCount];
private Dictionary<Mobile, PuzzleChestSolutionAndTime> m_Guesses = new Dictionary<Mobile, PuzzleChestSolutionAndTime>();
public PuzzleChestSolution Solution
{
get{ return m_Solution; }
set
{
m_Solution = value;
InitHints();
}
}
public PuzzleChestCylinder[] Hints{ get{ return m_Hints; } }
public PuzzleChestCylinder FirstHint{ get{ return m_Hints[0]; } set{ m_Hints[0] = value; } }
public PuzzleChestCylinder SecondHint{ get{ return m_Hints[1]; } set{ m_Hints[1] = value; } }
public PuzzleChestCylinder ThirdHint{ get{ return m_Hints[2]; } set{ m_Hints[2] = value; } }
public override string DefaultName
{
get { return null; }
}
public PuzzleChest( int itemID ) : base( itemID )
{
}
private void InitHints()
{
List<PuzzleChestCylinder> list = new List<PuzzleChestCylinder>( Solution.Cylinders.Length - 1 );
for ( int i = 1; i < Solution.Cylinders.Length; i++ )
list.Add( Solution.Cylinders[i] );
m_Hints = new PuzzleChestCylinder[HintsCount];
for ( int i = 0; i < m_Hints.Length; i++ ) {
int pos = Utility.Random( list.Count );
m_Hints[i] = list[pos];
list.RemoveAt( pos );
}
}
protected override void SetLockLevel()
{
LockLevel = 0; // Can't be unlocked
}
public override bool CheckLocked( Mobile from )
{
if ( Locked )
{
PuzzleChestSolution solution = GetLastGuess( from );
if ( solution != null )
solution = new PuzzleChestSolution( solution );
else
solution = new PuzzleChestSolution( PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None, PuzzleChestCylinder.None );
from.CloseGump( typeof( PuzzleGump ) );
from.CloseGump( typeof( StatusGump ) );
from.SendGump( new PuzzleGump( from, this, solution, 0 ) );
return true;
}
else
{
return false;
}
}
public PuzzleChestSolutionAndTime GetLastGuess( Mobile m )
{
PuzzleChestSolutionAndTime pcst = null;
m_Guesses.TryGetValue( m, out pcst );
return pcst;
}
public void SubmitSolution( Mobile m, PuzzleChestSolution solution )
{
int correctCylinders, correctColors;
if ( solution.Matches( this.Solution, out correctCylinders, out correctColors ) )
{
LockPick( m );
DisplayTo( m );
}
else
{
m_Guesses[m] = new PuzzleChestSolutionAndTime( DateTime.UtcNow, solution );
m.SendGump( new StatusGump( correctCylinders, correctColors ) );
DoDamage( m );
}
}
public void DoDamage( Mobile to )
{
switch ( Utility.Random( 4 ) )
{
case 0:
{
Effects.SendLocationEffect( to, to.Map, 0x113A, 20, 10 );
to.PlaySound( 0x231 );
to.LocalOverheadMessage( MessageType.Regular, 0x44, 1010523 ); // A toxic vapor envelops thee.
to.ApplyPoison( to, Poison.Regular );
break;
}
case 1:
{
Effects.SendLocationEffect( to, to.Map, 0x3709, 30 );
to.PlaySound( 0x54 );
to.LocalOverheadMessage( MessageType.Regular, 0xEE, 1010524 ); // Searing heat scorches thy skin.
AOS.Damage( to, to, Utility.RandomMinMax( 10, 40 ), 0, 100, 0, 0, 0 );
break;
}
case 2:
{
to.PlaySound( 0x223 );
to.LocalOverheadMessage( MessageType.Regular, 0x62, 1010525 ); // Pain lances through thee from a sharp metal blade.
AOS.Damage( to, to, Utility.RandomMinMax( 10, 40 ), 100, 0, 0, 0, 0 );
break;
}
default:
{
to.BoltEffect( 0 );
to.LocalOverheadMessage( MessageType.Regular, 0xDA, 1010526 ); // Lightning arcs through thy body.
AOS.Damage( to, to, Utility.RandomMinMax( 10, 40 ), 0, 0, 0, 0, 100 );
break;
}
}
}
private class PuzzleGump : Gump
{
private Mobile m_From;
private PuzzleChest m_Chest;
private PuzzleChestSolution m_Solution;
public PuzzleGump( Mobile from, PuzzleChest chest, PuzzleChestSolution solution, int check ) : base( 50, 50 )
{
m_From = from;
m_Chest = chest;
m_Solution = solution;
Dragable = false;
AddBackground( 25, 0, 500, 410, 0x53 );
AddImage( 62, 20, 0x67 );
AddHtmlLocalized( 80, 36, 110, 70, 1018309, true, false ); // A Puzzle Lock
/* Correctly choose the sequence of cylinders needed to open the latch. Each cylinder
* may potentially be used more than once. Beware! A false attempt could be deadly!
*/
AddHtmlLocalized( 214, 26, 270, 90, 1018310, true, true );
AddLeftCylinderButton( 62, 130, PuzzleChestCylinder.LightBlue, 10 );
AddLeftCylinderButton( 62, 180, PuzzleChestCylinder.Blue, 11 );
AddLeftCylinderButton( 62, 230, PuzzleChestCylinder.Green, 12 );
AddLeftCylinderButton( 62, 280, PuzzleChestCylinder.Orange, 13 );
AddRightCylinderButton( 451, 130, PuzzleChestCylinder.Purple, 14 );
AddRightCylinderButton( 451, 180, PuzzleChestCylinder.Red, 15 );
AddRightCylinderButton( 451, 230, PuzzleChestCylinder.DarkBlue, 16 );
AddRightCylinderButton( 451, 280, PuzzleChestCylinder.Yellow, 17 );
double lockpicking = from.Skills.Lockpicking.Base;
if ( lockpicking >= 60.0 )
{
AddHtmlLocalized( 160, 125, 230, 24, 1018308, false, false ); // Lockpicking hint:
AddBackground( 159, 150, 230, 95, 0x13EC );
if ( lockpicking >= 80.0 )
{
AddHtmlLocalized( 165, 157, 200, 40, 1018312, false, false ); // In the first slot:
AddCylinder( 350, 165, chest.Solution.First );
AddHtmlLocalized( 165, 197, 200, 40, 1018313, false, false ); // Used in unknown slot:
AddCylinder( 350, 200, chest.FirstHint );
if ( lockpicking >= 90.0 )
AddCylinder( 350, 212, chest.SecondHint );
if ( lockpicking >= 100.0 )
AddCylinder( 350, 224, chest.ThirdHint );
}
else
{
AddHtmlLocalized( 165, 157, 200, 40, 1018313, false, false ); // Used in unknown slot:
AddCylinder( 350, 160, chest.FirstHint );
if ( lockpicking >= 70.0 )
AddCylinder( 350, 172, chest.SecondHint );
}
}
PuzzleChestSolution lastGuess = chest.GetLastGuess( from );
if ( lastGuess != null )
{
AddHtmlLocalized( 127, 249, 170, 20, 1018311, false, false ); // Thy previous guess:
AddBackground( 290, 247, 115, 25, 0x13EC );
AddCylinder( 281, 254, lastGuess.First );
AddCylinder( 303, 254, lastGuess.Second );
AddCylinder( 325, 254, lastGuess.Third );
AddCylinder( 347, 254, lastGuess.Fourth );
AddCylinder( 369, 254, lastGuess.Fifth );
}
AddPedestal( 140, 270, solution.First, 0, check == 0 );
AddPedestal( 195, 270, solution.Second, 1, check == 1 );
AddPedestal( 250, 270, solution.Third, 2, check == 2 );
AddPedestal( 305, 270, solution.Fourth, 3, check == 3 );
AddPedestal( 360, 270, solution.Fifth, 4, check == 4 );
AddButton( 258, 370, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 );
}
private void AddLeftCylinderButton( int x, int y, PuzzleChestCylinder cylinder, int buttonID )
{
AddBackground( x, y, 30, 30, 0x13EC );
AddCylinder( x - 7, y + 10, cylinder );
AddButton( x + 38, y + 9, 0x13A8, 0x4B9, buttonID, GumpButtonType.Reply, 0 );
}
private void AddRightCylinderButton( int x, int y, PuzzleChestCylinder cylinder, int buttonID )
{
AddBackground( x, y, 30, 30, 0x13EC );
AddCylinder( x - 7, y + 10, cylinder );
AddButton( x - 26, y + 9, 0x13A8, 0x4B9, buttonID, GumpButtonType.Reply, 0 );
}
private void AddPedestal( int x, int y, PuzzleChestCylinder cylinder, int switchID, bool initialState )
{
AddItem( x, y, 0xB10 );
AddItem( x - 23, y + 12, 0xB12 );
AddItem( x + 23, y + 12, 0xB13 );
AddItem( x, y + 23, 0xB11 );
if ( cylinder != PuzzleChestCylinder.None )
{
AddItem( x, y + 2, 0x51A );
AddCylinder( x - 1, y + 19, cylinder );
}
else
{
AddItem( x, y + 2, 0x521 );
}
AddRadio( x + 7, y + 65, 0x867, 0x86A, initialState, switchID );
}
private void AddCylinder( int x, int y, PuzzleChestCylinder cylinder )
{
if ( cylinder != PuzzleChestCylinder.None )
AddItem( x, y, (int)cylinder );
else
AddItem( x + 9, y, (int)cylinder );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Chest.Deleted || info.ButtonID == 0 || !m_From.CheckAlive() )
return;
if ( m_From.AccessLevel == AccessLevel.Player && ( m_From.Map != m_Chest.Map || !m_From.InRange( m_Chest.GetWorldLocation(), 2 ) ) )
{
m_From.LocalOverheadMessage( MessageType.Regular, 0x3B2, 500446 ); // That is too far away.
return;
}
if ( info.ButtonID == 1 )
{
m_Chest.SubmitSolution( m_From, m_Solution );
}
else
{
if ( info.Switches.Length == 0 )
return;
int pedestal = info.Switches[0];
if ( pedestal < 0 || pedestal >= m_Solution.Cylinders.Length )
return;
PuzzleChestCylinder cylinder;
switch ( info.ButtonID )
{
case 10: cylinder = PuzzleChestCylinder.LightBlue; break;
case 11: cylinder = PuzzleChestCylinder.Blue; break;
case 12: cylinder = PuzzleChestCylinder.Green; break;
case 13: cylinder = PuzzleChestCylinder.Orange; break;
case 14: cylinder = PuzzleChestCylinder.Purple; break;
case 15: cylinder = PuzzleChestCylinder.Red; break;
case 16: cylinder = PuzzleChestCylinder.DarkBlue; break;
case 17: cylinder = PuzzleChestCylinder.Yellow; break;
default: return;
}
m_Solution.Cylinders[pedestal] = cylinder;
m_From.SendGump( new PuzzleGump( m_From, m_Chest, m_Solution, pedestal ) );
}
}
}
private class StatusGump : Gump
{
public StatusGump( int correctCylinders, int correctColors ) : base( 50, 50 )
{
AddBackground( 15, 250, 305, 163, 0x53 );
AddBackground( 28, 265, 280, 133, 0xBB8 );
AddHtmlLocalized( 35, 271, 270, 24, 1018314, false, false ); // Thou hast failed to solve the puzzle!
AddHtmlLocalized( 35, 297, 250, 24, 1018315, false, false ); // Correctly placed colors:
AddLabel( 285, 297, 0x44, correctCylinders.ToString() );
AddHtmlLocalized( 35, 323, 250, 24, 1018316, false, false ); // Used colors in wrong slots:
AddLabel( 285, 323, 0x44, correctColors.ToString() );
AddButton( 152, 369, 0xFA5, 0xFA7, 0, GumpButtonType.Reply, 0 );
}
}
public override void LockPick( Mobile from )
{
base.LockPick( from );
m_Guesses.Clear();
}
private static void GetRandomAOSStats( out int attributeCount, out int min, out int max )
{
int rnd = Utility.Random( 15 );
if ( rnd < 1 )
{
attributeCount = Utility.RandomMinMax( 2, 6 );
min = 20; max = 70;
}
else if ( rnd < 3 )
{
attributeCount = Utility.RandomMinMax( 2, 4 );
min = 20; max = 50;
}
else if ( rnd < 6 )
{
attributeCount = Utility.RandomMinMax( 2, 3 );
min = 20; max = 40;
}
else if ( rnd < 10 )
{
attributeCount = Utility.RandomMinMax( 1, 2 );
min = 10; max = 30;
}
else
{
attributeCount = 1;
min = 10; max = 20;
}
}
protected override void GenerateTreasure()
{
DropItem( new Gold( 600, 900 ) );
List<Item> gems = new List<Item>();
for ( int i = 0; i < 9; i++ )
{
Item gem = Loot.RandomGem();
Type gemType = gem.GetType();
foreach ( Item listGem in gems ) {
if ( listGem.GetType() == gemType ) {
listGem.Amount++;
gem.Delete();
break;
}
}
if ( !gem.Deleted )
gems.Add( gem );
}
foreach ( Item gem in gems )
DropItem( gem );
if ( 0.2 > Utility.RandomDouble() )
DropItem( new BagOfReagents( 50 ) );
for ( int i = 0; i < 2; i++ )
{
Item item;
if ( Core.AOS )
item = Loot.RandomArmorOrShieldOrWeaponOrJewelry();
else
item = Loot.RandomArmorOrShieldOrWeapon();
if ( item is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)item;
if ( Core.AOS )
{
int attributeCount;
int min, max;
GetRandomAOSStats( out attributeCount, out min, out max );
BaseRunicTool.ApplyAttributesTo( weapon, attributeCount, min, max );
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)Utility.Random( 6 );
weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random( 6 );
weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random( 6 );
}
DropItem( item );
}
else if ( item is BaseArmor )
{
BaseArmor armor = (BaseArmor)item;
if ( Core.AOS )
{
int attributeCount;
int min, max;
GetRandomAOSStats( out attributeCount, out min, out max );
BaseRunicTool.ApplyAttributesTo( armor, attributeCount, min, max );
}
else
{
armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random( 6 );
armor.Durability = (ArmorDurabilityLevel)Utility.Random( 6 );
}
DropItem( item );
}
else if( item is BaseHat )
{
BaseHat hat = (BaseHat)item;
if( Core.AOS )
{
int attributeCount;
int min, max;
GetRandomAOSStats( out attributeCount, out min, out max );
BaseRunicTool.ApplyAttributesTo( hat, attributeCount, min, max );
}
DropItem( item );
}
else if( item is BaseJewel )
{
int attributeCount;
int min, max;
GetRandomAOSStats( out attributeCount, out min, out max );
BaseRunicTool.ApplyAttributesTo( (BaseJewel)item, attributeCount, min, max );
DropItem( item );
}
}
Solution = new PuzzleChestSolution();
}
public void CleanupGuesses()
{
List<Mobile> toDelete = new List<Mobile>();
foreach ( KeyValuePair<Mobile, PuzzleChestSolutionAndTime> kvp in m_Guesses ) {
if ( DateTime.UtcNow - kvp.Value.When > CleanupTime )
toDelete.Add( kvp.Key );
}
foreach ( Mobile m in toDelete )
m_Guesses.Remove( m );
}
public PuzzleChest( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
CleanupGuesses();
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
m_Solution.Serialize( writer );
writer.WriteEncodedInt( (int) m_Hints.Length );
for ( int i = 0; i < m_Hints.Length; i++ )
{
writer.Write( (int) m_Hints[i] );
}
writer.WriteEncodedInt( (int) m_Guesses.Count );
foreach ( KeyValuePair<Mobile, PuzzleChestSolutionAndTime> kvp in m_Guesses ) {
writer.Write( kvp.Key );
kvp.Value.Serialize( writer );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Solution = new PuzzleChestSolution( reader );
int length = reader.ReadEncodedInt();
for ( int i = 0; i < length; i++ )
{
PuzzleChestCylinder cylinder = (PuzzleChestCylinder) reader.ReadInt();
if ( length == m_Hints.Length )
m_Hints[i] = cylinder;
}
if ( length != m_Hints.Length )
InitHints();
int guesses = reader.ReadEncodedInt();
for ( int i = 0; i < guesses; i++ )
{
Mobile m = reader.ReadMobile();
PuzzleChestSolutionAndTime sol = new PuzzleChestSolutionAndTime( reader );
m_Guesses[m] = sol;
}
}
}
[FlipableAttribute( 0xE41, 0xE40 )]
public class MetalGoldenPuzzleChest : PuzzleChest
{
[Constructable]
public MetalGoldenPuzzleChest() : base( 0xE41 )
{
}
public MetalGoldenPuzzleChest( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
[FlipableAttribute( 0xE80, 0x9A8 )]
public class StrongBoxPuzzle : PuzzleChest
{
[Constructable]
public StrongBoxPuzzle() : base( 0xE80 )
{
}
public StrongBoxPuzzle( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,177 @@
using System;
using Server;
namespace Server.Items
{
public class RaisableItem : Item
{
private int m_MaxElevation;
private int m_MoveSound;
private int m_StopSound;
private TimeSpan m_CloseDelay;
[CommandProperty( AccessLevel.GameMaster )]
public int MaxElevation
{
get{ return m_MaxElevation; }
set
{
if ( value <= 0 )
m_MaxElevation = 0;
else if ( value >= 60 )
m_MaxElevation = 60;
else
m_MaxElevation = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MoveSound{ get{ return m_MoveSound; } set{ m_MoveSound = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int StopSound{ get{ return m_StopSound; } set{ m_StopSound = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan CloseDelay{ get{ return m_CloseDelay; } set{ m_CloseDelay = value; } }
[Constructable]
public RaisableItem( int itemID ) : this( itemID, 20, -1, -1, TimeSpan.FromMinutes( 1.0 ) )
{
}
[Constructable]
public RaisableItem( int itemID, int maxElevation, TimeSpan closeDelay ) : this( itemID, maxElevation, -1, -1, closeDelay )
{
}
[Constructable]
public RaisableItem( int itemID, int maxElevation, int moveSound, int stopSound, TimeSpan closeDelay ) : base( itemID )
{
Movable = false;
m_MaxElevation = maxElevation;
m_MoveSound = moveSound;
m_StopSound = stopSound;
m_CloseDelay = closeDelay;
}
private int m_Elevation;
private RaiseTimer m_RaiseTimer;
public bool IsRaisable
{
get{ return m_RaiseTimer == null; }
}
public void Raise()
{
if ( !IsRaisable )
return;
m_RaiseTimer = new RaiseTimer( this );
m_RaiseTimer.Start();
}
private class RaiseTimer : Timer
{
private RaisableItem m_Item;
private DateTime m_CloseTime;
private bool m_Up;
private int m_Step;
public RaiseTimer( RaisableItem item ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 0.5 ) )
{
m_Item = item;
m_CloseTime = DateTime.UtcNow + item.CloseDelay;
m_Up = true;
Priority = TimerPriority.TenMS;
}
protected override void OnTick()
{
if ( m_Item.Deleted )
{
Stop();
return;
}
if ( m_Step++ % 3 == 0 )
{
if ( m_Up )
{
m_Item.Z++;
if ( ++m_Item.m_Elevation >= m_Item.MaxElevation )
{
Stop();
if ( m_Item.StopSound >= 0 )
Effects.PlaySound( m_Item.Location, m_Item.Map, m_Item.StopSound );
m_Up = false;
m_Step = 0;
TimeSpan delay = m_CloseTime - DateTime.UtcNow;
Timer.DelayCall( delay > TimeSpan.Zero ? delay : TimeSpan.Zero, new TimerCallback( Start ) );
return;
}
}
else
{
m_Item.Z--;
if ( --m_Item.m_Elevation <= 0 )
{
Stop();
if ( m_Item.StopSound >= 0 )
Effects.PlaySound( m_Item.Location, m_Item.Map, m_Item.StopSound );
m_Item.m_RaiseTimer = null;
return;
}
}
}
if ( m_Item.MoveSound >= 0 )
Effects.PlaySound( m_Item.Location, m_Item.Map, m_Item.MoveSound );
}
}
public RaisableItem( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_MaxElevation );
writer.WriteEncodedInt( (int) m_MoveSound );
writer.WriteEncodedInt( (int) m_StopSound );
writer.Write( (TimeSpan) m_CloseDelay );
writer.WriteEncodedInt( (int) m_Elevation );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_MaxElevation = reader.ReadEncodedInt();
m_MoveSound = reader.ReadEncodedInt();
m_StopSound = reader.ReadEncodedInt();
m_CloseDelay = reader.ReadTimeSpan();
int elevation = reader.ReadEncodedInt();
this.Z -= elevation;
}
}
}

View file

@ -0,0 +1,223 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class RaiseSwitch : Item
{
private RaisableItem m_RaisableItem;
[CommandProperty( AccessLevel.GameMaster )]
public RaisableItem RaisableItem
{
get{ return m_RaisableItem; }
set{ m_RaisableItem = value; }
}
[Constructable]
public RaiseSwitch() : this( 0x1093 )
{
}
protected RaiseSwitch( int itemID ) : base( itemID )
{
Movable = false;
}
public override void OnDoubleClick( Mobile m )
{
if ( !m.InRange( this, 2 ) )
{
m.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
if ( RaisableItem != null && RaisableItem.Deleted )
RaisableItem = null;
Flip();
if ( RaisableItem != null )
{
if ( RaisableItem.IsRaisable )
{
RaisableItem.Raise();
m.LocalOverheadMessage( MessageType.Regular, 0x5A, true, "You hear a grinding noise echoing in the distance." );
}
else
{
m.LocalOverheadMessage( MessageType.Regular, 0x5A, true, "You flip the switch again, but nothing happens." );
}
}
}
protected virtual void Flip()
{
if ( ItemID != 0x1093 )
{
ItemID = 0x1093;
StopResetTimer();
}
else
{
ItemID = 0x1095;
if ( RaisableItem != null && RaisableItem.CloseDelay >= TimeSpan.Zero )
StartResetTimer( RaisableItem.CloseDelay );
else
StartResetTimer( TimeSpan.FromMinutes( 2.0 ) );
}
Effects.PlaySound( Location, Map, 0x3E8 );
}
private ResetTimer m_ResetTimer;
protected void StartResetTimer( TimeSpan delay )
{
StopResetTimer();
m_ResetTimer = new ResetTimer( this, delay );
m_ResetTimer.Start();
}
protected void StopResetTimer()
{
if ( m_ResetTimer != null )
{
m_ResetTimer.Stop();
m_ResetTimer = null;
}
}
protected virtual void Reset()
{
if ( ItemID != 0x1093 )
Flip();
}
private class ResetTimer : Timer
{
private RaiseSwitch m_RaiseSwitch;
public ResetTimer( RaiseSwitch raiseSwitch, TimeSpan delay ) : base( delay )
{
m_RaiseSwitch = raiseSwitch;
Priority = ComputePriority( delay );
}
protected override void OnTick()
{
if ( m_RaiseSwitch.Deleted )
return;
m_RaiseSwitch.m_ResetTimer = null;
m_RaiseSwitch.Reset();
}
}
public RaiseSwitch( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write( (Item) m_RaisableItem );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_RaisableItem = (RaisableItem) reader.ReadItem();
Reset();
}
}
public class DisappearingRaiseSwitch : RaiseSwitch
{
public int CurrentRange{ get{ return Visible ? 3 : 2; } }
[Constructable]
public DisappearingRaiseSwitch() : base( 0x108F )
{
}
protected override void Flip()
{
}
protected override void Reset()
{
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( Utility.InRange( m.Location, Location, CurrentRange ) || Utility.InRange( oldLocation, Location, CurrentRange ) )
Refresh();
}
public override void OnMapChange()
{
if ( !Deleted )
Refresh();
}
public override void OnLocationChange( Point3D oldLoc )
{
if ( !Deleted )
Refresh();
}
public void Refresh()
{
bool found = false;
foreach ( Mobile mob in GetMobilesInRange( CurrentRange ) )
{
if ( mob.Hidden && mob.AccessLevel > AccessLevel.Player )
continue;
found = true;
break;
}
Visible = found;
}
public DisappearingRaiseSwitch( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
if ( RaisableItem != null && RaisableItem.Deleted )
RaisableItem = null;
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( Refresh ) );
}
}
}