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,161 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook1 : BaseBook
{
[Constructable]
public FishingGuideBook1() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Volume 1 - Uncommon Shore Fish";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"Bluegill Sunfish:",
"Be wary o these bluegills,",
"they be a bit snooty but",
"they be tastin' great on a",
"cracker."
),
new BookPageInfo
(
"Brook trout:",
"These be found in brooks",
"mostly, but sometimes",
"streams, ponds, creeks,",
"rivers, inlets, fords, and",
"occasionally puddles."
),
new BookPageInfo
(
"Green catfish:",
"Dont let the green color",
"scare ye away, it be",
"delicious! Folks what eat",
"them say they make yer eyes",
"turn green."
),
new BookPageInfo
(
"Kokanee salmon:",
"I named this'n fer me",
"favorite aunt in hopes that",
"she would leave me her ship.",
"Then she left it to her",
"boyfriend so I changed it to",
"Kokanee. "
),
new BookPageInfo
(
"Pike:",
"This fresh water fish be lookin'",
"a bit like their ocean cousin",
"the barracuda. But don't be",
"fooled, they bite!"
),
new BookPageInfo
(
"Pumpkinseed Sunfish:",
"Found in rivers and other shallow",
"waters, this fish be so named",
"because it be first caught by me",
"friend, Pumpkinseed Smith."
),
new BookPageInfo
(
"Rainbow trout:",
"These trout be colored a bit like",
"rainbow salmon but they're not,",
"they're trout."
),
new BookPageInfo
(
"Redbelly bream:",
"The secret ta catchin' these",
"particular bream is ta be fishin'",
"near the shores."
),
new BookPageInfo
(
"Smallmouth bass:",
"'Tis believed that this",
"fish is uncommon simply",
"because it be a picky 'eater. "
),
new BookPageInfo
(
"Uncommon shiner:",
"This fish is not to be",
"confused with the common",
"shiner. The uncommon",
"shiner tastes way better."
),
new BookPageInfo
(
"Walleye:",
"This be a tricky devil",
"'cause he can see ye coming.",
"'Tis best to fish her them",
"at night or ta be wearin'",
"a worm costume."
),
new BookPageInfo
(
"Yellow perch:",
"Ye can sometimes see",
"these swimmin' near rocks",
"and such. They be easy ta",
"spot cause they be yellow",
"somewhere on thar body."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook1( 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,232 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook2 : BaseBook
{
[Constructable]
public FishingGuideBook2() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Volume 2 - Uncommon Sea Fish";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"Amberjack:",
"One o these days Im",
"going ta hang up me",
"fishin pole and start",
"me own brewery, and Im",
"going to name me brew",
"amberjack."
),
new BookPageInfo
(
"Black sea bass",
"The black seabass be",
"a more purpley color in",
"me personal opinion,",
"but it wasn me what",
"named it. "
),
new BookPageInfo
(
"Blue grouper:",
"Dont let the green color",
"scare ye away, it be",
"delicious! Folks what eat",
"them say they make yer eyes",
"turn green."
),
new BookPageInfo
(
"Bluefish:",
"These be uncommon",
"because most fishermen",
"mistake them for other",
"fish cause they aint",
"actually blue. This be",
"thar natural defense. "
),
new BookPageInfo
(
"Bonefish:",
"This fish be havin ",
"lots o bones. Like",
"double the normal",
"amount. I seen some",
"that couldnt even move!"
),
new BookPageInfo
(
"Bonito:",
"Bonito be great when",
"smoked and dried. Tis",
"a favorite of Tokuno. "
),
new BookPageInfo
(
"Cape cod:",
"This fish be found off",
"the cape. Way off the",
"cape. Like, in the",
"middle o the sea. "
),
new BookPageInfo
(
"Captain snook:",
"Whatever sun baked ",
"swab named this poor",
"devil capn snook",
"should be keel hauled!",
"I knew Capn Snook,",
"this be no Capn Snook. "
),
new BookPageInfo
(
"Cobia:",
"Best to not be confusin",
"the cobia with the cobra,",
"the cobra be requiring",
"a totally different kind",
"o bait."
),
new BookPageInfo
(
"Gray snapper:",
"Old sailors say that",
"many generations ago",
"the gray snapper used",
"to be the blonde snapper."
),
new BookPageInfo
(
"Haddock:",
"When tha winds in",
"yar hair, the salts",
"on yar lips and yar",
"hooks wrapped around",
"yar pole, the haddock",
"be thar."
),
new BookPageInfo
(
"Mahi mahi:",
"They say that the most",
"persuasive argument is",
"repetition. This might",
"explain why mahi mahi",
"be so popular."
),
new BookPageInfo
(
"Red drum:",
"The red drum is thus",
"named because o the",
"sound it makes when",
"you thump it on the",
"head."
),
new BookPageInfo
(
"Red grouper:",
"Red grouper be extra",
"good with a dalop o",
"Madam Beamys hot sauce."
),
new BookPageInfo
(
"Red Snook:",
"This fish be found",
"anywhere the rest o",
"the fish in this handbook",
"be found."
),
new BookPageInfo
(
"Shad:",
"The shad be one o",
"me personal favorite",
"deep sea uncommon fish."
),
new BookPageInfo
(
"Tarpon:",
"This fella once told",
"me the word Tarpon be",
"derived from the word",
"Tarpaulin, but Is",
"pretty sure he was insane."
),
new BookPageInfo
(
"Yellowfin tuna:",
"The best thing about",
"tuna is that it tastes",
"like chicken that was",
"eaten by a fish."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook2( 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,169 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook3 : BaseBook
{
[Constructable]
public FishingGuideBook3() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Volume 3 - Uncommon Dungeon Fish";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"Crag Snapper:",
"Crag Snapper be fine",
"eating. Just mind yer",
"fingers. "
),
new BookPageInfo
(
"Cutthrout Trout:",
"This dungeon menace",
"'tis the very one that",
"gave rise to the ol'",
"saying. 'Ne'er take a",
"bath in dungeon water. "
),
new BookPageInfo
(
"Darkfish:",
"Ye find this fish in",
"undergroun rivers and",
"lakes. But only dark",
"undergroun rivers and",
"lakes. "
),
new BookPageInfo
(
"Demon Trout:",
"Beware, this big devil",
"comes out of the water",
"spicy. "
),
new BookPageInfo
(
"Drakefish:",
"The smaller cousin o'",
"the dragonfish, this",
"beauty be much easier",
"to catch and thus more",
"commonly used in cooking."
),
new BookPageInfo
(
"Dungeon Chub:",
"This be the only",
"subterranean member",
"o' the chub family. "
),
new BookPageInfo
(
"Grim Cisco:",
"This fish is sought",
"for medicinal",
"purposes. They say",
"it be the best cure",
"for hysteria. "
),
new BookPageInfo
(
"Infernal Tuna:",
"This fish be deadly",
"poisonous unless ye",
"cook it in butter",
"with a bit o' ",
"thyme and serve it",
"will ale. "
),
new BookPageInfo
(
"Lurker Fish:",
"These fish like to",
"hide up under",
"corpses floating",
"in underground rivers."
),
new BookPageInfo
(
"Orc Bass:",
"If ye be ever ",
"chased by orcs, ",
"throw one down an",
"keep runnin! Ever",
"since I started",
"tellin' folks this,",
"I been sellin more",
"orc bass. "
),
new BookPageInfo
(
"Snaggletoth Bass:",
"This dungeon lurker",
"be resemblin' a ",
"large mouth bass",
"excepting it be",
"having huge jagged",
"teeth."
),
new BookPageInfo
(
"Tormented Pike:",
"This pike be hunted",
"by every monster in",
"Sosaria except few a",
"few."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook3( 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,180 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook4 : BaseBook
{
[Constructable]
public FishingGuideBook4() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Volume 4 - Uncommon Crustaceans";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"apple crab:",
"Some say the apple",
"crab be so named",
"because it makes",
"a good cider. To",
"this, I say yuck! "
),
new BookPageInfo
(
"Blue crab:",
"The blue crab can",
"be identified by",
"the fact that they",
"be blue on the ",
"bottom. "
),
new BookPageInfo
(
"Dungeoness crab:",
"The dungeoness crab",
"was so named ",
"because 'twas first",
"discovered in a ",
"dungeon, later it",
"was discovered they",
"could be found ",
"anywhere."
),
new BookPageInfo
(
"King crab:",
"The Order is not",
"sure who made this",
"rascal king, but",
"we recon it took",
"some fast talkin'."
),
new BookPageInfo
(
"Rock crab:",
"The rock crab be",
"uncommon mostly",
"because they",
"often get stepped",
"on by accident."
),
new BookPageInfo
(
"Snow crab:",
"Contrary to popular",
"belief, the snow",
"crab is not found",
"in snow. They be",
"found in water",
"with the rest o'",
"the crabs."
),
new BookPageInfo
(
"Crusty lobster:",
"Juka like to use",
"the shell o' this",
"lobster for pie crust. "
),
new BookPageInfo
(
"Fred lobster:",
"On occasion I be",
"wonderin' to meself",
", who is Fred?",
"and how did he get",
"to name a lobster?"
),
new BookPageInfo
(
"Hummer lobster:",
"Some sailors say",
"they can hear the",
"hum of a hummer",
"lobster. But I",
"don't be seein'",
"'em catch more",
"than anyone else."
),
new BookPageInfo
(
"Rock lobster:",
"The rock lobster",
"be uncommon ",
"mostly because ",
"they often get ",
"st... Wait, I think",
"I used that one",
"already."
),
new BookPageInfo
(
"Shovel-nose lobster:",
"The shovel-nose ",
"lobster has a flat,",
"shovel like nose ",
"that it uses to dig",
"into the sand and hide. "
),
new BookPageInfo
(
"Spiney lobster:",
"Spiney lobsters be",
"hard on traps, ",
"sometimes when they",
"try to get in a ",
"trap they tear it",
"to pieces. "
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook4( 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,234 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook5 : BaseBook
{
[Constructable]
public FishingGuideBook5() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Volume 5 - Enchanted Sea Creatures";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"Autumn Dragonfish:",
"This beauty be",
"found in Ilshenar.",
"If prepared ",
"correctly and eaten,",
"it be improvin' yer",
"ability to meditate."
),
new BookPageInfo
(
"Bull Fish:",
"The bull fish be ",
"found in the ",
"labrynth o' Malas.",
"If prepared ",
"correctly and eaten,",
"it be increasin'",
"power to yer sword hand."
),
new BookPageInfo
(
"Crystal Fish:",
"This mystical fish",
"be found in the ",
"prism o' light. If",
"prepared correctly",
"and eaten, it be",
"protectin' a sailor",
"from lightning. "
),
new BookPageInfo
(
"Fairy Salmon:",
"This daring fish",
"swims the rivers o'",
String.Format("{0}. If prepared", FishInfo.GetFishLocation(typeof(FairySalmon))),
"correctly, and eaten,",
"it be helpin' improve",
"a sailor's concentration",
"when casting spells."
),
new BookPageInfo
(
"Fire Fish:",
"This fish be found",
"in the dungeon o' ",
"Shame. If prepared",
"correctly and eaten,",
"it be protecting a",
"sailor from fire."
),
new BookPageInfo
(
"Giant Koi:",
"This fish be found in",
"deep waters o' Tokuno.",
"If prepared correctly",
"and eaten, it be givin",
"a sailor it's ability",
"to dodge."
),
new BookPageInfo
(
"Great Barracuda:",
"This fish be found in",
"the deep waters o'",
"Felucca. If prepared",
"correctly and eaten,",
"it be increasin' yer",
"accuracy with weapons."
),
new BookPageInfo
(
"Holy Mackerel:",
"This fish be found in",
"the spirit filled ",
"waters o' Malas. If",
"prepared correctly and",
"eaten, it be making ye",
"gain mana more quickly."
),
new BookPageInfo
(
"Lava Fish:",
"This fish be found in",
"the lava rivers o' the",
String.Format("{0}. When ", FishInfo.GetFishLocation(typeof(LavaFish))),
"prepared correctly and",
"eaten, it be increasin'",
"yer mana when ye be ",
"injured."
),
new BookPageInfo
(
"Reaper Fish:",
"This fish be found in",
"the lakes o' dungeon",
"Doom. If prepared ",
"correctly and eaten ",
"it be protectin' ye ",
"from poison damage."
),
new BookPageInfo
(
"Summer Dragonfish:",
"This beautiful fish ",
"be found in the pools",
"o' dungeon Destard. ",
"If prepared correctly",
"and eaten, it will ",
"increase spell damage."
),
new BookPageInfo
(
"Unicorn Fish:",
"This great fish be ",
"found in the Twisted ",
"Weald. If prepared ",
"correctly and eaten, ",
"ye will recover from ",
"fatigue more quickly."
),
new BookPageInfo
(
"Yellowtail Barracuda:",
"This devil be found ",
"in the deep waters o'",
"Trammel. If prepared ",
"correctly and eaten,",
"ye will heal more",
"quickly."
),
new BookPageInfo
(
"Blue Lobster:",
"This lobster be exclusive",
"to the Ice Dungeon. If",
"prepared correctly and",
"eaten, it protects ye",
"from damage due to cold."
),
new BookPageInfo
(
"Spider Crab:",
"Found in the waters o'",
"Terathan Keep. If ",
"prepared correctly and",
"eaten, it be improvin",
"yer ability to focus."
),
new BookPageInfo
(
"Stone Crab:",
"This tough customer",
"be ound in the deep ",
"sea o' the Lost Lands.",
"If prepared correctly",
"and eaten, it makes yer",
"skin tougher."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook5( 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,260 @@
using Server;
using System;
namespace Server.Items
{
public class FishingGuideBook6 : BaseBook
{
[Constructable]
public FishingGuideBook6() : base( Utility.Random( 0xFF1, 2 ), false )
{
Name = "Vplume 6 - Legendary Sea Creatures";
}
public static readonly BookContent Content = new BookContent
(
null, "Cpt. Piddlewash",
new BookPageInfo
(
"Abyssal Dragonfish:",
"In the bottomless wells",
"o' Destard lurk many ",
"dangers. Some say a",
"black dragonfish swims",
"there."
),
new BookPageInfo
(
"Black Marlin:",
"Somewhere out in the ",
"deep waters o' Felucca,",
"sailors say they caught",
"a black marlin but it",
"got away."
),
new BookPageInfo
(
"Blue Marlin:",
"An old sailor once told",
"me that he saw a blue",
"marlin leap from the ",
"seas o' Trammel. This",
"hath ne'er been confirmed."
),
new BookPageInfo
(
"Dungeon Pike:",
"A journal was found in",
"the Terathan Keep by a",
"pile o' bones. The late",
"fisherman claimed that",
"he has caught this fish",
"thar."
),
new BookPageInfo
(
"Giant Samurai Fish:",
"Tokuno fishermen tell ",
"stories of ancient ",
"samurai fish o' legendary",
"size. None o' their ",
"stories have ever been",
"confirmed."
),
new BookPageInfo
(
"Golden Tuna:",
"This fish be only known",
"in the myth. But come",
"believe they exist in",
"the deep waters o' ",
"Tokuno."
),
new BookPageInfo
(
"Winter Dragonfish:",
"The Ice Dungeon holds",
"many mysteries, most",
"of them will kill ye. ",
"But there be a legend",
"of a dragonfish that",
"rules the rivers thar."
),
new BookPageInfo
(
"Kingfish",
"The kingfish be",
"extraordinarily rare.",
"They say that Lord ",
"British caught one ",
"once, but this ne'er",
"was confirmed."
),
new BookPageInfo
(
"Lantern Fish:",
"This fish be said to",
"live in the Prism o'",
"light. However like",
"many legends, it has",
"never been confirmed."
),
new BookPageInfo
(
"Rainbow Fish:",
"The elves tell a tale",
"of princess who fell",
"into the river of the",
"Twisted Weald and was",
"eaten by this elusive",
"fish."
),
new BookPageInfo
(
"Seeker Fish:",
"The story o' this fish",
"is that it wandered ",
"into the Labyrinth of",
"Malas and became lost.",
"'Tis an odd story with",
"many holes but it might",
"be thar."
),
new BookPageInfo
(
"Spring Dragonfish:",
"Before one was caught",
"by Mistress Kegwood ",
"in Ilshenar, these were",
"unknown. It hangs in ",
"the secret hall o' the",
"Order of the Dragonfish."
),
new BookPageInfo
(
"Stone Fish:",
"The stone harpies worship",
"a great Stone fish they",
"say sleeps at the bottom",
"o' the sea in the Lost ",
"Lands. Many of our order",
"seek to catch it."
),
new BookPageInfo
(
"Zombie Fish:",
"'Tis said that there be",
"an Undead fish in the ",
"waters o' Malas. Some say",
"it be an unholy experiment,",
"some say it be a lie."
),
new BookPageInfo
(
"Blood Lobster:",
"In the depths o' the",
"dungeon Shame this strange",
"creature be said to lurk.",
"Some say it feeds on the",
"blood o' the fallen."
),
new BookPageInfo
(
"Dread Lobster:",
"'Tis said that this ",
"lobster is the reason",
"monsters don't go into",
"the waters of Doom."
),
new BookPageInfo
(
"Tunnel Crab:",
"This creature be said",
"to live in the",
String.Format("{0} beneath Fire", FishInfo.GetFishLocation(typeof(TunnelCrab))),
"Island. 'Tis a goblin",
"legend so 'tis a bit",
"suspect."
),
new BookPageInfo
(
"Void Crab:",
"Some old fisherman in",
String.Format("{0} say they have", FishInfo.GetFishLocation(typeof(VoidCrab))),
"seen a crab that ",
"resembles a void demon",
"in the rivers. This has",
"not been confirmed."
),
new BookPageInfo
(
"Void Lobster:",
"The goblins o' the",
String.Format("{0} tell o' a", FishInfo.GetFishLocation(typeof(VoidLobster))),
"creature that looks like",
"a cross between a void",
"demon and a lobster. They",
"say it lives in the lava",
"therein."
)
);
public override BookContent DefaultContent{ get{ return Content; } }
public FishingGuideBook6( 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,93 @@
using Server;
using System;
using Server.Engines.Quests;
using Server.Multis;
using Server.Items;
namespace Server.Mobiles
{
public class FishMonger : MondainQuester
{
public override Type[] Quests { get { return new Type[] { typeof(ProfessionalFisherQuest) }; } }
[Constructable]
public FishMonger()
{
FishQuestHelper.AddMonger(this);
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = false;
Race = Race.Human;
Name = NameList.RandomName("male");
Title = "the fish monger";
Hue = Race.RandomSkinHue();
Race.RandomHair(this);
HairHue = Race.RandomHairHue();
}
public override void InitOutfit()
{
SetWearable(new ShortPants());
SetWearable(new Shirt());
SetWearable(new Sandals());
}
public override void OnTalk(PlayerMobile player)
{
int distance = 100;
BaseBoat boat = FishQuestHelper.GetBoat(player);
if (boat == null)
SayTo(player, 1116514); //Bring yer ship around, I might have some work for ye!);
else
{
bool inRange = InRange(boat.Location, distance) && boat.Map == this.Map;
if (!FishQuestHelper.HasFishQuest(player, this, inRange))
{
FishMonger monger = FishQuestHelper.GetRandomMonger(player, this);
if (monger == null)
SayTo(player, "It seems my fellow fish mongers are on vacation. Try again later, or perhaps another Facet.");
else
{
ProfessionalFisherQuest quest = new ProfessionalFisherQuest(player, monger, this, boat);
if (quest != null)
{
quest.Quester = this;
quest.Owner = player;
player.CloseGump(typeof(MondainQuestGump));
player.SendGump(new MondainQuestGump(quest));
if (boat.IsClassicBoat)
this.SayTo(player, "Such a weak vessle can only catch a weak line.");
}
}
}
}
}
public FishMonger(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();
FishQuestHelper.AddMonger(this);
}
}
}

View File

@@ -0,0 +1,459 @@
using Server;
using System;
using System.Collections.Generic;
using System.Collections;
using Server.Items;
using Server.Mobiles;
using Server.Multis;
namespace Server.Engines.Quests
{
public static class FishQuestHelper
{
public static Type[] Fish { get { return m_Fish; } }
private static Type[] m_Fish = new Type[]
{
//to level 80.0 (shore fish) index to 11
typeof(BluegillSunfish), typeof(BrookTrout), typeof(GreenCatfish),
typeof(KokaneeSalmon), typeof(PikeFish), typeof(PumpkinSeedSunfish),
typeof(RainbowTrout), typeof(RedbellyBream), typeof(SmallmouthBass),
typeof(UncommonShiner), typeof(Walleye), typeof(YellowPerch),
//to level 106 (deepwater and crustaceans) crustaceans index to 23 fish to 41
typeof(CrustyLobster), typeof(FredLobster), typeof(HummerLobster),
typeof(RockLobster), typeof(ShovelNoseLobster), typeof(SpineyLobster),
typeof(AppleCrab), typeof(BlueCrab), typeof(DungeonessCrab),
typeof(KingCrab), typeof(RockCrab), typeof(SnowCrab),
typeof(Amberjack), typeof(BlackSeabass), typeof(BlueGrouper),
typeof(BlueFish), typeof(Bonefish), typeof(Bonito),
typeof(CapeCod), typeof(CaptainSnook), typeof(Cobia),
typeof(GraySnapper), typeof(Haddock), typeof(MahiMahi),
typeof(RedDrum), typeof(RedGrouper), typeof(RedSnook),
typeof(Shad), typeof(Tarpon), typeof(YellowfinTuna),
//skill elvel to 120.0 for dungeon index to 53
typeof(CragSnapper), typeof(CutThroatTrout), typeof(DarkFish),
typeof(DemonTrout), typeof(DrakeFish), typeof(DungeonChub),
typeof(GrimCisco), typeof(InfernalTuna), typeof(LurkerFish),
typeof(OrcBass), typeof(SnaggletoothBass), typeof(TormentedPike)
};
public static int[] Labels { get { return m_Labels; } }
private static int[] m_Labels = new int[]
{
//to level 80.0 (shore fish) index to 11
1116417, 1116415, 1116421,
1116423, 1116414, 1116412,
1116416, 1116418, 1116419,
1116420, 1116422, 1116413,
//to level 106 (deepwater and crustaceans) crustaceans index to 23 fish to 41
1116383, 1116382, 1116381,
1116380, 1116384, 1116379,
1116378, 1116374, 1116373,
1116375, 1116376, 1116377,
1116402, 1116396, 1116411,
1116406, 1116409, 1116405,
1116395, 1116408, 1116400,
1116399, 1116394, 1116401,
1116410, 1116407, 1116398,
1116403, 1116397, 1116404,
//skill elvel to 120.0 for dungeon index to 53
1116432, 1116427, 1116431,
1116425, 1116429, 1116424,
1116428, 1116433, 1116435,
1116430, 1116426, 1116434
};
private static Type[][][] m_RewardTable = new Type[][][]
{
new Type[][]
{
new Type[] { typeof(Bait) },
new Type[] { typeof(LavaLobsterTrap) },
new Type[] { typeof(FishingGuideBook1), typeof(FishingGuideBook2) },
new Type[] { typeof(PowerScroll), typeof(FishingPole) },
},
new Type[][]
{
new Type[] { typeof(Bait) },
new Type[] { typeof(LavaHook), typeof(LavaLobsterTrap), typeof(JunkProofHook) },
new Type[] { typeof(FishingGuideBook1), typeof(FishingGuideBook2), typeof(FishingGuideBook3), typeof(FishingPole) },
new Type[] { typeof(PowerScroll), typeof(OracleOfTheSea), typeof(DredgingHook) },
},
new Type[][]
{
new Type[] { typeof(Bait) },
new Type[] { typeof(LavaHook), typeof(DredgingHook), typeof(JunkProofHook), typeof(FishingPole) },
new Type[] { typeof(FishingGuideBook3), typeof(FishingGuideBook4), typeof(FishingGuideBook5), },
new Type[] { typeof(PowerScroll), typeof(OracleOfTheSea) },
},
new Type[][]
{
new Type[] { typeof(Bait), typeof(JunkProofHook) },
new Type[] { typeof(OracleOfTheSea), typeof(LavaHook), typeof(FishingPole) },
new Type[] { typeof(FishingGuideBook4), typeof(FishingGuideBook5), typeof(FishingGuideBook6) },
new Type[] { typeof(PowerScroll), typeof(PermanentBoatPaint) },
}
};
public static void GiveRewards(Mobile from, PlayerFishingEntry entry, double points)
{
Container pack = from.Backpack;
if (pack == null)
pack = from.BankBox;
int tier = 1;
int category = 1;
double roll = Utility.RandomDouble();
if (points >= 100)
tier = 2;
else if (points >= 150)
tier = 3;
else if (points >= 210)
tier = 4;
if (roll < .10)
category = 4;
else if (roll < .25)
category = 3;
else if (roll < .50)
category = 2;
Type type = m_RewardTable[tier - 1][category - 1][Utility.Random(m_RewardTable[tier - 1][category - 1].Length)];
Item item = Loot.Construct(type);
if (item != null)
{
if (item is PowerScroll)
{
int value;
double chance = Utility.RandomDouble();
switch (tier)
{
default:
case 1:
if (0.01 > chance)
value = 120;
else if (0.05 > chance)
value = 115;
else if (chance > 0.25)
value = 110;
else value = 105;
break;
case 2:
if (0.05 > chance)
value = 120;
else if (0.25 > chance)
value = 115;
else
value = 110;
break;
case 3:
if (0.10 > chance)
value = 120;
else
value = 115;
break;
case 4:
value = 120;
break;
}
((PowerScroll)item).Skill = SkillName.Fishing;
((PowerScroll)item).Value = value;
from.SendLocalizedMessage(1149591); //
}
else if (item is BaseBook)
from.SendLocalizedMessage(1149590); //You receive a rare book.
else if (item is Bait)
{
Bait bait = (Bait)item;
switch (tier)
{
case 1: bait.Index = Utility.Random(15);
if(0.001 >= Utility.RandomDouble())
bait.Enhanced = true;
break;
case 2: bait.Index = Utility.Random(34);
if(0.005 >= Utility.RandomDouble())
bait.Enhanced = true;
break;
case 3: bait.Index = Utility.Random(34);
if(0.01 >= Utility.RandomDouble())
bait.Enhanced = true;
break;
case 4:
if (Utility.RandomBool())
bait.Index = 35;
else
bait.Index = Utility.RandomMinMax(16, 34);
if (0.05 >= Utility.RandomDouble())
bait.Enhanced = true;
break;
}
if (FishInfo.GetTypeFromIndex(bait.Index) == typeof(Charydbis))
{
bait.UsesRemaining = 5;
from.SendLocalizedMessage(1150871); //You receive charybdis bait
if (0.08 >= Utility.RandomDouble())
bait.Enhanced = true;
}
else
{
object label = FishInfo.GetFishLabel(bait.Index);
if (label is int)
from.SendLocalizedMessage(1149588, String.Format("#{0}\t", (int)label)); //You receive bait to catch ~1_val~
else
from.SendLocalizedMessage(1149588, (string)label); //You receive bait to catch ~1_val~
bait.UsesRemaining = (int)Math.Min(200, points / 2);
}
}
else if (item is PermanentBoatPaint)
{
from.SendMessage("You recieve permanent boat paint!");
}
else
{
if (item is FishingPole)
BaseRunicTool.ApplyAttributesTo((FishingPole)item, false, 0, Utility.RandomMinMax(1, tier + 1), 25, 100);
from.SendLocalizedMessage(1149589); //You receive some rare fishing equipment.
}
pack.DropItem(item);
if (entry != null)
entry.OnAfterReward(points);
}
}
public static List<FishMonger> Mongers { get { return m_Mongers; } }
private static List<FishMonger> m_Mongers = new List<FishMonger>();
public static void AddMonger(Mobile mob)
{
if (mob == null || !(mob is FishMonger) || m_Mongers.Contains((FishMonger)mob))
return;
m_Mongers.Add((FishMonger)mob);
}
public static FishMonger GetRandomMonger(PlayerMobile player, FishMonger monger)
{
bool NOGO = true;
FishMonger mob = null;
Map map = player.Map;
List<FishMonger> mongers = new List<FishMonger>(m_Mongers);
//First, remove quester
if (mongers.Contains(monger))
mongers.Remove(monger);
//Next, remove mongers from other facets in same region as quest giver
foreach (FishMonger m in m_Mongers)
{
if (m.Region != null && monger.Region != null && m.Region.Name == monger.Region.Name)
mongers.Remove(m);
}
//Now, remove mongers from other quests
if (player.Quests != null)
{
for (int i = 0; i < player.Quests.Count; i++)
{
if (player.Quests[i] is ProfessionalFisherQuest)
{
ProfessionalFisherQuest q = (ProfessionalFisherQuest)player.Quests[i];
if (mongers.Contains(q.TurnIn))
mongers.Remove(q.TurnIn);
}
}
}
if (mongers == null || mongers.Count < 1)
return null;
while (NOGO)
{
mob = mongers[Utility.Random(mongers.Count)];
if (mob.Region != null && mob.Region.Name != null)
NOGO = false;
}
return mob;
}
public static BaseBoat GetBoat(Mobile from)
{
List<BaseBoat> boats = new List<BaseBoat>();
foreach (BaseBoat boat in BaseBoat.Boats)
{
if (boat.Owner == from && !boat.IsRowBoat)
boats.Add(boat);
}
BaseBoat closest = null;
int range = 5000;
foreach (BaseBoat boat in boats)
{
int dist = (int)from.GetDistanceToSqrt(boat.Location);
if (closest == null || dist < range)
{
closest = boat;
range = dist;
}
}
return closest;
}
public static bool HasFishQuest(PlayerMobile player, MondainQuester quester, bool inRange)
{
//We need to bump the completed quests to the front so we can get credit before the incomplete quests.
List<ProfessionalFisherQuest> quests = new List<ProfessionalFisherQuest>();
if (player.Quests != null)
{
for (int i = 0; i < player.Quests.Count; i++)
{
if (player.Quests[i] is ProfessionalFisherQuest)
{
ProfessionalFisherQuest quest = player.Quests[i] as ProfessionalFisherQuest;
if (quest.Completed)
quests.Insert(0, quest);
else
quests.Add(quest);
}
}
}
for (int i = 0; i < quests.Count; i++)
{
ProfessionalFisherQuest quest = quests[i] as ProfessionalFisherQuest;
if (quest.Quester is Mobile && (Mobile)quest.Quester == quester)
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
return true;
}
if (quest.TurnIn == quester || (quest.TurnIn != null && quest.TurnIn.Region != null && quester.Region != null && quest.TurnIn.Region.Name == quester.Region.Name))
{
if (!inRange)
{
quester.SayTo(player, 1116519); //I can't find your ship! You need to bring it in closer.
return true;
}
if (quest.Completed)
{
quest.OnCompleted();
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
player.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
}
if (!inRange)
{
quester.SayTo(player, 1116514); //Bring yer ship around, I might have some work for ye!
return true;
}
return false;
}
public static int GetIndexForSkillLevel(Mobile from)
{
if (from == null)
return 0;
double skill = from.Skills[SkillName.Fishing].Base;
if (skill < 80.0)
return 11;
else if (skill < 106.0)
return 41;
else
return m_Fish.Length; //TODO CHECK
}
public static int GetIndexForType(Type type)
{
for (int i = 0; i < m_Fish.Length; i++)
{
if (m_Fish[i] == type)
return i;
}
return 0;
}
public static Type GetTypeFromIndex(int index)
{
if (index < 0 || index >= m_Fish.Length)
return null;
return m_Fish[index];
}
public static bool IsShallowWaterFish(Type type)
{
return GetIndexForType(type) <= 11;
}
public static bool IsCrustacean(Type type)
{
int index = GetIndexForType(type);
return index > 11 && index <= 23;
}
public static bool IsDeepWaterFish(Type type)
{
int index = GetIndexForType(type);
return index > 11 && index <= 41;
}
public static bool IsDungeonFish(Type type)
{
int index = GetIndexForType(type);
return index > 41 && index < m_Fish.Length;
}
}
}

View File

@@ -0,0 +1,108 @@
using Server;
using System;
using System.Collections.Generic;
using Server.Multis;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests
{
public class FishQuestObjective : BaseObjective
{
public Dictionary<Type, int[]> Line { get; set; }
public bool IsCompleted
{
get
{
foreach (KeyValuePair<Type, int[]> kvp in Line)
{
if (kvp.Value[0] < kvp.Value[1])
return false;
}
return true;
}
}
public FishQuestObjective()
{
}
public FishQuestObjective(Dictionary<Type, int> line)
: base(500, 0)
{
Line = new Dictionary<Type, int[]>();
foreach (KeyValuePair<Type, int> kvp in line)
{
Line[kvp.Key] = new int[] { 0, kvp.Value };
}
}
public override bool Update(object obj)
{
if (obj is Item)
{
Item item = (Item)obj;
foreach (KeyValuePair<Type, int[]> kvp in Line)
{
if (item.GetType() == kvp.Key)
{
kvp.Value[0] += item.Amount;
if (IsCompleted && Quest.Owner != null)
{
CurProgress = 500;
Quest.Owner.SendLocalizedMessage(1072273, null, 0x23); // You've completed a quest! Don't forget to collect your reward.
Quest.Owner.SendSound(Quest.CompleteSound);
}
else
Quest.Owner.SendSound(Quest.UpdateSound);
return true;
}
}
}
return false;
}
public bool CheckLift(Item item)
{
return item != null && Line.ContainsKey(item.GetType());
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(Line.Count);
foreach (KeyValuePair<Type, int[]> kvp in Line)
{
writer.Write(FishQuestHelper.GetIndexForType(kvp.Key));
writer.Write(kvp.Value[0]);
writer.Write(kvp.Value[1]);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int count = reader.ReadInt();
Line = new Dictionary<Type, int[]>();
for (int i = 0; i < count; i++)
{
Type type = FishQuestHelper.GetTypeFromIndex(reader.ReadInt());
int[] line = new int[] { reader.ReadInt(), reader.ReadInt() };
if (type != null)
Line[type] = line;
}
}
}
}

View File

@@ -0,0 +1,308 @@
using System;
using Server;
using Server.Mobiles;
using Server.Items;
using System.Collections.Generic;
using Server.Commands;
using Server.Multis;
namespace Server.Engines.Quests
{
public class PlayerFishingEntry
{
public static void Initialize()
{
CommandSystem.Register("FishMongerStatus", AccessLevel.Player, new CommandEventHandler(FishMongerStatus_OnCommand));
}
private Mobile m_Player;
private double m_Reputation;
private bool m_HasRecievedBritGal;
private Dictionary<int, int> m_HaveFished = new Dictionary<int, int>();
private Dictionary<int, int> m_TimesFished = new Dictionary<int, int>();
public Mobile Player { get { return m_Player; } }
public double Reputation { get { return m_Reputation; } set { m_Reputation = value; } }
public bool HasRecievedBritGal { get { return m_HasRecievedBritGal; } set { m_HasRecievedBritGal = value; } }
public Dictionary<int, int> HaveFished { get { return m_HaveFished; } }
public Dictionary<int, int> TimesFished { get { return m_TimesFished; } }
private static Dictionary<Mobile, PlayerFishingEntry> m_FishingEntries = new Dictionary<Mobile, PlayerFishingEntry>();
public static Dictionary<Mobile, PlayerFishingEntry> FishingEntries { get { return m_FishingEntries; } }
public static readonly double RewardAmount = 15000;
public PlayerFishingEntry(Mobile from)
{
m_Player = from;
m_Reputation = 0.0;
m_FishingEntries.Add(from, this);
m_HasRecievedBritGal = false;
}
public static PlayerFishingEntry GetEntry(Mobile from)
{
return GetEntry(from, false);
}
public static PlayerFishingEntry GetEntry(Mobile from, bool create)
{
if (m_FishingEntries.ContainsKey(from))
return m_FishingEntries[from];
if (create)
{
PlayerFishingEntry entry = new PlayerFishingEntry(from);
return entry;
}
return null;
}
public double GetPointsAwarded(FishQuestObjective obj)
{
double toAward = 0.0;
foreach (KeyValuePair<Type, int[]> kvp in obj.Line)
{
Type type = kvp.Key;
int value = kvp.Value[1];
if (FishQuestHelper.IsShallowWaterFish(type))
toAward += value;
else if (FishQuestHelper.IsCrustacean(type) || FishQuestHelper.IsDeepWaterFish(type))
toAward += value * 2;
else if (FishQuestHelper.IsDungeonFish(type))
toAward += value * 3;
m_Reputation += toAward;
}
return toAward;
}
public void OnAfterReward(double points)
{
if (m_Player == null || m_Player.NetState == null)
return;
if (points <= 100)
m_Player.SendMessage("You have gained a fair amount of reputation with the Fish Mongers.");
else if (points <= 150)
m_Player.SendMessage("You have gained a good amount of reputation with the Fish Mongers.");
else
m_Player.SendMessage("You have gained a large amount of reputation with the Fish Mongers.");
}
public int CalculateLines()
{
int eligibleIndex = FishQuestHelper.GetIndexForSkillLevel(m_Player);
double line2 = 0.0; double line3 = 0.0;
double line4 = 0.0; double line5 = 0.0; double line6 = 0.0;
for (int i = 0; i < eligibleIndex; i++)
{
if (!m_TimesFished.ContainsKey(i))
continue;
int timesDone = Math.Min(6, m_TimesFished[i]);
int toAdd = 100 / eligibleIndex;
switch (timesDone)
{
case 6: goto case 5;
case 5: line6 += toAdd; goto case 4;
case 4: line5 += toAdd; goto case 3;
case 3: line4 += toAdd; goto case 2;
case 2: line3 += toAdd; goto case 1;
case 1: line2 += toAdd; goto case 0;
case 0:
default: break;
}
}
if (Math.Min(85, line6) >= Utility.Random(100))
return 6;
if (Math.Min(85, line5) >= Utility.Random(100))
return 5;
if (Math.Min(85, line4) >= Utility.Random(100))
return 4;
if (Math.Min(85, line3) >= Utility.Random(100))
return 3;
if (Math.Min(85, line2) >= Utility.Random(100))
return 2;
return 1;
}
public void GetRandomFish(ref int index, ref int amount, List<int> chosen)
{
int eligibleIndex = FishQuestHelper.GetIndexForSkillLevel(m_Player);
while(true)
{
index = Utility.Random(eligibleIndex);
if (!chosen.Contains(index))
break;
}
if (m_HaveFished.ContainsKey(index))
amount = m_HaveFished[index];
else
amount = 10;
}
public void OnQuestResign(Type type)
{
int index = FishQuestHelper.GetIndexForType(type);
if (index < 0)
return;
m_Reputation -= 20;
if (m_HaveFished.ContainsKey(index))
{
if (m_HaveFished[index] > 10)
m_HaveFished[index] -= 5;
else
m_HaveFished[index] = 5;
}
else
m_HaveFished.Add(index, 10);
}
public void OnQuestComplete(FishQuestObjective obj)
{
foreach (KeyValuePair<Type, int[]> kvp in obj.Line)
{
Type type = kvp.Key;
int index = FishQuestHelper.GetIndexForType(type);
if (m_HaveFished.ContainsKey(index))
{
if (m_HaveFished[index] >= 20)
m_HaveFished[index] = 10;
else
m_HaveFished[index] += 5;
}
else
m_HaveFished.Add(index, 15);
if (!m_TimesFished.ContainsKey(index))
m_TimesFished[index] = 0;
m_TimesFished[index]++;
}
}
public PlayerFishingEntry(GenericReader reader)
{
int version = reader.ReadInt();
if (version > 0)
m_HasRecievedBritGal = reader.ReadBool();
else
m_HasRecievedBritGal = false;
m_Player = reader.ReadMobile();
m_Reputation = reader.ReadDouble();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
int index = reader.ReadInt();
int finished = reader.ReadInt();
if (index >= 0 && index < FishQuestHelper.Fish.Length)
m_HaveFished.Add(index, finished);
}
count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
int index = reader.ReadInt();
int fished = reader.ReadInt();
if (index >= 0 && index < FishQuestHelper.Fish.Length)
m_TimesFished.Add(index, fished);
}
if(m_Player != null)
m_FishingEntries.Add(m_Player, this);
}
public void Serialize(GenericWriter writer)
{
writer.Write((int)1);
writer.Write(m_HasRecievedBritGal);
writer.Write(m_Player);
writer.Write(m_Reputation);
writer.Write(m_HaveFished.Count);
foreach (KeyValuePair<int, int> kvp in m_HaveFished)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
writer.Write(m_TimesFished.Count);
foreach (KeyValuePair<int, int> kvp in m_TimesFished)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
}
public void GetFishMongerReputation(Mobile from)
{
if (from == null)
return;
from.SendMessage("You have earned {0} amount of reputation with the Fish Mongers.", GetStatus());
}
private string GetStatus()
{
double points = m_Reputation;
if (points < 500)
return m_Status[0];
if (points < 1000)
return m_Status[1];
if (points < 5000)
return m_Status[2];
if (points < 15000)
return m_Status[3];
if (points < 50000)
return m_Status[4];
return m_Status[5];
}
private string[] m_Status = new string[]
{
"a small",
"a fair",
"a moderate",
"a tremendous",
"an outstanding",
"an enormous",
};
public static void FishMongerStatus_OnCommand(CommandEventArgs e)
{
PlayerFishingEntry entry = GetEntry(e.Mobile);
if (entry != null)
entry.GetFishMongerReputation(e.Mobile);
else
e.Mobile.SendMessage("You have no reputation with the Fish Mongers.");
}
}
}

View File

@@ -0,0 +1,316 @@
using Server;
using System;
using System.Collections.Generic;
using Server.Multis;
using Server.Items;
using Server.Mobiles;
using Server.Gumps;
namespace Server.Engines.Quests
{
public class ProfessionalFisherQuest : BaseQuest
{
private object m_Title;
public override object Title { get { return m_Title; } } //Professional Fisher Quest - Floating Emporium
public override object Description { get { return 1116508; } } /*This quest is part of a category of quests where you catch uncommon fish and use your ship to deliver them to ports
* to gain rewards and better fishing orders.<br><br>Successful completion of this quest increases your standing with
* the fishmonger guild and unlocks bigger orders and greater rewards. Destroying the crate will forfeit the order and
* hurt your standing with the fishmonger guild.<br><br>You must have the High Seas booster pack to do this quest.
* <br><br>***NOTICE: You will not be able to dry dock your ship while you are on this quest. Destroying the crate in
* your hull will cancel the quest and re-enable dry docking.*** <br><br><center>-----</center><br><br>Greetings sailor,
* I see ye have a fine ship, might ye be looking for work?<br><br>I have some orders for some particular fish that needs
* catchin' an' deliverin' and I be lookin' for some business partners. If ye will agree to fill this order an' deliver
* it fer me, I will reward ye with a rare prize as payment. What say ye?*/
public override object Refuse { get { return 1116511; } } //As you wish. If'n ye change yer mind you know where to find me.
public override object Uncomplete { get { return 1116512; } } //Aye, partner, how goes the fishin? Me customer be waitin' fer ye and won't be payin' either of us till ye deliver.
public override object Complete { get { return 1116513; } } /*Ahoy, sailor! These be a fine batch o' fish and I'll be glad to pay the price. I will forwarded the money owed to
* the fishmonger who brokered this business with me compliments.<br><br>Fer ye I have a rare gift from the Order of
* the Dragonfish that ye can't buy with gold. Let me jes' tuck it in yer backpack here... There you go! Use it
* wisely and it can make ye wealthy!<br><br>If ye are interested in gettin more fishin' business from me, I have some
* orders of me own to fill and ship. Jes' let me know.*/
private FishMonger m_TurnIn;
private BaseBoat m_Boat;
private ShippingCrate m_Crate;
public FishMonger TurnIn { get { return m_TurnIn; } set { m_TurnIn = value; } }
public BaseBoat Boat { get { return m_Boat; } set { m_Boat = value; } }
public ShippingCrate Crate { get { return m_Crate; } set { m_Crate = value; } }
public ProfessionalFisherQuest()
{
AddObjective(new FishQuestObjective());
}
public ProfessionalFisherQuest(Mobile from, FishMonger monger, FishMonger quester, BaseBoat boat)
{
PlayerFishingEntry entry = PlayerFishingEntry.GetEntry(from, true);
int lines;
if (boat.IsClassicBoat)
lines = 1;
else
lines = entry.CalculateLines();
m_TurnIn = monger;
m_Boat = boat;
int index = 0;
int amount = 10;
Type type = null;
List<int> hasChosen = new List<int>();
Dictionary<Type, int> types = new Dictionary<Type, int>();
for (int i = 0; i < lines; i++)
{
entry.GetRandomFish(ref index, ref amount, hasChosen);
hasChosen.Add(index);
type = FishQuestHelper.GetTypeFromIndex(index);
if (amount < 5) amount = 5;
if (amount > 20) amount = 20;
types[type] = amount;
}
AddObjective(new FishQuestObjective(types));
AddReward(new BaseReward(1116510)); //A rare reward from the Order of the Dragonfish.
hasChosen.Clear();
m_Title = GetTitle(quester);
}
public override void OnAccept()
{
if (m_Boat == null)
{
RemoveQuest(false);
return;
}
m_Crate = new ShippingCrate(this);
if (m_Boat is BaseGalleon)
((BaseGalleon)m_Boat).GalleonHold.DropItem(m_Crate);
else
m_Boat.Hold.DropItem(m_Crate);
base.OnAccept();
}
private int GetTitle(Mobile monger)
{
Region reg = monger.Region;
if (reg == null || reg.Name == null)
return 1116507;
if (reg.Name == "Sea Market")
return 1116507; //Professional Fisher Quest - Floating Emporium
if (reg.Name == "Britain")
return 1116728; //Professional Fisher Quest - Britain
if (reg.Name == "Trinsic")
return 1116730; //Professional Fisher Quest - Trinsic
if (reg.Name == "Moonglow")
return 1116731; //Professional Fisher Quest - Moonglow
if (reg.Name == "Skara Brae")
return 1116732; //Professional Fisher Quest - Skara Brae
if (reg.Name == "Vesper")
return 1116733; //Professional Fisher Quest - Vesper
if (reg.Name == "Jhelom" || reg.Name == "Jhelom Islands")
return 1116734; //Professional Fisher Quest - Jhelom
if (reg.Name == "Papua")
return 1116735; //Professional Fisher Quest - Papua
return 1116507;
}
public override void OnResign(bool resignChain)
{
if (Owner != null)
{
PlayerFishingEntry entry = PlayerFishingEntry.GetEntry(Owner);
if (entry != null)
{
FishQuestObjective obj = GetObjective();
if (obj != null)
{
foreach(KeyValuePair<Type, int[]> kvp in obj.Line)
entry.OnQuestResign(kvp.Key);
}
}
}
if (m_Crate != null)
{
m_Crate.Quest = null;
m_Crate.Delete();
}
base.OnResign(resignChain);
}
public override void GiveRewards()
{
if (Owner != null)
{
PlayerFishingEntry entry = PlayerFishingEntry.GetEntry(Owner);
if (entry != null)
{
double pointsAwarded = 0;
FishQuestObjective obj = GetObjective();
if (obj != null)
{
pointsAwarded += entry.GetPointsAwarded(obj);
entry.OnQuestComplete(obj);
}
FishQuestHelper.GiveRewards(Owner, entry, pointsAwarded);
}
}
DeleteQuestItems();
base.GiveRewards();
}
public void DeleteQuestItems()
{
if (m_Crate == null)
return;
Container hold = null;
if (m_Crate.RootParent is Container)
hold = (Container)m_Crate.RootParent;
//Deletes quest reqeust
FishQuestObjective obj = GetObjective();
if (obj != null)
{
foreach(KeyValuePair<Type, int[]> kvp in obj.Line)
m_Crate.ConsumeTotal(kvp.Key, kvp.Value[1]);
}
//then moves any extras to the hold
if (hold != null)
{
foreach (Item item in new List<Item>(m_Crate.Items))
hold.DropItem(item);
}
if (m_Crate != null)
m_Crate.Delete();
}
public FishQuestObjective GetObjective()
{
if (Objectives.Count > 0)
return Objectives[0] as FishQuestObjective;
return null;
}
public override bool RenderObjective(MondainQuestGump g, bool offer)
{
if (offer)
g.AddHtmlLocalized(130, 45, 270, 16, 1049010, 0xFFFFFF, false, false); // Quest Offer
else
g.AddHtmlLocalized(130, 45, 270, 16, 1046026, 0xFFFFFF, false, false); // Quest Log
g.AddButton(130, 430, 0x2EEF, 0x2EF1, (int)Buttons.PreviousPage, GumpButtonType.Reply, 0);
g.AddButton(275, 430, 0x2EE9, 0x2EEB, (int)Buttons.NextPage, GumpButtonType.Reply, 0);
g.AddHtmlObject(160, 70, 200, 40, Title, BaseQuestGump.DarkGreen, false, false);
g.AddHtmlLocalized(98, 140, 312, 16, 1049073, 0x2710, false, false); // Objective:
g.AddHtmlLocalized(98, 160, 312, 16, 1116509, 0x15F90, false, false); //Fill the crate on your ship with the correct fish.
g.AddHtmlLocalized(98, 176, 312, 16, 1116518, 0x15F90, false, false); //Speak with the fishmonger at the port of delivery.
return true;
}
public override bool RenderDescription(MondainQuestGump g, bool offer)
{
if (offer)
g.AddHtmlLocalized(130, 45, 270, 16, 1049010, 0xFFFFFF, false, false); // Quest Offer
else
g.AddHtmlLocalized(130, 45, 270, 16, 1046026, 0xFFFFFF, false, false); // Quest Log
if (offer)
{
g.AddButton(95, 455, 0x2EE0, 0x2EE2, (int)Buttons.AcceptQuest, GumpButtonType.Reply, 0);
g.AddButton(313, 455, 0x2EF2, 0x2EF4, (int)Buttons.RefuseQuest, GumpButtonType.Reply, 0);
}
else
{
g.AddButton(95, 455, 0x2EF5, 0x2EF7, (int)Buttons.ResignQuest, GumpButtonType.Reply, 0);
g.AddButton(313, 455, 0x2EEC, 0x2EEE, (int)Buttons.CloseQuest, GumpButtonType.Reply, 0);
}
g.AddButton(275, 430, 0x2EE9, 0x2EEB, (int)Buttons.NextPage, GumpButtonType.Reply, 0);
g.AddHtmlObject(160, 70, 200, 40, Title, BaseQuestGump.DarkGreen, false, false);
g.AddHtmlLocalized(98, 140, 312, 16, 1072202, 0x2710, false, false); // Description
g.AddHtmlObject(98, 156, 312, 240, Description, BaseQuestGump.LightGreen, false, true);
return true;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_TurnIn);
writer.Write(m_Boat);
writer.Write(m_Crate);
if (m_Title is string)
{
writer.Write((int)0);
writer.Write((string)m_Title);
}
else
{
writer.Write((int)1);
writer.Write((int)m_Title);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_TurnIn = reader.ReadMobile() as FishMonger;
m_Boat = reader.ReadItem() as BaseBoat;
m_Crate = reader.ReadItem() as ShippingCrate;
if (m_Crate != null)
m_Crate.AddQuest(this);
switch (reader.ReadInt())
{
case 0:
m_Title = reader.ReadString();
break;
case 1:
m_Title = reader.ReadInt();
break;
}
AddReward(new BaseReward(1116510)); //A rare reward from the Order of the Dragonfish.
}
}
}

View File

@@ -0,0 +1,274 @@
using System;
using Server;
using System.Collections.Generic;
using Server.Engines.Quests;
using Server.Network;
namespace Server.Items
{
public class ShippingCrate : SmallCrate
{
public ProfessionalFisherQuest Quest { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool QuestComplete
{
get
{
if (Quest == null)
return false;
return Quest.Completed;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Mobile TurnInMonger
{
get
{
if (Quest == null)
return null;
return Quest.TurnIn;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Quester
{
get
{
if (Quest == null || !(Quest.Quester is Mobile))
return null;
return Quest.Quester as Mobile;
}
}
public override int DefaultMaxWeight { get { return 1200; } }
public override bool DisplaysContent { get { return false; } }
public ShippingCrate(ProfessionalFisherQuest quest)
{
Weight = 1.0;
Quest = quest;
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (Quest == null)
return;
int loc = 1116453; //~1_val~: ~2_val~/~3_val~
FishQuestObjective obj = Quest.GetObjective();
if (obj == null)
Delete();
foreach (KeyValuePair<Type, int[]> kvp in obj.Line)
{
int idx = FishQuestHelper.GetIndexForType(kvp.Key);
list.Add(loc, "#{0}\t{1}\t{2}", FishQuestHelper.Labels[idx], kvp.Value[0].ToString(), kvp.Value[1].ToString());
loc++;
}
object delivery = GetDeliveryInfo();
if (delivery is string)
list.Add((string)delivery);
else
list.Add((int)delivery);
list.Add(1076255); //NO-TRADE
list.Add(1072241, "{0}\t{1}\t{2}\t{3}", TotalItems, MaxItems, TotalWeight, MaxWeight);
}
public override bool OnDragLift(Mobile from)
{
if (Quest == null)
return base.OnDragLift(from);
if (Quest.Owner != from)
{
return false;
}
return base.OnDragLift(from);
}
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
{
return false;
}
public override bool OnDroppedToMobile(Mobile from, Mobile target)
{
from.SendLocalizedMessage(1076256); // That item cannot be traded.
return false;
}
public override bool DropToItem(Mobile from, Item target, Point3D p)
{
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool OnDroppedToWorld(Mobile from, Point3D p)
{
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
return false;
}
public override bool OnStackAttempt(Mobile from, Item stack, Item dropped)
{
if (dropped is BaseHighseasFish && Quest != null)
{
FishQuestObjective obj = Quest.GetObjective();
if (obj != null)
{
if (obj.CheckLift(dropped) && base.OnStackAttempt(from, stack, dropped))
{
obj.Update(dropped);
InvalidateProperties();
return true;
}
}
}
from.SendLocalizedMessage(1116461); // This is not needed to fill the order.
return false;
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is BaseHighseasFish && Quest != null)
{
FishQuestObjective obj = Quest.GetObjective();
if (obj != null && obj.CheckLift(dropped) && base.OnDragDrop(from, dropped))
{
obj.Update(dropped);
InvalidateProperties();
return true;
}
}
from.SendLocalizedMessage(1116461); // This is not needed to fill the order.
return false;
}
public override bool OnDragDropInto(Mobile from, Item dropped, Point3D p)
{
if (dropped is BaseHighseasFish && Quest != null)
{
FishQuestObjective obj = Quest.GetObjective();
if (obj != null && obj.CheckLift(dropped) && base.OnDragDropInto(from, dropped, p))
{
obj.Update(dropped);
InvalidateProperties();
return true;
}
}
from.SendLocalizedMessage(1116461); // This is not needed to fill the order.
return false;
}
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
{
if (Quest == null)
return base.CheckLift(from, item, ref reject);
FishQuestObjective obj = Quest.GetObjective();
if (obj != null && obj.CheckLift(item))
{
reject = LRReason.CannotLift;
return false;
}
return true;
}
public bool CheckCarve(Item item)
{
if (Quest == null)
return true;
FishQuestObjective obj = Quest.GetObjective();
if (obj.CheckLift(item))
return false;
return true;
}
public object GetDeliveryInfo()
{
if (Quest != null && Quest is ProfessionalFisherQuest && Quest.TurnIn != null)
{
Region reg = Quest.TurnIn.Region;
if (reg == null || reg.Name == null)
return "Unknown Delivery";
if (reg.Name == "Sea Market")
return 1116496;
if (reg.Name == "Britain")
return 1116497;
if (reg.Name == "Trinsic")
return 1116498;
if (reg.Name == "Moonglow")
return 1116499;
if (reg.Name == "Skara Brae")
return 1116500;
if (reg.Name == "Vesper")
return 1116501;
if (reg.Name == "Jhelom")
return 1116502;
if (reg.Name == "Papua")
return 1116503;
}
return "Unknown Delivery";
}
public void AddQuest(ProfessionalFisherQuest quest)
{
Quest = quest;
}
public override void Delete()
{
if (Quest != null && !Quest.Completed)
Quest.OnResign(false);
base.Delete();
}
public ShippingCrate(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,71 @@
using Server;
using System;
using Server.Mobiles;
using Server.Items;
using Server.Multis;
namespace Server.Engines.Quests
{
public class BountyQuestObjective : BaseObjective
{
private bool m_Captured;
private Mobile m_CapturedCaptain;
public bool Captured { get { return m_Captured; } set { m_Captured = value; } }
public Mobile CapturedCaptain { get { return m_CapturedCaptain; } set { m_CapturedCaptain = value; } }
public BountyQuestObjective()
{
}
public override bool Update(object obj)
{
Mobile from = (Mobile)obj;
Mobile captain = ((ProfessionalBountyQuest)Quest).Captain;
Mobile quester = Quest.Quester as Mobile;
if (from == null || captain == null)
return false;
Container pack = from.Backpack;
bool inRange = quester != null && quester.InRange(captain.Location, 75);
if (m_Captured && inRange)
return true;
Item item = pack.FindItemByType(typeof(DeathCertificate));
if (item != null && Quest is ProfessionalBountyQuest && ((DeathCertificate)item).Owner != null)
{
item.Delete();
return true;
}
return false;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt((int)1); // version
writer.Write(m_Captured);
writer.Write(m_CapturedCaptain);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
m_Captured = reader.ReadBool();
m_CapturedCaptain = reader.ReadMobile();
Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerCallback(ValidateCaught));
}
private void ValidateCaught()
{
if (m_CapturedCaptain != null && m_CapturedCaptain is PirateCaptain && this.Quest is ProfessionalBountyQuest)
((PirateCaptain)m_CapturedCaptain).Quest = this.Quest as ProfessionalBountyQuest;
}
}
}

View File

@@ -0,0 +1,60 @@
using Server;
using System;
using Server.Engines.Quests;
using Server.Multis;
namespace Server.Items
{
public class BindingPole : Item, IGalleonFixture
{
private BaseQuest m_Quest;
private BaseGalleon m_Galleon;
public BaseQuest Quest
{
get { return m_Quest; }
set { m_Quest = value; }
}
public BaseGalleon Galleon
{
get { return m_Galleon; }
set { m_Galleon = value; }
}
public override int LabelNumber { get { return 1116718; } }
public override void Delete()
{
base.Delete();
if (m_Quest != null)
m_Quest.OnResign(false);
if (m_Galleon != null)
m_Galleon.RemoveFixture(this);
}
public BindingPole(BaseQuest quest) : base(5696)
{
m_Quest = quest;
Movable = false;
}
public BindingPole(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,120 @@
using Server;
using System;
using Server.Engines.Quests;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Items
{
public class BindingRope : Item
{
private Mobile m_BoundMobile;
private ProfessionalBountyQuest m_Quest;
[CommandProperty(AccessLevel.GameMaster)]
public Mobile BoundMobile
{
get { return m_BoundMobile; }
set { m_BoundMobile = value; }
}
public ProfessionalBountyQuest Quest
{
get { return m_Quest; }
set { m_Quest = value; }
}
public override int LabelNumber { get { return 1116717; } }
public BindingRope(ProfessionalBountyQuest quest) : base(5368)
{
m_Quest = quest;
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) && m_BoundMobile == null)
{
from.Target = new InternalTarget(this);
from.SendLocalizedMessage(1116720); //Who do you want to tie up?
}
}
public void DoDelayedDelete(Mobile from)
{
Timer.DelayCall(TimeSpan.FromSeconds(2.5), new TimerStateCallback(DoDelete), from);
}
public void DoDelete(object o)
{
Mobile from = (Mobile)o;
if (from != null)
from.SendMessage("Your crew uses the rope to bind the captain to the front of your galleon.");
Delete();
}
private class InternalTarget : Target
{
private BindingRope m_Rope;
public InternalTarget(BindingRope rope) : base(2, false, TargetFlags.None)
{
m_Rope = rope;
}
protected override void OnTarget(Mobile from, object targeted)
{
if(targeted is Mobile)
{
if (targeted is PirateCaptain)
{
PirateCaptain cap = (PirateCaptain)targeted;
if(cap.Hits > cap.HitsMax / 10)
{
from.SendLocalizedMessage(1116756); //The pirate seems to have too much fight left to be bound.
}
else if(cap.TryBound(from, m_Rope.Quest))
{
m_Rope.BoundMobile = cap;
m_Rope.Quest.OnBound(cap);
cap.OnBound(m_Rope.Quest);
from.SendLocalizedMessage(1116721); //You begin binding the pirate.
m_Rope.DoDelayedDelete(from);
}
}
else
{
from.SendMessage("They cannot by bound by that!");
}
}
else
{
from.SendMessage("They cannot by bound by that!");
}
}
}
public BindingRope(Serial serial) : base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_BoundMobile);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_BoundMobile = reader.ReadMobile();
}
}
}

View File

@@ -0,0 +1,60 @@
using Server;
using System;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
public class DeathCertificate : Item
{
public override int LabelNumber { get { return 1116716; } }
private string m_Owner;
[CommandProperty(AccessLevel.GameMaster)]
public string Owner { get { return m_Owner; } }
public DeathCertificate(Mobile owner)
: base(0x14F0)
{
if (owner is PirateCaptain)
{
PirateCaptain capt = (PirateCaptain)owner;
if (capt.PirateName > 0)
m_Owner = String.Format("#{0}\t#{1}\t#{2}", capt.Adjective, capt.Noun, capt.PirateName);
else
m_Owner = String.Format("#{0}\t#{1}\t{2}", capt.Adjective, capt.Noun, Name);
}
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_Owner != null)
{
list.Add(1116690, m_Owner);
}
}
public DeathCertificate(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_Owner);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Owner = reader.ReadString();
}
}
}

View File

@@ -0,0 +1,685 @@
using Server;
using System;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.Quests;
using System.Linq;
namespace Server.Mobiles
{
public class BaseShipCaptain : BaseCreature
{
public static readonly TimeSpan DeleteAfterDeath = TimeSpan.FromMinutes(15);
public static readonly TimeSpan ResumeTime = TimeSpan.FromSeconds(Utility.RandomMinMax(30, 45));
public static readonly TimeSpan DecayRetry = TimeSpan.FromSeconds(30);
private BaseGalleon m_Galleon;
private bool m_OnCourse;
private DateTime m_NextCannonShot;
private DateTime m_NextMoveCheck;
private DateTime m_ActionTime;
private DateTime m_NextCrewCheck;
private SpawnZone m_Zone;
private bool m_Blockade;
private List<Mobile> m_Crew = new List<Mobile>();
[CommandProperty(AccessLevel.GameMaster)]
public BaseGalleon Galleon { get { return m_Galleon; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool OnCourse { get { return m_OnCourse; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextCannonShot { get { return m_NextCannonShot; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextMoveCheck { get { return m_NextMoveCheck; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime NextCrewCheck { get { return m_NextCrewCheck; } set { m_NextCrewCheck = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public SpawnZone Zone { get { return m_Zone; } set { m_Zone = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Blockade { get { return m_Blockade; } set { m_Blockade = value; } }
public List<Mobile> Crew { get { return m_Crew; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool Aggressive { get { return true; } }
public override bool PlayerRangeSensitive { get { return false; } }
public override double TreasureMapChance { get { return 0.05; } }
public override int TreasureMapLevel { get { return 7; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual TimeSpan ShootFrequency
{
get
{
return TimeSpan.FromSeconds(Math.Min(20, 20.0 - ((double)m_Crew.Count * 2.5)));
}
}
[Constructable]
public BaseShipCaptain() : this(null) { }
public BaseShipCaptain(BaseGalleon galleon)
: this(galleon, AIType.AI_Melee, FightMode.Weakest, 10, 1, .2, .4)
{
}
public BaseShipCaptain(BaseGalleon galleon, AIType ai, FightMode fm, int per, int range, double passive, double active)
: base(ai, fm, per, range, passive, active)
{
m_Galleon = galleon;
m_OnCourse = true;
m_StopTime = DateTime.MinValue;
if (this.Female = Utility.RandomBool())
{
Body = 0x191;
Name = NameList.RandomName("female");
AddItem(new Skirt(Utility.RandomNeutralHue()));
}
else
{
Body = 0x190;
Name = NameList.RandomName("male");
AddItem(new ShortPants(Utility.RandomNeutralHue()));
}
SetStr(500, 750);
SetDex(125, 175);
SetInt(61, 75);
SetHits(4500, 5000);
SetDamage(23, 35);
SetSkill(SkillName.Fencing, 115.0, 120.0);
SetSkill(SkillName.Macing, 115.0, 120.0);
SetSkill(SkillName.MagicResist, 115.0, 120.0);
SetSkill(SkillName.Swords, 115.0, 120.0);
SetSkill(SkillName.Tactics, 115.0, 120.0);
SetSkill(SkillName.Wrestling, 115.0, 120.0);
SetSkill(SkillName.Anatomy, 115.0, 120.0);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 45, 55);
SetResistance(ResistanceType.Fire, 45, 55);
SetResistance(ResistanceType.Cold, 45, 55);
SetResistance(ResistanceType.Poison, 45, 55);
SetResistance(ResistanceType.Energy, 45, 55);
if (galleon == null)
Timer.DelayCall(TimeSpan.FromSeconds(.5), new TimerCallback(SpawnShip));
}
public void SpawnShip()
{
BaseGalleon gal;
if (this is PirateCaptain)
gal = new OrcishGalleon(Direction.North);
else if (this.Map == Map.Tokuno)
gal = new TokunoGalleon(Direction.North);
else
gal = new GargishGalleon(Direction.North);
var p = Location;
Map map = Map;
// Move this sucka out of the way!
Internalize();
if (gal.CanFit(p, map, gal.ItemID))
{
gal.Owner = this;
gal.MoveToWorld(p, map);
m_Galleon = gal;
Server.Engines.Quests.BountyQuestSpawner.FillHold(m_Galleon);
MoveToWorld(new Point3D(p.X, p.Y - 1, gal.Z + gal.ZSurface), map);
int crewCount = Utility.RandomMinMax(3, 5);
for (int j = 0; j < crewCount; j++)
{
Mobile crew = new PirateCrew();
if (j == 0 && this is PirateCaptain)
crew.Title = "the orc captain";
AddToCrew(crew);
crew.MoveToWorld(new Point3D(gal.X + Utility.RandomList(-1, 1), gal.Y + Utility.RandomList(-1, 0, 1), gal.ZSurface), map);
}
gal.AutoAddCannons(this);
return;
}
else
{
gal.Delete();
Delete();
}
}
public void OnShipDelete()
{
if (this.Alive && !this.Deleted)
Kill();
for (int i = 0; i < m_Crew.Count; i++)
{
Mobile mob = m_Crew[i];
if (mob != null && !mob.Deleted)
mob.Kill();
}
}
public override void Delete()
{
if(BountyQuestSpawner.Instance != null)
BountyQuestSpawner.Instance.HandleDeath(this);
if (m_Galleon != null && !m_Galleon.Deleted)
{
m_Galleon.TimeOfDecay = DateTime.UtcNow + TimeSpan.FromMinutes(30);
Timer.DelayCall(DeleteAfterDeath, new TimerStateCallback(TryDecayGalleon), m_Galleon);
}
base.Delete();
}
public override void OnCombatantChange()
{
if (Combatant == null)
CantWalk = true;
else
CantWalk = false;
base.OnCombatantChange();
}
public void TryDecayGalleon(object obj)
{
BaseGalleon gal = obj as BaseGalleon;
if (gal == null)
return;
if (gal.PlayerCount() > 0)
{
Timer.DelayCall(DecayRetry, new TimerStateCallback(TryDecayGalleon), gal);
return;
}
if (gal != null && !gal.Deleted)
gal.ForceDecay();
}
public void AddToCrew(Mobile mob)
{
if (!m_Crew.Contains(mob))
m_Crew.Add(mob);
}
private DateTime m_StopTime;
private bool m_WillResume;
public void ResumeCourseTimed(TimeSpan ts, bool check)
{
if (!m_WillResume)
{
Timer.DelayCall(ts, new TimerCallback(ResumeCourse));
m_WillResume = true;
}
}
public void ResumeCourse()
{
if (m_Galleon != null)
{
m_Galleon.StartCourse(false, false);
m_WillResume = false;
m_OnCourse = true;
}
}
public override void OnThink()
{
base.OnThink();
if (m_Galleon == null)
return;
if (m_Galleon.Deleted)
OnShipDelete();
// Ship is fucked without his captain!!!
if (!m_Galleon.Contains(this))
return;
if (m_NextCrewCheck < DateTime.UtcNow)
{
CheckCrew();
}
if (!IsInBattle())
{
if (!m_OnCourse)
ResumeCourse();
else if (m_OnCourse && !m_Galleon.IsMoving && m_ActionTime < DateTime.UtcNow)
{
ResumeCourseTimed(ResumeTime, true);
m_ActionTime = DateTime.UtcNow + ResumeTime;
}
return;
}
m_OnCourse = false;
Mobile focusMob = GetFocusMob();
if(m_TargetBoat == null || !InRange(m_TargetBoat.Location, 25))
m_TargetBoat = GetFocusBoat(focusMob);
if (focusMob == null && m_TargetBoat == null)
return;
if (m_NextMoveCheck < DateTime.UtcNow && !m_Galleon.Scuttled && !m_Blockade)
{
Point3D pnt = m_TargetBoat != null ? m_TargetBoat.Location : focusMob.Location;
int dist = (int)GetDistanceToSqrt(pnt);
if (!Aggressive && dist < 25)
MoveBoat(pnt);
else if (Aggressive && dist >= 10 && dist <= 35)
MoveBoat(pnt);
else
{
m_Galleon.StopMove(false);
ResumeCourseTimed(TimeSpan.FromMinutes(2), false); //Loiter
}
}
if (m_TargetBoat != null && !m_TargetBoat.Scuttled)
ShootCannons(focusMob, true);
else
ShootCannons(focusMob, false);
}
private BaseGalleon m_TargetBoat;
public Mobile GetFocusMob()
{
Mobile focus = Combatant as Mobile;
if (focus == null || focus.Deleted || !focus.Alive)
{
int closest = 25;
foreach (Mobile mob in m_Crew)
{
if (mob.Alive && mob.Combatant is Mobile)
{
if (focus == null || (int)focus.GetDistanceToSqrt(mob) < closest)
{
focus = mob.Combatant as Mobile;
closest = (int)focus.GetDistanceToSqrt(mob);
}
}
}
}
return focus;
}
public BaseGalleon GetFocusBoat(Mobile focusMob)
{
if (focusMob == null || focusMob.Deleted || focusMob.Map == null || focusMob.Map == Map.Internal)
return null;
BaseGalleon g = BaseGalleon.FindGalleonAt(focusMob, focusMob.Map);
return g != m_Galleon ? g : null;
}
public void MoveBoat(Point3D p)
{
if (m_Galleon == null || m_Galleon.Contains(p))
return;
int x = p.X;
int y = p.Y;
int speed;
int flee = Aggressive ? 1 : -1;
//Direction d = Utility.GetDirectionTo(p.X, p.Y);
Direction dir = m_Galleon.GetMovementFor(x, y, out speed);
Direction f = m_Galleon.Facing;
if (!Aggressive)
dir = (Direction)(((int)dir + -4) & 0x7);
if (dir == Direction.West || dir == Direction.Left || dir == Direction.South)
{
m_Galleon.Turn(-2 * flee, true);
m_NextMoveCheck = DateTime.UtcNow + TimeSpan.FromSeconds(m_Galleon.TurnDelay);
return;
}
else if (dir == Direction.East || dir == Direction.Down)
{
m_Galleon.Turn(2 * flee, true);
m_NextMoveCheck = DateTime.UtcNow + TimeSpan.FromSeconds(m_Galleon.TurnDelay);
return;
}
m_Galleon.StartMove(dir, true);
}
private Dictionary<IShipCannon, DateTime> m_ShootTable = new Dictionary<IShipCannon, DateTime>();
public void ShootCannons(Mobile focus, bool shootAtBoat)
{
List<Item> cannons = new List<Item>(m_Galleon.Cannons.Where(i => !i.Deleted));
foreach (var cannon in cannons.OfType<IShipCannon>())
{
if (cannon != null)
{
if (m_ShootTable.ContainsKey(cannon) && m_ShootTable[cannon] > DateTime.UtcNow)
continue;
Direction facing = cannon.GetFacing();
if (shootAtBoat && HasTarget(focus, cannon, true))
{
cannon.AmmoType = AmmunitionType.Cannonball;
//cannon.LoadedAmmo = cannon.LoadTypes[0];
}
else if (!shootAtBoat && HasTarget(focus, cannon, false))
{
cannon.AmmoType = AmmunitionType.Grapeshot;
//cannon.LoadedAmmo = cannon.LoadTypes[1];
}
else
{
continue;
}
cannon.Shoot(this);
m_ShootTable[cannon] = DateTime.UtcNow + ShootFrequency + TimeSpan.FromSeconds(Utility.RandomMinMax(0, 3));
}
}
}
private bool HasTarget(Mobile focus, IShipCannon cannon, bool shootatboat)
{
if (cannon == null || cannon.Deleted || cannon.Map == null || cannon.Map == Map.Internal || m_Galleon == null || m_Galleon.Deleted)
return false;
Direction d = cannon.GetFacing();
int xOffset = 0; int yOffset = 0;
int cannonrange = cannon.Range;
int currentRange = 0;
Point3D pnt = cannon.Location;
switch (d)
{
case Direction.North:
xOffset = 0; yOffset = -1; break;
case Direction.South:
xOffset = 0; yOffset = 1; break;
case Direction.West:
xOffset = -1; yOffset = 0; break;
case Direction.East:
xOffset = 1; yOffset = 0; break;
}
int xo = xOffset;
int yo = yOffset;
while (currentRange++ <= cannonrange)
{
xOffset = xo;
yOffset = yo;
for (int i = -1; i <= 1; i++)
{
Point3D newPoint;
if (xOffset == 0)
newPoint = new Point3D(pnt.X + (xOffset + i), pnt.Y + (yOffset * currentRange), pnt.Z);
else
newPoint = new Point3D(pnt.X + (xOffset * currentRange), pnt.Y + (yOffset + i), pnt.Z);
if (shootatboat)
{
BaseGalleon g = BaseGalleon.FindGalleonAt(newPoint, this.Map);
if (g != null && g == m_TargetBoat && g != Galleon)
return true;
}
else
{
if (focus == null)
return false;
if (newPoint.X == focus.X && newPoint.Y == focus.Y)
{
return true;
}
}
}
}
return false;
}
private bool IsInBattle()
{
if (Combatant != null)
return true;
foreach (Mobile mob in m_Crew)
{
if (mob.Alive && mob.Combatant != null)
return true;
}
return false;
}
[CommandProperty(AccessLevel.GameMaster)]
public string AddHoldItem
{
get { return null; }
set
{
string str = value;
Type type = ScriptCompiler.FindTypeByName(str);
if (type != null && (type == typeof(Item) || type.IsSubclassOf(typeof(Item))))
{
Item item = Loot.Construct(type);
if (item != null)
HoldItem = item;
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public Item HoldItem
{
get { return null; }
set
{
Item item = value;
if (item != null)
AddItemToHold(item);
}
}
public void AddItemToHold(Item item)
{
if (item == null)
return;
if (m_Galleon != null && m_Galleon.GalleonHold != null)
m_Galleon.GalleonHold.DropItem(item);
else
item.Delete();
}
public void CheckCrew()
{
if (m_Galleon == null || m_Crew == null || Map == null || Map == Map.Internal)
return;
List<Mobile> crew = new List<Mobile>(m_Crew.Where(m => m != null && m.Alive && m.Map != null && m.Map != Map.Internal));
if (m_Galleon.GalleonPilot != null)
crew.Add(m_Galleon.GalleonPilot);
crew.Add(this);
foreach (var crewman in crew)
{
if(!m_Galleon.Contains(crewman))
{
crewman.MoveToWorld(new Point3D(m_Galleon.X + Utility.RandomList(-1, 1), m_Galleon.Y + Utility.RandomList(-1, 0, 1), m_Galleon.ZSurface), this.Map);
}
}
ColUtility.Free(crew);
m_NextCrewCheck = DateTime.UtcNow + TimeSpan.FromMinutes(30);
}
public void CheckBlock(StaticTile tile, Point3D p)
{
BaseBoat check = BaseBoat.FindBoatAt(p, Map);
if (check != null)
CheckBlock(check, p);
}
public void CheckBlock(IEntity e, Point3D loc)
{
if (m_Galleon == null || !m_OnCourse || IsInBattle())
{
return;
}
if (loc == Point3D.Zero)
{
loc = e.Location;
}
BaseBoat check = BaseBoat.FindBoatAt(new Point3D(e), Map);
if ((check != null && check != m_Galleon) || e is BaseCreature)
{
Direction d = Utility.GetDirection(m_Galleon, e);
int blockX = e.X;
int blockY = e.Y;
int x = m_Galleon.X;
int y = m_Galleon.Y;
Direction toMove = Direction.North;
switch (m_Galleon.Facing)
{
case Direction.North:
toMove = blockX > x ? Direction.West : Direction.East;
break;
case Direction.East:
toMove = blockY > y ? Direction.North : Direction.South;
break;
case Direction.South:
toMove = blockX < x ? Direction.East : Direction.West;
break;
case Direction.West:
toMove = blockY < y ? Direction.South : Direction.North;
break;
}
Movement.Movement.Offset(toMove, ref x, ref y);
int speed;
toMove = m_Galleon.GetMovementFor(x, y, out speed);
Timer.DelayCall(TimeSpan.FromSeconds(1), () =>
{
m_Galleon.StartMove(toMove, false);
});
ResumeCourseTimed(TimeSpan.FromSeconds(11), true);
}
}
public BaseShipCaptain(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
writer.Write(m_Blockade);
writer.Write((int)m_Zone);
writer.Write(m_StopTime);
writer.Write(m_Galleon);
writer.Write(m_OnCourse);
writer.Write(m_Crew.Count);
foreach (Mobile mob in m_Crew)
writer.Write(mob);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Blockade = reader.ReadBool();
m_Zone = (SpawnZone)reader.ReadInt();
m_StopTime = reader.ReadDateTime();
m_Galleon = reader.ReadItem() as BaseGalleon;
m_OnCourse = reader.ReadBool();
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Mobile mob = reader.ReadMobile() as Mobile;
if (mob != null && !mob.Deleted && mob.Alive)
m_Crew.Add(mob);
}
if (!m_Blockade)
ResumeCourseTimed(TimeSpan.FromSeconds(15), true);
if (m_Galleon != null)
{
Timer.DelayCall(TimeSpan.FromSeconds(30), CheckCrew);
}
m_NextMoveCheck = DateTime.UtcNow;
m_NextCannonShot = DateTime.UtcNow;
}
}
}

View File

@@ -0,0 +1,89 @@
using Server;
using System;
using Server.Engines.Quests;
using Server.Multis;
using Server.Items;
using System.Collections.Generic;
namespace Server.Mobiles
{
public class GBBigglesby : BaseVendor
{
public override bool IsActiveVendor { get { return false; } }
protected override List<SBInfo> SBInfos { get { return new List<SBInfo>(); } }
public override void InitSBInfo()
{
}
[Constructable]
public GBBigglesby()
: base("the proprietor")
{
Name = "G.B. Bigglesby";
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = false;
Race = Race.Human;
Hue = Race.RandomSkinHue();
Race.RandomHair(this);
HairHue = Race.RandomHairHue();
Item fancyShirt = new FancyShirt();
Item shirt = new Shirt(PirateCaptain.GetRandomShirtHue());
shirt.Layer = Layer.OuterTorso;
AddItem(new Cloak(5));
AddItem(new Cutlass());
AddItem(shirt);
AddItem(fancyShirt);
AddItem(new LongPants());
AddItem(new Boots());
m_NextSay = DateTime.UtcNow;
}
private int m_LastSay;
private DateTime m_NextSay;
public override void OnDoubleClick(Mobile m)
{
if (m_NextSay < DateTime.UtcNow)
{
if (m_LastSay == 0)
{
Say(1152651); //I'm G.B. Bigglesby, proprietor of the G.B. Bigglesby Free Trade Floating Emporium.
m_LastSay = 1;
}
else
{
Say(1152652); //This sea market be me life's work and 'tis me pride and joy..
m_LastSay = 0;
}
m_NextSay = DateTime.UtcNow + TimeSpan.FromSeconds(5);
}
}
public GBBigglesby(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();
m_NextSay = DateTime.UtcNow;
}
}
}

View File

@@ -0,0 +1,68 @@
using Server;
using System;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.Quests;
namespace Server.Mobiles
{
public class MerchantCaptain : BaseShipCaptain
{
public override bool Aggressive { get { return false; } }
public override bool InitialInnocent { get { return true; } }
[Constructable]
public MerchantCaptain(BaseGalleon galleon)
: base(galleon, AIType.AI_Melee, FightMode.Aggressor, 1, 10, .2, .4)
{
Title = "the merchant captain";
Hue = Race.RandomSkinHue();
Item hat;
if (Utility.RandomBool())
hat = new WideBrimHat();
else
hat = new TricorneHat();
hat.Hue = Utility.RandomNeutralHue();
AddItem(new Sandals());
AddItem(new FancyShirt(Utility.RandomNeutralHue()));
AddItem(hat);
AddItem(new Cloak(Utility.RandomNeutralHue()));
AddItem(new Dagger());
Utility.AssignRandomHair(this);
Fame = 22000;
Karma = -22000;
if (IsSoulboundEnemies)
IsSoulbound = true;
}
public override void GenerateLoot()
{
AddLoot(LootPack.SuperBoss, 2);
}
public MerchantCaptain(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,128 @@
using Server;
using System;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.Quests;
namespace Server.Mobiles
{
public class MerchantCrew : BaseCreature
{
public override bool InitialInnocent { get { return true; } }
public override WeaponAbility GetWeaponAbility()
{
Item weapon = FindItemOnLayer(Layer.TwoHanded);
if (weapon == null)
return null;
if (weapon is BaseWeapon)
{
if (Utility.RandomBool())
return ((BaseWeapon)weapon).PrimaryAbility;
else
return ((BaseWeapon)weapon).SecondaryAbility;
}
return null;
}
[Constructable]
public MerchantCrew()
: base(AIType.AI_Paladin, FightMode.Aggressor, 10, 1, .2, .4)
{
Title = "the merchant";
Hue = Race.RandomSkinHue();
if (this.Female = Utility.RandomBool())
{
Body = 0x191;
Name = NameList.RandomName("female");
AddItem(new Skirt(Utility.RandomNeutralHue()));
}
else
{
Body = 0x190;
Name = NameList.RandomName("male");
AddItem(new ShortPants(Utility.RandomNeutralHue()));
}
bool magery = 0.33 > Utility.RandomDouble();
SetStr(100, 125);
SetDex(125, 150);
SetInt(250, 400);
SetHits(250, 400);
SetDamage(15, 25);
if (magery)
{
ChangeAIType(AIType.AI_Mage);
SetSkill(SkillName.Magery, 100.0, 120.0);
SetSkill(SkillName.EvalInt, 100.0, 120.0);
SetSkill(SkillName.Meditation, 100.0, 120.0);
SetSkill(SkillName.MagicResist, 100.0, 120.0);
}
SetSkill(SkillName.Archery, 100.0, 120.0);
SetSkill(SkillName.Chivalry, 100.0, 120.0);
SetSkill(SkillName.Focus, 100.0, 120.0);
SetSkill(SkillName.Tactics, 100.0, 120.0);
SetSkill(SkillName.Wrestling, 100.0, 120.0);
SetSkill(SkillName.Anatomy, 100.0, 120.0);
SetDamageType(ResistanceType.Physical, 70);
SetResistance(ResistanceType.Physical, 45, 55);
SetResistance(ResistanceType.Fire, 45, 55);
SetResistance(ResistanceType.Cold, 45, 55);
SetResistance(ResistanceType.Poison, 45, 55);
SetResistance(ResistanceType.Energy, 45, 55);
Item bow;
switch (Utility.Random(4))
{
default:
case 0: bow = new CompositeBow(); PackItem(new Arrow(25)); break;
case 1: bow = new Crossbow(); PackItem(new Bolt(25)); break;
case 2: bow = new Bow(); PackItem(new Arrow(25)); break;
case 3: bow = new HeavyCrossbow(); PackItem(new Bolt(25)); break;
}
AddItem(bow);
AddItem(new TricorneHat());
AddItem(new FancyShirt());
AddItem(new Boots(Utility.RandomNeutralHue()));
AddItem(new GoldEarrings());
Fame = 8000;
Karma = 8000;
if (IsSoulboundEnemies)
IsSoulbound = true;
}
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public MerchantCrew(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,332 @@
using Server;
using System;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.Quests;
namespace Server.Mobiles
{
public class PirateCaptain : BaseShipCaptain
{
public static List<string> m_RedNames;
public static void Initialize()
{
m_RedNames = new List<string>();
foreach (Mobile mob in World.Mobiles.Values)
{
if (mob != null && mob is PlayerMobile && mob.Murderer)
m_RedNames.Add(mob.Name);
}
}
private DateTime m_NextTalk;
private int m_PirateName;
private int m_Adjective;
private int m_Noun;
public int PirateName { get { return m_PirateName; } }
public int Adjective { get { return m_Adjective; } }
public int Noun { get { return m_Noun; } }
public override bool AlwaysMurderer { get { return true; } }
public override bool Commandable { get { return false; } }
#region Bounty Quest
private ProfessionalBountyQuest m_Quest;
private bool m_IsCaught;
[CommandProperty(AccessLevel.GameMaster)]
public bool IsCaught { get { return m_IsCaught; } set { m_IsCaught = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public ProfessionalBountyQuest Quest { get { return m_Quest; } set { m_Quest = value; } }
#endregion
[Constructable]
public PirateCaptain()
: this(null)
{
}
public PirateCaptain(BaseGalleon galleon)
: base(galleon, AIType.AI_Melee, FightMode.Weakest, 25, 1, .2, .4)
{
PickRandomName();
if(m_PirateName > 0 && (m_PirateName == 1116679 || m_PirateName == 1116680 || m_PirateName == 1116683))
Female = true;
SpeechHue = Utility.RandomDyedHue();
Title = "the dread pirate";
Hue = Race.RandomSkinHue();
Body = Female ? 0x191 : 0x190;
SetStr(500, 750);
SetDex(125, 175);
SetInt(61, 75);
SetHits(4500, 5000);
SetDamage(23, 35);
SetSkill(SkillName.Fencing, 115.0, 120.0);
SetSkill(SkillName.Macing, 115.0, 120.0);
SetSkill(SkillName.MagicResist, 115.0, 120.0);
SetSkill(SkillName.Swords, 115.0, 120.0);
SetSkill(SkillName.Tactics, 115.0, 120.0);
SetSkill(SkillName.Wrestling, 115.0, 120.0);
SetSkill(SkillName.Anatomy, 115.0, 120.0);
Item hat;
Item fancyShirt = new FancyShirt();
Item shirt = new Shirt(GetRandomShirtHue());
shirt.Layer = Layer.OuterTorso;
if (Utility.RandomBool())
hat = new Bandana();
else
hat = new TricorneHat();
hat.Hue = Utility.RandomNeutralHue();
AddItem(new Boots());
AddItem(shirt);
AddItem(fancyShirt);
AddItem(hat);
AddItem(new Cloak(Utility.RandomNeutralHue()));
switch (Utility.Random(7))
{
case 0: AddItem(new Longsword()); break;
case 1: AddItem(new Cutlass()); break;
case 2: AddItem(new Broadsword()); break;
case 5: AddItem(new Dagger()); break;
}
Utility.AssignRandomHair(this);
Fame = 22000;
Karma = -22000;
if (IsSoulboundEnemies)
IsSoulbound = true;
}
public static int GetRandomShirtHue()
{
return Utility.RandomMinMax(2498, 2644);
}
public override void GenerateLoot()
{
AddLoot(LootPack.SuperBoss, 2);
}
public void PickRandomName()
{
m_Adjective = Utility.RandomMinMax(1116631, 1116650);
m_Noun = Utility.RandomMinMax(1116651, 1116670);
if (m_RedNames.Count == 0 || 0.90 > Utility.RandomDouble())
m_PirateName = Utility.RandomMinMax(1116671, 1116686);
else
{
m_PirateName = -1;
Name = GetRandomRedName();
}
}
public string GetRandomRedName()
{
return m_RedNames[Utility.Random(m_RedNames.Count)];
}
public override void AddNameProperties(ObjectPropertyList list)
{
string args;
if(m_PirateName > 0)
args = String.Format("#{0}\t#{1}\t#{2}", m_Adjective, m_Noun, m_PirateName);
else
args = String.Format("#{0}\t#{1}\t{2}", m_Adjective, m_Noun, Name);
list.Add(1116690, args);
}
public override void OnThink()
{
base.OnThink();
if (!IsCaught || m_NextTalk > DateTime.UtcNow)
return;
IPooledEnumerable eable = this.GetMobilesInRange(7);
foreach(Mobile mob in eable)
{
if (mob is PlayerMobile)
{
OnTalk();
break;
}
}
eable.Free();
}
public void OnTalk()
{
Say(Utility.RandomMinMax(1149701, 1149720));
m_NextTalk = DateTime.UtcNow + TimeSpan.FromMinutes(1);
}
#region Quest Stuff
public bool TryBound(Mobile from, BaseQuest quest)
{
if (from == null || Galleon == null || !Galleon.Contains(this) || quest == null)
return false;
if (m_IsCaught)
{
from.SendMessage("That pirate is already bound to a ship!");
return false;
}
Combatant = null;
Warmode = false;
m_IsCaught = true;
return true;
}
public void OnBound(ProfessionalBountyQuest quest)
{
if (quest == null || quest.Pole == null)
return;
BindingPole pole = quest.Pole;
int x = pole.X;
int y = pole.Y;
while (x == pole.X && y == pole.Y)
{
x = Utility.RandomMinMax(pole.X - 1, pole.X + 1);
y = Utility.RandomMinMax(pole.Y - 1, pole.Y + 1);
}
Frozen = true;
Item toDisarm = FindItemOnLayer(Layer.OneHanded);
if (toDisarm == null || !toDisarm.Movable)
toDisarm = FindItemOnLayer(Layer.TwoHanded);
if (toDisarm != null)
{
if (Backpack != null)
Backpack.DropItem(toDisarm);
else
toDisarm.Delete();
}
m_Quest = quest;
if (quest != null && quest.Galleon != null)
quest.Galleon.CapturedCaptain = this;
Timer.DelayCall(TimeSpan.FromSeconds(2.5), new TimerStateCallback(MoveCaptainToShip), new object[] { x, y, pole });
}
private void MoveCaptainToShip(object obj)
{
object[] objs = (object[])obj;
int x = (int)objs[0];
int y = (int)objs[1];
Item pole = objs[2] as Item;
if (pole != null)
MoveToWorld(new Point3D(x, y, pole.Z), pole.Map);
Blessed = true;
Title = "[Captured Captain]";
}
public override bool OnBeforeDeath()
{
List<PlayerMobile> hasQuest = new List<PlayerMobile>();
List<DamageStore> rights = GetLootingRights();
for (int i = 0; i < rights.Count; i++)
{
if (!rights[i].m_HasRight)
continue;
Mobile mob = rights[i].m_Mobile;
//if they have the quest and looting rights, give them a certificate
if (mob is PlayerMobile && mob.NetState != null && QuestHelper.GetQuest((PlayerMobile)mob, typeof(ProfessionalBountyQuest)) != null)
hasQuest.Add((PlayerMobile)mob);
}
if (hasQuest.Count > 0)
{
PlayerMobile questee = hasQuest[Utility.Random(hasQuest.Count)];
BaseQuest q = QuestHelper.GetQuest(questee, typeof(ProfessionalBountyQuest));
if (q != null && q is ProfessionalBountyQuest)
{
((ProfessionalBountyQuest)q).OnPirateDeath(this);
questee.AddToBackpack(new DeathCertificate(this));
}
}
if (m_IsCaught && m_Quest != null)
{
for (int i = 0; i < m_Quest.Objectives.Count; i++)
{
if (m_Quest.Objectives[i] is BountyQuestObjective && ((BountyQuestObjective)m_Quest.Objectives[i]).CapturedCaptain == this)
{
((BountyQuestObjective)m_Quest.Objectives[i]).CapturedCaptain = null;
((BountyQuestObjective)m_Quest.Objectives[i]).Captured = false;
m_Quest = null;
}
}
}
return base.OnBeforeDeath();
}
#endregion
public PirateCaptain(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)1);
writer.Write(m_IsCaught);
writer.Write(m_Adjective);
writer.Write(m_Noun);
writer.Write(m_PirateName);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_IsCaught = reader.ReadBool();
m_Adjective = reader.ReadInt();
m_Noun = reader.ReadInt();
m_PirateName = reader.ReadInt();
if (IsCaught)
Frozen = true;
m_NextTalk = DateTime.UtcNow;
}
}
}

View File

@@ -0,0 +1,210 @@
using Server;
using System;
using Server.Items;
using Server.Misc;
namespace Server.Mobiles
{
[CorpseName("a glowing orc corpse")]
public class PirateCrew : BaseCreature
{
public override WeaponAbility GetWeaponAbility()
{
Item weapon = FindItemOnLayer(Layer.TwoHanded);
if (weapon == null)
return null;
if (weapon is BaseWeapon)
{
if (Utility.RandomBool())
return ((BaseWeapon)weapon).PrimaryAbility;
else
return ((BaseWeapon)weapon).SecondaryAbility;
}
return null;
}
public override InhumanSpeech SpeechType { get { return InhumanSpeech.Orc; } }
private DateTime m_NextBomb;
private int m_Thrown;
[Constructable]
public PirateCrew() : base(AIType.AI_Melee, FightMode.Closest, 10, 1, .2, .4)
{
Name = "Orcish Crew";
Body = 0.33 > Utility.RandomDouble() ? 0x8C : Utility.RandomList(0xB5, 0xB6);
SetHits(2000);
if (Body == 0x8C) // Mage
{
SetStr(140, 160);
SetDex(130, 150);
SetInt(170, 190);
SetDamage(4, 14);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 30, 40);
SetResistance(ResistanceType.Fire, 30, 40);
SetResistance(ResistanceType.Cold, 20, 30);
SetResistance(ResistanceType.Poison, 30, 40);
SetResistance(ResistanceType.Energy, 30, 40);
ChangeAIType(AIType.AI_Mage);
SetSkill(SkillName.Wrestling, 45.0, 55.0);
SetSkill(SkillName.Tactics, 50.0, 60.0);
SetSkill(SkillName.MagicResist, 65.0, 75.0);
SetSkill(SkillName.Magery, 60.0, 70.0);
SetSkill(SkillName.EvalInt, 60.0, 75.0);
SetSkill(SkillName.Meditation, 70.0, 90.0);
SetSkill(SkillName.Focus, 80.0, 100.0);
}
else if (Body == 0xB6) // Bomber
{
SetStr(150, 200);
SetDex(90, 110);
SetInt(70, 100);
SetDamage(1, 8);
SetDamageType(ResistanceType.Physical, 75);
SetDamageType(ResistanceType.Fire, 25);
SetResistance(ResistanceType.Physical, 20, 30);
SetResistance(ResistanceType.Fire, 30, 40);
SetResistance(ResistanceType.Cold, 15, 25);
SetResistance(ResistanceType.Poison, 15, 25);
SetResistance(ResistanceType.Energy, 20, 30);
SetSkill(SkillName.Wrestling, 60.0, 90.0);
SetSkill(SkillName.Tactics, 70.0, 85.0);
SetSkill(SkillName.MagicResist, 70.0, 85.0);
}
else // Archer
{
SetStr(100, 130);
SetDex(100, 130);
SetInt(30, 70);
SetDamage(5, 7);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 20, 35);
SetResistance(ResistanceType.Fire, 30, 40);
SetResistance(ResistanceType.Cold, 15, 25);
SetResistance(ResistanceType.Poison, 15, 25);
SetResistance(ResistanceType.Energy, 20, 30);
ChangeAIType(AIType.AI_Archer);
SetSkill(SkillName.Tactics, 55.0, 70.0);
SetSkill(SkillName.MagicResist, 50.0, 70.0);
SetSkill(SkillName.Anatomy, 60.0, 85.0);
SetSkill(SkillName.Healing, 60.0, 80.0);
SetSkill(SkillName.Archery, 100.0, 120.0);
Item bow;
switch (Utility.Random(4))
{
default:
case 0: bow = new CompositeBow(); PackItem(new Arrow(25)); break;
case 1: bow = new Crossbow(); PackItem(new Bolt(25)); break;
case 2: bow = new Bow(); PackItem(new Arrow(25)); break;
case 3: bow = new HeavyCrossbow(); PackItem(new Bolt(25)); break;
}
AddItem(bow);
}
SetSkill(SkillName.DetectHidden, 40.0, 45.0);
Fame = 8000;
Karma = -8000;
if (IsSoulboundEnemies)
IsSoulbound = true;
}
public override void OnActionCombat()
{
if (Body == 0xB6)
{
Mobile combatant = Combatant as Mobile;
if (combatant == null || combatant.Deleted || combatant.Map != Map || !InRange(combatant, 12) || !CanBeHarmful(combatant) || !InLOS(combatant))
return;
if (DateTime.Now >= m_NextBomb)
{
ThrowBomb(combatant);
m_Thrown++;
if (0.75 >= Utility.RandomDouble() && (m_Thrown % 2) == 1) // 75% chance to quickly throw another bomb
m_NextBomb = DateTime.Now + TimeSpan.FromSeconds(3.0);
else
m_NextBomb = DateTime.Now + TimeSpan.FromSeconds(5.0 + (10.0 * Utility.RandomDouble())); // 5-15 seconds
}
}
}
public void ThrowBomb(Mobile m)
{
DoHarmful(m);
MovingParticles(m, 0x1C19, 1, 0, false, true, 0, 0, 9502, 6014, 0x11D, EffectLayer.Waist, 0);
new InternalTimer(m, this).Start();
}
private class InternalTimer : Timer
{
private readonly Mobile m_Mobile;
private readonly Mobile m_From;
public InternalTimer(Mobile m, Mobile from)
: base(TimeSpan.FromSeconds(1.0))
{
m_Mobile = m;
m_From = from;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
m_Mobile.PlaySound(0x11D);
AOS.Damage(m_Mobile, m_From, Utility.RandomMinMax(10, 20), 0, 100, 0, 0, 0);
}
}
public override int TreasureMapLevel { get { return 3; } }
public override void GenerateLoot()
{
AddLoot(LootPack.UltraRich, 2);
}
public PirateCrew(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,155 @@
using Server;
using System;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.Quests;
namespace Server.Mobiles
{
public class SeaMarketOfficer : MondainQuester
{
public override Type[] Quests { get { return new Type[] { typeof(ProfessionalBountyQuest) }; } }
public SeaMarketOfficer()
{
Title = "the officer";
Name = NameList.RandomName("male");
CantWalk = true;
}
public override void InitBody()
{
InitStats(100, 100, 25);
Female = false;
Race = Race.Human;
Hue = Race.RandomSkinHue();
Race.RandomHair(this);
HairHue = Race.RandomHairHue();
SetWearable(new ChainChest(), 1346);
SetWearable(new LeatherGloves(), 1346);
SetWearable(new Necklace(), 1153);
SetWearable(new Bandana());
SetWearable(new Scimitar());
SetWearable(new ThighBoots());
}
public override void OnTalk(PlayerMobile pm)
{
if (!HasQuest(pm))
{
BaseBoat boat = FishQuestHelper.GetBoat(pm);
if (boat != null && boat is BaseGalleon)
{
if (((BaseGalleon)boat).Scuttled)
{
pm.SendLocalizedMessage(1116752); //Your ship is a mess! Fix it first and then we can talk about catching pirates.
}
else
{
ProfessionalBountyQuest q = new ProfessionalBountyQuest((BaseGalleon)boat);
q.Owner = pm;
q.Quester = this;
pm.CloseGump(typeof(MondainQuestGump));
pm.SendGump(new MondainQuestGump(q));
}
}
else
{
SayTo(pm, 1116751); //The ship you are captaining could not take on a pirate ship. Bring a warship if you want this quest.
OnOfferFailed();
}
}
}
public override void Advertise()
{
}
public bool HasQuest(PlayerMobile pm)
{
if (pm.Quests == null)
return false;
for (int i = 0; i < pm.Quests.Count; i++)
{
BaseQuest quest = pm.Quests[i];
if (quest is ProfessionalBountyQuest)
{
if (this == quest.Quester)
{
for (int j = 0; j < quest.Objectives.Count; j++)
{
if (quest.Objectives[j].Update(pm))
quest.Objectives[j].Complete();
}
}
if (quest.Completed)
{
quest.OnCompleted();
pm.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.Complete, false, true));
}
else
{
pm.SendGump(new MondainQuestGump(quest, MondainQuestGump.Section.InProgress, false));
quest.InProgress();
}
return true;
}
}
return false;
}
public SeaMarketOfficer(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();
if (Map == Map.Trammel)
{
TramInstance = this;
}
else if (Map == Map.Felucca)
{
FelInstance = this;
}
}
public static SeaMarketOfficer TramInstance { get; set; }
public static SeaMarketOfficer FelInstance { get; set; }
public static void Initialize()
{
if (Core.HS)
{
if (TramInstance == null)
{
TramInstance = new SeaMarketOfficer();
TramInstance.MoveToWorld(new Point3D(4543, 2299, -1), Map.Trammel);
}
if (FelInstance == null)
{
FelInstance = new SeaMarketOfficer();
FelInstance.MoveToWorld(new Point3D(4543, 2299, -1), Map.Felucca);
}
}
}
}
}

View File

@@ -0,0 +1,382 @@
using Server;
using System;
using Server.Mobiles;
using Server.Items;
using Server.Multis;
using System.Collections.Generic;
using Server.Engines.PartySystem;
using Server.Gumps;
namespace Server.Engines.Quests
{
public class ProfessionalBountyQuest : BaseQuest
{
public override object Title { get { return 1116708; } }
public override object Description { get { return 1116709; } }
public override object Refuse { get { return 1116713; } }
public override object Uncomplete { get { return 1116714; } }
public override object Complete { get { return 1116715; } }
private BaseGalleon m_Galleon;
private BindingPole m_Pole;
private BindingRope m_Rope;
private Mobile m_Captain;
private List<Mobile> m_Helpers = new List<Mobile>();
public BaseGalleon Galleon { get { return m_Galleon; } }
public BindingPole Pole { get { return m_Pole; } }
public BindingRope Rope { get { return m_Rope; } }
public Mobile Captain { get { return m_Captain; } set { m_Captain = value; } }
public ProfessionalBountyQuest()
{
AddObjective(new BountyQuestObjective());
}
public ProfessionalBountyQuest(BaseGalleon galleon)
{
m_Galleon = galleon;
AddObjective(new BountyQuestObjective());
AddReward(new BaseReward(1116712)); //The gold listed on the bulletin board and a special reward from the officer if captured alive.
}
public override void OnAccept()
{
base.OnAccept();
AddPole();
if(Owner != null)
{
m_Rope = new BindingRope(this);
Owner.AddToBackpack(m_Rope);
}
}
public void OnBound(BaseCreature captain)
{
if (Owner != null)
{
m_Captain = captain;
CompileHelpersList(captain);
foreach (BaseObjective obj in Objectives)
{
if (obj is BountyQuestObjective)
{
((BountyQuestObjective)obj).Captured = true;
((BountyQuestObjective)obj).CapturedCaptain = captain;
}
}
}
}
public void OnPirateDeath(BaseCreature captain)
{
m_Captain = captain;
CompileHelpersList(captain);
foreach (BaseObjective obj in Objectives)
{
if (obj is BountyQuestObjective)
{
((BountyQuestObjective)obj).Captured = false;
((BountyQuestObjective)obj).CapturedCaptain = null;
}
}
}
private void CompileHelpersList(BaseCreature pirate)
{
if (Owner == null)
return;
Party p = Party.Get(Owner);
List<DamageStore> rights = pirate.GetLootingRights();
IPooledEnumerable eable = pirate.GetMobilesInRange(19);
foreach (Mobile mob in eable)
{
if (mob == Owner || !(mob is PlayerMobile))
continue;
Party mobParty = Party.Get(mob);
//Add party memebers regardless of looting rights
if (p != null && mobParty != null && p == mobParty)
{
m_Helpers.Add(mob);
continue;
}
// add those with looting rights
for (int i = rights.Count - 1; i >= 0; --i)
{
DamageStore ds = rights[i];
if (ds.m_HasRight && ds.m_Mobile == mob)
{
m_Helpers.Add(ds.m_Mobile);
break;
}
}
}
eable.Free();
}
public void AddPole()
{
if(m_Galleon == null)
return;
int dist = m_Galleon.CaptiveOffset;
int xOffset = 0;
int yOffset = 0;
m_Pole = new BindingPole(this);
switch (m_Galleon.Facing)
{
case Direction.North:
xOffset = 0;
yOffset = dist * -1;
break;
case Direction.South:
xOffset = 0;
yOffset = dist * 1;
break;
case Direction.East:
yOffset = 0;
xOffset = dist * 1;
break;
case Direction.West:
xOffset = dist * -1;
yOffset = 0;
break;
}
m_Pole.MoveToWorld(new Point3D(m_Galleon.X + xOffset, m_Galleon.Y + yOffset, m_Galleon.ZSurface), m_Galleon.Map);
m_Galleon.AddFixture(m_Pole);
}
public override void GiveRewards()
{
bool captured = false;
foreach(BaseObjective obj in Objectives)
{
if(obj is BountyQuestObjective && ((BountyQuestObjective)obj).Captured)
{
BountyQuestObjective o = (BountyQuestObjective)obj;
captured = true;
if (o.CapturedCaptain != null && o.CapturedCaptain is PirateCaptain)
{
PirateCaptain p = o.CapturedCaptain as PirateCaptain;
p.Quest = null;
}
o.CapturedCaptain = null;
o.Captured = false;
break;
}
}
if (Owner == null)
return;
m_Helpers.Add(Owner);
int totalAward = 7523;
if(m_Captain != null && BountyQuestSpawner.Bounties.ContainsKey(m_Captain))
totalAward = BountyQuestSpawner.Bounties[m_Captain];
int eachAward = totalAward;
if(m_Helpers.Count > 1)
eachAward = totalAward / m_Helpers.Count;
foreach(Mobile mob in m_Helpers)
{
if(mob.NetState != null || mob == Owner)
{
mob.AddToBackpack(new Gold(eachAward));
if (captured)
{
Item reward = Loot.Construct(m_CapturedRewards[Utility.Random(m_CapturedRewards.Length)]);
if (reward != null)
{
if (reward is RuinedShipPlans)
mob.SendLocalizedMessage(1149838); //Here is something special! It's a salvaged set of orc ship plans. Parts of it are unreadable, but if you could get another copy you might be able to fill in some of the missing parts...
else
mob.SendLocalizedMessage(1149840); //Here is some special cannon ammunition. It's imported!
if (reward is HeavyFlameCannonball || reward is LightFlameCannonball || reward is HeavyFrostCannonball || reward is LightFrostCannonball)
reward.Amount = Utility.RandomMinMax(5, 10);
mob.AddToBackpack(reward);
}
}
mob.SendLocalizedMessage(1149825, String.Format("{0}\t{1}", totalAward, eachAward)); //Here's your share of the ~1_val~ reward money, you get ~2_val~ gold. You've earned it!
}
else
{
foreach (Mobile mobile in m_Helpers)
{
if (mobile != mob && mobile.NetState != null)
mobile.SendLocalizedMessage(1149837, String.Format("{0}\t{1}\t{2}", eachAward, mob.Name, Owner.Name)); //~1_val~ gold is for ~2_val~, I can't find them so I'm giving this to Captain ~3_val~.
}
Owner.AddToBackpack(new Gold(eachAward));
}
}
if(m_Captain != null && m_Captain.Alive)
m_Captain.Delete();
base.GiveRewards();
}
public override void RemoveQuest( bool removeChain )
{
base.RemoveQuest(removeChain);
if (m_Rope != null && !m_Rope.Deleted)
{
m_Rope.Quest = null;
m_Rope.Delete();
}
if (m_Pole != null && !m_Pole.Deleted)
{
m_Pole.Quest = null;
m_Pole.Delete();
}
if (m_Galleon != null)
m_Galleon.CapturedCaptain = null;
}
public override bool RenderObjective(MondainQuestGump g, bool offer)
{
if (offer)
g.AddHtmlLocalized(130, 45, 270, 16, 1049010, 0xFFFFFF, false, false); // Quest Offer
else
g.AddHtmlLocalized(130, 45, 270, 16, 1046026, 0xFFFFFF, false, false); // Quest Log
g.AddButton(130, 430, 0x2EEF, 0x2EF1, (int)Buttons.PreviousPage, GumpButtonType.Reply, 0);
g.AddButton(275, 430, 0x2EE9, 0x2EEB, (int)Buttons.NextPage, GumpButtonType.Reply, 0);
g.AddHtmlObject(160, 70, 330, 16, Title, BaseQuestGump.DarkGreen, false, false);
g.AddHtmlLocalized(98, 140, 312, 16, 1049073, 0x2710, false, false); // Objective:
g.AddHtmlLocalized(98, 156, 312, 16, 1072208, 0x2710, false, false); // All of the following
int offset = 172;
g.AddHtmlLocalized(98, offset, 312, 16, 1116710, 0x2710, false, false); // Capture or kill a pirate listed on the bulletin board.
offset += 16;
g.AddHtmlLocalized(98, offset, 312, 32, 1116711, 0x15F90, false, false); //Return to the officer with the pirate or a death certificate for your reward.
offset += 32;
g.AddHtmlLocalized(98, offset, 312, 32, 1116712, 0x15F90, false, false); //The gold listed on the bulletin board and a special reward from the officer if captured alive.
return true;
}
private Type[] m_CapturedRewards = new Type[]
{
typeof(RuinedShipPlans), typeof(RuinedShipPlans),
typeof(LightFlameCannonball), typeof(HeavyFlameCannonball),
typeof(LightFrostCannonball), typeof(HeavyFrostCannonball),
typeof(LightFlameCannonball), typeof(HeavyFlameCannonball),
typeof(LightFrostCannonball), typeof(HeavyFrostCannonball),
/*typeof(HeavyScatterShot), typeof(LightScatterShot),
typeof(HeavyHotShot), typeof(LightHotShot),
typeof(HeavyFragShot), typeof(LightFragShot)*/
};
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.WriteEncodedInt( (int) 0 ); // version
writer.Write(m_Pole);
writer.Write(m_Rope);
writer.Write(m_Captain);
writer.Write(m_Galleon);
writer.Write(m_Helpers.Count);
foreach (Mobile mob in m_Helpers)
writer.Write(mob);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
m_Pole = reader.ReadItem() as BindingPole;
m_Rope = reader.ReadItem() as BindingRope;
m_Captain = reader.ReadMobile();
m_Galleon = reader.ReadItem() as BaseGalleon;
int count = reader.ReadInt();
for (int i = 0; i < count; i++)
{
Mobile mob = reader.ReadMobile();
if (mob != null)
m_Helpers.Add(mob);
}
if(m_Rope != null)
m_Rope.Quest = this;
if (m_Pole != null)
m_Pole.Quest = this;
else
AddPole();
AddReward(new BaseReward(1116712)); //The gold listed on the bulletin board and a special reward from the officer if captured alive.
}
public bool HasQuest(PlayerMobile pm)
{
if (pm.Quests == null)
return false;
for(int i = 0; i < pm.Quests.Count; i++)
{
BaseQuest quest = pm.Quests[i];
if(quest.Quester == this)
{
for(int j = 0; j < quest.Objectives.Count; j++)
{
if(quest.Objectives[j].Update(pm))
quest.Objectives[j].Complete();
}
if(quest.Completed)
{
quest.OnCompleted();
pm.SendGump( new MondainQuestGump( quest, MondainQuestGump.Section.Complete, false, true ) );
}
else
{
pm.SendGump( new MondainQuestGump( quest, MondainQuestGump.Section.InProgress, false ) );
quest.InProgress();
}
return true;
}
}
return false;
}
}
}