feat(champs): Ports Casiopia champions (#584)

This commit is contained in:
Kamron Batman 2021-05-09 00:20:43 -07:00 • committed by GitHub
parent 6e9477ea13
commit 7819830628
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1402 additions and 690 deletions

View file

@ -0,0 +1,107 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: CannedEvilTimer.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Generic;
using Server.Misc;
namespace Server.Engines.CannedEvil
{
public class CannedEvilTimer : Timer
{
public static void Initialize()
{
// TODO: Needs configuration
Instance = new CannedEvilTimer();
Instance.Start();
Instance.OnTick();
}
private static readonly HashSet<DungeonChampionSpawn> _dungeonSpawns = new();
private static readonly HashSet<LLChampionSpawn> _lostLandsSpawns = new();
private static DateTime _sliceTime;
public static CannedEvilTimer Instance { get; private set; }
public static void AddSpawn(DungeonChampionSpawn spawn)
{
_dungeonSpawns.Add(spawn);
Instance?.OnSlice(_dungeonSpawns, false);
}
public static void AddSpawn(LLChampionSpawn spawn)
{
_lostLandsSpawns.Add(spawn);
Instance?.OnSlice(_lostLandsSpawns, false);
}
public static void RemoveSpawn(DungeonChampionSpawn spawn)
{
_dungeonSpawns.Remove(spawn);
Instance?.OnSlice(_dungeonSpawns, false);
}
public static void RemoveSpawn(LLChampionSpawn spawn)
{
_lostLandsSpawns.Remove(spawn);
Instance?.OnSlice(_lostLandsSpawns, false);
}
public CannedEvilTimer() : base(TimeSpan.Zero, TimeSpan.FromMinutes(1.0))
{
Priority = TimerPriority.OneMinute;
_sliceTime = Core.Now;
}
public void OnSlice<T>(ICollection<T> list, bool rotate = true) where T : ChampionSpawn
{
if (list.Count > 0)
{
List<T> valid = new List<T>();
foreach (T spawn in list)
{
if (spawn.AlwaysActive && !spawn.Active)
{
spawn.ReadyToActivate = true;
}
else if (rotate && (!spawn.Active || spawn.Kills == 0 && spawn.Level == 0))
{
spawn.Active = false;
spawn.ReadyToActivate = false;
valid.Add(spawn);
}
}
if (valid.Count > 0)
{
valid[Utility.Random(valid.Count)].ReadyToActivate = true;
}
}
}
protected override void OnTick()
{
if (!AutoRestart.Restarting && Core.Now >= _sliceTime)
{
OnSlice(_dungeonSpawns);
OnSlice(_lostLandsSpawns);
_sliceTime = Core.Now.Date + TimeSpan.FromDays(1.0);
}
}
}
}

35
Projects/UOContent/Engines/CannedEvil/ChampionAltar.cs Normal file → Executable file
View file

@ -1,22 +1,37 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionAltar.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Items;
namespace Server.Engines.CannedEvil
{
public class ChampionAltar : PentagramAddon
{
private ChampionSpawn m_Spawn;
public ChampionSpawn Spawn { get; private set; }
public ChampionAltar(ChampionSpawn spawn) => m_Spawn = spawn;
public ChampionAltar(Serial serial) : base(serial)
{
}
public ChampionAltar(ChampionSpawn spawn) => Spawn = spawn;
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Spawn?.Delete();
Spawn?.Delete();
}
public ChampionAltar(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
@ -25,7 +40,7 @@ namespace Server.Engines.CannedEvil
writer.Write(0); // version
writer.Write(m_Spawn);
writer.Write(Spawn);
}
public override void Deserialize(IGenericReader reader)
@ -38,9 +53,9 @@ namespace Server.Engines.CannedEvil
{
case 0:
{
m_Spawn = reader.ReadEntity<ChampionSpawn>();
Spawn = reader.ReadEntity<ChampionSpawn>();
if (m_Spawn == null)
if (Spawn == null)
{
Delete();
}

View file

@ -0,0 +1,83 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionCommands.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Targeting;
namespace Server.Engines.CannedEvil
{
public static class ChampionCommands
{
public static void Initialize()
{
CommandSystem.Register("ClearChampByTarget", AccessLevel.Administrator, KillByTarget_OnCommand);
CommandSystem.Register("ClearChampByRegion", AccessLevel.Administrator, KillByRegion_OnCommand);
}
[Usage("ClearChampByTarget")]
[Description("Kills all minions of a champion spawn.")]
private static void KillByTarget_OnCommand(CommandEventArgs e)
{
e.Mobile.Target = new KillTarget();
e.Mobile.SendMessage("Which champion spawn would you like to clear?");
}
private class KillTarget : Target
{
public KillTarget() : base(15, false, TargetFlags.None)
{
}
protected override void OnTarget(Mobile from, object targ)
{
if (from == null || from.AccessLevel < AccessLevel.Administrator)
{
return;
}
ChampionSpawn spawn = targ switch
{
ChampionSpawn championSpawn => championSpawn,
IdolOfTheChampion champion => champion.Spawn,
ChampionAltar altar => altar.Spawn,
ChampionPlatform platform => platform.Spawn,
_ => null
};
if (spawn == null)
{
from.SendMessage("That is not a valid target. Please target the champion, altar, platform, or idol.");
}
spawn?.DeleteCreatures();
spawn?.Champion?.Delete();
}
}
[Usage("ClearChampByRegion")]
[Description("Kills all minions of a champion spawn.")]
private static void KillByRegion_OnCommand(CommandEventArgs e)
{
if (e.Mobile.Region is ChampionSpawnRegion { Spawn: { } } region)
{
region.Spawn.DeleteCreatures();
region.Spawn.Champion?.Delete();
}
else
{
e.Mobile.SendMessage("You are not in a champion spawn region.");
}
}
}
}

View file

@ -1,14 +1,29 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionPlatform.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Items;
namespace Server.Engines.CannedEvil
{
public class ChampionPlatform : BaseAddon
{
private ChampionSpawn m_Spawn;
public ChampionSpawn Spawn { get; private set; }
public ChampionPlatform(ChampionSpawn spawn)
{
m_Spawn = spawn;
Spawn = spawn;
for (var x = -2; x <= 2; ++x)
{
@ -41,16 +56,9 @@ namespace Server.Engines.CannedEvil
AddComponent(0x75C, 2, -2, 0);
}
public ChampionPlatform(Serial serial) : base(serial)
{
}
public void AddComponent(int id, int x, int y, int z)
{
var ac = new AddonComponent(id);
ac.Hue = 0x497;
AddonComponent ac = new AddonComponent(id) { Hue = 0x497 };
AddComponent(ac, x, y, z);
}
@ -58,7 +66,11 @@ namespace Server.Engines.CannedEvil
{
base.OnAfterDelete();
m_Spawn?.Delete();
Spawn?.Delete();
}
public ChampionPlatform(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
@ -67,7 +79,7 @@ namespace Server.Engines.CannedEvil
writer.Write(0); // version
writer.Write(m_Spawn);
writer.Write(Spawn);
}
public override void Deserialize(IGenericReader reader)
@ -80,9 +92,9 @@ namespace Server.Engines.CannedEvil
{
case 0:
{
m_Spawn = reader.ReadEntity<ChampionSpawn>();
Spawn = reader.ReadEntity<ChampionSpawn>();
if (m_Spawn == null)
if (Spawn == null)
{
Delete();
}

42
Projects/UOContent/Engines/CannedEvil/ChampionSkull.cs Normal file → Executable file
View file

@ -1,3 +1,18 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionSkull.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Engines.CannedEvil;
namespace Server.Items
@ -6,6 +21,19 @@ namespace Server.Items
{
private ChampionSkullType m_Type;
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullType Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1049479 + (int)m_Type;
[Constructible]
public ChampionSkull(ChampionSkullType type) : base(0x1AE1)
{
@ -28,19 +56,6 @@ namespace Server.Items
{
}
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullType Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1049479 + (int)m_Type;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
@ -62,7 +77,6 @@ namespace Server.Items
case 0:
{
m_Type = (ChampionSkullType)reader.ReadInt();
break;
}
}

View file

@ -1,26 +1,28 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionSkullBrazier.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using Server.Mobiles;
namespace Server.Engines.CannedEvil
{
public class ChampionSkullBrazier : AddonComponent
{
private Item m_Skull;
private ChampionSkullType m_Type;
public ChampionSkullBrazier(ChampionSkullPlatform platform, ChampionSkullType type) : base(0x19BB)
{
Hue = 0x455;
Light = LightType.Circle300;
Platform = platform;
m_Type = type;
}
public ChampionSkullBrazier(Serial serial) : base(serial)
{
}
private Item m_Skull;
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullPlatform Platform { get; private set; }
@ -49,6 +51,19 @@ namespace Server.Engines.CannedEvil
public override int LabelNumber => 1049489 + (int)m_Type;
public ChampionSkullBrazier(ChampionSkullPlatform platform, ChampionSkullType type) : base(0x19BB)
{
Hue = 0x455;
Light = LightType.Circle300;
Platform = platform;
m_Type = type;
}
public ChampionSkullBrazier(Serial serial) : base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
Platform?.Validate();
@ -63,7 +78,7 @@ namespace Server.Engines.CannedEvil
return;
}
if (m_Skull?.Deleted == true)
if (m_Skull is { Deleted: true })
{
Skull = null;
}
@ -94,7 +109,7 @@ namespace Server.Engines.CannedEvil
return;
}
if (m_Skull?.Deleted == true)
if (m_Skull is { Deleted: true })
{
Skull = null;
}
@ -135,6 +150,17 @@ namespace Server.Engines.CannedEvil
}
}
private class SacrificeTarget : Target
{
private readonly ChampionSkullBrazier m_Brazier;
public SacrificeTarget(ChampionSkullBrazier brazier) : base(12, false, TargetFlags.None) =>
m_Brazier = brazier;
protected override void OnTarget(Mobile from, object targeted) =>
m_Brazier.EndSacrifice(from, targeted as ChampionSkull);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
@ -179,17 +205,5 @@ namespace Server.Engines.CannedEvil
Light = LightType.Circle300;
}
}
private class SacrificeTarget : Target
{
private readonly ChampionSkullBrazier m_Brazier;
public SacrificeTarget(ChampionSkullBrazier brazier) : base(12, false, TargetFlags.None) => m_Brazier = brazier;
protected override void OnTarget(Mobile from, object targeted)
{
m_Brazier.EndSacrifice(from, targeted as ChampionSkull);
}
}
}
}

View file

@ -1,3 +1,18 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionSkullPlatform.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using Server.Items;
using Server.Mobiles;
@ -38,23 +53,16 @@ namespace Server.Engines.CannedEvil
AddComponent(new AddonComponent(0x50F), 0, 1, 4);
AddComponent(m_Death = new ChampionSkullBrazier(this, ChampionSkullType.Death), 0, 1, 5);
AddonComponent comp = new LocalizedAddonComponent(0x20D2, 1049495);
comp.Hue = 0x482;
AddonComponent comp = new LocalizedAddonComponent(0x20D2, 1049495) { Hue = 0x482 };
AddComponent(comp, 0, 0, 5);
comp = new LocalizedAddonComponent(0x0BCF, 1049496);
comp.Hue = 0x482;
comp = new LocalizedAddonComponent(0x0BCF, 1049496) { Hue = 0x482 };
AddComponent(comp, 0, 2, -7);
comp = new LocalizedAddonComponent(0x0BD0, 1049497);
comp.Hue = 0x482;
comp = new LocalizedAddonComponent(0x0BD0, 1049497) { Hue = 0x482 };
AddComponent(comp, 2, 0, -7);
}
public ChampionSkullPlatform(Serial serial) : base(serial)
{
}
public void Validate()
{
if (Validate(m_Power) && Validate(m_Enlightenment) && Validate(m_Venom) && Validate(m_Pain) &&
@ -86,7 +94,11 @@ namespace Server.Engines.CannedEvil
}
}
public bool Validate(ChampionSkullBrazier brazier) => brazier?.Skull?.Deleted == false;
public bool Validate(ChampionSkullBrazier brazier) => brazier is { Skull: { Deleted: false } };
public ChampionSkullPlatform(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{

View file

@ -1,3 +1,18 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionSkullType.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
namespace Server.Engines.CannedEvil
{
public enum ChampionSkullType
@ -7,6 +22,7 @@ namespace Server.Engines.CannedEvil
Venom,
Pain,
Greed,
Death
Death,
None
}
}

1115
Projects/UOContent/Engines/CannedEvil/ChampionSpawn.cs Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,18 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: ChampionSpawnType.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using Server.Mobiles;
@ -13,19 +28,12 @@ namespace Server.Engines.CannedEvil
UnholyTerror,
SleepingDragon,
Glade,
Pestilence
Pestilence,
Graveyard
}
public class ChampionSpawnInfo
{
public ChampionSpawnInfo(string name, Type champion, string[] levelNames, Type[][] spawnTypes)
{
Name = name;
Champion = champion;
LevelNames = levelNames;
SpawnTypes = spawnTypes;
}
public string Name { get; }
public Type Champion { get; }
@ -34,131 +42,81 @@ namespace Server.Engines.CannedEvil
public string[] LevelNames { get; }
public static ChampionSpawnInfo[] Table { get; } =
public ChampionSpawnInfo(string name, Type champion, string[] levelNames, Type[][] spawnTypes)
{
new(
"Abyss",
typeof(Semidar),
new[] { "Foe", "Assassin", "Conqueror" },
new[] // Abyss
{
// Abyss
new[] { typeof(GreaterMongbat), typeof(Imp) }, // Level 1
new[] { typeof(Gargoyle), typeof(Harpy) }, // Level 2
new[] { typeof(FireGargoyle), typeof(StoneGargoyle) }, // Level 3
new[] { typeof(Daemon), typeof(Succubus) } // Level 4
}
),
new(
"Arachnid",
typeof(Mephitis),
new[] { "Bane", "Killer", "Vanquisher" },
new[] // Arachnid
{
// Arachnid
new[] { typeof(Scorpion), typeof(GiantSpider) }, // Level 1
new[] { typeof(TerathanDrone), typeof(TerathanWarrior) }, // Level 2
new[] { typeof(DreadSpider), typeof(TerathanMatriarch) }, // Level 3
new[] { typeof(PoisonElemental), typeof(TerathanAvenger) } // Level 4
}
),
new(
"Cold Blood",
typeof(Rikktor),
new[] { "Blight", "Slayer", "Destroyer" },
new[] // Cold Blood
{
// Cold Blood
new[] { typeof(Lizardman), typeof(Snake) }, // Level 1
new[] { typeof(LavaLizard), typeof(OphidianWarrior) }, // Level 2
new[] { typeof(Drake), typeof(OphidianArchmage) }, // Level 3
new[] { typeof(Dragon), typeof(OphidianKnight) } // Level 4
}
),
new(
"Forest Lord",
typeof(LordOaks),
new[] { "Enemy", "Curse", "Slaughterer" },
new[] // Forest Lord
{
// Forest Lord
new[] { typeof(Pixie), typeof(ShadowWisp) }, // Level 1
new[] { typeof(Kirin), typeof(Wisp) }, // Level 2
new[] { typeof(Centaur), typeof(Unicorn) }, // Level 3
new[] { typeof(EtherealWarrior), typeof(SerpentineDragon) } // Level 4
}
),
new(
"Vermin Horde",
typeof(Barracoon),
new[] { "Adversary", "Subjugator", "Eradicator" },
new[] // Vermin Horde
{
// Vermin Horde
new[] { typeof(GiantRat), typeof(Slime) }, // Level 1
new[] { typeof(DireWolf), typeof(Ratman) }, // Level 2
new[] { typeof(HellHound), typeof(RatmanMage) }, // Level 3
new[] { typeof(RatmanArcher), typeof(SilverSerpent) } // Level 4
}
),
new(
"Unholy Terror",
typeof(Neira),
new[] { "Scourge", "Punisher", "Nemesis" },
new[] // Unholy Terror
{
// Unholy Terror
Core.AOS
? new[]
{
typeof(Bogle), typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith)
} // Level 1 (Pre-AoS)
: new[] { typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith) }, // Level 1
Name = name;
Champion = champion;
LevelNames = levelNames;
SpawnTypes = spawnTypes;
}
new[] { typeof(BoneMagi), typeof(Mummy), typeof(SkeletalMage) }, // Level 2
new[] { typeof(BoneKnight), typeof(Lich), typeof(SkeletalKnight) }, // Level 3
new[] { typeof(LichLord), typeof(RottingCorpse) } // Level 4
}
),
new(
"Sleeping Dragon",
typeof(Serado),
new[] { "Rival", "Challenger", "Antagonist" },
new[]
{
// Unholy Terror
new[] { typeof(DeathwatchBeetleHatchling), typeof(Lizardman) },
new[] { typeof(DeathwatchBeetle), typeof(Kappa) },
new[] { typeof(LesserHiryu), typeof(RevenantLion) },
new[] { typeof(Hiryu), typeof(Oni) }
}
),
new(
"Glade",
typeof(Twaulo),
new[] { "Banisher", "Enforcer", "Eradicator" },
new[]
{
// Glade
new[] { typeof(Pixie), typeof(ShadowWisp) },
new[] { typeof(Centaur), typeof(MLDryad) },
new[] { typeof(Satyr), typeof(CuSidhe) },
new[] { typeof(FeralTreefellow), typeof(RagingGrizzlyBear) }
}
),
new(
"The Corrupt",
typeof(Ilhenir),
new[] { "Cleanser", "Expunger", "Depurator" },
new[]
{
// Unholy Terror
new[] { typeof(PlagueSpawn), typeof(Bogling) },
new[] { typeof(PlagueBeast), typeof(BogThing) },
new[] { typeof(PlagueBeastLord), typeof(InterredGrizzle) },
new[] { typeof(FetidEssence), typeof(PestilentBandage) }
}
)
public static ChampionSpawnInfo[] Table { get; } = {
new("Abyss", typeof(Semidar), new[]{ "Foe", "Assassin", "Conqueror" }, new[]
{
new[]{ typeof(GreaterMongbat), typeof(Imp) }, // Level 1
new[]{ typeof(Gargoyle), typeof(Harpy) }, // Level 2
new[]{ typeof(FireGargoyle), typeof(StoneGargoyle) }, // Level 3
new[]{ typeof(Daemon), typeof(Succubus) } // Level 4
}),
new("Arachnid", typeof(Mephitis), new[]{ "Bane", "Killer", "Vanquisher" }, new[]
{
new[]{ typeof(Scorpion), typeof(GiantSpider) }, // Level 1
new[]{ typeof(TerathanDrone), typeof(TerathanWarrior) }, // Level 2
new[]{ typeof(DreadSpider), typeof(TerathanMatriarch) }, // Level 3
new[]{ typeof(PoisonElemental), typeof(TerathanAvenger) } // Level 4
}),
new("Cold Blood", typeof(Rikktor), new[]{ "Blight", "Slayer", "Destroyer" }, new[]
{
new[]{ typeof(Lizardman), typeof(GiantSerpent) }, // Level 1
new[]{ typeof(LavaLizard), typeof(OphidianWarrior) }, // Level 2
new[]{ typeof(Drake), typeof(OphidianArchmage) }, // Level 3
new[]{ typeof(Dragon), typeof(OphidianKnight) } // Level 4
}),
new("Forest Lord", typeof(LordOaks), new[]{ "Enemy", "Curse", "Slaughterer" }, new[]
{
new[]{ typeof(Pixie), typeof(ShadowWisp) }, // Level 1
new[]{ typeof(Kirin), typeof(Wisp) }, // Level 2
new[]{ typeof(Centaur), typeof(Unicorn) }, // Level 3
new[]{ typeof(EtherealWarrior), typeof(SerpentineDragon) } // Level 4
}),
new("Vermin Horde", typeof(Barracoon), new[]{ "Adversary", "Subjugator", "Eradicator" }, new[]
{
new[]{ typeof(GiantRat), typeof(Slime) }, // Level 1
new[]{ typeof(DireWolf), typeof(Ratman) }, // Level 2
new[]{ typeof(HellHound), typeof(RatmanMage) }, // Level 3
new[]{ typeof(RatmanArcher), typeof(SilverSerpent) } // Level 4
}),
new("Unholy Terror", typeof(Neira), new[]{ "Scourge", "Punisher", "Nemesis" }, new[]
{
Core.AOS ? // Level 1
new[]{ typeof(Bogle), typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith) }
: new[]{ typeof(Ghoul), typeof(Shade), typeof(Spectre), typeof(Wraith) },
new[]{ typeof(BoneMagi), typeof(Mummy), typeof(SkeletalMage) }, // Level 2
new[]{ typeof(BoneKnight), typeof(Lich), typeof(SkeletalKnight) }, // Level 3
new[]{ typeof(LichLord), typeof(RottingCorpse) } // Level 4
}),
new("Sleeping Dragon", typeof(Serado), new[]{ "Rival", "Challenger", "Antagonist" } , new[]
{
new[]{ typeof(DeathwatchBeetleHatchling), typeof(Lizardman) }, // Level 1
new[]{ typeof(DeathwatchBeetle), typeof(Kappa) }, // Level 2
new[]{ typeof(LesserHiryu), typeof(RevenantLion) }, // Level 3
new[]{ typeof(Hiryu), typeof(Oni) } // Level 4
}),
new("Glade", typeof(Twaulo), new[]{ "Banisher", "Enforcer", "Eradicator" } , new[]
{
new[]{ typeof(Pixie), typeof(ShadowWisp) }, // Level 1
new[]{ typeof(Centaur), typeof(MLDryad) }, // Level 2
new[]{ typeof(Satyr), typeof(CuSidhe) }, // Level 3
new[]{ typeof(FeralTreefellow), typeof(RagingGrizzlyBear) } // Level 4
}),
new("The Corrupt", typeof(Ilhenir), new[]{ "Cleanser", "Expunger", "Depurator" } , new[]
{
new[]{ typeof(PlagueSpawn), typeof(Bogling) }, // Level 1
new[]{ typeof(PlagueBeast), typeof(BogThing) }, // Level 2
new[]{ typeof(PlagueBeastLord), typeof(InterredGrizzle) }, // Level 3
new[]{ typeof(FetidEssence), typeof(PestilentBandage) } // Level 4
}),
};
public static ChampionSpawnInfo GetInfo(ChampionSpawnType type)

View file

@ -0,0 +1,54 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: DungeonChampionSpawn.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
namespace Server.Engines.CannedEvil
{
public class DungeonChampionSpawn : ChampionSpawn
{
[Constructible]
public DungeonChampionSpawn() : base()
{
CannedEvilTimer.AddSpawn(this);
}
public DungeonChampionSpawn(Serial serial) : base(serial)
{
CannedEvilTimer.AddSpawn(this);
}
public override bool ProximitySpawn => true;
public override bool AlwaysActive => false;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); //version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
CannedEvilTimer.RemoveSpawn(this);
}
}
}

View file

@ -0,0 +1,49 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: GenChampEntry.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server.Engines.CannedEvil
{
public record ChampionEntry
{
public readonly bool m_RandomizeType;
public readonly ChampionSpawnType m_Type;
public readonly Point3D m_SignLocation;
public readonly Type m_ChampType;
public readonly Map m_Map;
public readonly Point3D m_EjectLocation;
public readonly Map m_EjectMap;
public ChampionEntry(Type champtype, Point3D signloc, Map map, Point3D ejectloc, Map ejectmap) :
this(champtype, ChampionSpawnType.Abyss, signloc, map, ejectloc, ejectmap, true)
{
}
public ChampionEntry(
Type champtype, ChampionSpawnType type, Point3D signloc, Map map, Point3D ejectloc, Map ejectmap,
bool randomizetype = false
)
{
m_ChampType = champtype;
m_RandomizeType = randomizetype;
m_Type = type;
m_SignLocation = signloc;
m_Map = map;
m_EjectLocation = ejectloc;
m_EjectMap = ejectmap;
}
}
}

View file

@ -0,0 +1,116 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: GenChamps.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Generic;
using Server.Logging;
namespace Server.Engines.CannedEvil
{
public static class ChampionGenerator
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(ChampionGenerator));
public static void Initialize()
{
CommandSystem.Register("GenChamps", AccessLevel.Owner, ChampGen_OnCommand);
}
private static readonly ChampionEntry[] LLLocations = {
new(typeof(LLChampionSpawn), new Point3D(5511, 2360, 42), Map.Felucca, new Point3D(5439, 2323, 26 ), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(6038, 2401, 47), Map.Felucca, new Point3D(5988, 2340, 24), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5549, 2640, 16), Map.Felucca, new Point3D(5645, 2696, -8), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5636, 2916, 37), Map.Felucca, new Point3D(5721, 2949, 28), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(6035, 2943, 50), Map.Felucca, new Point3D(6098, 2997, 17), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5265, 3171, 105), Map.Felucca, new Point3D(5314, 3232, 2), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5282, 3368, 50), Map.Felucca, new Point3D(5215, 3318, 3), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5207, 3637, 20), Map.Felucca, new Point3D(5263, 3687, 0), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5954, 3475, 25), Map.Felucca, new Point3D(6013, 3529, 0), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5982, 3882, 20), Map.Felucca, new Point3D(5929, 3820, -1), Map.Felucca),
new(typeof(LLChampionSpawn), new Point3D(5724, 3991, 41), Map.Felucca, new Point3D(5774, 4041, 26), Map.Felucca),
new(typeof(LLChampionSpawn), ChampionSpawnType.ForestLord, new Point3D(5559, 3757, 21), Map.Felucca, new Point3D(5513, 3878, 3), Map.Felucca),
};
private static readonly ChampionEntry[] DungeonLocations = {
new(typeof(DungeonChampionSpawn), ChampionSpawnType.UnholyTerror, new Point3D(5179, 709, 20), Map.Felucca, new Point3D(4111, 432, 5), Map.Felucca),
new(typeof(DungeonChampionSpawn), ChampionSpawnType.VerminHorde, new Point3D(5557, 827, 65), Map.Felucca, new Point3D(5580, 632, 30), Map.Felucca),
new(typeof(DungeonChampionSpawn), ChampionSpawnType.ColdBlood, new Point3D(5259, 837, 64), Map.Felucca, new Point3D(1176, 2637, 0), Map.Felucca),
new(typeof(DungeonChampionSpawn), ChampionSpawnType.Abyss, new Point3D(5815, 1352, 5), Map.Felucca, new Point3D(2923, 3406, 8), Map.Felucca),
new(typeof(DungeonChampionSpawn), ChampionSpawnType.Arachnid, new Point3D(5190, 1607, 20), Map.Felucca, new Point3D(5482, 3161, -54), Map.Felucca),
};
[Usage("GenChamps")]
[Description("Generates champions for Felucca Dungeons & Lost Lands.")]
private static void ChampGen_OnCommand(CommandEventArgs e)
{
/*
//We take the assumption that we are spawning managed champions
for (int i = CannedEvilTimer.DungeonSpawns.Count - 1; i >= 0; i--)
CannedEvilTimer.DungeonSpawns[i].Delete();
for (int i = CannedEvilTimer.LLSpawns.Count - 1; i >= 0; i--)
CannedEvilTimer.LLSpawns[i].Delete();
*/
//We assume that all champion spawns are generated here.
List<ChampionSpawn> spawns = new List<ChampionSpawn>();
foreach (Item item in World.Items.Values)
{
if (item is ChampionSpawn spawn)
{
spawns.Add(spawn);
}
}
for (int i = spawns.Count - 1; i >= 0; i--)
{
spawns[i].Delete();
}
Process(DungeonLocations);
Process(LLLocations);
//ProcessIlshenar();
//ProcessTokuno();
}
private static void Process(ChampionEntry[] entries)
{
for (int i = 0; i < entries.Length; i++)
{
ChampionEntry entry = entries[i];
try
{
if (Activator.CreateInstance(entry.m_ChampType) is ChampionSpawn spawn)
{
spawn.RandomizeType = entry.m_RandomizeType;
spawn.Type = entry.m_Type;
spawn.MoveToWorld(entry.m_SignLocation, entry.m_Map);
spawn.EjectLocation = entry.m_EjectLocation;
spawn.EjectMap = entry.m_EjectMap;
if (spawn.AlwaysActive)
{
spawn.ReadyToActivate = true;
}
}
}
catch
{
logger.Warning($"Failed to generate champion spawn {entry.m_ChampType.FullName} at {entry.m_SignLocation} ({entry.m_Map})");
}
}
}
}
}

View file

@ -0,0 +1,55 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: LLChampionSpawn.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
namespace Server.Engines.CannedEvil
{
public class LLChampionSpawn : ChampionSpawn
{
public override bool HasStarRoomGate => false;
[Constructible]
public LLChampionSpawn()
{
CannedEvilTimer.AddSpawn(this);
}
public LLChampionSpawn(Serial serial) : base(serial)
{
}
public override bool AlwaysActive => false;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); //version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
CannedEvilTimer.AddSpawn(this);
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
CannedEvilTimer.RemoveSpawn(this);
}
}
}

View file

@ -1,20 +0,0 @@
using System;
namespace Server.Engines.CannedEvil
{
public class RestartTimer : Timer
{
private readonly ChampionSpawn m_Spawn;
public RestartTimer(ChampionSpawn spawn, TimeSpan delay) : base(delay)
{
m_Spawn = spawn;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
m_Spawn.EndRestart();
}
}
}

View file

@ -1,20 +0,0 @@
using System;
namespace Server.Engines.CannedEvil
{
public class SliceTimer : Timer
{
private readonly ChampionSpawn m_Spawn;
public SliceTimer(ChampionSpawn spawn) : base(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0))
{
m_Spawn = spawn;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Spawn.OnSlice();
}
}
}

View file

@ -314,14 +314,14 @@ namespace Server.Items
{
}
public override void Serialize( GenericWriter writer )
public override void Serialize(IGenericWriter writer)
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
public override void Deserialize(IGenericReader reader)
{
base.Deserialize( reader );

View file

@ -121,7 +121,7 @@ namespace Server.Items
if (Region.Find(bc.Home, map) is ChampionSpawnRegion region)
{
var spawn = region.ChampionSpawn;
var spawn = region.Spawn;
if (spawn?.IsChampionSpawn(bc) == true)
{

View file

@ -84,7 +84,7 @@ namespace Server.Spells.Necromancy
public override void OnCast()
{
var r = Caster.Region.GetRegion<ChampionSpawnRegion>();
if (r == null || !Caster.InRange(r.ChampionSpawn, Range))
if (r == null || !Caster.InRange(r.Spawn, Range))
{
Caster.SendLocalizedMessage(1072111); // You are not in a valid exorcism region.
}
@ -95,7 +95,7 @@ namespace Server.Spells.Necromancy
if (map != null)
{
// Surprisingly, no sparkle type effects
foreach (var m in r.ChampionSpawn.GetMobilesInRange(Range))
foreach (var m in r.Spawn.GetMobilesInRange(Range))
{
if (IsValidTarget(m))
{