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:
Back