ImaNewb

Member
ImaNewb submitted a new resource:

Crop Generator - Use the command "GenCrops"to generate all the empty farmlands with farmable crops

Just made a command that generates crop spawners on all empty farmland dirt patches on all maps. The script will search for Landtiles that match the 0x9 farm dirt and spawn crops in each field. It is set by default to have a 50% chance to placea spawner. This can be adjusted in the script in this section:
C#:
                                // 50% chance to place a spawner on this tile
                                if (random.NextDouble() < 0.5)
                                {...

Read more about this resource...
 
Yeah, you can already make crop spawn with Data\region\*xml files:

XML:
            <region name="A Carrot Field in Britain 1">
                <rect x="1208" y="1712" width="16" height="24" />
                <go x="1215" y="1723" z="0" />
                <spawning>
                    <object id="416" type="FarmableCarrot" minSpawnTime="PT10S" maxSpawnTime="PT30S" amount="8" />
                </spawning>
            </region>
            <region name="An Onion Field in Britain 1">
                <rect x="1224" y="1712" width="16" height="24" />
                <go x="1231" y="1723" z="0" />
                <spawning>
                    <object id="417" type="FarmableOnion" minSpawnTime="PT10S" maxSpawnTime="PT30S" amount="8" />
                </spawning>
            </region>
 
CS0234: Line 108: Type or namespace name 'LandTile' does not exist in namespace 'Server' (is it missing assembly reference?) My Server RUNUO2.0 .NET2.0

using System;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Items;
using Server.Mobiles;
using Server.Engines.XmlSpawner2;

namespace Server.Misc
{
public class GenCrops
{
private static List<string> vegetableTypes = new List<string>(new string[]
{
"FarmableCarrot", "FarmableCabbage", "FarmableLettuce", "FarmableOnion", "FarmablePumpkin", "FarmableCotton", "FarmableFlax", "FarmableTurnip", "FarmableWheat"
});

private const int NPCCount = 1;
private static TimeSpan MinTime = TimeSpan.FromMinutes(2.5);
private static TimeSpan MaxTime = TimeSpan.FromMinutes(10.0);
private const int Team = 0;
private const int HomeRange = 0;
private const int SpawnRange = 0;
private const bool TotalRespawn = true;

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

[Usage("GenCrops")]
[Description("Generates vegetable spawners on dirt tiles on all maps")]
private static void Generate_OnCommand(CommandEventArgs e)
{
Parse(e.Mobile);
}

public static void Parse(Mobile from)
{
from.SendMessage("Generating vegetable spawners on dirt tiles on all maps...");

List<Map> maps = new List<Map>();
{
maps.Add(Map.Felucca);
maps.Add(Map.Trammel);
maps.Add(Map.Ilshenar);
maps.Add(Map.Malas);
maps.Add(Map.Tokuno);
maps.Add(Map.TerMur);
};

foreach (Map map in maps)
{
GenerateCropsOnMap(from, map);
}

from.SendMessage("Vegetable generation complete on all maps.");
Console.WriteLine("Vegetable generation complete on all maps.");
}

public static void GenerateCropsOnMap(Mobile from, Map map)
{
int mapWidth = map.Width;
int mapHeight = map.Height;
Random random = new Random();
int spawnerCount = 0;
int cropIndex = 0;

Dictionary<Point2D, bool> visited = new Dictionary<Point2D, bool>();

for (int x = 0; x < mapWidth; x++)
{
for (int y = 0; y < mapHeight; y++)
{
Point2D point = new Point2D(x, y);
if (!visited.ContainsKey(point) && IsDirtTile(map, x, y))
{
List<Point2D> field = new List<Point2D>();
FindField(map, x, y, visited, field);

if (field.Count > 0)
{
string vegetableType = vegetableTypes[cropIndex];
cropIndex = (cropIndex + 1) % vegetableTypes.Count; // Move to the next crop type

foreach (Point2D tile in field)
{
// 50% chance to place a spawner on this tile
if (random.NextDouble() < 0.5)
{
MakeSpawner(new string[] { vegetableType }, tile.X, tile.Y, map.Tiles.GetLandTile(tile.X, tile.Y).Z, map);
spawnerCount++;
}
}
//Display each spawned coordinate
/* from.SendMessage(String.Format("Field planted with {0} at starting point ({1}, {2}) on {3}", vegetableType, x, y, map.Name)); */
}
}
}
}

from.SendMessage(String.Format("{0} vegetable spawners generated on {1}.", spawnerCount, map.Name));
Console.WriteLine(String.Format("{0} vegetable spawners generated on {1}.", spawnerCount, map.Name));
}

private static bool IsDirtTile(Server.Map map, int x, int y)
{
Server.LandTile landTile = map.Tiles.GetLandTile(x, y);
// 这里假设0x9是代表土地的地砖ID,你可以根据实际情况修改
return landTile.ID == 0x9;
}

private static void FindField(Map map, int x, int y, Dictionary<Point2D, bool> visited, List<Point2D> field)
{
Stack<Point2D> stack = new Stack<Point2D>();
stack.Push(new Point2D(x, y));

while (stack.Count > 0)
{
Point2D point = stack.Pop();
if (!visited.ContainsKey(point) && IsDirtTile(map, point.X, point.Y))
{
visited.Add(point, true);
field.Add(point);

foreach (Point2D neighbor in GetNeighbors(point))
{
if (!visited.ContainsKey(neighbor) && IsDirtTile(map, neighbor.X, neighbor.Y))
{
stack.Push(neighbor);
}
}
}
}
}

private static IEnumerable<Point2D> GetNeighbors(Point2D point)
{
yield return new Point2D(point.X + 1, point.Y);
yield return new Point2D(point.X - 1, point.Y);
yield return new Point2D(point.X, point.Y + 1);
yield return new Point2D(point.X, point.Y - 1);
}

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

ClearSpawners(x, y, z, map);

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

xs.MaxCount = NPCCount;
xs.MinDelay = MinTime;
xs.MaxDelay = MaxTime;
xs.Team = Team;
xs.HomeRange = HomeRange;
xs.SpawnRange = SpawnRange;

xs.MoveToWorld(new Point3D(x, y, z), map);

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

private static void ClearSpawners(int x, int y, int z, Map map)
{
foreach (Item item in map.GetItemsInRange(new Point3D(x, y, z), 0))
{
if (item is XmlSpawner)
{
item.Delete();
}
}
}
}
}
 
Yeah, you can already make crop spawn with Data\region\*xml files:

XML:
            <region name="A Carrot Field in Britain 1">
                <rect x="1208" y="1712" width="16" height="24" />
                <go x="1215" y="1723" z="0" />
                <spawning>
                    <object id="416" type="FarmableCarrot" minSpawnTime="PT10S" maxSpawnTime="PT30S" amount="8" />
                </spawning>
            </region>
            <region name="An Onion Field in Britain 1">
                <rect x="1224" y="1712" width="16" height="24" />
                <go x="1231" y="1723" z="0" />
                <spawning>
                    <object id="417" type="FarmableOnion" minSpawnTime="PT10S" maxSpawnTime="PT30S" amount="8" />
                </spawning>
            </region>
Sure if you want to go define a region and set coordinates etc. This xml file doesnt exist in RunUO by default you would need to add an xml file for it. It looks like download888 is using RunUO. This script just searches for the land tiles and spawns it up on servers like that.
CS0234: Line 108: Type or namespace name 'LandTile' does not exist in namespace 'Server' (is it missing assembly reference?) My Server RUNUO2.0 .NET2.0

using System;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Items;
using Server.Mobiles;
using Server.Engines.XmlSpawner2;

namespace Server.Misc
{
public class GenCrops
{
private static List<string> vegetableTypes = new List<string>(new string[]
{
"FarmableCarrot", "FarmableCabbage", "FarmableLettuce", "FarmableOnion", "FarmablePumpkin", "FarmableCotton", "FarmableFlax", "FarmableTurnip", "FarmableWheat"
});

private const int NPCCount = 1;
private static TimeSpan MinTime = TimeSpan.FromMinutes(2.5);
private static TimeSpan MaxTime = TimeSpan.FromMinutes(10.0);
private const int Team = 0;
private const int HomeRange = 0;
private const int SpawnRange = 0;
private const bool TotalRespawn = true;

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

[Usage("GenCrops")]
[Description("Generates vegetable spawners on dirt tiles on all maps")]
private static void Generate_OnCommand(CommandEventArgs e)
{
Parse(e.Mobile);
}

public static void Parse(Mobile from)
{
from.SendMessage("Generating vegetable spawners on dirt tiles on all maps...");

List<Map> maps = new List<Map>();
{
maps.Add(Map.Felucca);
maps.Add(Map.Trammel);
maps.Add(Map.Ilshenar);
maps.Add(Map.Malas);
maps.Add(Map.Tokuno);
maps.Add(Map.TerMur);
};

foreach (Map map in maps)
{
GenerateCropsOnMap(from, map);
}

from.SendMessage("Vegetable generation complete on all maps.");
Console.WriteLine("Vegetable generation complete on all maps.");
}

public static void GenerateCropsOnMap(Mobile from, Map map)
{
int mapWidth = map.Width;
int mapHeight = map.Height;
Random random = new Random();
int spawnerCount = 0;
int cropIndex = 0;

Dictionary<Point2D, bool> visited = new Dictionary<Point2D, bool>();

for (int x = 0; x < mapWidth; x++)
{
for (int y = 0; y < mapHeight; y++)
{
Point2D point = new Point2D(x, y);
if (!visited.ContainsKey(point) && IsDirtTile(map, x, y))
{
List<Point2D> field = new List<Point2D>();
FindField(map, x, y, visited, field);

if (field.Count > 0)
{
string vegetableType = vegetableTypes[cropIndex];
cropIndex = (cropIndex + 1) % vegetableTypes.Count; // Move to the next crop type

foreach (Point2D tile in field)
{
// 50% chance to place a spawner on this tile
if (random.NextDouble() < 0.5)
{
MakeSpawner(new string[] { vegetableType }, tile.X, tile.Y, map.Tiles.GetLandTile(tile.X, tile.Y).Z, map);
spawnerCount++;
}
}
//Display each spawned coordinate
/* from.SendMessage(String.Format("Field planted with {0} at starting point ({1}, {2}) on {3}", vegetableType, x, y, map.Name)); */
}
}
}
}

from.SendMessage(String.Format("{0} vegetable spawners generated on {1}.", spawnerCount, map.Name));
Console.WriteLine(String.Format("{0} vegetable spawners generated on {1}.", spawnerCount, map.Name));
}

private static bool IsDirtTile(Server.Map map, int x, int y)
{
Server.LandTile landTile = map.Tiles.GetLandTile(x, y);
// 这里假设0x9是代表土地的地砖ID,你可以根据实际情况修改
return landTile.ID == 0x9;
}

private static void FindField(Map map, int x, int y, Dictionary<Point2D, bool> visited, List<Point2D> field)
{
Stack<Point2D> stack = new Stack<Point2D>();
stack.Push(new Point2D(x, y));

while (stack.Count > 0)
{
Point2D point = stack.Pop();
if (!visited.ContainsKey(point) && IsDirtTile(map, point.X, point.Y))
{
visited.Add(point, true);
field.Add(point);

foreach (Point2D neighbor in GetNeighbors(point))
{
if (!visited.ContainsKey(neighbor) && IsDirtTile(map, neighbor.X, neighbor.Y))
{
stack.Push(neighbor);
}
}
}
}
}

private static IEnumerable<Point2D> GetNeighbors(Point2D point)
{
yield return new Point2D(point.X + 1, point.Y);
yield return new Point2D(point.X - 1, point.Y);
yield return new Point2D(point.X, point.Y + 1);
yield return new Point2D(point.X, point.Y - 1);
}

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

ClearSpawners(x, y, z, map);

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

xs.MaxCount = NPCCount;
xs.MinDelay = MinTime;
xs.MaxDelay = MaxTime;
xs.Team = Team;
xs.HomeRange = HomeRange;
xs.SpawnRange = SpawnRange;

xs.MoveToWorld(new Point3D(x, y, z), map);

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

private static void ClearSpawners(int x, int y, int z, Map map)
{
foreach (Item item in map.GetItemsInRange(new Point3D(x, y, z), 0))
{
if (item is XmlSpawner)
{
item.Delete();
}
}
}
}
}
.NET 2.0 is a very old .net to be using. What build of RunUO are you using? I tested this on RunUO 2.2 using .net 4.0 and it works. Also What version of XmlSpawner are you using? Does it reference LandTile? I am using XMLSpawner2 and it does make use of it.
C#:
// go through all of the tiles at the location and find those that are in the allowed tiles list
                    LandTile ltile = map.Tiles.GetLandTile(x, y);
 
Last edited:
//#定义跟踪
//#定义 RUNUO2RC1
//#定义 RESTRICTCONSTRUCTABLE
/*
** XmlSpawner2
** 版本 3.24
** 2008 年 2 月 11 日更新
** 阿特戈登
** 对 bobsmart 编写的原始 XmlSpawner 进行修改
*/
 
Last edited:
is there a command to wipe the crops and start over? or will [GenCrops wipe and re plant?
Yes here is the updated script

added remove command:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Server.Commands;
using Server.Mobiles;

namespace Server.Misc
{
    public class GenCrops
    {
        private static List<string> vegetableTypes = new List<string>
        {
            "FarmableCarrot", "FarmableCabbage", "FarmableLettuce", "FarmableOnion", "FarmablePumpkin", "FarmableCotton", "FarmableFlax", "FarmableTurnip", "FarmableWheat"
        };

        private const string SpawnerNamePrefix = "CropsGenSpawner_";
        private static string spawnerDataFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SpawnerData.txt");

        private const int NPCCount = 1;
        private static TimeSpan MinTime = TimeSpan.FromMinutes(2.5);
        private static TimeSpan MaxTime = TimeSpan.FromMinutes(10.0);
        private const int Team = 0;
        private const int HomeRange = 0;
        private const int SpawnRange = 0;
        private const bool TotalRespawn = true;

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

        private static void Generate_OnCommand(CommandEventArgs e)
        {
            Parse(e.Mobile, true);
            e.Mobile.SendMessage("Vegetable generation complete on all maps.");
        }

        private static void Remove_OnCommand(CommandEventArgs e)
        {
            Parse(e.Mobile, false);
            e.Mobile.SendMessage("Vegetable removal complete on all maps.");
        }

        private static void Parse(Mobile from, bool generate)
        {
            if (generate)
            {
                from.SendMessage("Generating vegetable spawners on dirt tiles on all maps...");
                List<string> spawnerData = new List<string>();
                foreach (Map map in Map.AllMaps)
                {
                    GenerateCropsOnMap(from, map, spawnerData);
                }
                WriteSpawnerDataToFile(spawnerData, from);
            }
            else
            {
                from.SendMessage("Removing vegetable spawners generated by GenCrops on all maps...");
                LoadAndDeleteSpawners(from);
            }
        }

        private static void GenerateCropsOnMap(Mobile from, Map map, List<string> spawnerData)
        {
            var random = new System.Random();
            int spawnerCount = 0;
            HashSet<Point2D> visited = new HashSet<Point2D>();

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Height; y++)
                {
                    if (!visited.Contains(new Point2D(x, y)) && IsDirtTile(map, x, y))
                    {
                        List<Point2D> field = new List<Point2D>();
                        FindField(map, x, y, visited, field);
                        if (field.Count > 0)
                        {
                            string vegetableType = vegetableTypes[random.Next(vegetableTypes.Count)];
                            foreach (var point in field)
                            {
                                if (random.NextDouble() < 0.5) // 50% chance to place a spawner
                                {
                                    XmlSpawner spawner = MakeSpawner(vegetableType, point.X, point.Y, map);
                                    if (spawner != null)
                                    {
                                        spawnerData.Add($"{map.Name}|{point.X}|{point.Y}|{vegetableType}");
                                        spawnerCount++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            from.SendMessage($"{spawnerCount} vegetable spawners generated on {map.Name}.");
        }

        private static void WriteSpawnerDataToFile(List<string> spawnerData, Mobile from)
        {
            try
            {
                if (spawnerData.Count > 0)
                {
                    File.WriteAllLines(spawnerDataFilePath, spawnerData);
                    from.SendMessage($"Spawner data saved to {spawnerDataFilePath}");
                }
                else
                {
                    from.SendMessage("No spawner data to save.");
                }
            }
            catch (Exception ex)
            {
                from.SendMessage($"Error saving spawner data: {ex.Message}");
            }
        }

        private static void LoadAndDeleteSpawners(Mobile from)
        {
            if (!File.Exists(spawnerDataFilePath))
            {
                from.SendMessage("Spawner data file not found.");
                return;
            }

            try
            {
                string[] spawnerData = File.ReadAllLines(spawnerDataFilePath);
                foreach (string data in spawnerData)
                {
                    string[] parts = data.Split('|');
                    if (parts.Length != 4)
                    {
                        from.SendMessage("Invalid spawner data format.");
                        continue;
                    }

                    string mapName = parts[0];
                    int x = int.Parse(parts[1]);
                    int y = int.Parse(parts[2]);
                    string type = parts[3];

                    Map map = Map.AllMaps.FirstOrDefault(m => m.Name == mapName);
                    if (map == null)
                    {
                        continue;
                    }

                    Point3D point = new Point3D(x, y, map.GetAverageZ(x, y));
                    foreach (Item item in map.GetItemsInRange(point, 0))
                    {
                        if (item is XmlSpawner spawner && spawner.Name == $"{SpawnerNamePrefix}{type}_{x}_{y}_{map.Name}")
                        {
                            spawner.Delete();
                            break;
                        }
                    }
                }
                File.Delete(spawnerDataFilePath);
            }
            catch (Exception ex)
            {
                from.SendMessage($"Error loading or deleting spawners: {ex.Message}");
            }
        }

        private static XmlSpawner MakeSpawner(string vegetableType, int x, int y, Map map)
        {
            string spawnerName = $"{SpawnerNamePrefix}{vegetableType}_{x}_{y}_{map.Name}";
            XmlSpawner spawner = new XmlSpawner(vegetableType)
            {
                MaxCount = NPCCount,
                MinDelay = MinTime,
                MaxDelay = MaxTime,
                Team = Team,
                HomeRange = HomeRange,
                SpawnRange = SpawnRange,
                Name = spawnerName
            };
            spawner.MoveToWorld(new Point3D(x, y, map.GetAverageZ(x, y)), map);

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

            return spawner;
        }

        private static bool IsDirtTile(Map map, int x, int y)
        {
            LandTile landTile = map.Tiles.GetLandTile(x, y);
            return landTile.ID == 0x9;
        }

        private static void FindField(Map map, int x, int y, HashSet<Point2D> visited, List<Point2D> field)
        {
            Stack<Point2D> stack = new Stack<Point2D>();
            stack.Push(new Point2D(x, y));

            while (stack.Count > 0)
            {
                Point2D point = stack.Pop();
                if (!visited.Contains(point) && IsDirtTile(map, point.X, point.Y))
                {
                    visited.Add(point);
                    field.Add(point);

                    foreach (var neighbor in GetNeighbors(point))
                    {
                        if (!visited.Contains(neighbor) && IsDirtTile(map, neighbor.X, neighbor.Y))
                        {
                            stack.Push(neighbor);
                        }
                    }
                }
            }
        }

        private static IEnumerable<Point2D> GetNeighbors(Point2D point)
        {
            yield return new Point2D(point.X + 1, point.Y);
            yield return new Point2D(point.X - 1, point.Y);
            yield return new Point2D(point.X, point.Y + 1);
            yield return new Point2D(point.X, point.Y - 1);
        }
    }
}
 
//#定义跟踪
//#定义 RUNUO2RC1
//#定义 RESTRICTCONSTRUCTABLE
/*
** XmlSpawner2
** 版本 3.24
** 2008 年 2 月 11 日更新
** 阿特戈登
** 对 bobsmart 编写的原始 XmlSpawner 进行修改
*/
For RunUO RC2 this should work

RunUO RC2:
using System;
using System.Collections.Generic;
using System.IO;
using Server;
using Server.Commands;
using Server.Items;
using Server.Mobiles;

namespace Server.Misc
{
    public class GenCrops
    {
        private static List<string> vegetableTypes = new List<string>
        {
            "FarmableCarrot", "FarmableCabbage", "FarmableLettuce",
            "FarmableOnion", "FarmablePumpkin", "FarmableCotton",
            "FarmableFlax", "FarmableTurnip", "FarmableWheat"
        };

        private const string SpawnerNamePrefix = "CropsGenSpawner_";
        private static string spawnerDataFilePath = Path.Combine(Core.BaseDirectory, "SpawnerData.txt");

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

        [Usage("GenCrops")]
        [Description("Generates vegetable spawners on all maps.")]
        private static void Generate_OnCommand(CommandEventArgs e)
        {
            Parse(e.Mobile, true);
            e.Mobile.SendMessage("Vegetable generation complete on all maps.");
        }

        [Usage("RemoveCrops")]
        [Description("Removes vegetable spawners generated by GenCrops on all maps.")]
        private static void RemoveCrops_OnCommand(CommandEventArgs e)
        {
            Parse(e.Mobile, false);
            e.Mobile.SendMessage("Vegetable removal complete on all maps.");
        }

        private static void Parse(Mobile from, bool generate)
        {
            if (generate)
            {
                from.SendMessage("Generating vegetable spawners on dirt tiles on all maps...");
                List<string> spawnerData = new List<string>();
                foreach (Map map in Map.AllMaps)
                {
                    GenerateCropsOnMap(from, map, spawnerData);
                }
                WriteSpawnerDataToFile(spawnerData, from);
            }
            else
            {
                from.SendMessage("Removing vegetable spawners generated by GenCrops on all maps...");
                LoadAndDeleteSpawners(from);
            }
        }

        private static void GenerateCropsOnMap(Mobile from, Map map, List<string> spawnerData)
        {
            var random = new Random();
            int spawnerCount = 0;
            Dictionary<Point2D, bool> visited = new Dictionary<Point2D, bool>();

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Height; y++)
                {
                    Point2D point = new Point2D(x, y);
                    if (!visited.ContainsKey(point) && IsDirtTile(map, x, y))
                    {
                        List<Point2D> field = new List<Point2D>();
                        FindField(map, x, y, visited, field);
                        if (field.Count > 0)
                        {
                            string vegetableType = vegetableTypes[random.Next(vegetableTypes.Count)];
                            foreach (var pt in field)
                            {
                                if (random.NextDouble() < 0.5) // 50% chance to place a spawner
                                {
                                    Spawner spawner = MakeSpawner(vegetableType, pt.X, pt.Y, map);
                                    if (spawner != null)
                                    {
                                        spawnerData.Add(map.Name + "|" + pt.X + "|" + pt.Y + "|" + vegetableType);
                                        spawnerCount++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            from.SendMessage(spawnerCount + " vegetable spawners generated on " + map.Name + ".");
        }

        private static void WriteSpawnerDataToFile(List<string> spawnerData, Mobile from)
        {
            try
            {
                if (spawnerData.Count > 0)
                {
                    File.WriteAllLines(spawnerDataFilePath, spawnerData.ToArray());
                    from.SendMessage("Spawner data saved to " + spawnerDataFilePath);
                }
                else
                {
                    from.SendMessage("No spawner data to save.");
                }
            }
            catch (Exception ex)
            {
                from.SendMessage("Error saving spawner data: " + ex.Message);
            }
        }

        private static void LoadAndDeleteSpawners(Mobile from)
        {
            if (!File.Exists(spawnerDataFilePath))
            {
                from.SendMessage("Spawner data file not found.");
                return;
            }

            try
            {
                string[] spawnerData = File.ReadAllLines(spawnerDataFilePath);
                foreach (string data in spawnerData)
                {
                    string[] parts = data.Split('|');
                    if (parts.Length != 4)
                    {
                        from.SendMessage("Invalid spawner data format.");
                        continue;
                    }

                    string mapName = parts[0];
                    int x = int.Parse(parts[1]);
                    int y = int.Parse(parts[2]);
                    string type = parts[3];

                    Map map = FindMapByName(mapName);
                    if (map == null)
                    {
                        continue;
                    }

                    Point3D point = new Point3D(x, y, map.GetAverageZ(x, y));
                    foreach (Item item in map.GetItemsInRange(point, 0))
                    {
                        Spawner spawner = item as Spawner;
                        if (spawner != null && spawner.Name == SpawnerNamePrefix + type + "_" + x + "_" + y + "_" + map.Name)
                        {
                            spawner.Delete();
                            break;
                        }
                    }
                }
                File.Delete(spawnerDataFilePath);
            }
            catch (Exception ex)
            {
                from.SendMessage("Error loading or deleting spawners: " + ex.Message);
            }
        }

        private static Spawner MakeSpawner(string vegetableType, int x, int y, Map map)
        {
            string spawnerName = SpawnerNamePrefix + vegetableType + "_" + x + "_" + y + "_" + map.Name;
            List<string> types = new List<string> { vegetableType };
            Spawner spawner = new Spawner(1, TimeSpan.FromMinutes(2.5), TimeSpan.FromMinutes(10.0), 0, 0, types) // Set home range to 0
            {
                Name = spawnerName,
                HomeRange = 0 // Ensure home range is set to 0
            };
            spawner.MoveToWorld(new Point3D(x, y, map.GetAverageZ(x, y)), map);
        
            // Manually call BringToHome to ensure items are brought to the spawner's location
            spawner.BringToHome();
        
            return spawner;
        }



        private static bool IsDirtTile(Map map, int x, int y)
        {
            Tile landTile = map.Tiles.GetLandTile(x, y);
            return landTile.ID == 0x9;
        }

        private static void FindField(Map map, int x, int y, Dictionary<Point2D, bool> visited, List<Point2D> field)
        {
            Stack<Point2D> stack = new Stack<Point2D>();
            stack.Push(new Point2D(x, y));

            while (stack.Count > 0)
            {
                Point2D point = stack.Pop();
                if (!visited.ContainsKey(point) && IsDirtTile(map, point.X, point.Y))
                {
                    visited[point] = true;
                    field.Add(point);

                    foreach (var neighbor in GetNeighbors(point))
                    {
                        if (!visited.ContainsKey(neighbor) && IsDirtTile(map, neighbor.X, neighbor.Y))
                        {
                            stack.Push(neighbor);
                        }
                    }
                }
            }
        }

        private static IEnumerable<Point2D> GetNeighbors(Point2D point)
        {
            yield return new Point2D(point.X + 1, point.Y);
            yield return new Point2D(point.X - 1, point.Y);
            yield return new Point2D(point.X, point.Y + 1);
            yield return new Point2D(point.X, point.Y - 1);
        }

        private static Map FindMapByName(string name)
        {
            foreach (Map map in Map.AllMaps)
            {
                if (map.Name == name)
                {
                    return map;
                }
            }
            return null;
        }
    }
}
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back