簡體   English   中英

我的問題是關於向對象添加更多的字符串條目

[英]My question is about adding more string entries to an object

我的問題是關於如何向MakeSpawner對象添加多個字符串?

此創建的對象具有13個單獨的字符串條目。

在當前配置中,它生成3個單獨的生成對象,每個對象只有一個字符串。 我需要制作一個至少包含八個單獨的刺項的物品。

namespace Server
{
    public class GenItems
    {
        private static int m_Count;


        private const int ICount = 8;
        private const int HomeRange = 20;
        private const bool TotalRespawn = false;

        public static void Initialize()
        {
            CommandSystem.Register("GenItems", AccessLevel.Administrator, new CommandEventHandler(Generate_OnCommand));
        }

        [Usage("GenItems")]
        [Description("Generates Items")]
        private static void Generate_OnCommand(CommandEventArgs e)
        {
            Parse(e.Mobile);
        }

        public static void Parse(Mobile from)
        {

            from.SendMessage("Generating all items...");


   MakeSpawner(new string[] { "aaa", "bbb", "ccc" },  2850, 810, 0);



        }

        private static Queue m_ToDelete = new Queue();

        public static void ClearSpawners(int x, int y, int z)
        {
            IPooledEnumerable eable = Map.Sample.GetItemsInRange(new Point3D(x, y, z), 0);

            foreach (Item item in eable)
            {
                if (item is Spawner && item.Z == z)
                    m_ToDelete.Enqueue(item);
            }

            eable.Free();

            while (m_ToDelete.Count > 0)
                ((Item)m_ToDelete.Dequeue()).Delete();
        }

        private static void MakeSpawner(string[] types, int x, int y, int z)
        {
            if (types.Length == 0)
                return;

            ClearSpawners(x, y, z);

            for (int i = 0; i < types.Length; ++i)
            {

                Spawner sp = new Spawner(types[i]);

                sp.Count = ICount;
                sp.HomeRange = HomeRange;

                sp.MoveToWorld(new Point3D(x, y, z), Map.Sample);

                if (TotalRespawn)
                {
                    sp.Respawn();
                    sp.BringToHome();
                }

                ++m_Count;
            }
        }
    }
}

由於我仍然是C#的新手,所以我沒有主意。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Server;
using Server.Items;

namespace Server.Mobiles
{
    public class Spawner : Item
    {
        private int m_Team;
        private int m_HomeRange;
        private int m_WalkingRange = -1; 
        private int m_Count;
        private TimeSpan m_MinDelay;
        private TimeSpan m_MaxDelay;
        private List<string> m_CreaturesName;
        private List<IEntity> m_Creatures;
        private DateTime m_End;
        private InternalTimer m_Timer;
        private bool m_Running;
        private bool m_Group;
        private WayPoint m_WayPoint;

        public bool IsFull{ get{ return ( m_Creatures != null && m_Creatures.Count >= m_Count ); } }

        public List<string> CreaturesName
        {
            get { return m_CreaturesName; }
            set
            {
                m_CreaturesName = value;
                if ( m_CreaturesName.Count < 1 )
                    Stop();

                InvalidateProperties();
            }
        }

        public override void OnAfterDuped( Item newItem )
        {
            Spawner s = newItem as Spawner;

            if ( s == null )
                return;

            s.m_CreaturesName = new List<string>( m_CreaturesName );
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public int Count
        {
            get { return m_Count; }
            set { m_Count = value; InvalidateProperties(); }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public WayPoint WayPoint
        {
            get
            {
                return m_WayPoint;
            }
            set
            {
                m_WayPoint = value;
            }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public bool Running
        {
            get { return m_Running; }
            set
            {
                if ( value )
                    Start();
                else
                    Stop();

                InvalidateProperties();
            }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public int HomeRange
        {
            get { return m_HomeRange; }
            set { m_HomeRange = value; InvalidateProperties(); }
        }

        [CommandProperty( AccessLevel.GameMaster )] 
        public int WalkingRange 
        { 
           get { return m_WalkingRange; } 
           set { m_WalkingRange = value; InvalidateProperties(); } 
        } 

        [CommandProperty( AccessLevel.GameMaster )]
        public int Team
        {
            get { return m_Team; }
            set { m_Team = value; InvalidateProperties(); }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public TimeSpan MinDelay
        {
            get { return m_MinDelay; }
            set { m_MinDelay = value; InvalidateProperties(); }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public TimeSpan MaxDelay
        {
            get { return m_MaxDelay; }
            set { m_MaxDelay = value; InvalidateProperties(); }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public TimeSpan NextSpawn
        {
            get
            {
                if ( m_Running )
                    return m_End - DateTime.Now;
                else
                    return TimeSpan.FromSeconds( 0 );
            }
            set
            {
                Start();
                DoTimer( value );
            }
        }

        [CommandProperty( AccessLevel.GameMaster )]
        public bool Group
        {
            get { return m_Group; }
            set { m_Group = value; InvalidateProperties(); }
        }

        [Constructable]
        public Spawner( int amount, int minDelay, int maxDelay, int team, int homeRange, string creatureName ) : base( 0x1f13 )
        {
            List<string> creaturesName = new List<string>();
            creaturesName.Add( creatureName.ToLower() );
            InitSpawn( amount, TimeSpan.FromMinutes( minDelay ), TimeSpan.FromMinutes( maxDelay ), team, homeRange, creaturesName );
        }

        [Constructable]
        public Spawner( string creatureName ) : base( 0x1f13 )
        {
            List<string> creaturesName = new List<string>();
            creaturesName.Add( creatureName.ToLower() );
            InitSpawn( 1, TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 10 ), 0, 4, creaturesName );
        }

        [Constructable]
        public Spawner() : base( 0x1f13 )
        {
            List<string> creaturesName = new List<string>();
            InitSpawn( 1, TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 10 ), 0, 4, creaturesName );
        }

        public Spawner( int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, List<string> creaturesName )
            : base( 0x1f13 )
        {
            InitSpawn( amount, minDelay, maxDelay, team, homeRange, creaturesName );
        }

        public override string DefaultName
        {
            get { return "Spawner"; }
        }

        public void InitSpawn( int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, List<string> creaturesName )
        {
            Visible = false;
            Movable = false;
            m_Running = true;
            m_Group = false;
            m_MinDelay = minDelay;
            m_MaxDelay = maxDelay;
            m_Count = amount;
            m_Team = team;
            m_HomeRange = homeRange;
            m_CreaturesName = creaturesName;
            m_Creatures = new List<IEntity>();
            DoTimer( TimeSpan.FromSeconds( 1 ) );
        }

        public Spawner( Serial serial ) : base( serial )
        {
        }

        public override void OnDoubleClick( Mobile from )
        {
            if ( from.AccessLevel < AccessLevel.GameMaster )
                return;

            SpawnerGump g = new SpawnerGump( this );
            from.SendGump( g );
        }

        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties( list );

            if ( m_Running )
            {
                list.Add( 1060742 ); // active

                list.Add( 1060656, m_Count.ToString() ); // amount to make: ~1_val~
                list.Add( 1061169, m_HomeRange.ToString() ); // range ~1_val~
                list.Add( 1060658, "walking range\t{0}", m_WalkingRange ); // ~1_val~: ~2_val~ 

                list.Add( 1060659, "group\t{0}", m_Group ); // ~1_val~: ~2_val~
                list.Add( 1060660, "team\t{0}", m_Team ); // ~1_val~: ~2_val~
                list.Add( 1060661, "speed\t{0} to {1}", m_MinDelay, m_MaxDelay ); // ~1_val~: ~2_val~

                for ( int i = 0; i < 2 && i < m_CreaturesName.Count; ++i )
                    list.Add( 1060662 + i, "{0}\t{1}", m_CreaturesName[i], CountCreatures( m_CreaturesName[i] ) );
            }
            else
            {
                list.Add( 1060743 ); // inactive
            }
        }

        public override void OnSingleClick( Mobile from )
        {
            base.OnSingleClick( from );

            if ( m_Running )
                LabelTo( from, "[Running]" );
            else
                LabelTo( from, "[Off]" );
        }

        public void Start()
        {
            if ( !m_Running )
            {
                if ( m_CreaturesName.Count > 0 )
                {
                    m_Running = true;
                    DoTimer();
                }
            }
        }

        public void Stop()
        {
            if ( m_Running )
            {
                m_Timer.Stop();
                m_Running = false;
            }
        }

        public void Defrag()
        {
            bool removed = false;

            for ( int i = 0; i < m_Creatures.Count; ++i )
            {
                IEntity e = m_Creatures[i];

                if ( e is Item )
                {
                    Item item = (Item)e;

                    if ( item.Deleted || item.Parent != null )
                    {
                        m_Creatures.RemoveAt( i );
                        --i;
                        removed = true;
                    }
                }
                else if ( e is Mobile )
                {
                    Mobile m = (Mobile)e;

                    if ( m.Deleted )
                    {
                        m_Creatures.RemoveAt( i );
                        --i;
                        removed = true;
                    }
                    else if ( m is BaseCreature )
                    {
                        BaseCreature bc = (BaseCreature)m;
                        if ( bc.Controlled || bc.IsStabled )
                        {
                            m_Creatures.RemoveAt( i );
                            --i;
                            removed = true;
                        }
                    }
                }
                else
                {
                    m_Creatures.RemoveAt( i );
                    --i;
                    removed = true;
                }
            }

            if ( removed )
                InvalidateProperties();
        }

        public void OnTick()
        {
            DoTimer();

            if ( m_Group )
            {
                Defrag();

                if  ( m_Creatures.Count == 0 )
                {
                    Respawn();
                }
                else
                {
                    return;
                }
            }
            else
            {
                Spawn();
            }
        }

        public void Respawn()
        {
            RemoveCreatures();

            for ( int i = 0; i < m_Count; i++ )
                Spawn();
        }

        public void Spawn()
        {
            if ( m_CreaturesName.Count > 0 )
                Spawn( Utility.Random( m_CreaturesName.Count ) );
        }

        public void Spawn( string creatureName )
        {
            for ( int i = 0; i < m_CreaturesName.Count; i++ )
            {
                if ( m_CreaturesName[i] == creatureName )
                {
                    Spawn( i );
                    break;
                }
            }
        }

        public void Spawn( int index )
        {
            Map map = Map;

            if ( map == null || map == Map.Internal || m_CreaturesName.Count == 0 || index >= m_CreaturesName.Count || Parent != null )
                return;

            Defrag();

            if ( m_Creatures.Count >= m_Count )
                return;

            Type type = SpawnerType.GetType( m_CreaturesName[index] );

            if ( type != null )
            {
                try
                {
                    object o = Activator.CreateInstance( type );

                    if ( o is Mobile )
                    {
                        Mobile m = (Mobile)o;

                        m_Creatures.Add( m );


                        Point3D loc = ( m is BaseVendor ? this.Location : GetSpawnPosition() );

                        m.OnBeforeSpawn( loc, map );
                        InvalidateProperties();


                        m.MoveToWorld( loc, map );

                        if ( m is BaseCreature )
                        {
                            BaseCreature c = (BaseCreature)m;

                            if( m_WalkingRange >= 0 )
                                c.RangeHome = m_WalkingRange;
                            else
                                c.RangeHome = m_HomeRange;

                            c.CurrentWayPoint = m_WayPoint;

                            if ( m_Team > 0 )
                                c.Team = m_Team;

                            c.Home = this.Location;
                        }

                        m.OnAfterSpawn();
                    }
                    else if ( o is Item )
                    {
                        Item item = (Item)o;

                        m_Creatures.Add( item );

                        Point3D loc = GetSpawnPosition();

                        item.OnBeforeSpawn( loc, map );
                        InvalidateProperties();

                        item.MoveToWorld( loc, map );

                        item.OnAfterSpawn();
                    }
                }
                catch
                {
                }
            }
        }

        public Point3D GetSpawnPosition()
        {
            Map map = Map;

            if ( map == null )
                return Location;

            // Try 10 times to find a Spawnable location.
            for ( int i = 0; i < 10; i++ )
            {
                int x = Location.X + (Utility.Random( (m_HomeRange * 2) + 1 ) - m_HomeRange);
                int y = Location.Y + (Utility.Random( (m_HomeRange * 2) + 1 ) - m_HomeRange);
                int z = Map.GetAverageZ( x, y );

                if ( Map.CanSpawnMobile( new Point2D( x, y ), this.Z ) )
                    return new Point3D( x, y, this.Z );
                else if ( Map.CanSpawnMobile( new Point2D( x, y ), z ) )
                    return new Point3D( x, y, z );
            }

            return this.Location;
        }

        public void DoTimer()
        {
            if ( !m_Running )
                return;

            int minSeconds = (int)m_MinDelay.TotalSeconds;
            int maxSeconds = (int)m_MaxDelay.TotalSeconds;

            TimeSpan delay = TimeSpan.FromSeconds( Utility.RandomMinMax( minSeconds, maxSeconds ) );
            DoTimer( delay );
        }

        public void DoTimer( TimeSpan delay )
        {
            if ( !m_Running )
                return;

            m_End = DateTime.Now + delay;

            if ( m_Timer != null )
                m_Timer.Stop();

            m_Timer = new InternalTimer( this, delay );
            m_Timer.Start();
        }

        private class InternalTimer : Timer
        {
            private Spawner m_Spawner;

            public InternalTimer( Spawner spawner, TimeSpan delay ) : base( delay )
            {
                if ( spawner.IsFull )
                    Priority = TimerPriority.FiveSeconds;
                else
                    Priority = TimerPriority.OneSecond;

                m_Spawner = spawner;
            }

            protected override void OnTick()
            {
                if ( m_Spawner != null )
                    if ( !m_Spawner.Deleted )
                        m_Spawner.OnTick();
            }
        }

        public int CountCreatures( string creatureName )
        {
            Defrag();

            int count = 0;

            for ( int i = 0; i < m_Creatures.Count; ++i )
                if ( Insensitive.Equals( creatureName, m_Creatures[i].GetType().Name ) )
                    ++count;

            return count;
        }

        public void RemoveCreatures( string creatureName )
        {
            Defrag();

            for ( int i = 0; i < m_Creatures.Count; ++i )
            {
                IEntity e = m_Creatures[i];

                if ( Insensitive.Equals( creatureName, e.GetType().Name ) )
                        e.Delete();
            }

            InvalidateProperties();
        }

        public void RemoveCreatures()
        {
            Defrag();

            for ( int i = 0; i < m_Creatures.Count; ++i )
                m_Creatures[i].Delete();

            InvalidateProperties();
        }

        public void BringToHome()
        {
            Defrag();

            for ( int i = 0; i < m_Creatures.Count; ++i )
            {
                IEntity e = m_Creatures[i];

                if ( e is Mobile )
                {
                    Mobile m = (Mobile)e;

                    m.MoveToWorld( Location, Map );
                }
                else if ( e is Item )
                {
                    Item item = (Item)e;

                    item.MoveToWorld( Location, Map );
                }
            }
        }

        public override void OnDelete()
        {
            base.OnDelete();

            RemoveCreatures();
            if ( m_Timer != null )
                m_Timer.Stop();
        }

        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );

            writer.Write( (int) 4 ); // version
            writer.Write( m_WalkingRange );

            writer.Write( m_WayPoint );

            writer.Write( m_Group );

            writer.Write( m_MinDelay );
            writer.Write( m_MaxDelay );
            writer.Write( m_Count );
            writer.Write( m_Team );
            writer.Write( m_HomeRange );
            writer.Write( m_Running );

            if ( m_Running )
                writer.WriteDeltaTime( m_End );

            writer.Write( m_CreaturesName.Count );

            for ( int i = 0; i < m_CreaturesName.Count; ++i )
                writer.Write( m_CreaturesName[i] );

            writer.Write( m_Creatures.Count );

            for ( int i = 0; i < m_Creatures.Count; ++i )
            {
                IEntity e = m_Creatures[i];

                if ( e is Item )
                    writer.Write( (Item)e );
                else if ( e is Mobile )
                    writer.Write( (Mobile)e );
                else
                    writer.Write( Serial.MinusOne );
            }
        }

        private static WarnTimer m_WarnTimer;

        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );

            int version = reader.ReadInt();

            switch ( version )
            {
                case 4:
                {
                    m_WalkingRange = reader.ReadInt();

                    goto case 3;
                }
                case 3:
                case 2:
                {
                    m_WayPoint = reader.ReadItem() as WayPoint;

                    goto case 1;
                }

                case 1:
                {
                    m_Group = reader.ReadBool();

                    goto case 0;
                }

                case 0:
                {
                    m_MinDelay = reader.ReadTimeSpan();
                    m_MaxDelay = reader.ReadTimeSpan();
                    m_Count = reader.ReadInt();
                    m_Team = reader.ReadInt();
                    m_HomeRange = reader.ReadInt();
                    m_Running = reader.ReadBool();

                    TimeSpan ts = TimeSpan.Zero;

                    if ( m_Running )
                        ts = reader.ReadDeltaTime() - DateTime.Now;

                    int size = reader.ReadInt();

                    m_CreaturesName = new List<string>( size );

                    for ( int i = 0; i < size; ++i )
                    {
                        string typeName = reader.ReadString();

                        m_CreaturesName.Add( typeName );

                        if ( SpawnerType.GetType( typeName ) == null )
                        {
                            if ( m_WarnTimer == null )
                                m_WarnTimer = new WarnTimer();

                            m_WarnTimer.Add( Location, Map, typeName );
                        }
                    }

                    int count = reader.ReadInt();

                    m_Creatures = new List<IEntity>( count );

                    for ( int i = 0; i < count; ++i )
                    {
                        IEntity e = World.FindEntity( reader.ReadInt() );

                        if ( e != null )
                            m_Creatures.Add( e );
                    }

                    if ( m_Running )
                        DoTimer( ts );

                    break;
                }
            }

            if ( version < 3 && Weight == 0 )
                Weight = -1;
        }

        private class WarnTimer : Timer
        {
            private ArrayList m_List;

            private class WarnEntry
            {
                public Point3D m_Point;
                public Map m_Map;
                public string m_Name;

                public WarnEntry( Point3D p, Map map, string name )
                {
                    m_Point = p;
                    m_Map = map;
                    m_Name = name;
                }
            }

            public WarnTimer() : base( TimeSpan.FromSeconds( 1.0 ) )
            {
                m_List = new ArrayList();
                Start();
            }

            public void Add( Point3D p, Map map, string name )
            {
                m_List.Add( new WarnEntry( p, map, name ) );
            }

            protected override void OnTick()
            {
                try
                {
                    Console.WriteLine( "Warning: {0} bad spawns detected, logged: 'badspawn.log'", m_List.Count );

                    using ( StreamWriter op = new StreamWriter( "badspawn.log", true ) )
                    {
                        op.WriteLine( "# Bad spawns : {0}", DateTime.Now );
                        op.WriteLine( "# Format: X Y Z F Name" );
                        op.WriteLine();

                        foreach ( WarnEntry e in m_List )
                            op.WriteLine( "{0}\t{1}\t{2}\t{3}\t{4}", e.m_Point.X, e.m_Point.Y, e.m_Point.Z, e.m_Map, e.m_Name );

                        op.WriteLine();
                        op.WriteLine();
                    }
                }
                catch
                {
                }
            }
        }
    }
}

要允許您將多個生物名稱傳遞給Spawner ,您應該像這樣更改Spawner的構造函數:

[Constructable]
public Spawner(params string[] creatureName ) : base( 0x1f13 )
{
    InitSpawn( 1, TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 10 ), 0, 4, creaturesName.ToList() );
}

然后像這樣修改您的MakeSpawner方法:

private static void MakeSpawner(string[] types, int x, int y, int z)
{
    if (types.Length == 0)
        return;

    ClearSpawners(x, y, z);

    Spawner sp = new Spawner(types);

    sp.Count = ICount;
    sp.HomeRange = HomeRange;

    sp.MoveToWorld(new Point3D(x, y, z), Map.Sample);

    if (TotalRespawn)
    {
        sp.Respawn();
        sp.BringToHome();
    }

    ++m_Count;

}

注意: params修飾符允許您傳遞單個字符串( new Spawner("a") ),許多字符串( new Spanwer("a", "b", "c") )或字符串數​​組( new Spanwer(types) )為相同的方法。 我還稍微修改了您的代碼,以利用LINQ( using System.Linq )進行到List<string>的轉換。

現在,我唯一擔心的是ClearSpawners(x, y, z); :如果您添加多個具有相同x,y,z的獨立生成器,那么(大概)會清除舊的生成器。 我猜想,由於這些是Spanwers,所以可能還不錯,並且每個位置只有一個生成器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM