Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 I’m",
|
||||
"going ta hang up me",
|
||||
"fishin’ pole and start",
|
||||
"me own brewery, and I’m",
|
||||
"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 ain’t",
|
||||
"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 couldn’t 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 cap’n snook",
|
||||
"should be keel hauled!",
|
||||
"I knew Cap’n Snook,",
|
||||
"this be no Cap’n 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’ wind’s in",
|
||||
"yar hair, the salt’s",
|
||||
"on yar lips and yar",
|
||||
"hook’s 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 Beamy’s 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 I’s",
|
||||
"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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user