opensim – Diff between revs 1 and 7

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 1 Rev 7
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 OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator 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  
28 using System; 28 using System;
29 using System.Collections; 29 using System.Collections;
30 using System.Collections.Generic; 30 using System.Collections.Generic;
31 using System.Runtime.Remoting.Lifetime; 31 using System.Runtime.Remoting.Lifetime;
32 using System.Text; 32 using System.Text;
33 using System.Threading; 33 using System.Threading;
34 using System.Text.RegularExpressions; 34 using System.Text.RegularExpressions;
35 using Nini.Config; 35 using Nini.Config;
36 using log4net; 36 using log4net;
37 using OpenMetaverse; 37 using OpenMetaverse;
38 using OpenMetaverse.Packets; 38 using OpenMetaverse.Packets;
39 using OpenSim; 39 using OpenSim;
40 using OpenSim.Framework; 40 using OpenSim.Framework;
41   41  
42 using OpenSim.Region.CoreModules; 42 using OpenSim.Region.CoreModules;
43 using OpenSim.Region.CoreModules.World.Land; 43 using OpenSim.Region.CoreModules.World.Land;
44 using OpenSim.Region.CoreModules.World.Terrain; 44 using OpenSim.Region.CoreModules.World.Terrain;
45 using OpenSim.Region.Framework.Interfaces; 45 using OpenSim.Region.Framework.Interfaces;
46 using OpenSim.Region.Framework.Scenes; 46 using OpenSim.Region.Framework.Scenes;
47 using OpenSim.Region.Framework.Scenes.Animation; 47 using OpenSim.Region.Framework.Scenes.Animation;
48 using OpenSim.Region.Framework.Scenes.Scripting; 48 using OpenSim.Region.Framework.Scenes.Scripting;
49 using OpenSim.Region.Physics.Manager; 49 using OpenSim.Region.Physics.Manager;
50 using OpenSim.Region.ScriptEngine.Shared; 50 using OpenSim.Region.ScriptEngine.Shared;
51 using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 51 using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
52 using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 52 using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
53 using OpenSim.Region.ScriptEngine.Interfaces; 53 using OpenSim.Region.ScriptEngine.Interfaces;
54 using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 54 using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
55 using OpenSim.Services.Interfaces; 55 using OpenSim.Services.Interfaces;
56 using GridRegion = OpenSim.Services.Interfaces.GridRegion; 56 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
57 using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 57 using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
58 using PrimType = OpenSim.Region.Framework.Scenes.PrimType; 58 using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
59 using AssetLandmark = OpenSim.Framework.AssetLandmark; 59 using AssetLandmark = OpenSim.Framework.AssetLandmark;
60 using RegionFlags = OpenSim.Framework.RegionFlags; 60 using RegionFlags = OpenSim.Framework.RegionFlags;
61   61  
62 using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 62 using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
63 using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 63 using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
64 using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 64 using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
65 using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 65 using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
66 using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 66 using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67 using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 67 using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68 using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 68 using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69 using System.Reflection; 69 using System.Reflection;
70 using System.Linq; 70 using System.Linq;
71 using PermissionMask = OpenSim.Framework.PermissionMask; 71 using PermissionMask = OpenSim.Framework.PermissionMask;
72   72  
73 namespace OpenSim.Region.ScriptEngine.Shared.Api 73 namespace OpenSim.Region.ScriptEngine.Shared.Api
74 { 74 {
75 // MUST be a ref type 75 // MUST be a ref type
76 public class UserInfoCacheEntry 76 public class UserInfoCacheEntry
77 { 77 {
78 public int time; 78 public int time;
79 public UserAccount account; 79 public UserAccount account;
80 public PresenceInfo pinfo; 80 public PresenceInfo pinfo;
81 } 81 }
82   82  
83 /// <summary> 83 /// <summary>
84 /// Contains all LSL ll-functions. This class will be in Default AppDomain. 84 /// Contains all LSL ll-functions. This class will be in Default AppDomain.
85 /// </summary> 85 /// </summary>
86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
87 { 87 {
88 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
89   89  
90 protected IScriptEngine m_ScriptEngine; 90 protected IScriptEngine m_ScriptEngine;
91 protected SceneObjectPart m_host; 91 protected SceneObjectPart m_host;
92   92  
93 /// <summary> 93 /// <summary>
94 /// Used for script sleeps when we are using co-operative script termination. 94 /// Used for script sleeps when we are using co-operative script termination.
95 /// </summary> 95 /// </summary>
96 /// <remarks>null if co-operative script termination is not active</remarks> 96 /// <remarks>null if co-operative script termination is not active</remarks>
97 WaitHandle m_coopSleepHandle; 97 WaitHandle m_coopSleepHandle;
98   98  
99 /// <summary> 99 /// <summary>
100 /// The item that hosts this script 100 /// The item that hosts this script
101 /// </summary> 101 /// </summary>
102 protected TaskInventoryItem m_item; 102 protected TaskInventoryItem m_item;
103   103  
104 protected bool throwErrorOnNotImplemented = false; 104 protected bool throwErrorOnNotImplemented = false;
105 protected AsyncCommandManager AsyncCommands = null; 105 protected AsyncCommandManager AsyncCommands = null;
106 protected float m_ScriptDelayFactor = 1.0f; 106 protected float m_ScriptDelayFactor = 1.0f;
107 protected float m_ScriptDistanceFactor = 1.0f; 107 protected float m_ScriptDistanceFactor = 1.0f;
108 protected float m_MinTimerInterval = 0.01f; 108 protected float m_MinTimerInterval = 0.05f;
109 protected float m_recoilScaleFactor = 0.0f; 109 protected float m_recoilScaleFactor = 0.0f;
110   110  
111 protected DateTime m_timer = DateTime.Now; 111 protected DateTime m_timer = DateTime.Now;
112 protected bool m_waitingForScriptAnswer = false; 112 protected bool m_waitingForScriptAnswer = false;
113 protected bool m_automaticLinkPermission = false; 113 protected bool m_automaticLinkPermission = false;
114 protected IMessageTransferModule m_TransferModule = null; 114 protected IMessageTransferModule m_TransferModule = null;
115 protected int m_notecardLineReadCharsMax = 255; 115 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 116 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 117 protected bool m_scriptConsoleChannelEnabled = false;
118 protected IUrlModule m_UrlModule = null; 118 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>();
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 121 protected ISoundModule m_SoundModule = null;
122   122  
123 //An array of HTTP/1.1 headers that are not allowed to be used 123 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 124 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 125 private string[] HttpStandardHeaders =
126 { 126 {
127 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", 127 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language",
128 "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control", 128 "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control",
129 "Connection", "Content-Encoding", "Content-Language", 129 "Connection", "Content-Encoding", "Content-Language",
130 "Content-Length", "Content-Location", "Content-MD5", 130 "Content-Length", "Content-Location", "Content-MD5",
131 "Content-Range", "Content-Type", "Date", "ETag", "Expect", 131 "Content-Range", "Content-Type", "Date", "ETag", "Expect",
132 "Expires", "From", "Host", "If-Match", "If-Modified-Since", 132 "Expires", "From", "Host", "If-Match", "If-Modified-Since",
133 "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified", 133 "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified",
134 "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate", 134 "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate",
135 "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server", 135 "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server",
136 "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent", 136 "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent",
137 "Vary", "Via", "Warning", "WWW-Authenticate" 137 "Vary", "Via", "Warning", "WWW-Authenticate"
138 }; 138 };
139   139  
140 public void Initialize( 140 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 142 {
143 m_ScriptEngine = scriptEngine; 143 m_ScriptEngine = scriptEngine;
144 m_host = host; 144 m_host = host;
145 m_item = item; 145 m_item = item;
146 m_coopSleepHandle = coopSleepHandle; 146 m_coopSleepHandle = coopSleepHandle;
147   147  
148 LoadConfig(); 148 LoadConfig();
149   149  
150 m_TransferModule = 150 m_TransferModule =
151 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 151 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>(); 153 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>();
154   154  
155 AsyncCommands = new AsyncCommandManager(m_ScriptEngine); 155 AsyncCommands = new AsyncCommandManager(m_ScriptEngine);
156 } 156 }
157   157  
158 /// <summary> 158 /// <summary>
159 /// Load configuration items that affect script, object and run-time behavior. */ 159 /// Load configuration items that affect script, object and run-time behavior. */
160 /// </summary> 160 /// </summary>
161 private void LoadConfig() 161 private void LoadConfig()
162 { 162 {
163 m_ScriptDelayFactor = 163 m_ScriptDelayFactor =
164 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 164 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
165 m_ScriptDistanceFactor = 165 m_ScriptDistanceFactor =
166 m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f); 166 m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f);
167 m_MinTimerInterval = 167 m_MinTimerInterval =
168 m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.01f); 168 m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.05f);
169 m_automaticLinkPermission = 169 m_automaticLinkPermission =
170 m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false); 170 m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false);
171 m_notecardLineReadCharsMax = 171 m_notecardLineReadCharsMax =
172 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); 172 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
173 if (m_notecardLineReadCharsMax > 65535) 173 if (m_notecardLineReadCharsMax > 65535)
174 m_notecardLineReadCharsMax = 65535; 174 m_notecardLineReadCharsMax = 65535;
175   175  
176 // load limits for particular subsystems. 176 // load limits for particular subsystems.
177 IConfig SMTPConfig; 177 IConfig SMTPConfig;
178 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { 178 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) {
179 // there's an smtp config, so load in the snooze time. 179 // there's an smtp config, so load in the snooze time.
180 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); 180 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
181 } 181 }
182   182  
183 // Rezzing an object with a velocity can create recoil. This feature seems to have been 183 // Rezzing an object with a velocity can create recoil. This feature seems to have been
184 // removed from recent versions of SL. The code computes recoil (vel*mass) and scales 184 // removed from recent versions of SL. The code computes recoil (vel*mass) and scales
185 // it by this factor. May be zero to turn off recoil all together. 185 // it by this factor. May be zero to turn off recoil all together.
186 m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor); 186 m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor);
187 } 187 }
188   188  
189 public override Object InitializeLifetimeService() 189 public override Object InitializeLifetimeService()
190 { 190 {
191 ILease lease = (ILease)base.InitializeLifetimeService(); 191 ILease lease = (ILease)base.InitializeLifetimeService();
192   192  
193 if (lease.CurrentState == LeaseState.Initial) 193 if (lease.CurrentState == LeaseState.Initial)
194 { 194 {
195 lease.InitialLeaseTime = TimeSpan.FromMinutes(0); 195 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
196 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); 196 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
197 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); 197 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
198 } 198 }
199 return lease; 199 return lease;
200 } 200 }
201   201  
202 protected virtual void ScriptSleep(int delay) 202 protected virtual void ScriptSleep(int delay)
203 { 203 {
204 delay = (int)((float)delay * m_ScriptDelayFactor); 204 delay = (int)((float)delay * m_ScriptDelayFactor);
205 if (delay == 0) 205 if (delay == 0)
206 return; 206 return;
207   207  
208 Sleep(delay); 208 Sleep(delay);
209 } 209 }
210   210  
211 protected virtual void Sleep(int delay) 211 protected virtual void Sleep(int delay)
212 { 212 {
213 if (m_coopSleepHandle == null) 213 if (m_coopSleepHandle == null)
214 System.Threading.Thread.Sleep(delay); 214 System.Threading.Thread.Sleep(delay);
215 else 215 else
216 CheckForCoopTermination(delay); 216 CheckForCoopTermination(delay);
217 } 217 }
218   218  
219 /// <summary> 219 /// <summary>
220 /// Check for co-operative termination. 220 /// Check for co-operative termination.
221 /// </summary> 221 /// </summary>
222 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param> 222 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param>
223 protected virtual void CheckForCoopTermination(int delay) 223 protected virtual void CheckForCoopTermination(int delay)
224 { 224 {
225 if (m_coopSleepHandle.WaitOne(delay)) 225 if (m_coopSleepHandle.WaitOne(delay))
226 throw new ScriptCoopStopException(); 226 throw new ScriptCoopStopException();
227 } 227 }
228   228  
229 public Scene World 229 public Scene World
230 { 230 {
231 get { return m_ScriptEngine.World; } 231 get { return m_ScriptEngine.World; }
232 } 232 }
233   233  
234 public void state(string newState) 234 public void state(string newState)
235 { 235 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 236 m_ScriptEngine.SetState(m_item.ItemID, newState);
237 } 237 }
238   238  
239 /// <summary> 239 /// <summary>
240 /// Reset the named script. The script must be present 240 /// Reset the named script. The script must be present
241 /// in the same prim. 241 /// in the same prim.
242 /// </summary> 242 /// </summary>
243 public void llResetScript() 243 public void llResetScript()
244 { 244 {
245 m_host.AddScriptLPS(1); 245 m_host.AddScriptLPS(1);
246   246  
247 // We need to tell the URL module, if we hav one, to release 247 // We need to tell the URL module, if we hav one, to release
248 // the allocated URLs 248 // the allocated URLs
249 if (m_UrlModule != null) 249 if (m_UrlModule != null)
250 m_UrlModule.ScriptRemoved(m_item.ItemID); 250 m_UrlModule.ScriptRemoved(m_item.ItemID);
251   251  
252 m_ScriptEngine.ApiResetScript(m_item.ItemID); 252 m_ScriptEngine.ApiResetScript(m_item.ItemID);
253 } 253 }
254   254  
255 public void llResetOtherScript(string name) 255 public void llResetOtherScript(string name)
256 { 256 {
257 UUID item; 257 UUID item;
258   258  
259 m_host.AddScriptLPS(1); 259 m_host.AddScriptLPS(1);
260   260  
261 if ((item = GetScriptByName(name)) != UUID.Zero) 261 if ((item = GetScriptByName(name)) != UUID.Zero)
262 m_ScriptEngine.ResetScript(item); 262 m_ScriptEngine.ResetScript(item);
263 else 263 else
264 Error("llResetOtherScript", "Can't find script '" + name + "'"); 264 Error("llResetOtherScript", "Can't find script '" + name + "'");
265 } 265 }
266   266  
267 public LSL_Integer llGetScriptState(string name) 267 public LSL_Integer llGetScriptState(string name)
268 { 268 {
269 UUID item; 269 UUID item;
270   270  
271 m_host.AddScriptLPS(1); 271 m_host.AddScriptLPS(1);
272   272  
273 if ((item = GetScriptByName(name)) != UUID.Zero) 273 if ((item = GetScriptByName(name)) != UUID.Zero)
274 { 274 {
275 return m_ScriptEngine.GetScriptState(item) ?1:0; 275 return m_ScriptEngine.GetScriptState(item) ?1:0;
276 } 276 }
277   277  
278 Error("llGetScriptState", "Can't find script '" + name + "'"); 278 Error("llGetScriptState", "Can't find script '" + name + "'");
279   279  
280 // If we didn't find it, then it's safe to 280 // If we didn't find it, then it's safe to
281 // assume it is not running. 281 // assume it is not running.
282   282  
283 return 0; 283 return 0;
284 } 284 }
285   285  
286 public void llSetScriptState(string name, int run) 286 public void llSetScriptState(string name, int run)
287 { 287 {
288 UUID item; 288 UUID item;
289   289  
290 m_host.AddScriptLPS(1); 290 m_host.AddScriptLPS(1);
291   291  
292 // These functions are supposed to be robust, 292 // These functions are supposed to be robust,
293 // so get the state one step at a time. 293 // so get the state one step at a time.
294   294  
295 if ((item = GetScriptByName(name)) != UUID.Zero) 295 if ((item = GetScriptByName(name)) != UUID.Zero)
296 { 296 {
297 m_ScriptEngine.SetScriptState(item, run == 0 ? false : true); 297 m_ScriptEngine.SetScriptState(item, run == 0 ? false : true);
298 } 298 }
299 else 299 else
300 { 300 {
301 Error("llSetScriptState", "Can't find script '" + name + "'"); 301 Error("llSetScriptState", "Can't find script '" + name + "'");
302 } 302 }
303 } 303 }
304   304  
305 /// <summary> 305 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 306 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 307 /// </summary>
308 /// <remarks> 308 /// <remarks>
309 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then 309 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
310 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset. 310 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
311 /// The ScenePresences receive linknums in the order in which they sat. 311 /// The ScenePresences receive linknums in the order in which they sat.
312 /// </remarks> 312 /// </remarks>
313 /// <returns> 313 /// <returns>
314 /// The link entity. null if not found. 314 /// The link entity. null if not found.
315 /// </returns> 315 /// </returns>
316 /// <param name='linknum'> 316 /// <param name='linknum'>
317 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4). 317 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
318 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned. 318 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
319 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any 319 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
320 /// positive integer is given in this case then null is returned. 320 /// positive integer is given in this case then null is returned.
321 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number 321 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
322 /// of entities, then the entity which corresponds to that linknum is returned. 322 /// of entities, then the entity which corresponds to that linknum is returned.
323 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then 323 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
324 /// null is returned. 324 /// null is returned.
325 /// </param> 325 /// </param>
326 public ISceneEntity GetLinkEntity(int linknum) 326 public ISceneEntity GetLinkEntity(int linknum)
327 { 327 {
328 if (linknum < 0) 328 if (linknum < 0)
329 { 329 {
330 if (linknum == ScriptBaseClass.LINK_THIS) 330 if (linknum == ScriptBaseClass.LINK_THIS)
331 return m_host; 331 return m_host;
332 else 332 else
333 return null; 333 return null;
334 } 334 }
335   335  
336 int actualPrimCount = m_host.ParentGroup.PrimCount; 336 int actualPrimCount = m_host.ParentGroup.PrimCount;
337 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); 337 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
338 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; 338 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
339   339  
340 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single 340 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
341 // prim that has any avatars sat upon it (in which case the root prim is link 1). 341 // prim that has any avatars sat upon it (in which case the root prim is link 1).
342 if (linknum == 0) 342 if (linknum == 0)
343 { 343 {
344 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) 344 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
345 return m_host; 345 return m_host;
346   346  
347 return null; 347 return null;
348 } 348 }
349 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but 349 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
350 // here we must match 1 (ScriptBaseClass.LINK_ROOT). 350 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
351 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1) 351 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
352 { 352 {
353 if (sittingAvatarIds.Count > 0) 353 if (sittingAvatarIds.Count > 0)
354 return m_host.ParentGroup.RootPart; 354 return m_host.ParentGroup.RootPart;
355 else 355 else
356 return null; 356 return null;
357 } 357 }
358 else if (linknum <= adjustedPrimCount) 358 else if (linknum <= adjustedPrimCount)
359 { 359 {
360 if (linknum <= actualPrimCount) 360 if (linknum <= actualPrimCount)
361 { 361 {
362 return m_host.ParentGroup.GetLinkNumPart(linknum); 362 return m_host.ParentGroup.GetLinkNumPart(linknum);
363 } 363 }
364 else 364 else
365 { 365 {
366 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]); 366 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
367 if (sp != null) 367 if (sp != null)
368 return sp; 368 return sp;
369 else 369 else
370 return null; 370 return null;
371 } 371 }
372 } 372 }
373 else 373 else
374 { 374 {
375 return null; 375 return null;
376 } 376 }
377 } 377 }
378   378  
379 public List<SceneObjectPart> GetLinkParts(int linkType) 379 public List<SceneObjectPart> GetLinkParts(int linkType)
380 { 380 {
381 return GetLinkParts(m_host, linkType); 381 return GetLinkParts(m_host, linkType);
382 } 382 }
383   383  
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 385 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 386 List<SceneObjectPart> ret = new List<SceneObjectPart>();
387 ret.Add(part); 387 ret.Add(part);
388   388  
389 switch (linkType) 389 switch (linkType)
390 { 390 {
391 case ScriptBaseClass.LINK_SET: 391 case ScriptBaseClass.LINK_SET:
392 return new List<SceneObjectPart>(part.ParentGroup.Parts); 392 return new List<SceneObjectPart>(part.ParentGroup.Parts);
393   393  
394 case ScriptBaseClass.LINK_ROOT: 394 case ScriptBaseClass.LINK_ROOT:
395 ret = new List<SceneObjectPart>(); 395 ret = new List<SceneObjectPart>();
396 ret.Add(part.ParentGroup.RootPart); 396 ret.Add(part.ParentGroup.RootPart);
397 return ret; 397 return ret;
398   398  
399 case ScriptBaseClass.LINK_ALL_OTHERS: 399 case ScriptBaseClass.LINK_ALL_OTHERS:
400 ret = new List<SceneObjectPart>(part.ParentGroup.Parts); 400 ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
401   401  
402 if (ret.Contains(part)) 402 if (ret.Contains(part))
403 ret.Remove(part); 403 ret.Remove(part);
404   404  
405 return ret; 405 return ret;
406   406  
407 case ScriptBaseClass.LINK_ALL_CHILDREN: 407 case ScriptBaseClass.LINK_ALL_CHILDREN:
408 ret = new List<SceneObjectPart>(part.ParentGroup.Parts); 408 ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
409   409  
410 if (ret.Contains(part.ParentGroup.RootPart)) 410 if (ret.Contains(part.ParentGroup.RootPart))
411 ret.Remove(part.ParentGroup.RootPart); 411 ret.Remove(part.ParentGroup.RootPart);
412 return ret; 412 return ret;
413   413  
414 case ScriptBaseClass.LINK_THIS: 414 case ScriptBaseClass.LINK_THIS:
415 return ret; 415 return ret;
416   416  
417 default: 417 default:
418 if (linkType < 0) 418 if (linkType < 0)
419 return new List<SceneObjectPart>(); 419 return new List<SceneObjectPart>();
420   420  
421 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType); 421 SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType);
422 if (target == null) 422 if (target == null)
423 return new List<SceneObjectPart>(); 423 return new List<SceneObjectPart>();
424 ret = new List<SceneObjectPart>(); 424 ret = new List<SceneObjectPart>();
425 ret.Add(target); 425 ret.Add(target);
426 return ret; 426 return ret;
427 } 427 }
428 } 428 }
429   429  
430 //These are the implementations of the various ll-functions used by the LSL scripts. 430 //These are the implementations of the various ll-functions used by the LSL scripts.
431 public LSL_Float llSin(double f) 431 public LSL_Float llSin(double f)
432 { 432 {
433 m_host.AddScriptLPS(1); 433 m_host.AddScriptLPS(1);
434 return (double)Math.Sin(f); 434 return (double)Math.Sin(f);
435 } 435 }
436   436  
437 public LSL_Float llCos(double f) 437 public LSL_Float llCos(double f)
438 { 438 {
439 m_host.AddScriptLPS(1); 439 m_host.AddScriptLPS(1);
440 return (double)Math.Cos(f); 440 return (double)Math.Cos(f);
441 } 441 }
442   442  
443 public LSL_Float llTan(double f) 443 public LSL_Float llTan(double f)
444 { 444 {
445 m_host.AddScriptLPS(1); 445 m_host.AddScriptLPS(1);
446 return (double)Math.Tan(f); 446 return (double)Math.Tan(f);
447 } 447 }
448   448  
449 public LSL_Float llAtan2(double x, double y) 449 public LSL_Float llAtan2(double x, double y)
450 { 450 {
451 m_host.AddScriptLPS(1); 451 m_host.AddScriptLPS(1);
452 return (double)Math.Atan2(x, y); 452 return (double)Math.Atan2(x, y);
453 } 453 }
454   454  
455 public LSL_Float llSqrt(double f) 455 public LSL_Float llSqrt(double f)
456 { 456 {
457 m_host.AddScriptLPS(1); 457 m_host.AddScriptLPS(1);
458 return (double)Math.Sqrt(f); 458 return (double)Math.Sqrt(f);
459 } 459 }
460   460  
461 public LSL_Float llPow(double fbase, double fexponent) 461 public LSL_Float llPow(double fbase, double fexponent)
462 { 462 {
463 m_host.AddScriptLPS(1); 463 m_host.AddScriptLPS(1);
464 return (double)Math.Pow(fbase, fexponent); 464 return (double)Math.Pow(fbase, fexponent);
465 } 465 }
466   466  
467 public LSL_Integer llAbs(int i) 467 public LSL_Integer llAbs(int i)
468 { 468 {
469 // changed to replicate LSL behaviour whereby minimum int value is returned untouched. 469 // changed to replicate LSL behaviour whereby minimum int value is returned untouched.
470 m_host.AddScriptLPS(1); 470 m_host.AddScriptLPS(1);
471 if (i == Int32.MinValue) 471 if (i == Int32.MinValue)
472 return i; 472 return i;
473 else 473 else
474 return (int)Math.Abs(i); 474 return (int)Math.Abs(i);
475 } 475 }
476   476  
477 public LSL_Float llFabs(double f) 477 public LSL_Float llFabs(double f)
478 { 478 {
479 m_host.AddScriptLPS(1); 479 m_host.AddScriptLPS(1);
480 return (double)Math.Abs(f); 480 return (double)Math.Abs(f);
481 } 481 }
482   482  
483 public LSL_Float llFrand(double mag) 483 public LSL_Float llFrand(double mag)
484 { 484 {
485 m_host.AddScriptLPS(1); 485 m_host.AddScriptLPS(1);
486 lock (Util.RandomClass) 486 lock (Util.RandomClass)
487 { 487 {
488 return Util.RandomClass.NextDouble() * mag; 488 return Util.RandomClass.NextDouble() * mag;
489 } 489 }
490 } 490 }
491   491  
492 public LSL_Integer llFloor(double f) 492 public LSL_Integer llFloor(double f)
493 { 493 {
494 m_host.AddScriptLPS(1); 494 m_host.AddScriptLPS(1);
495 return (int)Math.Floor(f); 495 return (int)Math.Floor(f);
496 } 496 }
497   497  
498 public LSL_Integer llCeil(double f) 498 public LSL_Integer llCeil(double f)
499 { 499 {
500 m_host.AddScriptLPS(1); 500 m_host.AddScriptLPS(1);
501 return (int)Math.Ceiling(f); 501 return (int)Math.Ceiling(f);
502 } 502 }
503   503  
504 // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven) 504 // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven)
505 public LSL_Integer llRound(double f) 505 public LSL_Integer llRound(double f)
506 { 506 {
507 m_host.AddScriptLPS(1); 507 m_host.AddScriptLPS(1);
508 return (int)Math.Round(f, MidpointRounding.AwayFromZero); 508 return (int)Math.Round(f, MidpointRounding.AwayFromZero);
509 } 509 }
510   510  
511 //This next group are vector operations involving squaring and square root. ckrinke 511 //This next group are vector operations involving squaring and square root. ckrinke
512 public LSL_Float llVecMag(LSL_Vector v) 512 public LSL_Float llVecMag(LSL_Vector v)
513 { 513 {
514 m_host.AddScriptLPS(1); 514 m_host.AddScriptLPS(1);
515 return LSL_Vector.Mag(v); 515 return LSL_Vector.Mag(v);
516 } 516 }
517   517  
518 public LSL_Vector llVecNorm(LSL_Vector v) 518 public LSL_Vector llVecNorm(LSL_Vector v)
519 { 519 {
520 m_host.AddScriptLPS(1); 520 m_host.AddScriptLPS(1);
521 return LSL_Vector.Norm(v); 521 return LSL_Vector.Norm(v);
522 } 522 }
523   523  
524 private double VecDist(LSL_Vector a, LSL_Vector b) 524 private double VecDist(LSL_Vector a, LSL_Vector b)
525 { 525 {
526 double dx = a.x - b.x; 526 double dx = a.x - b.x;
527 double dy = a.y - b.y; 527 double dy = a.y - b.y;
528 double dz = a.z - b.z; 528 double dz = a.z - b.z;
529 return Math.Sqrt(dx * dx + dy * dy + dz * dz); 529 return Math.Sqrt(dx * dx + dy * dy + dz * dz);
530 } 530 }
531   531  
532 public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b) 532 public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
533 { 533 {
534 m_host.AddScriptLPS(1); 534 m_host.AddScriptLPS(1);
535 return VecDist(a, b); 535 return VecDist(a, b);
536 } 536 }
537   537  
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539   539  
540 /// <summary> 540 /// <summary>
541 /// Convert an LSL rotation to a Euler vector. 541 /// Convert an LSL rotation to a Euler vector.
542 /// </summary> 542 /// </summary>
543 /// <remarks> 543 /// <remarks>
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf 544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2 545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks> 546 /// </remarks>
547 /// <param name="r"></param> 547 /// <param name="r"></param>
548 /// <returns></returns> 548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r) 549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 550 {
551 m_host.AddScriptLPS(1); 551 m_host.AddScriptLPS(1);
552   552  
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r.
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later.
555 if (m == 0.0) return new LSL_Vector(); 555 if (m == 0.0) return new LSL_Vector();
556 double x = Math.Atan2(-v.y, v.z); 556 double x = Math.Atan2(-v.y, v.z);
557 double sin = v.x / m; 557 double sin = v.x / m;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
559 double y = Math.Asin(sin); 559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0))); 561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x); 562 double z = Math.Atan2(v.y, v.x);
563   563  
564 return new LSL_Vector(x, y, z); 564 return new LSL_Vector(x, y, z);
565 } 565 }
566   566  
567 /* From wiki: 567 /* From wiki:
568 The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes 568 The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes
569 in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation, 569 in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation,
570 a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting 570 a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting
571 vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis. 571 vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis.
572 */ 572 */
573   573  
574 /* How we arrived at this llEuler2Rot 574 /* How we arrived at this llEuler2Rot
575 * 575 *
576 * Experiment in SL to determine conventions: 576 * Experiment in SL to determine conventions:
577 * llEuler2Rot(<PI,0,0>)=<1,0,0,0> 577 * llEuler2Rot(<PI,0,0>)=<1,0,0,0>
578 * llEuler2Rot(<0,PI,0>)=<0,1,0,0> 578 * llEuler2Rot(<0,PI,0>)=<0,1,0,0>
579 * llEuler2Rot(<0,0,PI>)=<0,0,1,0> 579 * llEuler2Rot(<0,0,PI>)=<0,0,1,0>
580 * 580 *
581 * Important facts about Quaternions 581 * Important facts about Quaternions
582 * - multiplication is non-commutative (a*b != b*a) 582 * - multiplication is non-commutative (a*b != b*a)
583 * - http://en.wikipedia.org/wiki/Quaternion#Basis_multiplication 583 * - http://en.wikipedia.org/wiki/Quaternion#Basis_multiplication
584 * 584 *
585 * Above SL experiment gives (c1,c2,c3,s1,s2,s3 as defined in our llEuler2Rot): 585 * Above SL experiment gives (c1,c2,c3,s1,s2,s3 as defined in our llEuler2Rot):
586 * Qx = c1+i*s1 586 * Qx = c1+i*s1
587 * Qy = c2+j*s2; 587 * Qy = c2+j*s2;
588 * Qz = c3+k*s3; 588 * Qz = c3+k*s3;
589 * 589 *
590 * Rotations applied in order (from above) Z, Y, X 590 * Rotations applied in order (from above) Z, Y, X
591 * Q = (Qz * Qy) * Qx 591 * Q = (Qz * Qy) * Qx
592 * ((c1+i*s1)*(c2+j*s2))*(c3+k*s3) 592 * ((c1+i*s1)*(c2+j*s2))*(c3+k*s3)
593 * (c1*c2+i*s1*c2+j*c1*s2+ij*s1*s2)*(c3+k*s3) 593 * (c1*c2+i*s1*c2+j*c1*s2+ij*s1*s2)*(c3+k*s3)
594 * (c1*c2+i*s1*c2+j*c1*s2+k*s1*s2)*(c3+k*s3) 594 * (c1*c2+i*s1*c2+j*c1*s2+k*s1*s2)*(c3+k*s3)
595 * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3+ik*s1*c2*s3+jk*c1*s2*s3+kk*s1*s2*s3 595 * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3+ik*s1*c2*s3+jk*c1*s2*s3+kk*s1*s2*s3
596 * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3 -j*s1*c2*s3 +i*c1*s2*s3 -s1*s2*s3 596 * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3 -j*s1*c2*s3 +i*c1*s2*s3 -s1*s2*s3
597 * regroup: x=i*(s1*c2*c3+c1*s2*s3) 597 * regroup: x=i*(s1*c2*c3+c1*s2*s3)
598 * y=j*(c1*s2*c3-s1*c2*s3) 598 * y=j*(c1*s2*c3-s1*c2*s3)
599 * z=k*(s1*s2*c3+c1*c2*s3) 599 * z=k*(s1*s2*c3+c1*c2*s3)
600 * s= c1*c2*c3-s1*s2*s3 600 * s= c1*c2*c3-s1*s2*s3
601 * 601 *
602 * This implementation agrees with the functions found here: 602 * This implementation agrees with the functions found here:
603 * http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions 603 * http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions
604 * And with the results in SL. 604 * And with the results in SL.
605 * 605 *
606 * It's also possible to calculate llEuler2Rot by direct multiplication of 606 * It's also possible to calculate llEuler2Rot by direct multiplication of
607 * the Qz, Qy, and Qx vectors (as above - and done in the "accurate" function 607 * the Qz, Qy, and Qx vectors (as above - and done in the "accurate" function
608 * from the wiki). 608 * from the wiki).
609 * Apparently in some cases this is better from a numerical precision perspective? 609 * Apparently in some cases this is better from a numerical precision perspective?
610 */ 610 */
611   611  
612 public LSL_Rotation llEuler2Rot(LSL_Vector v) 612 public LSL_Rotation llEuler2Rot(LSL_Vector v)
613 { 613 {
614 m_host.AddScriptLPS(1); 614 m_host.AddScriptLPS(1);
615   615  
616 double x,y,z,s; 616 double x,y,z,s;
617   617  
618 double c1 = Math.Cos(v.x * 0.5); 618 double c1 = Math.Cos(v.x * 0.5);
619 double c2 = Math.Cos(v.y * 0.5); 619 double c2 = Math.Cos(v.y * 0.5);
620 double c3 = Math.Cos(v.z * 0.5); 620 double c3 = Math.Cos(v.z * 0.5);
621 double s1 = Math.Sin(v.x * 0.5); 621 double s1 = Math.Sin(v.x * 0.5);
622 double s2 = Math.Sin(v.y * 0.5); 622 double s2 = Math.Sin(v.y * 0.5);
623 double s3 = Math.Sin(v.z * 0.5); 623 double s3 = Math.Sin(v.z * 0.5);
624   624  
625 x = s1 * c2 * c3 + c1 * s2 * s3; 625 x = s1 * c2 * c3 + c1 * s2 * s3;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 626 y = c1 * s2 * c3 - s1 * c2 * s3;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 627 z = s1 * s2 * c3 + c1 * c2 * s3;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 628 s = c1 * c2 * c3 - s1 * s2 * s3;
629   629  
630 return new LSL_Rotation(x, y, z, s); 630 return new LSL_Rotation(x, y, z, s);
631 } 631 }
632   632  
633 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) 633 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
634 { 634 {
635 m_host.AddScriptLPS(1); 635 m_host.AddScriptLPS(1);
636 double s; 636 double s;
637 double tr = fwd.x + left.y + up.z + 1.0; 637 double tr = fwd.x + left.y + up.z + 1.0;
638   638  
639 if (tr >= 1.0) 639 if (tr >= 1.0)
640 { 640 {
641 s = 0.5 / Math.Sqrt(tr); 641 s = 0.5 / Math.Sqrt(tr);
642 return new LSL_Rotation( 642 return new LSL_Rotation(
643 (left.z - up.y) * s, 643 (left.z - up.y) * s,
644 (up.x - fwd.z) * s, 644 (up.x - fwd.z) * s,
645 (fwd.y - left.x) * s, 645 (fwd.y - left.x) * s,
646 0.25 / s); 646 0.25 / s);
647 } 647 }
648 else 648 else
649 { 649 {
650 double max = (left.y > up.z) ? left.y : up.z; 650 double max = (left.y > up.z) ? left.y : up.z;
651   651  
652 if (max < fwd.x) 652 if (max < fwd.x)
653 { 653 {
654 s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0); 654 s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0);
655 double x = s * 0.5; 655 double x = s * 0.5;
656 s = 0.5 / s; 656 s = 0.5 / s;
657 return new LSL_Rotation( 657 return new LSL_Rotation(
658 x, 658 x,
659 (fwd.y + left.x) * s, 659 (fwd.y + left.x) * s,
660 (up.x + fwd.z) * s, 660 (up.x + fwd.z) * s,
661 (left.z - up.y) * s); 661 (left.z - up.y) * s);
662 } 662 }
663 else if (max == left.y) 663 else if (max == left.y)
664 { 664 {
665 s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0); 665 s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0);
666 double y = s * 0.5; 666 double y = s * 0.5;
667 s = 0.5 / s; 667 s = 0.5 / s;
668 return new LSL_Rotation( 668 return new LSL_Rotation(
669 (fwd.y + left.x) * s, 669 (fwd.y + left.x) * s,
670 y, 670 y,
671 (left.z + up.y) * s, 671 (left.z + up.y) * s,
672 (up.x - fwd.z) * s); 672 (up.x - fwd.z) * s);
673 } 673 }
674 else 674 else
675 { 675 {
676 s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0); 676 s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0);
677 double z = s * 0.5; 677 double z = s * 0.5;
678 s = 0.5 / s; 678 s = 0.5 / s;
679 return new LSL_Rotation( 679 return new LSL_Rotation(
680 (up.x + fwd.z) * s, 680 (up.x + fwd.z) * s,
681 (left.z + up.y) * s, 681 (left.z + up.y) * s,
682 z, 682 z,
683 (fwd.y - left.x) * s); 683 (fwd.y - left.x) * s);
684 } 684 }
685 } 685 }
686 } 686 }
687   687  
688 public LSL_Vector llRot2Fwd(LSL_Rotation r) 688 public LSL_Vector llRot2Fwd(LSL_Rotation r)
689 { 689 {
690 m_host.AddScriptLPS(1); 690 m_host.AddScriptLPS(1);
691   691  
692 double x, y, z, m; 692 double x, y, z, m;
693   693  
694 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; 694 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
695 // m is always greater than zero 695 // m is always greater than zero
696 // if m is not equal to 1 then Rotation needs to be normalized 696 // if m is not equal to 1 then Rotation needs to be normalized
697 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision 697 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
698 { 698 {
699 m = 1.0 / Math.Sqrt(m); 699 m = 1.0 / Math.Sqrt(m);
700 r.x *= m; 700 r.x *= m;
701 r.y *= m; 701 r.y *= m;
702 r.z *= m; 702 r.z *= m;
703 r.s *= m; 703 r.s *= m;
704 } 704 }
705   705  
706 // Fast Algebric Calculations instead of Vectors & Quaternions Product 706 // Fast Algebric Calculations instead of Vectors & Quaternions Product
707 x = r.x * r.x - r.y * r.y - r.z * r.z + r.s * r.s; 707 x = r.x * r.x - r.y * r.y - r.z * r.z + r.s * r.s;
708 y = 2 * (r.x * r.y + r.z * r.s); 708 y = 2 * (r.x * r.y + r.z * r.s);
709 z = 2 * (r.x * r.z - r.y * r.s); 709 z = 2 * (r.x * r.z - r.y * r.s);
710 return (new LSL_Vector(x, y, z)); 710 return (new LSL_Vector(x, y, z));
711 } 711 }
712   712  
713 public LSL_Vector llRot2Left(LSL_Rotation r) 713 public LSL_Vector llRot2Left(LSL_Rotation r)
714 { 714 {
715 m_host.AddScriptLPS(1); 715 m_host.AddScriptLPS(1);
716   716  
717 double x, y, z, m; 717 double x, y, z, m;
718   718  
719 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; 719 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
720 // m is always greater than zero 720 // m is always greater than zero
721 // if m is not equal to 1 then Rotation needs to be normalized 721 // if m is not equal to 1 then Rotation needs to be normalized
722 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision 722 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
723 { 723 {
724 m = 1.0 / Math.Sqrt(m); 724 m = 1.0 / Math.Sqrt(m);
725 r.x *= m; 725 r.x *= m;
726 r.y *= m; 726 r.y *= m;
727 r.z *= m; 727 r.z *= m;
728 r.s *= m; 728 r.s *= m;
729 } 729 }
730   730  
731 // Fast Algebric Calculations instead of Vectors & Quaternions Product 731 // Fast Algebric Calculations instead of Vectors & Quaternions Product
732 x = 2 * (r.x * r.y - r.z * r.s); 732 x = 2 * (r.x * r.y - r.z * r.s);
733 y = -r.x * r.x + r.y * r.y - r.z * r.z + r.s * r.s; 733 y = -r.x * r.x + r.y * r.y - r.z * r.z + r.s * r.s;
734 z = 2 * (r.x * r.s + r.y * r.z); 734 z = 2 * (r.x * r.s + r.y * r.z);
735 return (new LSL_Vector(x, y, z)); 735 return (new LSL_Vector(x, y, z));
736 } 736 }
737   737  
738 public LSL_Vector llRot2Up(LSL_Rotation r) 738 public LSL_Vector llRot2Up(LSL_Rotation r)
739 { 739 {
740 m_host.AddScriptLPS(1); 740 m_host.AddScriptLPS(1);
741 double x, y, z, m; 741 double x, y, z, m;
742   742  
743 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s; 743 m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
744 // m is always greater than zero 744 // m is always greater than zero
745 // if m is not equal to 1 then Rotation needs to be normalized 745 // if m is not equal to 1 then Rotation needs to be normalized
746 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision 746 if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
747 { 747 {
748 m = 1.0 / Math.Sqrt(m); 748 m = 1.0 / Math.Sqrt(m);
749 r.x *= m; 749 r.x *= m;
750 r.y *= m; 750 r.y *= m;
751 r.z *= m; 751 r.z *= m;
752 r.s *= m; 752 r.s *= m;
753 } 753 }
754   754  
755 // Fast Algebric Calculations instead of Vectors & Quaternions Product 755 // Fast Algebric Calculations instead of Vectors & Quaternions Product
756 x = 2 * (r.x * r.z + r.y * r.s); 756 x = 2 * (r.x * r.z + r.y * r.s);
757 y = 2 * (-r.x * r.s + r.y * r.z); 757 y = 2 * (-r.x * r.s + r.y * r.z);
758 z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s; 758 z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;
759 return (new LSL_Vector(x, y, z)); 759 return (new LSL_Vector(x, y, z));
760 } 760 }
761   761  
762 public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b) 762 public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
763 { 763 {
764 //A and B should both be normalized 764 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 765 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 766 LSL_Rotation rotBetween;
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise,
768 // continue calculation. 768 // continue calculation.
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f))
770 { 770 {
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
772 } 772 }
773 else 773 else
774 { 774 {
775 a = LSL_Vector.Norm(a); 775 a = LSL_Vector.Norm(a);
776 b = LSL_Vector.Norm(b); 776 b = LSL_Vector.Norm(b);
777 double dotProduct = LSL_Vector.Dot(a, b); 777 double dotProduct = LSL_Vector.Dot(a, b);
778 // There are two degenerate cases possible. These are for vectors 180 or 778 // There are two degenerate cases possible. These are for vectors 180 or
779 // 0 degrees apart. These have to be detected and handled individually. 779 // 0 degrees apart. These have to be detected and handled individually.
780 // 780 //
781 // Check for vectors 180 degrees apart. 781 // Check for vectors 180 degrees apart.
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 782 // A dot product of -1 would mean the angle between vectors is 180 degrees.
783 if (dotProduct < -0.9999999f) 783 if (dotProduct < -0.9999999f)
784 { 784 {
785 // First assume X axis is orthogonal to the vectors. 785 // First assume X axis is orthogonal to the vectors.
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f);
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a));
788 // Check for near zero vector. A very small non-zero number here will create 788 // Check for near zero vector. A very small non-zero number here will create
789 // a rotation in an undesired direction. 789 // a rotation in an undesired direction.
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 790 if (LSL_Vector.Mag(orthoVector) > 0.0001)
791 { 791 {
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f);
793 } 793 }
794 // If the magnitude of the vector was near zero, then assume the X axis is not 794 // If the magnitude of the vector was near zero, then assume the X axis is not
795 // orthogonal and use the Z axis instead. 795 // orthogonal and use the Z axis instead.
796 else 796 else
797 { 797 {
798 // Set 180 z rotation. 798 // Set 180 z rotation.
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
800 } 800 }
801 } 801 }
802 // Check for parallel vectors. 802 // Check for parallel vectors.
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 803 // A dot product of 1 would mean the angle between vectors is 0 degrees.
804 else if (dotProduct > 0.9999999f) 804 else if (dotProduct > 0.9999999f)
805 { 805 {
806 // Set zero rotation. 806 // Set zero rotation.
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
808 } 808 }
809 else 809 else
810 { 810 {
811 // All special checks have been performed so get the axis of rotation. 811 // All special checks have been performed so get the axis of rotation.
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
813 // Quarternion s value is the length of the unit vector + dot product. 813 // Quarternion s value is the length of the unit vector + dot product.
814 double qs = 1.0 + dotProduct; 814 double qs = 1.0 + dotProduct;
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
816 // Normalize the rotation. 816 // Normalize the rotation.
817 double mag = LSL_Rotation.Mag(rotBetween); 817 double mag = LSL_Rotation.Mag(rotBetween);
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 818 // We shouldn't have to worry about a divide by zero here. The qs value will be
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 819 // non-zero because we already know if we're here, then the dotProduct is not -1 so
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 820 // qs will not be zero. Also, we've already handled the input vectors being zero so the
821 // crossProduct vector should also not be zero. 821 // crossProduct vector should also not be zero.
822 rotBetween.x = rotBetween.x / mag; 822 rotBetween.x = rotBetween.x / mag;
823 rotBetween.y = rotBetween.y / mag; 823 rotBetween.y = rotBetween.y / mag;
824 rotBetween.z = rotBetween.z / mag; 824 rotBetween.z = rotBetween.z / mag;
825 rotBetween.s = rotBetween.s / mag; 825 rotBetween.s = rotBetween.s / mag;
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 826 // Check for undefined values and set zero rotation if any found. This code might not actually be required
827 // any longer since zero vectors are checked for at the top. 827 // any longer since zero vectors are checked for at the top.
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
829 { 829 {
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
831 } 831 }
832 } 832 }
833 } 833 }
834 return rotBetween; 834 return rotBetween;
835 } 835 }
836   836  
837 public void llWhisper(int channelID, string text) 837 public void llWhisper(int channelID, string text)
838 { 838 {
839 m_host.AddScriptLPS(1); 839 m_host.AddScriptLPS(1);
840   840  
841 if (text.Length > 1023) 841 if (text.Length > 1023)
842 text = text.Substring(0, 1023); 842 text = text.Substring(0, 1023);
843   843  
844 World.SimChat(Utils.StringToBytes(text), 844 World.SimChat(Utils.StringToBytes(text),
845 ChatTypeEnum.Whisper, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); 845 ChatTypeEnum.Whisper, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
846   846  
847 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 847 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
848 if (wComm != null) 848 if (wComm != null)
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 850 }
851   851  
852 public void llSay(int channelID, string text) 852 public void llSay(int channelID, string text)
853 { 853 {
854 m_host.AddScriptLPS(1); 854 m_host.AddScriptLPS(1);
855   855  
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 857 {
858 Console.WriteLine(text); 858 Console.WriteLine(text);
859 } 859 }
860 else 860 else
861 { 861 {
862 if (text.Length > 1023) 862 if (text.Length > 1023)
863 text = text.Substring(0, 1023); 863 text = text.Substring(0, 1023);
864   864  
865 World.SimChat(Utils.StringToBytes(text), 865 World.SimChat(Utils.StringToBytes(text),
866 ChatTypeEnum.Say, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); 866 ChatTypeEnum.Say, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
867   867  
868 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 868 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
869 if (wComm != null) 869 if (wComm != null)
870 wComm.DeliverMessage(ChatTypeEnum.Say, channelID, m_host.Name, m_host.UUID, text); 870 wComm.DeliverMessage(ChatTypeEnum.Say, channelID, m_host.Name, m_host.UUID, text);
871 } 871 }
872 } 872 }
873   873  
874 public void llShout(int channelID, string text) 874 public void llShout(int channelID, string text)
875 { 875 {
876 m_host.AddScriptLPS(1); 876 m_host.AddScriptLPS(1);
877   877  
878 if (text.Length > 1023) 878 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 879 text = text.Substring(0, 1023);
880   880  
881 World.SimChat(Utils.StringToBytes(text), 881 World.SimChat(Utils.StringToBytes(text),
882 ChatTypeEnum.Shout, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); 882 ChatTypeEnum.Shout, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
883   883  
884 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 884 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
885 if (wComm != null) 885 if (wComm != null)
886 wComm.DeliverMessage(ChatTypeEnum.Shout, channelID, m_host.Name, m_host.UUID, text); 886 wComm.DeliverMessage(ChatTypeEnum.Shout, channelID, m_host.Name, m_host.UUID, text);
887 } 887 }
888   888  
889 public void llRegionSay(int channelID, string text) 889 public void llRegionSay(int channelID, string text)
890 { 890 {
891 if (channelID == 0) 891 if (channelID == 0)
892 { 892 {
893 Error("llRegionSay", "Cannot use on channel 0"); 893 Error("llRegionSay", "Cannot use on channel 0");
894 return; 894 return;
895 } 895 }
896   896  
897 if (text.Length > 1023) 897 if (text.Length > 1023)
898 text = text.Substring(0, 1023); 898 text = text.Substring(0, 1023);
899   899  
900 m_host.AddScriptLPS(1); 900 m_host.AddScriptLPS(1);
901   901  
902 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 902 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
903 if (wComm != null) 903 if (wComm != null)
904 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); 904 wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
905 } 905 }
906   906  
907 public void llRegionSayTo(string target, int channel, string msg) 907 public void llRegionSayTo(string target, int channel, string msg)
908 { 908 {
909 if (msg.Length > 1023) 909 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 910 msg = msg.Substring(0, 1023);
911   911  
912 m_host.AddScriptLPS(1); 912 m_host.AddScriptLPS(1);
913   913  
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL) 914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 { 915 {
916 return; 916 return;
917 } 917 }
918   918  
919 UUID TargetID; 919 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 920 UUID.TryParse(target, out TargetID);
921   921  
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 923 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg);
925 } 925 }
926   926  
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 927 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
928 { 928 {
929 m_host.AddScriptLPS(1); 929 m_host.AddScriptLPS(1);
930 UUID keyID; 930 UUID keyID;
931 UUID.TryParse(ID, out keyID); 931 UUID.TryParse(ID, out keyID);
932 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 932 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
933 if (wComm != null) 933 if (wComm != null)
934 return wComm.Listen(m_host.LocalId, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg); 934 return wComm.Listen(m_host.LocalId, m_item.ItemID, m_host.UUID, channelID, name, keyID, msg);
935 else 935 else
936 return -1; 936 return -1;
937 } 937 }
938   938  
939 public void llListenControl(int number, int active) 939 public void llListenControl(int number, int active)
940 { 940 {
941 m_host.AddScriptLPS(1); 941 m_host.AddScriptLPS(1);
942 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 942 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
943 if (wComm != null) 943 if (wComm != null)
944 wComm.ListenControl(m_item.ItemID, number, active); 944 wComm.ListenControl(m_item.ItemID, number, active);
945 } 945 }
946   946  
947 public void llListenRemove(int number) 947 public void llListenRemove(int number)
948 { 948 {
949 m_host.AddScriptLPS(1); 949 m_host.AddScriptLPS(1);
950 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 950 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
951 if (wComm != null) 951 if (wComm != null)
952 wComm.ListenRemove(m_item.ItemID, number); 952 wComm.ListenRemove(m_item.ItemID, number);
953 } 953 }
954   954  
955 public void llSensor(string name, string id, int type, double range, double arc) 955 public void llSensor(string name, string id, int type, double range, double arc)
956 { 956 {
957 m_host.AddScriptLPS(1); 957 m_host.AddScriptLPS(1);
958 UUID keyID = UUID.Zero; 958 UUID keyID = UUID.Zero;
959 UUID.TryParse(id, out keyID); 959 UUID.TryParse(id, out keyID);
960   960  
961 AsyncCommands.SensorRepeatPlugin.SenseOnce(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, m_host); 961 AsyncCommands.SensorRepeatPlugin.SenseOnce(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, m_host);
962 } 962 }
963   963  
964 public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) 964 public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate)
965 { 965 {
966 m_host.AddScriptLPS(1); 966 m_host.AddScriptLPS(1);
967 UUID keyID = UUID.Zero; 967 UUID keyID = UUID.Zero;
968 UUID.TryParse(id, out keyID); 968 UUID.TryParse(id, out keyID);
969   969  
970 AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, rate, m_host); 970 AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_host.LocalId, m_item.ItemID, name, keyID, type, range, arc, rate, m_host);
971 } 971 }
972   972  
973 public void llSensorRemove() 973 public void llSensorRemove()
974 { 974 {
975 m_host.AddScriptLPS(1); 975 m_host.AddScriptLPS(1);
976 AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID); 976 AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_host.LocalId, m_item.ItemID);
977 } 977 }
978   978  
979 public string resolveName(UUID objecUUID) 979 public string resolveName(UUID objecUUID)
980 { 980 {
981 // try avatar username surname 981 // try avatar username surname
982 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, objecUUID); 982 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, objecUUID);
983 if (account != null) 983 if (account != null)
984 { 984 {
985 string avatarname = account.Name; 985 string avatarname = account.Name;
986 return avatarname; 986 return avatarname;
987 } 987 }
988 // try an scene object 988 // try an scene object
989 SceneObjectPart SOP = World.GetSceneObjectPart(objecUUID); 989 SceneObjectPart SOP = World.GetSceneObjectPart(objecUUID);
990 if (SOP != null) 990 if (SOP != null)
991 { 991 {
992 string objectname = SOP.Name; 992 string objectname = SOP.Name;
993 return objectname; 993 return objectname;
994 } 994 }
995   995  
996 EntityBase SensedObject; 996 EntityBase SensedObject;
997 World.Entities.TryGetValue(objecUUID, out SensedObject); 997 World.Entities.TryGetValue(objecUUID, out SensedObject);
998   998  
999 if (SensedObject == null) 999 if (SensedObject == null)
1000 { 1000 {
1001 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>(); 1001 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
1002 if (groups != null) 1002 if (groups != null)
1003 { 1003 {
1004 GroupRecord gr = groups.GetGroupRecord(objecUUID); 1004 GroupRecord gr = groups.GetGroupRecord(objecUUID);
1005 if (gr != null) 1005 if (gr != null)
1006 return gr.GroupName; 1006 return gr.GroupName;
1007 } 1007 }
1008 return String.Empty; 1008 return String.Empty;
1009 } 1009 }
1010   1010  
1011 return SensedObject.Name; 1011 return SensedObject.Name;
1012 } 1012 }
1013   1013  
1014 public LSL_String llDetectedName(int number) 1014 public LSL_String llDetectedName(int number)
1015 { 1015 {
1016 m_host.AddScriptLPS(1); 1016 m_host.AddScriptLPS(1);
1017 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1017 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1018 if (detectedParams == null) 1018 if (detectedParams == null)
1019 return String.Empty; 1019 return String.Empty;
1020 return detectedParams.Name; 1020 return detectedParams.Name;
1021 } 1021 }
1022   1022  
1023 public LSL_String llDetectedKey(int number) 1023 public LSL_String llDetectedKey(int number)
1024 { 1024 {
1025 m_host.AddScriptLPS(1); 1025 m_host.AddScriptLPS(1);
1026 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1026 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1027 if (detectedParams == null) 1027 if (detectedParams == null)
1028 return String.Empty; 1028 return String.Empty;
1029 return detectedParams.Key.ToString(); 1029 return detectedParams.Key.ToString();
1030 } 1030 }
1031   1031  
1032 public LSL_String llDetectedOwner(int number) 1032 public LSL_String llDetectedOwner(int number)
1033 { 1033 {
1034 m_host.AddScriptLPS(1); 1034 m_host.AddScriptLPS(1);
1035 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1035 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1036 if (detectedParams == null) 1036 if (detectedParams == null)
1037 return String.Empty; 1037 return String.Empty;
1038 return detectedParams.Owner.ToString(); 1038 return detectedParams.Owner.ToString();
1039 } 1039 }
1040   1040  
1041 public LSL_Integer llDetectedType(int number) 1041 public LSL_Integer llDetectedType(int number)
1042 { 1042 {
1043 m_host.AddScriptLPS(1); 1043 m_host.AddScriptLPS(1);
1044 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1044 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1045 if (detectedParams == null) 1045 if (detectedParams == null)
1046 return 0; 1046 return 0;
1047 return new LSL_Integer(detectedParams.Type); 1047 return new LSL_Integer(detectedParams.Type);
1048 } 1048 }
1049   1049  
1050 public LSL_Vector llDetectedPos(int number) 1050 public LSL_Vector llDetectedPos(int number)
1051 { 1051 {
1052 m_host.AddScriptLPS(1); 1052 m_host.AddScriptLPS(1);
1053 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1053 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1054 if (detectedParams == null) 1054 if (detectedParams == null)
1055 return new LSL_Vector(); 1055 return new LSL_Vector();
1056 return detectedParams.Position; 1056 return detectedParams.Position;
1057 } 1057 }
1058   1058  
1059 public LSL_Vector llDetectedVel(int number) 1059 public LSL_Vector llDetectedVel(int number)
1060 { 1060 {
1061 m_host.AddScriptLPS(1); 1061 m_host.AddScriptLPS(1);
1062 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1062 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1063 if (detectedParams == null) 1063 if (detectedParams == null)
1064 return new LSL_Vector(); 1064 return new LSL_Vector();
1065 return detectedParams.Velocity; 1065 return detectedParams.Velocity;
1066 } 1066 }
1067   1067  
1068 public LSL_Vector llDetectedGrab(int number) 1068 public LSL_Vector llDetectedGrab(int number)
1069 { 1069 {
1070 m_host.AddScriptLPS(1); 1070 m_host.AddScriptLPS(1);
1071 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1071 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1072 if (parms == null) 1072 if (parms == null)
1073 return new LSL_Vector(0, 0, 0); 1073 return new LSL_Vector(0, 0, 0);
1074   1074  
1075 return parms.OffsetPos; 1075 return parms.OffsetPos;
1076 } 1076 }
1077   1077  
1078 public LSL_Rotation llDetectedRot(int number) 1078 public LSL_Rotation llDetectedRot(int number)
1079 { 1079 {
1080 m_host.AddScriptLPS(1); 1080 m_host.AddScriptLPS(1);
1081 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1081 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1082 if (detectedParams == null) 1082 if (detectedParams == null)
1083 return new LSL_Rotation(); 1083 return new LSL_Rotation();
1084 return detectedParams.Rotation; 1084 return detectedParams.Rotation;
1085 } 1085 }
1086   1086  
1087 public LSL_Integer llDetectedGroup(int number) 1087 public LSL_Integer llDetectedGroup(int number)
1088 { 1088 {
1089 m_host.AddScriptLPS(1); 1089 m_host.AddScriptLPS(1);
1090 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1090 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1091 if (detectedParams == null) 1091 if (detectedParams == null)
1092 return new LSL_Integer(0); 1092 return new LSL_Integer(0);
1093 if (m_host.GroupID == detectedParams.Group) 1093 if (m_host.GroupID == detectedParams.Group)
1094 return new LSL_Integer(1); 1094 return new LSL_Integer(1);
1095 return new LSL_Integer(0); 1095 return new LSL_Integer(0);
1096 } 1096 }
1097   1097  
1098 public LSL_Integer llDetectedLinkNumber(int number) 1098 public LSL_Integer llDetectedLinkNumber(int number)
1099 { 1099 {
1100 m_host.AddScriptLPS(1); 1100 m_host.AddScriptLPS(1);
1101 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); 1101 DetectParams parms = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
1102 if (parms == null) 1102 if (parms == null)
1103 return new LSL_Integer(0); 1103 return new LSL_Integer(0);
1104   1104  
1105 return new LSL_Integer(parms.LinkNum); 1105 return new LSL_Integer(parms.LinkNum);
1106 } 1106 }
1107   1107  
1108 /// <summary> 1108 /// <summary>
1109 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchBinormal for details 1109 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchBinormal for details
1110 /// </summary> 1110 /// </summary>
1111 public LSL_Vector llDetectedTouchBinormal(int index) 1111 public LSL_Vector llDetectedTouchBinormal(int index)
1112 { 1112 {
1113 m_host.AddScriptLPS(1); 1113 m_host.AddScriptLPS(1);
1114 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1114 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1115 if (detectedParams == null) 1115 if (detectedParams == null)
1116 return new LSL_Vector(); 1116 return new LSL_Vector();
1117 return detectedParams.TouchBinormal; 1117 return detectedParams.TouchBinormal;
1118 } 1118 }
1119   1119  
1120 /// <summary> 1120 /// <summary>
1121 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchFace for details 1121 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchFace for details
1122 /// </summary> 1122 /// </summary>
1123 public LSL_Integer llDetectedTouchFace(int index) 1123 public LSL_Integer llDetectedTouchFace(int index)
1124 { 1124 {
1125 m_host.AddScriptLPS(1); 1125 m_host.AddScriptLPS(1);
1126 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1126 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1127 if (detectedParams == null) 1127 if (detectedParams == null)
1128 return new LSL_Integer(-1); 1128 return new LSL_Integer(-1);
1129 return new LSL_Integer(detectedParams.TouchFace); 1129 return new LSL_Integer(detectedParams.TouchFace);
1130 } 1130 }
1131   1131  
1132 /// <summary> 1132 /// <summary>
1133 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchNormal for details 1133 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchNormal for details
1134 /// </summary> 1134 /// </summary>
1135 public LSL_Vector llDetectedTouchNormal(int index) 1135 public LSL_Vector llDetectedTouchNormal(int index)
1136 { 1136 {
1137 m_host.AddScriptLPS(1); 1137 m_host.AddScriptLPS(1);
1138 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1138 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1139 if (detectedParams == null) 1139 if (detectedParams == null)
1140 return new LSL_Vector(); 1140 return new LSL_Vector();
1141 return detectedParams.TouchNormal; 1141 return detectedParams.TouchNormal;
1142 } 1142 }
1143   1143  
1144 /// <summary> 1144 /// <summary>
1145 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchPos for details 1145 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchPos for details
1146 /// </summary> 1146 /// </summary>
1147 public LSL_Vector llDetectedTouchPos(int index) 1147 public LSL_Vector llDetectedTouchPos(int index)
1148 { 1148 {
1149 m_host.AddScriptLPS(1); 1149 m_host.AddScriptLPS(1);
1150 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1150 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1151 if (detectedParams == null) 1151 if (detectedParams == null)
1152 return new LSL_Vector(); 1152 return new LSL_Vector();
1153 return detectedParams.TouchPos; 1153 return detectedParams.TouchPos;
1154 } 1154 }
1155   1155  
1156 /// <summary> 1156 /// <summary>
1157 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchST for details 1157 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchST for details
1158 /// </summary> 1158 /// </summary>
1159 public LSL_Vector llDetectedTouchST(int index) 1159 public LSL_Vector llDetectedTouchST(int index)
1160 { 1160 {
1161 m_host.AddScriptLPS(1); 1161 m_host.AddScriptLPS(1);
1162 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1162 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1163 if (detectedParams == null) 1163 if (detectedParams == null)
1164 return new LSL_Vector(-1.0, -1.0, 0.0); 1164 return new LSL_Vector(-1.0, -1.0, 0.0);
1165 return detectedParams.TouchST; 1165 return detectedParams.TouchST;
1166 } 1166 }
1167   1167  
1168 /// <summary> 1168 /// <summary>
1169 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchUV for details 1169 /// See http://wiki.secondlife.com/wiki/LlDetectedTouchUV for details
1170 /// </summary> 1170 /// </summary>
1171 public LSL_Vector llDetectedTouchUV(int index) 1171 public LSL_Vector llDetectedTouchUV(int index)
1172 { 1172 {
1173 m_host.AddScriptLPS(1); 1173 m_host.AddScriptLPS(1);
1174 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index); 1174 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, index);
1175 if (detectedParams == null) 1175 if (detectedParams == null)
1176 return new LSL_Vector(-1.0, -1.0, 0.0); 1176 return new LSL_Vector(-1.0, -1.0, 0.0);
1177 return detectedParams.TouchUV; 1177 return detectedParams.TouchUV;
1178 } 1178 }
1179   1179  
1180 public virtual void llDie() 1180 public virtual void llDie()
1181 { 1181 {
1182 m_host.AddScriptLPS(1); 1182 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1183 throw new SelfDeleteException();
1184 } 1184 }
1185   1185  
1186 public LSL_Float llGround(LSL_Vector offset) 1186 public LSL_Float llGround(LSL_Vector offset)
1187 { 1187 {
1188 m_host.AddScriptLPS(1); 1188 m_host.AddScriptLPS(1);
1189 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; 1189 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
1190   1190  
1191 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 1191 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
1192 LSL_Vector vsn = llGroundNormal(offset); 1192 LSL_Vector vsn = llGroundNormal(offset);
1193   1193  
1194 // Clamp to valid position 1194 // Clamp to valid position
1195 if (pos.X < 0) 1195 if (pos.X < 0)
1196 pos.X = 0; 1196 pos.X = 0;
1197 else if (pos.X >= World.Heightmap.Width) 1197 else if (pos.X >= World.Heightmap.Width)
1198 pos.X = World.Heightmap.Width - 1; 1198 pos.X = World.Heightmap.Width - 1;
1199 if (pos.Y < 0) 1199 if (pos.Y < 0)
1200 pos.Y = 0; 1200 pos.Y = 0;
1201 else if (pos.Y >= World.Heightmap.Height) 1201 else if (pos.Y >= World.Heightmap.Height)
1202 pos.Y = World.Heightmap.Height - 1; 1202 pos.Y = World.Heightmap.Height - 1;
1203   1203  
1204 //Get the height for the integer coordinates from the Heightmap 1204 //Get the height for the integer coordinates from the Heightmap
1205 float baseheight = (float)World.Heightmap[(int)pos.X, (int)pos.Y]; 1205 float baseheight = (float)World.Heightmap[(int)pos.X, (int)pos.Y];
1206   1206  
1207 //Calculate the difference between the actual coordinates and the integer coordinates 1207 //Calculate the difference between the actual coordinates and the integer coordinates
1208 float xdiff = pos.X - (float)((int)pos.X); 1208 float xdiff = pos.X - (float)((int)pos.X);
1209 float ydiff = pos.Y - (float)((int)pos.Y); 1209 float ydiff = pos.Y - (float)((int)pos.Y);
1210   1210  
1211 //Use the equation of the tangent plane to adjust the height to account for slope 1211 //Use the equation of the tangent plane to adjust the height to account for slope
1212   1212  
1213 return (((vsn.x * xdiff) + (vsn.y * ydiff)) / (-1 * vsn.z)) + baseheight; 1213 return (((vsn.x * xdiff) + (vsn.y * ydiff)) / (-1 * vsn.z)) + baseheight;
1214 } 1214 }
1215   1215  
1216 public LSL_Float llCloud(LSL_Vector offset) 1216 public LSL_Float llCloud(LSL_Vector offset)
1217 { 1217 {
1218 m_host.AddScriptLPS(1); 1218 m_host.AddScriptLPS(1);
1219 float cloudCover = 0f; 1219 float cloudCover = 0f;
1220 ICloudModule module = World.RequestModuleInterface<ICloudModule>(); 1220 ICloudModule module = World.RequestModuleInterface<ICloudModule>();
1221 if (module != null) 1221 if (module != null)
1222 { 1222 {
1223 Vector3 pos = m_host.GetWorldPosition(); 1223 Vector3 pos = m_host.GetWorldPosition();
1224 int x = (int)(pos.X + offset.x); 1224 int x = (int)(pos.X + offset.x);
1225 int y = (int)(pos.Y + offset.y); 1225 int y = (int)(pos.Y + offset.y);
1226   1226  
1227 cloudCover = module.CloudCover(x, y, 0); 1227 cloudCover = module.CloudCover(x, y, 0);
1228   1228  
1229 } 1229 }
1230 return cloudCover; 1230 return cloudCover;
1231 } 1231 }
1232   1232  
1233 public LSL_Vector llWind(LSL_Vector offset) 1233 public LSL_Vector llWind(LSL_Vector offset)
1234 { 1234 {
1235 m_host.AddScriptLPS(1); 1235 m_host.AddScriptLPS(1);
1236 LSL_Vector wind = new LSL_Vector(0, 0, 0); 1236 LSL_Vector wind = new LSL_Vector(0, 0, 0);
1237 IWindModule module = World.RequestModuleInterface<IWindModule>(); 1237 IWindModule module = World.RequestModuleInterface<IWindModule>();
1238 if (module != null) 1238 if (module != null)
1239 { 1239 {
1240 Vector3 pos = m_host.GetWorldPosition(); 1240 Vector3 pos = m_host.GetWorldPosition();
1241 int x = (int)(pos.X + offset.x); 1241 int x = (int)(pos.X + offset.x);
1242 int y = (int)(pos.Y + offset.y); 1242 int y = (int)(pos.Y + offset.y);
1243   1243  
1244 Vector3 windSpeed = module.WindSpeed(x, y, 0); 1244 Vector3 windSpeed = module.WindSpeed(x, y, 0);
1245   1245  
1246 wind.x = windSpeed.X; 1246 wind.x = windSpeed.X;
1247 wind.y = windSpeed.Y; 1247 wind.y = windSpeed.Y;
1248 } 1248 }
1249 return wind; 1249 return wind;
1250 } 1250 }
1251   1251  
1252 public void llSetStatus(int status, int value) 1252 public void llSetStatus(int status, int value)
1253 { 1253 {
1254 m_host.AddScriptLPS(1); 1254 m_host.AddScriptLPS(1);
1255   1255  
1256 int statusrotationaxis = 0; 1256 int statusrotationaxis = 0;
1257   1257  
1258 if ((status & ScriptBaseClass.STATUS_PHYSICS) == ScriptBaseClass.STATUS_PHYSICS) 1258 if ((status & ScriptBaseClass.STATUS_PHYSICS) == ScriptBaseClass.STATUS_PHYSICS)
1259 { 1259 {
1260 if (value != 0) 1260 if (value != 0)
1261 { 1261 {
1262 SceneObjectGroup group = m_host.ParentGroup; 1262 SceneObjectGroup group = m_host.ParentGroup;
1263 bool allow = true; 1263 bool allow = true;
1264   1264  
1265 foreach (SceneObjectPart part in group.Parts) 1265 foreach (SceneObjectPart part in group.Parts)
1266 { 1266 {
1267 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys) 1267 if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
1268 { 1268 {
1269 allow = false; 1269 allow = false;
1270 break; 1270 break;
1271 } 1271 }
1272 } 1272 }
1273   1273  
1274 if (!allow) 1274 if (!allow)
1275 return; 1275 return;
1276   1276  
1277 m_host.ScriptSetPhysicsStatus(true); 1277 m_host.ScriptSetPhysicsStatus(true);
1278 } 1278 }
1279 else 1279 else
1280 { 1280 {
1281 m_host.ScriptSetPhysicsStatus(false); 1281 m_host.ScriptSetPhysicsStatus(false);
1282 } 1282 }
1283 } 1283 }
1284   1284  
1285 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM) 1285 if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM)
1286 { 1286 {
1287 m_host.ParentGroup.ScriptSetPhantomStatus(value != 0); 1287 m_host.ParentGroup.ScriptSetPhantomStatus(value != 0);
1288 } 1288 }
1289   1289  
1290 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS) 1290 if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS)
1291 { 1291 {
1292 m_host.AddFlag(PrimFlags.CastShadows); 1292 m_host.AddFlag(PrimFlags.CastShadows);
1293 } 1293 }
1294   1294  
1295 if ((status & ScriptBaseClass.STATUS_ROTATE_X) == ScriptBaseClass.STATUS_ROTATE_X) 1295 if ((status & ScriptBaseClass.STATUS_ROTATE_X) == ScriptBaseClass.STATUS_ROTATE_X)
1296 { 1296 {
1297 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_X; 1297 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_X;
1298 } 1298 }
1299   1299  
1300 if ((status & ScriptBaseClass.STATUS_ROTATE_Y) == ScriptBaseClass.STATUS_ROTATE_Y) 1300 if ((status & ScriptBaseClass.STATUS_ROTATE_Y) == ScriptBaseClass.STATUS_ROTATE_Y)
1301 { 1301 {
1302 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Y; 1302 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Y;
1303 } 1303 }
1304   1304  
1305 if ((status & ScriptBaseClass.STATUS_ROTATE_Z) == ScriptBaseClass.STATUS_ROTATE_Z) 1305 if ((status & ScriptBaseClass.STATUS_ROTATE_Z) == ScriptBaseClass.STATUS_ROTATE_Z)
1306 { 1306 {
1307 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Z; 1307 statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Z;
1308 } 1308 }
1309   1309  
1310 if ((status & ScriptBaseClass.STATUS_BLOCK_GRAB) == ScriptBaseClass.STATUS_BLOCK_GRAB) 1310 if ((status & ScriptBaseClass.STATUS_BLOCK_GRAB) == ScriptBaseClass.STATUS_BLOCK_GRAB)
1311 { 1311 {
1312 if (value != 0) 1312 if (value != 0)
1313 m_host.SetBlockGrab(true); 1313 m_host.SetBlockGrab(true);
1314 else 1314 else
1315 m_host.SetBlockGrab(false); 1315 m_host.SetBlockGrab(false);
1316 } 1316 }
1317   1317  
1318 if ((status & ScriptBaseClass.STATUS_DIE_AT_EDGE) == ScriptBaseClass.STATUS_DIE_AT_EDGE) 1318 if ((status & ScriptBaseClass.STATUS_DIE_AT_EDGE) == ScriptBaseClass.STATUS_DIE_AT_EDGE)
1319 { 1319 {
1320 if (value != 0) 1320 if (value != 0)
1321 m_host.SetDieAtEdge(true); 1321 m_host.SetDieAtEdge(true);
1322 else 1322 else
1323 m_host.SetDieAtEdge(false); 1323 m_host.SetDieAtEdge(false);
1324 } 1324 }
1325   1325  
1326 if ((status & ScriptBaseClass.STATUS_RETURN_AT_EDGE) == ScriptBaseClass.STATUS_RETURN_AT_EDGE) 1326 if ((status & ScriptBaseClass.STATUS_RETURN_AT_EDGE) == ScriptBaseClass.STATUS_RETURN_AT_EDGE)
1327 { 1327 {
1328 if (value != 0) 1328 if (value != 0)
1329 m_host.SetReturnAtEdge(true); 1329 m_host.SetReturnAtEdge(true);
1330 else 1330 else
1331 m_host.SetReturnAtEdge(false); 1331 m_host.SetReturnAtEdge(false);
1332 } 1332 }
1333   1333  
1334 if ((status & ScriptBaseClass.STATUS_SANDBOX) == ScriptBaseClass.STATUS_SANDBOX) 1334 if ((status & ScriptBaseClass.STATUS_SANDBOX) == ScriptBaseClass.STATUS_SANDBOX)
1335 { 1335 {
1336 if (value != 0) 1336 if (value != 0)
1337 m_host.SetStatusSandbox(true); 1337 m_host.SetStatusSandbox(true);
1338 else 1338 else
1339 m_host.SetStatusSandbox(false); 1339 m_host.SetStatusSandbox(false);
1340 } 1340 }
1341   1341  
1342 if (statusrotationaxis != 0) 1342 if (statusrotationaxis != 0)
1343 { 1343 {
1344 m_host.SetAxisRotation(statusrotationaxis, value); 1344 m_host.SetAxisRotation(statusrotationaxis, value);
1345 } 1345 }
1346 } 1346 }
1347   1347  
1348 private bool IsPhysical() 1348 private bool IsPhysical()
1349 { 1349 {
1350 return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics); 1350 return ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics);
1351 } 1351 }
1352   1352  
1353 public LSL_Integer llGetStatus(int status) 1353 public LSL_Integer llGetStatus(int status)
1354 { 1354 {
1355 m_host.AddScriptLPS(1); 1355 m_host.AddScriptLPS(1);
1356 // m_log.Debug(m_host.ToString() + " status is " + m_host.GetEffectiveObjectFlags().ToString()); 1356 // m_log.Debug(m_host.ToString() + " status is " + m_host.GetEffectiveObjectFlags().ToString());
1357 switch (status) 1357 switch (status)
1358 { 1358 {
1359 case ScriptBaseClass.STATUS_PHYSICS: 1359 case ScriptBaseClass.STATUS_PHYSICS:
1360 return IsPhysical() ? 1 : 0; 1360 return IsPhysical() ? 1 : 0;
1361   1361  
1362 case ScriptBaseClass.STATUS_PHANTOM: 1362 case ScriptBaseClass.STATUS_PHANTOM:
1363 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom) 1363 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom)
1364 { 1364 {
1365 return 1; 1365 return 1;
1366 } 1366 }
1367 return 0; 1367 return 0;
1368   1368  
1369 case ScriptBaseClass.STATUS_CAST_SHADOWS: 1369 case ScriptBaseClass.STATUS_CAST_SHADOWS:
1370 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.CastShadows) == (uint)PrimFlags.CastShadows) 1370 if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.CastShadows) == (uint)PrimFlags.CastShadows)
1371 { 1371 {
1372 return 1; 1372 return 1;
1373 } 1373 }
1374 return 0; 1374 return 0;
1375   1375  
1376 case ScriptBaseClass.STATUS_BLOCK_GRAB: 1376 case ScriptBaseClass.STATUS_BLOCK_GRAB:
1377 if (m_host.GetBlockGrab()) 1377 if (m_host.GetBlockGrab())
1378 return 1; 1378 return 1;
1379 else 1379 else
1380 return 0; 1380 return 0;
1381   1381  
1382 case ScriptBaseClass.STATUS_DIE_AT_EDGE: 1382 case ScriptBaseClass.STATUS_DIE_AT_EDGE:
1383 if (m_host.GetDieAtEdge()) 1383 if (m_host.GetDieAtEdge())
1384 return 1; 1384 return 1;
1385 else 1385 else
1386 return 0; 1386 return 0;
1387   1387  
1388 case ScriptBaseClass.STATUS_RETURN_AT_EDGE: 1388 case ScriptBaseClass.STATUS_RETURN_AT_EDGE:
1389 if (m_host.GetReturnAtEdge()) 1389 if (m_host.GetReturnAtEdge())
1390 return 1; 1390 return 1;
1391 else 1391 else
1392 return 0; 1392 return 0;
1393   1393  
1394 case ScriptBaseClass.STATUS_ROTATE_X: 1394 case ScriptBaseClass.STATUS_ROTATE_X:
1395 // if (m_host.GetAxisRotation(2) != 0) 1395 // if (m_host.GetAxisRotation(2) != 0)
1396 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) 1396 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0)
1397 return 1; 1397 return 1;
1398 else 1398 else
1399 return 0; 1399 return 0;
1400   1400  
1401 case ScriptBaseClass.STATUS_ROTATE_Y: 1401 case ScriptBaseClass.STATUS_ROTATE_Y:
1402 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) 1402 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0)
1403 return 1; 1403 return 1;
1404 else 1404 else
1405 return 0; 1405 return 0;
1406   1406  
1407 case ScriptBaseClass.STATUS_ROTATE_Z: 1407 case ScriptBaseClass.STATUS_ROTATE_Z:
1408 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) 1408 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0)
1409 return 1; 1409 return 1;
1410 else 1410 else
1411 return 0; 1411 return 0;
1412   1412  
1413 case ScriptBaseClass.STATUS_SANDBOX: 1413 case ScriptBaseClass.STATUS_SANDBOX:
1414 if (m_host.GetStatusSandbox()) 1414 if (m_host.GetStatusSandbox())
1415 return 1; 1415 return 1;
1416 else 1416 else
1417 return 0; 1417 return 0;
1418 } 1418 }
1419 return 0; 1419 return 0;
1420 } 1420 }
1421   1421  
1422 public void llSetScale(LSL_Vector scale) 1422 public void llSetScale(LSL_Vector scale)
1423 { 1423 {
1424 m_host.AddScriptLPS(1); 1424 m_host.AddScriptLPS(1);
1425 SetScale(m_host, scale); 1425 SetScale(m_host, scale);
1426 } 1426 }
1427   1427  
1428 protected void SetScale(SceneObjectPart part, LSL_Vector scale) 1428 protected void SetScale(SceneObjectPart part, LSL_Vector scale)
1429 { 1429 {
1430 // TODO: this needs to trigger a persistance save as well 1430 // TODO: this needs to trigger a persistance save as well
1431 if (part == null || part.ParentGroup.IsDeleted) 1431 if (part == null || part.ParentGroup.IsDeleted)
1432 return; 1432 return;
1433   1433  
1434 // First we need to check whether or not we need to clamp the size of a physics-enabled prim 1434 // First we need to check whether or not we need to clamp the size of a physics-enabled prim
1435 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; 1435 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1436 if (pa != null && pa.IsPhysical) 1436 if (pa != null && pa.IsPhysical)
1437 { 1437 {
1438 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x)); 1438 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1439 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y)); 1439 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1440 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z)); 1440 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1441 } 1441 }
1442 else 1442 else
1443 { 1443 {
1444 // If not physical, then we clamp the scale to the non-physical min/max 1444 // If not physical, then we clamp the scale to the non-physical min/max
1445 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x)); 1445 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1446 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y)); 1446 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1447 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z)); 1447 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1448 } 1448 }
1449   1449  
1450 Vector3 tmp = part.Scale; 1450 Vector3 tmp = part.Scale;
1451 tmp.X = (float)scale.x; 1451 tmp.X = (float)scale.x;
1452 tmp.Y = (float)scale.y; 1452 tmp.Y = (float)scale.y;
1453 tmp.Z = (float)scale.z; 1453 tmp.Z = (float)scale.z;
1454 part.Scale = tmp; 1454 part.Scale = tmp;
1455 part.SendFullUpdateToAllClients(); 1455 part.SendFullUpdateToAllClients();
1456 } 1456 }
1457   1457  
1458 public LSL_Vector llGetScale() 1458 public LSL_Vector llGetScale()
1459 { 1459 {
1460 m_host.AddScriptLPS(1); 1460 m_host.AddScriptLPS(1);
1461 return new LSL_Vector(m_host.Scale.X, m_host.Scale.Y, m_host.Scale.Z); 1461 return new LSL_Vector(m_host.Scale.X, m_host.Scale.Y, m_host.Scale.Z);
1462 } 1462 }
1463   1463  
1464 public void llSetClickAction(int action) 1464 public void llSetClickAction(int action)
1465 { 1465 {
1466 m_host.AddScriptLPS(1); 1466 m_host.AddScriptLPS(1);
1467 m_host.ClickAction = (byte)action; 1467 m_host.ClickAction = (byte)action;
1468 m_host.ParentGroup.HasGroupChanged = true; 1468 m_host.ParentGroup.HasGroupChanged = true;
1469 m_host.ScheduleFullUpdate(); 1469 m_host.ScheduleFullUpdate();
1470 return; 1470 return;
1471 } 1471 }
1472   1472  
1473 public void llSetColor(LSL_Vector color, int face) 1473 public void llSetColor(LSL_Vector color, int face)
1474 { 1474 {
1475 m_host.AddScriptLPS(1); 1475 m_host.AddScriptLPS(1);
1476   1476  
1477 if (face == ScriptBaseClass.ALL_SIDES) 1477 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1478 face = SceneObjectPart.ALL_SIDES;
1479   1479  
1480 m_host.SetFaceColorAlpha(face, color, null); 1480 m_host.SetFaceColorAlpha(face, color, null);
1481 } 1481 }
1482   1482  
1483 public void llSetContentType(LSL_Key id, LSL_Integer type) 1483 public void llSetContentType(LSL_Key id, LSL_Integer type)
1484 { 1484 {
1485 m_host.AddScriptLPS(1); 1485 m_host.AddScriptLPS(1);
1486   1486  
1487 if (m_UrlModule == null) 1487 if (m_UrlModule == null)
1488 return; 1488 return;
1489   1489  
1490 // Make sure the content type is text/plain to start with 1490 // Make sure the content type is text/plain to start with
1491 m_UrlModule.HttpContentType(new UUID(id), "text/plain"); 1491 m_UrlModule.HttpContentType(new UUID(id), "text/plain");
1492   1492  
1493 // Is the object owner online and in the region 1493 // Is the object owner online and in the region
1494 ScenePresence agent = World.GetScenePresence(m_host.ParentGroup.OwnerID); 1494 ScenePresence agent = World.GetScenePresence(m_host.ParentGroup.OwnerID);
1495 if (agent == null || agent.IsChildAgent) 1495 if (agent == null || agent.IsChildAgent)
1496 return; // Fail if the owner is not in the same region 1496 return; // Fail if the owner is not in the same region
1497   1497  
1498 // Is it the embeded browser? 1498 // Is it the embeded browser?
1499 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent"); 1499 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent");
1500 if (userAgent.IndexOf("SecondLife") < 0) 1500 if (userAgent.IndexOf("SecondLife") < 0)
1501 return; // Not the embedded browser. Is this check good enough? 1501 return; // Not the embedded browser. Is this check good enough?
1502   1502  
1503 // Use the IP address of the client and check against the request 1503 // Use the IP address of the client and check against the request
1504 // seperate logins from the same IP will allow all of them to get non-text/plain as long 1504 // seperate logins from the same IP will allow all of them to get non-text/plain as long
1505 // as the owner is in the region. Same as SL! 1505 // as the owner is in the region. Same as SL!
1506 string logonFromIPAddress = agent.ControllingClient.RemoteEndPoint.Address.ToString(); 1506 string logonFromIPAddress = agent.ControllingClient.RemoteEndPoint.Address.ToString();
1507 string requestFromIPAddress = m_UrlModule.GetHttpHeader(new UUID(id), "remote_addr"); 1507 string requestFromIPAddress = m_UrlModule.GetHttpHeader(new UUID(id), "remote_addr");
1508 //m_log.Debug("IP from header='" + requestFromIPAddress + "' IP from endpoint='" + logonFromIPAddress + "'"); 1508 //m_log.Debug("IP from header='" + requestFromIPAddress + "' IP from endpoint='" + logonFromIPAddress + "'");
1509 if (requestFromIPAddress == null || requestFromIPAddress.Trim() == "") 1509 if (requestFromIPAddress == null || requestFromIPAddress.Trim() == "")
1510 return; 1510 return;
1511 if (logonFromIPAddress == null || logonFromIPAddress.Trim() == "") 1511 if (logonFromIPAddress == null || logonFromIPAddress.Trim() == "")
1512 return; 1512 return;
1513   1513  
1514 // If the request isnt from the same IP address then the request cannot be from the owner 1514 // If the request isnt from the same IP address then the request cannot be from the owner
1515 if (!requestFromIPAddress.Trim().Equals(logonFromIPAddress.Trim())) 1515 if (!requestFromIPAddress.Trim().Equals(logonFromIPAddress.Trim()))
1516 return; 1516 return;
1517   1517  
1518 switch (type) 1518 switch (type)
1519 { 1519 {
1520 case ScriptBaseClass.CONTENT_TYPE_HTML: 1520 case ScriptBaseClass.CONTENT_TYPE_HTML:
1521 m_UrlModule.HttpContentType(new UUID(id), "text/html"); 1521 m_UrlModule.HttpContentType(new UUID(id), "text/html");
1522 break; 1522 break;
1523 case ScriptBaseClass.CONTENT_TYPE_XML: 1523 case ScriptBaseClass.CONTENT_TYPE_XML:
1524 m_UrlModule.HttpContentType(new UUID(id), "application/xml"); 1524 m_UrlModule.HttpContentType(new UUID(id), "application/xml");
1525 break; 1525 break;
1526 case ScriptBaseClass.CONTENT_TYPE_XHTML: 1526 case ScriptBaseClass.CONTENT_TYPE_XHTML:
1527 m_UrlModule.HttpContentType(new UUID(id), "application/xhtml+xml"); 1527 m_UrlModule.HttpContentType(new UUID(id), "application/xhtml+xml");
1528 break; 1528 break;
1529 case ScriptBaseClass.CONTENT_TYPE_ATOM: 1529 case ScriptBaseClass.CONTENT_TYPE_ATOM:
1530 m_UrlModule.HttpContentType(new UUID(id), "application/atom+xml"); 1530 m_UrlModule.HttpContentType(new UUID(id), "application/atom+xml");
1531 break; 1531 break;
1532 case ScriptBaseClass.CONTENT_TYPE_JSON: 1532 case ScriptBaseClass.CONTENT_TYPE_JSON:
1533 m_UrlModule.HttpContentType(new UUID(id), "application/json"); 1533 m_UrlModule.HttpContentType(new UUID(id), "application/json");
1534 break; 1534 break;
1535 case ScriptBaseClass.CONTENT_TYPE_LLSD: 1535 case ScriptBaseClass.CONTENT_TYPE_LLSD:
1536 m_UrlModule.HttpContentType(new UUID(id), "application/llsd+xml"); 1536 m_UrlModule.HttpContentType(new UUID(id), "application/llsd+xml");
1537 break; 1537 break;
1538 case ScriptBaseClass.CONTENT_TYPE_FORM: 1538 case ScriptBaseClass.CONTENT_TYPE_FORM:
1539 m_UrlModule.HttpContentType(new UUID(id), "application/x-www-form-urlencoded"); 1539 m_UrlModule.HttpContentType(new UUID(id), "application/x-www-form-urlencoded");
1540 break; 1540 break;
1541 case ScriptBaseClass.CONTENT_TYPE_RSS: 1541 case ScriptBaseClass.CONTENT_TYPE_RSS:
1542 m_UrlModule.HttpContentType(new UUID(id), "application/rss+xml"); 1542 m_UrlModule.HttpContentType(new UUID(id), "application/rss+xml");
1543 break; 1543 break;
1544 default: 1544 default:
1545 m_UrlModule.HttpContentType(new UUID(id), "text/plain"); 1545 m_UrlModule.HttpContentType(new UUID(id), "text/plain");
1546 break; 1546 break;
1547 } 1547 }
1548 } 1548 }
1549   1549  
1550 public void SetTexGen(SceneObjectPart part, int face,int style) 1550 public void SetTexGen(SceneObjectPart part, int face,int style)
1551 { 1551 {
1552 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1553 MappingType textype; 1553 MappingType textype;
1554 textype = MappingType.Default; 1554 textype = MappingType.Default;
1555 if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR) 1555 if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR)
1556 textype = MappingType.Planar; 1556 textype = MappingType.Planar;
1557   1557  
1558 if (face >= 0 && face < GetNumberOfSides(part)) 1558 if (face >= 0 && face < GetNumberOfSides(part))
1559 { 1559 {
1560 tex.CreateFace((uint) face); 1560 tex.CreateFace((uint) face);
1561 tex.FaceTextures[face].TexMapType = textype; 1561 tex.FaceTextures[face].TexMapType = textype;
1562 part.UpdateTextureEntry(tex.GetBytes()); 1562 part.UpdateTextureEntry(tex.GetBytes());
1563 return; 1563 return;
1564 } 1564 }
1565 else if (face == ScriptBaseClass.ALL_SIDES) 1565 else if (face == ScriptBaseClass.ALL_SIDES)
1566 { 1566 {
1567 for (uint i = 0; i < GetNumberOfSides(part); i++) 1567 for (uint i = 0; i < GetNumberOfSides(part); i++)
1568 { 1568 {
1569 if (tex.FaceTextures[i] != null) 1569 if (tex.FaceTextures[i] != null)
1570 { 1570 {
1571 tex.FaceTextures[i].TexMapType = textype; 1571 tex.FaceTextures[i].TexMapType = textype;
1572 } 1572 }
1573 tex.DefaultTexture.TexMapType = textype; 1573 tex.DefaultTexture.TexMapType = textype;
1574 } 1574 }
1575 part.UpdateTextureEntry(tex.GetBytes()); 1575 part.UpdateTextureEntry(tex.GetBytes());
1576 return; 1576 return;
1577 } 1577 }
1578 } 1578 }
1579   1579  
1580 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1581 { 1581 {
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1582 Primitive.TextureEntry tex = part.Shape.Textures;
1583 if (face >= 0 && face < GetNumberOfSides(part)) 1583 if (face >= 0 && face < GetNumberOfSides(part))
1584 { 1584 {
1585 tex.CreateFace((uint) face); 1585 tex.CreateFace((uint) face);
1586 tex.FaceTextures[face].Glow = glow; 1586 tex.FaceTextures[face].Glow = glow;
1587 part.UpdateTextureEntry(tex.GetBytes()); 1587 part.UpdateTextureEntry(tex.GetBytes());
1588 return; 1588 return;
1589 } 1589 }
1590 else if (face == ScriptBaseClass.ALL_SIDES) 1590 else if (face == ScriptBaseClass.ALL_SIDES)
1591 { 1591 {
1592 for (uint i = 0; i < GetNumberOfSides(part); i++) 1592 for (uint i = 0; i < GetNumberOfSides(part); i++)
1593 { 1593 {
1594 if (tex.FaceTextures[i] != null) 1594 if (tex.FaceTextures[i] != null)
1595 { 1595 {
1596 tex.FaceTextures[i].Glow = glow; 1596 tex.FaceTextures[i].Glow = glow;
1597 } 1597 }
1598 tex.DefaultTexture.Glow = glow; 1598 tex.DefaultTexture.Glow = glow;
1599 } 1599 }
1600 part.UpdateTextureEntry(tex.GetBytes()); 1600 part.UpdateTextureEntry(tex.GetBytes());
1601 return; 1601 return;
1602 } 1602 }
1603 } 1603 }
1604   1604  
1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1606 { 1606 {
1607   1607  
1608 Shininess sval = new Shininess(); 1608 Shininess sval = new Shininess();
1609   1609  
1610 switch (shiny) 1610 switch (shiny)
1611 { 1611 {
1612 case 0: 1612 case 0:
1613 sval = Shininess.None; 1613 sval = Shininess.None;
1614 break; 1614 break;
1615 case 1: 1615 case 1:
1616 sval = Shininess.Low; 1616 sval = Shininess.Low;
1617 break; 1617 break;
1618 case 2: 1618 case 2:
1619 sval = Shininess.Medium; 1619 sval = Shininess.Medium;
1620 break; 1620 break;
1621 case 3: 1621 case 3:
1622 sval = Shininess.High; 1622 sval = Shininess.High;
1623 break; 1623 break;
1624 default: 1624 default:
1625 sval = Shininess.None; 1625 sval = Shininess.None;
1626 break; 1626 break;
1627 } 1627 }
1628   1628  
1629 Primitive.TextureEntry tex = part.Shape.Textures; 1629 Primitive.TextureEntry tex = part.Shape.Textures;
1630 if (face >= 0 && face < GetNumberOfSides(part)) 1630 if (face >= 0 && face < GetNumberOfSides(part))
1631 { 1631 {
1632 tex.CreateFace((uint) face); 1632 tex.CreateFace((uint) face);
1633 tex.FaceTextures[face].Shiny = sval; 1633 tex.FaceTextures[face].Shiny = sval;
1634 tex.FaceTextures[face].Bump = bump; 1634 tex.FaceTextures[face].Bump = bump;
1635 part.UpdateTextureEntry(tex.GetBytes()); 1635 part.UpdateTextureEntry(tex.GetBytes());
1636 return; 1636 return;
1637 } 1637 }
1638 else if (face == ScriptBaseClass.ALL_SIDES) 1638 else if (face == ScriptBaseClass.ALL_SIDES)
1639 { 1639 {
1640 for (uint i = 0; i < GetNumberOfSides(part); i++) 1640 for (uint i = 0; i < GetNumberOfSides(part); i++)
1641 { 1641 {
1642 if (tex.FaceTextures[i] != null) 1642 if (tex.FaceTextures[i] != null)
1643 { 1643 {
1644 tex.FaceTextures[i].Shiny = sval; 1644 tex.FaceTextures[i].Shiny = sval;
1645 tex.FaceTextures[i].Bump = bump; 1645 tex.FaceTextures[i].Bump = bump;
1646 } 1646 }
1647 tex.DefaultTexture.Shiny = sval; 1647 tex.DefaultTexture.Shiny = sval;
1648 tex.DefaultTexture.Bump = bump; 1648 tex.DefaultTexture.Bump = bump;
1649 } 1649 }
1650 part.UpdateTextureEntry(tex.GetBytes()); 1650 part.UpdateTextureEntry(tex.GetBytes());
1651 return; 1651 return;
1652 } 1652 }
1653 } 1653 }
1654   1654  
1655 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1655 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1656 { 1656 {
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1657 Primitive.TextureEntry tex = part.Shape.Textures;
1658 if (face >= 0 && face < GetNumberOfSides(part)) 1658 if (face >= 0 && face < GetNumberOfSides(part))
1659 { 1659 {
1660 tex.CreateFace((uint) face); 1660 tex.CreateFace((uint) face);
1661 tex.FaceTextures[face].Fullbright = bright; 1661 tex.FaceTextures[face].Fullbright = bright;
1662 part.UpdateTextureEntry(tex.GetBytes()); 1662 part.UpdateTextureEntry(tex.GetBytes());
1663 return; 1663 return;
1664 } 1664 }
1665 else if (face == ScriptBaseClass.ALL_SIDES) 1665 else if (face == ScriptBaseClass.ALL_SIDES)
1666 { 1666 {
1667 for (uint i = 0; i < GetNumberOfSides(part); i++) 1667 for (uint i = 0; i < GetNumberOfSides(part); i++)
1668 { 1668 {
1669 if (tex.FaceTextures[i] != null) 1669 if (tex.FaceTextures[i] != null)
1670 { 1670 {
1671 tex.FaceTextures[i].Fullbright = bright; 1671 tex.FaceTextures[i].Fullbright = bright;
1672 } 1672 }
1673 } 1673 }
1674 tex.DefaultTexture.Fullbright = bright; 1674 tex.DefaultTexture.Fullbright = bright;
1675 part.UpdateTextureEntry(tex.GetBytes()); 1675 part.UpdateTextureEntry(tex.GetBytes());
1676 return; 1676 return;
1677 } 1677 }
1678 } 1678 }
1679   1679  
1680 public LSL_Float llGetAlpha(int face) 1680 public LSL_Float llGetAlpha(int face)
1681 { 1681 {
1682 m_host.AddScriptLPS(1); 1682 m_host.AddScriptLPS(1);
1683   1683  
1684 return GetAlpha(m_host, face); 1684 return GetAlpha(m_host, face);
1685 } 1685 }
1686   1686  
1687 protected LSL_Float GetAlpha(SceneObjectPart part, int face) 1687 protected LSL_Float GetAlpha(SceneObjectPart part, int face)
1688 { 1688 {
1689 Primitive.TextureEntry tex = part.Shape.Textures; 1689 Primitive.TextureEntry tex = part.Shape.Textures;
1690 if (face == ScriptBaseClass.ALL_SIDES) 1690 if (face == ScriptBaseClass.ALL_SIDES)
1691 { 1691 {
1692 int i; 1692 int i;
1693 double sum = 0.0; 1693 double sum = 0.0;
1694 for (i = 0 ; i < GetNumberOfSides(part); i++) 1694 for (i = 0 ; i < GetNumberOfSides(part); i++)
1695 sum += (double)tex.GetFace((uint)i).RGBA.A; 1695 sum += (double)tex.GetFace((uint)i).RGBA.A;
1696 return sum; 1696 return sum;
1697 } 1697 }
1698 if (face >= 0 && face < GetNumberOfSides(part)) 1698 if (face >= 0 && face < GetNumberOfSides(part))
1699 { 1699 {
1700 return (double)tex.GetFace((uint)face).RGBA.A; 1700 return (double)tex.GetFace((uint)face).RGBA.A;
1701 } 1701 }
1702 return 0.0; 1702 return 0.0;
1703 } 1703 }
1704   1704  
1705 public void llSetAlpha(double alpha, int face) 1705 public void llSetAlpha(double alpha, int face)
1706 { 1706 {
1707 m_host.AddScriptLPS(1); 1707 m_host.AddScriptLPS(1);
1708   1708  
1709 SetAlpha(m_host, alpha, face); 1709 SetAlpha(m_host, alpha, face);
1710 } 1710 }
1711   1711  
1712 public void llSetLinkAlpha(int linknumber, double alpha, int face) 1712 public void llSetLinkAlpha(int linknumber, double alpha, int face)
1713 { 1713 {
1714 m_host.AddScriptLPS(1); 1714 m_host.AddScriptLPS(1);
1715   1715  
1716 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1716 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1717   1717  
1718 foreach (SceneObjectPart part in parts) 1718 foreach (SceneObjectPart part in parts)
1719 SetAlpha(part, alpha, face); 1719 SetAlpha(part, alpha, face);
1720 } 1720 }
1721   1721  
1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1723 { 1723 {
1724 Primitive.TextureEntry tex = part.Shape.Textures; 1724 Primitive.TextureEntry tex = part.Shape.Textures;
1725 Color4 texcolor; 1725 Color4 texcolor;
1726 if (face >= 0 && face < GetNumberOfSides(part)) 1726 if (face >= 0 && face < GetNumberOfSides(part))
1727 { 1727 {
1728 texcolor = tex.CreateFace((uint)face).RGBA; 1728 texcolor = tex.CreateFace((uint)face).RGBA;
1729 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1729 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1730 tex.FaceTextures[face].RGBA = texcolor; 1730 tex.FaceTextures[face].RGBA = texcolor;
1731 part.UpdateTextureEntry(tex.GetBytes()); 1731 part.UpdateTextureEntry(tex.GetBytes());
1732 return; 1732 return;
1733 } 1733 }
1734 else if (face == ScriptBaseClass.ALL_SIDES) 1734 else if (face == ScriptBaseClass.ALL_SIDES)
1735 { 1735 {
1736 for (int i = 0; i < GetNumberOfSides(part); i++) 1736 for (int i = 0; i < GetNumberOfSides(part); i++)
1737 { 1737 {
1738 if (tex.FaceTextures[i] != null) 1738 if (tex.FaceTextures[i] != null)
1739 { 1739 {
1740 texcolor = tex.FaceTextures[i].RGBA; 1740 texcolor = tex.FaceTextures[i].RGBA;
1741 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1741 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1742 tex.FaceTextures[i].RGBA = texcolor; 1742 tex.FaceTextures[i].RGBA = texcolor;
1743 } 1743 }
1744 } 1744 }
1745   1745  
1746 // In some cases, the default texture can be null, eg when every face 1746 // In some cases, the default texture can be null, eg when every face
1747 // has a unique texture 1747 // has a unique texture
1748 if (tex.DefaultTexture != null) 1748 if (tex.DefaultTexture != null)
1749 { 1749 {
1750 texcolor = tex.DefaultTexture.RGBA; 1750 texcolor = tex.DefaultTexture.RGBA;
1751 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1751 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1752 tex.DefaultTexture.RGBA = texcolor; 1752 tex.DefaultTexture.RGBA = texcolor;
1753 } 1753 }
1754   1754  
1755 part.UpdateTextureEntry(tex.GetBytes()); 1755 part.UpdateTextureEntry(tex.GetBytes());
1756 return; 1756 return;
1757 } 1757 }
1758 } 1758 }
1759   1759  
1760 /// <summary> 1760 /// <summary>
1761 /// Set flexi parameters of a part. 1761 /// Set flexi parameters of a part.
1762 /// 1762 ///
1763 /// FIXME: Much of this code should probably be within the part itself. 1763 /// FIXME: Much of this code should probably be within the part itself.
1764 /// </summary> 1764 /// </summary>
1765 /// <param name="part"></param> 1765 /// <param name="part"></param>
1766 /// <param name="flexi"></param> 1766 /// <param name="flexi"></param>
1767 /// <param name="softness"></param> 1767 /// <param name="softness"></param>
1768 /// <param name="gravity"></param> 1768 /// <param name="gravity"></param>
1769 /// <param name="friction"></param> 1769 /// <param name="friction"></param>
1770 /// <param name="wind"></param> 1770 /// <param name="wind"></param>
1771 /// <param name="tension"></param> 1771 /// <param name="tension"></param>
1772 /// <param name="Force"></param> 1772 /// <param name="Force"></param>
1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1774 float wind, float tension, LSL_Vector Force) 1774 float wind, float tension, LSL_Vector Force)
1775 { 1775 {
1776 if (part == null) 1776 if (part == null)
1777 return; 1777 return;
1778   1778  
1779 if (flexi) 1779 if (flexi)
1780 { 1780 {
1781 part.Shape.FlexiEntry = true; // this setting flexi true isn't working, but the below parameters do 1781 part.Shape.FlexiEntry = true; // this setting flexi true isn't working, but the below parameters do
1782 // work once the prim is already flexi 1782 // work once the prim is already flexi
1783 part.Shape.FlexiSoftness = softness; 1783 part.Shape.FlexiSoftness = softness;
1784 part.Shape.FlexiGravity = gravity; 1784 part.Shape.FlexiGravity = gravity;
1785 part.Shape.FlexiDrag = friction; 1785 part.Shape.FlexiDrag = friction;
1786 part.Shape.FlexiWind = wind; 1786 part.Shape.FlexiWind = wind;
1787 part.Shape.FlexiTension = tension; 1787 part.Shape.FlexiTension = tension;
1788 part.Shape.FlexiForceX = (float)Force.x; 1788 part.Shape.FlexiForceX = (float)Force.x;
1789 part.Shape.FlexiForceY = (float)Force.y; 1789 part.Shape.FlexiForceY = (float)Force.y;
1790 part.Shape.FlexiForceZ = (float)Force.z; 1790 part.Shape.FlexiForceZ = (float)Force.z;
1791 part.Shape.PathCurve = (byte)Extrusion.Flexible; 1791 part.Shape.PathCurve = (byte)Extrusion.Flexible;
1792 } 1792 }
1793 else 1793 else
1794 { 1794 {
1795 // Other values not set, they do not seem to be sent to the viewer 1795 // Other values not set, they do not seem to be sent to the viewer
1796 // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off 1796 // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off
1797 part.Shape.PathCurve = (byte)Extrusion.Straight; 1797 part.Shape.PathCurve = (byte)Extrusion.Straight;
1798 part.Shape.FlexiEntry = false; 1798 part.Shape.FlexiEntry = false;
1799 } 1799 }
1800 part.ParentGroup.HasGroupChanged = true; 1800 part.ParentGroup.HasGroupChanged = true;
1801 part.ScheduleFullUpdate(); 1801 part.ScheduleFullUpdate();
1802 } 1802 }
1803   1803  
1804 /// <summary> 1804 /// <summary>
1805 /// Set a light point on a part 1805 /// Set a light point on a part
1806 /// </summary> 1806 /// </summary>
1807 /// FIXME: Much of this code should probably be in SceneObjectGroup 1807 /// FIXME: Much of this code should probably be in SceneObjectGroup
1808 /// 1808 ///
1809 /// <param name="part"></param> 1809 /// <param name="part"></param>
1810 /// <param name="light"></param> 1810 /// <param name="light"></param>
1811 /// <param name="color"></param> 1811 /// <param name="color"></param>
1812 /// <param name="intensity"></param> 1812 /// <param name="intensity"></param>
1813 /// <param name="radius"></param> 1813 /// <param name="radius"></param>
1814 /// <param name="falloff"></param> 1814 /// <param name="falloff"></param>
1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1816 { 1816 {
1817 if (part == null) 1817 if (part == null)
1818 return; 1818 return;
1819   1819  
1820 if (light) 1820 if (light)
1821 { 1821 {
1822 part.Shape.LightEntry = true; 1822 part.Shape.LightEntry = true;
1823 part.Shape.LightColorR = Util.Clip((float)color.x, 0.0f, 1.0f); 1823 part.Shape.LightColorR = Util.Clip((float)color.x, 0.0f, 1.0f);
1824 part.Shape.LightColorG = Util.Clip((float)color.y, 0.0f, 1.0f); 1824 part.Shape.LightColorG = Util.Clip((float)color.y, 0.0f, 1.0f);
1825 part.Shape.LightColorB = Util.Clip((float)color.z, 0.0f, 1.0f); 1825 part.Shape.LightColorB = Util.Clip((float)color.z, 0.0f, 1.0f);
1826 part.Shape.LightIntensity = intensity; 1826 part.Shape.LightIntensity = intensity;
1827 part.Shape.LightRadius = radius; 1827 part.Shape.LightRadius = radius;
1828 part.Shape.LightFalloff = falloff; 1828 part.Shape.LightFalloff = falloff;
1829 } 1829 }
1830 else 1830 else
1831 { 1831 {
1832 part.Shape.LightEntry = false; 1832 part.Shape.LightEntry = false;
1833 } 1833 }
1834   1834  
1835 part.ParentGroup.HasGroupChanged = true; 1835 part.ParentGroup.HasGroupChanged = true;
1836 part.ScheduleFullUpdate(); 1836 part.ScheduleFullUpdate();
1837 } 1837 }
1838   1838  
1839 public LSL_Vector llGetColor(int face) 1839 public LSL_Vector llGetColor(int face)
1840 { 1840 {
1841 m_host.AddScriptLPS(1); 1841 m_host.AddScriptLPS(1);
1842 return GetColor(m_host, face); 1842 return GetColor(m_host, face);
1843 } 1843 }
1844   1844  
1845 protected LSL_Vector GetColor(SceneObjectPart part, int face) 1845 protected LSL_Vector GetColor(SceneObjectPart part, int face)
1846 { 1846 {
1847 Primitive.TextureEntry tex = part.Shape.Textures; 1847 Primitive.TextureEntry tex = part.Shape.Textures;
1848 Color4 texcolor; 1848 Color4 texcolor;
1849 LSL_Vector rgb = new LSL_Vector(); 1849 LSL_Vector rgb = new LSL_Vector();
1850 if (face == ScriptBaseClass.ALL_SIDES) 1850 if (face == ScriptBaseClass.ALL_SIDES)
1851 { 1851 {
1852 int i; 1852 int i;
1853   1853  
1854 for (i = 0 ; i < GetNumberOfSides(part); i++) 1854 for (i = 0 ; i < GetNumberOfSides(part); i++)
1855 { 1855 {
1856 texcolor = tex.GetFace((uint)i).RGBA; 1856 texcolor = tex.GetFace((uint)i).RGBA;
1857 rgb.x += texcolor.R; 1857 rgb.x += texcolor.R;
1858 rgb.y += texcolor.G; 1858 rgb.y += texcolor.G;
1859 rgb.z += texcolor.B; 1859 rgb.z += texcolor.B;
1860 } 1860 }
1861   1861  
1862 rgb.x /= (float)GetNumberOfSides(part); 1862 rgb.x /= (float)GetNumberOfSides(part);
1863 rgb.y /= (float)GetNumberOfSides(part); 1863 rgb.y /= (float)GetNumberOfSides(part);
1864 rgb.z /= (float)GetNumberOfSides(part); 1864 rgb.z /= (float)GetNumberOfSides(part);
1865   1865  
1866 return rgb; 1866 return rgb;
1867 } 1867 }
1868   1868  
1869 if (face >= 0 && face < GetNumberOfSides(part)) 1869 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 1870 {
1871 texcolor = tex.GetFace((uint)face).RGBA; 1871 texcolor = tex.GetFace((uint)face).RGBA;
1872 rgb.x = texcolor.R; 1872 rgb.x = texcolor.R;
1873 rgb.y = texcolor.G; 1873 rgb.y = texcolor.G;
1874 rgb.z = texcolor.B; 1874 rgb.z = texcolor.B;
1875   1875  
1876 return rgb; 1876 return rgb;
1877 } 1877 }
1878 else 1878 else
1879 { 1879 {
1880 return new LSL_Vector(); 1880 return new LSL_Vector();
1881 } 1881 }
1882 } 1882 }
1883   1883  
1884 public void llSetTexture(string texture, int face) 1884 public void llSetTexture(string texture, int face)
1885 { 1885 {
1886 m_host.AddScriptLPS(1); 1886 m_host.AddScriptLPS(1);
1887 SetTexture(m_host, texture, face); 1887 SetTexture(m_host, texture, face);
1888 ScriptSleep(200); 1888 ScriptSleep(200);
1889 } 1889 }
1890   1890  
1891 public void llSetLinkTexture(int linknumber, string texture, int face) 1891 public void llSetLinkTexture(int linknumber, string texture, int face)
1892 { 1892 {
1893 m_host.AddScriptLPS(1); 1893 m_host.AddScriptLPS(1);
1894   1894  
1895 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1895 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1896   1896  
1897 foreach (SceneObjectPart part in parts) 1897 foreach (SceneObjectPart part in parts)
1898 SetTexture(part, texture, face); 1898 SetTexture(part, texture, face);
1899   1899  
1900 ScriptSleep(200); 1900 ScriptSleep(200);
1901 } 1901 }
1902   1902  
1903 protected void SetTexture(SceneObjectPart part, string texture, int face) 1903 protected void SetTexture(SceneObjectPart part, string texture, int face)
1904 { 1904 {
1905 UUID textureID = new UUID(); 1905 UUID textureID = new UUID();
1906   1906  
1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
1908 if (textureID == UUID.Zero) 1908 if (textureID == UUID.Zero)
1909 { 1909 {
1910 if (!UUID.TryParse(texture, out textureID)) 1910 if (!UUID.TryParse(texture, out textureID))
1911 return; 1911 return;
1912 } 1912 }
1913   1913  
1914 Primitive.TextureEntry tex = part.Shape.Textures; 1914 Primitive.TextureEntry tex = part.Shape.Textures;
1915   1915  
1916 if (face >= 0 && face < GetNumberOfSides(part)) 1916 if (face >= 0 && face < GetNumberOfSides(part))
1917 { 1917 {
1918 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 1918 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
1919 texface.TextureID = textureID; 1919 texface.TextureID = textureID;
1920 tex.FaceTextures[face] = texface; 1920 tex.FaceTextures[face] = texface;
1921 part.UpdateTextureEntry(tex.GetBytes()); 1921 part.UpdateTextureEntry(tex.GetBytes());
1922 return; 1922 return;
1923 } 1923 }
1924 else if (face == ScriptBaseClass.ALL_SIDES) 1924 else if (face == ScriptBaseClass.ALL_SIDES)
1925 { 1925 {
1926 for (uint i = 0; i < GetNumberOfSides(part); i++) 1926 for (uint i = 0; i < GetNumberOfSides(part); i++)
1927 { 1927 {
1928 if (tex.FaceTextures[i] != null) 1928 if (tex.FaceTextures[i] != null)
1929 { 1929 {
1930 tex.FaceTextures[i].TextureID = textureID; 1930 tex.FaceTextures[i].TextureID = textureID;
1931 } 1931 }
1932 } 1932 }
1933 tex.DefaultTexture.TextureID = textureID; 1933 tex.DefaultTexture.TextureID = textureID;
1934 part.UpdateTextureEntry(tex.GetBytes()); 1934 part.UpdateTextureEntry(tex.GetBytes());
1935 return; 1935 return;
1936 } 1936 }
1937 } 1937 }
1938   1938  
1939 public void llScaleTexture(double u, double v, int face) 1939 public void llScaleTexture(double u, double v, int face)
1940 { 1940 {
1941 m_host.AddScriptLPS(1); 1941 m_host.AddScriptLPS(1);
1942   1942  
1943 ScaleTexture(m_host, u, v, face); 1943 ScaleTexture(m_host, u, v, face);
1944 ScriptSleep(200); 1944 ScriptSleep(200);
1945 } 1945 }
1946   1946  
1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1948 { 1948 {
1949 Primitive.TextureEntry tex = part.Shape.Textures; 1949 Primitive.TextureEntry tex = part.Shape.Textures;
1950 if (face >= 0 && face < GetNumberOfSides(part)) 1950 if (face >= 0 && face < GetNumberOfSides(part))
1951 { 1951 {
1952 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 1952 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
1953 texface.RepeatU = (float)u; 1953 texface.RepeatU = (float)u;
1954 texface.RepeatV = (float)v; 1954 texface.RepeatV = (float)v;
1955 tex.FaceTextures[face] = texface; 1955 tex.FaceTextures[face] = texface;
1956 part.UpdateTextureEntry(tex.GetBytes()); 1956 part.UpdateTextureEntry(tex.GetBytes());
1957 return; 1957 return;
1958 } 1958 }
1959 if (face == ScriptBaseClass.ALL_SIDES) 1959 if (face == ScriptBaseClass.ALL_SIDES)
1960 { 1960 {
1961 for (int i = 0; i < GetNumberOfSides(part); i++) 1961 for (int i = 0; i < GetNumberOfSides(part); i++)
1962 { 1962 {
1963 if (tex.FaceTextures[i] != null) 1963 if (tex.FaceTextures[i] != null)
1964 { 1964 {
1965 tex.FaceTextures[i].RepeatU = (float)u; 1965 tex.FaceTextures[i].RepeatU = (float)u;
1966 tex.FaceTextures[i].RepeatV = (float)v; 1966 tex.FaceTextures[i].RepeatV = (float)v;
1967 } 1967 }
1968 } 1968 }
1969 tex.DefaultTexture.RepeatU = (float)u; 1969 tex.DefaultTexture.RepeatU = (float)u;
1970 tex.DefaultTexture.RepeatV = (float)v; 1970 tex.DefaultTexture.RepeatV = (float)v;
1971 part.UpdateTextureEntry(tex.GetBytes()); 1971 part.UpdateTextureEntry(tex.GetBytes());
1972 return; 1972 return;
1973 } 1973 }
1974 } 1974 }
1975   1975  
1976 public void llOffsetTexture(double u, double v, int face) 1976 public void llOffsetTexture(double u, double v, int face)
1977 { 1977 {
1978 m_host.AddScriptLPS(1); 1978 m_host.AddScriptLPS(1);
1979 OffsetTexture(m_host, u, v, face); 1979 OffsetTexture(m_host, u, v, face);
1980 ScriptSleep(200); 1980 ScriptSleep(200);
1981 } 1981 }
1982   1982  
1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1984 { 1984 {
1985 Primitive.TextureEntry tex = part.Shape.Textures; 1985 Primitive.TextureEntry tex = part.Shape.Textures;
1986 if (face >= 0 && face < GetNumberOfSides(part)) 1986 if (face >= 0 && face < GetNumberOfSides(part))
1987 { 1987 {
1988 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 1988 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
1989 texface.OffsetU = (float)u; 1989 texface.OffsetU = (float)u;
1990 texface.OffsetV = (float)v; 1990 texface.OffsetV = (float)v;
1991 tex.FaceTextures[face] = texface; 1991 tex.FaceTextures[face] = texface;
1992 part.UpdateTextureEntry(tex.GetBytes()); 1992 part.UpdateTextureEntry(tex.GetBytes());
1993 return; 1993 return;
1994 } 1994 }
1995 if (face == ScriptBaseClass.ALL_SIDES) 1995 if (face == ScriptBaseClass.ALL_SIDES)
1996 { 1996 {
1997 for (int i = 0; i < GetNumberOfSides(part); i++) 1997 for (int i = 0; i < GetNumberOfSides(part); i++)
1998 { 1998 {
1999 if (tex.FaceTextures[i] != null) 1999 if (tex.FaceTextures[i] != null)
2000 { 2000 {
2001 tex.FaceTextures[i].OffsetU = (float)u; 2001 tex.FaceTextures[i].OffsetU = (float)u;
2002 tex.FaceTextures[i].OffsetV = (float)v; 2002 tex.FaceTextures[i].OffsetV = (float)v;
2003 } 2003 }
2004 } 2004 }
2005 tex.DefaultTexture.OffsetU = (float)u; 2005 tex.DefaultTexture.OffsetU = (float)u;
2006 tex.DefaultTexture.OffsetV = (float)v; 2006 tex.DefaultTexture.OffsetV = (float)v;
2007 part.UpdateTextureEntry(tex.GetBytes()); 2007 part.UpdateTextureEntry(tex.GetBytes());
2008 return; 2008 return;
2009 } 2009 }
2010 } 2010 }
2011   2011  
2012 public void llRotateTexture(double rotation, int face) 2012 public void llRotateTexture(double rotation, int face)
2013 { 2013 {
2014 m_host.AddScriptLPS(1); 2014 m_host.AddScriptLPS(1);
2015 RotateTexture(m_host, rotation, face); 2015 RotateTexture(m_host, rotation, face);
2016 ScriptSleep(200); 2016 ScriptSleep(200);
2017 } 2017 }
2018   2018  
2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2020 { 2020 {
2021 Primitive.TextureEntry tex = part.Shape.Textures; 2021 Primitive.TextureEntry tex = part.Shape.Textures;
2022 if (face >= 0 && face < GetNumberOfSides(part)) 2022 if (face >= 0 && face < GetNumberOfSides(part))
2023 { 2023 {
2024 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); 2024 Primitive.TextureEntryFace texface = tex.CreateFace((uint)face);
2025 texface.Rotation = (float)rotation; 2025 texface.Rotation = (float)rotation;
2026 tex.FaceTextures[face] = texface; 2026 tex.FaceTextures[face] = texface;
2027 part.UpdateTextureEntry(tex.GetBytes()); 2027 part.UpdateTextureEntry(tex.GetBytes());
2028 return; 2028 return;
2029 } 2029 }
2030 if (face == ScriptBaseClass.ALL_SIDES) 2030 if (face == ScriptBaseClass.ALL_SIDES)
2031 { 2031 {
2032 for (int i = 0; i < GetNumberOfSides(part); i++) 2032 for (int i = 0; i < GetNumberOfSides(part); i++)
2033 { 2033 {
2034 if (tex.FaceTextures[i] != null) 2034 if (tex.FaceTextures[i] != null)
2035 { 2035 {
2036 tex.FaceTextures[i].Rotation = (float)rotation; 2036 tex.FaceTextures[i].Rotation = (float)rotation;
2037 } 2037 }
2038 } 2038 }
2039 tex.DefaultTexture.Rotation = (float)rotation; 2039 tex.DefaultTexture.Rotation = (float)rotation;
2040 part.UpdateTextureEntry(tex.GetBytes()); 2040 part.UpdateTextureEntry(tex.GetBytes());
2041 return; 2041 return;
2042 } 2042 }
2043 } 2043 }
2044   2044  
2045 public LSL_String llGetTexture(int face) 2045 public LSL_String llGetTexture(int face)
2046 { 2046 {
2047 m_host.AddScriptLPS(1); 2047 m_host.AddScriptLPS(1);
2048 return GetTexture(m_host, face); 2048 return GetTexture(m_host, face);
2049 } 2049 }
2050   2050  
2051 protected LSL_String GetTexture(SceneObjectPart part, int face) 2051 protected LSL_String GetTexture(SceneObjectPart part, int face)
2052 { 2052 {
2053 Primitive.TextureEntry tex = part.Shape.Textures; 2053 Primitive.TextureEntry tex = part.Shape.Textures;
2054 if (face == ScriptBaseClass.ALL_SIDES) 2054 if (face == ScriptBaseClass.ALL_SIDES)
2055 { 2055 {
2056 face = 0; 2056 face = 0;
2057 } 2057 }
2058   2058  
2059 if (face >= 0 && face < GetNumberOfSides(part)) 2059 if (face >= 0 && face < GetNumberOfSides(part))
2060 { 2060 {
2061 Primitive.TextureEntryFace texface; 2061 Primitive.TextureEntryFace texface;
2062 texface = tex.GetFace((uint)face); 2062 texface = tex.GetFace((uint)face);
2063 string texture = texface.TextureID.ToString(); 2063 string texture = texface.TextureID.ToString();
2064   2064  
2065 lock (part.TaskInventory) 2065 lock (part.TaskInventory)
2066 { 2066 {
2067 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory) 2067 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in part.TaskInventory)
2068 { 2068 {
2069 if (inv.Value.AssetID == texface.TextureID) 2069 if (inv.Value.AssetID == texface.TextureID)
2070 { 2070 {
2071 texture = inv.Value.Name.ToString(); 2071 texture = inv.Value.Name.ToString();
2072 break; 2072 break;
2073 } 2073 }
2074 } 2074 }
2075 } 2075 }
2076   2076  
2077 return texture; 2077 return texture;
2078 } 2078 }
2079 else 2079 else
2080 { 2080 {
2081 return UUID.Zero.ToString(); 2081 return UUID.Zero.ToString();
2082 } 2082 }
2083 } 2083 }
2084   2084  
2085 public void llSetPos(LSL_Vector pos) 2085 public void llSetPos(LSL_Vector pos)
2086 { 2086 {
2087 m_host.AddScriptLPS(1); 2087 m_host.AddScriptLPS(1);
2088   2088  
2089 SetPos(m_host, pos, true); 2089 SetPos(m_host, pos, true);
2090   2090  
2091 ScriptSleep(200); 2091 ScriptSleep(200);
2092 } 2092 }
2093   2093  
2094 /// <summary> 2094 /// <summary>
2095 /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos 2095 /// Tries to move the entire object so that the root prim is within 0.1m of position. http://wiki.secondlife.com/wiki/LlSetRegionPos
2096 /// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into. 2096 /// Documentation indicates that the use of x/y coordinates up to 10 meters outside the bounds of a region will work but do not specify what happens if there is no adjacent region for the object to move into.
2097 /// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking. 2097 /// Uses the RegionSize constant here rather than hard-coding 266.0 to alert any developer modifying OpenSim to support variable-sized regions that this method will need tweaking.
2098 /// </summary> 2098 /// </summary>
2099 /// <param name="pos"></param> 2099 /// <param name="pos"></param>
2100 /// <returns>1 if successful, 0 otherwise.</returns> 2100 /// <returns>1 if successful, 0 otherwise.</returns>
2101 public LSL_Integer llSetRegionPos(LSL_Vector pos) 2101 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2102 { 2102 {
2103 m_host.AddScriptLPS(1); 2103 m_host.AddScriptLPS(1);
2104   2104  
2105 // BEGIN WORKAROUND 2105 // BEGIN WORKAROUND
2106 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. 2106 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
2107 // 2107 //
2108 // This workaround is to prevent silent failure of this function. 2108 // This workaround is to prevent silent failure of this function.
2109 // According to the specification on the SL Wiki, providing a position outside of the 2109 // According to the specification on the SL Wiki, providing a position outside of the
2110 if (pos.x < 0 || pos.x > World.RegionInfo.RegionSizeX || pos.y < 0 || pos.y > World.RegionInfo.RegionSizeY) 2110 if (pos.x < 0 || pos.x > World.RegionInfo.RegionSizeX || pos.y < 0 || pos.y > World.RegionInfo.RegionSizeY)
2111 { 2111 {
2112 return 0; 2112 return 0;
2113 } 2113 }
2114 // END WORK AROUND 2114 // END WORK AROUND
2115 else if ( // this is not part of the workaround if-block because it's not related to the workaround. 2115 else if ( // this is not part of the workaround if-block because it's not related to the workaround.
2116 IsPhysical() || 2116 IsPhysical() ||
2117 m_host.ParentGroup.IsAttachment || // return FALSE if attachment 2117 m_host.ParentGroup.IsAttachment || // return FALSE if attachment
2118 ( 2118 (
2119 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region. 2119 pos.x < -10.0 || // return FALSE if more than 10 meters into a west-adjacent region.
2120 pos.x > (World.RegionInfo.RegionSizeX + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2120 pos.x > (World.RegionInfo.RegionSizeX + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2121 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. 2121 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2122 pos.y > (World.RegionInfo.RegionSizeY + 10) || // return FALSE if more than 10 meters into a north-adjacent region. 2122 pos.y > (World.RegionInfo.RegionSizeY + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2123 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m 2123 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2124 ) 2124 )
2125 ) 2125 )
2126 { 2126 {
2127 return 0; 2127 return 0;
2128 } 2128 }
2129   2129  
2130 // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range. 2130 // if we reach this point, then the object is not physical, it's not an attachment, and the destination is within the valid range.
2131 // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read. 2131 // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read.
2132   2132  
2133 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; 2133 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
2134 LandData here = World.GetLandData(objectPos); 2134 LandData here = World.GetLandData(objectPos);
2135 LandData there = World.GetLandData(pos); 2135 LandData there = World.GetLandData(pos);
2136   2136  
2137 // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits. 2137 // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits.
2138   2138  
2139 bool sameParcel = here.GlobalID == there.GlobalID; 2139 bool sameParcel = here.GlobalID == there.GlobalID;
2140   2140  
2141 if (!sameParcel && !World.Permissions.CanRezObject( 2141 if (!sameParcel && !World.Permissions.CanRezObject(
2142 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos)) 2142 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
2143 { 2143 {
2144 return 0; 2144 return 0;
2145 } 2145 }
2146   2146  
2147 SetPos(m_host.ParentGroup.RootPart, pos, false); 2147 SetPos(m_host.ParentGroup.RootPart, pos, false);
2148   2148  
2149 return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0; 2149 return VecDist(pos, llGetRootPosition()) <= 0.1 ? 1 : 0;
2150 } 2150 }
2151   2151  
2152 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2152 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
2153 // note linked setpos is capped "differently" 2153 // note linked setpos is capped "differently"
2154 private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end) 2154 private LSL_Vector SetPosAdjust(LSL_Vector start, LSL_Vector end)
2155 { 2155 {
2156 if (llVecDist(start, end) > 10.0f * m_ScriptDistanceFactor) 2156 if (llVecDist(start, end) > 10.0f * m_ScriptDistanceFactor)
2157 return start + m_ScriptDistanceFactor * 10.0f * llVecNorm(end - start); 2157 return start + m_ScriptDistanceFactor * 10.0f * llVecNorm(end - start);
2158 else 2158 else
2159 return end; 2159 return end;
2160 } 2160 }
2161   2161  
2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
2163 { 2163 {
2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2165 return fromPos; 2165 return fromPos;
2166   2166  
2167 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2167 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
2168   2168  
2169   2169  
2170 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2170 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2171 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2171 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2172   2172  
2173 if (part.ParentGroup.RootPart == part) 2173 if (part.ParentGroup.RootPart == part)
2174 { 2174 {
2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2176 targetPos.z = ground; 2176 targetPos.z = ground;
2177 } 2177 }
2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2179   2179  
2180 return real_vec; 2180 return real_vec;
2181 } 2181 }
2182   2182  
2183 /// <summary> 2183 /// <summary>
2184 /// set object position, optionally capping the distance. 2184 /// set object position, optionally capping the distance.
2185 /// </summary> 2185 /// </summary>
2186 /// <param name="part"></param> 2186 /// <param name="part"></param>
2187 /// <param name="targetPos"></param> 2187 /// <param name="targetPos"></param>
2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2190 { 2190 {
2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
2192 LSL_Vector currentPos = GetPartLocalPos(part); 2192 LSL_Vector currentPos = GetPartLocalPos(part);
2193   2193  
2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2196   2196  
2197 if (part.ParentGroup.RootPart == part) 2197 if (part.ParentGroup.RootPart == part)
2198 { 2198 {
2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2200 targetPos.z = ground; 2200 targetPos.z = ground;
2201 SceneObjectGroup parent = part.ParentGroup; 2201 SceneObjectGroup parent = part.ParentGroup;
2202 parent.UpdateGroupPosition(!adjust ? targetPos : 2202 parent.UpdateGroupPosition(!adjust ? targetPos :
2203 SetPosAdjust(currentPos, targetPos)); 2203 SetPosAdjust(currentPos, targetPos));
2204 } 2204 }
2205 else 2205 else
2206 { 2206 {
2207 part.OffsetPosition = !adjust ? targetPos : 2207 part.OffsetPosition = !adjust ? targetPos :
2208 SetPosAdjust(currentPos, targetPos); 2208 SetPosAdjust(currentPos, targetPos);
2209 SceneObjectGroup parent = part.ParentGroup; 2209 SceneObjectGroup parent = part.ParentGroup;
2210 parent.HasGroupChanged = true; 2210 parent.HasGroupChanged = true;
2211 parent.ScheduleGroupForTerseUpdate(); 2211 parent.ScheduleGroupForTerseUpdate();
2212 } 2212 }
2213 } 2213 }
2214   2214  
2215 public LSL_Vector llGetPos() 2215 public LSL_Vector llGetPos()
2216 { 2216 {
2217 m_host.AddScriptLPS(1); 2217 m_host.AddScriptLPS(1);
2218 return m_host.GetWorldPosition(); 2218 return m_host.GetWorldPosition();
2219 } 2219 }
2220   2220  
2221 public LSL_Vector llGetLocalPos() 2221 public LSL_Vector llGetLocalPos()
2222 { 2222 {
2223 m_host.AddScriptLPS(1); 2223 m_host.AddScriptLPS(1);
2224 return GetPartLocalPos(m_host); 2224 return GetPartLocalPos(m_host);
2225 } 2225 }
2226   2226  
2227 protected LSL_Vector GetPartLocalPos(SceneObjectPart part) 2227 protected LSL_Vector GetPartLocalPos(SceneObjectPart part)
2228 { 2228 {
2229 m_host.AddScriptLPS(1); 2229 m_host.AddScriptLPS(1);
2230   2230  
2231 Vector3 pos; 2231 Vector3 pos;
2232   2232  
2233 if (!part.IsRoot) 2233 if (!part.IsRoot)
2234 { 2234 {
2235 pos = part.OffsetPosition; 2235 pos = part.OffsetPosition;
2236 } 2236 }
2237 else 2237 else
2238 { 2238 {
2239 if (part.ParentGroup.IsAttachment) 2239 if (part.ParentGroup.IsAttachment)
2240 { 2240 {
2241 pos = part.AttachedPos; 2241 pos = part.AttachedPos;
2242 } 2242 }
2243 else 2243 else
2244 { 2244 {
2245 pos = part.AbsolutePosition; 2245 pos = part.AbsolutePosition;
2246 } 2246 }
2247 } 2247 }
2248   2248  
2249 // m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2249 // m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2250   2250  
2251 return new LSL_Vector(pos); 2251 return new LSL_Vector(pos);
2252 } 2252 }
2253   2253  
2254 public void llSetRot(LSL_Rotation rot) 2254 public void llSetRot(LSL_Rotation rot)
2255 { 2255 {
2256 m_host.AddScriptLPS(1); 2256 m_host.AddScriptLPS(1);
2257   2257  
2258 // try to let this work as in SL... 2258 // try to let this work as in SL...
2259 if (m_host.ParentID == 0) 2259 if (m_host.ParentID == 0)
2260 { 2260 {
2261 // special case: If we are root, rotate complete SOG to new rotation 2261 // special case: If we are root, rotate complete SOG to new rotation
2262 SetRot(m_host, rot); 2262 SetRot(m_host, rot);
2263 } 2263 }
2264 else 2264 else
2265 { 2265 {
2266 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2266 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2267 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2267 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2268 if (rootPart != null) // better safe than sorry 2268 if (rootPart != null) // better safe than sorry
2269 { 2269 {
2270 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); 2270 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2271 } 2271 }
2272 } 2272 }
2273   2273  
2274 ScriptSleep(200); 2274 ScriptSleep(200);
2275 } 2275 }
2276   2276  
2277 public void llSetLocalRot(LSL_Rotation rot) 2277 public void llSetLocalRot(LSL_Rotation rot)
2278 { 2278 {
2279 m_host.AddScriptLPS(1); 2279 m_host.AddScriptLPS(1);
2280 SetRot(m_host, rot); 2280 SetRot(m_host, rot);
2281 ScriptSleep(200); 2281 ScriptSleep(200);
2282 } 2282 }
2283   2283  
2284 protected void SetRot(SceneObjectPart part, Quaternion rot) 2284 protected void SetRot(SceneObjectPart part, Quaternion rot)
2285 { 2285 {
2286 part.UpdateRotation(rot); 2286 part.UpdateRotation(rot);
2287 // Update rotation does not move the object in the physics scene if it's a linkset. 2287 // Update rotation does not move the object in the physics scene if it's a linkset.
2288   2288  
2289 //KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2289 //KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type
2290 // part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2290 // part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition;
2291   2291  
2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line 2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt 2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2294 // It's perfectly okay when the object is not an active physical body though. 2294 // It's perfectly okay when the object is not an active physical body though.
2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against 2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2296 // but only if the object is not physial and active. This is important for rotating doors. 2296 // but only if the object is not physial and active. This is important for rotating doors.
2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics 2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2298 // scene 2298 // scene
2299 PhysicsActor pa = part.PhysActor; 2299 PhysicsActor pa = part.PhysActor;
2300   2300  
2301 if (pa != null && !pa.IsPhysical) 2301 if (pa != null && !pa.IsPhysical)
2302 { 2302 {
2303 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2303 part.ParentGroup.ResetChildPrimPhysicsPositions();
2304 } 2304 }
2305 } 2305 }
2306   2306  
2307 /// <summary> 2307 /// <summary>
2308 /// See http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation 2308 /// See http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation
2309 /// </summary> 2309 /// </summary>
2310 public LSL_Rotation llGetRot() 2310 public LSL_Rotation llGetRot()
2311 { 2311 {
2312 // unlinked or root prim then use llRootRotation 2312 // unlinked or root prim then use llRootRotation
2313 // see llRootRotaion for references. 2313 // see llRootRotaion for references.
2314 if (m_host.LinkNum == 0 || m_host.LinkNum == 1) 2314 if (m_host.LinkNum == 0 || m_host.LinkNum == 1)
2315 { 2315 {
2316 return llGetRootRotation(); 2316 return llGetRootRotation();
2317 } 2317 }
2318   2318  
2319 m_host.AddScriptLPS(1); 2319 m_host.AddScriptLPS(1);
2320 Quaternion q = m_host.GetWorldRotation(); 2320 Quaternion q = m_host.GetWorldRotation();
2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2322 } 2322 }
2323   2323  
2324 private LSL_Rotation GetPartRot(SceneObjectPart part) 2324 private LSL_Rotation GetPartRot(SceneObjectPart part)
2325 { 2325 {
2326 Quaternion q; 2326 Quaternion q;
2327 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim 2327 if (part.LinkNum == 0 || part.LinkNum == 1) // unlinked or root prim
2328 { 2328 {
2329 if (part.ParentGroup.AttachmentPoint != 0) 2329 if (part.ParentGroup.AttachmentPoint != 0)
2330 { 2330 {
2331 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar); 2331 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2332 if (avatar != null) 2332 if (avatar != null)
2333 { 2333 {
2334 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2334 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2335 q = avatar.CameraRotation; // Mouselook 2335 q = avatar.CameraRotation; // Mouselook
2336 else 2336 else
2337 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate 2337 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
2338 } 2338 }
2339 else 2339 else
2340 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case 2340 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case
2341 } 2341 }
2342 else 2342 else
2343 q = part.ParentGroup.GroupRotation; // just the group rotation 2343 q = part.ParentGroup.GroupRotation; // just the group rotation
2344   2344  
2345 return new LSL_Rotation(q); 2345 return new LSL_Rotation(q);
2346 } 2346 }
2347   2347  
2348 return new LSL_Rotation(part.GetWorldRotation()); 2348 return new LSL_Rotation(part.GetWorldRotation());
2349 } 2349 }
2350   2350  
2351 public LSL_Rotation llGetLocalRot() 2351 public LSL_Rotation llGetLocalRot()
2352 { 2352 {
2353 m_host.AddScriptLPS(1); 2353 m_host.AddScriptLPS(1);
2354   2354  
2355 return new LSL_Rotation(m_host.RotationOffset); 2355 return new LSL_Rotation(m_host.RotationOffset);
2356 } 2356 }
2357   2357  
2358 public void llSetForce(LSL_Vector force, int local) 2358 public void llSetForce(LSL_Vector force, int local)
2359 { 2359 {
2360 m_host.AddScriptLPS(1); 2360 m_host.AddScriptLPS(1);
2361   2361  
2362 if (!m_host.ParentGroup.IsDeleted) 2362 if (!m_host.ParentGroup.IsDeleted)
2363 { 2363 {
2364 if (local != 0) 2364 if (local != 0)
2365 force *= llGetRot(); 2365 force *= llGetRot();
2366   2366  
2367 m_host.ParentGroup.RootPart.SetForce(force); 2367 m_host.ParentGroup.RootPart.SetForce(force);
2368 } 2368 }
2369 } 2369 }
2370   2370  
2371 public LSL_Vector llGetForce() 2371 public LSL_Vector llGetForce()
2372 { 2372 {
2373 LSL_Vector force = new LSL_Vector(0.0, 0.0, 0.0); 2373 LSL_Vector force = new LSL_Vector(0.0, 0.0, 0.0);
2374   2374  
2375 m_host.AddScriptLPS(1); 2375 m_host.AddScriptLPS(1);
2376   2376  
2377 if (!m_host.ParentGroup.IsDeleted) 2377 if (!m_host.ParentGroup.IsDeleted)
2378 { 2378 {
2379 force = m_host.ParentGroup.RootPart.GetForce(); 2379 force = m_host.ParentGroup.RootPart.GetForce();
2380 } 2380 }
2381   2381  
2382 return force; 2382 return force;
2383 } 2383 }
2384   2384  
2385 public void llSetVelocity(LSL_Vector velocity, int local) 2385 public void llSetVelocity(LSL_Vector velocity, int local)
2386 { 2386 {
2387 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2388   2388  
2389 if (!m_host.ParentGroup.IsDeleted) 2389 if (!m_host.ParentGroup.IsDeleted)
2390 { 2390 {
2391 if (local != 0) 2391 if (local != 0)
2392 velocity *= llGetRot(); 2392 velocity *= llGetRot();
2393   2393  
2394 m_host.ParentGroup.RootPart.Velocity = velocity; 2394 m_host.ParentGroup.RootPart.Velocity = velocity;
2395 } 2395 }
2396 } 2396 }
2397   2397  
2398 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local) 2398 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
2399 { 2399 {
2400 m_host.AddScriptLPS(1); 2400 m_host.AddScriptLPS(1);
2401   2401  
2402 if (!m_host.ParentGroup.IsDeleted) 2402 if (!m_host.ParentGroup.IsDeleted)
2403 { 2403 {
2404 if (local != 0) 2404 if (local != 0)
2405 angularVelocity *= llGetRot(); 2405 angularVelocity *= llGetRot();
2406   2406  
2407 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity; 2407 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2408 } 2408 }
2409 } 2409 }
2410   2410  
2411 public LSL_Integer llTarget(LSL_Vector position, double range) 2411 public LSL_Integer llTarget(LSL_Vector position, double range)
2412 { 2412 {
2413 m_host.AddScriptLPS(1); 2413 m_host.AddScriptLPS(1);
2414 return m_host.ParentGroup.registerTargetWaypoint(position, 2414 return m_host.ParentGroup.registerTargetWaypoint(position,
2415 (float)range); 2415 (float)range);
2416 } 2416 }
2417   2417  
2418 public void llTargetRemove(int number) 2418 public void llTargetRemove(int number)
2419 { 2419 {
2420 m_host.AddScriptLPS(1); 2420 m_host.AddScriptLPS(1);
2421 m_host.ParentGroup.unregisterTargetWaypoint(number); 2421 m_host.ParentGroup.unregisterTargetWaypoint(number);
2422 } 2422 }
2423   2423  
2424 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2424 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2425 { 2425 {
2426 m_host.AddScriptLPS(1); 2426 m_host.AddScriptLPS(1);
2427 return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); 2427 return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error);
2428 } 2428 }
2429   2429  
2430 public void llRotTargetRemove(int number) 2430 public void llRotTargetRemove(int number)
2431 { 2431 {
2432 m_host.AddScriptLPS(1); 2432 m_host.AddScriptLPS(1);
2433 m_host.ParentGroup.unregisterRotTargetWaypoint(number); 2433 m_host.ParentGroup.unregisterRotTargetWaypoint(number);
2434 } 2434 }
2435   2435  
2436 public void llMoveToTarget(LSL_Vector target, double tau) 2436 public void llMoveToTarget(LSL_Vector target, double tau)
2437 { 2437 {
2438 m_host.AddScriptLPS(1); 2438 m_host.AddScriptLPS(1);
2439 m_host.MoveToTarget(target, (float)tau); 2439 m_host.MoveToTarget(target, (float)tau);
2440 } 2440 }
2441   2441  
2442 public void llStopMoveToTarget() 2442 public void llStopMoveToTarget()
2443 { 2443 {
2444 m_host.AddScriptLPS(1); 2444 m_host.AddScriptLPS(1);
2445 m_host.StopMoveToTarget(); 2445 m_host.StopMoveToTarget();
2446 } 2446 }
2447   2447  
2448 public void llApplyImpulse(LSL_Vector force, int local) 2448 public void llApplyImpulse(LSL_Vector force, int local)
2449 { 2449 {
2450 m_host.AddScriptLPS(1); 2450 m_host.AddScriptLPS(1);
2451 //No energy force yet 2451 //No energy force yet
2452 Vector3 v = force; 2452 Vector3 v = force;
2453 if (v.Length() > 20000.0f) 2453 if (v.Length() > 20000.0f)
2454 { 2454 {
2455 v.Normalize(); 2455 v.Normalize();
2456 v = v * 20000.0f; 2456 v = v * 20000.0f;
2457 } 2457 }
2458 m_host.ApplyImpulse(v, local != 0); 2458 m_host.ApplyImpulse(v, local != 0);
2459 } 2459 }
2460   2460  
2461 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2461 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2462 { 2462 {
2463 m_host.AddScriptLPS(1); 2463 m_host.AddScriptLPS(1);
2464 m_host.ApplyAngularImpulse(force, local != 0); 2464 m_host.ApplyAngularImpulse(force, local != 0);
2465 } 2465 }
2466   2466  
2467 public void llSetTorque(LSL_Vector torque, int local) 2467 public void llSetTorque(LSL_Vector torque, int local)
2468 { 2468 {
2469 m_host.AddScriptLPS(1); 2469 m_host.AddScriptLPS(1);
2470 m_host.SetAngularImpulse(torque, local != 0); 2470 m_host.SetAngularImpulse(torque, local != 0);
2471 } 2471 }
2472   2472  
2473 public LSL_Vector llGetTorque() 2473 public LSL_Vector llGetTorque()
2474 { 2474 {
2475 m_host.AddScriptLPS(1); 2475 m_host.AddScriptLPS(1);
2476   2476  
2477 return new LSL_Vector(m_host.ParentGroup.GetTorque()); 2477 return new LSL_Vector(m_host.ParentGroup.GetTorque());
2478 } 2478 }
2479   2479  
2480 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) 2480 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local)
2481 { 2481 {
2482 m_host.AddScriptLPS(1); 2482 m_host.AddScriptLPS(1);
2483 llSetForce(force, local); 2483 llSetForce(force, local);
2484 llSetTorque(torque, local); 2484 llSetTorque(torque, local);
2485 } 2485 }
2486   2486  
2487 public LSL_Vector llGetVel() 2487 public LSL_Vector llGetVel()
2488 { 2488 {
2489 m_host.AddScriptLPS(1); 2489 m_host.AddScriptLPS(1);
2490   2490  
2491 Vector3 vel; 2491 Vector3 vel;
2492   2492  
2493 if (m_host.ParentGroup.IsAttachment) 2493 if (m_host.ParentGroup.IsAttachment)
2494 { 2494 {
2495 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2495 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2496 vel = avatar.Velocity; 2496 vel = avatar.Velocity;
2497 } 2497 }
2498 else 2498 else
2499 { 2499 {
2500 vel = m_host.Velocity; 2500 vel = m_host.Velocity;
2501 } 2501 }
2502   2502  
2503 return new LSL_Vector(vel); 2503 return new LSL_Vector(vel);
2504 } 2504 }
2505   2505  
2506 public LSL_Vector llGetAccel() 2506 public LSL_Vector llGetAccel()
2507 { 2507 {
2508 m_host.AddScriptLPS(1); 2508 m_host.AddScriptLPS(1);
2509   2509  
2510 return new LSL_Vector(m_host.Acceleration); 2510 return new LSL_Vector(m_host.Acceleration);
2511 } 2511 }
2512   2512  
2513 public LSL_Vector llGetOmega() 2513 public LSL_Vector llGetOmega()
2514 { 2514 {
2515 m_host.AddScriptLPS(1); 2515 m_host.AddScriptLPS(1);
2516   2516  
2517 return new LSL_Vector(m_host.AngularVelocity); 2517 return new LSL_Vector(m_host.AngularVelocity);
2518 } 2518 }
2519   2519  
2520 public LSL_Float llGetTimeOfDay() 2520 public LSL_Float llGetTimeOfDay()
2521 { 2521 {
2522 m_host.AddScriptLPS(1); 2522 m_host.AddScriptLPS(1);
2523 return (double)((DateTime.Now.TimeOfDay.TotalMilliseconds / 1000) % (3600 * 4)); 2523 return (double)((DateTime.Now.TimeOfDay.TotalMilliseconds / 1000) % (3600 * 4));
2524 } 2524 }
2525   2525  
2526 public LSL_Float llGetWallclock() 2526 public LSL_Float llGetWallclock()
2527 { 2527 {
2528 m_host.AddScriptLPS(1); 2528 m_host.AddScriptLPS(1);
2529 return DateTime.Now.TimeOfDay.TotalSeconds; 2529 return DateTime.Now.TimeOfDay.TotalSeconds;
2530 } 2530 }
2531   2531  
2532 public LSL_Float llGetTime() 2532 public LSL_Float llGetTime()
2533 { 2533 {
2534 m_host.AddScriptLPS(1); 2534 m_host.AddScriptLPS(1);
2535 TimeSpan ScriptTime = DateTime.Now - m_timer; 2535 TimeSpan ScriptTime = DateTime.Now - m_timer;
2536 return (double)(ScriptTime.TotalMilliseconds / 1000); 2536 return (double)(ScriptTime.TotalMilliseconds / 1000);
2537 } 2537 }
2538   2538  
2539 public void llResetTime() 2539 public void llResetTime()
2540 { 2540 {
2541 m_host.AddScriptLPS(1); 2541 m_host.AddScriptLPS(1);
2542 m_timer = DateTime.Now; 2542 m_timer = DateTime.Now;
2543 } 2543 }
2544   2544  
2545 public LSL_Float llGetAndResetTime() 2545 public LSL_Float llGetAndResetTime()
2546 { 2546 {
2547 m_host.AddScriptLPS(1); 2547 m_host.AddScriptLPS(1);
2548 TimeSpan ScriptTime = DateTime.Now - m_timer; 2548 TimeSpan ScriptTime = DateTime.Now - m_timer;
2549 m_timer = DateTime.Now; 2549 m_timer = DateTime.Now;
2550 return (double)(ScriptTime.TotalMilliseconds / 1000); 2550 return (double)(ScriptTime.TotalMilliseconds / 1000);
2551 } 2551 }
2552   2552  
2553 public void llSound(string sound, double volume, int queue, int loop) 2553 public void llSound(string sound, double volume, int queue, int loop)
2554 { 2554 {
2555 m_host.AddScriptLPS(1); 2555 m_host.AddScriptLPS(1);
2556 Deprecated("llSound", "Use llPlaySound instead"); 2556 Deprecated("llSound", "Use llPlaySound instead");
2557 } 2557 }
2558   2558  
2559 // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound 2559 // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound
2560 // 20080530 Updated to remove code duplication 2560 // 20080530 Updated to remove code duplication
2561 public void llPlaySound(string sound, double volume) 2561 public void llPlaySound(string sound, double volume)
2562 { 2562 {
2563 m_host.AddScriptLPS(1); 2563 m_host.AddScriptLPS(1);
2564   2564  
2565 // send the sound, once, to all clients in range 2565 // send the sound, once, to all clients in range
2566 if (m_SoundModule != null) 2566 if (m_SoundModule != null)
2567 { 2567 {
2568 m_SoundModule.SendSound( 2568 m_SoundModule.SendSound(
2569 m_host.UUID, 2569 m_host.UUID,
2570 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), 2570 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2571 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, 2571 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None,
2572 0, false, false); 2572 0, false, false);
2573 } 2573 }
2574 } 2574 }
2575   2575  
2576 public void llLoopSound(string sound, double volume) 2576 public void llLoopSound(string sound, double volume)
2577 { 2577 {
2578 m_host.AddScriptLPS(1); 2578 m_host.AddScriptLPS(1);
2579 if (m_SoundModule != null) 2579 if (m_SoundModule != null)
2580 { 2580 {
2581 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 2581 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2582 volume, 20, false); 2582 volume, 20, false);
2583 } 2583 }
2584 } 2584 }
2585   2585  
2586 public void llLoopSoundMaster(string sound, double volume) 2586 public void llLoopSoundMaster(string sound, double volume)
2587 { 2587 {
2588 m_host.AddScriptLPS(1); 2588 m_host.AddScriptLPS(1);
2589 if (m_SoundModule != null) 2589 if (m_SoundModule != null)
2590 { 2590 {
2591 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 2591 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2592 volume, 20, true); 2592 volume, 20, true);
2593 } 2593 }
2594 } 2594 }
2595   2595  
2596 public void llLoopSoundSlave(string sound, double volume) 2596 public void llLoopSoundSlave(string sound, double volume)
2597 { 2597 {
2598 m_host.AddScriptLPS(1); 2598 m_host.AddScriptLPS(1);
2599 lock (m_host.ParentGroup.LoopSoundSlavePrims) 2599 lock (m_host.ParentGroup.LoopSoundSlavePrims)
2600 { 2600 {
2601 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); 2601 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host);
2602 } 2602 }
2603 } 2603 }
2604   2604  
2605 public void llPlaySoundSlave(string sound, double volume) 2605 public void llPlaySoundSlave(string sound, double volume)
2606 { 2606 {
2607 m_host.AddScriptLPS(1); 2607 m_host.AddScriptLPS(1);
2608   2608  
2609 // send the sound, once, to all clients in range 2609 // send the sound, once, to all clients in range
2610 if (m_SoundModule != null) 2610 if (m_SoundModule != null)
2611 { 2611 {
2612 m_SoundModule.SendSound(m_host.UUID, 2612 m_SoundModule.SendSound(m_host.UUID,
2613 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, 2613 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2614 0, true, false); 2614 0, true, false);
2615 } 2615 }
2616 } 2616 }
2617   2617  
2618 public void llTriggerSound(string sound, double volume) 2618 public void llTriggerSound(string sound, double volume)
2619 { 2619 {
2620 m_host.AddScriptLPS(1); 2620 m_host.AddScriptLPS(1);
2621 // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. 2621 // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory.
2622 if (m_SoundModule != null) 2622 if (m_SoundModule != null)
2623 { 2623 {
2624 m_SoundModule.SendSound(m_host.UUID, 2624 m_SoundModule.SendSound(m_host.UUID,
2625 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0, 2625 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0,
2626 false, false); 2626 false, false);
2627 } 2627 }
2628 } 2628 }
2629   2629  
2630 public void llStopSound() 2630 public void llStopSound()
2631 { 2631 {
2632 m_host.AddScriptLPS(1); 2632 m_host.AddScriptLPS(1);
2633   2633  
2634 if (m_SoundModule != null) 2634 if (m_SoundModule != null)
2635 m_SoundModule.StopSound(m_host.UUID); 2635 m_SoundModule.StopSound(m_host.UUID);
2636 } 2636 }
2637   2637  
2638 public void llPreloadSound(string sound) 2638 public void llPreloadSound(string sound)
2639 { 2639 {
2640 m_host.AddScriptLPS(1); 2640 m_host.AddScriptLPS(1);
2641 if (m_SoundModule != null) 2641 if (m_SoundModule != null)
2642 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); 2642 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0);
2643 ScriptSleep(1000); 2643 ScriptSleep(1000);
2644 } 2644 }
2645   2645  
2646 /// <summary> 2646 /// <summary>
2647 /// Return a portion of the designated string bounded by 2647 /// Return a portion of the designated string bounded by
2648 /// inclusive indices (start and end). As usual, the negative 2648 /// inclusive indices (start and end). As usual, the negative
2649 /// indices, and the tolerance for out-of-bound values, makes 2649 /// indices, and the tolerance for out-of-bound values, makes
2650 /// this more complicated than it might otherwise seem. 2650 /// this more complicated than it might otherwise seem.
2651 /// </summary> 2651 /// </summary>
2652 public LSL_String llGetSubString(string src, int start, int end) 2652 public LSL_String llGetSubString(string src, int start, int end)
2653 { 2653 {
2654 m_host.AddScriptLPS(1); 2654 m_host.AddScriptLPS(1);
2655   2655  
2656 // Normalize indices (if negative). 2656 // Normalize indices (if negative).
2657 // After normlaization they may still be 2657 // After normlaization they may still be
2658 // negative, but that is now relative to 2658 // negative, but that is now relative to
2659 // the start, rather than the end, of the 2659 // the start, rather than the end, of the
2660 // sequence. 2660 // sequence.
2661   2661  
2662 if (start < 0) 2662 if (start < 0)
2663 { 2663 {
2664 start = src.Length+start; 2664 start = src.Length+start;
2665 } 2665 }
2666 if (end < 0) 2666 if (end < 0)
2667 { 2667 {
2668 end = src.Length+end; 2668 end = src.Length+end;
2669 } 2669 }
2670   2670  
2671 // Conventional substring 2671 // Conventional substring
2672 if (start <= end) 2672 if (start <= end)
2673 { 2673 {
2674 // Implies both bounds are out-of-range. 2674 // Implies both bounds are out-of-range.
2675 if (end < 0 || start >= src.Length) 2675 if (end < 0 || start >= src.Length)
2676 { 2676 {
2677 return String.Empty; 2677 return String.Empty;
2678 } 2678 }
2679 // If end is positive, then it directly 2679 // If end is positive, then it directly
2680 // corresponds to the lengt of the substring 2680 // corresponds to the lengt of the substring
2681 // needed (plus one of course). BUT, it 2681 // needed (plus one of course). BUT, it
2682 // must be within bounds. 2682 // must be within bounds.
2683 if (end >= src.Length) 2683 if (end >= src.Length)
2684 { 2684 {
2685 end = src.Length-1; 2685 end = src.Length-1;
2686 } 2686 }
2687   2687  
2688 if (start < 0) 2688 if (start < 0)
2689 { 2689 {
2690 return src.Substring(0,end+1); 2690 return src.Substring(0,end+1);
2691 } 2691 }
2692 // Both indices are positive 2692 // Both indices are positive
2693 return src.Substring(start, (end+1) - start); 2693 return src.Substring(start, (end+1) - start);
2694 } 2694 }
2695   2695  
2696 // Inverted substring (end < start) 2696 // Inverted substring (end < start)
2697 else 2697 else
2698 { 2698 {
2699 // Implies both indices are below the 2699 // Implies both indices are below the
2700 // lower bound. In the inverted case, that 2700 // lower bound. In the inverted case, that
2701 // means the entire string will be returned 2701 // means the entire string will be returned
2702 // unchanged. 2702 // unchanged.
2703 if (start < 0) 2703 if (start < 0)
2704 { 2704 {
2705 return src; 2705 return src;
2706 } 2706 }
2707 // If both indices are greater than the upper 2707 // If both indices are greater than the upper
2708 // bound the result may seem initially counter 2708 // bound the result may seem initially counter
2709 // intuitive. 2709 // intuitive.
2710 if (end >= src.Length) 2710 if (end >= src.Length)
2711 { 2711 {
2712 return src; 2712 return src;
2713 } 2713 }
2714   2714  
2715 if (end < 0) 2715 if (end < 0)
2716 { 2716 {
2717 if (start < src.Length) 2717 if (start < src.Length)
2718 { 2718 {
2719 return src.Substring(start); 2719 return src.Substring(start);
2720 } 2720 }
2721 else 2721 else
2722 { 2722 {
2723 return String.Empty; 2723 return String.Empty;
2724 } 2724 }
2725 } 2725 }
2726 else 2726 else
2727 { 2727 {
2728 if (start < src.Length) 2728 if (start < src.Length)
2729 { 2729 {
2730 return src.Substring(0,end+1) + src.Substring(start); 2730 return src.Substring(0,end+1) + src.Substring(start);
2731 } 2731 }
2732 else 2732 else
2733 { 2733 {
2734 return src.Substring(0,end+1); 2734 return src.Substring(0,end+1);
2735 } 2735 }
2736 } 2736 }
2737 } 2737 }
2738 } 2738 }
2739   2739  
2740 /// <summary> 2740 /// <summary>
2741 /// Delete substring removes the specified substring bounded 2741 /// Delete substring removes the specified substring bounded
2742 /// by the inclusive indices start and end. Indices may be 2742 /// by the inclusive indices start and end. Indices may be
2743 /// negative (indicating end-relative) and may be inverted, 2743 /// negative (indicating end-relative) and may be inverted,
2744 /// i.e. end < start. 2744 /// i.e. end < start.
2745 /// </summary> 2745 /// </summary>
2746 public LSL_String llDeleteSubString(string src, int start, int end) 2746 public LSL_String llDeleteSubString(string src, int start, int end)
2747 { 2747 {
2748 m_host.AddScriptLPS(1); 2748 m_host.AddScriptLPS(1);
2749   2749  
2750 // Normalize indices (if negative). 2750 // Normalize indices (if negative).
2751 // After normlaization they may still be 2751 // After normlaization they may still be
2752 // negative, but that is now relative to 2752 // negative, but that is now relative to
2753 // the start, rather than the end, of the 2753 // the start, rather than the end, of the
2754 // sequence. 2754 // sequence.
2755 if (start < 0) 2755 if (start < 0)
2756 { 2756 {
2757 start = src.Length+start; 2757 start = src.Length+start;
2758 } 2758 }
2759 if (end < 0) 2759 if (end < 0)
2760 { 2760 {
2761 end = src.Length+end; 2761 end = src.Length+end;
2762 } 2762 }
2763 // Conventionally delimited substring 2763 // Conventionally delimited substring
2764 if (start <= end) 2764 if (start <= end)
2765 { 2765 {
2766 // If both bounds are outside of the existing 2766 // If both bounds are outside of the existing
2767 // string, then return unchanges. 2767 // string, then return unchanges.
2768 if (end < 0 || start >= src.Length) 2768 if (end < 0 || start >= src.Length)
2769 { 2769 {
2770 return src; 2770 return src;
2771 } 2771 }
2772 // At least one bound is in-range, so we 2772 // At least one bound is in-range, so we
2773 // need to clip the out-of-bound argument. 2773 // need to clip the out-of-bound argument.
2774 if (start < 0) 2774 if (start < 0)
2775 { 2775 {
2776 start = 0; 2776 start = 0;
2777 } 2777 }
2778   2778  
2779 if (end >= src.Length) 2779 if (end >= src.Length)
2780 { 2780 {
2781 end = src.Length-1; 2781 end = src.Length-1;
2782 } 2782 }
2783   2783  
2784 return src.Remove(start,end-start+1); 2784 return src.Remove(start,end-start+1);
2785 } 2785 }
2786 // Inverted substring 2786 // Inverted substring
2787 else 2787 else
2788 { 2788 {
2789 // In this case, out of bounds means that 2789 // In this case, out of bounds means that
2790 // the existing string is part of the cut. 2790 // the existing string is part of the cut.
2791 if (start < 0 || end >= src.Length) 2791 if (start < 0 || end >= src.Length)
2792 { 2792 {
2793 return String.Empty; 2793 return String.Empty;
2794 } 2794 }
2795   2795  
2796 if (end > 0) 2796 if (end > 0)
2797 { 2797 {
2798 if (start < src.Length) 2798 if (start < src.Length)
2799 { 2799 {
2800 return src.Remove(start).Remove(0,end+1); 2800 return src.Remove(start).Remove(0,end+1);
2801 } 2801 }
2802 else 2802 else
2803 { 2803 {
2804 return src.Remove(0,end+1); 2804 return src.Remove(0,end+1);
2805 } 2805 }
2806 } 2806 }
2807 else 2807 else
2808 { 2808 {
2809 if (start < src.Length) 2809 if (start < src.Length)
2810 { 2810 {
2811 return src.Remove(start); 2811 return src.Remove(start);
2812 } 2812 }
2813 else 2813 else
2814 { 2814 {
2815 return src; 2815 return src;
2816 } 2816 }
2817 } 2817 }
2818 } 2818 }
2819 } 2819 }
2820   2820  
2821 /// <summary> 2821 /// <summary>
2822 /// Insert string inserts the specified string identified by src 2822 /// Insert string inserts the specified string identified by src
2823 /// at the index indicated by index. Index may be negative, in 2823 /// at the index indicated by index. Index may be negative, in
2824 /// which case it is end-relative. The index may exceed either 2824 /// which case it is end-relative. The index may exceed either
2825 /// string bound, with the result being a concatenation. 2825 /// string bound, with the result being a concatenation.
2826 /// </summary> 2826 /// </summary>
2827 public LSL_String llInsertString(string dest, int index, string src) 2827 public LSL_String llInsertString(string dest, int index, string src)
2828 { 2828 {
2829 m_host.AddScriptLPS(1); 2829 m_host.AddScriptLPS(1);
2830   2830  
2831 // Normalize indices (if negative). 2831 // Normalize indices (if negative).
2832 // After normlaization they may still be 2832 // After normlaization they may still be
2833 // negative, but that is now relative to 2833 // negative, but that is now relative to
2834 // the start, rather than the end, of the 2834 // the start, rather than the end, of the
2835 // sequence. 2835 // sequence.
2836 if (index < 0) 2836 if (index < 0)
2837 { 2837 {
2838 index = dest.Length+index; 2838 index = dest.Length+index;
2839   2839  
2840 // Negative now means it is less than the lower 2840 // Negative now means it is less than the lower
2841 // bound of the string. 2841 // bound of the string.
2842   2842  
2843 if (index < 0) 2843 if (index < 0)
2844 { 2844 {
2845 return src+dest; 2845 return src+dest;
2846 } 2846 }
2847   2847  
2848 } 2848 }
2849   2849  
2850 if (index >= dest.Length) 2850 if (index >= dest.Length)
2851 { 2851 {
2852 return dest+src; 2852 return dest+src;
2853 } 2853 }
2854   2854  
2855 // The index is in bounds. 2855 // The index is in bounds.
2856 // In this case the index refers to the index that will 2856 // In this case the index refers to the index that will
2857 // be assigned to the first character of the inserted string. 2857 // be assigned to the first character of the inserted string.
2858 // So unlike the other string operations, we do not add one 2858 // So unlike the other string operations, we do not add one
2859 // to get the correct string length. 2859 // to get the correct string length.
2860 return dest.Substring(0,index)+src+dest.Substring(index); 2860 return dest.Substring(0,index)+src+dest.Substring(index);
2861   2861  
2862 } 2862 }
2863   2863  
2864 public LSL_String llToUpper(string src) 2864 public LSL_String llToUpper(string src)
2865 { 2865 {
2866 m_host.AddScriptLPS(1); 2866 m_host.AddScriptLPS(1);
2867 return src.ToUpper(); 2867 return src.ToUpper();
2868 } 2868 }
2869   2869  
2870 public LSL_String llToLower(string src) 2870 public LSL_String llToLower(string src)
2871 { 2871 {
2872 m_host.AddScriptLPS(1); 2872 m_host.AddScriptLPS(1);
2873 return src.ToLower(); 2873 return src.ToLower();
2874 } 2874 }
2875   2875  
2876 public void llGiveMoney(string destination, int amount) 2876 public void llGiveMoney(string destination, int amount)
2877 { 2877 {
2878 Util.FireAndForget(x => 2878 Util.FireAndForget(x =>
2879 { 2879 {
2880 m_host.AddScriptLPS(1); 2880 m_host.AddScriptLPS(1);
2881   2881  
2882 if (m_item.PermsGranter == UUID.Zero) 2882 if (m_item.PermsGranter == UUID.Zero)
2883 return; 2883 return;
2884   2884  
2885 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) 2885 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
2886 { 2886 {
2887 Error("llGiveMoney", "No permissions to give money"); 2887 Error("llGiveMoney", "No permissions to give money");
2888 return; 2888 return;
2889 } 2889 }
2890   2890  
2891 UUID toID = new UUID(); 2891 UUID toID = new UUID();
2892   2892  
2893 if (!UUID.TryParse(destination, out toID)) 2893 if (!UUID.TryParse(destination, out toID))
2894 { 2894 {
2895 Error("llGiveMoney", "Bad key in llGiveMoney"); 2895 Error("llGiveMoney", "Bad key in llGiveMoney");
2896 return; 2896 return;
2897 } 2897 }
2898   2898  
2899 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); 2899 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
2900   2900  
2901 if (money == null) 2901 if (money == null)
2902 { 2902 {
2903 NotImplemented("llGiveMoney"); 2903 NotImplemented("llGiveMoney");
2904 return; 2904 return;
2905 } 2905 }
2906   2906  
2907 money.ObjectGiveMoney( 2907 money.ObjectGiveMoney(
2908 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 2908 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
2909 }); 2909 });
2910 } 2910 }
2911   2911  
2912 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2912 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2913 { 2913 {
2914 m_host.AddScriptLPS(1); 2914 m_host.AddScriptLPS(1);
2915 Deprecated("llMakeExplosion", "Use llParticleSystem instead"); 2915 Deprecated("llMakeExplosion", "Use llParticleSystem instead");
2916 ScriptSleep(100); 2916 ScriptSleep(100);
2917 } 2917 }
2918   2918  
2919 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) 2919 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset)
2920 { 2920 {
2921 m_host.AddScriptLPS(1); 2921 m_host.AddScriptLPS(1);
2922 Deprecated("llMakeFountain", "Use llParticleSystem instead"); 2922 Deprecated("llMakeFountain", "Use llParticleSystem instead");
2923 ScriptSleep(100); 2923 ScriptSleep(100);
2924 } 2924 }
2925   2925  
2926 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2926 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2927 { 2927 {
2928 m_host.AddScriptLPS(1); 2928 m_host.AddScriptLPS(1);
2929 Deprecated("llMakeSmoke", "Use llParticleSystem instead"); 2929 Deprecated("llMakeSmoke", "Use llParticleSystem instead");
2930 ScriptSleep(100); 2930 ScriptSleep(100);
2931 } 2931 }
2932   2932  
2933 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2933 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2934 { 2934 {
2935 m_host.AddScriptLPS(1); 2935 m_host.AddScriptLPS(1);
2936 Deprecated("llMakeFire", "Use llParticleSystem instead"); 2936 Deprecated("llMakeFire", "Use llParticleSystem instead");
2937 ScriptSleep(100); 2937 ScriptSleep(100);
2938 } 2938 }
2939   2939  
2940 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 2940 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
2941 { 2941 {
2942 m_host.AddScriptLPS(1); 2942 m_host.AddScriptLPS(1);
2943   2943  
2944 Util.FireAndForget(x => 2944 Util.FireAndForget(x =>
2945 { 2945 {
2946 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) 2946 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
2947 return; 2947 return;
2948   2948  
2949 float dist = (float)llVecDist(llGetPos(), pos); 2949 float dist = (float)llVecDist(llGetPos(), pos);
2950   2950  
2951 if (dist > m_ScriptDistanceFactor * 10.0f) 2951 if (dist > m_ScriptDistanceFactor * 10.0f)
2952 return; 2952 return;
2953   2953  
2954 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); 2954 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
2955   2955  
2956 if (item == null) 2956 if (item == null)
2957 { 2957 {
2958 Error("llRezAtRoot", "Can't find object '" + inventory + "'"); 2958 Error("llRezAtRoot", "Can't find object '" + inventory + "'");
2959 return; 2959 return;
2960 } 2960 }
2961   2961  
2962 if (item.InvType != (int)InventoryType.Object) 2962 if (item.InvType != (int)InventoryType.Object)
2963 { 2963 {
2964 Error("llRezAtRoot", "Can't create requested object; object is missing from database"); 2964 Error("llRezAtRoot", "Can't create requested object; object is missing from database");
2965 return; 2965 return;
2966 } 2966 }
2967   2967  
2968 // need the magnitude later 2968 // need the magnitude later
2969 // float velmag = (float)Util.GetMagnitude(llvel); 2969 // float velmag = (float)Util.GetMagnitude(llvel);
2970   2970  
2971 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param); 2971 List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param);
2972   2972  
2973 // If either of these are null, then there was an unknown error. 2973 // If either of these are null, then there was an unknown error.
2974 if (new_groups == null) 2974 if (new_groups == null)
2975 return; 2975 return;
2976   2976  
2977 foreach (SceneObjectGroup group in new_groups) 2977 foreach (SceneObjectGroup group in new_groups)
2978 { 2978 {
2979 // objects rezzed with this method are die_at_edge by default. 2979 // objects rezzed with this method are die_at_edge by default.
2980 group.RootPart.SetDieAtEdge(true); 2980 group.RootPart.SetDieAtEdge(true);
2981   2981  
2982 group.ResumeScripts(); 2982 group.ResumeScripts();
2983   2983  
2984 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( 2984 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
2985 "object_rez", new Object[] { 2985 "object_rez", new Object[] {
2986 new LSL_String( 2986 new LSL_String(
2987 group.RootPart.UUID.ToString()) }, 2987 group.RootPart.UUID.ToString()) },
2988 new DetectParams[0])); 2988 new DetectParams[0]));
2989   2989  
2990 float groupmass = group.GetMass(); 2990 float groupmass = group.GetMass();
2991   2991  
2992 PhysicsActor pa = group.RootPart.PhysActor; 2992 PhysicsActor pa = group.RootPart.PhysActor;
2993   2993  
2994 //Recoil. 2994 //Recoil.
2995 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 2995 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2996 { 2996 {
2997 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 2997 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2998 if (recoil != Vector3.Zero) 2998 if (recoil != Vector3.Zero)
2999 { 2999 {
3000 llApplyImpulse(recoil, 0); 3000 llApplyImpulse(recoil, 0);
3001 } 3001 }
3002 } 3002 }
3003 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3003 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3004 } 3004 }
3005 }); 3005 });
3006   3006  
3007 //ScriptSleep((int)((groupmass * velmag) / 10)); 3007 //ScriptSleep((int)((groupmass * velmag) / 10));
3008 ScriptSleep(100); 3008 ScriptSleep(100);
3009 } 3009 }
3010   3010  
3011 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3011 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3012 { 3012 {
3013 llRezAtRoot(inventory, pos, vel, rot, param); 3013 llRezAtRoot(inventory, pos, vel, rot, param);
3014 } 3014 }
3015   3015  
3016 public void llLookAt(LSL_Vector target, double strength, double damping) 3016 public void llLookAt(LSL_Vector target, double strength, double damping)
3017 { 3017 {
3018 m_host.AddScriptLPS(1); 3018 m_host.AddScriptLPS(1);
3019 // Determine where we are looking from 3019 // Determine where we are looking from
3020 LSL_Vector from = llGetPos(); 3020 LSL_Vector from = llGetPos();
3021   3021  
3022 // Work out the normalised vector from the source to the target 3022 // Work out the normalised vector from the source to the target
3023 LSL_Vector delta = llVecNorm(target - from); 3023 LSL_Vector delta = llVecNorm(target - from);
3024 LSL_Vector angle = new LSL_Vector(0,0,0); 3024 LSL_Vector angle = new LSL_Vector(0,0,0);
3025   3025  
3026 // Calculate the yaw 3026 // Calculate the yaw
3027 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3027 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system
3028 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3028 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
3029   3029  
3030 // Calculate pitch 3030 // Calculate pitch
3031 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3031 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z)));
3032   3032  
3033 // we need to convert from a vector describing 3033 // we need to convert from a vector describing
3034 // the angles of rotation in radians into rotation value 3034 // the angles of rotation in radians into rotation value
3035 LSL_Rotation rot = llEuler2Rot(angle); 3035 LSL_Rotation rot = llEuler2Rot(angle);
3036   3036  
3037 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3037 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3038 // set the rotation of the object, copy that behavior 3038 // set the rotation of the object, copy that behavior
3039 PhysicsActor pa = m_host.PhysActor; 3039 PhysicsActor pa = m_host.PhysActor;
3040   3040  
3041 if (strength == 0 || pa == null || !pa.IsPhysical) 3041 if (strength == 0 || pa == null || !pa.IsPhysical)
3042 { 3042 {
3043 llSetRot(rot); 3043 llSetRot(rot);
3044 } 3044 }
3045 else 3045 else
3046 { 3046 {
3047 m_host.StartLookAt(rot, (float)strength, (float)damping); 3047 m_host.StartLookAt(rot, (float)strength, (float)damping);
3048 } 3048 }
3049 } 3049 }
3050   3050  
3051 public void llStopLookAt() 3051 public void llStopLookAt()
3052 { 3052 {
3053 m_host.AddScriptLPS(1); 3053 m_host.AddScriptLPS(1);
3054 m_host.StopLookAt(); 3054 m_host.StopLookAt();
3055 } 3055 }
3056   3056  
3057 public void llSetTimerEvent(double sec) 3057 public void llSetTimerEvent(double sec)
3058 { 3058 {
3059 if (sec != 0.0 && sec < m_MinTimerInterval) 3059 if (sec != 0.0 && sec < m_MinTimerInterval)
3060 sec = m_MinTimerInterval; 3060 sec = m_MinTimerInterval;
3061 m_host.AddScriptLPS(1); 3061 m_host.AddScriptLPS(1);
3062 // Setting timer repeat 3062 // Setting timer repeat
3063 AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec); 3063 AsyncCommands.TimerPlugin.SetTimerEvent(m_host.LocalId, m_item.ItemID, sec);
3064 } 3064 }
3065   3065  
3066 public virtual void llSleep(double sec) 3066 public virtual void llSleep(double sec)
3067 { 3067 {
3068 // m_log.Info("llSleep snoozing " + sec + "s."); 3068 // m_log.Info("llSleep snoozing " + sec + "s.");
3069 m_host.AddScriptLPS(1); 3069 m_host.AddScriptLPS(1);
3070   3070  
3071 Sleep((int)(sec * 1000)); 3071 Sleep((int)(sec * 1000));
3072 } 3072 }
3073   3073  
3074 public LSL_Float llGetMass() 3074 public LSL_Float llGetMass()
3075 { 3075 {
3076 m_host.AddScriptLPS(1); 3076 m_host.AddScriptLPS(1);
3077   3077  
3078 if (m_host.ParentGroup.IsAttachment) 3078 if (m_host.ParentGroup.IsAttachment)
3079 { 3079 {
3080 ScenePresence attachedAvatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 3080 ScenePresence attachedAvatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
3081   3081  
3082 if (attachedAvatar != null) 3082 if (attachedAvatar != null)
3083 { 3083 {
3084 return attachedAvatar.GetMass(); 3084 return attachedAvatar.GetMass();
3085 } 3085 }
3086 else 3086 else
3087 { 3087 {
3088 return 0; 3088 return 0;
3089 } 3089 }
3090 } 3090 }
3091 else 3091 else
3092 { 3092 {
3093 if (m_host.IsRoot) 3093 if (m_host.IsRoot)
3094 { 3094 {
3095 return m_host.ParentGroup.GetMass(); 3095 return m_host.ParentGroup.GetMass();
3096 } 3096 }
3097 else 3097 else
3098 { 3098 {
3099 return m_host.GetMass(); 3099 return m_host.GetMass();
3100 } 3100 }
3101 } 3101 }
3102 } 3102 }
3103   3103  
3104 public void llCollisionFilter(string name, string id, int accept) 3104 public void llCollisionFilter(string name, string id, int accept)
3105 { 3105 {
3106 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
3107 m_host.CollisionFilter.Clear(); 3107 m_host.CollisionFilter.Clear();
3108 UUID objectID; 3108 UUID objectID;
3109   3109  
3110 if (!UUID.TryParse(id, out objectID)) 3110 if (!UUID.TryParse(id, out objectID))
3111 objectID = UUID.Zero; 3111 objectID = UUID.Zero;
3112   3112  
3113 if (objectID == UUID.Zero && name == "") 3113 if (objectID == UUID.Zero && name == "")
3114 return; 3114 return;
3115   3115  
3116 m_host.CollisionFilter.Add(accept,objectID.ToString() + name); 3116 m_host.CollisionFilter.Add(accept,objectID.ToString() + name);
3117 } 3117 }
3118   3118  
3119 public void llTakeControls(int controls, int accept, int pass_on) 3119 public void llTakeControls(int controls, int accept, int pass_on)
3120 { 3120 {
3121 if (m_item.PermsGranter != UUID.Zero) 3121 if (m_item.PermsGranter != UUID.Zero)
3122 { 3122 {
3123 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3123 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3124   3124  
3125 if (presence != null) 3125 if (presence != null)
3126 { 3126 {
3127 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 3127 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
3128 { 3128 {
3129 presence.RegisterControlEventsToScript(controls, accept, pass_on, m_host.LocalId, m_item.ItemID); 3129 presence.RegisterControlEventsToScript(controls, accept, pass_on, m_host.LocalId, m_item.ItemID);
3130 } 3130 }
3131 } 3131 }
3132 } 3132 }
3133   3133  
3134 m_host.AddScriptLPS(1); 3134 m_host.AddScriptLPS(1);
3135 } 3135 }
3136   3136  
3137 public void llReleaseControls() 3137 public void llReleaseControls()
3138 { 3138 {
3139 m_host.AddScriptLPS(1); 3139 m_host.AddScriptLPS(1);
3140   3140  
3141 if (m_item.PermsGranter != UUID.Zero) 3141 if (m_item.PermsGranter != UUID.Zero)
3142 { 3142 {
3143 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3143 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3144   3144  
3145 if (presence != null) 3145 if (presence != null)
3146 { 3146 {
3147 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 3147 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
3148 { 3148 {
3149 // Unregister controls from Presence 3149 // Unregister controls from Presence
3150 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3150 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3151 // Remove Take Control permission. 3151 // Remove Take Control permission.
3152 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3152 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3153 } 3153 }
3154 } 3154 }
3155 } 3155 }
3156 } 3156 }
3157   3157  
3158 public void llReleaseURL(string url) 3158 public void llReleaseURL(string url)
3159 { 3159 {
3160 m_host.AddScriptLPS(1); 3160 m_host.AddScriptLPS(1);
3161 if (m_UrlModule != null) 3161 if (m_UrlModule != null)
3162 m_UrlModule.ReleaseURL(url); 3162 m_UrlModule.ReleaseURL(url);
3163 } 3163 }
3164   3164  
3165 /// <summary> 3165 /// <summary>
3166 /// Attach the object containing this script to the avatar that owns it. 3166 /// Attach the object containing this script to the avatar that owns it.
3167 /// </summary> 3167 /// </summary>
3168 /// <param name='attachmentPoint'> 3168 /// <param name='attachmentPoint'>
3169 /// The attachment point (e.g. <see cref="OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass.ATTACH_CHEST">ATTACH_CHEST</see>) 3169 /// The attachment point (e.g. <see cref="OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass.ATTACH_CHEST">ATTACH_CHEST</see>)
3170 /// </param> 3170 /// </param>
3171 /// <returns>true if the attach suceeded, false if it did not</returns> 3171 /// <returns>true if the attach suceeded, false if it did not</returns>
3172 public bool AttachToAvatar(int attachmentPoint) 3172 public bool AttachToAvatar(int attachmentPoint)
3173 { 3173 {
3174 SceneObjectGroup grp = m_host.ParentGroup; 3174 SceneObjectGroup grp = m_host.ParentGroup;
3175 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3175 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
3176   3176  
3177 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3177 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3178   3178  
3179 if (attachmentsModule != null) 3179 if (attachmentsModule != null)
3180 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3180 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true);
3181 else 3181 else
3182 return false; 3182 return false;
3183 } 3183 }
3184   3184  
3185 /// <summary> 3185 /// <summary>
3186 /// Detach the object containing this script from the avatar it is attached to. 3186 /// Detach the object containing this script from the avatar it is attached to.
3187 /// </summary> 3187 /// </summary>
3188 /// <remarks> 3188 /// <remarks>
3189 /// Nothing happens if the object is not attached. 3189 /// Nothing happens if the object is not attached.
3190 /// </remarks> 3190 /// </remarks>
3191 public void DetachFromAvatar() 3191 public void DetachFromAvatar()
3192 { 3192 {
3193 Util.FireAndForget(DetachWrapper, m_host); 3193 Util.FireAndForget(DetachWrapper, m_host);
3194 } 3194 }
3195   3195  
3196 private void DetachWrapper(object o) 3196 private void DetachWrapper(object o)
3197 { 3197 {
3198 if (World.AttachmentsModule != null) 3198 if (World.AttachmentsModule != null)
3199 { 3199 {
3200 SceneObjectPart host = (SceneObjectPart)o; 3200 SceneObjectPart host = (SceneObjectPart)o;
3201 ScenePresence presence = World.GetScenePresence(host.OwnerID); 3201 ScenePresence presence = World.GetScenePresence(host.OwnerID);
3202 World.AttachmentsModule.DetachSingleAttachmentToInv(presence, host.ParentGroup); 3202 World.AttachmentsModule.DetachSingleAttachmentToInv(presence, host.ParentGroup);
3203 } 3203 }
3204 } 3204 }
3205   3205  
3206 public void llAttachToAvatar(int attachmentPoint) 3206 public void llAttachToAvatar(int attachmentPoint)
3207 { 3207 {
3208 m_host.AddScriptLPS(1); 3208 m_host.AddScriptLPS(1);
3209   3209  
3210 // if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) 3210 // if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3211 // return; 3211 // return;
3212   3212  
3213 if (m_item.PermsGranter != m_host.OwnerID) 3213 if (m_item.PermsGranter != m_host.OwnerID)
3214 return; 3214 return;
3215   3215  
3216 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 3216 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
3217 AttachToAvatar(attachmentPoint); 3217 AttachToAvatar(attachmentPoint);
3218 } 3218 }
3219   3219  
3220 public void llDetachFromAvatar() 3220 public void llDetachFromAvatar()
3221 { 3221 {
3222 m_host.AddScriptLPS(1); 3222 m_host.AddScriptLPS(1);
3223   3223  
3224 if (m_host.ParentGroup.AttachmentPoint == 0) 3224 if (m_host.ParentGroup.AttachmentPoint == 0)
3225 return; 3225 return;
3226   3226  
3227 if (m_item.PermsGranter != m_host.OwnerID) 3227 if (m_item.PermsGranter != m_host.OwnerID)
3228 return; 3228 return;
3229   3229  
3230 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) 3230 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0)
3231 DetachFromAvatar(); 3231 DetachFromAvatar();
3232 } 3232 }
3233   3233  
3234 public void llTakeCamera(string avatar) 3234 public void llTakeCamera(string avatar)
3235 { 3235 {
3236 m_host.AddScriptLPS(1); 3236 m_host.AddScriptLPS(1);
3237 Deprecated("llTakeCamera", "Use llSetCameraParams instead"); 3237 Deprecated("llTakeCamera", "Use llSetCameraParams instead");
3238 } 3238 }
3239   3239  
3240 public void llReleaseCamera(string avatar) 3240 public void llReleaseCamera(string avatar)
3241 { 3241 {
3242 m_host.AddScriptLPS(1); 3242 m_host.AddScriptLPS(1);
3243 Deprecated("llReleaseCamera", "Use llClearCameraParams instead"); 3243 Deprecated("llReleaseCamera", "Use llClearCameraParams instead");
3244 } 3244 }
3245   3245  
3246 public LSL_String llGetOwner() 3246 public LSL_String llGetOwner()
3247 { 3247 {
3248 m_host.AddScriptLPS(1); 3248 m_host.AddScriptLPS(1);
3249   3249  
3250 return m_host.OwnerID.ToString(); 3250 return m_host.OwnerID.ToString();
3251 } 3251 }
3252   3252  
3253 public void llInstantMessage(string user, string message) 3253 public void llInstantMessage(string user, string message)
3254 { 3254 {
3255 m_host.AddScriptLPS(1); 3255 m_host.AddScriptLPS(1);
3256   3256  
3257 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3257 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
3258 // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent, 3258 // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent,
3259 // but I don't think we have a list of scenes available from here. 3259 // but I don't think we have a list of scenes available from here.
3260 // (We also don't want to duplicate the code in OnInstantMessage if we can avoid it.) 3260 // (We also don't want to duplicate the code in OnInstantMessage if we can avoid it.)
3261   3261  
3262 // user is a UUID 3262 // user is a UUID
3263   3263  
3264 // TODO: figure out values for client, fromSession, and imSessionID 3264 // TODO: figure out values for client, fromSession, and imSessionID
3265 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch()); 3265 // client.SendInstantMessage(m_host.UUID, fromSession, message, user, imSessionID, m_host.Name, AgentManager.InstantMessageDialog.MessageFromAgent, (uint)Util.UnixTimeSinceEpoch());
3266 UUID friendTransactionID = UUID.Random(); 3266 UUID friendTransactionID = UUID.Random();
3267   3267  
3268 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3268 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3269   3269  
3270 GridInstantMessage msg = new GridInstantMessage(); 3270 GridInstantMessage msg = new GridInstantMessage();
3271 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3271 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3272 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3272 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3273 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3273 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3274 // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3274 // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3275 // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3275 // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3276 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3276 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp;
3277 //if (client != null) 3277 //if (client != null)
3278 //{ 3278 //{
3279 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3279 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
3280 //} 3280 //}
3281 //else 3281 //else
3282 //{ 3282 //{
3283 // msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it 3283 // msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it
3284 //} 3284 //}
3285 // Cap the message length at 1024. 3285 // Cap the message length at 1024.
3286 if (message != null && message.Length > 1024) 3286 if (message != null && message.Length > 1024)
3287 msg.message = message.Substring(0, 1024); 3287 msg.message = message.Substring(0, 1024);
3288 else 3288 else
3289 msg.message = message; 3289 msg.message = message;
3290 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3290 msg.dialog = (byte)19; // messgage from script ??? // dialog;
3291 msg.fromGroup = false;// fromGroup; 3291 msg.fromGroup = false;// fromGroup;
3292 msg.offline = (byte)0; //offline; 3292 msg.offline = (byte)0; //offline;
3293 msg.ParentEstateID = 0; //ParentEstateID; 3293 msg.ParentEstateID = 0; //ParentEstateID;
3294 msg.Position = new Vector3(m_host.AbsolutePosition); 3294 msg.Position = new Vector3(m_host.AbsolutePosition);
3295 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3295 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3296   3296  
3297 Vector3 pos = m_host.AbsolutePosition; 3297 Vector3 pos = m_host.AbsolutePosition;
3298 msg.binaryBucket 3298 msg.binaryBucket
3299 = Util.StringToBytes256( 3299 = Util.StringToBytes256(
3300 "{0}/{1}/{2}/{3}", 3300 "{0}/{1}/{2}/{3}",
3301 World.RegionInfo.RegionName, 3301 World.RegionInfo.RegionName,
3302 (int)Math.Floor(pos.X), 3302 (int)Math.Floor(pos.X),
3303 (int)Math.Floor(pos.Y), 3303 (int)Math.Floor(pos.Y),
3304 (int)Math.Floor(pos.Z)); 3304 (int)Math.Floor(pos.Z));
3305   3305  
3306 if (m_TransferModule != null) 3306 if (m_TransferModule != null)
3307 { 3307 {
3308 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3308 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3309 } 3309 }
3310   3310  
3311 ScriptSleep(2000); 3311 ScriptSleep(2000);
3312 } 3312 }
3313   3313  
3314 public void llEmail(string address, string subject, string message) 3314 public void llEmail(string address, string subject, string message)
3315 { 3315 {
3316 m_host.AddScriptLPS(1); 3316 m_host.AddScriptLPS(1);
3317 IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); 3317 IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>();
3318 if (emailModule == null) 3318 if (emailModule == null)
3319 { 3319 {
3320 Error("llEmail", "Email module not configured"); 3320 Error("llEmail", "Email module not configured");
3321 return; 3321 return;
3322 } 3322 }
3323   3323  
3324 emailModule.SendEmail(m_host.UUID, address, subject, message); 3324 emailModule.SendEmail(m_host.UUID, address, subject, message);
3325 ScriptSleep(EMAIL_PAUSE_TIME * 1000); 3325 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3326 } 3326 }
3327   3327  
3328 public void llGetNextEmail(string address, string subject) 3328 public void llGetNextEmail(string address, string subject)
3329 { 3329 {
3330 m_host.AddScriptLPS(1); 3330 m_host.AddScriptLPS(1);
3331 IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>(); 3331 IEmailModule emailModule = m_ScriptEngine.World.RequestModuleInterface<IEmailModule>();
3332 if (emailModule == null) 3332 if (emailModule == null)
3333 { 3333 {
3334 Error("llGetNextEmail", "Email module not configured"); 3334 Error("llGetNextEmail", "Email module not configured");
3335 return; 3335 return;
3336 } 3336 }
3337 Email email; 3337 Email email;
3338   3338  
3339 email = emailModule.GetNextEmail(m_host.UUID, address, subject); 3339 email = emailModule.GetNextEmail(m_host.UUID, address, subject);
3340   3340  
3341 if (email == null) 3341 if (email == null)
3342 return; 3342 return;
3343   3343  
3344 m_ScriptEngine.PostObjectEvent(m_host.LocalId, 3344 m_ScriptEngine.PostObjectEvent(m_host.LocalId,
3345 new EventParams("email", 3345 new EventParams("email",
3346 new Object[] { 3346 new Object[] {
3347 new LSL_String(email.time), 3347 new LSL_String(email.time),
3348 new LSL_String(email.sender), 3348 new LSL_String(email.sender),
3349 new LSL_String(email.subject), 3349 new LSL_String(email.subject),
3350 new LSL_String(email.message), 3350 new LSL_String(email.message),
3351 new LSL_Integer(email.numLeft)}, 3351 new LSL_Integer(email.numLeft)},
3352 new DetectParams[0])); 3352 new DetectParams[0]));
3353   3353  
3354 } 3354 }
3355   3355  
3356 public LSL_String llGetKey() 3356 public LSL_String llGetKey()
3357 { 3357 {
3358 m_host.AddScriptLPS(1); 3358 m_host.AddScriptLPS(1);
3359 return m_host.UUID.ToString(); 3359 return m_host.UUID.ToString();
3360 } 3360 }
3361   3361  
3362 public LSL_Key llGenerateKey() 3362 public LSL_Key llGenerateKey()
3363 { 3363 {
3364 m_host.AddScriptLPS(1); 3364 m_host.AddScriptLPS(1);
3365 return UUID.Random().ToString(); 3365 return UUID.Random().ToString();
3366 } 3366 }
3367   3367  
3368 public void llSetBuoyancy(double buoyancy) 3368 public void llSetBuoyancy(double buoyancy)
3369 { 3369 {
3370 m_host.AddScriptLPS(1); 3370 m_host.AddScriptLPS(1);
3371   3371  
3372 if (!m_host.ParentGroup.IsDeleted) 3372 if (!m_host.ParentGroup.IsDeleted)
3373 { 3373 {
3374 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); 3374 m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy);
3375 } 3375 }
3376 } 3376 }
3377   3377  
3378 /// <summary> 3378 /// <summary>
3379 /// Attempt to clamp the object on the Z axis at the given height over tau seconds. 3379 /// Attempt to clamp the object on the Z axis at the given height over tau seconds.
3380 /// </summary> 3380 /// </summary>
3381 /// <param name="height">Height to hover. Height of zero disables hover.</param> 3381 /// <param name="height">Height to hover. Height of zero disables hover.</param>
3382 /// <param name="water">False if height is calculated just from ground, otherwise uses ground or water depending on whichever is higher</param> 3382 /// <param name="water">False if height is calculated just from ground, otherwise uses ground or water depending on whichever is higher</param>
3383 /// <param name="tau">Number of seconds over which to reach target</param> 3383 /// <param name="tau">Number of seconds over which to reach target</param>
3384 public void llSetHoverHeight(double height, int water, double tau) 3384 public void llSetHoverHeight(double height, int water, double tau)
3385 { 3385 {
3386 m_host.AddScriptLPS(1); 3386 m_host.AddScriptLPS(1);
3387   3387  
3388 if (m_host.PhysActor != null) 3388 if (m_host.PhysActor != null)
3389 { 3389 {
3390 PIDHoverType hoverType = PIDHoverType.Ground; 3390 PIDHoverType hoverType = PIDHoverType.Ground;
3391 if (water != 0) 3391 if (water != 0)
3392 { 3392 {
3393 hoverType = PIDHoverType.GroundAndWater; 3393 hoverType = PIDHoverType.GroundAndWater;
3394 } 3394 }
3395   3395  
3396 m_host.SetHoverHeight((float)height, hoverType, (float)tau); 3396 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
3397 } 3397 }
3398 } 3398 }
3399   3399  
3400 public void llStopHover() 3400 public void llStopHover()
3401 { 3401 {
3402 m_host.AddScriptLPS(1); 3402 m_host.AddScriptLPS(1);
3403 if (m_host.PhysActor != null) 3403 if (m_host.PhysActor != null)
3404 { 3404 {
3405 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f); 3405 m_host.SetHoverHeight(0f, PIDHoverType.Ground, 0f);
3406 } 3406 }
3407 } 3407 }
3408   3408  
3409 public void llMinEventDelay(double delay) 3409 public void llMinEventDelay(double delay)
3410 { 3410 {
3411 m_host.AddScriptLPS(1); 3411 m_host.AddScriptLPS(1);
3412 try 3412 try
3413 { 3413 {
3414 m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay); 3414 m_ScriptEngine.SetMinEventDelay(m_item.ItemID, delay);
3415 } 3415 }
3416 catch (NotImplementedException) 3416 catch (NotImplementedException)
3417 { 3417 {
3418 // Currently not implemented in DotNetEngine only XEngine 3418 // Currently not implemented in DotNetEngine only XEngine
3419 NotImplemented("llMinEventDelay", "In DotNetEngine"); 3419 NotImplemented("llMinEventDelay", "In DotNetEngine");
3420 } 3420 }
3421 } 3421 }
3422   3422  
3423 public void llSoundPreload(string sound) 3423 public void llSoundPreload(string sound)
3424 { 3424 {
3425 m_host.AddScriptLPS(1); 3425 m_host.AddScriptLPS(1);
3426 Deprecated("llSoundPreload", "Use llPreloadSound instead"); 3426 Deprecated("llSoundPreload", "Use llPreloadSound instead");
3427 } 3427 }
3428   3428  
3429 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3429 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3430 { 3430 {
3431 m_host.AddScriptLPS(1); 3431 m_host.AddScriptLPS(1);
3432   3432  
3433 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3433 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3434 // set the rotation of the object, copy that behavior 3434 // set the rotation of the object, copy that behavior
3435 PhysicsActor pa = m_host.PhysActor; 3435 PhysicsActor pa = m_host.PhysActor;
3436   3436  
3437 if (strength == 0 || pa == null || !pa.IsPhysical) 3437 if (strength == 0 || pa == null || !pa.IsPhysical)
3438 { 3438 {
3439 llSetLocalRot(target); 3439 llSetLocalRot(target);
3440 } 3440 }
3441 else 3441 else
3442 { 3442 {
3443 m_host.RotLookAt(target, (float)strength, (float)damping); 3443 m_host.RotLookAt(target, (float)strength, (float)damping);
3444 } 3444 }
3445 } 3445 }
3446   3446  
3447 public LSL_Integer llStringLength(string str) 3447 public LSL_Integer llStringLength(string str)
3448 { 3448 {
3449 m_host.AddScriptLPS(1); 3449 m_host.AddScriptLPS(1);
3450 if (str.Length > 0) 3450 if (str.Length > 0)
3451 { 3451 {
3452 return str.Length; 3452 return str.Length;
3453 } 3453 }
3454 else 3454 else
3455 { 3455 {
3456 return 0; 3456 return 0;
3457 } 3457 }
3458 } 3458 }
3459   3459  
3460 public void llStartAnimation(string anim) 3460 public void llStartAnimation(string anim)
3461 { 3461 {
3462 m_host.AddScriptLPS(1); 3462 m_host.AddScriptLPS(1);
3463   3463  
3464 if (m_item.PermsGranter == UUID.Zero) 3464 if (m_item.PermsGranter == UUID.Zero)
3465 return; 3465 return;
3466   3466  
3467 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) 3467 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3468 { 3468 {
3469 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3469 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3470   3470  
3471 if (presence != null) 3471 if (presence != null)
3472 { 3472 {
3473 // Do NOT try to parse UUID, animations cannot be triggered by ID 3473 // Do NOT try to parse UUID, animations cannot be triggered by ID
3474 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); 3474 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
3475 if (animID == UUID.Zero) 3475 if (animID == UUID.Zero)
3476 presence.Animator.AddAnimation(anim, m_host.UUID); 3476 presence.Animator.AddAnimation(anim, m_host.UUID);
3477 else 3477 else
3478 presence.Animator.AddAnimation(animID, m_host.UUID); 3478 presence.Animator.AddAnimation(animID, m_host.UUID);
3479 } 3479 }
3480 } 3480 }
3481 } 3481 }
3482   3482  
3483 public void llStopAnimation(string anim) 3483 public void llStopAnimation(string anim)
3484 { 3484 {
3485 m_host.AddScriptLPS(1); 3485 m_host.AddScriptLPS(1);
3486   3486  
3487 if (m_item.PermsGranter == UUID.Zero) 3487 if (m_item.PermsGranter == UUID.Zero)
3488 return; 3488 return;
3489   3489  
3490 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) 3490 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3491 { 3491 {
3492 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3492 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3493   3493  
3494 if (presence != null) 3494 if (presence != null)
3495 { 3495 {
3496 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim); 3496 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim);
3497   3497  
3498 if (animID == UUID.Zero) 3498 if (animID == UUID.Zero)
3499 presence.Animator.RemoveAnimation(anim); 3499 presence.Animator.RemoveAnimation(anim);
3500 else 3500 else
3501 presence.Animator.RemoveAnimation(animID, true); 3501 presence.Animator.RemoveAnimation(animID, true);
3502 } 3502 }
3503 } 3503 }
3504 } 3504 }
3505   3505  
3506 public void llPointAt(LSL_Vector pos) 3506 public void llPointAt(LSL_Vector pos)
3507 { 3507 {
3508 m_host.AddScriptLPS(1); 3508 m_host.AddScriptLPS(1);
3509 } 3509 }
3510   3510  
3511 public void llStopPointAt() 3511 public void llStopPointAt()
3512 { 3512 {
3513 m_host.AddScriptLPS(1); 3513 m_host.AddScriptLPS(1);
3514 } 3514 }
3515   3515  
3516 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) 3516 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain)
3517 { 3517 {
3518 m_host.AddScriptLPS(1); 3518 m_host.AddScriptLPS(1);
3519 TargetOmega(m_host, axis, spinrate, gain); 3519 TargetOmega(m_host, axis, spinrate, gain);
3520 } 3520 }
3521   3521  
3522 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3522 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3523 { 3523 {
3524 part.UpdateAngularVelocity(axis * spinrate); 3524 part.UpdateAngularVelocity(axis * spinrate);
3525 } 3525 }
3526   3526  
3527 public LSL_Integer llGetStartParameter() 3527 public LSL_Integer llGetStartParameter()
3528 { 3528 {
3529 m_host.AddScriptLPS(1); 3529 m_host.AddScriptLPS(1);
3530 return m_ScriptEngine.GetStartParameter(m_item.ItemID); 3530 return m_ScriptEngine.GetStartParameter(m_item.ItemID);
3531 } 3531 }
3532   3532  
3533 public void llRequestPermissions(string agent, int perm) 3533 public void llRequestPermissions(string agent, int perm)
3534 { 3534 {
3535 UUID agentID; 3535 UUID agentID;
3536   3536  
3537 if (!UUID.TryParse(agent, out agentID)) 3537 if (!UUID.TryParse(agent, out agentID))
3538 return; 3538 return;
3539   3539  
3540 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3540 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3541 { 3541 {
3542 llReleaseControls(); 3542 llReleaseControls();
3543   3543  
3544 m_item.PermsGranter = UUID.Zero; 3544 m_item.PermsGranter = UUID.Zero;
3545 m_item.PermsMask = 0; 3545 m_item.PermsMask = 0;
3546   3546  
3547 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3547 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3548 "run_time_permissions", new Object[] { 3548 "run_time_permissions", new Object[] {
3549 new LSL_Integer(0) }, 3549 new LSL_Integer(0) },
3550 new DetectParams[0])); 3550 new DetectParams[0]));
3551   3551  
3552 return; 3552 return;
3553 } 3553 }
3554   3554  
3555 if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3555 if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3556 llReleaseControls(); 3556 llReleaseControls();
3557   3557  
3558 m_host.AddScriptLPS(1); 3558 m_host.AddScriptLPS(1);
3559   3559  
3560 int implicitPerms = 0; 3560 int implicitPerms = 0;
3561   3561  
3562 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) 3562 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
3563 { 3563 {
3564 // When attached, certain permissions are implicit if requested from owner 3564 // When attached, certain permissions are implicit if requested from owner
3565 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3565 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3566 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3566 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3567 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3567 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3568 ScriptBaseClass.PERMISSION_ATTACH; 3568 ScriptBaseClass.PERMISSION_ATTACH;
3569 } 3569 }
3570 else 3570 else
3571 { 3571 {
3572 if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID)) 3572 if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID))
3573 { 3573 {
3574 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3574 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3575 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3575 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3576 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3576 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3577 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3577 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3578 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3578 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3579 } 3579 }
3580 else 3580 else
3581 { 3581 {
3582 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3582 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3583 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3583 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3584 } 3584 }
3585 } 3585 }
3586   3586  
3587 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3587 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3588 { 3588 {
3589 lock (m_host.TaskInventory) 3589 lock (m_host.TaskInventory)
3590 { 3590 {
3591 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3591 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3592 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3592 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3593 } 3593 }
3594   3594  
3595 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3595 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3596 "run_time_permissions", new Object[] { 3596 "run_time_permissions", new Object[] {
3597 new LSL_Integer(perm) }, 3597 new LSL_Integer(perm) },
3598 new DetectParams[0])); 3598 new DetectParams[0]));
3599   3599  
3600 return; 3600 return;
3601 } 3601 }
3602   3602  
3603 ScenePresence presence = World.GetScenePresence(agentID); 3603 ScenePresence presence = World.GetScenePresence(agentID);
3604 if (presence != null) 3604 if (presence != null)
3605 { 3605 {
3606 // If permissions are being requested from an NPC and were not implicitly granted above then 3606 // If permissions are being requested from an NPC and were not implicitly granted above then
3607 // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner 3607 // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner
3608 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3608 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
3609 if (npcModule != null && npcModule.IsNPC(agentID, World)) 3609 if (npcModule != null && npcModule.IsNPC(agentID, World))
3610 { 3610 {
3611 if (npcModule.CheckPermissions(agentID, m_host.OwnerID)) 3611 if (npcModule.CheckPermissions(agentID, m_host.OwnerID))
3612 { 3612 {
3613 lock (m_host.TaskInventory) 3613 lock (m_host.TaskInventory)
3614 { 3614 {
3615 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3615 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3616 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3616 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3617 } 3617 }
3618   3618  
3619 m_ScriptEngine.PostScriptEvent( 3619 m_ScriptEngine.PostScriptEvent(
3620 m_item.ItemID, 3620 m_item.ItemID,
3621 new EventParams( 3621 new EventParams(
3622 "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); 3622 "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0]));
3623 } 3623 }
3624   3624  
3625 // it is an NPC, exit even if the permissions werent granted above, they are not going to answer 3625 // it is an NPC, exit even if the permissions werent granted above, they are not going to answer
3626 // the question! 3626 // the question!
3627 return; 3627 return;
3628 } 3628 }
3629   3629  
3630 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID); 3630 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID);
3631 if (ownerName == String.Empty) 3631 if (ownerName == String.Empty)
3632 ownerName = "(hippos)"; 3632 ownerName = "(hippos)";
3633   3633  
3634 if (!m_waitingForScriptAnswer) 3634 if (!m_waitingForScriptAnswer)
3635 { 3635 {
3636 lock (m_host.TaskInventory) 3636 lock (m_host.TaskInventory)
3637 { 3637 {
3638 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3638 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3639 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3639 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3640 } 3640 }
3641   3641  
3642 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3642 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3643 m_waitingForScriptAnswer=true; 3643 m_waitingForScriptAnswer=true;
3644 } 3644 }
3645   3645  
3646 presence.ControllingClient.SendScriptQuestion( 3646 presence.ControllingClient.SendScriptQuestion(
3647 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm); 3647 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm);
3648   3648  
3649 return; 3649 return;
3650 } 3650 }
3651   3651  
3652 // Requested agent is not in range, refuse perms 3652 // Requested agent is not in range, refuse perms
3653 m_ScriptEngine.PostScriptEvent( 3653 m_ScriptEngine.PostScriptEvent(
3654 m_item.ItemID, 3654 m_item.ItemID,
3655 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); 3655 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0]));
3656 } 3656 }
3657   3657  
3658 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer) 3658 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer)
3659 { 3659 {
3660 if (taskID != m_host.UUID) 3660 if (taskID != m_host.UUID)
3661 return; 3661 return;
3662   3662  
3663 client.OnScriptAnswer -= handleScriptAnswer; 3663 client.OnScriptAnswer -= handleScriptAnswer;
3664 m_waitingForScriptAnswer = false; 3664 m_waitingForScriptAnswer = false;
3665   3665  
3666 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3666 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3667 llReleaseControls(); 3667 llReleaseControls();
3668   3668  
3669 lock (m_host.TaskInventory) 3669 lock (m_host.TaskInventory)
3670 { 3670 {
3671 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3671 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3672 } 3672 }
3673   3673  
3674 m_ScriptEngine.PostScriptEvent( 3674 m_ScriptEngine.PostScriptEvent(
3675 m_item.ItemID, 3675 m_item.ItemID,
3676 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3676 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0]));
3677 } 3677 }
3678   3678  
3679 public LSL_String llGetPermissionsKey() 3679 public LSL_String llGetPermissionsKey()
3680 { 3680 {
3681 m_host.AddScriptLPS(1); 3681 m_host.AddScriptLPS(1);
3682   3682  
3683 return m_item.PermsGranter.ToString(); 3683 return m_item.PermsGranter.ToString();
3684 } 3684 }
3685   3685  
3686 public LSL_Integer llGetPermissions() 3686 public LSL_Integer llGetPermissions()
3687 { 3687 {
3688 m_host.AddScriptLPS(1); 3688 m_host.AddScriptLPS(1);
3689   3689  
3690 int perms = m_item.PermsMask; 3690 int perms = m_item.PermsMask;
3691   3691  
3692 if (m_automaticLinkPermission) 3692 if (m_automaticLinkPermission)
3693 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3693 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3694   3694  
3695 return perms; 3695 return perms;
3696 } 3696 }
3697   3697  
3698 public LSL_Integer llGetLinkNumber() 3698 public LSL_Integer llGetLinkNumber()
3699 { 3699 {
3700 m_host.AddScriptLPS(1); 3700 m_host.AddScriptLPS(1);
3701   3701  
3702 if (m_host.ParentGroup.PrimCount > 1) 3702 if (m_host.ParentGroup.PrimCount > 1)
3703 { 3703 {
3704 return m_host.LinkNum; 3704 return m_host.LinkNum;
3705 } 3705 }
3706 else 3706 else
3707 { 3707 {
3708 return 0; 3708 return 0;
3709 } 3709 }
3710 } 3710 }
3711   3711  
3712 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3712 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3713 { 3713 {
3714 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3714 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3715   3715  
3716 foreach (SceneObjectPart part in parts) 3716 foreach (SceneObjectPart part in parts)
3717 part.SetFaceColorAlpha(face, color, null); 3717 part.SetFaceColorAlpha(face, color, null);
3718 } 3718 }
3719   3719  
3720 public void llCreateLink(string target, int parent) 3720 public void llCreateLink(string target, int parent)
3721 { 3721 {
3722 m_host.AddScriptLPS(1); 3722 m_host.AddScriptLPS(1);
3723 UUID targetID; 3723 UUID targetID;
3724   3724  
3725 if (!UUID.TryParse(target, out targetID)) 3725 if (!UUID.TryParse(target, out targetID))
3726 return; 3726 return;
3727   3727  
3728 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3728 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3729 && !m_automaticLinkPermission) 3729 && !m_automaticLinkPermission)
3730 { 3730 {
3731 Error("llCreateLink", "PERMISSION_CHANGE_LINKS permission not set"); 3731 Error("llCreateLink", "PERMISSION_CHANGE_LINKS permission not set");
3732 return; 3732 return;
3733 } 3733 }
3734   3734  
3735 IClientAPI client = null; 3735 IClientAPI client = null;
3736 ScenePresence sp = World.GetScenePresence(m_item.PermsGranter); 3736 ScenePresence sp = World.GetScenePresence(m_item.PermsGranter);
3737 if (sp != null) 3737 if (sp != null)
3738 client = sp.ControllingClient; 3738 client = sp.ControllingClient;
3739   3739  
3740 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 3740 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3741   3741  
3742 if (targetPart.ParentGroup.AttachmentPoint != 0) 3742 if (targetPart.ParentGroup.AttachmentPoint != 0)
3743 return; // Fail silently if attached 3743 return; // Fail silently if attached
3744   3744  
3745 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID) 3745 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3746 return; 3746 return;
3747   3747  
3748 SceneObjectGroup parentPrim = null, childPrim = null; 3748 SceneObjectGroup parentPrim = null, childPrim = null;
3749   3749  
3750 if (targetPart != null) 3750 if (targetPart != null)
3751 { 3751 {
3752 if (parent != 0) 3752 if (parent != 0)
3753 { 3753 {
3754 parentPrim = m_host.ParentGroup; 3754 parentPrim = m_host.ParentGroup;
3755 childPrim = targetPart.ParentGroup; 3755 childPrim = targetPart.ParentGroup;
3756 } 3756 }
3757 else 3757 else
3758 { 3758 {
3759 parentPrim = targetPart.ParentGroup; 3759 parentPrim = targetPart.ParentGroup;
3760 childPrim = m_host.ParentGroup; 3760 childPrim = m_host.ParentGroup;
3761 } 3761 }
3762   3762  
3763 // Required for linking 3763 // Required for linking
3764 childPrim.RootPart.ClearUpdateSchedule(); 3764 childPrim.RootPart.ClearUpdateSchedule();
3765 parentPrim.LinkToGroup(childPrim, true); 3765 parentPrim.LinkToGroup(childPrim, true);
3766 } 3766 }
3767   3767  
3768 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3768 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3769 parentPrim.RootPart.CreateSelected = true; 3769 parentPrim.RootPart.CreateSelected = true;
3770 parentPrim.HasGroupChanged = true; 3770 parentPrim.HasGroupChanged = true;
3771 parentPrim.ScheduleGroupForFullUpdate(); 3771 parentPrim.ScheduleGroupForFullUpdate();
3772   3772  
3773 if (client != null) 3773 if (client != null)
3774 parentPrim.SendPropertiesToClient(client); 3774 parentPrim.SendPropertiesToClient(client);
3775   3775  
3776 ScriptSleep(1000); 3776 ScriptSleep(1000);
3777 } 3777 }
3778   3778  
3779 public void llBreakLink(int linknum) 3779 public void llBreakLink(int linknum)
3780 { 3780 {
3781 m_host.AddScriptLPS(1); 3781 m_host.AddScriptLPS(1);
3782   3782  
3783 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3783 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3784 && !m_automaticLinkPermission) 3784 && !m_automaticLinkPermission)
3785 { 3785 {
3786 Error("llBreakLink", "PERMISSION_CHANGE_LINKS permission not set"); 3786 Error("llBreakLink", "PERMISSION_CHANGE_LINKS permission not set");
3787 return; 3787 return;
3788 } 3788 }
3789   3789  
3790 if (linknum < ScriptBaseClass.LINK_THIS) 3790 if (linknum < ScriptBaseClass.LINK_THIS)
3791 return; 3791 return;
3792   3792  
3793 SceneObjectGroup parentPrim = m_host.ParentGroup; 3793 SceneObjectGroup parentPrim = m_host.ParentGroup;
3794   3794  
3795 if (parentPrim.AttachmentPoint != 0) 3795 if (parentPrim.AttachmentPoint != 0)
3796 return; // Fail silently if attached 3796 return; // Fail silently if attached
3797 SceneObjectPart childPrim = null; 3797 SceneObjectPart childPrim = null;
3798   3798  
3799 switch (linknum) 3799 switch (linknum)
3800 { 3800 {
3801 case ScriptBaseClass.LINK_ROOT: 3801 case ScriptBaseClass.LINK_ROOT:
3802 break; 3802 break;
3803 case ScriptBaseClass.LINK_SET: 3803 case ScriptBaseClass.LINK_SET:
3804 case ScriptBaseClass.LINK_ALL_OTHERS: 3804 case ScriptBaseClass.LINK_ALL_OTHERS:
3805 case ScriptBaseClass.LINK_ALL_CHILDREN: 3805 case ScriptBaseClass.LINK_ALL_CHILDREN:
3806 case ScriptBaseClass.LINK_THIS: 3806 case ScriptBaseClass.LINK_THIS:
3807 foreach (SceneObjectPart part in parentPrim.Parts) 3807 foreach (SceneObjectPart part in parentPrim.Parts)
3808 { 3808 {
3809 if (part.UUID != m_host.UUID) 3809 if (part.UUID != m_host.UUID)
3810 { 3810 {
3811 childPrim = part; 3811 childPrim = part;
3812 break; 3812 break;
3813 } 3813 }
3814 } 3814 }
3815 break; 3815 break;
3816 default: 3816 default:
3817 childPrim = parentPrim.GetLinkNumPart(linknum); 3817 childPrim = parentPrim.GetLinkNumPart(linknum);
3818 if (childPrim.UUID == m_host.UUID) 3818 if (childPrim.UUID == m_host.UUID)
3819 childPrim = null; 3819 childPrim = null;
3820 break; 3820 break;
3821 } 3821 }
3822   3822  
3823 if (linknum == ScriptBaseClass.LINK_ROOT) 3823 if (linknum == ScriptBaseClass.LINK_ROOT)
3824 { 3824 {
3825 // Restructuring Multiple Prims. 3825 // Restructuring Multiple Prims.
3826 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3826 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3827 parts.Remove(parentPrim.RootPart); 3827 parts.Remove(parentPrim.RootPart);
3828 foreach (SceneObjectPart part in parts) 3828 foreach (SceneObjectPart part in parts)
3829 { 3829 {
3830 parentPrim.DelinkFromGroup(part.LocalId, true); 3830 parentPrim.DelinkFromGroup(part.LocalId, true);
3831 } 3831 }
3832 parentPrim.HasGroupChanged = true; 3832 parentPrim.HasGroupChanged = true;
3833 parentPrim.ScheduleGroupForFullUpdate(); 3833 parentPrim.ScheduleGroupForFullUpdate();
3834 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3834 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3835   3835  
3836 if (parts.Count > 0) 3836 if (parts.Count > 0)
3837 { 3837 {
3838 SceneObjectPart newRoot = parts[0]; 3838 SceneObjectPart newRoot = parts[0];
3839 parts.Remove(newRoot); 3839 parts.Remove(newRoot);
3840 foreach (SceneObjectPart part in parts) 3840 foreach (SceneObjectPart part in parts)
3841 { 3841 {
3842 // Required for linking 3842 // Required for linking
3843 part.ClearUpdateSchedule(); 3843 part.ClearUpdateSchedule();
3844 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3844 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3845 } 3845 }
3846 newRoot.ParentGroup.HasGroupChanged = true; 3846 newRoot.ParentGroup.HasGroupChanged = true;
3847 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3847 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3848 } 3848 }
3849 } 3849 }
3850 else 3850 else
3851 { 3851 {
3852 if (childPrim == null) 3852 if (childPrim == null)
3853 return; 3853 return;
3854   3854  
3855 parentPrim.DelinkFromGroup(childPrim.LocalId, true); 3855 parentPrim.DelinkFromGroup(childPrim.LocalId, true);
3856 parentPrim.HasGroupChanged = true; 3856 parentPrim.HasGroupChanged = true;
3857 parentPrim.ScheduleGroupForFullUpdate(); 3857 parentPrim.ScheduleGroupForFullUpdate();
3858 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3858 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3859 } 3859 }
3860 } 3860 }
3861   3861  
3862 public void llBreakAllLinks() 3862 public void llBreakAllLinks()
3863 { 3863 {
3864 m_host.AddScriptLPS(1); 3864 m_host.AddScriptLPS(1);
3865 SceneObjectGroup parentPrim = m_host.ParentGroup; 3865 SceneObjectGroup parentPrim = m_host.ParentGroup;
3866 if (parentPrim.AttachmentPoint != 0) 3866 if (parentPrim.AttachmentPoint != 0)
3867 return; // Fail silently if attached 3867 return; // Fail silently if attached
3868   3868  
3869 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3869 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3870 parts.Remove(parentPrim.RootPart); 3870 parts.Remove(parentPrim.RootPart);
3871   3871  
3872 foreach (SceneObjectPart part in parts) 3872 foreach (SceneObjectPart part in parts)
3873 { 3873 {
3874 parentPrim.DelinkFromGroup(part.LocalId, true); 3874 parentPrim.DelinkFromGroup(part.LocalId, true);
3875 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3875 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3876 } 3876 }
3877 parentPrim.HasGroupChanged = true; 3877 parentPrim.HasGroupChanged = true;
3878 parentPrim.ScheduleGroupForFullUpdate(); 3878 parentPrim.ScheduleGroupForFullUpdate();
3879 } 3879 }
3880   3880  
3881 public LSL_String llGetLinkKey(int linknum) 3881 public LSL_String llGetLinkKey(int linknum)
3882 { 3882 {
3883 m_host.AddScriptLPS(1); 3883 m_host.AddScriptLPS(1);
3884   3884  
3885 ISceneEntity entity = GetLinkEntity(linknum); 3885 ISceneEntity entity = GetLinkEntity(linknum);
3886   3886  
3887 if (entity != null) 3887 if (entity != null)
3888 return entity.UUID.ToString(); 3888 return entity.UUID.ToString();
3889 else 3889 else
3890 return ScriptBaseClass.NULL_KEY; 3890 return ScriptBaseClass.NULL_KEY;
3891 } 3891 }
3892   3892  
3893 /// <summary> 3893 /// <summary>
3894 /// Returns the name of the child prim or seated avatar matching the 3894 /// Returns the name of the child prim or seated avatar matching the
3895 /// specified link number. 3895 /// specified link number.
3896 /// </summary> 3896 /// </summary>
3897 /// <param name="linknum"> 3897 /// <param name="linknum">
3898 /// The number of a link in the linkset or a link-related constant. 3898 /// The number of a link in the linkset or a link-related constant.
3899 /// </param> 3899 /// </param>
3900 /// <returns> 3900 /// <returns>
3901 /// The name determined to match the specified link number. 3901 /// The name determined to match the specified link number.
3902 /// </returns> 3902 /// </returns>
3903 /// <remarks> 3903 /// <remarks>
3904 /// The rules governing the returned name are not simple. The only 3904 /// The rules governing the returned name are not simple. The only
3905 /// time a blank name is returned is if the target prim has a blank 3905 /// time a blank name is returned is if the target prim has a blank
3906 /// name. If no prim with the given link number can be found then 3906 /// name. If no prim with the given link number can be found then
3907 /// usually NULL_KEY is returned but there are exceptions. 3907 /// usually NULL_KEY is returned but there are exceptions.
3908 /// 3908 ///
3909 /// In a single unlinked prim, A call with 0 returns the name, all 3909 /// In a single unlinked prim, A call with 0 returns the name, all
3910 /// other values for link number return NULL_KEY 3910 /// other values for link number return NULL_KEY
3911 /// 3911 ///
3912 /// In link sets it is more complicated. 3912 /// In link sets it is more complicated.
3913 /// 3913 ///
3914 /// If the script is in the root prim:- 3914 /// If the script is in the root prim:-
3915 /// A zero link number returns NULL_KEY. 3915 /// A zero link number returns NULL_KEY.
3916 /// Positive link numbers return the name of the prim, or NULL_KEY 3916 /// Positive link numbers return the name of the prim, or NULL_KEY
3917 /// if a prim does not exist at that position. 3917 /// if a prim does not exist at that position.
3918 /// Negative link numbers return the name of the first child prim. 3918 /// Negative link numbers return the name of the first child prim.
3919 /// 3919 ///
3920 /// If the script is in a child prim:- 3920 /// If the script is in a child prim:-
3921 /// Link numbers 0 or 1 return the name of the root prim. 3921 /// Link numbers 0 or 1 return the name of the root prim.
3922 /// Positive link numbers return the name of the prim or NULL_KEY 3922 /// Positive link numbers return the name of the prim or NULL_KEY
3923 /// if a prim does not exist at that position. 3923 /// if a prim does not exist at that position.
3924 /// Negative numbers return the name of the root prim. 3924 /// Negative numbers return the name of the root prim.
3925 /// 3925 ///
3926 /// References 3926 /// References
3927 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetLinkName 3927 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetLinkName
3928 /// Mentions NULL_KEY being returned 3928 /// Mentions NULL_KEY being returned
3929 /// http://wiki.secondlife.com/wiki/LlGetLinkName 3929 /// http://wiki.secondlife.com/wiki/LlGetLinkName
3930 /// Mentions using the LINK_* constants, some of which are negative 3930 /// Mentions using the LINK_* constants, some of which are negative
3931 /// </remarks> 3931 /// </remarks>
3932 public LSL_String llGetLinkName(int linknum) 3932 public LSL_String llGetLinkName(int linknum)
3933 { 3933 {
3934 m_host.AddScriptLPS(1); 3934 m_host.AddScriptLPS(1);
3935   3935  
3936 ISceneEntity entity = GetLinkEntity(linknum); 3936 ISceneEntity entity = GetLinkEntity(linknum);
3937   3937  
3938 if (entity != null) 3938 if (entity != null)
3939 return entity.Name; 3939 return entity.Name;
3940 else 3940 else
3941 return ScriptBaseClass.NULL_KEY; 3941 return ScriptBaseClass.NULL_KEY;
3942 } 3942 }
3943   3943  
3944 public LSL_Integer llGetInventoryNumber(int type) 3944 public LSL_Integer llGetInventoryNumber(int type)
3945 { 3945 {
3946 m_host.AddScriptLPS(1); 3946 m_host.AddScriptLPS(1);
3947 int count = 0; 3947 int count = 0;
3948   3948  
3949 lock (m_host.TaskInventory) 3949 lock (m_host.TaskInventory)
3950 { 3950 {
3951 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3951 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3952 { 3952 {
3953 if (inv.Value.Type == type || type == -1) 3953 if (inv.Value.Type == type || type == -1)
3954 { 3954 {
3955 count = count + 1; 3955 count = count + 1;
3956 } 3956 }
3957 } 3957 }
3958 } 3958 }
3959   3959  
3960 return count; 3960 return count;
3961 } 3961 }
3962   3962  
3963 public LSL_String llGetInventoryName(int type, int number) 3963 public LSL_String llGetInventoryName(int type, int number)
3964 { 3964 {
3965 m_host.AddScriptLPS(1); 3965 m_host.AddScriptLPS(1);
3966 ArrayList keys = new ArrayList(); 3966 ArrayList keys = new ArrayList();
3967   3967  
3968 lock (m_host.TaskInventory) 3968 lock (m_host.TaskInventory)
3969 { 3969 {
3970 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3970 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3971 { 3971 {
3972 if (inv.Value.Type == type || type == -1) 3972 if (inv.Value.Type == type || type == -1)
3973 { 3973 {
3974 keys.Add(inv.Value.Name); 3974 keys.Add(inv.Value.Name);
3975 } 3975 }
3976 } 3976 }
3977 } 3977 }
3978   3978  
3979 if (keys.Count == 0) 3979 if (keys.Count == 0)
3980 { 3980 {
3981 return String.Empty; 3981 return String.Empty;
3982 } 3982 }
3983 keys.Sort(); 3983 keys.Sort();
3984 if (keys.Count > number) 3984 if (keys.Count > number)
3985 { 3985 {
3986 return (string)keys[number]; 3986 return (string)keys[number];
3987 } 3987 }
3988 return String.Empty; 3988 return String.Empty;
3989 } 3989 }
3990   3990  
3991 public LSL_Float llGetEnergy() 3991 public LSL_Float llGetEnergy()
3992 { 3992 {
3993 m_host.AddScriptLPS(1); 3993 m_host.AddScriptLPS(1);
3994 // TODO: figure out real energy value 3994 // TODO: figure out real energy value
3995 return 1.0f; 3995 return 1.0f;
3996 } 3996 }
3997   3997  
3998 public void llGiveInventory(string destination, string inventory) 3998 public void llGiveInventory(string destination, string inventory)
3999 { 3999 {
4000 m_host.AddScriptLPS(1); 4000 m_host.AddScriptLPS(1);
4001   4001  
4002 UUID destId = UUID.Zero; 4002 UUID destId = UUID.Zero;
4003   4003  
4004 if (!UUID.TryParse(destination, out destId)) 4004 if (!UUID.TryParse(destination, out destId))
4005 { 4005 {
4006 Error("llGiveInventory", "Can't parse destination key '" + destination + "'"); 4006 Error("llGiveInventory", "Can't parse destination key '" + destination + "'");
4007 return; 4007 return;
4008 } 4008 }
4009   4009  
4010 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); 4010 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
4011   4011  
4012 if (item == null) 4012 if (item == null)
4013 { 4013 {
4014 Error("llGiveInventory", "Can't find inventory object '" + inventory + "'"); 4014 Error("llGiveInventory", "Can't find inventory object '" + inventory + "'");
4015 } 4015 }
4016   4016  
4017 UUID objId = item.ItemID; 4017 UUID objId = item.ItemID;
4018   4018  
4019 // check if destination is an object 4019 // check if destination is an object
4020 if (World.GetSceneObjectPart(destId) != null) 4020 if (World.GetSceneObjectPart(destId) != null)
4021 { 4021 {
4022 // destination is an object 4022 // destination is an object
4023 World.MoveTaskInventoryItem(destId, m_host, objId); 4023 World.MoveTaskInventoryItem(destId, m_host, objId);
4024 } 4024 }
4025 else 4025 else
4026 { 4026 {
4027 ScenePresence presence = World.GetScenePresence(destId); 4027 ScenePresence presence = World.GetScenePresence(destId);
4028   4028  
4029 if (presence == null) 4029 if (presence == null)
4030 { 4030 {
4031 UserAccount account = 4031 UserAccount account =
4032 World.UserAccountService.GetUserAccount( 4032 World.UserAccountService.GetUserAccount(
4033 World.RegionInfo.ScopeID, 4033 World.RegionInfo.ScopeID,
4034 destId); 4034 destId);
4035   4035  
4036 if (account == null) 4036 if (account == null)
4037 { 4037 {
4038 Error("llGiveInventory", "Can't find destination '" + destId.ToString() + "'"); 4038 Error("llGiveInventory", "Can't find destination '" + destId.ToString() + "'");
4039 return; 4039 return;
4040 } 4040 }
4041 } 4041 }
4042 // destination is an avatar 4042 // destination is an avatar
4043 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4043 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4044   4044  
4045 if (agentItem == null) 4045 if (agentItem == null)
4046 return; 4046 return;
4047   4047  
4048 if (m_TransferModule != null) 4048 if (m_TransferModule != null)
4049 { 4049 {
4050 byte[] bucket = new byte[1]; 4050 byte[] bucket = new byte[1];
4051 bucket[0] = (byte)item.Type; 4051 bucket[0] = (byte)item.Type;
4052   4052  
4053 GridInstantMessage msg = new GridInstantMessage(World, 4053 GridInstantMessage msg = new GridInstantMessage(World,
4054 m_host.OwnerID, m_host.Name, destId, 4054 m_host.OwnerID, m_host.Name, destId,
4055 (byte)InstantMessageDialog.TaskInventoryOffered, 4055 (byte)InstantMessageDialog.TaskInventoryOffered,
4056 false, item.Name+". "+m_host.Name+" is located at "+ 4056 false, item.Name+". "+m_host.Name+" is located at "+
4057 World.RegionInfo.RegionName+" "+ 4057 World.RegionInfo.RegionName+" "+
4058 m_host.AbsolutePosition.ToString(), 4058 m_host.AbsolutePosition.ToString(),
4059 agentItem.ID, true, m_host.AbsolutePosition, 4059 agentItem.ID, true, m_host.AbsolutePosition,
4060 bucket, true); 4060 bucket, true);
4061   4061  
4062 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4062 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4063 } 4063 }
4064   4064  
4065 ScriptSleep(3000); 4065 ScriptSleep(3000);
4066 } 4066 }
4067 } 4067 }
4068   4068  
4069 public void llRemoveInventory(string name) 4069 public void llRemoveInventory(string name)
4070 { 4070 {
4071 m_host.AddScriptLPS(1); 4071 m_host.AddScriptLPS(1);
4072   4072  
4073 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 4073 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
4074   4074  
4075 if (item == null) 4075 if (item == null)
4076 return; 4076 return;
4077   4077  
4078 if (item.ItemID == m_item.ItemID) 4078 if (item.ItemID == m_item.ItemID)
4079 throw new ScriptDeleteException(); 4079 throw new ScriptDeleteException();
4080 else 4080 else
4081 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4081 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4082 } 4082 }
4083   4083  
4084 public void llSetText(string text, LSL_Vector color, double alpha) 4084 public void llSetText(string text, LSL_Vector color, double alpha)
4085 { 4085 {
4086 m_host.AddScriptLPS(1); 4086 m_host.AddScriptLPS(1);
4087 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); 4087 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4088 if (text.Length > 254) 4088 if (text.Length > 254)
4089 text = text.Remove(254); 4089 text = text.Remove(254);
4090   4090  
4091 byte[] data; 4091 byte[] data;
4092 do 4092 do
4093 { 4093 {
4094 data = Util.UTF8.GetBytes(text); 4094 data = Util.UTF8.GetBytes(text);
4095 if (data.Length > 254) 4095 if (data.Length > 254)
4096 text = text.Substring(0, text.Length - 1); 4096 text = text.Substring(0, text.Length - 1);
4097 } while (data.Length > 254); 4097 } while (data.Length > 254);
4098   4098  
4099 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4099 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4100 //m_host.ParentGroup.HasGroupChanged = true; 4100 //m_host.ParentGroup.HasGroupChanged = true;
4101 //m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4101 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
4102 } 4102 }
4103   4103  
4104 public LSL_Float llWater(LSL_Vector offset) 4104 public LSL_Float llWater(LSL_Vector offset)
4105 { 4105 {
4106 m_host.AddScriptLPS(1); 4106 m_host.AddScriptLPS(1);
4107 return World.RegionInfo.RegionSettings.WaterHeight; 4107 return World.RegionInfo.RegionSettings.WaterHeight;
4108 } 4108 }
4109   4109  
4110 public void llPassTouches(int pass) 4110 public void llPassTouches(int pass)
4111 { 4111 {
4112 m_host.AddScriptLPS(1); 4112 m_host.AddScriptLPS(1);
4113 if (pass != 0) 4113 if (pass != 0)
4114 m_host.PassTouches = true; 4114 m_host.PassTouches = true;
4115 else 4115 else
4116 m_host.PassTouches = false; 4116 m_host.PassTouches = false;
4117 } 4117 }
4118   4118  
4119 public LSL_String llRequestAgentData(string id, int data) 4119 public LSL_String llRequestAgentData(string id, int data)
4120 { 4120 {
4121 m_host.AddScriptLPS(1); 4121 m_host.AddScriptLPS(1);
4122   4122  
4123 UUID uuid = (UUID)id; 4123 UUID uuid = (UUID)id;
4124 PresenceInfo pinfo = null; 4124 PresenceInfo pinfo = null;
4125 UserAccount account; 4125 UserAccount account;
4126   4126  
4127 UserInfoCacheEntry ce; 4127 UserInfoCacheEntry ce;
4128 if (!m_userInfoCache.TryGetValue(uuid, out ce)) 4128 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4129 { 4129 {
4130 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4130 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4131 if (account == null) 4131 if (account == null)
4132 { 4132 {
4133 m_userInfoCache[uuid] = null; // Cache negative 4133 m_userInfoCache[uuid] = null; // Cache negative
4134 return UUID.Zero.ToString(); 4134 return UUID.Zero.ToString();
4135 } 4135 }
4136   4136  
4137   4137  
4138 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4138 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4139 if (pinfos != null && pinfos.Length > 0) 4139 if (pinfos != null && pinfos.Length > 0)
4140 { 4140 {
4141 foreach (PresenceInfo p in pinfos) 4141 foreach (PresenceInfo p in pinfos)
4142 { 4142 {
4143 if (p.RegionID != UUID.Zero) 4143 if (p.RegionID != UUID.Zero)
4144 { 4144 {
4145 pinfo = p; 4145 pinfo = p;
4146 } 4146 }
4147 } 4147 }
4148 } 4148 }
4149   4149  
4150 ce = new UserInfoCacheEntry(); 4150 ce = new UserInfoCacheEntry();
4151 ce.time = Util.EnvironmentTickCount(); 4151 ce.time = Util.EnvironmentTickCount();
4152 ce.account = account; 4152 ce.account = account;
4153 ce.pinfo = pinfo; 4153 ce.pinfo = pinfo;
4154 } 4154 }
4155 else 4155 else
4156 { 4156 {
4157 if (ce == null) 4157 if (ce == null)
4158 return UUID.Zero.ToString(); 4158 return UUID.Zero.ToString();
4159   4159  
4160 account = ce.account; 4160 account = ce.account;
4161 pinfo = ce.pinfo; 4161 pinfo = ce.pinfo;
4162 } 4162 }
4163   4163  
4164 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4164 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4165 { 4165 {
4166 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4166 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4167 if (pinfos != null && pinfos.Length > 0) 4167 if (pinfos != null && pinfos.Length > 0)
4168 { 4168 {
4169 foreach (PresenceInfo p in pinfos) 4169 foreach (PresenceInfo p in pinfos)
4170 { 4170 {
4171 if (p.RegionID != UUID.Zero) 4171 if (p.RegionID != UUID.Zero)
4172 { 4172 {
4173 pinfo = p; 4173 pinfo = p;
4174 } 4174 }
4175 } 4175 }
4176 } 4176 }
4177 else 4177 else
4178 pinfo = null; 4178 pinfo = null;
4179   4179  
4180 ce.time = Util.EnvironmentTickCount(); 4180 ce.time = Util.EnvironmentTickCount();
4181 ce.pinfo = pinfo; 4181 ce.pinfo = pinfo;
4182 } 4182 }
4183   4183  
4184 string reply = String.Empty; 4184 string reply = String.Empty;
4185   4185  
4186 switch (data) 4186 switch (data)
4187 { 4187 {
4188 case 1: // DATA_ONLINE (0|1) 4188 case 1: // DATA_ONLINE (0|1)
4189 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4189 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4190 reply = "1"; 4190 reply = "1";
4191 else 4191 else
4192 reply = "0"; 4192 reply = "0";
4193 break; 4193 break;
4194 case 2: // DATA_NAME (First Last) 4194 case 2: // DATA_NAME (First Last)
4195 reply = account.FirstName + " " + account.LastName; 4195 reply = account.FirstName + " " + account.LastName;
4196 break; 4196 break;
4197 case 3: // DATA_BORN (YYYY-MM-DD) 4197 case 3: // DATA_BORN (YYYY-MM-DD)
4198 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4198 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4199 born = born.AddSeconds(account.Created); 4199 born = born.AddSeconds(account.Created);
4200 reply = born.ToString("yyyy-MM-dd"); 4200 reply = born.ToString("yyyy-MM-dd");
4201 break; 4201 break;
4202 case 4: // DATA_RATING (0,0,0,0,0,0) 4202 case 4: // DATA_RATING (0,0,0,0,0,0)
4203 reply = "0,0,0,0,0,0"; 4203 reply = "0,0,0,0,0,0";
4204 break; 4204 break;
4205 case 7: // DATA_USERLEVEL (integer) 4205 case 7: // DATA_USERLEVEL (integer)
4206 reply = account.UserLevel.ToString(); 4206 reply = account.UserLevel.ToString();
4207 break; 4207 break;
4208 case 8: // DATA_PAYINFO (0|1|2|3) 4208 case 8: // DATA_PAYINFO (0|1|2|3)
4209 reply = "0"; 4209 reply = "0";
4210 break; 4210 break;
4211 default: 4211 default:
4212 return UUID.Zero.ToString(); // Raise no event 4212 return UUID.Zero.ToString(); // Raise no event
4213 } 4213 }
4214   4214  
4215 UUID rq = UUID.Random(); 4215 UUID rq = UUID.Random();
4216   4216  
4217 UUID tid = AsyncCommands. 4217 UUID tid = AsyncCommands.
4218 DataserverPlugin.RegisterRequest(m_host.LocalId, 4218 DataserverPlugin.RegisterRequest(m_host.LocalId,
4219 m_item.ItemID, rq.ToString()); 4219 m_item.ItemID, rq.ToString());
4220   4220  
4221 AsyncCommands. 4221 AsyncCommands.
4222 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4222 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4223   4223  
4224 ScriptSleep(100); 4224 ScriptSleep(100);
4225 return tid.ToString(); 4225 return tid.ToString();
4226 } 4226 }
4227   4227  
4228 public LSL_String llRequestInventoryData(string name) 4228 public LSL_String llRequestInventoryData(string name)
4229 { 4229 {
4230 m_host.AddScriptLPS(1); 4230 m_host.AddScriptLPS(1);
4231   4231  
4232 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) 4232 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
4233 { 4233 {
4234 if (item.Type == 3 && item.Name == name) 4234 if (item.Type == 3 && item.Name == name)
4235 { 4235 {
4236 UUID tid = AsyncCommands. 4236 UUID tid = AsyncCommands.
4237 DataserverPlugin.RegisterRequest(m_host.LocalId, 4237 DataserverPlugin.RegisterRequest(m_host.LocalId,
4238 m_item.ItemID, item.AssetID.ToString()); 4238 m_item.ItemID, item.AssetID.ToString());
4239   4239  
4240 Vector3 region = new Vector3(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0); 4240 Vector3 region = new Vector3(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0);
4241   4241  
4242 World.AssetService.Get(item.AssetID.ToString(), this, 4242 World.AssetService.Get(item.AssetID.ToString(), this,
4243 delegate(string i, object sender, AssetBase a) 4243 delegate(string i, object sender, AssetBase a)
4244 { 4244 {
4245 AssetLandmark lm = new AssetLandmark(a); 4245 AssetLandmark lm = new AssetLandmark(a);
4246   4246  
4247 float rx = (uint)(lm.RegionHandle >> 32); 4247 float rx = (uint)(lm.RegionHandle >> 32);
4248 float ry = (uint)lm.RegionHandle; 4248 float ry = (uint)lm.RegionHandle;
4249 region = lm.Position + new Vector3(rx, ry, 0) - region; 4249 region = lm.Position + new Vector3(rx, ry, 0) - region;
4250   4250  
4251 string reply = region.ToString(); 4251 string reply = region.ToString();
4252 AsyncCommands. 4252 AsyncCommands.
4253 DataserverPlugin.DataserverReply(i.ToString(), 4253 DataserverPlugin.DataserverReply(i.ToString(),
4254 reply); 4254 reply);
4255 }); 4255 });
4256   4256  
4257 ScriptSleep(1000); 4257 ScriptSleep(1000);
4258 return tid.ToString(); 4258 return tid.ToString();
4259 } 4259 }
4260 } 4260 }
4261   4261  
4262 ScriptSleep(1000); 4262 ScriptSleep(1000);
4263 return String.Empty; 4263 return String.Empty;
4264 } 4264 }
4265   4265  
4266 public void llSetDamage(double damage) 4266 public void llSetDamage(double damage)
4267 { 4267 {
4268 m_host.AddScriptLPS(1); 4268 m_host.AddScriptLPS(1);
4269 m_host.ParentGroup.Damage = (float)damage; 4269 m_host.ParentGroup.Damage = (float)damage;
4270 } 4270 }
4271   4271  
4272 public void llTeleportAgentHome(string agent) 4272 public void llTeleportAgentHome(string agent)
4273 { 4273 {
4274 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
4275 UUID agentId = new UUID(); 4275 UUID agentId = new UUID();
4276 if (UUID.TryParse(agent, out agentId)) 4276 if (UUID.TryParse(agent, out agentId))
4277 { 4277 {
4278 ScenePresence presence = World.GetScenePresence(agentId); 4278 ScenePresence presence = World.GetScenePresence(agentId);
4279 if (presence != null) 4279 if (presence != null)
4280 { 4280 {
4281 // agent must be over the owners land 4281 // agent must be over the owners land
4282 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4282 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4283 { 4283 {
4284 World.TeleportClientHome(agentId, presence.ControllingClient); 4284 World.TeleportClientHome(agentId, presence.ControllingClient);
4285 } 4285 }
4286 } 4286 }
4287 } 4287 }
4288   4288  
4289 ScriptSleep(5000); 4289 ScriptSleep(5000);
4290 } 4290 }
4291   4291  
4292 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) 4292 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4293 { 4293 {
4294 m_host.AddScriptLPS(1); 4294 m_host.AddScriptLPS(1);
4295 UUID agentId = new UUID(); 4295 UUID agentId = new UUID();
4296   4296  
4297 if (UUID.TryParse(agent, out agentId)) 4297 if (UUID.TryParse(agent, out agentId))
4298 { 4298 {
4299 ScenePresence presence = World.GetScenePresence(agentId); 4299 ScenePresence presence = World.GetScenePresence(agentId);
4300 if (presence != null && presence.PresenceType != PresenceType.Npc) 4300 if (presence != null && presence.PresenceType != PresenceType.Npc)
4301 { 4301 {
4302 // agent must not be a god 4302 // agent must not be a god
4303 if (presence.GodLevel >= 200) return; 4303 if (presence.GodLevel >= 200) return;
4304   4304  
4305 if (destination == String.Empty) 4305 if (destination == String.Empty)
4306 destination = World.RegionInfo.RegionName; 4306 destination = World.RegionInfo.RegionName;
4307   4307  
4308 // agent must be over the owners land 4308 // agent must be over the owners land
4309 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4309 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4310 { 4310 {
4311 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4311 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4312 } 4312 }
4313 else // or must be wearing the prim 4313 else // or must be wearing the prim
4314 { 4314 {
4315 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4315 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4316 { 4316 {
4317 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4317 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4318 } 4318 }
4319 } 4319 }
4320 } 4320 }
4321 } 4321 }
4322 } 4322 }
4323   4323  
4324 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt) 4324 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4325 { 4325 {
4326 m_host.AddScriptLPS(1); 4326 m_host.AddScriptLPS(1);
4327 UUID agentId = new UUID(); 4327 UUID agentId = new UUID();
4328   4328  
4329 ulong regionHandle = Util.RegionWorldLocToHandle((uint)global_coords.x, (uint)global_coords.y); 4329 ulong regionHandle = Util.RegionWorldLocToHandle((uint)global_coords.x, (uint)global_coords.y);
4330   4330  
4331 if (UUID.TryParse(agent, out agentId)) 4331 if (UUID.TryParse(agent, out agentId))
4332 { 4332 {
4333 ScenePresence presence = World.GetScenePresence(agentId); 4333 ScenePresence presence = World.GetScenePresence(agentId);
4334 if (presence != null && presence.PresenceType != PresenceType.Npc) 4334 if (presence != null && presence.PresenceType != PresenceType.Npc)
4335 { 4335 {
4336 // agent must not be a god 4336 // agent must not be a god
4337 if (presence.GodLevel >= 200) return; 4337 if (presence.GodLevel >= 200) return;
4338   4338  
4339 // agent must be over the owners land 4339 // agent must be over the owners land
4340 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4340 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4341 { 4341 {
4342 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4342 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4343 } 4343 }
4344 else // or must be wearing the prim 4344 else // or must be wearing the prim
4345 { 4345 {
4346 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4346 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4347 { 4347 {
4348 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4348 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4349 } 4349 }
4350 } 4350 }
4351 } 4351 }
4352 } 4352 }
4353 } 4353 }
4354   4354  
4355 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) 4355 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt)
4356 { 4356 {
4357 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination); 4357 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination);
4358   4358  
4359 // The destinaion is not an asset ID and also doesn't name a landmark. 4359 // The destinaion is not an asset ID and also doesn't name a landmark.
4360 // Use it as a sim name 4360 // Use it as a sim name
4361 if (assetID == UUID.Zero) 4361 if (assetID == UUID.Zero)
4362 { 4362 {
4363 World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4363 World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4364 return; 4364 return;
4365 } 4365 }
4366   4366  
4367 AssetBase lma = World.AssetService.Get(assetID.ToString()); 4367 AssetBase lma = World.AssetService.Get(assetID.ToString());
4368 if (lma == null) 4368 if (lma == null)
4369 return; 4369 return;
4370   4370  
4371 if (lma.Type != (sbyte)AssetType.Landmark) 4371 if (lma.Type != (sbyte)AssetType.Landmark)
4372 return; 4372 return;
4373   4373  
4374 AssetLandmark lm = new AssetLandmark(lma); 4374 AssetLandmark lm = new AssetLandmark(lma);
4375   4375  
4376 World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4376 World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4377 } 4377 }
4378   4378  
4379 public void llTextBox(string agent, string message, int chatChannel) 4379 public void llTextBox(string agent, string message, int chatChannel)
4380 { 4380 {
4381 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4381 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
4382   4382  
4383 if (dm == null) 4383 if (dm == null)
4384 return; 4384 return;
4385   4385  
4386 m_host.AddScriptLPS(1); 4386 m_host.AddScriptLPS(1);
4387 UUID av = new UUID(); 4387 UUID av = new UUID();
4388 if (!UUID.TryParse(agent,out av)) 4388 if (!UUID.TryParse(agent,out av))
4389 { 4389 {
4390 Error("llTextBox", "First parameter must be a key"); 4390 Error("llTextBox", "First parameter must be a key");
4391 return; 4391 return;
4392 } 4392 }
4393   4393  
4394 if (message == string.Empty) 4394 if (message == string.Empty)
4395 { 4395 {
4396 Error("llTextBox", "Empty message"); 4396 Error("llTextBox", "Empty message");
4397 } 4397 }
4398 else if (message.Length > 512) 4398 else if (message.Length > 512)
4399 { 4399 {
4400 Error("llTextBox", "Message more than 512 characters"); 4400 Error("llTextBox", "Message more than 512 characters");
4401 } 4401 }
4402 else 4402 else
4403 { 4403 {
4404 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID); 4404 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID);
4405 ScriptSleep(1000); 4405 ScriptSleep(1000);
4406 } 4406 }
4407 } 4407 }
4408   4408  
4409 public void llModifyLand(int action, int brush) 4409 public void llModifyLand(int action, int brush)
4410 { 4410 {
4411 m_host.AddScriptLPS(1); 4411 m_host.AddScriptLPS(1);
4412 ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>(); 4412 ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>();
4413 if (tm != null) 4413 if (tm != null)
4414 { 4414 {
4415 tm.ModifyTerrain(m_host.OwnerID, m_host.AbsolutePosition, (byte) brush, (byte) action, m_host.OwnerID); 4415 tm.ModifyTerrain(m_host.OwnerID, m_host.AbsolutePosition, (byte) brush, (byte) action, m_host.OwnerID);
4416 } 4416 }
4417 } 4417 }
4418   4418  
4419 public void llCollisionSound(string impact_sound, double impact_volume) 4419 public void llCollisionSound(string impact_sound, double impact_volume)
4420 { 4420 {
4421 m_host.AddScriptLPS(1); 4421 m_host.AddScriptLPS(1);
4422   4422  
4423 // TODO: Parameter check logic required. 4423 // TODO: Parameter check logic required.
4424 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4424 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4425 m_host.CollisionSoundVolume = (float)impact_volume; 4425 m_host.CollisionSoundVolume = (float)impact_volume;
4426 } 4426 }
4427   4427  
4428 public LSL_String llGetAnimation(string id) 4428 public LSL_String llGetAnimation(string id)
4429 { 4429 {
4430 // This should only return a value if the avatar is in the same region 4430 // This should only return a value if the avatar is in the same region
4431 m_host.AddScriptLPS(1); 4431 m_host.AddScriptLPS(1);
4432 UUID avatar = (UUID)id; 4432 UUID avatar = (UUID)id;
4433 ScenePresence presence = World.GetScenePresence(avatar); 4433 ScenePresence presence = World.GetScenePresence(avatar);
4434 if (presence == null) 4434 if (presence == null)
4435 return ""; 4435 return "";
4436   4436  
4437 if (m_host.RegionHandle == presence.RegionHandle) 4437 if (m_host.RegionHandle == presence.RegionHandle)
4438 { 4438 {
4439 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames; 4439 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4440   4440  
4441 if (presence != null) 4441 if (presence != null)
4442 { 4442 {
4443 AnimationSet currentAnims = presence.Animator.Animations; 4443 AnimationSet currentAnims = presence.Animator.Animations;
4444 string currentAnimationState = String.Empty; 4444 string currentAnimationState = String.Empty;
4445 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4445 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState))
4446 return currentAnimationState; 4446 return currentAnimationState;
4447 } 4447 }
4448 } 4448 }
4449   4449  
4450 return String.Empty; 4450 return String.Empty;
4451 } 4451 }
4452   4452  
4453 public void llMessageLinked(int linknumber, int num, string msg, string id) 4453 public void llMessageLinked(int linknumber, int num, string msg, string id)
4454 { 4454 {
4455 m_host.AddScriptLPS(1); 4455 m_host.AddScriptLPS(1);
4456   4456  
4457 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4457 List<SceneObjectPart> parts = GetLinkParts(linknumber);
4458   4458  
4459 UUID partItemID; 4459 UUID partItemID;
4460 foreach (SceneObjectPart part in parts) 4460 foreach (SceneObjectPart part in parts)
4461 { 4461 {
4462 foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems()) 4462 foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems())
4463 { 4463 {
4464 if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT) 4464 if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT)
4465 { 4465 {
4466 partItemID = item.ItemID; 4466 partItemID = item.ItemID;
4467 int linkNumber = m_host.LinkNum; 4467 int linkNumber = m_host.LinkNum;
4468 if (m_host.ParentGroup.PrimCount == 1) 4468 if (m_host.ParentGroup.PrimCount == 1)
4469 linkNumber = 0; 4469 linkNumber = 0;
4470   4470  
4471 object[] resobj = new object[] 4471 object[] resobj = new object[]
4472 { 4472 {
4473 new LSL_Integer(linkNumber), new LSL_Integer(num), new LSL_String(msg), new LSL_String(id) 4473 new LSL_Integer(linkNumber), new LSL_Integer(num), new LSL_String(msg), new LSL_String(id)
4474 }; 4474 };
4475   4475  
4476 m_ScriptEngine.PostScriptEvent(partItemID, 4476 m_ScriptEngine.PostScriptEvent(partItemID,
4477 new EventParams("link_message", 4477 new EventParams("link_message",
4478 resobj, new DetectParams[0])); 4478 resobj, new DetectParams[0]));
4479 } 4479 }
4480 } 4480 }
4481 } 4481 }
4482 } 4482 }
4483   4483  
4484 public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) 4484 public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
4485 { 4485 {
4486 m_host.AddScriptLPS(1); 4486 m_host.AddScriptLPS(1);
4487 bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing; 4487 bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing;
4488 bool pushAllowed = false; 4488 bool pushAllowed = false;
4489   4489  
4490 bool pusheeIsAvatar = false; 4490 bool pusheeIsAvatar = false;
4491 UUID targetID = UUID.Zero; 4491 UUID targetID = UUID.Zero;
4492   4492  
4493 if (!UUID.TryParse(target,out targetID)) 4493 if (!UUID.TryParse(target,out targetID))
4494 return; 4494 return;
4495   4495  
4496 ScenePresence pusheeav = null; 4496 ScenePresence pusheeav = null;
4497 Vector3 PusheePos = Vector3.Zero; 4497 Vector3 PusheePos = Vector3.Zero;
4498 SceneObjectPart pusheeob = null; 4498 SceneObjectPart pusheeob = null;
4499   4499  
4500 ScenePresence avatar = World.GetScenePresence(targetID); 4500 ScenePresence avatar = World.GetScenePresence(targetID);
4501 if (avatar != null) 4501 if (avatar != null)
4502 { 4502 {
4503 pusheeIsAvatar = true; 4503 pusheeIsAvatar = true;
4504   4504  
4505 // Pushee doesn't have a physics actor 4505 // Pushee doesn't have a physics actor
4506 if (avatar.PhysicsActor == null) 4506 if (avatar.PhysicsActor == null)
4507 return; 4507 return;
4508   4508  
4509 // Pushee is in GodMode this pushing object isn't owned by them 4509 // Pushee is in GodMode this pushing object isn't owned by them
4510 if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) 4510 if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
4511 return; 4511 return;
4512   4512  
4513 pusheeav = avatar; 4513 pusheeav = avatar;
4514   4514  
4515 // Find pushee position 4515 // Find pushee position
4516 // Pushee Linked? 4516 // Pushee Linked?
4517 SceneObjectPart sitPart = pusheeav.ParentPart; 4517 SceneObjectPart sitPart = pusheeav.ParentPart;
4518 if (sitPart != null) 4518 if (sitPart != null)
4519 PusheePos = sitPart.AbsolutePosition; 4519 PusheePos = sitPart.AbsolutePosition;
4520 else 4520 else
4521 PusheePos = pusheeav.AbsolutePosition; 4521 PusheePos = pusheeav.AbsolutePosition;
4522 } 4522 }
4523   4523  
4524 if (!pusheeIsAvatar) 4524 if (!pusheeIsAvatar)
4525 { 4525 {
4526 // not an avatar so push is not affected by parcel flags 4526 // not an avatar so push is not affected by parcel flags
4527 pusheeob = World.GetSceneObjectPart((UUID)target); 4527 pusheeob = World.GetSceneObjectPart((UUID)target);
4528   4528  
4529 // We can't find object 4529 // We can't find object
4530 if (pusheeob == null) 4530 if (pusheeob == null)
4531 return; 4531 return;
4532   4532  
4533 // Object not pushable. Not an attachment and has no physics component 4533 // Object not pushable. Not an attachment and has no physics component
4534 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null) 4534 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4535 return; 4535 return;
4536   4536  
4537 PusheePos = pusheeob.AbsolutePosition; 4537 PusheePos = pusheeob.AbsolutePosition;
4538 pushAllowed = true; 4538 pushAllowed = true;
4539 } 4539 }
4540 else 4540 else
4541 { 4541 {
4542 if (pushrestricted) 4542 if (pushrestricted)
4543 { 4543 {
4544 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); 4544 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4545   4545  
4546 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4546 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4547 if (targetlandObj == null) 4547 if (targetlandObj == null)
4548 return; 4548 return;
4549   4549  
4550 // Need provisions for Group Owned here 4550 // Need provisions for Group Owned here
4551 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4551 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4552 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID) 4552 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID)
4553 { 4553 {
4554 pushAllowed = true; 4554 pushAllowed = true;
4555 } 4555 }
4556 } 4556 }
4557 else 4557 else
4558 { 4558 {
4559 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); 4559 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4560 if (targetlandObj == null) 4560 if (targetlandObj == null)
4561 { 4561 {
4562 // We didn't find the parcel but region isn't push restricted so assume it's ok 4562 // We didn't find the parcel but region isn't push restricted so assume it's ok
4563 pushAllowed = true; 4563 pushAllowed = true;
4564 } 4564 }
4565 else 4565 else
4566 { 4566 {
4567 // Parcel push restriction 4567 // Parcel push restriction
4568 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject) 4568 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)
4569 { 4569 {
4570 // Need provisions for Group Owned here 4570 // Need provisions for Group Owned here
4571 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4571 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4572 targetlandObj.LandData.IsGroupOwned || 4572 targetlandObj.LandData.IsGroupOwned ||
4573 m_host.OwnerID == targetID) 4573 m_host.OwnerID == targetID)
4574 { 4574 {
4575 pushAllowed = true; 4575 pushAllowed = true;
4576 } 4576 }
4577   4577  
4578 //ParcelFlags.RestrictPushObject 4578 //ParcelFlags.RestrictPushObject
4579 //pushAllowed = true; 4579 //pushAllowed = true;
4580 } 4580 }
4581 else 4581 else
4582 { 4582 {
4583 // Parcel isn't push restricted 4583 // Parcel isn't push restricted
4584 pushAllowed = true; 4584 pushAllowed = true;
4585 } 4585 }
4586 } 4586 }
4587 } 4587 }
4588 } 4588 }
4589   4589  
4590 if (pushAllowed) 4590 if (pushAllowed)
4591 { 4591 {
4592 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4592 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4593 float distance_term = distance * distance * distance; // Script Energy 4593 float distance_term = distance * distance * distance; // Script Energy
4594 float pusher_mass = m_host.GetMass(); 4594 float pusher_mass = m_host.GetMass();
4595   4595  
4596 float PUSH_ATTENUATION_DISTANCE = 17f; 4596 float PUSH_ATTENUATION_DISTANCE = 17f;
4597 float PUSH_ATTENUATION_SCALE = 5f; 4597 float PUSH_ATTENUATION_SCALE = 5f;
4598 float distance_attenuation = 1f; 4598 float distance_attenuation = 1f;
4599 if (distance > PUSH_ATTENUATION_DISTANCE) 4599 if (distance > PUSH_ATTENUATION_DISTANCE)
4600 { 4600 {
4601 float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE; 4601 float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE;
4602 distance_attenuation = 1f / normalized_units; 4602 distance_attenuation = 1f / normalized_units;
4603 } 4603 }
4604   4604  
4605 Vector3 applied_linear_impulse = impulse; 4605 Vector3 applied_linear_impulse = impulse;
4606 { 4606 {
4607 float impulse_length = applied_linear_impulse.Length(); 4607 float impulse_length = applied_linear_impulse.Length();
4608   4608  
4609 float desired_energy = impulse_length * pusher_mass; 4609 float desired_energy = impulse_length * pusher_mass;
4610 if (desired_energy > 0f) 4610 if (desired_energy > 0f)
4611 desired_energy += distance_term; 4611 desired_energy += distance_term;
4612   4612  
4613 float scaling_factor = 1f; 4613 float scaling_factor = 1f;
4614 scaling_factor *= distance_attenuation; 4614 scaling_factor *= distance_attenuation;
4615 applied_linear_impulse *= scaling_factor; 4615 applied_linear_impulse *= scaling_factor;
4616   4616  
4617 } 4617 }
4618   4618  
4619 if (pusheeIsAvatar) 4619 if (pusheeIsAvatar)
4620 { 4620 {
4621 if (pusheeav != null) 4621 if (pusheeav != null)
4622 { 4622 {
4623 PhysicsActor pa = pusheeav.PhysicsActor; 4623 PhysicsActor pa = pusheeav.PhysicsActor;
4624   4624  
4625 if (pa != null) 4625 if (pa != null)
4626 { 4626 {
4627 if (local != 0) 4627 if (local != 0)
4628 { 4628 {
4629 applied_linear_impulse *= m_host.GetWorldRotation(); 4629 applied_linear_impulse *= m_host.GetWorldRotation();
4630 } 4630 }
4631   4631  
4632 pa.AddForce(applied_linear_impulse, true); 4632 pa.AddForce(applied_linear_impulse, true);
4633 } 4633 }
4634 } 4634 }
4635 } 4635 }
4636 else 4636 else
4637 { 4637 {
4638 if (pusheeob != null) 4638 if (pusheeob != null)
4639 { 4639 {
4640 if (pusheeob.PhysActor != null) 4640 if (pusheeob.PhysActor != null)
4641 { 4641 {
4642 pusheeob.ApplyImpulse(applied_linear_impulse, local != 0); 4642 pusheeob.ApplyImpulse(applied_linear_impulse, local != 0);
4643 } 4643 }
4644 } 4644 }
4645 } 4645 }
4646 } 4646 }
4647 } 4647 }
4648   4648  
4649 public void llPassCollisions(int pass) 4649 public void llPassCollisions(int pass)
4650 { 4650 {
4651 m_host.AddScriptLPS(1); 4651 m_host.AddScriptLPS(1);
4652 if (pass == 0) 4652 if (pass == 0)
4653 { 4653 {
4654 m_host.PassCollisions = false; 4654 m_host.PassCollisions = false;
4655 } 4655 }
4656 else 4656 else
4657 { 4657 {
4658 m_host.PassCollisions = true; 4658 m_host.PassCollisions = true;
4659 } 4659 }
4660 } 4660 }
4661   4661  
4662 public LSL_String llGetScriptName() 4662 public LSL_String llGetScriptName()
4663 { 4663 {
4664 m_host.AddScriptLPS(1); 4664 m_host.AddScriptLPS(1);
4665   4665  
4666 return m_item.Name != null ? m_item.Name : String.Empty; 4666 return m_item.Name != null ? m_item.Name : String.Empty;
4667 } 4667 }
4668   4668  
4669 public LSL_Integer llGetLinkNumberOfSides(int link) 4669 public LSL_Integer llGetLinkNumberOfSides(int link)
4670 { 4670 {
4671 m_host.AddScriptLPS(1); 4671 m_host.AddScriptLPS(1);
4672   4672  
4673 SceneObjectPart linkedPart; 4673 SceneObjectPart linkedPart;
4674   4674  
4675 if (link == ScriptBaseClass.LINK_ROOT) 4675 if (link == ScriptBaseClass.LINK_ROOT)
4676 linkedPart = m_host.ParentGroup.RootPart; 4676 linkedPart = m_host.ParentGroup.RootPart;
4677 else if (link == ScriptBaseClass.LINK_THIS) 4677 else if (link == ScriptBaseClass.LINK_THIS)
4678 linkedPart = m_host; 4678 linkedPart = m_host;
4679 else 4679 else
4680 linkedPart = m_host.ParentGroup.GetLinkNumPart(link); 4680 linkedPart = m_host.ParentGroup.GetLinkNumPart(link);
4681   4681  
4682 return GetNumberOfSides(linkedPart); 4682 return GetNumberOfSides(linkedPart);
4683 } 4683 }
4684   4684  
4685 public LSL_Integer llGetNumberOfSides() 4685 public LSL_Integer llGetNumberOfSides()
4686 { 4686 {
4687 m_host.AddScriptLPS(1); 4687 m_host.AddScriptLPS(1);
4688   4688  
4689 return GetNumberOfSides(m_host); 4689 return GetNumberOfSides(m_host);
4690 } 4690 }
4691   4691  
4692 protected int GetNumberOfSides(SceneObjectPart part) 4692 protected int GetNumberOfSides(SceneObjectPart part)
4693 { 4693 {
4694 int sides = part.GetNumberOfSides(); 4694 int sides = part.GetNumberOfSides();
4695   4695  
4696 if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0) 4696 if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
4697 { 4697 {
4698 // Make up for a bug where LSL shows 4 sides rather than 2 4698 // Make up for a bug where LSL shows 4 sides rather than 2
4699 sides += 2; 4699 sides += 2;
4700 } 4700 }
4701   4701  
4702 return sides; 4702 return sides;
4703 } 4703 }
4704   4704  
4705   4705  
4706 /* The new / changed functions were tested with the following LSL script: 4706 /* The new / changed functions were tested with the following LSL script:
4707   4707  
4708 default 4708 default
4709 { 4709 {
4710 state_entry() 4710 state_entry()
4711 { 4711 {
4712 rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD); 4712 rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD);
4713   4713  
4714 llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot)); 4714 llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot));
4715 llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG)); 4715 llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG));
4716   4716  
4717 // convert back and forth between quaternion <-> vector and angle 4717 // convert back and forth between quaternion <-> vector and angle
4718   4718  
4719 rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot)); 4719 rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot));
4720   4720  
4721 llOwnerSay("Old rotation was: "+(string) rot); 4721 llOwnerSay("Old rotation was: "+(string) rot);
4722 llOwnerSay("re-converted rotation is: "+(string) newrot); 4722 llOwnerSay("re-converted rotation is: "+(string) newrot);
4723   4723  
4724 llSetRot(rot); // to check the parameters in the prim 4724 llSetRot(rot); // to check the parameters in the prim
4725 } 4725 }
4726 } 4726 }
4727 */ 4727 */
4728   4728  
4729 // Xantor 29/apr/2008 4729 // Xantor 29/apr/2008
4730 // Returns rotation described by rotating angle radians about axis. 4730 // Returns rotation described by rotating angle radians about axis.
4731 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) 4731 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
4732 public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle) 4732 public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle)
4733 { 4733 {
4734 m_host.AddScriptLPS(1); 4734 m_host.AddScriptLPS(1);
4735   4735  
4736 double x, y, z, s, t; 4736 double x, y, z, s, t;
4737   4737  
4738 s = Math.Cos(angle * 0.5); 4738 s = Math.Cos(angle * 0.5);
4739 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs 4739 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs
4740 axis = LSL_Vector.Norm(axis); 4740 axis = LSL_Vector.Norm(axis);
4741 x = axis.x * t; 4741 x = axis.x * t;
4742 y = axis.y * t; 4742 y = axis.y * t;
4743 z = axis.z * t; 4743 z = axis.z * t;
4744   4744  
4745 return new LSL_Rotation(x,y,z,s); 4745 return new LSL_Rotation(x,y,z,s);
4746 } 4746 }
4747   4747  
4748 /// <summary> 4748 /// <summary>
4749 /// Returns the axis of rotation for a quaternion 4749 /// Returns the axis of rotation for a quaternion
4750 /// </summary> 4750 /// </summary>
4751 /// <returns></returns> 4751 /// <returns></returns>
4752 /// <param name='rot'></param> 4752 /// <param name='rot'></param>
4753 public LSL_Vector llRot2Axis(LSL_Rotation rot) 4753 public LSL_Vector llRot2Axis(LSL_Rotation rot)
4754 { 4754 {
4755 m_host.AddScriptLPS(1); 4755 m_host.AddScriptLPS(1);
4756   4756  
4757 if (Math.Abs(rot.s) > 1) // normalization needed 4757 if (Math.Abs(rot.s) > 1) // normalization needed
4758 rot.Normalize(); 4758 rot.Normalize();
4759   4759  
4760 double s = Math.Sqrt(1 - rot.s * rot.s); 4760 double s = Math.Sqrt(1 - rot.s * rot.s);
4761 if (s < 0.001) 4761 if (s < 0.001)
4762 { 4762 {
4763 return new LSL_Vector(1, 0, 0); 4763 return new LSL_Vector(1, 0, 0);
4764 } 4764 }
4765 else 4765 else
4766 { 4766 {
4767 double invS = 1.0 / s; 4767 double invS = 1.0 / s;
4768 if (rot.s < 0) invS = -invS; 4768 if (rot.s < 0) invS = -invS;
4769 return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); 4769 return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS);
4770 } 4770 }
4771 } 4771 }
4772   4772  
4773   4773  
4774 // Returns the angle of a quaternion (see llRot2Axis for the axis) 4774 // Returns the angle of a quaternion (see llRot2Axis for the axis)
4775 public LSL_Float llRot2Angle(LSL_Rotation rot) 4775 public LSL_Float llRot2Angle(LSL_Rotation rot)
4776 { 4776 {
4777 m_host.AddScriptLPS(1); 4777 m_host.AddScriptLPS(1);
4778   4778  
4779 if (Math.Abs(rot.s) > 1) // normalization needed 4779 if (Math.Abs(rot.s) > 1) // normalization needed
4780 rot.Normalize(); 4780 rot.Normalize();
4781   4781  
4782 double angle = 2 * Math.Acos(rot.s); 4782 double angle = 2 * Math.Acos(rot.s);
4783 if (angle > Math.PI) 4783 if (angle > Math.PI)
4784 angle = 2 * Math.PI - angle; 4784 angle = 2 * Math.PI - angle;
4785   4785  
4786 return angle; 4786 return angle;
4787 } 4787 }
4788   4788  
4789 public LSL_Float llAcos(double val) 4789 public LSL_Float llAcos(double val)
4790 { 4790 {
4791 m_host.AddScriptLPS(1); 4791 m_host.AddScriptLPS(1);
4792 return (double)Math.Acos(val); 4792 return (double)Math.Acos(val);
4793 } 4793 }
4794   4794  
4795 public LSL_Float llAsin(double val) 4795 public LSL_Float llAsin(double val)
4796 { 4796 {
4797 m_host.AddScriptLPS(1); 4797 m_host.AddScriptLPS(1);
4798 return (double)Math.Asin(val); 4798 return (double)Math.Asin(val);
4799 } 4799 }
4800   4800  
4801 // jcochran 5/jan/2012 4801 // jcochran 5/jan/2012
4802 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) 4802 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
4803 { 4803 {
4804 m_host.AddScriptLPS(1); 4804 m_host.AddScriptLPS(1);
4805   4805  
4806 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s); 4806 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
4807 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s); 4807 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
4808 double aa_bb = aa * bb; 4808 double aa_bb = aa * bb;
4809 if (aa_bb == 0) return 0.0; 4809 if (aa_bb == 0) return 0.0;
4810 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s); 4810 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
4811 double quotient = (ab * ab) / aa_bb; 4811 double quotient = (ab * ab) / aa_bb;
4812 if (quotient >= 1.0) return 0.0; 4812 if (quotient >= 1.0) return 0.0;
4813 return Math.Acos(2 * quotient - 1); 4813 return Math.Acos(2 * quotient - 1);
4814 } 4814 }
4815   4815  
4816 public LSL_String llGetInventoryKey(string name) 4816 public LSL_String llGetInventoryKey(string name)
4817 { 4817 {
4818 m_host.AddScriptLPS(1); 4818 m_host.AddScriptLPS(1);
4819   4819  
4820 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 4820 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
4821   4821  
4822 if (item == null) 4822 if (item == null)
4823 return UUID.Zero.ToString(); 4823 return UUID.Zero.ToString();
4824   4824  
4825 if ((item.CurrentPermissions 4825 if ((item.CurrentPermissions
4826 & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4826 & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4827 == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4827 == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4828 { 4828 {
4829 return item.AssetID.ToString(); 4829 return item.AssetID.ToString();
4830 } 4830 }
4831   4831  
4832 return UUID.Zero.ToString(); 4832 return UUID.Zero.ToString();
4833 } 4833 }
4834   4834  
4835 public void llAllowInventoryDrop(int add) 4835 public void llAllowInventoryDrop(int add)
4836 { 4836 {
4837 m_host.AddScriptLPS(1); 4837 m_host.AddScriptLPS(1);
4838   4838  
4839 if (add != 0) 4839 if (add != 0)
4840 m_host.ParentGroup.RootPart.AllowedDrop = true; 4840 m_host.ParentGroup.RootPart.AllowedDrop = true;
4841 else 4841 else
4842 m_host.ParentGroup.RootPart.AllowedDrop = false; 4842 m_host.ParentGroup.RootPart.AllowedDrop = false;
4843   4843  
4844 // Update the object flags 4844 // Update the object flags
4845 m_host.ParentGroup.RootPart.aggregateScriptEvents(); 4845 m_host.ParentGroup.RootPart.aggregateScriptEvents();
4846 } 4846 }
4847   4847  
4848 public LSL_Vector llGetSunDirection() 4848 public LSL_Vector llGetSunDirection()
4849 { 4849 {
4850 m_host.AddScriptLPS(1); 4850 m_host.AddScriptLPS(1);
4851   4851  
4852 LSL_Vector SunDoubleVector3; 4852 LSL_Vector SunDoubleVector3;
4853 Vector3 SunFloatVector3; 4853 Vector3 SunFloatVector3;
4854   4854  
4855 // sunPosition estate setting is set in OpenSim.Region.CoreModules.SunModule 4855 // sunPosition estate setting is set in OpenSim.Region.CoreModules.SunModule
4856 // have to convert from Vector3 (float) to LSL_Vector (double) 4856 // have to convert from Vector3 (float) to LSL_Vector (double)
4857 SunFloatVector3 = World.RegionInfo.RegionSettings.SunVector; 4857 SunFloatVector3 = World.RegionInfo.RegionSettings.SunVector;
4858 SunDoubleVector3.x = (double)SunFloatVector3.X; 4858 SunDoubleVector3.x = (double)SunFloatVector3.X;
4859 SunDoubleVector3.y = (double)SunFloatVector3.Y; 4859 SunDoubleVector3.y = (double)SunFloatVector3.Y;
4860 SunDoubleVector3.z = (double)SunFloatVector3.Z; 4860 SunDoubleVector3.z = (double)SunFloatVector3.Z;
4861   4861  
4862 return SunDoubleVector3; 4862 return SunDoubleVector3;
4863 } 4863 }
4864   4864  
4865 public LSL_Vector llGetTextureOffset(int face) 4865 public LSL_Vector llGetTextureOffset(int face)
4866 { 4866 {
4867 m_host.AddScriptLPS(1); 4867 m_host.AddScriptLPS(1);
4868 return GetTextureOffset(m_host, face); 4868 return GetTextureOffset(m_host, face);
4869 } 4869 }
4870   4870  
4871 protected LSL_Vector GetTextureOffset(SceneObjectPart part, int face) 4871 protected LSL_Vector GetTextureOffset(SceneObjectPart part, int face)
4872 { 4872 {
4873 Primitive.TextureEntry tex = part.Shape.Textures; 4873 Primitive.TextureEntry tex = part.Shape.Textures;
4874 LSL_Vector offset = new LSL_Vector(); 4874 LSL_Vector offset = new LSL_Vector();
4875 if (face == ScriptBaseClass.ALL_SIDES) 4875 if (face == ScriptBaseClass.ALL_SIDES)
4876 { 4876 {
4877 face = 0; 4877 face = 0;
4878 } 4878 }
4879 if (face >= 0 && face < GetNumberOfSides(part)) 4879 if (face >= 0 && face < GetNumberOfSides(part))
4880 { 4880 {
4881 offset.x = tex.GetFace((uint)face).OffsetU; 4881 offset.x = tex.GetFace((uint)face).OffsetU;
4882 offset.y = tex.GetFace((uint)face).OffsetV; 4882 offset.y = tex.GetFace((uint)face).OffsetV;
4883 offset.z = 0.0; 4883 offset.z = 0.0;
4884 return offset; 4884 return offset;
4885 } 4885 }
4886 else 4886 else
4887 { 4887 {
4888 return offset; 4888 return offset;
4889 } 4889 }
4890 } 4890 }
4891   4891  
4892 public LSL_Vector llGetTextureScale(int side) 4892 public LSL_Vector llGetTextureScale(int side)
4893 { 4893 {
4894 m_host.AddScriptLPS(1); 4894 m_host.AddScriptLPS(1);
4895 Primitive.TextureEntry tex = m_host.Shape.Textures; 4895 Primitive.TextureEntry tex = m_host.Shape.Textures;
4896 LSL_Vector scale; 4896 LSL_Vector scale;
4897 if (side == -1) 4897 if (side == -1)
4898 { 4898 {
4899 side = 0; 4899 side = 0;
4900 } 4900 }
4901 scale.x = tex.GetFace((uint)side).RepeatU; 4901 scale.x = tex.GetFace((uint)side).RepeatU;
4902 scale.y = tex.GetFace((uint)side).RepeatV; 4902 scale.y = tex.GetFace((uint)side).RepeatV;
4903 scale.z = 0.0; 4903 scale.z = 0.0;
4904 return scale; 4904 return scale;
4905 } 4905 }
4906   4906  
4907 public LSL_Float llGetTextureRot(int face) 4907 public LSL_Float llGetTextureRot(int face)
4908 { 4908 {
4909 m_host.AddScriptLPS(1); 4909 m_host.AddScriptLPS(1);
4910 return GetTextureRot(m_host, face); 4910 return GetTextureRot(m_host, face);
4911 } 4911 }
4912   4912  
4913 protected LSL_Float GetTextureRot(SceneObjectPart part, int face) 4913 protected LSL_Float GetTextureRot(SceneObjectPart part, int face)
4914 { 4914 {
4915 Primitive.TextureEntry tex = part.Shape.Textures; 4915 Primitive.TextureEntry tex = part.Shape.Textures;
4916 if (face == -1) 4916 if (face == -1)
4917 { 4917 {
4918 face = 0; 4918 face = 0;
4919 } 4919 }
4920 if (face >= 0 && face < GetNumberOfSides(part)) 4920 if (face >= 0 && face < GetNumberOfSides(part))
4921 { 4921 {
4922 return tex.GetFace((uint)face).Rotation; 4922 return tex.GetFace((uint)face).Rotation;
4923 } 4923 }
4924 else 4924 else
4925 { 4925 {
4926 return 0.0; 4926 return 0.0;
4927 } 4927 }
4928 } 4928 }
4929   4929  
4930 public LSL_Integer llSubStringIndex(string source, string pattern) 4930 public LSL_Integer llSubStringIndex(string source, string pattern)
4931 { 4931 {
4932 m_host.AddScriptLPS(1); 4932 m_host.AddScriptLPS(1);
4933 return source.IndexOf(pattern); 4933 return source.IndexOf(pattern);
4934 } 4934 }
4935   4935  
4936 public LSL_String llGetOwnerKey(string id) 4936 public LSL_String llGetOwnerKey(string id)
4937 { 4937 {
4938 m_host.AddScriptLPS(1); 4938 m_host.AddScriptLPS(1);
4939 UUID key = new UUID(); 4939 UUID key = new UUID();
4940 if (UUID.TryParse(id, out key)) 4940 if (UUID.TryParse(id, out key))
4941 { 4941 {
4942 try 4942 try
4943 { 4943 {
4944 SceneObjectPart obj = World.GetSceneObjectPart(key); 4944 SceneObjectPart obj = World.GetSceneObjectPart(key);
4945 if (obj == null) 4945 if (obj == null)
4946 return id; // the key is for an agent so just return the key 4946 return id; // the key is for an agent so just return the key
4947 else 4947 else
4948 return obj.OwnerID.ToString(); 4948 return obj.OwnerID.ToString();
4949 } 4949 }
4950 catch (KeyNotFoundException) 4950 catch (KeyNotFoundException)
4951 { 4951 {
4952 return id; // The Object/Agent not in the region so just return the key 4952 return id; // The Object/Agent not in the region so just return the key
4953 } 4953 }
4954 } 4954 }
4955 else 4955 else
4956 { 4956 {
4957 return UUID.Zero.ToString(); 4957 return UUID.Zero.ToString();
4958 } 4958 }
4959 } 4959 }
4960   4960  
4961 public LSL_Vector llGetCenterOfMass() 4961 public LSL_Vector llGetCenterOfMass()
4962 { 4962 {
4963 m_host.AddScriptLPS(1); 4963 m_host.AddScriptLPS(1);
4964   4964  
4965 return new LSL_Vector(m_host.GetCenterOfMass()); 4965 return new LSL_Vector(m_host.GetCenterOfMass());
4966 } 4966 }
4967   4967  
4968 public LSL_List llListSort(LSL_List src, int stride, int ascending) 4968 public LSL_List llListSort(LSL_List src, int stride, int ascending)
4969 { 4969 {
4970 m_host.AddScriptLPS(1); 4970 m_host.AddScriptLPS(1);
4971   4971  
4972 if (stride <= 0) 4972 if (stride <= 0)
4973 { 4973 {
4974 stride = 1; 4974 stride = 1;
4975 } 4975 }
4976 return src.Sort(stride, ascending); 4976 return src.Sort(stride, ascending);
4977 } 4977 }
4978   4978  
4979 public LSL_Integer llGetListLength(LSL_List src) 4979 public LSL_Integer llGetListLength(LSL_List src)
4980 { 4980 {
4981 m_host.AddScriptLPS(1); 4981 m_host.AddScriptLPS(1);
4982   4982  
4983 if (src == null) 4983 if (src == null)
4984 { 4984 {
4985 return 0; 4985 return 0;
4986 } 4986 }
4987 else 4987 else
4988 { 4988 {
4989 return src.Length; 4989 return src.Length;
4990 } 4990 }
4991 } 4991 }
4992   4992  
4993 public LSL_Integer llList2Integer(LSL_List src, int index) 4993 public LSL_Integer llList2Integer(LSL_List src, int index)
4994 { 4994 {
4995 m_host.AddScriptLPS(1); 4995 m_host.AddScriptLPS(1);
4996 if (index < 0) 4996 if (index < 0)
4997 { 4997 {
4998 index = src.Length + index; 4998 index = src.Length + index;
4999 } 4999 }
5000 if (index >= src.Length || index < 0) 5000 if (index >= src.Length || index < 0)
5001 { 5001 {
5002 return 0; 5002 return 0;
5003 } 5003 }
5004   5004  
5005 // Vectors & Rotations always return zero in SL, but 5005 // Vectors & Rotations always return zero in SL, but
5006 // keys don't always return zero, it seems to be a bit complex. 5006 // keys don't always return zero, it seems to be a bit complex.
5007 else if (src.Data[index] is LSL_Vector || 5007 else if (src.Data[index] is LSL_Vector ||
5008 src.Data[index] is LSL_Rotation) 5008 src.Data[index] is LSL_Rotation)
5009 { 5009 {
5010 return 0; 5010 return 0;
5011 } 5011 }
5012 try 5012 try
5013 { 5013 {
5014   5014  
5015 if (src.Data[index] is LSL_Integer) 5015 if (src.Data[index] is LSL_Integer)
5016 return (LSL_Integer)src.Data[index]; 5016 return (LSL_Integer)src.Data[index];
5017 else if (src.Data[index] is LSL_Float) 5017 else if (src.Data[index] is LSL_Float)
5018 return Convert.ToInt32(((LSL_Float)src.Data[index]).value); 5018 return Convert.ToInt32(((LSL_Float)src.Data[index]).value);
5019 return new LSL_Integer(src.Data[index].ToString()); 5019 return new LSL_Integer(src.Data[index].ToString());
5020 } 5020 }
5021 catch (FormatException) 5021 catch (FormatException)
5022 { 5022 {
5023 return 0; 5023 return 0;
5024 } 5024 }
5025 } 5025 }
5026   5026  
5027 public LSL_Float llList2Float(LSL_List src, int index) 5027 public LSL_Float llList2Float(LSL_List src, int index)
5028 { 5028 {
5029 m_host.AddScriptLPS(1); 5029 m_host.AddScriptLPS(1);
5030 if (index < 0) 5030 if (index < 0)
5031 { 5031 {
5032 index = src.Length + index; 5032 index = src.Length + index;
5033 } 5033 }
5034 if (index >= src.Length || index < 0) 5034 if (index >= src.Length || index < 0)
5035 { 5035 {
5036 return 0.0; 5036 return 0.0;
5037 } 5037 }
5038   5038  
5039 // Vectors & Rotations always return zero in SL 5039 // Vectors & Rotations always return zero in SL
5040 else if (src.Data[index] is LSL_Vector || 5040 else if (src.Data[index] is LSL_Vector ||
5041 src.Data[index] is LSL_Rotation) 5041 src.Data[index] is LSL_Rotation)
5042 { 5042 {
5043 return 0; 5043 return 0;
5044 } 5044 }
5045 // valid keys seem to get parsed as integers then converted to floats 5045 // valid keys seem to get parsed as integers then converted to floats
5046 else 5046 else
5047 { 5047 {
5048 UUID uuidt; 5048 UUID uuidt;
5049 if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) 5049 if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt))
5050 { 5050 {
5051 return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); 5051 return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value);
5052 } 5052 }
5053 } 5053 }
5054 try 5054 try
5055 { 5055 {
5056 if (src.Data[index] is LSL_Integer) 5056 if (src.Data[index] is LSL_Integer)
5057 return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); 5057 return Convert.ToDouble(((LSL_Integer)src.Data[index]).value);
5058 else if (src.Data[index] is LSL_Float) 5058 else if (src.Data[index] is LSL_Float)
5059 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5059 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5060 else if (src.Data[index] is LSL_String) 5060 else if (src.Data[index] is LSL_String)
5061 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5061 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string);
5062 return Convert.ToDouble(src.Data[index]); 5062 return Convert.ToDouble(src.Data[index]);
5063 } 5063 }
5064 catch (FormatException) 5064 catch (FormatException)
5065 { 5065 {
5066 return 0.0; 5066 return 0.0;
5067 } 5067 }
5068 } 5068 }
5069   5069  
5070 public LSL_String llList2String(LSL_List src, int index) 5070 public LSL_String llList2String(LSL_List src, int index)
5071 { 5071 {
5072 m_host.AddScriptLPS(1); 5072 m_host.AddScriptLPS(1);
5073 if (index < 0) 5073 if (index < 0)
5074 { 5074 {
5075 index = src.Length + index; 5075 index = src.Length + index;
5076 } 5076 }
5077 if (index >= src.Length || index < 0) 5077 if (index >= src.Length || index < 0)
5078 { 5078 {
5079 return String.Empty; 5079 return String.Empty;
5080 } 5080 }
5081 return src.Data[index].ToString(); 5081 return src.Data[index].ToString();
5082 } 5082 }
5083   5083  
5084 public LSL_Key llList2Key(LSL_List src, int index) 5084 public LSL_Key llList2Key(LSL_List src, int index)
5085 { 5085 {
5086 m_host.AddScriptLPS(1); 5086 m_host.AddScriptLPS(1);
5087 if (index < 0) 5087 if (index < 0)
5088 { 5088 {
5089 index = src.Length + index; 5089 index = src.Length + index;
5090 } 5090 }
5091   5091  
5092 if (index >= src.Length || index < 0) 5092 if (index >= src.Length || index < 0)
5093 { 5093 {
5094 return ""; 5094 return "";
5095 } 5095 }
5096   5096  
5097 // SL spits out an empty string for types other than key & string 5097 // SL spits out an empty string for types other than key & string
5098 // At the time of patching, LSL_Key is currently LSL_String, 5098 // At the time of patching, LSL_Key is currently LSL_String,
5099 // so the OR check may be a little redundant, but it's being done 5099 // so the OR check may be a little redundant, but it's being done
5100 // for completion and should LSL_Key ever be implemented 5100 // for completion and should LSL_Key ever be implemented
5101 // as it's own struct 5101 // as it's own struct
5102 else if (!(src.Data[index] is LSL_String || 5102 else if (!(src.Data[index] is LSL_String ||
5103 src.Data[index] is LSL_Key)) 5103 src.Data[index] is LSL_Key))
5104 { 5104 {
5105 return ""; 5105 return "";
5106 } 5106 }
5107   5107  
5108 return src.Data[index].ToString(); 5108 return src.Data[index].ToString();
5109 } 5109 }
5110   5110  
5111 public LSL_Vector llList2Vector(LSL_List src, int index) 5111 public LSL_Vector llList2Vector(LSL_List src, int index)
5112 { 5112 {
5113 m_host.AddScriptLPS(1); 5113 m_host.AddScriptLPS(1);
5114 if (index < 0) 5114 if (index < 0)
5115 { 5115 {
5116 index = src.Length + index; 5116 index = src.Length + index;
5117 } 5117 }
5118 if (index >= src.Length || index < 0) 5118 if (index >= src.Length || index < 0)
5119 { 5119 {
5120 return new LSL_Vector(0, 0, 0); 5120 return new LSL_Vector(0, 0, 0);
5121 } 5121 }
5122 if (src.Data[index].GetType() == typeof(LSL_Vector)) 5122 if (src.Data[index].GetType() == typeof(LSL_Vector))
5123 { 5123 {
5124 return (LSL_Vector)src.Data[index]; 5124 return (LSL_Vector)src.Data[index];
5125 } 5125 }
5126   5126  
5127 // SL spits always out ZERO_VECTOR for anything other than 5127 // SL spits always out ZERO_VECTOR for anything other than
5128 // strings or vectors. Although keys always return ZERO_VECTOR, 5128 // strings or vectors. Although keys always return ZERO_VECTOR,
5129 // it is currently difficult to make the distinction between 5129 // it is currently difficult to make the distinction between
5130 // a string, a key as string and a string that by coincidence 5130 // a string, a key as string and a string that by coincidence
5131 // is a string, so we're going to leave that up to the 5131 // is a string, so we're going to leave that up to the
5132 // LSL_Vector constructor. 5132 // LSL_Vector constructor.
5133 else if (!(src.Data[index] is LSL_String || 5133 else if (!(src.Data[index] is LSL_String ||
5134 src.Data[index] is LSL_Vector)) 5134 src.Data[index] is LSL_Vector))
5135 { 5135 {
5136 return new LSL_Vector(0, 0, 0); 5136 return new LSL_Vector(0, 0, 0);
5137 } 5137 }
5138 else 5138 else
5139 { 5139 {
5140 return new LSL_Vector(src.Data[index].ToString()); 5140 return new LSL_Vector(src.Data[index].ToString());
5141 } 5141 }
5142 } 5142 }
5143   5143  
5144 public LSL_Rotation llList2Rot(LSL_List src, int index) 5144 public LSL_Rotation llList2Rot(LSL_List src, int index)
5145 { 5145 {
5146 m_host.AddScriptLPS(1); 5146 m_host.AddScriptLPS(1);
5147 if (index < 0) 5147 if (index < 0)
5148 { 5148 {
5149 index = src.Length + index; 5149 index = src.Length + index;
5150 } 5150 }
5151 if (index >= src.Length || index < 0) 5151 if (index >= src.Length || index < 0)
5152 { 5152 {
5153 return new LSL_Rotation(0, 0, 0, 1); 5153 return new LSL_Rotation(0, 0, 0, 1);
5154 } 5154 }
5155   5155  
5156 // SL spits always out ZERO_ROTATION for anything other than 5156 // SL spits always out ZERO_ROTATION for anything other than
5157 // strings or vectors. Although keys always return ZERO_ROTATION, 5157 // strings or vectors. Although keys always return ZERO_ROTATION,
5158 // it is currently difficult to make the distinction between 5158 // it is currently difficult to make the distinction between
5159 // a string, a key as string and a string that by coincidence 5159 // a string, a key as string and a string that by coincidence
5160 // is a string, so we're going to leave that up to the 5160 // is a string, so we're going to leave that up to the
5161 // LSL_Rotation constructor. 5161 // LSL_Rotation constructor.
5162 else if (!(src.Data[index] is LSL_String || 5162 else if (!(src.Data[index] is LSL_String ||
5163 src.Data[index] is LSL_Rotation)) 5163 src.Data[index] is LSL_Rotation))
5164 { 5164 {
5165 return new LSL_Rotation(0, 0, 0, 1); 5165 return new LSL_Rotation(0, 0, 0, 1);
5166 } 5166 }
5167 else if (src.Data[index].GetType() == typeof(LSL_Rotation)) 5167 else if (src.Data[index].GetType() == typeof(LSL_Rotation))
5168 { 5168 {
5169 return (LSL_Rotation)src.Data[index]; 5169 return (LSL_Rotation)src.Data[index];
5170 } 5170 }
5171 else 5171 else
5172 { 5172 {
5173 return new LSL_Rotation(src.Data[index].ToString()); 5173 return new LSL_Rotation(src.Data[index].ToString());
5174 } 5174 }
5175 } 5175 }
5176   5176  
5177 public LSL_List llList2List(LSL_List src, int start, int end) 5177 public LSL_List llList2List(LSL_List src, int start, int end)
5178 { 5178 {
5179 m_host.AddScriptLPS(1); 5179 m_host.AddScriptLPS(1);
5180 return src.GetSublist(start, end); 5180 return src.GetSublist(start, end);
5181 } 5181 }
5182   5182  
5183 public LSL_List llDeleteSubList(LSL_List src, int start, int end) 5183 public LSL_List llDeleteSubList(LSL_List src, int start, int end)
5184 { 5184 {
5185 return src.DeleteSublist(start, end); 5185 return src.DeleteSublist(start, end);
5186 } 5186 }
5187   5187  
5188 public LSL_Integer llGetListEntryType(LSL_List src, int index) 5188 public LSL_Integer llGetListEntryType(LSL_List src, int index)
5189 { 5189 {
5190 m_host.AddScriptLPS(1); 5190 m_host.AddScriptLPS(1);
5191 if (index < 0) 5191 if (index < 0)
5192 { 5192 {
5193 index = src.Length + index; 5193 index = src.Length + index;
5194 } 5194 }
5195 if (index >= src.Length) 5195 if (index >= src.Length)
5196 { 5196 {
5197 return 0; 5197 return 0;
5198 } 5198 }
5199   5199  
5200 if (src.Data[index] is LSL_Integer || src.Data[index] is Int32) 5200 if (src.Data[index] is LSL_Integer || src.Data[index] is Int32)
5201 return 1; 5201 return 1;
5202 if (src.Data[index] is LSL_Float || src.Data[index] is Single || src.Data[index] is Double) 5202 if (src.Data[index] is LSL_Float || src.Data[index] is Single || src.Data[index] is Double)
5203 return 2; 5203 return 2;
5204 if (src.Data[index] is LSL_String || src.Data[index] is String) 5204 if (src.Data[index] is LSL_String || src.Data[index] is String)
5205 { 5205 {
5206 UUID tuuid; 5206 UUID tuuid;
5207 if (UUID.TryParse(src.Data[index].ToString(), out tuuid)) 5207 if (UUID.TryParse(src.Data[index].ToString(), out tuuid))
5208 { 5208 {
5209 return 4; 5209 return 4;
5210 } 5210 }
5211 else 5211 else
5212 { 5212 {
5213 return 3; 5213 return 3;
5214 } 5214 }
5215 } 5215 }
5216 if (src.Data[index] is LSL_Vector) 5216 if (src.Data[index] is LSL_Vector)
5217 return 5; 5217 return 5;
5218 if (src.Data[index] is LSL_Rotation) 5218 if (src.Data[index] is LSL_Rotation)
5219 return 6; 5219 return 6;
5220 if (src.Data[index] is LSL_List) 5220 if (src.Data[index] is LSL_List)
5221 return 7; 5221 return 7;
5222 return 0; 5222 return 0;
5223   5223  
5224 } 5224 }
5225   5225  
5226 /// <summary> 5226 /// <summary>
5227 /// Process the supplied list and return the 5227 /// Process the supplied list and return the
5228 /// content of the list formatted as a comma 5228 /// content of the list formatted as a comma
5229 /// separated list. There is a space after 5229 /// separated list. There is a space after
5230 /// each comma. 5230 /// each comma.
5231 /// </summary> 5231 /// </summary>
5232 public LSL_String llList2CSV(LSL_List src) 5232 public LSL_String llList2CSV(LSL_List src)
5233 { 5233 {
5234 m_host.AddScriptLPS(1); 5234 m_host.AddScriptLPS(1);
5235   5235  
5236 return string.Join(", ", 5236 return string.Join(", ",
5237 (new List<object>(src.Data)).ConvertAll<string>(o => 5237 (new List<object>(src.Data)).ConvertAll<string>(o =>
5238 { 5238 {
5239 return o.ToString(); 5239 return o.ToString();
5240 }).ToArray()); 5240 }).ToArray());
5241 } 5241 }
5242   5242  
5243 /// <summary> 5243 /// <summary>
5244 /// The supplied string is scanned for commas 5244 /// The supplied string is scanned for commas
5245 /// and converted into a list. Commas are only 5245 /// and converted into a list. Commas are only
5246 /// effective if they are encountered outside 5246 /// effective if they are encountered outside
5247 /// of '<' '>' delimiters. Any whitespace 5247 /// of '<' '>' delimiters. Any whitespace
5248 /// before or after an element is trimmed. 5248 /// before or after an element is trimmed.
5249 /// </summary> 5249 /// </summary>
5250   5250  
5251 public LSL_List llCSV2List(string src) 5251 public LSL_List llCSV2List(string src)
5252 { 5252 {
5253   5253  
5254 LSL_List result = new LSL_List(); 5254 LSL_List result = new LSL_List();
5255 int parens = 0; 5255 int parens = 0;
5256 int start = 0; 5256 int start = 0;
5257 int length = 0; 5257 int length = 0;
5258   5258  
5259 m_host.AddScriptLPS(1); 5259 m_host.AddScriptLPS(1);
5260   5260  
5261 for (int i = 0; i < src.Length; i++) 5261 for (int i = 0; i < src.Length; i++)
5262 { 5262 {
5263 switch (src[i]) 5263 switch (src[i])
5264 { 5264 {
5265 case '<': 5265 case '<':
5266 parens++; 5266 parens++;
5267 length++; 5267 length++;
5268 break; 5268 break;
5269 case '>': 5269 case '>':
5270 if (parens > 0) 5270 if (parens > 0)
5271 parens--; 5271 parens--;
5272 length++; 5272 length++;
5273 break; 5273 break;
5274 case ',': 5274 case ',':
5275 if (parens == 0) 5275 if (parens == 0)
5276 { 5276 {
5277 result.Add(new LSL_String(src.Substring(start,length).Trim())); 5277 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5278 start += length+1; 5278 start += length+1;
5279 length = 0; 5279 length = 0;
5280 } 5280 }
5281 else 5281 else
5282 { 5282 {
5283 length++; 5283 length++;
5284 } 5284 }
5285 break; 5285 break;
5286 default: 5286 default:
5287 length++; 5287 length++;
5288 break; 5288 break;
5289 } 5289 }
5290 } 5290 }
5291   5291  
5292 result.Add(new LSL_String(src.Substring(start,length).Trim())); 5292 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5293   5293  
5294 return result; 5294 return result;
5295 } 5295 }
5296   5296  
5297 /// <summary> 5297 /// <summary>
5298 /// Randomizes the list, be arbitrarily reordering 5298 /// Randomizes the list, be arbitrarily reordering
5299 /// sublists of stride elements. As the stride approaches 5299 /// sublists of stride elements. As the stride approaches
5300 /// the size of the list, the options become very 5300 /// the size of the list, the options become very
5301 /// limited. 5301 /// limited.
5302 /// </summary> 5302 /// </summary>
5303 /// <remarks> 5303 /// <remarks>
5304 /// This could take a while for very large list 5304 /// This could take a while for very large list
5305 /// sizes. 5305 /// sizes.
5306 /// </remarks> 5306 /// </remarks>
5307   5307  
5308 public LSL_List llListRandomize(LSL_List src, int stride) 5308 public LSL_List llListRandomize(LSL_List src, int stride)
5309 { 5309 {
5310 LSL_List result; 5310 LSL_List result;
5311 Random rand = new Random(); 5311 Random rand = new Random();
5312   5312  
5313 int chunkk; 5313 int chunkk;
5314 int[] chunks; 5314 int[] chunks;
5315   5315  
5316 m_host.AddScriptLPS(1); 5316 m_host.AddScriptLPS(1);
5317   5317  
5318 if (stride <= 0) 5318 if (stride <= 0)
5319 { 5319 {
5320 stride = 1; 5320 stride = 1;
5321 } 5321 }
5322   5322  
5323 // Stride MUST be a factor of the list length 5323 // Stride MUST be a factor of the list length
5324 // If not, then return the src list. This also 5324 // If not, then return the src list. This also
5325 // traps those cases where stride > length. 5325 // traps those cases where stride > length.
5326   5326  
5327 if (src.Length != stride && src.Length%stride == 0) 5327 if (src.Length != stride && src.Length%stride == 0)
5328 { 5328 {
5329 chunkk = src.Length/stride; 5329 chunkk = src.Length/stride;
5330   5330  
5331 chunks = new int[chunkk]; 5331 chunks = new int[chunkk];
5332   5332  
5333 for (int i = 0; i < chunkk; i++) 5333 for (int i = 0; i < chunkk; i++)
5334 chunks[i] = i; 5334 chunks[i] = i;
5335   5335  
5336 // Knuth shuffle the chunkk index 5336 // Knuth shuffle the chunkk index
5337 for (int i = chunkk - 1; i >= 1; i--) 5337 for (int i = chunkk - 1; i >= 1; i--)
5338 { 5338 {
5339 // Elect an unrandomized chunk to swap 5339 // Elect an unrandomized chunk to swap
5340 int index = rand.Next(i + 1); 5340 int index = rand.Next(i + 1);
5341 int tmp; 5341 int tmp;
5342   5342  
5343 // and swap position with first unrandomized chunk 5343 // and swap position with first unrandomized chunk
5344 tmp = chunks[i]; 5344 tmp = chunks[i];
5345 chunks[i] = chunks[index]; 5345 chunks[i] = chunks[index];
5346 chunks[index] = tmp; 5346 chunks[index] = tmp;
5347 } 5347 }
5348   5348  
5349 // Construct the randomized list 5349 // Construct the randomized list
5350   5350  
5351 result = new LSL_List(); 5351 result = new LSL_List();
5352   5352  
5353 for (int i = 0; i < chunkk; i++) 5353 for (int i = 0; i < chunkk; i++)
5354 { 5354 {
5355 for (int j = 0; j < stride; j++) 5355 for (int j = 0; j < stride; j++)
5356 { 5356 {
5357 result.Add(src.Data[chunks[i]*stride+j]); 5357 result.Add(src.Data[chunks[i]*stride+j]);
5358 } 5358 }
5359 } 5359 }
5360 } 5360 }
5361 else { 5361 else {
5362 object[] array = new object[src.Length]; 5362 object[] array = new object[src.Length];
5363 Array.Copy(src.Data, 0, array, 0, src.Length); 5363 Array.Copy(src.Data, 0, array, 0, src.Length);
5364 result = new LSL_List(array); 5364 result = new LSL_List(array);
5365 } 5365 }
5366   5366  
5367 return result; 5367 return result;
5368 } 5368 }
5369   5369  
5370 /// <summary> 5370 /// <summary>
5371 /// Elements in the source list starting with 0 and then 5371 /// Elements in the source list starting with 0 and then
5372 /// every i+stride. If the stride is negative then the scan 5372 /// every i+stride. If the stride is negative then the scan
5373 /// is backwards producing an inverted result. 5373 /// is backwards producing an inverted result.
5374 /// Only those elements that are also in the specified 5374 /// Only those elements that are also in the specified
5375 /// range are included in the result. 5375 /// range are included in the result.
5376 /// </summary> 5376 /// </summary>
5377   5377  
5378 public LSL_List llList2ListStrided(LSL_List src, int start, int end, int stride) 5378 public LSL_List llList2ListStrided(LSL_List src, int start, int end, int stride)
5379 { 5379 {
5380   5380  
5381 LSL_List result = new LSL_List(); 5381 LSL_List result = new LSL_List();
5382 int[] si = new int[2]; 5382 int[] si = new int[2];
5383 int[] ei = new int[2]; 5383 int[] ei = new int[2];
5384 bool twopass = false; 5384 bool twopass = false;
5385   5385  
5386 m_host.AddScriptLPS(1); 5386 m_host.AddScriptLPS(1);
5387   5387  
5388 // First step is always to deal with negative indices 5388 // First step is always to deal with negative indices
5389   5389  
5390 if (start < 0) 5390 if (start < 0)
5391 start = src.Length+start; 5391 start = src.Length+start;
5392 if (end < 0) 5392 if (end < 0)
5393 end = src.Length+end; 5393 end = src.Length+end;
5394   5394  
5395 // Out of bounds indices are OK, just trim them 5395 // Out of bounds indices are OK, just trim them
5396 // accordingly 5396 // accordingly
5397   5397  
5398 if (start > src.Length) 5398 if (start > src.Length)
5399 start = src.Length; 5399 start = src.Length;
5400   5400  
5401 if (end > src.Length) 5401 if (end > src.Length)
5402 end = src.Length; 5402 end = src.Length;
5403   5403  
5404 if (stride == 0) 5404 if (stride == 0)
5405 stride = 1; 5405 stride = 1;
5406   5406  
5407 // There may be one or two ranges to be considered 5407 // There may be one or two ranges to be considered
5408   5408  
5409 if (start != end) 5409 if (start != end)
5410 { 5410 {
5411   5411  
5412 if (start <= end) 5412 if (start <= end)
5413 { 5413 {
5414 si[0] = start; 5414 si[0] = start;
5415 ei[0] = end; 5415 ei[0] = end;
5416 } 5416 }
5417 else 5417 else
5418 { 5418 {
5419 si[1] = start; 5419 si[1] = start;
5420 ei[1] = src.Length; 5420 ei[1] = src.Length;
5421 si[0] = 0; 5421 si[0] = 0;
5422 ei[0] = end; 5422 ei[0] = end;
5423 twopass = true; 5423 twopass = true;
5424 } 5424 }
5425   5425  
5426 // The scan always starts from the beginning of the 5426 // The scan always starts from the beginning of the
5427 // source list, but members are only selected if they 5427 // source list, but members are only selected if they
5428 // fall within the specified sub-range. The specified 5428 // fall within the specified sub-range. The specified
5429 // range values are inclusive. 5429 // range values are inclusive.
5430 // A negative stride reverses the direction of the 5430 // A negative stride reverses the direction of the
5431 // scan producing an inverted list as a result. 5431 // scan producing an inverted list as a result.
5432   5432  
5433 if (stride > 0) 5433 if (stride > 0)
5434 { 5434 {
5435 for (int i = 0; i < src.Length; i += stride) 5435 for (int i = 0; i < src.Length; i += stride)
5436 { 5436 {
5437 if (i<=ei[0] && i>=si[0]) 5437 if (i<=ei[0] && i>=si[0])
5438 result.Add(src.Data[i]); 5438 result.Add(src.Data[i]);
5439 if (twopass && i>=si[1] && i<=ei[1]) 5439 if (twopass && i>=si[1] && i<=ei[1])
5440 result.Add(src.Data[i]); 5440 result.Add(src.Data[i]);
5441 } 5441 }
5442 } 5442 }
5443 else if (stride < 0) 5443 else if (stride < 0)
5444 { 5444 {
5445 for (int i = src.Length - 1; i >= 0; i += stride) 5445 for (int i = src.Length - 1; i >= 0; i += stride)
5446 { 5446 {
5447 if (i <= ei[0] && i >= si[0]) 5447 if (i <= ei[0] && i >= si[0])
5448 result.Add(src.Data[i]); 5448 result.Add(src.Data[i]);
5449 if (twopass && i >= si[1] && i <= ei[1]) 5449 if (twopass && i >= si[1] && i <= ei[1])
5450 result.Add(src.Data[i]); 5450 result.Add(src.Data[i]);
5451 } 5451 }
5452 } 5452 }
5453 } 5453 }
5454 else 5454 else
5455 { 5455 {
5456 if (start%stride == 0) 5456 if (start%stride == 0)
5457 { 5457 {
5458 result.Add(src.Data[start]); 5458 result.Add(src.Data[start]);
5459 } 5459 }
5460 } 5460 }
5461   5461  
5462 return result; 5462 return result;
5463 } 5463 }
5464   5464  
5465 public LSL_Integer llGetRegionAgentCount() 5465 public LSL_Integer llGetRegionAgentCount()
5466 { 5466 {
5467 m_host.AddScriptLPS(1); 5467 m_host.AddScriptLPS(1);
5468 return new LSL_Integer(World.GetRootAgentCount()); 5468 return new LSL_Integer(World.GetRootAgentCount());
5469 } 5469 }
5470   5470  
5471 public LSL_Vector llGetRegionCorner() 5471 public LSL_Vector llGetRegionCorner()
5472 { 5472 {
5473 m_host.AddScriptLPS(1); 5473 m_host.AddScriptLPS(1);
5474 return new LSL_Vector(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0); 5474 return new LSL_Vector(World.RegionInfo.WorldLocX, World.RegionInfo.WorldLocY, 0);
5475 } 5475 }
5476   5476  
5477 /// <summary> 5477 /// <summary>
5478 /// Insert the list identified by <paramref name="src"/> into the 5478 /// Insert the list identified by <paramref name="src"/> into the
5479 /// list designated by <paramref name="dest"/> such that the first 5479 /// list designated by <paramref name="dest"/> such that the first
5480 /// new element has the index specified by <paramref name="index"/> 5480 /// new element has the index specified by <paramref name="index"/>
5481 /// </summary> 5481 /// </summary>
5482   5482  
5483 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) 5483 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index)
5484 { 5484 {
5485   5485  
5486 LSL_List pref = null; 5486 LSL_List pref = null;
5487 LSL_List suff = null; 5487 LSL_List suff = null;
5488   5488  
5489 m_host.AddScriptLPS(1); 5489 m_host.AddScriptLPS(1);
5490   5490  
5491 if (index < 0) 5491 if (index < 0)
5492 { 5492 {
5493 index = index+dest.Length; 5493 index = index+dest.Length;
5494 if (index < 0) 5494 if (index < 0)
5495 { 5495 {
5496 index = 0; 5496 index = 0;
5497 } 5497 }
5498 } 5498 }
5499   5499  
5500 if (index != 0) 5500 if (index != 0)
5501 { 5501 {
5502 pref = dest.GetSublist(0,index-1); 5502 pref = dest.GetSublist(0,index-1);
5503 if (index < dest.Length) 5503 if (index < dest.Length)
5504 { 5504 {
5505 suff = dest.GetSublist(index,-1); 5505 suff = dest.GetSublist(index,-1);
5506 return pref + src + suff; 5506 return pref + src + suff;
5507 } 5507 }
5508 else 5508 else
5509 { 5509 {
5510 return pref + src; 5510 return pref + src;
5511 } 5511 }
5512 } 5512 }
5513 else 5513 else
5514 { 5514 {
5515 if (index < dest.Length) 5515 if (index < dest.Length)
5516 { 5516 {
5517 suff = dest.GetSublist(index,-1); 5517 suff = dest.GetSublist(index,-1);
5518 return src + suff; 5518 return src + suff;
5519 } 5519 }
5520 else 5520 else
5521 { 5521 {
5522 return src; 5522 return src;
5523 } 5523 }
5524 } 5524 }
5525   5525  
5526 } 5526 }
5527   5527  
5528 /// <summary> 5528 /// <summary>
5529 /// Returns the index of the first occurrence of test 5529 /// Returns the index of the first occurrence of test
5530 /// in src. 5530 /// in src.
5531 /// </summary> 5531 /// </summary>
5532 /// <param name="src">Source list</param> 5532 /// <param name="src">Source list</param>
5533 /// <param name="test">List to search for</param> 5533 /// <param name="test">List to search for</param>
5534 /// <returns> 5534 /// <returns>
5535 /// The index number of the point in src where test was found if it was found. 5535 /// The index number of the point in src where test was found if it was found.
5536 /// Otherwise returns -1 5536 /// Otherwise returns -1
5537 /// </returns> 5537 /// </returns>
5538 public LSL_Integer llListFindList(LSL_List src, LSL_List test) 5538 public LSL_Integer llListFindList(LSL_List src, LSL_List test)
5539 { 5539 {
5540 int index = -1; 5540 int index = -1;
5541 int length = src.Length - test.Length + 1; 5541 int length = src.Length - test.Length + 1;
5542   5542  
5543 m_host.AddScriptLPS(1); 5543 m_host.AddScriptLPS(1);
5544   5544  
5545 // If either list is empty, do not match 5545 // If either list is empty, do not match
5546 if (src.Length != 0 && test.Length != 0) 5546 if (src.Length != 0 && test.Length != 0)
5547 { 5547 {
5548 for (int i = 0; i < length; i++) 5548 for (int i = 0; i < length; i++)
5549 { 5549 {
5550 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) 5550 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
5551 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code 5551 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
5552 // and so the comparison fails even if the LSL_Integer conceptually has the same value. 5552 // and so the comparison fails even if the LSL_Integer conceptually has the same value.
5553 // Therefore, here we test Equals on both the source and destination objects. 5553 // Therefore, here we test Equals on both the source and destination objects.
5554 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)). 5554 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5555 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) 5555 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))
5556 { 5556 {
5557 int j; 5557 int j;
5558 for (j = 1; j < test.Length; j++) 5558 for (j = 1; j < test.Length; j++)
5559 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))) 5559 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))
5560 break; 5560 break;
5561   5561  
5562 if (j == test.Length) 5562 if (j == test.Length)
5563 { 5563 {
5564 index = i; 5564 index = i;
5565 break; 5565 break;
5566 } 5566 }
5567 } 5567 }
5568 } 5568 }
5569 } 5569 }
5570   5570  
5571 return index; 5571 return index;
5572 } 5572 }
5573   5573  
5574 public LSL_String llGetObjectName() 5574 public LSL_String llGetObjectName()
5575 { 5575 {
5576 m_host.AddScriptLPS(1); 5576 m_host.AddScriptLPS(1);
5577 return m_host.Name !=null ? m_host.Name : String.Empty; 5577 return m_host.Name !=null ? m_host.Name : String.Empty;
5578 } 5578 }
5579   5579  
5580 public void llSetObjectName(string name) 5580 public void llSetObjectName(string name)
5581 { 5581 {
5582 m_host.AddScriptLPS(1); 5582 m_host.AddScriptLPS(1);
5583 m_host.Name = name != null ? name : String.Empty; 5583 m_host.Name = name != null ? name : String.Empty;
5584 } 5584 }
5585   5585  
5586 public LSL_String llGetDate() 5586 public LSL_String llGetDate()
5587 { 5587 {
5588 m_host.AddScriptLPS(1); 5588 m_host.AddScriptLPS(1);
5589 DateTime date = DateTime.Now.ToUniversalTime(); 5589 DateTime date = DateTime.Now.ToUniversalTime();
5590 string result = date.ToString("yyyy-MM-dd"); 5590 string result = date.ToString("yyyy-MM-dd");
5591 return result; 5591 return result;
5592 } 5592 }
5593   5593  
5594 public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir) 5594 public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir)
5595 { 5595 {
5596 m_host.AddScriptLPS(1); 5596 m_host.AddScriptLPS(1);
5597   5597  
5598 // edge will be used to pass the Region Coordinates offset 5598 // edge will be used to pass the Region Coordinates offset
5599 // we want to check for a neighboring sim 5599 // we want to check for a neighboring sim
5600 LSL_Vector edge = new LSL_Vector(0, 0, 0); 5600 LSL_Vector edge = new LSL_Vector(0, 0, 0);
5601   5601  
5602 if (dir.x == 0) 5602 if (dir.x == 0)
5603 { 5603 {
5604 if (dir.y == 0) 5604 if (dir.y == 0)
5605 { 5605 {
5606 // Direction vector is 0,0 so return 5606 // Direction vector is 0,0 so return
5607 // false since we're staying in the sim 5607 // false since we're staying in the sim
5608 return 0; 5608 return 0;
5609 } 5609 }
5610 else 5610 else
5611 { 5611 {
5612 // Y is the only valid direction 5612 // Y is the only valid direction
5613 edge.y = dir.y / Math.Abs(dir.y); 5613 edge.y = dir.y / Math.Abs(dir.y);
5614 } 5614 }
5615 } 5615 }
5616 else 5616 else
5617 { 5617 {
5618 LSL_Float mag; 5618 LSL_Float mag;
5619 if (dir.x > 0) 5619 if (dir.x > 0)
5620 { 5620 {
5621 mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x; 5621 mag = (World.RegionInfo.RegionSizeX - pos.x) / dir.x;
5622 } 5622 }
5623 else 5623 else
5624 { 5624 {
5625 mag = (pos.x/dir.x); 5625 mag = (pos.x/dir.x);
5626 } 5626 }
5627   5627  
5628 mag = Math.Abs(mag); 5628 mag = Math.Abs(mag);
5629   5629  
5630 edge.y = pos.y + (dir.y * mag); 5630 edge.y = pos.y + (dir.y * mag);
5631   5631  
5632 if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0) 5632 if (edge.y > World.RegionInfo.RegionSizeY || edge.y < 0)
5633 { 5633 {
5634 // Y goes out of bounds first 5634 // Y goes out of bounds first
5635 edge.y = dir.y / Math.Abs(dir.y); 5635 edge.y = dir.y / Math.Abs(dir.y);
5636 } 5636 }
5637 else 5637 else
5638 { 5638 {
5639 // X goes out of bounds first or its a corner exit 5639 // X goes out of bounds first or its a corner exit
5640 edge.y = 0; 5640 edge.y = 0;
5641 edge.x = dir.x / Math.Abs(dir.x); 5641 edge.x = dir.x / Math.Abs(dir.x);
5642 } 5642 }
5643 } 5643 }
5644   5644  
5645 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID); 5645 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID);
5646   5646  
5647 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x; 5647 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x;
5648 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y; 5648 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y;
5649   5649  
5650 foreach (GridRegion sri in neighbors) 5650 foreach (GridRegion sri in neighbors)
5651 { 5651 {
5652 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY) 5652 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5653 return 0; 5653 return 0;
5654 } 5654 }
5655   5655  
5656 return 1; 5656 return 1;
5657 } 5657 }
5658   5658  
5659 /// <summary> 5659 /// <summary>
5660 /// Not fully implemented yet. Still to do:- 5660 /// Not fully implemented yet. Still to do:-
5661 /// AGENT_BUSY 5661 /// AGENT_BUSY
5662 /// Remove as they are done 5662 /// Remove as they are done
5663 /// </summary> 5663 /// </summary>
5664 public LSL_Integer llGetAgentInfo(string id) 5664 public LSL_Integer llGetAgentInfo(string id)
5665 { 5665 {
5666 m_host.AddScriptLPS(1); 5666 m_host.AddScriptLPS(1);
5667   5667  
5668 UUID key = new UUID(); 5668 UUID key = new UUID();
5669 if (!UUID.TryParse(id, out key)) 5669 if (!UUID.TryParse(id, out key))
5670 { 5670 {
5671 return 0; 5671 return 0;
5672 } 5672 }
5673   5673  
5674 int flags = 0; 5674 int flags = 0;
5675   5675  
5676 ScenePresence agent = World.GetScenePresence(key); 5676 ScenePresence agent = World.GetScenePresence(key);
5677 if (agent == null) 5677 if (agent == null)
5678 { 5678 {
5679 return 0; 5679 return 0;
5680 } 5680 }
5681   5681  
5682 if (agent.IsChildAgent) 5682 if (agent.IsChildAgent)
5683 return 0; // Fail if they are not in the same region 5683 return 0; // Fail if they are not in the same region
5684   5684  
5685 // note: in OpenSim, sitting seems to cancel AGENT_ALWAYS_RUN, unlike SL 5685 // note: in OpenSim, sitting seems to cancel AGENT_ALWAYS_RUN, unlike SL
5686 if (agent.SetAlwaysRun) 5686 if (agent.SetAlwaysRun)
5687 { 5687 {
5688 flags |= ScriptBaseClass.AGENT_ALWAYS_RUN; 5688 flags |= ScriptBaseClass.AGENT_ALWAYS_RUN;
5689 } 5689 }
5690   5690  
5691 if (agent.HasAttachments()) 5691 if (agent.HasAttachments())
5692 { 5692 {
5693 flags |= ScriptBaseClass.AGENT_ATTACHMENTS; 5693 flags |= ScriptBaseClass.AGENT_ATTACHMENTS;
5694 if (agent.HasScriptedAttachments()) 5694 if (agent.HasScriptedAttachments())
5695 flags |= ScriptBaseClass.AGENT_SCRIPTED; 5695 flags |= ScriptBaseClass.AGENT_SCRIPTED;
5696 } 5696 }
5697   5697  
5698 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) 5698 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0)
5699 { 5699 {
5700 flags |= ScriptBaseClass.AGENT_FLYING; 5700 flags |= ScriptBaseClass.AGENT_FLYING;
5701 flags |= ScriptBaseClass.AGENT_IN_AIR; // flying always implies in-air, even if colliding with e.g. a wall 5701 flags |= ScriptBaseClass.AGENT_IN_AIR; // flying always implies in-air, even if colliding with e.g. a wall
5702 } 5702 }
5703   5703  
5704 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0) 5704 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0)
5705 { 5705 {
5706 flags |= ScriptBaseClass.AGENT_AWAY; 5706 flags |= ScriptBaseClass.AGENT_AWAY;
5707 } 5707 }
5708   5708  
5709 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 5709 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5710 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 5710 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5711 { 5711 {
5712 flags |= ScriptBaseClass.AGENT_MOUSELOOK; 5712 flags |= ScriptBaseClass.AGENT_MOUSELOOK;
5713 } 5713 }
5714   5714  
5715 if ((agent.State & (byte)AgentState.Typing) != (byte)0) 5715 if ((agent.State & (byte)AgentState.Typing) != (byte)0)
5716 { 5716 {
5717 flags |= ScriptBaseClass.AGENT_TYPING; 5717 flags |= ScriptBaseClass.AGENT_TYPING;
5718 } 5718 }
5719   5719  
5720 string agentMovementAnimation = agent.Animator.CurrentMovementAnimation; 5720 string agentMovementAnimation = agent.Animator.CurrentMovementAnimation;
5721   5721  
5722 if (agentMovementAnimation == "CROUCH") 5722 if (agentMovementAnimation == "CROUCH")
5723 { 5723 {
5724 flags |= ScriptBaseClass.AGENT_CROUCHING; 5724 flags |= ScriptBaseClass.AGENT_CROUCHING;
5725 } 5725 }
5726   5726  
5727 if (agentMovementAnimation == "WALK" || agentMovementAnimation == "CROUCHWALK") 5727 if (agentMovementAnimation == "WALK" || agentMovementAnimation == "CROUCHWALK")
5728 { 5728 {
5729 flags |= ScriptBaseClass.AGENT_WALKING; 5729 flags |= ScriptBaseClass.AGENT_WALKING;
5730 } 5730 }
5731   5731  
5732 // not colliding implies in air. Note: flying also implies in-air, even if colliding (see above) 5732 // not colliding implies in air. Note: flying also implies in-air, even if colliding (see above)
5733   5733  
5734 // note: AGENT_IN_AIR and AGENT_WALKING seem to be mutually exclusive states in SL. 5734 // note: AGENT_IN_AIR and AGENT_WALKING seem to be mutually exclusive states in SL.
5735   5735  
5736 // note: this may need some tweaking when walking downhill. you "fall down" for a brief instant 5736 // note: this may need some tweaking when walking downhill. you "fall down" for a brief instant
5737 // and don't collide when walking downhill, which instantly registers as in-air, briefly. should 5737 // and don't collide when walking downhill, which instantly registers as in-air, briefly. should
5738 // there be some minimum non-collision threshold time before claiming the avatar is in-air? 5738 // there be some minimum non-collision threshold time before claiming the avatar is in-air?
5739 if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && !agent.IsColliding ) 5739 if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && !agent.IsColliding )
5740 { 5740 {
5741 flags |= ScriptBaseClass.AGENT_IN_AIR; 5741 flags |= ScriptBaseClass.AGENT_IN_AIR;
5742 } 5742 }
5743   5743  
5744 if (agent.ParentPart != null) 5744 if (agent.ParentPart != null)
5745 { 5745 {
5746 flags |= ScriptBaseClass.AGENT_ON_OBJECT; 5746 flags |= ScriptBaseClass.AGENT_ON_OBJECT;
5747 flags |= ScriptBaseClass.AGENT_SITTING; 5747 flags |= ScriptBaseClass.AGENT_SITTING;
5748 } 5748 }
5749   5749  
5750 if (agent.Animator.Animations.ImplicitDefaultAnimation.AnimID 5750 if (agent.Animator.Animations.ImplicitDefaultAnimation.AnimID
5751 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 5751 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
5752 { 5752 {
5753 flags |= ScriptBaseClass.AGENT_SITTING; 5753 flags |= ScriptBaseClass.AGENT_SITTING;
5754 } 5754 }
5755   5755  
5756 return flags; 5756 return flags;
5757 } 5757 }
5758   5758  
5759 public LSL_String llGetAgentLanguage(string id) 5759 public LSL_String llGetAgentLanguage(string id)
5760 { 5760 {
5761 // This should only return a value if the avatar is in the same region 5761 // This should only return a value if the avatar is in the same region
5762 //ckrinke 1-30-09 : This needs to parse the XMLRPC language field supplied 5762 //ckrinke 1-30-09 : This needs to parse the XMLRPC language field supplied
5763 //by the client at login. Currently returning only en-us until our I18N 5763 //by the client at login. Currently returning only en-us until our I18N
5764 //effort gains momentum 5764 //effort gains momentum
5765 m_host.AddScriptLPS(1); 5765 m_host.AddScriptLPS(1);
5766 return "en-us"; 5766 return "en-us";
5767 } 5767 }
5768 /// <summary> 5768 /// <summary>
5769 /// http://wiki.secondlife.com/wiki/LlGetAgentList 5769 /// http://wiki.secondlife.com/wiki/LlGetAgentList
5770 /// The list of options is currently not used in SL 5770 /// The list of options is currently not used in SL
5771 /// scope is one of:- 5771 /// scope is one of:-
5772 /// AGENT_LIST_REGION - all in the region 5772 /// AGENT_LIST_REGION - all in the region
5773 /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object 5773 /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object
5774 /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the 5774 /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the
5775 /// current parcel. 5775 /// current parcel.
5776 /// </summary> 5776 /// </summary>
5777 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) 5777 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options)
5778 { 5778 {
5779 m_host.AddScriptLPS(1); 5779 m_host.AddScriptLPS(1);
5780   5780  
5781 // the constants are 1, 2 and 4 so bits are being set, but you 5781 // the constants are 1, 2 and 4 so bits are being set, but you
5782 // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 5782 // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4
5783 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION; 5783 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION;
5784 bool parcelOwned = scope == ScriptBaseClass.AGENT_LIST_PARCEL_OWNER; 5784 bool parcelOwned = scope == ScriptBaseClass.AGENT_LIST_PARCEL_OWNER;
5785 bool parcel = scope == ScriptBaseClass.AGENT_LIST_PARCEL; 5785 bool parcel = scope == ScriptBaseClass.AGENT_LIST_PARCEL;
5786   5786  
5787 LSL_List result = new LSL_List(); 5787 LSL_List result = new LSL_List();
5788   5788  
5789 if (!regionWide && !parcelOwned && !parcel) 5789 if (!regionWide && !parcelOwned && !parcel)
5790 { 5790 {
5791 result.Add("INVALID_SCOPE"); 5791 result.Add("INVALID_SCOPE");
5792 return result; 5792 return result;
5793 } 5793 }
5794   5794  
5795 ILandObject land; 5795 ILandObject land;
5796 UUID id = UUID.Zero; 5796 UUID id = UUID.Zero;
5797   5797  
5798 if (parcel || parcelOwned) 5798 if (parcel || parcelOwned)
5799 { 5799 {
5800 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition()); 5800 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
5801 if (land == null) 5801 if (land == null)
5802 { 5802 {
5803 id = UUID.Zero; 5803 id = UUID.Zero;
5804 } 5804 }
5805 else 5805 else
5806 { 5806 {
5807 if (parcelOwned) 5807 if (parcelOwned)
5808 { 5808 {
5809 id = land.LandData.OwnerID; 5809 id = land.LandData.OwnerID;
5810 } 5810 }
5811 else 5811 else
5812 { 5812 {
5813 id = land.LandData.GlobalID; 5813 id = land.LandData.GlobalID;
5814 } 5814 }
5815 } 5815 }
5816 } 5816 }
5817   5817  
5818 World.ForEachRootScenePresence( 5818 World.ForEachRootScenePresence(
5819 delegate (ScenePresence ssp) 5819 delegate (ScenePresence ssp)
5820 { 5820 {
5821 // Gods are not listed in SL 5821 // Gods are not listed in SL
5822 if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent) 5822 if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent)
5823 { 5823 {
5824 if (!regionWide) 5824 if (!regionWide)
5825 { 5825 {
5826 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition); 5826 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
5827 if (land != null) 5827 if (land != null)
5828 { 5828 {
5829 if (parcelOwned && land.LandData.OwnerID == id || 5829 if (parcelOwned && land.LandData.OwnerID == id ||
5830 parcel && land.LandData.GlobalID == id) 5830 parcel && land.LandData.GlobalID == id)
5831 { 5831 {
5832 result.Add(new LSL_Key(ssp.UUID.ToString())); 5832 result.Add(new LSL_Key(ssp.UUID.ToString()));
5833 } 5833 }
5834 } 5834 }
5835 } 5835 }
5836 else 5836 else
5837 { 5837 {
5838 result.Add(new LSL_Key(ssp.UUID.ToString())); 5838 result.Add(new LSL_Key(ssp.UUID.ToString()));
5839 } 5839 }
5840 } 5840 }
5841 // Maximum of 100 results 5841 // Maximum of 100 results
5842 if (result.Length > 99) 5842 if (result.Length > 99)
5843 { 5843 {
5844 return; 5844 return;
5845 } 5845 }
5846 } 5846 }
5847 ); 5847 );
5848 return result; 5848 return result;
5849 } 5849 }
5850   5850  
5851 public void llAdjustSoundVolume(double volume) 5851 public void llAdjustSoundVolume(double volume)
5852 { 5852 {
5853 m_host.AddScriptLPS(1); 5853 m_host.AddScriptLPS(1);
5854 m_host.AdjustSoundGain(volume); 5854 m_host.AdjustSoundGain(volume);
5855 ScriptSleep(100); 5855 ScriptSleep(100);
5856 } 5856 }
5857   5857  
5858 public void llSetSoundRadius(double radius) 5858 public void llSetSoundRadius(double radius)
5859 { 5859 {
5860 m_host.AddScriptLPS(1); 5860 m_host.AddScriptLPS(1);
5861 m_host.SoundRadius = radius; 5861 m_host.SoundRadius = radius;
5862 } 5862 }
5863   5863  
5864 public LSL_String llKey2Name(string id) 5864 public LSL_String llKey2Name(string id)
5865 { 5865 {
5866 m_host.AddScriptLPS(1); 5866 m_host.AddScriptLPS(1);
5867 UUID key = new UUID(); 5867 UUID key = new UUID();
5868 if (UUID.TryParse(id,out key)) 5868 if (UUID.TryParse(id,out key))
5869 { 5869 {
5870 ScenePresence presence = World.GetScenePresence(key); 5870 ScenePresence presence = World.GetScenePresence(key);
5871   5871  
5872 if (presence != null) 5872 if (presence != null)
5873 { 5873 {
5874 return presence.ControllingClient.Name; 5874 return presence.ControllingClient.Name;
5875 //return presence.Name; 5875 //return presence.Name;
5876 } 5876 }
5877   5877  
5878 if (World.GetSceneObjectPart(key) != null) 5878 if (World.GetSceneObjectPart(key) != null)
5879 { 5879 {
5880 return World.GetSceneObjectPart(key).Name; 5880 return World.GetSceneObjectPart(key).Name;
5881 } 5881 }
5882 } 5882 }
5883 return String.Empty; 5883 return String.Empty;
5884 } 5884 }
5885   5885  
5886   5886  
5887   5887  
5888 public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) 5888 public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate)
5889 { 5889 {
5890 m_host.AddScriptLPS(1); 5890 m_host.AddScriptLPS(1);
5891   5891  
5892 SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate); 5892 SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate);
5893 } 5893 }
5894   5894  
5895 public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate) 5895 public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate)
5896 { 5896 {
5897 m_host.AddScriptLPS(1); 5897 m_host.AddScriptLPS(1);
5898   5898  
5899 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5899 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5900   5900  
5901 foreach (SceneObjectPart part in parts) 5901 foreach (SceneObjectPart part in parts)
5902 { 5902 {
5903 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5903 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5904 } 5904 }
5905 } 5905 }
5906   5906  
5907 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 5907 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
5908 { 5908 {
5909   5909  
5910 Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation(); 5910 Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation();
5911 pTexAnim.Flags = (Primitive.TextureAnimMode)mode; 5911 pTexAnim.Flags = (Primitive.TextureAnimMode)mode;
5912   5912  
5913 //ALL_SIDES 5913 //ALL_SIDES
5914 if (face == ScriptBaseClass.ALL_SIDES) 5914 if (face == ScriptBaseClass.ALL_SIDES)
5915 face = 255; 5915 face = 255;
5916   5916  
5917 pTexAnim.Face = (uint)face; 5917 pTexAnim.Face = (uint)face;
5918 pTexAnim.Length = (float)length; 5918 pTexAnim.Length = (float)length;
5919 pTexAnim.Rate = (float)rate; 5919 pTexAnim.Rate = (float)rate;
5920 pTexAnim.SizeX = (uint)sizex; 5920 pTexAnim.SizeX = (uint)sizex;
5921 pTexAnim.SizeY = (uint)sizey; 5921 pTexAnim.SizeY = (uint)sizey;
5922 pTexAnim.Start = (float)start; 5922 pTexAnim.Start = (float)start;
5923   5923  
5924 part.AddTextureAnimation(pTexAnim); 5924 part.AddTextureAnimation(pTexAnim);
5925 part.SendFullUpdateToAllClients(); 5925 part.SendFullUpdateToAllClients();
5926 part.ParentGroup.HasGroupChanged = true; 5926 part.ParentGroup.HasGroupChanged = true;
5927 } 5927 }
5928   5928  
5929 public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, 5929 public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east,
5930 LSL_Vector bottom_south_west) 5930 LSL_Vector bottom_south_west)
5931 { 5931 {
5932 m_host.AddScriptLPS(1); 5932 m_host.AddScriptLPS(1);
5933 if (m_SoundModule != null) 5933 if (m_SoundModule != null)
5934 { 5934 {
5935 m_SoundModule.TriggerSoundLimited(m_host.UUID, 5935 m_SoundModule.TriggerSoundLimited(m_host.UUID,
5936 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, 5936 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume,
5937 bottom_south_west, top_north_east); 5937 bottom_south_west, top_north_east);
5938 } 5938 }
5939 } 5939 }
5940   5940  
5941 public void llEjectFromLand(string pest) 5941 public void llEjectFromLand(string pest)
5942 { 5942 {
5943 m_host.AddScriptLPS(1); 5943 m_host.AddScriptLPS(1);
5944 UUID agentID = new UUID(); 5944 UUID agentID = new UUID();
5945 if (UUID.TryParse(pest, out agentID)) 5945 if (UUID.TryParse(pest, out agentID))
5946 { 5946 {
5947 ScenePresence presence = World.GetScenePresence(agentID); 5947 ScenePresence presence = World.GetScenePresence(agentID);
5948 if (presence != null) 5948 if (presence != null)
5949 { 5949 {
5950 // agent must be over the owners land 5950 // agent must be over the owners land
5951 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition); 5951 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
5952 if (land == null) 5952 if (land == null)
5953 return; 5953 return;
5954   5954  
5955 if (m_host.OwnerID == land.LandData.OwnerID) 5955 if (m_host.OwnerID == land.LandData.OwnerID)
5956 { 5956 {
5957 World.TeleportClientHome(agentID, presence.ControllingClient); 5957 World.TeleportClientHome(agentID, presence.ControllingClient);
5958 } 5958 }
5959 } 5959 }
5960 } 5960 }
5961 ScriptSleep(5000); 5961 ScriptSleep(5000);
5962 } 5962 }
5963   5963  
5964 public LSL_Integer llOverMyLand(string id) 5964 public LSL_Integer llOverMyLand(string id)
5965 { 5965 {
5966 m_host.AddScriptLPS(1); 5966 m_host.AddScriptLPS(1);
5967 UUID key = new UUID(); 5967 UUID key = new UUID();
5968 if (UUID.TryParse(id, out key)) 5968 if (UUID.TryParse(id, out key))
5969 { 5969 {
5970 ScenePresence presence = World.GetScenePresence(key); 5970 ScenePresence presence = World.GetScenePresence(key);
5971 if (presence != null) // object is an avatar 5971 if (presence != null) // object is an avatar
5972 { 5972 {
5973 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 5973 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
5974 return 1; 5974 return 1;
5975 } 5975 }
5976 else // object is not an avatar 5976 else // object is not an avatar
5977 { 5977 {
5978 SceneObjectPart obj = World.GetSceneObjectPart(key); 5978 SceneObjectPart obj = World.GetSceneObjectPart(key);
5979   5979  
5980 if (obj != null) 5980 if (obj != null)
5981 { 5981 {
5982 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID) 5982 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
5983 return 1; 5983 return 1;
5984 } 5984 }
5985 } 5985 }
5986 } 5986 }
5987   5987  
5988 return 0; 5988 return 0;
5989 } 5989 }
5990   5990  
5991 public LSL_String llGetLandOwnerAt(LSL_Vector pos) 5991 public LSL_String llGetLandOwnerAt(LSL_Vector pos)
5992 { 5992 {
5993 m_host.AddScriptLPS(1); 5993 m_host.AddScriptLPS(1);
5994 ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 5994 ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
5995 if (land == null) 5995 if (land == null)
5996 return UUID.Zero.ToString(); 5996 return UUID.Zero.ToString();
5997 return land.LandData.OwnerID.ToString(); 5997 return land.LandData.OwnerID.ToString();
5998 } 5998 }
5999   5999  
6000 /// <summary> 6000 /// <summary>
6001 /// According to http://lslwiki.net/lslwiki/wakka.php?wakka=llGetAgentSize 6001 /// According to http://lslwiki.net/lslwiki/wakka.php?wakka=llGetAgentSize
6002 /// only the height of avatars vary and that says: 6002 /// only the height of avatars vary and that says:
6003 /// Width (x) and depth (y) are constant. (0.45m and 0.6m respectively). 6003 /// Width (x) and depth (y) are constant. (0.45m and 0.6m respectively).
6004 /// </summary> 6004 /// </summary>
6005 public LSL_Vector llGetAgentSize(string id) 6005 public LSL_Vector llGetAgentSize(string id)
6006 { 6006 {
6007 m_host.AddScriptLPS(1); 6007 m_host.AddScriptLPS(1);
6008 ScenePresence avatar = World.GetScenePresence((UUID)id); 6008 ScenePresence avatar = World.GetScenePresence((UUID)id);
6009 LSL_Vector agentSize; 6009 LSL_Vector agentSize;
6010 if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region 6010 if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region
6011 { 6011 {
6012 agentSize = ScriptBaseClass.ZERO_VECTOR; 6012 agentSize = ScriptBaseClass.ZERO_VECTOR;
6013 } 6013 }
6014 else 6014 else
6015 { 6015 {
6016 agentSize = GetAgentSize(avatar); 6016 agentSize = GetAgentSize(avatar);
6017 } 6017 }
6018   6018  
6019 return agentSize; 6019 return agentSize;
6020 } 6020 }
6021   6021  
6022 public LSL_Integer llSameGroup(string agent) 6022 public LSL_Integer llSameGroup(string agent)
6023 { 6023 {
6024 m_host.AddScriptLPS(1); 6024 m_host.AddScriptLPS(1);
6025 UUID agentId = new UUID(); 6025 UUID agentId = new UUID();
6026 if (!UUID.TryParse(agent, out agentId)) 6026 if (!UUID.TryParse(agent, out agentId))
6027 return new LSL_Integer(0); 6027 return new LSL_Integer(0);
6028 ScenePresence presence = World.GetScenePresence(agentId); 6028 ScenePresence presence = World.GetScenePresence(agentId);
6029 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6029 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6030 return new LSL_Integer(0); 6030 return new LSL_Integer(0);
6031 IClientAPI client = presence.ControllingClient; 6031 IClientAPI client = presence.ControllingClient;
6032 if (m_host.GroupID == client.ActiveGroupId) 6032 if (m_host.GroupID == client.ActiveGroupId)
6033 return new LSL_Integer(1); 6033 return new LSL_Integer(1);
6034 else 6034 else
6035 return new LSL_Integer(0); 6035 return new LSL_Integer(0);
6036 } 6036 }
6037   6037  
6038 public void llUnSit(string id) 6038 public void llUnSit(string id)
6039 { 6039 {
6040 m_host.AddScriptLPS(1); 6040 m_host.AddScriptLPS(1);
6041   6041  
6042 UUID key = new UUID(); 6042 UUID key = new UUID();
6043 if (UUID.TryParse(id, out key)) 6043 if (UUID.TryParse(id, out key))
6044 { 6044 {
6045 ScenePresence av = World.GetScenePresence(key); 6045 ScenePresence av = World.GetScenePresence(key);
6046   6046  
6047 if (av != null) 6047 if (av != null)
6048 { 6048 {
6049 if (llAvatarOnSitTarget() == id) 6049 if (llAvatarOnSitTarget() == id)
6050 { 6050 {
6051 // if the avatar is sitting on this object, then 6051 // if the avatar is sitting on this object, then
6052 // we can unsit them. We don't want random scripts unsitting random people 6052 // we can unsit them. We don't want random scripts unsitting random people
6053 // Lets avoid the popcorn avatar scenario. 6053 // Lets avoid the popcorn avatar scenario.
6054 av.StandUp(); 6054 av.StandUp();
6055 } 6055 }
6056 else 6056 else
6057 { 6057 {
6058 // If the object owner also owns the parcel 6058 // If the object owner also owns the parcel
6059 // or 6059 // or
6060 // if the land is group owned and the object is group owned by the same group 6060 // if the land is group owned and the object is group owned by the same group
6061 // or 6061 // or
6062 // if the object is owned by a person with estate access. 6062 // if the object is owned by a person with estate access.
6063 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition); 6063 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6064 if (parcel != null) 6064 if (parcel != null)
6065 { 6065 {
6066 if (m_host.OwnerID == parcel.LandData.OwnerID || 6066 if (m_host.OwnerID == parcel.LandData.OwnerID ||
6067 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID 6067 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID
6068 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) 6068 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID))
6069 { 6069 {
6070 av.StandUp(); 6070 av.StandUp();
6071 } 6071 }
6072 } 6072 }
6073 } 6073 }
6074 } 6074 }
6075 } 6075 }
6076 } 6076 }
6077   6077  
6078 public LSL_Vector llGroundSlope(LSL_Vector offset) 6078 public LSL_Vector llGroundSlope(LSL_Vector offset)
6079 { 6079 {
6080 m_host.AddScriptLPS(1); 6080 m_host.AddScriptLPS(1);
6081   6081  
6082 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 6082 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
6083 LSL_Vector vsn = llGroundNormal(offset); 6083 LSL_Vector vsn = llGroundNormal(offset);
6084   6084  
6085 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6085 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6086 //the height of that point on the plane. The resulting vector gives the slope. 6086 //the height of that point on the plane. The resulting vector gives the slope.
6087 Vector3 vsl = vsn; 6087 Vector3 vsl = vsn;
6088 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6088 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6089 vsl.Normalize(); 6089 vsl.Normalize();
6090 //Normalization might be overkill here 6090 //Normalization might be overkill here
6091   6091  
6092 vsn.x = vsl.X; 6092 vsn.x = vsl.X;
6093 vsn.y = vsl.Y; 6093 vsn.y = vsl.Y;
6094 vsn.z = vsl.Z; 6094 vsn.z = vsl.Z;
6095   6095  
6096 return vsn; 6096 return vsn;
6097 } 6097 }
6098   6098  
6099 public LSL_Vector llGroundNormal(LSL_Vector offset) 6099 public LSL_Vector llGroundNormal(LSL_Vector offset)
6100 { 6100 {
6101 m_host.AddScriptLPS(1); 6101 m_host.AddScriptLPS(1);
6102 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; 6102 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6103 // Clamp to valid position 6103 // Clamp to valid position
6104 if (pos.X < 0) 6104 if (pos.X < 0)
6105 pos.X = 0; 6105 pos.X = 0;
6106 else if (pos.X >= World.Heightmap.Width) 6106 else if (pos.X >= World.Heightmap.Width)
6107 pos.X = World.Heightmap.Width - 1; 6107 pos.X = World.Heightmap.Width - 1;
6108 if (pos.Y < 0) 6108 if (pos.Y < 0)
6109 pos.Y = 0; 6109 pos.Y = 0;
6110 else if (pos.Y >= World.Heightmap.Height) 6110 else if (pos.Y >= World.Heightmap.Height)
6111 pos.Y = World.Heightmap.Height - 1; 6111 pos.Y = World.Heightmap.Height - 1;
6112   6112  
6113 //Find two points in addition to the position to define a plane 6113 //Find two points in addition to the position to define a plane
6114 Vector3 p0 = new Vector3(pos.X, pos.Y, 6114 Vector3 p0 = new Vector3(pos.X, pos.Y,
6115 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6115 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6116 Vector3 p1 = new Vector3(); 6116 Vector3 p1 = new Vector3();
6117 Vector3 p2 = new Vector3(); 6117 Vector3 p2 = new Vector3();
6118 if ((pos.X + 1.0f) >= World.Heightmap.Width) 6118 if ((pos.X + 1.0f) >= World.Heightmap.Width)
6119 p1 = new Vector3(pos.X + 1.0f, pos.Y, 6119 p1 = new Vector3(pos.X + 1.0f, pos.Y,
6120 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6120 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6121 else 6121 else
6122 p1 = new Vector3(pos.X + 1.0f, pos.Y, 6122 p1 = new Vector3(pos.X + 1.0f, pos.Y,
6123 (float)World.Heightmap[(int)(pos.X + 1.0f), (int)pos.Y]); 6123 (float)World.Heightmap[(int)(pos.X + 1.0f), (int)pos.Y]);
6124 if ((pos.Y + 1.0f) >= World.Heightmap.Height) 6124 if ((pos.Y + 1.0f) >= World.Heightmap.Height)
6125 p2 = new Vector3(pos.X, pos.Y + 1.0f, 6125 p2 = new Vector3(pos.X, pos.Y + 1.0f,
6126 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6126 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6127 else 6127 else
6128 p2 = new Vector3(pos.X, pos.Y + 1.0f, 6128 p2 = new Vector3(pos.X, pos.Y + 1.0f,
6129 (float)World.Heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]); 6129 (float)World.Heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]);
6130   6130  
6131 //Find normalized vectors from p0 to p1 and p0 to p2 6131 //Find normalized vectors from p0 to p1 and p0 to p2
6132 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); 6132 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
6133 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); 6133 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
6134 v0.Normalize(); 6134 v0.Normalize();
6135 v1.Normalize(); 6135 v1.Normalize();
6136   6136  
6137 //Find the cross product of the vectors (the slope normal). 6137 //Find the cross product of the vectors (the slope normal).
6138 Vector3 vsn = new Vector3(); 6138 Vector3 vsn = new Vector3();
6139 vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y); 6139 vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y);
6140 vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z); 6140 vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
6141 vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X); 6141 vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
6142 vsn.Normalize(); 6142 vsn.Normalize();
6143 //I believe the crossproduct of two normalized vectors is a normalized vector so 6143 //I believe the crossproduct of two normalized vectors is a normalized vector so
6144 //this normalization may be overkill 6144 //this normalization may be overkill
6145   6145  
6146 return new LSL_Vector(vsn); 6146 return new LSL_Vector(vsn);
6147 } 6147 }
6148   6148  
6149 public LSL_Vector llGroundContour(LSL_Vector offset) 6149 public LSL_Vector llGroundContour(LSL_Vector offset)
6150 { 6150 {
6151 m_host.AddScriptLPS(1); 6151 m_host.AddScriptLPS(1);
6152 LSL_Vector x = llGroundSlope(offset); 6152 LSL_Vector x = llGroundSlope(offset);
6153 return new LSL_Vector(-x.y, x.x, 0.0); 6153 return new LSL_Vector(-x.y, x.x, 0.0);
6154 } 6154 }
6155   6155  
6156 public LSL_Integer llGetAttached() 6156 public LSL_Integer llGetAttached()
6157 { 6157 {
6158 m_host.AddScriptLPS(1); 6158 m_host.AddScriptLPS(1);
6159 return m_host.ParentGroup.AttachmentPoint; 6159 return m_host.ParentGroup.AttachmentPoint;
6160 } 6160 }
6161   6161  
6162 public virtual LSL_Integer llGetFreeMemory() 6162 public virtual LSL_Integer llGetFreeMemory()
6163 { 6163 {
6164 m_host.AddScriptLPS(1); 6164 m_host.AddScriptLPS(1);
6165 // Make scripts designed for LSO happy 6165 // Make scripts designed for LSO happy
6166 return 16384; 6166 return 16384;
6167 } 6167 }
6168   6168  
6169 public LSL_Integer llGetFreeURLs() 6169 public LSL_Integer llGetFreeURLs()
6170 { 6170 {
6171 m_host.AddScriptLPS(1); 6171 m_host.AddScriptLPS(1);
6172 if (m_UrlModule != null) 6172 if (m_UrlModule != null)
6173 return new LSL_Integer(m_UrlModule.GetFreeUrls()); 6173 return new LSL_Integer(m_UrlModule.GetFreeUrls());
6174 return new LSL_Integer(0); 6174 return new LSL_Integer(0);
6175 } 6175 }
6176   6176  
6177   6177  
6178 public LSL_String llGetRegionName() 6178 public LSL_String llGetRegionName()
6179 { 6179 {
6180 m_host.AddScriptLPS(1); 6180 m_host.AddScriptLPS(1);
6181 return World.RegionInfo.RegionName; 6181 return World.RegionInfo.RegionName;
6182 } 6182 }
6183   6183  
6184 public LSL_Float llGetRegionTimeDilation() 6184 public LSL_Float llGetRegionTimeDilation()
6185 { 6185 {
6186 m_host.AddScriptLPS(1); 6186 m_host.AddScriptLPS(1);
6187 return (double)World.TimeDilation; 6187 return (double)World.TimeDilation;
6188 } 6188 }
6189   6189  
6190 /// <summary> 6190 /// <summary>
6191 /// Returns the value reported in the client Statistics window 6191 /// Returns the value reported in the client Statistics window
6192 /// </summary> 6192 /// </summary>
6193 public LSL_Float llGetRegionFPS() 6193 public LSL_Float llGetRegionFPS()
6194 { 6194 {
6195 m_host.AddScriptLPS(1); 6195 m_host.AddScriptLPS(1);
6196 return World.StatsReporter.LastReportedSimFPS; 6196 return World.StatsReporter.LastReportedSimFPS;
6197 } 6197 }
6198   6198  
6199   6199  
6200 /* particle system rules should be coming into this routine as doubles, that is 6200 /* particle system rules should be coming into this routine as doubles, that is
6201 rule[0] should be an integer from this list and rule[1] should be the arg 6201 rule[0] should be an integer from this list and rule[1] should be the arg
6202 for the same integer. wiki.secondlife.com has most of this mapping, but some 6202 for the same integer. wiki.secondlife.com has most of this mapping, but some
6203 came from http://www.caligari-designs.com/p4u2 6203 came from http://www.caligari-designs.com/p4u2
6204   6204  
6205 We iterate through the list for 'Count' elements, incrementing by two for each 6205 We iterate through the list for 'Count' elements, incrementing by two for each
6206 iteration and set the members of Primitive.ParticleSystem, one at a time. 6206 iteration and set the members of Primitive.ParticleSystem, one at a time.
6207 */ 6207 */
6208   6208  
6209 public enum PrimitiveRule : int 6209 public enum PrimitiveRule : int
6210 { 6210 {
6211 PSYS_PART_FLAGS = 0, 6211 PSYS_PART_FLAGS = 0,
6212 PSYS_PART_START_COLOR = 1, 6212 PSYS_PART_START_COLOR = 1,
6213 PSYS_PART_START_ALPHA = 2, 6213 PSYS_PART_START_ALPHA = 2,
6214 PSYS_PART_END_COLOR = 3, 6214 PSYS_PART_END_COLOR = 3,
6215 PSYS_PART_END_ALPHA = 4, 6215 PSYS_PART_END_ALPHA = 4,
6216 PSYS_PART_START_SCALE = 5, 6216 PSYS_PART_START_SCALE = 5,
6217 PSYS_PART_END_SCALE = 6, 6217 PSYS_PART_END_SCALE = 6,
6218 PSYS_PART_MAX_AGE = 7, 6218 PSYS_PART_MAX_AGE = 7,
6219 PSYS_SRC_ACCEL = 8, 6219 PSYS_SRC_ACCEL = 8,
6220 PSYS_SRC_PATTERN = 9, 6220 PSYS_SRC_PATTERN = 9,
6221 PSYS_SRC_INNERANGLE = 10, 6221 PSYS_SRC_INNERANGLE = 10,
6222 PSYS_SRC_OUTERANGLE = 11, 6222 PSYS_SRC_OUTERANGLE = 11,
6223 PSYS_SRC_TEXTURE = 12, 6223 PSYS_SRC_TEXTURE = 12,
6224 PSYS_SRC_BURST_RATE = 13, 6224 PSYS_SRC_BURST_RATE = 13,
6225 PSYS_SRC_BURST_PART_COUNT = 15, 6225 PSYS_SRC_BURST_PART_COUNT = 15,
6226 PSYS_SRC_BURST_RADIUS = 16, 6226 PSYS_SRC_BURST_RADIUS = 16,
6227 PSYS_SRC_BURST_SPEED_MIN = 17, 6227 PSYS_SRC_BURST_SPEED_MIN = 17,
6228 PSYS_SRC_BURST_SPEED_MAX = 18, 6228 PSYS_SRC_BURST_SPEED_MAX = 18,
6229 PSYS_SRC_MAX_AGE = 19, 6229 PSYS_SRC_MAX_AGE = 19,
6230 PSYS_SRC_TARGET_KEY = 20, 6230 PSYS_SRC_TARGET_KEY = 20,
6231 PSYS_SRC_OMEGA = 21, 6231 PSYS_SRC_OMEGA = 21,
6232 PSYS_SRC_ANGLE_BEGIN = 22, 6232 PSYS_SRC_ANGLE_BEGIN = 22,
6233 PSYS_SRC_ANGLE_END = 23, 6233 PSYS_SRC_ANGLE_END = 23,
6234 PSYS_PART_BLEND_FUNC_SOURCE = 24, 6234 PSYS_PART_BLEND_FUNC_SOURCE = 24,
6235 PSYS_PART_BLEND_FUNC_DEST = 25, 6235 PSYS_PART_BLEND_FUNC_DEST = 25,
6236 PSYS_PART_START_GLOW = 26, 6236 PSYS_PART_START_GLOW = 26,
6237 PSYS_PART_END_GLOW = 27 6237 PSYS_PART_END_GLOW = 27
6238 } 6238 }
6239   6239  
6240 internal Primitive.ParticleSystem.ParticleDataFlags ConvertUINTtoFlags(uint flags) 6240 internal Primitive.ParticleSystem.ParticleDataFlags ConvertUINTtoFlags(uint flags)
6241 { 6241 {
6242 Primitive.ParticleSystem.ParticleDataFlags returnval = Primitive.ParticleSystem.ParticleDataFlags.None; 6242 Primitive.ParticleSystem.ParticleDataFlags returnval = Primitive.ParticleSystem.ParticleDataFlags.None;
6243   6243  
6244 return returnval; 6244 return returnval;
6245 } 6245 }
6246   6246  
6247 protected Primitive.ParticleSystem getNewParticleSystemWithSLDefaultValues() 6247 protected Primitive.ParticleSystem getNewParticleSystemWithSLDefaultValues()
6248 { 6248 {
6249 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(); 6249 Primitive.ParticleSystem ps = new Primitive.ParticleSystem();
6250   6250  
6251 // TODO find out about the other defaults and add them here 6251 // TODO find out about the other defaults and add them here
6252 ps.PartStartColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f); 6252 ps.PartStartColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
6253 ps.PartEndColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f); 6253 ps.PartEndColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
6254 ps.PartStartScaleX = 1.0f; 6254 ps.PartStartScaleX = 1.0f;
6255 ps.PartStartScaleY = 1.0f; 6255 ps.PartStartScaleY = 1.0f;
6256 ps.PartEndScaleX = 1.0f; 6256 ps.PartEndScaleX = 1.0f;
6257 ps.PartEndScaleY = 1.0f; 6257 ps.PartEndScaleY = 1.0f;
6258 ps.BurstSpeedMin = 1.0f; 6258 ps.BurstSpeedMin = 1.0f;
6259 ps.BurstSpeedMax = 1.0f; 6259 ps.BurstSpeedMax = 1.0f;
6260 ps.BurstRate = 0.1f; 6260 ps.BurstRate = 0.1f;
6261 ps.PartMaxAge = 10.0f; 6261 ps.PartMaxAge = 10.0f;
6262 ps.BurstPartCount = 1; 6262 ps.BurstPartCount = 1;
6263 ps.BlendFuncSource = ScriptBaseClass.PSYS_PART_BF_SOURCE_ALPHA; 6263 ps.BlendFuncSource = ScriptBaseClass.PSYS_PART_BF_SOURCE_ALPHA;
6264 ps.BlendFuncDest = ScriptBaseClass.PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA; 6264 ps.BlendFuncDest = ScriptBaseClass.PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA;
6265 ps.PartStartGlow = 0.0f; 6265 ps.PartStartGlow = 0.0f;
6266 ps.PartEndGlow = 0.0f; 6266 ps.PartEndGlow = 0.0f;
6267   6267  
6268 return ps; 6268 return ps;
6269 } 6269 }
6270   6270  
6271 public void llLinkParticleSystem(int linknumber, LSL_List rules) 6271 public void llLinkParticleSystem(int linknumber, LSL_List rules)
6272 { 6272 {
6273 m_host.AddScriptLPS(1); 6273 m_host.AddScriptLPS(1);
6274   6274  
6275 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6275 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6276   6276  
6277 foreach (SceneObjectPart part in parts) 6277 foreach (SceneObjectPart part in parts)
6278 { 6278 {
6279 SetParticleSystem(part, rules); 6279 SetParticleSystem(part, rules);
6280 } 6280 }
6281 } 6281 }
6282   6282  
6283 public void llParticleSystem(LSL_List rules) 6283 public void llParticleSystem(LSL_List rules)
6284 { 6284 {
6285 m_host.AddScriptLPS(1); 6285 m_host.AddScriptLPS(1);
6286 SetParticleSystem(m_host, rules); 6286 SetParticleSystem(m_host, rules);
6287 } 6287 }
6288   6288  
6289 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6289 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6290 { 6290 {
6291 if (rules.Length == 0) 6291 if (rules.Length == 0)
6292 { 6292 {
6293 part.RemoveParticleSystem(); 6293 part.RemoveParticleSystem();
6294 part.ParentGroup.HasGroupChanged = true; 6294 part.ParentGroup.HasGroupChanged = true;
6295 } 6295 }
6296 else 6296 else
6297 { 6297 {
6298 Primitive.ParticleSystem prules = getNewParticleSystemWithSLDefaultValues(); 6298 Primitive.ParticleSystem prules = getNewParticleSystemWithSLDefaultValues();
6299 LSL_Vector tempv = new LSL_Vector(); 6299 LSL_Vector tempv = new LSL_Vector();
6300   6300  
6301 float tempf = 0; 6301 float tempf = 0;
6302 int tmpi = 0; 6302 int tmpi = 0;
6303   6303  
6304 for (int i = 0; i < rules.Length; i += 2) 6304 for (int i = 0; i < rules.Length; i += 2)
6305 { 6305 {
6306 switch (rules.GetLSLIntegerItem(i)) 6306 switch (rules.GetLSLIntegerItem(i))
6307 { 6307 {
6308 case (int)ScriptBaseClass.PSYS_PART_FLAGS: 6308 case (int)ScriptBaseClass.PSYS_PART_FLAGS:
6309 prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); 6309 prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1);
6310 break; 6310 break;
6311   6311  
6312 case (int)ScriptBaseClass.PSYS_PART_START_COLOR: 6312 case (int)ScriptBaseClass.PSYS_PART_START_COLOR:
6313 tempv = rules.GetVector3Item(i + 1); 6313 tempv = rules.GetVector3Item(i + 1);
6314 prules.PartStartColor.R = (float)tempv.x; 6314 prules.PartStartColor.R = (float)tempv.x;
6315 prules.PartStartColor.G = (float)tempv.y; 6315 prules.PartStartColor.G = (float)tempv.y;
6316 prules.PartStartColor.B = (float)tempv.z; 6316 prules.PartStartColor.B = (float)tempv.z;
6317 break; 6317 break;
6318   6318  
6319 case (int)ScriptBaseClass.PSYS_PART_START_ALPHA: 6319 case (int)ScriptBaseClass.PSYS_PART_START_ALPHA:
6320 tempf = (float)rules.GetLSLFloatItem(i + 1); 6320 tempf = (float)rules.GetLSLFloatItem(i + 1);
6321 prules.PartStartColor.A = tempf; 6321 prules.PartStartColor.A = tempf;
6322 break; 6322 break;
6323   6323  
6324 case (int)ScriptBaseClass.PSYS_PART_END_COLOR: 6324 case (int)ScriptBaseClass.PSYS_PART_END_COLOR:
6325 tempv = rules.GetVector3Item(i + 1); 6325 tempv = rules.GetVector3Item(i + 1);
6326 prules.PartEndColor.R = (float)tempv.x; 6326 prules.PartEndColor.R = (float)tempv.x;
6327 prules.PartEndColor.G = (float)tempv.y; 6327 prules.PartEndColor.G = (float)tempv.y;
6328 prules.PartEndColor.B = (float)tempv.z; 6328 prules.PartEndColor.B = (float)tempv.z;
6329 break; 6329 break;
6330   6330  
6331 case (int)ScriptBaseClass.PSYS_PART_END_ALPHA: 6331 case (int)ScriptBaseClass.PSYS_PART_END_ALPHA:
6332 tempf = (float)rules.GetLSLFloatItem(i + 1); 6332 tempf = (float)rules.GetLSLFloatItem(i + 1);
6333 prules.PartEndColor.A = tempf; 6333 prules.PartEndColor.A = tempf;
6334 break; 6334 break;
6335   6335  
6336 case (int)ScriptBaseClass.PSYS_PART_START_SCALE: 6336 case (int)ScriptBaseClass.PSYS_PART_START_SCALE:
6337 tempv = rules.GetVector3Item(i + 1); 6337 tempv = rules.GetVector3Item(i + 1);
6338 prules.PartStartScaleX = (float)tempv.x; 6338 prules.PartStartScaleX = (float)tempv.x;
6339 prules.PartStartScaleY = (float)tempv.y; 6339 prules.PartStartScaleY = (float)tempv.y;
6340 break; 6340 break;
6341   6341  
6342 case (int)ScriptBaseClass.PSYS_PART_END_SCALE: 6342 case (int)ScriptBaseClass.PSYS_PART_END_SCALE:
6343 tempv = rules.GetVector3Item(i + 1); 6343 tempv = rules.GetVector3Item(i + 1);
6344 prules.PartEndScaleX = (float)tempv.x; 6344 prules.PartEndScaleX = (float)tempv.x;
6345 prules.PartEndScaleY = (float)tempv.y; 6345 prules.PartEndScaleY = (float)tempv.y;
6346 break; 6346 break;
6347   6347  
6348 case (int)ScriptBaseClass.PSYS_PART_MAX_AGE: 6348 case (int)ScriptBaseClass.PSYS_PART_MAX_AGE:
6349 tempf = (float)rules.GetLSLFloatItem(i + 1); 6349 tempf = (float)rules.GetLSLFloatItem(i + 1);
6350 prules.PartMaxAge = tempf; 6350 prules.PartMaxAge = tempf;
6351 break; 6351 break;
6352   6352  
6353 case (int)ScriptBaseClass.PSYS_SRC_ACCEL: 6353 case (int)ScriptBaseClass.PSYS_SRC_ACCEL:
6354 tempv = rules.GetVector3Item(i + 1); 6354 tempv = rules.GetVector3Item(i + 1);
6355 prules.PartAcceleration.X = (float)tempv.x; 6355 prules.PartAcceleration.X = (float)tempv.x;
6356 prules.PartAcceleration.Y = (float)tempv.y; 6356 prules.PartAcceleration.Y = (float)tempv.y;
6357 prules.PartAcceleration.Z = (float)tempv.z; 6357 prules.PartAcceleration.Z = (float)tempv.z;
6358 break; 6358 break;
6359   6359  
6360 case (int)ScriptBaseClass.PSYS_SRC_PATTERN: 6360 case (int)ScriptBaseClass.PSYS_SRC_PATTERN:
6361 tmpi = (int)rules.GetLSLIntegerItem(i + 1); 6361 tmpi = (int)rules.GetLSLIntegerItem(i + 1);
6362 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; 6362 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi;
6363 break; 6363 break;
6364   6364  
6365 // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The 6365 // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The
6366 // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The 6366 // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The
6367 // client tells the difference between the two by looking at the 0x02 bit in 6367 // client tells the difference between the two by looking at the 0x02 bit in
6368 // the PartFlags variable. 6368 // the PartFlags variable.
6369 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: 6369 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6370 tempf = (float)rules.GetLSLFloatItem(i + 1); 6370 tempf = (float)rules.GetLSLFloatItem(i + 1);
6371 prules.InnerAngle = (float)tempf; 6371 prules.InnerAngle = (float)tempf;
6372 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. 6372 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6373 break; 6373 break;
6374   6374  
6375 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: 6375 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6376 tempf = (float)rules.GetLSLFloatItem(i + 1); 6376 tempf = (float)rules.GetLSLFloatItem(i + 1);
6377 prules.OuterAngle = (float)tempf; 6377 prules.OuterAngle = (float)tempf;
6378 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. 6378 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6379 break; 6379 break;
6380   6380  
6381 case (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_SOURCE: 6381 case (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_SOURCE:
6382 tmpi = (int)rules.GetLSLIntegerItem(i + 1); 6382 tmpi = (int)rules.GetLSLIntegerItem(i + 1);
6383 prules.BlendFuncSource = (byte)tmpi; 6383 prules.BlendFuncSource = (byte)tmpi;
6384 break; 6384 break;
6385   6385  
6386 case (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_DEST: 6386 case (int)ScriptBaseClass.PSYS_PART_BLEND_FUNC_DEST:
6387 tmpi = (int)rules.GetLSLIntegerItem(i + 1); 6387 tmpi = (int)rules.GetLSLIntegerItem(i + 1);
6388 prules.BlendFuncDest = (byte)tmpi; 6388 prules.BlendFuncDest = (byte)tmpi;
6389 break; 6389 break;
6390   6390  
6391 case (int)ScriptBaseClass.PSYS_PART_START_GLOW: 6391 case (int)ScriptBaseClass.PSYS_PART_START_GLOW:
6392 tempf = (float)rules.GetLSLFloatItem(i + 1); 6392 tempf = (float)rules.GetLSLFloatItem(i + 1);
6393 prules.PartStartGlow = (float)tempf; 6393 prules.PartStartGlow = (float)tempf;
6394 break; 6394 break;
6395   6395  
6396 case (int)ScriptBaseClass.PSYS_PART_END_GLOW: 6396 case (int)ScriptBaseClass.PSYS_PART_END_GLOW:
6397 tempf = (float)rules.GetLSLFloatItem(i + 1); 6397 tempf = (float)rules.GetLSLFloatItem(i + 1);
6398 prules.PartEndGlow = (float)tempf; 6398 prules.PartEndGlow = (float)tempf;
6399 break; 6399 break;
6400   6400  
6401 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6401 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6402 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1)); 6402 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1));
6403 break; 6403 break;
6404   6404  
6405 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: 6405 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE:
6406 tempf = (float)rules.GetLSLFloatItem(i + 1); 6406 tempf = (float)rules.GetLSLFloatItem(i + 1);
6407 prules.BurstRate = (float)tempf; 6407 prules.BurstRate = (float)tempf;
6408 break; 6408 break;
6409   6409  
6410 case (int)ScriptBaseClass.PSYS_SRC_BURST_PART_COUNT: 6410 case (int)ScriptBaseClass.PSYS_SRC_BURST_PART_COUNT:
6411 prules.BurstPartCount = (byte)(int)rules.GetLSLIntegerItem(i + 1); 6411 prules.BurstPartCount = (byte)(int)rules.GetLSLIntegerItem(i + 1);
6412 break; 6412 break;
6413   6413  
6414 case (int)ScriptBaseClass.PSYS_SRC_BURST_RADIUS: 6414 case (int)ScriptBaseClass.PSYS_SRC_BURST_RADIUS:
6415 tempf = (float)rules.GetLSLFloatItem(i + 1); 6415 tempf = (float)rules.GetLSLFloatItem(i + 1);
6416 prules.BurstRadius = (float)tempf; 6416 prules.BurstRadius = (float)tempf;
6417 break; 6417 break;
6418   6418  
6419 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MIN: 6419 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MIN:
6420 tempf = (float)rules.GetLSLFloatItem(i + 1); 6420 tempf = (float)rules.GetLSLFloatItem(i + 1);
6421 prules.BurstSpeedMin = (float)tempf; 6421 prules.BurstSpeedMin = (float)tempf;
6422 break; 6422 break;
6423   6423  
6424 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MAX: 6424 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MAX:
6425 tempf = (float)rules.GetLSLFloatItem(i + 1); 6425 tempf = (float)rules.GetLSLFloatItem(i + 1);
6426 prules.BurstSpeedMax = (float)tempf; 6426 prules.BurstSpeedMax = (float)tempf;
6427 break; 6427 break;
6428   6428  
6429 case (int)ScriptBaseClass.PSYS_SRC_MAX_AGE: 6429 case (int)ScriptBaseClass.PSYS_SRC_MAX_AGE:
6430 tempf = (float)rules.GetLSLFloatItem(i + 1); 6430 tempf = (float)rules.GetLSLFloatItem(i + 1);
6431 prules.MaxAge = (float)tempf; 6431 prules.MaxAge = (float)tempf;
6432 break; 6432 break;
6433   6433  
6434 case (int)ScriptBaseClass.PSYS_SRC_TARGET_KEY: 6434 case (int)ScriptBaseClass.PSYS_SRC_TARGET_KEY:
6435 UUID key = UUID.Zero; 6435 UUID key = UUID.Zero;
6436 if (UUID.TryParse(rules.Data[i + 1].ToString(), out key)) 6436 if (UUID.TryParse(rules.Data[i + 1].ToString(), out key))
6437 { 6437 {
6438 prules.Target = key; 6438 prules.Target = key;
6439 } 6439 }
6440 else 6440 else
6441 { 6441 {
6442 prules.Target = part.UUID; 6442 prules.Target = part.UUID;
6443 } 6443 }
6444 break; 6444 break;
6445   6445  
6446 case (int)ScriptBaseClass.PSYS_SRC_OMEGA: 6446 case (int)ScriptBaseClass.PSYS_SRC_OMEGA:
6447 // AL: This is an assumption, since it is the only thing that would match. 6447 // AL: This is an assumption, since it is the only thing that would match.
6448 tempv = rules.GetVector3Item(i + 1); 6448 tempv = rules.GetVector3Item(i + 1);
6449 prules.AngularVelocity.X = (float)tempv.x; 6449 prules.AngularVelocity.X = (float)tempv.x;
6450 prules.AngularVelocity.Y = (float)tempv.y; 6450 prules.AngularVelocity.Y = (float)tempv.y;
6451 prules.AngularVelocity.Z = (float)tempv.z; 6451 prules.AngularVelocity.Z = (float)tempv.z;
6452 break; 6452 break;
6453   6453  
6454 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN: 6454 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN:
6455 tempf = (float)rules.GetLSLFloatItem(i + 1); 6455 tempf = (float)rules.GetLSLFloatItem(i + 1);
6456 prules.InnerAngle = (float)tempf; 6456 prules.InnerAngle = (float)tempf;
6457 prules.PartFlags |= 0x02; // Set new angle format. 6457 prules.PartFlags |= 0x02; // Set new angle format.
6458 break; 6458 break;
6459   6459  
6460 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END: 6460 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END:
6461 tempf = (float)rules.GetLSLFloatItem(i + 1); 6461 tempf = (float)rules.GetLSLFloatItem(i + 1);
6462 prules.OuterAngle = (float)tempf; 6462 prules.OuterAngle = (float)tempf;
6463 prules.PartFlags |= 0x02; // Set new angle format. 6463 prules.PartFlags |= 0x02; // Set new angle format.
6464 break; 6464 break;
6465 } 6465 }
6466   6466  
6467 } 6467 }
6468 prules.CRC = 1; 6468 prules.CRC = 1;
6469   6469  
6470 part.AddNewParticleSystem(prules); 6470 part.AddNewParticleSystem(prules);
6471 part.ParentGroup.HasGroupChanged = true; 6471 part.ParentGroup.HasGroupChanged = true;
6472 } 6472 }
6473 part.SendFullUpdateToAllClients(); 6473 part.SendFullUpdateToAllClients();
6474 } 6474 }
6475   6475  
6476 public void llGroundRepel(double height, int water, double tau) 6476 public void llGroundRepel(double height, int water, double tau)
6477 { 6477 {
6478 m_host.AddScriptLPS(1); 6478 m_host.AddScriptLPS(1);
6479 if (m_host.PhysActor != null) 6479 if (m_host.PhysActor != null)
6480 { 6480 {
6481 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0)); 6481 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0));
6482 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0)); 6482 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0));
6483 PIDHoverType hoverType = PIDHoverType.Ground; 6483 PIDHoverType hoverType = PIDHoverType.Ground;
6484 if (water != 0) 6484 if (water != 0)
6485 { 6485 {
6486 hoverType = PIDHoverType.GroundAndWater; 6486 hoverType = PIDHoverType.GroundAndWater;
6487 if (ground < waterLevel) 6487 if (ground < waterLevel)
6488 height += waterLevel; 6488 height += waterLevel;
6489 else 6489 else
6490 height += ground; 6490 height += ground;
6491 } 6491 }
6492 else 6492 else
6493 { 6493 {
6494 height += ground; 6494 height += ground;
6495 } 6495 }
6496   6496  
6497 m_host.SetHoverHeight((float)height, hoverType, (float)tau); 6497 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
6498 } 6498 }
6499 } 6499 }
6500   6500  
6501 public void llGiveInventoryList(string destination, string category, LSL_List inventory) 6501 public void llGiveInventoryList(string destination, string category, LSL_List inventory)
6502 { 6502 {
6503 m_host.AddScriptLPS(1); 6503 m_host.AddScriptLPS(1);
6504   6504  
6505 UUID destID; 6505 UUID destID;
6506 if (!UUID.TryParse(destination, out destID)) 6506 if (!UUID.TryParse(destination, out destID))
6507 return; 6507 return;
6508   6508  
6509 List<UUID> itemList = new List<UUID>(); 6509 List<UUID> itemList = new List<UUID>();
6510   6510  
6511 foreach (Object item in inventory.Data) 6511 foreach (Object item in inventory.Data)
6512 { 6512 {
6513 string rawItemString = item.ToString(); 6513 string rawItemString = item.ToString();
6514   6514  
6515 UUID itemID; 6515 UUID itemID;
6516 if (UUID.TryParse(rawItemString, out itemID)) 6516 if (UUID.TryParse(rawItemString, out itemID))
6517 { 6517 {
6518 itemList.Add(itemID); 6518 itemList.Add(itemID);
6519 } 6519 }
6520 else 6520 else
6521 { 6521 {
6522 TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString); 6522 TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString);
6523   6523  
6524 if (taskItem != null) 6524 if (taskItem != null)
6525 itemList.Add(taskItem.ItemID); 6525 itemList.Add(taskItem.ItemID);
6526 } 6526 }
6527 } 6527 }
6528   6528  
6529 if (itemList.Count == 0) 6529 if (itemList.Count == 0)
6530 return; 6530 return;
6531   6531  
6532 UUID folderID = m_ScriptEngine.World.MoveTaskInventoryItems(destID, category, m_host, itemList); 6532 UUID folderID = m_ScriptEngine.World.MoveTaskInventoryItems(destID, category, m_host, itemList);
6533   6533  
6534 if (folderID == UUID.Zero) 6534 if (folderID == UUID.Zero)
6535 return; 6535 return;
6536   6536  
6537 if (m_TransferModule != null) 6537 if (m_TransferModule != null)
6538 { 6538 {
6539 byte[] bucket = new byte[] { (byte)AssetType.Folder }; 6539 byte[] bucket = new byte[] { (byte)AssetType.Folder };
6540   6540  
6541 Vector3 pos = m_host.AbsolutePosition; 6541 Vector3 pos = m_host.AbsolutePosition;
6542   6542  
6543 GridInstantMessage msg = new GridInstantMessage(World, 6543 GridInstantMessage msg = new GridInstantMessage(World,
6544 m_host.OwnerID, m_host.Name, destID, 6544 m_host.OwnerID, m_host.Name, destID,
6545 (byte)InstantMessageDialog.TaskInventoryOffered, 6545 (byte)InstantMessageDialog.TaskInventoryOffered,
6546 false, string.Format("'{0}'", category), 6546 false, string.Format("'{0}'", category),
6547 // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 6547 // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6548 // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), 6548 // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6549 folderID, false, pos, 6549 folderID, false, pos,
6550 bucket, false); 6550 bucket, false);
6551   6551  
6552 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 6552 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
6553 } 6553 }
6554 } 6554 }
6555   6555  
6556 public void llSetVehicleType(int type) 6556 public void llSetVehicleType(int type)
6557 { 6557 {
6558 m_host.AddScriptLPS(1); 6558 m_host.AddScriptLPS(1);
6559   6559  
6560 if (!m_host.ParentGroup.IsDeleted) 6560 if (!m_host.ParentGroup.IsDeleted)
6561 { 6561 {
6562 m_host.ParentGroup.RootPart.SetVehicleType(type); 6562 m_host.ParentGroup.RootPart.SetVehicleType(type);
6563 } 6563 }
6564 } 6564 }
6565   6565  
6566 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6566 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6567 //CFK 9/28: so these are not complete yet. 6567 //CFK 9/28: so these are not complete yet.
6568 public void llSetVehicleFloatParam(int param, LSL_Float value) 6568 public void llSetVehicleFloatParam(int param, LSL_Float value)
6569 { 6569 {
6570 m_host.AddScriptLPS(1); 6570 m_host.AddScriptLPS(1);
6571   6571  
6572 if (!m_host.ParentGroup.IsDeleted) 6572 if (!m_host.ParentGroup.IsDeleted)
6573 { 6573 {
6574 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); 6574 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6575 } 6575 }
6576 } 6576 }
6577   6577  
6578 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6578 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6579 //CFK 9/28: so these are not complete yet. 6579 //CFK 9/28: so these are not complete yet.
6580 public void llSetVehicleVectorParam(int param, LSL_Vector vec) 6580 public void llSetVehicleVectorParam(int param, LSL_Vector vec)
6581 { 6581 {
6582 m_host.AddScriptLPS(1); 6582 m_host.AddScriptLPS(1);
6583   6583  
6584 if (!m_host.ParentGroup.IsDeleted) 6584 if (!m_host.ParentGroup.IsDeleted)
6585 { 6585 {
6586 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); 6586 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
6587 } 6587 }
6588 } 6588 }
6589   6589  
6590 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6590 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6591 //CFK 9/28: so these are not complete yet. 6591 //CFK 9/28: so these are not complete yet.
6592 public void llSetVehicleRotationParam(int param, LSL_Rotation rot) 6592 public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
6593 { 6593 {
6594 m_host.AddScriptLPS(1); 6594 m_host.AddScriptLPS(1);
6595   6595  
6596 if (!m_host.ParentGroup.IsDeleted) 6596 if (!m_host.ParentGroup.IsDeleted)
6597 { 6597 {
6598 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); 6598 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
6599 } 6599 }
6600 } 6600 }
6601   6601  
6602 public void llSetVehicleFlags(int flags) 6602 public void llSetVehicleFlags(int flags)
6603 { 6603 {
6604 m_host.AddScriptLPS(1); 6604 m_host.AddScriptLPS(1);
6605   6605  
6606 if (!m_host.ParentGroup.IsDeleted) 6606 if (!m_host.ParentGroup.IsDeleted)
6607 { 6607 {
6608 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); 6608 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6609 } 6609 }
6610 } 6610 }
6611   6611  
6612 public void llRemoveVehicleFlags(int flags) 6612 public void llRemoveVehicleFlags(int flags)
6613 { 6613 {
6614 m_host.AddScriptLPS(1); 6614 m_host.AddScriptLPS(1);
6615   6615  
6616 if (!m_host.ParentGroup.IsDeleted) 6616 if (!m_host.ParentGroup.IsDeleted)
6617 { 6617 {
6618 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); 6618 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6619 } 6619 }
6620 } 6620 }
6621   6621  
6622 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6622 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6623 { 6623 {
6624 part.SitTargetPosition = offset; 6624 part.SitTargetPosition = offset;
6625 part.SitTargetOrientation = rot; 6625 part.SitTargetOrientation = rot;
6626 part.ParentGroup.HasGroupChanged = true; 6626 part.ParentGroup.HasGroupChanged = true;
6627 } 6627 }
6628   6628  
6629 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) 6629 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot)
6630 { 6630 {
6631 m_host.AddScriptLPS(1); 6631 m_host.AddScriptLPS(1);
6632 SitTarget(m_host, offset, rot); 6632 SitTarget(m_host, offset, rot);
6633 } 6633 }
6634   6634  
6635 public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot) 6635 public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot)
6636 { 6636 {
6637 m_host.AddScriptLPS(1); 6637 m_host.AddScriptLPS(1);
6638 if (link == ScriptBaseClass.LINK_ROOT) 6638 if (link == ScriptBaseClass.LINK_ROOT)
6639 SitTarget(m_host.ParentGroup.RootPart, offset, rot); 6639 SitTarget(m_host.ParentGroup.RootPart, offset, rot);
6640 else if (link == ScriptBaseClass.LINK_THIS) 6640 else if (link == ScriptBaseClass.LINK_THIS)
6641 SitTarget(m_host, offset, rot); 6641 SitTarget(m_host, offset, rot);
6642 else 6642 else
6643 { 6643 {
6644 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 6644 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
6645 if (null != part) 6645 if (null != part)
6646 { 6646 {
6647 SitTarget(part, offset, rot); 6647 SitTarget(part, offset, rot);
6648 } 6648 }
6649 } 6649 }
6650 } 6650 }
6651   6651  
6652 public LSL_String llAvatarOnSitTarget() 6652 public LSL_String llAvatarOnSitTarget()
6653 { 6653 {
6654 m_host.AddScriptLPS(1); 6654 m_host.AddScriptLPS(1);
6655 return m_host.SitTargetAvatar.ToString(); 6655 return m_host.SitTargetAvatar.ToString();
6656 } 6656 }
6657   6657  
6658 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget 6658 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget
6659 public LSL_String llAvatarOnLinkSitTarget(int linknum) 6659 public LSL_String llAvatarOnLinkSitTarget(int linknum)
6660 { 6660 {
6661 m_host.AddScriptLPS(1); 6661 m_host.AddScriptLPS(1);
6662 if(linknum == ScriptBaseClass.LINK_SET || 6662 if(linknum == ScriptBaseClass.LINK_SET ||
6663 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 6663 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
6664 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 6664 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
6665   6665  
6666 List<SceneObjectPart> parts = GetLinkParts(linknum); 6666 List<SceneObjectPart> parts = GetLinkParts(linknum);
6667 if (parts.Count == 0) return UUID.Zero.ToString(); 6667 if (parts.Count == 0) return UUID.Zero.ToString();
6668 return parts[0].SitTargetAvatar.ToString(); 6668 return parts[0].SitTargetAvatar.ToString();
6669 } 6669 }
6670   6670  
6671   6671  
6672 public void llAddToLandPassList(string avatar, double hours) 6672 public void llAddToLandPassList(string avatar, double hours)
6673 { 6673 {
6674 m_host.AddScriptLPS(1); 6674 m_host.AddScriptLPS(1);
6675 UUID key; 6675 UUID key;
6676 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 6676 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
6677   6677  
6678 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 6678 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
6679 { 6679 {
6680 int expires = 0; 6680 int expires = 0;
6681 if (hours != 0) 6681 if (hours != 0)
6682 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours); 6682 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours);
6683   6683  
6684 if (UUID.TryParse(avatar, out key)) 6684 if (UUID.TryParse(avatar, out key))
6685 { 6685 {
6686 int idx = land.LandData.ParcelAccessList.FindIndex( 6686 int idx = land.LandData.ParcelAccessList.FindIndex(
6687 delegate(LandAccessEntry e) 6687 delegate(LandAccessEntry e)
6688 { 6688 {
6689 if (e.AgentID == key && e.Flags == AccessList.Access) 6689 if (e.AgentID == key && e.Flags == AccessList.Access)
6690 return true; 6690 return true;
6691 return false; 6691 return false;
6692 }); 6692 });
6693   6693  
6694 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires))) 6694 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires)))
6695 return; 6695 return;
6696   6696  
6697 if (idx != -1) 6697 if (idx != -1)
6698 land.LandData.ParcelAccessList.RemoveAt(idx); 6698 land.LandData.ParcelAccessList.RemoveAt(idx);
6699   6699  
6700 LandAccessEntry entry = new LandAccessEntry(); 6700 LandAccessEntry entry = new LandAccessEntry();
6701   6701  
6702 entry.AgentID = key; 6702 entry.AgentID = key;
6703 entry.Flags = AccessList.Access; 6703 entry.Flags = AccessList.Access;
6704 entry.Expires = expires; 6704 entry.Expires = expires;
6705   6705  
6706 land.LandData.ParcelAccessList.Add(entry); 6706 land.LandData.ParcelAccessList.Add(entry);
6707   6707  
6708 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 6708 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
6709 } 6709 }
6710 } 6710 }
6711 ScriptSleep(100); 6711 ScriptSleep(100);
6712 } 6712 }
6713   6713  
6714 public void llSetTouchText(string text) 6714 public void llSetTouchText(string text)
6715 { 6715 {
6716 m_host.AddScriptLPS(1); 6716 m_host.AddScriptLPS(1);
6717 m_host.TouchName = text; 6717 m_host.TouchName = text;
6718 } 6718 }
6719   6719  
6720 public void llSetSitText(string text) 6720 public void llSetSitText(string text)
6721 { 6721 {
6722 m_host.AddScriptLPS(1); 6722 m_host.AddScriptLPS(1);
6723 m_host.SitName = text; 6723 m_host.SitName = text;
6724 } 6724 }
6725   6725  
6726 public void llSetCameraEyeOffset(LSL_Vector offset) 6726 public void llSetCameraEyeOffset(LSL_Vector offset)
6727 { 6727 {
6728 m_host.AddScriptLPS(1); 6728 m_host.AddScriptLPS(1);
6729 m_host.SetCameraEyeOffset(offset); 6729 m_host.SetCameraEyeOffset(offset);
6730 } 6730 }
6731   6731  
6732 public void llSetCameraAtOffset(LSL_Vector offset) 6732 public void llSetCameraAtOffset(LSL_Vector offset)
6733 { 6733 {
6734 m_host.AddScriptLPS(1); 6734 m_host.AddScriptLPS(1);
6735 m_host.SetCameraAtOffset(offset); 6735 m_host.SetCameraAtOffset(offset);
6736 } 6736 }
6737   6737  
6738 public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) 6738 public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at)
6739 { 6739 {
6740 m_host.AddScriptLPS(1); 6740 m_host.AddScriptLPS(1);
6741   6741  
6742 if (link == ScriptBaseClass.LINK_SET || 6742 if (link == ScriptBaseClass.LINK_SET ||
6743 link == ScriptBaseClass.LINK_ALL_CHILDREN || 6743 link == ScriptBaseClass.LINK_ALL_CHILDREN ||
6744 link == ScriptBaseClass.LINK_ALL_OTHERS) return; 6744 link == ScriptBaseClass.LINK_ALL_OTHERS) return;
6745   6745  
6746 SceneObjectPart part = null; 6746 SceneObjectPart part = null;
6747   6747  
6748 switch (link) 6748 switch (link)
6749 { 6749 {
6750 case ScriptBaseClass.LINK_ROOT: 6750 case ScriptBaseClass.LINK_ROOT:
6751 part = m_host.ParentGroup.RootPart; 6751 part = m_host.ParentGroup.RootPart;
6752 break; 6752 break;
6753 case ScriptBaseClass.LINK_THIS: 6753 case ScriptBaseClass.LINK_THIS:
6754 part = m_host; 6754 part = m_host;
6755 break; 6755 break;
6756 default: 6756 default:
6757 part = m_host.ParentGroup.GetLinkNumPart(link); 6757 part = m_host.ParentGroup.GetLinkNumPart(link);
6758 break; 6758 break;
6759 } 6759 }
6760   6760  
6761 if (null != part) 6761 if (null != part)
6762 { 6762 {
6763 part.SetCameraEyeOffset(eye); 6763 part.SetCameraEyeOffset(eye);
6764 part.SetCameraAtOffset(at); 6764 part.SetCameraAtOffset(at);
6765 } 6765 }
6766 } 6766 }
6767   6767  
6768 public LSL_String llDumpList2String(LSL_List src, string seperator) 6768 public LSL_String llDumpList2String(LSL_List src, string seperator)
6769 { 6769 {
6770 m_host.AddScriptLPS(1); 6770 m_host.AddScriptLPS(1);
6771 if (src.Length == 0) 6771 if (src.Length == 0)
6772 { 6772 {
6773 return String.Empty; 6773 return String.Empty;
6774 } 6774 }
6775 string ret = String.Empty; 6775 string ret = String.Empty;
6776 foreach (object o in src.Data) 6776 foreach (object o in src.Data)
6777 { 6777 {
6778 ret = ret + o.ToString() + seperator; 6778 ret = ret + o.ToString() + seperator;
6779 } 6779 }
6780 ret = ret.Substring(0, ret.Length - seperator.Length); 6780 ret = ret.Substring(0, ret.Length - seperator.Length);
6781 return ret; 6781 return ret;
6782 } 6782 }
6783   6783  
6784 public LSL_Integer llScriptDanger(LSL_Vector pos) 6784 public LSL_Integer llScriptDanger(LSL_Vector pos)
6785 { 6785 {
6786 m_host.AddScriptLPS(1); 6786 m_host.AddScriptLPS(1);
6787 bool result = World.ScriptDanger(m_host.LocalId, pos); 6787 bool result = World.ScriptDanger(m_host.LocalId, pos);
6788 if (result) 6788 if (result)
6789 { 6789 {
6790 return 1; 6790 return 1;
6791 } 6791 }
6792 else 6792 else
6793 { 6793 {
6794 return 0; 6794 return 0;
6795 } 6795 }
6796   6796  
6797 } 6797 }
6798   6798  
6799 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) 6799 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel)
6800 { 6800 {
6801 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 6801 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
6802   6802  
6803 if (dm == null) 6803 if (dm == null)
6804 return; 6804 return;
6805   6805  
6806 m_host.AddScriptLPS(1); 6806 m_host.AddScriptLPS(1);
6807 UUID av = new UUID(); 6807 UUID av = new UUID();
6808 if (!UUID.TryParse(avatar,out av)) 6808 if (!UUID.TryParse(avatar,out av))
6809 { 6809 {
6810 Error("llDialog", "First parameter must be a key"); 6810 Error("llDialog", "First parameter must be a key");
6811 return; 6811 return;
6812 } 6812 }
6813 if (buttons.Length < 1) 6813 if (buttons.Length < 1)
6814 { 6814 {
6815 Error("llDialog", "At least 1 button must be shown"); 6815 Error("llDialog", "At least 1 button must be shown");
6816 return; 6816 return;
6817 } 6817 }
6818 if (buttons.Length > 12) 6818 if (buttons.Length > 12)
6819 { 6819 {
6820 Error("llDialog", "No more than 12 buttons can be shown"); 6820 Error("llDialog", "No more than 12 buttons can be shown");
6821 return; 6821 return;
6822 } 6822 }
6823 string[] buts = new string[buttons.Length]; 6823 string[] buts = new string[buttons.Length];
6824 for (int i = 0; i < buttons.Length; i++) 6824 for (int i = 0; i < buttons.Length; i++)
6825 { 6825 {
6826 if (buttons.Data[i].ToString() == String.Empty) 6826 if (buttons.Data[i].ToString() == String.Empty)
6827 { 6827 {
6828 Error("llDialog", "Button label cannot be blank"); 6828 Error("llDialog", "Button label cannot be blank");
6829 return; 6829 return;
6830 } 6830 }
6831 if (buttons.Data[i].ToString().Length > 24) 6831 if (buttons.Data[i].ToString().Length > 24)
6832 { 6832 {
6833 Error("llDialog", "Button label cannot be longer than 24 characters"); 6833 Error("llDialog", "Button label cannot be longer than 24 characters");
6834 return; 6834 return;
6835 } 6835 }
6836 buts[i] = buttons.Data[i].ToString(); 6836 buts[i] = buttons.Data[i].ToString();
6837 } 6837 }
6838   6838  
6839 dm.SendDialogToUser( 6839 dm.SendDialogToUser(
6840 av, m_host.Name, m_host.UUID, m_host.OwnerID, 6840 av, m_host.Name, m_host.UUID, m_host.OwnerID,
6841 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts); 6841 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts);
6842   6842  
6843 ScriptSleep(1000); 6843 ScriptSleep(1000);
6844 } 6844 }
6845   6845  
6846 public void llVolumeDetect(int detect) 6846 public void llVolumeDetect(int detect)
6847 { 6847 {
6848 m_host.AddScriptLPS(1); 6848 m_host.AddScriptLPS(1);
6849   6849  
6850 if (!m_host.ParentGroup.IsDeleted) 6850 if (!m_host.ParentGroup.IsDeleted)
6851 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); 6851 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0);
6852 } 6852 }
6853   6853  
6854 public void llRemoteLoadScript(string target, string name, int running, int start_param) 6854 public void llRemoteLoadScript(string target, string name, int running, int start_param)
6855 { 6855 {
6856 m_host.AddScriptLPS(1); 6856 m_host.AddScriptLPS(1);
6857 Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead"); 6857 Deprecated("llRemoteLoadScript", "Use llRemoteLoadScriptPin instead");
6858 ScriptSleep(3000); 6858 ScriptSleep(3000);
6859 } 6859 }
6860   6860  
6861 public void llSetRemoteScriptAccessPin(int pin) 6861 public void llSetRemoteScriptAccessPin(int pin)
6862 { 6862 {
6863 m_host.AddScriptLPS(1); 6863 m_host.AddScriptLPS(1);
6864 m_host.ScriptAccessPin = pin; 6864 m_host.ScriptAccessPin = pin;
6865 } 6865 }
6866   6866  
6867 public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) 6867 public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param)
6868 { 6868 {
6869 m_host.AddScriptLPS(1); 6869 m_host.AddScriptLPS(1);
6870   6870  
6871 UUID destId = UUID.Zero; 6871 UUID destId = UUID.Zero;
6872   6872  
6873 if (!UUID.TryParse(target, out destId)) 6873 if (!UUID.TryParse(target, out destId))
6874 { 6874 {
6875 Error("llRemoteLoadScriptPin", "Can't parse key '" + target + "'"); 6875 Error("llRemoteLoadScriptPin", "Can't parse key '" + target + "'");
6876 return; 6876 return;
6877 } 6877 }
6878   6878  
6879 // target must be a different prim than the one containing the script 6879 // target must be a different prim than the one containing the script
6880 if (m_host.UUID == destId) 6880 if (m_host.UUID == destId)
6881 { 6881 {
6882 return; 6882 return;
6883 } 6883 }
6884   6884  
6885 // copy the first script found with this inventory name 6885 // copy the first script found with this inventory name
6886 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 6886 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
6887   6887  
6888 // make sure the object is a script 6888 // make sure the object is a script
6889 if (item == null || item.Type != 10) 6889 if (item == null || item.Type != 10)
6890 { 6890 {
6891 Error("llRemoteLoadScriptPin", "Can't find script '" + name + "'"); 6891 Error("llRemoteLoadScriptPin", "Can't find script '" + name + "'");
6892 return; 6892 return;
6893 } 6893 }
6894   6894  
6895 // the rest of the permission checks are done in RezScript, so check the pin there as well 6895 // the rest of the permission checks are done in RezScript, so check the pin there as well
6896 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 6896 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6897   6897  
6898 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6898 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6899 ScriptSleep(3000); 6899 ScriptSleep(3000);
6900 } 6900 }
6901   6901  
6902 public void llOpenRemoteDataChannel() 6902 public void llOpenRemoteDataChannel()
6903 { 6903 {
6904 m_host.AddScriptLPS(1); 6904 m_host.AddScriptLPS(1);
6905 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6905 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6906 if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) 6906 if (xmlrpcMod != null && xmlrpcMod.IsEnabled())
6907 { 6907 {
6908 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); 6908 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero);
6909 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); 6909 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
6910 if (xmlRpcRouter != null) 6910 if (xmlRpcRouter != null)
6911 { 6911 {
6912 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName; 6912 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName;
6913   6913  
6914 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID, 6914 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID,
6915 m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName, 6915 m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName,
6916 xmlrpcMod.Port.ToString())); 6916 xmlrpcMod.Port.ToString()));
6917 } 6917 }
6918 object[] resobj = new object[] 6918 object[] resobj = new object[]
6919 { 6919 {
6920 new LSL_Integer(1), 6920 new LSL_Integer(1),
6921 new LSL_String(channelID.ToString()), 6921 new LSL_String(channelID.ToString()),
6922 new LSL_String(UUID.Zero.ToString()), 6922 new LSL_String(UUID.Zero.ToString()),
6923 new LSL_String(String.Empty), 6923 new LSL_String(String.Empty),
6924 new LSL_Integer(0), 6924 new LSL_Integer(0),
6925 new LSL_String(String.Empty) 6925 new LSL_String(String.Empty)
6926 }; 6926 };
6927 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj, 6927 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj,
6928 new DetectParams[0])); 6928 new DetectParams[0]));
6929 } 6929 }
6930 ScriptSleep(1000); 6930 ScriptSleep(1000);
6931 } 6931 }
6932   6932  
6933 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) 6933 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata)
6934 { 6934 {
6935 m_host.AddScriptLPS(1); 6935 m_host.AddScriptLPS(1);
6936 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6936 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6937 ScriptSleep(3000); 6937 ScriptSleep(3000);
6938 if (xmlrpcMod == null) 6938 if (xmlrpcMod == null)
6939 return ""; 6939 return "";
6940 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); 6940 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString();
6941 } 6941 }
6942   6942  
6943 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) 6943 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
6944 { 6944 {
6945 m_host.AddScriptLPS(1); 6945 m_host.AddScriptLPS(1);
6946 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6946 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6947 if (xmlrpcMod != null) 6947 if (xmlrpcMod != null)
6948 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); 6948 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata);
6949 ScriptSleep(3000); 6949 ScriptSleep(3000);
6950 } 6950 }
6951   6951  
6952 public void llCloseRemoteDataChannel(string channel) 6952 public void llCloseRemoteDataChannel(string channel)
6953 { 6953 {
6954 m_host.AddScriptLPS(1); 6954 m_host.AddScriptLPS(1);
6955   6955  
6956 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); 6956 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
6957 if (xmlRpcRouter != null) 6957 if (xmlRpcRouter != null)
6958 { 6958 {
6959 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID); 6959 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID);
6960 } 6960 }
6961   6961  
6962 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6962 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6963 if (xmlrpcMod != null) 6963 if (xmlrpcMod != null)
6964 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 6964 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
6965 ScriptSleep(1000); 6965 ScriptSleep(1000);
6966 } 6966 }
6967   6967  
6968 public LSL_String llMD5String(string src, int nonce) 6968 public LSL_String llMD5String(string src, int nonce)
6969 { 6969 {
6970 m_host.AddScriptLPS(1); 6970 m_host.AddScriptLPS(1);
6971 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 6971 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()));
6972 } 6972 }
6973   6973  
6974 public LSL_String llSHA1String(string src) 6974 public LSL_String llSHA1String(string src)
6975 { 6975 {
6976 m_host.AddScriptLPS(1); 6976 m_host.AddScriptLPS(1);
6977 return Util.SHA1Hash(src).ToLower(); 6977 return Util.SHA1Hash(src).ToLower();
6978 } 6978 }
6979   6979  
6980 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 6980 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6981 { 6981 {
6982 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 6982 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6983 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6983 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6984   6984  
6985 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6985 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6986 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6986 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
6987 holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE && 6987 holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE &&
6988 holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE) 6988 holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE)
6989 { 6989 {
6990 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; 6990 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
6991 } 6991 }
6992 shapeBlock.PathCurve = pathcurve; 6992 shapeBlock.PathCurve = pathcurve;
6993 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape. 6993 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape.
6994 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape. 6994 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape.
6995 if (cut.x < 0f) 6995 if (cut.x < 0f)
6996 { 6996 {
6997 cut.x = 0f; 6997 cut.x = 0f;
6998 } 6998 }
6999 if (cut.x > 1f) 6999 if (cut.x > 1f)
7000 { 7000 {
7001 cut.x = 1f; 7001 cut.x = 1f;
7002 } 7002 }
7003 if (cut.y < 0f) 7003 if (cut.y < 0f)
7004 { 7004 {
7005 cut.y = 0f; 7005 cut.y = 0f;
7006 } 7006 }
7007 if (cut.y > 1f) 7007 if (cut.y > 1f)
7008 { 7008 {
7009 cut.y = 1f; 7009 cut.y = 1f;
7010 } 7010 }
7011 if (cut.y - cut.x < 0.05f) 7011 if (cut.y - cut.x < 0.05f)
7012 { 7012 {
7013 cut.x = cut.y - 0.05f; 7013 cut.x = cut.y - 0.05f;
7014 if (cut.x < 0.0f) 7014 if (cut.x < 0.0f)
7015 { 7015 {
7016 cut.x = 0.0f; 7016 cut.x = 0.0f;
7017 cut.y = 0.05f; 7017 cut.y = 0.05f;
7018 } 7018 }
7019 } 7019 }
7020 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x); 7020 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x);
7021 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y)); 7021 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y));
7022 if (hollow < 0f) 7022 if (hollow < 0f)
7023 { 7023 {
7024 hollow = 0f; 7024 hollow = 0f;
7025 } 7025 }
7026 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a 7026 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a
7027 // Box or Tube) and the hole shape is a square, hollow is limited to 7027 // Box or Tube) and the hole shape is a square, hollow is limited to
7028 // a max of 70%. The viewer performs its own check on this value but 7028 // a max of 70%. The viewer performs its own check on this value but
7029 // we need to do it here also so llGetPrimitiveParams can have access 7029 // we need to do it here also so llGetPrimitiveParams can have access
7030 // to the correct value. 7030 // to the correct value.
7031 if (profileshape != (byte)ProfileCurve.Square && 7031 if (profileshape != (byte)ProfileCurve.Square &&
7032 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE) 7032 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE)
7033 { 7033 {
7034 if (hollow > 0.70f) 7034 if (hollow > 0.70f)
7035 { 7035 {
7036 hollow = 0.70f; 7036 hollow = 0.70f;
7037 } 7037 }
7038 } 7038 }
7039 // Otherwise, hollow is limited to 95%. 7039 // Otherwise, hollow is limited to 95%.
7040 else 7040 else
7041 { 7041 {
7042 if (hollow > 0.95f) 7042 if (hollow > 0.95f)
7043 { 7043 {
7044 hollow = 0.95f; 7044 hollow = 0.95f;
7045 } 7045 }
7046 } 7046 }
7047 shapeBlock.ProfileHollow = (ushort)(50000 * hollow); 7047 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
7048 if (twist.x < -1.0f) 7048 if (twist.x < -1.0f)
7049 { 7049 {
7050 twist.x = -1.0f; 7050 twist.x = -1.0f;
7051 } 7051 }
7052 if (twist.x > 1.0f) 7052 if (twist.x > 1.0f)
7053 { 7053 {
7054 twist.x = 1.0f; 7054 twist.x = 1.0f;
7055 } 7055 }
7056 if (twist.y < -1.0f) 7056 if (twist.y < -1.0f)
7057 { 7057 {
7058 twist.y = -1.0f; 7058 twist.y = -1.0f;
7059 } 7059 }
7060 if (twist.y > 1.0f) 7060 if (twist.y > 1.0f)
7061 { 7061 {
7062 twist.y = 1.0f; 7062 twist.y = 1.0f;
7063 } 7063 }
7064 // A fairly large precision error occurs for some calculations, 7064 // A fairly large precision error occurs for some calculations,
7065 // if a float or double is directly cast to a byte or sbyte 7065 // if a float or double is directly cast to a byte or sbyte
7066 // variable, in both .Net and Mono. In .Net, coding 7066 // variable, in both .Net and Mono. In .Net, coding
7067 // "(sbyte)(float)(some expression)" corrects the precision 7067 // "(sbyte)(float)(some expression)" corrects the precision
7068 // errors. But this does not work for Mono. This longer coding 7068 // errors. But this does not work for Mono. This longer coding
7069 // form of creating a tempoary float variable from the 7069 // form of creating a tempoary float variable from the
7070 // expression first, then casting that variable to a byte or 7070 // expression first, then casting that variable to a byte or
7071 // sbyte, works for both .Net and Mono. These types of 7071 // sbyte, works for both .Net and Mono. These types of
7072 // assignments occur in SetPrimtiveBlockShapeParams and 7072 // assignments occur in SetPrimtiveBlockShapeParams and
7073 // SetPrimitiveShapeParams in support of llSetPrimitiveParams. 7073 // SetPrimitiveShapeParams in support of llSetPrimitiveParams.
7074 tempFloat = (float)(100.0d * twist.x); 7074 tempFloat = (float)(100.0d * twist.x);
7075 shapeBlock.PathTwistBegin = (sbyte)tempFloat; 7075 shapeBlock.PathTwistBegin = (sbyte)tempFloat;
7076 tempFloat = (float)(100.0d * twist.y); 7076 tempFloat = (float)(100.0d * twist.y);
7077 shapeBlock.PathTwist = (sbyte)tempFloat; 7077 shapeBlock.PathTwist = (sbyte)tempFloat;
7078   7078  
7079 shapeBlock.ObjectLocalID = part.LocalId; 7079 shapeBlock.ObjectLocalID = part.LocalId;
7080   7080  
7081 part.Shape.SculptEntry = false; 7081 part.Shape.SculptEntry = false;
7082 return shapeBlock; 7082 return shapeBlock;
7083 } 7083 }
7084   7084  
7085 // Prim type box, cylinder and prism. 7085 // Prim type box, cylinder and prism.
7086 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7086 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
7087 { 7087 {
7088 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7088 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7089 ObjectShapePacket.ObjectDataBlock shapeBlock; 7089 ObjectShapePacket.ObjectDataBlock shapeBlock;
7090   7090  
7091 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7091 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7092   7092  
7093 if (taper_b.x < 0f) 7093 if (taper_b.x < 0f)
7094 { 7094 {
7095 taper_b.x = 0f; 7095 taper_b.x = 0f;
7096 } 7096 }
7097 if (taper_b.x > 2f) 7097 if (taper_b.x > 2f)
7098 { 7098 {
7099 taper_b.x = 2f; 7099 taper_b.x = 2f;
7100 } 7100 }
7101 if (taper_b.y < 0f) 7101 if (taper_b.y < 0f)
7102 { 7102 {
7103 taper_b.y = 0f; 7103 taper_b.y = 0f;
7104 } 7104 }
7105 if (taper_b.y > 2f) 7105 if (taper_b.y > 2f)
7106 { 7106 {
7107 taper_b.y = 2f; 7107 taper_b.y = 2f;
7108 } 7108 }
7109 tempFloat = (float)(100.0d * (2.0d - taper_b.x)); 7109 tempFloat = (float)(100.0d * (2.0d - taper_b.x));
7110 shapeBlock.PathScaleX = (byte)tempFloat; 7110 shapeBlock.PathScaleX = (byte)tempFloat;
7111 tempFloat = (float)(100.0d * (2.0d - taper_b.y)); 7111 tempFloat = (float)(100.0d * (2.0d - taper_b.y));
7112 shapeBlock.PathScaleY = (byte)tempFloat; 7112 shapeBlock.PathScaleY = (byte)tempFloat;
7113 if (topshear.x < -0.5f) 7113 if (topshear.x < -0.5f)
7114 { 7114 {
7115 topshear.x = -0.5f; 7115 topshear.x = -0.5f;
7116 } 7116 }
7117 if (topshear.x > 0.5f) 7117 if (topshear.x > 0.5f)
7118 { 7118 {
7119 topshear.x = 0.5f; 7119 topshear.x = 0.5f;
7120 } 7120 }
7121 if (topshear.y < -0.5f) 7121 if (topshear.y < -0.5f)
7122 { 7122 {
7123 topshear.y = -0.5f; 7123 topshear.y = -0.5f;
7124 } 7124 }
7125 if (topshear.y > 0.5f) 7125 if (topshear.y > 0.5f)
7126 { 7126 {
7127 topshear.y = 0.5f; 7127 topshear.y = 0.5f;
7128 } 7128 }
7129 tempFloat = (float)(100.0d * topshear.x); 7129 tempFloat = (float)(100.0d * topshear.x);
7130 shapeBlock.PathShearX = (byte)tempFloat; 7130 shapeBlock.PathShearX = (byte)tempFloat;
7131 tempFloat = (float)(100.0d * topshear.y); 7131 tempFloat = (float)(100.0d * topshear.y);
7132 shapeBlock.PathShearY = (byte)tempFloat; 7132 shapeBlock.PathShearY = (byte)tempFloat;
7133   7133  
7134 part.Shape.SculptEntry = false; 7134 part.Shape.SculptEntry = false;
7135 part.UpdateShape(shapeBlock); 7135 part.UpdateShape(shapeBlock);
7136 } 7136 }
7137   7137  
7138 // Prim type sphere. 7138 // Prim type sphere.
7139 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7139 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7140 { 7140 {
7141 ObjectShapePacket.ObjectDataBlock shapeBlock; 7141 ObjectShapePacket.ObjectDataBlock shapeBlock;
7142   7142  
7143 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7143 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7144   7144  
7145 // profile/path swapped for a sphere 7145 // profile/path swapped for a sphere
7146 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7146 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7147 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7147 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7148   7148  
7149 shapeBlock.PathScaleX = 100; 7149 shapeBlock.PathScaleX = 100;
7150 shapeBlock.PathScaleY = 100; 7150 shapeBlock.PathScaleY = 100;
7151   7151  
7152 if (dimple.x < 0f) 7152 if (dimple.x < 0f)
7153 { 7153 {
7154 dimple.x = 0f; 7154 dimple.x = 0f;
7155 } 7155 }
7156 if (dimple.x > 1f) 7156 if (dimple.x > 1f)
7157 { 7157 {
7158 dimple.x = 1f; 7158 dimple.x = 1f;
7159 } 7159 }
7160 if (dimple.y < 0f) 7160 if (dimple.y < 0f)
7161 { 7161 {
7162 dimple.y = 0f; 7162 dimple.y = 0f;
7163 } 7163 }
7164 if (dimple.y > 1f) 7164 if (dimple.y > 1f)
7165 { 7165 {
7166 dimple.y = 1f; 7166 dimple.y = 1f;
7167 } 7167 }
7168 if (dimple.y - cut.x < 0.05f) 7168 if (dimple.y - cut.x < 0.05f)
7169 { 7169 {
7170 dimple.x = cut.y - 0.05f; 7170 dimple.x = cut.y - 0.05f;
7171 } 7171 }
7172 shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x); 7172 shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x);
7173 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y)); 7173 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y));
7174   7174  
7175 part.Shape.SculptEntry = false; 7175 part.Shape.SculptEntry = false;
7176 part.UpdateShape(shapeBlock); 7176 part.UpdateShape(shapeBlock);
7177 } 7177 }
7178   7178  
7179 // Prim type torus, tube and ring. 7179 // Prim type torus, tube and ring.
7180 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7180 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
7181 { 7181 {
7182 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7182 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7183 ObjectShapePacket.ObjectDataBlock shapeBlock; 7183 ObjectShapePacket.ObjectDataBlock shapeBlock;
7184   7184  
7185 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7185 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7186   7186  
7187 // profile/path swapped for a torrus, tube, ring 7187 // profile/path swapped for a torrus, tube, ring
7188 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7188 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7189 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7189 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7190   7190  
7191 if (holesize.x < 0.05f) 7191 if (holesize.x < 0.05f)
7192 { 7192 {
7193 holesize.x = 0.05f; 7193 holesize.x = 0.05f;
7194 } 7194 }
7195 if (holesize.x > 1f) 7195 if (holesize.x > 1f)
7196 { 7196 {
7197 holesize.x = 1f; 7197 holesize.x = 1f;
7198 } 7198 }
7199 if (holesize.y < 0.05f) 7199 if (holesize.y < 0.05f)
7200 { 7200 {
7201 holesize.y = 0.05f; 7201 holesize.y = 0.05f;
7202 } 7202 }
7203 if (holesize.y > 0.5f) 7203 if (holesize.y > 0.5f)
7204 { 7204 {
7205 holesize.y = 0.5f; 7205 holesize.y = 0.5f;
7206 } 7206 }
7207 tempFloat = (float)(100.0d * (2.0d - holesize.x)); 7207 tempFloat = (float)(100.0d * (2.0d - holesize.x));
7208 shapeBlock.PathScaleX = (byte)tempFloat; 7208 shapeBlock.PathScaleX = (byte)tempFloat;
7209 tempFloat = (float)(100.0d * (2.0d - holesize.y)); 7209 tempFloat = (float)(100.0d * (2.0d - holesize.y));
7210 shapeBlock.PathScaleY = (byte)tempFloat; 7210 shapeBlock.PathScaleY = (byte)tempFloat;
7211 if (topshear.x < -0.5f) 7211 if (topshear.x < -0.5f)
7212 { 7212 {
7213 topshear.x = -0.5f; 7213 topshear.x = -0.5f;
7214 } 7214 }
7215 if (topshear.x > 0.5f) 7215 if (topshear.x > 0.5f)
7216 { 7216 {
7217 topshear.x = 0.5f; 7217 topshear.x = 0.5f;
7218 } 7218 }
7219 if (topshear.y < -0.5f) 7219 if (topshear.y < -0.5f)
7220 { 7220 {
7221 topshear.y = -0.5f; 7221 topshear.y = -0.5f;
7222 } 7222 }
7223 if (topshear.y > 0.5f) 7223 if (topshear.y > 0.5f)
7224 { 7224 {
7225 topshear.y = 0.5f; 7225 topshear.y = 0.5f;
7226 } 7226 }
7227 tempFloat = (float)(100.0d * topshear.x); 7227 tempFloat = (float)(100.0d * topshear.x);
7228 shapeBlock.PathShearX = (byte)tempFloat; 7228 shapeBlock.PathShearX = (byte)tempFloat;
7229 tempFloat = (float)(100.0d * topshear.y); 7229 tempFloat = (float)(100.0d * topshear.y);
7230 shapeBlock.PathShearY = (byte)tempFloat; 7230 shapeBlock.PathShearY = (byte)tempFloat;
7231 if (profilecut.x < 0f) 7231 if (profilecut.x < 0f)
7232 { 7232 {
7233 profilecut.x = 0f; 7233 profilecut.x = 0f;
7234 } 7234 }
7235 if (profilecut.x > 1f) 7235 if (profilecut.x > 1f)
7236 { 7236 {
7237 profilecut.x = 1f; 7237 profilecut.x = 1f;
7238 } 7238 }
7239 if (profilecut.y < 0f) 7239 if (profilecut.y < 0f)
7240 { 7240 {
7241 profilecut.y = 0f; 7241 profilecut.y = 0f;
7242 } 7242 }
7243 if (profilecut.y > 1f) 7243 if (profilecut.y > 1f)
7244 { 7244 {
7245 profilecut.y = 1f; 7245 profilecut.y = 1f;
7246 } 7246 }
7247 if (profilecut.y - profilecut.x < 0.05f) 7247 if (profilecut.y - profilecut.x < 0.05f)
7248 { 7248 {
7249 profilecut.x = profilecut.y - 0.05f; 7249 profilecut.x = profilecut.y - 0.05f;
7250 if (profilecut.x < 0.0f) 7250 if (profilecut.x < 0.0f)
7251 { 7251 {
7252 profilecut.x = 0.0f; 7252 profilecut.x = 0.0f;
7253 profilecut.y = 0.05f; 7253 profilecut.y = 0.05f;
7254 } 7254 }
7255 } 7255 }
7256 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); 7256 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x);
7257 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y)); 7257 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y));
7258 if (taper_a.x < -1f) 7258 if (taper_a.x < -1f)
7259 { 7259 {
7260 taper_a.x = -1f; 7260 taper_a.x = -1f;
7261 } 7261 }
7262 if (taper_a.x > 1f) 7262 if (taper_a.x > 1f)
7263 { 7263 {
7264 taper_a.x = 1f; 7264 taper_a.x = 1f;
7265 } 7265 }
7266 if (taper_a.y < -1f) 7266 if (taper_a.y < -1f)
7267 { 7267 {
7268 taper_a.y = -1f; 7268 taper_a.y = -1f;
7269 } 7269 }
7270 if (taper_a.y > 1f) 7270 if (taper_a.y > 1f)
7271 { 7271 {
7272 taper_a.y = 1f; 7272 taper_a.y = 1f;
7273 } 7273 }
7274 tempFloat = (float)(100.0d * taper_a.x); 7274 tempFloat = (float)(100.0d * taper_a.x);
7275 shapeBlock.PathTaperX = (sbyte)tempFloat; 7275 shapeBlock.PathTaperX = (sbyte)tempFloat;
7276 tempFloat = (float)(100.0d * taper_a.y); 7276 tempFloat = (float)(100.0d * taper_a.y);
7277 shapeBlock.PathTaperY = (sbyte)tempFloat; 7277 shapeBlock.PathTaperY = (sbyte)tempFloat;
7278 if (revolutions < 1f) 7278 if (revolutions < 1f)
7279 { 7279 {
7280 revolutions = 1f; 7280 revolutions = 1f;
7281 } 7281 }
7282 if (revolutions > 4f) 7282 if (revolutions > 4f)
7283 { 7283 {
7284 revolutions = 4f; 7284 revolutions = 4f;
7285 } 7285 }
7286 tempFloat = 66.66667f * (revolutions - 1.0f); 7286 tempFloat = 66.66667f * (revolutions - 1.0f);
7287 shapeBlock.PathRevolutions = (byte)tempFloat; 7287 shapeBlock.PathRevolutions = (byte)tempFloat;
7288 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 7288 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
7289 if (radiusoffset < 0f) 7289 if (radiusoffset < 0f)
7290 { 7290 {
7291 radiusoffset = 0f; 7291 radiusoffset = 0f;
7292 } 7292 }
7293 if (radiusoffset > 1f) 7293 if (radiusoffset > 1f)
7294 { 7294 {
7295 radiusoffset = 1f; 7295 radiusoffset = 1f;
7296 } 7296 }
7297 tempFloat = 100.0f * radiusoffset; 7297 tempFloat = 100.0f * radiusoffset;
7298 shapeBlock.PathRadiusOffset = (sbyte)tempFloat; 7298 shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
7299 if (skew < -0.95f) 7299 if (skew < -0.95f)
7300 { 7300 {
7301 skew = -0.95f; 7301 skew = -0.95f;
7302 } 7302 }
7303 if (skew > 0.95f) 7303 if (skew > 0.95f)
7304 { 7304 {
7305 skew = 0.95f; 7305 skew = 0.95f;
7306 } 7306 }
7307 tempFloat = 100.0f * skew; 7307 tempFloat = 100.0f * skew;
7308 shapeBlock.PathSkew = (sbyte)tempFloat; 7308 shapeBlock.PathSkew = (sbyte)tempFloat;
7309   7309  
7310 part.Shape.SculptEntry = false; 7310 part.Shape.SculptEntry = false;
7311 part.UpdateShape(shapeBlock); 7311 part.UpdateShape(shapeBlock);
7312 } 7312 }
7313   7313  
7314 // Prim type sculpt. 7314 // Prim type sculpt.
7315 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7315 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7316 { 7316 {
7317 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7317 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7318 UUID sculptId; 7318 UUID sculptId;
7319   7319  
7320 if (!UUID.TryParse(map, out sculptId)) 7320 if (!UUID.TryParse(map, out sculptId))
7321 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture); 7321 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture);
7322   7322  
7323 if (sculptId == UUID.Zero) 7323 if (sculptId == UUID.Zero)
7324 return; 7324 return;
7325   7325  
7326 shapeBlock.PathCurve = pathcurve; 7326 shapeBlock.PathCurve = pathcurve;
7327 shapeBlock.ObjectLocalID = part.LocalId; 7327 shapeBlock.ObjectLocalID = part.LocalId;
7328 shapeBlock.PathScaleX = 100; 7328 shapeBlock.PathScaleX = 100;
7329 shapeBlock.PathScaleY = 150; 7329 shapeBlock.PathScaleY = 150;
7330   7330  
7331 int flag = type & (ScriptBaseClass.PRIM_SCULPT_FLAG_INVERT | ScriptBaseClass.PRIM_SCULPT_FLAG_MIRROR); 7331 int flag = type & (ScriptBaseClass.PRIM_SCULPT_FLAG_INVERT | ScriptBaseClass.PRIM_SCULPT_FLAG_MIRROR);
7332   7332  
7333 if (type != (ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER | flag) && 7333 if (type != (ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER | flag) &&
7334 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE | flag) && 7334 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE | flag) &&
7335 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE | flag) && 7335 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE | flag) &&
7336 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7336 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7337 { 7337 {
7338 // default 7338 // default
7339 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7339 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7340 } 7340 }
7341   7341  
7342 part.Shape.SetSculptProperties((byte)type, sculptId); 7342 part.Shape.SetSculptProperties((byte)type, sculptId);
7343 part.Shape.SculptEntry = true; 7343 part.Shape.SculptEntry = true;
7344 part.UpdateShape(shapeBlock); 7344 part.UpdateShape(shapeBlock);
7345 } 7345 }
7346   7346  
7347 public void llSetPrimitiveParams(LSL_List rules) 7347 public void llSetPrimitiveParams(LSL_List rules)
7348 { 7348 {
7349 m_host.AddScriptLPS(1); 7349 m_host.AddScriptLPS(1);
7350   7350  
7351 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); 7351 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7352   7352  
7353 ScriptSleep(200); 7353 ScriptSleep(200);
7354 } 7354 }
7355   7355  
7356 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7356 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7357 { 7357 {
7358 m_host.AddScriptLPS(1); 7358 m_host.AddScriptLPS(1);
7359   7359  
7360 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7360 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7361   7361  
7362 ScriptSleep(200); 7362 ScriptSleep(200);
7363 } 7363 }
7364   7364  
7365 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7365 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7366 { 7366 {
7367 m_host.AddScriptLPS(1); 7367 m_host.AddScriptLPS(1);
7368   7368  
7369 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7369 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7370 } 7370 }
7371   7371  
7372 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7372 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7373 { 7373 {
7374 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7374 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7375   7375  
7376 LSL_List remaining = null; 7376 LSL_List remaining = null;
7377 uint rulesParsed = 0; 7377 uint rulesParsed = 0;
7378   7378  
7379 foreach (SceneObjectPart part in parts) 7379 foreach (SceneObjectPart part in parts)
7380 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7380 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7381   7381  
7382 while (remaining != null && remaining.Length > 2) 7382 while (remaining != null && remaining.Length > 2)
7383 { 7383 {
7384 linknumber = remaining.GetLSLIntegerItem(0); 7384 linknumber = remaining.GetLSLIntegerItem(0);
7385 rules = remaining.GetSublist(1, -1); 7385 rules = remaining.GetSublist(1, -1);
7386 parts = GetLinkParts(linknumber); 7386 parts = GetLinkParts(linknumber);
7387   7387  
7388 foreach (SceneObjectPart part in parts) 7388 foreach (SceneObjectPart part in parts)
7389 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7389 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7390 } 7390 }
7391 } 7391 }
7392   7392  
7393 public void llSetKeyframedMotion(LSL_List frames, LSL_List options) 7393 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7394 { 7394 {
7395 SceneObjectGroup group = m_host.ParentGroup; 7395 SceneObjectGroup group = m_host.ParentGroup;
7396   7396  
7397 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) 7397 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7398 return; 7398 return;
7399 if (group.IsAttachment) 7399 if (group.IsAttachment)
7400 return; 7400 return;
7401   7401  
7402 if (frames.Data.Length > 0) // We are getting a new motion 7402 if (frames.Data.Length > 0) // We are getting a new motion
7403 { 7403 {
7404 if (group.RootPart.KeyframeMotion != null) 7404 if (group.RootPart.KeyframeMotion != null)
7405 group.RootPart.KeyframeMotion.Delete(); 7405 group.RootPart.KeyframeMotion.Delete();
7406 group.RootPart.KeyframeMotion = null; 7406 group.RootPart.KeyframeMotion = null;
7407   7407  
7408 int idx = 0; 7408 int idx = 0;
7409   7409  
7410 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward; 7410 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7411 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation; 7411 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7412   7412  
7413 while (idx < options.Data.Length) 7413 while (idx < options.Data.Length)
7414 { 7414 {
7415 int option = (int)options.GetLSLIntegerItem(idx++); 7415 int option = (int)options.GetLSLIntegerItem(idx++);
7416 int remain = options.Data.Length - idx; 7416 int remain = options.Data.Length - idx;
7417   7417  
7418 switch (option) 7418 switch (option)
7419 { 7419 {
7420 case ScriptBaseClass.KFM_MODE: 7420 case ScriptBaseClass.KFM_MODE:
7421 if (remain < 1) 7421 if (remain < 1)
7422 break; 7422 break;
7423 int modeval = (int)options.GetLSLIntegerItem(idx++); 7423 int modeval = (int)options.GetLSLIntegerItem(idx++);
7424 switch(modeval) 7424 switch(modeval)
7425 { 7425 {
7426 case ScriptBaseClass.KFM_FORWARD: 7426 case ScriptBaseClass.KFM_FORWARD:
7427 mode = KeyframeMotion.PlayMode.Forward; 7427 mode = KeyframeMotion.PlayMode.Forward;
7428 break; 7428 break;
7429 case ScriptBaseClass.KFM_REVERSE: 7429 case ScriptBaseClass.KFM_REVERSE:
7430 mode = KeyframeMotion.PlayMode.Reverse; 7430 mode = KeyframeMotion.PlayMode.Reverse;
7431 break; 7431 break;
7432 case ScriptBaseClass.KFM_LOOP: 7432 case ScriptBaseClass.KFM_LOOP:
7433 mode = KeyframeMotion.PlayMode.Loop; 7433 mode = KeyframeMotion.PlayMode.Loop;
7434 break; 7434 break;
7435 case ScriptBaseClass.KFM_PING_PONG: 7435 case ScriptBaseClass.KFM_PING_PONG:
7436 mode = KeyframeMotion.PlayMode.PingPong; 7436 mode = KeyframeMotion.PlayMode.PingPong;
7437 break; 7437 break;
7438 } 7438 }
7439 break; 7439 break;
7440 case ScriptBaseClass.KFM_DATA: 7440 case ScriptBaseClass.KFM_DATA:
7441 if (remain < 1) 7441 if (remain < 1)
7442 break; 7442 break;
7443 int dataval = (int)options.GetLSLIntegerItem(idx++); 7443 int dataval = (int)options.GetLSLIntegerItem(idx++);
7444 data = (KeyframeMotion.DataFormat)dataval; 7444 data = (KeyframeMotion.DataFormat)dataval;
7445 break; 7445 break;
7446 } 7446 }
7447 } 7447 }
7448   7448  
7449 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7449 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
7450   7450  
7451 idx = 0; 7451 idx = 0;
7452   7452  
7453 int elemLength = 2; 7453 int elemLength = 2;
7454 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7454 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
7455 elemLength = 3; 7455 elemLength = 3;
7456   7456  
7457 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7457 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
7458 while (idx < frames.Data.Length) 7458 while (idx < frames.Data.Length)
7459 { 7459 {
7460 int remain = frames.Data.Length - idx; 7460 int remain = frames.Data.Length - idx;
7461   7461  
7462 if (remain < elemLength) 7462 if (remain < elemLength)
7463 break; 7463 break;
7464   7464  
7465 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7465 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
7466 frame.Position = null; 7466 frame.Position = null;
7467 frame.Rotation = null; 7467 frame.Rotation = null;
7468   7468  
7469 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7469 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
7470 { 7470 {
7471 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7471 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
7472 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7472 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
7473 } 7473 }
7474 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7474 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
7475 { 7475 {
7476 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++); 7476 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7477 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s); 7477 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7478 q.Normalize(); 7478 q.Normalize();
7479 frame.Rotation = q; 7479 frame.Rotation = q;
7480 } 7480 }
7481   7481  
7482 float tempf = (float)frames.GetLSLFloatItem(idx++); 7482 float tempf = (float)frames.GetLSLFloatItem(idx++);
7483 frame.TimeMS = (int)(tempf * 1000.0f); 7483 frame.TimeMS = (int)(tempf * 1000.0f);
7484   7484  
7485 keyframes.Add(frame); 7485 keyframes.Add(frame);
7486 } 7486 }
7487   7487  
7488 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7488 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
7489 group.RootPart.KeyframeMotion.Start(); 7489 group.RootPart.KeyframeMotion.Start();
7490 } 7490 }
7491 else 7491 else
7492 { 7492 {
7493 if (group.RootPart.KeyframeMotion == null) 7493 if (group.RootPart.KeyframeMotion == null)
7494 return; 7494 return;
7495   7495  
7496 if (options.Data.Length == 0) 7496 if (options.Data.Length == 0)
7497 { 7497 {
7498 group.RootPart.KeyframeMotion.Stop(); 7498 group.RootPart.KeyframeMotion.Stop();
7499 return; 7499 return;
7500 } 7500 }
7501   7501  
7502 int idx = 0; 7502 int idx = 0;
7503   7503  
7504 while (idx < options.Data.Length) 7504 while (idx < options.Data.Length)
7505 { 7505 {
7506 int option = (int)options.GetLSLIntegerItem(idx++); 7506 int option = (int)options.GetLSLIntegerItem(idx++);
7507   7507  
7508 switch (option) 7508 switch (option)
7509 { 7509 {
7510 case ScriptBaseClass.KFM_COMMAND: 7510 case ScriptBaseClass.KFM_COMMAND:
7511 int cmd = (int)options.GetLSLIntegerItem(idx++); 7511 int cmd = (int)options.GetLSLIntegerItem(idx++);
7512 switch (cmd) 7512 switch (cmd)
7513 { 7513 {
7514 case ScriptBaseClass.KFM_CMD_PLAY: 7514 case ScriptBaseClass.KFM_CMD_PLAY:
7515 group.RootPart.KeyframeMotion.Start(); 7515 group.RootPart.KeyframeMotion.Start();
7516 break; 7516 break;
7517 case ScriptBaseClass.KFM_CMD_STOP: 7517 case ScriptBaseClass.KFM_CMD_STOP:
7518 group.RootPart.KeyframeMotion.Stop(); 7518 group.RootPart.KeyframeMotion.Stop();
7519 break; 7519 break;
7520 case ScriptBaseClass.KFM_CMD_PAUSE: 7520 case ScriptBaseClass.KFM_CMD_PAUSE:
7521 group.RootPart.KeyframeMotion.Pause(); 7521 group.RootPart.KeyframeMotion.Pause();
7522 break; 7522 break;
7523 } 7523 }
7524 break; 7524 break;
7525 } 7525 }
7526 } 7526 }
7527 } 7527 }
7528 } 7528 }
7529   7529  
7530 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7530 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7531 { 7531 {
7532 int idx = 0; 7532 int idx = 0;
7533 int idxStart = 0; 7533 int idxStart = 0;
7534   7534  
7535 bool positionChanged = false; 7535 bool positionChanged = false;
7536 LSL_Vector currentPosition = GetPartLocalPos(part); 7536 LSL_Vector currentPosition = GetPartLocalPos(part);
7537   7537  
7538 try 7538 try
7539 { 7539 {
7540 while (idx < rules.Length) 7540 while (idx < rules.Length)
7541 { 7541 {
7542 ++rulesParsed; 7542 ++rulesParsed;
7543 int code = rules.GetLSLIntegerItem(idx++); 7543 int code = rules.GetLSLIntegerItem(idx++);
7544   7544  
7545 int remain = rules.Length - idx; 7545 int remain = rules.Length - idx;
7546 idxStart = idx; 7546 idxStart = idx;
7547   7547  
7548 int face; 7548 int face;
7549 LSL_Vector v; 7549 LSL_Vector v;
7550   7550  
7551 switch (code) 7551 switch (code)
7552 { 7552 {
7553 case (int)ScriptBaseClass.PRIM_POSITION: 7553 case (int)ScriptBaseClass.PRIM_POSITION:
7554 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 7554 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7555 if (remain < 1) 7555 if (remain < 1)
7556 return null; 7556 return null;
7557   7557  
7558 v=rules.GetVector3Item(idx++); 7558 v=rules.GetVector3Item(idx++);
7559 positionChanged = true; 7559 positionChanged = true;
7560 currentPosition = GetSetPosTarget(part, v, currentPosition); 7560 currentPosition = GetSetPosTarget(part, v, currentPosition);
7561   7561  
7562 break; 7562 break;
7563 case (int)ScriptBaseClass.PRIM_SIZE: 7563 case (int)ScriptBaseClass.PRIM_SIZE:
7564 if (remain < 1) 7564 if (remain < 1)
7565 return null; 7565 return null;
7566   7566  
7567 v=rules.GetVector3Item(idx++); 7567 v=rules.GetVector3Item(idx++);
7568 SetScale(part, v); 7568 SetScale(part, v);
7569   7569  
7570 break; 7570 break;
7571 case (int)ScriptBaseClass.PRIM_ROTATION: 7571 case (int)ScriptBaseClass.PRIM_ROTATION:
7572 if (remain < 1) 7572 if (remain < 1)
7573 return null; 7573 return null;
7574   7574  
7575 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7575 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7576 // try to let this work as in SL... 7576 // try to let this work as in SL...
7577 if (part.ParentID == 0) 7577 if (part.ParentID == 0)
7578 { 7578 {
7579 // special case: If we are root, rotate complete SOG to new rotation 7579 // special case: If we are root, rotate complete SOG to new rotation
7580 SetRot(part, q); 7580 SetRot(part, q);
7581 } 7581 }
7582 else 7582 else
7583 { 7583 {
7584 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7584 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7585 SceneObjectPart rootPart = part.ParentGroup.RootPart; 7585 SceneObjectPart rootPart = part.ParentGroup.RootPart;
7586 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 7586 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7587 } 7587 }
7588   7588  
7589 break; 7589 break;
7590   7590  
7591 case (int)ScriptBaseClass.PRIM_TYPE: 7591 case (int)ScriptBaseClass.PRIM_TYPE:
7592 if (remain < 3) 7592 if (remain < 3)
7593 return null; 7593 return null;
7594   7594  
7595 code = (int)rules.GetLSLIntegerItem(idx++); 7595 code = (int)rules.GetLSLIntegerItem(idx++);
7596   7596  
7597 remain = rules.Length - idx; 7597 remain = rules.Length - idx;
7598 float hollow; 7598 float hollow;
7599 LSL_Vector twist; 7599 LSL_Vector twist;
7600 LSL_Vector taper_b; 7600 LSL_Vector taper_b;
7601 LSL_Vector topshear; 7601 LSL_Vector topshear;
7602 float revolutions; 7602 float revolutions;
7603 float radiusoffset; 7603 float radiusoffset;
7604 float skew; 7604 float skew;
7605 LSL_Vector holesize; 7605 LSL_Vector holesize;
7606 LSL_Vector profilecut; 7606 LSL_Vector profilecut;
7607   7607  
7608 switch (code) 7608 switch (code)
7609 { 7609 {
7610 case (int)ScriptBaseClass.PRIM_TYPE_BOX: 7610 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7611 if (remain < 6) 7611 if (remain < 6)
7612 return null; 7612 return null;
7613   7613  
7614 face = (int)rules.GetLSLIntegerItem(idx++); 7614 face = (int)rules.GetLSLIntegerItem(idx++);
7615 v = rules.GetVector3Item(idx++); // cut 7615 v = rules.GetVector3Item(idx++); // cut
7616 hollow = (float)rules.GetLSLFloatItem(idx++); 7616 hollow = (float)rules.GetLSLFloatItem(idx++);
7617 twist = rules.GetVector3Item(idx++); 7617 twist = rules.GetVector3Item(idx++);
7618 taper_b = rules.GetVector3Item(idx++); 7618 taper_b = rules.GetVector3Item(idx++);
7619 topshear = rules.GetVector3Item(idx++); 7619 topshear = rules.GetVector3Item(idx++);
7620   7620  
7621 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7621 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7622 (byte)ProfileShape.Square, (byte)Extrusion.Straight); 7622 (byte)ProfileShape.Square, (byte)Extrusion.Straight);
7623 break; 7623 break;
7624   7624  
7625 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: 7625 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7626 if (remain < 6) 7626 if (remain < 6)
7627 return null; 7627 return null;
7628   7628  
7629 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7629 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7630 v = rules.GetVector3Item(idx++); // cut 7630 v = rules.GetVector3Item(idx++); // cut
7631 hollow = (float)rules.GetLSLFloatItem(idx++); 7631 hollow = (float)rules.GetLSLFloatItem(idx++);
7632 twist = rules.GetVector3Item(idx++); 7632 twist = rules.GetVector3Item(idx++);
7633 taper_b = rules.GetVector3Item(idx++); 7633 taper_b = rules.GetVector3Item(idx++);
7634 topshear = rules.GetVector3Item(idx++); 7634 topshear = rules.GetVector3Item(idx++);
7635 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7635 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7636 (byte)ProfileShape.Circle, (byte)Extrusion.Straight); 7636 (byte)ProfileShape.Circle, (byte)Extrusion.Straight);
7637 break; 7637 break;
7638   7638  
7639 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: 7639 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7640 if (remain < 6) 7640 if (remain < 6)
7641 return null; 7641 return null;
7642   7642  
7643 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7643 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7644 v = rules.GetVector3Item(idx++); //cut 7644 v = rules.GetVector3Item(idx++); //cut
7645 hollow = (float)rules.GetLSLFloatItem(idx++); 7645 hollow = (float)rules.GetLSLFloatItem(idx++);
7646 twist = rules.GetVector3Item(idx++); 7646 twist = rules.GetVector3Item(idx++);
7647 taper_b = rules.GetVector3Item(idx++); 7647 taper_b = rules.GetVector3Item(idx++);
7648 topshear = rules.GetVector3Item(idx++); 7648 topshear = rules.GetVector3Item(idx++);
7649 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7649 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7650 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight); 7650 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight);
7651 break; 7651 break;
7652   7652  
7653 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: 7653 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7654 if (remain < 5) 7654 if (remain < 5)
7655 return null; 7655 return null;
7656   7656  
7657 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7657 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7658 v = rules.GetVector3Item(idx++); // cut 7658 v = rules.GetVector3Item(idx++); // cut
7659 hollow = (float)rules.GetLSLFloatItem(idx++); 7659 hollow = (float)rules.GetLSLFloatItem(idx++);
7660 twist = rules.GetVector3Item(idx++); 7660 twist = rules.GetVector3Item(idx++);
7661 taper_b = rules.GetVector3Item(idx++); // dimple 7661 taper_b = rules.GetVector3Item(idx++); // dimple
7662 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 7662 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b,
7663 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1); 7663 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1);
7664 break; 7664 break;
7665   7665  
7666 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: 7666 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7667 if (remain < 11) 7667 if (remain < 11)
7668 return null; 7668 return null;
7669   7669  
7670 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7670 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7671 v = rules.GetVector3Item(idx++); //cut 7671 v = rules.GetVector3Item(idx++); //cut
7672 hollow = (float)rules.GetLSLFloatItem(idx++); 7672 hollow = (float)rules.GetLSLFloatItem(idx++);
7673 twist = rules.GetVector3Item(idx++); 7673 twist = rules.GetVector3Item(idx++);
7674 holesize = rules.GetVector3Item(idx++); 7674 holesize = rules.GetVector3Item(idx++);
7675 topshear = rules.GetVector3Item(idx++); 7675 topshear = rules.GetVector3Item(idx++);
7676 profilecut = rules.GetVector3Item(idx++); 7676 profilecut = rules.GetVector3Item(idx++);
7677 taper_b = rules.GetVector3Item(idx++); // taper_a 7677 taper_b = rules.GetVector3Item(idx++); // taper_a
7678 revolutions = (float)rules.GetLSLFloatItem(idx++); 7678 revolutions = (float)rules.GetLSLFloatItem(idx++);
7679 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7679 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7680 skew = (float)rules.GetLSLFloatItem(idx++); 7680 skew = (float)rules.GetLSLFloatItem(idx++);
7681 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7681 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7682 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1); 7682 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1);
7683 break; 7683 break;
7684   7684  
7685 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: 7685 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7686 if (remain < 11) 7686 if (remain < 11)
7687 return null; 7687 return null;
7688   7688  
7689 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7689 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7690 v = rules.GetVector3Item(idx++); //cut 7690 v = rules.GetVector3Item(idx++); //cut
7691 hollow = (float)rules.GetLSLFloatItem(idx++); 7691 hollow = (float)rules.GetLSLFloatItem(idx++);
7692 twist = rules.GetVector3Item(idx++); 7692 twist = rules.GetVector3Item(idx++);
7693 holesize = rules.GetVector3Item(idx++); 7693 holesize = rules.GetVector3Item(idx++);
7694 topshear = rules.GetVector3Item(idx++); 7694 topshear = rules.GetVector3Item(idx++);
7695 profilecut = rules.GetVector3Item(idx++); 7695 profilecut = rules.GetVector3Item(idx++);
7696 taper_b = rules.GetVector3Item(idx++); // taper_a 7696 taper_b = rules.GetVector3Item(idx++); // taper_a
7697 revolutions = (float)rules.GetLSLFloatItem(idx++); 7697 revolutions = (float)rules.GetLSLFloatItem(idx++);
7698 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7698 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7699 skew = (float)rules.GetLSLFloatItem(idx++); 7699 skew = (float)rules.GetLSLFloatItem(idx++);
7700 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7700 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7701 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1); 7701 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1);
7702 break; 7702 break;
7703   7703  
7704 case (int)ScriptBaseClass.PRIM_TYPE_RING: 7704 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7705 if (remain < 11) 7705 if (remain < 11)
7706 return null; 7706 return null;
7707   7707  
7708 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7708 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7709 v = rules.GetVector3Item(idx++); //cut 7709 v = rules.GetVector3Item(idx++); //cut
7710 hollow = (float)rules.GetLSLFloatItem(idx++); 7710 hollow = (float)rules.GetLSLFloatItem(idx++);
7711 twist = rules.GetVector3Item(idx++); 7711 twist = rules.GetVector3Item(idx++);
7712 holesize = rules.GetVector3Item(idx++); 7712 holesize = rules.GetVector3Item(idx++);
7713 topshear = rules.GetVector3Item(idx++); 7713 topshear = rules.GetVector3Item(idx++);
7714 profilecut = rules.GetVector3Item(idx++); 7714 profilecut = rules.GetVector3Item(idx++);
7715 taper_b = rules.GetVector3Item(idx++); // taper_a 7715 taper_b = rules.GetVector3Item(idx++); // taper_a
7716 revolutions = (float)rules.GetLSLFloatItem(idx++); 7716 revolutions = (float)rules.GetLSLFloatItem(idx++);
7717 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7717 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7718 skew = (float)rules.GetLSLFloatItem(idx++); 7718 skew = (float)rules.GetLSLFloatItem(idx++);
7719 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7719 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7720 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1); 7720 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1);
7721 break; 7721 break;
7722   7722  
7723 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: 7723 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7724 if (remain < 2) 7724 if (remain < 2)
7725 return null; 7725 return null;
7726   7726  
7727 string map = rules.Data[idx++].ToString(); 7727 string map = rules.Data[idx++].ToString();
7728 face = (int)rules.GetLSLIntegerItem(idx++); // type 7728 face = (int)rules.GetLSLIntegerItem(idx++); // type
7729 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1); 7729 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1);
7730 break; 7730 break;
7731 } 7731 }
7732   7732  
7733 break; 7733 break;
7734   7734  
7735 case (int)ScriptBaseClass.PRIM_TEXTURE: 7735 case (int)ScriptBaseClass.PRIM_TEXTURE:
7736 if (remain < 5) 7736 if (remain < 5)
7737 return null; 7737 return null;
7738   7738  
7739 face=(int)rules.GetLSLIntegerItem(idx++); 7739 face=(int)rules.GetLSLIntegerItem(idx++);
7740 string tex=rules.Data[idx++].ToString(); 7740 string tex=rules.Data[idx++].ToString();
7741 LSL_Vector repeats=rules.GetVector3Item(idx++); 7741 LSL_Vector repeats=rules.GetVector3Item(idx++);
7742 LSL_Vector offsets=rules.GetVector3Item(idx++); 7742 LSL_Vector offsets=rules.GetVector3Item(idx++);
7743 double rotation=(double)rules.GetLSLFloatItem(idx++); 7743 double rotation=(double)rules.GetLSLFloatItem(idx++);
7744   7744  
7745 SetTexture(part, tex, face); 7745 SetTexture(part, tex, face);
7746 ScaleTexture(part, repeats.x, repeats.y, face); 7746 ScaleTexture(part, repeats.x, repeats.y, face);
7747 OffsetTexture(part, offsets.x, offsets.y, face); 7747 OffsetTexture(part, offsets.x, offsets.y, face);
7748 RotateTexture(part, rotation, face); 7748 RotateTexture(part, rotation, face);
7749   7749  
7750 break; 7750 break;
7751   7751  
7752 case (int)ScriptBaseClass.PRIM_COLOR: 7752 case (int)ScriptBaseClass.PRIM_COLOR:
7753 if (remain < 3) 7753 if (remain < 3)
7754 return null; 7754 return null;
7755   7755  
7756 face=(int)rules.GetLSLIntegerItem(idx++); 7756 face=(int)rules.GetLSLIntegerItem(idx++);
7757 LSL_Vector color=rules.GetVector3Item(idx++); 7757 LSL_Vector color=rules.GetVector3Item(idx++);
7758 double alpha=(double)rules.GetLSLFloatItem(idx++); 7758 double alpha=(double)rules.GetLSLFloatItem(idx++);
7759   7759  
7760 part.SetFaceColorAlpha(face, color, alpha); 7760 part.SetFaceColorAlpha(face, color, alpha);
7761   7761  
7762 break; 7762 break;
7763   7763  
7764 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 7764 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7765 if (remain < 7) 7765 if (remain < 7)
7766 return null; 7766 return null;
7767   7767  
7768 bool flexi = rules.GetLSLIntegerItem(idx++); 7768 bool flexi = rules.GetLSLIntegerItem(idx++);
7769 int softness = rules.GetLSLIntegerItem(idx++); 7769 int softness = rules.GetLSLIntegerItem(idx++);
7770 float gravity = (float)rules.GetLSLFloatItem(idx++); 7770 float gravity = (float)rules.GetLSLFloatItem(idx++);
7771 float friction = (float)rules.GetLSLFloatItem(idx++); 7771 float friction = (float)rules.GetLSLFloatItem(idx++);
7772 float wind = (float)rules.GetLSLFloatItem(idx++); 7772 float wind = (float)rules.GetLSLFloatItem(idx++);
7773 float tension = (float)rules.GetLSLFloatItem(idx++); 7773 float tension = (float)rules.GetLSLFloatItem(idx++);
7774 LSL_Vector force = rules.GetVector3Item(idx++); 7774 LSL_Vector force = rules.GetVector3Item(idx++);
7775   7775  
7776 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force); 7776 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
7777   7777  
7778 break; 7778 break;
7779   7779  
7780 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 7780 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7781 if (remain < 5) 7781 if (remain < 5)
7782 return null; 7782 return null;
7783 bool light = rules.GetLSLIntegerItem(idx++); 7783 bool light = rules.GetLSLIntegerItem(idx++);
7784 LSL_Vector lightcolor = rules.GetVector3Item(idx++); 7784 LSL_Vector lightcolor = rules.GetVector3Item(idx++);
7785 float intensity = (float)rules.GetLSLFloatItem(idx++); 7785 float intensity = (float)rules.GetLSLFloatItem(idx++);
7786 float radius = (float)rules.GetLSLFloatItem(idx++); 7786 float radius = (float)rules.GetLSLFloatItem(idx++);
7787 float falloff = (float)rules.GetLSLFloatItem(idx++); 7787 float falloff = (float)rules.GetLSLFloatItem(idx++);
7788   7788  
7789 SetPointLight(part, light, lightcolor, intensity, radius, falloff); 7789 SetPointLight(part, light, lightcolor, intensity, radius, falloff);
7790   7790  
7791 break; 7791 break;
7792   7792  
7793 case (int)ScriptBaseClass.PRIM_GLOW: 7793 case (int)ScriptBaseClass.PRIM_GLOW:
7794 if (remain < 2) 7794 if (remain < 2)
7795 return null; 7795 return null;
7796 face = rules.GetLSLIntegerItem(idx++); 7796 face = rules.GetLSLIntegerItem(idx++);
7797 float glow = (float)rules.GetLSLFloatItem(idx++); 7797 float glow = (float)rules.GetLSLFloatItem(idx++);
7798   7798  
7799 SetGlow(part, face, glow); 7799 SetGlow(part, face, glow);
7800   7800  
7801 break; 7801 break;
7802   7802  
7803 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 7803 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7804 if (remain < 3) 7804 if (remain < 3)
7805 return null; 7805 return null;
7806 face = (int)rules.GetLSLIntegerItem(idx++); 7806 face = (int)rules.GetLSLIntegerItem(idx++);
7807 int shiny = (int)rules.GetLSLIntegerItem(idx++); 7807 int shiny = (int)rules.GetLSLIntegerItem(idx++);
7808 Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++); 7808 Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
7809   7809  
7810 SetShiny(part, face, shiny, bump); 7810 SetShiny(part, face, shiny, bump);
7811   7811  
7812 break; 7812 break;
7813   7813  
7814 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 7814 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7815 if (remain < 2) 7815 if (remain < 2)
7816 return null; 7816 return null;
7817 face = rules.GetLSLIntegerItem(idx++); 7817 face = rules.GetLSLIntegerItem(idx++);
7818 bool st = rules.GetLSLIntegerItem(idx++); 7818 bool st = rules.GetLSLIntegerItem(idx++);
7819 SetFullBright(part, face , st); 7819 SetFullBright(part, face , st);
7820 break; 7820 break;
7821   7821  
7822 case (int)ScriptBaseClass.PRIM_MATERIAL: 7822 case (int)ScriptBaseClass.PRIM_MATERIAL:
7823 if (remain < 1) 7823 if (remain < 1)
7824 return null; 7824 return null;
7825 int mat = rules.GetLSLIntegerItem(idx++); 7825 int mat = rules.GetLSLIntegerItem(idx++);
7826 if (mat < 0 || mat > 7) 7826 if (mat < 0 || mat > 7)
7827 return null; 7827 return null;
7828   7828  
7829 part.Material = Convert.ToByte(mat); 7829 part.Material = Convert.ToByte(mat);
7830 break; 7830 break;
7831   7831  
7832 case (int)ScriptBaseClass.PRIM_PHANTOM: 7832 case (int)ScriptBaseClass.PRIM_PHANTOM:
7833 if (remain < 1) 7833 if (remain < 1)
7834 return null; 7834 return null;
7835   7835  
7836 string ph = rules.Data[idx++].ToString(); 7836 string ph = rules.Data[idx++].ToString();
7837 part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 7837 part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
7838   7838  
7839 break; 7839 break;
7840   7840  
7841 case (int)ScriptBaseClass.PRIM_PHYSICS: 7841 case (int)ScriptBaseClass.PRIM_PHYSICS:
7842 if (remain < 1) 7842 if (remain < 1)
7843 return null; 7843 return null;
7844 string phy = rules.Data[idx++].ToString(); 7844 string phy = rules.Data[idx++].ToString();
7845 bool physics; 7845 bool physics;
7846   7846  
7847 if (phy.Equals("1")) 7847 if (phy.Equals("1"))
7848 physics = true; 7848 physics = true;
7849 else 7849 else
7850 physics = false; 7850 physics = false;
7851   7851  
7852 part.ScriptSetPhysicsStatus(physics); 7852 part.ScriptSetPhysicsStatus(physics);
7853 break; 7853 break;
7854   7854  
7855 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: 7855 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7856 if (remain < 1) 7856 if (remain < 1)
7857 return null; 7857 return null;
7858   7858  
7859 int shape_type = rules.GetLSLIntegerItem(idx++); 7859 int shape_type = rules.GetLSLIntegerItem(idx++);
7860   7860  
7861 ExtraPhysicsData physdata = new ExtraPhysicsData(); 7861 ExtraPhysicsData physdata = new ExtraPhysicsData();
7862 physdata.Density = part.Density; 7862 physdata.Density = part.Density;
7863 physdata.Bounce = part.Restitution; 7863 physdata.Bounce = part.Restitution;
7864 physdata.GravitationModifier = part.GravityModifier; 7864 physdata.GravitationModifier = part.GravityModifier;
7865 physdata.PhysShapeType = (PhysShapeType)shape_type; 7865 physdata.PhysShapeType = (PhysShapeType)shape_type;
7866   7866  
7867 part.UpdateExtraPhysics(physdata); 7867 part.UpdateExtraPhysics(physdata);
7868   7868  
7869 break; 7869 break;
7870   7870  
7871 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 7871 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7872 if (remain < 1) 7872 if (remain < 1)
7873 return null; 7873 return null;
7874 string temp = rules.Data[idx++].ToString(); 7874 string temp = rules.Data[idx++].ToString();
7875   7875  
7876 part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 7876 part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
7877   7877  
7878 break; 7878 break;
7879   7879  
7880 case (int)ScriptBaseClass.PRIM_TEXGEN: 7880 case (int)ScriptBaseClass.PRIM_TEXGEN:
7881 if (remain < 2) 7881 if (remain < 2)
7882 return null; 7882 return null;
7883 //face,type 7883 //face,type
7884 face = rules.GetLSLIntegerItem(idx++); 7884 face = rules.GetLSLIntegerItem(idx++);
7885 int style = rules.GetLSLIntegerItem(idx++); 7885 int style = rules.GetLSLIntegerItem(idx++);
7886 SetTexGen(part, face, style); 7886 SetTexGen(part, face, style);
7887 break; 7887 break;
7888 case (int)ScriptBaseClass.PRIM_TEXT: 7888 case (int)ScriptBaseClass.PRIM_TEXT:
7889 if (remain < 3) 7889 if (remain < 3)
7890 return null; 7890 return null;
7891 string primText = rules.GetLSLStringItem(idx++); 7891 string primText = rules.GetLSLStringItem(idx++);
7892 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 7892 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
7893 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 7893 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
7894 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f); 7894 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
7895 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 7895 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
7896   7896  
7897 break; 7897 break;
7898 case (int)ScriptBaseClass.PRIM_NAME: 7898 case (int)ScriptBaseClass.PRIM_NAME:
7899 if (remain < 1) 7899 if (remain < 1)
7900 return null; 7900 return null;
7901 string primName = rules.GetLSLStringItem(idx++); 7901 string primName = rules.GetLSLStringItem(idx++);
7902 part.Name = primName; 7902 part.Name = primName;
7903 break; 7903 break;
7904 case (int)ScriptBaseClass.PRIM_DESC: 7904 case (int)ScriptBaseClass.PRIM_DESC:
7905 if (remain < 1) 7905 if (remain < 1)
7906 return null; 7906 return null;
7907 string primDesc = rules.GetLSLStringItem(idx++); 7907 string primDesc = rules.GetLSLStringItem(idx++);
7908 part.Description = primDesc; 7908 part.Description = primDesc;
7909 break; 7909 break;
7910 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 7910 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7911 if (remain < 1) 7911 if (remain < 1)
7912 return null; 7912 return null;
7913 SetRot(part, rules.GetQuaternionItem(idx++)); 7913 SetRot(part, rules.GetQuaternionItem(idx++));
7914 break; 7914 break;
7915 case (int)ScriptBaseClass.PRIM_OMEGA: 7915 case (int)ScriptBaseClass.PRIM_OMEGA:
7916 if (remain < 3) 7916 if (remain < 3)
7917 return null; 7917 return null;
7918 LSL_Vector axis = rules.GetVector3Item(idx++); 7918 LSL_Vector axis = rules.GetVector3Item(idx++);
7919 LSL_Float spinrate = rules.GetLSLFloatItem(idx++); 7919 LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
7920 LSL_Float gain = rules.GetLSLFloatItem(idx++); 7920 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7921 TargetOmega(part, axis, (double)spinrate, (double)gain); 7921 TargetOmega(part, axis, (double)spinrate, (double)gain);
7922 break; 7922 break;
7923 case (int)ScriptBaseClass.PRIM_SLICE: 7923 case (int)ScriptBaseClass.PRIM_SLICE:
7924 if (remain < 1) 7924 if (remain < 1)
7925 return null; 7925 return null;
7926 LSL_Vector slice = rules.GetVector3Item(idx++); 7926 LSL_Vector slice = rules.GetVector3Item(idx++);
7927 part.UpdateSlice((float)slice.x, (float)slice.y); 7927 part.UpdateSlice((float)slice.x, (float)slice.y);
7928 break; 7928 break;
7929 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 7929 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7930 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 7930 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7931 return null; 7931 return null;
7932   7932  
7933 return rules.GetSublist(idx, -1); 7933 return rules.GetSublist(idx, -1);
7934 } 7934 }
7935 } 7935 }
7936 } 7936 }
7937 catch (InvalidCastException e) 7937 catch (InvalidCastException e)
7938 { 7938 {
7939 Error(originFunc, string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message); 7939 Error(originFunc, string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message);
7940 } 7940 }
7941 finally 7941 finally
7942 { 7942 {
7943 if (positionChanged) 7943 if (positionChanged)
7944 { 7944 {
7945 if (part.ParentGroup.RootPart == part) 7945 if (part.ParentGroup.RootPart == part)
7946 { 7946 {
7947 SceneObjectGroup parent = part.ParentGroup; 7947 SceneObjectGroup parent = part.ParentGroup;
7948 parent.UpdateGroupPosition(currentPosition); 7948 parent.UpdateGroupPosition(currentPosition);
7949 } 7949 }
7950 else 7950 else
7951 { 7951 {
7952 part.OffsetPosition = currentPosition; 7952 part.OffsetPosition = currentPosition;
7953 SceneObjectGroup parent = part.ParentGroup; 7953 SceneObjectGroup parent = part.ParentGroup;
7954 parent.HasGroupChanged = true; 7954 parent.HasGroupChanged = true;
7955 parent.ScheduleGroupForTerseUpdate(); 7955 parent.ScheduleGroupForTerseUpdate();
7956 } 7956 }
7957 } 7957 }
7958 } 7958 }
7959 return null; 7959 return null;
7960 } 7960 }
7961   7961  
7962 public LSL_String llStringToBase64(string str) 7962 public LSL_String llStringToBase64(string str)
7963 { 7963 {
7964 m_host.AddScriptLPS(1); 7964 m_host.AddScriptLPS(1);
7965 try 7965 try
7966 { 7966 {
7967 byte[] encData_byte = new byte[str.Length]; 7967 byte[] encData_byte = new byte[str.Length];
7968 encData_byte = Util.UTF8.GetBytes(str); 7968 encData_byte = Util.UTF8.GetBytes(str);
7969 string encodedData = Convert.ToBase64String(encData_byte); 7969 string encodedData = Convert.ToBase64String(encData_byte);
7970 return encodedData; 7970 return encodedData;
7971 } 7971 }
7972 catch 7972 catch
7973 { 7973 {
7974 Error("llBase64ToString", "Error encoding string"); 7974 Error("llBase64ToString", "Error encoding string");
7975 return String.Empty; 7975 return String.Empty;
7976 } 7976 }
7977 } 7977 }
7978   7978  
7979 public LSL_String llBase64ToString(string str) 7979 public LSL_String llBase64ToString(string str)
7980 { 7980 {
7981 m_host.AddScriptLPS(1); 7981 m_host.AddScriptLPS(1);
7982 try 7982 try
7983 { 7983 {
7984 return Util.Base64ToString(str); 7984 return Util.Base64ToString(str);
7985 } 7985 }
7986 catch 7986 catch
7987 { 7987 {
7988 Error("llBase64ToString", "Error decoding string"); 7988 Error("llBase64ToString", "Error decoding string");
7989 return String.Empty; 7989 return String.Empty;
7990 } 7990 }
7991 } 7991 }
7992   7992  
7993 public LSL_String llXorBase64Strings(string str1, string str2) 7993 public LSL_String llXorBase64Strings(string str1, string str2)
7994 { 7994 {
7995 m_host.AddScriptLPS(1); 7995 m_host.AddScriptLPS(1);
7996 Deprecated("llXorBase64Strings", "Use llXorBase64 instead"); 7996 Deprecated("llXorBase64Strings", "Use llXorBase64 instead");
7997 ScriptSleep(300); 7997 ScriptSleep(300);
7998 return String.Empty; 7998 return String.Empty;
7999 } 7999 }
8000   8000  
8001 public void llRemoteDataSetRegion() 8001 public void llRemoteDataSetRegion()
8002 { 8002 {
8003 m_host.AddScriptLPS(1); 8003 m_host.AddScriptLPS(1);
8004 Deprecated("llRemoteDataSetRegion", "Use llOpenRemoteDataChannel instead"); 8004 Deprecated("llRemoteDataSetRegion", "Use llOpenRemoteDataChannel instead");
8005 } 8005 }
8006   8006  
8007 public LSL_Float llLog10(double val) 8007 public LSL_Float llLog10(double val)
8008 { 8008 {
8009 m_host.AddScriptLPS(1); 8009 m_host.AddScriptLPS(1);
8010 return (double)Math.Log10(val); 8010 return (double)Math.Log10(val);
8011 } 8011 }
8012   8012  
8013 public LSL_Float llLog(double val) 8013 public LSL_Float llLog(double val)
8014 { 8014 {
8015 m_host.AddScriptLPS(1); 8015 m_host.AddScriptLPS(1);
8016 return (double)Math.Log(val); 8016 return (double)Math.Log(val);
8017 } 8017 }
8018   8018  
8019 public LSL_List llGetAnimationList(string id) 8019 public LSL_List llGetAnimationList(string id)
8020 { 8020 {
8021 m_host.AddScriptLPS(1); 8021 m_host.AddScriptLPS(1);
8022   8022  
8023 LSL_List l = new LSL_List(); 8023 LSL_List l = new LSL_List();
8024 ScenePresence av = World.GetScenePresence((UUID)id); 8024 ScenePresence av = World.GetScenePresence((UUID)id);
8025 if (av == null || av.IsChildAgent) // only if in the region 8025 if (av == null || av.IsChildAgent) // only if in the region
8026 return l; 8026 return l;
8027 UUID[] anims; 8027 UUID[] anims;
8028 anims = av.Animator.GetAnimationArray(); 8028 anims = av.Animator.GetAnimationArray();
8029 foreach (UUID foo in anims) 8029 foreach (UUID foo in anims)
8030 l.Add(new LSL_Key(foo.ToString())); 8030 l.Add(new LSL_Key(foo.ToString()));
8031 return l; 8031 return l;
8032 } 8032 }
8033   8033  
8034 public void llSetParcelMusicURL(string url) 8034 public void llSetParcelMusicURL(string url)
8035 { 8035 {
8036 m_host.AddScriptLPS(1); 8036 m_host.AddScriptLPS(1);
8037   8037  
8038 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 8038 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8039   8039  
8040 if (land.LandData.OwnerID != m_host.OwnerID) 8040 if (land.LandData.OwnerID != m_host.OwnerID)
8041 return; 8041 return;
8042   8042  
8043 land.SetMusicUrl(url); 8043 land.SetMusicUrl(url);
8044   8044  
8045 ScriptSleep(2000); 8045 ScriptSleep(2000);
8046 } 8046 }
8047   8047  
8048 public LSL_String llGetParcelMusicURL() 8048 public LSL_String llGetParcelMusicURL()
8049 { 8049 {
8050 m_host.AddScriptLPS(1); 8050 m_host.AddScriptLPS(1);
8051   8051  
8052 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 8052 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8053   8053  
8054 if (land.LandData.OwnerID != m_host.OwnerID) 8054 if (land.LandData.OwnerID != m_host.OwnerID)
8055 return String.Empty; 8055 return String.Empty;
8056   8056  
8057 return land.GetMusicUrl(); 8057 return land.GetMusicUrl();
8058 } 8058 }
8059   8059  
8060 public LSL_Vector llGetRootPosition() 8060 public LSL_Vector llGetRootPosition()
8061 { 8061 {
8062 m_host.AddScriptLPS(1); 8062 m_host.AddScriptLPS(1);
8063   8063  
8064 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition); 8064 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8065 } 8065 }
8066   8066  
8067 /// <summary> 8067 /// <summary>
8068 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetRot 8068 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetRot
8069 /// http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation 8069 /// http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation
8070 /// Also tested in sl in regards to the behaviour in attachments/mouselook 8070 /// Also tested in sl in regards to the behaviour in attachments/mouselook
8071 /// In the root prim:- 8071 /// In the root prim:-
8072 /// Returns the object rotation if not attached 8072 /// Returns the object rotation if not attached
8073 /// Returns the avatars rotation if attached 8073 /// Returns the avatars rotation if attached
8074 /// Returns the camera rotation if attached and the avatar is in mouselook 8074 /// Returns the camera rotation if attached and the avatar is in mouselook
8075 /// </summary> 8075 /// </summary>
8076 public LSL_Rotation llGetRootRotation() 8076 public LSL_Rotation llGetRootRotation()
8077 { 8077 {
8078 m_host.AddScriptLPS(1); 8078 m_host.AddScriptLPS(1);
8079 Quaternion q; 8079 Quaternion q;
8080 if (m_host.ParentGroup.AttachmentPoint != 0) 8080 if (m_host.ParentGroup.AttachmentPoint != 0)
8081 { 8081 {
8082 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 8082 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
8083 if (avatar != null) 8083 if (avatar != null)
8084 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8084 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
8085 q = avatar.CameraRotation; // Mouselook 8085 q = avatar.CameraRotation; // Mouselook
8086 else 8086 else
8087 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate 8087 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
8088 else 8088 else
8089 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case 8089 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case
8090 } 8090 }
8091 else 8091 else
8092 q = m_host.ParentGroup.GroupRotation; // just the group rotation 8092 q = m_host.ParentGroup.GroupRotation; // just the group rotation
8093   8093  
8094 return new LSL_Rotation(q); 8094 return new LSL_Rotation(q);
8095 } 8095 }
8096   8096  
8097 public LSL_String llGetObjectDesc() 8097 public LSL_String llGetObjectDesc()
8098 { 8098 {
8099 return m_host.Description!=null?m_host.Description:String.Empty; 8099 return m_host.Description!=null?m_host.Description:String.Empty;
8100 } 8100 }
8101   8101  
8102 public void llSetObjectDesc(string desc) 8102 public void llSetObjectDesc(string desc)
8103 { 8103 {
8104 m_host.AddScriptLPS(1); 8104 m_host.AddScriptLPS(1);
8105 m_host.Description = desc!=null?desc:String.Empty; 8105 m_host.Description = desc!=null?desc:String.Empty;
8106 } 8106 }
8107   8107  
8108 public LSL_String llGetCreator() 8108 public LSL_String llGetCreator()
8109 { 8109 {
8110 m_host.AddScriptLPS(1); 8110 m_host.AddScriptLPS(1);
8111 return m_host.CreatorID.ToString(); 8111 return m_host.CreatorID.ToString();
8112 } 8112 }
8113   8113  
8114 public LSL_String llGetTimestamp() 8114 public LSL_String llGetTimestamp()
8115 { 8115 {
8116 m_host.AddScriptLPS(1); 8116 m_host.AddScriptLPS(1);
8117 return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 8117 return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
8118 } 8118 }
8119   8119  
8120 public LSL_Integer llGetNumberOfPrims() 8120 public LSL_Integer llGetNumberOfPrims()
8121 { 8121 {
8122 m_host.AddScriptLPS(1); 8122 m_host.AddScriptLPS(1);
8123   8123  
8124 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8124 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount();
8125 } 8125 }
8126   8126  
8127 /// <summary> 8127 /// <summary>
8128 /// A partial implementation. 8128 /// A partial implementation.
8129 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox 8129 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox
8130 /// So far only valid for standing/flying/ground sitting avatars and single prim objects. 8130 /// So far only valid for standing/flying/ground sitting avatars and single prim objects.
8131 /// If the object has multiple prims and/or a sitting avatar then the bounding 8131 /// If the object has multiple prims and/or a sitting avatar then the bounding
8132 /// box is for the root prim only. 8132 /// box is for the root prim only.
8133 /// </summary> 8133 /// </summary>
8134 public LSL_List llGetBoundingBox(string obj) 8134 public LSL_List llGetBoundingBox(string obj)
8135 { 8135 {
8136 m_host.AddScriptLPS(1); 8136 m_host.AddScriptLPS(1);
8137 UUID objID = UUID.Zero; 8137 UUID objID = UUID.Zero;
8138 LSL_List result = new LSL_List(); 8138 LSL_List result = new LSL_List();
8139 if (!UUID.TryParse(obj, out objID)) 8139 if (!UUID.TryParse(obj, out objID))
8140 { 8140 {
8141 result.Add(new LSL_Vector()); 8141 result.Add(new LSL_Vector());
8142 result.Add(new LSL_Vector()); 8142 result.Add(new LSL_Vector());
8143 return result; 8143 return result;
8144 } 8144 }
8145 ScenePresence presence = World.GetScenePresence(objID); 8145 ScenePresence presence = World.GetScenePresence(objID);
8146 if (presence != null) 8146 if (presence != null)
8147 { 8147 {
8148 if (presence.ParentID == 0) // not sat on an object 8148 if (presence.ParentID == 0) // not sat on an object
8149 { 8149 {
8150 LSL_Vector lower; 8150 LSL_Vector lower;
8151 LSL_Vector upper; 8151 LSL_Vector upper;
8152 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8152 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8153 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8153 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8154 { 8154 {
8155 // This is for ground sitting avatars 8155 // This is for ground sitting avatars
8156 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8156 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8157 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8157 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8158 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8158 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8159 } 8159 }
8160 else 8160 else
8161 { 8161 {
8162 // This is for standing/flying avatars 8162 // This is for standing/flying avatars
8163 float height = presence.Appearance.AvatarHeight / 2.0f; 8163 float height = presence.Appearance.AvatarHeight / 2.0f;
8164 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8164 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8165 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8165 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8166 } 8166 }
8167 result.Add(lower); 8167 result.Add(lower);
8168 result.Add(upper); 8168 result.Add(upper);
8169 return result; 8169 return result;
8170 } 8170 }
8171 else 8171 else
8172 { 8172 {
8173 // sitting on an object so we need the bounding box of that 8173 // sitting on an object so we need the bounding box of that
8174 // which should include the avatar so set the UUID to the 8174 // which should include the avatar so set the UUID to the
8175 // UUID of the object the avatar is sat on and allow it to fall through 8175 // UUID of the object the avatar is sat on and allow it to fall through
8176 // to processing an object 8176 // to processing an object
8177 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8177 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8178 objID = p.UUID; 8178 objID = p.UUID;
8179 } 8179 }
8180 } 8180 }
8181 SceneObjectPart part = World.GetSceneObjectPart(objID); 8181 SceneObjectPart part = World.GetSceneObjectPart(objID);
8182 // Currently only works for single prims without a sitting avatar 8182 // Currently only works for single prims without a sitting avatar
8183 if (part != null) 8183 if (part != null)
8184 { 8184 {
8185 Vector3 halfSize = part.Scale / 2.0f; 8185 Vector3 halfSize = part.Scale / 2.0f;
8186 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8186 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f;
8187 LSL_Vector upper = new LSL_Vector(halfSize); 8187 LSL_Vector upper = new LSL_Vector(halfSize);
8188 result.Add(lower); 8188 result.Add(lower);
8189 result.Add(upper); 8189 result.Add(upper);
8190 return result; 8190 return result;
8191 } 8191 }
8192   8192  
8193 // Not found so return empty values 8193 // Not found so return empty values
8194 result.Add(new LSL_Vector()); 8194 result.Add(new LSL_Vector());
8195 result.Add(new LSL_Vector()); 8195 result.Add(new LSL_Vector());
8196 return result; 8196 return result;
8197 } 8197 }
8198   8198  
8199 public LSL_Vector llGetGeometricCenter() 8199 public LSL_Vector llGetGeometricCenter()
8200 { 8200 {
8201 return new LSL_Vector(m_host.GetGeometricCenter()); 8201 return new LSL_Vector(m_host.GetGeometricCenter());
8202 } 8202 }
8203   8203  
8204 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8204 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules)
8205 { 8205 {
8206 LSL_List result = new LSL_List(); 8206 LSL_List result = new LSL_List();
8207 LSL_List remaining = null; 8207 LSL_List remaining = null;
8208   8208  
8209 while (true) 8209 while (true)
8210 { 8210 {
8211 // m_log.DebugFormat( 8211 // m_log.DebugFormat(
8212 // "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}", 8212 // "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
8213 // rules.Length, entity != null ? entity.Name : "NULL"); 8213 // rules.Length, entity != null ? entity.Name : "NULL");
8214   8214  
8215 if (entity == null) 8215 if (entity == null)
8216 return result; 8216 return result;
8217   8217  
8218 if (entity is SceneObjectPart) 8218 if (entity is SceneObjectPart)
8219 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result); 8219 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8220 else 8220 else
8221 remaining = GetAgentParams((ScenePresence)entity, rules, ref result); 8221 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8222   8222  
8223 if (remaining == null || remaining.Length < 2) 8223 if (remaining == null || remaining.Length < 2)
8224 return result; 8224 return result;
8225   8225  
8226 int linknumber = remaining.GetLSLIntegerItem(0); 8226 int linknumber = remaining.GetLSLIntegerItem(0);
8227 rules = remaining.GetSublist(1, -1); 8227 rules = remaining.GetSublist(1, -1);
8228 entity = GetLinkEntity(linknumber); 8228 entity = GetLinkEntity(linknumber);
8229 } 8229 }
8230 } 8230 }
8231   8231  
8232 public LSL_List llGetPrimitiveParams(LSL_List rules) 8232 public LSL_List llGetPrimitiveParams(LSL_List rules)
8233 { 8233 {
8234 m_host.AddScriptLPS(1); 8234 m_host.AddScriptLPS(1);
8235   8235  
8236 return GetEntityParams(m_host, rules); 8236 return GetEntityParams(m_host, rules);
8237 } 8237 }
8238   8238  
8239 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8239 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8240 { 8240 {
8241 m_host.AddScriptLPS(1); 8241 m_host.AddScriptLPS(1);
8242   8242  
8243 return GetEntityParams(GetLinkEntity(linknumber), rules); 8243 return GetEntityParams(GetLinkEntity(linknumber), rules);
8244 } 8244 }
8245   8245  
8246 public LSL_Vector GetAgentSize(ScenePresence sp) 8246 public LSL_Vector GetAgentSize(ScenePresence sp)
8247 { 8247 {
8248 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8248 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight);
8249 } 8249 }
8250   8250  
8251 /// <summary> 8251 /// <summary>
8252 /// Gets params for a seated avatar in a linkset. 8252 /// Gets params for a seated avatar in a linkset.
8253 /// </summary> 8253 /// </summary>
8254 /// <returns></returns> 8254 /// <returns></returns>
8255 /// <param name='sp'></param> 8255 /// <param name='sp'></param>
8256 /// <param name='rules'></param> 8256 /// <param name='rules'></param>
8257 /// <param name='res'></param> 8257 /// <param name='res'></param>
8258 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res) 8258 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8259 { 8259 {
8260 int idx = 0; 8260 int idx = 0;
8261 while (idx < rules.Length) 8261 while (idx < rules.Length)
8262 { 8262 {
8263 int code = (int)rules.GetLSLIntegerItem(idx++); 8263 int code = (int)rules.GetLSLIntegerItem(idx++);
8264 int remain = rules.Length-idx; 8264 int remain = rules.Length-idx;
8265   8265  
8266 switch (code) 8266 switch (code)
8267 { 8267 {
8268 case (int)ScriptBaseClass.PRIM_MATERIAL: 8268 case (int)ScriptBaseClass.PRIM_MATERIAL:
8269 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8269 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH));
8270 break; 8270 break;
8271   8271  
8272 case (int)ScriptBaseClass.PRIM_PHYSICS: 8272 case (int)ScriptBaseClass.PRIM_PHYSICS:
8273 res.Add(ScriptBaseClass.FALSE); 8273 res.Add(ScriptBaseClass.FALSE);
8274 break; 8274 break;
8275   8275  
8276 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8276 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8277 res.Add(ScriptBaseClass.FALSE); 8277 res.Add(ScriptBaseClass.FALSE);
8278 break; 8278 break;
8279   8279  
8280 case (int)ScriptBaseClass.PRIM_PHANTOM: 8280 case (int)ScriptBaseClass.PRIM_PHANTOM:
8281 res.Add(ScriptBaseClass.FALSE); 8281 res.Add(ScriptBaseClass.FALSE);
8282 break; 8282 break;
8283   8283  
8284 case (int)ScriptBaseClass.PRIM_POSITION: 8284 case (int)ScriptBaseClass.PRIM_POSITION:
8285 res.Add(new LSL_Vector(sp.AbsolutePosition)); 8285 res.Add(new LSL_Vector(sp.AbsolutePosition));
8286 break; 8286 break;
8287   8287  
8288 case (int)ScriptBaseClass.PRIM_SIZE: 8288 case (int)ScriptBaseClass.PRIM_SIZE:
8289 res.Add(GetAgentSize(sp)); 8289 res.Add(GetAgentSize(sp));
8290 break; 8290 break;
8291   8291  
8292 case (int)ScriptBaseClass.PRIM_ROTATION: 8292 case (int)ScriptBaseClass.PRIM_ROTATION:
8293 res.Add(sp.GetWorldRotation()); 8293 res.Add(sp.GetWorldRotation());
8294 break; 8294 break;
8295   8295  
8296 case (int)ScriptBaseClass.PRIM_TYPE: 8296 case (int)ScriptBaseClass.PRIM_TYPE:
8297 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); 8297 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8298 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); 8298 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8299 res.Add(new LSL_Vector(0, 1, 0)); 8299 res.Add(new LSL_Vector(0, 1, 0));
8300 res.Add(new LSL_Float(0)); 8300 res.Add(new LSL_Float(0));
8301 res.Add(new LSL_Vector(0, 0, 0)); 8301 res.Add(new LSL_Vector(0, 0, 0));
8302 res.Add(new LSL_Vector(1, 1, 0)); 8302 res.Add(new LSL_Vector(1, 1, 0));
8303 res.Add(new LSL_Vector(0, 0, 0)); 8303 res.Add(new LSL_Vector(0, 0, 0));
8304 break; 8304 break;
8305   8305  
8306 case (int)ScriptBaseClass.PRIM_TEXTURE: 8306 case (int)ScriptBaseClass.PRIM_TEXTURE:
8307 if (remain < 1) 8307 if (remain < 1)
8308 return null; 8308 return null;
8309   8309  
8310 int face = (int)rules.GetLSLIntegerItem(idx++); 8310 int face = (int)rules.GetLSLIntegerItem(idx++);
8311 if (face > 21) 8311 if (face > 21)
8312 break; 8312 break;
8313   8313  
8314 res.Add(new LSL_String("")); 8314 res.Add(new LSL_String(""));
8315 res.Add(ScriptBaseClass.ZERO_VECTOR); 8315 res.Add(ScriptBaseClass.ZERO_VECTOR);
8316 res.Add(ScriptBaseClass.ZERO_VECTOR); 8316 res.Add(ScriptBaseClass.ZERO_VECTOR);
8317 res.Add(new LSL_Float(0)); 8317 res.Add(new LSL_Float(0));
8318 break; 8318 break;
8319   8319  
8320 case (int)ScriptBaseClass.PRIM_COLOR: 8320 case (int)ScriptBaseClass.PRIM_COLOR:
8321 if (remain < 1) 8321 if (remain < 1)
8322 return null; 8322 return null;
8323   8323  
8324 face = (int)rules.GetLSLIntegerItem(idx++); 8324 face = (int)rules.GetLSLIntegerItem(idx++);
8325 if (face > 21) 8325 if (face > 21)
8326 break; 8326 break;
8327   8327  
8328 res.Add(ScriptBaseClass.ZERO_VECTOR); 8328 res.Add(ScriptBaseClass.ZERO_VECTOR);
8329 res.Add(new LSL_Float(0)); 8329 res.Add(new LSL_Float(0));
8330 break; 8330 break;
8331   8331  
8332 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8332 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8333 if (remain < 1) 8333 if (remain < 1)
8334 return null; 8334 return null;
8335   8335  
8336 face = (int)rules.GetLSLIntegerItem(idx++); 8336 face = (int)rules.GetLSLIntegerItem(idx++);
8337 if (face > 21) 8337 if (face > 21)
8338 break; 8338 break;
8339   8339  
8340 res.Add(ScriptBaseClass.PRIM_SHINY_NONE); 8340 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8341 res.Add(ScriptBaseClass.PRIM_BUMP_NONE); 8341 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8342 break; 8342 break;
8343   8343  
8344 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8344 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8345 if (remain < 1) 8345 if (remain < 1)
8346 return null; 8346 return null;
8347   8347  
8348 face = (int)rules.GetLSLIntegerItem(idx++); 8348 face = (int)rules.GetLSLIntegerItem(idx++);
8349 if (face > 21) 8349 if (face > 21)
8350 break; 8350 break;
8351   8351  
8352 res.Add(ScriptBaseClass.FALSE); 8352 res.Add(ScriptBaseClass.FALSE);
8353 break; 8353 break;
8354   8354  
8355 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8355 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8356 res.Add(ScriptBaseClass.FALSE); 8356 res.Add(ScriptBaseClass.FALSE);
8357 res.Add(new LSL_Integer(0)); 8357 res.Add(new LSL_Integer(0));
8358 res.Add(new LSL_Float(0)); 8358 res.Add(new LSL_Float(0));
8359 res.Add(new LSL_Float(0)); 8359 res.Add(new LSL_Float(0));
8360 res.Add(new LSL_Float(0)); 8360 res.Add(new LSL_Float(0));
8361 res.Add(new LSL_Float(0)); 8361 res.Add(new LSL_Float(0));
8362 res.Add(ScriptBaseClass.ZERO_VECTOR); 8362 res.Add(ScriptBaseClass.ZERO_VECTOR);
8363 break; 8363 break;
8364   8364  
8365 case (int)ScriptBaseClass.PRIM_TEXGEN: 8365 case (int)ScriptBaseClass.PRIM_TEXGEN:
8366 if (remain < 1) 8366 if (remain < 1)
8367 return null; 8367 return null;
8368   8368  
8369 face = (int)rules.GetLSLIntegerItem(idx++); 8369 face = (int)rules.GetLSLIntegerItem(idx++);
8370 if (face > 21) 8370 if (face > 21)
8371 break; 8371 break;
8372   8372  
8373 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT); 8373 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8374 break; 8374 break;
8375   8375  
8376 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8376 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8377 res.Add(ScriptBaseClass.FALSE); 8377 res.Add(ScriptBaseClass.FALSE);
8378 res.Add(ScriptBaseClass.ZERO_VECTOR); 8378 res.Add(ScriptBaseClass.ZERO_VECTOR);
8379 res.Add(ScriptBaseClass.ZERO_VECTOR); 8379 res.Add(ScriptBaseClass.ZERO_VECTOR);
8380 break; 8380 break;
8381   8381  
8382 case (int)ScriptBaseClass.PRIM_GLOW: 8382 case (int)ScriptBaseClass.PRIM_GLOW:
8383 if (remain < 1) 8383 if (remain < 1)
8384 return null; 8384 return null;
8385   8385  
8386 face = (int)rules.GetLSLIntegerItem(idx++); 8386 face = (int)rules.GetLSLIntegerItem(idx++);
8387 if (face > 21) 8387 if (face > 21)
8388 break; 8388 break;
8389   8389  
8390 res.Add(new LSL_Float(0)); 8390 res.Add(new LSL_Float(0));
8391 break; 8391 break;
8392   8392  
8393 case (int)ScriptBaseClass.PRIM_TEXT: 8393 case (int)ScriptBaseClass.PRIM_TEXT:
8394 res.Add(new LSL_String("")); 8394 res.Add(new LSL_String(""));
8395 res.Add(ScriptBaseClass.ZERO_VECTOR); 8395 res.Add(ScriptBaseClass.ZERO_VECTOR);
8396 res.Add(new LSL_Float(1)); 8396 res.Add(new LSL_Float(1));
8397 break; 8397 break;
8398   8398  
8399 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8399 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8400 res.Add(new LSL_Rotation(sp.Rotation)); 8400 res.Add(new LSL_Rotation(sp.Rotation));
8401 break; 8401 break;
8402   8402  
8403 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8403 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8404 res.Add(new LSL_Vector(sp.OffsetPosition)); 8404 res.Add(new LSL_Vector(sp.OffsetPosition));
8405 break; 8405 break;
8406   8406  
8407 case (int)ScriptBaseClass.PRIM_SLICE: 8407 case (int)ScriptBaseClass.PRIM_SLICE:
8408 res.Add(new LSL_Vector(0, 1, 0)); 8408 res.Add(new LSL_Vector(0, 1, 0));
8409 break; 8409 break;
8410   8410  
8411 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8411 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8412 if(remain < 3) 8412 if(remain < 3)
8413 return null; 8413 return null;
8414   8414  
8415 return rules.GetSublist(idx, -1); 8415 return rules.GetSublist(idx, -1);
8416 } 8416 }
8417 } 8417 }
8418   8418  
8419 return null; 8419 return null;
8420 } 8420 }
8421   8421  
8422 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8422 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8423 { 8423 {
8424 int idx = 0; 8424 int idx = 0;
8425 while (idx < rules.Length) 8425 while (idx < rules.Length)
8426 { 8426 {
8427 int code = (int)rules.GetLSLIntegerItem(idx++); 8427 int code = (int)rules.GetLSLIntegerItem(idx++);
8428 int remain = rules.Length - idx; 8428 int remain = rules.Length - idx;
8429   8429  
8430 switch (code) 8430 switch (code)
8431 { 8431 {
8432 case (int)ScriptBaseClass.PRIM_MATERIAL: 8432 case (int)ScriptBaseClass.PRIM_MATERIAL:
8433 res.Add(new LSL_Integer(part.Material)); 8433 res.Add(new LSL_Integer(part.Material));
8434 break; 8434 break;
8435   8435  
8436 case (int)ScriptBaseClass.PRIM_PHYSICS: 8436 case (int)ScriptBaseClass.PRIM_PHYSICS:
8437 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0) 8437 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0)
8438 res.Add(new LSL_Integer(1)); 8438 res.Add(new LSL_Integer(1));
8439 else 8439 else
8440 res.Add(new LSL_Integer(0)); 8440 res.Add(new LSL_Integer(0));
8441 break; 8441 break;
8442   8442  
8443 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8443 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8444 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0) 8444 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0)
8445 res.Add(new LSL_Integer(1)); 8445 res.Add(new LSL_Integer(1));
8446 else 8446 else
8447 res.Add(new LSL_Integer(0)); 8447 res.Add(new LSL_Integer(0));
8448 break; 8448 break;
8449   8449  
8450 case (int)ScriptBaseClass.PRIM_PHANTOM: 8450 case (int)ScriptBaseClass.PRIM_PHANTOM:
8451 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) 8451 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
8452 res.Add(new LSL_Integer(1)); 8452 res.Add(new LSL_Integer(1));
8453 else 8453 else
8454 res.Add(new LSL_Integer(0)); 8454 res.Add(new LSL_Integer(0));
8455 break; 8455 break;
8456   8456  
8457 case (int)ScriptBaseClass.PRIM_POSITION: 8457 case (int)ScriptBaseClass.PRIM_POSITION:
8458 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8458 LSL_Vector v = new LSL_Vector(part.AbsolutePosition);
8459   8459  
8460 // For some reason, the part.AbsolutePosition.* values do not change if the 8460 // For some reason, the part.AbsolutePosition.* values do not change if the
8461 // linkset is rotated; they always reflect the child prim's world position 8461 // linkset is rotated; they always reflect the child prim's world position
8462 // as though the linkset is unrotated. This is incompatible behavior with SL's 8462 // as though the linkset is unrotated. This is incompatible behavior with SL's
8463 // implementation, so will break scripts imported from there (not to mention it 8463 // implementation, so will break scripts imported from there (not to mention it
8464 // makes it more difficult to determine a child prim's actual inworld position). 8464 // makes it more difficult to determine a child prim's actual inworld position).
8465 if (!part.IsRoot) 8465 if (!part.IsRoot)
8466 { 8466 {
8467 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition); 8467 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8468 v = ((v - rootPos) * llGetRootRotation()) + rootPos; 8468 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8469 } 8469 }
8470   8470  
8471 res.Add(v); 8471 res.Add(v);
8472 break; 8472 break;
8473   8473  
8474 case (int)ScriptBaseClass.PRIM_SIZE: 8474 case (int)ScriptBaseClass.PRIM_SIZE:
8475 res.Add(new LSL_Vector(part.Scale)); 8475 res.Add(new LSL_Vector(part.Scale));
8476 break; 8476 break;
8477   8477  
8478 case (int)ScriptBaseClass.PRIM_ROTATION: 8478 case (int)ScriptBaseClass.PRIM_ROTATION:
8479 res.Add(GetPartRot(part)); 8479 res.Add(GetPartRot(part));
8480 break; 8480 break;
8481   8481  
8482 case (int)ScriptBaseClass.PRIM_TYPE: 8482 case (int)ScriptBaseClass.PRIM_TYPE:
8483 // implementing box 8483 // implementing box
8484 PrimitiveBaseShape Shape = part.Shape; 8484 PrimitiveBaseShape Shape = part.Shape;
8485 int primType = (int)part.GetPrimType(); 8485 int primType = (int)part.GetPrimType();
8486 res.Add(new LSL_Integer(primType)); 8486 res.Add(new LSL_Integer(primType));
8487 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX 8487 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
8488 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY. 8488 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
8489 switch (primType) 8489 switch (primType)
8490 { 8490 {
8491 case ScriptBaseClass.PRIM_TYPE_BOX: 8491 case ScriptBaseClass.PRIM_TYPE_BOX:
8492 case ScriptBaseClass.PRIM_TYPE_CYLINDER: 8492 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
8493 case ScriptBaseClass.PRIM_TYPE_PRISM: 8493 case ScriptBaseClass.PRIM_TYPE_PRISM:
8494 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8494 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8495 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8495 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8496 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8496 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8497 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8497 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8498 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); 8498 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
8499 res.Add(new LSL_Vector(topshearx, topsheary, 0)); 8499 res.Add(new LSL_Vector(topshearx, topsheary, 0));
8500 break; 8500 break;
8501   8501  
8502 case ScriptBaseClass.PRIM_TYPE_SPHERE: 8502 case ScriptBaseClass.PRIM_TYPE_SPHERE:
8503 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8503 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8504 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8504 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
8505 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8505 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8506 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8506 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8507 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8507 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8508 break; 8508 break;
8509   8509  
8510 case ScriptBaseClass.PRIM_TYPE_SCULPT: 8510 case ScriptBaseClass.PRIM_TYPE_SCULPT:
8511 res.Add(new LSL_String(Shape.SculptTexture.ToString())); 8511 res.Add(new LSL_String(Shape.SculptTexture.ToString()));
8512 res.Add(new LSL_Integer(Shape.SculptType)); 8512 res.Add(new LSL_Integer(Shape.SculptType));
8513 break; 8513 break;
8514   8514  
8515 case ScriptBaseClass.PRIM_TYPE_RING: 8515 case ScriptBaseClass.PRIM_TYPE_RING:
8516 case ScriptBaseClass.PRIM_TYPE_TUBE: 8516 case ScriptBaseClass.PRIM_TYPE_TUBE:
8517 case ScriptBaseClass.PRIM_TYPE_TORUS: 8517 case ScriptBaseClass.PRIM_TYPE_TORUS:
8518 // holeshape 8518 // holeshape
8519 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8519 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8520   8520  
8521 // cut 8521 // cut
8522 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8522 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
8523   8523  
8524 // hollow 8524 // hollow
8525 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8525 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8526   8526  
8527 // twist 8527 // twist
8528 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8528 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8529   8529  
8530 // vector holesize 8530 // vector holesize
8531 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); 8531 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
8532   8532  
8533 // vector topshear 8533 // vector topshear
8534 res.Add(new LSL_Vector(topshearx, topsheary, 0)); 8534 res.Add(new LSL_Vector(topshearx, topsheary, 0));
8535   8535  
8536 // vector profilecut 8536 // vector profilecut
8537 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8537 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8538   8538  
8539 // vector tapera 8539 // vector tapera
8540 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8540 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8541   8541  
8542 // float revolutions 8542 // float revolutions
8543 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); 8543 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8544 // Slightly inaccurate, because an unsigned byte is being used to represent 8544 // Slightly inaccurate, because an unsigned byte is being used to represent
8545 // the entire range of floating-point values from 1.0 through 4.0 (which is how 8545 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8546 // SL does it). 8546 // SL does it).
8547 // 8547 //
8548 // Using these formulas to store and retrieve PathRevolutions, it is not 8548 // Using these formulas to store and retrieve PathRevolutions, it is not
8549 // possible to use all values between 1.00 and 4.00. For instance, you can't 8549 // possible to use all values between 1.00 and 4.00. For instance, you can't
8550 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you 8550 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8551 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them 8551 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8552 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar 8552 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8553 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. 8553 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8554 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8554 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8555 // such as 1.10. So, SL must store and retreive the actual user input rather 8555 // such as 1.10. So, SL must store and retreive the actual user input rather
8556 // than only storing the encoded value. 8556 // than only storing the encoded value.
8557   8557  
8558 // float radiusoffset 8558 // float radiusoffset
8559 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); 8559 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
8560   8560  
8561 // float skew 8561 // float skew
8562 res.Add(new LSL_Float(Shape.PathSkew / 100.0)); 8562 res.Add(new LSL_Float(Shape.PathSkew / 100.0));
8563 break; 8563 break;
8564 } 8564 }
8565 break; 8565 break;
8566   8566  
8567 case (int)ScriptBaseClass.PRIM_TEXTURE: 8567 case (int)ScriptBaseClass.PRIM_TEXTURE:
8568 if (remain < 1) 8568 if (remain < 1)
8569 return null; 8569 return null;
8570   8570  
8571 int face = (int)rules.GetLSLIntegerItem(idx++); 8571 int face = (int)rules.GetLSLIntegerItem(idx++);
8572 Primitive.TextureEntry tex = part.Shape.Textures; 8572 Primitive.TextureEntry tex = part.Shape.Textures;
8573 if (face == ScriptBaseClass.ALL_SIDES) 8573 if (face == ScriptBaseClass.ALL_SIDES)
8574 { 8574 {
8575 for (face = 0 ; face < GetNumberOfSides(part); face++) 8575 for (face = 0 ; face < GetNumberOfSides(part); face++)
8576 { 8576 {
8577 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8577 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8578   8578  
8579 res.Add(new LSL_String(texface.TextureID.ToString())); 8579 res.Add(new LSL_String(texface.TextureID.ToString()));
8580 res.Add(new LSL_Vector(texface.RepeatU, 8580 res.Add(new LSL_Vector(texface.RepeatU,
8581 texface.RepeatV, 8581 texface.RepeatV,
8582 0)); 8582 0));
8583 res.Add(new LSL_Vector(texface.OffsetU, 8583 res.Add(new LSL_Vector(texface.OffsetU,
8584 texface.OffsetV, 8584 texface.OffsetV,
8585 0)); 8585 0));
8586 res.Add(new LSL_Float(texface.Rotation)); 8586 res.Add(new LSL_Float(texface.Rotation));
8587 } 8587 }
8588 } 8588 }
8589 else 8589 else
8590 { 8590 {
8591 if (face >= 0 && face < GetNumberOfSides(part)) 8591 if (face >= 0 && face < GetNumberOfSides(part))
8592 { 8592 {
8593 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8593 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8594   8594  
8595 res.Add(new LSL_String(texface.TextureID.ToString())); 8595 res.Add(new LSL_String(texface.TextureID.ToString()));
8596 res.Add(new LSL_Vector(texface.RepeatU, 8596 res.Add(new LSL_Vector(texface.RepeatU,
8597 texface.RepeatV, 8597 texface.RepeatV,
8598 0)); 8598 0));
8599 res.Add(new LSL_Vector(texface.OffsetU, 8599 res.Add(new LSL_Vector(texface.OffsetU,
8600 texface.OffsetV, 8600 texface.OffsetV,
8601 0)); 8601 0));
8602 res.Add(new LSL_Float(texface.Rotation)); 8602 res.Add(new LSL_Float(texface.Rotation));
8603 } 8603 }
8604 } 8604 }
8605 break; 8605 break;
8606   8606  
8607 case (int)ScriptBaseClass.PRIM_COLOR: 8607 case (int)ScriptBaseClass.PRIM_COLOR:
8608 if (remain < 1) 8608 if (remain < 1)
8609 return null; 8609 return null;
8610   8610  
8611 face=(int)rules.GetLSLIntegerItem(idx++); 8611 face=(int)rules.GetLSLIntegerItem(idx++);
8612   8612  
8613 tex = part.Shape.Textures; 8613 tex = part.Shape.Textures;
8614 Color4 texcolor; 8614 Color4 texcolor;
8615 if (face == ScriptBaseClass.ALL_SIDES) 8615 if (face == ScriptBaseClass.ALL_SIDES)
8616 { 8616 {
8617 for (face = 0 ; face < GetNumberOfSides(part); face++) 8617 for (face = 0 ; face < GetNumberOfSides(part); face++)
8618 { 8618 {
8619 texcolor = tex.GetFace((uint)face).RGBA; 8619 texcolor = tex.GetFace((uint)face).RGBA;
8620 res.Add(new LSL_Vector(texcolor.R, 8620 res.Add(new LSL_Vector(texcolor.R,
8621 texcolor.G, 8621 texcolor.G,
8622 texcolor.B)); 8622 texcolor.B));
8623 res.Add(new LSL_Float(texcolor.A)); 8623 res.Add(new LSL_Float(texcolor.A));
8624 } 8624 }
8625 } 8625 }
8626 else 8626 else
8627 { 8627 {
8628 texcolor = tex.GetFace((uint)face).RGBA; 8628 texcolor = tex.GetFace((uint)face).RGBA;
8629 res.Add(new LSL_Vector(texcolor.R, 8629 res.Add(new LSL_Vector(texcolor.R,
8630 texcolor.G, 8630 texcolor.G,
8631 texcolor.B)); 8631 texcolor.B));
8632 res.Add(new LSL_Float(texcolor.A)); 8632 res.Add(new LSL_Float(texcolor.A));
8633 } 8633 }
8634 break; 8634 break;
8635   8635  
8636 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8636 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8637 if (remain < 1) 8637 if (remain < 1)
8638 return null; 8638 return null;
8639   8639  
8640 face=(int)rules.GetLSLIntegerItem(idx++); 8640 face=(int)rules.GetLSLIntegerItem(idx++);
8641   8641  
8642 tex = part.Shape.Textures; 8642 tex = part.Shape.Textures;
8643 if (face == ScriptBaseClass.ALL_SIDES) 8643 if (face == ScriptBaseClass.ALL_SIDES)
8644 { 8644 {
8645 for (face = 0; face < GetNumberOfSides(part); face++) 8645 for (face = 0; face < GetNumberOfSides(part); face++)
8646 { 8646 {
8647 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8647 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8648 // Convert Shininess to PRIM_SHINY_* 8648 // Convert Shininess to PRIM_SHINY_*
8649 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8649 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8650 // PRIM_BUMP_* 8650 // PRIM_BUMP_*
8651 res.Add(new LSL_Integer((int)texface.Bump)); 8651 res.Add(new LSL_Integer((int)texface.Bump));
8652 } 8652 }
8653 } 8653 }
8654 else 8654 else
8655 { 8655 {
8656 if (face >= 0 && face < GetNumberOfSides(part)) 8656 if (face >= 0 && face < GetNumberOfSides(part))
8657 { 8657 {
8658 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8658 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8659 // Convert Shininess to PRIM_SHINY_* 8659 // Convert Shininess to PRIM_SHINY_*
8660 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8660 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8661 // PRIM_BUMP_* 8661 // PRIM_BUMP_*
8662 res.Add(new LSL_Integer((int)texface.Bump)); 8662 res.Add(new LSL_Integer((int)texface.Bump));
8663 } 8663 }
8664 } 8664 }
8665 break; 8665 break;
8666   8666  
8667 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8667 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8668 if (remain < 1) 8668 if (remain < 1)
8669 return null; 8669 return null;
8670   8670  
8671 face = (int)rules.GetLSLIntegerItem(idx++); 8671 face = (int)rules.GetLSLIntegerItem(idx++);
8672   8672  
8673 tex = part.Shape.Textures; 8673 tex = part.Shape.Textures;
8674 if (face == ScriptBaseClass.ALL_SIDES) 8674 if (face == ScriptBaseClass.ALL_SIDES)
8675 { 8675 {
8676 for (face = 0; face < GetNumberOfSides(part); face++) 8676 for (face = 0; face < GetNumberOfSides(part); face++)
8677 { 8677 {
8678 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8678 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8679 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8679 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8680 } 8680 }
8681 } 8681 }
8682 else 8682 else
8683 { 8683 {
8684 if (face >= 0 && face < GetNumberOfSides(part)) 8684 if (face >= 0 && face < GetNumberOfSides(part))
8685 { 8685 {
8686 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8686 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8687 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8687 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8688 } 8688 }
8689 } 8689 }
8690 break; 8690 break;
8691   8691  
8692 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8692 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8693 PrimitiveBaseShape shape = part.Shape; 8693 PrimitiveBaseShape shape = part.Shape;
8694   8694  
8695 if (shape.FlexiEntry) 8695 if (shape.FlexiEntry)
8696 res.Add(new LSL_Integer(1)); // active 8696 res.Add(new LSL_Integer(1)); // active
8697 else 8697 else
8698 res.Add(new LSL_Integer(0)); 8698 res.Add(new LSL_Integer(0));
8699 res.Add(new LSL_Integer(shape.FlexiSoftness));// softness 8699 res.Add(new LSL_Integer(shape.FlexiSoftness));// softness
8700 res.Add(new LSL_Float(shape.FlexiGravity)); // gravity 8700 res.Add(new LSL_Float(shape.FlexiGravity)); // gravity
8701 res.Add(new LSL_Float(shape.FlexiDrag)); // friction 8701 res.Add(new LSL_Float(shape.FlexiDrag)); // friction
8702 res.Add(new LSL_Float(shape.FlexiWind)); // wind 8702 res.Add(new LSL_Float(shape.FlexiWind)); // wind
8703 res.Add(new LSL_Float(shape.FlexiTension)); // tension 8703 res.Add(new LSL_Float(shape.FlexiTension)); // tension
8704 res.Add(new LSL_Vector(shape.FlexiForceX, // force 8704 res.Add(new LSL_Vector(shape.FlexiForceX, // force
8705 shape.FlexiForceY, 8705 shape.FlexiForceY,
8706 shape.FlexiForceZ)); 8706 shape.FlexiForceZ));
8707 break; 8707 break;
8708   8708  
8709 case (int)ScriptBaseClass.PRIM_TEXGEN: 8709 case (int)ScriptBaseClass.PRIM_TEXGEN:
8710 if (remain < 1) 8710 if (remain < 1)
8711 return null; 8711 return null;
8712   8712  
8713 face=(int)rules.GetLSLIntegerItem(idx++); 8713 face=(int)rules.GetLSLIntegerItem(idx++);
8714   8714  
8715 tex = part.Shape.Textures; 8715 tex = part.Shape.Textures;
8716 if (face == ScriptBaseClass.ALL_SIDES) 8716 if (face == ScriptBaseClass.ALL_SIDES)
8717 { 8717 {
8718 for (face = 0; face < GetNumberOfSides(part); face++) 8718 for (face = 0; face < GetNumberOfSides(part); face++)
8719 { 8719 {
8720 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8720 MappingType texgen = tex.GetFace((uint)face).TexMapType;
8721 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8721 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc.
8722 res.Add(new LSL_Integer((uint)texgen >> 1)); 8722 res.Add(new LSL_Integer((uint)texgen >> 1));
8723 } 8723 }
8724 } 8724 }
8725 else 8725 else
8726 { 8726 {
8727 if (face >= 0 && face < GetNumberOfSides(part)) 8727 if (face >= 0 && face < GetNumberOfSides(part))
8728 { 8728 {
8729 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8729 MappingType texgen = tex.GetFace((uint)face).TexMapType;
8730 res.Add(new LSL_Integer((uint)texgen >> 1)); 8730 res.Add(new LSL_Integer((uint)texgen >> 1));
8731 } 8731 }
8732 } 8732 }
8733 break; 8733 break;
8734   8734  
8735 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8735 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8736 shape = part.Shape; 8736 shape = part.Shape;
8737   8737  
8738 if (shape.LightEntry) 8738 if (shape.LightEntry)
8739 res.Add(new LSL_Integer(1)); // active 8739 res.Add(new LSL_Integer(1)); // active
8740 else 8740 else
8741 res.Add(new LSL_Integer(0)); 8741 res.Add(new LSL_Integer(0));
8742 res.Add(new LSL_Vector(shape.LightColorR, // color 8742 res.Add(new LSL_Vector(shape.LightColorR, // color
8743 shape.LightColorG, 8743 shape.LightColorG,
8744 shape.LightColorB)); 8744 shape.LightColorB));
8745 res.Add(new LSL_Float(shape.LightIntensity)); // intensity 8745 res.Add(new LSL_Float(shape.LightIntensity)); // intensity
8746 res.Add(new LSL_Float(shape.LightRadius)); // radius 8746 res.Add(new LSL_Float(shape.LightRadius)); // radius
8747 res.Add(new LSL_Float(shape.LightFalloff)); // falloff 8747 res.Add(new LSL_Float(shape.LightFalloff)); // falloff
8748 break; 8748 break;
8749   8749  
8750 case (int)ScriptBaseClass.PRIM_GLOW: 8750 case (int)ScriptBaseClass.PRIM_GLOW:
8751 if (remain < 1) 8751 if (remain < 1)
8752 return null; 8752 return null;
8753   8753  
8754 face=(int)rules.GetLSLIntegerItem(idx++); 8754 face=(int)rules.GetLSLIntegerItem(idx++);
8755   8755  
8756 tex = part.Shape.Textures; 8756 tex = part.Shape.Textures;
8757 if (face == ScriptBaseClass.ALL_SIDES) 8757 if (face == ScriptBaseClass.ALL_SIDES)
8758 { 8758 {
8759 for (face = 0; face < GetNumberOfSides(part); face++) 8759 for (face = 0; face < GetNumberOfSides(part); face++)
8760 { 8760 {
8761 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8761 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8762 res.Add(new LSL_Float(texface.Glow)); 8762 res.Add(new LSL_Float(texface.Glow));
8763 } 8763 }
8764 } 8764 }
8765 else 8765 else
8766 { 8766 {
8767 if (face >= 0 && face < GetNumberOfSides(part)) 8767 if (face >= 0 && face < GetNumberOfSides(part))
8768 { 8768 {
8769 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8769 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8770 res.Add(new LSL_Float(texface.Glow)); 8770 res.Add(new LSL_Float(texface.Glow));
8771 } 8771 }
8772 } 8772 }
8773 break; 8773 break;
8774   8774  
8775 case (int)ScriptBaseClass.PRIM_TEXT: 8775 case (int)ScriptBaseClass.PRIM_TEXT:
8776 Color4 textColor = part.GetTextColor(); 8776 Color4 textColor = part.GetTextColor();
8777 res.Add(new LSL_String(part.Text)); 8777 res.Add(new LSL_String(part.Text));
8778 res.Add(new LSL_Vector(textColor.R, 8778 res.Add(new LSL_Vector(textColor.R,
8779 textColor.G, 8779 textColor.G,
8780 textColor.B)); 8780 textColor.B));
8781 res.Add(new LSL_Float(textColor.A)); 8781 res.Add(new LSL_Float(textColor.A));
8782 break; 8782 break;
8783 case (int)ScriptBaseClass.PRIM_NAME: 8783 case (int)ScriptBaseClass.PRIM_NAME:
8784 res.Add(new LSL_String(part.Name)); 8784 res.Add(new LSL_String(part.Name));
8785 break; 8785 break;
8786 case (int)ScriptBaseClass.PRIM_DESC: 8786 case (int)ScriptBaseClass.PRIM_DESC:
8787 res.Add(new LSL_String(part.Description)); 8787 res.Add(new LSL_String(part.Description));
8788 break; 8788 break;
8789 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8789 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8790 res.Add(new LSL_Rotation(part.RotationOffset)); 8790 res.Add(new LSL_Rotation(part.RotationOffset));
8791 break; 8791 break;
8792 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8792 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8793 res.Add(new LSL_Vector(GetPartLocalPos(part))); 8793 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8794 break; 8794 break;
8795 case (int)ScriptBaseClass.PRIM_SLICE: 8795 case (int)ScriptBaseClass.PRIM_SLICE:
8796 PrimType prim_type = part.GetPrimType(); 8796 PrimType prim_type = part.GetPrimType();
8797 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); 8797 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
8798 res.Add(new LSL_Vector( 8798 res.Add(new LSL_Vector(
8799 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0, 8799 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
8800 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0, 8800 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
8801 0 8801 0
8802 )); 8802 ));
8803 break; 8803 break;
8804 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8804 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8805   8805  
8806 // TODO: Should be issuing a runtime script warning in this case. 8806 // TODO: Should be issuing a runtime script warning in this case.
8807 if (remain < 2) 8807 if (remain < 2)
8808 return null; 8808 return null;
8809   8809  
8810 return rules.GetSublist(idx, -1); 8810 return rules.GetSublist(idx, -1);
8811 } 8811 }
8812 } 8812 }
8813   8813  
8814 return null; 8814 return null;
8815 } 8815 }
8816   8816  
8817 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 8817 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
8818 { 8818 {
8819 m_host.AddScriptLPS(1); 8819 m_host.AddScriptLPS(1);
8820 ScriptSleep(1000); 8820 ScriptSleep(1000);
8821 return GetPrimMediaParams(m_host, face, rules); 8821 return GetPrimMediaParams(m_host, face, rules);
8822 } 8822 }
8823   8823  
8824 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 8824 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
8825 { 8825 {
8826 m_host.AddScriptLPS(1); 8826 m_host.AddScriptLPS(1);
8827 ScriptSleep(1000); 8827 ScriptSleep(1000);
8828 if (link == ScriptBaseClass.LINK_ROOT) 8828 if (link == ScriptBaseClass.LINK_ROOT)
8829 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 8829 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
8830 else if (link == ScriptBaseClass.LINK_THIS) 8830 else if (link == ScriptBaseClass.LINK_THIS)
8831 return GetPrimMediaParams(m_host, face, rules); 8831 return GetPrimMediaParams(m_host, face, rules);
8832 else 8832 else
8833 { 8833 {
8834 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 8834 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
8835 if (null != part) 8835 if (null != part)
8836 return GetPrimMediaParams(part, face, rules); 8836 return GetPrimMediaParams(part, face, rules);
8837 } 8837 }
8838   8838  
8839 return new LSL_List(); 8839 return new LSL_List();
8840 } 8840 }
8841   8841  
8842 private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules) 8842 private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules)
8843 { 8843 {
8844 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid 8844 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
8845 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list). 8845 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
8846 // Assuming silently fail means give back an empty list. Ideally, need to check this. 8846 // Assuming silently fail means give back an empty list. Ideally, need to check this.
8847 if (face < 0 || face > part.GetNumberOfSides() - 1) 8847 if (face < 0 || face > part.GetNumberOfSides() - 1)
8848 return new LSL_List(); 8848 return new LSL_List();
8849   8849  
8850 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 8850 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8851 if (null == module) 8851 if (null == module)
8852 return new LSL_List(); 8852 return new LSL_List();
8853   8853  
8854 MediaEntry me = module.GetMediaEntry(part, face); 8854 MediaEntry me = module.GetMediaEntry(part, face);
8855   8855  
8856 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams 8856 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
8857 if (null == me) 8857 if (null == me)
8858 return new LSL_List(); 8858 return new LSL_List();
8859   8859  
8860 LSL_List res = new LSL_List(); 8860 LSL_List res = new LSL_List();
8861   8861  
8862 for (int i = 0; i < rules.Length; i++) 8862 for (int i = 0; i < rules.Length; i++)
8863 { 8863 {
8864 int code = (int)rules.GetLSLIntegerItem(i); 8864 int code = (int)rules.GetLSLIntegerItem(i);
8865   8865  
8866 switch (code) 8866 switch (code)
8867 { 8867 {
8868 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: 8868 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8869 // Not implemented 8869 // Not implemented
8870 res.Add(new LSL_Integer(0)); 8870 res.Add(new LSL_Integer(0));
8871 break; 8871 break;
8872   8872  
8873 case ScriptBaseClass.PRIM_MEDIA_CONTROLS: 8873 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8874 if (me.Controls == MediaControls.Standard) 8874 if (me.Controls == MediaControls.Standard)
8875 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD)); 8875 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
8876 else 8876 else
8877 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI)); 8877 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
8878 break; 8878 break;
8879   8879  
8880 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: 8880 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
8881 res.Add(new LSL_String(me.CurrentURL)); 8881 res.Add(new LSL_String(me.CurrentURL));
8882 break; 8882 break;
8883   8883  
8884 case ScriptBaseClass.PRIM_MEDIA_HOME_URL: 8884 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8885 res.Add(new LSL_String(me.HomeURL)); 8885 res.Add(new LSL_String(me.HomeURL));
8886 break; 8886 break;
8887   8887  
8888 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: 8888 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8889 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8889 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8890 break; 8890 break;
8891   8891  
8892 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: 8892 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
8893 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8893 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8894 break; 8894 break;
8895   8895  
8896 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: 8896 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
8897 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8897 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8898 break; 8898 break;
8899   8899  
8900 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: 8900 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
8901 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8901 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8902 break; 8902 break;
8903   8903  
8904 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: 8904 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
8905 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8905 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8906 break; 8906 break;
8907   8907  
8908 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: 8908 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
8909 res.Add(new LSL_Integer(me.Width)); 8909 res.Add(new LSL_Integer(me.Width));
8910 break; 8910 break;
8911   8911  
8912 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: 8912 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
8913 res.Add(new LSL_Integer(me.Height)); 8913 res.Add(new LSL_Integer(me.Height));
8914 break; 8914 break;
8915   8915  
8916 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: 8916 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
8917 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8917 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8918 break; 8918 break;
8919   8919  
8920 case ScriptBaseClass.PRIM_MEDIA_WHITELIST: 8920 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
8921 string[] urls = (string[])me.WhiteList.Clone(); 8921 string[] urls = (string[])me.WhiteList.Clone();
8922   8922  
8923 for (int j = 0; j < urls.Length; j++) 8923 for (int j = 0; j < urls.Length; j++)
8924 urls[j] = Uri.EscapeDataString(urls[j]); 8924 urls[j] = Uri.EscapeDataString(urls[j]);
8925   8925  
8926 res.Add(new LSL_String(string.Join(", ", urls))); 8926 res.Add(new LSL_String(string.Join(", ", urls)));
8927 break; 8927 break;
8928   8928  
8929 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: 8929 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
8930 res.Add(new LSL_Integer((int)me.InteractPermissions)); 8930 res.Add(new LSL_Integer((int)me.InteractPermissions));
8931 break; 8931 break;
8932   8932  
8933 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: 8933 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
8934 res.Add(new LSL_Integer((int)me.ControlPermissions)); 8934 res.Add(new LSL_Integer((int)me.ControlPermissions));
8935 break; 8935 break;
8936   8936  
8937 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS; 8937 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS;
8938 } 8938 }
8939 } 8939 }
8940   8940  
8941 return res; 8941 return res;
8942 } 8942 }
8943   8943  
8944 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules) 8944 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules)
8945 { 8945 {
8946 m_host.AddScriptLPS(1); 8946 m_host.AddScriptLPS(1);
8947 ScriptSleep(1000); 8947 ScriptSleep(1000);
8948 return SetPrimMediaParams(m_host, face, rules); 8948 return SetPrimMediaParams(m_host, face, rules);
8949 } 8949 }
8950   8950  
8951 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 8951 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
8952 { 8952 {
8953 m_host.AddScriptLPS(1); 8953 m_host.AddScriptLPS(1);
8954 ScriptSleep(1000); 8954 ScriptSleep(1000);
8955 if (link == ScriptBaseClass.LINK_ROOT) 8955 if (link == ScriptBaseClass.LINK_ROOT)
8956 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 8956 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
8957 else if (link == ScriptBaseClass.LINK_THIS) 8957 else if (link == ScriptBaseClass.LINK_THIS)
8958 return SetPrimMediaParams(m_host, face, rules); 8958 return SetPrimMediaParams(m_host, face, rules);
8959 else 8959 else
8960 { 8960 {
8961 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 8961 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
8962 if (null != part) 8962 if (null != part)
8963 return SetPrimMediaParams(part, face, rules); 8963 return SetPrimMediaParams(part, face, rules);
8964 } 8964 }
8965   8965  
8966 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 8966 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
8967 } 8967 }
8968   8968  
8969 private LSL_Integer SetPrimMediaParams(SceneObjectPart part, LSL_Integer face, LSL_List rules) 8969 private LSL_Integer SetPrimMediaParams(SceneObjectPart part, LSL_Integer face, LSL_List rules)
8970 { 8970 {
8971 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid 8971 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
8972 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. 8972 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
8973 // Don't perform the media check directly 8973 // Don't perform the media check directly
8974 if (face < 0 || face > part.GetNumberOfSides() - 1) 8974 if (face < 0 || face > part.GetNumberOfSides() - 1)
8975 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 8975 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
8976   8976  
8977 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 8977 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8978 if (null == module) 8978 if (null == module)
8979 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED; 8979 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED;
8980   8980  
8981 MediaEntry me = module.GetMediaEntry(part, face); 8981 MediaEntry me = module.GetMediaEntry(part, face);
8982 if (null == me) 8982 if (null == me)
8983 me = new MediaEntry(); 8983 me = new MediaEntry();
8984   8984  
8985 int i = 0; 8985 int i = 0;
8986   8986  
8987 while (i < rules.Length - 1) 8987 while (i < rules.Length - 1)
8988 { 8988 {
8989 int code = rules.GetLSLIntegerItem(i++); 8989 int code = rules.GetLSLIntegerItem(i++);
8990   8990  
8991 switch (code) 8991 switch (code)
8992 { 8992 {
8993 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: 8993 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8994 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false); 8994 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
8995 break; 8995 break;
8996   8996  
8997 case ScriptBaseClass.PRIM_MEDIA_CONTROLS: 8997 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8998 int v = rules.GetLSLIntegerItem(i++); 8998 int v = rules.GetLSLIntegerItem(i++);
8999 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v) 8999 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
9000 me.Controls = MediaControls.Standard; 9000 me.Controls = MediaControls.Standard;
9001 else 9001 else
9002 me.Controls = MediaControls.Mini; 9002 me.Controls = MediaControls.Mini;
9003 break; 9003 break;
9004   9004  
9005 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: 9005 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
9006 me.CurrentURL = rules.GetLSLStringItem(i++); 9006 me.CurrentURL = rules.GetLSLStringItem(i++);
9007 break; 9007 break;
9008   9008  
9009 case ScriptBaseClass.PRIM_MEDIA_HOME_URL: 9009 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
9010 me.HomeURL = rules.GetLSLStringItem(i++); 9010 me.HomeURL = rules.GetLSLStringItem(i++);
9011 break; 9011 break;
9012   9012  
9013 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: 9013 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
9014 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9014 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9015 break; 9015 break;
9016   9016  
9017 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: 9017 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
9018 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9018 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9019 break; 9019 break;
9020   9020  
9021 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: 9021 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
9022 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9022 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9023 break; 9023 break;
9024   9024  
9025 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: 9025 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
9026 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9026 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9027 break; 9027 break;
9028   9028  
9029 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: 9029 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
9030 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9030 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9031 break; 9031 break;
9032   9032  
9033 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: 9033 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
9034 me.Width = (int)rules.GetLSLIntegerItem(i++); 9034 me.Width = (int)rules.GetLSLIntegerItem(i++);
9035 break; 9035 break;
9036   9036  
9037 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: 9037 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
9038 me.Height = (int)rules.GetLSLIntegerItem(i++); 9038 me.Height = (int)rules.GetLSLIntegerItem(i++);
9039 break; 9039 break;
9040   9040  
9041 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: 9041 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
9042 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9042 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9043 break; 9043 break;
9044   9044  
9045 case ScriptBaseClass.PRIM_MEDIA_WHITELIST: 9045 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
9046 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' }); 9046 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
9047 List<string> whiteListUrls = new List<string>(); 9047 List<string> whiteListUrls = new List<string>();
9048 Array.ForEach( 9048 Array.ForEach(
9049 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); }); 9049 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
9050 me.WhiteList = whiteListUrls.ToArray(); 9050 me.WhiteList = whiteListUrls.ToArray();
9051 break; 9051 break;
9052   9052  
9053 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: 9053 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
9054 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); 9054 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
9055 break; 9055 break;
9056   9056  
9057 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: 9057 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
9058 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); 9058 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
9059 break; 9059 break;
9060   9060  
9061 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS; 9061 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS;
9062 } 9062 }
9063 } 9063 }
9064   9064  
9065 module.SetMediaEntry(part, face, me); 9065 module.SetMediaEntry(part, face, me);
9066   9066  
9067 return ScriptBaseClass.LSL_STATUS_OK; 9067 return ScriptBaseClass.LSL_STATUS_OK;
9068 } 9068 }
9069   9069  
9070 public LSL_Integer llClearPrimMedia(LSL_Integer face) 9070 public LSL_Integer llClearPrimMedia(LSL_Integer face)
9071 { 9071 {
9072 m_host.AddScriptLPS(1); 9072 m_host.AddScriptLPS(1);
9073 ScriptSleep(1000); 9073 ScriptSleep(1000);
9074 return ClearPrimMedia(m_host, face); 9074 return ClearPrimMedia(m_host, face);
9075 } 9075 }
9076   9076  
9077 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face) 9077 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face)
9078 { 9078 {
9079 m_host.AddScriptLPS(1); 9079 m_host.AddScriptLPS(1);
9080 ScriptSleep(1000); 9080 ScriptSleep(1000);
9081 if (link == ScriptBaseClass.LINK_ROOT) 9081 if (link == ScriptBaseClass.LINK_ROOT)
9082 return ClearPrimMedia(m_host.ParentGroup.RootPart, face); 9082 return ClearPrimMedia(m_host.ParentGroup.RootPart, face);
9083 else if (link == ScriptBaseClass.LINK_THIS) 9083 else if (link == ScriptBaseClass.LINK_THIS)
9084 return ClearPrimMedia(m_host, face); 9084 return ClearPrimMedia(m_host, face);
9085 else 9085 else
9086 { 9086 {
9087 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 9087 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
9088 if (null != part) 9088 if (null != part)
9089 return ClearPrimMedia(part, face); 9089 return ClearPrimMedia(part, face);
9090 } 9090 }
9091   9091  
9092 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 9092 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
9093 } 9093 }
9094   9094  
9095 private LSL_Integer ClearPrimMedia(SceneObjectPart part, LSL_Integer face) 9095 private LSL_Integer ClearPrimMedia(SceneObjectPart part, LSL_Integer face)
9096 { 9096 {
9097 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid 9097 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
9098 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. 9098 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
9099 // FIXME: Don't perform the media check directly 9099 // FIXME: Don't perform the media check directly
9100 if (face < 0 || face > part.GetNumberOfSides() - 1) 9100 if (face < 0 || face > part.GetNumberOfSides() - 1)
9101 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 9101 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
9102   9102  
9103 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 9103 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
9104 if (null == module) 9104 if (null == module)
9105 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED; 9105 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED;
9106   9106  
9107 module.ClearMediaEntry(part, face); 9107 module.ClearMediaEntry(part, face);
9108   9108  
9109 return ScriptBaseClass.LSL_STATUS_OK; 9109 return ScriptBaseClass.LSL_STATUS_OK;
9110 } 9110 }
9111   9111  
9112 // <remarks> 9112 // <remarks>
9113 // <para> 9113 // <para>
9114 // The .NET definition of base 64 is: 9114 // The .NET definition of base 64 is:
9115 // <list> 9115 // <list>
9116 // <item> 9116 // <item>
9117 // Significant: A-Z a-z 0-9 + - 9117 // Significant: A-Z a-z 0-9 + -
9118 // </item> 9118 // </item>
9119 // <item> 9119 // <item>
9120 // Whitespace: \t \n \r ' ' 9120 // Whitespace: \t \n \r ' '
9121 // </item> 9121 // </item>
9122 // <item> 9122 // <item>
9123 // Valueless: = 9123 // Valueless: =
9124 // </item> 9124 // </item>
9125 // <item> 9125 // <item>
9126 // End-of-string: \0 or '==' 9126 // End-of-string: \0 or '=='
9127 // </item> 9127 // </item>
9128 // </list> 9128 // </list>
9129 // </para> 9129 // </para>
9130 // <para> 9130 // <para>
9131 // Each point in a base-64 string represents 9131 // Each point in a base-64 string represents
9132 // a 6 bit value. A 32-bit integer can be 9132 // a 6 bit value. A 32-bit integer can be
9133 // represented using 6 characters (with some 9133 // represented using 6 characters (with some
9134 // redundancy). 9134 // redundancy).
9135 // </para> 9135 // </para>
9136 // <para> 9136 // <para>
9137 // LSL requires a base64 string to be 8 9137 // LSL requires a base64 string to be 8
9138 // characters in length. LSL also uses '/' 9138 // characters in length. LSL also uses '/'
9139 // rather than '-' (MIME compliant). 9139 // rather than '-' (MIME compliant).
9140 // </para> 9140 // </para>
9141 // <para> 9141 // <para>
9142 // RFC 1341 used as a reference (as specified 9142 // RFC 1341 used as a reference (as specified
9143 // by the SecondLife Wiki). 9143 // by the SecondLife Wiki).
9144 // </para> 9144 // </para>
9145 // <para> 9145 // <para>
9146 // SL do not record any kind of exception for 9146 // SL do not record any kind of exception for
9147 // these functions, so the string to integer 9147 // these functions, so the string to integer
9148 // conversion returns '0' if an invalid 9148 // conversion returns '0' if an invalid
9149 // character is encountered during conversion. 9149 // character is encountered during conversion.
9150 // </para> 9150 // </para>
9151 // <para> 9151 // <para>
9152 // References 9152 // References
9153 // <list> 9153 // <list>
9154 // <item> 9154 // <item>
9155 // http://lslwiki.net/lslwiki/wakka.php?wakka=Base64 9155 // http://lslwiki.net/lslwiki/wakka.php?wakka=Base64
9156 // </item> 9156 // </item>
9157 // <item> 9157 // <item>
9158 // </item> 9158 // </item>
9159 // </list> 9159 // </list>
9160 // </para> 9160 // </para>
9161 // </remarks> 9161 // </remarks>
9162   9162  
9163 // <summary> 9163 // <summary>
9164 // Table for converting 6-bit integers into 9164 // Table for converting 6-bit integers into
9165 // base-64 characters 9165 // base-64 characters
9166 // </summary> 9166 // </summary>
9167   9167  
9168 protected static readonly char[] i2ctable = 9168 protected static readonly char[] i2ctable =
9169 { 9169 {
9170 'A','B','C','D','E','F','G','H', 9170 'A','B','C','D','E','F','G','H',
9171 'I','J','K','L','M','N','O','P', 9171 'I','J','K','L','M','N','O','P',
9172 'Q','R','S','T','U','V','W','X', 9172 'Q','R','S','T','U','V','W','X',
9173 'Y','Z', 9173 'Y','Z',
9174 'a','b','c','d','e','f','g','h', 9174 'a','b','c','d','e','f','g','h',
9175 'i','j','k','l','m','n','o','p', 9175 'i','j','k','l','m','n','o','p',
9176 'q','r','s','t','u','v','w','x', 9176 'q','r','s','t','u','v','w','x',
9177 'y','z', 9177 'y','z',
9178 '0','1','2','3','4','5','6','7', 9178 '0','1','2','3','4','5','6','7',
9179 '8','9', 9179 '8','9',
9180 '+','/' 9180 '+','/'
9181 }; 9181 };
9182   9182  
9183 // <summary> 9183 // <summary>
9184 // Table for converting base-64 characters 9184 // Table for converting base-64 characters
9185 // into 6-bit integers. 9185 // into 6-bit integers.
9186 // </summary> 9186 // </summary>
9187   9187  
9188 protected static readonly int[] c2itable = 9188 protected static readonly int[] c2itable =
9189 { 9189 {
9190 -1,-1,-1,-1,-1,-1,-1,-1, // 0x 9190 -1,-1,-1,-1,-1,-1,-1,-1, // 0x
9191 -1,-1,-1,-1,-1,-1,-1,-1, 9191 -1,-1,-1,-1,-1,-1,-1,-1,
9192 -1,-1,-1,-1,-1,-1,-1,-1, // 1x 9192 -1,-1,-1,-1,-1,-1,-1,-1, // 1x
9193 -1,-1,-1,-1,-1,-1,-1,-1, 9193 -1,-1,-1,-1,-1,-1,-1,-1,
9194 -1,-1,-1,-1,-1,-1,-1,-1, // 2x 9194 -1,-1,-1,-1,-1,-1,-1,-1, // 2x
9195 -1,-1,-1,63,-1,-1,-1,64, 9195 -1,-1,-1,63,-1,-1,-1,64,
9196 53,54,55,56,57,58,59,60, // 3x 9196 53,54,55,56,57,58,59,60, // 3x
9197 61,62,-1,-1,-1,0,-1,-1, 9197 61,62,-1,-1,-1,0,-1,-1,
9198 -1,1,2,3,4,5,6,7, // 4x 9198 -1,1,2,3,4,5,6,7, // 4x
9199 8,9,10,11,12,13,14,15, 9199 8,9,10,11,12,13,14,15,
9200 16,17,18,19,20,21,22,23, // 5x 9200 16,17,18,19,20,21,22,23, // 5x
9201 24,25,26,-1,-1,-1,-1,-1, 9201 24,25,26,-1,-1,-1,-1,-1,
9202 -1,27,28,29,30,31,32,33, // 6x 9202 -1,27,28,29,30,31,32,33, // 6x
9203 34,35,36,37,38,39,40,41, 9203 34,35,36,37,38,39,40,41,
9204 42,43,44,45,46,47,48,49, // 7x 9204 42,43,44,45,46,47,48,49, // 7x
9205 50,51,52,-1,-1,-1,-1,-1, 9205 50,51,52,-1,-1,-1,-1,-1,
9206 -1,-1,-1,-1,-1,-1,-1,-1, // 8x 9206 -1,-1,-1,-1,-1,-1,-1,-1, // 8x
9207 -1,-1,-1,-1,-1,-1,-1,-1, 9207 -1,-1,-1,-1,-1,-1,-1,-1,
9208 -1,-1,-1,-1,-1,-1,-1,-1, // 9x 9208 -1,-1,-1,-1,-1,-1,-1,-1, // 9x
9209 -1,-1,-1,-1,-1,-1,-1,-1, 9209 -1,-1,-1,-1,-1,-1,-1,-1,
9210 -1,-1,-1,-1,-1,-1,-1,-1, // Ax 9210 -1,-1,-1,-1,-1,-1,-1,-1, // Ax
9211 -1,-1,-1,-1,-1,-1,-1,-1, 9211 -1,-1,-1,-1,-1,-1,-1,-1,
9212 -1,-1,-1,-1,-1,-1,-1,-1, // Bx 9212 -1,-1,-1,-1,-1,-1,-1,-1, // Bx
9213 -1,-1,-1,-1,-1,-1,-1,-1, 9213 -1,-1,-1,-1,-1,-1,-1,-1,
9214 -1,-1,-1,-1,-1,-1,-1,-1, // Cx 9214 -1,-1,-1,-1,-1,-1,-1,-1, // Cx
9215 -1,-1,-1,-1,-1,-1,-1,-1, 9215 -1,-1,-1,-1,-1,-1,-1,-1,
9216 -1,-1,-1,-1,-1,-1,-1,-1, // Dx 9216 -1,-1,-1,-1,-1,-1,-1,-1, // Dx
9217 -1,-1,-1,-1,-1,-1,-1,-1, 9217 -1,-1,-1,-1,-1,-1,-1,-1,
9218 -1,-1,-1,-1,-1,-1,-1,-1, // Ex 9218 -1,-1,-1,-1,-1,-1,-1,-1, // Ex
9219 -1,-1,-1,-1,-1,-1,-1,-1, 9219 -1,-1,-1,-1,-1,-1,-1,-1,
9220 -1,-1,-1,-1,-1,-1,-1,-1, // Fx 9220 -1,-1,-1,-1,-1,-1,-1,-1, // Fx
9221 -1,-1,-1,-1,-1,-1,-1,-1 9221 -1,-1,-1,-1,-1,-1,-1,-1
9222 }; 9222 };
9223   9223  
9224 // <summary> 9224 // <summary>
9225 // Converts a 32-bit integer into a Base64 9225 // Converts a 32-bit integer into a Base64
9226 // character string. Base64 character strings 9226 // character string. Base64 character strings
9227 // are always 8 characters long. All iinteger 9227 // are always 8 characters long. All iinteger
9228 // values are acceptable. 9228 // values are acceptable.
9229 // </summary> 9229 // </summary>
9230 // <param name="number"> 9230 // <param name="number">
9231 // 32-bit integer to be converted. 9231 // 32-bit integer to be converted.
9232 // </param> 9232 // </param>
9233 // <returns> 9233 // <returns>
9234 // 8 character string. The 1st six characters 9234 // 8 character string. The 1st six characters
9235 // contain the encoded number, the last two 9235 // contain the encoded number, the last two
9236 // characters are padded with "=". 9236 // characters are padded with "=".
9237 // </returns> 9237 // </returns>
9238   9238  
9239 public LSL_String llIntegerToBase64(int number) 9239 public LSL_String llIntegerToBase64(int number)
9240 { 9240 {
9241 // uninitialized string 9241 // uninitialized string
9242   9242  
9243 char[] imdt = new char[8]; 9243 char[] imdt = new char[8];
9244   9244  
9245 m_host.AddScriptLPS(1); 9245 m_host.AddScriptLPS(1);
9246   9246  
9247 // Manually unroll the loop 9247 // Manually unroll the loop
9248   9248  
9249 imdt[7] = '='; 9249 imdt[7] = '=';
9250 imdt[6] = '='; 9250 imdt[6] = '=';
9251 imdt[5] = i2ctable[number<<4 & 0x3F]; 9251 imdt[5] = i2ctable[number<<4 & 0x3F];
9252 imdt[4] = i2ctable[number>>2 & 0x3F]; 9252 imdt[4] = i2ctable[number>>2 & 0x3F];
9253 imdt[3] = i2ctable[number>>8 & 0x3F]; 9253 imdt[3] = i2ctable[number>>8 & 0x3F];
9254 imdt[2] = i2ctable[number>>14 & 0x3F]; 9254 imdt[2] = i2ctable[number>>14 & 0x3F];
9255 imdt[1] = i2ctable[number>>20 & 0x3F]; 9255 imdt[1] = i2ctable[number>>20 & 0x3F];
9256 imdt[0] = i2ctable[number>>26 & 0x3F]; 9256 imdt[0] = i2ctable[number>>26 & 0x3F];
9257   9257  
9258 return new string(imdt); 9258 return new string(imdt);
9259 } 9259 }
9260   9260  
9261 // <summary> 9261 // <summary>
9262 // Converts an eight character base-64 string 9262 // Converts an eight character base-64 string
9263 // into a 32-bit integer. 9263 // into a 32-bit integer.
9264 // </summary> 9264 // </summary>
9265 // <param name="str"> 9265 // <param name="str">
9266 // 8 characters string to be converted. Other 9266 // 8 characters string to be converted. Other
9267 // length strings return zero. 9267 // length strings return zero.
9268 // </param> 9268 // </param>
9269 // <returns> 9269 // <returns>
9270 // Returns an integer representing the 9270 // Returns an integer representing the
9271 // encoded value providedint he 1st 6 9271 // encoded value providedint he 1st 6
9272 // characters of the string. 9272 // characters of the string.
9273 // </returns> 9273 // </returns>
9274 // <remarks> 9274 // <remarks>
9275 // This is coded to behave like LSL's 9275 // This is coded to behave like LSL's
9276 // implementation (I think), based upon the 9276 // implementation (I think), based upon the
9277 // information available at the Wiki. 9277 // information available at the Wiki.
9278 // If more than 8 characters are supplied, 9278 // If more than 8 characters are supplied,
9279 // zero is returned. 9279 // zero is returned.
9280 // If a NULL string is supplied, zero will 9280 // If a NULL string is supplied, zero will
9281 // be returned. 9281 // be returned.
9282 // If fewer than 6 characters are supplied, then 9282 // If fewer than 6 characters are supplied, then
9283 // the answer will reflect a partial 9283 // the answer will reflect a partial
9284 // accumulation. 9284 // accumulation.
9285 // <para> 9285 // <para>
9286 // The 6-bit segments are 9286 // The 6-bit segments are
9287 // extracted left-to-right in big-endian mode, 9287 // extracted left-to-right in big-endian mode,
9288 // which means that segment 6 only contains the 9288 // which means that segment 6 only contains the
9289 // two low-order bits of the 32 bit integer as 9289 // two low-order bits of the 32 bit integer as
9290 // its high order 2 bits. A short string therefore 9290 // its high order 2 bits. A short string therefore
9291 // means loss of low-order information. E.g. 9291 // means loss of low-order information. E.g.
9292 // 9292 //
9293 // |<---------------------- 32-bit integer ----------------------->|<-Pad->| 9293 // |<---------------------- 32-bit integer ----------------------->|<-Pad->|
9294 // |<--Byte 0----->|<--Byte 1----->|<--Byte 2----->|<--Byte 3----->|<-Pad->| 9294 // |<--Byte 0----->|<--Byte 1----->|<--Byte 2----->|<--Byte 3----->|<-Pad->|
9295 // |3|3|2|2|2|2|2|2|2|2|2|2|1|1|1|1|1|1|1|1|1|1| | | | | | | | | | |P|P|P|P| 9295 // |3|3|2|2|2|2|2|2|2|2|2|2|1|1|1|1|1|1|1|1|1|1| | | | | | | | | | |P|P|P|P|
9296 // |1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|P|P|P|P| 9296 // |1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|9|8|7|6|5|4|3|2|1|0|P|P|P|P|
9297 // | str[0] | str[1] | str[2] | str[3] | str[4] | str[6] | 9297 // | str[0] | str[1] | str[2] | str[3] | str[4] | str[6] |
9298 // 9298 //
9299 // </para> 9299 // </para>
9300 // </remarks> 9300 // </remarks>
9301   9301  
9302 public LSL_Integer llBase64ToInteger(string str) 9302 public LSL_Integer llBase64ToInteger(string str)
9303 { 9303 {
9304 int number = 0; 9304 int number = 0;
9305 int digit; 9305 int digit;
9306   9306  
9307 m_host.AddScriptLPS(1); 9307 m_host.AddScriptLPS(1);
9308   9308  
9309 // Require a well-fromed base64 string 9309 // Require a well-fromed base64 string
9310   9310  
9311 if (str.Length > 8) 9311 if (str.Length > 8)
9312 return 0; 9312 return 0;
9313   9313  
9314 // The loop is unrolled in the interests 9314 // The loop is unrolled in the interests
9315 // of performance and simple necessity. 9315 // of performance and simple necessity.
9316 // 9316 //
9317 // MUST find 6 digits to be well formed 9317 // MUST find 6 digits to be well formed
9318 // -1 == invalid 9318 // -1 == invalid
9319 // 0 == padding 9319 // 0 == padding
9320   9320  
9321 if ((digit = c2itable[str[0]]) <= 0) 9321 if ((digit = c2itable[str[0]]) <= 0)
9322 { 9322 {
9323 return digit < 0 ? (int)0 : number; 9323 return digit < 0 ? (int)0 : number;
9324 } 9324 }
9325 number += --digit<<26; 9325 number += --digit<<26;
9326   9326  
9327 if ((digit = c2itable[str[1]]) <= 0) 9327 if ((digit = c2itable[str[1]]) <= 0)
9328 { 9328 {
9329 return digit < 0 ? (int)0 : number; 9329 return digit < 0 ? (int)0 : number;
9330 } 9330 }
9331 number += --digit<<20; 9331 number += --digit<<20;
9332   9332  
9333 if ((digit = c2itable[str[2]]) <= 0) 9333 if ((digit = c2itable[str[2]]) <= 0)
9334 { 9334 {
9335 return digit < 0 ? (int)0 : number; 9335 return digit < 0 ? (int)0 : number;
9336 } 9336 }
9337 number += --digit<<14; 9337 number += --digit<<14;
9338   9338  
9339 if ((digit = c2itable[str[3]]) <= 0) 9339 if ((digit = c2itable[str[3]]) <= 0)
9340 { 9340 {
9341 return digit < 0 ? (int)0 : number; 9341 return digit < 0 ? (int)0 : number;
9342 } 9342 }
9343 number += --digit<<8; 9343 number += --digit<<8;
9344   9344  
9345 if ((digit = c2itable[str[4]]) <= 0) 9345 if ((digit = c2itable[str[4]]) <= 0)
9346 { 9346 {
9347 return digit < 0 ? (int)0 : number; 9347 return digit < 0 ? (int)0 : number;
9348 } 9348 }
9349 number += --digit<<2; 9349 number += --digit<<2;
9350   9350  
9351 if ((digit = c2itable[str[5]]) <= 0) 9351 if ((digit = c2itable[str[5]]) <= 0)
9352 { 9352 {
9353 return digit < 0 ? (int)0 : number; 9353 return digit < 0 ? (int)0 : number;
9354 } 9354 }
9355 number += --digit>>4; 9355 number += --digit>>4;
9356   9356  
9357 // ignore trailing padding 9357 // ignore trailing padding
9358   9358  
9359 return number; 9359 return number;
9360 } 9360 }
9361   9361  
9362 public LSL_Float llGetGMTclock() 9362 public LSL_Float llGetGMTclock()
9363 { 9363 {
9364 m_host.AddScriptLPS(1); 9364 m_host.AddScriptLPS(1);
9365 return DateTime.UtcNow.TimeOfDay.TotalSeconds; 9365 return DateTime.UtcNow.TimeOfDay.TotalSeconds;
9366 } 9366 }
9367   9367  
9368 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) 9368 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header)
9369 { 9369 {
9370 m_host.AddScriptLPS(1); 9370 m_host.AddScriptLPS(1);
9371   9371  
9372 if (m_UrlModule != null) 9372 if (m_UrlModule != null)
9373 return m_UrlModule.GetHttpHeader(new UUID(request_id), header); 9373 return m_UrlModule.GetHttpHeader(new UUID(request_id), header);
9374 return String.Empty; 9374 return String.Empty;
9375 } 9375 }
9376   9376  
9377   9377  
9378 public LSL_String llGetSimulatorHostname() 9378 public LSL_String llGetSimulatorHostname()
9379 { 9379 {
9380 m_host.AddScriptLPS(1); 9380 m_host.AddScriptLPS(1);
9381 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); 9381 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
9382 return UrlModule.ExternalHostNameForLSL; 9382 return UrlModule.ExternalHostNameForLSL;
9383 } 9383 }
9384   9384  
9385 // <summary> 9385 // <summary>
9386 // Scan the string supplied in 'src' and 9386 // Scan the string supplied in 'src' and
9387 // tokenize it based upon two sets of 9387 // tokenize it based upon two sets of
9388 // tokenizers provided in two lists, 9388 // tokenizers provided in two lists,
9389 // separators and spacers. 9389 // separators and spacers.
9390 // </summary> 9390 // </summary>
9391 // 9391 //
9392 // <remarks> 9392 // <remarks>
9393 // Separators demarcate tokens and are 9393 // Separators demarcate tokens and are
9394 // elided as they are encountered. Spacers 9394 // elided as they are encountered. Spacers
9395 // also demarcate tokens, but are themselves 9395 // also demarcate tokens, but are themselves
9396 // retained as tokens. 9396 // retained as tokens.
9397 // 9397 //
9398 // Both separators and spacers may be arbitrarily 9398 // Both separators and spacers may be arbitrarily
9399 // long strings. i.e. ":::". 9399 // long strings. i.e. ":::".
9400 // 9400 //
9401 // The function returns an ordered list 9401 // The function returns an ordered list
9402 // representing the tokens found in the supplied 9402 // representing the tokens found in the supplied
9403 // sources string. If two successive tokenizers 9403 // sources string. If two successive tokenizers
9404 // are encountered, then a NULL entry is added 9404 // are encountered, then a NULL entry is added
9405 // to the list. 9405 // to the list.
9406 // 9406 //
9407 // It is a precondition that the source and 9407 // It is a precondition that the source and
9408 // toekizer lisst are non-null. If they are null, 9408 // toekizer lisst are non-null. If they are null,
9409 // then a null pointer exception will be thrown 9409 // then a null pointer exception will be thrown
9410 // while their lengths are being determined. 9410 // while their lengths are being determined.
9411 // 9411 //
9412 // A small amount of working memoryis required 9412 // A small amount of working memoryis required
9413 // of approximately 8*#tokenizers. 9413 // of approximately 8*#tokenizers.
9414 // 9414 //
9415 // There are many ways in which this function 9415 // There are many ways in which this function
9416 // can be implemented, this implementation is 9416 // can be implemented, this implementation is
9417 // fairly naive and assumes that when the 9417 // fairly naive and assumes that when the
9418 // function is invooked with a short source 9418 // function is invooked with a short source
9419 // string and/or short lists of tokenizers, then 9419 // string and/or short lists of tokenizers, then
9420 // performance will not be an issue. 9420 // performance will not be an issue.
9421 // 9421 //
9422 // In order to minimize the perofrmance 9422 // In order to minimize the perofrmance
9423 // effects of long strings, or large numbers 9423 // effects of long strings, or large numbers
9424 // of tokeizers, the function skips as far as 9424 // of tokeizers, the function skips as far as
9425 // possible whenever a toekenizer is found, 9425 // possible whenever a toekenizer is found,
9426 // and eliminates redundant tokenizers as soon 9426 // and eliminates redundant tokenizers as soon
9427 // as is possible. 9427 // as is possible.
9428 // 9428 //
9429 // The implementation tries to avoid any copying 9429 // The implementation tries to avoid any copying
9430 // of arrays or other objects. 9430 // of arrays or other objects.
9431 // </remarks> 9431 // </remarks>
9432   9432  
9433 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9433 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9434 { 9434 {
9435 int beginning = 0; 9435 int beginning = 0;
9436 int srclen = src.Length; 9436 int srclen = src.Length;
9437 int seplen = separators.Length; 9437 int seplen = separators.Length;
9438 object[] separray = separators.Data; 9438 object[] separray = separators.Data;
9439 int spclen = spacers.Length; 9439 int spclen = spacers.Length;
9440 object[] spcarray = spacers.Data; 9440 object[] spcarray = spacers.Data;
9441 int mlen = seplen+spclen; 9441 int mlen = seplen+spclen;
9442   9442  
9443 int[] offset = new int[mlen+1]; 9443 int[] offset = new int[mlen+1];
9444 bool[] active = new bool[mlen]; 9444 bool[] active = new bool[mlen];
9445   9445  
9446 int best; 9446 int best;
9447 int j; 9447 int j;
9448   9448  
9449 // Initial capacity reduces resize cost 9449 // Initial capacity reduces resize cost
9450   9450  
9451 LSL_List tokens = new LSL_List(); 9451 LSL_List tokens = new LSL_List();
9452   9452  
9453 // All entries are initially valid 9453 // All entries are initially valid
9454   9454  
9455 for (int i = 0; i < mlen; i++) 9455 for (int i = 0; i < mlen; i++)
9456 active[i] = true; 9456 active[i] = true;
9457   9457  
9458 offset[mlen] = srclen; 9458 offset[mlen] = srclen;
9459   9459  
9460 while (beginning < srclen) 9460 while (beginning < srclen)
9461 { 9461 {
9462   9462  
9463 best = mlen; // as bad as it gets 9463 best = mlen; // as bad as it gets
9464   9464  
9465 // Scan for separators 9465 // Scan for separators
9466   9466  
9467 for (j = 0; j < seplen; j++) 9467 for (j = 0; j < seplen; j++)
9468 { 9468 {
9469 if (separray[j].ToString() == String.Empty) 9469 if (separray[j].ToString() == String.Empty)
9470 active[j] = false; 9470 active[j] = false;
9471   9471  
9472 if (active[j]) 9472 if (active[j])
9473 { 9473 {
9474 // scan all of the markers 9474 // scan all of the markers
9475 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9475 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
9476 { 9476 {
9477 // not present at all 9477 // not present at all
9478 active[j] = false; 9478 active[j] = false;
9479 } 9479 }
9480 else 9480 else
9481 { 9481 {
9482 // present and correct 9482 // present and correct
9483 if (offset[j] < offset[best]) 9483 if (offset[j] < offset[best])
9484 { 9484 {
9485 // closest so far 9485 // closest so far
9486 best = j; 9486 best = j;
9487 if (offset[best] == beginning) 9487 if (offset[best] == beginning)
9488 break; 9488 break;
9489 } 9489 }
9490 } 9490 }
9491 } 9491 }
9492 } 9492 }
9493   9493  
9494 // Scan for spacers 9494 // Scan for spacers
9495   9495  
9496 if (offset[best] != beginning) 9496 if (offset[best] != beginning)
9497 { 9497 {
9498 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9498 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++)
9499 { 9499 {
9500 if (spcarray[j-seplen].ToString() == String.Empty) 9500 if (spcarray[j-seplen].ToString() == String.Empty)
9501 active[j] = false; 9501 active[j] = false;
9502   9502  
9503 if (active[j]) 9503 if (active[j])
9504 { 9504 {
9505 // scan all of the markers 9505 // scan all of the markers
9506 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 9506 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9507 { 9507 {
9508 // not present at all 9508 // not present at all
9509 active[j] = false; 9509 active[j] = false;
9510 } 9510 }
9511 else 9511 else
9512 { 9512 {
9513 // present and correct 9513 // present and correct
9514 if (offset[j] < offset[best]) 9514 if (offset[j] < offset[best])
9515 { 9515 {
9516 // closest so far 9516 // closest so far
9517 best = j; 9517 best = j;
9518 } 9518 }
9519 } 9519 }
9520 } 9520 }
9521 } 9521 }
9522 } 9522 }
9523   9523  
9524 // This is the normal exit from the scanning loop 9524 // This is the normal exit from the scanning loop
9525   9525  
9526 if (best == mlen) 9526 if (best == mlen)
9527 { 9527 {
9528 // no markers were found on this pass 9528 // no markers were found on this pass
9529 // so we're pretty much done 9529 // so we're pretty much done
9530 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0)) 9530 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9531 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); 9531 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9532 break; 9532 break;
9533 } 9533 }
9534   9534  
9535 // Otherwise we just add the newly delimited token 9535 // Otherwise we just add the newly delimited token
9536 // and recalculate where the search should continue. 9536 // and recalculate where the search should continue.
9537 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9537 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0))
9538 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9538 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning)));
9539   9539  
9540 if (best < seplen) 9540 if (best < seplen)
9541 { 9541 {
9542 beginning = offset[best] + (separray[best].ToString()).Length; 9542 beginning = offset[best] + (separray[best].ToString()).Length;
9543 } 9543 }
9544 else 9544 else
9545 { 9545 {
9546 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length; 9546 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9547 string str = spcarray[best - seplen].ToString(); 9547 string str = spcarray[best - seplen].ToString();
9548 if ((keepNulls) || ((!keepNulls) && (str.Length > 0))) 9548 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9549 tokens.Add(new LSL_String(str)); 9549 tokens.Add(new LSL_String(str));
9550 } 9550 }
9551 } 9551 }
9552   9552  
9553 // This an awkward an not very intuitive boundary case. If the 9553 // This an awkward an not very intuitive boundary case. If the
9554 // last substring is a tokenizer, then there is an implied trailing 9554 // last substring is a tokenizer, then there is an implied trailing
9555 // null list entry. Hopefully the single comparison will not be too 9555 // null list entry. Hopefully the single comparison will not be too
9556 // arduous. Alternatively the 'break' could be replced with a return 9556 // arduous. Alternatively the 'break' could be replced with a return
9557 // but that's shabby programming. 9557 // but that's shabby programming.
9558   9558  
9559 if ((beginning == srclen) && (keepNulls)) 9559 if ((beginning == srclen) && (keepNulls))
9560 { 9560 {
9561 if (srclen != 0) 9561 if (srclen != 0)
9562 tokens.Add(new LSL_String("")); 9562 tokens.Add(new LSL_String(""));
9563 } 9563 }
9564   9564  
9565 return tokens; 9565 return tokens;
9566 } 9566 }
9567   9567  
9568 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers) 9568 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9569 { 9569 {
9570 m_host.AddScriptLPS(1); 9570 m_host.AddScriptLPS(1);
9571 return this.ParseString(src, separators, spacers, false); 9571 return this.ParseString(src, separators, spacers, false);
9572 } 9572 }
9573   9573  
9574 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 9574 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9575 { 9575 {
9576 m_host.AddScriptLPS(1); 9576 m_host.AddScriptLPS(1);
9577 return this.ParseString(src, separators, spacers, true); 9577 return this.ParseString(src, separators, spacers, true);
9578 } 9578 }
9579   9579  
9580 public LSL_Integer llGetObjectPermMask(int mask) 9580 public LSL_Integer llGetObjectPermMask(int mask)
9581 { 9581 {
9582 m_host.AddScriptLPS(1); 9582 m_host.AddScriptLPS(1);
9583   9583  
9584 int permmask = 0; 9584 int permmask = 0;
9585   9585  
9586 if (mask == ScriptBaseClass.MASK_BASE)//0 9586 if (mask == ScriptBaseClass.MASK_BASE)//0
9587 { 9587 {
9588 permmask = (int)m_host.BaseMask; 9588 permmask = (int)m_host.BaseMask;
9589 } 9589 }
9590   9590  
9591 else if (mask == ScriptBaseClass.MASK_OWNER)//1 9591 else if (mask == ScriptBaseClass.MASK_OWNER)//1
9592 { 9592 {
9593 permmask = (int)m_host.OwnerMask; 9593 permmask = (int)m_host.OwnerMask;
9594 } 9594 }
9595   9595  
9596 else if (mask == ScriptBaseClass.MASK_GROUP)//2 9596 else if (mask == ScriptBaseClass.MASK_GROUP)//2
9597 { 9597 {
9598 permmask = (int)m_host.GroupMask; 9598 permmask = (int)m_host.GroupMask;
9599 } 9599 }
9600   9600  
9601 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3 9601 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3
9602 { 9602 {
9603 permmask = (int)m_host.EveryoneMask; 9603 permmask = (int)m_host.EveryoneMask;
9604 } 9604 }
9605   9605  
9606 else if (mask == ScriptBaseClass.MASK_NEXT)//4 9606 else if (mask == ScriptBaseClass.MASK_NEXT)//4
9607 { 9607 {
9608 permmask = (int)m_host.NextOwnerMask; 9608 permmask = (int)m_host.NextOwnerMask;
9609 } 9609 }
9610   9610  
9611 return permmask; 9611 return permmask;
9612 } 9612 }
9613   9613  
9614 public void llSetObjectPermMask(int mask, int value) 9614 public void llSetObjectPermMask(int mask, int value)
9615 { 9615 {
9616 m_host.AddScriptLPS(1); 9616 m_host.AddScriptLPS(1);
9617   9617  
9618 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 9618 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
9619 { 9619 {
9620 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 9620 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
9621 { 9621 {
9622 if (mask == ScriptBaseClass.MASK_BASE)//0 9622 if (mask == ScriptBaseClass.MASK_BASE)//0
9623 { 9623 {
9624 m_host.BaseMask = (uint)value; 9624 m_host.BaseMask = (uint)value;
9625 } 9625 }
9626   9626  
9627 else if (mask == ScriptBaseClass.MASK_OWNER)//1 9627 else if (mask == ScriptBaseClass.MASK_OWNER)//1
9628 { 9628 {
9629 m_host.OwnerMask = (uint)value; 9629 m_host.OwnerMask = (uint)value;
9630 } 9630 }
9631   9631  
9632 else if (mask == ScriptBaseClass.MASK_GROUP)//2 9632 else if (mask == ScriptBaseClass.MASK_GROUP)//2
9633 { 9633 {
9634 m_host.GroupMask = (uint)value; 9634 m_host.GroupMask = (uint)value;
9635 } 9635 }
9636   9636  
9637 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3 9637 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3
9638 { 9638 {
9639 m_host.EveryoneMask = (uint)value; 9639 m_host.EveryoneMask = (uint)value;
9640 } 9640 }
9641   9641  
9642 else if (mask == ScriptBaseClass.MASK_NEXT)//4 9642 else if (mask == ScriptBaseClass.MASK_NEXT)//4
9643 { 9643 {
9644 m_host.NextOwnerMask = (uint)value; 9644 m_host.NextOwnerMask = (uint)value;
9645 } 9645 }
9646 } 9646 }
9647 } 9647 }
9648 } 9648 }
9649   9649  
9650 public LSL_Integer llGetInventoryPermMask(string itemName, int mask) 9650 public LSL_Integer llGetInventoryPermMask(string itemName, int mask)
9651 { 9651 {
9652 m_host.AddScriptLPS(1); 9652 m_host.AddScriptLPS(1);
9653   9653  
9654 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9654 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9655   9655  
9656 if (item == null) 9656 if (item == null)
9657 return -1; 9657 return -1;
9658   9658  
9659 switch (mask) 9659 switch (mask)
9660 { 9660 {
9661 case 0: 9661 case 0:
9662 return (int)item.BasePermissions; 9662 return (int)item.BasePermissions;
9663 case 1: 9663 case 1:
9664 return (int)item.CurrentPermissions; 9664 return (int)item.CurrentPermissions;
9665 case 2: 9665 case 2:
9666 return (int)item.GroupPermissions; 9666 return (int)item.GroupPermissions;
9667 case 3: 9667 case 3:
9668 return (int)item.EveryonePermissions; 9668 return (int)item.EveryonePermissions;
9669 case 4: 9669 case 4:
9670 return (int)item.NextPermissions; 9670 return (int)item.NextPermissions;
9671 } 9671 }
9672   9672  
9673 return -1; 9673 return -1;
9674 } 9674 }
9675   9675  
9676 public void llSetInventoryPermMask(string itemName, int mask, int value) 9676 public void llSetInventoryPermMask(string itemName, int mask, int value)
9677 { 9677 {
9678 m_host.AddScriptLPS(1); 9678 m_host.AddScriptLPS(1);
9679   9679  
9680 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 9680 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
9681 { 9681 {
9682 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 9682 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
9683 { 9683 {
9684 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9684 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9685   9685  
9686 if (item != null) 9686 if (item != null)
9687 { 9687 {
9688 switch (mask) 9688 switch (mask)
9689 { 9689 {
9690 case 0: 9690 case 0:
9691 item.BasePermissions = (uint)value; 9691 item.BasePermissions = (uint)value;
9692 break; 9692 break;
9693 case 1: 9693 case 1:
9694 item.CurrentPermissions = (uint)value; 9694 item.CurrentPermissions = (uint)value;
9695 break; 9695 break;
9696 case 2: 9696 case 2:
9697 item.GroupPermissions = (uint)value; 9697 item.GroupPermissions = (uint)value;
9698 break; 9698 break;
9699 case 3: 9699 case 3:
9700 item.EveryonePermissions = (uint)value; 9700 item.EveryonePermissions = (uint)value;
9701 break; 9701 break;
9702 case 4: 9702 case 4:
9703 item.NextPermissions = (uint)value; 9703 item.NextPermissions = (uint)value;
9704 break; 9704 break;
9705 } 9705 }
9706 } 9706 }
9707 } 9707 }
9708 } 9708 }
9709 } 9709 }
9710   9710  
9711 public LSL_String llGetInventoryCreator(string itemName) 9711 public LSL_String llGetInventoryCreator(string itemName)
9712 { 9712 {
9713 m_host.AddScriptLPS(1); 9713 m_host.AddScriptLPS(1);
9714   9714  
9715 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9715 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9716   9716  
9717 if (item == null) 9717 if (item == null)
9718 { 9718 {
9719 Error("llGetInventoryCreator", "Can't find item '" + item + "'"); 9719 Error("llGetInventoryCreator", "Can't find item '" + item + "'");
9720   9720  
9721 return String.Empty; 9721 return String.Empty;
9722 } 9722 }
9723   9723  
9724 return item.CreatorID.ToString(); 9724 return item.CreatorID.ToString();
9725 } 9725 }
9726   9726  
9727 public void llOwnerSay(string msg) 9727 public void llOwnerSay(string msg)
9728 { 9728 {
9729 m_host.AddScriptLPS(1); 9729 m_host.AddScriptLPS(1);
9730   9730  
9731 World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, 9731 World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0,
9732 m_host.AbsolutePosition, m_host.Name, m_host.UUID, false); 9732 m_host.AbsolutePosition, m_host.Name, m_host.UUID, false);
9733 // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 9733 // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
9734 // wComm.DeliverMessage(ChatTypeEnum.Owner, 0, m_host.Name, m_host.UUID, msg); 9734 // wComm.DeliverMessage(ChatTypeEnum.Owner, 0, m_host.Name, m_host.UUID, msg);
9735 } 9735 }
9736   9736  
9737 public LSL_String llRequestSecureURL() 9737 public LSL_String llRequestSecureURL()
9738 { 9738 {
9739 m_host.AddScriptLPS(1); 9739 m_host.AddScriptLPS(1);
9740 if (m_UrlModule != null) 9740 if (m_UrlModule != null)
9741 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 9741 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
9742 return UUID.Zero.ToString(); 9742 return UUID.Zero.ToString();
9743 } 9743 }
9744   9744  
9745 public LSL_String llRequestSimulatorData(string simulator, int data) 9745 public LSL_String llRequestSimulatorData(string simulator, int data)
9746 { 9746 {
9747 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 9747 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
9748   9748  
9749 try 9749 try
9750 { 9750 {
9751 m_host.AddScriptLPS(1); 9751 m_host.AddScriptLPS(1);
9752   9752  
9753 string reply = String.Empty; 9753 string reply = String.Empty;
9754   9754  
9755 GridRegion info; 9755 GridRegion info;
9756   9756  
9757 if (World.RegionInfo.RegionName == simulator) 9757 if (World.RegionInfo.RegionName == simulator)
9758 info = new GridRegion(World.RegionInfo); 9758 info = new GridRegion(World.RegionInfo);
9759 else 9759 else
9760 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 9760 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
9761   9761  
9762 switch (data) 9762 switch (data)
9763 { 9763 {
9764 case ScriptBaseClass.DATA_SIM_POS: 9764 case ScriptBaseClass.DATA_SIM_POS:
9765 if (info == null) 9765 if (info == null)
9766 { 9766 {
9767 ScriptSleep(1000); 9767 ScriptSleep(1000);
9768 return UUID.Zero.ToString(); 9768 return UUID.Zero.ToString();
9769 } 9769 }
9770   9770  
9771 bool isHypergridRegion = false; 9771 bool isHypergridRegion = false;
9772   9772  
9773 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "") 9773 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "")
9774 { 9774 {
9775 // Hypergrid is currently placing real destination region co-ords into RegionSecret. 9775 // Hypergrid is currently placing real destination region co-ords into RegionSecret.
9776 // But other code can also use this field for a genuine RegionSecret! Therefore, if 9776 // But other code can also use this field for a genuine RegionSecret! Therefore, if
9777 // anything is present we need to disambiguate. 9777 // anything is present we need to disambiguate.
9778 // 9778 //
9779 // FIXME: Hypergrid should be storing this data in a different field. 9779 // FIXME: Hypergrid should be storing this data in a different field.
9780 RegionFlags regionFlags 9780 RegionFlags regionFlags
9781 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags( 9781 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags(
9782 info.ScopeID, info.RegionID); 9782 info.ScopeID, info.RegionID);
9783 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0; 9783 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0;
9784 } 9784 }
9785   9785  
9786 if (isHypergridRegion) 9786 if (isHypergridRegion)
9787 { 9787 {
9788 uint rx = 0, ry = 0; 9788 uint rx = 0, ry = 0;
9789 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); 9789 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry);
9790   9790  
9791 reply = new LSL_Vector( 9791 reply = new LSL_Vector(
9792 rx, 9792 rx,
9793 ry, 9793 ry,
9794 0).ToString(); 9794 0).ToString();
9795 } 9795 }
9796 else 9796 else
9797 { 9797 {
9798 // Local grid co-oridnates 9798 // Local grid co-oridnates
9799 reply = new LSL_Vector( 9799 reply = new LSL_Vector(
9800 info.RegionLocX, 9800 info.RegionLocX,
9801 info.RegionLocY, 9801 info.RegionLocY,
9802 0).ToString(); 9802 0).ToString();
9803 } 9803 }
9804 break; 9804 break;
9805 case ScriptBaseClass.DATA_SIM_STATUS: 9805 case ScriptBaseClass.DATA_SIM_STATUS:
9806 if (info != null) 9806 if (info != null)
9807 reply = "up"; // Duh! 9807 reply = "up"; // Duh!
9808 else 9808 else
9809 reply = "unknown"; 9809 reply = "unknown";
9810 break; 9810 break;
9811 case ScriptBaseClass.DATA_SIM_RATING: 9811 case ScriptBaseClass.DATA_SIM_RATING:
9812 if (info == null) 9812 if (info == null)
9813 { 9813 {
9814 ScriptSleep(1000); 9814 ScriptSleep(1000);
9815 return UUID.Zero.ToString(); 9815 return UUID.Zero.ToString();
9816 } 9816 }
9817 int access = info.Maturity; 9817 int access = info.Maturity;
9818 if (access == 0) 9818 if (access == 0)
9819 reply = "PG"; 9819 reply = "PG";
9820 else if (access == 1) 9820 else if (access == 1)
9821 reply = "MATURE"; 9821 reply = "MATURE";
9822 else if (access == 2) 9822 else if (access == 2)
9823 reply = "ADULT"; 9823 reply = "ADULT";
9824 else 9824 else
9825 reply = "UNKNOWN"; 9825 reply = "UNKNOWN";
9826 break; 9826 break;
9827 case ScriptBaseClass.DATA_SIM_RELEASE: 9827 case ScriptBaseClass.DATA_SIM_RELEASE:
9828 if (ossl != null) 9828 if (ossl != null)
9829 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData"); 9829 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData");
9830 reply = "OpenSim"; 9830 reply = "OpenSim";
9831 break; 9831 break;
9832 default: 9832 default:
9833 ScriptSleep(1000); 9833 ScriptSleep(1000);
9834 return UUID.Zero.ToString(); // Raise no event 9834 return UUID.Zero.ToString(); // Raise no event
9835 } 9835 }
9836 UUID rq = UUID.Random(); 9836 UUID rq = UUID.Random();
9837   9837  
9838 UUID tid = AsyncCommands. 9838 UUID tid = AsyncCommands.
9839 DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 9839 DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
9840   9840  
9841 AsyncCommands. 9841 AsyncCommands.
9842 DataserverPlugin.DataserverReply(rq.ToString(), reply); 9842 DataserverPlugin.DataserverReply(rq.ToString(), reply);
9843   9843  
9844 ScriptSleep(1000); 9844 ScriptSleep(1000);
9845 return tid.ToString(); 9845 return tid.ToString();
9846 } 9846 }
9847 catch(Exception) 9847 catch(Exception)
9848 { 9848 {
9849 //m_log.Error("[LSL_API]: llRequestSimulatorData" + e.ToString()); 9849 //m_log.Error("[LSL_API]: llRequestSimulatorData" + e.ToString());
9850 return UUID.Zero.ToString(); 9850 return UUID.Zero.ToString();
9851 } 9851 }
9852 } 9852 }
9853   9853  
9854 public LSL_String llRequestURL() 9854 public LSL_String llRequestURL()
9855 { 9855 {
9856 m_host.AddScriptLPS(1); 9856 m_host.AddScriptLPS(1);
9857   9857  
9858 if (m_UrlModule != null) 9858 if (m_UrlModule != null)
9859 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 9859 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
9860 return UUID.Zero.ToString(); 9860 return UUID.Zero.ToString();
9861 } 9861 }
9862   9862  
9863 public void llForceMouselook(int mouselook) 9863 public void llForceMouselook(int mouselook)
9864 { 9864 {
9865 m_host.AddScriptLPS(1); 9865 m_host.AddScriptLPS(1);
9866 m_host.SetForceMouselook(mouselook != 0); 9866 m_host.SetForceMouselook(mouselook != 0);
9867 } 9867 }
9868   9868  
9869 public LSL_Float llGetObjectMass(string id) 9869 public LSL_Float llGetObjectMass(string id)
9870 { 9870 {
9871 m_host.AddScriptLPS(1); 9871 m_host.AddScriptLPS(1);
9872 UUID key = new UUID(); 9872 UUID key = new UUID();
9873 if (UUID.TryParse(id, out key)) 9873 if (UUID.TryParse(id, out key))
9874 { 9874 {
9875 try 9875 try
9876 { 9876 {
9877 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9877 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9878 if (obj != null) 9878 if (obj != null)
9879 return (double)obj.GetMass(); 9879 return (double)obj.GetMass();
9880 // the object is null so the key is for an avatar 9880 // the object is null so the key is for an avatar
9881 ScenePresence avatar = World.GetScenePresence(key); 9881 ScenePresence avatar = World.GetScenePresence(key);
9882 if (avatar != null) 9882 if (avatar != null)
9883 if (avatar.IsChildAgent) 9883 if (avatar.IsChildAgent)
9884 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass 9884 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9885 // child agents have a mass of 1.0 9885 // child agents have a mass of 1.0
9886 return 1; 9886 return 1;
9887 else 9887 else
9888 return (double)avatar.GetMass(); 9888 return (double)avatar.GetMass();
9889 } 9889 }
9890 catch (KeyNotFoundException) 9890 catch (KeyNotFoundException)
9891 { 9891 {
9892 return 0; // The Object/Agent not in the region so just return zero 9892 return 0; // The Object/Agent not in the region so just return zero
9893 } 9893 }
9894 } 9894 }
9895 return 0; 9895 return 0;
9896 } 9896 }
9897   9897  
9898 /// <summary> 9898 /// <summary>
9899 /// illListReplaceList removes the sub-list defined by the inclusive indices 9899 /// illListReplaceList removes the sub-list defined by the inclusive indices
9900 /// start and end and inserts the src list in its place. The inclusive 9900 /// start and end and inserts the src list in its place. The inclusive
9901 /// nature of the indices means that at least one element must be deleted 9901 /// nature of the indices means that at least one element must be deleted
9902 /// if the indices are within the bounds of the existing list. I.e. 2,2 9902 /// if the indices are within the bounds of the existing list. I.e. 2,2
9903 /// will remove the element at index 2 and replace it with the source 9903 /// will remove the element at index 2 and replace it with the source
9904 /// list. Both indices may be negative, with the usual interpretation. An 9904 /// list. Both indices may be negative, with the usual interpretation. An
9905 /// interesting case is where end is lower than start. As these indices 9905 /// interesting case is where end is lower than start. As these indices
9906 /// bound the list to be removed, then 0->end, and start->lim are removed 9906 /// bound the list to be removed, then 0->end, and start->lim are removed
9907 /// and the source list is added as a suffix. 9907 /// and the source list is added as a suffix.
9908 /// </summary> 9908 /// </summary>
9909   9909  
9910 public LSL_List llListReplaceList(LSL_List dest, LSL_List src, int start, int end) 9910 public LSL_List llListReplaceList(LSL_List dest, LSL_List src, int start, int end)
9911 { 9911 {
9912 LSL_List pref = null; 9912 LSL_List pref = null;
9913   9913  
9914 m_host.AddScriptLPS(1); 9914 m_host.AddScriptLPS(1);
9915   9915  
9916 // Note that although we have normalized, both 9916 // Note that although we have normalized, both
9917 // indices could still be negative. 9917 // indices could still be negative.
9918 if (start < 0) 9918 if (start < 0)
9919 { 9919 {
9920 start = start+dest.Length; 9920 start = start+dest.Length;
9921 } 9921 }
9922   9922  
9923 if (end < 0) 9923 if (end < 0)
9924 { 9924 {
9925 end = end+dest.Length; 9925 end = end+dest.Length;
9926 } 9926 }
9927 // The comventional case, remove a sequence starting with 9927 // The comventional case, remove a sequence starting with
9928 // start and ending with end. And then insert the source 9928 // start and ending with end. And then insert the source
9929 // list. 9929 // list.
9930 if (start <= end) 9930 if (start <= end)
9931 { 9931 {
9932 // If greater than zero, then there is going to be a 9932 // If greater than zero, then there is going to be a
9933 // surviving prefix. Otherwise the inclusive nature 9933 // surviving prefix. Otherwise the inclusive nature
9934 // of the indices mean that we're going to add the 9934 // of the indices mean that we're going to add the
9935 // source list as a prefix. 9935 // source list as a prefix.
9936 if (start > 0) 9936 if (start > 0)
9937 { 9937 {
9938 pref = dest.GetSublist(0,start-1); 9938 pref = dest.GetSublist(0,start-1);
9939 // Only add a suffix if there is something 9939 // Only add a suffix if there is something
9940 // beyond the end index (it's inclusive too). 9940 // beyond the end index (it's inclusive too).
9941 if (end + 1 < dest.Length) 9941 if (end + 1 < dest.Length)
9942 { 9942 {
9943 return pref + src + dest.GetSublist(end + 1, -1); 9943 return pref + src + dest.GetSublist(end + 1, -1);
9944 } 9944 }
9945 else 9945 else
9946 { 9946 {
9947 return pref + src; 9947 return pref + src;
9948 } 9948 }
9949 } 9949 }
9950 // If start is less than or equal to zero, then 9950 // If start is less than or equal to zero, then
9951 // the new list is simply a prefix. We still need to 9951 // the new list is simply a prefix. We still need to
9952 // figure out any necessary surgery to the destination 9952 // figure out any necessary surgery to the destination
9953 // based upon end. Note that if end exceeds the upper 9953 // based upon end. Note that if end exceeds the upper
9954 // bound in this case, the entire destination list 9954 // bound in this case, the entire destination list
9955 // is removed. 9955 // is removed.
9956 else 9956 else
9957 { 9957 {
9958 if (end + 1 < dest.Length) 9958 if (end + 1 < dest.Length)
9959 { 9959 {
9960 return src + dest.GetSublist(end + 1, -1); 9960 return src + dest.GetSublist(end + 1, -1);
9961 } 9961 }
9962 else 9962 else
9963 { 9963 {
9964 return src; 9964 return src;
9965 } 9965 }
9966 } 9966 }
9967 } 9967 }
9968 // Finally, if start > end, we strip away a prefix and 9968 // Finally, if start > end, we strip away a prefix and
9969 // a suffix, to leave the list that sits <between> ens 9969 // a suffix, to leave the list that sits <between> ens
9970 // and start, and then tag on the src list. AT least 9970 // and start, and then tag on the src list. AT least
9971 // that's my interpretation. We can get sublist to do 9971 // that's my interpretation. We can get sublist to do
9972 // this for us. Note that one, or both of the indices 9972 // this for us. Note that one, or both of the indices
9973 // might have been negative. 9973 // might have been negative.
9974 else 9974 else
9975 { 9975 {
9976 return dest.GetSublist(end + 1, start - 1) + src; 9976 return dest.GetSublist(end + 1, start - 1) + src;
9977 } 9977 }
9978 } 9978 }
9979   9979  
9980 public void llLoadURL(string avatar_id, string message, string url) 9980 public void llLoadURL(string avatar_id, string message, string url)
9981 { 9981 {
9982 m_host.AddScriptLPS(1); 9982 m_host.AddScriptLPS(1);
9983   9983  
9984 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 9984 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
9985 if (null != dm) 9985 if (null != dm)
9986 dm.SendUrlToUser( 9986 dm.SendUrlToUser(
9987 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); 9987 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url);
9988   9988  
9989 ScriptSleep(10000); 9989 ScriptSleep(10000);
9990 } 9990 }
9991   9991  
9992 public void llParcelMediaCommandList(LSL_List commandList) 9992 public void llParcelMediaCommandList(LSL_List commandList)
9993 { 9993 {
9994 // TODO: Not implemented yet (missing in libomv?): 9994 // TODO: Not implemented yet (missing in libomv?):
9995 // PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) 9995 // PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later)
9996   9996  
9997 m_host.AddScriptLPS(1); 9997 m_host.AddScriptLPS(1);
9998   9998  
9999 // according to the docs, this command only works if script owner and land owner are the same 9999 // according to the docs, this command only works if script owner and land owner are the same
10000 // lets add estate owners and gods, too, and use the generic permission check. 10000 // lets add estate owners and gods, too, and use the generic permission check.
10001 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10001 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10002 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10002 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
10003   10003  
10004 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 10004 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
10005 byte loop = 0; 10005 byte loop = 0;
10006   10006  
10007 LandData landData = landObject.LandData; 10007 LandData landData = landObject.LandData;
10008 string url = landData.MediaURL; 10008 string url = landData.MediaURL;
10009 string texture = landData.MediaID.ToString(); 10009 string texture = landData.MediaID.ToString();
10010 bool autoAlign = landData.MediaAutoScale != 0; 10010 bool autoAlign = landData.MediaAutoScale != 0;
10011 string mediaType = ""; // TODO these have to be added as soon as LandData supports it 10011 string mediaType = ""; // TODO these have to be added as soon as LandData supports it
10012 string description = ""; 10012 string description = "";
10013 int width = 0; 10013 int width = 0;
10014 int height = 0; 10014 int height = 0;
10015   10015  
10016 ParcelMediaCommandEnum? commandToSend = null; 10016 ParcelMediaCommandEnum? commandToSend = null;
10017 float time = 0.0f; // default is from start 10017 float time = 0.0f; // default is from start
10018   10018  
10019 ScenePresence presence = null; 10019 ScenePresence presence = null;
10020   10020  
10021 for (int i = 0; i < commandList.Data.Length; i++) 10021 for (int i = 0; i < commandList.Data.Length; i++)
10022 { 10022 {
10023 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10023 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i];
10024 switch (command) 10024 switch (command)
10025 { 10025 {
10026 case ParcelMediaCommandEnum.Agent: 10026 case ParcelMediaCommandEnum.Agent:
10027 // we send only to one agent 10027 // we send only to one agent
10028 if ((i + 1) < commandList.Length) 10028 if ((i + 1) < commandList.Length)
10029 { 10029 {
10030 if (commandList.Data[i + 1] is LSL_String) 10030 if (commandList.Data[i + 1] is LSL_String)
10031 { 10031 {
10032 UUID agentID; 10032 UUID agentID;
10033 if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID)) 10033 if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID))
10034 { 10034 {
10035 presence = World.GetScenePresence(agentID); 10035 presence = World.GetScenePresence(agentID);
10036 } 10036 }
10037 } 10037 }
10038 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key"); 10038 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key");
10039 ++i; 10039 ++i;
10040 } 10040 }
10041 break; 10041 break;
10042   10042  
10043 case ParcelMediaCommandEnum.Loop: 10043 case ParcelMediaCommandEnum.Loop:
10044 loop = 1; 10044 loop = 1;
10045 commandToSend = command; 10045 commandToSend = command;
10046 update = true; //need to send the media update packet to set looping 10046 update = true; //need to send the media update packet to set looping
10047 break; 10047 break;
10048   10048  
10049 case ParcelMediaCommandEnum.Play: 10049 case ParcelMediaCommandEnum.Play:
10050 loop = 0; 10050 loop = 0;
10051 commandToSend = command; 10051 commandToSend = command;
10052 update = true; //need to send the media update packet to make sure it doesn't loop 10052 update = true; //need to send the media update packet to make sure it doesn't loop
10053 break; 10053 break;
10054   10054  
10055 case ParcelMediaCommandEnum.Pause: 10055 case ParcelMediaCommandEnum.Pause:
10056 case ParcelMediaCommandEnum.Stop: 10056 case ParcelMediaCommandEnum.Stop:
10057 case ParcelMediaCommandEnum.Unload: 10057 case ParcelMediaCommandEnum.Unload:
10058 commandToSend = command; 10058 commandToSend = command;
10059 break; 10059 break;
10060   10060  
10061 case ParcelMediaCommandEnum.Url: 10061 case ParcelMediaCommandEnum.Url:
10062 if ((i + 1) < commandList.Length) 10062 if ((i + 1) < commandList.Length)
10063 { 10063 {
10064 if (commandList.Data[i + 1] is LSL_String) 10064 if (commandList.Data[i + 1] is LSL_String)
10065 { 10065 {
10066 url = (LSL_String)commandList.Data[i + 1]; 10066 url = (LSL_String)commandList.Data[i + 1];
10067 update = true; 10067 update = true;
10068 } 10068 }
10069 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_URL must be a string"); 10069 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_URL must be a string");
10070 ++i; 10070 ++i;
10071 } 10071 }
10072 break; 10072 break;
10073   10073  
10074 case ParcelMediaCommandEnum.Texture: 10074 case ParcelMediaCommandEnum.Texture:
10075 if ((i + 1) < commandList.Length) 10075 if ((i + 1) < commandList.Length)
10076 { 10076 {
10077 if (commandList.Data[i + 1] is LSL_String) 10077 if (commandList.Data[i + 1] is LSL_String)
10078 { 10078 {
10079 texture = (LSL_String)commandList.Data[i + 1]; 10079 texture = (LSL_String)commandList.Data[i + 1];
10080 update = true; 10080 update = true;
10081 } 10081 }
10082 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or a key"); 10082 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or a key");
10083 ++i; 10083 ++i;
10084 } 10084 }
10085 break; 10085 break;
10086   10086  
10087 case ParcelMediaCommandEnum.Time: 10087 case ParcelMediaCommandEnum.Time:
10088 if ((i + 1) < commandList.Length) 10088 if ((i + 1) < commandList.Length)
10089 { 10089 {
10090 if (commandList.Data[i + 1] is LSL_Float) 10090 if (commandList.Data[i + 1] is LSL_Float)
10091 { 10091 {
10092 time = (float)(LSL_Float)commandList.Data[i + 1]; 10092 time = (float)(LSL_Float)commandList.Data[i + 1];
10093 } 10093 }
10094 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TIME must be a float"); 10094 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TIME must be a float");
10095 ++i; 10095 ++i;
10096 } 10096 }
10097 break; 10097 break;
10098   10098  
10099 case ParcelMediaCommandEnum.AutoAlign: 10099 case ParcelMediaCommandEnum.AutoAlign:
10100 if ((i + 1) < commandList.Length) 10100 if ((i + 1) < commandList.Length)
10101 { 10101 {
10102 if (commandList.Data[i + 1] is LSL_Integer) 10102 if (commandList.Data[i + 1] is LSL_Integer)
10103 { 10103 {
10104 autoAlign = (LSL_Integer)commandList.Data[i + 1]; 10104 autoAlign = (LSL_Integer)commandList.Data[i + 1];
10105 update = true; 10105 update = true;
10106 } 10106 }
10107   10107  
10108 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer"); 10108 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer");
10109 ++i; 10109 ++i;
10110 } 10110 }
10111 break; 10111 break;
10112   10112  
10113 case ParcelMediaCommandEnum.Type: 10113 case ParcelMediaCommandEnum.Type:
10114 if ((i + 1) < commandList.Length) 10114 if ((i + 1) < commandList.Length)
10115 { 10115 {
10116 if (commandList.Data[i + 1] is LSL_String) 10116 if (commandList.Data[i + 1] is LSL_String)
10117 { 10117 {
10118 mediaType = (LSL_String)commandList.Data[i + 1]; 10118 mediaType = (LSL_String)commandList.Data[i + 1];
10119 update = true; 10119 update = true;
10120 } 10120 }
10121 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string"); 10121 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string");
10122 ++i; 10122 ++i;
10123 } 10123 }
10124 break; 10124 break;
10125   10125  
10126 case ParcelMediaCommandEnum.Desc: 10126 case ParcelMediaCommandEnum.Desc:
10127 if ((i + 1) < commandList.Length) 10127 if ((i + 1) < commandList.Length)
10128 { 10128 {
10129 if (commandList.Data[i + 1] is LSL_String) 10129 if (commandList.Data[i + 1] is LSL_String)
10130 { 10130 {
10131 description = (LSL_String)commandList.Data[i + 1]; 10131 description = (LSL_String)commandList.Data[i + 1];
10132 update = true; 10132 update = true;
10133 } 10133 }
10134 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_DESC must be a string"); 10134 else Error("llParcelMediaCommandList", "The argument of PARCEL_MEDIA_COMMAND_DESC must be a string");
10135 ++i; 10135 ++i;
10136 } 10136 }
10137 break; 10137 break;
10138   10138  
10139 case ParcelMediaCommandEnum.Size: 10139 case ParcelMediaCommandEnum.Size:
10140 if ((i + 2) < commandList.Length) 10140 if ((i + 2) < commandList.Length)
10141 { 10141 {
10142 if (commandList.Data[i + 1] is LSL_Integer) 10142 if (commandList.Data[i + 1] is LSL_Integer)
10143 { 10143 {
10144 if (commandList.Data[i + 2] is LSL_Integer) 10144 if (commandList.Data[i + 2] is LSL_Integer)
10145 { 10145 {
10146 width = (LSL_Integer)commandList.Data[i + 1]; 10146 width = (LSL_Integer)commandList.Data[i + 1];
10147 height = (LSL_Integer)commandList.Data[i + 2]; 10147 height = (LSL_Integer)commandList.Data[i + 2];
10148 update = true; 10148 update = true;
10149 } 10149 }
10150 else Error("llParcelMediaCommandList", "The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer"); 10150 else Error("llParcelMediaCommandList", "The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer");
10151 } 10151 }
10152 else Error("llParcelMediaCommandList", "The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer"); 10152 else Error("llParcelMediaCommandList", "The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer");
10153 i += 2; 10153 i += 2;
10154 } 10154 }
10155 break; 10155 break;
10156   10156  
10157 default: 10157 default:
10158 NotImplemented("llParcelMediaCommandList", "Parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString()); 10158 NotImplemented("llParcelMediaCommandList", "Parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString());
10159 break; 10159 break;
10160 }//end switch 10160 }//end switch
10161 }//end for 10161 }//end for
10162   10162  
10163 // if we didn't get a presence, we send to all and change the url 10163 // if we didn't get a presence, we send to all and change the url
10164 // if we did get a presence, we only send to the agent specified, and *don't change the land settings*! 10164 // if we did get a presence, we only send to the agent specified, and *don't change the land settings*!
10165   10165  
10166 // did something important change or do we only start/stop/pause? 10166 // did something important change or do we only start/stop/pause?
10167 if (update) 10167 if (update)
10168 { 10168 {
10169 if (presence == null) 10169 if (presence == null)
10170 { 10170 {
10171 // we send to all 10171 // we send to all
10172 landData.MediaID = new UUID(texture); 10172 landData.MediaID = new UUID(texture);
10173 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; 10173 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0;
10174 landData.MediaWidth = width; 10174 landData.MediaWidth = width;
10175 landData.MediaHeight = height; 10175 landData.MediaHeight = height;
10176 landData.MediaType = mediaType; 10176 landData.MediaType = mediaType;
10177   10177  
10178 // do that one last, it will cause a ParcelPropertiesUpdate 10178 // do that one last, it will cause a ParcelPropertiesUpdate
10179 landObject.SetMediaUrl(url); 10179 landObject.SetMediaUrl(url);
10180   10180  
10181 // now send to all (non-child) agents in the parcel 10181 // now send to all (non-child) agents in the parcel
10182 World.ForEachRootScenePresence(delegate(ScenePresence sp) 10182 World.ForEachRootScenePresence(delegate(ScenePresence sp)
10183 { 10183 {
10184 if (sp.currentParcelUUID == landData.GlobalID) 10184 if (sp.currentParcelUUID == landData.GlobalID)
10185 { 10185 {
10186 sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, 10186 sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
10187 landData.MediaID, 10187 landData.MediaID,
10188 landData.MediaAutoScale, 10188 landData.MediaAutoScale,
10189 mediaType, 10189 mediaType,
10190 description, 10190 description,
10191 width, height, 10191 width, height,
10192 loop); 10192 loop);
10193 } 10193 }
10194 }); 10194 });
10195 } 10195 }
10196 else if (!presence.IsChildAgent) 10196 else if (!presence.IsChildAgent)
10197 { 10197 {
10198 // we only send to one (root) agent 10198 // we only send to one (root) agent
10199 presence.ControllingClient.SendParcelMediaUpdate(url, 10199 presence.ControllingClient.SendParcelMediaUpdate(url,
10200 new UUID(texture), 10200 new UUID(texture),
10201 autoAlign ? (byte)1 : (byte)0, 10201 autoAlign ? (byte)1 : (byte)0,
10202 mediaType, 10202 mediaType,
10203 description, 10203 description,
10204 width, height, 10204 width, height,
10205 loop); 10205 loop);
10206 } 10206 }
10207 } 10207 }
10208   10208  
10209 if (commandToSend != null) 10209 if (commandToSend != null)
10210 { 10210 {
10211 // the commandList contained a start/stop/... command, too 10211 // the commandList contained a start/stop/... command, too
10212 if (presence == null) 10212 if (presence == null)
10213 { 10213 {
10214 // send to all (non-child) agents in the parcel 10214 // send to all (non-child) agents in the parcel
10215 World.ForEachRootScenePresence(delegate(ScenePresence sp) 10215 World.ForEachRootScenePresence(delegate(ScenePresence sp)
10216 { 10216 {
10217 if (sp.currentParcelUUID == landData.GlobalID) 10217 if (sp.currentParcelUUID == landData.GlobalID)
10218 { 10218 {
10219 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 10219 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
10220 (ParcelMediaCommandEnum)commandToSend, 10220 (ParcelMediaCommandEnum)commandToSend,
10221 time); 10221 time);
10222 } 10222 }
10223 }); 10223 });
10224 } 10224 }
10225 else if (!presence.IsChildAgent) 10225 else if (!presence.IsChildAgent)
10226 { 10226 {
10227 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 10227 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
10228 (ParcelMediaCommandEnum)commandToSend, 10228 (ParcelMediaCommandEnum)commandToSend,
10229 time); 10229 time);
10230 } 10230 }
10231 } 10231 }
10232 ScriptSleep(2000); 10232 ScriptSleep(2000);
10233 } 10233 }
10234   10234  
10235 public LSL_List llParcelMediaQuery(LSL_List aList) 10235 public LSL_List llParcelMediaQuery(LSL_List aList)
10236 { 10236 {
10237 m_host.AddScriptLPS(1); 10237 m_host.AddScriptLPS(1);
10238 LSL_List list = new LSL_List(); 10238 LSL_List list = new LSL_List();
10239 //TO DO: make the implementation for the missing commands 10239 //TO DO: make the implementation for the missing commands
10240 //PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later) 10240 //PARCEL_MEDIA_COMMAND_LOOP_SET float loop Use this to get or set the parcel's media loop duration. (1.19.1 RC0 or later)
10241 for (int i = 0; i < aList.Data.Length; i++) 10241 for (int i = 0; i < aList.Data.Length; i++)
10242 { 10242 {
10243   10243  
10244 if (aList.Data[i] != null) 10244 if (aList.Data[i] != null)
10245 { 10245 {
10246 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10246 switch ((ParcelMediaCommandEnum) aList.Data[i])
10247 { 10247 {
10248 case ParcelMediaCommandEnum.Url: 10248 case ParcelMediaCommandEnum.Url:
10249 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10249 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10250 break; 10250 break;
10251 case ParcelMediaCommandEnum.Desc: 10251 case ParcelMediaCommandEnum.Desc:
10252 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description)); 10252 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10253 break; 10253 break;
10254 case ParcelMediaCommandEnum.Texture: 10254 case ParcelMediaCommandEnum.Texture:
10255 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString())); 10255 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
10256 break; 10256 break;
10257 case ParcelMediaCommandEnum.Type: 10257 case ParcelMediaCommandEnum.Type:
10258 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType)); 10258 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
10259 break; 10259 break;
10260 case ParcelMediaCommandEnum.Size: 10260 case ParcelMediaCommandEnum.Size:
10261 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth)); 10261 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth));
10262 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight)); 10262 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
10263 break; 10263 break;
10264 default: 10264 default:
10265 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10265 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
10266 NotImplemented("llParcelMediaQuery", "Parameter not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString()); 10266 NotImplemented("llParcelMediaQuery", "Parameter not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString());
10267 break; 10267 break;
10268 } 10268 }
10269   10269  
10270 } 10270 }
10271 } 10271 }
10272 ScriptSleep(2000); 10272 ScriptSleep(2000);
10273 return list; 10273 return list;
10274 } 10274 }
10275   10275  
10276 public LSL_Integer llModPow(int a, int b, int c) 10276 public LSL_Integer llModPow(int a, int b, int c)
10277 { 10277 {
10278 m_host.AddScriptLPS(1); 10278 m_host.AddScriptLPS(1);
10279 Int64 tmp = 0; 10279 Int64 tmp = 0;
10280 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); 10280 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp);
10281 ScriptSleep(1000); 10281 ScriptSleep(1000);
10282 return Convert.ToInt32(tmp); 10282 return Convert.ToInt32(tmp);
10283 } 10283 }
10284   10284  
10285 public LSL_Integer llGetInventoryType(string name) 10285 public LSL_Integer llGetInventoryType(string name)
10286 { 10286 {
10287 m_host.AddScriptLPS(1); 10287 m_host.AddScriptLPS(1);
10288   10288  
10289 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 10289 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
10290   10290  
10291 if (item == null) 10291 if (item == null)
10292 return -1; 10292 return -1;
10293   10293  
10294 return item.Type; 10294 return item.Type;
10295 } 10295 }
10296   10296  
10297 public void llSetPayPrice(int price, LSL_List quick_pay_buttons) 10297 public void llSetPayPrice(int price, LSL_List quick_pay_buttons)
10298 { 10298 {
10299 m_host.AddScriptLPS(1); 10299 m_host.AddScriptLPS(1);
10300   10300  
10301 if (quick_pay_buttons.Data.Length < 4) 10301 if (quick_pay_buttons.Data.Length < 4)
10302 { 10302 {
10303 Error("llSetPayPrice", "List must have at least 4 elements"); 10303 Error("llSetPayPrice", "List must have at least 4 elements");
10304 return; 10304 return;
10305 } 10305 }
10306 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10306 m_host.ParentGroup.RootPart.PayPrice[0]=price;
10307   10307  
10308 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10308 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0];
10309 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10309 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1];
10310 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10310 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2];
10311 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10311 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3];
10312 m_host.ParentGroup.HasGroupChanged = true; 10312 m_host.ParentGroup.HasGroupChanged = true;
10313 } 10313 }
10314   10314  
10315 public LSL_Vector llGetCameraPos() 10315 public LSL_Vector llGetCameraPos()
10316 { 10316 {
10317 m_host.AddScriptLPS(1); 10317 m_host.AddScriptLPS(1);
10318   10318  
10319 if (m_item.PermsGranter == UUID.Zero) 10319 if (m_item.PermsGranter == UUID.Zero)
10320 return Vector3.Zero; 10320 return Vector3.Zero;
10321   10321  
10322 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10322 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10323 { 10323 {
10324 Error("llGetCameraPos", "No permissions to track the camera"); 10324 Error("llGetCameraPos", "No permissions to track the camera");
10325 return Vector3.Zero; 10325 return Vector3.Zero;
10326 } 10326 }
10327   10327  
10328 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10328 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10329 if (presence != null) 10329 if (presence != null)
10330 { 10330 {
10331 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10331 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10332 return pos; 10332 return pos;
10333 } 10333 }
10334   10334  
10335 return Vector3.Zero; 10335 return Vector3.Zero;
10336 } 10336 }
10337   10337  
10338 public LSL_Rotation llGetCameraRot() 10338 public LSL_Rotation llGetCameraRot()
10339 { 10339 {
10340 m_host.AddScriptLPS(1); 10340 m_host.AddScriptLPS(1);
10341   10341  
10342 if (m_item.PermsGranter == UUID.Zero) 10342 if (m_item.PermsGranter == UUID.Zero)
10343 return Quaternion.Identity; 10343 return Quaternion.Identity;
10344   10344  
10345 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10345 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10346 { 10346 {
10347 Error("llGetCameraRot", "No permissions to track the camera"); 10347 Error("llGetCameraRot", "No permissions to track the camera");
10348 return Quaternion.Identity; 10348 return Quaternion.Identity;
10349 } 10349 }
10350   10350  
10351 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10351 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10352 if (presence != null) 10352 if (presence != null)
10353 { 10353 {
10354 return new LSL_Rotation(presence.CameraRotation); 10354 return new LSL_Rotation(presence.CameraRotation);
10355 } 10355 }
10356   10356  
10357 return Quaternion.Identity; 10357 return Quaternion.Identity;
10358 } 10358 }
10359   10359  
10360 public void llSetPrimURL(string url) 10360 public void llSetPrimURL(string url)
10361 { 10361 {
10362 m_host.AddScriptLPS(1); 10362 m_host.AddScriptLPS(1);
10363 Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead"); 10363 Deprecated("llSetPrimURL", "Use llSetPrimMediaParams instead");
10364 ScriptSleep(2000); 10364 ScriptSleep(2000);
10365 } 10365 }
10366   10366  
10367 public void llRefreshPrimURL() 10367 public void llRefreshPrimURL()
10368 { 10368 {
10369 m_host.AddScriptLPS(1); 10369 m_host.AddScriptLPS(1);
10370 Deprecated("llRefreshPrimURL"); 10370 Deprecated("llRefreshPrimURL");
10371 ScriptSleep(20000); 10371 ScriptSleep(20000);
10372 } 10372 }
10373   10373  
10374 public LSL_String llEscapeURL(string url) 10374 public LSL_String llEscapeURL(string url)
10375 { 10375 {
10376 m_host.AddScriptLPS(1); 10376 m_host.AddScriptLPS(1);
10377 try 10377 try
10378 { 10378 {
10379 return Uri.EscapeDataString(url); 10379 return Uri.EscapeDataString(url);
10380 } 10380 }
10381 catch (Exception ex) 10381 catch (Exception ex)
10382 { 10382 {
10383 return "llEscapeURL: " + ex.ToString(); 10383 return "llEscapeURL: " + ex.ToString();
10384 } 10384 }
10385 } 10385 }
10386   10386  
10387 public LSL_String llUnescapeURL(string url) 10387 public LSL_String llUnescapeURL(string url)
10388 { 10388 {
10389 m_host.AddScriptLPS(1); 10389 m_host.AddScriptLPS(1);
10390 try 10390 try
10391 { 10391 {
10392 return Uri.UnescapeDataString(url); 10392 return Uri.UnescapeDataString(url);
10393 } 10393 }
10394 catch (Exception ex) 10394 catch (Exception ex)
10395 { 10395 {
10396 return "llUnescapeURL: " + ex.ToString(); 10396 return "llUnescapeURL: " + ex.ToString();
10397 } 10397 }
10398 } 10398 }
10399   10399  
10400 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) 10400 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt)
10401 { 10401 {
10402 m_host.AddScriptLPS(1); 10402 m_host.AddScriptLPS(1);
10403 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10403 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10404 if (detectedParams == null) return; // only works on the first detected avatar 10404 if (detectedParams == null) return; // only works on the first detected avatar
10405   10405  
10406 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10406 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10407 if (avatar != null) 10407 if (avatar != null)
10408 { 10408 {
10409 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10409 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10410 simname, pos, lookAt); 10410 simname, pos, lookAt);
10411 } 10411 }
10412 ScriptSleep(1000); 10412 ScriptSleep(1000);
10413 } 10413 }
10414   10414  
10415 public void llAddToLandBanList(string avatar, double hours) 10415 public void llAddToLandBanList(string avatar, double hours)
10416 { 10416 {
10417 m_host.AddScriptLPS(1); 10417 m_host.AddScriptLPS(1);
10418 UUID key; 10418 UUID key;
10419 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10419 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10420 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10420 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10421 { 10421 {
10422 int expires = 0; 10422 int expires = 0;
10423 if (hours != 0) 10423 if (hours != 0)
10424 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours); 10424 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours);
10425   10425  
10426 if (UUID.TryParse(avatar, out key)) 10426 if (UUID.TryParse(avatar, out key))
10427 { 10427 {
10428 int idx = land.LandData.ParcelAccessList.FindIndex( 10428 int idx = land.LandData.ParcelAccessList.FindIndex(
10429 delegate(LandAccessEntry e) 10429 delegate(LandAccessEntry e)
10430 { 10430 {
10431 if (e.AgentID == key && e.Flags == AccessList.Ban) 10431 if (e.AgentID == key && e.Flags == AccessList.Ban)
10432 return true; 10432 return true;
10433 return false; 10433 return false;
10434 }); 10434 });
10435   10435  
10436 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires))) 10436 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires)))
10437 return; 10437 return;
10438   10438  
10439 if (idx != -1) 10439 if (idx != -1)
10440 land.LandData.ParcelAccessList.RemoveAt(idx); 10440 land.LandData.ParcelAccessList.RemoveAt(idx);
10441   10441  
10442 LandAccessEntry entry = new LandAccessEntry(); 10442 LandAccessEntry entry = new LandAccessEntry();
10443   10443  
10444 entry.AgentID = key; 10444 entry.AgentID = key;
10445 entry.Flags = AccessList.Ban; 10445 entry.Flags = AccessList.Ban;
10446 entry.Expires = expires; 10446 entry.Expires = expires;
10447   10447  
10448 land.LandData.ParcelAccessList.Add(entry); 10448 land.LandData.ParcelAccessList.Add(entry);
10449   10449  
10450 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10450 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10451 } 10451 }
10452 } 10452 }
10453 ScriptSleep(100); 10453 ScriptSleep(100);
10454 } 10454 }
10455   10455  
10456 public void llRemoveFromLandPassList(string avatar) 10456 public void llRemoveFromLandPassList(string avatar)
10457 { 10457 {
10458 m_host.AddScriptLPS(1); 10458 m_host.AddScriptLPS(1);
10459 UUID key; 10459 UUID key;
10460 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10460 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10461 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10461 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10462 { 10462 {
10463 if (UUID.TryParse(avatar, out key)) 10463 if (UUID.TryParse(avatar, out key))
10464 { 10464 {
10465 int idx = land.LandData.ParcelAccessList.FindIndex( 10465 int idx = land.LandData.ParcelAccessList.FindIndex(
10466 delegate(LandAccessEntry e) 10466 delegate(LandAccessEntry e)
10467 { 10467 {
10468 if (e.AgentID == key && e.Flags == AccessList.Access) 10468 if (e.AgentID == key && e.Flags == AccessList.Access)
10469 return true; 10469 return true;
10470 return false; 10470 return false;
10471 }); 10471 });
10472   10472  
10473 if (idx != -1) 10473 if (idx != -1)
10474 { 10474 {
10475 land.LandData.ParcelAccessList.RemoveAt(idx); 10475 land.LandData.ParcelAccessList.RemoveAt(idx);
10476 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10476 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10477 } 10477 }
10478 } 10478 }
10479 } 10479 }
10480 ScriptSleep(100); 10480 ScriptSleep(100);
10481 } 10481 }
10482   10482  
10483 public void llRemoveFromLandBanList(string avatar) 10483 public void llRemoveFromLandBanList(string avatar)
10484 { 10484 {
10485 m_host.AddScriptLPS(1); 10485 m_host.AddScriptLPS(1);
10486 UUID key; 10486 UUID key;
10487 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10487 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10488 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10488 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10489 { 10489 {
10490 if (UUID.TryParse(avatar, out key)) 10490 if (UUID.TryParse(avatar, out key))
10491 { 10491 {
10492 int idx = land.LandData.ParcelAccessList.FindIndex( 10492 int idx = land.LandData.ParcelAccessList.FindIndex(
10493 delegate(LandAccessEntry e) 10493 delegate(LandAccessEntry e)
10494 { 10494 {
10495 if (e.AgentID == key && e.Flags == AccessList.Ban) 10495 if (e.AgentID == key && e.Flags == AccessList.Ban)
10496 return true; 10496 return true;
10497 return false; 10497 return false;
10498 }); 10498 });
10499   10499  
10500 if (idx != -1) 10500 if (idx != -1)
10501 { 10501 {
10502 land.LandData.ParcelAccessList.RemoveAt(idx); 10502 land.LandData.ParcelAccessList.RemoveAt(idx);
10503 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10503 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10504 } 10504 }
10505 } 10505 }
10506 } 10506 }
10507 ScriptSleep(100); 10507 ScriptSleep(100);
10508 } 10508 }
10509   10509  
10510 public void llSetCameraParams(LSL_List rules) 10510 public void llSetCameraParams(LSL_List rules)
10511 { 10511 {
10512 m_host.AddScriptLPS(1); 10512 m_host.AddScriptLPS(1);
10513   10513  
10514 // the object we are in 10514 // the object we are in
10515 UUID objectID = m_host.ParentUUID; 10515 UUID objectID = m_host.ParentUUID;
10516 if (objectID == UUID.Zero) 10516 if (objectID == UUID.Zero)
10517 return; 10517 return;
10518   10518  
10519 // we need the permission first, to know which avatar we want to set the camera for 10519 // we need the permission first, to know which avatar we want to set the camera for
10520 UUID agentID = m_item.PermsGranter; 10520 UUID agentID = m_item.PermsGranter;
10521   10521  
10522 if (agentID == UUID.Zero) 10522 if (agentID == UUID.Zero)
10523 return; 10523 return;
10524   10524  
10525 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10525 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10526 return; 10526 return;
10527   10527  
10528 ScenePresence presence = World.GetScenePresence(agentID); 10528 ScenePresence presence = World.GetScenePresence(agentID);
10529   10529  
10530 // we are not interested in child-agents 10530 // we are not interested in child-agents
10531 if (presence.IsChildAgent) return; 10531 if (presence.IsChildAgent) return;
10532   10532  
10533 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10533 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10534 object[] data = rules.Data; 10534 object[] data = rules.Data;
10535 for (int i = 0; i < data.Length; ++i) { 10535 for (int i = 0; i < data.Length; ++i) {
10536 int type = Convert.ToInt32(data[i++].ToString()); 10536 int type = Convert.ToInt32(data[i++].ToString());
10537 if (i >= data.Length) break; // odd number of entries => ignore the last 10537 if (i >= data.Length) break; // odd number of entries => ignore the last
10538   10538  
10539 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10539 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10540 switch (type) { 10540 switch (type) {
10541 case ScriptBaseClass.CAMERA_FOCUS: 10541 case ScriptBaseClass.CAMERA_FOCUS:
10542 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10542 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10543 case ScriptBaseClass.CAMERA_POSITION: 10543 case ScriptBaseClass.CAMERA_POSITION:
10544 LSL_Vector v = (LSL_Vector)data[i]; 10544 LSL_Vector v = (LSL_Vector)data[i];
10545 parameters.Add(type + 1, (float)v.x); 10545 parameters.Add(type + 1, (float)v.x);
10546 parameters.Add(type + 2, (float)v.y); 10546 parameters.Add(type + 2, (float)v.y);
10547 parameters.Add(type + 3, (float)v.z); 10547 parameters.Add(type + 3, (float)v.z);
10548 break; 10548 break;
10549 default: 10549 default:
10550 // TODO: clean that up as soon as the implicit casts are in 10550 // TODO: clean that up as soon as the implicit casts are in
10551 if (data[i] is LSL_Float) 10551 if (data[i] is LSL_Float)
10552 parameters.Add(type, (float)((LSL_Float)data[i]).value); 10552 parameters.Add(type, (float)((LSL_Float)data[i]).value);
10553 else if (data[i] is LSL_Integer) 10553 else if (data[i] is LSL_Integer)
10554 parameters.Add(type, (float)((LSL_Integer)data[i]).value); 10554 parameters.Add(type, (float)((LSL_Integer)data[i]).value);
10555 else parameters.Add(type, Convert.ToSingle(data[i])); 10555 else parameters.Add(type, Convert.ToSingle(data[i]));
10556 break; 10556 break;
10557 } 10557 }
10558 } 10558 }
10559 if (parameters.Count > 0) presence.ControllingClient.SendSetFollowCamProperties(objectID, parameters); 10559 if (parameters.Count > 0) presence.ControllingClient.SendSetFollowCamProperties(objectID, parameters);
10560 } 10560 }
10561   10561  
10562 public void llClearCameraParams() 10562 public void llClearCameraParams()
10563 { 10563 {
10564 m_host.AddScriptLPS(1); 10564 m_host.AddScriptLPS(1);
10565   10565  
10566 // the object we are in 10566 // the object we are in
10567 UUID objectID = m_host.ParentUUID; 10567 UUID objectID = m_host.ParentUUID;
10568 if (objectID == UUID.Zero) 10568 if (objectID == UUID.Zero)
10569 return; 10569 return;
10570   10570  
10571 // we need the permission first, to know which avatar we want to clear the camera for 10571 // we need the permission first, to know which avatar we want to clear the camera for
10572 UUID agentID = m_item.PermsGranter; 10572 UUID agentID = m_item.PermsGranter;
10573   10573  
10574 if (agentID == UUID.Zero) 10574 if (agentID == UUID.Zero)
10575 return; 10575 return;
10576   10576  
10577 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10577 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10578 return; 10578 return;
10579   10579  
10580 ScenePresence presence = World.GetScenePresence(agentID); 10580 ScenePresence presence = World.GetScenePresence(agentID);
10581   10581  
10582 // we are not interested in child-agents 10582 // we are not interested in child-agents
10583 if (presence.IsChildAgent) 10583 if (presence.IsChildAgent)
10584 return; 10584 return;
10585   10585  
10586 presence.ControllingClient.SendClearFollowCamProperties(objectID); 10586 presence.ControllingClient.SendClearFollowCamProperties(objectID);
10587 } 10587 }
10588   10588  
10589 public LSL_Float llListStatistics(int operation, LSL_List src) 10589 public LSL_Float llListStatistics(int operation, LSL_List src)
10590 { 10590 {
10591 m_host.AddScriptLPS(1); 10591 m_host.AddScriptLPS(1);
10592 switch (operation) 10592 switch (operation)
10593 { 10593 {
10594 case ScriptBaseClass.LIST_STAT_RANGE: 10594 case ScriptBaseClass.LIST_STAT_RANGE:
10595 return src.Range(); 10595 return src.Range();
10596 case ScriptBaseClass.LIST_STAT_MIN: 10596 case ScriptBaseClass.LIST_STAT_MIN:
10597 return src.Min(); 10597 return src.Min();
10598 case ScriptBaseClass.LIST_STAT_MAX: 10598 case ScriptBaseClass.LIST_STAT_MAX:
10599 return src.Max(); 10599 return src.Max();
10600 case ScriptBaseClass.LIST_STAT_MEAN: 10600 case ScriptBaseClass.LIST_STAT_MEAN:
10601 return src.Mean(); 10601 return src.Mean();
10602 case ScriptBaseClass.LIST_STAT_MEDIAN: 10602 case ScriptBaseClass.LIST_STAT_MEDIAN:
10603 return LSL_List.ToDoubleList(src).Median(); 10603 return LSL_List.ToDoubleList(src).Median();
10604 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10604 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
10605 return src.NumericLength(); 10605 return src.NumericLength();
10606 case ScriptBaseClass.LIST_STAT_STD_DEV: 10606 case ScriptBaseClass.LIST_STAT_STD_DEV:
10607 return src.StdDev(); 10607 return src.StdDev();
10608 case ScriptBaseClass.LIST_STAT_SUM: 10608 case ScriptBaseClass.LIST_STAT_SUM:
10609 return src.Sum(); 10609 return src.Sum();
10610 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10610 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
10611 return src.SumSqrs(); 10611 return src.SumSqrs();
10612 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10612 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
10613 return src.GeometricMean(); 10613 return src.GeometricMean();
10614 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10614 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
10615 return src.HarmonicMean(); 10615 return src.HarmonicMean();
10616 default: 10616 default:
10617 return 0.0; 10617 return 0.0;
10618 } 10618 }
10619 } 10619 }
10620   10620  
10621 public LSL_Integer llGetUnixTime() 10621 public LSL_Integer llGetUnixTime()
10622 { 10622 {
10623 m_host.AddScriptLPS(1); 10623 m_host.AddScriptLPS(1);
10624 return Util.UnixTimeSinceEpoch(); 10624 return Util.UnixTimeSinceEpoch();
10625 } 10625 }
10626   10626  
10627 public LSL_Integer llGetParcelFlags(LSL_Vector pos) 10627 public LSL_Integer llGetParcelFlags(LSL_Vector pos)
10628 { 10628 {
10629 m_host.AddScriptLPS(1); 10629 m_host.AddScriptLPS(1);
10630 return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags; 10630 return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags;
10631 } 10631 }
10632   10632  
10633 public LSL_Integer llGetRegionFlags() 10633 public LSL_Integer llGetRegionFlags()
10634 { 10634 {
10635 m_host.AddScriptLPS(1); 10635 m_host.AddScriptLPS(1);
10636 IEstateModule estate = World.RequestModuleInterface<IEstateModule>(); 10636 IEstateModule estate = World.RequestModuleInterface<IEstateModule>();
10637 if (estate == null) 10637 if (estate == null)
10638 return 67108864; 10638 return 67108864;
10639 return (int)estate.GetRegionFlags(); 10639 return (int)estate.GetRegionFlags();
10640 } 10640 }
10641   10641  
10642 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10642 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10643 { 10643 {
10644 m_host.AddScriptLPS(1); 10644 m_host.AddScriptLPS(1);
10645 string ret = String.Empty; 10645 string ret = String.Empty;
10646 string src1 = llBase64ToString(str1); 10646 string src1 = llBase64ToString(str1);
10647 string src2 = llBase64ToString(str2); 10647 string src2 = llBase64ToString(str2);
10648 int c = 0; 10648 int c = 0;
10649 for (int i = 0; i < src1.Length; i++) 10649 for (int i = 0; i < src1.Length; i++)
10650 { 10650 {
10651 ret += (char) (src1[i] ^ src2[c]); 10651 ret += (char) (src1[i] ^ src2[c]);
10652   10652  
10653 c++; 10653 c++;
10654 if (c >= src2.Length) 10654 if (c >= src2.Length)
10655 c = 0; 10655 c = 0;
10656 } 10656 }
10657 return llStringToBase64(ret); 10657 return llStringToBase64(ret);
10658 } 10658 }
10659   10659  
10660 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10660 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
10661 { 10661 {
10662 // Partial implementation: support for parameter flags needed 10662 // Partial implementation: support for parameter flags needed
10663 // see http://wiki.secondlife.com/wiki/LlHTTPRequest 10663 // see http://wiki.secondlife.com/wiki/LlHTTPRequest
10664 // parameter flags support are implemented in ScriptsHttpRequests.cs 10664 // parameter flags support are implemented in ScriptsHttpRequests.cs
10665 // in StartHttpRequest 10665 // in StartHttpRequest
10666   10666  
10667 m_host.AddScriptLPS(1); 10667 m_host.AddScriptLPS(1);
10668 IHttpRequestModule httpScriptMod = 10668 IHttpRequestModule httpScriptMod =
10669 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 10669 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
10670 List<string> param = new List<string>(); 10670 List<string> param = new List<string>();
10671 bool ok; 10671 bool ok;
10672 Int32 flag; 10672 Int32 flag;
10673   10673  
10674 for (int i = 0; i < parameters.Data.Length; i += 2) 10674 for (int i = 0; i < parameters.Data.Length; i += 2)
10675 { 10675 {
10676 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag); 10676 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
10677 if (!ok || flag < 0 || 10677 if (!ok || flag < 0 ||
10678 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE) 10678 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
10679 { 10679 {
10680 Error("llHTTPRequest", "Parameter " + i.ToString() + " is an invalid flag"); 10680 Error("llHTTPRequest", "Parameter " + i.ToString() + " is an invalid flag");
10681 } 10681 }
10682   10682  
10683 param.Add(parameters.Data[i].ToString()); //Add parameter flag 10683 param.Add(parameters.Data[i].ToString()); //Add parameter flag
10684   10684  
10685 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER) 10685 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
10686 { 10686 {
10687 param.Add(parameters.Data[i+1].ToString()); //Add parameter value 10687 param.Add(parameters.Data[i+1].ToString()); //Add parameter value
10688 } 10688 }
10689 else 10689 else
10690 { 10690 {
10691 //Parameters are in pairs and custom header takes 10691 //Parameters are in pairs and custom header takes
10692 //arguments in pairs so adjust for header marker. 10692 //arguments in pairs so adjust for header marker.
10693 ++i; 10693 ++i;
10694   10694  
10695 //Maximum of 8 headers are allowed based on the 10695 //Maximum of 8 headers are allowed based on the
10696 //Second Life documentation for llHTTPRequest. 10696 //Second Life documentation for llHTTPRequest.
10697 for (int count = 1; count <= 8; ++count) 10697 for (int count = 1; count <= 8; ++count)
10698 { 10698 {
10699 //Enough parameters remaining for (another) header? 10699 //Enough parameters remaining for (another) header?
10700 if (parameters.Data.Length - i < 2) 10700 if (parameters.Data.Length - i < 2)
10701 { 10701 {
10702 //There must be at least one name/value pair for custom header 10702 //There must be at least one name/value pair for custom header
10703 if (count == 1) 10703 if (count == 1)
10704 Error("llHTTPRequest", "Missing name/value for custom header at parameter " + i.ToString()); 10704 Error("llHTTPRequest", "Missing name/value for custom header at parameter " + i.ToString());
10705 break; 10705 break;
10706 } 10706 }
10707   10707  
10708 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase)) 10708 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
10709 Error("llHTTPRequest", "Name is invalid as a custom header at parameter " + i.ToString()); 10709 Error("llHTTPRequest", "Name is invalid as a custom header at parameter " + i.ToString());
10710   10710  
10711 param.Add(parameters.Data[i].ToString()); 10711 param.Add(parameters.Data[i].ToString());
10712 param.Add(parameters.Data[i+1].ToString()); 10712 param.Add(parameters.Data[i+1].ToString());
10713   10713  
10714 //Have we reached the end of the list of headers? 10714 //Have we reached the end of the list of headers?
10715 //End is marked by a string with a single digit. 10715 //End is marked by a string with a single digit.
10716 if (i+2 >= parameters.Data.Length || 10716 if (i+2 >= parameters.Data.Length ||
10717 Char.IsDigit(parameters.Data[i].ToString()[0])) 10717 Char.IsDigit(parameters.Data[i].ToString()[0]))
10718 { 10718 {
10719 break; 10719 break;
10720 } 10720 }
10721   10721  
10722 i += 2; 10722 i += 2;
10723 } 10723 }
10724 } 10724 }
10725 } 10725 }
10726   10726  
10727 Vector3 position = m_host.AbsolutePosition; 10727 Vector3 position = m_host.AbsolutePosition;
10728 Vector3 velocity = m_host.Velocity; 10728 Vector3 velocity = m_host.Velocity;
10729 Quaternion rotation = m_host.RotationOffset; 10729 Quaternion rotation = m_host.RotationOffset;
10730 string ownerName = String.Empty; 10730 string ownerName = String.Empty;
10731 ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID); 10731 ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID);
10732 if (scenePresence == null) 10732 if (scenePresence == null)
10733 ownerName = resolveName(m_host.OwnerID); 10733 ownerName = resolveName(m_host.OwnerID);
10734 else 10734 else
10735 ownerName = scenePresence.Name; 10735 ownerName = scenePresence.Name;
10736   10736  
10737 RegionInfo regionInfo = World.RegionInfo; 10737 RegionInfo regionInfo = World.RegionInfo;
10738   10738  
10739 Dictionary<string, string> httpHeaders = new Dictionary<string, string>(); 10739 Dictionary<string, string> httpHeaders = new Dictionary<string, string>();
10740   10740  
10741 string shard = "OpenSim"; 10741 string shard = "OpenSim";
10742 IConfigSource config = m_ScriptEngine.ConfigSource; 10742 IConfigSource config = m_ScriptEngine.ConfigSource;
10743 if (config.Configs["Network"] != null) 10743 if (config.Configs["Network"] != null)
10744 { 10744 {
10745 shard = config.Configs["Network"].GetString("shard", shard); 10745 shard = config.Configs["Network"].GetString("shard", shard);
10746 } 10746 }
10747   10747  
10748 httpHeaders["X-SecondLife-Shard"] = shard; 10748 httpHeaders["X-SecondLife-Shard"] = shard;
10749 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name; 10749 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name;
10750 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString(); 10750 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString();
10751 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY); 10751 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY);
10752 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z); 10752 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z);
10753 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); 10753 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z);
10754 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); 10754 httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W);
10755 httpHeaders["X-SecondLife-Owner-Name"] = ownerName; 10755 httpHeaders["X-SecondLife-Owner-Name"] = ownerName;
10756 httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString(); 10756 httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString();
10757 string userAgent = config.Configs["Network"].GetString("user_agent", null); 10757 string userAgent = config.Configs["Network"].GetString("user_agent", null);
10758 if (userAgent != null) 10758 if (userAgent != null)
10759 httpHeaders["User-Agent"] = userAgent; 10759 httpHeaders["User-Agent"] = userAgent;
10760   10760  
10761 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 10761 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10762 Regex r = new Regex(authregex); 10762 Regex r = new Regex(authregex);
10763 int[] gnums = r.GetGroupNumbers(); 10763 int[] gnums = r.GetGroupNumbers();
10764 Match m = r.Match(url); 10764 Match m = r.Match(url);
10765 if (m.Success) { 10765 if (m.Success) {
10766 for (int i = 1; i < gnums.Length; i++) { 10766 for (int i = 1; i < gnums.Length; i++) {
10767 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10767 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10768 //CaptureCollection cc = g.Captures; 10768 //CaptureCollection cc = g.Captures;
10769 } 10769 }
10770 if (m.Groups.Count == 5) { 10770 if (m.Groups.Count == 5) {
10771 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10771 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10772 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10772 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10773 } 10773 }
10774 } 10774 }
10775   10775  
10776 UUID reqID 10776 UUID reqID
10777 = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body); 10777 = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body);
10778   10778  
10779 if (reqID != UUID.Zero) 10779 if (reqID != UUID.Zero)
10780 return reqID.ToString(); 10780 return reqID.ToString();
10781 else 10781 else
10782 return null; 10782 return null;
10783 } 10783 }
10784   10784  
10785   10785  
10786 public void llHTTPResponse(LSL_Key id, int status, string body) 10786 public void llHTTPResponse(LSL_Key id, int status, string body)
10787 { 10787 {
10788 // Partial implementation: support for parameter flags needed 10788 // Partial implementation: support for parameter flags needed
10789 // see http://wiki.secondlife.com/wiki/llHTTPResponse 10789 // see http://wiki.secondlife.com/wiki/llHTTPResponse
10790   10790  
10791 m_host.AddScriptLPS(1); 10791 m_host.AddScriptLPS(1);
10792   10792  
10793 if (m_UrlModule != null) 10793 if (m_UrlModule != null)
10794 m_UrlModule.HttpResponse(new UUID(id), status,body); 10794 m_UrlModule.HttpResponse(new UUID(id), status,body);
10795 } 10795 }
10796   10796  
10797 public void llResetLandBanList() 10797 public void llResetLandBanList()
10798 { 10798 {
10799 m_host.AddScriptLPS(1); 10799 m_host.AddScriptLPS(1);
10800 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; 10800 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10801 if (land.OwnerID == m_host.OwnerID) 10801 if (land.OwnerID == m_host.OwnerID)
10802 { 10802 {
10803 foreach (LandAccessEntry entry in land.ParcelAccessList) 10803 foreach (LandAccessEntry entry in land.ParcelAccessList)
10804 { 10804 {
10805 if (entry.Flags == AccessList.Ban) 10805 if (entry.Flags == AccessList.Ban)
10806 { 10806 {
10807 land.ParcelAccessList.Remove(entry); 10807 land.ParcelAccessList.Remove(entry);
10808 } 10808 }
10809 } 10809 }
10810 } 10810 }
10811 ScriptSleep(100); 10811 ScriptSleep(100);
10812 } 10812 }
10813   10813  
10814 public void llResetLandPassList() 10814 public void llResetLandPassList()
10815 { 10815 {
10816 m_host.AddScriptLPS(1); 10816 m_host.AddScriptLPS(1);
10817 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; 10817 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10818 if (land.OwnerID == m_host.OwnerID) 10818 if (land.OwnerID == m_host.OwnerID)
10819 { 10819 {
10820 foreach (LandAccessEntry entry in land.ParcelAccessList) 10820 foreach (LandAccessEntry entry in land.ParcelAccessList)
10821 { 10821 {
10822 if (entry.Flags == AccessList.Access) 10822 if (entry.Flags == AccessList.Access)
10823 { 10823 {
10824 land.ParcelAccessList.Remove(entry); 10824 land.ParcelAccessList.Remove(entry);
10825 } 10825 }
10826 } 10826 }
10827 } 10827 }
10828 ScriptSleep(100); 10828 ScriptSleep(100);
10829 } 10829 }
10830   10830  
10831 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 10831 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
10832 { 10832 {
10833 m_host.AddScriptLPS(1); 10833 m_host.AddScriptLPS(1);
10834   10834  
10835 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10835 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10836   10836  
10837 if (lo == null) 10837 if (lo == null)
10838 return 0; 10838 return 0;
10839   10839  
10840 IPrimCounts pc = lo.PrimCounts; 10840 IPrimCounts pc = lo.PrimCounts;
10841   10841  
10842 if (sim_wide != ScriptBaseClass.FALSE) 10842 if (sim_wide != ScriptBaseClass.FALSE)
10843 { 10843 {
10844 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL) 10844 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
10845 { 10845 {
10846 return pc.Simulator; 10846 return pc.Simulator;
10847 } 10847 }
10848 else 10848 else
10849 { 10849 {
10850 // counts not implemented yet 10850 // counts not implemented yet
10851 return 0; 10851 return 0;
10852 } 10852 }
10853 } 10853 }
10854 else 10854 else
10855 { 10855 {
10856 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL) 10856 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
10857 return pc.Total; 10857 return pc.Total;
10858 else if (category == ScriptBaseClass.PARCEL_COUNT_OWNER) 10858 else if (category == ScriptBaseClass.PARCEL_COUNT_OWNER)
10859 return pc.Owner; 10859 return pc.Owner;
10860 else if (category == ScriptBaseClass.PARCEL_COUNT_GROUP) 10860 else if (category == ScriptBaseClass.PARCEL_COUNT_GROUP)
10861 return pc.Group; 10861 return pc.Group;
10862 else if (category == ScriptBaseClass.PARCEL_COUNT_OTHER) 10862 else if (category == ScriptBaseClass.PARCEL_COUNT_OTHER)
10863 return pc.Others; 10863 return pc.Others;
10864 else if (category == ScriptBaseClass.PARCEL_COUNT_SELECTED) 10864 else if (category == ScriptBaseClass.PARCEL_COUNT_SELECTED)
10865 return pc.Selected; 10865 return pc.Selected;
10866 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 10866 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
10867 return 0; // counts not implemented yet 10867 return 0; // counts not implemented yet
10868 } 10868 }
10869   10869  
10870 return 0; 10870 return 0;
10871 } 10871 }
10872   10872  
10873 public LSL_List llGetParcelPrimOwners(LSL_Vector pos) 10873 public LSL_List llGetParcelPrimOwners(LSL_Vector pos)
10874 { 10874 {
10875 m_host.AddScriptLPS(1); 10875 m_host.AddScriptLPS(1);
10876 LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10876 LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10877 LSL_List ret = new LSL_List(); 10877 LSL_List ret = new LSL_List();
10878 if (land != null) 10878 if (land != null)
10879 { 10879 {
10880 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10880 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
10881 { 10881 {
10882 ret.Add(new LSL_String(detectedParams.Key.ToString())); 10882 ret.Add(new LSL_String(detectedParams.Key.ToString()));
10883 ret.Add(new LSL_Integer(detectedParams.Value)); 10883 ret.Add(new LSL_Integer(detectedParams.Value));
10884 } 10884 }
10885 } 10885 }
10886 ScriptSleep(2000); 10886 ScriptSleep(2000);
10887 return ret; 10887 return ret;
10888 } 10888 }
10889   10889  
10890 public LSL_Integer llGetObjectPrimCount(string object_id) 10890 public LSL_Integer llGetObjectPrimCount(string object_id)
10891 { 10891 {
10892 m_host.AddScriptLPS(1); 10892 m_host.AddScriptLPS(1);
10893 SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id)); 10893 SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id));
10894 if (part == null) 10894 if (part == null)
10895 { 10895 {
10896 return 0; 10896 return 0;
10897 } 10897 }
10898 else 10898 else
10899 { 10899 {
10900 return part.ParentGroup.PrimCount; 10900 return part.ParentGroup.PrimCount;
10901 } 10901 }
10902 } 10902 }
10903   10903  
10904 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide) 10904 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide)
10905 { 10905 {
10906 m_host.AddScriptLPS(1); 10906 m_host.AddScriptLPS(1);
10907   10907  
10908 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10908 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10909   10909  
10910 if (lo == null) 10910 if (lo == null)
10911 return 0; 10911 return 0;
10912   10912  
10913 if (sim_wide != 0) 10913 if (sim_wide != 0)
10914 return lo.GetSimulatorMaxPrimCount(); 10914 return lo.GetSimulatorMaxPrimCount();
10915 else 10915 else
10916 return lo.GetParcelMaxPrimCount(); 10916 return lo.GetParcelMaxPrimCount();
10917 } 10917 }
10918   10918  
10919 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 10919 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
10920 { 10920 {
10921 m_host.AddScriptLPS(1); 10921 m_host.AddScriptLPS(1);
10922 LandData land = World.GetLandData(pos); 10922 LandData land = World.GetLandData(pos);
10923 if (land == null) 10923 if (land == null)
10924 { 10924 {
10925 return new LSL_List(0); 10925 return new LSL_List(0);
10926 } 10926 }
10927 LSL_List ret = new LSL_List(); 10927 LSL_List ret = new LSL_List();
10928 foreach (object o in param.Data) 10928 foreach (object o in param.Data)
10929 { 10929 {
10930 switch (o.ToString()) 10930 switch (o.ToString())
10931 { 10931 {
10932 case "0": 10932 case "0":
10933 ret.Add(new LSL_String(land.Name)); 10933 ret.Add(new LSL_String(land.Name));
10934 break; 10934 break;
10935 case "1": 10935 case "1":
10936 ret.Add(new LSL_String(land.Description)); 10936 ret.Add(new LSL_String(land.Description));
10937 break; 10937 break;
10938 case "2": 10938 case "2":
10939 ret.Add(new LSL_Key(land.OwnerID.ToString())); 10939 ret.Add(new LSL_Key(land.OwnerID.ToString()));
10940 break; 10940 break;
10941 case "3": 10941 case "3":
10942 ret.Add(new LSL_Key(land.GroupID.ToString())); 10942 ret.Add(new LSL_Key(land.GroupID.ToString()));
10943 break; 10943 break;
10944 case "4": 10944 case "4":
10945 ret.Add(new LSL_Integer(land.Area)); 10945 ret.Add(new LSL_Integer(land.Area));
10946 break; 10946 break;
10947 case "5": 10947 case "5":
10948 ret.Add(new LSL_Key(land.GlobalID.ToString())); 10948 ret.Add(new LSL_Key(land.GlobalID.ToString()));
10949 break; 10949 break;
10950 default: 10950 default:
10951 ret.Add(new LSL_Integer(0)); 10951 ret.Add(new LSL_Integer(0));
10952 break; 10952 break;
10953 } 10953 }
10954 } 10954 }
10955 return ret; 10955 return ret;
10956 } 10956 }
10957   10957  
10958 public LSL_String llStringTrim(string src, int type) 10958 public LSL_String llStringTrim(string src, int type)
10959 { 10959 {
10960 m_host.AddScriptLPS(1); 10960 m_host.AddScriptLPS(1);
10961 if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); } 10961 if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); }
10962 if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); } 10962 if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); }
10963 if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); } 10963 if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); }
10964 return src; 10964 return src;
10965 } 10965 }
10966   10966  
10967 public LSL_List llGetObjectDetails(string id, LSL_List args) 10967 public LSL_List llGetObjectDetails(string id, LSL_List args)
10968 { 10968 {
10969 m_host.AddScriptLPS(1); 10969 m_host.AddScriptLPS(1);
10970   10970  
10971 LSL_List ret = new LSL_List(); 10971 LSL_List ret = new LSL_List();
10972 UUID key = new UUID(); 10972 UUID key = new UUID();
10973 if (UUID.TryParse(id, out key)) 10973 if (UUID.TryParse(id, out key))
10974 { 10974 {
10975 ScenePresence av = World.GetScenePresence(key); 10975 ScenePresence av = World.GetScenePresence(key);
10976   10976  
10977 if (av != null) 10977 if (av != null)
10978 { 10978 {
10979 foreach (object o in args.Data) 10979 foreach (object o in args.Data)
10980 { 10980 {
10981 switch (int.Parse(o.ToString())) 10981 switch (int.Parse(o.ToString()))
10982 { 10982 {
10983 case ScriptBaseClass.OBJECT_NAME: 10983 case ScriptBaseClass.OBJECT_NAME:
10984 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname)); 10984 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname));
10985 break; 10985 break;
10986 case ScriptBaseClass.OBJECT_DESC: 10986 case ScriptBaseClass.OBJECT_DESC:
10987 ret.Add(new LSL_String("")); 10987 ret.Add(new LSL_String(""));
10988 break; 10988 break;
10989 case ScriptBaseClass.OBJECT_POS: 10989 case ScriptBaseClass.OBJECT_POS:
10990 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10990 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
10991 break; 10991 break;
10992 case ScriptBaseClass.OBJECT_ROT: 10992 case ScriptBaseClass.OBJECT_ROT:
10993 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 10993 ret.Add(new LSL_Rotation(av.GetWorldRotation()));
10994 break; 10994 break;
10995 case ScriptBaseClass.OBJECT_VELOCITY: 10995 case ScriptBaseClass.OBJECT_VELOCITY:
10996 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10996 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
10997 break; 10997 break;
10998 case ScriptBaseClass.OBJECT_OWNER: 10998 case ScriptBaseClass.OBJECT_OWNER:
10999 ret.Add(new LSL_String(id)); 10999 ret.Add(new LSL_String(id));
11000 break; 11000 break;
11001 case ScriptBaseClass.OBJECT_GROUP: 11001 case ScriptBaseClass.OBJECT_GROUP:
11002 ret.Add(new LSL_String(UUID.Zero.ToString())); 11002 ret.Add(new LSL_String(UUID.Zero.ToString()));
11003 break; 11003 break;
11004 case ScriptBaseClass.OBJECT_CREATOR: 11004 case ScriptBaseClass.OBJECT_CREATOR:
11005 ret.Add(new LSL_String(UUID.Zero.ToString())); 11005 ret.Add(new LSL_String(UUID.Zero.ToString()));
11006 break; 11006 break;
11007 // For the following 8 see the Object version below 11007 // For the following 8 see the Object version below
11008 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 11008 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
11009 ret.Add(new LSL_Integer(av.RunningScriptCount())); 11009 ret.Add(new LSL_Integer(av.RunningScriptCount()));
11010 break; 11010 break;
11011 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11011 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11012 ret.Add(new LSL_Integer(av.ScriptCount())); 11012 ret.Add(new LSL_Integer(av.ScriptCount()));
11013 break; 11013 break;
11014 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11014 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11015 ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); 11015 ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384));
11016 break; 11016 break;
11017 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11017 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11018 ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f)); 11018 ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f));
11019 break; 11019 break;
11020 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11020 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11021 ret.Add(new LSL_Integer(1)); 11021 ret.Add(new LSL_Integer(1));
11022 break; 11022 break;
11023 case ScriptBaseClass.OBJECT_SERVER_COST: 11023 case ScriptBaseClass.OBJECT_SERVER_COST:
11024 ret.Add(new LSL_Float(0)); 11024 ret.Add(new LSL_Float(0));
11025 break; 11025 break;
11026 case ScriptBaseClass.OBJECT_STREAMING_COST: 11026 case ScriptBaseClass.OBJECT_STREAMING_COST:
11027 ret.Add(new LSL_Float(0)); 11027 ret.Add(new LSL_Float(0));
11028 break; 11028 break;
11029 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11029 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11030 ret.Add(new LSL_Float(0)); 11030 ret.Add(new LSL_Float(0));
11031 break; 11031 break;
11032 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11032 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11033 ret.Add(new LSL_Float(0)); 11033 ret.Add(new LSL_Float(0));
11034 break; 11034 break;
11035 case ScriptBaseClass.OBJECT_ROOT: 11035 case ScriptBaseClass.OBJECT_ROOT:
11036 SceneObjectPart p = av.ParentPart; 11036 SceneObjectPart p = av.ParentPart;
11037 if (p != null) 11037 if (p != null)
11038 { 11038 {
11039 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString())); 11039 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString()));
11040 } 11040 }
11041 else 11041 else
11042 { 11042 {
11043 ret.Add(new LSL_String(id)); 11043 ret.Add(new LSL_String(id));
11044 } 11044 }
11045 break; 11045 break;
11046 case ScriptBaseClass.OBJECT_ATTACHED_POINT: 11046 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11047 ret.Add(new LSL_Integer(0)); 11047 ret.Add(new LSL_Integer(0));
11048 break; 11048 break;
11049 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding 11049 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding
11050 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR)); 11050 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR));
11051 break; 11051 break;
11052 case ScriptBaseClass.OBJECT_PHYSICS: 11052 case ScriptBaseClass.OBJECT_PHYSICS:
11053 ret.Add(new LSL_Integer(0)); 11053 ret.Add(new LSL_Integer(0));
11054 break; 11054 break;
11055 case ScriptBaseClass.OBJECT_PHANTOM: 11055 case ScriptBaseClass.OBJECT_PHANTOM:
11056 ret.Add(new LSL_Integer(0)); 11056 ret.Add(new LSL_Integer(0));
11057 break; 11057 break;
11058 case ScriptBaseClass.OBJECT_TEMP_ON_REZ: 11058 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11059 ret.Add(new LSL_Integer(0)); 11059 ret.Add(new LSL_Integer(0));
11060 break; 11060 break;
11061 default: 11061 default:
11062 // Invalid or unhandled constant. 11062 // Invalid or unhandled constant.
11063 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11063 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
11064 break; 11064 break;
11065 } 11065 }
11066 } 11066 }
11067   11067  
11068 return ret; 11068 return ret;
11069 } 11069 }
11070   11070  
11071 SceneObjectPart obj = World.GetSceneObjectPart(key); 11071 SceneObjectPart obj = World.GetSceneObjectPart(key);
11072 if (obj != null) 11072 if (obj != null)
11073 { 11073 {
11074 foreach (object o in args.Data) 11074 foreach (object o in args.Data)
11075 { 11075 {
11076 switch (int.Parse(o.ToString())) 11076 switch (int.Parse(o.ToString()))
11077 { 11077 {
11078 case ScriptBaseClass.OBJECT_NAME: 11078 case ScriptBaseClass.OBJECT_NAME:
11079 ret.Add(new LSL_String(obj.Name)); 11079 ret.Add(new LSL_String(obj.Name));
11080 break; 11080 break;
11081 case ScriptBaseClass.OBJECT_DESC: 11081 case ScriptBaseClass.OBJECT_DESC:
11082 ret.Add(new LSL_String(obj.Description)); 11082 ret.Add(new LSL_String(obj.Description));
11083 break; 11083 break;
11084 case ScriptBaseClass.OBJECT_POS: 11084 case ScriptBaseClass.OBJECT_POS:
11085 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11085 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z));
11086 break; 11086 break;
11087 case ScriptBaseClass.OBJECT_ROT: 11087 case ScriptBaseClass.OBJECT_ROT:
11088 { 11088 {
11089 Quaternion rot = Quaternion.Identity; 11089 Quaternion rot = Quaternion.Identity;
11090   11090  
11091 if (obj.ParentGroup.RootPart == obj) 11091 if (obj.ParentGroup.RootPart == obj)
11092 rot = obj.ParentGroup.GroupRotation; 11092 rot = obj.ParentGroup.GroupRotation;
11093 else 11093 else
11094 rot = obj.GetWorldRotation(); 11094 rot = obj.GetWorldRotation();
11095   11095  
11096 LSL_Rotation objrot = new LSL_Rotation(rot); 11096 LSL_Rotation objrot = new LSL_Rotation(rot);
11097 ret.Add(objrot); 11097 ret.Add(objrot);
11098 } 11098 }
11099 break; 11099 break;
11100 case ScriptBaseClass.OBJECT_VELOCITY: 11100 case ScriptBaseClass.OBJECT_VELOCITY:
11101 ret.Add(new LSL_Vector(obj.Velocity)); 11101 ret.Add(new LSL_Vector(obj.Velocity));
11102 break; 11102 break;
11103 case ScriptBaseClass.OBJECT_OWNER: 11103 case ScriptBaseClass.OBJECT_OWNER:
11104 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11104 ret.Add(new LSL_String(obj.OwnerID.ToString()));
11105 break; 11105 break;
11106 case ScriptBaseClass.OBJECT_GROUP: 11106 case ScriptBaseClass.OBJECT_GROUP:
11107 ret.Add(new LSL_String(obj.GroupID.ToString())); 11107 ret.Add(new LSL_String(obj.GroupID.ToString()));
11108 break; 11108 break;
11109 case ScriptBaseClass.OBJECT_CREATOR: 11109 case ScriptBaseClass.OBJECT_CREATOR:
11110 ret.Add(new LSL_String(obj.CreatorID.ToString())); 11110 ret.Add(new LSL_String(obj.CreatorID.ToString()));
11111 break; 11111 break;
11112 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 11112 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
11113 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount())); 11113 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount()));
11114 break; 11114 break;
11115 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11115 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11116 ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount())); 11116 ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount()));
11117 break; 11117 break;
11118 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11118 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11119 // The value returned in SL for mono scripts is 65536 * number of active scripts 11119 // The value returned in SL for mono scripts is 65536 * number of active scripts
11120 // and 16384 * number of active scripts for LSO. since llGetFreememory 11120 // and 16384 * number of active scripts for LSO. since llGetFreememory
11121 // is coded to give the LSO value use it here 11121 // is coded to give the LSO value use it here
11122 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); 11122 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384));
11123 break; 11123 break;
11124 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11124 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11125 // Average cpu time in seconds per simulator frame expended on all scripts in the object 11125 // Average cpu time in seconds per simulator frame expended on all scripts in the object
11126 ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f)); 11126 ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f));
11127 break; 11127 break;
11128 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11128 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11129 // according to the SL wiki A prim or linkset will have prim 11129 // according to the SL wiki A prim or linkset will have prim
11130 // equivalent of the number of prims in a linkset if it does not 11130 // equivalent of the number of prims in a linkset if it does not
11131 // contain a mesh anywhere in the link set or is not a normal prim 11131 // contain a mesh anywhere in the link set or is not a normal prim
11132 // The value returned in SL for normal prims is prim count 11132 // The value returned in SL for normal prims is prim count
11133 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11133 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11134 break; 11134 break;
11135 // The following 3 costs I have intentionaly coded to return zero. They are part of 11135 // The following 3 costs I have intentionaly coded to return zero. They are part of
11136 // "Land Impact" calculations. These calculations are probably not applicable 11136 // "Land Impact" calculations. These calculations are probably not applicable
11137 // to OpenSim and are not yet complete in SL 11137 // to OpenSim and are not yet complete in SL
11138 case ScriptBaseClass.OBJECT_SERVER_COST: 11138 case ScriptBaseClass.OBJECT_SERVER_COST:
11139 // The linden calculation is here 11139 // The linden calculation is here
11140 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11140 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
11141 // The value returned in SL for normal prims looks like the prim count 11141 // The value returned in SL for normal prims looks like the prim count
11142 ret.Add(new LSL_Float(0)); 11142 ret.Add(new LSL_Float(0));
11143 break; 11143 break;
11144 case ScriptBaseClass.OBJECT_STREAMING_COST: 11144 case ScriptBaseClass.OBJECT_STREAMING_COST:
11145 // The linden calculation is here 11145 // The linden calculation is here
11146 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11146 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost
11147 // The value returned in SL for normal prims looks like the prim count * 0.06 11147 // The value returned in SL for normal prims looks like the prim count * 0.06
11148 ret.Add(new LSL_Float(0)); 11148 ret.Add(new LSL_Float(0));
11149 break; 11149 break;
11150 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11150 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11151 // The linden calculation is here 11151 // The linden calculation is here
11152 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11152 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics
11153 // The value returned in SL for normal prims looks like the prim count 11153 // The value returned in SL for normal prims looks like the prim count
11154 ret.Add(new LSL_Float(0)); 11154 ret.Add(new LSL_Float(0));
11155 break; 11155 break;
11156 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11156 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11157 ret.Add(new LSL_Float(0)); 11157 ret.Add(new LSL_Float(0));
11158 break; 11158 break;
11159 case ScriptBaseClass.OBJECT_ROOT: 11159 case ScriptBaseClass.OBJECT_ROOT:
11160 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString())); 11160 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString()));
11161 break; 11161 break;
11162 case ScriptBaseClass.OBJECT_ATTACHED_POINT: 11162 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11163 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint)); 11163 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint));
11164 break; 11164 break;
11165 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: 11165 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE:
11166 byte pcode = obj.Shape.PCode; 11166 byte pcode = obj.Shape.PCode;
11167 if (obj.ParentGroup.AttachmentPoint != 0 11167 if (obj.ParentGroup.AttachmentPoint != 0
11168 || pcode == (byte)PCode.Grass 11168 || pcode == (byte)PCode.Grass
11169 || pcode == (byte)PCode.Tree 11169 || pcode == (byte)PCode.Tree
11170 || pcode == (byte)PCode.NewTree) 11170 || pcode == (byte)PCode.NewTree)
11171 { 11171 {
11172 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER)); 11172 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER));
11173 } 11173 }
11174 else 11174 else
11175 { 11175 {
11176 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET)); 11176 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET));
11177 } 11177 }
11178 break; 11178 break;
11179 case ScriptBaseClass.OBJECT_PHYSICS: 11179 case ScriptBaseClass.OBJECT_PHYSICS:
11180 if (obj.ParentGroup.AttachmentPoint != 0) 11180 if (obj.ParentGroup.AttachmentPoint != 0)
11181 { 11181 {
11182 ret.Add(new LSL_Integer(0)); // Always false if attached 11182 ret.Add(new LSL_Integer(0)); // Always false if attached
11183 } 11183 }
11184 else 11184 else
11185 { 11185 {
11186 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0)); 11186 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0));
11187 } 11187 }
11188 break; 11188 break;
11189 case ScriptBaseClass.OBJECT_PHANTOM: 11189 case ScriptBaseClass.OBJECT_PHANTOM:
11190 if (obj.ParentGroup.AttachmentPoint != 0) 11190 if (obj.ParentGroup.AttachmentPoint != 0)
11191 { 11191 {
11192 ret.Add(new LSL_Integer(0)); // Always false if attached 11192 ret.Add(new LSL_Integer(0)); // Always false if attached
11193 } 11193 }
11194 else 11194 else
11195 { 11195 {
11196 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0)); 11196 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0));
11197 } 11197 }
11198 break; 11198 break;
11199 case ScriptBaseClass.OBJECT_TEMP_ON_REZ: 11199 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11200 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); 11200 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0));
11201 break; 11201 break;
11202 default: 11202 default:
11203 // Invalid or unhandled constant. 11203 // Invalid or unhandled constant.
11204 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11204 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
11205 break; 11205 break;
11206 } 11206 }
11207 } 11207 }
11208   11208  
11209 return ret; 11209 return ret;
11210 } 11210 }
11211 } 11211 }
11212   11212  
11213 return new LSL_List(); 11213 return new LSL_List();
11214 } 11214 }
11215   11215  
11216 internal UUID GetScriptByName(string name) 11216 internal UUID GetScriptByName(string name)
11217 { 11217 {
11218 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11218 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11219   11219  
11220 if (item == null || item.Type != 10) 11220 if (item == null || item.Type != 10)
11221 return UUID.Zero; 11221 return UUID.Zero;
11222   11222  
11223 return item.ItemID; 11223 return item.ItemID;
11224 } 11224 }
11225   11225  
11226 /// <summary> 11226 /// <summary>
11227 /// Reports the script error in the viewer's Script Warning/Error dialog and shouts it on the debug channel. 11227 /// Reports the script error in the viewer's Script Warning/Error dialog and shouts it on the debug channel.
11228 /// </summary> 11228 /// </summary>
11229 /// <param name="command">The name of the command that generated the error.</param> 11229 /// <param name="command">The name of the command that generated the error.</param>
11230 /// <param name="message">The error message to report to the user.</param> 11230 /// <param name="message">The error message to report to the user.</param>
11231 internal void Error(string command, string message) 11231 internal void Error(string command, string message)
11232 { 11232 {
11233 string text = command + ": " + message; 11233 string text = command + ": " + message;
11234 if (text.Length > 1023) 11234 if (text.Length > 1023)
11235 { 11235 {
11236 text = text.Substring(0, 1023); 11236 text = text.Substring(0, 1023);
11237 } 11237 }
11238   11238  
11239 World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, ScriptBaseClass.DEBUG_CHANNEL, 11239 World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, ScriptBaseClass.DEBUG_CHANNEL,
11240 m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false); 11240 m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
11241   11241  
11242 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 11242 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
11243 if (wComm != null) 11243 if (wComm != null)
11244 { 11244 {
11245 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, text); 11245 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, text);
11246 } 11246 }
11247 } 11247 }
11248   11248  
11249 /// <summary> 11249 /// <summary>
11250 /// Reports that the command is not implemented as a script error. 11250 /// Reports that the command is not implemented as a script error.
11251 /// </summary> 11251 /// </summary>
11252 /// <param name="command">The name of the command that is not implemented.</param> 11252 /// <param name="command">The name of the command that is not implemented.</param>
11253 /// <param name="message">Additional information to report to the user. (Optional)</param> 11253 /// <param name="message">Additional information to report to the user. (Optional)</param>
11254 internal void NotImplemented(string command, string message = "") 11254 internal void NotImplemented(string command, string message = "")
11255 { 11255 {
11256 if (throwErrorOnNotImplemented) 11256 if (throwErrorOnNotImplemented)
11257 { 11257 {
11258 if (message != "") 11258 if (message != "")
11259 { 11259 {
11260 message = " - " + message; 11260 message = " - " + message;
11261 } 11261 }
11262   11262  
11263 throw new NotImplementedException("Command not implemented: " + command + message); 11263 throw new NotImplementedException("Command not implemented: " + command + message);
11264 } 11264 }
11265 else 11265 else
11266 { 11266 {
11267 string text = "Command not implemented"; 11267 string text = "Command not implemented";
11268 if (message != "") 11268 if (message != "")
11269 { 11269 {
11270 text = text + " - " + message; 11270 text = text + " - " + message;
11271 } 11271 }
11272   11272  
11273 Error(command, text); 11273 Error(command, text);
11274 } 11274 }
11275 } 11275 }
11276   11276  
11277 /// <summary> 11277 /// <summary>
11278 /// Reports that the command is deprecated as a script error. 11278 /// Reports that the command is deprecated as a script error.
11279 /// </summary> 11279 /// </summary>
11280 /// <param name="command">The name of the command that is deprecated.</param> 11280 /// <param name="command">The name of the command that is deprecated.</param>
11281 /// <param name="message">Additional information to report to the user. (Optional)</param> 11281 /// <param name="message">Additional information to report to the user. (Optional)</param>
11282 internal void Deprecated(string command, string message = "") 11282 internal void Deprecated(string command, string message = "")
11283 { 11283 {
11284 string text = "Command deprecated"; 11284 string text = "Command deprecated";
11285 if (message != "") 11285 if (message != "")
11286 { 11286 {
11287 text = text + " - " + message; 11287 text = text + " - " + message;
11288 } 11288 }
11289   11289  
11290 Error(command, text); 11290 Error(command, text);
11291 } 11291 }
11292   11292  
11293 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset); 11293 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset);
11294 protected void WithNotecard(UUID assetID, AssetRequestCallback cb) 11294 protected void WithNotecard(UUID assetID, AssetRequestCallback cb)
11295 { 11295 {
11296 World.AssetService.Get(assetID.ToString(), this, 11296 World.AssetService.Get(assetID.ToString(), this,
11297 delegate(string i, object sender, AssetBase a) 11297 delegate(string i, object sender, AssetBase a)
11298 { 11298 {
11299 UUID uuid = UUID.Zero; 11299 UUID uuid = UUID.Zero;
11300 UUID.TryParse(i, out uuid); 11300 UUID.TryParse(i, out uuid);
11301 cb(uuid, a); 11301 cb(uuid, a);
11302 }); 11302 });
11303 } 11303 }
11304   11304  
11305 public LSL_String llGetNumberOfNotecardLines(string name) 11305 public LSL_String llGetNumberOfNotecardLines(string name)
11306 { 11306 {
11307 m_host.AddScriptLPS(1); 11307 m_host.AddScriptLPS(1);
11308   11308  
11309 UUID assetID = UUID.Zero; 11309 UUID assetID = UUID.Zero;
11310   11310  
11311 if (!UUID.TryParse(name, out assetID)) 11311 if (!UUID.TryParse(name, out assetID))
11312 { 11312 {
11313 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11313 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11314   11314  
11315 if (item != null && item.Type == 7) 11315 if (item != null && item.Type == 7)
11316 assetID = item.AssetID; 11316 assetID = item.AssetID;
11317 } 11317 }
11318   11318  
11319 if (assetID == UUID.Zero) 11319 if (assetID == UUID.Zero)
11320 { 11320 {
11321 // => complain loudly, as specified by the LSL docs 11321 // => complain loudly, as specified by the LSL docs
11322 Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'"); 11322 Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'");
11323   11323  
11324 return UUID.Zero.ToString(); 11324 return UUID.Zero.ToString();
11325 } 11325 }
11326   11326  
11327 string reqIdentifier = UUID.Random().ToString(); 11327 string reqIdentifier = UUID.Random().ToString();
11328   11328  
11329 // was: UUID tid = tid = AsyncCommands. 11329 // was: UUID tid = tid = AsyncCommands.
11330 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); 11330 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11331   11331  
11332 if (NotecardCache.IsCached(assetID)) 11332 if (NotecardCache.IsCached(assetID))
11333 { 11333 {
11334 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString()); 11334 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
11335   11335  
11336 ScriptSleep(100); 11336 ScriptSleep(100);
11337 return tid.ToString(); 11337 return tid.ToString();
11338 } 11338 }
11339   11339  
11340 WithNotecard(assetID, delegate (UUID id, AssetBase a) 11340 WithNotecard(assetID, delegate (UUID id, AssetBase a)
11341 { 11341 {
11342 if (a == null || a.Type != 7) 11342 if (a == null || a.Type != 7)
11343 { 11343 {
11344 Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'"); 11344 Error("llGetNumberOfNotecardLines", "Can't find notecard '" + name + "'");
11345 return; 11345 return;
11346 } 11346 }
11347   11347  
11348 string data = Encoding.UTF8.GetString(a.Data); 11348 string data = Encoding.UTF8.GetString(a.Data);
11349 //m_log.Debug(data); 11349 //m_log.Debug(data);
11350 NotecardCache.Cache(id, data); 11350 NotecardCache.Cache(id, data);
11351 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString()); 11351 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11352 }); 11352 });
11353   11353  
11354 ScriptSleep(100); 11354 ScriptSleep(100);
11355 return tid.ToString(); 11355 return tid.ToString();
11356 } 11356 }
11357   11357  
11358 public LSL_String llGetNotecardLine(string name, int line) 11358 public LSL_String llGetNotecardLine(string name, int line)
11359 { 11359 {
11360 m_host.AddScriptLPS(1); 11360 m_host.AddScriptLPS(1);
11361   11361  
11362 UUID assetID = UUID.Zero; 11362 UUID assetID = UUID.Zero;
11363   11363  
11364 if (!UUID.TryParse(name, out assetID)) 11364 if (!UUID.TryParse(name, out assetID))
11365 { 11365 {
11366 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11366 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11367   11367  
11368 if (item != null && item.Type == 7) 11368 if (item != null && item.Type == 7)
11369 assetID = item.AssetID; 11369 assetID = item.AssetID;
11370 } 11370 }
11371   11371  
11372 if (assetID == UUID.Zero) 11372 if (assetID == UUID.Zero)
11373 { 11373 {
11374 // => complain loudly, as specified by the LSL docs 11374 // => complain loudly, as specified by the LSL docs
11375 Error("llGetNotecardLine", "Can't find notecard '" + name + "'"); 11375 Error("llGetNotecardLine", "Can't find notecard '" + name + "'");
11376   11376  
11377 return UUID.Zero.ToString(); 11377 return UUID.Zero.ToString();
11378 } 11378 }
11379   11379  
11380 string reqIdentifier = UUID.Random().ToString(); 11380 string reqIdentifier = UUID.Random().ToString();
11381   11381  
11382 // was: UUID tid = tid = AsyncCommands. 11382 // was: UUID tid = tid = AsyncCommands.
11383 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); 11383 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11384   11384  
11385 if (NotecardCache.IsCached(assetID)) 11385 if (NotecardCache.IsCached(assetID))
11386 { 11386 {
11387 AsyncCommands.DataserverPlugin.DataserverReply( 11387 AsyncCommands.DataserverPlugin.DataserverReply(
11388 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11388 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11389   11389  
11390 ScriptSleep(100); 11390 ScriptSleep(100);
11391 return tid.ToString(); 11391 return tid.ToString();
11392 } 11392 }
11393   11393  
11394 WithNotecard(assetID, delegate (UUID id, AssetBase a) 11394 WithNotecard(assetID, delegate (UUID id, AssetBase a)
11395 { 11395 {
11396 if (a == null || a.Type != 7) 11396 if (a == null || a.Type != 7)
11397 { 11397 {
11398 Error("llGetNotecardLine", "Can't find notecard '" + name + "'"); 11398 Error("llGetNotecardLine", "Can't find notecard '" + name + "'");
11399 return; 11399 return;
11400 } 11400 }
11401   11401  
11402 string data = Encoding.UTF8.GetString(a.Data); 11402 string data = Encoding.UTF8.GetString(a.Data);
11403 //m_log.Debug(data); 11403 //m_log.Debug(data);
11404 NotecardCache.Cache(id, data); 11404 NotecardCache.Cache(id, data);
11405 AsyncCommands.DataserverPlugin.DataserverReply( 11405 AsyncCommands.DataserverPlugin.DataserverReply(
11406 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11406 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11407 }); 11407 });
11408   11408  
11409 ScriptSleep(100); 11409 ScriptSleep(100);
11410 return tid.ToString(); 11410 return tid.ToString();
11411 } 11411 }
11412   11412  
11413 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc) 11413 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
11414 { 11414 {
11415 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11415 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11416 if (obj == null) 11416 if (obj == null)
11417 return; 11417 return;
11418   11418  
11419 if (obj.OwnerID != m_host.OwnerID) 11419 if (obj.OwnerID != m_host.OwnerID)
11420 return; 11420 return;
11421   11421  
11422 uint rulesParsed = 0; 11422 uint rulesParsed = 0;
11423 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed); 11423 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
11424   11424  
11425 while ((object)remaining != null && remaining.Length > 2) 11425 while ((object)remaining != null && remaining.Length > 2)
11426 { 11426 {
11427 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11427 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
11428 LSL_List newrules = remaining.GetSublist(1, -1); 11428 LSL_List newrules = remaining.GetSublist(1, -1);
11429 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11429 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
11430 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed); 11430 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
11431 } 11431 }
11432 } 11432 }
11433 } 11433 }
11434   11434  
11435 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11435 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
11436 { 11436 {
11437 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11437 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11438   11438  
11439 LSL_List result = new LSL_List(); 11439 LSL_List result = new LSL_List();
11440   11440  
11441 if (obj != null && obj.OwnerID == m_host.OwnerID) 11441 if (obj != null && obj.OwnerID == m_host.OwnerID)
11442 { 11442 {
11443 LSL_List remaining = GetPrimParams(obj, rules, ref result); 11443 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11444   11444  
11445 while (remaining != null && remaining.Length > 2) 11445 while (remaining != null && remaining.Length > 2)
11446 { 11446 {
11447 int linknumber = remaining.GetLSLIntegerItem(0); 11447 int linknumber = remaining.GetLSLIntegerItem(0);
11448 rules = remaining.GetSublist(1, -1); 11448 rules = remaining.GetSublist(1, -1);
11449 List<SceneObjectPart> parts = GetLinkParts(linknumber); 11449 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11450   11450  
11451 foreach (SceneObjectPart part in parts) 11451 foreach (SceneObjectPart part in parts)
11452 remaining = GetPrimParams(part, rules, ref result); 11452 remaining = GetPrimParams(part, rules, ref result);
11453 } 11453 }
11454 } 11454 }
11455   11455  
11456 return result; 11456 return result;
11457 } 11457 }
11458   11458  
11459 public void print(string str) 11459 public void print(string str)
11460 { 11460 {
11461 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11461 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print
11462 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11462 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
11463 if (ossl != null) 11463 if (ossl != null)
11464 { 11464 {
11465 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11465 ossl.CheckThreatLevel(ThreatLevel.High, "print");
11466 m_log.Info("LSL print():" + str); 11466 m_log.Info("LSL print():" + str);
11467 } 11467 }
11468 } 11468 }
11469   11469  
11470 private string Name2Username(string name) 11470 private string Name2Username(string name)
11471 { 11471 {
11472 string[] parts = name.Split(new char[] {' '}); 11472 string[] parts = name.Split(new char[] {' '});
11473 if (parts.Length < 2) 11473 if (parts.Length < 2)
11474 return name.ToLower(); 11474 return name.ToLower();
11475 if (parts[1] == "Resident") 11475 if (parts[1] == "Resident")
11476 return parts[0].ToLower(); 11476 return parts[0].ToLower();
11477   11477  
11478 return name.Replace(" ", ".").ToLower(); 11478 return name.Replace(" ", ".").ToLower();
11479 } 11479 }
11480   11480  
11481 public LSL_String llGetUsername(string id) 11481 public LSL_String llGetUsername(string id)
11482 { 11482 {
11483 return Name2Username(llKey2Name(id)); 11483 return Name2Username(llKey2Name(id));
11484 } 11484 }
11485   11485  
11486 public LSL_String llRequestUsername(string id) 11486 public LSL_String llRequestUsername(string id)
11487 { 11487 {
11488 UUID rq = UUID.Random(); 11488 UUID rq = UUID.Random();
11489   11489  
11490 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 11490 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11491   11491  
11492 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); 11492 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
11493   11493  
11494 return rq.ToString(); 11494 return rq.ToString();
11495 } 11495 }
11496   11496  
11497 public LSL_String llGetDisplayName(string id) 11497 public LSL_String llGetDisplayName(string id)
11498 { 11498 {
11499 return llKey2Name(id); 11499 return llKey2Name(id);
11500 } 11500 }
11501   11501  
11502 public LSL_String llRequestDisplayName(string id) 11502 public LSL_String llRequestDisplayName(string id)
11503 { 11503 {
11504 UUID rq = UUID.Random(); 11504 UUID rq = UUID.Random();
11505   11505  
11506 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 11506 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11507   11507  
11508 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); 11508 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
11509   11509  
11510 return rq.ToString(); 11510 return rq.ToString();
11511 } 11511 }
11512   11512  
11513 private struct Tri 11513 private struct Tri
11514 { 11514 {
11515 public Vector3 p1; 11515 public Vector3 p1;
11516 public Vector3 p2; 11516 public Vector3 p2;
11517 public Vector3 p3; 11517 public Vector3 p3;
11518 } 11518 }
11519   11519  
11520 private bool InBoundingBox(ScenePresence avatar, Vector3 point) 11520 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11521 { 11521 {
11522 float height = avatar.Appearance.AvatarHeight; 11522 float height = avatar.Appearance.AvatarHeight;
11523 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2); 11523 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11524 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2); 11524 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11525   11525  
11526 if (point.X > b1.X && point.X < b2.X && 11526 if (point.X > b1.X && point.X < b2.X &&
11527 point.Y > b1.Y && point.Y < b2.Y && 11527 point.Y > b1.Y && point.Y < b2.Y &&
11528 point.Z > b1.Z && point.Z < b2.Z) 11528 point.Z > b1.Z && point.Z < b2.Z)
11529 return true; 11529 return true;
11530 return false; 11530 return false;
11531 } 11531 }
11532   11532  
11533 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) 11533 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11534 { 11534 {
11535 List<ContactResult> contacts = new List<ContactResult>(); 11535 List<ContactResult> contacts = new List<ContactResult>();
11536   11536  
11537 Vector3 ab = rayEnd - rayStart; 11537 Vector3 ab = rayEnd - rayStart;
11538   11538  
11539 World.ForEachScenePresence(delegate(ScenePresence sp) 11539 World.ForEachScenePresence(delegate(ScenePresence sp)
11540 { 11540 {
11541 Vector3 ac = sp.AbsolutePosition - rayStart; 11541 Vector3 ac = sp.AbsolutePosition - rayStart;
11542 // Vector3 bc = sp.AbsolutePosition - rayEnd; 11542 // Vector3 bc = sp.AbsolutePosition - rayEnd;
11543   11543  
11544 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11544 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11545   11545  
11546 if (d > 1.5) 11546 if (d > 1.5)
11547 return; 11547 return;
11548   11548  
11549 double d2 = Vector3.Dot(Vector3.Negate(ab), ac); 11549 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11550   11550  
11551 if (d2 > 0) 11551 if (d2 > 0)
11552 return; 11552 return;
11553   11553  
11554 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d); 11554 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11555 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab)); 11555 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11556   11556  
11557 if (!InBoundingBox(sp, p)) 11557 if (!InBoundingBox(sp, p))
11558 return; 11558 return;
11559   11559  
11560 ContactResult result = new ContactResult (); 11560 ContactResult result = new ContactResult ();
11561 result.ConsumerID = sp.LocalId; 11561 result.ConsumerID = sp.LocalId;
11562 result.Depth = Vector3.Distance(rayStart, p); 11562 result.Depth = Vector3.Distance(rayStart, p);
11563 result.Normal = Vector3.Zero; 11563 result.Normal = Vector3.Zero;
11564 result.Pos = p; 11564 result.Pos = p;
11565   11565  
11566 contacts.Add(result); 11566 contacts.Add(result);
11567 }); 11567 });
11568   11568  
11569 return contacts.ToArray(); 11569 return contacts.ToArray();
11570 } 11570 }
11571   11571  
11572 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom) 11572 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11573 { 11573 {
11574 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); 11574 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11575 List<ContactResult> contacts = new List<ContactResult>(); 11575 List<ContactResult> contacts = new List<ContactResult>();
11576   11576  
11577 Vector3 ab = rayEnd - rayStart; 11577 Vector3 ab = rayEnd - rayStart;
11578   11578  
11579 World.ForEachSOG(delegate(SceneObjectGroup group) 11579 World.ForEachSOG(delegate(SceneObjectGroup group)
11580 { 11580 {
11581 if (m_host.ParentGroup == group) 11581 if (m_host.ParentGroup == group)
11582 return; 11582 return;
11583   11583  
11584 if (group.IsAttachment) 11584 if (group.IsAttachment)
11585 return; 11585 return;
11586   11586  
11587 if (group.RootPart.PhysActor == null) 11587 if (group.RootPart.PhysActor == null)
11588 { 11588 {
11589 if (!includePhantom) 11589 if (!includePhantom)
11590 return; 11590 return;
11591 } 11591 }
11592 else 11592 else
11593 { 11593 {
11594 if (group.RootPart.PhysActor.IsPhysical) 11594 if (group.RootPart.PhysActor.IsPhysical)
11595 { 11595 {
11596 if (!includePhysical) 11596 if (!includePhysical)
11597 return; 11597 return;
11598 } 11598 }
11599 else 11599 else
11600 { 11600 {
11601 if (!includeNonPhysical) 11601 if (!includeNonPhysical)
11602 return; 11602 return;
11603 } 11603 }
11604 } 11604 }
11605   11605  
11606 // Find the radius ouside of which we don't even need to hit test 11606 // Find the radius ouside of which we don't even need to hit test
11607 float minX; 11607 float minX;
11608 float maxX; 11608 float maxX;
11609 float minY; 11609 float minY;
11610 float maxY; 11610 float maxY;
11611 float minZ; 11611 float minZ;
11612 float maxZ; 11612 float maxZ;
11613   11613  
11614 float radius = 0.0f; 11614 float radius = 0.0f;
11615   11615  
11616 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); 11616 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11617   11617  
11618 if (Math.Abs(minX) > radius) 11618 if (Math.Abs(minX) > radius)
11619 radius = Math.Abs(minX); 11619 radius = Math.Abs(minX);
11620 if (Math.Abs(minY) > radius) 11620 if (Math.Abs(minY) > radius)
11621 radius = Math.Abs(minY); 11621 radius = Math.Abs(minY);
11622 if (Math.Abs(minZ) > radius) 11622 if (Math.Abs(minZ) > radius)
11623 radius = Math.Abs(minZ); 11623 radius = Math.Abs(minZ);
11624 if (Math.Abs(maxX) > radius) 11624 if (Math.Abs(maxX) > radius)
11625 radius = Math.Abs(maxX); 11625 radius = Math.Abs(maxX);
11626 if (Math.Abs(maxY) > radius) 11626 if (Math.Abs(maxY) > radius)
11627 radius = Math.Abs(maxY); 11627 radius = Math.Abs(maxY);
11628 if (Math.Abs(maxZ) > radius) 11628 if (Math.Abs(maxZ) > radius)
11629 radius = Math.Abs(maxZ); 11629 radius = Math.Abs(maxZ);
11630 radius = radius*1.413f; 11630 radius = radius*1.413f;
11631 Vector3 ac = group.AbsolutePosition - rayStart; 11631 Vector3 ac = group.AbsolutePosition - rayStart;
11632 // Vector3 bc = group.AbsolutePosition - rayEnd; 11632 // Vector3 bc = group.AbsolutePosition - rayEnd;
11633   11633  
11634 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11634 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11635   11635  
11636 // Too far off ray, don't bother 11636 // Too far off ray, don't bother
11637 if (d > radius) 11637 if (d > radius)
11638 return; 11638 return;
11639   11639  
11640 // Behind ray, drop 11640 // Behind ray, drop
11641 double d2 = Vector3.Dot(Vector3.Negate(ab), ac); 11641 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11642 if (d2 > 0) 11642 if (d2 > 0)
11643 return; 11643 return;
11644   11644  
11645 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); 11645 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11646 EntityIntersection intersection = group.TestIntersection(ray, true, false); 11646 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11647 // Miss. 11647 // Miss.
11648 if (!intersection.HitTF) 11648 if (!intersection.HitTF)
11649 return; 11649 return;
11650   11650  
11651 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); 11651 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
11652 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); 11652 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
11653 //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z); 11653 //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
11654 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && 11654 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
11655 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && 11655 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
11656 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) 11656 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
11657 return; 11657 return;
11658   11658  
11659 ContactResult result = new ContactResult (); 11659 ContactResult result = new ContactResult ();
11660 result.ConsumerID = group.LocalId; 11660 result.ConsumerID = group.LocalId;
11661 result.Depth = intersection.distance; 11661 result.Depth = intersection.distance;
11662 result.Normal = intersection.normal; 11662 result.Normal = intersection.normal;
11663 result.Pos = intersection.ipoint; 11663 result.Pos = intersection.ipoint;
11664   11664  
11665 contacts.Add(result); 11665 contacts.Add(result);
11666 }); 11666 });
11667   11667  
11668 return contacts.ToArray(); 11668 return contacts.ToArray();
11669 } 11669 }
11670   11670  
11671 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd) 11671 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11672 { 11672 {
11673 double[,] heightfield = World.Heightmap.GetDoubles(); 11673 double[,] heightfield = World.Heightmap.GetDoubles();
11674 List<ContactResult> contacts = new List<ContactResult>(); 11674 List<ContactResult> contacts = new List<ContactResult>();
11675   11675  
11676 double min = 2048.0; 11676 double min = 2048.0;
11677 double max = 0.0; 11677 double max = 0.0;
11678   11678  
11679 // Find the min and max of the heightfield 11679 // Find the min and max of the heightfield
11680 for (int x = 0 ; x < World.Heightmap.Width ; x++) 11680 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11681 { 11681 {
11682 for (int y = 0 ; y < World.Heightmap.Height ; y++) 11682 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11683 { 11683 {
11684 if (heightfield[x, y] > max) 11684 if (heightfield[x, y] > max)
11685 max = heightfield[x, y]; 11685 max = heightfield[x, y];
11686 if (heightfield[x, y] < min) 11686 if (heightfield[x, y] < min)
11687 min = heightfield[x, y]; 11687 min = heightfield[x, y];
11688 } 11688 }
11689 } 11689 }
11690   11690  
11691   11691  
11692 // A ray extends past rayEnd, but doesn't go back before 11692 // A ray extends past rayEnd, but doesn't go back before
11693 // rayStart. If the start is above the highest point of the ground 11693 // rayStart. If the start is above the highest point of the ground
11694 // and the ray goes up, we can't hit the ground. Ever. 11694 // and the ray goes up, we can't hit the ground. Ever.
11695 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z) 11695 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11696 return null; 11696 return null;
11697   11697  
11698 // Same for going down 11698 // Same for going down
11699 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z) 11699 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11700 return null; 11700 return null;
11701   11701  
11702 List<Tri> trilist = new List<Tri>(); 11702 List<Tri> trilist = new List<Tri>();
11703   11703  
11704 // Create our triangle list 11704 // Create our triangle list
11705 for (int x = 1 ; x < World.Heightmap.Width ; x++) 11705 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11706 { 11706 {
11707 for (int y = 1 ; y < World.Heightmap.Height ; y++) 11707 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11708 { 11708 {
11709 Tri t1 = new Tri(); 11709 Tri t1 = new Tri();
11710 Tri t2 = new Tri(); 11710 Tri t2 = new Tri();
11711   11711  
11712 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]); 11712 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11713 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]); 11713 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11714 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]); 11714 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11715 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]); 11715 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11716   11716  
11717 t1.p1 = p1; 11717 t1.p1 = p1;
11718 t1.p2 = p2; 11718 t1.p2 = p2;
11719 t1.p3 = p3; 11719 t1.p3 = p3;
11720   11720  
11721 t2.p1 = p3; 11721 t2.p1 = p3;
11722 t2.p2 = p4; 11722 t2.p2 = p4;
11723 t2.p3 = p1; 11723 t2.p3 = p1;
11724   11724  
11725 trilist.Add(t1); 11725 trilist.Add(t1);
11726 trilist.Add(t2); 11726 trilist.Add(t2);
11727 } 11727 }
11728 } 11728 }
11729   11729  
11730 // Ray direction 11730 // Ray direction
11731 Vector3 rayDirection = rayEnd - rayStart; 11731 Vector3 rayDirection = rayEnd - rayStart;
11732   11732  
11733 foreach (Tri t in trilist) 11733 foreach (Tri t in trilist)
11734 { 11734 {
11735 // Compute triangle plane normal and edges 11735 // Compute triangle plane normal and edges
11736 Vector3 u = t.p2 - t.p1; 11736 Vector3 u = t.p2 - t.p1;
11737 Vector3 v = t.p3 - t.p1; 11737 Vector3 v = t.p3 - t.p1;
11738 Vector3 n = Vector3.Cross(u, v); 11738 Vector3 n = Vector3.Cross(u, v);
11739   11739  
11740 if (n == Vector3.Zero) 11740 if (n == Vector3.Zero)
11741 continue; 11741 continue;
11742   11742  
11743 Vector3 w0 = rayStart - t.p1; 11743 Vector3 w0 = rayStart - t.p1;
11744 double a = -Vector3.Dot(n, w0); 11744 double a = -Vector3.Dot(n, w0);
11745 double b = Vector3.Dot(n, rayDirection); 11745 double b = Vector3.Dot(n, rayDirection);
11746   11746  
11747 // Not intersecting the plane, or in plane (same thing) 11747 // Not intersecting the plane, or in plane (same thing)
11748 // Ignoring this MAY cause the ground to not be detected 11748 // Ignoring this MAY cause the ground to not be detected
11749 // sometimes 11749 // sometimes
11750 if (Math.Abs(b) < 0.000001) 11750 if (Math.Abs(b) < 0.000001)
11751 continue; 11751 continue;
11752   11752  
11753 double r = a / b; 11753 double r = a / b;
11754   11754  
11755 // ray points away from plane 11755 // ray points away from plane
11756 if (r < 0.0) 11756 if (r < 0.0)
11757 continue; 11757 continue;
11758   11758  
11759 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r); 11759 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11760   11760  
11761 float uu = Vector3.Dot(u, u); 11761 float uu = Vector3.Dot(u, u);
11762 float uv = Vector3.Dot(u, v); 11762 float uv = Vector3.Dot(u, v);
11763 float vv = Vector3.Dot(v, v); 11763 float vv = Vector3.Dot(v, v);
11764 Vector3 w = ip - t.p1; 11764 Vector3 w = ip - t.p1;
11765 float wu = Vector3.Dot(w, u); 11765 float wu = Vector3.Dot(w, u);
11766 float wv = Vector3.Dot(w, v); 11766 float wv = Vector3.Dot(w, v);
11767 float d = uv * uv - uu * vv; 11767 float d = uv * uv - uu * vv;
11768   11768  
11769 float cs = (uv * wv - vv * wu) / d; 11769 float cs = (uv * wv - vv * wu) / d;
11770 if (cs < 0 || cs > 1.0) 11770 if (cs < 0 || cs > 1.0)
11771 continue; 11771 continue;
11772 float ct = (uv * wu - uu * wv) / d; 11772 float ct = (uv * wu - uu * wv) / d;
11773 if (ct < 0 || (cs + ct) > 1.0) 11773 if (ct < 0 || (cs + ct) > 1.0)
11774 continue; 11774 continue;
11775   11775  
11776 // Add contact point 11776 // Add contact point
11777 ContactResult result = new ContactResult (); 11777 ContactResult result = new ContactResult ();
11778 result.ConsumerID = 0; 11778 result.ConsumerID = 0;
11779 result.Depth = Vector3.Distance(rayStart, ip); 11779 result.Depth = Vector3.Distance(rayStart, ip);
11780 result.Normal = n; 11780 result.Normal = n;
11781 result.Pos = ip; 11781 result.Pos = ip;
11782   11782  
11783 contacts.Add(result); 11783 contacts.Add(result);
11784 } 11784 }
11785   11785  
11786 if (contacts.Count == 0) 11786 if (contacts.Count == 0)
11787 return null; 11787 return null;
11788   11788  
11789 contacts.Sort(delegate(ContactResult a, ContactResult b) 11789 contacts.Sort(delegate(ContactResult a, ContactResult b)
11790 { 11790 {
11791 return (int)(a.Depth - b.Depth); 11791 return (int)(a.Depth - b.Depth);
11792 }); 11792 });
11793   11793  
11794 return contacts[0]; 11794 return contacts[0];
11795 } 11795 }
11796   11796  
11797 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11797 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11798 { 11798 {
11799 LSL_List list = new LSL_List(); 11799 LSL_List list = new LSL_List();
11800   11800  
11801 m_host.AddScriptLPS(1); 11801 m_host.AddScriptLPS(1);
11802   11802  
11803 Vector3 rayStart = start; 11803 Vector3 rayStart = start;
11804 Vector3 rayEnd = end; 11804 Vector3 rayEnd = end;
11805 Vector3 dir = rayEnd - rayStart; 11805 Vector3 dir = rayEnd - rayStart;
11806   11806  
11807 float dist = Vector3.Mag(dir); 11807 float dist = Vector3.Mag(dir);
11808   11808  
11809 int count = 1; 11809 int count = 1;
11810 bool detectPhantom = false; 11810 bool detectPhantom = false;
11811 int dataFlags = 0; 11811 int dataFlags = 0;
11812 int rejectTypes = 0; 11812 int rejectTypes = 0;
11813   11813  
11814 for (int i = 0; i < options.Length; i += 2) 11814 for (int i = 0; i < options.Length; i += 2)
11815 { 11815 {
11816 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11816 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
11817 count = options.GetLSLIntegerItem(i + 1); 11817 count = options.GetLSLIntegerItem(i + 1);
11818 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11818 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
11819 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0); 11819 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
11820 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11820 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
11821 dataFlags = options.GetLSLIntegerItem(i + 1); 11821 dataFlags = options.GetLSLIntegerItem(i + 1);
11822 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11822 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
11823 rejectTypes = options.GetLSLIntegerItem(i + 1); 11823 rejectTypes = options.GetLSLIntegerItem(i + 1);
11824 } 11824 }
11825   11825  
11826 if (count > 16) 11826 if (count > 16)
11827 count = 16; 11827 count = 16;
11828   11828  
11829 List<ContactResult> results = new List<ContactResult>(); 11829 List<ContactResult> results = new List<ContactResult>();
11830   11830  
11831 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11831 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
11832 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11832 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
11833 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11833 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
11834 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11834 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11835   11835  
11836   11836  
11837 if (World.SupportsRayCastFiltered()) 11837 if (World.SupportsRayCastFiltered())
11838 { 11838 {
11839 if (dist == 0) 11839 if (dist == 0)
11840 return list; 11840 return list;
11841   11841  
11842 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; 11842 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11843 if (checkTerrain) 11843 if (checkTerrain)
11844 rayfilter |= RayFilterFlags.land; 11844 rayfilter |= RayFilterFlags.land;
11845 // if (checkAgents) 11845 // if (checkAgents)
11846 // rayfilter |= RayFilterFlags.agent; 11846 // rayfilter |= RayFilterFlags.agent;
11847 if (checkPhysical) 11847 if (checkPhysical)
11848 rayfilter |= RayFilterFlags.physical; 11848 rayfilter |= RayFilterFlags.physical;
11849 if (checkNonPhysical) 11849 if (checkNonPhysical)
11850 rayfilter |= RayFilterFlags.nonphysical; 11850 rayfilter |= RayFilterFlags.nonphysical;
11851 if (detectPhantom) 11851 if (detectPhantom)
11852 rayfilter |= RayFilterFlags.LSLPhantom; 11852 rayfilter |= RayFilterFlags.LSLPhantom;
11853   11853  
11854 Vector3 direction = dir * ( 1/dist); 11854 Vector3 direction = dir * ( 1/dist);
11855   11855  
11856 if(rayfilter == 0) 11856 if(rayfilter == 0)
11857 { 11857 {
11858 list.Add(new LSL_Integer(0)); 11858 list.Add(new LSL_Integer(0));
11859 return list; 11859 return list;
11860 } 11860 }
11861   11861  
11862 // get some more contacts to sort ??? 11862 // get some more contacts to sort ???
11863 int physcount = 4 * count; 11863 int physcount = 4 * count;
11864 if (physcount > 20) 11864 if (physcount > 20)
11865 physcount = 20; 11865 physcount = 20;
11866   11866  
11867 object physresults; 11867 object physresults;
11868 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter); 11868 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11869   11869  
11870 if (physresults == null) 11870 if (physresults == null)
11871 { 11871 {
11872 list.Add(new LSL_Integer(-3)); // timeout error 11872 list.Add(new LSL_Integer(-3)); // timeout error
11873 return list; 11873 return list;
11874 } 11874 }
11875   11875  
11876 results = (List<ContactResult>)physresults; 11876 results = (List<ContactResult>)physresults;
11877   11877  
11878 // for now physics doesn't detect sitted avatars so do it outside physics 11878 // for now physics doesn't detect sitted avatars so do it outside physics
11879 if (checkAgents) 11879 if (checkAgents)
11880 { 11880 {
11881 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 11881 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11882 foreach (ContactResult r in agentHits) 11882 foreach (ContactResult r in agentHits)
11883 results.Add(r); 11883 results.Add(r);
11884 } 11884 }
11885   11885  
11886 // TODO: Replace this with a better solution. ObjectIntersection can only 11886 // TODO: Replace this with a better solution. ObjectIntersection can only
11887 // detect nonphysical phantoms. They are detected by virtue of being 11887 // detect nonphysical phantoms. They are detected by virtue of being
11888 // nonphysical (e.g. no PhysActor) so will not conflict with detecting 11888 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
11889 // physicsl phantoms as done by the physics scene 11889 // physicsl phantoms as done by the physics scene
11890 // We don't want anything else but phantoms here. 11890 // We don't want anything else but phantoms here.
11891 if (detectPhantom) 11891 if (detectPhantom)
11892 { 11892 {
11893 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true); 11893 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
11894 foreach (ContactResult r in objectHits) 11894 foreach (ContactResult r in objectHits)
11895 results.Add(r); 11895 results.Add(r);
11896 } 11896 }
11897 } 11897 }
11898 else 11898 else
11899 { 11899 {
11900 if (checkAgents) 11900 if (checkAgents)
11901 { 11901 {
11902 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 11902 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11903 foreach (ContactResult r in agentHits) 11903 foreach (ContactResult r in agentHits)
11904 results.Add(r); 11904 results.Add(r);
11905 } 11905 }
11906   11906  
11907 if (checkPhysical || checkNonPhysical || detectPhantom) 11907 if (checkPhysical || checkNonPhysical || detectPhantom)
11908 { 11908 {
11909 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 11909 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11910 for (int iter = 0; iter < objectHits.Length; iter++) 11910 for (int iter = 0; iter < objectHits.Length; iter++)
11911 { 11911 {
11912 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. 11912 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
11913 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); 11913 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
11914 results.Add(objectHits[iter]); 11914 results.Add(objectHits[iter]);
11915 } 11915 }
11916 } 11916 }
11917 } 11917 }
11918   11918  
11919 if (checkTerrain) 11919 if (checkTerrain)
11920 { 11920 {
11921 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 11921 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11922 if (groundContact != null) 11922 if (groundContact != null)
11923 results.Add((ContactResult)groundContact); 11923 results.Add((ContactResult)groundContact);
11924 } 11924 }
11925   11925  
11926 results.Sort(delegate(ContactResult a, ContactResult b) 11926 results.Sort(delegate(ContactResult a, ContactResult b)
11927 { 11927 {
11928 return a.Depth.CompareTo(b.Depth); 11928 return a.Depth.CompareTo(b.Depth);
11929 }); 11929 });
11930   11930  
11931 int values = 0; 11931 int values = 0;
11932 SceneObjectGroup thisgrp = m_host.ParentGroup; 11932 SceneObjectGroup thisgrp = m_host.ParentGroup;
11933   11933  
11934 foreach (ContactResult result in results) 11934 foreach (ContactResult result in results)
11935 { 11935 {
11936 if (result.Depth > dist) 11936 if (result.Depth > dist)
11937 continue; 11937 continue;
11938   11938  
11939 // physics ray can return colisions with host prim 11939 // physics ray can return colisions with host prim
11940 if (m_host.LocalId == result.ConsumerID) 11940 if (m_host.LocalId == result.ConsumerID)
11941 continue; 11941 continue;
11942   11942  
11943 UUID itemID = UUID.Zero; 11943 UUID itemID = UUID.Zero;
11944 int linkNum = 0; 11944 int linkNum = 0;
11945   11945  
11946 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID); 11946 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11947 // It's a prim! 11947 // It's a prim!
11948 if (part != null) 11948 if (part != null)
11949 { 11949 {
11950 // dont detect members of same object ??? 11950 // dont detect members of same object ???
11951 if (part.ParentGroup == thisgrp) 11951 if (part.ParentGroup == thisgrp)
11952 continue; 11952 continue;
11953   11953  
11954 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY) 11954 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
11955 itemID = part.ParentGroup.UUID; 11955 itemID = part.ParentGroup.UUID;
11956 else 11956 else
11957 itemID = part.UUID; 11957 itemID = part.UUID;
11958   11958  
11959 linkNum = part.LinkNum; 11959 linkNum = part.LinkNum;
11960 } 11960 }
11961 else 11961 else
11962 { 11962 {
11963 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 11963 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
11964 /// It it a boy? a girl? 11964 /// It it a boy? a girl?
11965 if (sp != null) 11965 if (sp != null)
11966 itemID = sp.UUID; 11966 itemID = sp.UUID;
11967 } 11967 }
11968   11968  
11969 list.Add(new LSL_String(itemID.ToString())); 11969 list.Add(new LSL_String(itemID.ToString()));
11970 list.Add(new LSL_String(result.Pos.ToString())); 11970 list.Add(new LSL_String(result.Pos.ToString()));
11971   11971  
11972 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11972 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11973 list.Add(new LSL_Integer(linkNum)); 11973 list.Add(new LSL_Integer(linkNum));
11974   11974  
11975 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11975 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11976 list.Add(new LSL_Vector(result.Normal)); 11976 list.Add(new LSL_Vector(result.Normal));
11977   11977  
11978 values++; 11978 values++;
11979 if (values >= count) 11979 if (values >= count)
11980 break; 11980 break;
11981 } 11981 }
11982   11982  
11983 list.Add(new LSL_Integer(values)); 11983 list.Add(new LSL_Integer(values));
11984   11984  
11985 return list; 11985 return list;
11986 } 11986 }
11987   11987  
11988 public LSL_Integer llManageEstateAccess(int action, string avatar) 11988 public LSL_Integer llManageEstateAccess(int action, string avatar)
11989 { 11989 {
11990 m_host.AddScriptLPS(1); 11990 m_host.AddScriptLPS(1);
11991 EstateSettings estate = World.RegionInfo.EstateSettings; 11991 EstateSettings estate = World.RegionInfo.EstateSettings;
11992 bool isAccount = false; 11992 bool isAccount = false;
11993 bool isGroup = false; 11993 bool isGroup = false;
11994   11994  
11995 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID)) 11995 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID))
11996 return 0; 11996 return 0;
11997   11997  
11998 UUID id = new UUID(); 11998 UUID id = new UUID();
11999 if (!UUID.TryParse(avatar, out id)) 11999 if (!UUID.TryParse(avatar, out id))
12000 return 0; 12000 return 0;
12001   12001  
12002 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id); 12002 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id);
12003 isAccount = account != null ? true : false; 12003 isAccount = account != null ? true : false;
12004 if (!isAccount) 12004 if (!isAccount)
12005 { 12005 {
12006 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>(); 12006 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
12007 if (groups != null) 12007 if (groups != null)
12008 { 12008 {
12009 GroupRecord group = groups.GetGroupRecord(id); 12009 GroupRecord group = groups.GetGroupRecord(id);
12010 isGroup = group != null ? true : false; 12010 isGroup = group != null ? true : false;
12011 if (!isGroup) 12011 if (!isGroup)
12012 return 0; 12012 return 0;
12013 } 12013 }
12014 else 12014 else
12015 return 0; 12015 return 0;
12016 } 12016 }
12017   12017  
12018 switch (action) 12018 switch (action)
12019 { 12019 {
12020 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12020 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
12021 if (!isAccount) return 0; 12021 if (!isAccount) return 0;
12022 if (estate.HasAccess(id)) return 1; 12022 if (estate.HasAccess(id)) return 1;
12023 if (estate.IsBanned(id)) 12023 if (estate.IsBanned(id))
12024 estate.RemoveBan(id); 12024 estate.RemoveBan(id);
12025 estate.AddEstateUser(id); 12025 estate.AddEstateUser(id);
12026 break; 12026 break;
12027 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE: 12027 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE:
12028 if (!isAccount || !estate.HasAccess(id)) return 0; 12028 if (!isAccount || !estate.HasAccess(id)) return 0;
12029 estate.RemoveEstateUser(id); 12029 estate.RemoveEstateUser(id);
12030 break; 12030 break;
12031 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD: 12031 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD:
12032 if (!isGroup) return 0; 12032 if (!isGroup) return 0;
12033 if (estate.GroupAccess(id)) return 1; 12033 if (estate.GroupAccess(id)) return 1;
12034 estate.AddEstateGroup(id); 12034 estate.AddEstateGroup(id);
12035 break; 12035 break;
12036 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE: 12036 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE:
12037 if (!isGroup || !estate.GroupAccess(id)) return 0; 12037 if (!isGroup || !estate.GroupAccess(id)) return 0;
12038 estate.RemoveEstateGroup(id); 12038 estate.RemoveEstateGroup(id);
12039 break; 12039 break;
12040 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12040 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
12041 if (!isAccount) return 0; 12041 if (!isAccount) return 0;
12042 if (estate.IsBanned(id)) return 1; 12042 if (estate.IsBanned(id)) return 1;
12043 EstateBan ban = new EstateBan(); 12043 EstateBan ban = new EstateBan();
12044 ban.EstateID = estate.EstateID; 12044 ban.EstateID = estate.EstateID;
12045 ban.BannedUserID = id; 12045 ban.BannedUserID = id;
12046 estate.AddBan(ban); 12046 estate.AddBan(ban);
12047 break; 12047 break;
12048 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12048 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
12049 if (!isAccount || !estate.IsBanned(id)) return 0; 12049 if (!isAccount || !estate.IsBanned(id)) return 0;
12050 estate.RemoveBan(id); 12050 estate.RemoveBan(id);
12051 break; 12051 break;
12052 default: return 0; 12052 default: return 0;
12053 } 12053 }
12054 return 1; 12054 return 1;
12055 } 12055 }
12056   12056  
12057 public LSL_Integer llGetMemoryLimit() 12057 public LSL_Integer llGetMemoryLimit()
12058 { 12058 {
12059 m_host.AddScriptLPS(1); 12059 m_host.AddScriptLPS(1);
12060 // The value returned for LSO scripts in SL 12060 // The value returned for LSO scripts in SL
12061 return 16384; 12061 return 16384;
12062 } 12062 }
12063   12063  
12064 public LSL_Integer llSetMemoryLimit(LSL_Integer limit) 12064 public LSL_Integer llSetMemoryLimit(LSL_Integer limit)
12065 { 12065 {
12066 m_host.AddScriptLPS(1); 12066 m_host.AddScriptLPS(1);
12067 // Treat as an LSO script 12067 // Treat as an LSO script
12068 return ScriptBaseClass.FALSE; 12068 return ScriptBaseClass.FALSE;
12069 } 12069 }
12070   12070  
12071 public LSL_Integer llGetSPMaxMemory() 12071 public LSL_Integer llGetSPMaxMemory()
12072 { 12072 {
12073 m_host.AddScriptLPS(1); 12073 m_host.AddScriptLPS(1);
12074 // The value returned for LSO scripts in SL 12074 // The value returned for LSO scripts in SL
12075 return 16384; 12075 return 16384;
12076 } 12076 }
12077   12077  
12078 public virtual LSL_Integer llGetUsedMemory() 12078 public virtual LSL_Integer llGetUsedMemory()
12079 { 12079 {
12080 m_host.AddScriptLPS(1); 12080 m_host.AddScriptLPS(1);
12081 // The value returned for LSO scripts in SL 12081 // The value returned for LSO scripts in SL
12082 return 16384; 12082 return 16384;
12083 } 12083 }
12084   12084  
12085 public void llScriptProfiler(LSL_Integer flags) 12085 public void llScriptProfiler(LSL_Integer flags)
12086 { 12086 {
12087 m_host.AddScriptLPS(1); 12087 m_host.AddScriptLPS(1);
12088 // This does nothing for LSO scripts in SL 12088 // This does nothing for LSO scripts in SL
12089 } 12089 }
12090   12090  
12091 #region Not Implemented 12091 #region Not Implemented
12092 // 12092 //
12093 // Listing the unimplemented lsl functions here, please move 12093 // Listing the unimplemented lsl functions here, please move
12094 // them from this region as they are completed 12094 // them from this region as they are completed
12095 // 12095 //
12096   12096  
12097 public void llGetEnv(LSL_String name) 12097 public void llGetEnv(LSL_String name)
12098 { 12098 {
12099 m_host.AddScriptLPS(1); 12099 m_host.AddScriptLPS(1);
12100 NotImplemented("llGetEnv"); 12100 NotImplemented("llGetEnv");
12101 } 12101 }
12102   12102  
12103 public void llSetSoundQueueing(int queue) 12103 public void llSetSoundQueueing(int queue)
12104 { 12104 {
12105 m_host.AddScriptLPS(1); 12105 m_host.AddScriptLPS(1);
12106   12106  
12107 if (m_SoundModule != null) 12107 if (m_SoundModule != null)
12108 m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); 12108 m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value);
12109 } 12109 }
12110   12110  
12111 public void llCollisionSprite(string impact_sprite) 12111 public void llCollisionSprite(string impact_sprite)
12112 { 12112 {
12113 m_host.AddScriptLPS(1); 12113 m_host.AddScriptLPS(1);
12114 NotImplemented("llCollisionSprite"); 12114 NotImplemented("llCollisionSprite");
12115 } 12115 }
12116   12116  
12117 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12117 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12118 { 12118 {
12119 m_host.AddScriptLPS(1); 12119 m_host.AddScriptLPS(1);
12120 NotImplemented("llGodLikeRezObject"); 12120 NotImplemented("llGodLikeRezObject");
12121 } 12121 }
12122   12122  
12123 public LSL_String llTransferLindenDollars(string destination, int amount) 12123 public LSL_String llTransferLindenDollars(string destination, int amount)
12124 { 12124 {
12125 UUID txn = UUID.Random(); 12125 UUID txn = UUID.Random();
12126   12126  
12127 Util.FireAndForget(delegate(object x) 12127 Util.FireAndForget(delegate(object x)
12128 { 12128 {
12129 int replycode = 0; 12129 int replycode = 0;
12130 string replydata = destination + "," + amount.ToString(); 12130 string replydata = destination + "," + amount.ToString();
12131   12131  
12132 try 12132 try
12133 { 12133 {
12134 TaskInventoryItem item = m_item; 12134 TaskInventoryItem item = m_item;
12135 if (item == null) 12135 if (item == null)
12136 { 12136 {
12137 replydata = "SERVICE_ERROR"; 12137 replydata = "SERVICE_ERROR";
12138 return; 12138 return;
12139 } 12139 }
12140   12140  
12141 m_host.AddScriptLPS(1); 12141 m_host.AddScriptLPS(1);
12142   12142  
12143 if (item.PermsGranter == UUID.Zero) 12143 if (item.PermsGranter == UUID.Zero)
12144 { 12144 {
12145 replydata = "MISSING_PERMISSION_DEBIT"; 12145 replydata = "MISSING_PERMISSION_DEBIT";
12146 return; 12146 return;
12147 } 12147 }
12148   12148  
12149 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) 12149 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12150 { 12150 {
12151 replydata = "MISSING_PERMISSION_DEBIT"; 12151 replydata = "MISSING_PERMISSION_DEBIT";
12152 return; 12152 return;
12153 } 12153 }
12154   12154  
12155 UUID toID = new UUID(); 12155 UUID toID = new UUID();
12156   12156  
12157 if (!UUID.TryParse(destination, out toID)) 12157 if (!UUID.TryParse(destination, out toID))
12158 { 12158 {
12159 replydata = "INVALID_AGENT"; 12159 replydata = "INVALID_AGENT";
12160 return; 12160 return;
12161 } 12161 }
12162   12162  
12163 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); 12163 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12164   12164  
12165 if (money == null) 12165 if (money == null)
12166 { 12166 {
12167 replydata = "TRANSFERS_DISABLED"; 12167 replydata = "TRANSFERS_DISABLED";
12168 return; 12168 return;
12169 } 12169 }
12170   12170  
12171 bool result = money.ObjectGiveMoney( 12171 bool result = money.ObjectGiveMoney(
12172 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12172 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12173   12173  
12174 if (result) 12174 if (result)
12175 { 12175 {
12176 replycode = 1; 12176 replycode = 1;
12177 return; 12177 return;
12178 } 12178 }
12179   12179  
12180 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12180 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12181 } 12181 }
12182 finally 12182 finally
12183 { 12183 {
12184 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 12184 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12185 "transaction_result", new Object[] { 12185 "transaction_result", new Object[] {
12186 new LSL_String(txn.ToString()), 12186 new LSL_String(txn.ToString()),
12187 new LSL_Integer(replycode), 12187 new LSL_Integer(replycode),
12188 new LSL_String(replydata) }, 12188 new LSL_String(replydata) },
12189 new DetectParams[0])); 12189 new DetectParams[0]));
12190 } 12190 }
12191 }); 12191 });
12192   12192  
12193 return txn.ToString(); 12193 return txn.ToString();
12194 } 12194 }
12195   12195  
12196 #endregion 12196 #endregion
12197 } 12197 }
12198   12198  
12199 public class NotecardCache 12199 public class NotecardCache
12200 { 12200 {
12201 protected class Notecard 12201 protected class Notecard
12202 { 12202 {
12203 public string[] text; 12203 public string[] text;
12204 public DateTime lastRef; 12204 public DateTime lastRef;
12205 } 12205 }
12206   12206  
12207 protected static Dictionary<UUID, Notecard> m_Notecards = 12207 protected static Dictionary<UUID, Notecard> m_Notecards =
12208 new Dictionary<UUID, Notecard>(); 12208 new Dictionary<UUID, Notecard>();
12209   12209  
12210 public static void Cache(UUID assetID, string text) 12210 public static void Cache(UUID assetID, string text)
12211 { 12211 {
12212 CheckCache(); 12212 CheckCache();
12213   12213  
12214 lock (m_Notecards) 12214 lock (m_Notecards)
12215 { 12215 {
12216 if (m_Notecards.ContainsKey(assetID)) 12216 if (m_Notecards.ContainsKey(assetID))
12217 return; 12217 return;
12218   12218  
12219 Notecard nc = new Notecard(); 12219 Notecard nc = new Notecard();
12220 nc.lastRef = DateTime.Now; 12220 nc.lastRef = DateTime.Now;
12221 nc.text = SLUtil.ParseNotecardToList(text).ToArray(); 12221 nc.text = SLUtil.ParseNotecardToList(text).ToArray();
12222 m_Notecards[assetID] = nc; 12222 m_Notecards[assetID] = nc;
12223 } 12223 }
12224 } 12224 }
12225   12225  
12226 public static bool IsCached(UUID assetID) 12226 public static bool IsCached(UUID assetID)
12227 { 12227 {
12228 lock (m_Notecards) 12228 lock (m_Notecards)
12229 { 12229 {
12230 return m_Notecards.ContainsKey(assetID); 12230 return m_Notecards.ContainsKey(assetID);
12231 } 12231 }
12232 } 12232 }
12233   12233  
12234 public static int GetLines(UUID assetID) 12234 public static int GetLines(UUID assetID)
12235 { 12235 {
12236 if (!IsCached(assetID)) 12236 if (!IsCached(assetID))
12237 return -1; 12237 return -1;
12238   12238  
12239 lock (m_Notecards) 12239 lock (m_Notecards)
12240 { 12240 {
12241 m_Notecards[assetID].lastRef = DateTime.Now; 12241 m_Notecards[assetID].lastRef = DateTime.Now;
12242 return m_Notecards[assetID].text.Length; 12242 return m_Notecards[assetID].text.Length;
12243 } 12243 }
12244 } 12244 }
12245   12245  
12246 /// <summary> 12246 /// <summary>
12247 /// Get a notecard line. 12247 /// Get a notecard line.
12248 /// </summary> 12248 /// </summary>
12249 /// <param name="assetID"></param> 12249 /// <param name="assetID"></param>
12250 /// <param name="lineNumber">Lines start at index 0</param> 12250 /// <param name="lineNumber">Lines start at index 0</param>
12251 /// <returns></returns> 12251 /// <returns></returns>
12252 public static string GetLine(UUID assetID, int lineNumber) 12252 public static string GetLine(UUID assetID, int lineNumber)
12253 { 12253 {
12254 if (lineNumber < 0) 12254 if (lineNumber < 0)
12255 return ""; 12255 return "";
12256   12256  
12257 string data; 12257 string data;
12258   12258  
12259 if (!IsCached(assetID)) 12259 if (!IsCached(assetID))
12260 return ""; 12260 return "";
12261   12261  
12262 lock (m_Notecards) 12262 lock (m_Notecards)
12263 { 12263 {
12264 m_Notecards[assetID].lastRef = DateTime.Now; 12264 m_Notecards[assetID].lastRef = DateTime.Now;
12265   12265  
12266 if (lineNumber >= m_Notecards[assetID].text.Length) 12266 if (lineNumber >= m_Notecards[assetID].text.Length)
12267 return "\n\n\n"; 12267 return "\n\n\n";
12268   12268  
12269 data = m_Notecards[assetID].text[lineNumber]; 12269 data = m_Notecards[assetID].text[lineNumber];
12270   12270  
12271 return data; 12271 return data;
12272 } 12272 }
12273 } 12273 }
12274   12274  
12275 /// <summary> 12275 /// <summary>
12276 /// Get a notecard line. 12276 /// Get a notecard line.
12277 /// </summary> 12277 /// </summary>
12278 /// <param name="assetID"></param> 12278 /// <param name="assetID"></param>
12279 /// <param name="lineNumber">Lines start at index 0</param> 12279 /// <param name="lineNumber">Lines start at index 0</param>
12280 /// <param name="maxLength"> 12280 /// <param name="maxLength">
12281 /// Maximum length of the returned line. 12281 /// Maximum length of the returned line.
12282 /// </param> 12282 /// </param>
12283 /// <returns> 12283 /// <returns>
12284 /// If the line length is longer than <paramref name="maxLength"/>, 12284 /// If the line length is longer than <paramref name="maxLength"/>,
12285 /// the return string will be truncated. 12285 /// the return string will be truncated.
12286 /// </returns> 12286 /// </returns>
12287 public static string GetLine(UUID assetID, int lineNumber, int maxLength) 12287 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
12288 { 12288 {
12289 string line = GetLine(assetID, lineNumber); 12289 string line = GetLine(assetID, lineNumber);
12290   12290  
12291 if (line.Length > maxLength) 12291 if (line.Length > maxLength)
12292 line = line.Substring(0, maxLength); 12292 line = line.Substring(0, maxLength);
12293   12293  
12294 return line; 12294 return line;
12295 } 12295 }
12296   12296  
12297 public static void CheckCache() 12297 public static void CheckCache()
12298 { 12298 {
12299 lock (m_Notecards) 12299 lock (m_Notecards)
12300 { 12300 {
12301 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 12301 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
12302 { 12302 {
12303 Notecard nc = m_Notecards[key]; 12303 Notecard nc = m_Notecards[key];
12304 if (nc.lastRef.AddSeconds(30) < DateTime.Now) 12304 if (nc.lastRef.AddSeconds(30) < DateTime.Now)
12305 m_Notecards.Remove(key); 12305 m_Notecards.Remove(key);
12306 } 12306 }
12307 } 12307 }
12308 } 12308 }
12309 } 12309 }
12310 } 12310 }
12311   12311