fix: Adds safety to corpses and cleans up quests (#1685)

### Summary
- Adds some more checks in case a corpse's owner is somehow null. Would like to eventually allow null owner corpses, but more work is needed.
- Cleans up variable unboxing and reassignment in quests. Also flattens quest logic. Still more work needs to be done.
- Codegens more quest items/mobiles.
This commit is contained in:
Kamron Batman 2024-02-18 19:33:08 -08:00 committed by GitHub
parent 0d5aa1d022
commit e994505ad0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
90 changed files with 2623 additions and 3168 deletions

View file

@ -136,7 +136,7 @@ namespace Server.Engines.Harvest
if (qs is CollectorQuest)
{
QuestObjective obj = qs.FindObjective<FishPearlsObjective>();
var obj = qs.FindObjective<FishPearlsObjective>();
if (obj?.Completed == false)
{

View file

@ -41,7 +41,7 @@ public abstract partial class BaseAmbitiousSolenQueen : BaseQuester
}
else
{
QuestObjective obj = qs.FindObjective<ReturnAfterKillsObjective>();
var obj = qs.FindObjective<ReturnAfterKillsObjective>();
if (obj?.Completed == false)
{
@ -88,7 +88,7 @@ public abstract partial class BaseAmbitiousSolenQueen : BaseQuester
}
else
{
QuestSystem newQuest = new AmbitiousQueenQuest(player, RedSolen);
var newQuest = new AmbitiousQueenQuest(player, RedSolen);
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(AmbitiousQueenQuest)))
{
@ -110,7 +110,7 @@ public abstract partial class BaseAmbitiousSolenQueen : BaseQuester
return base.OnDragDrop(from, dropped);
}
QuestObjective obj = qs.FindObjective<GatherFungiObjective>();
var obj = qs.FindObjective<GatherFungiObjective>();
if (obj?.Completed != false || dropped is not ZoogiFungus fungi)
{

View file

@ -36,19 +36,10 @@ public partial class AlbertaGiacco : BaseQuester
HairHue = 0x457;
}
public override bool CanTalkTo(PlayerMobile to)
{
QuestSystem qs = to.Quest as CollectorQuest;
if (qs == null)
{
return false;
}
return qs.IsObjectiveInProgress(typeof(FindAlbertaObjective))
|| qs.IsObjectiveInProgress(typeof(SitOnTheStoolObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnPaintingObjective));
}
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is CollectorQuest qs && (qs.IsObjectiveInProgress(typeof(FindAlbertaObjective))
|| qs.IsObjectiveInProgress(typeof(SitOnTheStoolObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnPaintingObjective)));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
@ -58,7 +49,7 @@ public partial class AlbertaGiacco : BaseQuester
{
Direction = GetDirectionTo(player);
QuestObjective obj = qs.FindObjective<FindAlbertaObjective>();
var obj = qs.FindObjective<FindAlbertaObjective>();
if (obj?.Completed == false)
{

View file

@ -45,110 +45,9 @@ public partial class ElwoodMcCarrin : BaseQuester
var qs = player.Quest;
if (qs is CollectorQuest)
if (qs is not CollectorQuest)
{
if (qs.IsObjectiveInProgress(typeof(FishPearlsObjective)))
{
qs.AddConversation(new ElwoodDuringFishConversation());
}
else
{
QuestObjective obj = qs.FindObjective<ReturnPearlsObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(FindAlbertaObjective)))
{
qs.AddConversation(new ElwoodDuringPainting1Conversation());
}
else if (qs.IsObjectiveInProgress(typeof(SitOnTheStoolObjective)))
{
qs.AddConversation(new ElwoodDuringPainting2Conversation());
}
else
{
obj = qs.FindObjective<ReturnPaintingObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(FindGabrielObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph1Conversation());
}
else if (qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph2Conversation());
}
else if (qs.IsObjectiveInProgress(typeof(ReturnSheetMusicObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph3Conversation());
}
else
{
obj = qs.FindObjective<ReturnAutographObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(FindTomasObjective)))
{
qs.AddConversation(new ElwoodDuringToys1Conversation());
}
else if (qs.IsObjectiveInProgress(typeof(CaptureImagesObjective)))
{
qs.AddConversation(new ElwoodDuringToys2Conversation());
}
else if (qs.IsObjectiveInProgress(typeof(ReturnImagesObjective)))
{
qs.AddConversation(new ElwoodDuringToys3Conversation());
}
else
{
obj = qs.FindObjective<ReturnToysObjective>();
if (obj?.Completed == false)
{
obj.Complete();
if (GiveReward(player))
{
qs.AddConversation(new EndConversation());
}
else
{
qs.AddConversation(new FullEndConversation(true));
}
}
else
{
obj = qs.FindObjective<MakeRoomObjective>();
if (obj?.Completed == false)
{
if (GiveReward(player))
{
obj.Complete();
qs.AddConversation(new EndConversation());
}
else
{
qs.AddConversation(new FullEndConversation(false));
}
}
}
}
}
}
}
}
else
{
QuestSystem newQuest = new CollectorQuest(player);
var newQuest = new CollectorQuest(player);
if (qs == null && QuestSystem.CanOfferQuest(player, typeof(CollectorQuest)))
{
@ -158,10 +57,113 @@ public partial class ElwoodMcCarrin : BaseQuester
{
newQuest.AddConversation(new DontOfferConversation());
}
return;
}
if (qs.IsObjectiveInProgress(typeof(FishPearlsObjective)))
{
qs.AddConversation(new ElwoodDuringFishConversation());
return;
}
if (qs.FindObjective<ReturnPearlsObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(FindAlbertaObjective)))
{
qs.AddConversation(new ElwoodDuringPainting1Conversation());
return;
}
if (qs.IsObjectiveInProgress(typeof(SitOnTheStoolObjective)))
{
qs.AddConversation(new ElwoodDuringPainting2Conversation());
return;
}
if (qs.FindObjective<ReturnPaintingObjective>() is { Completed: false } obj2)
{
obj2.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(FindGabrielObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph1Conversation());
return;
}
if (qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph2Conversation());
return;
}
if (qs.IsObjectiveInProgress(typeof(ReturnSheetMusicObjective)))
{
qs.AddConversation(new ElwoodDuringAutograph3Conversation());
return;
}
if (qs.FindObjective<ReturnAutographObjective>() is { Completed: false } obj3)
{
obj3.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(FindTomasObjective)))
{
qs.AddConversation(new ElwoodDuringToys1Conversation());
return;
}
if (qs.IsObjectiveInProgress(typeof(CaptureImagesObjective)))
{
qs.AddConversation(new ElwoodDuringToys2Conversation());
return;
}
if (qs.IsObjectiveInProgress(typeof(ReturnImagesObjective)))
{
qs.AddConversation(new ElwoodDuringToys3Conversation());
return;
}
if (qs.FindObjective<ReturnToysObjective>() is { Completed: false } obj4)
{
obj4.Complete();
if (GiveReward(player))
{
qs.AddConversation(new EndConversation());
}
else
{
qs.AddConversation(new FullEndConversation(true));
}
return;
}
if (qs.FindObjective<MakeRoomObjective>() is { Completed: false } obj5)
{
if (GiveReward(player))
{
obj5.Complete();
qs.AddConversation(new EndConversation());
}
else
{
qs.AddConversation(new FullEndConversation(false));
}
}
}
public bool GiveReward(Mobile to)
public static bool GiveReward(Mobile to)
{
var bag = new Bag();

View file

@ -37,52 +37,44 @@ public partial class GabrielPiete : BaseQuester
FacialHairHue = 0x460;
}
public override bool CanTalkTo(PlayerMobile to)
{
QuestSystem qs = to.Quest as CollectorQuest;
if (qs == null)
{
return false;
}
return qs.IsObjectiveInProgress(typeof(FindGabrielObjective))
|| qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnSheetMusicObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnAutographObjective));
}
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is CollectorQuest qs && (qs.IsObjectiveInProgress(typeof(FindGabrielObjective))
|| qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnSheetMusicObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnAutographObjective)));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is CollectorQuest)
if (qs is not CollectorQuest)
{
Direction = GetDirectionTo(player);
return;
}
QuestObjective obj = qs.FindObjective<FindGabrielObjective>();
Direction = GetDirectionTo(player);
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective)))
{
qs.AddConversation(new GabrielNoSheetMusicConversation());
}
else
{
obj = qs.FindObjective<ReturnSheetMusicObjective>();
if (qs.FindObjective<FindGabrielObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(ReturnAutographObjective)))
{
qs.AddConversation(new GabrielIgnoreConversation());
}
}
if (qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective)))
{
qs.AddConversation(new GabrielNoSheetMusicConversation());
return;
}
if (qs.FindObjective<ReturnSheetMusicObjective>() is { Completed: false } obj2)
{
obj2.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(ReturnAutographObjective)))
{
qs.AddConversation(new GabrielIgnoreConversation());
}
}
}

View file

@ -35,17 +35,8 @@ public partial class Impresario : BaseQuester
Utility.AssignRandomFacialHair(this);
}
public override bool CanTalkTo(PlayerMobile to)
{
QuestSystem qs = to.Quest as CollectorQuest;
if (qs == null)
{
return false;
}
return qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective));
}
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is CollectorQuest qs && qs.IsObjectiveInProgress(typeof(FindSheetMusicObjective));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
@ -119,34 +110,38 @@ public class SheetMusicOfferGump : BaseQuestGump
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 1 && info.IsSwitched(1))
if (info.ButtonID != 1 || !info.IsSwitched(1))
{
if (sender.Mobile is PlayerMobile player)
{
var qs = player.Quest;
return;
}
if (qs is not CollectorQuest)
{
return;
}
if (sender.Mobile is not PlayerMobile player)
{
return;
}
var obj = qs.FindObjective<FindSheetMusicObjective>();
var qs = player.Quest;
if (obj?.Completed != false)
{
return;
}
if (qs is not CollectorQuest)
{
return;
}
if (player.Backpack?.ConsumeTotal(typeof(Gold), 10) == true || Banker.Withdraw(player, 10))
{
obj.Complete();
}
else
{
// You don't have enough gold to buy the sheet music.
player.SendLocalizedMessage(1055108);
}
}
var obj = qs.FindObjective<FindSheetMusicObjective>();
if (obj?.Completed != false)
{
return;
}
if (player.Backpack?.ConsumeTotal(typeof(Gold), 10) == true || Banker.Withdraw(player, 10))
{
obj.Complete();
}
else
{
// You don't have enough gold to buy the sheet music.
player.SendLocalizedMessage(1055108);
}
}
}

View file

@ -35,60 +35,50 @@ public partial class TomasONeerlan : BaseQuester
HairHue = 0x455;
}
public override bool CanTalkTo(PlayerMobile to)
{
QuestSystem qs = to.Quest as CollectorQuest;
if (qs == null)
{
return false;
}
return qs.IsObjectiveInProgress(typeof(FindTomasObjective))
|| qs.IsObjectiveInProgress(typeof(CaptureImagesObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnImagesObjective));
}
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is CollectorQuest qs && (qs.IsObjectiveInProgress(typeof(FindTomasObjective))
|| qs.IsObjectiveInProgress(typeof(CaptureImagesObjective))
|| qs.IsObjectiveInProgress(typeof(ReturnImagesObjective)));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is CollectorQuest)
if (qs is not CollectorQuest)
{
Direction = GetDirectionTo(player);
return;
}
QuestObjective obj = qs.FindObjective<FindTomasObjective>();
Direction = GetDirectionTo(player);
if (obj?.Completed == false)
if (qs.FindObjective<FindTomasObjective>() is { Completed: false } obj1) {
var paints = new EnchantedPaints();
if (!player.PlaceInBackpack(paints))
{
Item paints = new EnchantedPaints();
if (!player.PlaceInBackpack(paints))
{
paints.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
else
{
obj.Complete();
}
}
else if (qs.IsObjectiveInProgress(typeof(CaptureImagesObjective)))
{
qs.AddConversation(new TomasDuringCollectingConversation());
paints.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
else
{
obj = qs.FindObjective<ReturnImagesObjective>();
if (obj?.Completed == false)
{
player.Backpack?.ConsumeUpTo(typeof(EnchantedPaints), 1);
obj.Complete();
}
obj1.Complete();
}
return;
}
if (qs.IsObjectiveInProgress(typeof(CaptureImagesObjective)))
{
qs.AddConversation(new TomasDuringCollectingConversation());
return;
}
if (qs.FindObjective<ReturnImagesObjective>() is { Completed: false } obj2)
{
player.Backpack?.ConsumeUpTo(typeof(EnchantedPaints), 1);
obj2.Complete();
}
}
}

View file

@ -446,8 +446,8 @@ namespace Server.Engines.Quests
return false;
}
if (questType == typeof(UzeraanTurmoilQuest) && pm.Profession != 1 && pm.Profession != 2 && pm.Profession != 5
) // warrior / magician / paladin
// warrior / magician / paladin
if (questType == typeof(UzeraanTurmoilQuest) && pm.Profession != 1 && pm.Profession != 2 && pm.Profession != 5)
{
return false;
}

View file

@ -32,7 +32,7 @@ public partial class CrystalCaveBarrier : Item
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<SpeakCavePasswordObjective>();
var obj = qs.FindObjective<SpeakCavePasswordObjective>();
if (obj?.Completed == true)
{

View file

@ -52,7 +52,7 @@ public partial class KronusScroll : QuestItem
{
if (pm.Map == m_WellOfTearsMap && m_WellOfTearsArea.Contains(pm.Location))
{
QuestObjective obj = qs.FindObjective<UseCallingScrollObjective>();
var obj = qs.FindObjective<UseCallingScrollObjective>();
if (obj?.Completed == false)
{

View file

@ -29,7 +29,7 @@ public partial class KronusScrollBox : MetalBox
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<FindCallingScrollObjective>();
var obj = qs.FindObjective<FindCallingScrollObjective>();
if (obj?.Completed == false || DarkTidesQuest.HasLostCallingScroll(from))
{

View file

@ -24,7 +24,7 @@ public partial class ScrollOfAbraxus : QuestItem
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<RetrieveAbraxusScrollObjective>();
var obj = qs.FindObjective<RetrieveAbraxusScrollObjective>();
if (obj?.Completed == false)
{
@ -46,7 +46,7 @@ public partial class ScrollOfAbraxus : QuestItem
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<ReadAbraxusScrollObjective>();
var obj = qs.FindObjective<ReadAbraxusScrollObjective>();
if (obj?.Completed == false)
{

View file

@ -57,7 +57,7 @@ public partial class Horus : BaseQuester
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<FindCrystalCaveObjective>();
var obj = qs.FindObjective<FindCrystalCaveObjective>();
if (obj?.Completed == false)
{
@ -70,48 +70,47 @@ public partial class Horus : BaseQuester
{
base.OnMovement(m, oldLocation);
if (InRange(m.Location, 2) && !InRange(oldLocation, 2) && m is PlayerMobile pm)
if (!InRange(m.Location, 2) || InRange(oldLocation, 2) || m is not PlayerMobile pm)
{
var qs = pm.Quest;
return;
}
if (qs is DarkTidesQuest)
var qs = pm.Quest;
if (qs is not DarkTidesQuest)
{
return;
}
if (qs.FindObjective<ReturnToCrystalCaveObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (qs.FindObjective<FindHorusAboutRewardObjective>() is { Completed: false } obj2)
{
var cont = GetNewContainer();
cont.DropItem(new Gold(500));
BaseJewel jewel = new GoldBracelet();
if (Core.AOS)
{
QuestObjective obj = qs.FindObjective<ReturnToCrystalCaveObjective>();
BaseRunicTool.ApplyAttributesTo(jewel, 3, 20, 40);
}
if (obj?.Completed == false)
{
obj.Complete();
}
else
{
obj = qs.FindObjective<FindHorusAboutRewardObjective>();
cont.DropItem(jewel);
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new Gold(500));
BaseJewel jewel = new GoldBracelet();
if (Core.AOS)
{
BaseRunicTool.ApplyAttributesTo(jewel, 3, 20, 40);
}
cont.DropItem(jewel);
if (!pm.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
pm.SendLocalizedMessage(1046260);
}
else
{
obj.Complete();
}
}
}
if (pm.PlaceInBackpack(cont))
{
obj2.Complete();
}
else
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
pm.SendLocalizedMessage(1046260);
}
}
}
@ -120,36 +119,30 @@ public partial class Horus : BaseQuester
{
base.GetContextMenuEntries(from, list);
if (from.Alive)
if (!from.Alive || from is not PlayerMobile pm)
{
if (from is PlayerMobile pm)
{
var qs = pm.Quest;
return;
}
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<SpeakCavePasswordObjective>();
var enabled = obj?.Completed == false;
var qs = pm.Quest;
list.Add(new SpeakPasswordEntry(this, pm, enabled));
}
}
if (qs is DarkTidesQuest)
{
var obj = qs.FindObjective<SpeakCavePasswordObjective>();
var enabled = obj?.Completed == false;
list.Add(new SpeakPasswordEntry(this, pm, enabled));
}
}
public virtual void OnPasswordSpoken(PlayerMobile from)
{
var qs = from.Quest;
var obj = (from.Quest as DarkTidesQuest)?.FindObjective<SpeakCavePasswordObjective>();
if (qs is DarkTidesQuest)
if (obj?.Completed == false)
{
QuestObjective obj = qs.FindObjective<SpeakCavePasswordObjective>();
if (obj?.Completed == false)
{
obj.Complete();
return;
}
obj.Complete();
return;
}
from.SendLocalizedMessage(1060185); // Horus ignores you.

View file

@ -89,86 +89,80 @@ public partial class Mardoth : BaseQuester
{
var qs = player.Quest;
if (qs is DarkTidesQuest)
if (qs == null && QuestSystem.CanOfferQuest(player, typeof(DarkTidesQuest)))
{
if (DarkTidesQuest.HasLostCallingScroll(player))
new DarkTidesQuest(player).SendOffer();
return;
}
if (qs is not DarkTidesQuest)
{
return;
}
if (DarkTidesQuest.HasLostCallingScroll(player))
{
qs.AddConversation(new LostCallingScrollConversation(true));
return;
}
if (qs.FindObjective<FindMardothAboutVaultObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (qs.FindObjective<FindMardothAboutKronusObjective>() is { Completed: false } obj2)
{
obj2.Complete();
return;
}
if (qs.FindObjective<FindMardothEndObjective>() is { Completed: false } obj3)
{
var cont = GetNewContainer();
cont.DropItem(new PigIron(20));
cont.DropItem(new NoxCrystal(20));
cont.DropItem(new BatWing(25));
cont.DropItem(new DaemonBlood(20));
cont.DropItem(new GraveDust(20));
BaseWeapon weapon = new BoneHarvester();
weapon.Slayer = SlayerName.OrcSlaying;
if (Core.AOS)
{
qs.AddConversation(new LostCallingScrollConversation(true));
BaseRunicTool.ApplyAttributesTo(weapon, 3, 20, 40);
}
else
{
QuestObjective obj = qs.FindObjective<FindMardothAboutVaultObjective>();
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 4);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 4);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 4);
}
if (obj?.Completed == false)
{
obj.Complete();
}
else
{
obj = qs.FindObjective<FindMardothAboutKronusObjective>();
cont.DropItem(weapon);
if (obj?.Completed == false)
{
obj.Complete();
}
else
{
obj = qs.FindObjective<FindMardothEndObjective>();
cont.DropItem(new BankCheck(2000));
cont.DropItem(new EnchantedSextant());
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new PigIron(20));
cont.DropItem(new NoxCrystal(20));
cont.DropItem(new BatWing(25));
cont.DropItem(new DaemonBlood(20));
cont.DropItem(new GraveDust(20));
BaseWeapon weapon = new BoneHarvester();
weapon.Slayer = SlayerName.OrcSlaying;
if (Core.AOS)
{
BaseRunicTool.ApplyAttributesTo(weapon, 3, 20, 40);
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 4);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 4);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 4);
}
cont.DropItem(weapon);
cont.DropItem(new BankCheck(2000));
cont.DropItem(new EnchantedSextant());
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
else
{
obj.Complete();
}
}
else if (contextMenu)
{
FocusTo(player);
player.SendLocalizedMessage(1061821); // Mardoth has nothing more for you at this time.
}
}
}
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
else
{
obj3.Complete();
}
}
else if (qs == null && QuestSystem.CanOfferQuest(player, typeof(DarkTidesQuest)))
else if (contextMenu)
{
new DarkTidesQuest(player).SendOffer();
FocusTo(player);
player.SendLocalizedMessage(1061821); // Mardoth has nothing more for you at this time.
}
}
@ -176,22 +170,24 @@ public partial class Mardoth : BaseQuester
{
base.OnMovement(m, oldLocation);
if (m is PlayerMobile && !m.Frozen && !m.Alive && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
if (m is not PlayerMobile || m.Frozen || m.Alive || !InRange(m, 4) || InRange(oldLocation, 4) || !InLOS(m))
{
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
return;
}
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
}
}

View file

@ -60,7 +60,7 @@ public partial class EminosKatanaChest : WoodenChest
}
else
{
QuestObjective obj = qs.FindObjective<HallwayWalkObjective>();
var obj = qs.FindObjective<HallwayWalkObjective>();
if (obj?.Completed == false)
{

View file

@ -21,7 +21,7 @@ public partial class WhiteNinjaQuestTeleporter : DynamicTeleporter
if (qs is EminosUndertakingQuest)
{
QuestObjective obj = qs.FindObjective<SearchForSwordObjective>();
var obj = qs.FindObjective<SearchForSwordObjective>();
if (obj != null)
{

View file

@ -80,23 +80,19 @@ public partial class Emino : BaseQuester
return;
}
QuestObjective obj = qs.FindObjective<FindEminoBeginObjective>();
if (obj?.Completed == false)
if (qs.FindObjective<FindEminoBeginObjective>() is { Completed: false } obj1)
{
obj.Complete();
obj1.Complete();
return;
}
obj = qs.FindObjective<UseTeleporterObjective>();
if (obj?.Completed == false)
if (qs.FindObjective<UseTeleporterObjective>() is { Completed: false } obj2)
{
Item note = new NoteForZoel();
var note = new NoteForZoel();
if (player.PlaceInBackpack(note))
{
obj.Complete();
obj2.Complete();
player.AddToBackpack(new LeatherNinjaPants());
player.AddToBackpack(new LeatherNinjaMitts());
@ -111,9 +107,7 @@ public partial class Emino : BaseQuester
return;
}
obj = qs.FindObjective<ReturnFromInnObjective>();
if (obj?.Completed == false)
if (qs.FindObjective<ReturnFromInnObjective>() is { Completed: false } obj3)
{
var cont = GetNewContainer();
@ -127,7 +121,7 @@ public partial class Emino : BaseQuester
if (player.PlaceInBackpack(cont))
{
obj.Complete();
obj3.Complete();
}
else
{
@ -145,60 +139,47 @@ public partial class Emino : BaseQuester
return;
}
obj = qs.FindObjective<GiveEminoSwordObjective>();
if (obj?.Completed == false)
if (qs.FindObjective<GiveEminoSwordObjective>() is { Completed: false } obj4)
{
Item katana = null;
var katana = player.Backpack?.FindItemByType<EminosKatana>();
if (player.Backpack != null)
if (katana == null)
{
katana = player.Backpack.FindItemByType<EminosKatana>();
return;
}
if (katana != null)
var stolenTreasure = false;
var walk = qs.FindObjective<HallwayWalkObjective>();
if (walk != null)
{
var stolenTreasure = false;
stolenTreasure = walk.StolenTreasure;
}
var walk = qs.FindObjective<HallwayWalkObjective>();
var kama = new Kama();
BaseRunicTool.ApplyAttributesTo(kama, 1, 10, stolenTreasure ? 20 : 30);
if (walk != null)
{
stolenTreasure = walk.StolenTreasure;
}
var kama = new Kama();
if (player.PlaceInBackpack(kama))
{
katana.Delete();
obj4.Complete();
if (stolenTreasure)
{
BaseRunicTool.ApplyAttributesTo(kama, 1, 10, 20);
qs.AddConversation(new EarnLessGiftsConversation());
}
else
{
BaseRunicTool.ApplyAttributesTo(kama, 1, 10, 30);
}
if (player.PlaceInBackpack(kama))
{
katana.Delete();
obj.Complete();
if (stolenTreasure)
{
qs.AddConversation(new EarnLessGiftsConversation());
}
else
{
qs.AddConversation(new EarnGiftsConversation());
}
}
else
{
kama.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
qs.AddConversation(new EarnGiftsConversation());
}
}
else
{
kama.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
}
}
@ -206,22 +187,24 @@ public partial class Emino : BaseQuester
{
base.OnMovement(m, oldLocation);
if (!m.Frozen && !m.Alive && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
if (m.Frozen || m.Alive || !InRange(m, 4) || InRange(oldLocation, 4) || !InLOS(m))
{
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
return;
}
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
}
}

View file

@ -54,7 +54,7 @@ public partial class Zoel : BaseQuester
if (qs is EminosUndertakingQuest)
{
QuestObjective obj = qs.FindObjective<FindZoelObjective>();
var obj = qs.FindObjective<FindZoelObjective>();
if (obj?.Completed == false)
{
@ -73,7 +73,7 @@ public partial class Zoel : BaseQuester
{
if (dropped is NoteForZoel)
{
QuestObjective obj = qs.FindObjective<GiveZoelNoteObjective>();
var obj = qs.FindObjective<GiveZoelNoteObjective>();
if (obj?.Completed == false)
{

View file

@ -42,7 +42,7 @@ public partial class HaochisKatanaGenerator : Item
}
else
{
QuestObjective obj = qs.FindObjective<FifthTrialIntroObjective>();
var obj = qs.FindObjective<FifthTrialIntroObjective>();
if (obj?.Completed == false)
{

View file

@ -37,7 +37,7 @@ public partial class HonorCandle : CandleLong
if (qs is HaochisTrialsQuest)
{
QuestObjective obj = qs.FindObjective<SixthTrialIntroObjective>();
var obj = qs.FindObjective<SixthTrialIntroObjective>();
if (obj?.Completed == false)
{

View file

@ -50,7 +50,7 @@ public partial class DeadlyImp : BaseCreature
var qs = player.Quest;
if (qs is HaochisTrialsQuest)
{
QuestObjective obj = qs.FindObjective<SecondTrialAttackObjective>();
var obj = qs.FindObjective<SecondTrialAttackObjective>();
if (obj?.Completed == false)
{
obj.Complete();

View file

@ -57,7 +57,7 @@ public partial class FierceDragon : BaseCreature
var qs = player.Quest;
if (qs is HaochisTrialsQuest)
{
QuestObjective obj = qs.FindObjective<SecondTrialAttackObjective>();
var obj = qs.FindObjective<SecondTrialAttackObjective>();
if (obj?.Completed == false)
{
obj.Complete();

View file

@ -47,115 +47,95 @@ public partial class Haochi : BaseQuester
{
var qs = player.Quest;
if (qs is HaochisTrialsQuest)
if (qs is not HaochisTrialsQuest)
{
if (HaochisTrialsQuest.HasLostHaochisKatana(player))
return;
}
if (HaochisTrialsQuest.HasLostHaochisKatana(player))
{
qs.AddConversation(new LostSwordConversation());
return;
}
if (qs.FindObjective<FindHaochiObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (qs.FindObjective<FirstTrialReturnObjective>() is { Completed: false } obj2)
{
player.AddToBackpack(new LeatherDo());
obj2.Complete();
return;
}
if (qs.FindObjective<SecondTrialReturnObjective>() is { Completed: false } obj3)
{
if (obj3.Dragon)
{
player.AddToBackpack(new LeatherSuneate());
}
obj3.Complete();
return;
}
if (qs.FindObjective<ThirdTrialReturnObjective>() is { Completed: false } obj4)
{
player.AddToBackpack(new LeatherHaidate());
obj4.Complete();
return;
}
if (qs.FindObjective<FourthTrialReturnObjective>() is { Completed: false } obj5)
{
if (!obj5.KilledCat)
{
var cont = GetNewContainer();
cont.DropItem(new LeatherHiroSode());
cont.DropItem(new JinBaori());
player.AddToBackpack(cont);
}
obj5.Complete();
return;
}
if (qs.FindObjective<FifthTrialReturnObjective>() is { Completed: false } obj6)
{
var katana = player.Backpack?.FindItemByType<HaochisKatana>();
if (katana == null)
{
qs.AddConversation(new LostSwordConversation());
return;
}
QuestObjective obj = qs.FindObjective<FindHaochiObjective>();
katana.Delete();
obj6.Complete();
if (obj?.Completed == false)
{
obj.Complete();
return;
}
qs.AddConversation(
new SixthTrialIntroConversation(qs.FindObjective<FifthTrialIntroObjective>()?.StolenTreasure == true)
);
}
obj = qs.FindObjective<FirstTrialReturnObjective>();
if (qs.FindObjective<SixthTrialReturnObjective>() is { Completed: false } obj7)
{
obj7.Complete();
return;
}
if (obj?.Completed == false)
{
player.AddToBackpack(new LeatherDo());
obj.Complete();
return;
}
if (qs.FindObjective<SeventhTrialReturnObjective>() is { Completed: false } obj8)
{
BaseWeapon weapon = new Daisho();
BaseRunicTool.ApplyAttributesTo(weapon, Utility.Random(1, 3), 10, 30);
player.AddToBackpack(weapon);
obj = qs.FindObjective<SecondTrialReturnObjective>();
BaseArmor armor = new LeatherDo();
BaseRunicTool.ApplyAttributesTo(armor, Utility.Random(1, 3), 10, 20);
player.AddToBackpack(armor);
if (obj?.Completed == false)
{
if (((SecondTrialReturnObjective)obj).Dragon)
{
player.AddToBackpack(new LeatherSuneate());
}
obj.Complete();
return;
}
obj = qs.FindObjective<ThirdTrialReturnObjective>();
if (obj?.Completed == false)
{
player.AddToBackpack(new LeatherHiroSode());
obj.Complete();
return;
}
obj = qs.FindObjective<FourthTrialReturnObjective>();
if (obj?.Completed == false)
{
if (!((FourthTrialReturnObjective)obj).KilledCat)
{
var cont = GetNewContainer();
cont.DropItem(new LeatherHiroSode());
cont.DropItem(new JinBaori());
player.AddToBackpack(cont);
}
obj.Complete();
return;
}
obj = qs.FindObjective<FifthTrialReturnObjective>();
if (obj?.Completed == false)
{
var katana = player.Backpack?.FindItemByType<HaochisKatana>();
if (katana == null)
{
return;
}
katana.Delete();
obj.Complete();
obj = qs.FindObjective<FifthTrialIntroObjective>();
if (((FifthTrialIntroObjective)obj)?.StolenTreasure == true)
{
qs.AddConversation(new SixthTrialIntroConversation(true));
}
else
{
qs.AddConversation(new SixthTrialIntroConversation(false));
}
}
obj = qs.FindObjective<SixthTrialReturnObjective>();
if (obj?.Completed == false)
{
obj.Complete();
return;
}
obj = qs.FindObjective<SeventhTrialReturnObjective>();
if (obj?.Completed == false)
{
BaseWeapon weapon = new Daisho();
BaseRunicTool.ApplyAttributesTo(weapon, Utility.Random(1, 3), 10, 30);
player.AddToBackpack(weapon);
BaseArmor armor = new LeatherDo();
BaseRunicTool.ApplyAttributesTo(armor, Utility.Random(1, 3), 10, 20);
player.AddToBackpack(armor);
obj.Complete();
}
obj8.Complete();
}
}
}

View file

@ -49,7 +49,7 @@ public partial class Relnia : BaseQuester
if (qs is HaochisTrialsQuest)
{
QuestObjective obj = qs.FindObjective<FourthTrialCatsObjective>();
var obj = qs.FindObjective<FourthTrialCatsObjective>();
if (obj?.Completed == false)
{

View file

@ -25,7 +25,7 @@ public class QuestCompleteObjectiveRegion : BaseRegion
{
if (m is PlayerMobile player && player?.Quest != null && player.Quest.GetType() == Quest)
{
QuestObjective obj = player.Quest.FindObjective(Objective);
var obj = player.Quest.FindObjective(Objective);
if (obj is { Completed: false })
{

View file

@ -1,102 +1,46 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.ContextMenus;
using Server.Engines.Plants;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Engines.Quests.Matriarch
namespace Server.Engines.Quests.Matriarch;
[SerializationGenerator(0)]
public abstract partial class BaseSolenMatriarch : BaseQuester
{
public abstract class BaseSolenMatriarch : BaseQuester
public BaseSolenMatriarch()
{
public BaseSolenMatriarch()
Body = 0x328;
if (!RedSolen)
{
Body = 0x328;
if (!RedSolen)
{
Hue = 0x44E;
}
SpeechHue = 0;
Hue = 0x44E;
}
public BaseSolenMatriarch(Serial serial) : base(serial)
SpeechHue = 0;
}
public abstract bool RedSolen { get; }
public override string DefaultName => "the solen matriarch";
public override bool DisallowAllMoves => false;
public override int GetIdleSound() => 0x10D;
public override bool CanTalkTo(PlayerMobile to) =>
SolenMatriarchQuest.IsFriend(to, RedSolen) || to.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
Direction = GetDirectionTo(player);
if (player.Quest is not SolenMatriarchQuest qs || qs.RedSolen != RedSolen)
{
}
public abstract bool RedSolen { get; }
public override string DefaultName => "the solen matriarch";
public override bool DisallowAllMoves => false;
public override int GetIdleSound() => 0x10D;
public override bool CanTalkTo(PlayerMobile to)
{
if (SolenMatriarchQuest.IsFriend(to, RedSolen))
if (SolenMatriarchQuest.IsFriend(player, RedSolen))
{
return true;
}
return to.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen;
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
Direction = GetDirectionTo(player);
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
{
if (qs.IsObjectiveInProgress(typeof(KillInfiltratorsObjective)))
{
qs.AddConversation(new DuringKillInfiltratorsConversation());
}
else
{
QuestObjective obj = qs.FindObjective<ReturnAfterKillsObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(GatherWaterObjective)))
{
qs.AddConversation(new DuringWaterGatheringConversation());
}
else
{
obj = qs.FindObjective<ReturnAfterWaterObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
{
qs.AddConversation(new DuringFungiProcessConversation());
}
else
{
obj = qs.FindObjective<GetRewardObjective>();
if (obj?.Completed == false)
{
if (SolenMatriarchQuest.GiveRewardTo(player))
{
obj.Complete();
}
else
{
qs.AddConversation(new FullBackpackConversation(false));
}
}
}
}
}
}
else if (SolenMatriarchQuest.IsFriend(player, RedSolen))
{
QuestSystem newQuest = new SolenMatriarchQuest(player, RedSolen);
var newQuest = new SolenMatriarchQuest(player, RedSolen);
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(SolenMatriarchQuest)))
{
@ -107,227 +51,221 @@ namespace Server.Engines.Quests.Matriarch
newQuest.AddConversation(new DontOfferConversation(true));
}
}
return;
}
public override bool OnDragDrop(Mobile from, Item dropped)
if (qs.IsObjectiveInProgress(typeof(KillInfiltratorsObjective)))
{
if (from is PlayerMobile player)
qs.AddConversation(new DuringKillInfiltratorsConversation());
return;
}
if (qs.FindObjective<ReturnAfterKillsObjective>() is { Completed: false } obj1)
{
obj1.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(GatherWaterObjective)))
{
qs.AddConversation(new DuringWaterGatheringConversation());
return;
}
if (qs.FindObjective<ReturnAfterWaterObjective>() is { Completed: false } obj2)
{
obj2.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
{
qs.AddConversation(new DuringFungiProcessConversation());
return;
}
if (qs.FindObjective<GetRewardObjective>() is { Completed: false } obj3)
{
if (SolenMatriarchQuest.GiveRewardTo(player))
{
if (dropped is Seed)
{
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
{
SayTo(player, 1054080); // Thank you for that plant seed. Those have such wonderful flavor.
}
else
{
QuestSystem newQuest = new SolenMatriarchQuest(player, RedSolen);
obj3.Complete();
}
else
{
qs.AddConversation(new FullBackpackConversation(false));
}
}
}
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(SolenMatriarchQuest)))
{
newQuest.SendOffer();
}
else
{
newQuest.AddConversation(
new DontOfferConversation(SolenMatriarchQuest.IsFriend(player, RedSolen))
);
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (from is not PlayerMobile player)
{
return base.OnDragDrop(from, dropped);
}
dropped.Delete();
return true;
}
if (dropped is not Seed)
{
if (dropped is ZoogiFungus fungus)
{
OnGivenFungi(player, fungus);
if (dropped is ZoogiFungus fungus)
{
OnGivenFungi(player, fungus);
return fungus.Deleted;
}
return fungus.Deleted;
}
return base.OnDragDrop(from, dropped);
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
{
base.GetContextMenuEntries(from, list);
SayTo(player, 1054080); // Thank you for that plant seed. Those have such wonderful flavor.
}
else
{
var newQuest = new SolenMatriarchQuest(player, RedSolen);
if (from.Alive)
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(SolenMatriarchQuest)))
{
if (from is PlayerMobile pm)
{
if (pm.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
{
if (qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
{
list.Add(new ProcessZoogiFungusEntry(this, pm));
}
}
}
newQuest.SendOffer();
}
else
{
newQuest.AddConversation(
new DontOfferConversation(SolenMatriarchQuest.IsFriend(player, RedSolen))
);
}
}
public void OnGivenFungi(PlayerMobile player, ZoogiFungus fungi)
dropped.Delete();
return true;
}
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
{
base.GetContextMenuEntries(from, list);
if (from.Alive && from is PlayerMobile pm && pm.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen &&
qs.IsObjectiveInProgress(typeof(ProcessFungiObjective)))
{
Direction = GetDirectionTo(player);
list.Add(new ProcessZoogiFungusEntry(this, pm));
}
}
if (player.Quest is SolenMatriarchQuest qs && qs.RedSolen == RedSolen)
{
QuestObjective obj = qs.FindObjective<ProcessFungiObjective>();
public void OnGivenFungi(PlayerMobile player, ZoogiFungus fungi)
{
Direction = GetDirectionTo(player);
if (obj?.Completed == false)
{
var amount = fungi.Amount / 2;
if (amount > 100)
{
amount = 100;
}
if (amount > 0)
{
if (amount * 2 >= fungi.Amount)
{
fungi.Delete();
}
else
{
fungi.Amount -= amount * 2;
}
var powder = new PowderOfTranslocation(amount);
player.AddToBackpack(powder);
player.SendLocalizedMessage(1054100); // You receive some powder of translocation.
obj.Complete();
}
}
}
if (player.Quest is not SolenMatriarchQuest qs || qs.RedSolen != RedSolen)
{
return;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
var obj = qs.FindObjective<ProcessFungiObjective>();
writer.WriteEncodedInt(0); // version
if (obj?.Completed != false)
{
return;
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var amount = fungi.Amount / 2;
var version = reader.ReadEncodedInt();
if (amount > 100)
{
amount = 100;
}
private class ProcessZoogiFungusEntry : ContextMenuEntry
if (amount > 0)
{
private readonly PlayerMobile m_From;
private readonly BaseSolenMatriarch m_Matriarch;
public ProcessZoogiFungusEntry(BaseSolenMatriarch matriarch, PlayerMobile from) : base(6184)
if (amount * 2 >= fungi.Amount)
{
m_Matriarch = matriarch;
m_From = from;
fungi.Delete();
}
else
{
fungi.Amount -= amount * 2;
}
public override void OnClick()
{
if (m_From.Alive)
{
m_From.Target = new ProcessFungiTarget(m_Matriarch, m_From);
}
}
var powder = new PowderOfTranslocation(amount);
player.AddToBackpack(powder);
player.SendLocalizedMessage(1054100); // You receive some powder of translocation.
obj.Complete();
}
}
private class ProcessZoogiFungusEntry : ContextMenuEntry
{
private readonly PlayerMobile _from;
private readonly BaseSolenMatriarch _matriarch;
public ProcessZoogiFungusEntry(BaseSolenMatriarch matriarch, PlayerMobile from) : base(6184)
{
_matriarch = matriarch;
_from = from;
}
private class ProcessFungiTarget : Target
public override void OnClick()
{
private readonly PlayerMobile m_From;
private readonly BaseSolenMatriarch m_Matriarch;
public ProcessFungiTarget(BaseSolenMatriarch matriarch, PlayerMobile from) : base(-1, false, TargetFlags.None)
if (_from.Alive)
{
m_Matriarch = matriarch;
m_From = from;
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
from.SendLocalizedMessage(1042021, "", 0x59); // Cancelled.
}
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is ZoogiFungus fungus)
{
if (fungus.IsChildOf(m_From.Backpack))
{
m_Matriarch.OnGivenFungi(m_From, fungus);
}
else
{
m_From.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
_from.Target = new ProcessFungiTarget(_matriarch, _from);
}
}
}
public class RedSolenMatriarch : BaseSolenMatriarch
private class ProcessFungiTarget : Target
{
[Constructible]
public RedSolenMatriarch()
private readonly PlayerMobile _from;
private readonly BaseSolenMatriarch _matriarch;
public ProcessFungiTarget(BaseSolenMatriarch matriarch, PlayerMobile from) : base(-1, false, TargetFlags.None)
{
_matriarch = matriarch;
_from = from;
}
public RedSolenMatriarch(Serial serial) : base(serial)
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
from.SendLocalizedMessage(1042021, "", 0x59); // Cancelled.
}
public override bool RedSolen => true;
public override void Serialize(IGenericWriter writer)
protected override void OnTarget(Mobile from, object targeted)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
}
}
public class BlackSolenMatriarch : BaseSolenMatriarch
{
[Constructible]
public BlackSolenMatriarch()
{
}
public BlackSolenMatriarch(Serial serial) : base(serial)
{
}
public override bool RedSolen => false;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
if (targeted is ZoogiFungus fungus)
{
if (fungus.IsChildOf(_from.Backpack))
{
_matriarch.OnGivenFungi(_from, fungus);
}
else
{
_from.SendLocalizedMessage(1042001); // That must be in your pack for you to use it.
}
}
}
}
}
[SerializationGenerator(0)]
public partial class RedSolenMatriarch : BaseSolenMatriarch
{
[Constructible]
public RedSolenMatriarch()
{
}
public override bool RedSolen => true;
}
[SerializationGenerator(0)]
public partial class BlackSolenMatriarch : BaseSolenMatriarch
{
[Constructible]
public BlackSolenMatriarch()
{
}
public override bool RedSolen => false;
}

View file

@ -1,154 +1,137 @@
using ModernUO.Serialization;
using Server.Engines.Plants;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Naturalist
namespace Server.Engines.Quests.Naturalist;
[SerializationGenerator(0)]
public partial class Naturalist : BaseQuester
{
public class Naturalist : BaseQuester
[Constructible]
public Naturalist() : base("the Naturalist")
{
[Constructible]
public Naturalist() : base("the Naturalist")
}
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
AddItem(new Tunic(0x598));
AddItem(new LongPants(0x59B));
AddItem(new Boots());
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
if (player.Quest is StudyOfSolenQuest qs && qs.Naturalist == this)
{
}
public Naturalist(Serial serial) : base(serial)
{
}
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
AddItem(new Tunic(0x598));
AddItem(new LongPants(0x59B));
AddItem(new Boots());
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
if (player.Quest is StudyOfSolenQuest qs && qs.Naturalist == this)
var study = qs.FindObjective<StudyNestsObjective>();
if (study == null)
{
var study = qs.FindObjective<StudyNestsObjective>();
if (study == null)
{
return;
}
if (!study.Completed)
{
PlaySound(0x41F);
qs.AddConversation(new NaturalistDuringStudyConversation());
return;
}
QuestObjective obj = qs.FindObjective<ReturnToNaturalistObjective>();
if (obj?.Completed == false)
{
Seed reward;
var type = Utility.Random(17) switch
{
0 => PlantType.CampionFlowers,
1 => PlantType.Poppies,
2 => PlantType.Snowdrops,
3 => PlantType.Bulrushes,
4 => PlantType.Lilies,
5 => PlantType.PampasGrass,
6 => PlantType.Rushes,
7 => PlantType.ElephantEarPlant,
8 => PlantType.Fern,
9 => PlantType.PonytailPalm,
10 => PlantType.SmallPalm,
11 => PlantType.CenturyPlant,
12 => PlantType.WaterPlant,
13 => PlantType.SnakePlant,
14 => PlantType.PricklyPearCactus,
15 => PlantType.BarrelCactus,
_ => PlantType.TribarrelCactus
};
if (study.StudiedSpecialNest)
{
reward = new Seed(type, PlantHue.FireRed);
}
else
{
var hue = Utility.Random(3) switch
{
0 => PlantHue.Pink,
1 => PlantHue.Magenta,
_ => PlantHue.Aqua
};
reward = new Seed(type, hue);
}
if (player.PlaceInBackpack(reward))
{
obj.Complete();
PlaySound(0x449);
PlaySound(0x41B);
if (study.StudiedSpecialNest)
{
qs.AddConversation(new SpecialEndConversation());
}
else
{
qs.AddConversation(new EndConversation());
}
}
else
{
reward.Delete();
qs.AddConversation(new FullBackpackConversation());
}
}
return;
}
else
{
QuestSystem newQuest = new StudyOfSolenQuest(player, this);
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(StudyOfSolenQuest)))
if (!study.Completed)
{
PlaySound(0x41F);
qs.AddConversation(new NaturalistDuringStudyConversation());
return;
}
var obj = qs.FindObjective<ReturnToNaturalistObjective>();
if (obj?.Completed == false)
{
Seed reward;
var type = Utility.Random(17) switch
{
PlaySound(0x42F);
newQuest.SendOffer();
0 => PlantType.CampionFlowers,
1 => PlantType.Poppies,
2 => PlantType.Snowdrops,
3 => PlantType.Bulrushes,
4 => PlantType.Lilies,
5 => PlantType.PampasGrass,
6 => PlantType.Rushes,
7 => PlantType.ElephantEarPlant,
8 => PlantType.Fern,
9 => PlantType.PonytailPalm,
10 => PlantType.SmallPalm,
11 => PlantType.CenturyPlant,
12 => PlantType.WaterPlant,
13 => PlantType.SnakePlant,
14 => PlantType.PricklyPearCactus,
15 => PlantType.BarrelCactus,
_ => PlantType.TribarrelCactus
};
if (study.StudiedSpecialNest)
{
reward = new Seed(type, PlantHue.FireRed);
}
else
{
PlaySound(0x448);
newQuest.AddConversation(new DontOfferConversation());
var hue = Utility.Random(3) switch
{
0 => PlantHue.Pink,
1 => PlantHue.Magenta,
_ => PlantHue.Aqua
};
reward = new Seed(type, hue);
}
if (player.PlaceInBackpack(reward))
{
obj.Complete();
PlaySound(0x449);
PlaySound(0x41B);
if (study.StudiedSpecialNest)
{
qs.AddConversation(new SpecialEndConversation());
}
else
{
qs.AddConversation(new EndConversation());
}
}
else
{
reward.Delete();
qs.AddConversation(new FullBackpackConversation());
}
}
}
public override void Serialize(IGenericWriter writer)
else
{
base.Serialize(writer);
var newQuest = new StudyOfSolenQuest(player, this);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(StudyOfSolenQuest)))
{
PlaySound(0x42F);
newQuest.SendOffer();
}
else
{
PlaySound(0x448);
newQuest.AddConversation(new DontOfferConversation());
}
}
}
}

View file

@ -1,150 +1,120 @@
using ModernUO.Serialization;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Zento
namespace Server.Engines.Quests.Zento;
[SerializationGenerator(0)]
public partial class AnsellaGryen : BaseQuester
{
public class AnsellaGryen : BaseQuester
[Constructible]
public AnsellaGryen()
{
[Constructible]
public AnsellaGryen()
}
public override string DefaultName => "Ansella Gryen";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83EA;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
HairItemID = 0x203B;
HairHue = 0x1BB;
AddItem(new SamuraiTabi(0x8FD));
AddItem(new FemaleKimono(0x4B6));
AddItem(new Obi(0x526));
AddItem(new GoldBracelet());
}
public override int GetAutoTalkRange(PlayerMobile m) => m.Quest == null ? 3 : -1;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is TerribleHatchlingsQuest)
{
}
public AnsellaGryen(Serial serial) : base(serial)
{
}
public override string DefaultName => "Ansella Gryen";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83EA;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
HairItemID = 0x203B;
HairHue = 0x1BB;
AddItem(new SamuraiTabi(0x8FD));
AddItem(new FemaleKimono(0x4B6));
AddItem(new Obi(0x526));
AddItem(new GoldBracelet());
}
public override int GetAutoTalkRange(PlayerMobile m)
{
if (m.Quest == null)
if (qs.IsObjectiveInProgress(typeof(FirstKillObjective)))
{
return 3;
qs.AddConversation(new DirectionConversation());
return;
}
return -1;
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is TerribleHatchlingsQuest)
if (qs.IsObjectiveInProgress(typeof(SecondKillObjective))
|| qs.IsObjectiveInProgress(typeof(ThirdKillObjective)))
{
if (qs.IsObjectiveInProgress(typeof(FirstKillObjective)))
qs.AddConversation(new TakeCareConversation());
return;
}
var obj = qs.FindObjective<ReturnObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new Gold(Utility.RandomMinMax(100, 200)));
if (Utility.RandomBool())
{
qs.AddConversation(new DirectionConversation());
if (Loot.Construct(Loot.SEWeaponTypes) is BaseWeapon weapon)
{
BaseRunicTool.ApplyAttributesTo(weapon, 3, 10, 30);
cont.DropItem(weapon);
}
}
else if (qs.IsObjectiveInProgress(typeof(SecondKillObjective))
|| qs.IsObjectiveInProgress(typeof(ThirdKillObjective)))
else if (Loot.Construct(Loot.SEArmorTypes) is BaseArmor armor)
{
qs.AddConversation(new TakeCareConversation());
BaseRunicTool.ApplyAttributesTo(armor, 1, 10, 20);
cont.DropItem(armor);
}
if (player.PlaceInBackpack(cont))
{
obj.Complete();
}
else
{
QuestObjective obj = qs.FindObjective<ReturnObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new Gold(Utility.RandomMinMax(100, 200)));
if (Utility.RandomBool())
{
if (Loot.Construct(Loot.SEWeaponTypes) is BaseWeapon weapon)
{
BaseRunicTool.ApplyAttributesTo(weapon, 3, 10, 30);
cont.DropItem(weapon);
}
}
else
{
if (Loot.Construct(Loot.SEArmorTypes) is BaseArmor armor)
{
BaseRunicTool.ApplyAttributesTo(armor, 1, 10, 20);
cont.DropItem(armor);
}
}
if (player.PlaceInBackpack(cont))
{
obj.Complete();
}
else
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
}
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
}
else
}
else
{
var newQuest = new TerribleHatchlingsQuest(player);
if (qs != null)
{
var newQuest = new TerribleHatchlingsQuest(player);
if (qs != null)
if (contextMenu)
{
if (contextMenu)
{
SayTo(
player,
1063322
); // Before you can help me with the Terrible Hatchlings, you'll need to finish the quest you've already taken!
}
}
else if (QuestSystem.CanOfferQuest(player, typeof(TerribleHatchlingsQuest), out var inRestartPeriod))
{
newQuest.SendOffer();
}
else if (inRestartPeriod && contextMenu)
{
SayTo(player, 1049357); // I have nothing more for you at this time.
// Before you can help me with the Terrible Hatchlings, you'll need to finish the quest you've already taken!
SayTo(player, 1063322);
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadEncodedInt();
}
public override void TurnToTokuno()
{
else if (QuestSystem.CanOfferQuest(player, typeof(TerribleHatchlingsQuest), out var inRestartPeriod))
{
newQuest.SendOffer();
}
else if (inRestartPeriod && contextMenu)
{
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
}
public override void TurnToTokuno()
{
}
}

View file

@ -84,7 +84,7 @@ public partial class Victoria : BaseQuester
return base.OnDragDrop(from, dropped);
}
QuestObjective obj = qs.FindObjective<CollectBonesObjective>();
var obj = qs.FindObjective<CollectBonesObjective>();
if (obj?.Completed == false)
{

View file

@ -82,7 +82,7 @@ namespace Server.Engines.Quests.Doom
{
base.Cancel();
QuestObjective obj = FindObjective<CollectBonesObjective>();
var obj = FindObjective<CollectBonesObjective>();
if (obj?.CurProgress > 0)
{

View file

@ -1,177 +1,134 @@
using ModernUO.Serialization;
using Server.Items;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
public enum CannonDirection
{
public enum CannonDirection
North,
East,
South,
West
}
[SerializationGenerator(0, false)]
public partial class Cannon : BaseAddon
{
[SerializableField(0, setter: "private")]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private CannonDirection _cannonDirection;
[SerializableField(1)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private MilitiaCanoneer _canoneer;
[Constructible]
public Cannon(CannonDirection direction)
{
North,
East,
South,
West
}
CannonDirection = direction;
public class Cannon : BaseAddon
{
[Constructible]
public Cannon(CannonDirection direction)
switch (direction)
{
CannonDirection = direction;
switch (direction)
{
case CannonDirection.North:
{
AddComponent(new CannonComponent(0xE8D), 0, 0, 0);
AddComponent(new CannonComponent(0xE8C), 0, 1, 0);
AddComponent(new CannonComponent(0xE8B), 0, 2, 0);
break;
}
case CannonDirection.East:
{
AddComponent(new CannonComponent(0xE96), 0, 0, 0);
AddComponent(new CannonComponent(0xE95), -1, 0, 0);
AddComponent(new CannonComponent(0xE94), -2, 0, 0);
break;
}
case CannonDirection.South:
{
AddComponent(new CannonComponent(0xE91), 0, 0, 0);
AddComponent(new CannonComponent(0xE92), 0, -1, 0);
AddComponent(new CannonComponent(0xE93), 0, -2, 0);
break;
}
default:
{
AddComponent(new CannonComponent(0xE8E), 0, 0, 0);
AddComponent(new CannonComponent(0xE8F), 1, 0, 0);
AddComponent(new CannonComponent(0xE90), 2, 0, 0);
break;
}
}
}
public Cannon(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public CannonDirection CannonDirection { get; private set; }
[CommandProperty(AccessLevel.GameMaster)]
public MilitiaCanoneer Canoneer { get; set; }
public override bool HandlesOnMovement => Canoneer?.Deleted == false && Canoneer.Active;
public void DoFireEffect(Point3D target)
{
var from = CannonDirection switch
{
CannonDirection.North => new Point3D(X, Y - 1, Z),
CannonDirection.East => new Point3D(X + 1, Y, Z),
CannonDirection.South => new Point3D(X, Y + 1, Z),
_ => new Point3D(X - 1, Y, Z)
};
Effects.SendLocationEffect(from, Map, 0x36B0, 16, 1);
Effects.PlaySound(from, Map, 0x11D);
Effects.SendLocationEffect(target, Map, 0x36B0, 16, 1);
Effects.PlaySound(target, Map, 0x11D);
}
public void Fire(Mobile from, Mobile target)
{
DoFireEffect(target.Location);
target.Damage(9999, from);
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (!(Canoneer?.Deleted == false && Canoneer.Active))
{
return;
}
var canFire = CannonDirection switch
{
CannonDirection.North => m.X >= X - 7 && m.X <= X + 7 && m.Y == Y - 7 && oldLocation.Y < Y - 7,
CannonDirection.East => m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X + 7 && oldLocation.X > X + 7,
CannonDirection.South => m.X >= X - 7 && m.X <= X + 7 && m.Y == Y + 7 && oldLocation.Y > Y + 7,
_ => m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X - 7 && oldLocation.X < X - 7
};
if (canFire && Canoneer.WillFire(this, m))
{
Fire(Canoneer, m);
}
}
public override void Serialize(IGenericWriter writer)
{
if (Canoneer?.Deleted == true)
{
Canoneer = null;
}
base.Serialize(writer);
writer.Write(0); // version
writer.WriteEncodedInt((int)CannonDirection);
writer.Write(Canoneer);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
CannonDirection = (CannonDirection)reader.ReadEncodedInt();
Canoneer = (MilitiaCanoneer)reader.ReadEntity<Mobile>();
}
}
public class CannonComponent : AddonComponent
{
public CannonComponent(int itemID) : base(itemID)
{
}
public CannonComponent(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public MilitiaCanoneer Canoneer
{
get => Addon is Cannon cannon ? cannon.Canoneer : null;
set
{
if (Addon is Cannon cannon)
case CannonDirection.North:
{
cannon.Canoneer = value;
AddComponent(new CannonComponent(0xE8D), 0, 0, 0);
AddComponent(new CannonComponent(0xE8C), 0, 1, 0);
AddComponent(new CannonComponent(0xE8B), 0, 2, 0);
break;
}
}
case CannonDirection.East:
{
AddComponent(new CannonComponent(0xE96), 0, 0, 0);
AddComponent(new CannonComponent(0xE95), -1, 0, 0);
AddComponent(new CannonComponent(0xE94), -2, 0, 0);
break;
}
case CannonDirection.South:
{
AddComponent(new CannonComponent(0xE91), 0, 0, 0);
AddComponent(new CannonComponent(0xE92), 0, -1, 0);
AddComponent(new CannonComponent(0xE93), 0, -2, 0);
break;
}
default:
{
AddComponent(new CannonComponent(0xE8E), 0, 0, 0);
AddComponent(new CannonComponent(0xE8F), 1, 0, 0);
AddComponent(new CannonComponent(0xE90), 2, 0, 0);
break;
}
}
}
public override bool HandlesOnMovement => _canoneer?.Deleted == false && _canoneer.Active;
public void DoFireEffect(Point3D target)
{
var from = _cannonDirection switch
{
CannonDirection.North => new Point3D(X, Y - 1, Z),
CannonDirection.East => new Point3D(X + 1, Y, Z),
CannonDirection.South => new Point3D(X, Y + 1, Z),
_ => new Point3D(X - 1, Y, Z)
};
Effects.SendLocationEffect(from, Map, 0x36B0, 16, 1);
Effects.PlaySound(from, Map, 0x11D);
Effects.SendLocationEffect(target, Map, 0x36B0, 16, 1);
Effects.PlaySound(target, Map, 0x11D);
}
public void Fire(Mobile from, Mobile target)
{
DoFireEffect(target.Location);
target.Damage(9999, from);
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
if (!(Canoneer?.Deleted == false && Canoneer.Active))
{
return;
}
public override void Serialize(IGenericWriter writer)
var canFire = CannonDirection switch
{
base.Serialize(writer);
CannonDirection.North => m.X >= X - 7 && m.X <= X + 7 && m.Y == Y - 7 && oldLocation.Y < Y - 7,
CannonDirection.East => m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X + 7 && oldLocation.X > X + 7,
CannonDirection.South => m.X >= X - 7 && m.X <= X + 7 && m.Y == Y + 7 && oldLocation.Y > Y + 7,
_ => m.Y >= Y - 7 && m.Y <= Y + 7 && m.X == X - 7 && oldLocation.X < X - 7
};
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
if (canFire && Canoneer.WillFire(this, m))
{
base.Deserialize(reader);
var version = reader.ReadInt();
Fire(Canoneer, m);
}
}
}
[SerializationGenerator(0, false)]
public partial class CannonComponent : AddonComponent
{
public CannonComponent(int itemID) : base(itemID)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public MilitiaCanoneer Canoneer
{
get => (Addon as Cannon)?.Canoneer;
set
{
if (Addon is Cannon cannon)
{
cannon.Canoneer = value;
}
}
}
}

View file

@ -1,74 +1,56 @@
using ModernUO.Serialization;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class DaemonBloodChest : MetalChest
{
public class DaemonBloodChest : MetalChest
[Constructible]
public DaemonBloodChest() => Movable = false;
public override void OnDoubleClick(Mobile from)
{
[Constructible]
public DaemonBloodChest() => Movable = false;
public DaemonBloodChest(Serial serial) : base(serial)
if (from is not PlayerMobile player || !player.InRange(GetWorldLocation(), 2))
{
}
public override void OnDoubleClick(Mobile from)
{
if (from is PlayerMobile player && player.InRange(GetWorldLocation(), 2))
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
{
QuestObjective obj = qs.FindObjective<GetDaemonBloodObjective>();
if (obj?.Completed == false || UzeraanTurmoilQuest.HasLostDaemonBlood(player))
{
Item vial = new QuestDaemonBlood();
if (player.PlaceInBackpack(vial))
{
player.SendLocalizedMessage(
1049331,
"",
0x22
); // You take a vial of blood from the chest and put it in your pack.
if (obj?.Completed == false)
{
obj.Complete();
}
}
else
{
player.SendLocalizedMessage(
1049338,
"",
0x22
); // You find a vial of blood, but can't pick it up because your pack is too full. Come back when you have more room in your pack.
vial.Delete();
}
return;
}
}
}
base.OnDoubleClick(from);
return;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
var qs = player.Quest;
writer.Write(0); // version
if (qs is not UzeraanTurmoilQuest)
{
base.OnDoubleClick(from);
return;
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var obj = qs.FindObjective<GetDaemonBloodObjective>();
var version = reader.ReadInt();
if (obj?.Completed != false && !UzeraanTurmoilQuest.HasLostDaemonBlood(player))
{
base.OnDoubleClick(from);
return;
}
Item vial = new QuestDaemonBlood();
if (player.PlaceInBackpack(vial))
{
// You take a vial of blood from the chest and put it in your pack.
player.SendLocalizedMessage(1049331, "", 0x22);
if (obj?.Completed == false)
{
obj.Complete();
}
}
else
{
// You find a vial of blood, but can't pick it up because your pack is too full. Come back when you have more room in your pack.
player.SendLocalizedMessage(1049338, "", 0x22);
vial.Delete();
}
}
}

View file

@ -1,30 +1,13 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class QuestDaemonBlood : QuestItem
{
public class QuestDaemonBlood : QuestItem
{
[Constructible]
public QuestDaemonBlood() : base(0xF7D) => Weight = 1.0;
[Constructible]
public QuestDaemonBlood() : base(0xF7D) => Weight = 1.0;
public QuestDaemonBlood(Serial serial) : base(serial)
{
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
}

View file

@ -1,30 +1,13 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class QuestDaemonBone : QuestItem
{
public class QuestDaemonBone : QuestItem
{
[Constructible]
public QuestDaemonBone() : base(0xF80) => Weight = 1.0;
[Constructible]
public QuestDaemonBone() : base(0xF80) => Weight = 1.0;
public QuestDaemonBone(Serial serial) : base(serial)
{
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
}

View file

@ -1,30 +1,13 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class QuestFertileDirt : QuestItem
{
public class QuestFertileDirt : QuestItem
{
[Constructible]
public QuestFertileDirt() : base(0xF81) => Weight = 1.0;
[Constructible]
public QuestFertileDirt() : base(0xF81) => Weight = 1.0;
public QuestFertileDirt(Serial serial) : base(serial)
{
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public override bool CanDrop(PlayerMobile player) => player.Quest is not UzeraanTurmoilQuest;
}

View file

@ -1,211 +1,156 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class SchmendrickApprenticeCorpse : Corpse
{
public class SchmendrickApprenticeCorpse : Corpse
private static int _hairHue;
[SerializableField(0, setter: "private")]
private Lantern _lantern;
[Constructible]
public SchmendrickApprenticeCorpse() : base(GetOwner(), GetHair(), GetFacialHair(), GetEquipment())
{
private static int m_HairHue;
Direction = Direction.West;
private Lantern m_Lantern;
[Constructible]
public SchmendrickApprenticeCorpse() : base(GetOwner(), GetHair(), GetFacialHair(), GetEquipment())
foreach (var item in EquipItems)
{
Direction = Direction.West;
foreach (var item in EquipItems)
{
DropItem(item);
}
m_Lantern = new Lantern { Movable = false, Protected = true };
m_Lantern.Ignite();
DropItem(item);
}
public SchmendrickApprenticeCorpse(Serial serial) : base(serial)
_lantern = new Lantern { Movable = false, Protected = true };
_lantern.Ignite();
}
private static Mobile GetOwner()
{
var apprentice = new Mobile
{
Hue = Race.Human.RandomSkinHue(),
Female = false,
Body = 0x190,
Name = NameList.RandomName("male")
};
apprentice.Delete();
return apprentice;
}
private static List<Item> GetEquipment() =>
[
new Robe(QuestSystem.RandomBrightHue()),
new WizardsHat(Utility.RandomNeutralHue()),
new Shoes(Utility.RandomNeutralHue()),
new Spellbook()
];
private static HairInfo GetHair()
{
_hairHue = Race.Human.RandomHairHue();
return new HairInfo(Race.Human.RandomHair(false), _hairHue);
}
private static FacialHairInfo GetFacialHair()
{
_hairHue = Race.Human.RandomHairHue();
return new FacialHairInfo(Race.Human.RandomFacialHair(false), _hairHue);
}
public override void AddNameProperty(IPropertyList list)
{
if (ItemID == 0x2006) // Corpse form
{
list.Add("a human corpse");
list.Add(1049144, Name); // the remains of ~1_NAME~ the apprentice
}
else
{
list.Add(1049145); // the remains of a wizard's apprentice
}
}
public override void OnSingleClick(Mobile from)
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
if (ItemID == 0x2006) // Corpse form
{
// the remains of ~1_NAME~ the apprentice
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049144, "", Name);
}
else
{
// the remains of a wizard's apprentice
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049145);
}
}
public override void Open(Mobile from, bool checkSelfLoot)
{
if (!from.InRange(GetWorldLocation(), 2))
{
return;
}
// TODO: What is this? Why are we creating and deleting a mobile?
private static Mobile GetOwner()
if (from is not PlayerMobile player)
{
var apprentice = new Mobile();
apprentice.Hue = Race.Human.RandomSkinHue();
apprentice.Female = false;
apprentice.Body = 0x190;
apprentice.Name = NameList.RandomName("male");
apprentice.Delete();
return apprentice;
return;
}
private static List<Item> GetEquipment()
if (player.Quest is not UzeraanTurmoilQuest qs || qs.FindObjective<FindApprenticeObjective>() is not
{ Completed: false } obj)
{
var list = new List<Item>();
list.Add(new Robe(QuestSystem.RandomBrightHue()));
list.Add(new WizardsHat(Utility.RandomNeutralHue()));
list.Add(new Shoes(Utility.RandomNeutralHue()));
list.Add(new Spellbook());
return list;
// This is the corpse of a wizard's apprentice. You can't bring yourself to search it without a good reason.
from.SendLocalizedMessage(1049143, "", 0x22);
return;
}
private static HairInfo GetHair()
var scroll = new SchmendrickScrollOfPower();
if (player.PlaceInBackpack(scroll))
{
m_HairHue = Race.Human.RandomHairHue();
return new HairInfo(Race.Human.RandomHair(false), m_HairHue);
player.SendLocalizedMessage(1049147, "", 0x22); // You find the scroll and put it in your pack.
obj.Complete();
}
private static FacialHairInfo GetFacialHair()
else
{
m_HairHue = Race.Human.RandomHairHue();
return new FacialHairInfo(Race.Human.RandomFacialHair(false), m_HairHue);
// You find the scroll, but can't pick it up because your pack is too full. Come back when you have more room in your pack.
player.SendLocalizedMessage(1049146, "", 0x22);
scroll.Delete();
}
}
public override void AddNameProperty(IPropertyList list)
public override void OnLocationChange(Point3D oldLoc)
{
if (_lantern?.Deleted == false)
{
if (ItemID == 0x2006) // Corpse form
{
list.Add("a human corpse");
list.Add(1049144, Name); // the remains of ~1_NAME~ the apprentice
}
else
{
list.Add(1049145); // the remains of a wizard's apprentice
}
_lantern.Location = new Point3D(X, Y + 1, Z);
}
}
public override void OnSingleClick(Mobile from)
public override void OnMapChange()
{
if (_lantern?.Deleted == false)
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
if (ItemID == 0x2006) // Corpse form
{
from.NetState.SendMessageLocalized(
Serial,
ItemID,
MessageType.Label,
hue,
3,
1049144,
"",
Name
); // the remains of ~1_NAME~ the apprentice
}
else
{
from.NetState.SendMessageLocalized(
Serial,
ItemID,
MessageType.Label,
hue,
3,
1049145
); // the remains of a wizard's apprentice
}
_lantern.Map = Map;
}
}
public override void Open(Mobile from, bool checkSelfLoot)
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (_lantern?.Deleted == false)
{
if (!from.InRange(GetWorldLocation(), 2))
{
return;
}
if (from is PlayerMobile player)
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
{
QuestObjective obj = qs.FindObjective<FindApprenticeObjective>();
if (obj?.Completed == false)
{
Item scroll = new SchmendrickScrollOfPower();
if (player.PlaceInBackpack(scroll))
{
player.SendLocalizedMessage(1049147, "", 0x22); // You find the scroll and put it in your pack.
obj.Complete();
}
else
{
player.SendLocalizedMessage(
1049146,
"",
0x22
); // You find the scroll, but can't pick it up because your pack is too full. Come back when you have more room in your pack.
scroll.Delete();
}
return;
}
}
}
from.SendLocalizedMessage(
1049143,
"",
0x22
); // This is the corpse of a wizard's apprentice. You can't bring yourself to search it without a good reason.
}
public override void OnLocationChange(Point3D oldLoc)
{
if (m_Lantern?.Deleted == false)
{
m_Lantern.Location = new Point3D(X, Y + 1, Z);
}
}
public override void OnMapChange()
{
if (m_Lantern?.Deleted == false)
{
m_Lantern.Map = Map;
}
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
if (m_Lantern?.Deleted == false)
{
m_Lantern.Delete();
}
}
public override void Serialize(IGenericWriter writer)
{
if (m_Lantern?.Deleted == true)
{
m_Lantern = null;
}
base.Serialize(writer);
writer.Write(0); // version
writer.Write(m_Lantern);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Lantern = (Lantern)reader.ReadEntity<Item>();
_lantern.Delete();
}
}
}

View file

@ -1,37 +1,20 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class SchmendrickScrollOfPower : QuestItem
{
public class SchmendrickScrollOfPower : QuestItem
public SchmendrickScrollOfPower() : base(0xE34)
{
public SchmendrickScrollOfPower() : base(0xE34)
{
Weight = 1.0;
Hue = 0x34D;
}
public SchmendrickScrollOfPower(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1049118; // a scroll with ancient markings
public override bool CanDrop(PlayerMobile player) =>
!(player.Quest is UzeraanTurmoilQuest qs &&
qs.IsObjectiveInProgress(typeof(ReturnScrollOfPowerObjective)));
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
Weight = 1.0;
Hue = 0x34D;
}
public override int LabelNumber => 1049118; // a scroll with ancient markings
public override bool CanDrop(PlayerMobile player) =>
!(player.Quest is UzeraanTurmoilQuest qs &&
qs.IsObjectiveInProgress(typeof(ReturnScrollOfPowerObjective)));
}

View file

@ -1,34 +1,17 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class UzeraanTurmoilHorn : HornOfRetreat
{
public class UzeraanTurmoilHorn : HornOfRetreat
[Constructible]
public UzeraanTurmoilHorn()
{
[Constructible]
public UzeraanTurmoilHorn()
{
DestLoc = new Point3D(3597, 2582, 0);
DestMap = Map.Trammel;
}
public UzeraanTurmoilHorn(Serial serial) : base(serial)
{
}
public override bool ValidateUse(Mobile from) => from is PlayerMobile pm && pm.Quest is UzeraanTurmoilQuest;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
DestLoc = new Point3D(3597, 2582, 0);
DestMap = Map.Trammel;
}
public override bool ValidateUse(Mobile from) => from is PlayerMobile pm && pm.Quest is UzeraanTurmoilQuest;
}

View file

@ -1,73 +1,58 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class UzeraanTurmoilTeleporter : DynamicTeleporter
{
public class UzeraanTurmoilTeleporter : DynamicTeleporter
[Constructible]
public UzeraanTurmoilTeleporter()
{
[Constructible]
public UzeraanTurmoilTeleporter()
}
public override bool GetDestination(PlayerMobile player, ref Point3D loc, ref Map map)
{
var qs = player.Quest;
if (qs is not UzeraanTurmoilQuest)
{
}
public UzeraanTurmoilTeleporter(Serial serial) : base(serial)
{
}
public override bool GetDestination(PlayerMobile player, ref Point3D loc, ref Map map)
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
{
if (qs.IsObjectiveInProgress(typeof(FindSchmendrickObjective))
|| qs.IsObjectiveInProgress(typeof(FindApprenticeObjective))
|| UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
loc = new Point3D(5222, 1858, 0);
map = Map.Trammel;
return true;
}
if (qs.IsObjectiveInProgress(typeof(FindDryadObjective))
|| UzeraanTurmoilQuest.HasLostFertileDirt(player))
{
loc = new Point3D(3557, 2690, 2);
map = Map.Trammel;
return true;
}
if (player.Profession != 5 // paladin
&& (qs.IsObjectiveInProgress(typeof(GetDaemonBoneObjective))
|| UzeraanTurmoilQuest.HasLostDaemonBone(player)))
{
loc = new Point3D(3422, 2653, 48);
map = Map.Trammel;
return true;
}
if (qs.IsObjectiveInProgress(typeof(CashBankCheckObjective)))
{
loc = new Point3D(3624, 2610, 0);
map = Map.Trammel;
return true;
}
}
return false;
}
public override void Serialize(IGenericWriter writer)
if (qs.IsObjectiveInProgress(typeof(FindSchmendrickObjective))
|| qs.IsObjectiveInProgress(typeof(FindApprenticeObjective))
|| UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
base.Serialize(writer);
writer.Write(0); // version
loc = new Point3D(5222, 1858, 0);
map = Map.Trammel;
return true;
}
public override void Deserialize(IGenericReader reader)
if (qs.IsObjectiveInProgress(typeof(FindDryadObjective))
|| UzeraanTurmoilQuest.HasLostFertileDirt(player))
{
base.Deserialize(reader);
var version = reader.ReadInt();
loc = new Point3D(3557, 2690, 2);
map = Map.Trammel;
return true;
}
if (player.Profession != 5 // paladin
&& (qs.IsObjectiveInProgress(typeof(GetDaemonBoneObjective))
|| UzeraanTurmoilQuest.HasLostDaemonBone(player)))
{
loc = new Point3D(3422, 2653, 48);
map = Map.Trammel;
return true;
}
if (qs.IsObjectiveInProgress(typeof(CashBankCheckObjective)))
{
loc = new Point3D(3624, 2610, 0);
map = Map.Trammel;
return true;
}
return false;
}
}

View file

@ -1,116 +1,82 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class Dryad : BaseQuester
{
public class Dryad : BaseQuester
[Constructible]
public Dryad() : base("the Dryad")
{
[Constructible]
public Dryad() : base("the Dryad")
SetSkill(SkillName.Peacemaking, 80.0, 100.0);
SetSkill(SkillName.Cooking, 80.0, 100.0);
SetSkill(SkillName.Provocation, 80.0, 100.0);
SetSkill(SkillName.Musicianship, 80.0, 100.0);
SetSkill(SkillName.Poisoning, 80.0, 100.0);
SetSkill(SkillName.Archery, 80.0, 100.0);
SetSkill(SkillName.Tailoring, 80.0, 100.0);
}
public override bool IsActiveVendor => true;
public override bool DisallowAllMoves => false;
public override bool ClickTitle => true;
public override bool CanTeach => true;
public override string DefaultName => "Anwin Brenna";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x85A7;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
AddItem(new Kilt(0x301));
AddItem(new FancyShirt(0x300));
HairItemID = 0x203D; // Pony Tail
HairHue = 0x22;
var bow = new Bow();
bow.Movable = false;
AddItem(bow);
}
public override void InitSBInfo()
{
_sbInfos.Add(new SBDryad());
}
public override int GetAutoTalkRange(PlayerMobile pm) => 4;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is UzeraanTurmoilQuest qs && qs.FindObjective<FindDryadObjective>() != null;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
{
SetSkill(SkillName.Peacemaking, 80.0, 100.0);
SetSkill(SkillName.Cooking, 80.0, 100.0);
SetSkill(SkillName.Provocation, 80.0, 100.0);
SetSkill(SkillName.Musicianship, 80.0, 100.0);
SetSkill(SkillName.Poisoning, 80.0, 100.0);
SetSkill(SkillName.Archery, 80.0, 100.0);
SetSkill(SkillName.Tailoring, 80.0, 100.0);
}
public Dryad(Serial serial) : base(serial)
{
}
public override bool IsActiveVendor => true;
public override bool DisallowAllMoves => false;
public override bool ClickTitle => true;
public override bool CanTeach => true;
public override string DefaultName => "Anwin Brenna";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x85A7;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
AddItem(new Kilt(0x301));
AddItem(new FancyShirt(0x300));
HairItemID = 0x203D; // Pony Tail
HairHue = 0x22;
var bow = new Bow();
bow.Movable = false;
AddItem(bow);
}
public override void InitSBInfo()
{
_sbInfos.Add(new SBDryad());
}
public override int GetAutoTalkRange(PlayerMobile pm) => 4;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is UzeraanTurmoilQuest qs && qs.FindObjective<FindDryadObjective>() != null;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
if (UzeraanTurmoilQuest.HasLostFertileDirt(player))
{
if (UzeraanTurmoilQuest.HasLostFertileDirt(player))
FocusTo(player);
qs.AddConversation(new LostFertileDirtConversation(false));
}
else
{
var obj = qs.FindObjective<FindDryadObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
qs.AddConversation(new LostFertileDirtConversation(false));
}
else
{
QuestObjective obj = qs.FindObjective<FindDryadObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
Item fertileDirt = new QuestFertileDirt();
if (!player.PlaceInBackpack(fertileDirt))
{
fertileDirt.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
else
{
obj.Complete();
}
}
else if (contextMenu)
{
FocusTo(player);
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (from is PlayerMobile player)
{
if (player.Quest is UzeraanTurmoilQuest qs && dropped is Apple &&
UzeraanTurmoilQuest.HasLostFertileDirt(from))
{
FocusTo(from);
Item fertileDirt = new QuestFertileDirt();
@ -120,65 +86,78 @@ namespace Server.Engines.Quests.Haven
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Consume();
qs.AddConversation(new DryadAppleConversation());
return dropped.Deleted;
else
{
obj.Complete();
}
}
else if (contextMenu)
{
FocusTo(player);
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (from is not PlayerMobile { Quest: UzeraanTurmoilQuest qs } player || dropped is not Apple ||
!UzeraanTurmoilQuest.HasLostFertileDirt(from))
{
return base.OnDragDrop(from, dropped);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
FocusTo(from);
writer.Write(0); // version
Item fertileDirt = new QuestFertileDirt();
if (!player.PlaceInBackpack(fertileDirt))
{
fertileDirt.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
return false;
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
dropped.Consume();
qs.AddConversation(new DryadAppleConversation());
return dropped.Deleted;
}
}
var version = reader.ReadInt();
public class SBDryad : SBInfo
{
public override IShopSellInfo SellInfo { get; } = new InternalSellInfo();
public override List<GenericBuyInfo> BuyInfo { get; } = new InternalBuyInfo();
public class InternalBuyInfo : List<GenericBuyInfo>
{
public InternalBuyInfo()
{
Add(new GenericBuyInfo(typeof(Bandage), 5, 20, 0xE21, 0));
Add(new GenericBuyInfo(typeof(Ginseng), 3, 20, 0xF85, 0));
Add(new GenericBuyInfo(typeof(Garlic), 3, 20, 0xF84, 0));
Add(new GenericBuyInfo(typeof(Bloodmoss), 5, 20, 0xF7B, 0));
Add(new GenericBuyInfo(typeof(Nightshade), 3, 20, 0xF88, 0));
Add(new GenericBuyInfo(typeof(SpidersSilk), 3, 20, 0xF8D, 0));
Add(new GenericBuyInfo(typeof(MandrakeRoot), 3, 20, 0xF86, 0));
}
}
public class SBDryad : SBInfo
public class InternalSellInfo : GenericSellInfo
{
public override IShopSellInfo SellInfo { get; } = new InternalSellInfo();
public override List<GenericBuyInfo> BuyInfo { get; } = new InternalBuyInfo();
public class InternalBuyInfo : List<GenericBuyInfo>
public InternalSellInfo()
{
public InternalBuyInfo()
{
Add(new GenericBuyInfo(typeof(Bandage), 5, 20, 0xE21, 0));
Add(new GenericBuyInfo(typeof(Ginseng), 3, 20, 0xF85, 0));
Add(new GenericBuyInfo(typeof(Garlic), 3, 20, 0xF84, 0));
Add(new GenericBuyInfo(typeof(Bloodmoss), 5, 20, 0xF7B, 0));
Add(new GenericBuyInfo(typeof(Nightshade), 3, 20, 0xF88, 0));
Add(new GenericBuyInfo(typeof(SpidersSilk), 3, 20, 0xF8D, 0));
Add(new GenericBuyInfo(typeof(MandrakeRoot), 3, 20, 0xF86, 0));
}
}
public class InternalSellInfo : GenericSellInfo
{
public InternalSellInfo()
{
Add(typeof(Bandage), 2);
Add(typeof(Garlic), 2);
Add(typeof(Ginseng), 2);
Add(typeof(Bloodmoss), 3);
Add(typeof(Nightshade), 2);
Add(typeof(SpidersSilk), 2);
Add(typeof(MandrakeRoot), 2);
}
Add(typeof(Bandage), 2);
Add(typeof(Garlic), 2);
Add(typeof(Ginseng), 2);
Add(typeof(Bloodmoss), 3);
Add(typeof(Nightshade), 2);
Add(typeof(SpidersSilk), 2);
Add(typeof(MandrakeRoot), 2);
}
}
}

View file

@ -1,72 +1,55 @@
using ModernUO.Serialization;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class MansionGuard : BaseQuester
{
public class MansionGuard : BaseQuester
[Constructible]
public MansionGuard() : base("the Mansion Guard")
{
[Constructible]
public MansionGuard() : base("the Mansion Guard")
}
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
AddItem(new PlateChest());
AddItem(new PlateArms());
AddItem(new PlateGloves());
AddItem(new PlateLegs());
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
var weapon = new Bardiche();
weapon.Movable = false;
AddItem(weapon);
}
public override int GetAutoTalkRange(PlayerMobile pm) => 3;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest == null && QuestSystem.CanOfferQuest(to, typeof(UzeraanTurmoilQuest));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(UzeraanTurmoilQuest)))
{
}
Direction = GetDirectionTo(player);
public MansionGuard(Serial serial) : base(serial)
{
}
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
AddItem(new PlateChest());
AddItem(new PlateArms());
AddItem(new PlateGloves());
AddItem(new PlateLegs());
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
var weapon = new Bardiche();
weapon.Movable = false;
AddItem(weapon);
}
public override int GetAutoTalkRange(PlayerMobile pm) => 3;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest == null && QuestSystem.CanOfferQuest(to, typeof(UzeraanTurmoilQuest));
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
if (player.Quest == null && QuestSystem.CanOfferQuest(player, typeof(UzeraanTurmoilQuest)))
{
Direction = GetDirectionTo(player);
new UzeraanTurmoilQuest(player).SendOffer();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
new UzeraanTurmoilQuest(player).SendOffer();
}
}
}

View file

@ -1,100 +1,91 @@
using ModernUO.Serialization;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class MilitiaCanoneer : BaseQuester
{
public class MilitiaCanoneer : BaseQuester
private static readonly int[] _cannonFireClilocs = [
500651, // You're evil, and must die!
1049098, // I shall make short work of thee.
1049320, // FIRE!
1043149 // Thou deservest to die!
];
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _active;
[Constructible]
public MilitiaCanoneer() : base("the Militia Canoneer") => _active = true;
public override void InitBody()
{
[Constructible]
public MilitiaCanoneer() : base("the Militia Canoneer") => Active = true;
InitStats(100, 125, 25);
public MilitiaCanoneer(Serial serial) : base(serial)
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
AddItem(new PlateChest());
AddItem(new PlateArms());
AddItem(new PlateGloves());
AddItem(new PlateLegs());
var torch = new Torch
{
}
Movable = false
};
[CommandProperty(AccessLevel.GameMaster)]
public bool Active { get; set; }
AddItem(torch);
torch.Ignite();
}
public override void InitBody()
public override bool CanTalkTo(PlayerMobile to) => false;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
}
public override bool IsEnemy(Mobile m)
{
while (!m.Player && m is not BaseVendor)
{
InitStats(100, 125, 25);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
}
public override void InitOutfit()
{
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
AddItem(new PlateChest());
AddItem(new PlateArms());
AddItem(new PlateGloves());
AddItem(new PlateLegs());
var torch = new Torch();
torch.Movable = false;
AddItem(torch);
torch.Ignite();
}
public override bool CanTalkTo(PlayerMobile to) => false;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
}
public override bool IsEnemy(Mobile m)
{
if (m.Player || m is BaseVendor)
{
return false;
}
if (m is BaseCreature bc)
{
var master = bc.GetMaster();
if (master != null)
{
return IsEnemy(master);
m = master;
continue;
}
}
return m.Karma < 0;
}
public bool WillFire(Cannon cannon, Mobile target)
{
if (Active && IsEnemy(target))
{
Direction = GetDirectionTo(target);
Say(Utility.RandomList(500651, 1049098, 1049320, 1043149));
return true;
}
return false;
}
return false;
public bool WillFire(Cannon cannon, Mobile target)
{
if (_active && IsEnemy(target))
{
Direction = GetDirectionTo(target);
Say(_cannonFireClilocs.RandomElement());
return true;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
writer.Write(Active);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
Active = reader.ReadBool();
}
return false;
}
}

View file

@ -1,180 +1,133 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class MilitiaFighter : BaseCreature
{
public class MilitiaFighter : BaseCreature
[Constructible]
public MilitiaFighter() : base(AIType.AI_Melee)
{
[Constructible]
public MilitiaFighter() : base(AIType.AI_Melee)
InitStats(40, 30, 5);
Title = "the Militia Fighter";
SpeechHue = Utility.RandomDyedHue();
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
AddItem(new ThighBoots(0x1BB));
AddItem(new LeatherChest());
AddItem(new LeatherArms());
AddItem(new LeatherLegs());
AddItem(new LeatherCap());
AddItem(new LeatherGloves());
AddItem(new LeatherGorget());
var weapon = Utility.Random(6) switch
{
InitStats(40, 30, 5);
Title = "the Militia Fighter";
0 => (Item)new Broadsword(),
1 => new Cutlass(),
2 => new Katana(),
3 => new Longsword(),
4 => new Scimitar(),
_ => new VikingSword()
};
SpeechHue = Utility.RandomDyedHue();
weapon.Movable = false;
AddItem(weapon);
Hue = Race.Human.RandomSkinHue();
Female = false;
Body = 0x190;
Name = NameList.RandomName("male");
Utility.AssignRandomHair(this);
Utility.AssignRandomFacialHair(this, HairHue);
AddItem(new ThighBoots(0x1BB));
AddItem(new LeatherChest());
AddItem(new LeatherArms());
AddItem(new LeatherLegs());
AddItem(new LeatherCap());
AddItem(new LeatherGloves());
AddItem(new LeatherGorget());
var weapon = Utility.Random(6) switch
{
0 => (Item)new Broadsword(),
1 => new Cutlass(),
2 => new Katana(),
3 => new Longsword(),
4 => new Scimitar(),
_ => new VikingSword()
};
weapon.Movable = false;
AddItem(weapon);
Item shield = new BronzeShield();
shield.Movable = false;
AddItem(shield);
SetSkill(SkillName.Swords, 20.0);
}
public MilitiaFighter(Serial serial) : base(serial)
Item shield = new BronzeShield
{
}
Movable = false
};
public override bool ClickTitle => false;
AddItem(shield);
public override bool IsEnemy(Mobile m)
SetSkill(SkillName.Swords, 20.0);
}
public override bool ClickTitle => false;
public override bool IsEnemy(Mobile m)
{
while (!m.Player && m is not BaseVendor)
{
if (m.Player || m is BaseVendor)
{
return false;
}
if (m is BaseCreature bc)
{
var master = bc.GetMaster();
if (master != null)
{
return IsEnemy(master);
m = master;
continue;
}
}
return m.Karma < 0;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
return false;
}
}
writer.Write(0); // version
[SerializationGenerator(0, false)]
public partial class MilitiaFighterCorpse : Corpse
{
public MilitiaFighterCorpse(Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> equipItems) : base(
owner,
hair,
facialhair,
equipItems
)
{
}
public override void AddNameProperty(IPropertyList list)
{
if (ItemID == 0x2006) // Corpse form
{
list.Add("a human corpse");
list.Add(1049318, Name); // the remains of ~1_NAME~ the militia fighter
}
public override void Deserialize(IGenericReader reader)
else
{
base.Deserialize(reader);
var version = reader.ReadInt();
list.Add(1049319); // the remains of a militia fighter
}
}
public class MilitiaFighterCorpse : Corpse
public override void OnSingleClick(Mobile from)
{
public MilitiaFighterCorpse(Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> equipItems) : base(
owner,
hair,
facialhair,
equipItems
)
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
if (ItemID == 0x2006) // Corpse form
{
// the remains of ~1_NAME~ the militia fighter
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049318, "", Name);
}
public MilitiaFighterCorpse(Serial serial) : base(serial)
else
{
// the remains of a militia fighter
from.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Label, hue, 3, 1049319);
}
}
public override void AddNameProperty(IPropertyList list)
public override void Open(Mobile from, bool checkSelfLoot)
{
if (from.InRange(GetWorldLocation(), 2))
{
if (ItemID == 0x2006) // Corpse form
{
list.Add("a human corpse");
list.Add(1049318, Name); // the remains of ~1_NAME~ the militia fighter
}
else
{
list.Add(1049319); // the remains of a militia fighter
}
}
public override void OnSingleClick(Mobile from)
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
if (ItemID == 0x2006) // Corpse form
{
from.NetState.SendMessageLocalized(
Serial,
ItemID,
MessageType.Label,
hue,
3,
1049318,
"",
Name
); // the remains of ~1_NAME~ the militia fighter
}
else
{
from.NetState.SendMessageLocalized(
Serial,
ItemID,
MessageType.Label,
hue,
3,
1049319
); // the remains of a militia fighter
}
}
public override void Open(Mobile from, bool checkSelfLoot)
{
if (from.InRange(GetWorldLocation(), 2))
{
from.SendLocalizedMessage(
1049661,
"",
0x22
); // Thinking about his sacrifice, you can't bring yourself to loot the body of this militia fighter.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
// Thinking about his sacrifice, you can't bring yourself to loot the body of this militia fighter.
from.SendLocalizedMessage(1049661, "", 0x22);
}
}
}

View file

@ -1,149 +1,136 @@
using ModernUO.Serialization;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class Schmendrick : BaseQuester
{
public class Schmendrick : BaseQuester
[Constructible]
public Schmendrick() : base("the High Mage")
{
[Constructible]
public Schmendrick() : base("the High Mage")
}
public override string DefaultName => "Schmendrick";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83F3;
Female = false;
Body = 0x190;
}
public override void InitOutfit()
{
AddItem(new Robe(0x4DD));
AddItem(new WizardsHat(0x482));
AddItem(new Shoes(0x482));
HairItemID = 0x203C;
HairHue = 0x455;
FacialHairItemID = 0x203E;
FacialHairHue = 0x455;
var staff = new GlacialStaff
{
Movable = false
};
AddItem(staff);
var pack = new Backpack
{
Movable = false
};
AddItem(pack);
}
public override int GetAutoTalkRange(PlayerMobile pm) => 7;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is UzeraanTurmoilQuest qs && qs.FindObjective<FindSchmendrickObjective>() != null;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is not UzeraanTurmoilQuest)
{
return;
}
public Schmendrick(Serial serial) : base(serial)
if (UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
FocusTo(player);
qs.AddConversation(new LostScrollOfPowerConversation(false));
return;
}
public override string DefaultName => "Schmendrick";
var obj = qs.FindObjective<FindSchmendrickObjective>();
public override void InitBody()
if (obj?.Completed == false)
{
InitStats(100, 100, 25);
Hue = 0x83F3;
Female = false;
Body = 0x190;
FocusTo(player);
obj.Complete();
}
public override void InitOutfit()
else if (contextMenu)
{
AddItem(new Robe(0x4DD));
AddItem(new WizardsHat(0x482));
AddItem(new Shoes(0x482));
HairItemID = 0x203C;
HairHue = 0x455;
FacialHairItemID = 0x203E;
FacialHairHue = 0x455;
var staff = new GlacialStaff();
staff.Movable = false;
AddItem(staff);
var pack = new Backpack();
pack.Movable = false;
AddItem(pack);
FocusTo(player);
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
public override int GetAutoTalkRange(PlayerMobile pm) => 7;
public override bool CanTalkTo(PlayerMobile to) =>
to.Quest is UzeraanTurmoilQuest qs && qs.FindObjective<FindSchmendrickObjective>() != null;
public override void OnTalk(PlayerMobile player, bool contextMenu)
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is not BlankScroll || !UzeraanTurmoilQuest.HasLostScrollOfPower(from))
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
{
if (UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
FocusTo(player);
qs.AddConversation(new LostScrollOfPowerConversation(false));
}
else
{
QuestObjective obj = qs.FindObjective<FindSchmendrickObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
obj.Complete();
}
else if (contextMenu)
{
FocusTo(player);
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is BlankScroll && UzeraanTurmoilQuest.HasLostScrollOfPower(from))
{
FocusTo(from);
Item scroll = new SchmendrickScrollOfPower();
if (!from.PlaceInBackpack(scroll))
{
scroll.Delete();
from.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Consume();
from.SendLocalizedMessage(
1049346
); // Schmendrick scribbles on the scroll for a few moments and hands you the finished product.
return dropped.Deleted;
}
return base.OnDragDrop(from, dropped);
}
public override void OnMovement(Mobile m, Point3D oldLocation)
FocusTo(from);
var scroll = new SchmendrickScrollOfPower();
if (!from.PlaceInBackpack(scroll))
{
base.OnMovement(m, oldLocation);
if (m is PlayerMobile && !m.Frozen && !m.Alive && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
{
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
}
scroll.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
from.SendLocalizedMessage(1046260);
return false;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
dropped.Consume();
writer.Write(0); // version
// Schmendrick scribbles on the scroll for a few moments and hands you the finished product.
from.SendLocalizedMessage(1049346);
return dropped.Deleted;
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
base.OnMovement(m, oldLocation);
if (m is not PlayerMobile || m.Frozen || m.Alive || !InRange(m, 4) || InRange(oldLocation, 4) || !InLOS(m))
{
return;
}
public override void Deserialize(IGenericReader reader)
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
return;
}
Direction = GetDirectionTo(m);
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
}

View file

@ -1,427 +1,399 @@
using ModernUO.Serialization;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Haven
namespace Server.Engines.Quests.Haven;
[SerializationGenerator(0, false)]
public partial class Uzeraan : BaseQuester
{
public class Uzeraan : BaseQuester
[Constructible]
public Uzeraan() : base("the Conjurer")
{
[Constructible]
public Uzeraan() : base("the Conjurer")
}
public override string DefaultName => "Uzeraan";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83F3;
Female = false;
Body = 0x190;
}
public override void InitOutfit()
{
AddItem(new Robe(0x4DD));
AddItem(new WizardsHat(0x8A5));
AddItem(new Shoes(0x8A5));
HairItemID = 0x203C;
HairHue = 0x455;
FacialHairItemID = 0x203E;
FacialHairHue = 0x455;
var staff = new BlackStaff
{
Movable = false
};
AddItem(staff);
}
public override int GetAutoTalkRange(PlayerMobile pm) => 3;
public override bool CanTalkTo(PlayerMobile to) => to.Quest is UzeraanTurmoilQuest;
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
var qs = player.Quest;
if (qs is not UzeraanTurmoilQuest)
{
return;
}
public Uzeraan(Serial serial) : base(serial)
if (UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
qs.AddConversation(new LostScrollOfPowerConversation(true));
return;
}
public override string DefaultName => "Uzeraan";
public override void InitBody()
if (UzeraanTurmoilQuest.HasLostFertileDirt(player))
{
InitStats(100, 100, 25);
Hue = 0x83F3;
Female = false;
Body = 0x190;
qs.AddConversation(new LostFertileDirtConversation(true));
return;
}
public override void InitOutfit()
if (UzeraanTurmoilQuest.HasLostDaemonBlood(player))
{
AddItem(new Robe(0x4DD));
AddItem(new WizardsHat(0x8A5));
AddItem(new Shoes(0x8A5));
HairItemID = 0x203C;
HairHue = 0x455;
FacialHairItemID = 0x203E;
FacialHairHue = 0x455;
var staff = new BlackStaff();
staff.Movable = false;
AddItem(staff);
qs.AddConversation(new LostDaemonBloodConversation());
return;
}
public override int GetAutoTalkRange(PlayerMobile pm) => 3;
public override bool CanTalkTo(PlayerMobile to) => to.Quest is UzeraanTurmoilQuest;
public override void OnTalk(PlayerMobile player, bool contextMenu)
if (UzeraanTurmoilQuest.HasLostDaemonBone(player))
{
var qs = player.Quest;
qs.AddConversation(new LostDaemonBoneConversation());
return;
}
if (qs is UzeraanTurmoilQuest)
if (player.Profession == 2) // magician
{
var backpack = player.Backpack;
if (backpack == null
|| backpack.GetAmount(typeof(BlackPearl)) < 30
|| backpack.GetAmount(typeof(Bloodmoss)) < 30
|| backpack.GetAmount(typeof(Garlic)) < 30
|| backpack.GetAmount(typeof(Ginseng)) < 30
|| backpack.GetAmount(typeof(MandrakeRoot)) < 30
|| backpack.GetAmount(typeof(Nightshade)) < 30
|| backpack.GetAmount(typeof(SulfurousAsh)) < 30
|| backpack.GetAmount(typeof(SpidersSilk)) < 30)
{
if (UzeraanTurmoilQuest.HasLostScrollOfPower(player))
{
qs.AddConversation(new LostScrollOfPowerConversation(true));
}
else if (UzeraanTurmoilQuest.HasLostFertileDirt(player))
{
qs.AddConversation(new LostFertileDirtConversation(true));
}
else if (UzeraanTurmoilQuest.HasLostDaemonBlood(player))
{
qs.AddConversation(new LostDaemonBloodConversation());
}
else if (UzeraanTurmoilQuest.HasLostDaemonBone(player))
{
qs.AddConversation(new LostDaemonBoneConversation());
}
else
{
if (player.Profession == 2) // magician
{
var backpack = player.Backpack;
if (backpack == null
|| backpack.GetAmount(typeof(BlackPearl)) < 30
|| backpack.GetAmount(typeof(Bloodmoss)) < 30
|| backpack.GetAmount(typeof(Garlic)) < 30
|| backpack.GetAmount(typeof(Ginseng)) < 30
|| backpack.GetAmount(typeof(MandrakeRoot)) < 30
|| backpack.GetAmount(typeof(Nightshade)) < 30
|| backpack.GetAmount(typeof(SulfurousAsh)) < 30
|| backpack.GetAmount(typeof(SpidersSilk)) < 30)
{
qs.AddConversation(new FewReagentsConversation());
}
}
QuestObjective obj = qs.FindObjective<FindUzeraanBeginObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else
{
obj = qs.FindObjective<FindUzeraanFirstTaskObjective>();
if (obj?.Completed == false)
{
obj.Complete();
}
else
{
obj = qs.FindObjective<FindUzeraanAboutReportObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
if (player.Profession == 2) // magician
{
cont.DropItem(new MarkScroll(5));
cont.DropItem(new RecallScroll(5));
for (var i = 0; i < 5; i++)
{
cont.DropItem(new RecallRune());
}
}
else
{
cont.DropItem(new Gold(300));
for (var i = 0; i < 6; i++)
{
cont.DropItem(new NightSightPotion());
cont.DropItem(new LesserHealPotion());
}
}
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
else
{
obj.Complete();
}
}
else
{
obj = qs.FindObjective<ReturnScrollOfPowerObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049378); // Hand me the scroll, if you have it.
}
else
{
obj = qs.FindObjective<ReturnFertileDirtObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049381); // Hand me the Fertile Dirt, if you have it.
}
else
{
obj = qs.FindObjective<ReturnDaemonBloodObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049379); // Hand me the Vial of Blood, if you have it.
}
else
{
obj = qs.FindObjective<ReturnDaemonBoneObjective>();
if (obj?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049380); // Hand me the Daemon Bone, if you have it.
}
else
{
SayTo(player, 1049357); // I have nothing more for you at this time.
}
}
}
}
}
}
}
}
qs.AddConversation(new FewReagentsConversation());
}
}
public override bool OnDragDrop(Mobile from, Item dropped)
if (qs.FindObjective<FindUzeraanBeginObjective>() is { Completed: false } obj1)
{
if (from is PlayerMobile player)
obj1.Complete();
return;
}
if (qs.FindObjective<FindUzeraanFirstTaskObjective>() is { Completed: false } obj2)
{
obj2.Complete();
return;
}
if (qs.FindObjective<FindUzeraanAboutReportObjective>() is { Completed: false } obj3)
{
var cont = GetNewContainer();
if (player.Profession == 2) // magician
{
var qs = player.Quest;
if (qs is UzeraanTurmoilQuest)
cont.DropItem(new MarkScroll(5));
cont.DropItem(new RecallScroll(5));
for (var i = 0; i < 5; i++)
{
if (dropped is UzeraanTurmoilHorn horn)
{
if (player.Young)
{
if (horn.Charges < 10)
{
SayTo(from, 1049384); // I have recharged the item for you.
horn.Charges = 10;
}
else
{
SayTo(from, 1049385); // That doesn't need recharging yet.
}
}
else
{
player.SendLocalizedMessage(1114333); // You must be young to have this item recharged.
}
return false;
}
if (dropped is SchmendrickScrollOfPower)
{
QuestObjective obj = qs.FindObjective<ReturnScrollOfPowerObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new TreasureMap(player.Young ? 0 : 1, Map.Trammel));
cont.DropItem(new Shovel());
cont.DropItem(new UzeraanTurmoilHorn());
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestFertileDirt)
{
QuestObjective obj = qs.FindObjective<ReturnFertileDirtObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
if (player.Profession == 2) // magician
{
cont.DropItem(new BlackPearl(20));
cont.DropItem(new Bloodmoss(20));
cont.DropItem(new Garlic(20));
cont.DropItem(new Ginseng(20));
cont.DropItem(new MandrakeRoot(20));
cont.DropItem(new Nightshade(20));
cont.DropItem(new SulfurousAsh(20));
cont.DropItem(new SpidersSilk(20));
for (var i = 0; i < 3; i++)
{
cont.DropItem(Loot.RandomScroll(0, 23, SpellbookType.Regular));
}
}
else
{
cont.DropItem(new Gold(300));
cont.DropItem(new Bandage(25));
for (var i = 0; i < 5; i++)
{
cont.DropItem(new LesserHealPotion());
}
}
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestDaemonBlood)
{
QuestObjective obj = qs.FindObjective<ReturnDaemonBloodObjective>();
if (obj?.Completed == false)
{
Item reward;
if (player.Profession == 2) // magician
{
var cont = GetNewContainer();
cont.DropItem(new ExplosionScroll(4));
cont.DropItem(new MagicWizardsHat());
reward = cont;
}
else
{
var weapon = Utility.Random(6) switch
{
0 => (BaseWeapon)new Broadsword(),
1 => new Cutlass(),
2 => new Katana(),
3 => new Longsword(),
4 => new Scimitar(),
_ => new VikingSword()
};
if (Core.AOS)
{
BaseRunicTool.ApplyAttributesTo(weapon, 3, 20, 40);
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 4);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 4);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 4);
}
weapon.Slayer = SlayerName.Silver;
reward = weapon;
}
if (!player.PlaceInBackpack(reward))
{
reward.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestDaemonBone)
{
QuestObjective obj = qs.FindObjective<ReturnDaemonBoneObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new BankCheck(2000));
cont.DropItem(new EnchantedSextant());
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
cont.DropItem(new RecallRune());
}
}
else
{
cont.DropItem(new Gold(300));
for (var i = 0; i < 6; i++)
{
cont.DropItem(new NightSightPotion());
cont.DropItem(new LesserHealPotion());
}
}
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
else
{
obj3.Complete();
}
return;
}
if (qs.FindObjective<ReturnScrollOfPowerObjective>()?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049378); // Hand me the scroll, if you have it.
return;
}
if (qs.FindObjective<ReturnFertileDirtObjective>()?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049381); // Hand me the Fertile Dirt, if you have it.
return;
}
if (qs.FindObjective<ReturnDaemonBloodObjective>()?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049379); // Hand me the Vial of Blood, if you have it.
return;
}
if (qs.FindObjective<ReturnDaemonBoneObjective>()?.Completed == false)
{
FocusTo(player);
SayTo(player, 1049380); // Hand me the Daemon Bone, if you have it.
return;
}
SayTo(player, 1049357); // I have nothing more for you at this time.
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (from is not PlayerMobile player)
{
return base.OnDragDrop(from, dropped);
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
base.OnMovement(m, oldLocation);
var qs = player.Quest;
if (m is PlayerMobile && !m.Frozen && !m.Alive && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
if (qs is not UzeraanTurmoilQuest)
{
return base.OnDragDrop(from, dropped);
}
if (dropped is UzeraanTurmoilHorn horn)
{
if (player.Young)
{
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
if (horn.Charges < 10)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
SayTo(from, 1049384); // I have recharged the item for you.
horn.Charges = 10;
}
else
{
Direction = GetDirectionTo(m);
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
SayTo(from, 1049385); // That doesn't need recharging yet.
}
}
else
{
player.SendLocalizedMessage(1114333); // You must be young to have this item recharged.
}
return false;
}
if (dropped is SchmendrickScrollOfPower)
{
var obj = qs.FindObjective<ReturnScrollOfPowerObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new TreasureMap(player.Young ? 0 : 1, Map.Trammel));
cont.DropItem(new Shovel());
cont.DropItem(new UzeraanTurmoilHorn());
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestFertileDirt)
{
var obj = qs.FindObjective<ReturnFertileDirtObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
if (player.Profession == 2) // magician
{
cont.DropItem(new BlackPearl(20));
cont.DropItem(new Bloodmoss(20));
cont.DropItem(new Garlic(20));
cont.DropItem(new Ginseng(20));
cont.DropItem(new MandrakeRoot(20));
cont.DropItem(new Nightshade(20));
cont.DropItem(new SulfurousAsh(20));
cont.DropItem(new SpidersSilk(20));
for (var i = 0; i < 3; i++)
{
cont.DropItem(Loot.RandomScroll(0, 23, SpellbookType.Regular));
}
}
else
{
cont.DropItem(new Gold(300));
cont.DropItem(new Bandage(25));
for (var i = 0; i < 5; i++)
{
cont.DropItem(new LesserHealPotion());
}
}
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestDaemonBlood)
{
var obj = qs.FindObjective<ReturnDaemonBloodObjective>();
if (obj?.Completed == false)
{
Item reward;
if (player.Profession == 2) // magician
{
var cont = GetNewContainer();
cont.DropItem(new ExplosionScroll(4));
cont.DropItem(new MagicWizardsHat());
reward = cont;
}
else
{
var weapon = Utility.Random(6) switch
{
0 => (BaseWeapon)new Broadsword(),
1 => new Cutlass(),
2 => new Katana(),
3 => new Longsword(),
4 => new Scimitar(),
_ => new VikingSword()
};
if (Core.AOS)
{
BaseRunicTool.ApplyAttributesTo(weapon, 3, 20, 40);
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 4);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 4);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 4);
}
weapon.Slayer = SlayerName.Silver;
reward = weapon;
}
if (!player.PlaceInBackpack(reward))
{
reward.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
else if (dropped is QuestDaemonBone)
{
var obj = qs.FindObjective<ReturnDaemonBoneObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new BankCheck(2000));
cont.DropItem(new EnchantedSextant());
if (!player.PlaceInBackpack(cont))
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
return false;
}
dropped.Delete();
obj.Complete();
return true;
}
}
public override void Serialize(IGenericWriter writer)
return base.OnDragDrop(from, dropped);
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
base.OnMovement(m, oldLocation);
if (m is PlayerMobile && !m.Frozen && !m.Alive && InRange(m, 4) && !InRange(oldLocation, 4) && InLOS(m))
{
base.Serialize(writer);
if (m.Map?.CanFit(m.Location, 16, false, false) != true)
{
m.SendLocalizedMessage(502391); // Thou can not be resurrected there!
}
else
{
Direction = GetDirectionTo(m);
writer.Write(0); // version
}
m.PlaySound(0x214);
m.FixedEffect(0x376A, 10, 16);
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m.CloseGump<ResurrectGump>();
m.SendGump(new ResurrectGump(m, ResurrectMessage.Healer));
}
}
}
}

View file

@ -190,14 +190,14 @@ namespace Server.Engines.Quests.Haven
{
case KillHordeMinionsStep.First:
{
QuestObjective obj = new KillHordeMinionsObjective(KillHordeMinionsStep.LearnKarma);
var obj = new KillHordeMinionsObjective(KillHordeMinionsStep.LearnKarma);
System.AddObjective(obj);
obj.CurProgress = CurProgress;
break;
}
case KillHordeMinionsStep.LearnKarma:
{
QuestObjective obj = new KillHordeMinionsObjective(KillHordeMinionsStep.Others);
var obj = new KillHordeMinionsObjective(KillHordeMinionsStep.Others);
System.AddObjective(obj);
obj.CurProgress = CurProgress;
break;

View file

@ -1,28 +1,12 @@
namespace Server.Items
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class Cauldron : Item
{
public class Cauldron : Item
{
[Constructible]
public Cauldron() : base(0x9ED) => Weight = 1.0;
[Constructible]
public Cauldron() : base(0x9ED) => Weight = 1.0;
public Cauldron(Serial serial) : base(serial)
{
}
public override string DefaultName => "a cauldron";
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public override string DefaultName => "a cauldron";
}

View file

@ -1,105 +1,75 @@
using System.Collections.Generic;
using ModernUO.Serialization;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.Quests.Hag
namespace Server.Engines.Quests.Hag;
[SerializationGenerator(0, false)]
public partial class HagApprenticeCorpse : Corpse
{
public class HagApprenticeCorpse : Corpse
[Constructible]
public HagApprenticeCorpse() : base(GetOwner(), []) => Direction = Direction.South;
private static Mobile GetOwner()
{
[Constructible]
public HagApprenticeCorpse() : base(GetOwner(), GetEquipment())
var apprentice = new Mobile
{
Direction = Direction.South;
Hue = Race.Human.RandomSkinHue(),
Female = false,
Body = 0x190
};
foreach (var item in EquipItems)
apprentice.Delete();
return apprentice;
}
public override void AddNameProperty(IPropertyList list)
{
list.Add("a charred corpse");
}
public override void OnSingleClick(Mobile from)
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
from.NetState.SendMessage(Serial, ItemID, MessageType.Label, hue, 3, true, null, "", "a charred corpse");
}
public override void Open(Mobile from, bool checkSelfLoot)
{
if (!from.InRange(GetWorldLocation(), 2))
{
return;
}
if (from is PlayerMobile player)
{
var qs = player.Quest;
if (qs is WitchApprenticeQuest)
{
DropItem(item);
}
}
public HagApprenticeCorpse(Serial serial) : base(serial)
{
}
// TODO: What is this? Why are we creating a mobile and deleting it?
private static Mobile GetOwner()
{
var apprentice = new Mobile();
apprentice.Hue = Race.Human.RandomSkinHue();
apprentice.Female = false;
apprentice.Body = 0x190;
apprentice.Delete();
return apprentice;
}
private static List<Item> GetEquipment() => new();
public override void AddNameProperty(IPropertyList list)
{
list.Add("a charred corpse");
}
public override void OnSingleClick(Mobile from)
{
var hue = Notoriety.GetHue(NotorietyHandlers.CorpseNotoriety(from, this));
from.NetState.SendMessage(Serial, ItemID, MessageType.Label, hue, 3, true, null, "", "a charred corpse");
}
public override void Open(Mobile from, bool checkSelfLoot)
{
if (!from.InRange(GetWorldLocation(), 2))
{
return;
}
if (from is PlayerMobile player)
{
var qs = player.Quest;
if (qs is WitchApprenticeQuest)
var obj = qs.FindObjective<FindApprenticeObjective>();
if (obj?.Completed == false)
{
var obj = qs.FindObjective<FindApprenticeObjective>();
if (obj?.Completed == false)
if (obj.Corpse == this)
{
if (obj.Corpse == this)
{
obj.Complete();
Delete();
}
else
{
SendLocalizedMessageTo(
from,
1055047
); // You examine the corpse, but it doesn't fit the description of the particular apprentice the Hag tasked you with finding.
}
return;
obj.Complete();
Delete();
}
else
{
// You examine the corpse, but it doesn't fit the description of the particular apprentice the Hag tasked you with finding.
SendLocalizedMessageTo(from, 1055047);
}
return;
}
}
SendLocalizedMessageTo(from, 1055048); // You examine the corpse, but find nothing of interest.
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
SendLocalizedMessageTo(from, 1055048); // You examine the corpse, but find nothing of interest.
}
}

View file

@ -1,36 +1,20 @@
namespace Server.Items
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class HagCauldron : BaseAddon
{
public class HagCauldron : BaseAddon
[Constructible]
public HagCauldron()
{
[Constructible]
public HagCauldron()
{
AddonComponent pot;
pot = new AddonComponent(2420);
AddComponent(pot, 0, 0, 0); // pot w/ support
AddonComponent pot;
pot = new AddonComponent(2420);
AddComponent(pot, 0, 0, 0); // pot w/ support
AddonComponent fire;
fire = new AddonComponent(4012); // fire pit
fire.Light = LightType.Circle150;
AddComponent(fire, 0, 0, 0);
}
public HagCauldron(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
AddonComponent fire;
fire = new AddonComponent(4012); // fire pit
fire.Light = LightType.Circle150;
AddComponent(fire, 0, 0, 0);
}
}

View file

@ -1,71 +1,52 @@
using System;
using ModernUO.Serialization;
namespace Server.Items
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class HagStew : BaseAddon
{
public class HagStew : BaseAddon
[Constructible]
public HagStew()
{
[Constructible]
public HagStew()
// stew
AddComponent(new AddonComponent(2416)
{
AddonComponent stew;
stew = new AddonComponent(2416);
stew.Name = "stew";
stew.Visible = true;
AddComponent(stew, 0, 0, -7); // stew
}
Name = "stew",
Visible = true
}, 0, 0, -7);
}
public HagStew(Serial serial) : base(serial)
public override void OnComponentUsed(AddonComponent stew, Mobile from)
{
if (!from.InRange(GetWorldLocation(), 2))
{
from.SendMessage("You are too far away.");
}
public override void OnComponentUsed(AddonComponent stew, Mobile from)
else
{
if (!from.InRange(GetWorldLocation(), 2))
stew.Visible = false;
var hagstew = new BreadLoaf(); // this decides your fillrate
hagstew.Eat(from);
Timer timer = new ShowStew(stew);
timer.Start();
}
}
public class ShowStew : Timer
{
private readonly AddonComponent _stew;
public ShowStew(AddonComponent ac) : base(TimeSpan.FromSeconds(30)) => _stew = ac;
protected override void OnTick()
{
if (_stew.Visible == false)
{
from.SendMessage("You are too far away.");
}
else
{
stew.Visible = false;
var hagstew = new BreadLoaf(); // this decides your fillrate
hagstew.Eat(from);
Timer m_timer = new ShowStew(stew);
m_timer.Start();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
public class ShowStew : Timer
{
private readonly AddonComponent stew;
public ShowStew(AddonComponent ac) : base(TimeSpan.FromSeconds(30))
{
stew = ac;
}
protected override void OnTick()
{
if (stew.Visible == false)
{
Stop();
stew.Visible = true;
}
Stop();
_stew.Visible = true;
}
}
}

View file

@ -1,81 +1,51 @@
namespace Server.Engines.Quests.Hag
using ModernUO.Serialization;
namespace Server.Engines.Quests.Hag;
[SerializationGenerator(0, false)]
public partial class HangoverCure : Item
{
public class HangoverCure : Item
[EncodedInt]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private int _uses;
[Constructible]
public HangoverCure() : base(0xE2B)
{
[Constructible]
public HangoverCure() : base(0xE2B)
{
Weight = 1.0;
Hue = 0x2D;
Weight = 1.0;
Hue = 0x2D;
Uses = 20;
_uses = 20;
}
public override int LabelNumber => 1055060; // Grizelda's Extra Strength Hangover Cure
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
SendLocalizedMessageTo(from, 1042038); // You must have the object in your backpack to use it.
return;
}
public HangoverCure(Serial serial) : base(serial)
if (Uses > 0)
{
from.PlaySound(0x2D6);
from.SendLocalizedMessage(501206); // An awful taste fills your mouth.
if (from.BAC > 0)
{
from.BAC = 0;
from.SendLocalizedMessage(501204); // You are now sober!
}
Uses--;
}
public override int LabelNumber => 1055060; // Grizelda's Extra Strength Hangover Cure
[CommandProperty(AccessLevel.GameMaster)]
public int Uses { get; set; }
public override void OnDoubleClick(Mobile from)
else
{
if (!IsChildOf(from.Backpack))
{
SendLocalizedMessageTo(from, 1042038); // You must have the object in your backpack to use it.
return;
}
if (Uses > 0)
{
from.PlaySound(0x2D6);
from.SendLocalizedMessage(501206); // An awful taste fills your mouth.
if (from.BAC > 0)
{
from.BAC = 0;
from.SendLocalizedMessage(501204); // You are now sober!
}
Uses--;
}
else
{
Delete();
from.SendLocalizedMessage(501201); // There wasn't enough left to have any effect.
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // version
writer.WriteEncodedInt(Uses);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 1:
{
Uses = reader.ReadEncodedInt();
break;
}
case 0:
{
Uses = 20;
break;
}
}
Delete();
from.SendLocalizedMessage(501201); // There wasn't enough left to have any effect.
}
}
}

View file

@ -1,72 +1,59 @@
using ModernUO.Serialization;
using Server.Mobiles;
namespace Server.Engines.Quests.Hag
namespace Server.Engines.Quests.Hag;
[SerializationGenerator(0, false)]
public partial class MagicFlute : Item
{
public class MagicFlute : Item
[Constructible]
public MagicFlute() : base(0x1421) => Hue = 0x8AB;
public override int LabelNumber => 1055051; // magic flute
public override void OnDoubleClick(Mobile from)
{
[Constructible]
public MagicFlute() : base(0x1421) => Hue = 0x8AB;
public MagicFlute(Serial serial) : base(serial)
if (!IsChildOf(from.Backpack))
{
SendLocalizedMessageTo(from, 1042292); // You must have the object in your backpack to use it.
return;
}
public override int LabelNumber => 1055051; // magic flute
from.PlaySound(0x3D);
public override void OnDoubleClick(Mobile from)
if (from is not PlayerMobile player)
{
if (!IsChildOf(from.Backpack))
{
SendLocalizedMessageTo(from, 1042292); // You must have the object in your backpack to use it.
return;
}
from.PlaySound(0x3D);
if (from is PlayerMobile player)
{
var qs = player.Quest;
if (qs is WitchApprenticeQuest)
{
var obj = qs.FindObjective<FindZeefzorpulObjective>();
if (obj?.Completed == false)
{
if (player.Map != Map.Trammel && player.Map != Map.Felucca || !player.InRange(obj.ImpLocation, 8))
{
player.SendLocalizedMessage(
1055053
); // Nothing happens. Zeefzorpul must not be hiding in this area.
}
else if (player.InRange(obj.ImpLocation, 4))
{
Delete();
obj.Complete();
}
else
{
player.SendLocalizedMessage(
1055052
); // The flute sparkles. Zeefzorpul must be in a good hiding place nearby.
}
}
}
}
return;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
var qs = player.Quest;
writer.Write(0); // version
if (qs is not WitchApprenticeQuest)
{
return;
}
public override void Deserialize(IGenericReader reader)
var obj = qs.FindObjective<FindZeefzorpulObjective>();
if (obj?.Completed != false)
{
base.Deserialize(reader);
var version = reader.ReadInt();
return;
}
if (player.Map != Map.Trammel && player.Map != Map.Felucca || !player.InRange(obj.ImpLocation, 8))
{
// Nothing happens. Zeefzorpul must not be hiding in this area.
player.SendLocalizedMessage(1055053);
return;
}
if (player.InRange(obj.ImpLocation, 4))
{
Delete();
obj.Complete();
return;
}
// The flute sparkles. Zeefzorpul must be in a good hiding place nearby.
player.SendLocalizedMessage(1055052);
}
}

View file

@ -1,28 +1,12 @@
namespace Server.Engines.Quests.Hag
using ModernUO.Serialization;
namespace Server.Engines.Quests.Hag;
[SerializationGenerator(0, false)]
public partial class MoonfireBrew : Item
{
public class MoonfireBrew : Item
{
[Constructible]
public MoonfireBrew() : base(0xF04) => Weight = 1.0;
[Constructible]
public MoonfireBrew() : base(0xF04) => Weight = 1.0;
public MoonfireBrew(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1055065; // a bottle of magical moonfire brew
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public override int LabelNumber => 1055065; // a bottle of magical moonfire brew
}

View file

@ -1,232 +1,205 @@
using ModernUO.Serialization;
using Server.Engines.Virtues;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.Quests.Hag
namespace Server.Engines.Quests.Hag;
[SerializationGenerator(0, false)]
public partial class Grizelda : BaseQuester
{
public class Grizelda : BaseQuester
[Constructible]
public Grizelda() : base("the Hag")
{
[Constructible]
public Grizelda() : base("the Hag")
}
public override bool ClickTitle => true;
public override string DefaultName => "Grizelda";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83EA;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
AddItem(new Robe(0x1));
AddItem(new Sandals());
AddItem(new WizardsHat(0x1));
AddItem(new GoldBracelet());
HairItemID = 0x203C;
Item staff = new GnarledStaff();
staff.Movable = false;
AddItem(staff);
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
Direction = GetDirectionTo(player);
var qs = player.Quest;
if (qs is not WitchApprenticeQuest)
{
}
var newQuest = new WitchApprenticeQuest(player);
public Grizelda(Serial serial) : base(serial)
{
}
public override bool ClickTitle => true;
public override string DefaultName => "Grizelda";
public override void InitBody()
{
InitStats(100, 100, 25);
Hue = 0x83EA;
Female = true;
Body = 0x191;
}
public override void InitOutfit()
{
AddItem(new Robe(0x1));
AddItem(new Sandals());
AddItem(new WizardsHat(0x1));
AddItem(new GoldBracelet());
HairItemID = 0x203C;
Item staff = new GnarledStaff();
staff.Movable = false;
AddItem(staff);
}
public override void OnTalk(PlayerMobile player, bool contextMenu)
{
Direction = GetDirectionTo(player);
var qs = player.Quest;
if (qs is WitchApprenticeQuest)
if (qs != null)
{
if (qs.IsObjectiveInProgress(typeof(FindApprenticeObjective)))
newQuest.AddConversation(new DontOfferConversation());
}
else if (QuestSystem.CanOfferQuest(player, typeof(WitchApprenticeQuest), out var inRestartPeriod))
{
PlaySound(0x20);
PlaySound(0x206);
newQuest.SendOffer();
}
else if (inRestartPeriod)
{
PlaySound(0x259);
PlaySound(0x206);
newQuest.AddConversation(new RecentlyFinishedConversation());
}
return;
}
if (qs.IsObjectiveInProgress(typeof(FindApprenticeObjective)))
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringCorpseSearchConversation());
return;
}
if (qs.FindObjective<FindGrizeldaAboutMurderObjective>() is { Completed: false } obj1)
{
PlaySound(0x420);
PlaySound(0x20);
obj1.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(KillImpsObjective))
|| qs.IsObjectiveInProgress(typeof(FindZeefzorpulObjective)))
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringImpSearchConversation());
return;
}
if (qs.FindObjective<ReturnRecipeObjective>() is { Completed: false } obj2)
{
PlaySound(0x258);
PlaySound(0x41B);
obj2.Complete();
return;
}
if (qs.IsObjectiveInProgress(typeof(FindIngredientObjective)))
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringIngredientsConversation());
return;
}
if (qs.FindObjective<ReturnIngredientsObjective>() is { Completed: false } obj3)
{
var cont = GetNewContainer();
cont.DropItem(new BlackPearl(30));
cont.DropItem(new Bloodmoss(30));
cont.DropItem(new Garlic(30));
cont.DropItem(new Ginseng(30));
cont.DropItem(new MandrakeRoot(30));
cont.DropItem(new Nightshade(30));
cont.DropItem(new SulfurousAsh(30));
cont.DropItem(new SpidersSilk(30));
cont.DropItem(new Cauldron());
cont.DropItem(new MoonfireBrew());
cont.DropItem(new TreasureMap(Utility.RandomMinMax(1, 4), Map));
cont.DropItem(new Gold(2000, 2200));
if (Utility.RandomBool())
{
var weapon = Loot.RandomWeapon();
if (Core.AOS)
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringCorpseSearchConversation());
BaseRunicTool.ApplyAttributesTo(weapon, 2, 20, 30);
}
else
{
QuestObjective obj = qs.FindObjective<FindGrizeldaAboutMurderObjective>();
if (obj?.Completed == false)
{
PlaySound(0x420);
PlaySound(0x20);
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(KillImpsObjective))
|| qs.IsObjectiveInProgress(typeof(FindZeefzorpulObjective)))
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringImpSearchConversation());
}
else
{
obj = qs.FindObjective<ReturnRecipeObjective>();
if (obj?.Completed == false)
{
PlaySound(0x258);
PlaySound(0x41B);
obj.Complete();
}
else if (qs.IsObjectiveInProgress(typeof(FindIngredientObjective)))
{
PlaySound(0x259);
PlaySound(0x206);
qs.AddConversation(new HagDuringIngredientsConversation());
}
else
{
obj = qs.FindObjective<ReturnIngredientsObjective>();
if (obj?.Completed == false)
{
var cont = GetNewContainer();
cont.DropItem(new BlackPearl(30));
cont.DropItem(new Bloodmoss(30));
cont.DropItem(new Garlic(30));
cont.DropItem(new Ginseng(30));
cont.DropItem(new MandrakeRoot(30));
cont.DropItem(new Nightshade(30));
cont.DropItem(new SulfurousAsh(30));
cont.DropItem(new SpidersSilk(30));
cont.DropItem(new Cauldron());
cont.DropItem(new MoonfireBrew());
cont.DropItem(new TreasureMap(Utility.RandomMinMax(1, 4), Map));
cont.DropItem(new Gold(2000, 2200));
if (Utility.RandomBool())
{
var weapon = Loot.RandomWeapon();
if (Core.AOS)
{
BaseRunicTool.ApplyAttributesTo(weapon, 2, 20, 30);
}
else
{
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 3);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 3);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 3);
}
cont.DropItem(weapon);
}
else
{
Item item;
if (Core.AOS)
{
item = Loot.RandomArmorOrShieldOrJewelry();
if (item is BaseArmor armor)
{
BaseRunicTool.ApplyAttributesTo(armor, 2, 20, 30);
}
else if (item is BaseJewel jewel)
{
BaseRunicTool.ApplyAttributesTo(jewel, 2, 20, 30);
}
}
else
{
var armor = Loot.RandomArmorOrShield();
item = armor;
armor.ProtectionLevel = (ArmorProtectionLevel)RandomMinMaxScaled(2, 3);
armor.Durability = (ArmorDurabilityLevel)RandomMinMaxScaled(2, 3);
}
cont.DropItem(item);
}
if (player.BAC > 0)
{
cont.DropItem(new HangoverCure());
}
if (player.PlaceInBackpack(cont))
{
var gainedPath = false;
if (VirtueSystem.Award(
player,
VirtueName.Sacrifice,
250,
ref gainedPath
)) // TODO: Check amount on OSI.
{
player.SendLocalizedMessage(1054160); // You have gained in sacrifice.
}
PlaySound(0x253);
PlaySound(0x20);
obj.Complete();
}
else
{
cont.Delete();
player.SendLocalizedMessage(
1046260
); // You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
}
}
}
}
weapon.DamageLevel = (WeaponDamageLevel)RandomMinMaxScaled(2, 3);
weapon.AccuracyLevel = (WeaponAccuracyLevel)RandomMinMaxScaled(2, 3);
weapon.DurabilityLevel = (WeaponDurabilityLevel)RandomMinMaxScaled(2, 3);
}
cont.DropItem(weapon);
}
else
{
QuestSystem newQuest = new WitchApprenticeQuest(player);
Item item;
if (qs != null)
if (Core.AOS)
{
newQuest.AddConversation(new DontOfferConversation());
item = Loot.RandomArmorOrShieldOrJewelry();
if (item is BaseArmor armor)
{
BaseRunicTool.ApplyAttributesTo(armor, 2, 20, 30);
}
else if (item is BaseJewel jewel)
{
BaseRunicTool.ApplyAttributesTo(jewel, 2, 20, 30);
}
}
else if (QuestSystem.CanOfferQuest(player, typeof(WitchApprenticeQuest), out var inRestartPeriod))
else
{
PlaySound(0x20);
PlaySound(0x206);
newQuest.SendOffer();
}
else if (inRestartPeriod)
{
PlaySound(0x259);
PlaySound(0x206);
newQuest.AddConversation(new RecentlyFinishedConversation());
var armor = Loot.RandomArmorOrShield();
item = armor;
armor.ProtectionLevel = (ArmorProtectionLevel)RandomMinMaxScaled(2, 3);
armor.Durability = (ArmorDurabilityLevel)RandomMinMaxScaled(2, 3);
}
cont.DropItem(item);
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
if (player.BAC > 0)
{
cont.DropItem(new HangoverCure());
}
writer.Write(0); // version
}
if (player.PlaceInBackpack(cont))
{
var gainedPath = false;
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
// TODO: Check amount on OSI.
if (VirtueSystem.Award(player, VirtueName.Sacrifice, 250, ref gainedPath))
{
player.SendLocalizedMessage(1054160); // You have gained in sacrifice.
}
var version = reader.ReadInt();
PlaySound(0x253);
PlaySound(0x20);
obj3.Complete();
}
else
{
cont.Delete();
// You need to clear some space in your inventory to continue with the quest. Come back here when you have more space in your inventory.
player.SendLocalizedMessage(1046260);
}
}
}
}

View file

@ -61,7 +61,7 @@ namespace Server.Engines.Quests.Hag
Timer.StartTimer(TimeSpan.FromSeconds(3.0), () => DeleteImp(imp));
}
private void DeleteImp(Mobile m)
private static void DeleteImp(Mobile m)
{
if (m?.Deleted == false)
{

View file

@ -608,7 +608,7 @@ public abstract partial class BaseBeverage : Item, IHasQuantity
{
if (from is PlayerMobile { Quest: SolenMatriarchQuest qs })
{
QuestObjective obj = qs.FindObjective<GatherWaterObjective>();
var obj = qs.FindObjective<GatherWaterObjective>();
if (obj?.Completed == false)
{

View file

@ -183,7 +183,7 @@ public partial class BankCheck : Item
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<CashBankCheckObjective>();
var obj = qs.FindObjective<CashBankCheckObjective>();
if (obj?.Completed == false)
{

View file

@ -47,16 +47,19 @@ public static class CorpsePackets
}
}
if (beheld.Hair?.ItemID > 0)
if (beheld.Owner != null)
{
writer.Write((byte)(Layer.Hair + 1));
writer.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
}
if (beheld.Hair?.ItemID > 0)
{
writer.Write((byte)(Layer.Hair + 1));
writer.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
}
if (beheld.FacialHair?.ItemID > 0)
{
writer.Write((byte)(Layer.FacialHair + 1));
writer.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
if (beheld.FacialHair?.ItemID > 0)
{
writer.Write((byte)(Layer.FacialHair + 1));
writer.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
}
}
writer.Write((byte)Layer.Invalid);
@ -115,38 +118,41 @@ public static class CorpsePackets
}
}
if (hairItemID > 0)
if (beheld.Owner != null)
{
writer.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
writer.Write((ushort)hairItemID);
writer.Write((byte)0); // signed, itemID offset
writer.Write((ushort)1);
writer.Write(0); // X/Y
if (ns.ContainerGridLines)
if (hairItemID > 0)
{
writer.Write((byte)0); // Grid Location?
writer.Write(HairInfo.FakeSerial(beheld.Owner.Serial) - 2);
writer.Write((ushort)hairItemID);
writer.Write((byte)0); // signed, itemID offset
writer.Write((ushort)1);
writer.Write(0); // X/Y
if (ns.ContainerGridLines)
{
writer.Write((byte)0); // Grid Location?
}
writer.Write(beheld.Serial);
writer.Write((ushort)beheld.Hair!.Hue);
++written;
}
writer.Write(beheld.Serial);
writer.Write((ushort)beheld.Hair!.Hue);
++written;
}
if (facialHairItemID > 0)
{
writer.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
writer.Write((ushort)facialHairItemID);
writer.Write((byte)0); // signed, itemID offset
writer.Write((ushort)1);
writer.Write(0); // X/Y
if (ns.ContainerGridLines)
if (facialHairItemID > 0)
{
writer.Write((byte)0); // Grid Location?
}
writer.Write(beheld.Serial);
writer.Write((ushort)beheld.FacialHair!.Hue);
writer.Write(FacialHairInfo.FakeSerial(beheld.Owner.Serial) - 2);
writer.Write((ushort)facialHairItemID);
writer.Write((byte)0); // signed, itemID offset
writer.Write((ushort)1);
writer.Write(0); // X/Y
if (ns.ContainerGridLines)
{
writer.Write((byte)0); // Grid Location?
}
writer.Write(beheld.Serial);
writer.Write((ushort)beheld.FacialHair!.Hue);
++written;
++written;
}
}
writer.Seek(1, SeekOrigin.Begin);

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Hag.Grizelda"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Hag.HagApprenticeCorpse"
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Engines.Quests.Hag.HangoverCure",
"properties": [
{
"name": "Uses",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
"EncodedInt"
]
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Hag.MagicFlute"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Hag.MoonfireBrew"
}

View file

@ -0,0 +1,16 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.Cannon",
"properties": [
{
"name": "CannonDirection",
"type": "Server.Engines.Quests.Haven.CannonDirection",
"rule": "EnumMigrationRule"
},
{
"name": "Canoneer",
"type": "Server.Engines.Quests.Haven.MilitiaCanoneer",
"rule": "SerializableInterfaceMigrationRule"
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.CannonComponent"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.DaemonBloodChest"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.Dryad"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.MansionGuard"
}

View file

@ -0,0 +1,14 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.MilitiaCanoneer",
"properties": [
{
"name": "Active",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.MilitiaFighter"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.MilitiaFighterCorpse"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.QuestDaemonBlood"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.QuestDaemonBone"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.QuestFertileDirt"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.Schmendrick"
}

View file

@ -0,0 +1,11 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.SchmendrickApprenticeCorpse",
"properties": [
{
"name": "Lantern",
"type": "Server.Items.Lantern",
"rule": "SerializableInterfaceMigrationRule"
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.SchmendrickScrollOfPower"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.Uzeraan"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.UzeraanTurmoilHorn"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Haven.UzeraanTurmoilTeleporter"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Matriarch.BaseSolenMatriarch"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Matriarch.BlackSolenMatriarch"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Matriarch.RedSolenMatriarch"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Naturalist.Naturalist"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Quests.Zento.AnsellaGryen"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.Cauldron"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.HagCauldron"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.HagStew"
}

View file

@ -1373,7 +1373,7 @@ public abstract class BaseAI
if (qs is DarkTidesQuest)
{
QuestObjective obj = qs.FindObjective<FetchAbraxusScrollObjective>();
var obj = qs.FindObjective<FetchAbraxusScrollObjective>();
if (obj?.Completed == false)
{

View file

@ -148,12 +148,7 @@ namespace Server.Spells.Necromancy
}
else
{
Type type = null;
if (c.Owner != null)
{
type = c.Owner.GetType();
}
Type type = c.Owner?.GetType();
if (c.ItemID != 0x2006 || c.Animated || type == typeof(PlayerMobile) || type == null ||
c.Owner?.Fame < 100 ||