aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs1470
1 files changed, 735 insertions, 735 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
index 09c3117..eff6159 100644
--- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs
@@ -1,736 +1,736 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using libsecondlife; 32using libsecondlife;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Modules.Framework; 37using OpenSim.Region.Environment.Modules.Framework;
38using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders; 38using OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders;
39using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes; 39using OpenSim.Region.Environment.Modules.World.Terrain.FloodBrushes;
40using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes; 40using OpenSim.Region.Environment.Modules.World.Terrain.PaintBrushes;
41using OpenSim.Region.Environment.Scenes; 41using OpenSim.Region.Environment.Scenes;
42 42
43namespace OpenSim.Region.Environment.Modules.World.Terrain 43namespace OpenSim.Region.Environment.Modules.World.Terrain
44{ 44{
45 public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule 45 public class TerrainModule : IRegionModule, ICommandableModule, ITerrainModule
46 { 46 {
47 #region StandardTerrainEffects enum 47 #region StandardTerrainEffects enum
48 48
49 /// <summary> 49 /// <summary>
50 /// A standard set of terrain brushes and effects recognised by viewers 50 /// A standard set of terrain brushes and effects recognised by viewers
51 /// </summary> 51 /// </summary>
52 public enum StandardTerrainEffects : byte 52 public enum StandardTerrainEffects : byte
53 { 53 {
54 Flatten = 0, 54 Flatten = 0,
55 Raise = 1, 55 Raise = 1,
56 Lower = 2, 56 Lower = 2,
57 Smooth = 3, 57 Smooth = 3,
58 Noise = 4, 58 Noise = 4,
59 Revert = 5, 59 Revert = 5,
60 60
61 // Extended brushes 61 // Extended brushes
62 Erode = 255, 62 Erode = 255,
63 Weather = 254, 63 Weather = 254,
64 Olsen = 253 64 Olsen = 253
65 } 65 }
66 66
67 #endregion 67 #endregion
68 68
69 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 69 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
70 70
71 private readonly Commander m_commander = new Commander("Terrain"); 71 private readonly Commander m_commander = new Commander("Terrain");
72 72
73 private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = 73 private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects =
74 new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); 74 new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>();
75 75
76 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); 76 private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>();
77 77
78 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = 78 private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects =
79 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); 79 new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>();
80 80
81 private ITerrainChannel m_channel; 81 private ITerrainChannel m_channel;
82 private Dictionary<Location, ITerrainChannel> m_channels; 82 private Dictionary<Location, ITerrainChannel> m_channels;
83 private Dictionary<string, ITerrainEffect> m_plugineffects; 83 private Dictionary<string, ITerrainEffect> m_plugineffects;
84 private ITerrainChannel m_revert; 84 private ITerrainChannel m_revert;
85 private Scene m_scene; 85 private Scene m_scene;
86 private bool m_tainted = false; 86 private bool m_tainted = false;
87 87
88 #region ICommandableModule Members 88 #region ICommandableModule Members
89 89
90 public ICommander CommandInterface 90 public ICommander CommandInterface
91 { 91 {
92 get { return m_commander; } 92 get { return m_commander; }
93 } 93 }
94 94
95 #endregion 95 #endregion
96 96
97 #region IRegionModule Members 97 #region IRegionModule Members
98 98
99 /// <summary> 99 /// <summary>
100 /// Creates and initialises a terrain module for a region 100 /// Creates and initialises a terrain module for a region
101 /// </summary> 101 /// </summary>
102 /// <param name="scene">Region initialising</param> 102 /// <param name="scene">Region initialising</param>
103 /// <param name="config">Config for the region</param> 103 /// <param name="config">Config for the region</param>
104 public void Initialise(Scene scene, IConfigSource config) 104 public void Initialise(Scene scene, IConfigSource config)
105 { 105 {
106 m_scene = scene; 106 m_scene = scene;
107 107
108 // Install terrain module in the simulator 108 // Install terrain module in the simulator
109 if (m_scene.Heightmap == null) 109 if (m_scene.Heightmap == null)
110 { 110 {
111 lock (m_scene) 111 lock (m_scene)
112 { 112 {
113 m_channel = new TerrainChannel(); 113 m_channel = new TerrainChannel();
114 m_scene.Heightmap = m_channel; 114 m_scene.Heightmap = m_channel;
115 m_revert = new TerrainChannel(); 115 m_revert = new TerrainChannel();
116 UpdateRevertMap(); 116 UpdateRevertMap();
117 } 117 }
118 } 118 }
119 else 119 else
120 { 120 {
121 m_channel = m_scene.Heightmap; 121 m_channel = m_scene.Heightmap;
122 m_revert = new TerrainChannel(); 122 m_revert = new TerrainChannel();
123 UpdateRevertMap(); 123 UpdateRevertMap();
124 } 124 }
125 125
126 m_scene.RegisterModuleInterface<ITerrainModule>(this); 126 m_scene.RegisterModuleInterface<ITerrainModule>(this);
127 m_scene.EventManager.OnNewClient += EventManager_OnNewClient; 127 m_scene.EventManager.OnNewClient += EventManager_OnNewClient;
128 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; 128 m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole;
129 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick; 129 m_scene.EventManager.OnTerrainTick += EventManager_OnTerrainTick;
130 } 130 }
131 131
132 /// <summary> 132 /// <summary>
133 /// Enables terrain module when called 133 /// Enables terrain module when called
134 /// </summary> 134 /// </summary>
135 public void PostInitialise() 135 public void PostInitialise()
136 { 136 {
137 InstallDefaultEffects(); 137 InstallDefaultEffects();
138 InstallInterfaces(); 138 InstallInterfaces();
139 LoadPlugins(); 139 LoadPlugins();
140 } 140 }
141 141
142 public void Close() 142 public void Close()
143 { 143 {
144 } 144 }
145 145
146 public string Name 146 public string Name
147 { 147 {
148 get { return "TerrainModule"; } 148 get { return "TerrainModule"; }
149 } 149 }
150 150
151 public bool IsSharedModule 151 public bool IsSharedModule
152 { 152 {
153 get { return false; } 153 get { return false; }
154 } 154 }
155 155
156 #endregion 156 #endregion
157 157
158 #region ITerrainModule Members 158 #region ITerrainModule Members
159 159
160 /// <summary> 160 /// <summary>
161 /// Loads a terrain file from disk and installs it in the scene. 161 /// Loads a terrain file from disk and installs it in the scene.
162 /// </summary> 162 /// </summary>
163 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> 163 /// <param name="filename">Filename to terrain file. Type is determined by extension.</param>
164 public void LoadFromFile(string filename) 164 public void LoadFromFile(string filename)
165 { 165 {
166 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 166 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
167 { 167 {
168 if (filename.EndsWith(loader.Key)) 168 if (filename.EndsWith(loader.Key))
169 { 169 {
170 lock (m_scene) 170 lock (m_scene)
171 { 171 {
172 try 172 try
173 { 173 {
174 ITerrainChannel channel = loader.Value.LoadFile(filename); 174 ITerrainChannel channel = loader.Value.LoadFile(filename);
175 m_scene.Heightmap = channel; 175 m_scene.Heightmap = channel;
176 m_channel = channel; 176 m_channel = channel;
177 UpdateRevertMap(); 177 UpdateRevertMap();
178 } 178 }
179 catch (NotImplementedException) 179 catch (NotImplementedException)
180 { 180 {
181 m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + 181 m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value +
182 " parser does not support file loading. (May be save only)"); 182 " parser does not support file loading. (May be save only)");
183 throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); 183 throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value));
184 } 184 }
185 catch (FileNotFoundException) 185 catch (FileNotFoundException)
186 { 186 {
187 m_log.Error( 187 m_log.Error(
188 "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); 188 "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)");
189 throw new TerrainException( 189 throw new TerrainException(
190 String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename)); 190 String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename));
191 } 191 }
192 } 192 }
193 CheckForTerrainUpdates(); 193 CheckForTerrainUpdates();
194 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); 194 m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully");
195 return; 195 return;
196 } 196 }
197 } 197 }
198 m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); 198 m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format.");
199 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); 199 throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename));
200 } 200 }
201 201
202 /// <summary> 202 /// <summary>
203 /// Saves the current heightmap to a specified file. 203 /// Saves the current heightmap to a specified file.
204 /// </summary> 204 /// </summary>
205 /// <param name="filename">The destination filename</param> 205 /// <param name="filename">The destination filename</param>
206 public void SaveToFile(string filename) 206 public void SaveToFile(string filename)
207 { 207 {
208 try 208 try
209 { 209 {
210 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 210 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
211 { 211 {
212 if (filename.EndsWith(loader.Key)) 212 if (filename.EndsWith(loader.Key))
213 { 213 {
214 loader.Value.SaveFile(filename, m_channel); 214 loader.Value.SaveFile(filename, m_channel);
215 return; 215 return;
216 } 216 }
217 } 217 }
218 } 218 }
219 catch (NotImplementedException) 219 catch (NotImplementedException)
220 { 220 {
221 m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); 221 m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented.");
222 throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); 222 throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented"));
223 } 223 }
224 } 224 }
225 225
226 #region Plugin Loading Methods 226 #region Plugin Loading Methods
227 227
228 private void LoadPlugins() 228 private void LoadPlugins()
229 { 229 {
230 m_plugineffects = new Dictionary<string, ITerrainEffect>(); 230 m_plugineffects = new Dictionary<string, ITerrainEffect>();
231 // Load the files in the Terrain/ dir 231 // Load the files in the Terrain/ dir
232 string[] files = Directory.GetFiles("Terrain"); 232 string[] files = Directory.GetFiles("Terrain");
233 foreach (string file in files) 233 foreach (string file in files)
234 { 234 {
235 m_log.Info("Loading effects in " + file); 235 m_log.Info("Loading effects in " + file);
236 try 236 try
237 { 237 {
238 Assembly library = Assembly.LoadFrom(file); 238 Assembly library = Assembly.LoadFrom(file);
239 foreach (Type pluginType in library.GetTypes()) 239 foreach (Type pluginType in library.GetTypes())
240 { 240 {
241 try 241 try
242 { 242 {
243 if (pluginType.IsAbstract || pluginType.IsNotPublic) 243 if (pluginType.IsAbstract || pluginType.IsNotPublic)
244 continue; 244 continue;
245 245
246 if (pluginType.GetInterface("ITerrainEffect", false) != null) 246 if (pluginType.GetInterface("ITerrainEffect", false) != null)
247 { 247 {
248 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); 248 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
249 if (!m_plugineffects.ContainsKey(pluginType.Name)) 249 if (!m_plugineffects.ContainsKey(pluginType.Name))
250 { 250 {
251 m_plugineffects.Add(pluginType.Name, terEffect); 251 m_plugineffects.Add(pluginType.Name, terEffect);
252 m_log.Info("E ... " + pluginType.Name); 252 m_log.Info("E ... " + pluginType.Name);
253 } 253 }
254 else 254 else
255 { 255 {
256 m_log.Warn("E ... " + pluginType.Name + " (Already added)"); 256 m_log.Warn("E ... " + pluginType.Name + " (Already added)");
257 } 257 }
258 } 258 }
259 else if (pluginType.GetInterface("ITerrainLoader", false) != null) 259 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
260 { 260 {
261 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); 261 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
262 m_loaders[terLoader.FileExtension] = terLoader; 262 m_loaders[terLoader.FileExtension] = terLoader;
263 m_log.Info("L ... " + pluginType.Name); 263 m_log.Info("L ... " + pluginType.Name);
264 } 264 }
265 } 265 }
266 catch (AmbiguousMatchException) 266 catch (AmbiguousMatchException)
267 { 267 {
268 } 268 }
269 } 269 }
270 } 270 }
271 catch (BadImageFormatException) 271 catch (BadImageFormatException)
272 { 272 {
273 } 273 }
274 } 274 }
275 } 275 }
276 276
277 #endregion 277 #endregion
278 278
279 #endregion 279 #endregion
280 280
281 /// <summary> 281 /// <summary>
282 /// Installs into terrain module the standard suite of brushes 282 /// Installs into terrain module the standard suite of brushes
283 /// </summary> 283 /// </summary>
284 private void InstallDefaultEffects() 284 private void InstallDefaultEffects()
285 { 285 {
286 // Draggable Paint Brush Effects 286 // Draggable Paint Brush Effects
287 m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere(); 287 m_painteffects[StandardTerrainEffects.Raise] = new RaiseSphere();
288 m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere(); 288 m_painteffects[StandardTerrainEffects.Lower] = new LowerSphere();
289 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere(); 289 m_painteffects[StandardTerrainEffects.Smooth] = new SmoothSphere();
290 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere(); 290 m_painteffects[StandardTerrainEffects.Noise] = new NoiseSphere();
291 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere(); 291 m_painteffects[StandardTerrainEffects.Flatten] = new FlattenSphere();
292 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert); 292 m_painteffects[StandardTerrainEffects.Revert] = new RevertSphere(m_revert);
293 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere(); 293 m_painteffects[StandardTerrainEffects.Erode] = new ErodeSphere();
294 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere(); 294 m_painteffects[StandardTerrainEffects.Weather] = new WeatherSphere();
295 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere(); 295 m_painteffects[StandardTerrainEffects.Olsen] = new OlsenSphere();
296 296
297 // Area of effect selection effects 297 // Area of effect selection effects
298 m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea(); 298 m_floodeffects[StandardTerrainEffects.Raise] = new RaiseArea();
299 m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea(); 299 m_floodeffects[StandardTerrainEffects.Lower] = new LowerArea();
300 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea(); 300 m_floodeffects[StandardTerrainEffects.Smooth] = new SmoothArea();
301 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea(); 301 m_floodeffects[StandardTerrainEffects.Noise] = new NoiseArea();
302 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); 302 m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea();
303 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); 303 m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert);
304 304
305 // Filesystem load/save loaders 305 // Filesystem load/save loaders
306 m_loaders[".r32"] = new RAW32(); 306 m_loaders[".r32"] = new RAW32();
307 m_loaders[".f32"] = m_loaders[".r32"]; 307 m_loaders[".f32"] = m_loaders[".r32"];
308 m_loaders[".ter"] = new Terragen(); 308 m_loaders[".ter"] = new Terragen();
309 m_loaders[".raw"] = new LLRAW(); 309 m_loaders[".raw"] = new LLRAW();
310 m_loaders[".jpg"] = new JPEG(); 310 m_loaders[".jpg"] = new JPEG();
311 m_loaders[".jpeg"] = m_loaders[".jpg"]; 311 m_loaders[".jpeg"] = m_loaders[".jpg"];
312 m_loaders[".bmp"] = new BMP(); 312 m_loaders[".bmp"] = new BMP();
313 m_loaders[".png"] = new PNG(); 313 m_loaders[".png"] = new PNG();
314 m_loaders[".gif"] = new GIF(); 314 m_loaders[".gif"] = new GIF();
315 m_loaders[".tif"] = new TIFF(); 315 m_loaders[".tif"] = new TIFF();
316 m_loaders[".tiff"] = m_loaders[".tif"]; 316 m_loaders[".tiff"] = m_loaders[".tif"];
317 } 317 }
318 318
319 /// <summary> 319 /// <summary>
320 /// Saves the current state of the region into the revert map buffer. 320 /// Saves the current state of the region into the revert map buffer.
321 /// </summary> 321 /// </summary>
322 public void UpdateRevertMap() 322 public void UpdateRevertMap()
323 { 323 {
324 int x; 324 int x;
325 for (x = 0; x < m_channel.Width; x++) 325 for (x = 0; x < m_channel.Width; x++)
326 { 326 {
327 int y; 327 int y;
328 for (y = 0; y < m_channel.Height; y++) 328 for (y = 0; y < m_channel.Height; y++)
329 { 329 {
330 m_revert[x, y] = m_channel[x, y]; 330 m_revert[x, y] = m_channel[x, y];
331 } 331 }
332 } 332 }
333 } 333 }
334 334
335 /// <summary> 335 /// <summary>
336 /// Loads a tile from a larger terrain file and installs it into the region. 336 /// Loads a tile from a larger terrain file and installs it into the region.
337 /// </summary> 337 /// </summary>
338 /// <param name="filename">The terrain file to load</param> 338 /// <param name="filename">The terrain file to load</param>
339 /// <param name="fileWidth">The width of the file in units</param> 339 /// <param name="fileWidth">The width of the file in units</param>
340 /// <param name="fileHeight">The height of the file in units</param> 340 /// <param name="fileHeight">The height of the file in units</param>
341 /// <param name="fileStartX">Where to begin our slice</param> 341 /// <param name="fileStartX">Where to begin our slice</param>
342 /// <param name="fileStartY">Where to begin our slice</param> 342 /// <param name="fileStartY">Where to begin our slice</param>
343 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) 343 public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
344 { 344 {
345 int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX; 345 int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX;
346 int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY; 346 int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY;
347 347
348 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) 348 if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
349 { 349 {
350 // this region is included in the tile request 350 // this region is included in the tile request
351 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 351 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
352 { 352 {
353 if (filename.EndsWith(loader.Key)) 353 if (filename.EndsWith(loader.Key))
354 { 354 {
355 lock (m_scene) 355 lock (m_scene)
356 { 356 {
357 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, 357 ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY,
358 fileWidth, fileHeight, 358 fileWidth, fileHeight,
359 (int) Constants.RegionSize, 359 (int) Constants.RegionSize,
360 (int) Constants.RegionSize); 360 (int) Constants.RegionSize);
361 m_scene.Heightmap = channel; 361 m_scene.Heightmap = channel;
362 m_channel = channel; 362 m_channel = channel;
363 UpdateRevertMap(); 363 UpdateRevertMap();
364 } 364 }
365 return; 365 return;
366 } 366 }
367 } 367 }
368 } 368 }
369 } 369 }
370 370
371 /// <summary> 371 /// <summary>
372 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections 372 /// Performs updates to the region periodically, synchronising physics and other heightmap aware sections
373 /// </summary> 373 /// </summary>
374 private void EventManager_OnTerrainTick() 374 private void EventManager_OnTerrainTick()
375 { 375 {
376 if (m_tainted) 376 if (m_tainted)
377 { 377 {
378 m_tainted = false; 378 m_tainted = false;
379 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); 379 m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised());
380 m_scene.SaveTerrain(); 380 m_scene.SaveTerrain();
381 m_scene.CreateTerrainTexture(true); 381 m_scene.CreateTerrainTexture(true);
382 } 382 }
383 } 383 }
384 384
385 /// <summary> 385 /// <summary>
386 /// Processes commandline input. Do not call directly. 386 /// Processes commandline input. Do not call directly.
387 /// </summary> 387 /// </summary>
388 /// <param name="args">Commandline arguments</param> 388 /// <param name="args">Commandline arguments</param>
389 private void EventManager_OnPluginConsole(string[] args) 389 private void EventManager_OnPluginConsole(string[] args)
390 { 390 {
391 if (args[0] == "terrain") 391 if (args[0] == "terrain")
392 { 392 {
393 string[] tmpArgs = new string[args.Length - 2]; 393 string[] tmpArgs = new string[args.Length - 2];
394 int i; 394 int i;
395 for (i = 2; i < args.Length; i++) 395 for (i = 2; i < args.Length; i++)
396 tmpArgs[i - 2] = args[i]; 396 tmpArgs[i - 2] = args[i];
397 397
398 m_commander.ProcessConsoleCommand(args[1], tmpArgs); 398 m_commander.ProcessConsoleCommand(args[1], tmpArgs);
399 } 399 }
400 } 400 }
401 401
402 /// <summary> 402 /// <summary>
403 /// Installs terrain brush hook to IClientAPI 403 /// Installs terrain brush hook to IClientAPI
404 /// </summary> 404 /// </summary>
405 /// <param name="client"></param> 405 /// <param name="client"></param>
406 private void EventManager_OnNewClient(IClientAPI client) 406 private void EventManager_OnNewClient(IClientAPI client)
407 { 407 {
408 client.OnModifyTerrain += client_OnModifyTerrain; 408 client.OnModifyTerrain += client_OnModifyTerrain;
409 } 409 }
410 410
411 /// <summary> 411 /// <summary>
412 /// Checks to see if the terrain has been modified since last check 412 /// Checks to see if the terrain has been modified since last check
413 /// </summary> 413 /// </summary>
414 private void CheckForTerrainUpdates() 414 private void CheckForTerrainUpdates()
415 { 415 {
416 bool shouldTaint = false; 416 bool shouldTaint = false;
417 float[] serialised = m_channel.GetFloatsSerialised(); 417 float[] serialised = m_channel.GetFloatsSerialised();
418 int x; 418 int x;
419 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize) 419 for (x = 0; x < m_channel.Width; x += Constants.TerrainPatchSize)
420 { 420 {
421 int y; 421 int y;
422 for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize) 422 for (y = 0; y < m_channel.Height; y += Constants.TerrainPatchSize)
423 { 423 {
424 if (m_channel.Tainted(x, y)) 424 if (m_channel.Tainted(x, y))
425 { 425 {
426 SendToClients(serialised, x, y); 426 SendToClients(serialised, x, y);
427 shouldTaint = true; 427 shouldTaint = true;
428 } 428 }
429 } 429 }
430 } 430 }
431 if (shouldTaint) 431 if (shouldTaint)
432 { 432 {
433 m_tainted = true; 433 m_tainted = true;
434 } 434 }
435 } 435 }
436 436
437 /// <summary> 437 /// <summary>
438 /// Sends a copy of the current terrain to the scenes clients 438 /// Sends a copy of the current terrain to the scenes clients
439 /// </summary> 439 /// </summary>
440 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param> 440 /// <param name="serialised">A copy of the terrain as a 1D float array of size w*h</param>
441 /// <param name="x">The patch corner to send</param> 441 /// <param name="x">The patch corner to send</param>
442 /// <param name="y">The patch corner to send</param> 442 /// <param name="y">The patch corner to send</param>
443 private void SendToClients(float[] serialised, int x, int y) 443 private void SendToClients(float[] serialised, int x, int y)
444 { 444 {
445 m_scene.ForEachClient( 445 m_scene.ForEachClient(
446 delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); }); 446 delegate(IClientAPI controller) { controller.SendLayerData(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, serialised); });
447 } 447 }
448 448
449 private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, 449 private void client_OnModifyTerrain(float height, float seconds, byte size, byte action, float north, float west,
450 float south, float east, IClientAPI remoteClient) 450 float south, float east, IClientAPI remoteClient)
451 { 451 {
452 // Not a good permissions check, if in area mode, need to check the entire area. 452 // Not a good permissions check, if in area mode, need to check the entire area.
453 if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0))) 453 if (m_scene.PermissionsMngr.CanTerraform(remoteClient.AgentId, new LLVector3(north, west, 0)))
454 { 454 {
455 if (north == south && east == west) 455 if (north == south && east == west)
456 { 456 {
457 if (m_painteffects.ContainsKey((StandardTerrainEffects) action)) 457 if (m_painteffects.ContainsKey((StandardTerrainEffects) action))
458 { 458 {
459 m_painteffects[(StandardTerrainEffects) action].PaintEffect( 459 m_painteffects[(StandardTerrainEffects) action].PaintEffect(
460 m_channel, west, south, size, seconds); 460 m_channel, west, south, size, seconds);
461 461
462 CheckForTerrainUpdates(); 462 CheckForTerrainUpdates();
463 } 463 }
464 else 464 else
465 { 465 {
466 m_log.Debug("Unknown terrain brush type " + action); 466 m_log.Debug("Unknown terrain brush type " + action);
467 } 467 }
468 } 468 }
469 else 469 else
470 { 470 {
471 if (m_floodeffects.ContainsKey((StandardTerrainEffects) action)) 471 if (m_floodeffects.ContainsKey((StandardTerrainEffects) action))
472 { 472 {
473 bool[,] fillArea = new bool[m_channel.Width,m_channel.Height]; 473 bool[,] fillArea = new bool[m_channel.Width,m_channel.Height];
474 fillArea.Initialize(); 474 fillArea.Initialize();
475 475
476 int x; 476 int x;
477 for (x = 0; x < m_channel.Width; x++) 477 for (x = 0; x < m_channel.Width; x++)
478 { 478 {
479 int y; 479 int y;
480 for (y = 0; y < m_channel.Height; y++) 480 for (y = 0; y < m_channel.Height; y++)
481 { 481 {
482 if (x < east && x > west) 482 if (x < east && x > west)
483 { 483 {
484 if (y < north && y > south) 484 if (y < north && y > south)
485 { 485 {
486 fillArea[x, y] = true; 486 fillArea[x, y] = true;
487 } 487 }
488 } 488 }
489 } 489 }
490 } 490 }
491 491
492 m_floodeffects[(StandardTerrainEffects) action].FloodEffect( 492 m_floodeffects[(StandardTerrainEffects) action].FloodEffect(
493 m_channel, fillArea, size); 493 m_channel, fillArea, size);
494 494
495 CheckForTerrainUpdates(); 495 CheckForTerrainUpdates();
496 } 496 }
497 else 497 else
498 { 498 {
499 m_log.Debug("Unknown terrain flood type " + action); 499 m_log.Debug("Unknown terrain flood type " + action);
500 } 500 }
501 } 501 }
502 } 502 }
503 } 503 }
504 504
505 #region Console Commands 505 #region Console Commands
506 506
507 private void InterfaceLoadFile(Object[] args) 507 private void InterfaceLoadFile(Object[] args)
508 { 508 {
509 LoadFromFile((string) args[0]); 509 LoadFromFile((string) args[0]);
510 CheckForTerrainUpdates(); 510 CheckForTerrainUpdates();
511 } 511 }
512 512
513 private void InterfaceLoadTileFile(Object[] args) 513 private void InterfaceLoadTileFile(Object[] args)
514 { 514 {
515 LoadFromFile((string) args[0], 515 LoadFromFile((string) args[0],
516 (int) args[1], 516 (int) args[1],
517 (int) args[2], 517 (int) args[2],
518 (int) args[3], 518 (int) args[3],
519 (int) args[4]); 519 (int) args[4]);
520 CheckForTerrainUpdates(); 520 CheckForTerrainUpdates();
521 } 521 }
522 522
523 private void InterfaceSaveFile(Object[] args) 523 private void InterfaceSaveFile(Object[] args)
524 { 524 {
525 SaveToFile((string) args[0]); 525 SaveToFile((string) args[0]);
526 } 526 }
527 527
528 private void InterfaceBakeTerrain(Object[] args) 528 private void InterfaceBakeTerrain(Object[] args)
529 { 529 {
530 UpdateRevertMap(); 530 UpdateRevertMap();
531 } 531 }
532 532
533 private void InterfaceRevertTerrain(Object[] args) 533 private void InterfaceRevertTerrain(Object[] args)
534 { 534 {
535 int x, y; 535 int x, y;
536 for (x = 0; x < m_channel.Width; x++) 536 for (x = 0; x < m_channel.Width; x++)
537 for (y = 0; y < m_channel.Height; y++) 537 for (y = 0; y < m_channel.Height; y++)
538 m_channel[x, y] = m_revert[x, y]; 538 m_channel[x, y] = m_revert[x, y];
539 539
540 CheckForTerrainUpdates(); 540 CheckForTerrainUpdates();
541 } 541 }
542 542
543 private void InterfaceElevateTerrain(Object[] args) 543 private void InterfaceElevateTerrain(Object[] args)
544 { 544 {
545 int x, y; 545 int x, y;
546 for (x = 0; x < m_channel.Width; x++) 546 for (x = 0; x < m_channel.Width; x++)
547 for (y = 0; y < m_channel.Height; y++) 547 for (y = 0; y < m_channel.Height; y++)
548 m_channel[x, y] += (double) args[0]; 548 m_channel[x, y] += (double) args[0];
549 CheckForTerrainUpdates(); 549 CheckForTerrainUpdates();
550 } 550 }
551 551
552 private void InterfaceMultiplyTerrain(Object[] args) 552 private void InterfaceMultiplyTerrain(Object[] args)
553 { 553 {
554 int x, y; 554 int x, y;
555 for (x = 0; x < m_channel.Width; x++) 555 for (x = 0; x < m_channel.Width; x++)
556 for (y = 0; y < m_channel.Height; y++) 556 for (y = 0; y < m_channel.Height; y++)
557 m_channel[x, y] *= (double) args[0]; 557 m_channel[x, y] *= (double) args[0];
558 CheckForTerrainUpdates(); 558 CheckForTerrainUpdates();
559 } 559 }
560 560
561 private void InterfaceLowerTerrain(Object[] args) 561 private void InterfaceLowerTerrain(Object[] args)
562 { 562 {
563 int x, y; 563 int x, y;
564 for (x = 0; x < m_channel.Width; x++) 564 for (x = 0; x < m_channel.Width; x++)
565 for (y = 0; y < m_channel.Height; y++) 565 for (y = 0; y < m_channel.Height; y++)
566 m_channel[x, y] -= (double) args[0]; 566 m_channel[x, y] -= (double) args[0];
567 CheckForTerrainUpdates(); 567 CheckForTerrainUpdates();
568 } 568 }
569 569
570 private void InterfaceFillTerrain(Object[] args) 570 private void InterfaceFillTerrain(Object[] args)
571 { 571 {
572 int x, y; 572 int x, y;
573 573
574 for (x = 0; x < m_channel.Width; x++) 574 for (x = 0; x < m_channel.Width; x++)
575 for (y = 0; y < m_channel.Height; y++) 575 for (y = 0; y < m_channel.Height; y++)
576 m_channel[x, y] = (double) args[0]; 576 m_channel[x, y] = (double) args[0];
577 CheckForTerrainUpdates(); 577 CheckForTerrainUpdates();
578 } 578 }
579 579
580 private void InterfaceShowDebugStats(Object[] args) 580 private void InterfaceShowDebugStats(Object[] args)
581 { 581 {
582 double max = Double.MinValue; 582 double max = Double.MinValue;
583 double min = double.MaxValue; 583 double min = double.MaxValue;
584 double avg; 584 double avg;
585 double sum = 0; 585 double sum = 0;
586 586
587 int x; 587 int x;
588 for (x = 0; x < m_channel.Width; x++) 588 for (x = 0; x < m_channel.Width; x++)
589 { 589 {
590 int y; 590 int y;
591 for (y = 0; y < m_channel.Height; y++) 591 for (y = 0; y < m_channel.Height; y++)
592 { 592 {
593 sum += m_channel[x, y]; 593 sum += m_channel[x, y];
594 if (max < m_channel[x, y]) 594 if (max < m_channel[x, y])
595 max = m_channel[x, y]; 595 max = m_channel[x, y];
596 if (min > m_channel[x, y]) 596 if (min > m_channel[x, y])
597 min = m_channel[x, y]; 597 min = m_channel[x, y];
598 } 598 }
599 } 599 }
600 600
601 avg = sum / (m_channel.Height * m_channel.Width); 601 avg = sum / (m_channel.Height * m_channel.Width);
602 602
603 m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height); 603 m_log.Info("Channel " + m_channel.Width + "x" + m_channel.Height);
604 m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum); 604 m_log.Info("max/min/avg/sum: " + max + "/" + min + "/" + avg + "/" + sum);
605 } 605 }
606 606
607 private void InterfaceEnableExperimentalBrushes(Object[] args) 607 private void InterfaceEnableExperimentalBrushes(Object[] args)
608 { 608 {
609 if ((bool) args[0]) 609 if ((bool) args[0])
610 { 610 {
611 m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere(); 611 m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere();
612 m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere(); 612 m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere();
613 m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere(); 613 m_painteffects[StandardTerrainEffects.Smooth] = new ErodeSphere();
614 } 614 }
615 else 615 else
616 { 616 {
617 InstallDefaultEffects(); 617 InstallDefaultEffects();
618 } 618 }
619 } 619 }
620 620
621 private void InterfaceRunPluginEffect(Object[] args) 621 private void InterfaceRunPluginEffect(Object[] args)
622 { 622 {
623 if ((string) args[0] == "list") 623 if ((string) args[0] == "list")
624 { 624 {
625 m_log.Info("List of loaded plugins"); 625 m_log.Info("List of loaded plugins");
626 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) 626 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
627 { 627 {
628 m_log.Info(kvp.Key); 628 m_log.Info(kvp.Key);
629 } 629 }
630 return; 630 return;
631 } 631 }
632 if ((string) args[0] == "reload") 632 if ((string) args[0] == "reload")
633 { 633 {
634 LoadPlugins(); 634 LoadPlugins();
635 return; 635 return;
636 } 636 }
637 if (m_plugineffects.ContainsKey((string) args[0])) 637 if (m_plugineffects.ContainsKey((string) args[0]))
638 { 638 {
639 m_plugineffects[(string) args[0]].RunEffect(m_channel); 639 m_plugineffects[(string) args[0]].RunEffect(m_channel);
640 CheckForTerrainUpdates(); 640 CheckForTerrainUpdates();
641 } 641 }
642 else 642 else
643 { 643 {
644 m_log.Warn("No such plugin effect loaded."); 644 m_log.Warn("No such plugin effect loaded.");
645 } 645 }
646 } 646 }
647 647
648 private void InstallInterfaces() 648 private void InstallInterfaces()
649 { 649 {
650 // Load / Save 650 // Load / Save
651 string supportedFileExtensions = ""; 651 string supportedFileExtensions = "";
652 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) 652 foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
653 supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")"; 653 supportedFileExtensions += " " + loader.Key + " (" + loader.Value + ")";
654 654
655 Command loadFromFileCommand = 655 Command loadFromFileCommand =
656 new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file."); 656 new Command("load", InterfaceLoadFile, "Loads a terrain from a specified file.");
657 loadFromFileCommand.AddArgument("filename", 657 loadFromFileCommand.AddArgument("filename",
658 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + 658 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
659 supportedFileExtensions, "String"); 659 supportedFileExtensions, "String");
660 660
661 Command saveToFileCommand = 661 Command saveToFileCommand =
662 new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file."); 662 new Command("save", InterfaceSaveFile, "Saves the current heightmap to a specified file.");
663 saveToFileCommand.AddArgument("filename", 663 saveToFileCommand.AddArgument("filename",
664 "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " + 664 "The destination filename for your heightmap, the file extension determines the format to save in. Supported extensions include: " +
665 supportedFileExtensions, "String"); 665 supportedFileExtensions, "String");
666 666
667 Command loadFromTileCommand = 667 Command loadFromTileCommand =
668 new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file."); 668 new Command("load-tile", InterfaceLoadTileFile, "Loads a terrain from a section of a larger file.");
669 loadFromTileCommand.AddArgument("filename", 669 loadFromTileCommand.AddArgument("filename",
670 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " + 670 "The file you wish to load from, the file extension determines the loader to be used. Supported extensions include: " +
671 supportedFileExtensions, "String"); 671 supportedFileExtensions, "String");
672 loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer"); 672 loadFromTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
673 loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer"); 673 loadFromTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
674 loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file", 674 loadFromTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
675 "Integer"); 675 "Integer");
676 loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file", 676 loadFromTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
677 "Integer"); 677 "Integer");
678 678
679 // Terrain adjustments 679 // Terrain adjustments
680 Command fillRegionCommand = 680 Command fillRegionCommand =
681 new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value."); 681 new Command("fill", InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
682 fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.", 682 fillRegionCommand.AddArgument("value", "The numeric value of the height you wish to set your region to.",
683 "Double"); 683 "Double");
684 684
685 Command elevateCommand = 685 Command elevateCommand =
686 new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount."); 686 new Command("elevate", InterfaceElevateTerrain, "Raises the current heightmap by the specified amount.");
687 elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double"); 687 elevateCommand.AddArgument("amount", "The amount of height to add to the terrain in meters.", "Double");
688 688
689 Command lowerCommand = 689 Command lowerCommand =
690 new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount."); 690 new Command("lower", InterfaceLowerTerrain, "Lowers the current heightmap by the specified amount.");
691 lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double"); 691 lowerCommand.AddArgument("amount", "The amount of height to remove from the terrain in meters.", "Double");
692 692
693 Command multiplyCommand = 693 Command multiplyCommand =
694 new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified."); 694 new Command("multiply", InterfaceMultiplyTerrain, "Multiplies the heightmap by the value specified.");
695 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double"); 695 multiplyCommand.AddArgument("value", "The value to multiply the heightmap by.", "Double");
696 696
697 Command bakeRegionCommand = 697 Command bakeRegionCommand =
698 new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map."); 698 new Command("bake", InterfaceBakeTerrain, "Saves the current terrain into the regions revert map.");
699 Command revertRegionCommand = 699 Command revertRegionCommand =
700 new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap."); 700 new Command("revert", InterfaceRevertTerrain, "Loads the revert map terrain into the regions heightmap.");
701 701
702 // Debug 702 // Debug
703 Command showDebugStatsCommand = 703 Command showDebugStatsCommand =
704 new Command("stats", InterfaceShowDebugStats, 704 new Command("stats", InterfaceShowDebugStats,
705 "Shows some information about the regions heightmap for debugging purposes."); 705 "Shows some information about the regions heightmap for debugging purposes.");
706 706
707 Command experimentalBrushesCommand = 707 Command experimentalBrushesCommand =
708 new Command("newbrushes", InterfaceEnableExperimentalBrushes, 708 new Command("newbrushes", InterfaceEnableExperimentalBrushes,
709 "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time."); 709 "Enables experimental brushes which replace the standard terrain brushes. WARNING: This is a debug setting and may be removed at any time.");
710 experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean"); 710 experimentalBrushesCommand.AddArgument("Enabled?", "true / false - Enable new brushes", "Boolean");
711 711
712 //Plugins 712 //Plugins
713 Command pluginRunCommand = 713 Command pluginRunCommand =
714 new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect"); 714 new Command("effect", InterfaceRunPluginEffect, "Runs a specified plugin effect");
715 pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String"); 715 pluginRunCommand.AddArgument("name", "The plugin effect you wish to run, or 'list' to see all plugins", "String");
716 716
717 m_commander.RegisterCommand("load", loadFromFileCommand); 717 m_commander.RegisterCommand("load", loadFromFileCommand);
718 m_commander.RegisterCommand("load-tile", loadFromTileCommand); 718 m_commander.RegisterCommand("load-tile", loadFromTileCommand);
719 m_commander.RegisterCommand("save", saveToFileCommand); 719 m_commander.RegisterCommand("save", saveToFileCommand);
720 m_commander.RegisterCommand("fill", fillRegionCommand); 720 m_commander.RegisterCommand("fill", fillRegionCommand);
721 m_commander.RegisterCommand("elevate", elevateCommand); 721 m_commander.RegisterCommand("elevate", elevateCommand);
722 m_commander.RegisterCommand("lower", lowerCommand); 722 m_commander.RegisterCommand("lower", lowerCommand);
723 m_commander.RegisterCommand("multiply", multiplyCommand); 723 m_commander.RegisterCommand("multiply", multiplyCommand);
724 m_commander.RegisterCommand("bake", bakeRegionCommand); 724 m_commander.RegisterCommand("bake", bakeRegionCommand);
725 m_commander.RegisterCommand("revert", revertRegionCommand); 725 m_commander.RegisterCommand("revert", revertRegionCommand);
726 m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand); 726 m_commander.RegisterCommand("newbrushes", experimentalBrushesCommand);
727 m_commander.RegisterCommand("stats", showDebugStatsCommand); 727 m_commander.RegisterCommand("stats", showDebugStatsCommand);
728 m_commander.RegisterCommand("effect", pluginRunCommand); 728 m_commander.RegisterCommand("effect", pluginRunCommand);
729 729
730 // Add this to our scene so scripts can call these functions 730 // Add this to our scene so scripts can call these functions
731 m_scene.RegisterModuleCommander("Terrain", m_commander); 731 m_scene.RegisterModuleCommander("Terrain", m_commander);
732 } 732 }
733 733
734 #endregion 734 #endregion
735 } 735 }
736} \ No newline at end of file 736} \ No newline at end of file