////////////////////////////////////////////////////////////////////////// // Your module's main class must have a constructor that takes // ONLY a ModuleHost object. public EmptyModule( Furnarchy.ModuleHost host ) { m_host = host; // Subscribe to some commonly used events. (optional) m_host.EnabledEvent += new Furnarchy.EnabledDelegate( onEnabled ); m_host.DisabledEvent += new Furnarchy.DisabledDelegate( onDisabled ); m_host.TouchedEvent += new Furnarchy.TouchedDelegate( onTouched ); m_host.TickEvent += new Furnarchy.TickDelegate( onTick ); }
////////////////////////////////////////////////////////////////////////// // Your module's main class must have a constructor that takes // ONLY a ModuleHost object. public EmptyModule( Furnarchy.ModuleHost host ) { m_host = host; // Our list of toasters. m_toasters = new LinkedList<Toaster>( ); // Create our player context submenu you see when you right-click // on an avatar. m_player_menu = new MenuItem( ); m_player_menu.MenuItems.Add( "Toaster!" ).Click += new EventHandler( onMenuToasterClick ); // Attach it to Furc's player context menu. m_host.Client.attachPlayerMenu( m_player_menu ); /* Subscribe to events. */ // We need to intercept avatar creation, movement, and update commands to make // sure people are created as and remain toasters. The Net subsystem // exposes these events. m_host.Net.InboundAvatarCreateEvent += new Furnarchy.InboundAvatarCreateDelegate( onInboundAvatarCreate ); m_host.Net.InboundAvatarMoveEvent += new Furnarchy.InboundAvatarMoveDelegate( onInboundAvatarMove ); m_host.Net.InboundAvatarUpdateEvent += new Furnarchy.InboundAvatarUpdateDelegate( onInboundAvatarUpdate ); m_host.Net.InboundAvatarShowEvent += new Furnarchy.InboundAvatarShowDelegate( onInboundAvatarShow ); m_host.Net.InboundAvatarShow2Event += new Furnarchy.InboundAvatarShow2Delegate( onInboundAvatarShow2 ); // The Client subsystem's PlayerMenuShowingEvent event will tell us when the player // context menu is being shown and the player's name. This allows us to customize the // menu per-player. m_host.Client.PlayerMenuShowingEvent += new Furnarchy.PlayerMenuShowingDelegate( onPlayerMenuShowing ); // Some other common events we'll handle. m_host.EnabledEvent += new Furnarchy.EnabledDelegate( onEnabled ); m_host.DisabledEvent += new Furnarchy.DisabledDelegate( onDisabled ); m_host.TouchedEvent += new Furnarchy.TouchedDelegate( onTouched ); m_host.CommandEvent += new Furnarchy.CommandDelegate( onCommand ); // Load up the toasters file. loadToasters( ); // Enable ourselves right away. m_host.Enabled = true; }
// This event is raised roughly every 75ms. void onTick( object sender, Furnarchy.TickEventArgs e ) { // e.dt is the number of milliseconds that have passed since the last tick event. }
// Player context menu is about to be shown. void onPlayerMenuShowing( object sender, Furnarchy.PlayerMenuShowingEventArgs e ) { // Check the "Toaster" menu item if the player is already a toaster. if (findToaster( e.player_name ) != null) m_player_menu.MenuItems[ 0 ].Checked = true; else // Not a toaster, so uncheck it. m_player_menu.MenuItems[ 0 ].Checked = false; }
// An avatar's appearance is changing. void onInboundAvatarUpdate( object sender, Furnarchy.InboundAvatarUpdateEventArgs e ) { if (m_host.Enabled) { // Use the World subsystem to find the avatar's name. Furnarchy.MonsterInfo info = m_host.World.getMonsterInfo( e.guid ); if (info.guid != 0) { LinkedListNode<Toaster> t = findToaster( info.name ); if (t != null) { // This avatar is in our toaster list! // Rebuild the command so that the avatar frame is a toaster. // The basic format of an avatar update command is: // B{guid}{frame}{colors} // format() can easily build this line for us. e.line = m_host.Net.format( "B%4N%2N%c", e.guid, makeToasterFrame( e.frame ), e.colors ); // Remember the avatar's real frame number in case we have to un-toaster him later. t.Value = new Toaster( t.Value.shortname, e.frame ); } } } }
// An avatar is being created. void onInboundAvatarCreate( object sender, Furnarchy.InboundAvatarCreateEventArgs e ) { if (m_host.Enabled) { LinkedListNode<Toaster> t = findToaster( e.name ); if (t != null) { // This avatar is in our toaster list! // Rebuild the command so that the avatar frame is a toaster. // The basic format of an avatar creation command is: // <{guid}{x}{y}{frame}{name}{colors}{flags} // format() can easily build this line for us. e.line = m_host.Net.format( "<%4N%2N%2N%2N%s%c%1N", e.guid, e.x, e.y, makeToasterFrame( e.frame ), e.name, e.colors, e.flags ); // Remember the avatar's real frame number in case we have to un-toaster him later. t.Value = new Toaster( t.Value.shortname, e.frame ); } } }
void onCommand( object sender, Furnarchy.CommandEventArgs e ) { if (e.args[ 0 ].ToLower( ) == "toaster") { if (e.args.Length > 1) { if (e.args[ 1 ].ToLower( ) == "clear") { // User said "@toaster clear", so flush the toaster list! clearToasters( false ); saveToasters( ); // Set 'handled' to true to indicate we handled the command. e.handled = true; return; } else if (e.args[ 1 ].ToLower( ) == "list") { // User said "@toaster list", so list the toasters! StringBuilder sb = new StringBuilder( String.Format( "{0} toasters: ", m_toasters.Count ) ); for (LinkedListNode<Toaster> i = m_toasters.First; i != null; i = i.Next) { sb.Append( "<i>" ); sb.Append( i.Value.shortname ); sb.Append( "</i>" ); if (i.Next != null) sb.Append( ", " ); else sb.Append( "." ); } m_host.speak( sb.ToString( ) ); // Set 'handled' to true to indicate we handled the command. e.handled = true; return; } } // Touch this module so we raise an onTouched event and spit out the instructions. m_host.touch( ); // Set 'handled' to true to indicate we handled the command. e.handled = true; return; } }