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;
}
}
}