#W# Added: Town gathering spots for citizens.
This commit is contained in:
parent
d05a274ba6
commit
55aada83d4
6 changed files with 475 additions and 3 deletions
127
Projects/UOContent/Misc/RandomThings.cs
Normal file
127
Projects/UOContent/Misc/RandomThings.cs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
using System;
|
||||
using Server;
|
||||
using System.Collections;
|
||||
using Server.Misc;
|
||||
using Server.Network;
|
||||
using Server.Commands;
|
||||
using Server.Commands.Generic;
|
||||
using Server.Items;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
class RandomThings
|
||||
{
|
||||
public static string GetRandomRealDungeon()
|
||||
{
|
||||
string rDungeon = "Unknown";
|
||||
switch( Utility.RandomMinMax( 0, 8 ))
|
||||
{
|
||||
case 0: rDungeon = "Dungeon Covetous"; break;
|
||||
case 1: rDungeon = "Dungeon Despice"; break;
|
||||
case 2: rDungeon = "Dungeon Deceit"; break;
|
||||
case 3: rDungeon = "Dungeon Destard"; break;
|
||||
case 4: rDungeon = "Dungeon Despise"; break;
|
||||
case 5: rDungeon = "Dungeon Shame"; break;
|
||||
case 6: rDungeon = "Dungeon Hythloth"; break;
|
||||
case 7: rDungeon = "Dungeon Terathan Keep"; break;
|
||||
case 8: rDungeon = "Dungeon of Ice"; break;
|
||||
}
|
||||
return rDungeon;
|
||||
}
|
||||
|
||||
public static string GetRandomRealTown()
|
||||
{
|
||||
string rTown = "Unknown";
|
||||
switch( Utility.RandomMinMax( 0, 12 ))
|
||||
{
|
||||
case 0: rTown = "Bastion"; break;
|
||||
case 1: rTown = "Mireport"; break;
|
||||
case 2: rTown = "Myrish"; break;
|
||||
case 3: rTown = "Teareek"; break;
|
||||
case 4: rTown = "Landow"; break;
|
||||
case 5: rTown = "Rivermouth"; break;
|
||||
case 6: rTown = "Wharf's End"; break;
|
||||
case 7: rTown = "Coldbarrow"; break;
|
||||
case 8: rTown = "Fairwinds"; break;
|
||||
case 9: rTown = "Stonehollow"; break;
|
||||
case 10: rTown = "Cresthaven"; break;
|
||||
case 11: rTown = "Port Grim"; break;
|
||||
case 12: rTown = "Maerid"; break;
|
||||
}
|
||||
return rTown;
|
||||
}
|
||||
|
||||
public static string GetRandomFakeDungeon()
|
||||
{
|
||||
string fDungeon = "Unknown";
|
||||
switch( Utility.RandomMinMax( 0, 2))
|
||||
{
|
||||
case 0: fDungeon = "Scourge Keep"; break;
|
||||
case 1: fDungeon = "Eliffs Cave"; break;
|
||||
case 2: fDungeon = "Crypts Elbow"; break;
|
||||
}
|
||||
return fDungeon;
|
||||
}
|
||||
|
||||
public static string GetRandomFakeTown()
|
||||
{
|
||||
string fTown = "Unknown";
|
||||
switch( Utility.RandomMinMax( 0, 2))
|
||||
{
|
||||
case 0: fTown = "Klydeport"; break;
|
||||
case 1: fTown = "Longshore"; break;
|
||||
case 2: fTown = "Tessburg"; break;
|
||||
}
|
||||
return fTown;
|
||||
}
|
||||
|
||||
public static string GetRandomAdjective()
|
||||
{
|
||||
string adj = "an odd";
|
||||
switch( Utility.RandomMinMax( 0, 6 ))
|
||||
{
|
||||
case 0: adj = "an odd"; break;
|
||||
case 1: adj = "a weirdly crafted"; break;
|
||||
case 2: adj = "a suspiciously shiny"; break;
|
||||
case 3: adj = "a blood-stained"; break;
|
||||
case 4: adj = "a masterfully forged"; break;
|
||||
case 5: adj = "an ancient, cursed"; break;
|
||||
case 6: adj = "a rusted but reliable"; break;
|
||||
}
|
||||
return adj;
|
||||
}
|
||||
|
||||
public static string GetRandomName()
|
||||
{
|
||||
string name = "John";
|
||||
switch( Utility.RandomMinMax( 0, 7 ))
|
||||
{
|
||||
case 0: name = "Balthazar"; break;
|
||||
case 1: name = "Kaelen"; break;
|
||||
case 2: name = "Elias"; break;
|
||||
case 3: name = "Gwendolyn"; break;
|
||||
case 4: name = "Darius"; break;
|
||||
case 5: name = "Seraphina"; break;
|
||||
case 6: name = "Vander"; break;
|
||||
case 7: name = "Isolde"; break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static string GetRandomTitle()
|
||||
{
|
||||
string title = "King";
|
||||
switch( Utility.RandomMinMax( 0, 5 ))
|
||||
{
|
||||
case 0: title = "King"; break;
|
||||
case 1: title = "Queen"; break;
|
||||
case 2: title = "Baron"; break;
|
||||
case 3: title = "Duke"; break;
|
||||
case 4: title = "Lord"; break;
|
||||
case 5: title = "Lady"; break;
|
||||
}
|
||||
return title;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ using System;
|
|||
using Server;
|
||||
using Server.Items;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Misc;
|
||||
using Server.Custom;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
|
|
@ -12,12 +14,29 @@ namespace Server.Mobiles
|
|||
|
||||
private static readonly string[] _ChatterLines = new string[]
|
||||
{
|
||||
// General
|
||||
"Lovely weather we're having today.",
|
||||
"I heard the dungeons are more dangerous than usual...",
|
||||
"Just another quiet day in town.",
|
||||
"I need to visit the provisioner soon.",
|
||||
"Have you seen my lost dog?",
|
||||
"The guards seem on edge lately."
|
||||
"The guards seem on edge lately.",
|
||||
"Just another quiet day in town.",
|
||||
|
||||
// Real Dungeon
|
||||
"I heard the {rdungeon} is more dangerous than usual...",
|
||||
"Stay away from {rdungeon}, I lost a good friend there.",
|
||||
|
||||
// Real Town
|
||||
"Did you hear the recent news from {rtown}?",
|
||||
|
||||
// Fake Dungeon
|
||||
"Did you hear that {fdungeon} has been destroyed?",
|
||||
|
||||
// Fake Town
|
||||
"I'm thinking of packing up and moving to {ftown}.",
|
||||
|
||||
// Active Dungeon of the Day
|
||||
"I saw a huge group of adventurers heading toward {activedungeon} this morning.",
|
||||
"They say the magical energies are shifting around {activedungeon} today."
|
||||
};
|
||||
|
||||
// Add your custom titles here!
|
||||
|
|
@ -148,6 +167,29 @@ namespace Server.Mobiles
|
|||
if (playerNearby)
|
||||
{
|
||||
string line = _ChatterLines[Utility.Random(_ChatterLines.Length)];
|
||||
|
||||
if (line.Contains("{rdungeon}"))
|
||||
line = line.Replace("{rdungeon}", Server.Misc.RandomThings.GetRandomRealDungeon());
|
||||
|
||||
if (line.Contains("{rtown}"))
|
||||
line = line.Replace("{rtown}", Server.Misc.RandomThings.GetRandomRealTown());
|
||||
|
||||
if (line.Contains("{fdungeon}"))
|
||||
line = line.Replace("{fdungeon}", Server.Misc.RandomThings.GetRandomFakeDungeon());
|
||||
|
||||
if (line.Contains("{ftown}"))
|
||||
line = line.Replace("{ftown}", Server.Misc.RandomThings.GetRandomFakeTown());
|
||||
|
||||
if (line.Contains("{activedungeon}"))
|
||||
{
|
||||
string dotd = Server.Custom.DailyDungeonManager.ActiveDungeon;
|
||||
|
||||
if (string.IsNullOrEmpty(dotd))
|
||||
dotd = "one of the local dungeons";
|
||||
|
||||
line = line.Replace("{activedungeon}", dotd);
|
||||
}
|
||||
|
||||
Say(line);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class FriendlyTownMonster : BaseCreature
|
||||
{
|
||||
private DateTime _NextChatter;
|
||||
public override bool InitialInnocent => true;
|
||||
|
||||
[Constructible]
|
||||
public FriendlyTownMonster() : base(AIType.AI_Animal, FightMode.None)
|
||||
{
|
||||
Name = NameList.RandomName("orc");
|
||||
Title = "the civilized";
|
||||
Body = Utility.RandomList(17, 1075, 1072);
|
||||
BaseSoundID = 0x45A;
|
||||
|
||||
Karma = 1000;
|
||||
Fame = 1000;
|
||||
_NextChatter = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(10, 20));
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
if (Deleted) return;
|
||||
|
||||
if (DateTime.UtcNow > _NextChatter)
|
||||
{
|
||||
bool playerNearby = false;
|
||||
foreach (Mobile m in GetMobilesInRange(8))
|
||||
{
|
||||
if (m != null && m.Player && m.Alive)
|
||||
{
|
||||
playerNearby = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (playerNearby)
|
||||
{
|
||||
string[] lines = {
|
||||
"*grunts amicably*",
|
||||
"Me like town. No heroes trying to stab me.",
|
||||
"Guards no chase me here.",
|
||||
"You have shiny coins for trading?"
|
||||
};
|
||||
Say(lines[Utility.Random(lines.Length)]);
|
||||
}
|
||||
|
||||
_NextChatter = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(30, 60));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsHarmfulCriminal(Mobile target) => true;
|
||||
|
||||
public FriendlyTownMonster(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class GatheringCitizen : Citizen
|
||||
{
|
||||
private Direction _GatherDirection;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Direction GatherDirection
|
||||
{
|
||||
get => _GatherDirection;
|
||||
set => _GatherDirection = value;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public GatheringCitizen() : base()
|
||||
{
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (Direction != _GatherDirection)
|
||||
{
|
||||
Direction = _GatherDirection;
|
||||
}
|
||||
}
|
||||
|
||||
public GatheringCitizen(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)_GatherDirection);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
_GatherDirection = (Direction)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class GatheringMonster : FriendlyTownMonster
|
||||
{
|
||||
private Direction _GatherDirection;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Direction GatherDirection
|
||||
{
|
||||
get => _GatherDirection;
|
||||
set => _GatherDirection = value;
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
public GatheringMonster() : base()
|
||||
{
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (Direction != _GatherDirection)
|
||||
{
|
||||
Direction = _GatherDirection;
|
||||
}
|
||||
}
|
||||
|
||||
public GatheringMonster(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)_GatherDirection);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
_GatherDirection = (Direction)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TownGatheringSpot : Item
|
||||
{
|
||||
private List<Mobile> _Attendees = new List<Mobile>();
|
||||
|
||||
[Constructible]
|
||||
public TownGatheringSpot() : base(0xFF8D)
|
||||
{
|
||||
Name = "Town Gathering Spot";
|
||||
Visible = true;
|
||||
Movable = false;
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), CheckAndSpawn);
|
||||
}
|
||||
|
||||
private void CheckAndSpawn()
|
||||
{
|
||||
if (Deleted || Map == null || Map == Map.Internal)
|
||||
return;
|
||||
|
||||
_Attendees.RemoveAll(m => m == null || m.Deleted || !m.Alive);
|
||||
|
||||
if (_Attendees.Count == 0)
|
||||
{
|
||||
SpawnGathering();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.AccessLevel >= AccessLevel.GameMaster)
|
||||
{
|
||||
SpawnGathering();
|
||||
from.SendMessage("Gathering forcefully respawned and reset!");
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnGathering()
|
||||
{
|
||||
foreach(Mobile m in _Attendees)
|
||||
{
|
||||
if (m != null && !m.Deleted)
|
||||
m.Delete();
|
||||
}
|
||||
_Attendees.Clear();
|
||||
|
||||
Mobile east = new GatheringCitizen();
|
||||
Mobile south = new GatheringCitizen();
|
||||
Mobile west = new GatheringMonster();
|
||||
Mobile north = new GatheringMonster();
|
||||
|
||||
PlaceAndFace(east, Location.X + 3, Location.Y, Location.Z, Direction.West);
|
||||
PlaceAndFace(west, Location.X - 3, Location.Y, Location.Z, Direction.East);
|
||||
PlaceAndFace(south, Location.X, Location.Y + 3, Location.Z, Direction.North);
|
||||
PlaceAndFace(north, Location.X, Location.Y - 3, Location.Z, Direction.South);
|
||||
}
|
||||
|
||||
private void PlaceAndFace(Mobile m, int x, int y, int z, Direction facing)
|
||||
{
|
||||
m.MoveToWorld(new Point3D(x, y, z), Map);
|
||||
m.CantWalk = true;
|
||||
|
||||
if (m is GatheringCitizen gc)
|
||||
{
|
||||
gc.GatherDirection = facing;
|
||||
}
|
||||
else if (m is GatheringMonster gm)
|
||||
{
|
||||
gm.GatherDirection = facing;
|
||||
}
|
||||
|
||||
m.Direction = facing;
|
||||
|
||||
_Attendees.Add(m);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
foreach (Mobile m in _Attendees)
|
||||
{
|
||||
if (m != null && !m.Deleted)
|
||||
{
|
||||
m.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
_Attendees.Clear();
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public TownGatheringSpot(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(_Attendees.Count);
|
||||
foreach (Mobile m in _Attendees)
|
||||
{
|
||||
writer.Write(m);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Mobile m = reader.ReadEntity<Mobile>();
|
||||
|
||||
if (m != null && !m.Deleted)
|
||||
{
|
||||
_Attendees.Add(m);
|
||||
}
|
||||
}
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(1.0), CheckAndSpawn);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue