Full Version : Time attack dungeon
xmlspawner >>Q&A >>Time attack dungeon


<< Prev | Next >>

afonso- 03-05-2009
Hi everyone =) It's been a while since I came here last, but I have a problem that I think only XMLSpawner can handle.

I've been working on getting my shard up to 2.0, and part of it means adding new content.

One of the things I want to do (and something my players have been asking) is a time-attack dungeon. The idea is to have a course, filled with traps and beasts and puzzles, to be completed solo. Each player must finish the course as fast as they can.

How do I go about it?

My idea so far:

Create two stones, and a script that records the time it takes to click one and then the other. That way, the players clicked one to start, and one to finish.
I have no idea on how to start a timer, but I think I'll be able to figure it out eventually. The other was would be to use two XML spawners that would activate on player triggering, which brings me to my second idea

Recording the time
I was thinking of using an XMLAttachment to keep track of the player time. Again, I have no idea of how to do this, as I'm just starting to learn about attachments. the attachment would be added the first time a player used the dungeon, and would use the recorded time to keep scores

Top players
Using the attachment, I want to create a board that names the 5 players with the quickest time.


And that's basically it. Honestly, I was hoping something like this had already been made (I'm pretty sure it's not a completely original idea), but I don't mind giving this a go. I would ask my friends here for a little guide, namely some scripts or examples that may shine a light on the upcoming road =)

Thank you for listening
Afonso

EDIT:

Here's what I've got so far (heavily based on XMLPoints )

CODE

using System;
using System.IO;
using System.Xml;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.Collections;
using System.Collections.Generic;
using Server.Targeting;
using Server.Gumps;
using System.Text;
using Server.Regions;
using Server.Spells;
using Server.Commands;
using Server.Commands.Generic;

namespace Server.Engines.XmlSpawner2
{

public class XmlTimeAttack : XmlAttachment
{
 private TimeSpan m_PersonalBest;
 private DateTime m_GameStart;
 private DateTime m_GameEnd;
 private TimeSpan m_GameTime;
 
 private Point3D StartLocation = new Point3D (1064,819,-75);
 private Point3D EndLocation  = new Point3D (1073,819,-75);
 public Map m_StartingMap = Map.Malas;
 
 // a serial constructor is REQUIRED
 public XmlTimeAttack(ASerial serial) : base(serial)
 {
 }

 [Attachable]
 public XmlTimeAttack()
 {
 }
 
 
 [CommandProperty( AccessLevel.GameMaster )]
 public TimeSpan PersonalBest { get{ return m_PersonalBest; } set { m_PersonalBest = value; } }

 public void Start()
 {
  m_GameStart = DateTime.Now;
 }

 public void Stop()
 {
   m_GameEnd = DateTime.Now;
   m_GameTime = ( DateTime.Now.Subtract( m_GameStart ) );
   
   if ( PersonalBest > m_GameTime )
   {
    m_PersonalBest = m_GameTime;
   }
 }
 
 public override bool HandlesOnMovement { get { return true; } }
 
 public override void OnMovement(MovementEventArgs e )
 {
  base.OnMovement(e);
     
  if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;

  if( e.Mobile.Location == StartLocation && e.Mobile.Map == m_StartingMap )
  {
   e.Mobile.SendMessage( "you're at the start zone" );

   Start();
  }
  else if ( e.Mobile.Location == EndLocation && e.Mobile.Map == m_StartingMap )
  {
   e.Mobile.SendMessage( "you're at the end zone" );
   Stop();
  }
  else
   return;
 }
 
 public static new void Initialize()
 {
  // Register our speech handler
  EventSink.Speech += new SpeechEventHandler( EventSink_Speech );
 
  CommandSystem.Register( "AddAllTA", AccessLevel.Administrator, new CommandEventHandler( AddAllTA_OnCommand ) );
  CommandSystem.Register( "RemoveAllTA", AccessLevel.Administrator, new CommandEventHandler( RemoveAllTA_OnCommand ) );
 
 }
 
 
 
 [Usage( "AddAllTA" )]
 [Description( "Adds the XmlTimeAttack attachment to all players" )]
 public static void AddAllTA_OnCommand( CommandEventArgs e )
 {
  int count = 0;
  foreach(Mobile m in World.Mobiles.Values)
  {
   if(m.Player)
   {
    // does this player already have a time attack attachment?
    ArrayList list = XmlAttach.FindAttachments(m,typeof(XmlTimeAttack));
    if(list == null || list.Count == 0)
    {
     XmlAttachment x = new XmlTimeAttack();
     XmlAttach.AttachTo(e.Mobile, m,x);
     count++;
    }
   }
  }
  e.Mobile.SendMessage("Added XmlTimeAttack attachments to {0} players",count);
 }

 
 
 [Usage( "RemoveAllTA" )]
 [Description( "Removes the XmlTimeAttack attachment from all players" )]
 public static void RemoveAllTA_OnCommand( CommandEventArgs e )
 {
  int count = 0;
  foreach(Mobile m in World.Mobiles.Values)
  {
   if(m.Player)
   {
    ArrayList list = XmlAttach.FindAttachments(XmlAttach.MobileAttachments,  m, typeof(XmlTimeAttack));
    if(list != null && list.Count > 0)
    {
     foreach(XmlAttachment x in list)
     {
      x.Delete();
     }
    }
    count++;
   }
  }
  e.Mobile.SendMessage("Removed XmlTimeAttack attachments from {0} players",count);
 }

 public static void EventSink_Speech( SpeechEventArgs args )
 {
  Mobile from = args.Mobile;
 
  if(from == null || from.Map == null || !from.Player) return;
 
  if(args.Speech != null && args.Speech.ToLower() == "showpoints")
   ShowPBOverhead(from);
 
 }
 
 public static void ShowPBOverhead( Mobile from )
 {
  if(from == null) return;

  from.PublicOverheadMessage( MessageType.Regular, 0x3B2, false, GetPoints(from).ToString());
 }
 
 public static TimeSpan GetPoints(Mobile m)
 {
  TimeSpan val = TimeSpan.Zero;

  ArrayList list = XmlAttach.FindAttachments(m,typeof(XmlTimeAttack));
  if(list != null && list.Count > 0)
  {
   val = ((XmlTimeAttack)list[0]).PersonalBest;
  }
           
  return val;
 }
 
 
 public override void Serialize( GenericWriter writer )
 {
  base.Serialize(writer);
 
  writer.Write( (int) 0 );
 
  writer.Write(m_PersonalBest);
  writer.Write(m_GameStart);
  writer.Write(m_GameEnd);
  writer.Write(m_GameTime);
  writer.Write(StartLocation);
  writer.Write(EndLocation);
  writer.Write(m_StartingMap.ToString());  
 
 }

 public override void Deserialize(GenericReader reader)
 {
  base.Deserialize(reader);
 
  int version = reader.ReadInt();
 
  switch(version)
  {
   case 0:
   {
    m_PersonalBest = reader.ReadTimeSpan();
    m_GameStart = reader.ReadDateTime();
    m_GameEnd = reader.ReadDateTime();
    m_GameTime = reader.ReadTimeSpan();
    StartLocation = reader.ReadPoint3D();
    EndLocation = reader.ReadPoint3D();
    break;
   }
  }
 }
}
}



It compiles, but the timer isn't working....