#W# Add a new kind of towncrier the HintCrier.

This commit is contained in:
WarrentyExpired 2026-07-15 18:36:11 -04:00
parent 7fea9764af
commit 717dbd4e1a
4 changed files with 267 additions and 0 deletions

View file

@ -0,0 +1,32 @@
using System;
using Server;
using Server.Commands;
using Server.Mobiles; // Needed to access HintCrier
namespace Server.Scripts.Commands
{
public class BroadcastCrierCommand
{
public static void Initialize()
{
// Registers the command so only GameMasters or higher can use it
CommandSystem.Register( "BroadcastCrier", AccessLevel.GameMaster, new CommandEventHandler( BroadcastCrier_OnCommand ) );
}
[Usage( "BroadcastCrier <message>" )]
[Description( "Forces all HintCriers to shout a custom message to test the AnnounceEvent method." )]
public static void BroadcastCrier_OnCommand( CommandEventArgs e )
{
// Make sure the GM actually typed a message
if ( string.IsNullOrWhiteSpace( e.ArgString ) )
{
e.Mobile.SendMessage( "Usage: [BroadcastCrier <message>" );
return;
}
// Pass whatever the GM typed directly into our static AnnounceEvent method
HintCrier.AnnounceEvent( e.ArgString );
e.Mobile.SendMessage( "Event announced to all Hint Criers." );
}
}
}

View file

@ -0,0 +1,149 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
public class HintCrier : BaseCreature
{
private static List<HintCrier> m_Instances = new List<HintCrier>();
public static List<HintCrier> Instances { get { return m_Instances; } }
// The timer that handles ambient shouting
private Timer m_AutoShoutTimer;
public static void AnnounceEvent( string message )
{
foreach ( HintCrier crier in m_Instances )
{
crier.PublicOverheadMessage( MessageType.Regular, 0x2B, false, message );
}
}
private static string[] m_Hints = new string[]
{
"I hear a pure dexterous warrior strikes 10% harder than the rest...",
"They say exceptional weapons have the ability to deal more damage.",
"Rumor has it that some armors have invisible limits to evasion...",
"Walk near the crops and they just might harvest themselves..."
};
[Constructable]
public HintCrier() : base( AIType.AI_Vendor, FightMode.None, 10, 1, 0.2, 0.4 )
{
m_Instances.Add( this );
Title = "the town crier";
Hue = Utility.RandomSkinHue();
Invulnerable = true;
CantWalk = true;
SpeechHue = 0x31;
WhisperHue = 0x31;
YellHue = 0x31;
if ( Utility.RandomBool() )
{
Body = 0x191;
Name = NameList.RandomName( "female" );
}
else
{
Body = 0x190;
Name = NameList.RandomName( "male" );
}
AddItem( new FancyShirt( Utility.RandomBlueHue() ) );
AddItem( new Kilt( Utility.RandomGreenHue() ) );
AddItem( new FeatheredHat( Utility.RandomGreenHue() ) );
AddItem( new ThighBoots() );
Utility.AssignRandomHair( this );
StartTimer();
}
public HintCrier( Serial serial ) : base( serial )
{
m_Instances.Add( this );
}
// Starts a looping timer that shouts a hint every 3 to 5 minutes
private void StartTimer()
{
if ( m_AutoShoutTimer == null )
{
m_AutoShoutTimer = Timer.DelayCall( TimeSpan.FromSeconds( 15.0 ), TimeSpan.FromSeconds( 30.0 ), new TimerCallback( AutoShout_Callback ) );
}
}
// Cleans up the timer if the NPC is deleted
private void StopTimer()
{
if ( m_AutoShoutTimer != null )
{
m_AutoShoutTimer.Stop();
m_AutoShoutTimer = null;
}
}
private void AutoShout_Callback()
{
// Only shout if there is a player within 15 tiles to save server resources
bool playerNearby = false;
foreach ( Mobile m in GetMobilesInRange( 15 ) )
{
if ( m.Player )
{
playerNearby = true;
break;
}
}
if ( playerNearby )
{
string hint = m_Hints[Utility.Random( m_Hints.Length )];
PublicOverheadMessage( MessageType.Regular, 0x2B, false, hint );
}
}
public override bool HandlesOnSpeech( Mobile from )
{
return ( from.Alive && InRange( from, 12 ) );
}
public override void OnSpeech( SpeechEventArgs e )
{
string speech = e.Speech.ToLower();
if ( (e.HasKeyword( 0x30 ) || speech.Contains("hint") || speech.Contains("rumor") || speech.Contains("secret")) && e.Mobile.Alive && InRange( e.Mobile, 12 ) )
{
Direction = GetDirectionTo( e.Mobile );
string hint = m_Hints[Utility.Random( m_Hints.Length )];
PublicOverheadMessage( MessageType.Regular, 0x2B, false, hint );
}
}
public override void OnDelete()
{
StopTimer();
m_Instances.Remove( this );
base.OnDelete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
// Restart the timer when the server reboots and loads the NPC
StartTimer();
}
}
}

View file

@ -0,0 +1,84 @@
using System;
using Server;
using Server.Items;
namespace Server.Mobiles
{
public class LordBritish : BaseCreature
{
[Constructable]
public LordBritish() : base( AIType.AI_Vendor, FightMode.None, 10, 1, 0.2, 0.4 )
{
Name = "Lord British";
Title = "the Sovereign of Britannia";
Body = 400; // Human Male body type
HairItemID = 0x203B;
HairHue = 0x44E;
FacialHairItemID = 0x204B;
FacialHairHue = 0x44E;
Hue = 0x83EA; // Standard human skin tone
SpeechHue = 0x3B2; // Royal yellow/gold text when he speaks
// Make him invulnerable (Set to false if you want players to try and kill him!)
//Blessed = true;
// Base Stats
SetStr( 100 );
SetDex( 100 );
SetInt( 100 );
// Base Skills
SetSkill( SkillName.MagicResist, 100.0 );
SetSkill( SkillName.Swords, 100.0 );
SetSkill( SkillName.Tactics, 100.0 );
// Custom colored plate armor (1150 is a bright white/silver hue)
Item chest = new PlateChest();
chest.Hue = 1150;
AddItem( chest );
Item legs = new PlateLegs();
legs.Hue = 1150;
AddItem( legs );
Item arms = new PlateArms();
arms.Hue = 1150;
AddItem( arms );
Item gloves = new PlateGloves();
gloves.Hue = 1150;
AddItem( gloves );
Item gorget = new PlateGorget();
gorget.Hue = 1150;
AddItem( gorget );
// A royal red cloak
Item cloak = new Cloak();
cloak.Hue = 32;
AddItem( cloak );
AddItem( new ThighBoots() );
}
public LordBritish( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}