diff --git a/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs b/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs new file mode 100644 index 0000000000..33c3fbe35b --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs @@ -0,0 +1,149 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenSim.Region.CoreModules.World.Terrain; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.CoreModules.World.Terrain.Features +{ + public class RectangleFeature : TerrainFeature + { + public RectangleFeature(ITerrainModule module) : base(module) + { + } + + public override string CreateFeature(ITerrainChannel map, string[] args) + { + string val; + string result; + if (args.Length < 7) + { + result = "Usage: " + GetUsage(); + } + else + { + result = String.Empty; + + float targetElevation; + val = base.parseFloat(args[3], out targetElevation); + if (val != String.Empty) + { + result = val; + } + + int xOrigin; + val = base.parseInt(args[4], out xOrigin); + if (val != String.Empty) + { + result = val; + } + else if (xOrigin < 0 || xOrigin >= map.Width) + { + result = "x-origin must be within the region"; + } + + int yOrigin; + val = base.parseInt(args[5], out yOrigin); + if (val != String.Empty) + { + result = val; + } + else if (yOrigin < 0 || yOrigin >= map.Height) + { + result = "y-origin must be within the region"; + } + + int xDelta; + val = base.parseInt(args[6], out xDelta); + if (val != String.Empty) + { + result = val; + } + else if (xDelta <= 0) + { + result = "x-size must be greater than zero"; + } + + int yDelta; + if (args.Length > 7) + { + val = base.parseInt(args[7], out yDelta); + if (val != String.Empty) + { + result = val; + } + else if (yDelta <= 0) + { + result = "y-size must be greater than zero"; + } + } + else + { + // no y-size.. make it square + yDelta = xDelta; + } + + // slightly more complex validation, if required. + if (result == String.Empty) + { + if (xOrigin + xDelta > map.Width) + { + result = "(x-origin + x-size) must be within the region size"; + } + else if (yOrigin + yDelta > map.Height) + { + result = "(y-origin + y-size) must be within the region size"; + } + } + + // if it's all good, then do the work + if (result == String.Empty) + { + int yPos = yOrigin + yDelta; + while(--yPos >= yOrigin) + { + int xPos = xOrigin + xDelta; + while(--xPos >= xOrigin) + { + map[xPos, yPos] = (double)targetElevation; + } + } + } + } + + return result; + } + + public override string GetUsage() + { + return "rectangle []"; + } + } + +} + diff --git a/OpenSim/Region/CoreModules/World/Terrain/ITerrainFeature.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainFeature.cs new file mode 100644 index 0000000000..78a43dbaff --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainFeature.cs @@ -0,0 +1,60 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.CoreModules.World.Terrain +{ + public interface ITerrainFeature + { + /// + /// Creates the feature. + /// + /// + /// Empty string if successful, otherwise error message. + /// + /// + /// ITerrainChannel holding terrain data. + /// + /// + /// command-line arguments from console. + /// + string CreateFeature(ITerrainChannel map, string[] args); + + /// + /// Gets a string describing the usage. + /// + /// + /// A string describing parameters for creating the feature. + /// Format is "feature-name ..." + /// + string GetUsage(); + } + +} + diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainFeature.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainFeature.cs new file mode 100644 index 0000000000..701a729d2e --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainFeature.cs @@ -0,0 +1,89 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Reflection; + +using OpenSim.Region.Framework.Interfaces; + +namespace OpenSim.Region.CoreModules.World.Terrain +{ + public abstract class TerrainFeature : ITerrainFeature + { + protected ITerrainModule m_module; + + protected TerrainFeature(ITerrainModule module) + { + m_module = module; + } + + public abstract string CreateFeature(ITerrainChannel map, string[] args); + + public abstract string GetUsage(); + + protected string parseFloat(String s, out float f) + { + string result; + double d; + if (Double.TryParse(s, out d)) + { + try + { + f = (float)d; + result = String.Empty; + } + catch(InvalidCastException) + { + result = String.Format("{0} is invalid", s); + f = -1.0f; + } + } + else + { + f = -1.0f; + result = String.Format("{0} is invalid", s); + } + return result; + } + + protected string parseInt(String s, out int i) + { + string result; + if (Int32.TryParse(s, out i)) + { + result = String.Empty; + } + else + { + result = String.Format("{0} is invalid", s); + } + return result; + } + + } + +} + diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index cd76693f42..3bb804098c 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -42,6 +42,7 @@ using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Region.CoreModules.Framework.InterfaceCommander; using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; +using OpenSim.Region.CoreModules.World.Terrain.Features; using OpenSim.Region.CoreModules.World.Terrain.FloodBrushes; using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; using OpenSim.Region.Framework.Interfaces; @@ -74,6 +75,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain #endregion + /// + /// Terrain Features + /// + public enum TerrainFeatures: byte + { + Rectangle = 1, + } + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); #pragma warning disable 414 @@ -90,8 +99,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain private readonly Dictionary m_painteffects = new Dictionary(); - private ITerrainChannel m_channel; private Dictionary m_plugineffects; + + private Dictionary m_featureEffects = + new Dictionary(); + + private ITerrainChannel m_channel; private ITerrainChannel m_revert; private Scene m_scene; private volatile bool m_tainted; @@ -648,6 +661,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); + // Terrain Feature effects + m_featureEffects["rectangle"] = new RectangleFeature(this); + // Filesystem load/save loaders m_loaders[".r32"] = new RAW32(); m_loaders[".f32"] = m_loaders[".r32"]; @@ -1622,7 +1638,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); - //Plugins + // Plugins Command pluginRunCommand = new Command("effect", CommandIntentions.COMMAND_HAZARDOUS, InterfaceRunPluginEffect, "Runs a specified plugin effect"); pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String"); @@ -1648,9 +1664,46 @@ namespace OpenSim.Region.CoreModules.World.Terrain // Add this to our scene so scripts can call these functions m_scene.RegisterModuleCommander(m_commander); + + // Add Feature command to Scene, since Command object requires fixed-length arglists + m_scene.AddCommand("Terrain", this, "terrain feature", + "terrain feature ", "Constructs a feature of the requested type.", FeatureCommand); + } + public void FeatureCommand(string module, string[] cmd) + { + string result; + if (cmd.Length > 2) + { + string featureType = cmd[2]; + ITerrainFeature feature; + if (!m_featureEffects.TryGetValue(featureType, out feature)) + { + result = String.Format("Terrain Feature \"{0}\" not found.", featureType); + } + else if ((cmd.Length > 3) && (cmd[3] == "usage")) + { + result = "Usage: " + feature.GetUsage(); + } + else + { + result = feature.CreateFeature(m_channel, cmd); + } + + if(result == String.Empty) + { + result = "Created Feature"; + m_log.DebugFormat("Created terrain feature {0}", featureType); + } + } + else + { + result = "Usage: ..."; + } + MainConsole.Instance.Output(result); + } #endregion }