clockwerk-opensim-stable – Diff between revs 1 and 2

Subversion Repositories:
Rev:
Only display areas with differencesRegard whitespace
Rev 1 Rev 2
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 = true; 104 protected bool throwErrorOnNotImplemented = true;
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.5f; 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.5f); 168 m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.5f);
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 ShoutError("llResetOtherScript: script "+name+" not found"); 264 ShoutError("llResetOtherScript: script "+name+" not found");
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 ShoutError("llGetScriptState: script "+name+" not found"); 278 ShoutError("llGetScriptState: script "+name+" not found");
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 ShoutError("llSetScriptState: script "+name+" not found"); 301 ShoutError("llSetScriptState: script "+name+" not found");
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 LSLError("Cannot use llRegionSay() on channel 0"); 893 LSLError("Cannot use llRegionSay() 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 > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) 2110 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
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 > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2120 pos.x > (Constants.RegionSize + 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 > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. 2122 pos.y > (Constants.RegionSize + 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 // This function has been deprecated 2556 // This function has been deprecated
2557 // see http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSound 2557 // see http://www.lslwiki.net/lslwiki/wakka.php?wakka=llSound
2558 Deprecated("llSound"); 2558 Deprecated("llSound");
2559 } 2559 }
2560   2560  
2561 // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound 2561 // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound
2562 // 20080530 Updated to remove code duplication 2562 // 20080530 Updated to remove code duplication
2563 public void llPlaySound(string sound, double volume) 2563 public void llPlaySound(string sound, double volume)
2564 { 2564 {
2565 m_host.AddScriptLPS(1); 2565 m_host.AddScriptLPS(1);
2566   2566  
2567 // send the sound, once, to all clients in range 2567 // send the sound, once, to all clients in range
2568 if (m_SoundModule != null) 2568 if (m_SoundModule != null)
2569 { 2569 {
2570 m_SoundModule.SendSound( 2570 m_SoundModule.SendSound(
2571 m_host.UUID, 2571 m_host.UUID,
2572 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), 2572 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2573 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, 2573 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None,
2574 0, false, false); 2574 0, false, false);
2575 } 2575 }
2576 } 2576 }
2577   2577  
2578 public void llLoopSound(string sound, double volume) 2578 public void llLoopSound(string sound, double volume)
2579 { 2579 {
2580 m_host.AddScriptLPS(1); 2580 m_host.AddScriptLPS(1);
2581 if (m_SoundModule != null) 2581 if (m_SoundModule != null)
2582 { 2582 {
2583 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 2583 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2584 volume, 20, false); 2584 volume, 20, false);
2585 } 2585 }
2586 } 2586 }
2587   2587  
2588 public void llLoopSoundMaster(string sound, double volume) 2588 public void llLoopSoundMaster(string sound, double volume)
2589 { 2589 {
2590 m_host.AddScriptLPS(1); 2590 m_host.AddScriptLPS(1);
2591 if (m_SoundModule != null) 2591 if (m_SoundModule != null)
2592 { 2592 {
2593 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 2593 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2594 volume, 20, true); 2594 volume, 20, true);
2595 } 2595 }
2596 } 2596 }
2597   2597  
2598 public void llLoopSoundSlave(string sound, double volume) 2598 public void llLoopSoundSlave(string sound, double volume)
2599 { 2599 {
2600 m_host.AddScriptLPS(1); 2600 m_host.AddScriptLPS(1);
2601 lock (m_host.ParentGroup.LoopSoundSlavePrims) 2601 lock (m_host.ParentGroup.LoopSoundSlavePrims)
2602 { 2602 {
2603 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); 2603 m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host);
2604 } 2604 }
2605 } 2605 }
2606   2606  
2607 public void llPlaySoundSlave(string sound, double volume) 2607 public void llPlaySoundSlave(string sound, double volume)
2608 { 2608 {
2609 m_host.AddScriptLPS(1); 2609 m_host.AddScriptLPS(1);
2610   2610  
2611 // send the sound, once, to all clients in range 2611 // send the sound, once, to all clients in range
2612 if (m_SoundModule != null) 2612 if (m_SoundModule != null)
2613 { 2613 {
2614 m_SoundModule.SendSound(m_host.UUID, 2614 m_SoundModule.SendSound(m_host.UUID,
2615 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, 2615 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2616 0, true, false); 2616 0, true, false);
2617 } 2617 }
2618 } 2618 }
2619   2619  
2620 public void llTriggerSound(string sound, double volume) 2620 public void llTriggerSound(string sound, double volume)
2621 { 2621 {
2622 m_host.AddScriptLPS(1); 2622 m_host.AddScriptLPS(1);
2623 // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. 2623 // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory.
2624 if (m_SoundModule != null) 2624 if (m_SoundModule != null)
2625 { 2625 {
2626 m_SoundModule.SendSound(m_host.UUID, 2626 m_SoundModule.SendSound(m_host.UUID,
2627 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0, 2627 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0,
2628 false, false); 2628 false, false);
2629 } 2629 }
2630 } 2630 }
2631   2631  
2632 public void llStopSound() 2632 public void llStopSound()
2633 { 2633 {
2634 m_host.AddScriptLPS(1); 2634 m_host.AddScriptLPS(1);
2635   2635  
2636 if (m_SoundModule != null) 2636 if (m_SoundModule != null)
2637 m_SoundModule.StopSound(m_host.UUID); 2637 m_SoundModule.StopSound(m_host.UUID);
2638 } 2638 }
2639   2639  
2640 public void llPreloadSound(string sound) 2640 public void llPreloadSound(string sound)
2641 { 2641 {
2642 m_host.AddScriptLPS(1); 2642 m_host.AddScriptLPS(1);
2643 if (m_SoundModule != null) 2643 if (m_SoundModule != null)
2644 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); 2644 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0);
2645 ScriptSleep(1000); 2645 ScriptSleep(1000);
2646 } 2646 }
2647   2647  
2648 /// <summary> 2648 /// <summary>
2649 /// Return a portion of the designated string bounded by 2649 /// Return a portion of the designated string bounded by
2650 /// inclusive indices (start and end). As usual, the negative 2650 /// inclusive indices (start and end). As usual, the negative
2651 /// indices, and the tolerance for out-of-bound values, makes 2651 /// indices, and the tolerance for out-of-bound values, makes
2652 /// this more complicated than it might otherwise seem. 2652 /// this more complicated than it might otherwise seem.
2653 /// </summary> 2653 /// </summary>
2654 public LSL_String llGetSubString(string src, int start, int end) 2654 public LSL_String llGetSubString(string src, int start, int end)
2655 { 2655 {
2656 m_host.AddScriptLPS(1); 2656 m_host.AddScriptLPS(1);
2657   2657  
2658 // Normalize indices (if negative). 2658 // Normalize indices (if negative).
2659 // After normlaization they may still be 2659 // After normlaization they may still be
2660 // negative, but that is now relative to 2660 // negative, but that is now relative to
2661 // the start, rather than the end, of the 2661 // the start, rather than the end, of the
2662 // sequence. 2662 // sequence.
2663   2663  
2664 if (start < 0) 2664 if (start < 0)
2665 { 2665 {
2666 start = src.Length+start; 2666 start = src.Length+start;
2667 } 2667 }
2668 if (end < 0) 2668 if (end < 0)
2669 { 2669 {
2670 end = src.Length+end; 2670 end = src.Length+end;
2671 } 2671 }
2672   2672  
2673 // Conventional substring 2673 // Conventional substring
2674 if (start <= end) 2674 if (start <= end)
2675 { 2675 {
2676 // Implies both bounds are out-of-range. 2676 // Implies both bounds are out-of-range.
2677 if (end < 0 || start >= src.Length) 2677 if (end < 0 || start >= src.Length)
2678 { 2678 {
2679 return String.Empty; 2679 return String.Empty;
2680 } 2680 }
2681 // If end is positive, then it directly 2681 // If end is positive, then it directly
2682 // corresponds to the lengt of the substring 2682 // corresponds to the lengt of the substring
2683 // needed (plus one of course). BUT, it 2683 // needed (plus one of course). BUT, it
2684 // must be within bounds. 2684 // must be within bounds.
2685 if (end >= src.Length) 2685 if (end >= src.Length)
2686 { 2686 {
2687 end = src.Length-1; 2687 end = src.Length-1;
2688 } 2688 }
2689   2689  
2690 if (start < 0) 2690 if (start < 0)
2691 { 2691 {
2692 return src.Substring(0,end+1); 2692 return src.Substring(0,end+1);
2693 } 2693 }
2694 // Both indices are positive 2694 // Both indices are positive
2695 return src.Substring(start, (end+1) - start); 2695 return src.Substring(start, (end+1) - start);
2696 } 2696 }
2697   2697  
2698 // Inverted substring (end < start) 2698 // Inverted substring (end < start)
2699 else 2699 else
2700 { 2700 {
2701 // Implies both indices are below the 2701 // Implies both indices are below the
2702 // lower bound. In the inverted case, that 2702 // lower bound. In the inverted case, that
2703 // means the entire string will be returned 2703 // means the entire string will be returned
2704 // unchanged. 2704 // unchanged.
2705 if (start < 0) 2705 if (start < 0)
2706 { 2706 {
2707 return src; 2707 return src;
2708 } 2708 }
2709 // If both indices are greater than the upper 2709 // If both indices are greater than the upper
2710 // bound the result may seem initially counter 2710 // bound the result may seem initially counter
2711 // intuitive. 2711 // intuitive.
2712 if (end >= src.Length) 2712 if (end >= src.Length)
2713 { 2713 {
2714 return src; 2714 return src;
2715 } 2715 }
2716   2716  
2717 if (end < 0) 2717 if (end < 0)
2718 { 2718 {
2719 if (start < src.Length) 2719 if (start < src.Length)
2720 { 2720 {
2721 return src.Substring(start); 2721 return src.Substring(start);
2722 } 2722 }
2723 else 2723 else
2724 { 2724 {
2725 return String.Empty; 2725 return String.Empty;
2726 } 2726 }
2727 } 2727 }
2728 else 2728 else
2729 { 2729 {
2730 if (start < src.Length) 2730 if (start < src.Length)
2731 { 2731 {
2732 return src.Substring(0,end+1) + src.Substring(start); 2732 return src.Substring(0,end+1) + src.Substring(start);
2733 } 2733 }
2734 else 2734 else
2735 { 2735 {
2736 return src.Substring(0,end+1); 2736 return src.Substring(0,end+1);
2737 } 2737 }
2738 } 2738 }
2739 } 2739 }
2740 } 2740 }
2741   2741  
2742 /// <summary> 2742 /// <summary>
2743 /// Delete substring removes the specified substring bounded 2743 /// Delete substring removes the specified substring bounded
2744 /// by the inclusive indices start and end. Indices may be 2744 /// by the inclusive indices start and end. Indices may be
2745 /// negative (indicating end-relative) and may be inverted, 2745 /// negative (indicating end-relative) and may be inverted,
2746 /// i.e. end < start. 2746 /// i.e. end < start.
2747 /// </summary> 2747 /// </summary>
2748 public LSL_String llDeleteSubString(string src, int start, int end) 2748 public LSL_String llDeleteSubString(string src, int start, int end)
2749 { 2749 {
2750 m_host.AddScriptLPS(1); 2750 m_host.AddScriptLPS(1);
2751   2751  
2752 // Normalize indices (if negative). 2752 // Normalize indices (if negative).
2753 // After normlaization they may still be 2753 // After normlaization they may still be
2754 // negative, but that is now relative to 2754 // negative, but that is now relative to
2755 // the start, rather than the end, of the 2755 // the start, rather than the end, of the
2756 // sequence. 2756 // sequence.
2757 if (start < 0) 2757 if (start < 0)
2758 { 2758 {
2759 start = src.Length+start; 2759 start = src.Length+start;
2760 } 2760 }
2761 if (end < 0) 2761 if (end < 0)
2762 { 2762 {
2763 end = src.Length+end; 2763 end = src.Length+end;
2764 } 2764 }
2765 // Conventionally delimited substring 2765 // Conventionally delimited substring
2766 if (start <= end) 2766 if (start <= end)
2767 { 2767 {
2768 // If both bounds are outside of the existing 2768 // If both bounds are outside of the existing
2769 // string, then return unchanges. 2769 // string, then return unchanges.
2770 if (end < 0 || start >= src.Length) 2770 if (end < 0 || start >= src.Length)
2771 { 2771 {
2772 return src; 2772 return src;
2773 } 2773 }
2774 // At least one bound is in-range, so we 2774 // At least one bound is in-range, so we
2775 // need to clip the out-of-bound argument. 2775 // need to clip the out-of-bound argument.
2776 if (start < 0) 2776 if (start < 0)
2777 { 2777 {
2778 start = 0; 2778 start = 0;
2779 } 2779 }
2780   2780  
2781 if (end >= src.Length) 2781 if (end >= src.Length)
2782 { 2782 {
2783 end = src.Length-1; 2783 end = src.Length-1;
2784 } 2784 }
2785   2785  
2786 return src.Remove(start,end-start+1); 2786 return src.Remove(start,end-start+1);
2787 } 2787 }
2788 // Inverted substring 2788 // Inverted substring
2789 else 2789 else
2790 { 2790 {
2791 // In this case, out of bounds means that 2791 // In this case, out of bounds means that
2792 // the existing string is part of the cut. 2792 // the existing string is part of the cut.
2793 if (start < 0 || end >= src.Length) 2793 if (start < 0 || end >= src.Length)
2794 { 2794 {
2795 return String.Empty; 2795 return String.Empty;
2796 } 2796 }
2797   2797  
2798 if (end > 0) 2798 if (end > 0)
2799 { 2799 {
2800 if (start < src.Length) 2800 if (start < src.Length)
2801 { 2801 {
2802 return src.Remove(start).Remove(0,end+1); 2802 return src.Remove(start).Remove(0,end+1);
2803 } 2803 }
2804 else 2804 else
2805 { 2805 {
2806 return src.Remove(0,end+1); 2806 return src.Remove(0,end+1);
2807 } 2807 }
2808 } 2808 }
2809 else 2809 else
2810 { 2810 {
2811 if (start < src.Length) 2811 if (start < src.Length)
2812 { 2812 {
2813 return src.Remove(start); 2813 return src.Remove(start);
2814 } 2814 }
2815 else 2815 else
2816 { 2816 {
2817 return src; 2817 return src;
2818 } 2818 }
2819 } 2819 }
2820 } 2820 }
2821 } 2821 }
2822   2822  
2823 /// <summary> 2823 /// <summary>
2824 /// Insert string inserts the specified string identified by src 2824 /// Insert string inserts the specified string identified by src
2825 /// at the index indicated by index. Index may be negative, in 2825 /// at the index indicated by index. Index may be negative, in
2826 /// which case it is end-relative. The index may exceed either 2826 /// which case it is end-relative. The index may exceed either
2827 /// string bound, with the result being a concatenation. 2827 /// string bound, with the result being a concatenation.
2828 /// </summary> 2828 /// </summary>
2829 public LSL_String llInsertString(string dest, int index, string src) 2829 public LSL_String llInsertString(string dest, int index, string src)
2830 { 2830 {
2831 m_host.AddScriptLPS(1); 2831 m_host.AddScriptLPS(1);
2832   2832  
2833 // Normalize indices (if negative). 2833 // Normalize indices (if negative).
2834 // After normlaization they may still be 2834 // After normlaization they may still be
2835 // negative, but that is now relative to 2835 // negative, but that is now relative to
2836 // the start, rather than the end, of the 2836 // the start, rather than the end, of the
2837 // sequence. 2837 // sequence.
2838 if (index < 0) 2838 if (index < 0)
2839 { 2839 {
2840 index = dest.Length+index; 2840 index = dest.Length+index;
2841   2841  
2842 // Negative now means it is less than the lower 2842 // Negative now means it is less than the lower
2843 // bound of the string. 2843 // bound of the string.
2844   2844  
2845 if (index < 0) 2845 if (index < 0)
2846 { 2846 {
2847 return src+dest; 2847 return src+dest;
2848 } 2848 }
2849   2849  
2850 } 2850 }
2851   2851  
2852 if (index >= dest.Length) 2852 if (index >= dest.Length)
2853 { 2853 {
2854 return dest+src; 2854 return dest+src;
2855 } 2855 }
2856   2856  
2857 // The index is in bounds. 2857 // The index is in bounds.
2858 // In this case the index refers to the index that will 2858 // In this case the index refers to the index that will
2859 // be assigned to the first character of the inserted string. 2859 // be assigned to the first character of the inserted string.
2860 // So unlike the other string operations, we do not add one 2860 // So unlike the other string operations, we do not add one
2861 // to get the correct string length. 2861 // to get the correct string length.
2862 return dest.Substring(0,index)+src+dest.Substring(index); 2862 return dest.Substring(0,index)+src+dest.Substring(index);
2863   2863  
2864 } 2864 }
2865   2865  
2866 public LSL_String llToUpper(string src) 2866 public LSL_String llToUpper(string src)
2867 { 2867 {
2868 m_host.AddScriptLPS(1); 2868 m_host.AddScriptLPS(1);
2869 return src.ToUpper(); 2869 return src.ToUpper();
2870 } 2870 }
2871   2871  
2872 public LSL_String llToLower(string src) 2872 public LSL_String llToLower(string src)
2873 { 2873 {
2874 m_host.AddScriptLPS(1); 2874 m_host.AddScriptLPS(1);
2875 return src.ToLower(); 2875 return src.ToLower();
2876 } 2876 }
2877   2877  
2878 public void llGiveMoney(string destination, int amount) 2878 public void llGiveMoney(string destination, int amount)
2879 { 2879 {
2880 Util.FireAndForget(x => 2880 Util.FireAndForget(x =>
2881 { 2881 {
2882 m_host.AddScriptLPS(1); 2882 m_host.AddScriptLPS(1);
2883   2883  
2884 if (m_item.PermsGranter == UUID.Zero) 2884 if (m_item.PermsGranter == UUID.Zero)
2885 return; 2885 return;
2886   2886  
2887 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) 2887 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
2888 { 2888 {
2889 LSLError("No permissions to give money"); 2889 LSLError("No permissions to give money");
2890 return; 2890 return;
2891 } 2891 }
2892   2892  
2893 UUID toID = new UUID(); 2893 UUID toID = new UUID();
2894   2894  
2895 if (!UUID.TryParse(destination, out toID)) 2895 if (!UUID.TryParse(destination, out toID))
2896 { 2896 {
2897 LSLError("Bad key in llGiveMoney"); 2897 LSLError("Bad key in llGiveMoney");
2898 return; 2898 return;
2899 } 2899 }
2900   2900  
2901 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); 2901 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
2902   2902  
2903 if (money == null) 2903 if (money == null)
2904 { 2904 {
2905 NotImplemented("llGiveMoney"); 2905 NotImplemented("llGiveMoney");
2906 return; 2906 return;
2907 } 2907 }
2908   2908  
2909 money.ObjectGiveMoney( 2909 money.ObjectGiveMoney(
2910 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 2910 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
2911 }); 2911 });
2912 } 2912 }
2913   2913  
2914 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2914 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2915 { 2915 {
2916 m_host.AddScriptLPS(1); 2916 m_host.AddScriptLPS(1);
2917 Deprecated("llMakeExplosion"); 2917 Deprecated("llMakeExplosion");
2918 ScriptSleep(100); 2918 ScriptSleep(100);
2919 } 2919 }
2920   2920  
2921 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset) 2921 public void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset)
2922 { 2922 {
2923 m_host.AddScriptLPS(1); 2923 m_host.AddScriptLPS(1);
2924 Deprecated("llMakeFountain"); 2924 Deprecated("llMakeFountain");
2925 ScriptSleep(100); 2925 ScriptSleep(100);
2926 } 2926 }
2927   2927  
2928 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2928 public void llMakeSmoke(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2929 { 2929 {
2930 m_host.AddScriptLPS(1); 2930 m_host.AddScriptLPS(1);
2931 Deprecated("llMakeSmoke"); 2931 Deprecated("llMakeSmoke");
2932 ScriptSleep(100); 2932 ScriptSleep(100);
2933 } 2933 }
2934   2934  
2935 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 2935 public void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
2936 { 2936 {
2937 m_host.AddScriptLPS(1); 2937 m_host.AddScriptLPS(1);
2938 Deprecated("llMakeFire"); 2938 Deprecated("llMakeFire");
2939 ScriptSleep(100); 2939 ScriptSleep(100);
2940 } 2940 }
2941   2941  
2942 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 2942 public void llRezAtRoot(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
2943 { 2943 {
2944 m_host.AddScriptLPS(1); 2944 m_host.AddScriptLPS(1);
2945   2945  
2946 Util.FireAndForget(x => 2946 Util.FireAndForget(x =>
2947 { 2947 {
2948 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) 2948 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
2949 return; 2949 return;
2950   2950  
2951 float dist = (float)llVecDist(llGetPos(), pos); 2951 float dist = (float)llVecDist(llGetPos(), pos);
2952   2952  
2953 if (dist > m_ScriptDistanceFactor * 10.0f) 2953 if (dist > m_ScriptDistanceFactor * 10.0f)
2954 return; 2954 return;
2955   2955  
2956 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); 2956 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
2957   2957  
2958 if (item == null) 2958 if (item == null)
2959 { 2959 {
2960 llSay(0, "Could not find object " + inventory); 2960 llSay(0, "Could not find object " + inventory);
2961 return; 2961 return;
2962 } 2962 }
2963   2963  
2964 if (item.InvType != (int)InventoryType.Object) 2964 if (item.InvType != (int)InventoryType.Object)
2965 { 2965 {
2966 llSay(0, "Unable to create requested object. Object is missing from database."); 2966 llSay(0, "Unable to create requested object. Object is missing from database.");
2967 return; 2967 return;
2968 } 2968 }
2969   2969  
2970 // need the magnitude later 2970 // need the magnitude later
2971 // float velmag = (float)Util.GetMagnitude(llvel); 2971 // float velmag = (float)Util.GetMagnitude(llvel);
2972   2972  
2973 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param); 2973 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
2974   2974  
2975 // If either of these are null, then there was an unknown error. 2975 // If either of these are null, then there was an unknown error.
2976 if (new_group == null) 2976 if (new_group == null)
2977 return; 2977 return;
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 new_group.RootPart.SetDieAtEdge(true); 2980 new_group.RootPart.SetDieAtEdge(true);
2981   2981  
2982 new_group.ResumeScripts(); 2982 new_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 new_group.RootPart.UUID.ToString()) }, 2987 new_group.RootPart.UUID.ToString()) },
2988 new DetectParams[0])); 2988 new DetectParams[0]));
2989   2989  
2990 float groupmass = new_group.GetMass(); 2990 float groupmass = new_group.GetMass();
2991   2991  
2992 PhysicsActor pa = new_group.RootPart.PhysActor; 2992 PhysicsActor pa = new_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 //ScriptSleep((int)((groupmass * velmag) / 10)); 3006 //ScriptSleep((int)((groupmass * velmag) / 10));
3007 ScriptSleep(100); 3007 ScriptSleep(100);
3008 } 3008 }
3009   3009  
3010 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3010 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
3011 { 3011 {
3012 llRezAtRoot(inventory, pos, vel, rot, param); 3012 llRezAtRoot(inventory, pos, vel, rot, param);
3013 } 3013 }
3014   3014  
3015 public void llLookAt(LSL_Vector target, double strength, double damping) 3015 public void llLookAt(LSL_Vector target, double strength, double damping)
3016 { 3016 {
3017 m_host.AddScriptLPS(1); 3017 m_host.AddScriptLPS(1);
3018 // Determine where we are looking from 3018 // Determine where we are looking from
3019 LSL_Vector from = llGetPos(); 3019 LSL_Vector from = llGetPos();
3020   3020  
3021 // Work out the normalised vector from the source to the target 3021 // Work out the normalised vector from the source to the target
3022 LSL_Vector delta = llVecNorm(target - from); 3022 LSL_Vector delta = llVecNorm(target - from);
3023 LSL_Vector angle = new LSL_Vector(0,0,0); 3023 LSL_Vector angle = new LSL_Vector(0,0,0);
3024   3024  
3025 // Calculate the yaw 3025 // Calculate the yaw
3026 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3026 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system
3027 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3027 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
3028   3028  
3029 // Calculate pitch 3029 // Calculate pitch
3030 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3030 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z)));
3031   3031  
3032 // we need to convert from a vector describing 3032 // we need to convert from a vector describing
3033 // the angles of rotation in radians into rotation value 3033 // the angles of rotation in radians into rotation value
3034 LSL_Rotation rot = llEuler2Rot(angle); 3034 LSL_Rotation rot = llEuler2Rot(angle);
3035   3035  
3036 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3036 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3037 // set the rotation of the object, copy that behavior 3037 // set the rotation of the object, copy that behavior
3038 PhysicsActor pa = m_host.PhysActor; 3038 PhysicsActor pa = m_host.PhysActor;
3039   3039  
3040 if (strength == 0 || pa == null || !pa.IsPhysical) 3040 if (strength == 0 || pa == null || !pa.IsPhysical)
3041 { 3041 {
3042 llSetRot(rot); 3042 llSetRot(rot);
3043 } 3043 }
3044 else 3044 else
3045 { 3045 {
3046 m_host.StartLookAt(rot, (float)strength, (float)damping); 3046 m_host.StartLookAt(rot, (float)strength, (float)damping);
3047 } 3047 }
3048 } 3048 }
3049   3049  
3050 public void llStopLookAt() 3050 public void llStopLookAt()
3051 { 3051 {
3052 m_host.AddScriptLPS(1); 3052 m_host.AddScriptLPS(1);
3053 // NotImplemented("llStopLookAt"); 3053 // NotImplemented("llStopLookAt");
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"); 3237 Deprecated("llTakeCamera");
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"); 3243 Deprecated("llReleaseCamera");
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 ShoutError("llEmail: email module not configured"); 3320 ShoutError("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 llSleep(EMAIL_PAUSE_TIME); 3325 llSleep(EMAIL_PAUSE_TIME);
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 ShoutError("llGetNextEmail: email module not configured"); 3334 ShoutError("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 /// <summary> 3423 /// <summary>
3424 /// llSoundPreload is deprecated. In SL this appears to do absolutely nothing 3424 /// llSoundPreload is deprecated. In SL this appears to do absolutely nothing
3425 /// and is documented to have no delay. 3425 /// and is documented to have no delay.
3426 /// </summary> 3426 /// </summary>
3427 public void llSoundPreload(string sound) 3427 public void llSoundPreload(string sound)
3428 { 3428 {
3429 m_host.AddScriptLPS(1); 3429 m_host.AddScriptLPS(1);
3430 } 3430 }
3431   3431  
3432 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3432 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3433 { 3433 {
3434 m_host.AddScriptLPS(1); 3434 m_host.AddScriptLPS(1);
3435   3435  
3436 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3436 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3437 // set the rotation of the object, copy that behavior 3437 // set the rotation of the object, copy that behavior
3438 PhysicsActor pa = m_host.PhysActor; 3438 PhysicsActor pa = m_host.PhysActor;
3439   3439  
3440 if (strength == 0 || pa == null || !pa.IsPhysical) 3440 if (strength == 0 || pa == null || !pa.IsPhysical)
3441 { 3441 {
3442 llSetLocalRot(target); 3442 llSetLocalRot(target);
3443 } 3443 }
3444 else 3444 else
3445 { 3445 {
3446 m_host.RotLookAt(target, (float)strength, (float)damping); 3446 m_host.RotLookAt(target, (float)strength, (float)damping);
3447 } 3447 }
3448 } 3448 }
3449   3449  
3450 public LSL_Integer llStringLength(string str) 3450 public LSL_Integer llStringLength(string str)
3451 { 3451 {
3452 m_host.AddScriptLPS(1); 3452 m_host.AddScriptLPS(1);
3453 if (str.Length > 0) 3453 if (str.Length > 0)
3454 { 3454 {
3455 return str.Length; 3455 return str.Length;
3456 } 3456 }
3457 else 3457 else
3458 { 3458 {
3459 return 0; 3459 return 0;
3460 } 3460 }
3461 } 3461 }
3462   3462  
3463 public void llStartAnimation(string anim) 3463 public void llStartAnimation(string anim)
3464 { 3464 {
3465 m_host.AddScriptLPS(1); 3465 m_host.AddScriptLPS(1);
3466   3466  
3467 if (m_item.PermsGranter == UUID.Zero) 3467 if (m_item.PermsGranter == UUID.Zero)
3468 return; 3468 return;
3469   3469  
3470 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) 3470 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3471 { 3471 {
3472 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3472 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3473   3473  
3474 if (presence != null) 3474 if (presence != null)
3475 { 3475 {
3476 // Do NOT try to parse UUID, animations cannot be triggered by ID 3476 // Do NOT try to parse UUID, animations cannot be triggered by ID
3477 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); 3477 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
3478 if (animID == UUID.Zero) 3478 if (animID == UUID.Zero)
3479 presence.Animator.AddAnimation(anim, m_host.UUID); 3479 presence.Animator.AddAnimation(anim, m_host.UUID);
3480 else 3480 else
3481 presence.Animator.AddAnimation(animID, m_host.UUID); 3481 presence.Animator.AddAnimation(animID, m_host.UUID);
3482 } 3482 }
3483 } 3483 }
3484 } 3484 }
3485   3485  
3486 public void llStopAnimation(string anim) 3486 public void llStopAnimation(string anim)
3487 { 3487 {
3488 m_host.AddScriptLPS(1); 3488 m_host.AddScriptLPS(1);
3489   3489  
3490 if (m_item.PermsGranter == UUID.Zero) 3490 if (m_item.PermsGranter == UUID.Zero)
3491 return; 3491 return;
3492   3492  
3493 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) 3493 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0)
3494 { 3494 {
3495 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 3495 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
3496   3496  
3497 if (presence != null) 3497 if (presence != null)
3498 { 3498 {
3499 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim); 3499 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim);
3500   3500  
3501 if (animID == UUID.Zero) 3501 if (animID == UUID.Zero)
3502 presence.Animator.RemoveAnimation(anim); 3502 presence.Animator.RemoveAnimation(anim);
3503 else 3503 else
3504 presence.Animator.RemoveAnimation(animID, true); 3504 presence.Animator.RemoveAnimation(animID, true);
3505 } 3505 }
3506 } 3506 }
3507 } 3507 }
3508   3508  
3509 public void llPointAt(LSL_Vector pos) 3509 public void llPointAt(LSL_Vector pos)
3510 { 3510 {
3511 m_host.AddScriptLPS(1); 3511 m_host.AddScriptLPS(1);
3512 } 3512 }
3513   3513  
3514 public void llStopPointAt() 3514 public void llStopPointAt()
3515 { 3515 {
3516 m_host.AddScriptLPS(1); 3516 m_host.AddScriptLPS(1);
3517 } 3517 }
3518   3518  
3519 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) 3519 public void llTargetOmega(LSL_Vector axis, double spinrate, double gain)
3520 { 3520 {
3521 m_host.AddScriptLPS(1); 3521 m_host.AddScriptLPS(1);
3522 TargetOmega(m_host, axis, spinrate, gain); 3522 TargetOmega(m_host, axis, spinrate, gain);
3523 } 3523 }
3524   3524  
3525 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3525 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3526 { 3526 {
3527 part.UpdateAngularVelocity(axis * spinrate); 3527 part.UpdateAngularVelocity(axis * spinrate);
3528 } 3528 }
3529   3529  
3530 public LSL_Integer llGetStartParameter() 3530 public LSL_Integer llGetStartParameter()
3531 { 3531 {
3532 m_host.AddScriptLPS(1); 3532 m_host.AddScriptLPS(1);
3533 return m_ScriptEngine.GetStartParameter(m_item.ItemID); 3533 return m_ScriptEngine.GetStartParameter(m_item.ItemID);
3534 } 3534 }
3535   3535  
3536 public void llRequestPermissions(string agent, int perm) 3536 public void llRequestPermissions(string agent, int perm)
3537 { 3537 {
3538 UUID agentID; 3538 UUID agentID;
3539   3539  
3540 if (!UUID.TryParse(agent, out agentID)) 3540 if (!UUID.TryParse(agent, out agentID))
3541 return; 3541 return;
3542   3542  
3543 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3543 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3544 { 3544 {
3545 llReleaseControls(); 3545 llReleaseControls();
3546   3546  
3547 m_item.PermsGranter = UUID.Zero; 3547 m_item.PermsGranter = UUID.Zero;
3548 m_item.PermsMask = 0; 3548 m_item.PermsMask = 0;
3549   3549  
3550 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3550 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3551 "run_time_permissions", new Object[] { 3551 "run_time_permissions", new Object[] {
3552 new LSL_Integer(0) }, 3552 new LSL_Integer(0) },
3553 new DetectParams[0])); 3553 new DetectParams[0]));
3554   3554  
3555 return; 3555 return;
3556 } 3556 }
3557   3557  
3558 if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3558 if (m_item.PermsGranter != agentID || (perm & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3559 llReleaseControls(); 3559 llReleaseControls();
3560   3560  
3561 m_host.AddScriptLPS(1); 3561 m_host.AddScriptLPS(1);
3562   3562  
3563 int implicitPerms = 0; 3563 int implicitPerms = 0;
3564   3564  
3565 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar) 3565 if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
3566 { 3566 {
3567 // When attached, certain permissions are implicit if requested from owner 3567 // When attached, certain permissions are implicit if requested from owner
3568 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3568 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3569 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3569 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3570 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3570 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3571 ScriptBaseClass.PERMISSION_ATTACH; 3571 ScriptBaseClass.PERMISSION_ATTACH;
3572 } 3572 }
3573 else 3573 else
3574 { 3574 {
3575 if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID)) 3575 if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID))
3576 { 3576 {
3577 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3577 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3578 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3578 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3579 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3579 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3580 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3580 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3581 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3581 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3582 } 3582 }
3583 else 3583 else
3584 { 3584 {
3585 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3585 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3586 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3586 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3587 } 3587 }
3588 } 3588 }
3589   3589  
3590 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3590 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3591 { 3591 {
3592 lock (m_host.TaskInventory) 3592 lock (m_host.TaskInventory)
3593 { 3593 {
3594 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3594 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3595 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3595 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3596 } 3596 }
3597   3597  
3598 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3598 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3599 "run_time_permissions", new Object[] { 3599 "run_time_permissions", new Object[] {
3600 new LSL_Integer(perm) }, 3600 new LSL_Integer(perm) },
3601 new DetectParams[0])); 3601 new DetectParams[0]));
3602   3602  
3603 return; 3603 return;
3604 } 3604 }
3605   3605  
3606 ScenePresence presence = World.GetScenePresence(agentID); 3606 ScenePresence presence = World.GetScenePresence(agentID);
3607 if (presence != null) 3607 if (presence != null)
3608 { 3608 {
3609 // If permissions are being requested from an NPC and were not implicitly granted above then 3609 // If permissions are being requested from an NPC and were not implicitly granted above then
3610 // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner 3610 // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner
3611 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3611 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
3612 if (npcModule != null && npcModule.IsNPC(agentID, World)) 3612 if (npcModule != null && npcModule.IsNPC(agentID, World))
3613 { 3613 {
3614 if (npcModule.CheckPermissions(agentID, m_host.OwnerID)) 3614 if (npcModule.CheckPermissions(agentID, m_host.OwnerID))
3615 { 3615 {
3616 lock (m_host.TaskInventory) 3616 lock (m_host.TaskInventory)
3617 { 3617 {
3618 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3618 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3619 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3619 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3620 } 3620 }
3621   3621  
3622 m_ScriptEngine.PostScriptEvent( 3622 m_ScriptEngine.PostScriptEvent(
3623 m_item.ItemID, 3623 m_item.ItemID,
3624 new EventParams( 3624 new EventParams(
3625 "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); 3625 "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0]));
3626 } 3626 }
3627   3627  
3628 // it is an NPC, exit even if the permissions werent granted above, they are not going to answer 3628 // it is an NPC, exit even if the permissions werent granted above, they are not going to answer
3629 // the question! 3629 // the question!
3630 return; 3630 return;
3631 } 3631 }
3632   3632  
3633 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID); 3633 string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID);
3634 if (ownerName == String.Empty) 3634 if (ownerName == String.Empty)
3635 ownerName = "(hippos)"; 3635 ownerName = "(hippos)";
3636   3636  
3637 if (!m_waitingForScriptAnswer) 3637 if (!m_waitingForScriptAnswer)
3638 { 3638 {
3639 lock (m_host.TaskInventory) 3639 lock (m_host.TaskInventory)
3640 { 3640 {
3641 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3641 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3642 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3642 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3643 } 3643 }
3644   3644  
3645 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3645 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3646 m_waitingForScriptAnswer=true; 3646 m_waitingForScriptAnswer=true;
3647 } 3647 }
3648   3648  
3649 presence.ControllingClient.SendScriptQuestion( 3649 presence.ControllingClient.SendScriptQuestion(
3650 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm); 3650 m_host.UUID, m_host.ParentGroup.RootPart.Name, ownerName, m_item.ItemID, perm);
3651   3651  
3652 return; 3652 return;
3653 } 3653 }
3654   3654  
3655 // Requested agent is not in range, refuse perms 3655 // Requested agent is not in range, refuse perms
3656 m_ScriptEngine.PostScriptEvent( 3656 m_ScriptEngine.PostScriptEvent(
3657 m_item.ItemID, 3657 m_item.ItemID,
3658 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); 3658 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0]));
3659 } 3659 }
3660   3660  
3661 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer) 3661 void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer)
3662 { 3662 {
3663 if (taskID != m_host.UUID) 3663 if (taskID != m_host.UUID)
3664 return; 3664 return;
3665   3665  
3666 client.OnScriptAnswer -= handleScriptAnswer; 3666 client.OnScriptAnswer -= handleScriptAnswer;
3667 m_waitingForScriptAnswer = false; 3667 m_waitingForScriptAnswer = false;
3668   3668  
3669 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3669 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3670 llReleaseControls(); 3670 llReleaseControls();
3671   3671  
3672 lock (m_host.TaskInventory) 3672 lock (m_host.TaskInventory)
3673 { 3673 {
3674 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3674 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3675 } 3675 }
3676   3676  
3677 m_ScriptEngine.PostScriptEvent( 3677 m_ScriptEngine.PostScriptEvent(
3678 m_item.ItemID, 3678 m_item.ItemID,
3679 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3679 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0]));
3680 } 3680 }
3681   3681  
3682 public LSL_String llGetPermissionsKey() 3682 public LSL_String llGetPermissionsKey()
3683 { 3683 {
3684 m_host.AddScriptLPS(1); 3684 m_host.AddScriptLPS(1);
3685   3685  
3686 return m_item.PermsGranter.ToString(); 3686 return m_item.PermsGranter.ToString();
3687 } 3687 }
3688   3688  
3689 public LSL_Integer llGetPermissions() 3689 public LSL_Integer llGetPermissions()
3690 { 3690 {
3691 m_host.AddScriptLPS(1); 3691 m_host.AddScriptLPS(1);
3692   3692  
3693 int perms = m_item.PermsMask; 3693 int perms = m_item.PermsMask;
3694   3694  
3695 if (m_automaticLinkPermission) 3695 if (m_automaticLinkPermission)
3696 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3696 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3697   3697  
3698 return perms; 3698 return perms;
3699 } 3699 }
3700   3700  
3701 public LSL_Integer llGetLinkNumber() 3701 public LSL_Integer llGetLinkNumber()
3702 { 3702 {
3703 m_host.AddScriptLPS(1); 3703 m_host.AddScriptLPS(1);
3704   3704  
3705 if (m_host.ParentGroup.PrimCount > 1) 3705 if (m_host.ParentGroup.PrimCount > 1)
3706 { 3706 {
3707 return m_host.LinkNum; 3707 return m_host.LinkNum;
3708 } 3708 }
3709 else 3709 else
3710 { 3710 {
3711 return 0; 3711 return 0;
3712 } 3712 }
3713 } 3713 }
3714   3714  
3715 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3715 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3716 { 3716 {
3717 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3717 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3718   3718  
3719 foreach (SceneObjectPart part in parts) 3719 foreach (SceneObjectPart part in parts)
3720 part.SetFaceColorAlpha(face, color, null); 3720 part.SetFaceColorAlpha(face, color, null);
3721 } 3721 }
3722   3722  
3723 public void llCreateLink(string target, int parent) 3723 public void llCreateLink(string target, int parent)
3724 { 3724 {
3725 m_host.AddScriptLPS(1); 3725 m_host.AddScriptLPS(1);
3726 UUID targetID; 3726 UUID targetID;
3727   3727  
3728 if (!UUID.TryParse(target, out targetID)) 3728 if (!UUID.TryParse(target, out targetID))
3729 return; 3729 return;
3730   3730  
3731 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3731 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3732 && !m_automaticLinkPermission) 3732 && !m_automaticLinkPermission)
3733 { 3733 {
3734 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3734 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3735 return; 3735 return;
3736 } 3736 }
3737   3737  
3738 IClientAPI client = null; 3738 IClientAPI client = null;
3739 ScenePresence sp = World.GetScenePresence(m_item.PermsGranter); 3739 ScenePresence sp = World.GetScenePresence(m_item.PermsGranter);
3740 if (sp != null) 3740 if (sp != null)
3741 client = sp.ControllingClient; 3741 client = sp.ControllingClient;
3742   3742  
3743 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); 3743 SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID);
3744   3744  
3745 if (targetPart.ParentGroup.AttachmentPoint != 0) 3745 if (targetPart.ParentGroup.AttachmentPoint != 0)
3746 return; // Fail silently if attached 3746 return; // Fail silently if attached
3747   3747  
3748 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID) 3748 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3749 return; 3749 return;
3750   3750  
3751 SceneObjectGroup parentPrim = null, childPrim = null; 3751 SceneObjectGroup parentPrim = null, childPrim = null;
3752   3752  
3753 if (targetPart != null) 3753 if (targetPart != null)
3754 { 3754 {
3755 if (parent != 0) 3755 if (parent != 0)
3756 { 3756 {
3757 parentPrim = m_host.ParentGroup; 3757 parentPrim = m_host.ParentGroup;
3758 childPrim = targetPart.ParentGroup; 3758 childPrim = targetPart.ParentGroup;
3759 } 3759 }
3760 else 3760 else
3761 { 3761 {
3762 parentPrim = targetPart.ParentGroup; 3762 parentPrim = targetPart.ParentGroup;
3763 childPrim = m_host.ParentGroup; 3763 childPrim = m_host.ParentGroup;
3764 } 3764 }
3765   3765  
3766 // Required for linking 3766 // Required for linking
3767 childPrim.RootPart.ClearUpdateSchedule(); 3767 childPrim.RootPart.ClearUpdateSchedule();
3768 parentPrim.LinkToGroup(childPrim, true); 3768 parentPrim.LinkToGroup(childPrim, true);
3769 } 3769 }
3770   3770  
3771 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3771 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3772 parentPrim.RootPart.CreateSelected = true; 3772 parentPrim.RootPart.CreateSelected = true;
3773 parentPrim.HasGroupChanged = true; 3773 parentPrim.HasGroupChanged = true;
3774 parentPrim.ScheduleGroupForFullUpdate(); 3774 parentPrim.ScheduleGroupForFullUpdate();
3775   3775  
3776 if (client != null) 3776 if (client != null)
3777 parentPrim.SendPropertiesToClient(client); 3777 parentPrim.SendPropertiesToClient(client);
3778   3778  
3779 ScriptSleep(1000); 3779 ScriptSleep(1000);
3780 } 3780 }
3781   3781  
3782 public void llBreakLink(int linknum) 3782 public void llBreakLink(int linknum)
3783 { 3783 {
3784 m_host.AddScriptLPS(1); 3784 m_host.AddScriptLPS(1);
3785   3785  
3786 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3786 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3787 && !m_automaticLinkPermission) 3787 && !m_automaticLinkPermission)
3788 { 3788 {
3789 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3789 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3790 return; 3790 return;
3791 } 3791 }
3792   3792  
3793 if (linknum < ScriptBaseClass.LINK_THIS) 3793 if (linknum < ScriptBaseClass.LINK_THIS)
3794 return; 3794 return;
3795   3795  
3796 SceneObjectGroup parentPrim = m_host.ParentGroup; 3796 SceneObjectGroup parentPrim = m_host.ParentGroup;
3797   3797  
3798 if (parentPrim.AttachmentPoint != 0) 3798 if (parentPrim.AttachmentPoint != 0)
3799 return; // Fail silently if attached 3799 return; // Fail silently if attached
3800 SceneObjectPart childPrim = null; 3800 SceneObjectPart childPrim = null;
3801   3801  
3802 switch (linknum) 3802 switch (linknum)
3803 { 3803 {
3804 case ScriptBaseClass.LINK_ROOT: 3804 case ScriptBaseClass.LINK_ROOT:
3805 break; 3805 break;
3806 case ScriptBaseClass.LINK_SET: 3806 case ScriptBaseClass.LINK_SET:
3807 case ScriptBaseClass.LINK_ALL_OTHERS: 3807 case ScriptBaseClass.LINK_ALL_OTHERS:
3808 case ScriptBaseClass.LINK_ALL_CHILDREN: 3808 case ScriptBaseClass.LINK_ALL_CHILDREN:
3809 case ScriptBaseClass.LINK_THIS: 3809 case ScriptBaseClass.LINK_THIS:
3810 foreach (SceneObjectPart part in parentPrim.Parts) 3810 foreach (SceneObjectPart part in parentPrim.Parts)
3811 { 3811 {
3812 if (part.UUID != m_host.UUID) 3812 if (part.UUID != m_host.UUID)
3813 { 3813 {
3814 childPrim = part; 3814 childPrim = part;
3815 break; 3815 break;
3816 } 3816 }
3817 } 3817 }
3818 break; 3818 break;
3819 default: 3819 default:
3820 childPrim = parentPrim.GetLinkNumPart(linknum); 3820 childPrim = parentPrim.GetLinkNumPart(linknum);
3821 if (childPrim.UUID == m_host.UUID) 3821 if (childPrim.UUID == m_host.UUID)
3822 childPrim = null; 3822 childPrim = null;
3823 break; 3823 break;
3824 } 3824 }
3825   3825  
3826 if (linknum == ScriptBaseClass.LINK_ROOT) 3826 if (linknum == ScriptBaseClass.LINK_ROOT)
3827 { 3827 {
3828 // Restructuring Multiple Prims. 3828 // Restructuring Multiple Prims.
3829 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3829 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3830 parts.Remove(parentPrim.RootPart); 3830 parts.Remove(parentPrim.RootPart);
3831 foreach (SceneObjectPart part in parts) 3831 foreach (SceneObjectPart part in parts)
3832 { 3832 {
3833 parentPrim.DelinkFromGroup(part.LocalId, true); 3833 parentPrim.DelinkFromGroup(part.LocalId, true);
3834 } 3834 }
3835 parentPrim.HasGroupChanged = true; 3835 parentPrim.HasGroupChanged = true;
3836 parentPrim.ScheduleGroupForFullUpdate(); 3836 parentPrim.ScheduleGroupForFullUpdate();
3837 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3837 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3838   3838  
3839 if (parts.Count > 0) 3839 if (parts.Count > 0)
3840 { 3840 {
3841 SceneObjectPart newRoot = parts[0]; 3841 SceneObjectPart newRoot = parts[0];
3842 parts.Remove(newRoot); 3842 parts.Remove(newRoot);
3843 foreach (SceneObjectPart part in parts) 3843 foreach (SceneObjectPart part in parts)
3844 { 3844 {
3845 // Required for linking 3845 // Required for linking
3846 part.ClearUpdateSchedule(); 3846 part.ClearUpdateSchedule();
3847 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3847 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3848 } 3848 }
3849 newRoot.ParentGroup.HasGroupChanged = true; 3849 newRoot.ParentGroup.HasGroupChanged = true;
3850 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3850 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3851 } 3851 }
3852 } 3852 }
3853 else 3853 else
3854 { 3854 {
3855 if (childPrim == null) 3855 if (childPrim == null)
3856 return; 3856 return;
3857   3857  
3858 parentPrim.DelinkFromGroup(childPrim.LocalId, true); 3858 parentPrim.DelinkFromGroup(childPrim.LocalId, true);
3859 parentPrim.HasGroupChanged = true; 3859 parentPrim.HasGroupChanged = true;
3860 parentPrim.ScheduleGroupForFullUpdate(); 3860 parentPrim.ScheduleGroupForFullUpdate();
3861 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3861 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3862 } 3862 }
3863 } 3863 }
3864   3864  
3865 public void llBreakAllLinks() 3865 public void llBreakAllLinks()
3866 { 3866 {
3867 m_host.AddScriptLPS(1); 3867 m_host.AddScriptLPS(1);
3868 SceneObjectGroup parentPrim = m_host.ParentGroup; 3868 SceneObjectGroup parentPrim = m_host.ParentGroup;
3869 if (parentPrim.AttachmentPoint != 0) 3869 if (parentPrim.AttachmentPoint != 0)
3870 return; // Fail silently if attached 3870 return; // Fail silently if attached
3871   3871  
3872 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3872 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3873 parts.Remove(parentPrim.RootPart); 3873 parts.Remove(parentPrim.RootPart);
3874   3874  
3875 foreach (SceneObjectPart part in parts) 3875 foreach (SceneObjectPart part in parts)
3876 { 3876 {
3877 parentPrim.DelinkFromGroup(part.LocalId, true); 3877 parentPrim.DelinkFromGroup(part.LocalId, true);
3878 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3878 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3879 } 3879 }
3880 parentPrim.HasGroupChanged = true; 3880 parentPrim.HasGroupChanged = true;
3881 parentPrim.ScheduleGroupForFullUpdate(); 3881 parentPrim.ScheduleGroupForFullUpdate();
3882 } 3882 }
3883   3883  
3884 public LSL_String llGetLinkKey(int linknum) 3884 public LSL_String llGetLinkKey(int linknum)
3885 { 3885 {
3886 m_host.AddScriptLPS(1); 3886 m_host.AddScriptLPS(1);
3887   3887  
3888 ISceneEntity entity = GetLinkEntity(linknum); 3888 ISceneEntity entity = GetLinkEntity(linknum);
3889   3889  
3890 if (entity != null) 3890 if (entity != null)
3891 return entity.UUID.ToString(); 3891 return entity.UUID.ToString();
3892 else 3892 else
3893 return ScriptBaseClass.NULL_KEY; 3893 return ScriptBaseClass.NULL_KEY;
3894 } 3894 }
3895   3895  
3896 /// <summary> 3896 /// <summary>
3897 /// Returns the name of the child prim or seated avatar matching the 3897 /// Returns the name of the child prim or seated avatar matching the
3898 /// specified link number. 3898 /// specified link number.
3899 /// </summary> 3899 /// </summary>
3900 /// <param name="linknum"> 3900 /// <param name="linknum">
3901 /// The number of a link in the linkset or a link-related constant. 3901 /// The number of a link in the linkset or a link-related constant.
3902 /// </param> 3902 /// </param>
3903 /// <returns> 3903 /// <returns>
3904 /// The name determined to match the specified link number. 3904 /// The name determined to match the specified link number.
3905 /// </returns> 3905 /// </returns>
3906 /// <remarks> 3906 /// <remarks>
3907 /// The rules governing the returned name are not simple. The only 3907 /// The rules governing the returned name are not simple. The only
3908 /// time a blank name is returned is if the target prim has a blank 3908 /// time a blank name is returned is if the target prim has a blank
3909 /// name. If no prim with the given link number can be found then 3909 /// name. If no prim with the given link number can be found then
3910 /// usually NULL_KEY is returned but there are exceptions. 3910 /// usually NULL_KEY is returned but there are exceptions.
3911 /// 3911 ///
3912 /// In a single unlinked prim, A call with 0 returns the name, all 3912 /// In a single unlinked prim, A call with 0 returns the name, all
3913 /// other values for link number return NULL_KEY 3913 /// other values for link number return NULL_KEY
3914 /// 3914 ///
3915 /// In link sets it is more complicated. 3915 /// In link sets it is more complicated.
3916 /// 3916 ///
3917 /// If the script is in the root prim:- 3917 /// If the script is in the root prim:-
3918 /// A zero link number returns NULL_KEY. 3918 /// A zero link number returns NULL_KEY.
3919 /// Positive link numbers return the name of the prim, or NULL_KEY 3919 /// Positive link numbers return the name of the prim, or NULL_KEY
3920 /// if a prim does not exist at that position. 3920 /// if a prim does not exist at that position.
3921 /// Negative link numbers return the name of the first child prim. 3921 /// Negative link numbers return the name of the first child prim.
3922 /// 3922 ///
3923 /// If the script is in a child prim:- 3923 /// If the script is in a child prim:-
3924 /// Link numbers 0 or 1 return the name of the root prim. 3924 /// Link numbers 0 or 1 return the name of the root prim.
3925 /// Positive link numbers return the name of the prim or NULL_KEY 3925 /// Positive link numbers return the name of the prim or NULL_KEY
3926 /// if a prim does not exist at that position. 3926 /// if a prim does not exist at that position.
3927 /// Negative numbers return the name of the root prim. 3927 /// Negative numbers return the name of the root prim.
3928 /// 3928 ///
3929 /// References 3929 /// References
3930 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetLinkName 3930 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetLinkName
3931 /// Mentions NULL_KEY being returned 3931 /// Mentions NULL_KEY being returned
3932 /// http://wiki.secondlife.com/wiki/LlGetLinkName 3932 /// http://wiki.secondlife.com/wiki/LlGetLinkName
3933 /// Mentions using the LINK_* constants, some of which are negative 3933 /// Mentions using the LINK_* constants, some of which are negative
3934 /// </remarks> 3934 /// </remarks>
3935 public LSL_String llGetLinkName(int linknum) 3935 public LSL_String llGetLinkName(int linknum)
3936 { 3936 {
3937 m_host.AddScriptLPS(1); 3937 m_host.AddScriptLPS(1);
3938   3938  
3939 ISceneEntity entity = GetLinkEntity(linknum); 3939 ISceneEntity entity = GetLinkEntity(linknum);
3940   3940  
3941 if (entity != null) 3941 if (entity != null)
3942 return entity.Name; 3942 return entity.Name;
3943 else 3943 else
3944 return ScriptBaseClass.NULL_KEY; 3944 return ScriptBaseClass.NULL_KEY;
3945 } 3945 }
3946   3946  
3947 public LSL_Integer llGetInventoryNumber(int type) 3947 public LSL_Integer llGetInventoryNumber(int type)
3948 { 3948 {
3949 m_host.AddScriptLPS(1); 3949 m_host.AddScriptLPS(1);
3950 int count = 0; 3950 int count = 0;
3951   3951  
3952 lock (m_host.TaskInventory) 3952 lock (m_host.TaskInventory)
3953 { 3953 {
3954 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3954 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3955 { 3955 {
3956 if (inv.Value.Type == type || type == -1) 3956 if (inv.Value.Type == type || type == -1)
3957 { 3957 {
3958 count = count + 1; 3958 count = count + 1;
3959 } 3959 }
3960 } 3960 }
3961 } 3961 }
3962   3962  
3963 return count; 3963 return count;
3964 } 3964 }
3965   3965  
3966 public LSL_String llGetInventoryName(int type, int number) 3966 public LSL_String llGetInventoryName(int type, int number)
3967 { 3967 {
3968 m_host.AddScriptLPS(1); 3968 m_host.AddScriptLPS(1);
3969 ArrayList keys = new ArrayList(); 3969 ArrayList keys = new ArrayList();
3970   3970  
3971 lock (m_host.TaskInventory) 3971 lock (m_host.TaskInventory)
3972 { 3972 {
3973 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 3973 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3974 { 3974 {
3975 if (inv.Value.Type == type || type == -1) 3975 if (inv.Value.Type == type || type == -1)
3976 { 3976 {
3977 keys.Add(inv.Value.Name); 3977 keys.Add(inv.Value.Name);
3978 } 3978 }
3979 } 3979 }
3980 } 3980 }
3981   3981  
3982 if (keys.Count == 0) 3982 if (keys.Count == 0)
3983 { 3983 {
3984 return String.Empty; 3984 return String.Empty;
3985 } 3985 }
3986 keys.Sort(); 3986 keys.Sort();
3987 if (keys.Count > number) 3987 if (keys.Count > number)
3988 { 3988 {
3989 return (string)keys[number]; 3989 return (string)keys[number];
3990 } 3990 }
3991 return String.Empty; 3991 return String.Empty;
3992 } 3992 }
3993   3993  
3994 public LSL_Float llGetEnergy() 3994 public LSL_Float llGetEnergy()
3995 { 3995 {
3996 m_host.AddScriptLPS(1); 3996 m_host.AddScriptLPS(1);
3997 // TODO: figure out real energy value 3997 // TODO: figure out real energy value
3998 return 1.0f; 3998 return 1.0f;
3999 } 3999 }
4000   4000  
4001 public void llGiveInventory(string destination, string inventory) 4001 public void llGiveInventory(string destination, string inventory)
4002 { 4002 {
4003 m_host.AddScriptLPS(1); 4003 m_host.AddScriptLPS(1);
4004   4004  
4005 UUID destId = UUID.Zero; 4005 UUID destId = UUID.Zero;
4006   4006  
4007 if (!UUID.TryParse(destination, out destId)) 4007 if (!UUID.TryParse(destination, out destId))
4008 { 4008 {
4009 llSay(0, "Could not parse key " + destination); 4009 llSay(0, "Could not parse key " + destination);
4010 return; 4010 return;
4011 } 4011 }
4012   4012  
4013 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); 4013 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
4014   4014  
4015 if (item == null) 4015 if (item == null)
4016 { 4016 {
4017 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4017 llSay(0, String.Format("Could not find object '{0}'", inventory));
4018 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4018 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4019 } 4019 }
4020   4020  
4021 UUID objId = item.ItemID; 4021 UUID objId = item.ItemID;
4022   4022  
4023 // check if destination is an object 4023 // check if destination is an object
4024 if (World.GetSceneObjectPart(destId) != null) 4024 if (World.GetSceneObjectPart(destId) != null)
4025 { 4025 {
4026 // destination is an object 4026 // destination is an object
4027 World.MoveTaskInventoryItem(destId, m_host, objId); 4027 World.MoveTaskInventoryItem(destId, m_host, objId);
4028 } 4028 }
4029 else 4029 else
4030 { 4030 {
4031 ScenePresence presence = World.GetScenePresence(destId); 4031 ScenePresence presence = World.GetScenePresence(destId);
4032   4032  
4033 if (presence == null) 4033 if (presence == null)
4034 { 4034 {
4035 UserAccount account = 4035 UserAccount account =
4036 World.UserAccountService.GetUserAccount( 4036 World.UserAccountService.GetUserAccount(
4037 World.RegionInfo.ScopeID, 4037 World.RegionInfo.ScopeID,
4038 destId); 4038 destId);
4039   4039  
4040 if (account == null) 4040 if (account == null)
4041 { 4041 {
4042 llSay(0, "Can't find destination "+destId.ToString()); 4042 llSay(0, "Can't find destination "+destId.ToString());
4043 return; 4043 return;
4044 } 4044 }
4045 } 4045 }
4046 // destination is an avatar 4046 // destination is an avatar
4047 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4047 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4048   4048  
4049 if (agentItem == null) 4049 if (agentItem == null)
4050 return; 4050 return;
4051   4051  
4052 if (m_TransferModule != null) 4052 if (m_TransferModule != null)
4053 { 4053 {
4054 byte[] bucket = new byte[1]; 4054 byte[] bucket = new byte[1];
4055 bucket[0] = (byte)item.Type; 4055 bucket[0] = (byte)item.Type;
4056   4056  
4057 GridInstantMessage msg = new GridInstantMessage(World, 4057 GridInstantMessage msg = new GridInstantMessage(World,
4058 m_host.OwnerID, m_host.Name, destId, 4058 m_host.OwnerID, m_host.Name, destId,
4059 (byte)InstantMessageDialog.TaskInventoryOffered, 4059 (byte)InstantMessageDialog.TaskInventoryOffered,
4060 false, item.Name+". "+m_host.Name+" is located at "+ 4060 false, item.Name+". "+m_host.Name+" is located at "+
4061 World.RegionInfo.RegionName+" "+ 4061 World.RegionInfo.RegionName+" "+
4062 m_host.AbsolutePosition.ToString(), 4062 m_host.AbsolutePosition.ToString(),
4063 agentItem.ID, true, m_host.AbsolutePosition, 4063 agentItem.ID, true, m_host.AbsolutePosition,
4064 bucket, true); 4064 bucket, true);
4065   4065  
4066 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4066 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4067 } 4067 }
4068   4068  
4069 ScriptSleep(3000); 4069 ScriptSleep(3000);
4070 } 4070 }
4071 } 4071 }
4072   4072  
4073 public void llRemoveInventory(string name) 4073 public void llRemoveInventory(string name)
4074 { 4074 {
4075 m_host.AddScriptLPS(1); 4075 m_host.AddScriptLPS(1);
4076   4076  
4077 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 4077 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
4078   4078  
4079 if (item == null) 4079 if (item == null)
4080 return; 4080 return;
4081   4081  
4082 if (item.ItemID == m_item.ItemID) 4082 if (item.ItemID == m_item.ItemID)
4083 throw new ScriptDeleteException(); 4083 throw new ScriptDeleteException();
4084 else 4084 else
4085 m_host.Inventory.RemoveInventoryItem(item.ItemID); 4085 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4086 } 4086 }
4087   4087  
4088 public void llSetText(string text, LSL_Vector color, double alpha) 4088 public void llSetText(string text, LSL_Vector color, double alpha)
4089 { 4089 {
4090 m_host.AddScriptLPS(1); 4090 m_host.AddScriptLPS(1);
4091 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f); 4091 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4092 if (text.Length > 254) 4092 if (text.Length > 254)
4093 text = text.Remove(254); 4093 text = text.Remove(254);
4094   4094  
4095 byte[] data; 4095 byte[] data;
4096 do 4096 do
4097 { 4097 {
4098 data = Util.UTF8.GetBytes(text); 4098 data = Util.UTF8.GetBytes(text);
4099 if (data.Length > 254) 4099 if (data.Length > 254)
4100 text = text.Substring(0, text.Length - 1); 4100 text = text.Substring(0, text.Length - 1);
4101 } while (data.Length > 254); 4101 } while (data.Length > 254);
4102   4102  
4103 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4103 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4104 //m_host.ParentGroup.HasGroupChanged = true; 4104 //m_host.ParentGroup.HasGroupChanged = true;
4105 //m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4105 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
4106 } 4106 }
4107   4107  
4108 public LSL_Float llWater(LSL_Vector offset) 4108 public LSL_Float llWater(LSL_Vector offset)
4109 { 4109 {
4110 m_host.AddScriptLPS(1); 4110 m_host.AddScriptLPS(1);
4111 return World.RegionInfo.RegionSettings.WaterHeight; 4111 return World.RegionInfo.RegionSettings.WaterHeight;
4112 } 4112 }
4113   4113  
4114 public void llPassTouches(int pass) 4114 public void llPassTouches(int pass)
4115 { 4115 {
4116 m_host.AddScriptLPS(1); 4116 m_host.AddScriptLPS(1);
4117 if (pass != 0) 4117 if (pass != 0)
4118 m_host.PassTouches = true; 4118 m_host.PassTouches = true;
4119 else 4119 else
4120 m_host.PassTouches = false; 4120 m_host.PassTouches = false;
4121 } 4121 }
4122   4122  
4123 public LSL_String llRequestAgentData(string id, int data) 4123 public LSL_String llRequestAgentData(string id, int data)
4124 { 4124 {
4125 m_host.AddScriptLPS(1); 4125 m_host.AddScriptLPS(1);
4126   4126  
4127 UUID uuid = (UUID)id; 4127 UUID uuid = (UUID)id;
4128 PresenceInfo pinfo = null; 4128 PresenceInfo pinfo = null;
4129 UserAccount account; 4129 UserAccount account;
4130   4130  
4131 UserInfoCacheEntry ce; 4131 UserInfoCacheEntry ce;
4132 if (!m_userInfoCache.TryGetValue(uuid, out ce)) 4132 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4133 { 4133 {
4134 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4134 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4135 if (account == null) 4135 if (account == null)
4136 { 4136 {
4137 m_userInfoCache[uuid] = null; // Cache negative 4137 m_userInfoCache[uuid] = null; // Cache negative
4138 return UUID.Zero.ToString(); 4138 return UUID.Zero.ToString();
4139 } 4139 }
4140   4140  
4141   4141  
4142 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4142 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4143 if (pinfos != null && pinfos.Length > 0) 4143 if (pinfos != null && pinfos.Length > 0)
4144 { 4144 {
4145 foreach (PresenceInfo p in pinfos) 4145 foreach (PresenceInfo p in pinfos)
4146 { 4146 {
4147 if (p.RegionID != UUID.Zero) 4147 if (p.RegionID != UUID.Zero)
4148 { 4148 {
4149 pinfo = p; 4149 pinfo = p;
4150 } 4150 }
4151 } 4151 }
4152 } 4152 }
4153   4153  
4154 ce = new UserInfoCacheEntry(); 4154 ce = new UserInfoCacheEntry();
4155 ce.time = Util.EnvironmentTickCount(); 4155 ce.time = Util.EnvironmentTickCount();
4156 ce.account = account; 4156 ce.account = account;
4157 ce.pinfo = pinfo; 4157 ce.pinfo = pinfo;
4158 } 4158 }
4159 else 4159 else
4160 { 4160 {
4161 if (ce == null) 4161 if (ce == null)
4162 return UUID.Zero.ToString(); 4162 return UUID.Zero.ToString();
4163   4163  
4164 account = ce.account; 4164 account = ce.account;
4165 pinfo = ce.pinfo; 4165 pinfo = ce.pinfo;
4166 } 4166 }
4167   4167  
4168 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4168 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4169 { 4169 {
4170 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4170 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4171 if (pinfos != null && pinfos.Length > 0) 4171 if (pinfos != null && pinfos.Length > 0)
4172 { 4172 {
4173 foreach (PresenceInfo p in pinfos) 4173 foreach (PresenceInfo p in pinfos)
4174 { 4174 {
4175 if (p.RegionID != UUID.Zero) 4175 if (p.RegionID != UUID.Zero)
4176 { 4176 {
4177 pinfo = p; 4177 pinfo = p;
4178 } 4178 }
4179 } 4179 }
4180 } 4180 }
4181 else 4181 else
4182 pinfo = null; 4182 pinfo = null;
4183   4183  
4184 ce.time = Util.EnvironmentTickCount(); 4184 ce.time = Util.EnvironmentTickCount();
4185 ce.pinfo = pinfo; 4185 ce.pinfo = pinfo;
4186 } 4186 }
4187   4187  
4188 string reply = String.Empty; 4188 string reply = String.Empty;
4189   4189  
4190 switch (data) 4190 switch (data)
4191 { 4191 {
4192 case 1: // DATA_ONLINE (0|1) 4192 case 1: // DATA_ONLINE (0|1)
4193 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4193 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4194 reply = "1"; 4194 reply = "1";
4195 else 4195 else
4196 reply = "0"; 4196 reply = "0";
4197 break; 4197 break;
4198 case 2: // DATA_NAME (First Last) 4198 case 2: // DATA_NAME (First Last)
4199 reply = account.FirstName + " " + account.LastName; 4199 reply = account.FirstName + " " + account.LastName;
4200 break; 4200 break;
4201 case 3: // DATA_BORN (YYYY-MM-DD) 4201 case 3: // DATA_BORN (YYYY-MM-DD)
4202 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4202 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4203 born = born.AddSeconds(account.Created); 4203 born = born.AddSeconds(account.Created);
4204 reply = born.ToString("yyyy-MM-dd"); 4204 reply = born.ToString("yyyy-MM-dd");
4205 break; 4205 break;
4206 case 4: // DATA_RATING (0,0,0,0,0,0) 4206 case 4: // DATA_RATING (0,0,0,0,0,0)
4207 reply = "0,0,0,0,0,0"; 4207 reply = "0,0,0,0,0,0";
4208 break; 4208 break;
4209 case 7: // DATA_USERLEVEL (integer) 4209 case 7: // DATA_USERLEVEL (integer)
4210 reply = account.UserLevel.ToString(); 4210 reply = account.UserLevel.ToString();
4211 break; 4211 break;
4212 case 8: // DATA_PAYINFO (0|1|2|3) 4212 case 8: // DATA_PAYINFO (0|1|2|3)
4213 reply = "0"; 4213 reply = "0";
4214 break; 4214 break;
4215 default: 4215 default:
4216 return UUID.Zero.ToString(); // Raise no event 4216 return UUID.Zero.ToString(); // Raise no event
4217 } 4217 }
4218   4218  
4219 UUID rq = UUID.Random(); 4219 UUID rq = UUID.Random();
4220   4220  
4221 UUID tid = AsyncCommands. 4221 UUID tid = AsyncCommands.
4222 DataserverPlugin.RegisterRequest(m_host.LocalId, 4222 DataserverPlugin.RegisterRequest(m_host.LocalId,
4223 m_item.ItemID, rq.ToString()); 4223 m_item.ItemID, rq.ToString());
4224   4224  
4225 AsyncCommands. 4225 AsyncCommands.
4226 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4226 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4227   4227  
4228 ScriptSleep(100); 4228 ScriptSleep(100);
4229 return tid.ToString(); 4229 return tid.ToString();
4230 } 4230 }
4231   4231  
4232 public LSL_String llRequestInventoryData(string name) 4232 public LSL_String llRequestInventoryData(string name)
4233 { 4233 {
4234 m_host.AddScriptLPS(1); 4234 m_host.AddScriptLPS(1);
4235   4235  
4236 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems()) 4236 foreach (TaskInventoryItem item in m_host.Inventory.GetInventoryItems())
4237 { 4237 {
4238 if (item.Type == 3 && item.Name == name) 4238 if (item.Type == 3 && item.Name == name)
4239 { 4239 {
4240 UUID tid = AsyncCommands. 4240 UUID tid = AsyncCommands.
4241 DataserverPlugin.RegisterRequest(m_host.LocalId, 4241 DataserverPlugin.RegisterRequest(m_host.LocalId,
4242 m_item.ItemID, item.AssetID.ToString()); 4242 m_item.ItemID, item.AssetID.ToString());
4243   4243  
4244 Vector3 region = new Vector3( 4244 Vector3 region = new Vector3(
4245 World.RegionInfo.RegionLocX * Constants.RegionSize, 4245 World.RegionInfo.RegionLocX * Constants.RegionSize,
4246 World.RegionInfo.RegionLocY * Constants.RegionSize, 4246 World.RegionInfo.RegionLocY * Constants.RegionSize,
4247 0); 4247 0);
4248   4248  
4249 World.AssetService.Get(item.AssetID.ToString(), this, 4249 World.AssetService.Get(item.AssetID.ToString(), this,
4250 delegate(string i, object sender, AssetBase a) 4250 delegate(string i, object sender, AssetBase a)
4251 { 4251 {
4252 AssetLandmark lm = new AssetLandmark(a); 4252 AssetLandmark lm = new AssetLandmark(a);
4253   4253  
4254 float rx = (uint)(lm.RegionHandle >> 32); 4254 float rx = (uint)(lm.RegionHandle >> 32);
4255 float ry = (uint)lm.RegionHandle; 4255 float ry = (uint)lm.RegionHandle;
4256 region = lm.Position + new Vector3(rx, ry, 0) - region; 4256 region = lm.Position + new Vector3(rx, ry, 0) - region;
4257   4257  
4258 string reply = region.ToString(); 4258 string reply = region.ToString();
4259 AsyncCommands. 4259 AsyncCommands.
4260 DataserverPlugin.DataserverReply(i.ToString(), 4260 DataserverPlugin.DataserverReply(i.ToString(),
4261 reply); 4261 reply);
4262 }); 4262 });
4263   4263  
4264 ScriptSleep(1000); 4264 ScriptSleep(1000);
4265 return tid.ToString(); 4265 return tid.ToString();
4266 } 4266 }
4267 } 4267 }
4268   4268  
4269 ScriptSleep(1000); 4269 ScriptSleep(1000);
4270 return String.Empty; 4270 return String.Empty;
4271 } 4271 }
4272   4272  
4273 public void llSetDamage(double damage) 4273 public void llSetDamage(double damage)
4274 { 4274 {
4275 m_host.AddScriptLPS(1); 4275 m_host.AddScriptLPS(1);
4276 m_host.ParentGroup.Damage = (float)damage; 4276 m_host.ParentGroup.Damage = (float)damage;
4277 } 4277 }
4278   4278  
4279 public void llTeleportAgentHome(string agent) 4279 public void llTeleportAgentHome(string agent)
4280 { 4280 {
4281 m_host.AddScriptLPS(1); 4281 m_host.AddScriptLPS(1);
4282 UUID agentId = new UUID(); 4282 UUID agentId = new UUID();
4283 if (UUID.TryParse(agent, out agentId)) 4283 if (UUID.TryParse(agent, out agentId))
4284 { 4284 {
4285 ScenePresence presence = World.GetScenePresence(agentId); 4285 ScenePresence presence = World.GetScenePresence(agentId);
4286 if (presence != null) 4286 if (presence != null)
4287 { 4287 {
4288 // agent must be over the owners land 4288 // agent must be over the owners land
4289 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4289 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4290 { 4290 {
4291 World.TeleportClientHome(agentId, presence.ControllingClient); 4291 World.TeleportClientHome(agentId, presence.ControllingClient);
4292 } 4292 }
4293 } 4293 }
4294 } 4294 }
4295   4295  
4296 ScriptSleep(5000); 4296 ScriptSleep(5000);
4297 } 4297 }
4298   4298  
4299 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt) 4299 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4300 { 4300 {
4301 m_host.AddScriptLPS(1); 4301 m_host.AddScriptLPS(1);
4302 UUID agentId = new UUID(); 4302 UUID agentId = new UUID();
4303   4303  
4304 if (UUID.TryParse(agent, out agentId)) 4304 if (UUID.TryParse(agent, out agentId))
4305 { 4305 {
4306 ScenePresence presence = World.GetScenePresence(agentId); 4306 ScenePresence presence = World.GetScenePresence(agentId);
4307 if (presence != null && presence.PresenceType != PresenceType.Npc) 4307 if (presence != null && presence.PresenceType != PresenceType.Npc)
4308 { 4308 {
4309 // agent must not be a god 4309 // agent must not be a god
4310 if (presence.GodLevel >= 200) return; 4310 if (presence.GodLevel >= 200) return;
4311   4311  
4312 if (destination == String.Empty) 4312 if (destination == String.Empty)
4313 destination = World.RegionInfo.RegionName; 4313 destination = World.RegionInfo.RegionName;
4314   4314  
4315 // agent must be over the owners land 4315 // agent must be over the owners land
4316 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4316 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4317 { 4317 {
4318 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4318 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4319 } 4319 }
4320 else // or must be wearing the prim 4320 else // or must be wearing the prim
4321 { 4321 {
4322 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4322 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4323 { 4323 {
4324 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4324 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4325 } 4325 }
4326 } 4326 }
4327 } 4327 }
4328 } 4328 }
4329 } 4329 }
4330   4330  
4331 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt) 4331 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4332 { 4332 {
4333 m_host.AddScriptLPS(1); 4333 m_host.AddScriptLPS(1);
4334 UUID agentId = new UUID(); 4334 UUID agentId = new UUID();
4335   4335  
4336 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4336 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
4337   4337  
4338 if (UUID.TryParse(agent, out agentId)) 4338 if (UUID.TryParse(agent, out agentId))
4339 { 4339 {
4340 ScenePresence presence = World.GetScenePresence(agentId); 4340 ScenePresence presence = World.GetScenePresence(agentId);
4341 if (presence != null && presence.PresenceType != PresenceType.Npc) 4341 if (presence != null && presence.PresenceType != PresenceType.Npc)
4342 { 4342 {
4343 // agent must not be a god 4343 // agent must not be a god
4344 if (presence.GodLevel >= 200) return; 4344 if (presence.GodLevel >= 200) return;
4345   4345  
4346 // agent must be over the owners land 4346 // agent must be over the owners land
4347 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4347 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4348 { 4348 {
4349 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4349 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4350 } 4350 }
4351 else // or must be wearing the prim 4351 else // or must be wearing the prim
4352 { 4352 {
4353 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4353 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4354 { 4354 {
4355 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4355 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4356 } 4356 }
4357 } 4357 }
4358 } 4358 }
4359 } 4359 }
4360 } 4360 }
4361   4361  
4362 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) 4362 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt)
4363 { 4363 {
4364 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination); 4364 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination);
4365   4365  
4366 // The destinaion is not an asset ID and also doesn't name a landmark. 4366 // The destinaion is not an asset ID and also doesn't name a landmark.
4367 // Use it as a sim name 4367 // Use it as a sim name
4368 if (assetID == UUID.Zero) 4368 if (assetID == UUID.Zero)
4369 { 4369 {
4370 World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4370 World.RequestTeleportLocation(sp.ControllingClient, destination, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4371 return; 4371 return;
4372 } 4372 }
4373   4373  
4374 AssetBase lma = World.AssetService.Get(assetID.ToString()); 4374 AssetBase lma = World.AssetService.Get(assetID.ToString());
4375 if (lma == null) 4375 if (lma == null)
4376 return; 4376 return;
4377   4377  
4378 if (lma.Type != (sbyte)AssetType.Landmark) 4378 if (lma.Type != (sbyte)AssetType.Landmark)
4379 return; 4379 return;
4380   4380  
4381 AssetLandmark lm = new AssetLandmark(lma); 4381 AssetLandmark lm = new AssetLandmark(lma);
4382   4382  
4383 World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4383 World.RequestTeleportLocation(sp.ControllingClient, lm.RegionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4384 } 4384 }
4385   4385  
4386 public void llTextBox(string agent, string message, int chatChannel) 4386 public void llTextBox(string agent, string message, int chatChannel)
4387 { 4387 {
4388 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4388 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
4389   4389  
4390 if (dm == null) 4390 if (dm == null)
4391 return; 4391 return;
4392   4392  
4393 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
4394 UUID av = new UUID(); 4394 UUID av = new UUID();
4395 if (!UUID.TryParse(agent,out av)) 4395 if (!UUID.TryParse(agent,out av))
4396 { 4396 {
4397 LSLError("First parameter to llDialog needs to be a key"); 4397 LSLError("First parameter to llDialog needs to be a key");
4398 return; 4398 return;
4399 } 4399 }
4400   4400  
4401 if (message == string.Empty) 4401 if (message == string.Empty)
4402 { 4402 {
4403 ShoutError("Trying to use llTextBox with empty message."); 4403 ShoutError("Trying to use llTextBox with empty message.");
4404 } 4404 }
4405 else if (message.Length > 512) 4405 else if (message.Length > 512)
4406 { 4406 {
4407 ShoutError("Trying to use llTextBox with message over 512 characters."); 4407 ShoutError("Trying to use llTextBox with message over 512 characters.");
4408 } 4408 }
4409 else 4409 else
4410 { 4410 {
4411 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID); 4411 dm.SendTextBoxToUser(av, message, chatChannel, m_host.Name, m_host.UUID, m_host.OwnerID);
4412 ScriptSleep(1000); 4412 ScriptSleep(1000);
4413 } 4413 }
4414 } 4414 }
4415   4415  
4416 public void llModifyLand(int action, int brush) 4416 public void llModifyLand(int action, int brush)
4417 { 4417 {
4418 m_host.AddScriptLPS(1); 4418 m_host.AddScriptLPS(1);
4419 ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>(); 4419 ITerrainModule tm = m_ScriptEngine.World.RequestModuleInterface<ITerrainModule>();
4420 if (tm != null) 4420 if (tm != null)
4421 { 4421 {
4422 tm.ModifyTerrain(m_host.OwnerID, m_host.AbsolutePosition, (byte) brush, (byte) action, m_host.OwnerID); 4422 tm.ModifyTerrain(m_host.OwnerID, m_host.AbsolutePosition, (byte) brush, (byte) action, m_host.OwnerID);
4423 } 4423 }
4424 } 4424 }
4425   4425  
4426 public void llCollisionSound(string impact_sound, double impact_volume) 4426 public void llCollisionSound(string impact_sound, double impact_volume)
4427 { 4427 {
4428 m_host.AddScriptLPS(1); 4428 m_host.AddScriptLPS(1);
4429   4429  
4430 // TODO: Parameter check logic required. 4430 // TODO: Parameter check logic required.
4431 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4431 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4432 m_host.CollisionSoundVolume = (float)impact_volume; 4432 m_host.CollisionSoundVolume = (float)impact_volume;
4433 } 4433 }
4434   4434  
4435 public LSL_String llGetAnimation(string id) 4435 public LSL_String llGetAnimation(string id)
4436 { 4436 {
4437 // This should only return a value if the avatar is in the same region 4437 // This should only return a value if the avatar is in the same region
4438 m_host.AddScriptLPS(1); 4438 m_host.AddScriptLPS(1);
4439 UUID avatar = (UUID)id; 4439 UUID avatar = (UUID)id;
4440 ScenePresence presence = World.GetScenePresence(avatar); 4440 ScenePresence presence = World.GetScenePresence(avatar);
4441 if (presence == null) 4441 if (presence == null)
4442 return ""; 4442 return "";
4443   4443  
4444 if (m_host.RegionHandle == presence.RegionHandle) 4444 if (m_host.RegionHandle == presence.RegionHandle)
4445 { 4445 {
4446 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames; 4446 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4447   4447  
4448 if (presence != null) 4448 if (presence != null)
4449 { 4449 {
4450 AnimationSet currentAnims = presence.Animator.Animations; 4450 AnimationSet currentAnims = presence.Animator.Animations;
4451 string currentAnimationState = String.Empty; 4451 string currentAnimationState = String.Empty;
4452 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4452 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState))
4453 return currentAnimationState; 4453 return currentAnimationState;
4454 } 4454 }
4455 } 4455 }
4456   4456  
4457 return String.Empty; 4457 return String.Empty;
4458 } 4458 }
4459   4459  
4460 public void llMessageLinked(int linknumber, int num, string msg, string id) 4460 public void llMessageLinked(int linknumber, int num, string msg, string id)
4461 { 4461 {
4462 m_host.AddScriptLPS(1); 4462 m_host.AddScriptLPS(1);
4463   4463  
4464 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4464 List<SceneObjectPart> parts = GetLinkParts(linknumber);
4465   4465  
4466 UUID partItemID; 4466 UUID partItemID;
4467 foreach (SceneObjectPart part in parts) 4467 foreach (SceneObjectPart part in parts)
4468 { 4468 {
4469 foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems()) 4469 foreach (TaskInventoryItem item in part.Inventory.GetInventoryItems())
4470 { 4470 {
4471 if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT) 4471 if (item.Type == ScriptBaseClass.INVENTORY_SCRIPT)
4472 { 4472 {
4473 partItemID = item.ItemID; 4473 partItemID = item.ItemID;
4474 int linkNumber = m_host.LinkNum; 4474 int linkNumber = m_host.LinkNum;
4475 if (m_host.ParentGroup.PrimCount == 1) 4475 if (m_host.ParentGroup.PrimCount == 1)
4476 linkNumber = 0; 4476 linkNumber = 0;
4477   4477  
4478 object[] resobj = new object[] 4478 object[] resobj = new object[]
4479 { 4479 {
4480 new LSL_Integer(linkNumber), new LSL_Integer(num), new LSL_String(msg), new LSL_String(id) 4480 new LSL_Integer(linkNumber), new LSL_Integer(num), new LSL_String(msg), new LSL_String(id)
4481 }; 4481 };
4482   4482  
4483 m_ScriptEngine.PostScriptEvent(partItemID, 4483 m_ScriptEngine.PostScriptEvent(partItemID,
4484 new EventParams("link_message", 4484 new EventParams("link_message",
4485 resobj, new DetectParams[0])); 4485 resobj, new DetectParams[0]));
4486 } 4486 }
4487 } 4487 }
4488 } 4488 }
4489 } 4489 }
4490   4490  
4491 public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local) 4491 public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
4492 { 4492 {
4493 m_host.AddScriptLPS(1); 4493 m_host.AddScriptLPS(1);
4494 bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing; 4494 bool pushrestricted = World.RegionInfo.RegionSettings.RestrictPushing;
4495 bool pushAllowed = false; 4495 bool pushAllowed = false;
4496   4496  
4497 bool pusheeIsAvatar = false; 4497 bool pusheeIsAvatar = false;
4498 UUID targetID = UUID.Zero; 4498 UUID targetID = UUID.Zero;
4499   4499  
4500 if (!UUID.TryParse(target,out targetID)) 4500 if (!UUID.TryParse(target,out targetID))
4501 return; 4501 return;
4502   4502  
4503 ScenePresence pusheeav = null; 4503 ScenePresence pusheeav = null;
4504 Vector3 PusheePos = Vector3.Zero; 4504 Vector3 PusheePos = Vector3.Zero;
4505 SceneObjectPart pusheeob = null; 4505 SceneObjectPart pusheeob = null;
4506   4506  
4507 ScenePresence avatar = World.GetScenePresence(targetID); 4507 ScenePresence avatar = World.GetScenePresence(targetID);
4508 if (avatar != null) 4508 if (avatar != null)
4509 { 4509 {
4510 pusheeIsAvatar = true; 4510 pusheeIsAvatar = true;
4511   4511  
4512 // Pushee doesn't have a physics actor 4512 // Pushee doesn't have a physics actor
4513 if (avatar.PhysicsActor == null) 4513 if (avatar.PhysicsActor == null)
4514 return; 4514 return;
4515   4515  
4516 // Pushee is in GodMode this pushing object isn't owned by them 4516 // Pushee is in GodMode this pushing object isn't owned by them
4517 if (avatar.GodLevel > 0 && m_host.OwnerID != targetID) 4517 if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
4518 return; 4518 return;
4519   4519  
4520 pusheeav = avatar; 4520 pusheeav = avatar;
4521   4521  
4522 // Find pushee position 4522 // Find pushee position
4523 // Pushee Linked? 4523 // Pushee Linked?
4524 SceneObjectPart sitPart = pusheeav.ParentPart; 4524 SceneObjectPart sitPart = pusheeav.ParentPart;
4525 if (sitPart != null) 4525 if (sitPart != null)
4526 PusheePos = sitPart.AbsolutePosition; 4526 PusheePos = sitPart.AbsolutePosition;
4527 else 4527 else
4528 PusheePos = pusheeav.AbsolutePosition; 4528 PusheePos = pusheeav.AbsolutePosition;
4529 } 4529 }
4530   4530  
4531 if (!pusheeIsAvatar) 4531 if (!pusheeIsAvatar)
4532 { 4532 {
4533 // not an avatar so push is not affected by parcel flags 4533 // not an avatar so push is not affected by parcel flags
4534 pusheeob = World.GetSceneObjectPart((UUID)target); 4534 pusheeob = World.GetSceneObjectPart((UUID)target);
4535   4535  
4536 // We can't find object 4536 // We can't find object
4537 if (pusheeob == null) 4537 if (pusheeob == null)
4538 return; 4538 return;
4539   4539  
4540 // Object not pushable. Not an attachment and has no physics component 4540 // Object not pushable. Not an attachment and has no physics component
4541 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null) 4541 if (!pusheeob.ParentGroup.IsAttachment && pusheeob.PhysActor == null)
4542 return; 4542 return;
4543   4543  
4544 PusheePos = pusheeob.AbsolutePosition; 4544 PusheePos = pusheeob.AbsolutePosition;
4545 pushAllowed = true; 4545 pushAllowed = true;
4546 } 4546 }
4547 else 4547 else
4548 { 4548 {
4549 if (pushrestricted) 4549 if (pushrestricted)
4550 { 4550 {
4551 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); 4551 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4552   4552  
4553 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4553 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4554 if (targetlandObj == null) 4554 if (targetlandObj == null)
4555 return; 4555 return;
4556   4556  
4557 // Need provisions for Group Owned here 4557 // Need provisions for Group Owned here
4558 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4558 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4559 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID) 4559 targetlandObj.LandData.IsGroupOwned || m_host.OwnerID == targetID)
4560 { 4560 {
4561 pushAllowed = true; 4561 pushAllowed = true;
4562 } 4562 }
4563 } 4563 }
4564 else 4564 else
4565 { 4565 {
4566 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos); 4566 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4567 if (targetlandObj == null) 4567 if (targetlandObj == null)
4568 { 4568 {
4569 // We didn't find the parcel but region isn't push restricted so assume it's ok 4569 // We didn't find the parcel but region isn't push restricted so assume it's ok
4570 pushAllowed = true; 4570 pushAllowed = true;
4571 } 4571 }
4572 else 4572 else
4573 { 4573 {
4574 // Parcel push restriction 4574 // Parcel push restriction
4575 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject) 4575 if ((targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)
4576 { 4576 {
4577 // Need provisions for Group Owned here 4577 // Need provisions for Group Owned here
4578 if (m_host.OwnerID == targetlandObj.LandData.OwnerID || 4578 if (m_host.OwnerID == targetlandObj.LandData.OwnerID ||
4579 targetlandObj.LandData.IsGroupOwned || 4579 targetlandObj.LandData.IsGroupOwned ||
4580 m_host.OwnerID == targetID) 4580 m_host.OwnerID == targetID)
4581 { 4581 {
4582 pushAllowed = true; 4582 pushAllowed = true;
4583 } 4583 }
4584   4584  
4585 //ParcelFlags.RestrictPushObject 4585 //ParcelFlags.RestrictPushObject
4586 //pushAllowed = true; 4586 //pushAllowed = true;
4587 } 4587 }
4588 else 4588 else
4589 { 4589 {
4590 // Parcel isn't push restricted 4590 // Parcel isn't push restricted
4591 pushAllowed = true; 4591 pushAllowed = true;
4592 } 4592 }
4593 } 4593 }
4594 } 4594 }
4595 } 4595 }
4596   4596  
4597 if (pushAllowed) 4597 if (pushAllowed)
4598 { 4598 {
4599 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4599 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4600 float distance_term = distance * distance * distance; // Script Energy 4600 float distance_term = distance * distance * distance; // Script Energy
4601 float pusher_mass = m_host.GetMass(); 4601 float pusher_mass = m_host.GetMass();
4602   4602  
4603 float PUSH_ATTENUATION_DISTANCE = 17f; 4603 float PUSH_ATTENUATION_DISTANCE = 17f;
4604 float PUSH_ATTENUATION_SCALE = 5f; 4604 float PUSH_ATTENUATION_SCALE = 5f;
4605 float distance_attenuation = 1f; 4605 float distance_attenuation = 1f;
4606 if (distance > PUSH_ATTENUATION_DISTANCE) 4606 if (distance > PUSH_ATTENUATION_DISTANCE)
4607 { 4607 {
4608 float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE; 4608 float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE;
4609 distance_attenuation = 1f / normalized_units; 4609 distance_attenuation = 1f / normalized_units;
4610 } 4610 }
4611   4611  
4612 Vector3 applied_linear_impulse = impulse; 4612 Vector3 applied_linear_impulse = impulse;
4613 { 4613 {
4614 float impulse_length = applied_linear_impulse.Length(); 4614 float impulse_length = applied_linear_impulse.Length();
4615   4615  
4616 float desired_energy = impulse_length * pusher_mass; 4616 float desired_energy = impulse_length * pusher_mass;
4617 if (desired_energy > 0f) 4617 if (desired_energy > 0f)
4618 desired_energy += distance_term; 4618 desired_energy += distance_term;
4619   4619  
4620 float scaling_factor = 1f; 4620 float scaling_factor = 1f;
4621 scaling_factor *= distance_attenuation; 4621 scaling_factor *= distance_attenuation;
4622 applied_linear_impulse *= scaling_factor; 4622 applied_linear_impulse *= scaling_factor;
4623   4623  
4624 } 4624 }
4625   4625  
4626 if (pusheeIsAvatar) 4626 if (pusheeIsAvatar)
4627 { 4627 {
4628 if (pusheeav != null) 4628 if (pusheeav != null)
4629 { 4629 {
4630 PhysicsActor pa = pusheeav.PhysicsActor; 4630 PhysicsActor pa = pusheeav.PhysicsActor;
4631   4631  
4632 if (pa != null) 4632 if (pa != null)
4633 { 4633 {
4634 if (local != 0) 4634 if (local != 0)
4635 { 4635 {
4636 applied_linear_impulse *= m_host.GetWorldRotation(); 4636 applied_linear_impulse *= m_host.GetWorldRotation();
4637 } 4637 }
4638   4638  
4639 pa.AddForce(applied_linear_impulse, true); 4639 pa.AddForce(applied_linear_impulse, true);
4640 } 4640 }
4641 } 4641 }
4642 } 4642 }
4643 else 4643 else
4644 { 4644 {
4645 if (pusheeob != null) 4645 if (pusheeob != null)
4646 { 4646 {
4647 if (pusheeob.PhysActor != null) 4647 if (pusheeob.PhysActor != null)
4648 { 4648 {
4649 pusheeob.ApplyImpulse(applied_linear_impulse, local != 0); 4649 pusheeob.ApplyImpulse(applied_linear_impulse, local != 0);
4650 } 4650 }
4651 } 4651 }
4652 } 4652 }
4653 } 4653 }
4654 } 4654 }
4655   4655  
4656 public void llPassCollisions(int pass) 4656 public void llPassCollisions(int pass)
4657 { 4657 {
4658 m_host.AddScriptLPS(1); 4658 m_host.AddScriptLPS(1);
4659 if (pass == 0) 4659 if (pass == 0)
4660 { 4660 {
4661 m_host.PassCollisions = false; 4661 m_host.PassCollisions = false;
4662 } 4662 }
4663 else 4663 else
4664 { 4664 {
4665 m_host.PassCollisions = true; 4665 m_host.PassCollisions = true;
4666 } 4666 }
4667 } 4667 }
4668   4668  
4669 public LSL_String llGetScriptName() 4669 public LSL_String llGetScriptName()
4670 { 4670 {
4671 m_host.AddScriptLPS(1); 4671 m_host.AddScriptLPS(1);
4672   4672  
4673 return m_item.Name != null ? m_item.Name : String.Empty; 4673 return m_item.Name != null ? m_item.Name : String.Empty;
4674 } 4674 }
4675   4675  
4676 public LSL_Integer llGetLinkNumberOfSides(int link) 4676 public LSL_Integer llGetLinkNumberOfSides(int link)
4677 { 4677 {
4678 m_host.AddScriptLPS(1); 4678 m_host.AddScriptLPS(1);
4679   4679  
4680 SceneObjectPart linkedPart; 4680 SceneObjectPart linkedPart;
4681   4681  
4682 if (link == ScriptBaseClass.LINK_ROOT) 4682 if (link == ScriptBaseClass.LINK_ROOT)
4683 linkedPart = m_host.ParentGroup.RootPart; 4683 linkedPart = m_host.ParentGroup.RootPart;
4684 else if (link == ScriptBaseClass.LINK_THIS) 4684 else if (link == ScriptBaseClass.LINK_THIS)
4685 linkedPart = m_host; 4685 linkedPart = m_host;
4686 else 4686 else
4687 linkedPart = m_host.ParentGroup.GetLinkNumPart(link); 4687 linkedPart = m_host.ParentGroup.GetLinkNumPart(link);
4688   4688  
4689 return GetNumberOfSides(linkedPart); 4689 return GetNumberOfSides(linkedPart);
4690 } 4690 }
4691   4691  
4692 public LSL_Integer llGetNumberOfSides() 4692 public LSL_Integer llGetNumberOfSides()
4693 { 4693 {
4694 m_host.AddScriptLPS(1); 4694 m_host.AddScriptLPS(1);
4695   4695  
4696 return GetNumberOfSides(m_host); 4696 return GetNumberOfSides(m_host);
4697 } 4697 }
4698   4698  
4699 protected int GetNumberOfSides(SceneObjectPart part) 4699 protected int GetNumberOfSides(SceneObjectPart part)
4700 { 4700 {
4701 int sides = part.GetNumberOfSides(); 4701 int sides = part.GetNumberOfSides();
4702   4702  
4703 if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0) 4703 if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
4704 { 4704 {
4705 // Make up for a bug where LSL shows 4 sides rather than 2 4705 // Make up for a bug where LSL shows 4 sides rather than 2
4706 sides += 2; 4706 sides += 2;
4707 } 4707 }
4708   4708  
4709 return sides; 4709 return sides;
4710 } 4710 }
4711   4711  
4712   4712  
4713 /* The new / changed functions were tested with the following LSL script: 4713 /* The new / changed functions were tested with the following LSL script:
4714   4714  
4715 default 4715 default
4716 { 4716 {
4717 state_entry() 4717 state_entry()
4718 { 4718 {
4719 rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD); 4719 rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD);
4720   4720  
4721 llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot)); 4721 llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot));
4722 llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG)); 4722 llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG));
4723   4723  
4724 // convert back and forth between quaternion <-> vector and angle 4724 // convert back and forth between quaternion <-> vector and angle
4725   4725  
4726 rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot)); 4726 rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot));
4727   4727  
4728 llOwnerSay("Old rotation was: "+(string) rot); 4728 llOwnerSay("Old rotation was: "+(string) rot);
4729 llOwnerSay("re-converted rotation is: "+(string) newrot); 4729 llOwnerSay("re-converted rotation is: "+(string) newrot);
4730   4730  
4731 llSetRot(rot); // to check the parameters in the prim 4731 llSetRot(rot); // to check the parameters in the prim
4732 } 4732 }
4733 } 4733 }
4734 */ 4734 */
4735   4735  
4736 // Xantor 29/apr/2008 4736 // Xantor 29/apr/2008
4737 // Returns rotation described by rotating angle radians about axis. 4737 // Returns rotation described by rotating angle radians about axis.
4738 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2)) 4738 // q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
4739 public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle) 4739 public LSL_Rotation llAxisAngle2Rot(LSL_Vector axis, double angle)
4740 { 4740 {
4741 m_host.AddScriptLPS(1); 4741 m_host.AddScriptLPS(1);
4742   4742  
4743 double x, y, z, s, t; 4743 double x, y, z, s, t;
4744   4744  
4745 s = Math.Cos(angle * 0.5); 4745 s = Math.Cos(angle * 0.5);
4746 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs 4746 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs
4747 axis = LSL_Vector.Norm(axis); 4747 axis = LSL_Vector.Norm(axis);
4748 x = axis.x * t; 4748 x = axis.x * t;
4749 y = axis.y * t; 4749 y = axis.y * t;
4750 z = axis.z * t; 4750 z = axis.z * t;
4751   4751  
4752 return new LSL_Rotation(x,y,z,s); 4752 return new LSL_Rotation(x,y,z,s);
4753 } 4753 }
4754   4754  
4755 /// <summary> 4755 /// <summary>
4756 /// Returns the axis of rotation for a quaternion 4756 /// Returns the axis of rotation for a quaternion
4757 /// </summary> 4757 /// </summary>
4758 /// <returns></returns> 4758 /// <returns></returns>
4759 /// <param name='rot'></param> 4759 /// <param name='rot'></param>
4760 public LSL_Vector llRot2Axis(LSL_Rotation rot) 4760 public LSL_Vector llRot2Axis(LSL_Rotation rot)
4761 { 4761 {
4762 m_host.AddScriptLPS(1); 4762 m_host.AddScriptLPS(1);
4763   4763  
4764 if (Math.Abs(rot.s) > 1) // normalization needed 4764 if (Math.Abs(rot.s) > 1) // normalization needed
4765 rot.Normalize(); 4765 rot.Normalize();
4766   4766  
4767 double s = Math.Sqrt(1 - rot.s * rot.s); 4767 double s = Math.Sqrt(1 - rot.s * rot.s);
4768 if (s < 0.001) 4768 if (s < 0.001)
4769 { 4769 {
4770 return new LSL_Vector(1, 0, 0); 4770 return new LSL_Vector(1, 0, 0);
4771 } 4771 }
4772 else 4772 else
4773 { 4773 {
4774 double invS = 1.0 / s; 4774 double invS = 1.0 / s;
4775 if (rot.s < 0) invS = -invS; 4775 if (rot.s < 0) invS = -invS;
4776 return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); 4776 return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS);
4777 } 4777 }
4778 } 4778 }
4779   4779  
4780   4780  
4781 // Returns the angle of a quaternion (see llRot2Axis for the axis) 4781 // Returns the angle of a quaternion (see llRot2Axis for the axis)
4782 public LSL_Float llRot2Angle(LSL_Rotation rot) 4782 public LSL_Float llRot2Angle(LSL_Rotation rot)
4783 { 4783 {
4784 m_host.AddScriptLPS(1); 4784 m_host.AddScriptLPS(1);
4785   4785  
4786 if (Math.Abs(rot.s) > 1) // normalization needed 4786 if (Math.Abs(rot.s) > 1) // normalization needed
4787 rot.Normalize(); 4787 rot.Normalize();
4788   4788  
4789 double angle = 2 * Math.Acos(rot.s); 4789 double angle = 2 * Math.Acos(rot.s);
4790 if (angle > Math.PI) 4790 if (angle > Math.PI)
4791 angle = 2 * Math.PI - angle; 4791 angle = 2 * Math.PI - angle;
4792   4792  
4793 return angle; 4793 return angle;
4794 } 4794 }
4795   4795  
4796 public LSL_Float llAcos(double val) 4796 public LSL_Float llAcos(double val)
4797 { 4797 {
4798 m_host.AddScriptLPS(1); 4798 m_host.AddScriptLPS(1);
4799 return (double)Math.Acos(val); 4799 return (double)Math.Acos(val);
4800 } 4800 }
4801   4801  
4802 public LSL_Float llAsin(double val) 4802 public LSL_Float llAsin(double val)
4803 { 4803 {
4804 m_host.AddScriptLPS(1); 4804 m_host.AddScriptLPS(1);
4805 return (double)Math.Asin(val); 4805 return (double)Math.Asin(val);
4806 } 4806 }
4807   4807  
4808 // jcochran 5/jan/2012 4808 // jcochran 5/jan/2012
4809 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) 4809 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
4810 { 4810 {
4811 m_host.AddScriptLPS(1); 4811 m_host.AddScriptLPS(1);
4812   4812  
4813 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s); 4813 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
4814 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s); 4814 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
4815 double aa_bb = aa * bb; 4815 double aa_bb = aa * bb;
4816 if (aa_bb == 0) return 0.0; 4816 if (aa_bb == 0) return 0.0;
4817 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s); 4817 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
4818 double quotient = (ab * ab) / aa_bb; 4818 double quotient = (ab * ab) / aa_bb;
4819 if (quotient >= 1.0) return 0.0; 4819 if (quotient >= 1.0) return 0.0;
4820 return Math.Acos(2 * quotient - 1); 4820 return Math.Acos(2 * quotient - 1);
4821 } 4821 }
4822   4822  
4823 public LSL_String llGetInventoryKey(string name) 4823 public LSL_String llGetInventoryKey(string name)
4824 { 4824 {
4825 m_host.AddScriptLPS(1); 4825 m_host.AddScriptLPS(1);
4826   4826  
4827 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 4827 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
4828   4828  
4829 if (item == null) 4829 if (item == null)
4830 return UUID.Zero.ToString(); 4830 return UUID.Zero.ToString();
4831   4831  
4832 if ((item.CurrentPermissions 4832 if ((item.CurrentPermissions
4833 & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4833 & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4834 == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4834 == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4835 { 4835 {
4836 return item.AssetID.ToString(); 4836 return item.AssetID.ToString();
4837 } 4837 }
4838   4838  
4839 return UUID.Zero.ToString(); 4839 return UUID.Zero.ToString();
4840 } 4840 }
4841   4841  
4842 public void llAllowInventoryDrop(int add) 4842 public void llAllowInventoryDrop(int add)
4843 { 4843 {
4844 m_host.AddScriptLPS(1); 4844 m_host.AddScriptLPS(1);
4845   4845  
4846 if (add != 0) 4846 if (add != 0)
4847 m_host.ParentGroup.RootPart.AllowedDrop = true; 4847 m_host.ParentGroup.RootPart.AllowedDrop = true;
4848 else 4848 else
4849 m_host.ParentGroup.RootPart.AllowedDrop = false; 4849 m_host.ParentGroup.RootPart.AllowedDrop = false;
4850   4850  
4851 // Update the object flags 4851 // Update the object flags
4852 m_host.ParentGroup.RootPart.aggregateScriptEvents(); 4852 m_host.ParentGroup.RootPart.aggregateScriptEvents();
4853 } 4853 }
4854   4854  
4855 public LSL_Vector llGetSunDirection() 4855 public LSL_Vector llGetSunDirection()
4856 { 4856 {
4857 m_host.AddScriptLPS(1); 4857 m_host.AddScriptLPS(1);
4858   4858  
4859 LSL_Vector SunDoubleVector3; 4859 LSL_Vector SunDoubleVector3;
4860 Vector3 SunFloatVector3; 4860 Vector3 SunFloatVector3;
4861   4861  
4862 // sunPosition estate setting is set in OpenSim.Region.CoreModules.SunModule 4862 // sunPosition estate setting is set in OpenSim.Region.CoreModules.SunModule
4863 // have to convert from Vector3 (float) to LSL_Vector (double) 4863 // have to convert from Vector3 (float) to LSL_Vector (double)
4864 SunFloatVector3 = World.RegionInfo.RegionSettings.SunVector; 4864 SunFloatVector3 = World.RegionInfo.RegionSettings.SunVector;
4865 SunDoubleVector3.x = (double)SunFloatVector3.X; 4865 SunDoubleVector3.x = (double)SunFloatVector3.X;
4866 SunDoubleVector3.y = (double)SunFloatVector3.Y; 4866 SunDoubleVector3.y = (double)SunFloatVector3.Y;
4867 SunDoubleVector3.z = (double)SunFloatVector3.Z; 4867 SunDoubleVector3.z = (double)SunFloatVector3.Z;
4868   4868  
4869 return SunDoubleVector3; 4869 return SunDoubleVector3;
4870 } 4870 }
4871   4871  
4872 public LSL_Vector llGetTextureOffset(int face) 4872 public LSL_Vector llGetTextureOffset(int face)
4873 { 4873 {
4874 m_host.AddScriptLPS(1); 4874 m_host.AddScriptLPS(1);
4875 return GetTextureOffset(m_host, face); 4875 return GetTextureOffset(m_host, face);
4876 } 4876 }
4877   4877  
4878 protected LSL_Vector GetTextureOffset(SceneObjectPart part, int face) 4878 protected LSL_Vector GetTextureOffset(SceneObjectPart part, int face)
4879 { 4879 {
4880 Primitive.TextureEntry tex = part.Shape.Textures; 4880 Primitive.TextureEntry tex = part.Shape.Textures;
4881 LSL_Vector offset = new LSL_Vector(); 4881 LSL_Vector offset = new LSL_Vector();
4882 if (face == ScriptBaseClass.ALL_SIDES) 4882 if (face == ScriptBaseClass.ALL_SIDES)
4883 { 4883 {
4884 face = 0; 4884 face = 0;
4885 } 4885 }
4886 if (face >= 0 && face < GetNumberOfSides(part)) 4886 if (face >= 0 && face < GetNumberOfSides(part))
4887 { 4887 {
4888 offset.x = tex.GetFace((uint)face).OffsetU; 4888 offset.x = tex.GetFace((uint)face).OffsetU;
4889 offset.y = tex.GetFace((uint)face).OffsetV; 4889 offset.y = tex.GetFace((uint)face).OffsetV;
4890 offset.z = 0.0; 4890 offset.z = 0.0;
4891 return offset; 4891 return offset;
4892 } 4892 }
4893 else 4893 else
4894 { 4894 {
4895 return offset; 4895 return offset;
4896 } 4896 }
4897 } 4897 }
4898   4898  
4899 public LSL_Vector llGetTextureScale(int side) 4899 public LSL_Vector llGetTextureScale(int side)
4900 { 4900 {
4901 m_host.AddScriptLPS(1); 4901 m_host.AddScriptLPS(1);
4902 Primitive.TextureEntry tex = m_host.Shape.Textures; 4902 Primitive.TextureEntry tex = m_host.Shape.Textures;
4903 LSL_Vector scale; 4903 LSL_Vector scale;
4904 if (side == -1) 4904 if (side == -1)
4905 { 4905 {
4906 side = 0; 4906 side = 0;
4907 } 4907 }
4908 scale.x = tex.GetFace((uint)side).RepeatU; 4908 scale.x = tex.GetFace((uint)side).RepeatU;
4909 scale.y = tex.GetFace((uint)side).RepeatV; 4909 scale.y = tex.GetFace((uint)side).RepeatV;
4910 scale.z = 0.0; 4910 scale.z = 0.0;
4911 return scale; 4911 return scale;
4912 } 4912 }
4913   4913  
4914 public LSL_Float llGetTextureRot(int face) 4914 public LSL_Float llGetTextureRot(int face)
4915 { 4915 {
4916 m_host.AddScriptLPS(1); 4916 m_host.AddScriptLPS(1);
4917 return GetTextureRot(m_host, face); 4917 return GetTextureRot(m_host, face);
4918 } 4918 }
4919   4919  
4920 protected LSL_Float GetTextureRot(SceneObjectPart part, int face) 4920 protected LSL_Float GetTextureRot(SceneObjectPart part, int face)
4921 { 4921 {
4922 Primitive.TextureEntry tex = part.Shape.Textures; 4922 Primitive.TextureEntry tex = part.Shape.Textures;
4923 if (face == -1) 4923 if (face == -1)
4924 { 4924 {
4925 face = 0; 4925 face = 0;
4926 } 4926 }
4927 if (face >= 0 && face < GetNumberOfSides(part)) 4927 if (face >= 0 && face < GetNumberOfSides(part))
4928 { 4928 {
4929 return tex.GetFace((uint)face).Rotation; 4929 return tex.GetFace((uint)face).Rotation;
4930 } 4930 }
4931 else 4931 else
4932 { 4932 {
4933 return 0.0; 4933 return 0.0;
4934 } 4934 }
4935 } 4935 }
4936   4936  
4937 public LSL_Integer llSubStringIndex(string source, string pattern) 4937 public LSL_Integer llSubStringIndex(string source, string pattern)
4938 { 4938 {
4939 m_host.AddScriptLPS(1); 4939 m_host.AddScriptLPS(1);
4940 return source.IndexOf(pattern); 4940 return source.IndexOf(pattern);
4941 } 4941 }
4942   4942  
4943 public LSL_String llGetOwnerKey(string id) 4943 public LSL_String llGetOwnerKey(string id)
4944 { 4944 {
4945 m_host.AddScriptLPS(1); 4945 m_host.AddScriptLPS(1);
4946 UUID key = new UUID(); 4946 UUID key = new UUID();
4947 if (UUID.TryParse(id, out key)) 4947 if (UUID.TryParse(id, out key))
4948 { 4948 {
4949 try 4949 try
4950 { 4950 {
4951 SceneObjectPart obj = World.GetSceneObjectPart(key); 4951 SceneObjectPart obj = World.GetSceneObjectPart(key);
4952 if (obj == null) 4952 if (obj == null)
4953 return id; // the key is for an agent so just return the key 4953 return id; // the key is for an agent so just return the key
4954 else 4954 else
4955 return obj.OwnerID.ToString(); 4955 return obj.OwnerID.ToString();
4956 } 4956 }
4957 catch (KeyNotFoundException) 4957 catch (KeyNotFoundException)
4958 { 4958 {
4959 return id; // The Object/Agent not in the region so just return the key 4959 return id; // The Object/Agent not in the region so just return the key
4960 } 4960 }
4961 } 4961 }
4962 else 4962 else
4963 { 4963 {
4964 return UUID.Zero.ToString(); 4964 return UUID.Zero.ToString();
4965 } 4965 }
4966 } 4966 }
4967   4967  
4968 public LSL_Vector llGetCenterOfMass() 4968 public LSL_Vector llGetCenterOfMass()
4969 { 4969 {
4970 m_host.AddScriptLPS(1); 4970 m_host.AddScriptLPS(1);
4971   4971  
4972 return new LSL_Vector(m_host.GetCenterOfMass()); 4972 return new LSL_Vector(m_host.GetCenterOfMass());
4973 } 4973 }
4974   4974  
4975 public LSL_List llListSort(LSL_List src, int stride, int ascending) 4975 public LSL_List llListSort(LSL_List src, int stride, int ascending)
4976 { 4976 {
4977 m_host.AddScriptLPS(1); 4977 m_host.AddScriptLPS(1);
4978   4978  
4979 if (stride <= 0) 4979 if (stride <= 0)
4980 { 4980 {
4981 stride = 1; 4981 stride = 1;
4982 } 4982 }
4983 return src.Sort(stride, ascending); 4983 return src.Sort(stride, ascending);
4984 } 4984 }
4985   4985  
4986 public LSL_Integer llGetListLength(LSL_List src) 4986 public LSL_Integer llGetListLength(LSL_List src)
4987 { 4987 {
4988 m_host.AddScriptLPS(1); 4988 m_host.AddScriptLPS(1);
4989   4989  
4990 if (src == null) 4990 if (src == null)
4991 { 4991 {
4992 return 0; 4992 return 0;
4993 } 4993 }
4994 else 4994 else
4995 { 4995 {
4996 return src.Length; 4996 return src.Length;
4997 } 4997 }
4998 } 4998 }
4999   4999  
5000 public LSL_Integer llList2Integer(LSL_List src, int index) 5000 public LSL_Integer llList2Integer(LSL_List src, int index)
5001 { 5001 {
5002 m_host.AddScriptLPS(1); 5002 m_host.AddScriptLPS(1);
5003 if (index < 0) 5003 if (index < 0)
5004 { 5004 {
5005 index = src.Length + index; 5005 index = src.Length + index;
5006 } 5006 }
5007 if (index >= src.Length || index < 0) 5007 if (index >= src.Length || index < 0)
5008 { 5008 {
5009 return 0; 5009 return 0;
5010 } 5010 }
5011   5011  
5012 // Vectors & Rotations always return zero in SL, but 5012 // Vectors & Rotations always return zero in SL, but
5013 // keys don't always return zero, it seems to be a bit complex. 5013 // keys don't always return zero, it seems to be a bit complex.
5014 else if (src.Data[index] is LSL_Vector || 5014 else if (src.Data[index] is LSL_Vector ||
5015 src.Data[index] is LSL_Rotation) 5015 src.Data[index] is LSL_Rotation)
5016 { 5016 {
5017 return 0; 5017 return 0;
5018 } 5018 }
5019 try 5019 try
5020 { 5020 {
5021   5021  
5022 if (src.Data[index] is LSL_Integer) 5022 if (src.Data[index] is LSL_Integer)
5023 return (LSL_Integer)src.Data[index]; 5023 return (LSL_Integer)src.Data[index];
5024 else if (src.Data[index] is LSL_Float) 5024 else if (src.Data[index] is LSL_Float)
5025 return Convert.ToInt32(((LSL_Float)src.Data[index]).value); 5025 return Convert.ToInt32(((LSL_Float)src.Data[index]).value);
5026 return new LSL_Integer(src.Data[index].ToString()); 5026 return new LSL_Integer(src.Data[index].ToString());
5027 } 5027 }
5028 catch (FormatException) 5028 catch (FormatException)
5029 { 5029 {
5030 return 0; 5030 return 0;
5031 } 5031 }
5032 } 5032 }
5033   5033  
5034 public LSL_Float llList2Float(LSL_List src, int index) 5034 public LSL_Float llList2Float(LSL_List src, int index)
5035 { 5035 {
5036 m_host.AddScriptLPS(1); 5036 m_host.AddScriptLPS(1);
5037 if (index < 0) 5037 if (index < 0)
5038 { 5038 {
5039 index = src.Length + index; 5039 index = src.Length + index;
5040 } 5040 }
5041 if (index >= src.Length || index < 0) 5041 if (index >= src.Length || index < 0)
5042 { 5042 {
5043 return 0.0; 5043 return 0.0;
5044 } 5044 }
5045   5045  
5046 // Vectors & Rotations always return zero in SL 5046 // Vectors & Rotations always return zero in SL
5047 else if (src.Data[index] is LSL_Vector || 5047 else if (src.Data[index] is LSL_Vector ||
5048 src.Data[index] is LSL_Rotation) 5048 src.Data[index] is LSL_Rotation)
5049 { 5049 {
5050 return 0; 5050 return 0;
5051 } 5051 }
5052 // valid keys seem to get parsed as integers then converted to floats 5052 // valid keys seem to get parsed as integers then converted to floats
5053 else 5053 else
5054 { 5054 {
5055 UUID uuidt; 5055 UUID uuidt;
5056 if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) 5056 if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt))
5057 { 5057 {
5058 return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); 5058 return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value);
5059 } 5059 }
5060 } 5060 }
5061 try 5061 try
5062 { 5062 {
5063 if (src.Data[index] is LSL_Integer) 5063 if (src.Data[index] is LSL_Integer)
5064 return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); 5064 return Convert.ToDouble(((LSL_Integer)src.Data[index]).value);
5065 else if (src.Data[index] is LSL_Float) 5065 else if (src.Data[index] is LSL_Float)
5066 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5066 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5067 else if (src.Data[index] is LSL_String) 5067 else if (src.Data[index] is LSL_String)
5068 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5068 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string);
5069 return Convert.ToDouble(src.Data[index]); 5069 return Convert.ToDouble(src.Data[index]);
5070 } 5070 }
5071 catch (FormatException) 5071 catch (FormatException)
5072 { 5072 {
5073 return 0.0; 5073 return 0.0;
5074 } 5074 }
5075 } 5075 }
5076   5076  
5077 public LSL_String llList2String(LSL_List src, int index) 5077 public LSL_String llList2String(LSL_List src, int index)
5078 { 5078 {
5079 m_host.AddScriptLPS(1); 5079 m_host.AddScriptLPS(1);
5080 if (index < 0) 5080 if (index < 0)
5081 { 5081 {
5082 index = src.Length + index; 5082 index = src.Length + index;
5083 } 5083 }
5084 if (index >= src.Length || index < 0) 5084 if (index >= src.Length || index < 0)
5085 { 5085 {
5086 return String.Empty; 5086 return String.Empty;
5087 } 5087 }
5088 return src.Data[index].ToString(); 5088 return src.Data[index].ToString();
5089 } 5089 }
5090   5090  
5091 public LSL_Key llList2Key(LSL_List src, int index) 5091 public LSL_Key llList2Key(LSL_List src, int index)
5092 { 5092 {
5093 m_host.AddScriptLPS(1); 5093 m_host.AddScriptLPS(1);
5094 if (index < 0) 5094 if (index < 0)
5095 { 5095 {
5096 index = src.Length + index; 5096 index = src.Length + index;
5097 } 5097 }
5098   5098  
5099 if (index >= src.Length || index < 0) 5099 if (index >= src.Length || index < 0)
5100 { 5100 {
5101 return ""; 5101 return "";
5102 } 5102 }
5103   5103  
5104 // SL spits out an empty string for types other than key & string 5104 // SL spits out an empty string for types other than key & string
5105 // At the time of patching, LSL_Key is currently LSL_String, 5105 // At the time of patching, LSL_Key is currently LSL_String,
5106 // so the OR check may be a little redundant, but it's being done 5106 // so the OR check may be a little redundant, but it's being done
5107 // for completion and should LSL_Key ever be implemented 5107 // for completion and should LSL_Key ever be implemented
5108 // as it's own struct 5108 // as it's own struct
5109 else if (!(src.Data[index] is LSL_String || 5109 else if (!(src.Data[index] is LSL_String ||
5110 src.Data[index] is LSL_Key)) 5110 src.Data[index] is LSL_Key))
5111 { 5111 {
5112 return ""; 5112 return "";
5113 } 5113 }
5114   5114  
5115 return src.Data[index].ToString(); 5115 return src.Data[index].ToString();
5116 } 5116 }
5117   5117  
5118 public LSL_Vector llList2Vector(LSL_List src, int index) 5118 public LSL_Vector llList2Vector(LSL_List src, int index)
5119 { 5119 {
5120 m_host.AddScriptLPS(1); 5120 m_host.AddScriptLPS(1);
5121 if (index < 0) 5121 if (index < 0)
5122 { 5122 {
5123 index = src.Length + index; 5123 index = src.Length + index;
5124 } 5124 }
5125 if (index >= src.Length || index < 0) 5125 if (index >= src.Length || index < 0)
5126 { 5126 {
5127 return new LSL_Vector(0, 0, 0); 5127 return new LSL_Vector(0, 0, 0);
5128 } 5128 }
5129 if (src.Data[index].GetType() == typeof(LSL_Vector)) 5129 if (src.Data[index].GetType() == typeof(LSL_Vector))
5130 { 5130 {
5131 return (LSL_Vector)src.Data[index]; 5131 return (LSL_Vector)src.Data[index];
5132 } 5132 }
5133   5133  
5134 // SL spits always out ZERO_VECTOR for anything other than 5134 // SL spits always out ZERO_VECTOR for anything other than
5135 // strings or vectors. Although keys always return ZERO_VECTOR, 5135 // strings or vectors. Although keys always return ZERO_VECTOR,
5136 // it is currently difficult to make the distinction between 5136 // it is currently difficult to make the distinction between
5137 // a string, a key as string and a string that by coincidence 5137 // a string, a key as string and a string that by coincidence
5138 // is a string, so we're going to leave that up to the 5138 // is a string, so we're going to leave that up to the
5139 // LSL_Vector constructor. 5139 // LSL_Vector constructor.
5140 else if (!(src.Data[index] is LSL_String || 5140 else if (!(src.Data[index] is LSL_String ||
5141 src.Data[index] is LSL_Vector)) 5141 src.Data[index] is LSL_Vector))
5142 { 5142 {
5143 return new LSL_Vector(0, 0, 0); 5143 return new LSL_Vector(0, 0, 0);
5144 } 5144 }
5145 else 5145 else
5146 { 5146 {
5147 return new LSL_Vector(src.Data[index].ToString()); 5147 return new LSL_Vector(src.Data[index].ToString());
5148 } 5148 }
5149 } 5149 }
5150   5150  
5151 public LSL_Rotation llList2Rot(LSL_List src, int index) 5151 public LSL_Rotation llList2Rot(LSL_List src, int index)
5152 { 5152 {
5153 m_host.AddScriptLPS(1); 5153 m_host.AddScriptLPS(1);
5154 if (index < 0) 5154 if (index < 0)
5155 { 5155 {
5156 index = src.Length + index; 5156 index = src.Length + index;
5157 } 5157 }
5158 if (index >= src.Length || index < 0) 5158 if (index >= src.Length || index < 0)
5159 { 5159 {
5160 return new LSL_Rotation(0, 0, 0, 1); 5160 return new LSL_Rotation(0, 0, 0, 1);
5161 } 5161 }
5162   5162  
5163 // SL spits always out ZERO_ROTATION for anything other than 5163 // SL spits always out ZERO_ROTATION for anything other than
5164 // strings or vectors. Although keys always return ZERO_ROTATION, 5164 // strings or vectors. Although keys always return ZERO_ROTATION,
5165 // it is currently difficult to make the distinction between 5165 // it is currently difficult to make the distinction between
5166 // a string, a key as string and a string that by coincidence 5166 // a string, a key as string and a string that by coincidence
5167 // is a string, so we're going to leave that up to the 5167 // is a string, so we're going to leave that up to the
5168 // LSL_Rotation constructor. 5168 // LSL_Rotation constructor.
5169 else if (!(src.Data[index] is LSL_String || 5169 else if (!(src.Data[index] is LSL_String ||
5170 src.Data[index] is LSL_Rotation)) 5170 src.Data[index] is LSL_Rotation))
5171 { 5171 {
5172 return new LSL_Rotation(0, 0, 0, 1); 5172 return new LSL_Rotation(0, 0, 0, 1);
5173 } 5173 }
5174 else if (src.Data[index].GetType() == typeof(LSL_Rotation)) 5174 else if (src.Data[index].GetType() == typeof(LSL_Rotation))
5175 { 5175 {
5176 return (LSL_Rotation)src.Data[index]; 5176 return (LSL_Rotation)src.Data[index];
5177 } 5177 }
5178 else 5178 else
5179 { 5179 {
5180 return new LSL_Rotation(src.Data[index].ToString()); 5180 return new LSL_Rotation(src.Data[index].ToString());
5181 } 5181 }
5182 } 5182 }
5183   5183  
5184 public LSL_List llList2List(LSL_List src, int start, int end) 5184 public LSL_List llList2List(LSL_List src, int start, int end)
5185 { 5185 {
5186 m_host.AddScriptLPS(1); 5186 m_host.AddScriptLPS(1);
5187 return src.GetSublist(start, end); 5187 return src.GetSublist(start, end);
5188 } 5188 }
5189   5189  
5190 public LSL_List llDeleteSubList(LSL_List src, int start, int end) 5190 public LSL_List llDeleteSubList(LSL_List src, int start, int end)
5191 { 5191 {
5192 return src.DeleteSublist(start, end); 5192 return src.DeleteSublist(start, end);
5193 } 5193 }
5194   5194  
5195 public LSL_Integer llGetListEntryType(LSL_List src, int index) 5195 public LSL_Integer llGetListEntryType(LSL_List src, int index)
5196 { 5196 {
5197 m_host.AddScriptLPS(1); 5197 m_host.AddScriptLPS(1);
5198 if (index < 0) 5198 if (index < 0)
5199 { 5199 {
5200 index = src.Length + index; 5200 index = src.Length + index;
5201 } 5201 }
5202 if (index >= src.Length) 5202 if (index >= src.Length)
5203 { 5203 {
5204 return 0; 5204 return 0;
5205 } 5205 }
5206   5206  
5207 if (src.Data[index] is LSL_Integer || src.Data[index] is Int32) 5207 if (src.Data[index] is LSL_Integer || src.Data[index] is Int32)
5208 return 1; 5208 return 1;
5209 if (src.Data[index] is LSL_Float || src.Data[index] is Single || src.Data[index] is Double) 5209 if (src.Data[index] is LSL_Float || src.Data[index] is Single || src.Data[index] is Double)
5210 return 2; 5210 return 2;
5211 if (src.Data[index] is LSL_String || src.Data[index] is String) 5211 if (src.Data[index] is LSL_String || src.Data[index] is String)
5212 { 5212 {
5213 UUID tuuid; 5213 UUID tuuid;
5214 if (UUID.TryParse(src.Data[index].ToString(), out tuuid)) 5214 if (UUID.TryParse(src.Data[index].ToString(), out tuuid))
5215 { 5215 {
5216 return 4; 5216 return 4;
5217 } 5217 }
5218 else 5218 else
5219 { 5219 {
5220 return 3; 5220 return 3;
5221 } 5221 }
5222 } 5222 }
5223 if (src.Data[index] is LSL_Vector) 5223 if (src.Data[index] is LSL_Vector)
5224 return 5; 5224 return 5;
5225 if (src.Data[index] is LSL_Rotation) 5225 if (src.Data[index] is LSL_Rotation)
5226 return 6; 5226 return 6;
5227 if (src.Data[index] is LSL_List) 5227 if (src.Data[index] is LSL_List)
5228 return 7; 5228 return 7;
5229 return 0; 5229 return 0;
5230   5230  
5231 } 5231 }
5232   5232  
5233 /// <summary> 5233 /// <summary>
5234 /// Process the supplied list and return the 5234 /// Process the supplied list and return the
5235 /// content of the list formatted as a comma 5235 /// content of the list formatted as a comma
5236 /// separated list. There is a space after 5236 /// separated list. There is a space after
5237 /// each comma. 5237 /// each comma.
5238 /// </summary> 5238 /// </summary>
5239 public LSL_String llList2CSV(LSL_List src) 5239 public LSL_String llList2CSV(LSL_List src)
5240 { 5240 {
5241 m_host.AddScriptLPS(1); 5241 m_host.AddScriptLPS(1);
5242   5242  
5243 return string.Join(", ", 5243 return string.Join(", ",
5244 (new List<object>(src.Data)).ConvertAll<string>(o => 5244 (new List<object>(src.Data)).ConvertAll<string>(o =>
5245 { 5245 {
5246 return o.ToString(); 5246 return o.ToString();
5247 }).ToArray()); 5247 }).ToArray());
5248 } 5248 }
5249   5249  
5250 /// <summary> 5250 /// <summary>
5251 /// The supplied string is scanned for commas 5251 /// The supplied string is scanned for commas
5252 /// and converted into a list. Commas are only 5252 /// and converted into a list. Commas are only
5253 /// effective if they are encountered outside 5253 /// effective if they are encountered outside
5254 /// of '<' '>' delimiters. Any whitespace 5254 /// of '<' '>' delimiters. Any whitespace
5255 /// before or after an element is trimmed. 5255 /// before or after an element is trimmed.
5256 /// </summary> 5256 /// </summary>
5257   5257  
5258 public LSL_List llCSV2List(string src) 5258 public LSL_List llCSV2List(string src)
5259 { 5259 {
5260   5260  
5261 LSL_List result = new LSL_List(); 5261 LSL_List result = new LSL_List();
5262 int parens = 0; 5262 int parens = 0;
5263 int start = 0; 5263 int start = 0;
5264 int length = 0; 5264 int length = 0;
5265   5265  
5266 m_host.AddScriptLPS(1); 5266 m_host.AddScriptLPS(1);
5267   5267  
5268 for (int i = 0; i < src.Length; i++) 5268 for (int i = 0; i < src.Length; i++)
5269 { 5269 {
5270 switch (src[i]) 5270 switch (src[i])
5271 { 5271 {
5272 case '<': 5272 case '<':
5273 parens++; 5273 parens++;
5274 length++; 5274 length++;
5275 break; 5275 break;
5276 case '>': 5276 case '>':
5277 if (parens > 0) 5277 if (parens > 0)
5278 parens--; 5278 parens--;
5279 length++; 5279 length++;
5280 break; 5280 break;
5281 case ',': 5281 case ',':
5282 if (parens == 0) 5282 if (parens == 0)
5283 { 5283 {
5284 result.Add(new LSL_String(src.Substring(start,length).Trim())); 5284 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5285 start += length+1; 5285 start += length+1;
5286 length = 0; 5286 length = 0;
5287 } 5287 }
5288 else 5288 else
5289 { 5289 {
5290 length++; 5290 length++;
5291 } 5291 }
5292 break; 5292 break;
5293 default: 5293 default:
5294 length++; 5294 length++;
5295 break; 5295 break;
5296 } 5296 }
5297 } 5297 }
5298   5298  
5299 result.Add(new LSL_String(src.Substring(start,length).Trim())); 5299 result.Add(new LSL_String(src.Substring(start,length).Trim()));
5300   5300  
5301 return result; 5301 return result;
5302 } 5302 }
5303   5303  
5304 /// <summary> 5304 /// <summary>
5305 /// Randomizes the list, be arbitrarily reordering 5305 /// Randomizes the list, be arbitrarily reordering
5306 /// sublists of stride elements. As the stride approaches 5306 /// sublists of stride elements. As the stride approaches
5307 /// the size of the list, the options become very 5307 /// the size of the list, the options become very
5308 /// limited. 5308 /// limited.
5309 /// </summary> 5309 /// </summary>
5310 /// <remarks> 5310 /// <remarks>
5311 /// This could take a while for very large list 5311 /// This could take a while for very large list
5312 /// sizes. 5312 /// sizes.
5313 /// </remarks> 5313 /// </remarks>
5314   5314  
5315 public LSL_List llListRandomize(LSL_List src, int stride) 5315 public LSL_List llListRandomize(LSL_List src, int stride)
5316 { 5316 {
5317 LSL_List result; 5317 LSL_List result;
5318 Random rand = new Random(); 5318 Random rand = new Random();
5319   5319  
5320 int chunkk; 5320 int chunkk;
5321 int[] chunks; 5321 int[] chunks;
5322   5322  
5323 m_host.AddScriptLPS(1); 5323 m_host.AddScriptLPS(1);
5324   5324  
5325 if (stride <= 0) 5325 if (stride <= 0)
5326 { 5326 {
5327 stride = 1; 5327 stride = 1;
5328 } 5328 }
5329   5329  
5330 // Stride MUST be a factor of the list length 5330 // Stride MUST be a factor of the list length
5331 // If not, then return the src list. This also 5331 // If not, then return the src list. This also
5332 // traps those cases where stride > length. 5332 // traps those cases where stride > length.
5333   5333  
5334 if (src.Length != stride && src.Length%stride == 0) 5334 if (src.Length != stride && src.Length%stride == 0)
5335 { 5335 {
5336 chunkk = src.Length/stride; 5336 chunkk = src.Length/stride;
5337   5337  
5338 chunks = new int[chunkk]; 5338 chunks = new int[chunkk];
5339   5339  
5340 for (int i = 0; i < chunkk; i++) 5340 for (int i = 0; i < chunkk; i++)
5341 chunks[i] = i; 5341 chunks[i] = i;
5342   5342  
5343 // Knuth shuffle the chunkk index 5343 // Knuth shuffle the chunkk index
5344 for (int i = chunkk - 1; i >= 1; i--) 5344 for (int i = chunkk - 1; i >= 1; i--)
5345 { 5345 {
5346 // Elect an unrandomized chunk to swap 5346 // Elect an unrandomized chunk to swap
5347 int index = rand.Next(i + 1); 5347 int index = rand.Next(i + 1);
5348 int tmp; 5348 int tmp;
5349   5349  
5350 // and swap position with first unrandomized chunk 5350 // and swap position with first unrandomized chunk
5351 tmp = chunks[i]; 5351 tmp = chunks[i];
5352 chunks[i] = chunks[index]; 5352 chunks[i] = chunks[index];
5353 chunks[index] = tmp; 5353 chunks[index] = tmp;
5354 } 5354 }
5355   5355  
5356 // Construct the randomized list 5356 // Construct the randomized list
5357   5357  
5358 result = new LSL_List(); 5358 result = new LSL_List();
5359   5359  
5360 for (int i = 0; i < chunkk; i++) 5360 for (int i = 0; i < chunkk; i++)
5361 { 5361 {
5362 for (int j = 0; j < stride; j++) 5362 for (int j = 0; j < stride; j++)
5363 { 5363 {
5364 result.Add(src.Data[chunks[i]*stride+j]); 5364 result.Add(src.Data[chunks[i]*stride+j]);
5365 } 5365 }
5366 } 5366 }
5367 } 5367 }
5368 else { 5368 else {
5369 object[] array = new object[src.Length]; 5369 object[] array = new object[src.Length];
5370 Array.Copy(src.Data, 0, array, 0, src.Length); 5370 Array.Copy(src.Data, 0, array, 0, src.Length);
5371 result = new LSL_List(array); 5371 result = new LSL_List(array);
5372 } 5372 }
5373   5373  
5374 return result; 5374 return result;
5375 } 5375 }
5376   5376  
5377 /// <summary> 5377 /// <summary>
5378 /// Elements in the source list starting with 0 and then 5378 /// Elements in the source list starting with 0 and then
5379 /// every i+stride. If the stride is negative then the scan 5379 /// every i+stride. If the stride is negative then the scan
5380 /// is backwards producing an inverted result. 5380 /// is backwards producing an inverted result.
5381 /// Only those elements that are also in the specified 5381 /// Only those elements that are also in the specified
5382 /// range are included in the result. 5382 /// range are included in the result.
5383 /// </summary> 5383 /// </summary>
5384   5384  
5385 public LSL_List llList2ListStrided(LSL_List src, int start, int end, int stride) 5385 public LSL_List llList2ListStrided(LSL_List src, int start, int end, int stride)
5386 { 5386 {
5387   5387  
5388 LSL_List result = new LSL_List(); 5388 LSL_List result = new LSL_List();
5389 int[] si = new int[2]; 5389 int[] si = new int[2];
5390 int[] ei = new int[2]; 5390 int[] ei = new int[2];
5391 bool twopass = false; 5391 bool twopass = false;
5392   5392  
5393 m_host.AddScriptLPS(1); 5393 m_host.AddScriptLPS(1);
5394   5394  
5395 // First step is always to deal with negative indices 5395 // First step is always to deal with negative indices
5396   5396  
5397 if (start < 0) 5397 if (start < 0)
5398 start = src.Length+start; 5398 start = src.Length+start;
5399 if (end < 0) 5399 if (end < 0)
5400 end = src.Length+end; 5400 end = src.Length+end;
5401   5401  
5402 // Out of bounds indices are OK, just trim them 5402 // Out of bounds indices are OK, just trim them
5403 // accordingly 5403 // accordingly
5404   5404  
5405 if (start > src.Length) 5405 if (start > src.Length)
5406 start = src.Length; 5406 start = src.Length;
5407   5407  
5408 if (end > src.Length) 5408 if (end > src.Length)
5409 end = src.Length; 5409 end = src.Length;
5410   5410  
5411 if (stride == 0) 5411 if (stride == 0)
5412 stride = 1; 5412 stride = 1;
5413   5413  
5414 // There may be one or two ranges to be considered 5414 // There may be one or two ranges to be considered
5415   5415  
5416 if (start != end) 5416 if (start != end)
5417 { 5417 {
5418   5418  
5419 if (start <= end) 5419 if (start <= end)
5420 { 5420 {
5421 si[0] = start; 5421 si[0] = start;
5422 ei[0] = end; 5422 ei[0] = end;
5423 } 5423 }
5424 else 5424 else
5425 { 5425 {
5426 si[1] = start; 5426 si[1] = start;
5427 ei[1] = src.Length; 5427 ei[1] = src.Length;
5428 si[0] = 0; 5428 si[0] = 0;
5429 ei[0] = end; 5429 ei[0] = end;
5430 twopass = true; 5430 twopass = true;
5431 } 5431 }
5432   5432  
5433 // The scan always starts from the beginning of the 5433 // The scan always starts from the beginning of the
5434 // source list, but members are only selected if they 5434 // source list, but members are only selected if they
5435 // fall within the specified sub-range. The specified 5435 // fall within the specified sub-range. The specified
5436 // range values are inclusive. 5436 // range values are inclusive.
5437 // A negative stride reverses the direction of the 5437 // A negative stride reverses the direction of the
5438 // scan producing an inverted list as a result. 5438 // scan producing an inverted list as a result.
5439   5439  
5440 if (stride > 0) 5440 if (stride > 0)
5441 { 5441 {
5442 for (int i = 0; i < src.Length; i += stride) 5442 for (int i = 0; i < src.Length; i += stride)
5443 { 5443 {
5444 if (i<=ei[0] && i>=si[0]) 5444 if (i<=ei[0] && i>=si[0])
5445 result.Add(src.Data[i]); 5445 result.Add(src.Data[i]);
5446 if (twopass && i>=si[1] && i<=ei[1]) 5446 if (twopass && i>=si[1] && i<=ei[1])
5447 result.Add(src.Data[i]); 5447 result.Add(src.Data[i]);
5448 } 5448 }
5449 } 5449 }
5450 else if (stride < 0) 5450 else if (stride < 0)
5451 { 5451 {
5452 for (int i = src.Length - 1; i >= 0; i += stride) 5452 for (int i = src.Length - 1; i >= 0; i += stride)
5453 { 5453 {
5454 if (i <= ei[0] && i >= si[0]) 5454 if (i <= ei[0] && i >= si[0])
5455 result.Add(src.Data[i]); 5455 result.Add(src.Data[i]);
5456 if (twopass && i >= si[1] && i <= ei[1]) 5456 if (twopass && i >= si[1] && i <= ei[1])
5457 result.Add(src.Data[i]); 5457 result.Add(src.Data[i]);
5458 } 5458 }
5459 } 5459 }
5460 } 5460 }
5461 else 5461 else
5462 { 5462 {
5463 if (start%stride == 0) 5463 if (start%stride == 0)
5464 { 5464 {
5465 result.Add(src.Data[start]); 5465 result.Add(src.Data[start]);
5466 } 5466 }
5467 } 5467 }
5468   5468  
5469 return result; 5469 return result;
5470 } 5470 }
5471   5471  
5472 public LSL_Integer llGetRegionAgentCount() 5472 public LSL_Integer llGetRegionAgentCount()
5473 { 5473 {
5474 m_host.AddScriptLPS(1); 5474 m_host.AddScriptLPS(1);
5475 return new LSL_Integer(World.GetRootAgentCount()); 5475 return new LSL_Integer(World.GetRootAgentCount());
5476 } 5476 }
5477   5477  
5478 public LSL_Vector llGetRegionCorner() 5478 public LSL_Vector llGetRegionCorner()
5479 { 5479 {
5480 m_host.AddScriptLPS(1); 5480 m_host.AddScriptLPS(1);
5481 return new LSL_Vector(World.RegionInfo.RegionLocX * Constants.RegionSize, World.RegionInfo.RegionLocY * Constants.RegionSize, 0); 5481 return new LSL_Vector(World.RegionInfo.RegionLocX * Constants.RegionSize, World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
5482 } 5482 }
5483   5483  
5484 /// <summary> 5484 /// <summary>
5485 /// Insert the list identified by <paramref name="src"/> into the 5485 /// Insert the list identified by <paramref name="src"/> into the
5486 /// list designated by <paramref name="dest"/> such that the first 5486 /// list designated by <paramref name="dest"/> such that the first
5487 /// new element has the index specified by <paramref name="index"/> 5487 /// new element has the index specified by <paramref name="index"/>
5488 /// </summary> 5488 /// </summary>
5489   5489  
5490 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) 5490 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index)
5491 { 5491 {
5492   5492  
5493 LSL_List pref = null; 5493 LSL_List pref = null;
5494 LSL_List suff = null; 5494 LSL_List suff = null;
5495   5495  
5496 m_host.AddScriptLPS(1); 5496 m_host.AddScriptLPS(1);
5497   5497  
5498 if (index < 0) 5498 if (index < 0)
5499 { 5499 {
5500 index = index+dest.Length; 5500 index = index+dest.Length;
5501 if (index < 0) 5501 if (index < 0)
5502 { 5502 {
5503 index = 0; 5503 index = 0;
5504 } 5504 }
5505 } 5505 }
5506   5506  
5507 if (index != 0) 5507 if (index != 0)
5508 { 5508 {
5509 pref = dest.GetSublist(0,index-1); 5509 pref = dest.GetSublist(0,index-1);
5510 if (index < dest.Length) 5510 if (index < dest.Length)
5511 { 5511 {
5512 suff = dest.GetSublist(index,-1); 5512 suff = dest.GetSublist(index,-1);
5513 return pref + src + suff; 5513 return pref + src + suff;
5514 } 5514 }
5515 else 5515 else
5516 { 5516 {
5517 return pref + src; 5517 return pref + src;
5518 } 5518 }
5519 } 5519 }
5520 else 5520 else
5521 { 5521 {
5522 if (index < dest.Length) 5522 if (index < dest.Length)
5523 { 5523 {
5524 suff = dest.GetSublist(index,-1); 5524 suff = dest.GetSublist(index,-1);
5525 return src + suff; 5525 return src + suff;
5526 } 5526 }
5527 else 5527 else
5528 { 5528 {
5529 return src; 5529 return src;
5530 } 5530 }
5531 } 5531 }
5532   5532  
5533 } 5533 }
5534   5534  
5535 /// <summary> 5535 /// <summary>
5536 /// Returns the index of the first occurrence of test 5536 /// Returns the index of the first occurrence of test
5537 /// in src. 5537 /// in src.
5538 /// </summary> 5538 /// </summary>
5539 /// <param name="src">Source list</param> 5539 /// <param name="src">Source list</param>
5540 /// <param name="test">List to search for</param> 5540 /// <param name="test">List to search for</param>
5541 /// <returns> 5541 /// <returns>
5542 /// The index number of the point in src where test was found if it was found. 5542 /// The index number of the point in src where test was found if it was found.
5543 /// Otherwise returns -1 5543 /// Otherwise returns -1
5544 /// </returns> 5544 /// </returns>
5545 public LSL_Integer llListFindList(LSL_List src, LSL_List test) 5545 public LSL_Integer llListFindList(LSL_List src, LSL_List test)
5546 { 5546 {
5547 int index = -1; 5547 int index = -1;
5548 int length = src.Length - test.Length + 1; 5548 int length = src.Length - test.Length + 1;
5549   5549  
5550 m_host.AddScriptLPS(1); 5550 m_host.AddScriptLPS(1);
5551   5551  
5552 // If either list is empty, do not match 5552 // If either list is empty, do not match
5553 if (src.Length != 0 && test.Length != 0) 5553 if (src.Length != 0 && test.Length != 0)
5554 { 5554 {
5555 for (int i = 0; i < length; i++) 5555 for (int i = 0; i < length; i++)
5556 { 5556 {
5557 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int) 5557 // Why this piece of insanity? This is because most script constants are C# value types (e.g. int)
5558 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code 5558 // rather than wrapped LSL types. Such a script constant does not have int.Equal(LSL_Integer) code
5559 // and so the comparison fails even if the LSL_Integer conceptually has the same value. 5559 // and so the comparison fails even if the LSL_Integer conceptually has the same value.
5560 // Therefore, here we test Equals on both the source and destination objects. 5560 // Therefore, here we test Equals on both the source and destination objects.
5561 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)). 5561 // However, a future better approach may be use LSL struct script constants (e.g. LSL_Integer(1)).
5562 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i])) 5562 if (src.Data[i].Equals(test.Data[0]) || test.Data[0].Equals(src.Data[i]))
5563 { 5563 {
5564 int j; 5564 int j;
5565 for (j = 1; j < test.Length; j++) 5565 for (j = 1; j < test.Length; j++)
5566 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j]))) 5566 if (!(src.Data[i+j].Equals(test.Data[j]) || test.Data[j].Equals(src.Data[i+j])))
5567 break; 5567 break;
5568   5568  
5569 if (j == test.Length) 5569 if (j == test.Length)
5570 { 5570 {
5571 index = i; 5571 index = i;
5572 break; 5572 break;
5573 } 5573 }
5574 } 5574 }
5575 } 5575 }
5576 } 5576 }
5577   5577  
5578 return index; 5578 return index;
5579 } 5579 }
5580   5580  
5581 public LSL_String llGetObjectName() 5581 public LSL_String llGetObjectName()
5582 { 5582 {
5583 m_host.AddScriptLPS(1); 5583 m_host.AddScriptLPS(1);
5584 return m_host.Name !=null ? m_host.Name : String.Empty; 5584 return m_host.Name !=null ? m_host.Name : String.Empty;
5585 } 5585 }
5586   5586  
5587 public void llSetObjectName(string name) 5587 public void llSetObjectName(string name)
5588 { 5588 {
5589 m_host.AddScriptLPS(1); 5589 m_host.AddScriptLPS(1);
5590 m_host.Name = name != null ? name : String.Empty; 5590 m_host.Name = name != null ? name : String.Empty;
5591 } 5591 }
5592   5592  
5593 public LSL_String llGetDate() 5593 public LSL_String llGetDate()
5594 { 5594 {
5595 m_host.AddScriptLPS(1); 5595 m_host.AddScriptLPS(1);
5596 DateTime date = DateTime.Now.ToUniversalTime(); 5596 DateTime date = DateTime.Now.ToUniversalTime();
5597 string result = date.ToString("yyyy-MM-dd"); 5597 string result = date.ToString("yyyy-MM-dd");
5598 return result; 5598 return result;
5599 } 5599 }
5600   5600  
5601 public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir) 5601 public LSL_Integer llEdgeOfWorld(LSL_Vector pos, LSL_Vector dir)
5602 { 5602 {
5603 m_host.AddScriptLPS(1); 5603 m_host.AddScriptLPS(1);
5604   5604  
5605 // edge will be used to pass the Region Coordinates offset 5605 // edge will be used to pass the Region Coordinates offset
5606 // we want to check for a neighboring sim 5606 // we want to check for a neighboring sim
5607 LSL_Vector edge = new LSL_Vector(0, 0, 0); 5607 LSL_Vector edge = new LSL_Vector(0, 0, 0);
5608   5608  
5609 if (dir.x == 0) 5609 if (dir.x == 0)
5610 { 5610 {
5611 if (dir.y == 0) 5611 if (dir.y == 0)
5612 { 5612 {
5613 // Direction vector is 0,0 so return 5613 // Direction vector is 0,0 so return
5614 // false since we're staying in the sim 5614 // false since we're staying in the sim
5615 return 0; 5615 return 0;
5616 } 5616 }
5617 else 5617 else
5618 { 5618 {
5619 // Y is the only valid direction 5619 // Y is the only valid direction
5620 edge.y = dir.y / Math.Abs(dir.y); 5620 edge.y = dir.y / Math.Abs(dir.y);
5621 } 5621 }
5622 } 5622 }
5623 else 5623 else
5624 { 5624 {
5625 LSL_Float mag; 5625 LSL_Float mag;
5626 if (dir.x > 0) 5626 if (dir.x > 0)
5627 { 5627 {
5628 mag = (Constants.RegionSize - pos.x) / dir.x; 5628 mag = (Constants.RegionSize - pos.x) / dir.x;
5629 } 5629 }
5630 else 5630 else
5631 { 5631 {
5632 mag = (pos.x/dir.x); 5632 mag = (pos.x/dir.x);
5633 } 5633 }
5634   5634  
5635 mag = Math.Abs(mag); 5635 mag = Math.Abs(mag);
5636   5636  
5637 edge.y = pos.y + (dir.y * mag); 5637 edge.y = pos.y + (dir.y * mag);
5638   5638  
5639 if (edge.y > Constants.RegionSize || edge.y < 0) 5639 if (edge.y > Constants.RegionSize || edge.y < 0)
5640 { 5640 {
5641 // Y goes out of bounds first 5641 // Y goes out of bounds first
5642 edge.y = dir.y / Math.Abs(dir.y); 5642 edge.y = dir.y / Math.Abs(dir.y);
5643 } 5643 }
5644 else 5644 else
5645 { 5645 {
5646 // X goes out of bounds first or its a corner exit 5646 // X goes out of bounds first or its a corner exit
5647 edge.y = 0; 5647 edge.y = 0;
5648 edge.x = dir.x / Math.Abs(dir.x); 5648 edge.x = dir.x / Math.Abs(dir.x);
5649 } 5649 }
5650 } 5650 }
5651   5651  
5652 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID); 5652 List<GridRegion> neighbors = World.GridService.GetNeighbours(World.RegionInfo.ScopeID, World.RegionInfo.RegionID);
5653   5653  
5654 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x; 5654 uint neighborX = World.RegionInfo.RegionLocX + (uint)dir.x;
5655 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y; 5655 uint neighborY = World.RegionInfo.RegionLocY + (uint)dir.y;
5656   5656  
5657 foreach (GridRegion sri in neighbors) 5657 foreach (GridRegion sri in neighbors)
5658 { 5658 {
5659 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY) 5659 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5660 return 0; 5660 return 0;
5661 } 5661 }
5662   5662  
5663 return 1; 5663 return 1;
5664 } 5664 }
5665   5665  
5666 /// <summary> 5666 /// <summary>
5667 /// Not fully implemented yet. Still to do:- 5667 /// Not fully implemented yet. Still to do:-
5668 /// AGENT_BUSY 5668 /// AGENT_BUSY
5669 /// Remove as they are done 5669 /// Remove as they are done
5670 /// </summary> 5670 /// </summary>
5671 public LSL_Integer llGetAgentInfo(string id) 5671 public LSL_Integer llGetAgentInfo(string id)
5672 { 5672 {
5673 m_host.AddScriptLPS(1); 5673 m_host.AddScriptLPS(1);
5674   5674  
5675 UUID key = new UUID(); 5675 UUID key = new UUID();
5676 if (!UUID.TryParse(id, out key)) 5676 if (!UUID.TryParse(id, out key))
5677 { 5677 {
5678 return 0; 5678 return 0;
5679 } 5679 }
5680   5680  
5681 int flags = 0; 5681 int flags = 0;
5682   5682  
5683 ScenePresence agent = World.GetScenePresence(key); 5683 ScenePresence agent = World.GetScenePresence(key);
5684 if (agent == null) 5684 if (agent == null)
5685 { 5685 {
5686 return 0; 5686 return 0;
5687 } 5687 }
5688   5688  
5689 if (agent.IsChildAgent) 5689 if (agent.IsChildAgent)
5690 return 0; // Fail if they are not in the same region 5690 return 0; // Fail if they are not in the same region
5691   5691  
5692 // note: in OpenSim, sitting seems to cancel AGENT_ALWAYS_RUN, unlike SL 5692 // note: in OpenSim, sitting seems to cancel AGENT_ALWAYS_RUN, unlike SL
5693 if (agent.SetAlwaysRun) 5693 if (agent.SetAlwaysRun)
5694 { 5694 {
5695 flags |= ScriptBaseClass.AGENT_ALWAYS_RUN; 5695 flags |= ScriptBaseClass.AGENT_ALWAYS_RUN;
5696 } 5696 }
5697   5697  
5698 if (agent.HasAttachments()) 5698 if (agent.HasAttachments())
5699 { 5699 {
5700 flags |= ScriptBaseClass.AGENT_ATTACHMENTS; 5700 flags |= ScriptBaseClass.AGENT_ATTACHMENTS;
5701 if (agent.HasScriptedAttachments()) 5701 if (agent.HasScriptedAttachments())
5702 flags |= ScriptBaseClass.AGENT_SCRIPTED; 5702 flags |= ScriptBaseClass.AGENT_SCRIPTED;
5703 } 5703 }
5704   5704  
5705 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) 5705 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0)
5706 { 5706 {
5707 flags |= ScriptBaseClass.AGENT_FLYING; 5707 flags |= ScriptBaseClass.AGENT_FLYING;
5708 flags |= ScriptBaseClass.AGENT_IN_AIR; // flying always implies in-air, even if colliding with e.g. a wall 5708 flags |= ScriptBaseClass.AGENT_IN_AIR; // flying always implies in-air, even if colliding with e.g. a wall
5709 } 5709 }
5710   5710  
5711 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0) 5711 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0)
5712 { 5712 {
5713 flags |= ScriptBaseClass.AGENT_AWAY; 5713 flags |= ScriptBaseClass.AGENT_AWAY;
5714 } 5714 }
5715   5715  
5716 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 5716 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5717 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 5717 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5718 { 5718 {
5719 flags |= ScriptBaseClass.AGENT_MOUSELOOK; 5719 flags |= ScriptBaseClass.AGENT_MOUSELOOK;
5720 } 5720 }
5721   5721  
5722 if ((agent.State & (byte)AgentState.Typing) != (byte)0) 5722 if ((agent.State & (byte)AgentState.Typing) != (byte)0)
5723 { 5723 {
5724 flags |= ScriptBaseClass.AGENT_TYPING; 5724 flags |= ScriptBaseClass.AGENT_TYPING;
5725 } 5725 }
5726   5726  
5727 string agentMovementAnimation = agent.Animator.CurrentMovementAnimation; 5727 string agentMovementAnimation = agent.Animator.CurrentMovementAnimation;
5728   5728  
5729 if (agentMovementAnimation == "CROUCH") 5729 if (agentMovementAnimation == "CROUCH")
5730 { 5730 {
5731 flags |= ScriptBaseClass.AGENT_CROUCHING; 5731 flags |= ScriptBaseClass.AGENT_CROUCHING;
5732 } 5732 }
5733   5733  
5734 if (agentMovementAnimation == "WALK" || agentMovementAnimation == "CROUCHWALK") 5734 if (agentMovementAnimation == "WALK" || agentMovementAnimation == "CROUCHWALK")
5735 { 5735 {
5736 flags |= ScriptBaseClass.AGENT_WALKING; 5736 flags |= ScriptBaseClass.AGENT_WALKING;
5737 } 5737 }
5738   5738  
5739 // not colliding implies in air. Note: flying also implies in-air, even if colliding (see above) 5739 // not colliding implies in air. Note: flying also implies in-air, even if colliding (see above)
5740   5740  
5741 // note: AGENT_IN_AIR and AGENT_WALKING seem to be mutually exclusive states in SL. 5741 // note: AGENT_IN_AIR and AGENT_WALKING seem to be mutually exclusive states in SL.
5742   5742  
5743 // note: this may need some tweaking when walking downhill. you "fall down" for a brief instant 5743 // note: this may need some tweaking when walking downhill. you "fall down" for a brief instant
5744 // and don't collide when walking downhill, which instantly registers as in-air, briefly. should 5744 // and don't collide when walking downhill, which instantly registers as in-air, briefly. should
5745 // there be some minimum non-collision threshold time before claiming the avatar is in-air? 5745 // there be some minimum non-collision threshold time before claiming the avatar is in-air?
5746 if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && !agent.IsColliding ) 5746 if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 && !agent.IsColliding )
5747 { 5747 {
5748 flags |= ScriptBaseClass.AGENT_IN_AIR; 5748 flags |= ScriptBaseClass.AGENT_IN_AIR;
5749 } 5749 }
5750   5750  
5751 if (agent.ParentPart != null) 5751 if (agent.ParentPart != null)
5752 { 5752 {
5753 flags |= ScriptBaseClass.AGENT_ON_OBJECT; 5753 flags |= ScriptBaseClass.AGENT_ON_OBJECT;
5754 flags |= ScriptBaseClass.AGENT_SITTING; 5754 flags |= ScriptBaseClass.AGENT_SITTING;
5755 } 5755 }
5756   5756  
5757 if (agent.Animator.Animations.ImplicitDefaultAnimation.AnimID 5757 if (agent.Animator.Animations.ImplicitDefaultAnimation.AnimID
5758 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 5758 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
5759 { 5759 {
5760 flags |= ScriptBaseClass.AGENT_SITTING; 5760 flags |= ScriptBaseClass.AGENT_SITTING;
5761 } 5761 }
5762   5762  
5763 return flags; 5763 return flags;
5764 } 5764 }
5765   5765  
5766 public LSL_String llGetAgentLanguage(string id) 5766 public LSL_String llGetAgentLanguage(string id)
5767 { 5767 {
5768 // This should only return a value if the avatar is in the same region 5768 // This should only return a value if the avatar is in the same region
5769 //ckrinke 1-30-09 : This needs to parse the XMLRPC language field supplied 5769 //ckrinke 1-30-09 : This needs to parse the XMLRPC language field supplied
5770 //by the client at login. Currently returning only en-us until our I18N 5770 //by the client at login. Currently returning only en-us until our I18N
5771 //effort gains momentum 5771 //effort gains momentum
5772 m_host.AddScriptLPS(1); 5772 m_host.AddScriptLPS(1);
5773 return "en-us"; 5773 return "en-us";
5774 } 5774 }
5775 /// <summary> 5775 /// <summary>
5776 /// http://wiki.secondlife.com/wiki/LlGetAgentList 5776 /// http://wiki.secondlife.com/wiki/LlGetAgentList
5777 /// The list of options is currently not used in SL 5777 /// The list of options is currently not used in SL
5778 /// scope is one of:- 5778 /// scope is one of:-
5779 /// AGENT_LIST_REGION - all in the region 5779 /// AGENT_LIST_REGION - all in the region
5780 /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object 5780 /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object
5781 /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the 5781 /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the
5782 /// current parcel. 5782 /// current parcel.
5783 /// </summary> 5783 /// </summary>
5784 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) 5784 public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options)
5785 { 5785 {
5786 m_host.AddScriptLPS(1); 5786 m_host.AddScriptLPS(1);
5787   5787  
5788 // the constants are 1, 2 and 4 so bits are being set, but you 5788 // the constants are 1, 2 and 4 so bits are being set, but you
5789 // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 5789 // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4
5790 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION; 5790 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION;
5791 bool parcelOwned = scope == ScriptBaseClass.AGENT_LIST_PARCEL_OWNER; 5791 bool parcelOwned = scope == ScriptBaseClass.AGENT_LIST_PARCEL_OWNER;
5792 bool parcel = scope == ScriptBaseClass.AGENT_LIST_PARCEL; 5792 bool parcel = scope == ScriptBaseClass.AGENT_LIST_PARCEL;
5793   5793  
5794 LSL_List result = new LSL_List(); 5794 LSL_List result = new LSL_List();
5795   5795  
5796 if (!regionWide && !parcelOwned && !parcel) 5796 if (!regionWide && !parcelOwned && !parcel)
5797 { 5797 {
5798 result.Add("INVALID_SCOPE"); 5798 result.Add("INVALID_SCOPE");
5799 return result; 5799 return result;
5800 } 5800 }
5801   5801  
5802 ILandObject land; 5802 ILandObject land;
5803 UUID id = UUID.Zero; 5803 UUID id = UUID.Zero;
5804   5804  
5805 if (parcel || parcelOwned) 5805 if (parcel || parcelOwned)
5806 { 5806 {
5807 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition()); 5807 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
5808 if (land == null) 5808 if (land == null)
5809 { 5809 {
5810 id = UUID.Zero; 5810 id = UUID.Zero;
5811 } 5811 }
5812 else 5812 else
5813 { 5813 {
5814 if (parcelOwned) 5814 if (parcelOwned)
5815 { 5815 {
5816 id = land.LandData.OwnerID; 5816 id = land.LandData.OwnerID;
5817 } 5817 }
5818 else 5818 else
5819 { 5819 {
5820 id = land.LandData.GlobalID; 5820 id = land.LandData.GlobalID;
5821 } 5821 }
5822 } 5822 }
5823 } 5823 }
5824   5824  
5825 World.ForEachRootScenePresence( 5825 World.ForEachRootScenePresence(
5826 delegate (ScenePresence ssp) 5826 delegate (ScenePresence ssp)
5827 { 5827 {
5828 // Gods are not listed in SL 5828 // Gods are not listed in SL
5829 if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent) 5829 if (!ssp.IsDeleted && ssp.GodLevel == 0.0 && !ssp.IsChildAgent)
5830 { 5830 {
5831 if (!regionWide) 5831 if (!regionWide)
5832 { 5832 {
5833 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition); 5833 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
5834 if (land != null) 5834 if (land != null)
5835 { 5835 {
5836 if (parcelOwned && land.LandData.OwnerID == id || 5836 if (parcelOwned && land.LandData.OwnerID == id ||
5837 parcel && land.LandData.GlobalID == id) 5837 parcel && land.LandData.GlobalID == id)
5838 { 5838 {
5839 result.Add(new LSL_Key(ssp.UUID.ToString())); 5839 result.Add(new LSL_Key(ssp.UUID.ToString()));
5840 } 5840 }
5841 } 5841 }
5842 } 5842 }
5843 else 5843 else
5844 { 5844 {
5845 result.Add(new LSL_Key(ssp.UUID.ToString())); 5845 result.Add(new LSL_Key(ssp.UUID.ToString()));
5846 } 5846 }
5847 } 5847 }
5848 // Maximum of 100 results 5848 // Maximum of 100 results
5849 if (result.Length > 99) 5849 if (result.Length > 99)
5850 { 5850 {
5851 return; 5851 return;
5852 } 5852 }
5853 } 5853 }
5854 ); 5854 );
5855 return result; 5855 return result;
5856 } 5856 }
5857   5857  
5858 public void llAdjustSoundVolume(double volume) 5858 public void llAdjustSoundVolume(double volume)
5859 { 5859 {
5860 m_host.AddScriptLPS(1); 5860 m_host.AddScriptLPS(1);
5861 m_host.AdjustSoundGain(volume); 5861 m_host.AdjustSoundGain(volume);
5862 ScriptSleep(100); 5862 ScriptSleep(100);
5863 } 5863 }
5864   5864  
5865 public void llSetSoundRadius(double radius) 5865 public void llSetSoundRadius(double radius)
5866 { 5866 {
5867 m_host.AddScriptLPS(1); 5867 m_host.AddScriptLPS(1);
5868 m_host.SoundRadius = radius; 5868 m_host.SoundRadius = radius;
5869 } 5869 }
5870   5870  
5871 public LSL_String llKey2Name(string id) 5871 public LSL_String llKey2Name(string id)
5872 { 5872 {
5873 m_host.AddScriptLPS(1); 5873 m_host.AddScriptLPS(1);
5874 UUID key = new UUID(); 5874 UUID key = new UUID();
5875 if (UUID.TryParse(id,out key)) 5875 if (UUID.TryParse(id,out key))
5876 { 5876 {
5877 ScenePresence presence = World.GetScenePresence(key); 5877 ScenePresence presence = World.GetScenePresence(key);
5878   5878  
5879 if (presence != null) 5879 if (presence != null)
5880 { 5880 {
5881 return presence.ControllingClient.Name; 5881 return presence.ControllingClient.Name;
5882 //return presence.Name; 5882 //return presence.Name;
5883 } 5883 }
5884   5884  
5885 if (World.GetSceneObjectPart(key) != null) 5885 if (World.GetSceneObjectPart(key) != null)
5886 { 5886 {
5887 return World.GetSceneObjectPart(key).Name; 5887 return World.GetSceneObjectPart(key).Name;
5888 } 5888 }
5889 } 5889 }
5890 return String.Empty; 5890 return String.Empty;
5891 } 5891 }
5892   5892  
5893   5893  
5894   5894  
5895 public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) 5895 public void llSetTextureAnim(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 SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate); 5899 SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate);
5900 } 5900 }
5901   5901  
5902 public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate) 5902 public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate)
5903 { 5903 {
5904 m_host.AddScriptLPS(1); 5904 m_host.AddScriptLPS(1);
5905   5905  
5906 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5906 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5907   5907  
5908 foreach (SceneObjectPart part in parts) 5908 foreach (SceneObjectPart part in parts)
5909 { 5909 {
5910 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5910 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5911 } 5911 }
5912 } 5912 }
5913   5913  
5914 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 5914 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
5915 { 5915 {
5916   5916  
5917 Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation(); 5917 Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation();
5918 pTexAnim.Flags = (Primitive.TextureAnimMode)mode; 5918 pTexAnim.Flags = (Primitive.TextureAnimMode)mode;
5919   5919  
5920 //ALL_SIDES 5920 //ALL_SIDES
5921 if (face == ScriptBaseClass.ALL_SIDES) 5921 if (face == ScriptBaseClass.ALL_SIDES)
5922 face = 255; 5922 face = 255;
5923   5923  
5924 pTexAnim.Face = (uint)face; 5924 pTexAnim.Face = (uint)face;
5925 pTexAnim.Length = (float)length; 5925 pTexAnim.Length = (float)length;
5926 pTexAnim.Rate = (float)rate; 5926 pTexAnim.Rate = (float)rate;
5927 pTexAnim.SizeX = (uint)sizex; 5927 pTexAnim.SizeX = (uint)sizex;
5928 pTexAnim.SizeY = (uint)sizey; 5928 pTexAnim.SizeY = (uint)sizey;
5929 pTexAnim.Start = (float)start; 5929 pTexAnim.Start = (float)start;
5930   5930  
5931 part.AddTextureAnimation(pTexAnim); 5931 part.AddTextureAnimation(pTexAnim);
5932 part.SendFullUpdateToAllClients(); 5932 part.SendFullUpdateToAllClients();
5933 part.ParentGroup.HasGroupChanged = true; 5933 part.ParentGroup.HasGroupChanged = true;
5934 } 5934 }
5935   5935  
5936 public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, 5936 public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east,
5937 LSL_Vector bottom_south_west) 5937 LSL_Vector bottom_south_west)
5938 { 5938 {
5939 m_host.AddScriptLPS(1); 5939 m_host.AddScriptLPS(1);
5940 if (m_SoundModule != null) 5940 if (m_SoundModule != null)
5941 { 5941 {
5942 m_SoundModule.TriggerSoundLimited(m_host.UUID, 5942 m_SoundModule.TriggerSoundLimited(m_host.UUID,
5943 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, 5943 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume,
5944 bottom_south_west, top_north_east); 5944 bottom_south_west, top_north_east);
5945 } 5945 }
5946 } 5946 }
5947   5947  
5948 public void llEjectFromLand(string pest) 5948 public void llEjectFromLand(string pest)
5949 { 5949 {
5950 m_host.AddScriptLPS(1); 5950 m_host.AddScriptLPS(1);
5951 UUID agentID = new UUID(); 5951 UUID agentID = new UUID();
5952 if (UUID.TryParse(pest, out agentID)) 5952 if (UUID.TryParse(pest, out agentID))
5953 { 5953 {
5954 ScenePresence presence = World.GetScenePresence(agentID); 5954 ScenePresence presence = World.GetScenePresence(agentID);
5955 if (presence != null) 5955 if (presence != null)
5956 { 5956 {
5957 // agent must be over the owners land 5957 // agent must be over the owners land
5958 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition); 5958 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
5959 if (land == null) 5959 if (land == null)
5960 return; 5960 return;
5961   5961  
5962 if (m_host.OwnerID == land.LandData.OwnerID) 5962 if (m_host.OwnerID == land.LandData.OwnerID)
5963 { 5963 {
5964 World.TeleportClientHome(agentID, presence.ControllingClient); 5964 World.TeleportClientHome(agentID, presence.ControllingClient);
5965 } 5965 }
5966 } 5966 }
5967 } 5967 }
5968 ScriptSleep(5000); 5968 ScriptSleep(5000);
5969 } 5969 }
5970   5970  
5971 public LSL_Integer llOverMyLand(string id) 5971 public LSL_Integer llOverMyLand(string id)
5972 { 5972 {
5973 m_host.AddScriptLPS(1); 5973 m_host.AddScriptLPS(1);
5974 UUID key = new UUID(); 5974 UUID key = new UUID();
5975 if (UUID.TryParse(id, out key)) 5975 if (UUID.TryParse(id, out key))
5976 { 5976 {
5977 ScenePresence presence = World.GetScenePresence(key); 5977 ScenePresence presence = World.GetScenePresence(key);
5978 if (presence != null) // object is an avatar 5978 if (presence != null) // object is an avatar
5979 { 5979 {
5980 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 5980 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
5981 return 1; 5981 return 1;
5982 } 5982 }
5983 else // object is not an avatar 5983 else // object is not an avatar
5984 { 5984 {
5985 SceneObjectPart obj = World.GetSceneObjectPart(key); 5985 SceneObjectPart obj = World.GetSceneObjectPart(key);
5986   5986  
5987 if (obj != null) 5987 if (obj != null)
5988 { 5988 {
5989 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID) 5989 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
5990 return 1; 5990 return 1;
5991 } 5991 }
5992 } 5992 }
5993 } 5993 }
5994   5994  
5995 return 0; 5995 return 0;
5996 } 5996 }
5997   5997  
5998 public LSL_String llGetLandOwnerAt(LSL_Vector pos) 5998 public LSL_String llGetLandOwnerAt(LSL_Vector pos)
5999 { 5999 {
6000 m_host.AddScriptLPS(1); 6000 m_host.AddScriptLPS(1);
6001 ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 6001 ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
6002 if (land == null) 6002 if (land == null)
6003 return UUID.Zero.ToString(); 6003 return UUID.Zero.ToString();
6004 return land.LandData.OwnerID.ToString(); 6004 return land.LandData.OwnerID.ToString();
6005 } 6005 }
6006   6006  
6007 /// <summary> 6007 /// <summary>
6008 /// According to http://lslwiki.net/lslwiki/wakka.php?wakka=llGetAgentSize 6008 /// According to http://lslwiki.net/lslwiki/wakka.php?wakka=llGetAgentSize
6009 /// only the height of avatars vary and that says: 6009 /// only the height of avatars vary and that says:
6010 /// Width (x) and depth (y) are constant. (0.45m and 0.6m respectively). 6010 /// Width (x) and depth (y) are constant. (0.45m and 0.6m respectively).
6011 /// </summary> 6011 /// </summary>
6012 public LSL_Vector llGetAgentSize(string id) 6012 public LSL_Vector llGetAgentSize(string id)
6013 { 6013 {
6014 m_host.AddScriptLPS(1); 6014 m_host.AddScriptLPS(1);
6015 ScenePresence avatar = World.GetScenePresence((UUID)id); 6015 ScenePresence avatar = World.GetScenePresence((UUID)id);
6016 LSL_Vector agentSize; 6016 LSL_Vector agentSize;
6017 if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region 6017 if (avatar == null || avatar.IsChildAgent) // Fail if not in the same region
6018 { 6018 {
6019 agentSize = ScriptBaseClass.ZERO_VECTOR; 6019 agentSize = ScriptBaseClass.ZERO_VECTOR;
6020 } 6020 }
6021 else 6021 else
6022 { 6022 {
6023 agentSize = GetAgentSize(avatar); 6023 agentSize = GetAgentSize(avatar);
6024 } 6024 }
6025   6025  
6026 return agentSize; 6026 return agentSize;
6027 } 6027 }
6028   6028  
6029 public LSL_Integer llSameGroup(string agent) 6029 public LSL_Integer llSameGroup(string agent)
6030 { 6030 {
6031 m_host.AddScriptLPS(1); 6031 m_host.AddScriptLPS(1);
6032 UUID agentId = new UUID(); 6032 UUID agentId = new UUID();
6033 if (!UUID.TryParse(agent, out agentId)) 6033 if (!UUID.TryParse(agent, out agentId))
6034 return new LSL_Integer(0); 6034 return new LSL_Integer(0);
6035 ScenePresence presence = World.GetScenePresence(agentId); 6035 ScenePresence presence = World.GetScenePresence(agentId);
6036 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6036 if (presence == null || presence.IsChildAgent) // Return flase for child agents
6037 return new LSL_Integer(0); 6037 return new LSL_Integer(0);
6038 IClientAPI client = presence.ControllingClient; 6038 IClientAPI client = presence.ControllingClient;
6039 if (m_host.GroupID == client.ActiveGroupId) 6039 if (m_host.GroupID == client.ActiveGroupId)
6040 return new LSL_Integer(1); 6040 return new LSL_Integer(1);
6041 else 6041 else
6042 return new LSL_Integer(0); 6042 return new LSL_Integer(0);
6043 } 6043 }
6044   6044  
6045 public void llUnSit(string id) 6045 public void llUnSit(string id)
6046 { 6046 {
6047 m_host.AddScriptLPS(1); 6047 m_host.AddScriptLPS(1);
6048   6048  
6049 UUID key = new UUID(); 6049 UUID key = new UUID();
6050 if (UUID.TryParse(id, out key)) 6050 if (UUID.TryParse(id, out key))
6051 { 6051 {
6052 ScenePresence av = World.GetScenePresence(key); 6052 ScenePresence av = World.GetScenePresence(key);
6053   6053  
6054 if (av != null) 6054 if (av != null)
6055 { 6055 {
6056 if (llAvatarOnSitTarget() == id) 6056 if (llAvatarOnSitTarget() == id)
6057 { 6057 {
6058 // if the avatar is sitting on this object, then 6058 // if the avatar is sitting on this object, then
6059 // we can unsit them. We don't want random scripts unsitting random people 6059 // we can unsit them. We don't want random scripts unsitting random people
6060 // Lets avoid the popcorn avatar scenario. 6060 // Lets avoid the popcorn avatar scenario.
6061 av.StandUp(); 6061 av.StandUp();
6062 } 6062 }
6063 else 6063 else
6064 { 6064 {
6065 // If the object owner also owns the parcel 6065 // If the object owner also owns the parcel
6066 // or 6066 // or
6067 // if the land is group owned and the object is group owned by the same group 6067 // if the land is group owned and the object is group owned by the same group
6068 // or 6068 // or
6069 // if the object is owned by a person with estate access. 6069 // if the object is owned by a person with estate access.
6070 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition); 6070 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6071 if (parcel != null) 6071 if (parcel != null)
6072 { 6072 {
6073 if (m_host.OwnerID == parcel.LandData.OwnerID || 6073 if (m_host.OwnerID == parcel.LandData.OwnerID ||
6074 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID 6074 (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID
6075 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) 6075 && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID))
6076 { 6076 {
6077 av.StandUp(); 6077 av.StandUp();
6078 } 6078 }
6079 } 6079 }
6080 } 6080 }
6081 } 6081 }
6082 } 6082 }
6083 } 6083 }
6084   6084  
6085 public LSL_Vector llGroundSlope(LSL_Vector offset) 6085 public LSL_Vector llGroundSlope(LSL_Vector offset)
6086 { 6086 {
6087 m_host.AddScriptLPS(1); 6087 m_host.AddScriptLPS(1);
6088   6088  
6089 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 6089 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
6090 LSL_Vector vsn = llGroundNormal(offset); 6090 LSL_Vector vsn = llGroundNormal(offset);
6091   6091  
6092 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6092 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6093 //the height of that point on the plane. The resulting vector gives the slope. 6093 //the height of that point on the plane. The resulting vector gives the slope.
6094 Vector3 vsl = vsn; 6094 Vector3 vsl = vsn;
6095 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6095 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6096 vsl.Normalize(); 6096 vsl.Normalize();
6097 //Normalization might be overkill here 6097 //Normalization might be overkill here
6098   6098  
6099 vsn.x = vsl.X; 6099 vsn.x = vsl.X;
6100 vsn.y = vsl.Y; 6100 vsn.y = vsl.Y;
6101 vsn.z = vsl.Z; 6101 vsn.z = vsl.Z;
6102   6102  
6103 return vsn; 6103 return vsn;
6104 } 6104 }
6105   6105  
6106 public LSL_Vector llGroundNormal(LSL_Vector offset) 6106 public LSL_Vector llGroundNormal(LSL_Vector offset)
6107 { 6107 {
6108 m_host.AddScriptLPS(1); 6108 m_host.AddScriptLPS(1);
6109 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset; 6109 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6110 // Clamp to valid position 6110 // Clamp to valid position
6111 if (pos.X < 0) 6111 if (pos.X < 0)
6112 pos.X = 0; 6112 pos.X = 0;
6113 else if (pos.X >= World.Heightmap.Width) 6113 else if (pos.X >= World.Heightmap.Width)
6114 pos.X = World.Heightmap.Width - 1; 6114 pos.X = World.Heightmap.Width - 1;
6115 if (pos.Y < 0) 6115 if (pos.Y < 0)
6116 pos.Y = 0; 6116 pos.Y = 0;
6117 else if (pos.Y >= World.Heightmap.Height) 6117 else if (pos.Y >= World.Heightmap.Height)
6118 pos.Y = World.Heightmap.Height - 1; 6118 pos.Y = World.Heightmap.Height - 1;
6119   6119  
6120 //Find two points in addition to the position to define a plane 6120 //Find two points in addition to the position to define a plane
6121 Vector3 p0 = new Vector3(pos.X, pos.Y, 6121 Vector3 p0 = new Vector3(pos.X, pos.Y,
6122 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6122 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6123 Vector3 p1 = new Vector3(); 6123 Vector3 p1 = new Vector3();
6124 Vector3 p2 = new Vector3(); 6124 Vector3 p2 = new Vector3();
6125 if ((pos.X + 1.0f) >= World.Heightmap.Width) 6125 if ((pos.X + 1.0f) >= World.Heightmap.Width)
6126 p1 = new Vector3(pos.X + 1.0f, pos.Y, 6126 p1 = new Vector3(pos.X + 1.0f, pos.Y,
6127 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6127 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6128 else 6128 else
6129 p1 = new Vector3(pos.X + 1.0f, pos.Y, 6129 p1 = new Vector3(pos.X + 1.0f, pos.Y,
6130 (float)World.Heightmap[(int)(pos.X + 1.0f), (int)pos.Y]); 6130 (float)World.Heightmap[(int)(pos.X + 1.0f), (int)pos.Y]);
6131 if ((pos.Y + 1.0f) >= World.Heightmap.Height) 6131 if ((pos.Y + 1.0f) >= World.Heightmap.Height)
6132 p2 = new Vector3(pos.X, pos.Y + 1.0f, 6132 p2 = new Vector3(pos.X, pos.Y + 1.0f,
6133 (float)World.Heightmap[(int)pos.X, (int)pos.Y]); 6133 (float)World.Heightmap[(int)pos.X, (int)pos.Y]);
6134 else 6134 else
6135 p2 = new Vector3(pos.X, pos.Y + 1.0f, 6135 p2 = new Vector3(pos.X, pos.Y + 1.0f,
6136 (float)World.Heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]); 6136 (float)World.Heightmap[(int)pos.X, (int)(pos.Y + 1.0f)]);
6137   6137  
6138 //Find normalized vectors from p0 to p1 and p0 to p2 6138 //Find normalized vectors from p0 to p1 and p0 to p2
6139 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); 6139 Vector3 v0 = new Vector3(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
6140 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z); 6140 Vector3 v1 = new Vector3(p2.X - p0.X, p2.Y - p0.Y, p2.Z - p0.Z);
6141 v0.Normalize(); 6141 v0.Normalize();
6142 v1.Normalize(); 6142 v1.Normalize();
6143   6143  
6144 //Find the cross product of the vectors (the slope normal). 6144 //Find the cross product of the vectors (the slope normal).
6145 Vector3 vsn = new Vector3(); 6145 Vector3 vsn = new Vector3();
6146 vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y); 6146 vsn.X = (v0.Y * v1.Z) - (v0.Z * v1.Y);
6147 vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z); 6147 vsn.Y = (v0.Z * v1.X) - (v0.X * v1.Z);
6148 vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X); 6148 vsn.Z = (v0.X * v1.Y) - (v0.Y * v1.X);
6149 vsn.Normalize(); 6149 vsn.Normalize();
6150 //I believe the crossproduct of two normalized vectors is a normalized vector so 6150 //I believe the crossproduct of two normalized vectors is a normalized vector so
6151 //this normalization may be overkill 6151 //this normalization may be overkill
6152   6152  
6153 return new LSL_Vector(vsn); 6153 return new LSL_Vector(vsn);
6154 } 6154 }
6155   6155  
6156 public LSL_Vector llGroundContour(LSL_Vector offset) 6156 public LSL_Vector llGroundContour(LSL_Vector offset)
6157 { 6157 {
6158 m_host.AddScriptLPS(1); 6158 m_host.AddScriptLPS(1);
6159 LSL_Vector x = llGroundSlope(offset); 6159 LSL_Vector x = llGroundSlope(offset);
6160 return new LSL_Vector(-x.y, x.x, 0.0); 6160 return new LSL_Vector(-x.y, x.x, 0.0);
6161 } 6161 }
6162   6162  
6163 public LSL_Integer llGetAttached() 6163 public LSL_Integer llGetAttached()
6164 { 6164 {
6165 m_host.AddScriptLPS(1); 6165 m_host.AddScriptLPS(1);
6166 return m_host.ParentGroup.AttachmentPoint; 6166 return m_host.ParentGroup.AttachmentPoint;
6167 } 6167 }
6168   6168  
6169 public virtual LSL_Integer llGetFreeMemory() 6169 public virtual LSL_Integer llGetFreeMemory()
6170 { 6170 {
6171 m_host.AddScriptLPS(1); 6171 m_host.AddScriptLPS(1);
6172 // Make scripts designed for LSO happy 6172 // Make scripts designed for LSO happy
6173 return 16384; 6173 return 16384;
6174 } 6174 }
6175   6175  
6176 public LSL_Integer llGetFreeURLs() 6176 public LSL_Integer llGetFreeURLs()
6177 { 6177 {
6178 m_host.AddScriptLPS(1); 6178 m_host.AddScriptLPS(1);
6179 if (m_UrlModule != null) 6179 if (m_UrlModule != null)
6180 return new LSL_Integer(m_UrlModule.GetFreeUrls()); 6180 return new LSL_Integer(m_UrlModule.GetFreeUrls());
6181 return new LSL_Integer(0); 6181 return new LSL_Integer(0);
6182 } 6182 }
6183   6183  
6184   6184  
6185 public LSL_String llGetRegionName() 6185 public LSL_String llGetRegionName()
6186 { 6186 {
6187 m_host.AddScriptLPS(1); 6187 m_host.AddScriptLPS(1);
6188 return World.RegionInfo.RegionName; 6188 return World.RegionInfo.RegionName;
6189 } 6189 }
6190   6190  
6191 public LSL_Float llGetRegionTimeDilation() 6191 public LSL_Float llGetRegionTimeDilation()
6192 { 6192 {
6193 m_host.AddScriptLPS(1); 6193 m_host.AddScriptLPS(1);
6194 return (double)World.TimeDilation; 6194 return (double)World.TimeDilation;
6195 } 6195 }
6196   6196  
6197 /// <summary> 6197 /// <summary>
6198 /// Returns the value reported in the client Statistics window 6198 /// Returns the value reported in the client Statistics window
6199 /// </summary> 6199 /// </summary>
6200 public LSL_Float llGetRegionFPS() 6200 public LSL_Float llGetRegionFPS()
6201 { 6201 {
6202 m_host.AddScriptLPS(1); 6202 m_host.AddScriptLPS(1);
6203 return World.StatsReporter.LastReportedSimFPS; 6203 return World.StatsReporter.LastReportedSimFPS;
6204 } 6204 }
6205   6205  
6206   6206  
6207 /* particle system rules should be coming into this routine as doubles, that is 6207 /* particle system rules should be coming into this routine as doubles, that is
6208 rule[0] should be an integer from this list and rule[1] should be the arg 6208 rule[0] should be an integer from this list and rule[1] should be the arg
6209 for the same integer. wiki.secondlife.com has most of this mapping, but some 6209 for the same integer. wiki.secondlife.com has most of this mapping, but some
6210 came from http://www.caligari-designs.com/p4u2 6210 came from http://www.caligari-designs.com/p4u2
6211   6211  
6212 We iterate through the list for 'Count' elements, incrementing by two for each 6212 We iterate through the list for 'Count' elements, incrementing by two for each
6213 iteration and set the members of Primitive.ParticleSystem, one at a time. 6213 iteration and set the members of Primitive.ParticleSystem, one at a time.
6214 */ 6214 */
6215   6215  
6216 public enum PrimitiveRule : int 6216 public enum PrimitiveRule : int
6217 { 6217 {
6218 PSYS_PART_FLAGS = 0, 6218 PSYS_PART_FLAGS = 0,
6219 PSYS_PART_START_COLOR = 1, 6219 PSYS_PART_START_COLOR = 1,
6220 PSYS_PART_START_ALPHA = 2, 6220 PSYS_PART_START_ALPHA = 2,
6221 PSYS_PART_END_COLOR = 3, 6221 PSYS_PART_END_COLOR = 3,
6222 PSYS_PART_END_ALPHA = 4, 6222 PSYS_PART_END_ALPHA = 4,
6223 PSYS_PART_START_SCALE = 5, 6223 PSYS_PART_START_SCALE = 5,
6224 PSYS_PART_END_SCALE = 6, 6224 PSYS_PART_END_SCALE = 6,
6225 PSYS_PART_MAX_AGE = 7, 6225 PSYS_PART_MAX_AGE = 7,
6226 PSYS_SRC_ACCEL = 8, 6226 PSYS_SRC_ACCEL = 8,
6227 PSYS_SRC_PATTERN = 9, 6227 PSYS_SRC_PATTERN = 9,
6228 PSYS_SRC_INNERANGLE = 10, 6228 PSYS_SRC_INNERANGLE = 10,
6229 PSYS_SRC_OUTERANGLE = 11, 6229 PSYS_SRC_OUTERANGLE = 11,
6230 PSYS_SRC_TEXTURE = 12, 6230 PSYS_SRC_TEXTURE = 12,
6231 PSYS_SRC_BURST_RATE = 13, 6231 PSYS_SRC_BURST_RATE = 13,
6232 PSYS_SRC_BURST_PART_COUNT = 15, 6232 PSYS_SRC_BURST_PART_COUNT = 15,
6233 PSYS_SRC_BURST_RADIUS = 16, 6233 PSYS_SRC_BURST_RADIUS = 16,
6234 PSYS_SRC_BURST_SPEED_MIN = 17, 6234 PSYS_SRC_BURST_SPEED_MIN = 17,
6235 PSYS_SRC_BURST_SPEED_MAX = 18, 6235 PSYS_SRC_BURST_SPEED_MAX = 18,
6236 PSYS_SRC_MAX_AGE = 19, 6236 PSYS_SRC_MAX_AGE = 19,
6237 PSYS_SRC_TARGET_KEY = 20, 6237 PSYS_SRC_TARGET_KEY = 20,
6238 PSYS_SRC_OMEGA = 21, 6238 PSYS_SRC_OMEGA = 21,
6239 PSYS_SRC_ANGLE_BEGIN = 22, 6239 PSYS_SRC_ANGLE_BEGIN = 22,
6240 PSYS_SRC_ANGLE_END = 23 6240 PSYS_SRC_ANGLE_END = 23
6241 } 6241 }
6242   6242  
6243 internal Primitive.ParticleSystem.ParticleDataFlags ConvertUINTtoFlags(uint flags) 6243 internal Primitive.ParticleSystem.ParticleDataFlags ConvertUINTtoFlags(uint flags)
6244 { 6244 {
6245 Primitive.ParticleSystem.ParticleDataFlags returnval = Primitive.ParticleSystem.ParticleDataFlags.None; 6245 Primitive.ParticleSystem.ParticleDataFlags returnval = Primitive.ParticleSystem.ParticleDataFlags.None;
6246   6246  
6247 return returnval; 6247 return returnval;
6248 } 6248 }
6249   6249  
6250 protected Primitive.ParticleSystem getNewParticleSystemWithSLDefaultValues() 6250 protected Primitive.ParticleSystem getNewParticleSystemWithSLDefaultValues()
6251 { 6251 {
6252 Primitive.ParticleSystem ps = new Primitive.ParticleSystem(); 6252 Primitive.ParticleSystem ps = new Primitive.ParticleSystem();
6253   6253  
6254 // TODO find out about the other defaults and add them here 6254 // TODO find out about the other defaults and add them here
6255 ps.PartStartColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f); 6255 ps.PartStartColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
6256 ps.PartEndColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f); 6256 ps.PartEndColor = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
6257 ps.PartStartScaleX = 1.0f; 6257 ps.PartStartScaleX = 1.0f;
6258 ps.PartStartScaleY = 1.0f; 6258 ps.PartStartScaleY = 1.0f;
6259 ps.PartEndScaleX = 1.0f; 6259 ps.PartEndScaleX = 1.0f;
6260 ps.PartEndScaleY = 1.0f; 6260 ps.PartEndScaleY = 1.0f;
6261 ps.BurstSpeedMin = 1.0f; 6261 ps.BurstSpeedMin = 1.0f;
6262 ps.BurstSpeedMax = 1.0f; 6262 ps.BurstSpeedMax = 1.0f;
6263 ps.BurstRate = 0.1f; 6263 ps.BurstRate = 0.1f;
6264 ps.PartMaxAge = 10.0f; 6264 ps.PartMaxAge = 10.0f;
6265 ps.BurstPartCount = 1; 6265 ps.BurstPartCount = 1;
6266 return ps; 6266 return ps;
6267 } 6267 }
6268   6268  
6269 public void llLinkParticleSystem(int linknumber, LSL_List rules) 6269 public void llLinkParticleSystem(int linknumber, LSL_List rules)
6270 { 6270 {
6271 m_host.AddScriptLPS(1); 6271 m_host.AddScriptLPS(1);
6272   6272  
6273 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6273 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6274   6274  
6275 foreach (SceneObjectPart part in parts) 6275 foreach (SceneObjectPart part in parts)
6276 { 6276 {
6277 SetParticleSystem(part, rules); 6277 SetParticleSystem(part, rules);
6278 } 6278 }
6279 } 6279 }
6280   6280  
6281 public void llParticleSystem(LSL_List rules) 6281 public void llParticleSystem(LSL_List rules)
6282 { 6282 {
6283 m_host.AddScriptLPS(1); 6283 m_host.AddScriptLPS(1);
6284 SetParticleSystem(m_host, rules); 6284 SetParticleSystem(m_host, rules);
6285 } 6285 }
6286   6286  
6287 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6287 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6288 { 6288 {
6289 if (rules.Length == 0) 6289 if (rules.Length == 0)
6290 { 6290 {
6291 part.RemoveParticleSystem(); 6291 part.RemoveParticleSystem();
6292 part.ParentGroup.HasGroupChanged = true; 6292 part.ParentGroup.HasGroupChanged = true;
6293 } 6293 }
6294 else 6294 else
6295 { 6295 {
6296 Primitive.ParticleSystem prules = getNewParticleSystemWithSLDefaultValues(); 6296 Primitive.ParticleSystem prules = getNewParticleSystemWithSLDefaultValues();
6297 LSL_Vector tempv = new LSL_Vector(); 6297 LSL_Vector tempv = new LSL_Vector();
6298   6298  
6299 float tempf = 0; 6299 float tempf = 0;
6300   6300  
6301 for (int i = 0; i < rules.Length; i += 2) 6301 for (int i = 0; i < rules.Length; i += 2)
6302 { 6302 {
6303 switch (rules.GetLSLIntegerItem(i)) 6303 switch (rules.GetLSLIntegerItem(i))
6304 { 6304 {
6305 case (int)ScriptBaseClass.PSYS_PART_FLAGS: 6305 case (int)ScriptBaseClass.PSYS_PART_FLAGS:
6306 prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); 6306 prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1);
6307 break; 6307 break;
6308   6308  
6309 case (int)ScriptBaseClass.PSYS_PART_START_COLOR: 6309 case (int)ScriptBaseClass.PSYS_PART_START_COLOR:
6310 tempv = rules.GetVector3Item(i + 1); 6310 tempv = rules.GetVector3Item(i + 1);
6311 prules.PartStartColor.R = (float)tempv.x; 6311 prules.PartStartColor.R = (float)tempv.x;
6312 prules.PartStartColor.G = (float)tempv.y; 6312 prules.PartStartColor.G = (float)tempv.y;
6313 prules.PartStartColor.B = (float)tempv.z; 6313 prules.PartStartColor.B = (float)tempv.z;
6314 break; 6314 break;
6315   6315  
6316 case (int)ScriptBaseClass.PSYS_PART_START_ALPHA: 6316 case (int)ScriptBaseClass.PSYS_PART_START_ALPHA:
6317 tempf = (float)rules.GetLSLFloatItem(i + 1); 6317 tempf = (float)rules.GetLSLFloatItem(i + 1);
6318 prules.PartStartColor.A = tempf; 6318 prules.PartStartColor.A = tempf;
6319 break; 6319 break;
6320   6320  
6321 case (int)ScriptBaseClass.PSYS_PART_END_COLOR: 6321 case (int)ScriptBaseClass.PSYS_PART_END_COLOR:
6322 tempv = rules.GetVector3Item(i + 1); 6322 tempv = rules.GetVector3Item(i + 1);
6323 prules.PartEndColor.R = (float)tempv.x; 6323 prules.PartEndColor.R = (float)tempv.x;
6324 prules.PartEndColor.G = (float)tempv.y; 6324 prules.PartEndColor.G = (float)tempv.y;
6325 prules.PartEndColor.B = (float)tempv.z; 6325 prules.PartEndColor.B = (float)tempv.z;
6326 break; 6326 break;
6327   6327  
6328 case (int)ScriptBaseClass.PSYS_PART_END_ALPHA: 6328 case (int)ScriptBaseClass.PSYS_PART_END_ALPHA:
6329 tempf = (float)rules.GetLSLFloatItem(i + 1); 6329 tempf = (float)rules.GetLSLFloatItem(i + 1);
6330 prules.PartEndColor.A = tempf; 6330 prules.PartEndColor.A = tempf;
6331 break; 6331 break;
6332   6332  
6333 case (int)ScriptBaseClass.PSYS_PART_START_SCALE: 6333 case (int)ScriptBaseClass.PSYS_PART_START_SCALE:
6334 tempv = rules.GetVector3Item(i + 1); 6334 tempv = rules.GetVector3Item(i + 1);
6335 prules.PartStartScaleX = (float)tempv.x; 6335 prules.PartStartScaleX = (float)tempv.x;
6336 prules.PartStartScaleY = (float)tempv.y; 6336 prules.PartStartScaleY = (float)tempv.y;
6337 break; 6337 break;
6338   6338  
6339 case (int)ScriptBaseClass.PSYS_PART_END_SCALE: 6339 case (int)ScriptBaseClass.PSYS_PART_END_SCALE:
6340 tempv = rules.GetVector3Item(i + 1); 6340 tempv = rules.GetVector3Item(i + 1);
6341 prules.PartEndScaleX = (float)tempv.x; 6341 prules.PartEndScaleX = (float)tempv.x;
6342 prules.PartEndScaleY = (float)tempv.y; 6342 prules.PartEndScaleY = (float)tempv.y;
6343 break; 6343 break;
6344   6344  
6345 case (int)ScriptBaseClass.PSYS_PART_MAX_AGE: 6345 case (int)ScriptBaseClass.PSYS_PART_MAX_AGE:
6346 tempf = (float)rules.GetLSLFloatItem(i + 1); 6346 tempf = (float)rules.GetLSLFloatItem(i + 1);
6347 prules.PartMaxAge = tempf; 6347 prules.PartMaxAge = tempf;
6348 break; 6348 break;
6349   6349  
6350 case (int)ScriptBaseClass.PSYS_SRC_ACCEL: 6350 case (int)ScriptBaseClass.PSYS_SRC_ACCEL:
6351 tempv = rules.GetVector3Item(i + 1); 6351 tempv = rules.GetVector3Item(i + 1);
6352 prules.PartAcceleration.X = (float)tempv.x; 6352 prules.PartAcceleration.X = (float)tempv.x;
6353 prules.PartAcceleration.Y = (float)tempv.y; 6353 prules.PartAcceleration.Y = (float)tempv.y;
6354 prules.PartAcceleration.Z = (float)tempv.z; 6354 prules.PartAcceleration.Z = (float)tempv.z;
6355 break; 6355 break;
6356   6356  
6357 case (int)ScriptBaseClass.PSYS_SRC_PATTERN: 6357 case (int)ScriptBaseClass.PSYS_SRC_PATTERN:
6358 int tmpi = (int)rules.GetLSLIntegerItem(i + 1); 6358 int tmpi = (int)rules.GetLSLIntegerItem(i + 1);
6359 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; 6359 prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi;
6360 break; 6360 break;
6361   6361  
6362 // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The 6362 // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The
6363 // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The 6363 // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The
6364 // client tells the difference between the two by looking at the 0x02 bit in 6364 // client tells the difference between the two by looking at the 0x02 bit in
6365 // the PartFlags variable. 6365 // the PartFlags variable.
6366 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: 6366 case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE:
6367 tempf = (float)rules.GetLSLFloatItem(i + 1); 6367 tempf = (float)rules.GetLSLFloatItem(i + 1);
6368 prules.InnerAngle = (float)tempf; 6368 prules.InnerAngle = (float)tempf;
6369 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. 6369 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6370 break; 6370 break;
6371   6371  
6372 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: 6372 case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE:
6373 tempf = (float)rules.GetLSLFloatItem(i + 1); 6373 tempf = (float)rules.GetLSLFloatItem(i + 1);
6374 prules.OuterAngle = (float)tempf; 6374 prules.OuterAngle = (float)tempf;
6375 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. 6375 prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off.
6376 break; 6376 break;
6377   6377  
6378 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6378 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6379 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1)); 6379 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1));
6380 break; 6380 break;
6381   6381  
6382 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: 6382 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE:
6383 tempf = (float)rules.GetLSLFloatItem(i + 1); 6383 tempf = (float)rules.GetLSLFloatItem(i + 1);
6384 prules.BurstRate = (float)tempf; 6384 prules.BurstRate = (float)tempf;
6385 break; 6385 break;
6386   6386  
6387 case (int)ScriptBaseClass.PSYS_SRC_BURST_PART_COUNT: 6387 case (int)ScriptBaseClass.PSYS_SRC_BURST_PART_COUNT:
6388 prules.BurstPartCount = (byte)(int)rules.GetLSLIntegerItem(i + 1); 6388 prules.BurstPartCount = (byte)(int)rules.GetLSLIntegerItem(i + 1);
6389 break; 6389 break;
6390   6390  
6391 case (int)ScriptBaseClass.PSYS_SRC_BURST_RADIUS: 6391 case (int)ScriptBaseClass.PSYS_SRC_BURST_RADIUS:
6392 tempf = (float)rules.GetLSLFloatItem(i + 1); 6392 tempf = (float)rules.GetLSLFloatItem(i + 1);
6393 prules.BurstRadius = (float)tempf; 6393 prules.BurstRadius = (float)tempf;
6394 break; 6394 break;
6395   6395  
6396 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MIN: 6396 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MIN:
6397 tempf = (float)rules.GetLSLFloatItem(i + 1); 6397 tempf = (float)rules.GetLSLFloatItem(i + 1);
6398 prules.BurstSpeedMin = (float)tempf; 6398 prules.BurstSpeedMin = (float)tempf;
6399 break; 6399 break;
6400   6400  
6401 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MAX: 6401 case (int)ScriptBaseClass.PSYS_SRC_BURST_SPEED_MAX:
6402 tempf = (float)rules.GetLSLFloatItem(i + 1); 6402 tempf = (float)rules.GetLSLFloatItem(i + 1);
6403 prules.BurstSpeedMax = (float)tempf; 6403 prules.BurstSpeedMax = (float)tempf;
6404 break; 6404 break;
6405   6405  
6406 case (int)ScriptBaseClass.PSYS_SRC_MAX_AGE: 6406 case (int)ScriptBaseClass.PSYS_SRC_MAX_AGE:
6407 tempf = (float)rules.GetLSLFloatItem(i + 1); 6407 tempf = (float)rules.GetLSLFloatItem(i + 1);
6408 prules.MaxAge = (float)tempf; 6408 prules.MaxAge = (float)tempf;
6409 break; 6409 break;
6410   6410  
6411 case (int)ScriptBaseClass.PSYS_SRC_TARGET_KEY: 6411 case (int)ScriptBaseClass.PSYS_SRC_TARGET_KEY:
6412 UUID key = UUID.Zero; 6412 UUID key = UUID.Zero;
6413 if (UUID.TryParse(rules.Data[i + 1].ToString(), out key)) 6413 if (UUID.TryParse(rules.Data[i + 1].ToString(), out key))
6414 { 6414 {
6415 prules.Target = key; 6415 prules.Target = key;
6416 } 6416 }
6417 else 6417 else
6418 { 6418 {
6419 prules.Target = part.UUID; 6419 prules.Target = part.UUID;
6420 } 6420 }
6421 break; 6421 break;
6422   6422  
6423 case (int)ScriptBaseClass.PSYS_SRC_OMEGA: 6423 case (int)ScriptBaseClass.PSYS_SRC_OMEGA:
6424 // AL: This is an assumption, since it is the only thing that would match. 6424 // AL: This is an assumption, since it is the only thing that would match.
6425 tempv = rules.GetVector3Item(i + 1); 6425 tempv = rules.GetVector3Item(i + 1);
6426 prules.AngularVelocity.X = (float)tempv.x; 6426 prules.AngularVelocity.X = (float)tempv.x;
6427 prules.AngularVelocity.Y = (float)tempv.y; 6427 prules.AngularVelocity.Y = (float)tempv.y;
6428 prules.AngularVelocity.Z = (float)tempv.z; 6428 prules.AngularVelocity.Z = (float)tempv.z;
6429 break; 6429 break;
6430   6430  
6431 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN: 6431 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN:
6432 tempf = (float)rules.GetLSLFloatItem(i + 1); 6432 tempf = (float)rules.GetLSLFloatItem(i + 1);
6433 prules.InnerAngle = (float)tempf; 6433 prules.InnerAngle = (float)tempf;
6434 prules.PartFlags |= 0x02; // Set new angle format. 6434 prules.PartFlags |= 0x02; // Set new angle format.
6435 break; 6435 break;
6436   6436  
6437 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END: 6437 case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END:
6438 tempf = (float)rules.GetLSLFloatItem(i + 1); 6438 tempf = (float)rules.GetLSLFloatItem(i + 1);
6439 prules.OuterAngle = (float)tempf; 6439 prules.OuterAngle = (float)tempf;
6440 prules.PartFlags |= 0x02; // Set new angle format. 6440 prules.PartFlags |= 0x02; // Set new angle format.
6441 break; 6441 break;
6442 } 6442 }
6443   6443  
6444 } 6444 }
6445 prules.CRC = 1; 6445 prules.CRC = 1;
6446   6446  
6447 part.AddNewParticleSystem(prules); 6447 part.AddNewParticleSystem(prules);
6448 part.ParentGroup.HasGroupChanged = true; 6448 part.ParentGroup.HasGroupChanged = true;
6449 } 6449 }
6450 part.SendFullUpdateToAllClients(); 6450 part.SendFullUpdateToAllClients();
6451 } 6451 }
6452   6452  
6453 public void llGroundRepel(double height, int water, double tau) 6453 public void llGroundRepel(double height, int water, double tau)
6454 { 6454 {
6455 m_host.AddScriptLPS(1); 6455 m_host.AddScriptLPS(1);
6456 if (m_host.PhysActor != null) 6456 if (m_host.PhysActor != null)
6457 { 6457 {
6458 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0)); 6458 float ground = (float)llGround(new LSL_Types.Vector3(0, 0, 0));
6459 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0)); 6459 float waterLevel = (float)llWater(new LSL_Types.Vector3(0, 0, 0));
6460 PIDHoverType hoverType = PIDHoverType.Ground; 6460 PIDHoverType hoverType = PIDHoverType.Ground;
6461 if (water != 0) 6461 if (water != 0)
6462 { 6462 {
6463 hoverType = PIDHoverType.GroundAndWater; 6463 hoverType = PIDHoverType.GroundAndWater;
6464 if (ground < waterLevel) 6464 if (ground < waterLevel)
6465 height += waterLevel; 6465 height += waterLevel;
6466 else 6466 else
6467 height += ground; 6467 height += ground;
6468 } 6468 }
6469 else 6469 else
6470 { 6470 {
6471 height += ground; 6471 height += ground;
6472 } 6472 }
6473   6473  
6474 m_host.SetHoverHeight((float)height, hoverType, (float)tau); 6474 m_host.SetHoverHeight((float)height, hoverType, (float)tau);
6475 } 6475 }
6476 } 6476 }
6477   6477  
6478 public void llGiveInventoryList(string destination, string category, LSL_List inventory) 6478 public void llGiveInventoryList(string destination, string category, LSL_List inventory)
6479 { 6479 {
6480 m_host.AddScriptLPS(1); 6480 m_host.AddScriptLPS(1);
6481   6481  
6482 UUID destID; 6482 UUID destID;
6483 if (!UUID.TryParse(destination, out destID)) 6483 if (!UUID.TryParse(destination, out destID))
6484 return; 6484 return;
6485   6485  
6486 List<UUID> itemList = new List<UUID>(); 6486 List<UUID> itemList = new List<UUID>();
6487   6487  
6488 foreach (Object item in inventory.Data) 6488 foreach (Object item in inventory.Data)
6489 { 6489 {
6490 string rawItemString = item.ToString(); 6490 string rawItemString = item.ToString();
6491   6491  
6492 UUID itemID; 6492 UUID itemID;
6493 if (UUID.TryParse(rawItemString, out itemID)) 6493 if (UUID.TryParse(rawItemString, out itemID))
6494 { 6494 {
6495 itemList.Add(itemID); 6495 itemList.Add(itemID);
6496 } 6496 }
6497 else 6497 else
6498 { 6498 {
6499 TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString); 6499 TaskInventoryItem taskItem = m_host.Inventory.GetInventoryItem(rawItemString);
6500   6500  
6501 if (taskItem != null) 6501 if (taskItem != null)
6502 itemList.Add(taskItem.ItemID); 6502 itemList.Add(taskItem.ItemID);
6503 } 6503 }
6504 } 6504 }
6505   6505  
6506 if (itemList.Count == 0) 6506 if (itemList.Count == 0)
6507 return; 6507 return;
6508   6508  
6509 UUID folderID = m_ScriptEngine.World.MoveTaskInventoryItems(destID, category, m_host, itemList); 6509 UUID folderID = m_ScriptEngine.World.MoveTaskInventoryItems(destID, category, m_host, itemList);
6510   6510  
6511 if (folderID == UUID.Zero) 6511 if (folderID == UUID.Zero)
6512 return; 6512 return;
6513   6513  
6514 if (m_TransferModule != null) 6514 if (m_TransferModule != null)
6515 { 6515 {
6516 byte[] bucket = new byte[] { (byte)AssetType.Folder }; 6516 byte[] bucket = new byte[] { (byte)AssetType.Folder };
6517   6517  
6518 Vector3 pos = m_host.AbsolutePosition; 6518 Vector3 pos = m_host.AbsolutePosition;
6519   6519  
6520 GridInstantMessage msg = new GridInstantMessage(World, 6520 GridInstantMessage msg = new GridInstantMessage(World,
6521 m_host.OwnerID, m_host.Name, destID, 6521 m_host.OwnerID, m_host.Name, destID,
6522 (byte)InstantMessageDialog.TaskInventoryOffered, 6522 (byte)InstantMessageDialog.TaskInventoryOffered,
6523 false, string.Format("'{0}'", category), 6523 false, string.Format("'{0}'", category),
6524 // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 6524 // We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6525 // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), 6525 // false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6526 folderID, false, pos, 6526 folderID, false, pos,
6527 bucket, false); 6527 bucket, false);
6528   6528  
6529 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 6529 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
6530 } 6530 }
6531 } 6531 }
6532   6532  
6533 public void llSetVehicleType(int type) 6533 public void llSetVehicleType(int type)
6534 { 6534 {
6535 m_host.AddScriptLPS(1); 6535 m_host.AddScriptLPS(1);
6536   6536  
6537 if (!m_host.ParentGroup.IsDeleted) 6537 if (!m_host.ParentGroup.IsDeleted)
6538 { 6538 {
6539 m_host.ParentGroup.RootPart.SetVehicleType(type); 6539 m_host.ParentGroup.RootPart.SetVehicleType(type);
6540 } 6540 }
6541 } 6541 }
6542   6542  
6543 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6543 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6544 //CFK 9/28: so these are not complete yet. 6544 //CFK 9/28: so these are not complete yet.
6545 public void llSetVehicleFloatParam(int param, LSL_Float value) 6545 public void llSetVehicleFloatParam(int param, LSL_Float value)
6546 { 6546 {
6547 m_host.AddScriptLPS(1); 6547 m_host.AddScriptLPS(1);
6548   6548  
6549 if (!m_host.ParentGroup.IsDeleted) 6549 if (!m_host.ParentGroup.IsDeleted)
6550 { 6550 {
6551 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value); 6551 m_host.ParentGroup.RootPart.SetVehicleFloatParam(param, (float)value);
6552 } 6552 }
6553 } 6553 }
6554   6554  
6555 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6555 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6556 //CFK 9/28: so these are not complete yet. 6556 //CFK 9/28: so these are not complete yet.
6557 public void llSetVehicleVectorParam(int param, LSL_Vector vec) 6557 public void llSetVehicleVectorParam(int param, LSL_Vector vec)
6558 { 6558 {
6559 m_host.AddScriptLPS(1); 6559 m_host.AddScriptLPS(1);
6560   6560  
6561 if (!m_host.ParentGroup.IsDeleted) 6561 if (!m_host.ParentGroup.IsDeleted)
6562 { 6562 {
6563 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec); 6563 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
6564 } 6564 }
6565 } 6565 }
6566   6566  
6567 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in 6567 //CFK 9/28: Most, but not all of the underlying plumbing between here and the physics modules is in
6568 //CFK 9/28: so these are not complete yet. 6568 //CFK 9/28: so these are not complete yet.
6569 public void llSetVehicleRotationParam(int param, LSL_Rotation rot) 6569 public void llSetVehicleRotationParam(int param, LSL_Rotation rot)
6570 { 6570 {
6571 m_host.AddScriptLPS(1); 6571 m_host.AddScriptLPS(1);
6572   6572  
6573 if (!m_host.ParentGroup.IsDeleted) 6573 if (!m_host.ParentGroup.IsDeleted)
6574 { 6574 {
6575 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); 6575 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
6576 } 6576 }
6577 } 6577 }
6578   6578  
6579 public void llSetVehicleFlags(int flags) 6579 public void llSetVehicleFlags(int flags)
6580 { 6580 {
6581 m_host.AddScriptLPS(1); 6581 m_host.AddScriptLPS(1);
6582   6582  
6583 if (!m_host.ParentGroup.IsDeleted) 6583 if (!m_host.ParentGroup.IsDeleted)
6584 { 6584 {
6585 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false); 6585 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, false);
6586 } 6586 }
6587 } 6587 }
6588   6588  
6589 public void llRemoveVehicleFlags(int flags) 6589 public void llRemoveVehicleFlags(int flags)
6590 { 6590 {
6591 m_host.AddScriptLPS(1); 6591 m_host.AddScriptLPS(1);
6592   6592  
6593 if (!m_host.ParentGroup.IsDeleted) 6593 if (!m_host.ParentGroup.IsDeleted)
6594 { 6594 {
6595 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true); 6595 m_host.ParentGroup.RootPart.SetVehicleFlags(flags, true);
6596 } 6596 }
6597 } 6597 }
6598   6598  
6599 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6599 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6600 { 6600 {
6601 part.SitTargetPosition = offset; 6601 part.SitTargetPosition = offset;
6602 part.SitTargetOrientation = rot; 6602 part.SitTargetOrientation = rot;
6603 part.ParentGroup.HasGroupChanged = true; 6603 part.ParentGroup.HasGroupChanged = true;
6604 } 6604 }
6605   6605  
6606 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) 6606 public void llSitTarget(LSL_Vector offset, LSL_Rotation rot)
6607 { 6607 {
6608 m_host.AddScriptLPS(1); 6608 m_host.AddScriptLPS(1);
6609 SitTarget(m_host, offset, rot); 6609 SitTarget(m_host, offset, rot);
6610 } 6610 }
6611   6611  
6612 public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot) 6612 public void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot)
6613 { 6613 {
6614 m_host.AddScriptLPS(1); 6614 m_host.AddScriptLPS(1);
6615 if (link == ScriptBaseClass.LINK_ROOT) 6615 if (link == ScriptBaseClass.LINK_ROOT)
6616 SitTarget(m_host.ParentGroup.RootPart, offset, rot); 6616 SitTarget(m_host.ParentGroup.RootPart, offset, rot);
6617 else if (link == ScriptBaseClass.LINK_THIS) 6617 else if (link == ScriptBaseClass.LINK_THIS)
6618 SitTarget(m_host, offset, rot); 6618 SitTarget(m_host, offset, rot);
6619 else 6619 else
6620 { 6620 {
6621 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 6621 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
6622 if (null != part) 6622 if (null != part)
6623 { 6623 {
6624 SitTarget(part, offset, rot); 6624 SitTarget(part, offset, rot);
6625 } 6625 }
6626 } 6626 }
6627 } 6627 }
6628   6628  
6629 public LSL_String llAvatarOnSitTarget() 6629 public LSL_String llAvatarOnSitTarget()
6630 { 6630 {
6631 m_host.AddScriptLPS(1); 6631 m_host.AddScriptLPS(1);
6632 return m_host.SitTargetAvatar.ToString(); 6632 return m_host.SitTargetAvatar.ToString();
6633 } 6633 }
6634   6634  
6635 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget 6635 // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget
6636 public LSL_String llAvatarOnLinkSitTarget(int linknum) 6636 public LSL_String llAvatarOnLinkSitTarget(int linknum)
6637 { 6637 {
6638 m_host.AddScriptLPS(1); 6638 m_host.AddScriptLPS(1);
6639 if(linknum == ScriptBaseClass.LINK_SET || 6639 if(linknum == ScriptBaseClass.LINK_SET ||
6640 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 6640 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
6641 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 6641 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
6642   6642  
6643 List<SceneObjectPart> parts = GetLinkParts(linknum); 6643 List<SceneObjectPart> parts = GetLinkParts(linknum);
6644 if (parts.Count == 0) return UUID.Zero.ToString(); 6644 if (parts.Count == 0) return UUID.Zero.ToString();
6645 return parts[0].SitTargetAvatar.ToString(); 6645 return parts[0].SitTargetAvatar.ToString();
6646 } 6646 }
6647   6647  
6648   6648  
6649 public void llAddToLandPassList(string avatar, double hours) 6649 public void llAddToLandPassList(string avatar, double hours)
6650 { 6650 {
6651 m_host.AddScriptLPS(1); 6651 m_host.AddScriptLPS(1);
6652 UUID key; 6652 UUID key;
6653 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 6653 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
6654   6654  
6655 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 6655 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
6656 { 6656 {
6657 int expires = 0; 6657 int expires = 0;
6658 if (hours != 0) 6658 if (hours != 0)
6659 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours); 6659 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours);
6660   6660  
6661 if (UUID.TryParse(avatar, out key)) 6661 if (UUID.TryParse(avatar, out key))
6662 { 6662 {
6663 int idx = land.LandData.ParcelAccessList.FindIndex( 6663 int idx = land.LandData.ParcelAccessList.FindIndex(
6664 delegate(LandAccessEntry e) 6664 delegate(LandAccessEntry e)
6665 { 6665 {
6666 if (e.AgentID == key && e.Flags == AccessList.Access) 6666 if (e.AgentID == key && e.Flags == AccessList.Access)
6667 return true; 6667 return true;
6668 return false; 6668 return false;
6669 }); 6669 });
6670   6670  
6671 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires))) 6671 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires)))
6672 return; 6672 return;
6673   6673  
6674 if (idx != -1) 6674 if (idx != -1)
6675 land.LandData.ParcelAccessList.RemoveAt(idx); 6675 land.LandData.ParcelAccessList.RemoveAt(idx);
6676   6676  
6677 LandAccessEntry entry = new LandAccessEntry(); 6677 LandAccessEntry entry = new LandAccessEntry();
6678   6678  
6679 entry.AgentID = key; 6679 entry.AgentID = key;
6680 entry.Flags = AccessList.Access; 6680 entry.Flags = AccessList.Access;
6681 entry.Expires = expires; 6681 entry.Expires = expires;
6682   6682  
6683 land.LandData.ParcelAccessList.Add(entry); 6683 land.LandData.ParcelAccessList.Add(entry);
6684   6684  
6685 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 6685 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
6686 } 6686 }
6687 } 6687 }
6688 ScriptSleep(100); 6688 ScriptSleep(100);
6689 } 6689 }
6690   6690  
6691 public void llSetTouchText(string text) 6691 public void llSetTouchText(string text)
6692 { 6692 {
6693 m_host.AddScriptLPS(1); 6693 m_host.AddScriptLPS(1);
6694 m_host.TouchName = text; 6694 m_host.TouchName = text;
6695 } 6695 }
6696   6696  
6697 public void llSetSitText(string text) 6697 public void llSetSitText(string text)
6698 { 6698 {
6699 m_host.AddScriptLPS(1); 6699 m_host.AddScriptLPS(1);
6700 m_host.SitName = text; 6700 m_host.SitName = text;
6701 } 6701 }
6702   6702  
6703 public void llSetCameraEyeOffset(LSL_Vector offset) 6703 public void llSetCameraEyeOffset(LSL_Vector offset)
6704 { 6704 {
6705 m_host.AddScriptLPS(1); 6705 m_host.AddScriptLPS(1);
6706 m_host.SetCameraEyeOffset(offset); 6706 m_host.SetCameraEyeOffset(offset);
6707 } 6707 }
6708   6708  
6709 public void llSetCameraAtOffset(LSL_Vector offset) 6709 public void llSetCameraAtOffset(LSL_Vector offset)
6710 { 6710 {
6711 m_host.AddScriptLPS(1); 6711 m_host.AddScriptLPS(1);
6712 m_host.SetCameraAtOffset(offset); 6712 m_host.SetCameraAtOffset(offset);
6713 } 6713 }
6714   6714  
6715 public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) 6715 public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at)
6716 { 6716 {
6717 m_host.AddScriptLPS(1); 6717 m_host.AddScriptLPS(1);
6718   6718  
6719 if (link == ScriptBaseClass.LINK_SET || 6719 if (link == ScriptBaseClass.LINK_SET ||
6720 link == ScriptBaseClass.LINK_ALL_CHILDREN || 6720 link == ScriptBaseClass.LINK_ALL_CHILDREN ||
6721 link == ScriptBaseClass.LINK_ALL_OTHERS) return; 6721 link == ScriptBaseClass.LINK_ALL_OTHERS) return;
6722   6722  
6723 SceneObjectPart part = null; 6723 SceneObjectPart part = null;
6724   6724  
6725 switch (link) 6725 switch (link)
6726 { 6726 {
6727 case ScriptBaseClass.LINK_ROOT: 6727 case ScriptBaseClass.LINK_ROOT:
6728 part = m_host.ParentGroup.RootPart; 6728 part = m_host.ParentGroup.RootPart;
6729 break; 6729 break;
6730 case ScriptBaseClass.LINK_THIS: 6730 case ScriptBaseClass.LINK_THIS:
6731 part = m_host; 6731 part = m_host;
6732 break; 6732 break;
6733 default: 6733 default:
6734 part = m_host.ParentGroup.GetLinkNumPart(link); 6734 part = m_host.ParentGroup.GetLinkNumPart(link);
6735 break; 6735 break;
6736 } 6736 }
6737   6737  
6738 if (null != part) 6738 if (null != part)
6739 { 6739 {
6740 part.SetCameraEyeOffset(eye); 6740 part.SetCameraEyeOffset(eye);
6741 part.SetCameraAtOffset(at); 6741 part.SetCameraAtOffset(at);
6742 } 6742 }
6743 } 6743 }
6744   6744  
6745 public LSL_String llDumpList2String(LSL_List src, string seperator) 6745 public LSL_String llDumpList2String(LSL_List src, string seperator)
6746 { 6746 {
6747 m_host.AddScriptLPS(1); 6747 m_host.AddScriptLPS(1);
6748 if (src.Length == 0) 6748 if (src.Length == 0)
6749 { 6749 {
6750 return String.Empty; 6750 return String.Empty;
6751 } 6751 }
6752 string ret = String.Empty; 6752 string ret = String.Empty;
6753 foreach (object o in src.Data) 6753 foreach (object o in src.Data)
6754 { 6754 {
6755 ret = ret + o.ToString() + seperator; 6755 ret = ret + o.ToString() + seperator;
6756 } 6756 }
6757 ret = ret.Substring(0, ret.Length - seperator.Length); 6757 ret = ret.Substring(0, ret.Length - seperator.Length);
6758 return ret; 6758 return ret;
6759 } 6759 }
6760   6760  
6761 public LSL_Integer llScriptDanger(LSL_Vector pos) 6761 public LSL_Integer llScriptDanger(LSL_Vector pos)
6762 { 6762 {
6763 m_host.AddScriptLPS(1); 6763 m_host.AddScriptLPS(1);
6764 bool result = World.ScriptDanger(m_host.LocalId, pos); 6764 bool result = World.ScriptDanger(m_host.LocalId, pos);
6765 if (result) 6765 if (result)
6766 { 6766 {
6767 return 1; 6767 return 1;
6768 } 6768 }
6769 else 6769 else
6770 { 6770 {
6771 return 0; 6771 return 0;
6772 } 6772 }
6773   6773  
6774 } 6774 }
6775   6775  
6776 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel) 6776 public void llDialog(string avatar, string message, LSL_List buttons, int chat_channel)
6777 { 6777 {
6778 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 6778 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
6779   6779  
6780 if (dm == null) 6780 if (dm == null)
6781 return; 6781 return;
6782   6782  
6783 m_host.AddScriptLPS(1); 6783 m_host.AddScriptLPS(1);
6784 UUID av = new UUID(); 6784 UUID av = new UUID();
6785 if (!UUID.TryParse(avatar,out av)) 6785 if (!UUID.TryParse(avatar,out av))
6786 { 6786 {
6787 LSLError("First parameter to llDialog needs to be a key"); 6787 LSLError("First parameter to llDialog needs to be a key");
6788 return; 6788 return;
6789 } 6789 }
6790 if (buttons.Length < 1) 6790 if (buttons.Length < 1)
6791 { 6791 {
6792 LSLError("No less than 1 button can be shown"); 6792 LSLError("No less than 1 button can be shown");
6793 return; 6793 return;
6794 } 6794 }
6795 if (buttons.Length > 12) 6795 if (buttons.Length > 12)
6796 { 6796 {
6797 LSLError("No more than 12 buttons can be shown"); 6797 LSLError("No more than 12 buttons can be shown");
6798 return; 6798 return;
6799 } 6799 }
6800 string[] buts = new string[buttons.Length]; 6800 string[] buts = new string[buttons.Length];
6801 for (int i = 0; i < buttons.Length; i++) 6801 for (int i = 0; i < buttons.Length; i++)
6802 { 6802 {
6803 if (buttons.Data[i].ToString() == String.Empty) 6803 if (buttons.Data[i].ToString() == String.Empty)
6804 { 6804 {
6805 LSLError("button label cannot be blank"); 6805 LSLError("button label cannot be blank");
6806 return; 6806 return;
6807 } 6807 }
6808 if (buttons.Data[i].ToString().Length > 24) 6808 if (buttons.Data[i].ToString().Length > 24)
6809 { 6809 {
6810 LSLError("button label cannot be longer than 24 characters"); 6810 LSLError("button label cannot be longer than 24 characters");
6811 return; 6811 return;
6812 } 6812 }
6813 buts[i] = buttons.Data[i].ToString(); 6813 buts[i] = buttons.Data[i].ToString();
6814 } 6814 }
6815   6815  
6816 dm.SendDialogToUser( 6816 dm.SendDialogToUser(
6817 av, m_host.Name, m_host.UUID, m_host.OwnerID, 6817 av, m_host.Name, m_host.UUID, m_host.OwnerID,
6818 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts); 6818 message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buts);
6819   6819  
6820 ScriptSleep(1000); 6820 ScriptSleep(1000);
6821 } 6821 }
6822   6822  
6823 public void llVolumeDetect(int detect) 6823 public void llVolumeDetect(int detect)
6824 { 6824 {
6825 m_host.AddScriptLPS(1); 6825 m_host.AddScriptLPS(1);
6826   6826  
6827 if (!m_host.ParentGroup.IsDeleted) 6827 if (!m_host.ParentGroup.IsDeleted)
6828 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0); 6828 m_host.ParentGroup.ScriptSetVolumeDetect(detect != 0);
6829 } 6829 }
6830   6830  
6831 /// <summary> 6831 /// <summary>
6832 /// This is a depecated function so this just replicates the result of 6832 /// This is a depecated function so this just replicates the result of
6833 /// invoking it in SL 6833 /// invoking it in SL
6834 /// </summary> 6834 /// </summary>
6835 public void llRemoteLoadScript(string target, string name, int running, int start_param) 6835 public void llRemoteLoadScript(string target, string name, int running, int start_param)
6836 { 6836 {
6837 m_host.AddScriptLPS(1); 6837 m_host.AddScriptLPS(1);
6838 // Report an error as it does in SL 6838 // Report an error as it does in SL
6839 ShoutError("Deprecated. Please use llRemoteLoadScriptPin instead."); 6839 ShoutError("Deprecated. Please use llRemoteLoadScriptPin instead.");
6840 ScriptSleep(3000); 6840 ScriptSleep(3000);
6841 } 6841 }
6842   6842  
6843 public void llSetRemoteScriptAccessPin(int pin) 6843 public void llSetRemoteScriptAccessPin(int pin)
6844 { 6844 {
6845 m_host.AddScriptLPS(1); 6845 m_host.AddScriptLPS(1);
6846 m_host.ScriptAccessPin = pin; 6846 m_host.ScriptAccessPin = pin;
6847 } 6847 }
6848   6848  
6849 public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) 6849 public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param)
6850 { 6850 {
6851 m_host.AddScriptLPS(1); 6851 m_host.AddScriptLPS(1);
6852   6852  
6853 UUID destId = UUID.Zero; 6853 UUID destId = UUID.Zero;
6854   6854  
6855 if (!UUID.TryParse(target, out destId)) 6855 if (!UUID.TryParse(target, out destId))
6856 { 6856 {
6857 llSay(0, "Could not parse key " + target); 6857 llSay(0, "Could not parse key " + target);
6858 return; 6858 return;
6859 } 6859 }
6860   6860  
6861 // target must be a different prim than the one containing the script 6861 // target must be a different prim than the one containing the script
6862 if (m_host.UUID == destId) 6862 if (m_host.UUID == destId)
6863 { 6863 {
6864 return; 6864 return;
6865 } 6865 }
6866   6866  
6867 // copy the first script found with this inventory name 6867 // copy the first script found with this inventory name
6868 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 6868 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
6869   6869  
6870 // make sure the object is a script 6870 // make sure the object is a script
6871 if (item == null || item.Type != 10) 6871 if (item == null || item.Type != 10)
6872 { 6872 {
6873 llSay(0, "Could not find script " + name); 6873 llSay(0, "Could not find script " + name);
6874 return; 6874 return;
6875 } 6875 }
6876   6876  
6877 // the rest of the permission checks are done in RezScript, so check the pin there as well 6877 // the rest of the permission checks are done in RezScript, so check the pin there as well
6878 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 6878 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6879   6879  
6880 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6880 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6881 ScriptSleep(3000); 6881 ScriptSleep(3000);
6882 } 6882 }
6883   6883  
6884 public void llOpenRemoteDataChannel() 6884 public void llOpenRemoteDataChannel()
6885 { 6885 {
6886 m_host.AddScriptLPS(1); 6886 m_host.AddScriptLPS(1);
6887 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6887 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6888 if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) 6888 if (xmlrpcMod != null && xmlrpcMod.IsEnabled())
6889 { 6889 {
6890 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); 6890 UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero);
6891 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); 6891 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
6892 if (xmlRpcRouter != null) 6892 if (xmlRpcRouter != null)
6893 { 6893 {
6894 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName; 6894 string ExternalHostName = m_ScriptEngine.World.RegionInfo.ExternalHostName;
6895   6895  
6896 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID, 6896 xmlRpcRouter.RegisterNewReceiver(m_ScriptEngine.ScriptModule, channelID, m_host.UUID,
6897 m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName, 6897 m_item.ItemID, String.Format("http://{0}:{1}/", ExternalHostName,
6898 xmlrpcMod.Port.ToString())); 6898 xmlrpcMod.Port.ToString()));
6899 } 6899 }
6900 object[] resobj = new object[] 6900 object[] resobj = new object[]
6901 { 6901 {
6902 new LSL_Integer(1), 6902 new LSL_Integer(1),
6903 new LSL_String(channelID.ToString()), 6903 new LSL_String(channelID.ToString()),
6904 new LSL_String(UUID.Zero.ToString()), 6904 new LSL_String(UUID.Zero.ToString()),
6905 new LSL_String(String.Empty), 6905 new LSL_String(String.Empty),
6906 new LSL_Integer(0), 6906 new LSL_Integer(0),
6907 new LSL_String(String.Empty) 6907 new LSL_String(String.Empty)
6908 }; 6908 };
6909 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj, 6909 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams("remote_data", resobj,
6910 new DetectParams[0])); 6910 new DetectParams[0]));
6911 } 6911 }
6912 ScriptSleep(1000); 6912 ScriptSleep(1000);
6913 } 6913 }
6914   6914  
6915 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) 6915 public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata)
6916 { 6916 {
6917 m_host.AddScriptLPS(1); 6917 m_host.AddScriptLPS(1);
6918 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6918 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6919 ScriptSleep(3000); 6919 ScriptSleep(3000);
6920 if (xmlrpcMod == null) 6920 if (xmlrpcMod == null)
6921 return ""; 6921 return "";
6922 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); 6922 return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString();
6923 } 6923 }
6924   6924  
6925 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) 6925 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
6926 { 6926 {
6927 m_host.AddScriptLPS(1); 6927 m_host.AddScriptLPS(1);
6928 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6928 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6929 if (xmlrpcMod != null) 6929 if (xmlrpcMod != null)
6930 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); 6930 xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata);
6931 ScriptSleep(3000); 6931 ScriptSleep(3000);
6932 } 6932 }
6933   6933  
6934 public void llCloseRemoteDataChannel(string channel) 6934 public void llCloseRemoteDataChannel(string channel)
6935 { 6935 {
6936 m_host.AddScriptLPS(1); 6936 m_host.AddScriptLPS(1);
6937   6937  
6938 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>(); 6938 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
6939 if (xmlRpcRouter != null) 6939 if (xmlRpcRouter != null)
6940 { 6940 {
6941 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID); 6941 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID);
6942 } 6942 }
6943   6943  
6944 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 6944 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
6945 if (xmlrpcMod != null) 6945 if (xmlrpcMod != null)
6946 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 6946 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
6947 ScriptSleep(1000); 6947 ScriptSleep(1000);
6948 } 6948 }
6949   6949  
6950 public LSL_String llMD5String(string src, int nonce) 6950 public LSL_String llMD5String(string src, int nonce)
6951 { 6951 {
6952 m_host.AddScriptLPS(1); 6952 m_host.AddScriptLPS(1);
6953 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 6953 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()));
6954 } 6954 }
6955   6955  
6956 public LSL_String llSHA1String(string src) 6956 public LSL_String llSHA1String(string src)
6957 { 6957 {
6958 m_host.AddScriptLPS(1); 6958 m_host.AddScriptLPS(1);
6959 return Util.SHA1Hash(src).ToLower(); 6959 return Util.SHA1Hash(src).ToLower();
6960 } 6960 }
6961   6961  
6962 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 6962 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6963 { 6963 {
6964 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 6964 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6965 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6965 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6966   6966  
6967 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6967 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6968 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6968 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
6969 holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE && 6969 holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE &&
6970 holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE) 6970 holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE)
6971 { 6971 {
6972 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT; 6972 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
6973 } 6973 }
6974 shapeBlock.PathCurve = pathcurve; 6974 shapeBlock.PathCurve = pathcurve;
6975 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape. 6975 shapeBlock.ProfileCurve = (byte)holeshape; // Set the hole shape.
6976 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape. 6976 shapeBlock.ProfileCurve += profileshape; // Add in the profile shape.
6977 if (cut.x < 0f) 6977 if (cut.x < 0f)
6978 { 6978 {
6979 cut.x = 0f; 6979 cut.x = 0f;
6980 } 6980 }
6981 if (cut.x > 1f) 6981 if (cut.x > 1f)
6982 { 6982 {
6983 cut.x = 1f; 6983 cut.x = 1f;
6984 } 6984 }
6985 if (cut.y < 0f) 6985 if (cut.y < 0f)
6986 { 6986 {
6987 cut.y = 0f; 6987 cut.y = 0f;
6988 } 6988 }
6989 if (cut.y > 1f) 6989 if (cut.y > 1f)
6990 { 6990 {
6991 cut.y = 1f; 6991 cut.y = 1f;
6992 } 6992 }
6993 if (cut.y - cut.x < 0.05f) 6993 if (cut.y - cut.x < 0.05f)
6994 { 6994 {
6995 cut.x = cut.y - 0.05f; 6995 cut.x = cut.y - 0.05f;
6996 if (cut.x < 0.0f) 6996 if (cut.x < 0.0f)
6997 { 6997 {
6998 cut.x = 0.0f; 6998 cut.x = 0.0f;
6999 cut.y = 0.05f; 6999 cut.y = 0.05f;
7000 } 7000 }
7001 } 7001 }
7002 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x); 7002 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x);
7003 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y)); 7003 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y));
7004 if (hollow < 0f) 7004 if (hollow < 0f)
7005 { 7005 {
7006 hollow = 0f; 7006 hollow = 0f;
7007 } 7007 }
7008 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a 7008 // If the prim is a Cylinder, Prism, Sphere, Torus or Ring (or not a
7009 // Box or Tube) and the hole shape is a square, hollow is limited to 7009 // Box or Tube) and the hole shape is a square, hollow is limited to
7010 // a max of 70%. The viewer performs its own check on this value but 7010 // a max of 70%. The viewer performs its own check on this value but
7011 // we need to do it here also so llGetPrimitiveParams can have access 7011 // we need to do it here also so llGetPrimitiveParams can have access
7012 // to the correct value. 7012 // to the correct value.
7013 if (profileshape != (byte)ProfileCurve.Square && 7013 if (profileshape != (byte)ProfileCurve.Square &&
7014 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE) 7014 holeshape == (int)ScriptBaseClass.PRIM_HOLE_SQUARE)
7015 { 7015 {
7016 if (hollow > 0.70f) 7016 if (hollow > 0.70f)
7017 { 7017 {
7018 hollow = 0.70f; 7018 hollow = 0.70f;
7019 } 7019 }
7020 } 7020 }
7021 // Otherwise, hollow is limited to 95%. 7021 // Otherwise, hollow is limited to 95%.
7022 else 7022 else
7023 { 7023 {
7024 if (hollow > 0.95f) 7024 if (hollow > 0.95f)
7025 { 7025 {
7026 hollow = 0.95f; 7026 hollow = 0.95f;
7027 } 7027 }
7028 } 7028 }
7029 shapeBlock.ProfileHollow = (ushort)(50000 * hollow); 7029 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
7030 if (twist.x < -1.0f) 7030 if (twist.x < -1.0f)
7031 { 7031 {
7032 twist.x = -1.0f; 7032 twist.x = -1.0f;
7033 } 7033 }
7034 if (twist.x > 1.0f) 7034 if (twist.x > 1.0f)
7035 { 7035 {
7036 twist.x = 1.0f; 7036 twist.x = 1.0f;
7037 } 7037 }
7038 if (twist.y < -1.0f) 7038 if (twist.y < -1.0f)
7039 { 7039 {
7040 twist.y = -1.0f; 7040 twist.y = -1.0f;
7041 } 7041 }
7042 if (twist.y > 1.0f) 7042 if (twist.y > 1.0f)
7043 { 7043 {
7044 twist.y = 1.0f; 7044 twist.y = 1.0f;
7045 } 7045 }
7046 // A fairly large precision error occurs for some calculations, 7046 // A fairly large precision error occurs for some calculations,
7047 // if a float or double is directly cast to a byte or sbyte 7047 // if a float or double is directly cast to a byte or sbyte
7048 // variable, in both .Net and Mono. In .Net, coding 7048 // variable, in both .Net and Mono. In .Net, coding
7049 // "(sbyte)(float)(some expression)" corrects the precision 7049 // "(sbyte)(float)(some expression)" corrects the precision
7050 // errors. But this does not work for Mono. This longer coding 7050 // errors. But this does not work for Mono. This longer coding
7051 // form of creating a tempoary float variable from the 7051 // form of creating a tempoary float variable from the
7052 // expression first, then casting that variable to a byte or 7052 // expression first, then casting that variable to a byte or
7053 // sbyte, works for both .Net and Mono. These types of 7053 // sbyte, works for both .Net and Mono. These types of
7054 // assignments occur in SetPrimtiveBlockShapeParams and 7054 // assignments occur in SetPrimtiveBlockShapeParams and
7055 // SetPrimitiveShapeParams in support of llSetPrimitiveParams. 7055 // SetPrimitiveShapeParams in support of llSetPrimitiveParams.
7056 tempFloat = (float)(100.0d * twist.x); 7056 tempFloat = (float)(100.0d * twist.x);
7057 shapeBlock.PathTwistBegin = (sbyte)tempFloat; 7057 shapeBlock.PathTwistBegin = (sbyte)tempFloat;
7058 tempFloat = (float)(100.0d * twist.y); 7058 tempFloat = (float)(100.0d * twist.y);
7059 shapeBlock.PathTwist = (sbyte)tempFloat; 7059 shapeBlock.PathTwist = (sbyte)tempFloat;
7060   7060  
7061 shapeBlock.ObjectLocalID = part.LocalId; 7061 shapeBlock.ObjectLocalID = part.LocalId;
7062   7062  
7063 part.Shape.SculptEntry = false; 7063 part.Shape.SculptEntry = false;
7064 return shapeBlock; 7064 return shapeBlock;
7065 } 7065 }
7066   7066  
7067 // Prim type box, cylinder and prism. 7067 // Prim type box, cylinder and prism.
7068 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) 7068 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)
7069 { 7069 {
7070 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7070 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7071 ObjectShapePacket.ObjectDataBlock shapeBlock; 7071 ObjectShapePacket.ObjectDataBlock shapeBlock;
7072   7072  
7073 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7073 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7074   7074  
7075 if (taper_b.x < 0f) 7075 if (taper_b.x < 0f)
7076 { 7076 {
7077 taper_b.x = 0f; 7077 taper_b.x = 0f;
7078 } 7078 }
7079 if (taper_b.x > 2f) 7079 if (taper_b.x > 2f)
7080 { 7080 {
7081 taper_b.x = 2f; 7081 taper_b.x = 2f;
7082 } 7082 }
7083 if (taper_b.y < 0f) 7083 if (taper_b.y < 0f)
7084 { 7084 {
7085 taper_b.y = 0f; 7085 taper_b.y = 0f;
7086 } 7086 }
7087 if (taper_b.y > 2f) 7087 if (taper_b.y > 2f)
7088 { 7088 {
7089 taper_b.y = 2f; 7089 taper_b.y = 2f;
7090 } 7090 }
7091 tempFloat = (float)(100.0d * (2.0d - taper_b.x)); 7091 tempFloat = (float)(100.0d * (2.0d - taper_b.x));
7092 shapeBlock.PathScaleX = (byte)tempFloat; 7092 shapeBlock.PathScaleX = (byte)tempFloat;
7093 tempFloat = (float)(100.0d * (2.0d - taper_b.y)); 7093 tempFloat = (float)(100.0d * (2.0d - taper_b.y));
7094 shapeBlock.PathScaleY = (byte)tempFloat; 7094 shapeBlock.PathScaleY = (byte)tempFloat;
7095 if (topshear.x < -0.5f) 7095 if (topshear.x < -0.5f)
7096 { 7096 {
7097 topshear.x = -0.5f; 7097 topshear.x = -0.5f;
7098 } 7098 }
7099 if (topshear.x > 0.5f) 7099 if (topshear.x > 0.5f)
7100 { 7100 {
7101 topshear.x = 0.5f; 7101 topshear.x = 0.5f;
7102 } 7102 }
7103 if (topshear.y < -0.5f) 7103 if (topshear.y < -0.5f)
7104 { 7104 {
7105 topshear.y = -0.5f; 7105 topshear.y = -0.5f;
7106 } 7106 }
7107 if (topshear.y > 0.5f) 7107 if (topshear.y > 0.5f)
7108 { 7108 {
7109 topshear.y = 0.5f; 7109 topshear.y = 0.5f;
7110 } 7110 }
7111 tempFloat = (float)(100.0d * topshear.x); 7111 tempFloat = (float)(100.0d * topshear.x);
7112 shapeBlock.PathShearX = (byte)tempFloat; 7112 shapeBlock.PathShearX = (byte)tempFloat;
7113 tempFloat = (float)(100.0d * topshear.y); 7113 tempFloat = (float)(100.0d * topshear.y);
7114 shapeBlock.PathShearY = (byte)tempFloat; 7114 shapeBlock.PathShearY = (byte)tempFloat;
7115   7115  
7116 part.Shape.SculptEntry = false; 7116 part.Shape.SculptEntry = false;
7117 part.UpdateShape(shapeBlock); 7117 part.UpdateShape(shapeBlock);
7118 } 7118 }
7119   7119  
7120 // Prim type sphere. 7120 // Prim type sphere.
7121 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7121 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7122 { 7122 {
7123 ObjectShapePacket.ObjectDataBlock shapeBlock; 7123 ObjectShapePacket.ObjectDataBlock shapeBlock;
7124   7124  
7125 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7125 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7126   7126  
7127 // profile/path swapped for a sphere 7127 // profile/path swapped for a sphere
7128 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7128 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7129 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7129 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7130   7130  
7131 shapeBlock.PathScaleX = 100; 7131 shapeBlock.PathScaleX = 100;
7132 shapeBlock.PathScaleY = 100; 7132 shapeBlock.PathScaleY = 100;
7133   7133  
7134 if (dimple.x < 0f) 7134 if (dimple.x < 0f)
7135 { 7135 {
7136 dimple.x = 0f; 7136 dimple.x = 0f;
7137 } 7137 }
7138 if (dimple.x > 1f) 7138 if (dimple.x > 1f)
7139 { 7139 {
7140 dimple.x = 1f; 7140 dimple.x = 1f;
7141 } 7141 }
7142 if (dimple.y < 0f) 7142 if (dimple.y < 0f)
7143 { 7143 {
7144 dimple.y = 0f; 7144 dimple.y = 0f;
7145 } 7145 }
7146 if (dimple.y > 1f) 7146 if (dimple.y > 1f)
7147 { 7147 {
7148 dimple.y = 1f; 7148 dimple.y = 1f;
7149 } 7149 }
7150 if (dimple.y - cut.x < 0.05f) 7150 if (dimple.y - cut.x < 0.05f)
7151 { 7151 {
7152 dimple.x = cut.y - 0.05f; 7152 dimple.x = cut.y - 0.05f;
7153 } 7153 }
7154 shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x); 7154 shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x);
7155 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y)); 7155 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y));
7156   7156  
7157 part.Shape.SculptEntry = false; 7157 part.Shape.SculptEntry = false;
7158 part.UpdateShape(shapeBlock); 7158 part.UpdateShape(shapeBlock);
7159 } 7159 }
7160   7160  
7161 // Prim type torus, tube and ring. 7161 // Prim type torus, tube and ring.
7162 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) 7162 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)
7163 { 7163 {
7164 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7164 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7165 ObjectShapePacket.ObjectDataBlock shapeBlock; 7165 ObjectShapePacket.ObjectDataBlock shapeBlock;
7166   7166  
7167 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7167 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
7168   7168  
7169 // profile/path swapped for a torrus, tube, ring 7169 // profile/path swapped for a torrus, tube, ring
7170 shapeBlock.PathBegin = shapeBlock.ProfileBegin; 7170 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
7171 shapeBlock.PathEnd = shapeBlock.ProfileEnd; 7171 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
7172   7172  
7173 if (holesize.x < 0.05f) 7173 if (holesize.x < 0.05f)
7174 { 7174 {
7175 holesize.x = 0.05f; 7175 holesize.x = 0.05f;
7176 } 7176 }
7177 if (holesize.x > 1f) 7177 if (holesize.x > 1f)
7178 { 7178 {
7179 holesize.x = 1f; 7179 holesize.x = 1f;
7180 } 7180 }
7181 if (holesize.y < 0.05f) 7181 if (holesize.y < 0.05f)
7182 { 7182 {
7183 holesize.y = 0.05f; 7183 holesize.y = 0.05f;
7184 } 7184 }
7185 if (holesize.y > 0.5f) 7185 if (holesize.y > 0.5f)
7186 { 7186 {
7187 holesize.y = 0.5f; 7187 holesize.y = 0.5f;
7188 } 7188 }
7189 tempFloat = (float)(100.0d * (2.0d - holesize.x)); 7189 tempFloat = (float)(100.0d * (2.0d - holesize.x));
7190 shapeBlock.PathScaleX = (byte)tempFloat; 7190 shapeBlock.PathScaleX = (byte)tempFloat;
7191 tempFloat = (float)(100.0d * (2.0d - holesize.y)); 7191 tempFloat = (float)(100.0d * (2.0d - holesize.y));
7192 shapeBlock.PathScaleY = (byte)tempFloat; 7192 shapeBlock.PathScaleY = (byte)tempFloat;
7193 if (topshear.x < -0.5f) 7193 if (topshear.x < -0.5f)
7194 { 7194 {
7195 topshear.x = -0.5f; 7195 topshear.x = -0.5f;
7196 } 7196 }
7197 if (topshear.x > 0.5f) 7197 if (topshear.x > 0.5f)
7198 { 7198 {
7199 topshear.x = 0.5f; 7199 topshear.x = 0.5f;
7200 } 7200 }
7201 if (topshear.y < -0.5f) 7201 if (topshear.y < -0.5f)
7202 { 7202 {
7203 topshear.y = -0.5f; 7203 topshear.y = -0.5f;
7204 } 7204 }
7205 if (topshear.y > 0.5f) 7205 if (topshear.y > 0.5f)
7206 { 7206 {
7207 topshear.y = 0.5f; 7207 topshear.y = 0.5f;
7208 } 7208 }
7209 tempFloat = (float)(100.0d * topshear.x); 7209 tempFloat = (float)(100.0d * topshear.x);
7210 shapeBlock.PathShearX = (byte)tempFloat; 7210 shapeBlock.PathShearX = (byte)tempFloat;
7211 tempFloat = (float)(100.0d * topshear.y); 7211 tempFloat = (float)(100.0d * topshear.y);
7212 shapeBlock.PathShearY = (byte)tempFloat; 7212 shapeBlock.PathShearY = (byte)tempFloat;
7213 if (profilecut.x < 0f) 7213 if (profilecut.x < 0f)
7214 { 7214 {
7215 profilecut.x = 0f; 7215 profilecut.x = 0f;
7216 } 7216 }
7217 if (profilecut.x > 1f) 7217 if (profilecut.x > 1f)
7218 { 7218 {
7219 profilecut.x = 1f; 7219 profilecut.x = 1f;
7220 } 7220 }
7221 if (profilecut.y < 0f) 7221 if (profilecut.y < 0f)
7222 { 7222 {
7223 profilecut.y = 0f; 7223 profilecut.y = 0f;
7224 } 7224 }
7225 if (profilecut.y > 1f) 7225 if (profilecut.y > 1f)
7226 { 7226 {
7227 profilecut.y = 1f; 7227 profilecut.y = 1f;
7228 } 7228 }
7229 if (profilecut.y - profilecut.x < 0.05f) 7229 if (profilecut.y - profilecut.x < 0.05f)
7230 { 7230 {
7231 profilecut.x = profilecut.y - 0.05f; 7231 profilecut.x = profilecut.y - 0.05f;
7232 if (profilecut.x < 0.0f) 7232 if (profilecut.x < 0.0f)
7233 { 7233 {
7234 profilecut.x = 0.0f; 7234 profilecut.x = 0.0f;
7235 profilecut.y = 0.05f; 7235 profilecut.y = 0.05f;
7236 } 7236 }
7237 } 7237 }
7238 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); 7238 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x);
7239 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y)); 7239 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y));
7240 if (taper_a.x < -1f) 7240 if (taper_a.x < -1f)
7241 { 7241 {
7242 taper_a.x = -1f; 7242 taper_a.x = -1f;
7243 } 7243 }
7244 if (taper_a.x > 1f) 7244 if (taper_a.x > 1f)
7245 { 7245 {
7246 taper_a.x = 1f; 7246 taper_a.x = 1f;
7247 } 7247 }
7248 if (taper_a.y < -1f) 7248 if (taper_a.y < -1f)
7249 { 7249 {
7250 taper_a.y = -1f; 7250 taper_a.y = -1f;
7251 } 7251 }
7252 if (taper_a.y > 1f) 7252 if (taper_a.y > 1f)
7253 { 7253 {
7254 taper_a.y = 1f; 7254 taper_a.y = 1f;
7255 } 7255 }
7256 tempFloat = (float)(100.0d * taper_a.x); 7256 tempFloat = (float)(100.0d * taper_a.x);
7257 shapeBlock.PathTaperX = (sbyte)tempFloat; 7257 shapeBlock.PathTaperX = (sbyte)tempFloat;
7258 tempFloat = (float)(100.0d * taper_a.y); 7258 tempFloat = (float)(100.0d * taper_a.y);
7259 shapeBlock.PathTaperY = (sbyte)tempFloat; 7259 shapeBlock.PathTaperY = (sbyte)tempFloat;
7260 if (revolutions < 1f) 7260 if (revolutions < 1f)
7261 { 7261 {
7262 revolutions = 1f; 7262 revolutions = 1f;
7263 } 7263 }
7264 if (revolutions > 4f) 7264 if (revolutions > 4f)
7265 { 7265 {
7266 revolutions = 4f; 7266 revolutions = 4f;
7267 } 7267 }
7268 tempFloat = 66.66667f * (revolutions - 1.0f); 7268 tempFloat = 66.66667f * (revolutions - 1.0f);
7269 shapeBlock.PathRevolutions = (byte)tempFloat; 7269 shapeBlock.PathRevolutions = (byte)tempFloat;
7270 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1 7270 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
7271 if (radiusoffset < 0f) 7271 if (radiusoffset < 0f)
7272 { 7272 {
7273 radiusoffset = 0f; 7273 radiusoffset = 0f;
7274 } 7274 }
7275 if (radiusoffset > 1f) 7275 if (radiusoffset > 1f)
7276 { 7276 {
7277 radiusoffset = 1f; 7277 radiusoffset = 1f;
7278 } 7278 }
7279 tempFloat = 100.0f * radiusoffset; 7279 tempFloat = 100.0f * radiusoffset;
7280 shapeBlock.PathRadiusOffset = (sbyte)tempFloat; 7280 shapeBlock.PathRadiusOffset = (sbyte)tempFloat;
7281 if (skew < -0.95f) 7281 if (skew < -0.95f)
7282 { 7282 {
7283 skew = -0.95f; 7283 skew = -0.95f;
7284 } 7284 }
7285 if (skew > 0.95f) 7285 if (skew > 0.95f)
7286 { 7286 {
7287 skew = 0.95f; 7287 skew = 0.95f;
7288 } 7288 }
7289 tempFloat = 100.0f * skew; 7289 tempFloat = 100.0f * skew;
7290 shapeBlock.PathSkew = (sbyte)tempFloat; 7290 shapeBlock.PathSkew = (sbyte)tempFloat;
7291   7291  
7292 part.Shape.SculptEntry = false; 7292 part.Shape.SculptEntry = false;
7293 part.UpdateShape(shapeBlock); 7293 part.UpdateShape(shapeBlock);
7294 } 7294 }
7295   7295  
7296 // Prim type sculpt. 7296 // Prim type sculpt.
7297 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7297 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7298 { 7298 {
7299 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7299 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7300 UUID sculptId; 7300 UUID sculptId;
7301   7301  
7302 if (!UUID.TryParse(map, out sculptId)) 7302 if (!UUID.TryParse(map, out sculptId))
7303 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture); 7303 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture);
7304   7304  
7305 if (sculptId == UUID.Zero) 7305 if (sculptId == UUID.Zero)
7306 return; 7306 return;
7307   7307  
7308 shapeBlock.PathCurve = pathcurve; 7308 shapeBlock.PathCurve = pathcurve;
7309 shapeBlock.ObjectLocalID = part.LocalId; 7309 shapeBlock.ObjectLocalID = part.LocalId;
7310 shapeBlock.PathScaleX = 100; 7310 shapeBlock.PathScaleX = 100;
7311 shapeBlock.PathScaleY = 150; 7311 shapeBlock.PathScaleY = 150;
7312   7312  
7313 int flag = type & (ScriptBaseClass.PRIM_SCULPT_FLAG_INVERT | ScriptBaseClass.PRIM_SCULPT_FLAG_MIRROR); 7313 int flag = type & (ScriptBaseClass.PRIM_SCULPT_FLAG_INVERT | ScriptBaseClass.PRIM_SCULPT_FLAG_MIRROR);
7314   7314  
7315 if (type != (ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER | flag) && 7315 if (type != (ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER | flag) &&
7316 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE | flag) && 7316 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE | flag) &&
7317 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE | flag) && 7317 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE | flag) &&
7318 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7318 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7319 { 7319 {
7320 // default 7320 // default
7321 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7321 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7322 } 7322 }
7323   7323  
7324 part.Shape.SetSculptProperties((byte)type, sculptId); 7324 part.Shape.SetSculptProperties((byte)type, sculptId);
7325 part.Shape.SculptEntry = true; 7325 part.Shape.SculptEntry = true;
7326 part.UpdateShape(shapeBlock); 7326 part.UpdateShape(shapeBlock);
7327 } 7327 }
7328   7328  
7329 public void llSetPrimitiveParams(LSL_List rules) 7329 public void llSetPrimitiveParams(LSL_List rules)
7330 { 7330 {
7331 m_host.AddScriptLPS(1); 7331 m_host.AddScriptLPS(1);
7332   7332  
7333 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); 7333 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7334   7334  
7335 ScriptSleep(200); 7335 ScriptSleep(200);
7336 } 7336 }
7337   7337  
7338 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7338 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7339 { 7339 {
7340 m_host.AddScriptLPS(1); 7340 m_host.AddScriptLPS(1);
7341   7341  
7342 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7342 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7343   7343  
7344 ScriptSleep(200); 7344 ScriptSleep(200);
7345 } 7345 }
7346   7346  
7347 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7347 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7348 { 7348 {
7349 m_host.AddScriptLPS(1); 7349 m_host.AddScriptLPS(1);
7350   7350  
7351 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7351 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7352 } 7352 }
7353   7353  
7354 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7354 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7355 { 7355 {
7356 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7356 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7357   7357  
7358 LSL_List remaining = null; 7358 LSL_List remaining = null;
7359 uint rulesParsed = 0; 7359 uint rulesParsed = 0;
7360   7360  
7361 foreach (SceneObjectPart part in parts) 7361 foreach (SceneObjectPart part in parts)
7362 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7362 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7363   7363  
7364 while (remaining != null && remaining.Length > 2) 7364 while (remaining != null && remaining.Length > 2)
7365 { 7365 {
7366 linknumber = remaining.GetLSLIntegerItem(0); 7366 linknumber = remaining.GetLSLIntegerItem(0);
7367 rules = remaining.GetSublist(1, -1); 7367 rules = remaining.GetSublist(1, -1);
7368 parts = GetLinkParts(linknumber); 7368 parts = GetLinkParts(linknumber);
7369   7369  
7370 foreach (SceneObjectPart part in parts) 7370 foreach (SceneObjectPart part in parts)
7371 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7371 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7372 } 7372 }
7373 } 7373 }
7374   7374  
7375 public void llSetKeyframedMotion(LSL_List frames, LSL_List options) 7375 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7376 { 7376 {
7377 SceneObjectGroup group = m_host.ParentGroup; 7377 SceneObjectGroup group = m_host.ParentGroup;
7378   7378  
7379 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical) 7379 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7380 return; 7380 return;
7381 if (group.IsAttachment) 7381 if (group.IsAttachment)
7382 return; 7382 return;
7383   7383  
7384 if (frames.Data.Length > 0) // We are getting a new motion 7384 if (frames.Data.Length > 0) // We are getting a new motion
7385 { 7385 {
7386 if (group.RootPart.KeyframeMotion != null) 7386 if (group.RootPart.KeyframeMotion != null)
7387 group.RootPart.KeyframeMotion.Delete(); 7387 group.RootPart.KeyframeMotion.Delete();
7388 group.RootPart.KeyframeMotion = null; 7388 group.RootPart.KeyframeMotion = null;
7389   7389  
7390 int idx = 0; 7390 int idx = 0;
7391   7391  
7392 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward; 7392 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7393 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation; 7393 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7394   7394  
7395 while (idx < options.Data.Length) 7395 while (idx < options.Data.Length)
7396 { 7396 {
7397 int option = (int)options.GetLSLIntegerItem(idx++); 7397 int option = (int)options.GetLSLIntegerItem(idx++);
7398 int remain = options.Data.Length - idx; 7398 int remain = options.Data.Length - idx;
7399   7399  
7400 switch (option) 7400 switch (option)
7401 { 7401 {
7402 case ScriptBaseClass.KFM_MODE: 7402 case ScriptBaseClass.KFM_MODE:
7403 if (remain < 1) 7403 if (remain < 1)
7404 break; 7404 break;
7405 int modeval = (int)options.GetLSLIntegerItem(idx++); 7405 int modeval = (int)options.GetLSLIntegerItem(idx++);
7406 switch(modeval) 7406 switch(modeval)
7407 { 7407 {
7408 case ScriptBaseClass.KFM_FORWARD: 7408 case ScriptBaseClass.KFM_FORWARD:
7409 mode = KeyframeMotion.PlayMode.Forward; 7409 mode = KeyframeMotion.PlayMode.Forward;
7410 break; 7410 break;
7411 case ScriptBaseClass.KFM_REVERSE: 7411 case ScriptBaseClass.KFM_REVERSE:
7412 mode = KeyframeMotion.PlayMode.Reverse; 7412 mode = KeyframeMotion.PlayMode.Reverse;
7413 break; 7413 break;
7414 case ScriptBaseClass.KFM_LOOP: 7414 case ScriptBaseClass.KFM_LOOP:
7415 mode = KeyframeMotion.PlayMode.Loop; 7415 mode = KeyframeMotion.PlayMode.Loop;
7416 break; 7416 break;
7417 case ScriptBaseClass.KFM_PING_PONG: 7417 case ScriptBaseClass.KFM_PING_PONG:
7418 mode = KeyframeMotion.PlayMode.PingPong; 7418 mode = KeyframeMotion.PlayMode.PingPong;
7419 break; 7419 break;
7420 } 7420 }
7421 break; 7421 break;
7422 case ScriptBaseClass.KFM_DATA: 7422 case ScriptBaseClass.KFM_DATA:
7423 if (remain < 1) 7423 if (remain < 1)
7424 break; 7424 break;
7425 int dataval = (int)options.GetLSLIntegerItem(idx++); 7425 int dataval = (int)options.GetLSLIntegerItem(idx++);
7426 data = (KeyframeMotion.DataFormat)dataval; 7426 data = (KeyframeMotion.DataFormat)dataval;
7427 break; 7427 break;
7428 } 7428 }
7429 } 7429 }
7430   7430  
7431 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7431 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
7432   7432  
7433 idx = 0; 7433 idx = 0;
7434   7434  
7435 int elemLength = 2; 7435 int elemLength = 2;
7436 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7436 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
7437 elemLength = 3; 7437 elemLength = 3;
7438   7438  
7439 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7439 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
7440 while (idx < frames.Data.Length) 7440 while (idx < frames.Data.Length)
7441 { 7441 {
7442 int remain = frames.Data.Length - idx; 7442 int remain = frames.Data.Length - idx;
7443   7443  
7444 if (remain < elemLength) 7444 if (remain < elemLength)
7445 break; 7445 break;
7446   7446  
7447 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7447 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
7448 frame.Position = null; 7448 frame.Position = null;
7449 frame.Rotation = null; 7449 frame.Rotation = null;
7450   7450  
7451 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7451 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
7452 { 7452 {
7453 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7453 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
7454 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7454 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
7455 } 7455 }
7456 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7456 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
7457 { 7457 {
7458 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++); 7458 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7459 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s); 7459 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7460 q.Normalize(); 7460 q.Normalize();
7461 frame.Rotation = q; 7461 frame.Rotation = q;
7462 } 7462 }
7463   7463  
7464 float tempf = (float)frames.GetLSLFloatItem(idx++); 7464 float tempf = (float)frames.GetLSLFloatItem(idx++);
7465 frame.TimeMS = (int)(tempf * 1000.0f); 7465 frame.TimeMS = (int)(tempf * 1000.0f);
7466   7466  
7467 keyframes.Add(frame); 7467 keyframes.Add(frame);
7468 } 7468 }
7469   7469  
7470 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7470 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
7471 group.RootPart.KeyframeMotion.Start(); 7471 group.RootPart.KeyframeMotion.Start();
7472 } 7472 }
7473 else 7473 else
7474 { 7474 {
7475 if (group.RootPart.KeyframeMotion == null) 7475 if (group.RootPart.KeyframeMotion == null)
7476 return; 7476 return;
7477   7477  
7478 if (options.Data.Length == 0) 7478 if (options.Data.Length == 0)
7479 { 7479 {
7480 group.RootPart.KeyframeMotion.Stop(); 7480 group.RootPart.KeyframeMotion.Stop();
7481 return; 7481 return;
7482 } 7482 }
7483   7483  
7484 int idx = 0; 7484 int idx = 0;
7485   7485  
7486 while (idx < options.Data.Length) 7486 while (idx < options.Data.Length)
7487 { 7487 {
7488 int option = (int)options.GetLSLIntegerItem(idx++); 7488 int option = (int)options.GetLSLIntegerItem(idx++);
7489   7489  
7490 switch (option) 7490 switch (option)
7491 { 7491 {
7492 case ScriptBaseClass.KFM_COMMAND: 7492 case ScriptBaseClass.KFM_COMMAND:
7493 int cmd = (int)options.GetLSLIntegerItem(idx++); 7493 int cmd = (int)options.GetLSLIntegerItem(idx++);
7494 switch (cmd) 7494 switch (cmd)
7495 { 7495 {
7496 case ScriptBaseClass.KFM_CMD_PLAY: 7496 case ScriptBaseClass.KFM_CMD_PLAY:
7497 group.RootPart.KeyframeMotion.Start(); 7497 group.RootPart.KeyframeMotion.Start();
7498 break; 7498 break;
7499 case ScriptBaseClass.KFM_CMD_STOP: 7499 case ScriptBaseClass.KFM_CMD_STOP:
7500 group.RootPart.KeyframeMotion.Stop(); 7500 group.RootPart.KeyframeMotion.Stop();
7501 break; 7501 break;
7502 case ScriptBaseClass.KFM_CMD_PAUSE: 7502 case ScriptBaseClass.KFM_CMD_PAUSE:
7503 group.RootPart.KeyframeMotion.Pause(); 7503 group.RootPart.KeyframeMotion.Pause();
7504 break; 7504 break;
7505 } 7505 }
7506 break; 7506 break;
7507 } 7507 }
7508 } 7508 }
7509 } 7509 }
7510 } 7510 }
7511   7511  
7512 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7512 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7513 { 7513 {
7514 int idx = 0; 7514 int idx = 0;
7515 int idxStart = 0; 7515 int idxStart = 0;
7516   7516  
7517 bool positionChanged = false; 7517 bool positionChanged = false;
7518 LSL_Vector currentPosition = GetPartLocalPos(part); 7518 LSL_Vector currentPosition = GetPartLocalPos(part);
7519   7519  
7520 try 7520 try
7521 { 7521 {
7522 while (idx < rules.Length) 7522 while (idx < rules.Length)
7523 { 7523 {
7524 ++rulesParsed; 7524 ++rulesParsed;
7525 int code = rules.GetLSLIntegerItem(idx++); 7525 int code = rules.GetLSLIntegerItem(idx++);
7526   7526  
7527 int remain = rules.Length - idx; 7527 int remain = rules.Length - idx;
7528 idxStart = idx; 7528 idxStart = idx;
7529   7529  
7530 int face; 7530 int face;
7531 LSL_Vector v; 7531 LSL_Vector v;
7532   7532  
7533 switch (code) 7533 switch (code)
7534 { 7534 {
7535 case (int)ScriptBaseClass.PRIM_POSITION: 7535 case (int)ScriptBaseClass.PRIM_POSITION:
7536 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 7536 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7537 if (remain < 1) 7537 if (remain < 1)
7538 return null; 7538 return null;
7539   7539  
7540 v=rules.GetVector3Item(idx++); 7540 v=rules.GetVector3Item(idx++);
7541 positionChanged = true; 7541 positionChanged = true;
7542 currentPosition = GetSetPosTarget(part, v, currentPosition); 7542 currentPosition = GetSetPosTarget(part, v, currentPosition);
7543   7543  
7544 break; 7544 break;
7545 case (int)ScriptBaseClass.PRIM_SIZE: 7545 case (int)ScriptBaseClass.PRIM_SIZE:
7546 if (remain < 1) 7546 if (remain < 1)
7547 return null; 7547 return null;
7548   7548  
7549 v=rules.GetVector3Item(idx++); 7549 v=rules.GetVector3Item(idx++);
7550 SetScale(part, v); 7550 SetScale(part, v);
7551   7551  
7552 break; 7552 break;
7553 case (int)ScriptBaseClass.PRIM_ROTATION: 7553 case (int)ScriptBaseClass.PRIM_ROTATION:
7554 if (remain < 1) 7554 if (remain < 1)
7555 return null; 7555 return null;
7556   7556  
7557 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7557 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7558 // try to let this work as in SL... 7558 // try to let this work as in SL...
7559 if (part.ParentID == 0) 7559 if (part.ParentID == 0)
7560 { 7560 {
7561 // special case: If we are root, rotate complete SOG to new rotation 7561 // special case: If we are root, rotate complete SOG to new rotation
7562 SetRot(part, q); 7562 SetRot(part, q);
7563 } 7563 }
7564 else 7564 else
7565 { 7565 {
7566 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7566 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7567 SceneObjectPart rootPart = part.ParentGroup.RootPart; 7567 SceneObjectPart rootPart = part.ParentGroup.RootPart;
7568 SetRot(part, rootPart.RotationOffset * (Quaternion)q); 7568 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
7569 } 7569 }
7570   7570  
7571 break; 7571 break;
7572   7572  
7573 case (int)ScriptBaseClass.PRIM_TYPE: 7573 case (int)ScriptBaseClass.PRIM_TYPE:
7574 if (remain < 3) 7574 if (remain < 3)
7575 return null; 7575 return null;
7576   7576  
7577 code = (int)rules.GetLSLIntegerItem(idx++); 7577 code = (int)rules.GetLSLIntegerItem(idx++);
7578   7578  
7579 remain = rules.Length - idx; 7579 remain = rules.Length - idx;
7580 float hollow; 7580 float hollow;
7581 LSL_Vector twist; 7581 LSL_Vector twist;
7582 LSL_Vector taper_b; 7582 LSL_Vector taper_b;
7583 LSL_Vector topshear; 7583 LSL_Vector topshear;
7584 float revolutions; 7584 float revolutions;
7585 float radiusoffset; 7585 float radiusoffset;
7586 float skew; 7586 float skew;
7587 LSL_Vector holesize; 7587 LSL_Vector holesize;
7588 LSL_Vector profilecut; 7588 LSL_Vector profilecut;
7589   7589  
7590 switch (code) 7590 switch (code)
7591 { 7591 {
7592 case (int)ScriptBaseClass.PRIM_TYPE_BOX: 7592 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7593 if (remain < 6) 7593 if (remain < 6)
7594 return null; 7594 return null;
7595   7595  
7596 face = (int)rules.GetLSLIntegerItem(idx++); 7596 face = (int)rules.GetLSLIntegerItem(idx++);
7597 v = rules.GetVector3Item(idx++); // cut 7597 v = rules.GetVector3Item(idx++); // cut
7598 hollow = (float)rules.GetLSLFloatItem(idx++); 7598 hollow = (float)rules.GetLSLFloatItem(idx++);
7599 twist = rules.GetVector3Item(idx++); 7599 twist = rules.GetVector3Item(idx++);
7600 taper_b = rules.GetVector3Item(idx++); 7600 taper_b = rules.GetVector3Item(idx++);
7601 topshear = rules.GetVector3Item(idx++); 7601 topshear = rules.GetVector3Item(idx++);
7602   7602  
7603 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7603 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7604 (byte)ProfileShape.Square, (byte)Extrusion.Straight); 7604 (byte)ProfileShape.Square, (byte)Extrusion.Straight);
7605 break; 7605 break;
7606   7606  
7607 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: 7607 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7608 if (remain < 6) 7608 if (remain < 6)
7609 return null; 7609 return null;
7610   7610  
7611 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7611 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7612 v = rules.GetVector3Item(idx++); // cut 7612 v = rules.GetVector3Item(idx++); // cut
7613 hollow = (float)rules.GetLSLFloatItem(idx++); 7613 hollow = (float)rules.GetLSLFloatItem(idx++);
7614 twist = rules.GetVector3Item(idx++); 7614 twist = rules.GetVector3Item(idx++);
7615 taper_b = rules.GetVector3Item(idx++); 7615 taper_b = rules.GetVector3Item(idx++);
7616 topshear = rules.GetVector3Item(idx++); 7616 topshear = rules.GetVector3Item(idx++);
7617 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7617 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7618 (byte)ProfileShape.Circle, (byte)Extrusion.Straight); 7618 (byte)ProfileShape.Circle, (byte)Extrusion.Straight);
7619 break; 7619 break;
7620   7620  
7621 case (int)ScriptBaseClass.PRIM_TYPE_PRISM: 7621 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7622 if (remain < 6) 7622 if (remain < 6)
7623 return null; 7623 return null;
7624   7624  
7625 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7625 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7626 v = rules.GetVector3Item(idx++); //cut 7626 v = rules.GetVector3Item(idx++); //cut
7627 hollow = (float)rules.GetLSLFloatItem(idx++); 7627 hollow = (float)rules.GetLSLFloatItem(idx++);
7628 twist = rules.GetVector3Item(idx++); 7628 twist = rules.GetVector3Item(idx++);
7629 taper_b = rules.GetVector3Item(idx++); 7629 taper_b = rules.GetVector3Item(idx++);
7630 topshear = rules.GetVector3Item(idx++); 7630 topshear = rules.GetVector3Item(idx++);
7631 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear, 7631 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, topshear,
7632 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight); 7632 (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Straight);
7633 break; 7633 break;
7634   7634  
7635 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: 7635 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7636 if (remain < 5) 7636 if (remain < 5)
7637 return null; 7637 return null;
7638   7638  
7639 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7639 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7640 v = rules.GetVector3Item(idx++); // cut 7640 v = rules.GetVector3Item(idx++); // cut
7641 hollow = (float)rules.GetLSLFloatItem(idx++); 7641 hollow = (float)rules.GetLSLFloatItem(idx++);
7642 twist = rules.GetVector3Item(idx++); 7642 twist = rules.GetVector3Item(idx++);
7643 taper_b = rules.GetVector3Item(idx++); // dimple 7643 taper_b = rules.GetVector3Item(idx++); // dimple
7644 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b, 7644 SetPrimitiveShapeParams(part, face, v, hollow, twist, taper_b,
7645 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1); 7645 (byte)ProfileShape.HalfCircle, (byte)Extrusion.Curve1);
7646 break; 7646 break;
7647   7647  
7648 case (int)ScriptBaseClass.PRIM_TYPE_TORUS: 7648 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7649 if (remain < 11) 7649 if (remain < 11)
7650 return null; 7650 return null;
7651   7651  
7652 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7652 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7653 v = rules.GetVector3Item(idx++); //cut 7653 v = rules.GetVector3Item(idx++); //cut
7654 hollow = (float)rules.GetLSLFloatItem(idx++); 7654 hollow = (float)rules.GetLSLFloatItem(idx++);
7655 twist = rules.GetVector3Item(idx++); 7655 twist = rules.GetVector3Item(idx++);
7656 holesize = rules.GetVector3Item(idx++); 7656 holesize = rules.GetVector3Item(idx++);
7657 topshear = rules.GetVector3Item(idx++); 7657 topshear = rules.GetVector3Item(idx++);
7658 profilecut = rules.GetVector3Item(idx++); 7658 profilecut = rules.GetVector3Item(idx++);
7659 taper_b = rules.GetVector3Item(idx++); // taper_a 7659 taper_b = rules.GetVector3Item(idx++); // taper_a
7660 revolutions = (float)rules.GetLSLFloatItem(idx++); 7660 revolutions = (float)rules.GetLSLFloatItem(idx++);
7661 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7661 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7662 skew = (float)rules.GetLSLFloatItem(idx++); 7662 skew = (float)rules.GetLSLFloatItem(idx++);
7663 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7663 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7664 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1); 7664 revolutions, radiusoffset, skew, (byte)ProfileShape.Circle, (byte)Extrusion.Curve1);
7665 break; 7665 break;
7666   7666  
7667 case (int)ScriptBaseClass.PRIM_TYPE_TUBE: 7667 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7668 if (remain < 11) 7668 if (remain < 11)
7669 return null; 7669 return null;
7670   7670  
7671 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7671 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7672 v = rules.GetVector3Item(idx++); //cut 7672 v = rules.GetVector3Item(idx++); //cut
7673 hollow = (float)rules.GetLSLFloatItem(idx++); 7673 hollow = (float)rules.GetLSLFloatItem(idx++);
7674 twist = rules.GetVector3Item(idx++); 7674 twist = rules.GetVector3Item(idx++);
7675 holesize = rules.GetVector3Item(idx++); 7675 holesize = rules.GetVector3Item(idx++);
7676 topshear = rules.GetVector3Item(idx++); 7676 topshear = rules.GetVector3Item(idx++);
7677 profilecut = rules.GetVector3Item(idx++); 7677 profilecut = rules.GetVector3Item(idx++);
7678 taper_b = rules.GetVector3Item(idx++); // taper_a 7678 taper_b = rules.GetVector3Item(idx++); // taper_a
7679 revolutions = (float)rules.GetLSLFloatItem(idx++); 7679 revolutions = (float)rules.GetLSLFloatItem(idx++);
7680 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7680 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7681 skew = (float)rules.GetLSLFloatItem(idx++); 7681 skew = (float)rules.GetLSLFloatItem(idx++);
7682 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7682 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7683 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1); 7683 revolutions, radiusoffset, skew, (byte)ProfileShape.Square, (byte)Extrusion.Curve1);
7684 break; 7684 break;
7685   7685  
7686 case (int)ScriptBaseClass.PRIM_TYPE_RING: 7686 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7687 if (remain < 11) 7687 if (remain < 11)
7688 return null; 7688 return null;
7689   7689  
7690 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape 7690 face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
7691 v = rules.GetVector3Item(idx++); //cut 7691 v = rules.GetVector3Item(idx++); //cut
7692 hollow = (float)rules.GetLSLFloatItem(idx++); 7692 hollow = (float)rules.GetLSLFloatItem(idx++);
7693 twist = rules.GetVector3Item(idx++); 7693 twist = rules.GetVector3Item(idx++);
7694 holesize = rules.GetVector3Item(idx++); 7694 holesize = rules.GetVector3Item(idx++);
7695 topshear = rules.GetVector3Item(idx++); 7695 topshear = rules.GetVector3Item(idx++);
7696 profilecut = rules.GetVector3Item(idx++); 7696 profilecut = rules.GetVector3Item(idx++);
7697 taper_b = rules.GetVector3Item(idx++); // taper_a 7697 taper_b = rules.GetVector3Item(idx++); // taper_a
7698 revolutions = (float)rules.GetLSLFloatItem(idx++); 7698 revolutions = (float)rules.GetLSLFloatItem(idx++);
7699 radiusoffset = (float)rules.GetLSLFloatItem(idx++); 7699 radiusoffset = (float)rules.GetLSLFloatItem(idx++);
7700 skew = (float)rules.GetLSLFloatItem(idx++); 7700 skew = (float)rules.GetLSLFloatItem(idx++);
7701 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b, 7701 SetPrimitiveShapeParams(part, face, v, hollow, twist, holesize, topshear, profilecut, taper_b,
7702 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1); 7702 revolutions, radiusoffset, skew, (byte)ProfileShape.EquilateralTriangle, (byte)Extrusion.Curve1);
7703 break; 7703 break;
7704   7704  
7705 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: 7705 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7706 if (remain < 2) 7706 if (remain < 2)
7707 return null; 7707 return null;
7708   7708  
7709 string map = rules.Data[idx++].ToString(); 7709 string map = rules.Data[idx++].ToString();
7710 face = (int)rules.GetLSLIntegerItem(idx++); // type 7710 face = (int)rules.GetLSLIntegerItem(idx++); // type
7711 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1); 7711 SetPrimitiveShapeParams(part, map, face, (byte)Extrusion.Curve1);
7712 break; 7712 break;
7713 } 7713 }
7714   7714  
7715 break; 7715 break;
7716   7716  
7717 case (int)ScriptBaseClass.PRIM_TEXTURE: 7717 case (int)ScriptBaseClass.PRIM_TEXTURE:
7718 if (remain < 5) 7718 if (remain < 5)
7719 return null; 7719 return null;
7720   7720  
7721 face=(int)rules.GetLSLIntegerItem(idx++); 7721 face=(int)rules.GetLSLIntegerItem(idx++);
7722 string tex=rules.Data[idx++].ToString(); 7722 string tex=rules.Data[idx++].ToString();
7723 LSL_Vector repeats=rules.GetVector3Item(idx++); 7723 LSL_Vector repeats=rules.GetVector3Item(idx++);
7724 LSL_Vector offsets=rules.GetVector3Item(idx++); 7724 LSL_Vector offsets=rules.GetVector3Item(idx++);
7725 double rotation=(double)rules.GetLSLFloatItem(idx++); 7725 double rotation=(double)rules.GetLSLFloatItem(idx++);
7726   7726  
7727 SetTexture(part, tex, face); 7727 SetTexture(part, tex, face);
7728 ScaleTexture(part, repeats.x, repeats.y, face); 7728 ScaleTexture(part, repeats.x, repeats.y, face);
7729 OffsetTexture(part, offsets.x, offsets.y, face); 7729 OffsetTexture(part, offsets.x, offsets.y, face);
7730 RotateTexture(part, rotation, face); 7730 RotateTexture(part, rotation, face);
7731   7731  
7732 break; 7732 break;
7733   7733  
7734 case (int)ScriptBaseClass.PRIM_COLOR: 7734 case (int)ScriptBaseClass.PRIM_COLOR:
7735 if (remain < 3) 7735 if (remain < 3)
7736 return null; 7736 return null;
7737   7737  
7738 face=(int)rules.GetLSLIntegerItem(idx++); 7738 face=(int)rules.GetLSLIntegerItem(idx++);
7739 LSL_Vector color=rules.GetVector3Item(idx++); 7739 LSL_Vector color=rules.GetVector3Item(idx++);
7740 double alpha=(double)rules.GetLSLFloatItem(idx++); 7740 double alpha=(double)rules.GetLSLFloatItem(idx++);
7741   7741  
7742 part.SetFaceColorAlpha(face, color, alpha); 7742 part.SetFaceColorAlpha(face, color, alpha);
7743   7743  
7744 break; 7744 break;
7745   7745  
7746 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 7746 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7747 if (remain < 7) 7747 if (remain < 7)
7748 return null; 7748 return null;
7749   7749  
7750 bool flexi = rules.GetLSLIntegerItem(idx++); 7750 bool flexi = rules.GetLSLIntegerItem(idx++);
7751 int softness = rules.GetLSLIntegerItem(idx++); 7751 int softness = rules.GetLSLIntegerItem(idx++);
7752 float gravity = (float)rules.GetLSLFloatItem(idx++); 7752 float gravity = (float)rules.GetLSLFloatItem(idx++);
7753 float friction = (float)rules.GetLSLFloatItem(idx++); 7753 float friction = (float)rules.GetLSLFloatItem(idx++);
7754 float wind = (float)rules.GetLSLFloatItem(idx++); 7754 float wind = (float)rules.GetLSLFloatItem(idx++);
7755 float tension = (float)rules.GetLSLFloatItem(idx++); 7755 float tension = (float)rules.GetLSLFloatItem(idx++);
7756 LSL_Vector force = rules.GetVector3Item(idx++); 7756 LSL_Vector force = rules.GetVector3Item(idx++);
7757   7757  
7758 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force); 7758 SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
7759   7759  
7760 break; 7760 break;
7761   7761  
7762 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 7762 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7763 if (remain < 5) 7763 if (remain < 5)
7764 return null; 7764 return null;
7765 bool light = rules.GetLSLIntegerItem(idx++); 7765 bool light = rules.GetLSLIntegerItem(idx++);
7766 LSL_Vector lightcolor = rules.GetVector3Item(idx++); 7766 LSL_Vector lightcolor = rules.GetVector3Item(idx++);
7767 float intensity = (float)rules.GetLSLFloatItem(idx++); 7767 float intensity = (float)rules.GetLSLFloatItem(idx++);
7768 float radius = (float)rules.GetLSLFloatItem(idx++); 7768 float radius = (float)rules.GetLSLFloatItem(idx++);
7769 float falloff = (float)rules.GetLSLFloatItem(idx++); 7769 float falloff = (float)rules.GetLSLFloatItem(idx++);
7770   7770  
7771 SetPointLight(part, light, lightcolor, intensity, radius, falloff); 7771 SetPointLight(part, light, lightcolor, intensity, radius, falloff);
7772   7772  
7773 break; 7773 break;
7774   7774  
7775 case (int)ScriptBaseClass.PRIM_GLOW: 7775 case (int)ScriptBaseClass.PRIM_GLOW:
7776 if (remain < 2) 7776 if (remain < 2)
7777 return null; 7777 return null;
7778 face = rules.GetLSLIntegerItem(idx++); 7778 face = rules.GetLSLIntegerItem(idx++);
7779 float glow = (float)rules.GetLSLFloatItem(idx++); 7779 float glow = (float)rules.GetLSLFloatItem(idx++);
7780   7780  
7781 SetGlow(part, face, glow); 7781 SetGlow(part, face, glow);
7782   7782  
7783 break; 7783 break;
7784   7784  
7785 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 7785 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7786 if (remain < 3) 7786 if (remain < 3)
7787 return null; 7787 return null;
7788 face = (int)rules.GetLSLIntegerItem(idx++); 7788 face = (int)rules.GetLSLIntegerItem(idx++);
7789 int shiny = (int)rules.GetLSLIntegerItem(idx++); 7789 int shiny = (int)rules.GetLSLIntegerItem(idx++);
7790 Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++); 7790 Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
7791   7791  
7792 SetShiny(part, face, shiny, bump); 7792 SetShiny(part, face, shiny, bump);
7793   7793  
7794 break; 7794 break;
7795   7795  
7796 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 7796 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7797 if (remain < 2) 7797 if (remain < 2)
7798 return null; 7798 return null;
7799 face = rules.GetLSLIntegerItem(idx++); 7799 face = rules.GetLSLIntegerItem(idx++);
7800 bool st = rules.GetLSLIntegerItem(idx++); 7800 bool st = rules.GetLSLIntegerItem(idx++);
7801 SetFullBright(part, face , st); 7801 SetFullBright(part, face , st);
7802 break; 7802 break;
7803   7803  
7804 case (int)ScriptBaseClass.PRIM_MATERIAL: 7804 case (int)ScriptBaseClass.PRIM_MATERIAL:
7805 if (remain < 1) 7805 if (remain < 1)
7806 return null; 7806 return null;
7807 int mat = rules.GetLSLIntegerItem(idx++); 7807 int mat = rules.GetLSLIntegerItem(idx++);
7808 if (mat < 0 || mat > 7) 7808 if (mat < 0 || mat > 7)
7809 return null; 7809 return null;
7810   7810  
7811 part.Material = Convert.ToByte(mat); 7811 part.Material = Convert.ToByte(mat);
7812 break; 7812 break;
7813   7813  
7814 case (int)ScriptBaseClass.PRIM_PHANTOM: 7814 case (int)ScriptBaseClass.PRIM_PHANTOM:
7815 if (remain < 1) 7815 if (remain < 1)
7816 return null; 7816 return null;
7817   7817  
7818 string ph = rules.Data[idx++].ToString(); 7818 string ph = rules.Data[idx++].ToString();
7819 part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 7819 part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
7820   7820  
7821 break; 7821 break;
7822   7822  
7823 case (int)ScriptBaseClass.PRIM_PHYSICS: 7823 case (int)ScriptBaseClass.PRIM_PHYSICS:
7824 if (remain < 1) 7824 if (remain < 1)
7825 return null; 7825 return null;
7826 string phy = rules.Data[idx++].ToString(); 7826 string phy = rules.Data[idx++].ToString();
7827 bool physics; 7827 bool physics;
7828   7828  
7829 if (phy.Equals("1")) 7829 if (phy.Equals("1"))
7830 physics = true; 7830 physics = true;
7831 else 7831 else
7832 physics = false; 7832 physics = false;
7833   7833  
7834 part.ScriptSetPhysicsStatus(physics); 7834 part.ScriptSetPhysicsStatus(physics);
7835 break; 7835 break;
7836   7836  
7837 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: 7837 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7838 if (remain < 1) 7838 if (remain < 1)
7839 return null; 7839 return null;
7840   7840  
7841 int shape_type = rules.GetLSLIntegerItem(idx++); 7841 int shape_type = rules.GetLSLIntegerItem(idx++);
7842   7842  
7843 ExtraPhysicsData physdata = new ExtraPhysicsData(); 7843 ExtraPhysicsData physdata = new ExtraPhysicsData();
7844 physdata.Density = part.Density; 7844 physdata.Density = part.Density;
7845 physdata.Bounce = part.Restitution; 7845 physdata.Bounce = part.Restitution;
7846 physdata.GravitationModifier = part.GravityModifier; 7846 physdata.GravitationModifier = part.GravityModifier;
7847 physdata.PhysShapeType = (PhysShapeType)shape_type; 7847 physdata.PhysShapeType = (PhysShapeType)shape_type;
7848   7848  
7849 part.UpdateExtraPhysics(physdata); 7849 part.UpdateExtraPhysics(physdata);
7850   7850  
7851 break; 7851 break;
7852   7852  
7853 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 7853 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7854 if (remain < 1) 7854 if (remain < 1)
7855 return null; 7855 return null;
7856 string temp = rules.Data[idx++].ToString(); 7856 string temp = rules.Data[idx++].ToString();
7857   7857  
7858 part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 7858 part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
7859   7859  
7860 break; 7860 break;
7861   7861  
7862 case (int)ScriptBaseClass.PRIM_TEXGEN: 7862 case (int)ScriptBaseClass.PRIM_TEXGEN:
7863 if (remain < 2) 7863 if (remain < 2)
7864 return null; 7864 return null;
7865 //face,type 7865 //face,type
7866 face = rules.GetLSLIntegerItem(idx++); 7866 face = rules.GetLSLIntegerItem(idx++);
7867 int style = rules.GetLSLIntegerItem(idx++); 7867 int style = rules.GetLSLIntegerItem(idx++);
7868 SetTexGen(part, face, style); 7868 SetTexGen(part, face, style);
7869 break; 7869 break;
7870 case (int)ScriptBaseClass.PRIM_TEXT: 7870 case (int)ScriptBaseClass.PRIM_TEXT:
7871 if (remain < 3) 7871 if (remain < 3)
7872 return null; 7872 return null;
7873 string primText = rules.GetLSLStringItem(idx++); 7873 string primText = rules.GetLSLStringItem(idx++);
7874 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 7874 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
7875 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 7875 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
7876 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f); 7876 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
7877 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 7877 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
7878   7878  
7879 break; 7879 break;
7880 case (int)ScriptBaseClass.PRIM_NAME: 7880 case (int)ScriptBaseClass.PRIM_NAME:
7881 if (remain < 1) 7881 if (remain < 1)
7882 return null; 7882 return null;
7883 string primName = rules.GetLSLStringItem(idx++); 7883 string primName = rules.GetLSLStringItem(idx++);
7884 part.Name = primName; 7884 part.Name = primName;
7885 break; 7885 break;
7886 case (int)ScriptBaseClass.PRIM_DESC: 7886 case (int)ScriptBaseClass.PRIM_DESC:
7887 if (remain < 1) 7887 if (remain < 1)
7888 return null; 7888 return null;
7889 string primDesc = rules.GetLSLStringItem(idx++); 7889 string primDesc = rules.GetLSLStringItem(idx++);
7890 part.Description = primDesc; 7890 part.Description = primDesc;
7891 break; 7891 break;
7892 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 7892 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7893 if (remain < 1) 7893 if (remain < 1)
7894 return null; 7894 return null;
7895 SetRot(part, rules.GetQuaternionItem(idx++)); 7895 SetRot(part, rules.GetQuaternionItem(idx++));
7896 break; 7896 break;
7897 case (int)ScriptBaseClass.PRIM_OMEGA: 7897 case (int)ScriptBaseClass.PRIM_OMEGA:
7898 if (remain < 3) 7898 if (remain < 3)
7899 return null; 7899 return null;
7900 LSL_Vector axis = rules.GetVector3Item(idx++); 7900 LSL_Vector axis = rules.GetVector3Item(idx++);
7901 LSL_Float spinrate = rules.GetLSLFloatItem(idx++); 7901 LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
7902 LSL_Float gain = rules.GetLSLFloatItem(idx++); 7902 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7903 TargetOmega(part, axis, (double)spinrate, (double)gain); 7903 TargetOmega(part, axis, (double)spinrate, (double)gain);
7904 break; 7904 break;
7905 case (int)ScriptBaseClass.PRIM_SLICE: 7905 case (int)ScriptBaseClass.PRIM_SLICE:
7906 if (remain < 1) 7906 if (remain < 1)
7907 return null; 7907 return null;
7908 LSL_Vector slice = rules.GetVector3Item(idx++); 7908 LSL_Vector slice = rules.GetVector3Item(idx++);
7909 part.UpdateSlice((float)slice.x, (float)slice.y); 7909 part.UpdateSlice((float)slice.x, (float)slice.y);
7910 break; 7910 break;
7911 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 7911 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7912 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 7912 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7913 return null; 7913 return null;
7914   7914  
7915 return rules.GetSublist(idx, -1); 7915 return rules.GetSublist(idx, -1);
7916 } 7916 }
7917 } 7917 }
7918 } 7918 }
7919 catch (InvalidCastException e) 7919 catch (InvalidCastException e)
7920 { 7920 {
7921 ShoutError(string.Format( 7921 ShoutError(string.Format(
7922 "{0} error running rule #{1}: arg #{2} ", 7922 "{0} error running rule #{1}: arg #{2} ",
7923 originFunc, rulesParsed, idx - idxStart) + e.Message); 7923 originFunc, rulesParsed, idx - idxStart) + e.Message);
7924 } 7924 }
7925 finally 7925 finally
7926 { 7926 {
7927 if (positionChanged) 7927 if (positionChanged)
7928 { 7928 {
7929 if (part.ParentGroup.RootPart == part) 7929 if (part.ParentGroup.RootPart == part)
7930 { 7930 {
7931 SceneObjectGroup parent = part.ParentGroup; 7931 SceneObjectGroup parent = part.ParentGroup;
7932 parent.UpdateGroupPosition(currentPosition); 7932 parent.UpdateGroupPosition(currentPosition);
7933 } 7933 }
7934 else 7934 else
7935 { 7935 {
7936 part.OffsetPosition = currentPosition; 7936 part.OffsetPosition = currentPosition;
7937 SceneObjectGroup parent = part.ParentGroup; 7937 SceneObjectGroup parent = part.ParentGroup;
7938 parent.HasGroupChanged = true; 7938 parent.HasGroupChanged = true;
7939 parent.ScheduleGroupForTerseUpdate(); 7939 parent.ScheduleGroupForTerseUpdate();
7940 } 7940 }
7941 } 7941 }
7942 } 7942 }
7943 return null; 7943 return null;
7944 } 7944 }
7945   7945  
7946 public LSL_String llStringToBase64(string str) 7946 public LSL_String llStringToBase64(string str)
7947 { 7947 {
7948 m_host.AddScriptLPS(1); 7948 m_host.AddScriptLPS(1);
7949 try 7949 try
7950 { 7950 {
7951 byte[] encData_byte = new byte[str.Length]; 7951 byte[] encData_byte = new byte[str.Length];
7952 encData_byte = Util.UTF8.GetBytes(str); 7952 encData_byte = Util.UTF8.GetBytes(str);
7953 string encodedData = Convert.ToBase64String(encData_byte); 7953 string encodedData = Convert.ToBase64String(encData_byte);
7954 return encodedData; 7954 return encodedData;
7955 } 7955 }
7956 catch (Exception e) 7956 catch (Exception e)
7957 { 7957 {
7958 throw new Exception("Error in base64Encode" + e.Message); 7958 throw new Exception("Error in base64Encode" + e.Message);
7959 } 7959 }
7960 } 7960 }
7961   7961  
7962 public LSL_String llBase64ToString(string str) 7962 public LSL_String llBase64ToString(string str)
7963 { 7963 {
7964 m_host.AddScriptLPS(1); 7964 m_host.AddScriptLPS(1);
7965 try 7965 try
7966 { 7966 {
7967 return Util.Base64ToString(str); 7967 return Util.Base64ToString(str);
7968 } 7968 }
7969 catch (Exception e) 7969 catch (Exception e)
7970 { 7970 {
7971 throw new Exception("Error in base64Decode" + e.Message); 7971 throw new Exception("Error in base64Decode" + e.Message);
7972 } 7972 }
7973 } 7973 }
7974   7974  
7975 public LSL_String llXorBase64Strings(string str1, string str2) 7975 public LSL_String llXorBase64Strings(string str1, string str2)
7976 { 7976 {
7977 m_host.AddScriptLPS(1); 7977 m_host.AddScriptLPS(1);
7978 Deprecated("llXorBase64Strings"); 7978 Deprecated("llXorBase64Strings");
7979 ScriptSleep(300); 7979 ScriptSleep(300);
7980 return String.Empty; 7980 return String.Empty;
7981 } 7981 }
7982   7982  
7983 public void llRemoteDataSetRegion() 7983 public void llRemoteDataSetRegion()
7984 { 7984 {
7985 m_host.AddScriptLPS(1); 7985 m_host.AddScriptLPS(1);
7986 Deprecated("llRemoteDataSetRegion"); 7986 Deprecated("llRemoteDataSetRegion");
7987 } 7987 }
7988   7988  
7989 public LSL_Float llLog10(double val) 7989 public LSL_Float llLog10(double val)
7990 { 7990 {
7991 m_host.AddScriptLPS(1); 7991 m_host.AddScriptLPS(1);
7992 return (double)Math.Log10(val); 7992 return (double)Math.Log10(val);
7993 } 7993 }
7994   7994  
7995 public LSL_Float llLog(double val) 7995 public LSL_Float llLog(double val)
7996 { 7996 {
7997 m_host.AddScriptLPS(1); 7997 m_host.AddScriptLPS(1);
7998 return (double)Math.Log(val); 7998 return (double)Math.Log(val);
7999 } 7999 }
8000   8000  
8001 public LSL_List llGetAnimationList(string id) 8001 public LSL_List llGetAnimationList(string id)
8002 { 8002 {
8003 m_host.AddScriptLPS(1); 8003 m_host.AddScriptLPS(1);
8004   8004  
8005 LSL_List l = new LSL_List(); 8005 LSL_List l = new LSL_List();
8006 ScenePresence av = World.GetScenePresence((UUID)id); 8006 ScenePresence av = World.GetScenePresence((UUID)id);
8007 if (av == null || av.IsChildAgent) // only if in the region 8007 if (av == null || av.IsChildAgent) // only if in the region
8008 return l; 8008 return l;
8009 UUID[] anims; 8009 UUID[] anims;
8010 anims = av.Animator.GetAnimationArray(); 8010 anims = av.Animator.GetAnimationArray();
8011 foreach (UUID foo in anims) 8011 foreach (UUID foo in anims)
8012 l.Add(new LSL_Key(foo.ToString())); 8012 l.Add(new LSL_Key(foo.ToString()));
8013 return l; 8013 return l;
8014 } 8014 }
8015   8015  
8016 public void llSetParcelMusicURL(string url) 8016 public void llSetParcelMusicURL(string url)
8017 { 8017 {
8018 m_host.AddScriptLPS(1); 8018 m_host.AddScriptLPS(1);
8019   8019  
8020 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 8020 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8021   8021  
8022 if (land.LandData.OwnerID != m_host.OwnerID) 8022 if (land.LandData.OwnerID != m_host.OwnerID)
8023 return; 8023 return;
8024   8024  
8025 land.SetMusicUrl(url); 8025 land.SetMusicUrl(url);
8026   8026  
8027 ScriptSleep(2000); 8027 ScriptSleep(2000);
8028 } 8028 }
8029   8029  
8030 public LSL_String llGetParcelMusicURL() 8030 public LSL_String llGetParcelMusicURL()
8031 { 8031 {
8032 m_host.AddScriptLPS(1); 8032 m_host.AddScriptLPS(1);
8033   8033  
8034 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 8034 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8035   8035  
8036 if (land.LandData.OwnerID != m_host.OwnerID) 8036 if (land.LandData.OwnerID != m_host.OwnerID)
8037 return String.Empty; 8037 return String.Empty;
8038   8038  
8039 return land.GetMusicUrl(); 8039 return land.GetMusicUrl();
8040 } 8040 }
8041   8041  
8042 public LSL_Vector llGetRootPosition() 8042 public LSL_Vector llGetRootPosition()
8043 { 8043 {
8044 m_host.AddScriptLPS(1); 8044 m_host.AddScriptLPS(1);
8045   8045  
8046 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition); 8046 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8047 } 8047 }
8048   8048  
8049 /// <summary> 8049 /// <summary>
8050 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetRot 8050 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetRot
8051 /// http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation 8051 /// http://lslwiki.net/lslwiki/wakka.php?wakka=ChildRotation
8052 /// Also tested in sl in regards to the behaviour in attachments/mouselook 8052 /// Also tested in sl in regards to the behaviour in attachments/mouselook
8053 /// In the root prim:- 8053 /// In the root prim:-
8054 /// Returns the object rotation if not attached 8054 /// Returns the object rotation if not attached
8055 /// Returns the avatars rotation if attached 8055 /// Returns the avatars rotation if attached
8056 /// Returns the camera rotation if attached and the avatar is in mouselook 8056 /// Returns the camera rotation if attached and the avatar is in mouselook
8057 /// </summary> 8057 /// </summary>
8058 public LSL_Rotation llGetRootRotation() 8058 public LSL_Rotation llGetRootRotation()
8059 { 8059 {
8060 m_host.AddScriptLPS(1); 8060 m_host.AddScriptLPS(1);
8061 Quaternion q; 8061 Quaternion q;
8062 if (m_host.ParentGroup.AttachmentPoint != 0) 8062 if (m_host.ParentGroup.AttachmentPoint != 0)
8063 { 8063 {
8064 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 8064 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
8065 if (avatar != null) 8065 if (avatar != null)
8066 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8066 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
8067 q = avatar.CameraRotation; // Mouselook 8067 q = avatar.CameraRotation; // Mouselook
8068 else 8068 else
8069 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate 8069 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
8070 else 8070 else
8071 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case 8071 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case
8072 } 8072 }
8073 else 8073 else
8074 q = m_host.ParentGroup.GroupRotation; // just the group rotation 8074 q = m_host.ParentGroup.GroupRotation; // just the group rotation
8075   8075  
8076 return new LSL_Rotation(q); 8076 return new LSL_Rotation(q);
8077 } 8077 }
8078   8078  
8079 public LSL_String llGetObjectDesc() 8079 public LSL_String llGetObjectDesc()
8080 { 8080 {
8081 return m_host.Description!=null?m_host.Description:String.Empty; 8081 return m_host.Description!=null?m_host.Description:String.Empty;
8082 } 8082 }
8083   8083  
8084 public void llSetObjectDesc(string desc) 8084 public void llSetObjectDesc(string desc)
8085 { 8085 {
8086 m_host.AddScriptLPS(1); 8086 m_host.AddScriptLPS(1);
8087 m_host.Description = desc!=null?desc:String.Empty; 8087 m_host.Description = desc!=null?desc:String.Empty;
8088 } 8088 }
8089   8089  
8090 public LSL_String llGetCreator() 8090 public LSL_String llGetCreator()
8091 { 8091 {
8092 m_host.AddScriptLPS(1); 8092 m_host.AddScriptLPS(1);
8093 return m_host.CreatorID.ToString(); 8093 return m_host.CreatorID.ToString();
8094 } 8094 }
8095   8095  
8096 public LSL_String llGetTimestamp() 8096 public LSL_String llGetTimestamp()
8097 { 8097 {
8098 m_host.AddScriptLPS(1); 8098 m_host.AddScriptLPS(1);
8099 return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 8099 return DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
8100 } 8100 }
8101   8101  
8102 public LSL_Integer llGetNumberOfPrims() 8102 public LSL_Integer llGetNumberOfPrims()
8103 { 8103 {
8104 m_host.AddScriptLPS(1); 8104 m_host.AddScriptLPS(1);
8105   8105  
8106 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8106 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount();
8107 } 8107 }
8108   8108  
8109 /// <summary> 8109 /// <summary>
8110 /// A partial implementation. 8110 /// A partial implementation.
8111 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox 8111 /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox
8112 /// So far only valid for standing/flying/ground sitting avatars and single prim objects. 8112 /// So far only valid for standing/flying/ground sitting avatars and single prim objects.
8113 /// If the object has multiple prims and/or a sitting avatar then the bounding 8113 /// If the object has multiple prims and/or a sitting avatar then the bounding
8114 /// box is for the root prim only. 8114 /// box is for the root prim only.
8115 /// </summary> 8115 /// </summary>
8116 public LSL_List llGetBoundingBox(string obj) 8116 public LSL_List llGetBoundingBox(string obj)
8117 { 8117 {
8118 m_host.AddScriptLPS(1); 8118 m_host.AddScriptLPS(1);
8119 UUID objID = UUID.Zero; 8119 UUID objID = UUID.Zero;
8120 LSL_List result = new LSL_List(); 8120 LSL_List result = new LSL_List();
8121 if (!UUID.TryParse(obj, out objID)) 8121 if (!UUID.TryParse(obj, out objID))
8122 { 8122 {
8123 result.Add(new LSL_Vector()); 8123 result.Add(new LSL_Vector());
8124 result.Add(new LSL_Vector()); 8124 result.Add(new LSL_Vector());
8125 return result; 8125 return result;
8126 } 8126 }
8127 ScenePresence presence = World.GetScenePresence(objID); 8127 ScenePresence presence = World.GetScenePresence(objID);
8128 if (presence != null) 8128 if (presence != null)
8129 { 8129 {
8130 if (presence.ParentID == 0) // not sat on an object 8130 if (presence.ParentID == 0) // not sat on an object
8131 { 8131 {
8132 LSL_Vector lower; 8132 LSL_Vector lower;
8133 LSL_Vector upper; 8133 LSL_Vector upper;
8134 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8134 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8135 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8135 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8136 { 8136 {
8137 // This is for ground sitting avatars 8137 // This is for ground sitting avatars
8138 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8138 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8139 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8139 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8140 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8140 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8141 } 8141 }
8142 else 8142 else
8143 { 8143 {
8144 // This is for standing/flying avatars 8144 // This is for standing/flying avatars
8145 float height = presence.Appearance.AvatarHeight / 2.0f; 8145 float height = presence.Appearance.AvatarHeight / 2.0f;
8146 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8146 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8147 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8147 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8148 } 8148 }
8149 result.Add(lower); 8149 result.Add(lower);
8150 result.Add(upper); 8150 result.Add(upper);
8151 return result; 8151 return result;
8152 } 8152 }
8153 else 8153 else
8154 { 8154 {
8155 // sitting on an object so we need the bounding box of that 8155 // sitting on an object so we need the bounding box of that
8156 // which should include the avatar so set the UUID to the 8156 // which should include the avatar so set the UUID to the
8157 // UUID of the object the avatar is sat on and allow it to fall through 8157 // UUID of the object the avatar is sat on and allow it to fall through
8158 // to processing an object 8158 // to processing an object
8159 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8159 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8160 objID = p.UUID; 8160 objID = p.UUID;
8161 } 8161 }
8162 } 8162 }
8163 SceneObjectPart part = World.GetSceneObjectPart(objID); 8163 SceneObjectPart part = World.GetSceneObjectPart(objID);
8164 // Currently only works for single prims without a sitting avatar 8164 // Currently only works for single prims without a sitting avatar
8165 if (part != null) 8165 if (part != null)
8166 { 8166 {
8167 Vector3 halfSize = part.Scale / 2.0f; 8167 Vector3 halfSize = part.Scale / 2.0f;
8168 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8168 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f;
8169 LSL_Vector upper = new LSL_Vector(halfSize); 8169 LSL_Vector upper = new LSL_Vector(halfSize);
8170 result.Add(lower); 8170 result.Add(lower);
8171 result.Add(upper); 8171 result.Add(upper);
8172 return result; 8172 return result;
8173 } 8173 }
8174   8174  
8175 // Not found so return empty values 8175 // Not found so return empty values
8176 result.Add(new LSL_Vector()); 8176 result.Add(new LSL_Vector());
8177 result.Add(new LSL_Vector()); 8177 result.Add(new LSL_Vector());
8178 return result; 8178 return result;
8179 } 8179 }
8180   8180  
8181 public LSL_Vector llGetGeometricCenter() 8181 public LSL_Vector llGetGeometricCenter()
8182 { 8182 {
8183 return new LSL_Vector(m_host.GetGeometricCenter()); 8183 return new LSL_Vector(m_host.GetGeometricCenter());
8184 } 8184 }
8185   8185  
8186 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8186 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules)
8187 { 8187 {
8188 LSL_List result = new LSL_List(); 8188 LSL_List result = new LSL_List();
8189 LSL_List remaining = null; 8189 LSL_List remaining = null;
8190   8190  
8191 while (true) 8191 while (true)
8192 { 8192 {
8193 // m_log.DebugFormat( 8193 // m_log.DebugFormat(
8194 // "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}", 8194 // "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
8195 // rules.Length, entity != null ? entity.Name : "NULL"); 8195 // rules.Length, entity != null ? entity.Name : "NULL");
8196   8196  
8197 if (entity == null) 8197 if (entity == null)
8198 return result; 8198 return result;
8199   8199  
8200 if (entity is SceneObjectPart) 8200 if (entity is SceneObjectPart)
8201 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result); 8201 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8202 else 8202 else
8203 remaining = GetAgentParams((ScenePresence)entity, rules, ref result); 8203 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8204   8204  
8205 if (remaining == null || remaining.Length < 2) 8205 if (remaining == null || remaining.Length < 2)
8206 return result; 8206 return result;
8207   8207  
8208 int linknumber = remaining.GetLSLIntegerItem(0); 8208 int linknumber = remaining.GetLSLIntegerItem(0);
8209 rules = remaining.GetSublist(1, -1); 8209 rules = remaining.GetSublist(1, -1);
8210 entity = GetLinkEntity(linknumber); 8210 entity = GetLinkEntity(linknumber);
8211 } 8211 }
8212 } 8212 }
8213   8213  
8214 public LSL_List llGetPrimitiveParams(LSL_List rules) 8214 public LSL_List llGetPrimitiveParams(LSL_List rules)
8215 { 8215 {
8216 m_host.AddScriptLPS(1); 8216 m_host.AddScriptLPS(1);
8217   8217  
8218 return GetEntityParams(m_host, rules); 8218 return GetEntityParams(m_host, rules);
8219 } 8219 }
8220   8220  
8221 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8221 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8222 { 8222 {
8223 m_host.AddScriptLPS(1); 8223 m_host.AddScriptLPS(1);
8224   8224  
8225 return GetEntityParams(GetLinkEntity(linknumber), rules); 8225 return GetEntityParams(GetLinkEntity(linknumber), rules);
8226 } 8226 }
8227   8227  
8228 public LSL_Vector GetAgentSize(ScenePresence sp) 8228 public LSL_Vector GetAgentSize(ScenePresence sp)
8229 { 8229 {
8230 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8230 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight);
8231 } 8231 }
8232   8232  
8233 /// <summary> 8233 /// <summary>
8234 /// Gets params for a seated avatar in a linkset. 8234 /// Gets params for a seated avatar in a linkset.
8235 /// </summary> 8235 /// </summary>
8236 /// <returns></returns> 8236 /// <returns></returns>
8237 /// <param name='sp'></param> 8237 /// <param name='sp'></param>
8238 /// <param name='rules'></param> 8238 /// <param name='rules'></param>
8239 /// <param name='res'></param> 8239 /// <param name='res'></param>
8240 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res) 8240 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8241 { 8241 {
8242 int idx = 0; 8242 int idx = 0;
8243 while (idx < rules.Length) 8243 while (idx < rules.Length)
8244 { 8244 {
8245 int code = (int)rules.GetLSLIntegerItem(idx++); 8245 int code = (int)rules.GetLSLIntegerItem(idx++);
8246 int remain = rules.Length-idx; 8246 int remain = rules.Length-idx;
8247   8247  
8248 switch (code) 8248 switch (code)
8249 { 8249 {
8250 case (int)ScriptBaseClass.PRIM_MATERIAL: 8250 case (int)ScriptBaseClass.PRIM_MATERIAL:
8251 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8251 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH));
8252 break; 8252 break;
8253   8253  
8254 case (int)ScriptBaseClass.PRIM_PHYSICS: 8254 case (int)ScriptBaseClass.PRIM_PHYSICS:
8255 res.Add(ScriptBaseClass.FALSE); 8255 res.Add(ScriptBaseClass.FALSE);
8256 break; 8256 break;
8257   8257  
8258 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8258 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8259 res.Add(ScriptBaseClass.FALSE); 8259 res.Add(ScriptBaseClass.FALSE);
8260 break; 8260 break;
8261   8261  
8262 case (int)ScriptBaseClass.PRIM_PHANTOM: 8262 case (int)ScriptBaseClass.PRIM_PHANTOM:
8263 res.Add(ScriptBaseClass.FALSE); 8263 res.Add(ScriptBaseClass.FALSE);
8264 break; 8264 break;
8265   8265  
8266 case (int)ScriptBaseClass.PRIM_POSITION: 8266 case (int)ScriptBaseClass.PRIM_POSITION:
8267 res.Add(new LSL_Vector(sp.AbsolutePosition)); 8267 res.Add(new LSL_Vector(sp.AbsolutePosition));
8268 break; 8268 break;
8269   8269  
8270 case (int)ScriptBaseClass.PRIM_SIZE: 8270 case (int)ScriptBaseClass.PRIM_SIZE:
8271 res.Add(GetAgentSize(sp)); 8271 res.Add(GetAgentSize(sp));
8272 break; 8272 break;
8273   8273  
8274 case (int)ScriptBaseClass.PRIM_ROTATION: 8274 case (int)ScriptBaseClass.PRIM_ROTATION:
8275 res.Add(sp.GetWorldRotation()); 8275 res.Add(sp.GetWorldRotation());
8276 break; 8276 break;
8277   8277  
8278 case (int)ScriptBaseClass.PRIM_TYPE: 8278 case (int)ScriptBaseClass.PRIM_TYPE:
8279 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); 8279 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8280 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); 8280 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8281 res.Add(new LSL_Vector(0, 1, 0)); 8281 res.Add(new LSL_Vector(0, 1, 0));
8282 res.Add(new LSL_Float(0)); 8282 res.Add(new LSL_Float(0));
8283 res.Add(new LSL_Vector(0, 0, 0)); 8283 res.Add(new LSL_Vector(0, 0, 0));
8284 res.Add(new LSL_Vector(1, 1, 0)); 8284 res.Add(new LSL_Vector(1, 1, 0));
8285 res.Add(new LSL_Vector(0, 0, 0)); 8285 res.Add(new LSL_Vector(0, 0, 0));
8286 break; 8286 break;
8287   8287  
8288 case (int)ScriptBaseClass.PRIM_TEXTURE: 8288 case (int)ScriptBaseClass.PRIM_TEXTURE:
8289 if (remain < 1) 8289 if (remain < 1)
8290 return null; 8290 return null;
8291   8291  
8292 int face = (int)rules.GetLSLIntegerItem(idx++); 8292 int face = (int)rules.GetLSLIntegerItem(idx++);
8293 if (face > 21) 8293 if (face > 21)
8294 break; 8294 break;
8295   8295  
8296 res.Add(new LSL_String("")); 8296 res.Add(new LSL_String(""));
8297 res.Add(ScriptBaseClass.ZERO_VECTOR); 8297 res.Add(ScriptBaseClass.ZERO_VECTOR);
8298 res.Add(ScriptBaseClass.ZERO_VECTOR); 8298 res.Add(ScriptBaseClass.ZERO_VECTOR);
8299 res.Add(new LSL_Float(0)); 8299 res.Add(new LSL_Float(0));
8300 break; 8300 break;
8301   8301  
8302 case (int)ScriptBaseClass.PRIM_COLOR: 8302 case (int)ScriptBaseClass.PRIM_COLOR:
8303 if (remain < 1) 8303 if (remain < 1)
8304 return null; 8304 return null;
8305   8305  
8306 face = (int)rules.GetLSLIntegerItem(idx++); 8306 face = (int)rules.GetLSLIntegerItem(idx++);
8307 if (face > 21) 8307 if (face > 21)
8308 break; 8308 break;
8309   8309  
8310 res.Add(ScriptBaseClass.ZERO_VECTOR); 8310 res.Add(ScriptBaseClass.ZERO_VECTOR);
8311 res.Add(new LSL_Float(0)); 8311 res.Add(new LSL_Float(0));
8312 break; 8312 break;
8313   8313  
8314 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8314 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8315 if (remain < 1) 8315 if (remain < 1)
8316 return null; 8316 return null;
8317   8317  
8318 face = (int)rules.GetLSLIntegerItem(idx++); 8318 face = (int)rules.GetLSLIntegerItem(idx++);
8319 if (face > 21) 8319 if (face > 21)
8320 break; 8320 break;
8321   8321  
8322 res.Add(ScriptBaseClass.PRIM_SHINY_NONE); 8322 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8323 res.Add(ScriptBaseClass.PRIM_BUMP_NONE); 8323 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8324 break; 8324 break;
8325   8325  
8326 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8326 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8327 if (remain < 1) 8327 if (remain < 1)
8328 return null; 8328 return null;
8329   8329  
8330 face = (int)rules.GetLSLIntegerItem(idx++); 8330 face = (int)rules.GetLSLIntegerItem(idx++);
8331 if (face > 21) 8331 if (face > 21)
8332 break; 8332 break;
8333   8333  
8334 res.Add(ScriptBaseClass.FALSE); 8334 res.Add(ScriptBaseClass.FALSE);
8335 break; 8335 break;
8336   8336  
8337 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8337 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8338 res.Add(ScriptBaseClass.FALSE); 8338 res.Add(ScriptBaseClass.FALSE);
8339 res.Add(new LSL_Integer(0)); 8339 res.Add(new LSL_Integer(0));
8340 res.Add(new LSL_Float(0)); 8340 res.Add(new LSL_Float(0));
8341 res.Add(new LSL_Float(0)); 8341 res.Add(new LSL_Float(0));
8342 res.Add(new LSL_Float(0)); 8342 res.Add(new LSL_Float(0));
8343 res.Add(new LSL_Float(0)); 8343 res.Add(new LSL_Float(0));
8344 res.Add(ScriptBaseClass.ZERO_VECTOR); 8344 res.Add(ScriptBaseClass.ZERO_VECTOR);
8345 break; 8345 break;
8346   8346  
8347 case (int)ScriptBaseClass.PRIM_TEXGEN: 8347 case (int)ScriptBaseClass.PRIM_TEXGEN:
8348 if (remain < 1) 8348 if (remain < 1)
8349 return null; 8349 return null;
8350   8350  
8351 face = (int)rules.GetLSLIntegerItem(idx++); 8351 face = (int)rules.GetLSLIntegerItem(idx++);
8352 if (face > 21) 8352 if (face > 21)
8353 break; 8353 break;
8354   8354  
8355 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT); 8355 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8356 break; 8356 break;
8357   8357  
8358 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8358 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8359 res.Add(ScriptBaseClass.FALSE); 8359 res.Add(ScriptBaseClass.FALSE);
8360 res.Add(ScriptBaseClass.ZERO_VECTOR); 8360 res.Add(ScriptBaseClass.ZERO_VECTOR);
8361 res.Add(ScriptBaseClass.ZERO_VECTOR); 8361 res.Add(ScriptBaseClass.ZERO_VECTOR);
8362 break; 8362 break;
8363   8363  
8364 case (int)ScriptBaseClass.PRIM_GLOW: 8364 case (int)ScriptBaseClass.PRIM_GLOW:
8365 if (remain < 1) 8365 if (remain < 1)
8366 return null; 8366 return null;
8367   8367  
8368 face = (int)rules.GetLSLIntegerItem(idx++); 8368 face = (int)rules.GetLSLIntegerItem(idx++);
8369 if (face > 21) 8369 if (face > 21)
8370 break; 8370 break;
8371   8371  
8372 res.Add(new LSL_Float(0)); 8372 res.Add(new LSL_Float(0));
8373 break; 8373 break;
8374   8374  
8375 case (int)ScriptBaseClass.PRIM_TEXT: 8375 case (int)ScriptBaseClass.PRIM_TEXT:
8376 res.Add(new LSL_String("")); 8376 res.Add(new LSL_String(""));
8377 res.Add(ScriptBaseClass.ZERO_VECTOR); 8377 res.Add(ScriptBaseClass.ZERO_VECTOR);
8378 res.Add(new LSL_Float(1)); 8378 res.Add(new LSL_Float(1));
8379 break; 8379 break;
8380   8380  
8381 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8381 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8382 res.Add(new LSL_Rotation(sp.Rotation)); 8382 res.Add(new LSL_Rotation(sp.Rotation));
8383 break; 8383 break;
8384   8384  
8385 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8385 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8386 res.Add(new LSL_Vector(sp.OffsetPosition)); 8386 res.Add(new LSL_Vector(sp.OffsetPosition));
8387 break; 8387 break;
8388   8388  
8389 case (int)ScriptBaseClass.PRIM_SLICE: 8389 case (int)ScriptBaseClass.PRIM_SLICE:
8390 res.Add(new LSL_Vector(0, 1, 0)); 8390 res.Add(new LSL_Vector(0, 1, 0));
8391 break; 8391 break;
8392   8392  
8393 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8393 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8394 if(remain < 3) 8394 if(remain < 3)
8395 return null; 8395 return null;
8396   8396  
8397 return rules.GetSublist(idx, -1); 8397 return rules.GetSublist(idx, -1);
8398 } 8398 }
8399 } 8399 }
8400   8400  
8401 return null; 8401 return null;
8402 } 8402 }
8403   8403  
8404 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8404 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8405 { 8405 {
8406 int idx = 0; 8406 int idx = 0;
8407 while (idx < rules.Length) 8407 while (idx < rules.Length)
8408 { 8408 {
8409 int code = (int)rules.GetLSLIntegerItem(idx++); 8409 int code = (int)rules.GetLSLIntegerItem(idx++);
8410 int remain = rules.Length - idx; 8410 int remain = rules.Length - idx;
8411   8411  
8412 switch (code) 8412 switch (code)
8413 { 8413 {
8414 case (int)ScriptBaseClass.PRIM_MATERIAL: 8414 case (int)ScriptBaseClass.PRIM_MATERIAL:
8415 res.Add(new LSL_Integer(part.Material)); 8415 res.Add(new LSL_Integer(part.Material));
8416 break; 8416 break;
8417   8417  
8418 case (int)ScriptBaseClass.PRIM_PHYSICS: 8418 case (int)ScriptBaseClass.PRIM_PHYSICS:
8419 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0) 8419 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0)
8420 res.Add(new LSL_Integer(1)); 8420 res.Add(new LSL_Integer(1));
8421 else 8421 else
8422 res.Add(new LSL_Integer(0)); 8422 res.Add(new LSL_Integer(0));
8423 break; 8423 break;
8424   8424  
8425 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8425 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8426 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0) 8426 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0)
8427 res.Add(new LSL_Integer(1)); 8427 res.Add(new LSL_Integer(1));
8428 else 8428 else
8429 res.Add(new LSL_Integer(0)); 8429 res.Add(new LSL_Integer(0));
8430 break; 8430 break;
8431   8431  
8432 case (int)ScriptBaseClass.PRIM_PHANTOM: 8432 case (int)ScriptBaseClass.PRIM_PHANTOM:
8433 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) 8433 if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
8434 res.Add(new LSL_Integer(1)); 8434 res.Add(new LSL_Integer(1));
8435 else 8435 else
8436 res.Add(new LSL_Integer(0)); 8436 res.Add(new LSL_Integer(0));
8437 break; 8437 break;
8438   8438  
8439 case (int)ScriptBaseClass.PRIM_POSITION: 8439 case (int)ScriptBaseClass.PRIM_POSITION:
8440 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8440 LSL_Vector v = new LSL_Vector(part.AbsolutePosition);
8441   8441  
8442 // For some reason, the part.AbsolutePosition.* values do not change if the 8442 // For some reason, the part.AbsolutePosition.* values do not change if the
8443 // linkset is rotated; they always reflect the child prim's world position 8443 // linkset is rotated; they always reflect the child prim's world position
8444 // as though the linkset is unrotated. This is incompatible behavior with SL's 8444 // as though the linkset is unrotated. This is incompatible behavior with SL's
8445 // implementation, so will break scripts imported from there (not to mention it 8445 // implementation, so will break scripts imported from there (not to mention it
8446 // makes it more difficult to determine a child prim's actual inworld position). 8446 // makes it more difficult to determine a child prim's actual inworld position).
8447 if (!part.IsRoot) 8447 if (!part.IsRoot)
8448 { 8448 {
8449 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition); 8449 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8450 v = ((v - rootPos) * llGetRootRotation()) + rootPos; 8450 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8451 } 8451 }
8452   8452  
8453 res.Add(v); 8453 res.Add(v);
8454 break; 8454 break;
8455   8455  
8456 case (int)ScriptBaseClass.PRIM_SIZE: 8456 case (int)ScriptBaseClass.PRIM_SIZE:
8457 res.Add(new LSL_Vector(part.Scale)); 8457 res.Add(new LSL_Vector(part.Scale));
8458 break; 8458 break;
8459   8459  
8460 case (int)ScriptBaseClass.PRIM_ROTATION: 8460 case (int)ScriptBaseClass.PRIM_ROTATION:
8461 res.Add(GetPartRot(part)); 8461 res.Add(GetPartRot(part));
8462 break; 8462 break;
8463   8463  
8464 case (int)ScriptBaseClass.PRIM_TYPE: 8464 case (int)ScriptBaseClass.PRIM_TYPE:
8465 // implementing box 8465 // implementing box
8466 PrimitiveBaseShape Shape = part.Shape; 8466 PrimitiveBaseShape Shape = part.Shape;
8467 int primType = (int)part.GetPrimType(); 8467 int primType = (int)part.GetPrimType();
8468 res.Add(new LSL_Integer(primType)); 8468 res.Add(new LSL_Integer(primType));
8469 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX 8469 double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
8470 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY. 8470 double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
8471 switch (primType) 8471 switch (primType)
8472 { 8472 {
8473 case ScriptBaseClass.PRIM_TYPE_BOX: 8473 case ScriptBaseClass.PRIM_TYPE_BOX:
8474 case ScriptBaseClass.PRIM_TYPE_CYLINDER: 8474 case ScriptBaseClass.PRIM_TYPE_CYLINDER:
8475 case ScriptBaseClass.PRIM_TYPE_PRISM: 8475 case ScriptBaseClass.PRIM_TYPE_PRISM:
8476 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8476 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8477 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8477 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8478 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8478 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8479 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8479 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8480 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); 8480 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
8481 res.Add(new LSL_Vector(topshearx, topsheary, 0)); 8481 res.Add(new LSL_Vector(topshearx, topsheary, 0));
8482 break; 8482 break;
8483   8483  
8484 case ScriptBaseClass.PRIM_TYPE_SPHERE: 8484 case ScriptBaseClass.PRIM_TYPE_SPHERE:
8485 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8485 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8486 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); 8486 res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0));
8487 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8487 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8488 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8488 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8489 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8489 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8490 break; 8490 break;
8491   8491  
8492 case ScriptBaseClass.PRIM_TYPE_SCULPT: 8492 case ScriptBaseClass.PRIM_TYPE_SCULPT:
8493 res.Add(new LSL_String(Shape.SculptTexture.ToString())); 8493 res.Add(new LSL_String(Shape.SculptTexture.ToString()));
8494 res.Add(new LSL_Integer(Shape.SculptType)); 8494 res.Add(new LSL_Integer(Shape.SculptType));
8495 break; 8495 break;
8496   8496  
8497 case ScriptBaseClass.PRIM_TYPE_RING: 8497 case ScriptBaseClass.PRIM_TYPE_RING:
8498 case ScriptBaseClass.PRIM_TYPE_TUBE: 8498 case ScriptBaseClass.PRIM_TYPE_TUBE:
8499 case ScriptBaseClass.PRIM_TYPE_TORUS: 8499 case ScriptBaseClass.PRIM_TYPE_TORUS:
8500 // holeshape 8500 // holeshape
8501 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. 8501 res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble.
8502   8502  
8503 // cut 8503 // cut
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   8505  
8506 // hollow 8506 // hollow
8507 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); 8507 res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
8508   8508  
8509 // twist 8509 // twist
8510 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); 8510 res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
8511   8511  
8512 // vector holesize 8512 // vector holesize
8513 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); 8513 res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
8514   8514  
8515 // vector topshear 8515 // vector topshear
8516 res.Add(new LSL_Vector(topshearx, topsheary, 0)); 8516 res.Add(new LSL_Vector(topshearx, topsheary, 0));
8517   8517  
8518 // vector profilecut 8518 // vector profilecut
8519 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); 8519 res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
8520   8520  
8521 // vector tapera 8521 // vector tapera
8522 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8522 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8523   8523  
8524 // float revolutions 8524 // float revolutions
8525 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); 8525 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8526 // Slightly inaccurate, because an unsigned byte is being used to represent 8526 // Slightly inaccurate, because an unsigned byte is being used to represent
8527 // the entire range of floating-point values from 1.0 through 4.0 (which is how 8527 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8528 // SL does it). 8528 // SL does it).
8529 // 8529 //
8530 // Using these formulas to store and retrieve PathRevolutions, it is not 8530 // Using these formulas to store and retrieve PathRevolutions, it is not
8531 // possible to use all values between 1.00 and 4.00. For instance, you can't 8531 // possible to use all values between 1.00 and 4.00. For instance, you can't
8532 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you 8532 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8533 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them 8533 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8534 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar 8534 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8535 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. 8535 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8536 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8536 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8537 // such as 1.10. So, SL must store and retreive the actual user input rather 8537 // such as 1.10. So, SL must store and retreive the actual user input rather
8538 // than only storing the encoded value. 8538 // than only storing the encoded value.
8539   8539  
8540 // float radiusoffset 8540 // float radiusoffset
8541 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); 8541 res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
8542   8542  
8543 // float skew 8543 // float skew
8544 res.Add(new LSL_Float(Shape.PathSkew / 100.0)); 8544 res.Add(new LSL_Float(Shape.PathSkew / 100.0));
8545 break; 8545 break;
8546 } 8546 }
8547 break; 8547 break;
8548   8548  
8549 case (int)ScriptBaseClass.PRIM_TEXTURE: 8549 case (int)ScriptBaseClass.PRIM_TEXTURE:
8550 if (remain < 1) 8550 if (remain < 1)
8551 return null; 8551 return null;
8552   8552  
8553 int face = (int)rules.GetLSLIntegerItem(idx++); 8553 int face = (int)rules.GetLSLIntegerItem(idx++);
8554 Primitive.TextureEntry tex = part.Shape.Textures; 8554 Primitive.TextureEntry tex = part.Shape.Textures;
8555 if (face == ScriptBaseClass.ALL_SIDES) 8555 if (face == ScriptBaseClass.ALL_SIDES)
8556 { 8556 {
8557 for (face = 0 ; face < GetNumberOfSides(part); face++) 8557 for (face = 0 ; face < GetNumberOfSides(part); face++)
8558 { 8558 {
8559 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8559 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8560   8560  
8561 res.Add(new LSL_String(texface.TextureID.ToString())); 8561 res.Add(new LSL_String(texface.TextureID.ToString()));
8562 res.Add(new LSL_Vector(texface.RepeatU, 8562 res.Add(new LSL_Vector(texface.RepeatU,
8563 texface.RepeatV, 8563 texface.RepeatV,
8564 0)); 8564 0));
8565 res.Add(new LSL_Vector(texface.OffsetU, 8565 res.Add(new LSL_Vector(texface.OffsetU,
8566 texface.OffsetV, 8566 texface.OffsetV,
8567 0)); 8567 0));
8568 res.Add(new LSL_Float(texface.Rotation)); 8568 res.Add(new LSL_Float(texface.Rotation));
8569 } 8569 }
8570 } 8570 }
8571 else 8571 else
8572 { 8572 {
8573 if (face >= 0 && face < GetNumberOfSides(part)) 8573 if (face >= 0 && face < GetNumberOfSides(part))
8574 { 8574 {
8575 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8575 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8576   8576  
8577 res.Add(new LSL_String(texface.TextureID.ToString())); 8577 res.Add(new LSL_String(texface.TextureID.ToString()));
8578 res.Add(new LSL_Vector(texface.RepeatU, 8578 res.Add(new LSL_Vector(texface.RepeatU,
8579 texface.RepeatV, 8579 texface.RepeatV,
8580 0)); 8580 0));
8581 res.Add(new LSL_Vector(texface.OffsetU, 8581 res.Add(new LSL_Vector(texface.OffsetU,
8582 texface.OffsetV, 8582 texface.OffsetV,
8583 0)); 8583 0));
8584 res.Add(new LSL_Float(texface.Rotation)); 8584 res.Add(new LSL_Float(texface.Rotation));
8585 } 8585 }
8586 } 8586 }
8587 break; 8587 break;
8588   8588  
8589 case (int)ScriptBaseClass.PRIM_COLOR: 8589 case (int)ScriptBaseClass.PRIM_COLOR:
8590 if (remain < 1) 8590 if (remain < 1)
8591 return null; 8591 return null;
8592   8592  
8593 face=(int)rules.GetLSLIntegerItem(idx++); 8593 face=(int)rules.GetLSLIntegerItem(idx++);
8594   8594  
8595 tex = part.Shape.Textures; 8595 tex = part.Shape.Textures;
8596 Color4 texcolor; 8596 Color4 texcolor;
8597 if (face == ScriptBaseClass.ALL_SIDES) 8597 if (face == ScriptBaseClass.ALL_SIDES)
8598 { 8598 {
8599 for (face = 0 ; face < GetNumberOfSides(part); face++) 8599 for (face = 0 ; face < GetNumberOfSides(part); face++)
8600 { 8600 {
8601 texcolor = tex.GetFace((uint)face).RGBA; 8601 texcolor = tex.GetFace((uint)face).RGBA;
8602 res.Add(new LSL_Vector(texcolor.R, 8602 res.Add(new LSL_Vector(texcolor.R,
8603 texcolor.G, 8603 texcolor.G,
8604 texcolor.B)); 8604 texcolor.B));
8605 res.Add(new LSL_Float(texcolor.A)); 8605 res.Add(new LSL_Float(texcolor.A));
8606 } 8606 }
8607 } 8607 }
8608 else 8608 else
8609 { 8609 {
8610 texcolor = tex.GetFace((uint)face).RGBA; 8610 texcolor = tex.GetFace((uint)face).RGBA;
8611 res.Add(new LSL_Vector(texcolor.R, 8611 res.Add(new LSL_Vector(texcolor.R,
8612 texcolor.G, 8612 texcolor.G,
8613 texcolor.B)); 8613 texcolor.B));
8614 res.Add(new LSL_Float(texcolor.A)); 8614 res.Add(new LSL_Float(texcolor.A));
8615 } 8615 }
8616 break; 8616 break;
8617   8617  
8618 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8618 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8619 if (remain < 1) 8619 if (remain < 1)
8620 return null; 8620 return null;
8621   8621  
8622 face=(int)rules.GetLSLIntegerItem(idx++); 8622 face=(int)rules.GetLSLIntegerItem(idx++);
8623   8623  
8624 tex = part.Shape.Textures; 8624 tex = part.Shape.Textures;
8625 if (face == ScriptBaseClass.ALL_SIDES) 8625 if (face == ScriptBaseClass.ALL_SIDES)
8626 { 8626 {
8627 for (face = 0; face < GetNumberOfSides(part); face++) 8627 for (face = 0; face < GetNumberOfSides(part); face++)
8628 { 8628 {
8629 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8629 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8630 // Convert Shininess to PRIM_SHINY_* 8630 // Convert Shininess to PRIM_SHINY_*
8631 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8631 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8632 // PRIM_BUMP_* 8632 // PRIM_BUMP_*
8633 res.Add(new LSL_Integer((int)texface.Bump)); 8633 res.Add(new LSL_Integer((int)texface.Bump));
8634 } 8634 }
8635 } 8635 }
8636 else 8636 else
8637 { 8637 {
8638 if (face >= 0 && face < GetNumberOfSides(part)) 8638 if (face >= 0 && face < GetNumberOfSides(part))
8639 { 8639 {
8640 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8640 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8641 // Convert Shininess to PRIM_SHINY_* 8641 // Convert Shininess to PRIM_SHINY_*
8642 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8642 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8643 // PRIM_BUMP_* 8643 // PRIM_BUMP_*
8644 res.Add(new LSL_Integer((int)texface.Bump)); 8644 res.Add(new LSL_Integer((int)texface.Bump));
8645 } 8645 }
8646 } 8646 }
8647 break; 8647 break;
8648   8648  
8649 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8649 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8650 if (remain < 1) 8650 if (remain < 1)
8651 return null; 8651 return null;
8652   8652  
8653 face = (int)rules.GetLSLIntegerItem(idx++); 8653 face = (int)rules.GetLSLIntegerItem(idx++);
8654   8654  
8655 tex = part.Shape.Textures; 8655 tex = part.Shape.Textures;
8656 if (face == ScriptBaseClass.ALL_SIDES) 8656 if (face == ScriptBaseClass.ALL_SIDES)
8657 { 8657 {
8658 for (face = 0; face < GetNumberOfSides(part); face++) 8658 for (face = 0; face < GetNumberOfSides(part); face++)
8659 { 8659 {
8660 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8660 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8661 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8661 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8662 } 8662 }
8663 } 8663 }
8664 else 8664 else
8665 { 8665 {
8666 if (face >= 0 && face < GetNumberOfSides(part)) 8666 if (face >= 0 && face < GetNumberOfSides(part))
8667 { 8667 {
8668 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8668 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8669 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8669 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8670 } 8670 }
8671 } 8671 }
8672 break; 8672 break;
8673   8673  
8674 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8674 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8675 PrimitiveBaseShape shape = part.Shape; 8675 PrimitiveBaseShape shape = part.Shape;
8676   8676  
8677 if (shape.FlexiEntry) 8677 if (shape.FlexiEntry)
8678 res.Add(new LSL_Integer(1)); // active 8678 res.Add(new LSL_Integer(1)); // active
8679 else 8679 else
8680 res.Add(new LSL_Integer(0)); 8680 res.Add(new LSL_Integer(0));
8681 res.Add(new LSL_Integer(shape.FlexiSoftness));// softness 8681 res.Add(new LSL_Integer(shape.FlexiSoftness));// softness
8682 res.Add(new LSL_Float(shape.FlexiGravity)); // gravity 8682 res.Add(new LSL_Float(shape.FlexiGravity)); // gravity
8683 res.Add(new LSL_Float(shape.FlexiDrag)); // friction 8683 res.Add(new LSL_Float(shape.FlexiDrag)); // friction
8684 res.Add(new LSL_Float(shape.FlexiWind)); // wind 8684 res.Add(new LSL_Float(shape.FlexiWind)); // wind
8685 res.Add(new LSL_Float(shape.FlexiTension)); // tension 8685 res.Add(new LSL_Float(shape.FlexiTension)); // tension
8686 res.Add(new LSL_Vector(shape.FlexiForceX, // force 8686 res.Add(new LSL_Vector(shape.FlexiForceX, // force
8687 shape.FlexiForceY, 8687 shape.FlexiForceY,
8688 shape.FlexiForceZ)); 8688 shape.FlexiForceZ));
8689 break; 8689 break;
8690   8690  
8691 case (int)ScriptBaseClass.PRIM_TEXGEN: 8691 case (int)ScriptBaseClass.PRIM_TEXGEN:
8692 if (remain < 1) 8692 if (remain < 1)
8693 return null; 8693 return null;
8694   8694  
8695 face=(int)rules.GetLSLIntegerItem(idx++); 8695 face=(int)rules.GetLSLIntegerItem(idx++);
8696   8696  
8697 tex = part.Shape.Textures; 8697 tex = part.Shape.Textures;
8698 if (face == ScriptBaseClass.ALL_SIDES) 8698 if (face == ScriptBaseClass.ALL_SIDES)
8699 { 8699 {
8700 for (face = 0; face < GetNumberOfSides(part); face++) 8700 for (face = 0; face < GetNumberOfSides(part); face++)
8701 { 8701 {
8702 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8702 MappingType texgen = tex.GetFace((uint)face).TexMapType;
8703 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8703 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc.
8704 res.Add(new LSL_Integer((uint)texgen >> 1)); 8704 res.Add(new LSL_Integer((uint)texgen >> 1));
8705 } 8705 }
8706 } 8706 }
8707 else 8707 else
8708 { 8708 {
8709 if (face >= 0 && face < GetNumberOfSides(part)) 8709 if (face >= 0 && face < GetNumberOfSides(part))
8710 { 8710 {
8711 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8711 MappingType texgen = tex.GetFace((uint)face).TexMapType;
8712 res.Add(new LSL_Integer((uint)texgen >> 1)); 8712 res.Add(new LSL_Integer((uint)texgen >> 1));
8713 } 8713 }
8714 } 8714 }
8715 break; 8715 break;
8716   8716  
8717 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8717 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8718 shape = part.Shape; 8718 shape = part.Shape;
8719   8719  
8720 if (shape.LightEntry) 8720 if (shape.LightEntry)
8721 res.Add(new LSL_Integer(1)); // active 8721 res.Add(new LSL_Integer(1)); // active
8722 else 8722 else
8723 res.Add(new LSL_Integer(0)); 8723 res.Add(new LSL_Integer(0));
8724 res.Add(new LSL_Vector(shape.LightColorR, // color 8724 res.Add(new LSL_Vector(shape.LightColorR, // color
8725 shape.LightColorG, 8725 shape.LightColorG,
8726 shape.LightColorB)); 8726 shape.LightColorB));
8727 res.Add(new LSL_Float(shape.LightIntensity)); // intensity 8727 res.Add(new LSL_Float(shape.LightIntensity)); // intensity
8728 res.Add(new LSL_Float(shape.LightRadius)); // radius 8728 res.Add(new LSL_Float(shape.LightRadius)); // radius
8729 res.Add(new LSL_Float(shape.LightFalloff)); // falloff 8729 res.Add(new LSL_Float(shape.LightFalloff)); // falloff
8730 break; 8730 break;
8731   8731  
8732 case (int)ScriptBaseClass.PRIM_GLOW: 8732 case (int)ScriptBaseClass.PRIM_GLOW:
8733 if (remain < 1) 8733 if (remain < 1)
8734 return null; 8734 return null;
8735   8735  
8736 face=(int)rules.GetLSLIntegerItem(idx++); 8736 face=(int)rules.GetLSLIntegerItem(idx++);
8737   8737  
8738 tex = part.Shape.Textures; 8738 tex = part.Shape.Textures;
8739 if (face == ScriptBaseClass.ALL_SIDES) 8739 if (face == ScriptBaseClass.ALL_SIDES)
8740 { 8740 {
8741 for (face = 0; face < GetNumberOfSides(part); face++) 8741 for (face = 0; face < GetNumberOfSides(part); face++)
8742 { 8742 {
8743 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8743 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8744 res.Add(new LSL_Float(texface.Glow)); 8744 res.Add(new LSL_Float(texface.Glow));
8745 } 8745 }
8746 } 8746 }
8747 else 8747 else
8748 { 8748 {
8749 if (face >= 0 && face < GetNumberOfSides(part)) 8749 if (face >= 0 && face < GetNumberOfSides(part))
8750 { 8750 {
8751 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8751 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8752 res.Add(new LSL_Float(texface.Glow)); 8752 res.Add(new LSL_Float(texface.Glow));
8753 } 8753 }
8754 } 8754 }
8755 break; 8755 break;
8756   8756  
8757 case (int)ScriptBaseClass.PRIM_TEXT: 8757 case (int)ScriptBaseClass.PRIM_TEXT:
8758 Color4 textColor = part.GetTextColor(); 8758 Color4 textColor = part.GetTextColor();
8759 res.Add(new LSL_String(part.Text)); 8759 res.Add(new LSL_String(part.Text));
8760 res.Add(new LSL_Vector(textColor.R, 8760 res.Add(new LSL_Vector(textColor.R,
8761 textColor.G, 8761 textColor.G,
8762 textColor.B)); 8762 textColor.B));
8763 res.Add(new LSL_Float(textColor.A)); 8763 res.Add(new LSL_Float(textColor.A));
8764 break; 8764 break;
8765 case (int)ScriptBaseClass.PRIM_NAME: 8765 case (int)ScriptBaseClass.PRIM_NAME:
8766 res.Add(new LSL_String(part.Name)); 8766 res.Add(new LSL_String(part.Name));
8767 break; 8767 break;
8768 case (int)ScriptBaseClass.PRIM_DESC: 8768 case (int)ScriptBaseClass.PRIM_DESC:
8769 res.Add(new LSL_String(part.Description)); 8769 res.Add(new LSL_String(part.Description));
8770 break; 8770 break;
8771 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8771 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8772 res.Add(new LSL_Rotation(part.RotationOffset)); 8772 res.Add(new LSL_Rotation(part.RotationOffset));
8773 break; 8773 break;
8774 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 8774 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8775 res.Add(new LSL_Vector(GetPartLocalPos(part))); 8775 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8776 break; 8776 break;
8777 case (int)ScriptBaseClass.PRIM_SLICE: 8777 case (int)ScriptBaseClass.PRIM_SLICE:
8778 PrimType prim_type = part.GetPrimType(); 8778 PrimType prim_type = part.GetPrimType();
8779 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); 8779 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
8780 res.Add(new LSL_Vector( 8780 res.Add(new LSL_Vector(
8781 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0, 8781 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
8782 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0, 8782 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
8783 0 8783 0
8784 )); 8784 ));
8785 break; 8785 break;
8786 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8786 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8787   8787  
8788 // TODO: Should be issuing a runtime script warning in this case. 8788 // TODO: Should be issuing a runtime script warning in this case.
8789 if (remain < 2) 8789 if (remain < 2)
8790 return null; 8790 return null;
8791   8791  
8792 return rules.GetSublist(idx, -1); 8792 return rules.GetSublist(idx, -1);
8793 } 8793 }
8794 } 8794 }
8795   8795  
8796 return null; 8796 return null;
8797 } 8797 }
8798   8798  
8799 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 8799 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
8800 { 8800 {
8801 m_host.AddScriptLPS(1); 8801 m_host.AddScriptLPS(1);
8802 ScriptSleep(1000); 8802 ScriptSleep(1000);
8803 return GetPrimMediaParams(m_host, face, rules); 8803 return GetPrimMediaParams(m_host, face, rules);
8804 } 8804 }
8805   8805  
8806 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 8806 public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
8807 { 8807 {
8808 m_host.AddScriptLPS(1); 8808 m_host.AddScriptLPS(1);
8809 ScriptSleep(1000); 8809 ScriptSleep(1000);
8810 if (link == ScriptBaseClass.LINK_ROOT) 8810 if (link == ScriptBaseClass.LINK_ROOT)
8811 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 8811 return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
8812 else if (link == ScriptBaseClass.LINK_THIS) 8812 else if (link == ScriptBaseClass.LINK_THIS)
8813 return GetPrimMediaParams(m_host, face, rules); 8813 return GetPrimMediaParams(m_host, face, rules);
8814 else 8814 else
8815 { 8815 {
8816 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 8816 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
8817 if (null != part) 8817 if (null != part)
8818 return GetPrimMediaParams(part, face, rules); 8818 return GetPrimMediaParams(part, face, rules);
8819 } 8819 }
8820   8820  
8821 return new LSL_List(); 8821 return new LSL_List();
8822 } 8822 }
8823   8823  
8824 private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules) 8824 private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules)
8825 { 8825 {
8826 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid 8826 // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid
8827 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list). 8827 // TODO: Need to correctly handle case where a face has no media (which gives back an empty list).
8828 // Assuming silently fail means give back an empty list. Ideally, need to check this. 8828 // Assuming silently fail means give back an empty list. Ideally, need to check this.
8829 if (face < 0 || face > part.GetNumberOfSides() - 1) 8829 if (face < 0 || face > part.GetNumberOfSides() - 1)
8830 return new LSL_List(); 8830 return new LSL_List();
8831   8831  
8832 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 8832 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8833 if (null == module) 8833 if (null == module)
8834 return new LSL_List(); 8834 return new LSL_List();
8835   8835  
8836 MediaEntry me = module.GetMediaEntry(part, face); 8836 MediaEntry me = module.GetMediaEntry(part, face);
8837   8837  
8838 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams 8838 // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams
8839 if (null == me) 8839 if (null == me)
8840 return new LSL_List(); 8840 return new LSL_List();
8841   8841  
8842 LSL_List res = new LSL_List(); 8842 LSL_List res = new LSL_List();
8843   8843  
8844 for (int i = 0; i < rules.Length; i++) 8844 for (int i = 0; i < rules.Length; i++)
8845 { 8845 {
8846 int code = (int)rules.GetLSLIntegerItem(i); 8846 int code = (int)rules.GetLSLIntegerItem(i);
8847   8847  
8848 switch (code) 8848 switch (code)
8849 { 8849 {
8850 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: 8850 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8851 // Not implemented 8851 // Not implemented
8852 res.Add(new LSL_Integer(0)); 8852 res.Add(new LSL_Integer(0));
8853 break; 8853 break;
8854   8854  
8855 case ScriptBaseClass.PRIM_MEDIA_CONTROLS: 8855 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8856 if (me.Controls == MediaControls.Standard) 8856 if (me.Controls == MediaControls.Standard)
8857 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD)); 8857 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD));
8858 else 8858 else
8859 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI)); 8859 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI));
8860 break; 8860 break;
8861   8861  
8862 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: 8862 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
8863 res.Add(new LSL_String(me.CurrentURL)); 8863 res.Add(new LSL_String(me.CurrentURL));
8864 break; 8864 break;
8865   8865  
8866 case ScriptBaseClass.PRIM_MEDIA_HOME_URL: 8866 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8867 res.Add(new LSL_String(me.HomeURL)); 8867 res.Add(new LSL_String(me.HomeURL));
8868 break; 8868 break;
8869   8869  
8870 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: 8870 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8871 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8871 res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8872 break; 8872 break;
8873   8873  
8874 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: 8874 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
8875 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8875 res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8876 break; 8876 break;
8877   8877  
8878 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: 8878 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
8879 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8879 res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8880 break; 8880 break;
8881   8881  
8882 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: 8882 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
8883 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8883 res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8884 break; 8884 break;
8885   8885  
8886 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: 8886 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
8887 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8887 res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8888 break; 8888 break;
8889   8889  
8890 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: 8890 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
8891 res.Add(new LSL_Integer(me.Width)); 8891 res.Add(new LSL_Integer(me.Width));
8892 break; 8892 break;
8893   8893  
8894 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: 8894 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
8895 res.Add(new LSL_Integer(me.Height)); 8895 res.Add(new LSL_Integer(me.Height));
8896 break; 8896 break;
8897   8897  
8898 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: 8898 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
8899 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); 8899 res.Add(me.EnableWhiteList ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE);
8900 break; 8900 break;
8901   8901  
8902 case ScriptBaseClass.PRIM_MEDIA_WHITELIST: 8902 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
8903 string[] urls = (string[])me.WhiteList.Clone(); 8903 string[] urls = (string[])me.WhiteList.Clone();
8904   8904  
8905 for (int j = 0; j < urls.Length; j++) 8905 for (int j = 0; j < urls.Length; j++)
8906 urls[j] = Uri.EscapeDataString(urls[j]); 8906 urls[j] = Uri.EscapeDataString(urls[j]);
8907   8907  
8908 res.Add(new LSL_String(string.Join(", ", urls))); 8908 res.Add(new LSL_String(string.Join(", ", urls)));
8909 break; 8909 break;
8910   8910  
8911 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: 8911 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
8912 res.Add(new LSL_Integer((int)me.InteractPermissions)); 8912 res.Add(new LSL_Integer((int)me.InteractPermissions));
8913 break; 8913 break;
8914   8914  
8915 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: 8915 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
8916 res.Add(new LSL_Integer((int)me.ControlPermissions)); 8916 res.Add(new LSL_Integer((int)me.ControlPermissions));
8917 break; 8917 break;
8918   8918  
8919 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS; 8919 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS;
8920 } 8920 }
8921 } 8921 }
8922   8922  
8923 return res; 8923 return res;
8924 } 8924 }
8925   8925  
8926 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules) 8926 public LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules)
8927 { 8927 {
8928 m_host.AddScriptLPS(1); 8928 m_host.AddScriptLPS(1);
8929 ScriptSleep(1000); 8929 ScriptSleep(1000);
8930 return SetPrimMediaParams(m_host, face, rules); 8930 return SetPrimMediaParams(m_host, face, rules);
8931 } 8931 }
8932   8932  
8933 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) 8933 public LSL_Integer llSetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules)
8934 { 8934 {
8935 m_host.AddScriptLPS(1); 8935 m_host.AddScriptLPS(1);
8936 ScriptSleep(1000); 8936 ScriptSleep(1000);
8937 if (link == ScriptBaseClass.LINK_ROOT) 8937 if (link == ScriptBaseClass.LINK_ROOT)
8938 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); 8938 return SetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules);
8939 else if (link == ScriptBaseClass.LINK_THIS) 8939 else if (link == ScriptBaseClass.LINK_THIS)
8940 return SetPrimMediaParams(m_host, face, rules); 8940 return SetPrimMediaParams(m_host, face, rules);
8941 else 8941 else
8942 { 8942 {
8943 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 8943 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
8944 if (null != part) 8944 if (null != part)
8945 return SetPrimMediaParams(part, face, rules); 8945 return SetPrimMediaParams(part, face, rules);
8946 } 8946 }
8947   8947  
8948 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 8948 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
8949 } 8949 }
8950   8950  
8951 private LSL_Integer SetPrimMediaParams(SceneObjectPart part, LSL_Integer face, LSL_List rules) 8951 private LSL_Integer SetPrimMediaParams(SceneObjectPart part, LSL_Integer face, LSL_List rules)
8952 { 8952 {
8953 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid 8953 // LSL Spec http://wiki.secondlife.com/wiki/LlSetPrimMediaParams says to fail silently if face is invalid
8954 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. 8954 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
8955 // Don't perform the media check directly 8955 // Don't perform the media check directly
8956 if (face < 0 || face > part.GetNumberOfSides() - 1) 8956 if (face < 0 || face > part.GetNumberOfSides() - 1)
8957 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 8957 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
8958   8958  
8959 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 8959 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
8960 if (null == module) 8960 if (null == module)
8961 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED; 8961 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED;
8962   8962  
8963 MediaEntry me = module.GetMediaEntry(part, face); 8963 MediaEntry me = module.GetMediaEntry(part, face);
8964 if (null == me) 8964 if (null == me)
8965 me = new MediaEntry(); 8965 me = new MediaEntry();
8966   8966  
8967 int i = 0; 8967 int i = 0;
8968   8968  
8969 while (i < rules.Length - 1) 8969 while (i < rules.Length - 1)
8970 { 8970 {
8971 int code = rules.GetLSLIntegerItem(i++); 8971 int code = rules.GetLSLIntegerItem(i++);
8972   8972  
8973 switch (code) 8973 switch (code)
8974 { 8974 {
8975 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: 8975 case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE:
8976 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false); 8976 me.EnableAlterntiveImage = (rules.GetLSLIntegerItem(i++) != 0 ? true : false);
8977 break; 8977 break;
8978   8978  
8979 case ScriptBaseClass.PRIM_MEDIA_CONTROLS: 8979 case ScriptBaseClass.PRIM_MEDIA_CONTROLS:
8980 int v = rules.GetLSLIntegerItem(i++); 8980 int v = rules.GetLSLIntegerItem(i++);
8981 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v) 8981 if (ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD == v)
8982 me.Controls = MediaControls.Standard; 8982 me.Controls = MediaControls.Standard;
8983 else 8983 else
8984 me.Controls = MediaControls.Mini; 8984 me.Controls = MediaControls.Mini;
8985 break; 8985 break;
8986   8986  
8987 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: 8987 case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL:
8988 me.CurrentURL = rules.GetLSLStringItem(i++); 8988 me.CurrentURL = rules.GetLSLStringItem(i++);
8989 break; 8989 break;
8990   8990  
8991 case ScriptBaseClass.PRIM_MEDIA_HOME_URL: 8991 case ScriptBaseClass.PRIM_MEDIA_HOME_URL:
8992 me.HomeURL = rules.GetLSLStringItem(i++); 8992 me.HomeURL = rules.GetLSLStringItem(i++);
8993 break; 8993 break;
8994   8994  
8995 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: 8995 case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP:
8996 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 8996 me.AutoLoop = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
8997 break; 8997 break;
8998   8998  
8999 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: 8999 case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY:
9000 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9000 me.AutoPlay = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9001 break; 9001 break;
9002   9002  
9003 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: 9003 case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE:
9004 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9004 me.AutoScale = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9005 break; 9005 break;
9006   9006  
9007 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: 9007 case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM:
9008 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9008 me.AutoZoom = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9009 break; 9009 break;
9010   9010  
9011 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: 9011 case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT:
9012 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9012 me.InteractOnFirstClick = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9013 break; 9013 break;
9014   9014  
9015 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: 9015 case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS:
9016 me.Width = (int)rules.GetLSLIntegerItem(i++); 9016 me.Width = (int)rules.GetLSLIntegerItem(i++);
9017 break; 9017 break;
9018   9018  
9019 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS: 9019 case ScriptBaseClass.PRIM_MEDIA_HEIGHT_PIXELS:
9020 me.Height = (int)rules.GetLSLIntegerItem(i++); 9020 me.Height = (int)rules.GetLSLIntegerItem(i++);
9021 break; 9021 break;
9022   9022  
9023 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE: 9023 case ScriptBaseClass.PRIM_MEDIA_WHITELIST_ENABLE:
9024 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false); 9024 me.EnableWhiteList = (ScriptBaseClass.TRUE == rules.GetLSLIntegerItem(i++) ? true : false);
9025 break; 9025 break;
9026   9026  
9027 case ScriptBaseClass.PRIM_MEDIA_WHITELIST: 9027 case ScriptBaseClass.PRIM_MEDIA_WHITELIST:
9028 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' }); 9028 string[] rawWhiteListUrls = rules.GetLSLStringItem(i++).ToString().Split(new char[] { ',' });
9029 List<string> whiteListUrls = new List<string>(); 9029 List<string> whiteListUrls = new List<string>();
9030 Array.ForEach( 9030 Array.ForEach(
9031 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); }); 9031 rawWhiteListUrls, delegate(string rawUrl) { whiteListUrls.Add(rawUrl.Trim()); });
9032 me.WhiteList = whiteListUrls.ToArray(); 9032 me.WhiteList = whiteListUrls.ToArray();
9033 break; 9033 break;
9034   9034  
9035 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT: 9035 case ScriptBaseClass.PRIM_MEDIA_PERMS_INTERACT:
9036 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); 9036 me.InteractPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
9037 break; 9037 break;
9038   9038  
9039 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL: 9039 case ScriptBaseClass.PRIM_MEDIA_PERMS_CONTROL:
9040 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++); 9040 me.ControlPermissions = (MediaPermission)(byte)(int)rules.GetLSLIntegerItem(i++);
9041 break; 9041 break;
9042   9042  
9043 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS; 9043 default: return ScriptBaseClass.LSL_STATUS_MALFORMED_PARAMS;
9044 } 9044 }
9045 } 9045 }
9046   9046  
9047 module.SetMediaEntry(part, face, me); 9047 module.SetMediaEntry(part, face, me);
9048   9048  
9049 return ScriptBaseClass.LSL_STATUS_OK; 9049 return ScriptBaseClass.LSL_STATUS_OK;
9050 } 9050 }
9051   9051  
9052 public LSL_Integer llClearPrimMedia(LSL_Integer face) 9052 public LSL_Integer llClearPrimMedia(LSL_Integer face)
9053 { 9053 {
9054 m_host.AddScriptLPS(1); 9054 m_host.AddScriptLPS(1);
9055 ScriptSleep(1000); 9055 ScriptSleep(1000);
9056 return ClearPrimMedia(m_host, face); 9056 return ClearPrimMedia(m_host, face);
9057 } 9057 }
9058   9058  
9059 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face) 9059 public LSL_Integer llClearLinkMedia(LSL_Integer link, LSL_Integer face)
9060 { 9060 {
9061 m_host.AddScriptLPS(1); 9061 m_host.AddScriptLPS(1);
9062 ScriptSleep(1000); 9062 ScriptSleep(1000);
9063 if (link == ScriptBaseClass.LINK_ROOT) 9063 if (link == ScriptBaseClass.LINK_ROOT)
9064 return ClearPrimMedia(m_host.ParentGroup.RootPart, face); 9064 return ClearPrimMedia(m_host.ParentGroup.RootPart, face);
9065 else if (link == ScriptBaseClass.LINK_THIS) 9065 else if (link == ScriptBaseClass.LINK_THIS)
9066 return ClearPrimMedia(m_host, face); 9066 return ClearPrimMedia(m_host, face);
9067 else 9067 else
9068 { 9068 {
9069 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); 9069 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link);
9070 if (null != part) 9070 if (null != part)
9071 return ClearPrimMedia(part, face); 9071 return ClearPrimMedia(part, face);
9072 } 9072 }
9073   9073  
9074 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 9074 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
9075 } 9075 }
9076   9076  
9077 private LSL_Integer ClearPrimMedia(SceneObjectPart part, LSL_Integer face) 9077 private LSL_Integer ClearPrimMedia(SceneObjectPart part, LSL_Integer face)
9078 { 9078 {
9079 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid 9079 // LSL Spec http://wiki.secondlife.com/wiki/LlClearPrimMedia says to fail silently if face is invalid
9080 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this. 9080 // Assuming silently fail means sending back LSL_STATUS_OK. Ideally, need to check this.
9081 // FIXME: Don't perform the media check directly 9081 // FIXME: Don't perform the media check directly
9082 if (face < 0 || face > part.GetNumberOfSides() - 1) 9082 if (face < 0 || face > part.GetNumberOfSides() - 1)
9083 return ScriptBaseClass.LSL_STATUS_NOT_FOUND; 9083 return ScriptBaseClass.LSL_STATUS_NOT_FOUND;
9084   9084  
9085 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>(); 9085 IMoapModule module = m_ScriptEngine.World.RequestModuleInterface<IMoapModule>();
9086 if (null == module) 9086 if (null == module)
9087 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED; 9087 return ScriptBaseClass.LSL_STATUS_NOT_SUPPORTED;
9088   9088  
9089 module.ClearMediaEntry(part, face); 9089 module.ClearMediaEntry(part, face);
9090   9090  
9091 return ScriptBaseClass.LSL_STATUS_OK; 9091 return ScriptBaseClass.LSL_STATUS_OK;
9092 } 9092 }
9093   9093  
9094 // <remarks> 9094 // <remarks>
9095 // <para> 9095 // <para>
9096 // The .NET definition of base 64 is: 9096 // The .NET definition of base 64 is:
9097 // <list> 9097 // <list>
9098 // <item> 9098 // <item>
9099 // Significant: A-Z a-z 0-9 + - 9099 // Significant: A-Z a-z 0-9 + -
9100 // </item> 9100 // </item>
9101 // <item> 9101 // <item>
9102 // Whitespace: \t \n \r ' ' 9102 // Whitespace: \t \n \r ' '
9103 // </item> 9103 // </item>
9104 // <item> 9104 // <item>
9105 // Valueless: = 9105 // Valueless: =
9106 // </item> 9106 // </item>
9107 // <item> 9107 // <item>
9108 // End-of-string: \0 or '==' 9108 // End-of-string: \0 or '=='
9109 // </item> 9109 // </item>
9110 // </list> 9110 // </list>
9111 // </para> 9111 // </para>
9112 // <para> 9112 // <para>
9113 // Each point in a base-64 string represents 9113 // Each point in a base-64 string represents
9114 // a 6 bit value. A 32-bit integer can be 9114 // a 6 bit value. A 32-bit integer can be
9115 // represented using 6 characters (with some 9115 // represented using 6 characters (with some
9116 // redundancy). 9116 // redundancy).
9117 // </para> 9117 // </para>
9118 // <para> 9118 // <para>
9119 // LSL requires a base64 string to be 8 9119 // LSL requires a base64 string to be 8
9120 // characters in length. LSL also uses '/' 9120 // characters in length. LSL also uses '/'
9121 // rather than '-' (MIME compliant). 9121 // rather than '-' (MIME compliant).
9122 // </para> 9122 // </para>
9123 // <para> 9123 // <para>
9124 // RFC 1341 used as a reference (as specified 9124 // RFC 1341 used as a reference (as specified
9125 // by the SecondLife Wiki). 9125 // by the SecondLife Wiki).
9126 // </para> 9126 // </para>
9127 // <para> 9127 // <para>
9128 // SL do not record any kind of exception for 9128 // SL do not record any kind of exception for
9129 // these functions, so the string to integer 9129 // these functions, so the string to integer
9130 // conversion returns '0' if an invalid 9130 // conversion returns '0' if an invalid
9131 // character is encountered during conversion. 9131 // character is encountered during conversion.
9132 // </para> 9132 // </para>
9133 // <para> 9133 // <para>
9134 // References 9134 // References
9135 // <list> 9135 // <list>
9136 // <item> 9136 // <item>
9137 // http://lslwiki.net/lslwiki/wakka.php?wakka=Base64 9137 // http://lslwiki.net/lslwiki/wakka.php?wakka=Base64
9138 // </item> 9138 // </item>
9139 // <item> 9139 // <item>
9140 // </item> 9140 // </item>
9141 // </list> 9141 // </list>
9142 // </para> 9142 // </para>
9143 // </remarks> 9143 // </remarks>
9144   9144  
9145 // <summary> 9145 // <summary>
9146 // Table for converting 6-bit integers into 9146 // Table for converting 6-bit integers into
9147 // base-64 characters 9147 // base-64 characters
9148 // </summary> 9148 // </summary>
9149   9149  
9150 protected static readonly char[] i2ctable = 9150 protected static readonly char[] i2ctable =
9151 { 9151 {
9152 'A','B','C','D','E','F','G','H', 9152 'A','B','C','D','E','F','G','H',
9153 'I','J','K','L','M','N','O','P', 9153 'I','J','K','L','M','N','O','P',
9154 'Q','R','S','T','U','V','W','X', 9154 'Q','R','S','T','U','V','W','X',
9155 'Y','Z', 9155 'Y','Z',
9156 'a','b','c','d','e','f','g','h', 9156 'a','b','c','d','e','f','g','h',
9157 'i','j','k','l','m','n','o','p', 9157 'i','j','k','l','m','n','o','p',
9158 'q','r','s','t','u','v','w','x', 9158 'q','r','s','t','u','v','w','x',
9159 'y','z', 9159 'y','z',
9160 '0','1','2','3','4','5','6','7', 9160 '0','1','2','3','4','5','6','7',
9161 '8','9', 9161 '8','9',
9162 '+','/' 9162 '+','/'
9163 }; 9163 };
9164   9164  
9165 // <summary> 9165 // <summary>
9166 // Table for converting base-64 characters 9166 // Table for converting base-64 characters
9167 // into 6-bit integers. 9167 // into 6-bit integers.
9168 // </summary> 9168 // </summary>
9169   9169  
9170 protected static readonly int[] c2itable = 9170 protected static readonly int[] c2itable =
9171 { 9171 {
9172 -1,-1,-1,-1,-1,-1,-1,-1, // 0x 9172 -1,-1,-1,-1,-1,-1,-1,-1, // 0x
9173 -1,-1,-1,-1,-1,-1,-1,-1, 9173 -1,-1,-1,-1,-1,-1,-1,-1,
9174 -1,-1,-1,-1,-1,-1,-1,-1, // 1x 9174 -1,-1,-1,-1,-1,-1,-1,-1, // 1x
9175 -1,-1,-1,-1,-1,-1,-1,-1, 9175 -1,-1,-1,-1,-1,-1,-1,-1,
9176 -1,-1,-1,-1,-1,-1,-1,-1, // 2x 9176 -1,-1,-1,-1,-1,-1,-1,-1, // 2x
9177 -1,-1,-1,63,-1,-1,-1,64, 9177 -1,-1,-1,63,-1,-1,-1,64,
9178 53,54,55,56,57,58,59,60, // 3x 9178 53,54,55,56,57,58,59,60, // 3x
9179 61,62,-1,-1,-1,0,-1,-1, 9179 61,62,-1,-1,-1,0,-1,-1,
9180 -1,1,2,3,4,5,6,7, // 4x 9180 -1,1,2,3,4,5,6,7, // 4x
9181 8,9,10,11,12,13,14,15, 9181 8,9,10,11,12,13,14,15,
9182 16,17,18,19,20,21,22,23, // 5x 9182 16,17,18,19,20,21,22,23, // 5x
9183 24,25,26,-1,-1,-1,-1,-1, 9183 24,25,26,-1,-1,-1,-1,-1,
9184 -1,27,28,29,30,31,32,33, // 6x 9184 -1,27,28,29,30,31,32,33, // 6x
9185 34,35,36,37,38,39,40,41, 9185 34,35,36,37,38,39,40,41,
9186 42,43,44,45,46,47,48,49, // 7x 9186 42,43,44,45,46,47,48,49, // 7x
9187 50,51,52,-1,-1,-1,-1,-1, 9187 50,51,52,-1,-1,-1,-1,-1,
9188 -1,-1,-1,-1,-1,-1,-1,-1, // 8x 9188 -1,-1,-1,-1,-1,-1,-1,-1, // 8x
9189 -1,-1,-1,-1,-1,-1,-1,-1, 9189 -1,-1,-1,-1,-1,-1,-1,-1,
9190 -1,-1,-1,-1,-1,-1,-1,-1, // 9x 9190 -1,-1,-1,-1,-1,-1,-1,-1, // 9x
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, // Ax 9192 -1,-1,-1,-1,-1,-1,-1,-1, // Ax
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, // Bx 9194 -1,-1,-1,-1,-1,-1,-1,-1, // Bx
9195 -1,-1,-1,-1,-1,-1,-1,-1, 9195 -1,-1,-1,-1,-1,-1,-1,-1,
9196 -1,-1,-1,-1,-1,-1,-1,-1, // Cx 9196 -1,-1,-1,-1,-1,-1,-1,-1, // Cx
9197 -1,-1,-1,-1,-1,-1,-1,-1, 9197 -1,-1,-1,-1,-1,-1,-1,-1,
9198 -1,-1,-1,-1,-1,-1,-1,-1, // Dx 9198 -1,-1,-1,-1,-1,-1,-1,-1, // Dx
9199 -1,-1,-1,-1,-1,-1,-1,-1, 9199 -1,-1,-1,-1,-1,-1,-1,-1,
9200 -1,-1,-1,-1,-1,-1,-1,-1, // Ex 9200 -1,-1,-1,-1,-1,-1,-1,-1, // Ex
9201 -1,-1,-1,-1,-1,-1,-1,-1, 9201 -1,-1,-1,-1,-1,-1,-1,-1,
9202 -1,-1,-1,-1,-1,-1,-1,-1, // Fx 9202 -1,-1,-1,-1,-1,-1,-1,-1, // Fx
9203 -1,-1,-1,-1,-1,-1,-1,-1 9203 -1,-1,-1,-1,-1,-1,-1,-1
9204 }; 9204 };
9205   9205  
9206 // <summary> 9206 // <summary>
9207 // Converts a 32-bit integer into a Base64 9207 // Converts a 32-bit integer into a Base64
9208 // character string. Base64 character strings 9208 // character string. Base64 character strings
9209 // are always 8 characters long. All iinteger 9209 // are always 8 characters long. All iinteger
9210 // values are acceptable. 9210 // values are acceptable.
9211 // </summary> 9211 // </summary>
9212 // <param name="number"> 9212 // <param name="number">
9213 // 32-bit integer to be converted. 9213 // 32-bit integer to be converted.
9214 // </param> 9214 // </param>
9215 // <returns> 9215 // <returns>
9216 // 8 character string. The 1st six characters 9216 // 8 character string. The 1st six characters
9217 // contain the encoded number, the last two 9217 // contain the encoded number, the last two
9218 // characters are padded with "=". 9218 // characters are padded with "=".
9219 // </returns> 9219 // </returns>
9220   9220  
9221 public LSL_String llIntegerToBase64(int number) 9221 public LSL_String llIntegerToBase64(int number)
9222 { 9222 {
9223 // uninitialized string 9223 // uninitialized string
9224   9224  
9225 char[] imdt = new char[8]; 9225 char[] imdt = new char[8];
9226   9226  
9227 m_host.AddScriptLPS(1); 9227 m_host.AddScriptLPS(1);
9228   9228  
9229 // Manually unroll the loop 9229 // Manually unroll the loop
9230   9230  
9231 imdt[7] = '='; 9231 imdt[7] = '=';
9232 imdt[6] = '='; 9232 imdt[6] = '=';
9233 imdt[5] = i2ctable[number<<4 & 0x3F]; 9233 imdt[5] = i2ctable[number<<4 & 0x3F];
9234 imdt[4] = i2ctable[number>>2 & 0x3F]; 9234 imdt[4] = i2ctable[number>>2 & 0x3F];
9235 imdt[3] = i2ctable[number>>8 & 0x3F]; 9235 imdt[3] = i2ctable[number>>8 & 0x3F];
9236 imdt[2] = i2ctable[number>>14 & 0x3F]; 9236 imdt[2] = i2ctable[number>>14 & 0x3F];
9237 imdt[1] = i2ctable[number>>20 & 0x3F]; 9237 imdt[1] = i2ctable[number>>20 & 0x3F];
9238 imdt[0] = i2ctable[number>>26 & 0x3F]; 9238 imdt[0] = i2ctable[number>>26 & 0x3F];
9239   9239  
9240 return new string(imdt); 9240 return new string(imdt);
9241 } 9241 }
9242   9242  
9243 // <summary> 9243 // <summary>
9244 // Converts an eight character base-64 string 9244 // Converts an eight character base-64 string
9245 // into a 32-bit integer. 9245 // into a 32-bit integer.
9246 // </summary> 9246 // </summary>
9247 // <param name="str"> 9247 // <param name="str">
9248 // 8 characters string to be converted. Other 9248 // 8 characters string to be converted. Other
9249 // length strings return zero. 9249 // length strings return zero.
9250 // </param> 9250 // </param>
9251 // <returns> 9251 // <returns>
9252 // Returns an integer representing the 9252 // Returns an integer representing the
9253 // encoded value providedint he 1st 6 9253 // encoded value providedint he 1st 6
9254 // characters of the string. 9254 // characters of the string.
9255 // </returns> 9255 // </returns>
9256 // <remarks> 9256 // <remarks>
9257 // This is coded to behave like LSL's 9257 // This is coded to behave like LSL's
9258 // implementation (I think), based upon the 9258 // implementation (I think), based upon the
9259 // information available at the Wiki. 9259 // information available at the Wiki.
9260 // If more than 8 characters are supplied, 9260 // If more than 8 characters are supplied,
9261 // zero is returned. 9261 // zero is returned.
9262 // If a NULL string is supplied, zero will 9262 // If a NULL string is supplied, zero will
9263 // be returned. 9263 // be returned.
9264 // If fewer than 6 characters are supplied, then 9264 // If fewer than 6 characters are supplied, then
9265 // the answer will reflect a partial 9265 // the answer will reflect a partial
9266 // accumulation. 9266 // accumulation.
9267 // <para> 9267 // <para>
9268 // The 6-bit segments are 9268 // The 6-bit segments are
9269 // extracted left-to-right in big-endian mode, 9269 // extracted left-to-right in big-endian mode,
9270 // which means that segment 6 only contains the 9270 // which means that segment 6 only contains the
9271 // two low-order bits of the 32 bit integer as 9271 // two low-order bits of the 32 bit integer as
9272 // its high order 2 bits. A short string therefore 9272 // its high order 2 bits. A short string therefore
9273 // means loss of low-order information. E.g. 9273 // means loss of low-order information. E.g.
9274 // 9274 //
9275 // |<---------------------- 32-bit integer ----------------------->|<-Pad->| 9275 // |<---------------------- 32-bit integer ----------------------->|<-Pad->|
9276 // |<--Byte 0----->|<--Byte 1----->|<--Byte 2----->|<--Byte 3----->|<-Pad->| 9276 // |<--Byte 0----->|<--Byte 1----->|<--Byte 2----->|<--Byte 3----->|<-Pad->|
9277 // |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| 9277 // |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|
9278 // |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| 9278 // |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|
9279 // | str[0] | str[1] | str[2] | str[3] | str[4] | str[6] | 9279 // | str[0] | str[1] | str[2] | str[3] | str[4] | str[6] |
9280 // 9280 //
9281 // </para> 9281 // </para>
9282 // </remarks> 9282 // </remarks>
9283   9283  
9284 public LSL_Integer llBase64ToInteger(string str) 9284 public LSL_Integer llBase64ToInteger(string str)
9285 { 9285 {
9286 int number = 0; 9286 int number = 0;
9287 int digit; 9287 int digit;
9288   9288  
9289 m_host.AddScriptLPS(1); 9289 m_host.AddScriptLPS(1);
9290   9290  
9291 // Require a well-fromed base64 string 9291 // Require a well-fromed base64 string
9292   9292  
9293 if (str.Length > 8) 9293 if (str.Length > 8)
9294 return 0; 9294 return 0;
9295   9295  
9296 // The loop is unrolled in the interests 9296 // The loop is unrolled in the interests
9297 // of performance and simple necessity. 9297 // of performance and simple necessity.
9298 // 9298 //
9299 // MUST find 6 digits to be well formed 9299 // MUST find 6 digits to be well formed
9300 // -1 == invalid 9300 // -1 == invalid
9301 // 0 == padding 9301 // 0 == padding
9302   9302  
9303 if ((digit = c2itable[str[0]]) <= 0) 9303 if ((digit = c2itable[str[0]]) <= 0)
9304 { 9304 {
9305 return digit < 0 ? (int)0 : number; 9305 return digit < 0 ? (int)0 : number;
9306 } 9306 }
9307 number += --digit<<26; 9307 number += --digit<<26;
9308   9308  
9309 if ((digit = c2itable[str[1]]) <= 0) 9309 if ((digit = c2itable[str[1]]) <= 0)
9310 { 9310 {
9311 return digit < 0 ? (int)0 : number; 9311 return digit < 0 ? (int)0 : number;
9312 } 9312 }
9313 number += --digit<<20; 9313 number += --digit<<20;
9314   9314  
9315 if ((digit = c2itable[str[2]]) <= 0) 9315 if ((digit = c2itable[str[2]]) <= 0)
9316 { 9316 {
9317 return digit < 0 ? (int)0 : number; 9317 return digit < 0 ? (int)0 : number;
9318 } 9318 }
9319 number += --digit<<14; 9319 number += --digit<<14;
9320   9320  
9321 if ((digit = c2itable[str[3]]) <= 0) 9321 if ((digit = c2itable[str[3]]) <= 0)
9322 { 9322 {
9323 return digit < 0 ? (int)0 : number; 9323 return digit < 0 ? (int)0 : number;
9324 } 9324 }
9325 number += --digit<<8; 9325 number += --digit<<8;
9326   9326  
9327 if ((digit = c2itable[str[4]]) <= 0) 9327 if ((digit = c2itable[str[4]]) <= 0)
9328 { 9328 {
9329 return digit < 0 ? (int)0 : number; 9329 return digit < 0 ? (int)0 : number;
9330 } 9330 }
9331 number += --digit<<2; 9331 number += --digit<<2;
9332   9332  
9333 if ((digit = c2itable[str[5]]) <= 0) 9333 if ((digit = c2itable[str[5]]) <= 0)
9334 { 9334 {
9335 return digit < 0 ? (int)0 : number; 9335 return digit < 0 ? (int)0 : number;
9336 } 9336 }
9337 number += --digit>>4; 9337 number += --digit>>4;
9338   9338  
9339 // ignore trailing padding 9339 // ignore trailing padding
9340   9340  
9341 return number; 9341 return number;
9342 } 9342 }
9343   9343  
9344 public LSL_Float llGetGMTclock() 9344 public LSL_Float llGetGMTclock()
9345 { 9345 {
9346 m_host.AddScriptLPS(1); 9346 m_host.AddScriptLPS(1);
9347 return DateTime.UtcNow.TimeOfDay.TotalSeconds; 9347 return DateTime.UtcNow.TimeOfDay.TotalSeconds;
9348 } 9348 }
9349   9349  
9350 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header) 9350 public LSL_String llGetHTTPHeader(LSL_Key request_id, string header)
9351 { 9351 {
9352 m_host.AddScriptLPS(1); 9352 m_host.AddScriptLPS(1);
9353   9353  
9354 if (m_UrlModule != null) 9354 if (m_UrlModule != null)
9355 return m_UrlModule.GetHttpHeader(new UUID(request_id), header); 9355 return m_UrlModule.GetHttpHeader(new UUID(request_id), header);
9356 return String.Empty; 9356 return String.Empty;
9357 } 9357 }
9358   9358  
9359   9359  
9360 public LSL_String llGetSimulatorHostname() 9360 public LSL_String llGetSimulatorHostname()
9361 { 9361 {
9362 m_host.AddScriptLPS(1); 9362 m_host.AddScriptLPS(1);
9363 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>(); 9363 IUrlModule UrlModule = World.RequestModuleInterface<IUrlModule>();
9364 return UrlModule.ExternalHostNameForLSL; 9364 return UrlModule.ExternalHostNameForLSL;
9365 } 9365 }
9366   9366  
9367 // <summary> 9367 // <summary>
9368 // Scan the string supplied in 'src' and 9368 // Scan the string supplied in 'src' and
9369 // tokenize it based upon two sets of 9369 // tokenize it based upon two sets of
9370 // tokenizers provided in two lists, 9370 // tokenizers provided in two lists,
9371 // separators and spacers. 9371 // separators and spacers.
9372 // </summary> 9372 // </summary>
9373 // 9373 //
9374 // <remarks> 9374 // <remarks>
9375 // Separators demarcate tokens and are 9375 // Separators demarcate tokens and are
9376 // elided as they are encountered. Spacers 9376 // elided as they are encountered. Spacers
9377 // also demarcate tokens, but are themselves 9377 // also demarcate tokens, but are themselves
9378 // retained as tokens. 9378 // retained as tokens.
9379 // 9379 //
9380 // Both separators and spacers may be arbitrarily 9380 // Both separators and spacers may be arbitrarily
9381 // long strings. i.e. ":::". 9381 // long strings. i.e. ":::".
9382 // 9382 //
9383 // The function returns an ordered list 9383 // The function returns an ordered list
9384 // representing the tokens found in the supplied 9384 // representing the tokens found in the supplied
9385 // sources string. If two successive tokenizers 9385 // sources string. If two successive tokenizers
9386 // are encountered, then a NULL entry is added 9386 // are encountered, then a NULL entry is added
9387 // to the list. 9387 // to the list.
9388 // 9388 //
9389 // It is a precondition that the source and 9389 // It is a precondition that the source and
9390 // toekizer lisst are non-null. If they are null, 9390 // toekizer lisst are non-null. If they are null,
9391 // then a null pointer exception will be thrown 9391 // then a null pointer exception will be thrown
9392 // while their lengths are being determined. 9392 // while their lengths are being determined.
9393 // 9393 //
9394 // A small amount of working memoryis required 9394 // A small amount of working memoryis required
9395 // of approximately 8*#tokenizers. 9395 // of approximately 8*#tokenizers.
9396 // 9396 //
9397 // There are many ways in which this function 9397 // There are many ways in which this function
9398 // can be implemented, this implementation is 9398 // can be implemented, this implementation is
9399 // fairly naive and assumes that when the 9399 // fairly naive and assumes that when the
9400 // function is invooked with a short source 9400 // function is invooked with a short source
9401 // string and/or short lists of tokenizers, then 9401 // string and/or short lists of tokenizers, then
9402 // performance will not be an issue. 9402 // performance will not be an issue.
9403 // 9403 //
9404 // In order to minimize the perofrmance 9404 // In order to minimize the perofrmance
9405 // effects of long strings, or large numbers 9405 // effects of long strings, or large numbers
9406 // of tokeizers, the function skips as far as 9406 // of tokeizers, the function skips as far as
9407 // possible whenever a toekenizer is found, 9407 // possible whenever a toekenizer is found,
9408 // and eliminates redundant tokenizers as soon 9408 // and eliminates redundant tokenizers as soon
9409 // as is possible. 9409 // as is possible.
9410 // 9410 //
9411 // The implementation tries to avoid any copying 9411 // The implementation tries to avoid any copying
9412 // of arrays or other objects. 9412 // of arrays or other objects.
9413 // </remarks> 9413 // </remarks>
9414   9414  
9415 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9415 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9416 { 9416 {
9417 int beginning = 0; 9417 int beginning = 0;
9418 int srclen = src.Length; 9418 int srclen = src.Length;
9419 int seplen = separators.Length; 9419 int seplen = separators.Length;
9420 object[] separray = separators.Data; 9420 object[] separray = separators.Data;
9421 int spclen = spacers.Length; 9421 int spclen = spacers.Length;
9422 object[] spcarray = spacers.Data; 9422 object[] spcarray = spacers.Data;
9423 int mlen = seplen+spclen; 9423 int mlen = seplen+spclen;
9424   9424  
9425 int[] offset = new int[mlen+1]; 9425 int[] offset = new int[mlen+1];
9426 bool[] active = new bool[mlen]; 9426 bool[] active = new bool[mlen];
9427   9427  
9428 int best; 9428 int best;
9429 int j; 9429 int j;
9430   9430  
9431 // Initial capacity reduces resize cost 9431 // Initial capacity reduces resize cost
9432   9432  
9433 LSL_List tokens = new LSL_List(); 9433 LSL_List tokens = new LSL_List();
9434   9434  
9435 // All entries are initially valid 9435 // All entries are initially valid
9436   9436  
9437 for (int i = 0; i < mlen; i++) 9437 for (int i = 0; i < mlen; i++)
9438 active[i] = true; 9438 active[i] = true;
9439   9439  
9440 offset[mlen] = srclen; 9440 offset[mlen] = srclen;
9441   9441  
9442 while (beginning < srclen) 9442 while (beginning < srclen)
9443 { 9443 {
9444   9444  
9445 best = mlen; // as bad as it gets 9445 best = mlen; // as bad as it gets
9446   9446  
9447 // Scan for separators 9447 // Scan for separators
9448   9448  
9449 for (j = 0; j < seplen; j++) 9449 for (j = 0; j < seplen; j++)
9450 { 9450 {
9451 if (separray[j].ToString() == String.Empty) 9451 if (separray[j].ToString() == String.Empty)
9452 active[j] = false; 9452 active[j] = false;
9453   9453  
9454 if (active[j]) 9454 if (active[j])
9455 { 9455 {
9456 // scan all of the markers 9456 // scan all of the markers
9457 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9457 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
9458 { 9458 {
9459 // not present at all 9459 // not present at all
9460 active[j] = false; 9460 active[j] = false;
9461 } 9461 }
9462 else 9462 else
9463 { 9463 {
9464 // present and correct 9464 // present and correct
9465 if (offset[j] < offset[best]) 9465 if (offset[j] < offset[best])
9466 { 9466 {
9467 // closest so far 9467 // closest so far
9468 best = j; 9468 best = j;
9469 if (offset[best] == beginning) 9469 if (offset[best] == beginning)
9470 break; 9470 break;
9471 } 9471 }
9472 } 9472 }
9473 } 9473 }
9474 } 9474 }
9475   9475  
9476 // Scan for spacers 9476 // Scan for spacers
9477   9477  
9478 if (offset[best] != beginning) 9478 if (offset[best] != beginning)
9479 { 9479 {
9480 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9480 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++)
9481 { 9481 {
9482 if (spcarray[j-seplen].ToString() == String.Empty) 9482 if (spcarray[j-seplen].ToString() == String.Empty)
9483 active[j] = false; 9483 active[j] = false;
9484   9484  
9485 if (active[j]) 9485 if (active[j])
9486 { 9486 {
9487 // scan all of the markers 9487 // scan all of the markers
9488 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 9488 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9489 { 9489 {
9490 // not present at all 9490 // not present at all
9491 active[j] = false; 9491 active[j] = false;
9492 } 9492 }
9493 else 9493 else
9494 { 9494 {
9495 // present and correct 9495 // present and correct
9496 if (offset[j] < offset[best]) 9496 if (offset[j] < offset[best])
9497 { 9497 {
9498 // closest so far 9498 // closest so far
9499 best = j; 9499 best = j;
9500 } 9500 }
9501 } 9501 }
9502 } 9502 }
9503 } 9503 }
9504 } 9504 }
9505   9505  
9506 // This is the normal exit from the scanning loop 9506 // This is the normal exit from the scanning loop
9507   9507  
9508 if (best == mlen) 9508 if (best == mlen)
9509 { 9509 {
9510 // no markers were found on this pass 9510 // no markers were found on this pass
9511 // so we're pretty much done 9511 // so we're pretty much done
9512 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0)) 9512 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9513 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); 9513 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9514 break; 9514 break;
9515 } 9515 }
9516   9516  
9517 // Otherwise we just add the newly delimited token 9517 // Otherwise we just add the newly delimited token
9518 // and recalculate where the search should continue. 9518 // and recalculate where the search should continue.
9519 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9519 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0))
9520 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9520 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning)));
9521   9521  
9522 if (best < seplen) 9522 if (best < seplen)
9523 { 9523 {
9524 beginning = offset[best] + (separray[best].ToString()).Length; 9524 beginning = offset[best] + (separray[best].ToString()).Length;
9525 } 9525 }
9526 else 9526 else
9527 { 9527 {
9528 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length; 9528 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9529 string str = spcarray[best - seplen].ToString(); 9529 string str = spcarray[best - seplen].ToString();
9530 if ((keepNulls) || ((!keepNulls) && (str.Length > 0))) 9530 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9531 tokens.Add(new LSL_String(str)); 9531 tokens.Add(new LSL_String(str));
9532 } 9532 }
9533 } 9533 }
9534   9534  
9535 // This an awkward an not very intuitive boundary case. If the 9535 // This an awkward an not very intuitive boundary case. If the
9536 // last substring is a tokenizer, then there is an implied trailing 9536 // last substring is a tokenizer, then there is an implied trailing
9537 // null list entry. Hopefully the single comparison will not be too 9537 // null list entry. Hopefully the single comparison will not be too
9538 // arduous. Alternatively the 'break' could be replced with a return 9538 // arduous. Alternatively the 'break' could be replced with a return
9539 // but that's shabby programming. 9539 // but that's shabby programming.
9540   9540  
9541 if ((beginning == srclen) && (keepNulls)) 9541 if ((beginning == srclen) && (keepNulls))
9542 { 9542 {
9543 if (srclen != 0) 9543 if (srclen != 0)
9544 tokens.Add(new LSL_String("")); 9544 tokens.Add(new LSL_String(""));
9545 } 9545 }
9546   9546  
9547 return tokens; 9547 return tokens;
9548 } 9548 }
9549   9549  
9550 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers) 9550 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9551 { 9551 {
9552 m_host.AddScriptLPS(1); 9552 m_host.AddScriptLPS(1);
9553 return this.ParseString(src, separators, spacers, false); 9553 return this.ParseString(src, separators, spacers, false);
9554 } 9554 }
9555   9555  
9556 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 9556 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9557 { 9557 {
9558 m_host.AddScriptLPS(1); 9558 m_host.AddScriptLPS(1);
9559 return this.ParseString(src, separators, spacers, true); 9559 return this.ParseString(src, separators, spacers, true);
9560 } 9560 }
9561   9561  
9562 public LSL_Integer llGetObjectPermMask(int mask) 9562 public LSL_Integer llGetObjectPermMask(int mask)
9563 { 9563 {
9564 m_host.AddScriptLPS(1); 9564 m_host.AddScriptLPS(1);
9565   9565  
9566 int permmask = 0; 9566 int permmask = 0;
9567   9567  
9568 if (mask == ScriptBaseClass.MASK_BASE)//0 9568 if (mask == ScriptBaseClass.MASK_BASE)//0
9569 { 9569 {
9570 permmask = (int)m_host.BaseMask; 9570 permmask = (int)m_host.BaseMask;
9571 } 9571 }
9572   9572  
9573 else if (mask == ScriptBaseClass.MASK_OWNER)//1 9573 else if (mask == ScriptBaseClass.MASK_OWNER)//1
9574 { 9574 {
9575 permmask = (int)m_host.OwnerMask; 9575 permmask = (int)m_host.OwnerMask;
9576 } 9576 }
9577   9577  
9578 else if (mask == ScriptBaseClass.MASK_GROUP)//2 9578 else if (mask == ScriptBaseClass.MASK_GROUP)//2
9579 { 9579 {
9580 permmask = (int)m_host.GroupMask; 9580 permmask = (int)m_host.GroupMask;
9581 } 9581 }
9582   9582  
9583 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3 9583 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3
9584 { 9584 {
9585 permmask = (int)m_host.EveryoneMask; 9585 permmask = (int)m_host.EveryoneMask;
9586 } 9586 }
9587   9587  
9588 else if (mask == ScriptBaseClass.MASK_NEXT)//4 9588 else if (mask == ScriptBaseClass.MASK_NEXT)//4
9589 { 9589 {
9590 permmask = (int)m_host.NextOwnerMask; 9590 permmask = (int)m_host.NextOwnerMask;
9591 } 9591 }
9592   9592  
9593 return permmask; 9593 return permmask;
9594 } 9594 }
9595   9595  
9596 public void llSetObjectPermMask(int mask, int value) 9596 public void llSetObjectPermMask(int mask, int value)
9597 { 9597 {
9598 m_host.AddScriptLPS(1); 9598 m_host.AddScriptLPS(1);
9599   9599  
9600 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 9600 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
9601 { 9601 {
9602 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 9602 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
9603 { 9603 {
9604 if (mask == ScriptBaseClass.MASK_BASE)//0 9604 if (mask == ScriptBaseClass.MASK_BASE)//0
9605 { 9605 {
9606 m_host.BaseMask = (uint)value; 9606 m_host.BaseMask = (uint)value;
9607 } 9607 }
9608   9608  
9609 else if (mask == ScriptBaseClass.MASK_OWNER)//1 9609 else if (mask == ScriptBaseClass.MASK_OWNER)//1
9610 { 9610 {
9611 m_host.OwnerMask = (uint)value; 9611 m_host.OwnerMask = (uint)value;
9612 } 9612 }
9613   9613  
9614 else if (mask == ScriptBaseClass.MASK_GROUP)//2 9614 else if (mask == ScriptBaseClass.MASK_GROUP)//2
9615 { 9615 {
9616 m_host.GroupMask = (uint)value; 9616 m_host.GroupMask = (uint)value;
9617 } 9617 }
9618   9618  
9619 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3 9619 else if (mask == ScriptBaseClass.MASK_EVERYONE)//3
9620 { 9620 {
9621 m_host.EveryoneMask = (uint)value; 9621 m_host.EveryoneMask = (uint)value;
9622 } 9622 }
9623   9623  
9624 else if (mask == ScriptBaseClass.MASK_NEXT)//4 9624 else if (mask == ScriptBaseClass.MASK_NEXT)//4
9625 { 9625 {
9626 m_host.NextOwnerMask = (uint)value; 9626 m_host.NextOwnerMask = (uint)value;
9627 } 9627 }
9628 } 9628 }
9629 } 9629 }
9630 } 9630 }
9631   9631  
9632 public LSL_Integer llGetInventoryPermMask(string itemName, int mask) 9632 public LSL_Integer llGetInventoryPermMask(string itemName, int mask)
9633 { 9633 {
9634 m_host.AddScriptLPS(1); 9634 m_host.AddScriptLPS(1);
9635   9635  
9636 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9636 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9637   9637  
9638 if (item == null) 9638 if (item == null)
9639 return -1; 9639 return -1;
9640   9640  
9641 switch (mask) 9641 switch (mask)
9642 { 9642 {
9643 case 0: 9643 case 0:
9644 return (int)item.BasePermissions; 9644 return (int)item.BasePermissions;
9645 case 1: 9645 case 1:
9646 return (int)item.CurrentPermissions; 9646 return (int)item.CurrentPermissions;
9647 case 2: 9647 case 2:
9648 return (int)item.GroupPermissions; 9648 return (int)item.GroupPermissions;
9649 case 3: 9649 case 3:
9650 return (int)item.EveryonePermissions; 9650 return (int)item.EveryonePermissions;
9651 case 4: 9651 case 4:
9652 return (int)item.NextPermissions; 9652 return (int)item.NextPermissions;
9653 } 9653 }
9654   9654  
9655 return -1; 9655 return -1;
9656 } 9656 }
9657   9657  
9658 public void llSetInventoryPermMask(string itemName, int mask, int value) 9658 public void llSetInventoryPermMask(string itemName, int mask, int value)
9659 { 9659 {
9660 m_host.AddScriptLPS(1); 9660 m_host.AddScriptLPS(1);
9661   9661  
9662 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false)) 9662 if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
9663 { 9663 {
9664 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 9664 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
9665 { 9665 {
9666 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9666 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9667   9667  
9668 if (item != null) 9668 if (item != null)
9669 { 9669 {
9670 switch (mask) 9670 switch (mask)
9671 { 9671 {
9672 case 0: 9672 case 0:
9673 item.BasePermissions = (uint)value; 9673 item.BasePermissions = (uint)value;
9674 break; 9674 break;
9675 case 1: 9675 case 1:
9676 item.CurrentPermissions = (uint)value; 9676 item.CurrentPermissions = (uint)value;
9677 break; 9677 break;
9678 case 2: 9678 case 2:
9679 item.GroupPermissions = (uint)value; 9679 item.GroupPermissions = (uint)value;
9680 break; 9680 break;
9681 case 3: 9681 case 3:
9682 item.EveryonePermissions = (uint)value; 9682 item.EveryonePermissions = (uint)value;
9683 break; 9683 break;
9684 case 4: 9684 case 4:
9685 item.NextPermissions = (uint)value; 9685 item.NextPermissions = (uint)value;
9686 break; 9686 break;
9687 } 9687 }
9688 } 9688 }
9689 } 9689 }
9690 } 9690 }
9691 } 9691 }
9692   9692  
9693 public LSL_String llGetInventoryCreator(string itemName) 9693 public LSL_String llGetInventoryCreator(string itemName)
9694 { 9694 {
9695 m_host.AddScriptLPS(1); 9695 m_host.AddScriptLPS(1);
9696   9696  
9697 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName); 9697 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
9698   9698  
9699 if (item == null) 9699 if (item == null)
9700 { 9700 {
9701 llSay(0, "No item name '" + item + "'"); 9701 llSay(0, "No item name '" + item + "'");
9702   9702  
9703 return String.Empty; 9703 return String.Empty;
9704 } 9704 }
9705   9705  
9706 return item.CreatorID.ToString(); 9706 return item.CreatorID.ToString();
9707 } 9707 }
9708   9708  
9709 public void llOwnerSay(string msg) 9709 public void llOwnerSay(string msg)
9710 { 9710 {
9711 m_host.AddScriptLPS(1); 9711 m_host.AddScriptLPS(1);
9712   9712  
9713 World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, 9713 World.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0,
9714 m_host.AbsolutePosition, m_host.Name, m_host.UUID, false); 9714 m_host.AbsolutePosition, m_host.Name, m_host.UUID, false);
9715 // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 9715 // IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
9716 // wComm.DeliverMessage(ChatTypeEnum.Owner, 0, m_host.Name, m_host.UUID, msg); 9716 // wComm.DeliverMessage(ChatTypeEnum.Owner, 0, m_host.Name, m_host.UUID, msg);
9717 } 9717 }
9718   9718  
9719 public LSL_String llRequestSecureURL() 9719 public LSL_String llRequestSecureURL()
9720 { 9720 {
9721 m_host.AddScriptLPS(1); 9721 m_host.AddScriptLPS(1);
9722 if (m_UrlModule != null) 9722 if (m_UrlModule != null)
9723 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 9723 return m_UrlModule.RequestSecureURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
9724 return UUID.Zero.ToString(); 9724 return UUID.Zero.ToString();
9725 } 9725 }
9726   9726  
9727 public LSL_String llRequestSimulatorData(string simulator, int data) 9727 public LSL_String llRequestSimulatorData(string simulator, int data)
9728 { 9728 {
9729 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 9729 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
9730   9730  
9731 try 9731 try
9732 { 9732 {
9733 m_host.AddScriptLPS(1); 9733 m_host.AddScriptLPS(1);
9734   9734  
9735 string reply = String.Empty; 9735 string reply = String.Empty;
9736   9736  
9737 GridRegion info; 9737 GridRegion info;
9738   9738  
9739 if (World.RegionInfo.RegionName == simulator) 9739 if (World.RegionInfo.RegionName == simulator)
9740 info = new GridRegion(World.RegionInfo); 9740 info = new GridRegion(World.RegionInfo);
9741 else 9741 else
9742 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); 9742 info = World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator);
9743   9743  
9744 switch (data) 9744 switch (data)
9745 { 9745 {
9746 case ScriptBaseClass.DATA_SIM_POS: 9746 case ScriptBaseClass.DATA_SIM_POS:
9747 if (info == null) 9747 if (info == null)
9748 { 9748 {
9749 ScriptSleep(1000); 9749 ScriptSleep(1000);
9750 return UUID.Zero.ToString(); 9750 return UUID.Zero.ToString();
9751 } 9751 }
9752   9752  
9753 bool isHypergridRegion = false; 9753 bool isHypergridRegion = false;
9754   9754  
9755 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "") 9755 if (World.RegionInfo.RegionName != simulator && info.RegionSecret != "")
9756 { 9756 {
9757 // Hypergrid is currently placing real destination region co-ords into RegionSecret. 9757 // Hypergrid is currently placing real destination region co-ords into RegionSecret.
9758 // But other code can also use this field for a genuine RegionSecret! Therefore, if 9758 // But other code can also use this field for a genuine RegionSecret! Therefore, if
9759 // anything is present we need to disambiguate. 9759 // anything is present we need to disambiguate.
9760 // 9760 //
9761 // FIXME: Hypergrid should be storing this data in a different field. 9761 // FIXME: Hypergrid should be storing this data in a different field.
9762 RegionFlags regionFlags 9762 RegionFlags regionFlags
9763 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags( 9763 = (RegionFlags)m_ScriptEngine.World.GridService.GetRegionFlags(
9764 info.ScopeID, info.RegionID); 9764 info.ScopeID, info.RegionID);
9765 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0; 9765 isHypergridRegion = (regionFlags & RegionFlags.Hyperlink) != 0;
9766 } 9766 }
9767   9767  
9768 if (isHypergridRegion) 9768 if (isHypergridRegion)
9769 { 9769 {
9770 uint rx = 0, ry = 0; 9770 uint rx = 0, ry = 0;
9771 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); 9771 Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry);
9772   9772  
9773 reply = new LSL_Vector( 9773 reply = new LSL_Vector(
9774 rx, 9774 rx,
9775 ry, 9775 ry,
9776 0).ToString(); 9776 0).ToString();
9777 } 9777 }
9778 else 9778 else
9779 { 9779 {
9780 // Local grid co-oridnates 9780 // Local grid co-oridnates
9781 reply = new LSL_Vector( 9781 reply = new LSL_Vector(
9782 info.RegionLocX, 9782 info.RegionLocX,
9783 info.RegionLocY, 9783 info.RegionLocY,
9784 0).ToString(); 9784 0).ToString();
9785 } 9785 }
9786 break; 9786 break;
9787 case ScriptBaseClass.DATA_SIM_STATUS: 9787 case ScriptBaseClass.DATA_SIM_STATUS:
9788 if (info != null) 9788 if (info != null)
9789 reply = "up"; // Duh! 9789 reply = "up"; // Duh!
9790 else 9790 else
9791 reply = "unknown"; 9791 reply = "unknown";
9792 break; 9792 break;
9793 case ScriptBaseClass.DATA_SIM_RATING: 9793 case ScriptBaseClass.DATA_SIM_RATING:
9794 if (info == null) 9794 if (info == null)
9795 { 9795 {
9796 ScriptSleep(1000); 9796 ScriptSleep(1000);
9797 return UUID.Zero.ToString(); 9797 return UUID.Zero.ToString();
9798 } 9798 }
9799 int access = info.Maturity; 9799 int access = info.Maturity;
9800 if (access == 0) 9800 if (access == 0)
9801 reply = "PG"; 9801 reply = "PG";
9802 else if (access == 1) 9802 else if (access == 1)
9803 reply = "MATURE"; 9803 reply = "MATURE";
9804 else if (access == 2) 9804 else if (access == 2)
9805 reply = "ADULT"; 9805 reply = "ADULT";
9806 else 9806 else
9807 reply = "UNKNOWN"; 9807 reply = "UNKNOWN";
9808 break; 9808 break;
9809 case ScriptBaseClass.DATA_SIM_RELEASE: 9809 case ScriptBaseClass.DATA_SIM_RELEASE:
9810 if (ossl != null) 9810 if (ossl != null)
9811 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData"); 9811 ossl.CheckThreatLevel(ThreatLevel.High, "llRequestSimulatorData");
9812 reply = "OpenSim"; 9812 reply = "OpenSim";
9813 break; 9813 break;
9814 default: 9814 default:
9815 ScriptSleep(1000); 9815 ScriptSleep(1000);
9816 return UUID.Zero.ToString(); // Raise no event 9816 return UUID.Zero.ToString(); // Raise no event
9817 } 9817 }
9818 UUID rq = UUID.Random(); 9818 UUID rq = UUID.Random();
9819   9819  
9820 UUID tid = AsyncCommands. 9820 UUID tid = AsyncCommands.
9821 DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 9821 DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
9822   9822  
9823 AsyncCommands. 9823 AsyncCommands.
9824 DataserverPlugin.DataserverReply(rq.ToString(), reply); 9824 DataserverPlugin.DataserverReply(rq.ToString(), reply);
9825   9825  
9826 ScriptSleep(1000); 9826 ScriptSleep(1000);
9827 return tid.ToString(); 9827 return tid.ToString();
9828 } 9828 }
9829 catch(Exception) 9829 catch(Exception)
9830 { 9830 {
9831 //m_log.Error("[LSL_API]: llRequestSimulatorData" + e.ToString()); 9831 //m_log.Error("[LSL_API]: llRequestSimulatorData" + e.ToString());
9832 return UUID.Zero.ToString(); 9832 return UUID.Zero.ToString();
9833 } 9833 }
9834 } 9834 }
9835   9835  
9836 public LSL_String llRequestURL() 9836 public LSL_String llRequestURL()
9837 { 9837 {
9838 m_host.AddScriptLPS(1); 9838 m_host.AddScriptLPS(1);
9839   9839  
9840 if (m_UrlModule != null) 9840 if (m_UrlModule != null)
9841 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString(); 9841 return m_UrlModule.RequestURL(m_ScriptEngine.ScriptModule, m_host, m_item.ItemID).ToString();
9842 return UUID.Zero.ToString(); 9842 return UUID.Zero.ToString();
9843 } 9843 }
9844   9844  
9845 public void llForceMouselook(int mouselook) 9845 public void llForceMouselook(int mouselook)
9846 { 9846 {
9847 m_host.AddScriptLPS(1); 9847 m_host.AddScriptLPS(1);
9848 m_host.SetForceMouselook(mouselook != 0); 9848 m_host.SetForceMouselook(mouselook != 0);
9849 } 9849 }
9850   9850  
9851 public LSL_Float llGetObjectMass(string id) 9851 public LSL_Float llGetObjectMass(string id)
9852 { 9852 {
9853 m_host.AddScriptLPS(1); 9853 m_host.AddScriptLPS(1);
9854 UUID key = new UUID(); 9854 UUID key = new UUID();
9855 if (UUID.TryParse(id, out key)) 9855 if (UUID.TryParse(id, out key))
9856 { 9856 {
9857 try 9857 try
9858 { 9858 {
9859 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9859 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9860 if (obj != null) 9860 if (obj != null)
9861 return (double)obj.GetMass(); 9861 return (double)obj.GetMass();
9862 // the object is null so the key is for an avatar 9862 // the object is null so the key is for an avatar
9863 ScenePresence avatar = World.GetScenePresence(key); 9863 ScenePresence avatar = World.GetScenePresence(key);
9864 if (avatar != null) 9864 if (avatar != null)
9865 if (avatar.IsChildAgent) 9865 if (avatar.IsChildAgent)
9866 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass 9866 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9867 // child agents have a mass of 1.0 9867 // child agents have a mass of 1.0
9868 return 1; 9868 return 1;
9869 else 9869 else
9870 return (double)avatar.GetMass(); 9870 return (double)avatar.GetMass();
9871 } 9871 }
9872 catch (KeyNotFoundException) 9872 catch (KeyNotFoundException)
9873 { 9873 {
9874 return 0; // The Object/Agent not in the region so just return zero 9874 return 0; // The Object/Agent not in the region so just return zero
9875 } 9875 }
9876 } 9876 }
9877 return 0; 9877 return 0;
9878 } 9878 }
9879   9879  
9880 /// <summary> 9880 /// <summary>
9881 /// illListReplaceList removes the sub-list defined by the inclusive indices 9881 /// illListReplaceList removes the sub-list defined by the inclusive indices
9882 /// start and end and inserts the src list in its place. The inclusive 9882 /// start and end and inserts the src list in its place. The inclusive
9883 /// nature of the indices means that at least one element must be deleted 9883 /// nature of the indices means that at least one element must be deleted
9884 /// if the indices are within the bounds of the existing list. I.e. 2,2 9884 /// if the indices are within the bounds of the existing list. I.e. 2,2
9885 /// will remove the element at index 2 and replace it with the source 9885 /// will remove the element at index 2 and replace it with the source
9886 /// list. Both indices may be negative, with the usual interpretation. An 9886 /// list. Both indices may be negative, with the usual interpretation. An
9887 /// interesting case is where end is lower than start. As these indices 9887 /// interesting case is where end is lower than start. As these indices
9888 /// bound the list to be removed, then 0->end, and start->lim are removed 9888 /// bound the list to be removed, then 0->end, and start->lim are removed
9889 /// and the source list is added as a suffix. 9889 /// and the source list is added as a suffix.
9890 /// </summary> 9890 /// </summary>
9891   9891  
9892 public LSL_List llListReplaceList(LSL_List dest, LSL_List src, int start, int end) 9892 public LSL_List llListReplaceList(LSL_List dest, LSL_List src, int start, int end)
9893 { 9893 {
9894 LSL_List pref = null; 9894 LSL_List pref = null;
9895   9895  
9896 m_host.AddScriptLPS(1); 9896 m_host.AddScriptLPS(1);
9897   9897  
9898 // Note that although we have normalized, both 9898 // Note that although we have normalized, both
9899 // indices could still be negative. 9899 // indices could still be negative.
9900 if (start < 0) 9900 if (start < 0)
9901 { 9901 {
9902 start = start+dest.Length; 9902 start = start+dest.Length;
9903 } 9903 }
9904   9904  
9905 if (end < 0) 9905 if (end < 0)
9906 { 9906 {
9907 end = end+dest.Length; 9907 end = end+dest.Length;
9908 } 9908 }
9909 // The comventional case, remove a sequence starting with 9909 // The comventional case, remove a sequence starting with
9910 // start and ending with end. And then insert the source 9910 // start and ending with end. And then insert the source
9911 // list. 9911 // list.
9912 if (start <= end) 9912 if (start <= end)
9913 { 9913 {
9914 // If greater than zero, then there is going to be a 9914 // If greater than zero, then there is going to be a
9915 // surviving prefix. Otherwise the inclusive nature 9915 // surviving prefix. Otherwise the inclusive nature
9916 // of the indices mean that we're going to add the 9916 // of the indices mean that we're going to add the
9917 // source list as a prefix. 9917 // source list as a prefix.
9918 if (start > 0) 9918 if (start > 0)
9919 { 9919 {
9920 pref = dest.GetSublist(0,start-1); 9920 pref = dest.GetSublist(0,start-1);
9921 // Only add a suffix if there is something 9921 // Only add a suffix if there is something
9922 // beyond the end index (it's inclusive too). 9922 // beyond the end index (it's inclusive too).
9923 if (end + 1 < dest.Length) 9923 if (end + 1 < dest.Length)
9924 { 9924 {
9925 return pref + src + dest.GetSublist(end + 1, -1); 9925 return pref + src + dest.GetSublist(end + 1, -1);
9926 } 9926 }
9927 else 9927 else
9928 { 9928 {
9929 return pref + src; 9929 return pref + src;
9930 } 9930 }
9931 } 9931 }
9932 // If start is less than or equal to zero, then 9932 // If start is less than or equal to zero, then
9933 // the new list is simply a prefix. We still need to 9933 // the new list is simply a prefix. We still need to
9934 // figure out any necessary surgery to the destination 9934 // figure out any necessary surgery to the destination
9935 // based upon end. Note that if end exceeds the upper 9935 // based upon end. Note that if end exceeds the upper
9936 // bound in this case, the entire destination list 9936 // bound in this case, the entire destination list
9937 // is removed. 9937 // is removed.
9938 else 9938 else
9939 { 9939 {
9940 if (end + 1 < dest.Length) 9940 if (end + 1 < dest.Length)
9941 { 9941 {
9942 return src + dest.GetSublist(end + 1, -1); 9942 return src + dest.GetSublist(end + 1, -1);
9943 } 9943 }
9944 else 9944 else
9945 { 9945 {
9946 return src; 9946 return src;
9947 } 9947 }
9948 } 9948 }
9949 } 9949 }
9950 // Finally, if start > end, we strip away a prefix and 9950 // Finally, if start > end, we strip away a prefix and
9951 // a suffix, to leave the list that sits <between> ens 9951 // a suffix, to leave the list that sits <between> ens
9952 // and start, and then tag on the src list. AT least 9952 // and start, and then tag on the src list. AT least
9953 // that's my interpretation. We can get sublist to do 9953 // that's my interpretation. We can get sublist to do
9954 // this for us. Note that one, or both of the indices 9954 // this for us. Note that one, or both of the indices
9955 // might have been negative. 9955 // might have been negative.
9956 else 9956 else
9957 { 9957 {
9958 return dest.GetSublist(end + 1, start - 1) + src; 9958 return dest.GetSublist(end + 1, start - 1) + src;
9959 } 9959 }
9960 } 9960 }
9961   9961  
9962 public void llLoadURL(string avatar_id, string message, string url) 9962 public void llLoadURL(string avatar_id, string message, string url)
9963 { 9963 {
9964 m_host.AddScriptLPS(1); 9964 m_host.AddScriptLPS(1);
9965   9965  
9966 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 9966 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
9967 if (null != dm) 9967 if (null != dm)
9968 dm.SendUrlToUser( 9968 dm.SendUrlToUser(
9969 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); 9969 new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url);
9970   9970  
9971 ScriptSleep(10000); 9971 ScriptSleep(10000);
9972 } 9972 }
9973   9973  
9974 public void llParcelMediaCommandList(LSL_List commandList) 9974 public void llParcelMediaCommandList(LSL_List commandList)
9975 { 9975 {
9976 // TODO: Not implemented yet (missing in libomv?): 9976 // TODO: Not implemented yet (missing in libomv?):
9977 // 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) 9977 // 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)
9978   9978  
9979 m_host.AddScriptLPS(1); 9979 m_host.AddScriptLPS(1);
9980   9980  
9981 // according to the docs, this command only works if script owner and land owner are the same 9981 // according to the docs, this command only works if script owner and land owner are the same
9982 // lets add estate owners and gods, too, and use the generic permission check. 9982 // lets add estate owners and gods, too, and use the generic permission check.
9983 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 9983 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
9984 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 9984 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
9985   9985  
9986 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 9986 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
9987 byte loop = 0; 9987 byte loop = 0;
9988   9988  
9989 LandData landData = landObject.LandData; 9989 LandData landData = landObject.LandData;
9990 string url = landData.MediaURL; 9990 string url = landData.MediaURL;
9991 string texture = landData.MediaID.ToString(); 9991 string texture = landData.MediaID.ToString();
9992 bool autoAlign = landData.MediaAutoScale != 0; 9992 bool autoAlign = landData.MediaAutoScale != 0;
9993 string mediaType = ""; // TODO these have to be added as soon as LandData supports it 9993 string mediaType = ""; // TODO these have to be added as soon as LandData supports it
9994 string description = ""; 9994 string description = "";
9995 int width = 0; 9995 int width = 0;
9996 int height = 0; 9996 int height = 0;
9997   9997  
9998 ParcelMediaCommandEnum? commandToSend = null; 9998 ParcelMediaCommandEnum? commandToSend = null;
9999 float time = 0.0f; // default is from start 9999 float time = 0.0f; // default is from start
10000   10000  
10001 ScenePresence presence = null; 10001 ScenePresence presence = null;
10002   10002  
10003 for (int i = 0; i < commandList.Data.Length; i++) 10003 for (int i = 0; i < commandList.Data.Length; i++)
10004 { 10004 {
10005 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10005 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i];
10006 switch (command) 10006 switch (command)
10007 { 10007 {
10008 case ParcelMediaCommandEnum.Agent: 10008 case ParcelMediaCommandEnum.Agent:
10009 // we send only to one agent 10009 // we send only to one agent
10010 if ((i + 1) < commandList.Length) 10010 if ((i + 1) < commandList.Length)
10011 { 10011 {
10012 if (commandList.Data[i + 1] is LSL_String) 10012 if (commandList.Data[i + 1] is LSL_String)
10013 { 10013 {
10014 UUID agentID; 10014 UUID agentID;
10015 if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID)) 10015 if (UUID.TryParse((LSL_String)commandList.Data[i + 1], out agentID))
10016 { 10016 {
10017 presence = World.GetScenePresence(agentID); 10017 presence = World.GetScenePresence(agentID);
10018 } 10018 }
10019 } 10019 }
10020 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key"); 10020 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AGENT must be a key");
10021 ++i; 10021 ++i;
10022 } 10022 }
10023 break; 10023 break;
10024   10024  
10025 case ParcelMediaCommandEnum.Loop: 10025 case ParcelMediaCommandEnum.Loop:
10026 loop = 1; 10026 loop = 1;
10027 commandToSend = command; 10027 commandToSend = command;
10028 update = true; //need to send the media update packet to set looping 10028 update = true; //need to send the media update packet to set looping
10029 break; 10029 break;
10030   10030  
10031 case ParcelMediaCommandEnum.Play: 10031 case ParcelMediaCommandEnum.Play:
10032 loop = 0; 10032 loop = 0;
10033 commandToSend = command; 10033 commandToSend = command;
10034 update = true; //need to send the media update packet to make sure it doesn't loop 10034 update = true; //need to send the media update packet to make sure it doesn't loop
10035 break; 10035 break;
10036   10036  
10037 case ParcelMediaCommandEnum.Pause: 10037 case ParcelMediaCommandEnum.Pause:
10038 case ParcelMediaCommandEnum.Stop: 10038 case ParcelMediaCommandEnum.Stop:
10039 case ParcelMediaCommandEnum.Unload: 10039 case ParcelMediaCommandEnum.Unload:
10040 commandToSend = command; 10040 commandToSend = command;
10041 break; 10041 break;
10042   10042  
10043 case ParcelMediaCommandEnum.Url: 10043 case ParcelMediaCommandEnum.Url:
10044 if ((i + 1) < commandList.Length) 10044 if ((i + 1) < commandList.Length)
10045 { 10045 {
10046 if (commandList.Data[i + 1] is LSL_String) 10046 if (commandList.Data[i + 1] is LSL_String)
10047 { 10047 {
10048 url = (LSL_String)commandList.Data[i + 1]; 10048 url = (LSL_String)commandList.Data[i + 1];
10049 update = true; 10049 update = true;
10050 } 10050 }
10051 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_URL must be a string."); 10051 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_URL must be a string.");
10052 ++i; 10052 ++i;
10053 } 10053 }
10054 break; 10054 break;
10055   10055  
10056 case ParcelMediaCommandEnum.Texture: 10056 case ParcelMediaCommandEnum.Texture:
10057 if ((i + 1) < commandList.Length) 10057 if ((i + 1) < commandList.Length)
10058 { 10058 {
10059 if (commandList.Data[i + 1] is LSL_String) 10059 if (commandList.Data[i + 1] is LSL_String)
10060 { 10060 {
10061 texture = (LSL_String)commandList.Data[i + 1]; 10061 texture = (LSL_String)commandList.Data[i + 1];
10062 update = true; 10062 update = true;
10063 } 10063 }
10064 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or key."); 10064 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TEXTURE must be a string or key.");
10065 ++i; 10065 ++i;
10066 } 10066 }
10067 break; 10067 break;
10068   10068  
10069 case ParcelMediaCommandEnum.Time: 10069 case ParcelMediaCommandEnum.Time:
10070 if ((i + 1) < commandList.Length) 10070 if ((i + 1) < commandList.Length)
10071 { 10071 {
10072 if (commandList.Data[i + 1] is LSL_Float) 10072 if (commandList.Data[i + 1] is LSL_Float)
10073 { 10073 {
10074 time = (float)(LSL_Float)commandList.Data[i + 1]; 10074 time = (float)(LSL_Float)commandList.Data[i + 1];
10075 } 10075 }
10076 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TIME must be a float."); 10076 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TIME must be a float.");
10077 ++i; 10077 ++i;
10078 } 10078 }
10079 break; 10079 break;
10080   10080  
10081 case ParcelMediaCommandEnum.AutoAlign: 10081 case ParcelMediaCommandEnum.AutoAlign:
10082 if ((i + 1) < commandList.Length) 10082 if ((i + 1) < commandList.Length)
10083 { 10083 {
10084 if (commandList.Data[i + 1] is LSL_Integer) 10084 if (commandList.Data[i + 1] is LSL_Integer)
10085 { 10085 {
10086 autoAlign = (LSL_Integer)commandList.Data[i + 1]; 10086 autoAlign = (LSL_Integer)commandList.Data[i + 1];
10087 update = true; 10087 update = true;
10088 } 10088 }
10089   10089  
10090 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer."); 10090 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_AUTO_ALIGN must be an integer.");
10091 ++i; 10091 ++i;
10092 } 10092 }
10093 break; 10093 break;
10094   10094  
10095 case ParcelMediaCommandEnum.Type: 10095 case ParcelMediaCommandEnum.Type:
10096 if ((i + 1) < commandList.Length) 10096 if ((i + 1) < commandList.Length)
10097 { 10097 {
10098 if (commandList.Data[i + 1] is LSL_String) 10098 if (commandList.Data[i + 1] is LSL_String)
10099 { 10099 {
10100 mediaType = (LSL_String)commandList.Data[i + 1]; 10100 mediaType = (LSL_String)commandList.Data[i + 1];
10101 update = true; 10101 update = true;
10102 } 10102 }
10103 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string."); 10103 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_TYPE must be a string.");
10104 ++i; 10104 ++i;
10105 } 10105 }
10106 break; 10106 break;
10107   10107  
10108 case ParcelMediaCommandEnum.Desc: 10108 case ParcelMediaCommandEnum.Desc:
10109 if ((i + 1) < commandList.Length) 10109 if ((i + 1) < commandList.Length)
10110 { 10110 {
10111 if (commandList.Data[i + 1] is LSL_String) 10111 if (commandList.Data[i + 1] is LSL_String)
10112 { 10112 {
10113 description = (LSL_String)commandList.Data[i + 1]; 10113 description = (LSL_String)commandList.Data[i + 1];
10114 update = true; 10114 update = true;
10115 } 10115 }
10116 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_DESC must be a string."); 10116 else ShoutError("The argument of PARCEL_MEDIA_COMMAND_DESC must be a string.");
10117 ++i; 10117 ++i;
10118 } 10118 }
10119 break; 10119 break;
10120   10120  
10121 case ParcelMediaCommandEnum.Size: 10121 case ParcelMediaCommandEnum.Size:
10122 if ((i + 2) < commandList.Length) 10122 if ((i + 2) < commandList.Length)
10123 { 10123 {
10124 if (commandList.Data[i + 1] is LSL_Integer) 10124 if (commandList.Data[i + 1] is LSL_Integer)
10125 { 10125 {
10126 if (commandList.Data[i + 2] is LSL_Integer) 10126 if (commandList.Data[i + 2] is LSL_Integer)
10127 { 10127 {
10128 width = (LSL_Integer)commandList.Data[i + 1]; 10128 width = (LSL_Integer)commandList.Data[i + 1];
10129 height = (LSL_Integer)commandList.Data[i + 2]; 10129 height = (LSL_Integer)commandList.Data[i + 2];
10130 update = true; 10130 update = true;
10131 } 10131 }
10132 else ShoutError("The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); 10132 else ShoutError("The second argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer.");
10133 } 10133 }
10134 else ShoutError("The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer."); 10134 else ShoutError("The first argument of PARCEL_MEDIA_COMMAND_SIZE must be an integer.");
10135 i += 2; 10135 i += 2;
10136 } 10136 }
10137 break; 10137 break;
10138   10138  
10139 default: 10139 default:
10140 NotImplemented("llParcelMediaCommandList parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString()); 10140 NotImplemented("llParcelMediaCommandList parameter not supported yet: " + Enum.Parse(typeof(ParcelMediaCommandEnum), commandList.Data[i].ToString()).ToString());
10141 break; 10141 break;
10142 }//end switch 10142 }//end switch
10143 }//end for 10143 }//end for
10144   10144  
10145 // if we didn't get a presence, we send to all and change the url 10145 // if we didn't get a presence, we send to all and change the url
10146 // if we did get a presence, we only send to the agent specified, and *don't change the land settings*! 10146 // if we did get a presence, we only send to the agent specified, and *don't change the land settings*!
10147   10147  
10148 // did something important change or do we only start/stop/pause? 10148 // did something important change or do we only start/stop/pause?
10149 if (update) 10149 if (update)
10150 { 10150 {
10151 if (presence == null) 10151 if (presence == null)
10152 { 10152 {
10153 // we send to all 10153 // we send to all
10154 landData.MediaID = new UUID(texture); 10154 landData.MediaID = new UUID(texture);
10155 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0; 10155 landData.MediaAutoScale = autoAlign ? (byte)1 : (byte)0;
10156 landData.MediaWidth = width; 10156 landData.MediaWidth = width;
10157 landData.MediaHeight = height; 10157 landData.MediaHeight = height;
10158 landData.MediaType = mediaType; 10158 landData.MediaType = mediaType;
10159   10159  
10160 // do that one last, it will cause a ParcelPropertiesUpdate 10160 // do that one last, it will cause a ParcelPropertiesUpdate
10161 landObject.SetMediaUrl(url); 10161 landObject.SetMediaUrl(url);
10162   10162  
10163 // now send to all (non-child) agents in the parcel 10163 // now send to all (non-child) agents in the parcel
10164 World.ForEachRootScenePresence(delegate(ScenePresence sp) 10164 World.ForEachRootScenePresence(delegate(ScenePresence sp)
10165 { 10165 {
10166 if (sp.currentParcelUUID == landData.GlobalID) 10166 if (sp.currentParcelUUID == landData.GlobalID)
10167 { 10167 {
10168 sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL, 10168 sp.ControllingClient.SendParcelMediaUpdate(landData.MediaURL,
10169 landData.MediaID, 10169 landData.MediaID,
10170 landData.MediaAutoScale, 10170 landData.MediaAutoScale,
10171 mediaType, 10171 mediaType,
10172 description, 10172 description,
10173 width, height, 10173 width, height,
10174 loop); 10174 loop);
10175 } 10175 }
10176 }); 10176 });
10177 } 10177 }
10178 else if (!presence.IsChildAgent) 10178 else if (!presence.IsChildAgent)
10179 { 10179 {
10180 // we only send to one (root) agent 10180 // we only send to one (root) agent
10181 presence.ControllingClient.SendParcelMediaUpdate(url, 10181 presence.ControllingClient.SendParcelMediaUpdate(url,
10182 new UUID(texture), 10182 new UUID(texture),
10183 autoAlign ? (byte)1 : (byte)0, 10183 autoAlign ? (byte)1 : (byte)0,
10184 mediaType, 10184 mediaType,
10185 description, 10185 description,
10186 width, height, 10186 width, height,
10187 loop); 10187 loop);
10188 } 10188 }
10189 } 10189 }
10190   10190  
10191 if (commandToSend != null) 10191 if (commandToSend != null)
10192 { 10192 {
10193 // the commandList contained a start/stop/... command, too 10193 // the commandList contained a start/stop/... command, too
10194 if (presence == null) 10194 if (presence == null)
10195 { 10195 {
10196 // send to all (non-child) agents in the parcel 10196 // send to all (non-child) agents in the parcel
10197 World.ForEachRootScenePresence(delegate(ScenePresence sp) 10197 World.ForEachRootScenePresence(delegate(ScenePresence sp)
10198 { 10198 {
10199 if (sp.currentParcelUUID == landData.GlobalID) 10199 if (sp.currentParcelUUID == landData.GlobalID)
10200 { 10200 {
10201 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 10201 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
10202 (ParcelMediaCommandEnum)commandToSend, 10202 (ParcelMediaCommandEnum)commandToSend,
10203 time); 10203 time);
10204 } 10204 }
10205 }); 10205 });
10206 } 10206 }
10207 else if (!presence.IsChildAgent) 10207 else if (!presence.IsChildAgent)
10208 { 10208 {
10209 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 10209 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
10210 (ParcelMediaCommandEnum)commandToSend, 10210 (ParcelMediaCommandEnum)commandToSend,
10211 time); 10211 time);
10212 } 10212 }
10213 } 10213 }
10214 ScriptSleep(2000); 10214 ScriptSleep(2000);
10215 } 10215 }
10216   10216  
10217 public LSL_List llParcelMediaQuery(LSL_List aList) 10217 public LSL_List llParcelMediaQuery(LSL_List aList)
10218 { 10218 {
10219 m_host.AddScriptLPS(1); 10219 m_host.AddScriptLPS(1);
10220 LSL_List list = new LSL_List(); 10220 LSL_List list = new LSL_List();
10221 //TO DO: make the implementation for the missing commands 10221 //TO DO: make the implementation for the missing commands
10222 //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) 10222 //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)
10223 for (int i = 0; i < aList.Data.Length; i++) 10223 for (int i = 0; i < aList.Data.Length; i++)
10224 { 10224 {
10225   10225  
10226 if (aList.Data[i] != null) 10226 if (aList.Data[i] != null)
10227 { 10227 {
10228 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10228 switch ((ParcelMediaCommandEnum) aList.Data[i])
10229 { 10229 {
10230 case ParcelMediaCommandEnum.Url: 10230 case ParcelMediaCommandEnum.Url:
10231 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10231 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10232 break; 10232 break;
10233 case ParcelMediaCommandEnum.Desc: 10233 case ParcelMediaCommandEnum.Desc:
10234 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description)); 10234 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10235 break; 10235 break;
10236 case ParcelMediaCommandEnum.Texture: 10236 case ParcelMediaCommandEnum.Texture:
10237 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString())); 10237 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
10238 break; 10238 break;
10239 case ParcelMediaCommandEnum.Type: 10239 case ParcelMediaCommandEnum.Type:
10240 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType)); 10240 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
10241 break; 10241 break;
10242 case ParcelMediaCommandEnum.Size: 10242 case ParcelMediaCommandEnum.Size:
10243 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth)); 10243 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth));
10244 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight)); 10244 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
10245 break; 10245 break;
10246 default: 10246 default:
10247 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10247 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
10248 NotImplemented("llParcelMediaQuery parameter do not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString()); 10248 NotImplemented("llParcelMediaQuery parameter do not supported yet: " + Enum.Parse(mediaCommandEnum.GetType() , aList.Data[i].ToString()).ToString());
10249 break; 10249 break;
10250 } 10250 }
10251   10251  
10252 } 10252 }
10253 } 10253 }
10254 ScriptSleep(2000); 10254 ScriptSleep(2000);
10255 return list; 10255 return list;
10256 } 10256 }
10257   10257  
10258 public LSL_Integer llModPow(int a, int b, int c) 10258 public LSL_Integer llModPow(int a, int b, int c)
10259 { 10259 {
10260 m_host.AddScriptLPS(1); 10260 m_host.AddScriptLPS(1);
10261 Int64 tmp = 0; 10261 Int64 tmp = 0;
10262 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); 10262 Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp);
10263 ScriptSleep(1000); 10263 ScriptSleep(1000);
10264 return Convert.ToInt32(tmp); 10264 return Convert.ToInt32(tmp);
10265 } 10265 }
10266   10266  
10267 public LSL_Integer llGetInventoryType(string name) 10267 public LSL_Integer llGetInventoryType(string name)
10268 { 10268 {
10269 m_host.AddScriptLPS(1); 10269 m_host.AddScriptLPS(1);
10270   10270  
10271 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 10271 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
10272   10272  
10273 if (item == null) 10273 if (item == null)
10274 return -1; 10274 return -1;
10275   10275  
10276 return item.Type; 10276 return item.Type;
10277 } 10277 }
10278   10278  
10279 public void llSetPayPrice(int price, LSL_List quick_pay_buttons) 10279 public void llSetPayPrice(int price, LSL_List quick_pay_buttons)
10280 { 10280 {
10281 m_host.AddScriptLPS(1); 10281 m_host.AddScriptLPS(1);
10282   10282  
10283 if (quick_pay_buttons.Data.Length < 4) 10283 if (quick_pay_buttons.Data.Length < 4)
10284 { 10284 {
10285 LSLError("List must have at least 4 elements"); 10285 LSLError("List must have at least 4 elements");
10286 return; 10286 return;
10287 } 10287 }
10288 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10288 m_host.ParentGroup.RootPart.PayPrice[0]=price;
10289   10289  
10290 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10290 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0];
10291 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10291 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1];
10292 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10292 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2];
10293 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10293 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3];
10294 m_host.ParentGroup.HasGroupChanged = true; 10294 m_host.ParentGroup.HasGroupChanged = true;
10295 } 10295 }
10296   10296  
10297 public LSL_Vector llGetCameraPos() 10297 public LSL_Vector llGetCameraPos()
10298 { 10298 {
10299 m_host.AddScriptLPS(1); 10299 m_host.AddScriptLPS(1);
10300   10300  
10301 if (m_item.PermsGranter == UUID.Zero) 10301 if (m_item.PermsGranter == UUID.Zero)
10302 return Vector3.Zero; 10302 return Vector3.Zero;
10303   10303  
10304 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10304 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10305 { 10305 {
10306 ShoutError("No permissions to track the camera"); 10306 ShoutError("No permissions to track the camera");
10307 return Vector3.Zero; 10307 return Vector3.Zero;
10308 } 10308 }
10309   10309  
10310 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10310 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10311 if (presence != null) 10311 if (presence != null)
10312 { 10312 {
10313 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10313 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10314 return pos; 10314 return pos;
10315 } 10315 }
10316   10316  
10317 return Vector3.Zero; 10317 return Vector3.Zero;
10318 } 10318 }
10319   10319  
10320 public LSL_Rotation llGetCameraRot() 10320 public LSL_Rotation llGetCameraRot()
10321 { 10321 {
10322 m_host.AddScriptLPS(1); 10322 m_host.AddScriptLPS(1);
10323   10323  
10324 if (m_item.PermsGranter == UUID.Zero) 10324 if (m_item.PermsGranter == UUID.Zero)
10325 return Quaternion.Identity; 10325 return Quaternion.Identity;
10326   10326  
10327 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10327 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10328 { 10328 {
10329 ShoutError("No permissions to track the camera"); 10329 ShoutError("No permissions to track the camera");
10330 return Quaternion.Identity; 10330 return Quaternion.Identity;
10331 } 10331 }
10332   10332  
10333 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10333 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10334 if (presence != null) 10334 if (presence != null)
10335 { 10335 {
10336 return new LSL_Rotation(presence.CameraRotation); 10336 return new LSL_Rotation(presence.CameraRotation);
10337 } 10337 }
10338   10338  
10339 return Quaternion.Identity; 10339 return Quaternion.Identity;
10340 } 10340 }
10341   10341  
10342 /// <summary> 10342 /// <summary>
10343 /// The SL implementation does nothing, it is deprecated 10343 /// The SL implementation does nothing, it is deprecated
10344 /// This duplicates SL 10344 /// This duplicates SL
10345 /// </summary> 10345 /// </summary>
10346 public void llSetPrimURL(string url) 10346 public void llSetPrimURL(string url)
10347 { 10347 {
10348 m_host.AddScriptLPS(1); 10348 m_host.AddScriptLPS(1);
10349 ScriptSleep(2000); 10349 ScriptSleep(2000);
10350 } 10350 }
10351   10351  
10352 /// <summary> 10352 /// <summary>
10353 /// The SL implementation shouts an error, it is deprecated 10353 /// The SL implementation shouts an error, it is deprecated
10354 /// This duplicates SL 10354 /// This duplicates SL
10355 /// </summary> 10355 /// </summary>
10356 public void llRefreshPrimURL() 10356 public void llRefreshPrimURL()
10357 { 10357 {
10358 m_host.AddScriptLPS(1); 10358 m_host.AddScriptLPS(1);
10359 ShoutError("llRefreshPrimURL - not yet supported"); 10359 ShoutError("llRefreshPrimURL - not yet supported");
10360 ScriptSleep(20000); 10360 ScriptSleep(20000);
10361 } 10361 }
10362   10362  
10363 public LSL_String llEscapeURL(string url) 10363 public LSL_String llEscapeURL(string url)
10364 { 10364 {
10365 m_host.AddScriptLPS(1); 10365 m_host.AddScriptLPS(1);
10366 try 10366 try
10367 { 10367 {
10368 return Uri.EscapeDataString(url); 10368 return Uri.EscapeDataString(url);
10369 } 10369 }
10370 catch (Exception ex) 10370 catch (Exception ex)
10371 { 10371 {
10372 return "llEscapeURL: " + ex.ToString(); 10372 return "llEscapeURL: " + ex.ToString();
10373 } 10373 }
10374 } 10374 }
10375   10375  
10376 public LSL_String llUnescapeURL(string url) 10376 public LSL_String llUnescapeURL(string url)
10377 { 10377 {
10378 m_host.AddScriptLPS(1); 10378 m_host.AddScriptLPS(1);
10379 try 10379 try
10380 { 10380 {
10381 return Uri.UnescapeDataString(url); 10381 return Uri.UnescapeDataString(url);
10382 } 10382 }
10383 catch (Exception ex) 10383 catch (Exception ex)
10384 { 10384 {
10385 return "llUnescapeURL: " + ex.ToString(); 10385 return "llUnescapeURL: " + ex.ToString();
10386 } 10386 }
10387 } 10387 }
10388   10388  
10389 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) 10389 public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt)
10390 { 10390 {
10391 m_host.AddScriptLPS(1); 10391 m_host.AddScriptLPS(1);
10392 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10392 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10393 if (detectedParams == null) return; // only works on the first detected avatar 10393 if (detectedParams == null) return; // only works on the first detected avatar
10394   10394  
10395 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10395 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10396 if (avatar != null) 10396 if (avatar != null)
10397 { 10397 {
10398 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10398 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10399 simname, pos, lookAt); 10399 simname, pos, lookAt);
10400 } 10400 }
10401 ScriptSleep(1000); 10401 ScriptSleep(1000);
10402 } 10402 }
10403   10403  
10404 public void llAddToLandBanList(string avatar, double hours) 10404 public void llAddToLandBanList(string avatar, double hours)
10405 { 10405 {
10406 m_host.AddScriptLPS(1); 10406 m_host.AddScriptLPS(1);
10407 UUID key; 10407 UUID key;
10408 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10408 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10409 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10409 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10410 { 10410 {
10411 int expires = 0; 10411 int expires = 0;
10412 if (hours != 0) 10412 if (hours != 0)
10413 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours); 10413 expires = Util.UnixTimeSinceEpoch() + (int)(3600.0 * hours);
10414   10414  
10415 if (UUID.TryParse(avatar, out key)) 10415 if (UUID.TryParse(avatar, out key))
10416 { 10416 {
10417 int idx = land.LandData.ParcelAccessList.FindIndex( 10417 int idx = land.LandData.ParcelAccessList.FindIndex(
10418 delegate(LandAccessEntry e) 10418 delegate(LandAccessEntry e)
10419 { 10419 {
10420 if (e.AgentID == key && e.Flags == AccessList.Ban) 10420 if (e.AgentID == key && e.Flags == AccessList.Ban)
10421 return true; 10421 return true;
10422 return false; 10422 return false;
10423 }); 10423 });
10424   10424  
10425 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires))) 10425 if (idx != -1 && (land.LandData.ParcelAccessList[idx].Expires == 0 || (expires != 0 && expires < land.LandData.ParcelAccessList[idx].Expires)))
10426 return; 10426 return;
10427   10427  
10428 if (idx != -1) 10428 if (idx != -1)
10429 land.LandData.ParcelAccessList.RemoveAt(idx); 10429 land.LandData.ParcelAccessList.RemoveAt(idx);
10430   10430  
10431 LandAccessEntry entry = new LandAccessEntry(); 10431 LandAccessEntry entry = new LandAccessEntry();
10432   10432  
10433 entry.AgentID = key; 10433 entry.AgentID = key;
10434 entry.Flags = AccessList.Ban; 10434 entry.Flags = AccessList.Ban;
10435 entry.Expires = expires; 10435 entry.Expires = expires;
10436   10436  
10437 land.LandData.ParcelAccessList.Add(entry); 10437 land.LandData.ParcelAccessList.Add(entry);
10438   10438  
10439 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10439 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10440 } 10440 }
10441 } 10441 }
10442 ScriptSleep(100); 10442 ScriptSleep(100);
10443 } 10443 }
10444   10444  
10445 public void llRemoveFromLandPassList(string avatar) 10445 public void llRemoveFromLandPassList(string avatar)
10446 { 10446 {
10447 m_host.AddScriptLPS(1); 10447 m_host.AddScriptLPS(1);
10448 UUID key; 10448 UUID key;
10449 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10449 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10450 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10450 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10451 { 10451 {
10452 if (UUID.TryParse(avatar, out key)) 10452 if (UUID.TryParse(avatar, out key))
10453 { 10453 {
10454 int idx = land.LandData.ParcelAccessList.FindIndex( 10454 int idx = land.LandData.ParcelAccessList.FindIndex(
10455 delegate(LandAccessEntry e) 10455 delegate(LandAccessEntry e)
10456 { 10456 {
10457 if (e.AgentID == key && e.Flags == AccessList.Access) 10457 if (e.AgentID == key && e.Flags == AccessList.Access)
10458 return true; 10458 return true;
10459 return false; 10459 return false;
10460 }); 10460 });
10461   10461  
10462 if (idx != -1) 10462 if (idx != -1)
10463 { 10463 {
10464 land.LandData.ParcelAccessList.RemoveAt(idx); 10464 land.LandData.ParcelAccessList.RemoveAt(idx);
10465 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10465 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10466 } 10466 }
10467 } 10467 }
10468 } 10468 }
10469 ScriptSleep(100); 10469 ScriptSleep(100);
10470 } 10470 }
10471   10471  
10472 public void llRemoveFromLandBanList(string avatar) 10472 public void llRemoveFromLandBanList(string avatar)
10473 { 10473 {
10474 m_host.AddScriptLPS(1); 10474 m_host.AddScriptLPS(1);
10475 UUID key; 10475 UUID key;
10476 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10476 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10477 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10477 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10478 { 10478 {
10479 if (UUID.TryParse(avatar, out key)) 10479 if (UUID.TryParse(avatar, out key))
10480 { 10480 {
10481 int idx = land.LandData.ParcelAccessList.FindIndex( 10481 int idx = land.LandData.ParcelAccessList.FindIndex(
10482 delegate(LandAccessEntry e) 10482 delegate(LandAccessEntry e)
10483 { 10483 {
10484 if (e.AgentID == key && e.Flags == AccessList.Ban) 10484 if (e.AgentID == key && e.Flags == AccessList.Ban)
10485 return true; 10485 return true;
10486 return false; 10486 return false;
10487 }); 10487 });
10488   10488  
10489 if (idx != -1) 10489 if (idx != -1)
10490 { 10490 {
10491 land.LandData.ParcelAccessList.RemoveAt(idx); 10491 land.LandData.ParcelAccessList.RemoveAt(idx);
10492 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); 10492 World.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
10493 } 10493 }
10494 } 10494 }
10495 } 10495 }
10496 ScriptSleep(100); 10496 ScriptSleep(100);
10497 } 10497 }
10498   10498  
10499 public void llSetCameraParams(LSL_List rules) 10499 public void llSetCameraParams(LSL_List rules)
10500 { 10500 {
10501 m_host.AddScriptLPS(1); 10501 m_host.AddScriptLPS(1);
10502   10502  
10503 // the object we are in 10503 // the object we are in
10504 UUID objectID = m_host.ParentUUID; 10504 UUID objectID = m_host.ParentUUID;
10505 if (objectID == UUID.Zero) 10505 if (objectID == UUID.Zero)
10506 return; 10506 return;
10507   10507  
10508 // we need the permission first, to know which avatar we want to set the camera for 10508 // we need the permission first, to know which avatar we want to set the camera for
10509 UUID agentID = m_item.PermsGranter; 10509 UUID agentID = m_item.PermsGranter;
10510   10510  
10511 if (agentID == UUID.Zero) 10511 if (agentID == UUID.Zero)
10512 return; 10512 return;
10513   10513  
10514 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10514 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10515 return; 10515 return;
10516   10516  
10517 ScenePresence presence = World.GetScenePresence(agentID); 10517 ScenePresence presence = World.GetScenePresence(agentID);
10518   10518  
10519 // we are not interested in child-agents 10519 // we are not interested in child-agents
10520 if (presence.IsChildAgent) return; 10520 if (presence.IsChildAgent) return;
10521   10521  
10522 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10522 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10523 object[] data = rules.Data; 10523 object[] data = rules.Data;
10524 for (int i = 0; i < data.Length; ++i) { 10524 for (int i = 0; i < data.Length; ++i) {
10525 int type = Convert.ToInt32(data[i++].ToString()); 10525 int type = Convert.ToInt32(data[i++].ToString());
10526 if (i >= data.Length) break; // odd number of entries => ignore the last 10526 if (i >= data.Length) break; // odd number of entries => ignore the last
10527   10527  
10528 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10528 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10529 switch (type) { 10529 switch (type) {
10530 case ScriptBaseClass.CAMERA_FOCUS: 10530 case ScriptBaseClass.CAMERA_FOCUS:
10531 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10531 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10532 case ScriptBaseClass.CAMERA_POSITION: 10532 case ScriptBaseClass.CAMERA_POSITION:
10533 LSL_Vector v = (LSL_Vector)data[i]; 10533 LSL_Vector v = (LSL_Vector)data[i];
10534 parameters.Add(type + 1, (float)v.x); 10534 parameters.Add(type + 1, (float)v.x);
10535 parameters.Add(type + 2, (float)v.y); 10535 parameters.Add(type + 2, (float)v.y);
10536 parameters.Add(type + 3, (float)v.z); 10536 parameters.Add(type + 3, (float)v.z);
10537 break; 10537 break;
10538 default: 10538 default:
10539 // TODO: clean that up as soon as the implicit casts are in 10539 // TODO: clean that up as soon as the implicit casts are in
10540 if (data[i] is LSL_Float) 10540 if (data[i] is LSL_Float)
10541 parameters.Add(type, (float)((LSL_Float)data[i]).value); 10541 parameters.Add(type, (float)((LSL_Float)data[i]).value);
10542 else if (data[i] is LSL_Integer) 10542 else if (data[i] is LSL_Integer)
10543 parameters.Add(type, (float)((LSL_Integer)data[i]).value); 10543 parameters.Add(type, (float)((LSL_Integer)data[i]).value);
10544 else parameters.Add(type, Convert.ToSingle(data[i])); 10544 else parameters.Add(type, Convert.ToSingle(data[i]));
10545 break; 10545 break;
10546 } 10546 }
10547 } 10547 }
10548 if (parameters.Count > 0) presence.ControllingClient.SendSetFollowCamProperties(objectID, parameters); 10548 if (parameters.Count > 0) presence.ControllingClient.SendSetFollowCamProperties(objectID, parameters);
10549 } 10549 }
10550   10550  
10551 public void llClearCameraParams() 10551 public void llClearCameraParams()
10552 { 10552 {
10553 m_host.AddScriptLPS(1); 10553 m_host.AddScriptLPS(1);
10554   10554  
10555 // the object we are in 10555 // the object we are in
10556 UUID objectID = m_host.ParentUUID; 10556 UUID objectID = m_host.ParentUUID;
10557 if (objectID == UUID.Zero) 10557 if (objectID == UUID.Zero)
10558 return; 10558 return;
10559   10559  
10560 // we need the permission first, to know which avatar we want to clear the camera for 10560 // we need the permission first, to know which avatar we want to clear the camera for
10561 UUID agentID = m_item.PermsGranter; 10561 UUID agentID = m_item.PermsGranter;
10562   10562  
10563 if (agentID == UUID.Zero) 10563 if (agentID == UUID.Zero)
10564 return; 10564 return;
10565   10565  
10566 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) 10566 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10567 return; 10567 return;
10568   10568  
10569 ScenePresence presence = World.GetScenePresence(agentID); 10569 ScenePresence presence = World.GetScenePresence(agentID);
10570   10570  
10571 // we are not interested in child-agents 10571 // we are not interested in child-agents
10572 if (presence.IsChildAgent) 10572 if (presence.IsChildAgent)
10573 return; 10573 return;
10574   10574  
10575 presence.ControllingClient.SendClearFollowCamProperties(objectID); 10575 presence.ControllingClient.SendClearFollowCamProperties(objectID);
10576 } 10576 }
10577   10577  
10578 public LSL_Float llListStatistics(int operation, LSL_List src) 10578 public LSL_Float llListStatistics(int operation, LSL_List src)
10579 { 10579 {
10580 m_host.AddScriptLPS(1); 10580 m_host.AddScriptLPS(1);
10581 switch (operation) 10581 switch (operation)
10582 { 10582 {
10583 case ScriptBaseClass.LIST_STAT_RANGE: 10583 case ScriptBaseClass.LIST_STAT_RANGE:
10584 return src.Range(); 10584 return src.Range();
10585 case ScriptBaseClass.LIST_STAT_MIN: 10585 case ScriptBaseClass.LIST_STAT_MIN:
10586 return src.Min(); 10586 return src.Min();
10587 case ScriptBaseClass.LIST_STAT_MAX: 10587 case ScriptBaseClass.LIST_STAT_MAX:
10588 return src.Max(); 10588 return src.Max();
10589 case ScriptBaseClass.LIST_STAT_MEAN: 10589 case ScriptBaseClass.LIST_STAT_MEAN:
10590 return src.Mean(); 10590 return src.Mean();
10591 case ScriptBaseClass.LIST_STAT_MEDIAN: 10591 case ScriptBaseClass.LIST_STAT_MEDIAN:
10592 return LSL_List.ToDoubleList(src).Median(); 10592 return LSL_List.ToDoubleList(src).Median();
10593 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10593 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
10594 return src.NumericLength(); 10594 return src.NumericLength();
10595 case ScriptBaseClass.LIST_STAT_STD_DEV: 10595 case ScriptBaseClass.LIST_STAT_STD_DEV:
10596 return src.StdDev(); 10596 return src.StdDev();
10597 case ScriptBaseClass.LIST_STAT_SUM: 10597 case ScriptBaseClass.LIST_STAT_SUM:
10598 return src.Sum(); 10598 return src.Sum();
10599 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10599 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
10600 return src.SumSqrs(); 10600 return src.SumSqrs();
10601 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10601 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
10602 return src.GeometricMean(); 10602 return src.GeometricMean();
10603 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10603 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
10604 return src.HarmonicMean(); 10604 return src.HarmonicMean();
10605 default: 10605 default:
10606 return 0.0; 10606 return 0.0;
10607 } 10607 }
10608 } 10608 }
10609   10609  
10610 public LSL_Integer llGetUnixTime() 10610 public LSL_Integer llGetUnixTime()
10611 { 10611 {
10612 m_host.AddScriptLPS(1); 10612 m_host.AddScriptLPS(1);
10613 return Util.UnixTimeSinceEpoch(); 10613 return Util.UnixTimeSinceEpoch();
10614 } 10614 }
10615   10615  
10616 public LSL_Integer llGetParcelFlags(LSL_Vector pos) 10616 public LSL_Integer llGetParcelFlags(LSL_Vector pos)
10617 { 10617 {
10618 m_host.AddScriptLPS(1); 10618 m_host.AddScriptLPS(1);
10619 return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags; 10619 return (int)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y).LandData.Flags;
10620 } 10620 }
10621   10621  
10622 public LSL_Integer llGetRegionFlags() 10622 public LSL_Integer llGetRegionFlags()
10623 { 10623 {
10624 m_host.AddScriptLPS(1); 10624 m_host.AddScriptLPS(1);
10625 IEstateModule estate = World.RequestModuleInterface<IEstateModule>(); 10625 IEstateModule estate = World.RequestModuleInterface<IEstateModule>();
10626 if (estate == null) 10626 if (estate == null)
10627 return 67108864; 10627 return 67108864;
10628 return (int)estate.GetRegionFlags(); 10628 return (int)estate.GetRegionFlags();
10629 } 10629 }
10630   10630  
10631 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10631 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10632 { 10632 {
10633 m_host.AddScriptLPS(1); 10633 m_host.AddScriptLPS(1);
10634 string ret = String.Empty; 10634 string ret = String.Empty;
10635 string src1 = llBase64ToString(str1); 10635 string src1 = llBase64ToString(str1);
10636 string src2 = llBase64ToString(str2); 10636 string src2 = llBase64ToString(str2);
10637 int c = 0; 10637 int c = 0;
10638 for (int i = 0; i < src1.Length; i++) 10638 for (int i = 0; i < src1.Length; i++)
10639 { 10639 {
10640 ret += (char) (src1[i] ^ src2[c]); 10640 ret += (char) (src1[i] ^ src2[c]);
10641   10641  
10642 c++; 10642 c++;
10643 if (c >= src2.Length) 10643 if (c >= src2.Length)
10644 c = 0; 10644 c = 0;
10645 } 10645 }
10646 return llStringToBase64(ret); 10646 return llStringToBase64(ret);
10647 } 10647 }
10648   10648  
10649 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10649 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
10650 { 10650 {
10651 // Partial implementation: support for parameter flags needed 10651 // Partial implementation: support for parameter flags needed
10652 // see http://wiki.secondlife.com/wiki/LlHTTPRequest 10652 // see http://wiki.secondlife.com/wiki/LlHTTPRequest
10653 // parameter flags support are implemented in ScriptsHttpRequests.cs 10653 // parameter flags support are implemented in ScriptsHttpRequests.cs
10654 // in StartHttpRequest 10654 // in StartHttpRequest
10655   10655  
10656 m_host.AddScriptLPS(1); 10656 m_host.AddScriptLPS(1);
10657 IHttpRequestModule httpScriptMod = 10657 IHttpRequestModule httpScriptMod =
10658 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 10658 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
10659 List<string> param = new List<string>(); 10659 List<string> param = new List<string>();
10660 bool ok; 10660 bool ok;
10661 Int32 flag; 10661 Int32 flag;
10662   10662  
10663 for (int i = 0; i < parameters.Data.Length; i += 2) 10663 for (int i = 0; i < parameters.Data.Length; i += 2)
10664 { 10664 {
10665 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag); 10665 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
10666 if (!ok || flag < 0 || 10666 if (!ok || flag < 0 ||
10667 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE) 10667 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
10668 { 10668 {
10669 throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag"); 10669 throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag");
10670 } 10670 }
10671   10671  
10672 param.Add(parameters.Data[i].ToString()); //Add parameter flag 10672 param.Add(parameters.Data[i].ToString()); //Add parameter flag
10673   10673  
10674 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER) 10674 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
10675 { 10675 {
10676 param.Add(parameters.Data[i+1].ToString()); //Add parameter value 10676 param.Add(parameters.Data[i+1].ToString()); //Add parameter value
10677 } 10677 }
10678 else 10678 else
10679 { 10679 {
10680 //Parameters are in pairs and custom header takes 10680 //Parameters are in pairs and custom header takes
10681 //arguments in pairs so adjust for header marker. 10681 //arguments in pairs so adjust for header marker.
10682 ++i; 10682 ++i;
10683   10683  
10684 //Maximum of 8 headers are allowed based on the 10684 //Maximum of 8 headers are allowed based on the
10685 //Second Life documentation for llHTTPRequest. 10685 //Second Life documentation for llHTTPRequest.
10686 for (int count = 1; count <= 8; ++count) 10686 for (int count = 1; count <= 8; ++count)
10687 { 10687 {
10688 //Enough parameters remaining for (another) header? 10688 //Enough parameters remaining for (another) header?
10689 if (parameters.Data.Length - i < 2) 10689 if (parameters.Data.Length - i < 2)
10690 { 10690 {
10691 //There must be at least one name/value pair for custom header 10691 //There must be at least one name/value pair for custom header
10692 if (count == 1) 10692 if (count == 1)
10693 throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString()); 10693 throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString());
10694 break; 10694 break;
10695 } 10695 }
10696   10696  
10697 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase)) 10697 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
10698 throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString()); 10698 throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString());
10699   10699  
10700 param.Add(parameters.Data[i].ToString()); 10700 param.Add(parameters.Data[i].ToString());
10701 param.Add(parameters.Data[i+1].ToString()); 10701 param.Add(parameters.Data[i+1].ToString());
10702   10702  
10703 //Have we reached the end of the list of headers? 10703 //Have we reached the end of the list of headers?
10704 //End is marked by a string with a single digit. 10704 //End is marked by a string with a single digit.
10705 if (i+2 >= parameters.Data.Length || 10705 if (i+2 >= parameters.Data.Length ||
10706 Char.IsDigit(parameters.Data[i].ToString()[0])) 10706 Char.IsDigit(parameters.Data[i].ToString()[0]))
10707 { 10707 {
10708 break; 10708 break;
10709 } 10709 }
10710   10710  
10711 i += 2; 10711 i += 2;
10712 } 10712 }
10713 } 10713 }
10714 } 10714 }
10715   10715  
10716 Vector3 position = m_host.AbsolutePosition; 10716 Vector3 position = m_host.AbsolutePosition;
10717 Vector3 velocity = m_host.Velocity; 10717 Vector3 velocity = m_host.Velocity;
10718 Quaternion rotation = m_host.RotationOffset; 10718 Quaternion rotation = m_host.RotationOffset;
10719 string ownerName = String.Empty; 10719 string ownerName = String.Empty;
10720 ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID); 10720 ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID);
10721 if (scenePresence == null) 10721 if (scenePresence == null)
10722 ownerName = resolveName(m_host.OwnerID); 10722 ownerName = resolveName(m_host.OwnerID);
10723 else 10723 else
10724 ownerName = scenePresence.Name; 10724 ownerName = scenePresence.Name;
10725   10725  
10726 RegionInfo regionInfo = World.RegionInfo; 10726 RegionInfo regionInfo = World.RegionInfo;
10727   10727  
10728 Dictionary<string, string> httpHeaders = new Dictionary<string, string>(); 10728 Dictionary<string, string> httpHeaders = new Dictionary<string, string>();
10729   10729  
10730 string shard = "OpenSim"; 10730 string shard = "OpenSim";
10731 IConfigSource config = m_ScriptEngine.ConfigSource; 10731 IConfigSource config = m_ScriptEngine.ConfigSource;
10732 if (config.Configs["Network"] != null) 10732 if (config.Configs["Network"] != null)
10733 { 10733 {
10734 shard = config.Configs["Network"].GetString("shard", shard); 10734 shard = config.Configs["Network"].GetString("shard", shard);
10735 } 10735 }
10736   10736  
10737 httpHeaders["X-SecondLife-Shard"] = shard; 10737 httpHeaders["X-SecondLife-Shard"] = shard;
10738 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name; 10738 httpHeaders["X-SecondLife-Object-Name"] = m_host.Name;
10739 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString(); 10739 httpHeaders["X-SecondLife-Object-Key"] = m_host.UUID.ToString();
10740 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY); 10740 httpHeaders["X-SecondLife-Region"] = string.Format("{0} ({1}, {2})", regionInfo.RegionName, regionInfo.RegionLocX, regionInfo.RegionLocY);
10741 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z); 10741 httpHeaders["X-SecondLife-Local-Position"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", position.X, position.Y, position.Z);
10742 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); 10742 httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z);
10743 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); 10743 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);
10744 httpHeaders["X-SecondLife-Owner-Name"] = ownerName; 10744 httpHeaders["X-SecondLife-Owner-Name"] = ownerName;
10745 httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString(); 10745 httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString();
10746 string userAgent = config.Configs["Network"].GetString("user_agent", null); 10746 string userAgent = config.Configs["Network"].GetString("user_agent", null);
10747 if (userAgent != null) 10747 if (userAgent != null)
10748 httpHeaders["User-Agent"] = userAgent; 10748 httpHeaders["User-Agent"] = userAgent;
10749   10749  
10750 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 10750 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10751 Regex r = new Regex(authregex); 10751 Regex r = new Regex(authregex);
10752 int[] gnums = r.GetGroupNumbers(); 10752 int[] gnums = r.GetGroupNumbers();
10753 Match m = r.Match(url); 10753 Match m = r.Match(url);
10754 if (m.Success) { 10754 if (m.Success) {
10755 for (int i = 1; i < gnums.Length; i++) { 10755 for (int i = 1; i < gnums.Length; i++) {
10756 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10756 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10757 //CaptureCollection cc = g.Captures; 10757 //CaptureCollection cc = g.Captures;
10758 } 10758 }
10759 if (m.Groups.Count == 5) { 10759 if (m.Groups.Count == 5) {
10760 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10760 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10761 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10761 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10762 } 10762 }
10763 } 10763 }
10764   10764  
10765 UUID reqID 10765 UUID reqID
10766 = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body); 10766 = httpScriptMod.StartHttpRequest(m_host.LocalId, m_item.ItemID, url, param, httpHeaders, body);
10767   10767  
10768 if (reqID != UUID.Zero) 10768 if (reqID != UUID.Zero)
10769 return reqID.ToString(); 10769 return reqID.ToString();
10770 else 10770 else
10771 return null; 10771 return null;
10772 } 10772 }
10773   10773  
10774   10774  
10775 public void llHTTPResponse(LSL_Key id, int status, string body) 10775 public void llHTTPResponse(LSL_Key id, int status, string body)
10776 { 10776 {
10777 // Partial implementation: support for parameter flags needed 10777 // Partial implementation: support for parameter flags needed
10778 // see http://wiki.secondlife.com/wiki/llHTTPResponse 10778 // see http://wiki.secondlife.com/wiki/llHTTPResponse
10779   10779  
10780 m_host.AddScriptLPS(1); 10780 m_host.AddScriptLPS(1);
10781   10781  
10782 if (m_UrlModule != null) 10782 if (m_UrlModule != null)
10783 m_UrlModule.HttpResponse(new UUID(id), status,body); 10783 m_UrlModule.HttpResponse(new UUID(id), status,body);
10784 } 10784 }
10785   10785  
10786 public void llResetLandBanList() 10786 public void llResetLandBanList()
10787 { 10787 {
10788 m_host.AddScriptLPS(1); 10788 m_host.AddScriptLPS(1);
10789 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; 10789 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10790 if (land.OwnerID == m_host.OwnerID) 10790 if (land.OwnerID == m_host.OwnerID)
10791 { 10791 {
10792 foreach (LandAccessEntry entry in land.ParcelAccessList) 10792 foreach (LandAccessEntry entry in land.ParcelAccessList)
10793 { 10793 {
10794 if (entry.Flags == AccessList.Ban) 10794 if (entry.Flags == AccessList.Ban)
10795 { 10795 {
10796 land.ParcelAccessList.Remove(entry); 10796 land.ParcelAccessList.Remove(entry);
10797 } 10797 }
10798 } 10798 }
10799 } 10799 }
10800 ScriptSleep(100); 10800 ScriptSleep(100);
10801 } 10801 }
10802   10802  
10803 public void llResetLandPassList() 10803 public void llResetLandPassList()
10804 { 10804 {
10805 m_host.AddScriptLPS(1); 10805 m_host.AddScriptLPS(1);
10806 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData; 10806 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
10807 if (land.OwnerID == m_host.OwnerID) 10807 if (land.OwnerID == m_host.OwnerID)
10808 { 10808 {
10809 foreach (LandAccessEntry entry in land.ParcelAccessList) 10809 foreach (LandAccessEntry entry in land.ParcelAccessList)
10810 { 10810 {
10811 if (entry.Flags == AccessList.Access) 10811 if (entry.Flags == AccessList.Access)
10812 { 10812 {
10813 land.ParcelAccessList.Remove(entry); 10813 land.ParcelAccessList.Remove(entry);
10814 } 10814 }
10815 } 10815 }
10816 } 10816 }
10817 ScriptSleep(100); 10817 ScriptSleep(100);
10818 } 10818 }
10819   10819  
10820 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 10820 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
10821 { 10821 {
10822 m_host.AddScriptLPS(1); 10822 m_host.AddScriptLPS(1);
10823   10823  
10824 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10824 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10825   10825  
10826 if (lo == null) 10826 if (lo == null)
10827 return 0; 10827 return 0;
10828   10828  
10829 IPrimCounts pc = lo.PrimCounts; 10829 IPrimCounts pc = lo.PrimCounts;
10830   10830  
10831 if (sim_wide != ScriptBaseClass.FALSE) 10831 if (sim_wide != ScriptBaseClass.FALSE)
10832 { 10832 {
10833 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL) 10833 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
10834 { 10834 {
10835 return pc.Simulator; 10835 return pc.Simulator;
10836 } 10836 }
10837 else 10837 else
10838 { 10838 {
10839 // counts not implemented yet 10839 // counts not implemented yet
10840 return 0; 10840 return 0;
10841 } 10841 }
10842 } 10842 }
10843 else 10843 else
10844 { 10844 {
10845 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL) 10845 if (category == ScriptBaseClass.PARCEL_COUNT_TOTAL)
10846 return pc.Total; 10846 return pc.Total;
10847 else if (category == ScriptBaseClass.PARCEL_COUNT_OWNER) 10847 else if (category == ScriptBaseClass.PARCEL_COUNT_OWNER)
10848 return pc.Owner; 10848 return pc.Owner;
10849 else if (category == ScriptBaseClass.PARCEL_COUNT_GROUP) 10849 else if (category == ScriptBaseClass.PARCEL_COUNT_GROUP)
10850 return pc.Group; 10850 return pc.Group;
10851 else if (category == ScriptBaseClass.PARCEL_COUNT_OTHER) 10851 else if (category == ScriptBaseClass.PARCEL_COUNT_OTHER)
10852 return pc.Others; 10852 return pc.Others;
10853 else if (category == ScriptBaseClass.PARCEL_COUNT_SELECTED) 10853 else if (category == ScriptBaseClass.PARCEL_COUNT_SELECTED)
10854 return pc.Selected; 10854 return pc.Selected;
10855 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 10855 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
10856 return 0; // counts not implemented yet 10856 return 0; // counts not implemented yet
10857 } 10857 }
10858   10858  
10859 return 0; 10859 return 0;
10860 } 10860 }
10861   10861  
10862 public LSL_List llGetParcelPrimOwners(LSL_Vector pos) 10862 public LSL_List llGetParcelPrimOwners(LSL_Vector pos)
10863 { 10863 {
10864 m_host.AddScriptLPS(1); 10864 m_host.AddScriptLPS(1);
10865 LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10865 LandObject land = (LandObject)World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10866 LSL_List ret = new LSL_List(); 10866 LSL_List ret = new LSL_List();
10867 if (land != null) 10867 if (land != null)
10868 { 10868 {
10869 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners()) 10869 foreach (KeyValuePair<UUID, int> detectedParams in land.GetLandObjectOwners())
10870 { 10870 {
10871 ret.Add(new LSL_String(detectedParams.Key.ToString())); 10871 ret.Add(new LSL_String(detectedParams.Key.ToString()));
10872 ret.Add(new LSL_Integer(detectedParams.Value)); 10872 ret.Add(new LSL_Integer(detectedParams.Value));
10873 } 10873 }
10874 } 10874 }
10875 ScriptSleep(2000); 10875 ScriptSleep(2000);
10876 return ret; 10876 return ret;
10877 } 10877 }
10878   10878  
10879 public LSL_Integer llGetObjectPrimCount(string object_id) 10879 public LSL_Integer llGetObjectPrimCount(string object_id)
10880 { 10880 {
10881 m_host.AddScriptLPS(1); 10881 m_host.AddScriptLPS(1);
10882 SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id)); 10882 SceneObjectPart part = World.GetSceneObjectPart(new UUID(object_id));
10883 if (part == null) 10883 if (part == null)
10884 { 10884 {
10885 return 0; 10885 return 0;
10886 } 10886 }
10887 else 10887 else
10888 { 10888 {
10889 return part.ParentGroup.PrimCount; 10889 return part.ParentGroup.PrimCount;
10890 } 10890 }
10891 } 10891 }
10892   10892  
10893 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide) 10893 public LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide)
10894 { 10894 {
10895 m_host.AddScriptLPS(1); 10895 m_host.AddScriptLPS(1);
10896   10896  
10897 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 10897 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
10898   10898  
10899 if (lo == null) 10899 if (lo == null)
10900 return 0; 10900 return 0;
10901   10901  
10902 if (sim_wide != 0) 10902 if (sim_wide != 0)
10903 return lo.GetSimulatorMaxPrimCount(); 10903 return lo.GetSimulatorMaxPrimCount();
10904 else 10904 else
10905 return lo.GetParcelMaxPrimCount(); 10905 return lo.GetParcelMaxPrimCount();
10906 } 10906 }
10907   10907  
10908 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 10908 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
10909 { 10909 {
10910 m_host.AddScriptLPS(1); 10910 m_host.AddScriptLPS(1);
10911 LandData land = World.GetLandData(pos); 10911 LandData land = World.GetLandData(pos);
10912 if (land == null) 10912 if (land == null)
10913 { 10913 {
10914 return new LSL_List(0); 10914 return new LSL_List(0);
10915 } 10915 }
10916 LSL_List ret = new LSL_List(); 10916 LSL_List ret = new LSL_List();
10917 foreach (object o in param.Data) 10917 foreach (object o in param.Data)
10918 { 10918 {
10919 switch (o.ToString()) 10919 switch (o.ToString())
10920 { 10920 {
10921 case "0": 10921 case "0":
10922 ret.Add(new LSL_String(land.Name)); 10922 ret.Add(new LSL_String(land.Name));
10923 break; 10923 break;
10924 case "1": 10924 case "1":
10925 ret.Add(new LSL_String(land.Description)); 10925 ret.Add(new LSL_String(land.Description));
10926 break; 10926 break;
10927 case "2": 10927 case "2":
10928 ret.Add(new LSL_Key(land.OwnerID.ToString())); 10928 ret.Add(new LSL_Key(land.OwnerID.ToString()));
10929 break; 10929 break;
10930 case "3": 10930 case "3":
10931 ret.Add(new LSL_Key(land.GroupID.ToString())); 10931 ret.Add(new LSL_Key(land.GroupID.ToString()));
10932 break; 10932 break;
10933 case "4": 10933 case "4":
10934 ret.Add(new LSL_Integer(land.Area)); 10934 ret.Add(new LSL_Integer(land.Area));
10935 break; 10935 break;
10936 case "5": 10936 case "5":
10937 ret.Add(new LSL_Key(land.GlobalID.ToString())); 10937 ret.Add(new LSL_Key(land.GlobalID.ToString()));
10938 break; 10938 break;
10939 default: 10939 default:
10940 ret.Add(new LSL_Integer(0)); 10940 ret.Add(new LSL_Integer(0));
10941 break; 10941 break;
10942 } 10942 }
10943 } 10943 }
10944 return ret; 10944 return ret;
10945 } 10945 }
10946   10946  
10947 public LSL_String llStringTrim(string src, int type) 10947 public LSL_String llStringTrim(string src, int type)
10948 { 10948 {
10949 m_host.AddScriptLPS(1); 10949 m_host.AddScriptLPS(1);
10950 if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); } 10950 if (type == (int)ScriptBaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); }
10951 if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); } 10951 if (type == (int)ScriptBaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); }
10952 if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); } 10952 if (type == (int)ScriptBaseClass.STRING_TRIM) { return src.Trim(); }
10953 return src; 10953 return src;
10954 } 10954 }
10955   10955  
10956 public LSL_List llGetObjectDetails(string id, LSL_List args) 10956 public LSL_List llGetObjectDetails(string id, LSL_List args)
10957 { 10957 {
10958 m_host.AddScriptLPS(1); 10958 m_host.AddScriptLPS(1);
10959   10959  
10960 LSL_List ret = new LSL_List(); 10960 LSL_List ret = new LSL_List();
10961 UUID key = new UUID(); 10961 UUID key = new UUID();
10962 if (UUID.TryParse(id, out key)) 10962 if (UUID.TryParse(id, out key))
10963 { 10963 {
10964 ScenePresence av = World.GetScenePresence(key); 10964 ScenePresence av = World.GetScenePresence(key);
10965   10965  
10966 if (av != null) 10966 if (av != null)
10967 { 10967 {
10968 foreach (object o in args.Data) 10968 foreach (object o in args.Data)
10969 { 10969 {
10970 switch (int.Parse(o.ToString())) 10970 switch (int.Parse(o.ToString()))
10971 { 10971 {
10972 case ScriptBaseClass.OBJECT_NAME: 10972 case ScriptBaseClass.OBJECT_NAME:
10973 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname)); 10973 ret.Add(new LSL_String(av.Firstname + " " + av.Lastname));
10974 break; 10974 break;
10975 case ScriptBaseClass.OBJECT_DESC: 10975 case ScriptBaseClass.OBJECT_DESC:
10976 ret.Add(new LSL_String("")); 10976 ret.Add(new LSL_String(""));
10977 break; 10977 break;
10978 case ScriptBaseClass.OBJECT_POS: 10978 case ScriptBaseClass.OBJECT_POS:
10979 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 10979 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z));
10980 break; 10980 break;
10981 case ScriptBaseClass.OBJECT_ROT: 10981 case ScriptBaseClass.OBJECT_ROT:
10982 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 10982 ret.Add(new LSL_Rotation(av.GetWorldRotation()));
10983 break; 10983 break;
10984 case ScriptBaseClass.OBJECT_VELOCITY: 10984 case ScriptBaseClass.OBJECT_VELOCITY:
10985 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 10985 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z));
10986 break; 10986 break;
10987 case ScriptBaseClass.OBJECT_OWNER: 10987 case ScriptBaseClass.OBJECT_OWNER:
10988 ret.Add(new LSL_String(id)); 10988 ret.Add(new LSL_String(id));
10989 break; 10989 break;
10990 case ScriptBaseClass.OBJECT_GROUP: 10990 case ScriptBaseClass.OBJECT_GROUP:
10991 ret.Add(new LSL_String(UUID.Zero.ToString())); 10991 ret.Add(new LSL_String(UUID.Zero.ToString()));
10992 break; 10992 break;
10993 case ScriptBaseClass.OBJECT_CREATOR: 10993 case ScriptBaseClass.OBJECT_CREATOR:
10994 ret.Add(new LSL_String(UUID.Zero.ToString())); 10994 ret.Add(new LSL_String(UUID.Zero.ToString()));
10995 break; 10995 break;
10996 // For the following 8 see the Object version below 10996 // For the following 8 see the Object version below
10997 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 10997 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
10998 ret.Add(new LSL_Integer(av.RunningScriptCount())); 10998 ret.Add(new LSL_Integer(av.RunningScriptCount()));
10999 break; 10999 break;
11000 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11000 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11001 ret.Add(new LSL_Integer(av.ScriptCount())); 11001 ret.Add(new LSL_Integer(av.ScriptCount()));
11002 break; 11002 break;
11003 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11003 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11004 ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384)); 11004 ret.Add(new LSL_Integer(av.RunningScriptCount() * 16384));
11005 break; 11005 break;
11006 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11006 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11007 ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f)); 11007 ret.Add(new LSL_Float(av.ScriptExecutionTime() / 1000.0f));
11008 break; 11008 break;
11009 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11009 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11010 ret.Add(new LSL_Integer(1)); 11010 ret.Add(new LSL_Integer(1));
11011 break; 11011 break;
11012 case ScriptBaseClass.OBJECT_SERVER_COST: 11012 case ScriptBaseClass.OBJECT_SERVER_COST:
11013 ret.Add(new LSL_Float(0)); 11013 ret.Add(new LSL_Float(0));
11014 break; 11014 break;
11015 case ScriptBaseClass.OBJECT_STREAMING_COST: 11015 case ScriptBaseClass.OBJECT_STREAMING_COST:
11016 ret.Add(new LSL_Float(0)); 11016 ret.Add(new LSL_Float(0));
11017 break; 11017 break;
11018 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11018 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11019 ret.Add(new LSL_Float(0)); 11019 ret.Add(new LSL_Float(0));
11020 break; 11020 break;
11021 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11021 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11022 ret.Add(new LSL_Float(0)); 11022 ret.Add(new LSL_Float(0));
11023 break; 11023 break;
11024 case ScriptBaseClass.OBJECT_ROOT: 11024 case ScriptBaseClass.OBJECT_ROOT:
11025 SceneObjectPart p = av.ParentPart; 11025 SceneObjectPart p = av.ParentPart;
11026 if (p != null) 11026 if (p != null)
11027 { 11027 {
11028 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString())); 11028 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString()));
11029 } 11029 }
11030 else 11030 else
11031 { 11031 {
11032 ret.Add(new LSL_String(id)); 11032 ret.Add(new LSL_String(id));
11033 } 11033 }
11034 break; 11034 break;
11035 case ScriptBaseClass.OBJECT_ATTACHED_POINT: 11035 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11036 ret.Add(new LSL_Integer(0)); 11036 ret.Add(new LSL_Integer(0));
11037 break; 11037 break;
11038 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding 11038 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding
11039 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR)); 11039 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR));
11040 break; 11040 break;
11041 case ScriptBaseClass.OBJECT_PHYSICS: 11041 case ScriptBaseClass.OBJECT_PHYSICS:
11042 ret.Add(new LSL_Integer(0)); 11042 ret.Add(new LSL_Integer(0));
11043 break; 11043 break;
11044 case ScriptBaseClass.OBJECT_PHANTOM: 11044 case ScriptBaseClass.OBJECT_PHANTOM:
11045 ret.Add(new LSL_Integer(0)); 11045 ret.Add(new LSL_Integer(0));
11046 break; 11046 break;
11047 case ScriptBaseClass.OBJECT_TEMP_ON_REZ: 11047 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11048 ret.Add(new LSL_Integer(0)); 11048 ret.Add(new LSL_Integer(0));
11049 break; 11049 break;
11050 default: 11050 default:
11051 // Invalid or unhandled constant. 11051 // Invalid or unhandled constant.
11052 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11052 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
11053 break; 11053 break;
11054 } 11054 }
11055 } 11055 }
11056   11056  
11057 return ret; 11057 return ret;
11058 } 11058 }
11059   11059  
11060 SceneObjectPart obj = World.GetSceneObjectPart(key); 11060 SceneObjectPart obj = World.GetSceneObjectPart(key);
11061 if (obj != null) 11061 if (obj != null)
11062 { 11062 {
11063 foreach (object o in args.Data) 11063 foreach (object o in args.Data)
11064 { 11064 {
11065 switch (int.Parse(o.ToString())) 11065 switch (int.Parse(o.ToString()))
11066 { 11066 {
11067 case ScriptBaseClass.OBJECT_NAME: 11067 case ScriptBaseClass.OBJECT_NAME:
11068 ret.Add(new LSL_String(obj.Name)); 11068 ret.Add(new LSL_String(obj.Name));
11069 break; 11069 break;
11070 case ScriptBaseClass.OBJECT_DESC: 11070 case ScriptBaseClass.OBJECT_DESC:
11071 ret.Add(new LSL_String(obj.Description)); 11071 ret.Add(new LSL_String(obj.Description));
11072 break; 11072 break;
11073 case ScriptBaseClass.OBJECT_POS: 11073 case ScriptBaseClass.OBJECT_POS:
11074 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11074 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z));
11075 break; 11075 break;
11076 case ScriptBaseClass.OBJECT_ROT: 11076 case ScriptBaseClass.OBJECT_ROT:
11077 { 11077 {
11078 Quaternion rot = Quaternion.Identity; 11078 Quaternion rot = Quaternion.Identity;
11079   11079  
11080 if (obj.ParentGroup.RootPart == obj) 11080 if (obj.ParentGroup.RootPart == obj)
11081 rot = obj.ParentGroup.GroupRotation; 11081 rot = obj.ParentGroup.GroupRotation;
11082 else 11082 else
11083 rot = obj.GetWorldRotation(); 11083 rot = obj.GetWorldRotation();
11084   11084  
11085 LSL_Rotation objrot = new LSL_Rotation(rot); 11085 LSL_Rotation objrot = new LSL_Rotation(rot);
11086 ret.Add(objrot); 11086 ret.Add(objrot);
11087 } 11087 }
11088 break; 11088 break;
11089 case ScriptBaseClass.OBJECT_VELOCITY: 11089 case ScriptBaseClass.OBJECT_VELOCITY:
11090 ret.Add(new LSL_Vector(obj.Velocity)); 11090 ret.Add(new LSL_Vector(obj.Velocity));
11091 break; 11091 break;
11092 case ScriptBaseClass.OBJECT_OWNER: 11092 case ScriptBaseClass.OBJECT_OWNER:
11093 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11093 ret.Add(new LSL_String(obj.OwnerID.ToString()));
11094 break; 11094 break;
11095 case ScriptBaseClass.OBJECT_GROUP: 11095 case ScriptBaseClass.OBJECT_GROUP:
11096 ret.Add(new LSL_String(obj.GroupID.ToString())); 11096 ret.Add(new LSL_String(obj.GroupID.ToString()));
11097 break; 11097 break;
11098 case ScriptBaseClass.OBJECT_CREATOR: 11098 case ScriptBaseClass.OBJECT_CREATOR:
11099 ret.Add(new LSL_String(obj.CreatorID.ToString())); 11099 ret.Add(new LSL_String(obj.CreatorID.ToString()));
11100 break; 11100 break;
11101 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: 11101 case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT:
11102 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount())); 11102 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount()));
11103 break; 11103 break;
11104 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: 11104 case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT:
11105 ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount())); 11105 ret.Add(new LSL_Integer(obj.ParentGroup.ScriptCount()));
11106 break; 11106 break;
11107 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: 11107 case ScriptBaseClass.OBJECT_SCRIPT_MEMORY:
11108 // The value returned in SL for mono scripts is 65536 * number of active scripts 11108 // The value returned in SL for mono scripts is 65536 * number of active scripts
11109 // and 16384 * number of active scripts for LSO. since llGetFreememory 11109 // and 16384 * number of active scripts for LSO. since llGetFreememory
11110 // is coded to give the LSO value use it here 11110 // is coded to give the LSO value use it here
11111 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384)); 11111 ret.Add(new LSL_Integer(obj.ParentGroup.RunningScriptCount() * 16384));
11112 break; 11112 break;
11113 case ScriptBaseClass.OBJECT_SCRIPT_TIME: 11113 case ScriptBaseClass.OBJECT_SCRIPT_TIME:
11114 // Average cpu time in seconds per simulator frame expended on all scripts in the object 11114 // Average cpu time in seconds per simulator frame expended on all scripts in the object
11115 ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f)); 11115 ret.Add(new LSL_Float(obj.ParentGroup.ScriptExecutionTime() / 1000.0f));
11116 break; 11116 break;
11117 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: 11117 case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE:
11118 // according to the SL wiki A prim or linkset will have prim 11118 // according to the SL wiki A prim or linkset will have prim
11119 // equivalent of the number of prims in a linkset if it does not 11119 // equivalent of the number of prims in a linkset if it does not
11120 // contain a mesh anywhere in the link set or is not a normal prim 11120 // contain a mesh anywhere in the link set or is not a normal prim
11121 // The value returned in SL for normal prims is prim count 11121 // The value returned in SL for normal prims is prim count
11122 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11122 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11123 break; 11123 break;
11124 // The following 3 costs I have intentionaly coded to return zero. They are part of 11124 // The following 3 costs I have intentionaly coded to return zero. They are part of
11125 // "Land Impact" calculations. These calculations are probably not applicable 11125 // "Land Impact" calculations. These calculations are probably not applicable
11126 // to OpenSim and are not yet complete in SL 11126 // to OpenSim and are not yet complete in SL
11127 case ScriptBaseClass.OBJECT_SERVER_COST: 11127 case ScriptBaseClass.OBJECT_SERVER_COST:
11128 // The linden calculation is here 11128 // The linden calculation is here
11129 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11129 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
11130 // The value returned in SL for normal prims looks like the prim count 11130 // The value returned in SL for normal prims looks like the prim count
11131 ret.Add(new LSL_Float(0)); 11131 ret.Add(new LSL_Float(0));
11132 break; 11132 break;
11133 case ScriptBaseClass.OBJECT_STREAMING_COST: 11133 case ScriptBaseClass.OBJECT_STREAMING_COST:
11134 // The linden calculation is here 11134 // The linden calculation is here
11135 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11135 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost
11136 // The value returned in SL for normal prims looks like the prim count * 0.06 11136 // The value returned in SL for normal prims looks like the prim count * 0.06
11137 ret.Add(new LSL_Float(0)); 11137 ret.Add(new LSL_Float(0));
11138 break; 11138 break;
11139 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11139 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11140 // The linden calculation is here 11140 // The linden calculation is here
11141 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11141 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics
11142 // The value returned in SL for normal prims looks like the prim count 11142 // The value returned in SL for normal prims looks like the prim count
11143 ret.Add(new LSL_Float(0)); 11143 ret.Add(new LSL_Float(0));
11144 break; 11144 break;
11145 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11145 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11146 ret.Add(new LSL_Float(0)); 11146 ret.Add(new LSL_Float(0));
11147 break; 11147 break;
11148 case ScriptBaseClass.OBJECT_ROOT: 11148 case ScriptBaseClass.OBJECT_ROOT:
11149 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString())); 11149 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString()));
11150 break; 11150 break;
11151 case ScriptBaseClass.OBJECT_ATTACHED_POINT: 11151 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11152 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint)); 11152 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint));
11153 break; 11153 break;
11154 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: 11154 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE:
11155 byte pcode = obj.Shape.PCode; 11155 byte pcode = obj.Shape.PCode;
11156 if (obj.ParentGroup.AttachmentPoint != 0 11156 if (obj.ParentGroup.AttachmentPoint != 0
11157 || pcode == (byte)PCode.Grass 11157 || pcode == (byte)PCode.Grass
11158 || pcode == (byte)PCode.Tree 11158 || pcode == (byte)PCode.Tree
11159 || pcode == (byte)PCode.NewTree) 11159 || pcode == (byte)PCode.NewTree)
11160 { 11160 {
11161 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER)); 11161 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER));
11162 } 11162 }
11163 else 11163 else
11164 { 11164 {
11165 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET)); 11165 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET));
11166 } 11166 }
11167 break; 11167 break;
11168 case ScriptBaseClass.OBJECT_PHYSICS: 11168 case ScriptBaseClass.OBJECT_PHYSICS:
11169 if (obj.ParentGroup.AttachmentPoint != 0) 11169 if (obj.ParentGroup.AttachmentPoint != 0)
11170 { 11170 {
11171 ret.Add(new LSL_Integer(0)); // Always false if attached 11171 ret.Add(new LSL_Integer(0)); // Always false if attached
11172 } 11172 }
11173 else 11173 else
11174 { 11174 {
11175 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0)); 11175 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0));
11176 } 11176 }
11177 break; 11177 break;
11178 case ScriptBaseClass.OBJECT_PHANTOM: 11178 case ScriptBaseClass.OBJECT_PHANTOM:
11179 if (obj.ParentGroup.AttachmentPoint != 0) 11179 if (obj.ParentGroup.AttachmentPoint != 0)
11180 { 11180 {
11181 ret.Add(new LSL_Integer(0)); // Always false if attached 11181 ret.Add(new LSL_Integer(0)); // Always false if attached
11182 } 11182 }
11183 else 11183 else
11184 { 11184 {
11185 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0)); 11185 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0));
11186 } 11186 }
11187 break; 11187 break;
11188 case ScriptBaseClass.OBJECT_TEMP_ON_REZ: 11188 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11189 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); 11189 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0));
11190 break; 11190 break;
11191 default: 11191 default:
11192 // Invalid or unhandled constant. 11192 // Invalid or unhandled constant.
11193 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11193 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
11194 break; 11194 break;
11195 } 11195 }
11196 } 11196 }
11197   11197  
11198 return ret; 11198 return ret;
11199 } 11199 }
11200 } 11200 }
11201   11201  
11202 return new LSL_List(); 11202 return new LSL_List();
11203 } 11203 }
11204   11204  
11205 internal UUID GetScriptByName(string name) 11205 internal UUID GetScriptByName(string name)
11206 { 11206 {
11207 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11207 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11208   11208  
11209 if (item == null || item.Type != 10) 11209 if (item == null || item.Type != 10)
11210 return UUID.Zero; 11210 return UUID.Zero;
11211   11211  
11212 return item.ItemID; 11212 return item.ItemID;
11213 } 11213 }
11214   11214  
11215 internal void ShoutError(string msg) 11215 internal void ShoutError(string msg)
11216 { 11216 {
11217 llShout(ScriptBaseClass.DEBUG_CHANNEL, msg); 11217 llShout(ScriptBaseClass.DEBUG_CHANNEL, msg);
11218 } 11218 }
11219   11219  
11220 internal void NotImplemented(string command) 11220 internal void NotImplemented(string command)
11221 { 11221 {
11222 if (throwErrorOnNotImplemented) 11222 if (throwErrorOnNotImplemented)
11223 throw new NotImplementedException("Command not implemented: " + command); 11223 throw new NotImplementedException("Command not implemented: " + command);
11224 } 11224 }
11225   11225  
11226 internal void Deprecated(string command) 11226 internal void Deprecated(string command)
11227 { 11227 {
11228 throw new ScriptException("Command deprecated: " + command); 11228 throw new ScriptException("Command deprecated: " + command);
11229 } 11229 }
11230   11230  
11231 internal void LSLError(string msg) 11231 internal void LSLError(string msg)
11232 { 11232 {
11233 throw new ScriptException("LSL Runtime Error: " + msg); 11233 throw new ScriptException("LSL Runtime Error: " + msg);
11234 } 11234 }
11235   11235  
11236 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset); 11236 public delegate void AssetRequestCallback(UUID assetID, AssetBase asset);
11237 protected void WithNotecard(UUID assetID, AssetRequestCallback cb) 11237 protected void WithNotecard(UUID assetID, AssetRequestCallback cb)
11238 { 11238 {
11239 World.AssetService.Get(assetID.ToString(), this, 11239 World.AssetService.Get(assetID.ToString(), this,
11240 delegate(string i, object sender, AssetBase a) 11240 delegate(string i, object sender, AssetBase a)
11241 { 11241 {
11242 UUID uuid = UUID.Zero; 11242 UUID uuid = UUID.Zero;
11243 UUID.TryParse(i, out uuid); 11243 UUID.TryParse(i, out uuid);
11244 cb(uuid, a); 11244 cb(uuid, a);
11245 }); 11245 });
11246 } 11246 }
11247   11247  
11248 public LSL_String llGetNumberOfNotecardLines(string name) 11248 public LSL_String llGetNumberOfNotecardLines(string name)
11249 { 11249 {
11250 m_host.AddScriptLPS(1); 11250 m_host.AddScriptLPS(1);
11251   11251  
11252 UUID assetID = UUID.Zero; 11252 UUID assetID = UUID.Zero;
11253   11253  
11254 if (!UUID.TryParse(name, out assetID)) 11254 if (!UUID.TryParse(name, out assetID))
11255 { 11255 {
11256 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11256 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11257   11257  
11258 if (item != null && item.Type == 7) 11258 if (item != null && item.Type == 7)
11259 assetID = item.AssetID; 11259 assetID = item.AssetID;
11260 } 11260 }
11261   11261  
11262 if (assetID == UUID.Zero) 11262 if (assetID == UUID.Zero)
11263 { 11263 {
11264 // => complain loudly, as specified by the LSL docs 11264 // => complain loudly, as specified by the LSL docs
11265 ShoutError("Notecard '" + name + "' could not be found."); 11265 ShoutError("Notecard '" + name + "' could not be found.");
11266   11266  
11267 return UUID.Zero.ToString(); 11267 return UUID.Zero.ToString();
11268 } 11268 }
11269   11269  
11270 string reqIdentifier = UUID.Random().ToString(); 11270 string reqIdentifier = UUID.Random().ToString();
11271   11271  
11272 // was: UUID tid = tid = AsyncCommands. 11272 // was: UUID tid = tid = AsyncCommands.
11273 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); 11273 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11274   11274  
11275 if (NotecardCache.IsCached(assetID)) 11275 if (NotecardCache.IsCached(assetID))
11276 { 11276 {
11277 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString()); 11277 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
11278   11278  
11279 ScriptSleep(100); 11279 ScriptSleep(100);
11280 return tid.ToString(); 11280 return tid.ToString();
11281 } 11281 }
11282   11282  
11283 WithNotecard(assetID, delegate (UUID id, AssetBase a) 11283 WithNotecard(assetID, delegate (UUID id, AssetBase a)
11284 { 11284 {
11285 if (a == null || a.Type != 7) 11285 if (a == null || a.Type != 7)
11286 { 11286 {
11287 ShoutError("Notecard '" + name + "' could not be found."); 11287 ShoutError("Notecard '" + name + "' could not be found.");
11288 return; 11288 return;
11289 } 11289 }
11290   11290  
11291 string data = Encoding.UTF8.GetString(a.Data); 11291 string data = Encoding.UTF8.GetString(a.Data);
11292 //m_log.Debug(data); 11292 //m_log.Debug(data);
11293 NotecardCache.Cache(id, data); 11293 NotecardCache.Cache(id, data);
11294 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString()); 11294 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11295 }); 11295 });
11296   11296  
11297 ScriptSleep(100); 11297 ScriptSleep(100);
11298 return tid.ToString(); 11298 return tid.ToString();
11299 } 11299 }
11300   11300  
11301 public LSL_String llGetNotecardLine(string name, int line) 11301 public LSL_String llGetNotecardLine(string name, int line)
11302 { 11302 {
11303 m_host.AddScriptLPS(1); 11303 m_host.AddScriptLPS(1);
11304   11304  
11305 UUID assetID = UUID.Zero; 11305 UUID assetID = UUID.Zero;
11306   11306  
11307 if (!UUID.TryParse(name, out assetID)) 11307 if (!UUID.TryParse(name, out assetID))
11308 { 11308 {
11309 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); 11309 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
11310   11310  
11311 if (item != null && item.Type == 7) 11311 if (item != null && item.Type == 7)
11312 assetID = item.AssetID; 11312 assetID = item.AssetID;
11313 } 11313 }
11314   11314  
11315 if (assetID == UUID.Zero) 11315 if (assetID == UUID.Zero)
11316 { 11316 {
11317 // => complain loudly, as specified by the LSL docs 11317 // => complain loudly, as specified by the LSL docs
11318 ShoutError("Notecard '" + name + "' could not be found."); 11318 ShoutError("Notecard '" + name + "' could not be found.");
11319   11319  
11320 return UUID.Zero.ToString(); 11320 return UUID.Zero.ToString();
11321 } 11321 }
11322   11322  
11323 string reqIdentifier = UUID.Random().ToString(); 11323 string reqIdentifier = UUID.Random().ToString();
11324   11324  
11325 // was: UUID tid = tid = AsyncCommands. 11325 // was: UUID tid = tid = AsyncCommands.
11326 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier); 11326 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11327   11327  
11328 if (NotecardCache.IsCached(assetID)) 11328 if (NotecardCache.IsCached(assetID))
11329 { 11329 {
11330 AsyncCommands.DataserverPlugin.DataserverReply( 11330 AsyncCommands.DataserverPlugin.DataserverReply(
11331 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11331 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11332   11332  
11333 ScriptSleep(100); 11333 ScriptSleep(100);
11334 return tid.ToString(); 11334 return tid.ToString();
11335 } 11335 }
11336   11336  
11337 WithNotecard(assetID, delegate (UUID id, AssetBase a) 11337 WithNotecard(assetID, delegate (UUID id, AssetBase a)
11338 { 11338 {
11339 if (a == null || a.Type != 7) 11339 if (a == null || a.Type != 7)
11340 { 11340 {
11341 ShoutError("Notecard '" + name + "' could not be found."); 11341 ShoutError("Notecard '" + name + "' could not be found.");
11342 return; 11342 return;
11343 } 11343 }
11344   11344  
11345 string data = Encoding.UTF8.GetString(a.Data); 11345 string data = Encoding.UTF8.GetString(a.Data);
11346 //m_log.Debug(data); 11346 //m_log.Debug(data);
11347 NotecardCache.Cache(id, data); 11347 NotecardCache.Cache(id, data);
11348 AsyncCommands.DataserverPlugin.DataserverReply( 11348 AsyncCommands.DataserverPlugin.DataserverReply(
11349 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11349 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11350 }); 11350 });
11351   11351  
11352 ScriptSleep(100); 11352 ScriptSleep(100);
11353 return tid.ToString(); 11353 return tid.ToString();
11354 } 11354 }
11355   11355  
11356 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc) 11356 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
11357 { 11357 {
11358 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11358 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11359 if (obj == null) 11359 if (obj == null)
11360 return; 11360 return;
11361   11361  
11362 if (obj.OwnerID != m_host.OwnerID) 11362 if (obj.OwnerID != m_host.OwnerID)
11363 return; 11363 return;
11364   11364  
11365 uint rulesParsed = 0; 11365 uint rulesParsed = 0;
11366 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed); 11366 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
11367   11367  
11368 while ((object)remaining != null && remaining.Length > 2) 11368 while ((object)remaining != null && remaining.Length > 2)
11369 { 11369 {
11370 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11370 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
11371 LSL_List newrules = remaining.GetSublist(1, -1); 11371 LSL_List newrules = remaining.GetSublist(1, -1);
11372 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11372 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
11373 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed); 11373 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
11374 } 11374 }
11375 } 11375 }
11376 } 11376 }
11377   11377  
11378 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11378 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
11379 { 11379 {
11380 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11380 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
11381   11381  
11382 LSL_List result = new LSL_List(); 11382 LSL_List result = new LSL_List();
11383   11383  
11384 if (obj != null && obj.OwnerID == m_host.OwnerID) 11384 if (obj != null && obj.OwnerID == m_host.OwnerID)
11385 { 11385 {
11386 LSL_List remaining = GetPrimParams(obj, rules, ref result); 11386 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11387   11387  
11388 while (remaining != null && remaining.Length > 2) 11388 while (remaining != null && remaining.Length > 2)
11389 { 11389 {
11390 int linknumber = remaining.GetLSLIntegerItem(0); 11390 int linknumber = remaining.GetLSLIntegerItem(0);
11391 rules = remaining.GetSublist(1, -1); 11391 rules = remaining.GetSublist(1, -1);
11392 List<SceneObjectPart> parts = GetLinkParts(linknumber); 11392 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11393   11393  
11394 foreach (SceneObjectPart part in parts) 11394 foreach (SceneObjectPart part in parts)
11395 remaining = GetPrimParams(part, rules, ref result); 11395 remaining = GetPrimParams(part, rules, ref result);
11396 } 11396 }
11397 } 11397 }
11398   11398  
11399 return result; 11399 return result;
11400 } 11400 }
11401   11401  
11402 public void print(string str) 11402 public void print(string str)
11403 { 11403 {
11404 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11404 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print
11405 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11405 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
11406 if (ossl != null) 11406 if (ossl != null)
11407 { 11407 {
11408 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11408 ossl.CheckThreatLevel(ThreatLevel.High, "print");
11409 m_log.Info("LSL print():" + str); 11409 m_log.Info("LSL print():" + str);
11410 } 11410 }
11411 } 11411 }
11412   11412  
11413 private string Name2Username(string name) 11413 private string Name2Username(string name)
11414 { 11414 {
11415 string[] parts = name.Split(new char[] {' '}); 11415 string[] parts = name.Split(new char[] {' '});
11416 if (parts.Length < 2) 11416 if (parts.Length < 2)
11417 return name.ToLower(); 11417 return name.ToLower();
11418 if (parts[1] == "Resident") 11418 if (parts[1] == "Resident")
11419 return parts[0].ToLower(); 11419 return parts[0].ToLower();
11420   11420  
11421 return name.Replace(" ", ".").ToLower(); 11421 return name.Replace(" ", ".").ToLower();
11422 } 11422 }
11423   11423  
11424 public LSL_String llGetUsername(string id) 11424 public LSL_String llGetUsername(string id)
11425 { 11425 {
11426 return Name2Username(llKey2Name(id)); 11426 return Name2Username(llKey2Name(id));
11427 } 11427 }
11428   11428  
11429 public LSL_String llRequestUsername(string id) 11429 public LSL_String llRequestUsername(string id)
11430 { 11430 {
11431 UUID rq = UUID.Random(); 11431 UUID rq = UUID.Random();
11432   11432  
11433 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 11433 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11434   11434  
11435 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id))); 11435 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), Name2Username(llKey2Name(id)));
11436   11436  
11437 return rq.ToString(); 11437 return rq.ToString();
11438 } 11438 }
11439   11439  
11440 public LSL_String llGetDisplayName(string id) 11440 public LSL_String llGetDisplayName(string id)
11441 { 11441 {
11442 return llKey2Name(id); 11442 return llKey2Name(id);
11443 } 11443 }
11444   11444  
11445 public LSL_String llRequestDisplayName(string id) 11445 public LSL_String llRequestDisplayName(string id)
11446 { 11446 {
11447 UUID rq = UUID.Random(); 11447 UUID rq = UUID.Random();
11448   11448  
11449 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString()); 11449 AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, rq.ToString());
11450   11450  
11451 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id)); 11451 AsyncCommands.DataserverPlugin.DataserverReply(rq.ToString(), llKey2Name(id));
11452   11452  
11453 return rq.ToString(); 11453 return rq.ToString();
11454 } 11454 }
11455   11455  
11456 private struct Tri 11456 private struct Tri
11457 { 11457 {
11458 public Vector3 p1; 11458 public Vector3 p1;
11459 public Vector3 p2; 11459 public Vector3 p2;
11460 public Vector3 p3; 11460 public Vector3 p3;
11461 } 11461 }
11462   11462  
11463 private bool InBoundingBox(ScenePresence avatar, Vector3 point) 11463 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11464 { 11464 {
11465 float height = avatar.Appearance.AvatarHeight; 11465 float height = avatar.Appearance.AvatarHeight;
11466 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2); 11466 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11467 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2); 11467 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11468   11468  
11469 if (point.X > b1.X && point.X < b2.X && 11469 if (point.X > b1.X && point.X < b2.X &&
11470 point.Y > b1.Y && point.Y < b2.Y && 11470 point.Y > b1.Y && point.Y < b2.Y &&
11471 point.Z > b1.Z && point.Z < b2.Z) 11471 point.Z > b1.Z && point.Z < b2.Z)
11472 return true; 11472 return true;
11473 return false; 11473 return false;
11474 } 11474 }
11475   11475  
11476 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd) 11476 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11477 { 11477 {
11478 List<ContactResult> contacts = new List<ContactResult>(); 11478 List<ContactResult> contacts = new List<ContactResult>();
11479   11479  
11480 Vector3 ab = rayEnd - rayStart; 11480 Vector3 ab = rayEnd - rayStart;
11481   11481  
11482 World.ForEachScenePresence(delegate(ScenePresence sp) 11482 World.ForEachScenePresence(delegate(ScenePresence sp)
11483 { 11483 {
11484 Vector3 ac = sp.AbsolutePosition - rayStart; 11484 Vector3 ac = sp.AbsolutePosition - rayStart;
11485 // Vector3 bc = sp.AbsolutePosition - rayEnd; 11485 // Vector3 bc = sp.AbsolutePosition - rayEnd;
11486   11486  
11487 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11487 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11488   11488  
11489 if (d > 1.5) 11489 if (d > 1.5)
11490 return; 11490 return;
11491   11491  
11492 double d2 = Vector3.Dot(Vector3.Negate(ab), ac); 11492 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11493   11493  
11494 if (d2 > 0) 11494 if (d2 > 0)
11495 return; 11495 return;
11496   11496  
11497 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d); 11497 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11498 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab)); 11498 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11499   11499  
11500 if (!InBoundingBox(sp, p)) 11500 if (!InBoundingBox(sp, p))
11501 return; 11501 return;
11502   11502  
11503 ContactResult result = new ContactResult (); 11503 ContactResult result = new ContactResult ();
11504 result.ConsumerID = sp.LocalId; 11504 result.ConsumerID = sp.LocalId;
11505 result.Depth = Vector3.Distance(rayStart, p); 11505 result.Depth = Vector3.Distance(rayStart, p);
11506 result.Normal = Vector3.Zero; 11506 result.Normal = Vector3.Zero;
11507 result.Pos = p; 11507 result.Pos = p;
11508   11508  
11509 contacts.Add(result); 11509 contacts.Add(result);
11510 }); 11510 });
11511   11511  
11512 return contacts.ToArray(); 11512 return contacts.ToArray();
11513 } 11513 }
11514   11514  
11515 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom) 11515 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11516 { 11516 {
11517 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); 11517 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11518 List<ContactResult> contacts = new List<ContactResult>(); 11518 List<ContactResult> contacts = new List<ContactResult>();
11519   11519  
11520 Vector3 ab = rayEnd - rayStart; 11520 Vector3 ab = rayEnd - rayStart;
11521   11521  
11522 World.ForEachSOG(delegate(SceneObjectGroup group) 11522 World.ForEachSOG(delegate(SceneObjectGroup group)
11523 { 11523 {
11524 if (m_host.ParentGroup == group) 11524 if (m_host.ParentGroup == group)
11525 return; 11525 return;
11526   11526  
11527 if (group.IsAttachment) 11527 if (group.IsAttachment)
11528 return; 11528 return;
11529   11529  
11530 if (group.RootPart.PhysActor == null) 11530 if (group.RootPart.PhysActor == null)
11531 { 11531 {
11532 if (!includePhantom) 11532 if (!includePhantom)
11533 return; 11533 return;
11534 } 11534 }
11535 else 11535 else
11536 { 11536 {
11537 if (group.RootPart.PhysActor.IsPhysical) 11537 if (group.RootPart.PhysActor.IsPhysical)
11538 { 11538 {
11539 if (!includePhysical) 11539 if (!includePhysical)
11540 return; 11540 return;
11541 } 11541 }
11542 else 11542 else
11543 { 11543 {
11544 if (!includeNonPhysical) 11544 if (!includeNonPhysical)
11545 return; 11545 return;
11546 } 11546 }
11547 } 11547 }
11548   11548  
11549 // Find the radius ouside of which we don't even need to hit test 11549 // Find the radius ouside of which we don't even need to hit test
11550 float minX; 11550 float minX;
11551 float maxX; 11551 float maxX;
11552 float minY; 11552 float minY;
11553 float maxY; 11553 float maxY;
11554 float minZ; 11554 float minZ;
11555 float maxZ; 11555 float maxZ;
11556   11556  
11557 float radius = 0.0f; 11557 float radius = 0.0f;
11558   11558  
11559 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); 11559 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11560   11560  
11561 if (Math.Abs(minX) > radius) 11561 if (Math.Abs(minX) > radius)
11562 radius = Math.Abs(minX); 11562 radius = Math.Abs(minX);
11563 if (Math.Abs(minY) > radius) 11563 if (Math.Abs(minY) > radius)
11564 radius = Math.Abs(minY); 11564 radius = Math.Abs(minY);
11565 if (Math.Abs(minZ) > radius) 11565 if (Math.Abs(minZ) > radius)
11566 radius = Math.Abs(minZ); 11566 radius = Math.Abs(minZ);
11567 if (Math.Abs(maxX) > radius) 11567 if (Math.Abs(maxX) > radius)
11568 radius = Math.Abs(maxX); 11568 radius = Math.Abs(maxX);
11569 if (Math.Abs(maxY) > radius) 11569 if (Math.Abs(maxY) > radius)
11570 radius = Math.Abs(maxY); 11570 radius = Math.Abs(maxY);
11571 if (Math.Abs(maxZ) > radius) 11571 if (Math.Abs(maxZ) > radius)
11572 radius = Math.Abs(maxZ); 11572 radius = Math.Abs(maxZ);
11573 radius = radius*1.413f; 11573 radius = radius*1.413f;
11574 Vector3 ac = group.AbsolutePosition - rayStart; 11574 Vector3 ac = group.AbsolutePosition - rayStart;
11575 // Vector3 bc = group.AbsolutePosition - rayEnd; 11575 // Vector3 bc = group.AbsolutePosition - rayEnd;
11576   11576  
11577 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 11577 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11578   11578  
11579 // Too far off ray, don't bother 11579 // Too far off ray, don't bother
11580 if (d > radius) 11580 if (d > radius)
11581 return; 11581 return;
11582   11582  
11583 // Behind ray, drop 11583 // Behind ray, drop
11584 double d2 = Vector3.Dot(Vector3.Negate(ab), ac); 11584 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11585 if (d2 > 0) 11585 if (d2 > 0)
11586 return; 11586 return;
11587   11587  
11588 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart)); 11588 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11589 EntityIntersection intersection = group.TestIntersection(ray, true, false); 11589 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11590 // Miss. 11590 // Miss.
11591 if (!intersection.HitTF) 11591 if (!intersection.HitTF)
11592 return; 11592 return;
11593   11593  
11594 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ); 11594 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
11595 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ); 11595 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
11596 //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); 11596 //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);
11597 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X && 11597 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
11598 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y && 11598 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
11599 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z)) 11599 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
11600 return; 11600 return;
11601   11601  
11602 ContactResult result = new ContactResult (); 11602 ContactResult result = new ContactResult ();
11603 result.ConsumerID = group.LocalId; 11603 result.ConsumerID = group.LocalId;
11604 result.Depth = intersection.distance; 11604 result.Depth = intersection.distance;
11605 result.Normal = intersection.normal; 11605 result.Normal = intersection.normal;
11606 result.Pos = intersection.ipoint; 11606 result.Pos = intersection.ipoint;
11607   11607  
11608 contacts.Add(result); 11608 contacts.Add(result);
11609 }); 11609 });
11610   11610  
11611 return contacts.ToArray(); 11611 return contacts.ToArray();
11612 } 11612 }
11613   11613  
11614 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd) 11614 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11615 { 11615 {
11616 double[,] heightfield = World.Heightmap.GetDoubles(); 11616 double[,] heightfield = World.Heightmap.GetDoubles();
11617 List<ContactResult> contacts = new List<ContactResult>(); 11617 List<ContactResult> contacts = new List<ContactResult>();
11618   11618  
11619 double min = 2048.0; 11619 double min = 2048.0;
11620 double max = 0.0; 11620 double max = 0.0;
11621   11621  
11622 // Find the min and max of the heightfield 11622 // Find the min and max of the heightfield
11623 for (int x = 0 ; x < World.Heightmap.Width ; x++) 11623 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11624 { 11624 {
11625 for (int y = 0 ; y < World.Heightmap.Height ; y++) 11625 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11626 { 11626 {
11627 if (heightfield[x, y] > max) 11627 if (heightfield[x, y] > max)
11628 max = heightfield[x, y]; 11628 max = heightfield[x, y];
11629 if (heightfield[x, y] < min) 11629 if (heightfield[x, y] < min)
11630 min = heightfield[x, y]; 11630 min = heightfield[x, y];
11631 } 11631 }
11632 } 11632 }
11633   11633  
11634   11634  
11635 // A ray extends past rayEnd, but doesn't go back before 11635 // A ray extends past rayEnd, but doesn't go back before
11636 // rayStart. If the start is above the highest point of the ground 11636 // rayStart. If the start is above the highest point of the ground
11637 // and the ray goes up, we can't hit the ground. Ever. 11637 // and the ray goes up, we can't hit the ground. Ever.
11638 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z) 11638 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11639 return null; 11639 return null;
11640   11640  
11641 // Same for going down 11641 // Same for going down
11642 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z) 11642 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11643 return null; 11643 return null;
11644   11644  
11645 List<Tri> trilist = new List<Tri>(); 11645 List<Tri> trilist = new List<Tri>();
11646   11646  
11647 // Create our triangle list 11647 // Create our triangle list
11648 for (int x = 1 ; x < World.Heightmap.Width ; x++) 11648 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11649 { 11649 {
11650 for (int y = 1 ; y < World.Heightmap.Height ; y++) 11650 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11651 { 11651 {
11652 Tri t1 = new Tri(); 11652 Tri t1 = new Tri();
11653 Tri t2 = new Tri(); 11653 Tri t2 = new Tri();
11654   11654  
11655 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]); 11655 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11656 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]); 11656 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11657 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]); 11657 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11658 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]); 11658 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11659   11659  
11660 t1.p1 = p1; 11660 t1.p1 = p1;
11661 t1.p2 = p2; 11661 t1.p2 = p2;
11662 t1.p3 = p3; 11662 t1.p3 = p3;
11663   11663  
11664 t2.p1 = p3; 11664 t2.p1 = p3;
11665 t2.p2 = p4; 11665 t2.p2 = p4;
11666 t2.p3 = p1; 11666 t2.p3 = p1;
11667   11667  
11668 trilist.Add(t1); 11668 trilist.Add(t1);
11669 trilist.Add(t2); 11669 trilist.Add(t2);
11670 } 11670 }
11671 } 11671 }
11672   11672  
11673 // Ray direction 11673 // Ray direction
11674 Vector3 rayDirection = rayEnd - rayStart; 11674 Vector3 rayDirection = rayEnd - rayStart;
11675   11675  
11676 foreach (Tri t in trilist) 11676 foreach (Tri t in trilist)
11677 { 11677 {
11678 // Compute triangle plane normal and edges 11678 // Compute triangle plane normal and edges
11679 Vector3 u = t.p2 - t.p1; 11679 Vector3 u = t.p2 - t.p1;
11680 Vector3 v = t.p3 - t.p1; 11680 Vector3 v = t.p3 - t.p1;
11681 Vector3 n = Vector3.Cross(u, v); 11681 Vector3 n = Vector3.Cross(u, v);
11682   11682  
11683 if (n == Vector3.Zero) 11683 if (n == Vector3.Zero)
11684 continue; 11684 continue;
11685   11685  
11686 Vector3 w0 = rayStart - t.p1; 11686 Vector3 w0 = rayStart - t.p1;
11687 double a = -Vector3.Dot(n, w0); 11687 double a = -Vector3.Dot(n, w0);
11688 double b = Vector3.Dot(n, rayDirection); 11688 double b = Vector3.Dot(n, rayDirection);
11689   11689  
11690 // Not intersecting the plane, or in plane (same thing) 11690 // Not intersecting the plane, or in plane (same thing)
11691 // Ignoring this MAY cause the ground to not be detected 11691 // Ignoring this MAY cause the ground to not be detected
11692 // sometimes 11692 // sometimes
11693 if (Math.Abs(b) < 0.000001) 11693 if (Math.Abs(b) < 0.000001)
11694 continue; 11694 continue;
11695   11695  
11696 double r = a / b; 11696 double r = a / b;
11697   11697  
11698 // ray points away from plane 11698 // ray points away from plane
11699 if (r < 0.0) 11699 if (r < 0.0)
11700 continue; 11700 continue;
11701   11701  
11702 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r); 11702 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11703   11703  
11704 float uu = Vector3.Dot(u, u); 11704 float uu = Vector3.Dot(u, u);
11705 float uv = Vector3.Dot(u, v); 11705 float uv = Vector3.Dot(u, v);
11706 float vv = Vector3.Dot(v, v); 11706 float vv = Vector3.Dot(v, v);
11707 Vector3 w = ip - t.p1; 11707 Vector3 w = ip - t.p1;
11708 float wu = Vector3.Dot(w, u); 11708 float wu = Vector3.Dot(w, u);
11709 float wv = Vector3.Dot(w, v); 11709 float wv = Vector3.Dot(w, v);
11710 float d = uv * uv - uu * vv; 11710 float d = uv * uv - uu * vv;
11711   11711  
11712 float cs = (uv * wv - vv * wu) / d; 11712 float cs = (uv * wv - vv * wu) / d;
11713 if (cs < 0 || cs > 1.0) 11713 if (cs < 0 || cs > 1.0)
11714 continue; 11714 continue;
11715 float ct = (uv * wu - uu * wv) / d; 11715 float ct = (uv * wu - uu * wv) / d;
11716 if (ct < 0 || (cs + ct) > 1.0) 11716 if (ct < 0 || (cs + ct) > 1.0)
11717 continue; 11717 continue;
11718   11718  
11719 // Add contact point 11719 // Add contact point
11720 ContactResult result = new ContactResult (); 11720 ContactResult result = new ContactResult ();
11721 result.ConsumerID = 0; 11721 result.ConsumerID = 0;
11722 result.Depth = Vector3.Distance(rayStart, ip); 11722 result.Depth = Vector3.Distance(rayStart, ip);
11723 result.Normal = n; 11723 result.Normal = n;
11724 result.Pos = ip; 11724 result.Pos = ip;
11725   11725  
11726 contacts.Add(result); 11726 contacts.Add(result);
11727 } 11727 }
11728   11728  
11729 if (contacts.Count == 0) 11729 if (contacts.Count == 0)
11730 return null; 11730 return null;
11731   11731  
11732 contacts.Sort(delegate(ContactResult a, ContactResult b) 11732 contacts.Sort(delegate(ContactResult a, ContactResult b)
11733 { 11733 {
11734 return (int)(a.Depth - b.Depth); 11734 return (int)(a.Depth - b.Depth);
11735 }); 11735 });
11736   11736  
11737 return contacts[0]; 11737 return contacts[0];
11738 } 11738 }
11739   11739  
11740 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11740 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11741 { 11741 {
11742 LSL_List list = new LSL_List(); 11742 LSL_List list = new LSL_List();
11743   11743  
11744 m_host.AddScriptLPS(1); 11744 m_host.AddScriptLPS(1);
11745   11745  
11746 Vector3 rayStart = start; 11746 Vector3 rayStart = start;
11747 Vector3 rayEnd = end; 11747 Vector3 rayEnd = end;
11748 Vector3 dir = rayEnd - rayStart; 11748 Vector3 dir = rayEnd - rayStart;
11749   11749  
11750 float dist = Vector3.Mag(dir); 11750 float dist = Vector3.Mag(dir);
11751   11751  
11752 int count = 1; 11752 int count = 1;
11753 bool detectPhantom = false; 11753 bool detectPhantom = false;
11754 int dataFlags = 0; 11754 int dataFlags = 0;
11755 int rejectTypes = 0; 11755 int rejectTypes = 0;
11756   11756  
11757 for (int i = 0; i < options.Length; i += 2) 11757 for (int i = 0; i < options.Length; i += 2)
11758 { 11758 {
11759 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11759 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
11760 count = options.GetLSLIntegerItem(i + 1); 11760 count = options.GetLSLIntegerItem(i + 1);
11761 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11761 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
11762 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0); 11762 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
11763 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11763 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
11764 dataFlags = options.GetLSLIntegerItem(i + 1); 11764 dataFlags = options.GetLSLIntegerItem(i + 1);
11765 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11765 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
11766 rejectTypes = options.GetLSLIntegerItem(i + 1); 11766 rejectTypes = options.GetLSLIntegerItem(i + 1);
11767 } 11767 }
11768   11768  
11769 if (count > 16) 11769 if (count > 16)
11770 count = 16; 11770 count = 16;
11771   11771  
11772 List<ContactResult> results = new List<ContactResult>(); 11772 List<ContactResult> results = new List<ContactResult>();
11773   11773  
11774 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11774 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
11775 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11775 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
11776 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11776 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
11777 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11777 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11778   11778  
11779   11779  
11780 if (World.SupportsRayCastFiltered()) 11780 if (World.SupportsRayCastFiltered())
11781 { 11781 {
11782 if (dist == 0) 11782 if (dist == 0)
11783 return list; 11783 return list;
11784   11784  
11785 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull; 11785 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11786 if (checkTerrain) 11786 if (checkTerrain)
11787 rayfilter |= RayFilterFlags.land; 11787 rayfilter |= RayFilterFlags.land;
11788 // if (checkAgents) 11788 // if (checkAgents)
11789 // rayfilter |= RayFilterFlags.agent; 11789 // rayfilter |= RayFilterFlags.agent;
11790 if (checkPhysical) 11790 if (checkPhysical)
11791 rayfilter |= RayFilterFlags.physical; 11791 rayfilter |= RayFilterFlags.physical;
11792 if (checkNonPhysical) 11792 if (checkNonPhysical)
11793 rayfilter |= RayFilterFlags.nonphysical; 11793 rayfilter |= RayFilterFlags.nonphysical;
11794 if (detectPhantom) 11794 if (detectPhantom)
11795 rayfilter |= RayFilterFlags.LSLPhantom; 11795 rayfilter |= RayFilterFlags.LSLPhantom;
11796   11796  
11797 Vector3 direction = dir * ( 1/dist); 11797 Vector3 direction = dir * ( 1/dist);
11798   11798  
11799 if(rayfilter == 0) 11799 if(rayfilter == 0)
11800 { 11800 {
11801 list.Add(new LSL_Integer(0)); 11801 list.Add(new LSL_Integer(0));
11802 return list; 11802 return list;
11803 } 11803 }
11804   11804  
11805 // get some more contacts to sort ??? 11805 // get some more contacts to sort ???
11806 int physcount = 4 * count; 11806 int physcount = 4 * count;
11807 if (physcount > 20) 11807 if (physcount > 20)
11808 physcount = 20; 11808 physcount = 20;
11809   11809  
11810 object physresults; 11810 object physresults;
11811 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter); 11811 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11812   11812  
11813 if (physresults == null) 11813 if (physresults == null)
11814 { 11814 {
11815 list.Add(new LSL_Integer(-3)); // timeout error 11815 list.Add(new LSL_Integer(-3)); // timeout error
11816 return list; 11816 return list;
11817 } 11817 }
11818   11818  
11819 results = (List<ContactResult>)physresults; 11819 results = (List<ContactResult>)physresults;
11820   11820  
11821 // for now physics doesn't detect sitted avatars so do it outside physics 11821 // for now physics doesn't detect sitted avatars so do it outside physics
11822 if (checkAgents) 11822 if (checkAgents)
11823 { 11823 {
11824 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 11824 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11825 foreach (ContactResult r in agentHits) 11825 foreach (ContactResult r in agentHits)
11826 results.Add(r); 11826 results.Add(r);
11827 } 11827 }
11828   11828  
11829 // TODO: Replace this with a better solution. ObjectIntersection can only 11829 // TODO: Replace this with a better solution. ObjectIntersection can only
11830 // detect nonphysical phantoms. They are detected by virtue of being 11830 // detect nonphysical phantoms. They are detected by virtue of being
11831 // nonphysical (e.g. no PhysActor) so will not conflict with detecting 11831 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
11832 // physicsl phantoms as done by the physics scene 11832 // physicsl phantoms as done by the physics scene
11833 // We don't want anything else but phantoms here. 11833 // We don't want anything else but phantoms here.
11834 if (detectPhantom) 11834 if (detectPhantom)
11835 { 11835 {
11836 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true); 11836 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
11837 foreach (ContactResult r in objectHits) 11837 foreach (ContactResult r in objectHits)
11838 results.Add(r); 11838 results.Add(r);
11839 } 11839 }
11840 } 11840 }
11841 else 11841 else
11842 { 11842 {
11843 if (checkAgents) 11843 if (checkAgents)
11844 { 11844 {
11845 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 11845 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11846 foreach (ContactResult r in agentHits) 11846 foreach (ContactResult r in agentHits)
11847 results.Add(r); 11847 results.Add(r);
11848 } 11848 }
11849   11849  
11850 if (checkPhysical || checkNonPhysical || detectPhantom) 11850 if (checkPhysical || checkNonPhysical || detectPhantom)
11851 { 11851 {
11852 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 11852 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11853 for (int iter = 0; iter < objectHits.Length; iter++) 11853 for (int iter = 0; iter < objectHits.Length; iter++)
11854 { 11854 {
11855 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler. 11855 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
11856 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart); 11856 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
11857 results.Add(objectHits[iter]); 11857 results.Add(objectHits[iter]);
11858 } 11858 }
11859 } 11859 }
11860 } 11860 }
11861   11861  
11862 if (checkTerrain) 11862 if (checkTerrain)
11863 { 11863 {
11864 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 11864 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11865 if (groundContact != null) 11865 if (groundContact != null)
11866 results.Add((ContactResult)groundContact); 11866 results.Add((ContactResult)groundContact);
11867 } 11867 }
11868   11868  
11869 results.Sort(delegate(ContactResult a, ContactResult b) 11869 results.Sort(delegate(ContactResult a, ContactResult b)
11870 { 11870 {
11871 return a.Depth.CompareTo(b.Depth); 11871 return a.Depth.CompareTo(b.Depth);
11872 }); 11872 });
11873   11873  
11874 int values = 0; 11874 int values = 0;
11875 SceneObjectGroup thisgrp = m_host.ParentGroup; 11875 SceneObjectGroup thisgrp = m_host.ParentGroup;
11876   11876  
11877 foreach (ContactResult result in results) 11877 foreach (ContactResult result in results)
11878 { 11878 {
11879 if (result.Depth > dist) 11879 if (result.Depth > dist)
11880 continue; 11880 continue;
11881   11881  
11882 // physics ray can return colisions with host prim 11882 // physics ray can return colisions with host prim
11883 if (m_host.LocalId == result.ConsumerID) 11883 if (m_host.LocalId == result.ConsumerID)
11884 continue; 11884 continue;
11885   11885  
11886 UUID itemID = UUID.Zero; 11886 UUID itemID = UUID.Zero;
11887 int linkNum = 0; 11887 int linkNum = 0;
11888   11888  
11889 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID); 11889 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11890 // It's a prim! 11890 // It's a prim!
11891 if (part != null) 11891 if (part != null)
11892 { 11892 {
11893 // dont detect members of same object ??? 11893 // dont detect members of same object ???
11894 if (part.ParentGroup == thisgrp) 11894 if (part.ParentGroup == thisgrp)
11895 continue; 11895 continue;
11896   11896  
11897 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY) 11897 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
11898 itemID = part.ParentGroup.UUID; 11898 itemID = part.ParentGroup.UUID;
11899 else 11899 else
11900 itemID = part.UUID; 11900 itemID = part.UUID;
11901   11901  
11902 linkNum = part.LinkNum; 11902 linkNum = part.LinkNum;
11903 } 11903 }
11904 else 11904 else
11905 { 11905 {
11906 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 11906 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
11907 /// It it a boy? a girl? 11907 /// It it a boy? a girl?
11908 if (sp != null) 11908 if (sp != null)
11909 itemID = sp.UUID; 11909 itemID = sp.UUID;
11910 } 11910 }
11911   11911  
11912 list.Add(new LSL_String(itemID.ToString())); 11912 list.Add(new LSL_String(itemID.ToString()));
11913 list.Add(new LSL_String(result.Pos.ToString())); 11913 list.Add(new LSL_String(result.Pos.ToString()));
11914   11914  
11915 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11915 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11916 list.Add(new LSL_Integer(linkNum)); 11916 list.Add(new LSL_Integer(linkNum));
11917   11917  
11918 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11918 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
11919 list.Add(new LSL_Vector(result.Normal)); 11919 list.Add(new LSL_Vector(result.Normal));
11920   11920  
11921 values++; 11921 values++;
11922 if (values >= count) 11922 if (values >= count)
11923 break; 11923 break;
11924 } 11924 }
11925   11925  
11926 list.Add(new LSL_Integer(values)); 11926 list.Add(new LSL_Integer(values));
11927   11927  
11928 return list; 11928 return list;
11929 } 11929 }
11930   11930  
11931 public LSL_Integer llManageEstateAccess(int action, string avatar) 11931 public LSL_Integer llManageEstateAccess(int action, string avatar)
11932 { 11932 {
11933 m_host.AddScriptLPS(1); 11933 m_host.AddScriptLPS(1);
11934 EstateSettings estate = World.RegionInfo.EstateSettings; 11934 EstateSettings estate = World.RegionInfo.EstateSettings;
11935 bool isAccount = false; 11935 bool isAccount = false;
11936 bool isGroup = false; 11936 bool isGroup = false;
11937   11937  
11938 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID)) 11938 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManagerOrOwner(m_host.OwnerID))
11939 return 0; 11939 return 0;
11940   11940  
11941 UUID id = new UUID(); 11941 UUID id = new UUID();
11942 if (!UUID.TryParse(avatar, out id)) 11942 if (!UUID.TryParse(avatar, out id))
11943 return 0; 11943 return 0;
11944   11944  
11945 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id); 11945 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id);
11946 isAccount = account != null ? true : false; 11946 isAccount = account != null ? true : false;
11947 if (!isAccount) 11947 if (!isAccount)
11948 { 11948 {
11949 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>(); 11949 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
11950 if (groups != null) 11950 if (groups != null)
11951 { 11951 {
11952 GroupRecord group = groups.GetGroupRecord(id); 11952 GroupRecord group = groups.GetGroupRecord(id);
11953 isGroup = group != null ? true : false; 11953 isGroup = group != null ? true : false;
11954 if (!isGroup) 11954 if (!isGroup)
11955 return 0; 11955 return 0;
11956 } 11956 }
11957 else 11957 else
11958 return 0; 11958 return 0;
11959 } 11959 }
11960   11960  
11961 switch (action) 11961 switch (action)
11962 { 11962 {
11963 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11963 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11964 if (!isAccount) return 0; 11964 if (!isAccount) return 0;
11965 if (estate.HasAccess(id)) return 1; 11965 if (estate.HasAccess(id)) return 1;
11966 if (estate.IsBanned(id)) 11966 if (estate.IsBanned(id))
11967 estate.RemoveBan(id); 11967 estate.RemoveBan(id);
11968 estate.AddEstateUser(id); 11968 estate.AddEstateUser(id);
11969 break; 11969 break;
11970 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE: 11970 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE:
11971 if (!isAccount || !estate.HasAccess(id)) return 0; 11971 if (!isAccount || !estate.HasAccess(id)) return 0;
11972 estate.RemoveEstateUser(id); 11972 estate.RemoveEstateUser(id);
11973 break; 11973 break;
11974 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD: 11974 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD:
11975 if (!isGroup) return 0; 11975 if (!isGroup) return 0;
11976 if (estate.GroupAccess(id)) return 1; 11976 if (estate.GroupAccess(id)) return 1;
11977 estate.AddEstateGroup(id); 11977 estate.AddEstateGroup(id);
11978 break; 11978 break;
11979 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE: 11979 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE:
11980 if (!isGroup || !estate.GroupAccess(id)) return 0; 11980 if (!isGroup || !estate.GroupAccess(id)) return 0;
11981 estate.RemoveEstateGroup(id); 11981 estate.RemoveEstateGroup(id);
11982 break; 11982 break;
11983 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11983 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11984 if (!isAccount) return 0; 11984 if (!isAccount) return 0;
11985 if (estate.IsBanned(id)) return 1; 11985 if (estate.IsBanned(id)) return 1;
11986 EstateBan ban = new EstateBan(); 11986 EstateBan ban = new EstateBan();
11987 ban.EstateID = estate.EstateID; 11987 ban.EstateID = estate.EstateID;
11988 ban.BannedUserID = id; 11988 ban.BannedUserID = id;
11989 estate.AddBan(ban); 11989 estate.AddBan(ban);
11990 break; 11990 break;
11991 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11991 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11992 if (!isAccount || !estate.IsBanned(id)) return 0; 11992 if (!isAccount || !estate.IsBanned(id)) return 0;
11993 estate.RemoveBan(id); 11993 estate.RemoveBan(id);
11994 break; 11994 break;
11995 default: return 0; 11995 default: return 0;
11996 } 11996 }
11997 return 1; 11997 return 1;
11998 } 11998 }
11999   11999  
12000 public LSL_Integer llGetMemoryLimit() 12000 public LSL_Integer llGetMemoryLimit()
12001 { 12001 {
12002 m_host.AddScriptLPS(1); 12002 m_host.AddScriptLPS(1);
12003 // The value returned for LSO scripts in SL 12003 // The value returned for LSO scripts in SL
12004 return 16384; 12004 return 16384;
12005 } 12005 }
12006   12006  
12007 public LSL_Integer llSetMemoryLimit(LSL_Integer limit) 12007 public LSL_Integer llSetMemoryLimit(LSL_Integer limit)
12008 { 12008 {
12009 m_host.AddScriptLPS(1); 12009 m_host.AddScriptLPS(1);
12010 // Treat as an LSO script 12010 // Treat as an LSO script
12011 return ScriptBaseClass.FALSE; 12011 return ScriptBaseClass.FALSE;
12012 } 12012 }
12013   12013  
12014 public LSL_Integer llGetSPMaxMemory() 12014 public LSL_Integer llGetSPMaxMemory()
12015 { 12015 {
12016 m_host.AddScriptLPS(1); 12016 m_host.AddScriptLPS(1);
12017 // The value returned for LSO scripts in SL 12017 // The value returned for LSO scripts in SL
12018 return 16384; 12018 return 16384;
12019 } 12019 }
12020   12020  
12021 public virtual LSL_Integer llGetUsedMemory() 12021 public virtual LSL_Integer llGetUsedMemory()
12022 { 12022 {
12023 m_host.AddScriptLPS(1); 12023 m_host.AddScriptLPS(1);
12024 // The value returned for LSO scripts in SL 12024 // The value returned for LSO scripts in SL
12025 return 16384; 12025 return 16384;
12026 } 12026 }
12027   12027  
12028 public void llScriptProfiler(LSL_Integer flags) 12028 public void llScriptProfiler(LSL_Integer flags)
12029 { 12029 {
12030 m_host.AddScriptLPS(1); 12030 m_host.AddScriptLPS(1);
12031 // This does nothing for LSO scripts in SL 12031 // This does nothing for LSO scripts in SL
12032 } 12032 }
12033   12033  
12034 #region Not Implemented 12034 #region Not Implemented
12035 // 12035 //
12036 // Listing the unimplemented lsl functions here, please move 12036 // Listing the unimplemented lsl functions here, please move
12037 // them from this region as they are completed 12037 // them from this region as they are completed
12038 // 12038 //
12039   12039  
12040 public void llGetEnv(LSL_String name) 12040 public void llGetEnv(LSL_String name)
12041 { 12041 {
12042 m_host.AddScriptLPS(1); 12042 m_host.AddScriptLPS(1);
12043 NotImplemented("llGetEnv"); 12043 NotImplemented("llGetEnv");
12044 } 12044 }
12045   12045  
12046 public void llSetSoundQueueing(int queue) 12046 public void llSetSoundQueueing(int queue)
12047 { 12047 {
12048 m_host.AddScriptLPS(1); 12048 m_host.AddScriptLPS(1);
12049   12049  
12050 if (m_SoundModule != null) 12050 if (m_SoundModule != null)
12051 m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value); 12051 m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value);
12052 } 12052 }
12053   12053  
12054 public void llCollisionSprite(string impact_sprite) 12054 public void llCollisionSprite(string impact_sprite)
12055 { 12055 {
12056 m_host.AddScriptLPS(1); 12056 m_host.AddScriptLPS(1);
12057 NotImplemented("llCollisionSprite"); 12057 NotImplemented("llCollisionSprite");
12058 } 12058 }
12059   12059  
12060 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12060 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12061 { 12061 {
12062 m_host.AddScriptLPS(1); 12062 m_host.AddScriptLPS(1);
12063 NotImplemented("llGodLikeRezObject"); 12063 NotImplemented("llGodLikeRezObject");
12064 } 12064 }
12065   12065  
12066 public LSL_String llTransferLindenDollars(string destination, int amount) 12066 public LSL_String llTransferLindenDollars(string destination, int amount)
12067 { 12067 {
12068 UUID txn = UUID.Random(); 12068 UUID txn = UUID.Random();
12069   12069  
12070 Util.FireAndForget(delegate(object x) 12070 Util.FireAndForget(delegate(object x)
12071 { 12071 {
12072 int replycode = 0; 12072 int replycode = 0;
12073 string replydata = destination + "," + amount.ToString(); 12073 string replydata = destination + "," + amount.ToString();
12074   12074  
12075 try 12075 try
12076 { 12076 {
12077 TaskInventoryItem item = m_item; 12077 TaskInventoryItem item = m_item;
12078 if (item == null) 12078 if (item == null)
12079 { 12079 {
12080 replydata = "SERVICE_ERROR"; 12080 replydata = "SERVICE_ERROR";
12081 return; 12081 return;
12082 } 12082 }
12083   12083  
12084 m_host.AddScriptLPS(1); 12084 m_host.AddScriptLPS(1);
12085   12085  
12086 if (item.PermsGranter == UUID.Zero) 12086 if (item.PermsGranter == UUID.Zero)
12087 { 12087 {
12088 replydata = "MISSING_PERMISSION_DEBIT"; 12088 replydata = "MISSING_PERMISSION_DEBIT";
12089 return; 12089 return;
12090 } 12090 }
12091   12091  
12092 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) 12092 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12093 { 12093 {
12094 replydata = "MISSING_PERMISSION_DEBIT"; 12094 replydata = "MISSING_PERMISSION_DEBIT";
12095 return; 12095 return;
12096 } 12096 }
12097   12097  
12098 UUID toID = new UUID(); 12098 UUID toID = new UUID();
12099   12099  
12100 if (!UUID.TryParse(destination, out toID)) 12100 if (!UUID.TryParse(destination, out toID))
12101 { 12101 {
12102 replydata = "INVALID_AGENT"; 12102 replydata = "INVALID_AGENT";
12103 return; 12103 return;
12104 } 12104 }
12105   12105  
12106 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>(); 12106 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12107   12107  
12108 if (money == null) 12108 if (money == null)
12109 { 12109 {
12110 replydata = "TRANSFERS_DISABLED"; 12110 replydata = "TRANSFERS_DISABLED";
12111 return; 12111 return;
12112 } 12112 }
12113   12113  
12114 bool result = money.ObjectGiveMoney( 12114 bool result = money.ObjectGiveMoney(
12115 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12115 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12116   12116  
12117 if (result) 12117 if (result)
12118 { 12118 {
12119 replycode = 1; 12119 replycode = 1;
12120 return; 12120 return;
12121 } 12121 }
12122   12122  
12123 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12123 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12124 } 12124 }
12125 finally 12125 finally
12126 { 12126 {
12127 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 12127 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12128 "transaction_result", new Object[] { 12128 "transaction_result", new Object[] {
12129 new LSL_String(txn.ToString()), 12129 new LSL_String(txn.ToString()),
12130 new LSL_Integer(replycode), 12130 new LSL_Integer(replycode),
12131 new LSL_String(replydata) }, 12131 new LSL_String(replydata) },
12132 new DetectParams[0])); 12132 new DetectParams[0]));
12133 } 12133 }
12134 }); 12134 });
12135   12135  
12136 return txn.ToString(); 12136 return txn.ToString();
12137 } 12137 }
12138   12138  
12139 #endregion 12139 #endregion
12140 } 12140 }
12141   12141  
12142 public class NotecardCache 12142 public class NotecardCache
12143 { 12143 {
12144 protected class Notecard 12144 protected class Notecard
12145 { 12145 {
12146 public string[] text; 12146 public string[] text;
12147 public DateTime lastRef; 12147 public DateTime lastRef;
12148 } 12148 }
12149   12149  
12150 protected static Dictionary<UUID, Notecard> m_Notecards = 12150 protected static Dictionary<UUID, Notecard> m_Notecards =
12151 new Dictionary<UUID, Notecard>(); 12151 new Dictionary<UUID, Notecard>();
12152   12152  
12153 public static void Cache(UUID assetID, string text) 12153 public static void Cache(UUID assetID, string text)
12154 { 12154 {
12155 CheckCache(); 12155 CheckCache();
12156   12156  
12157 lock (m_Notecards) 12157 lock (m_Notecards)
12158 { 12158 {
12159 if (m_Notecards.ContainsKey(assetID)) 12159 if (m_Notecards.ContainsKey(assetID))
12160 return; 12160 return;
12161   12161  
12162 Notecard nc = new Notecard(); 12162 Notecard nc = new Notecard();
12163 nc.lastRef = DateTime.Now; 12163 nc.lastRef = DateTime.Now;
12164 nc.text = SLUtil.ParseNotecardToList(text).ToArray(); 12164 nc.text = SLUtil.ParseNotecardToList(text).ToArray();
12165 m_Notecards[assetID] = nc; 12165 m_Notecards[assetID] = nc;
12166 } 12166 }
12167 } 12167 }
12168   12168  
12169 public static bool IsCached(UUID assetID) 12169 public static bool IsCached(UUID assetID)
12170 { 12170 {
12171 lock (m_Notecards) 12171 lock (m_Notecards)
12172 { 12172 {
12173 return m_Notecards.ContainsKey(assetID); 12173 return m_Notecards.ContainsKey(assetID);
12174 } 12174 }
12175 } 12175 }
12176   12176  
12177 public static int GetLines(UUID assetID) 12177 public static int GetLines(UUID assetID)
12178 { 12178 {
12179 if (!IsCached(assetID)) 12179 if (!IsCached(assetID))
12180 return -1; 12180 return -1;
12181   12181  
12182 lock (m_Notecards) 12182 lock (m_Notecards)
12183 { 12183 {
12184 m_Notecards[assetID].lastRef = DateTime.Now; 12184 m_Notecards[assetID].lastRef = DateTime.Now;
12185 return m_Notecards[assetID].text.Length; 12185 return m_Notecards[assetID].text.Length;
12186 } 12186 }
12187 } 12187 }
12188   12188  
12189 /// <summary> 12189 /// <summary>
12190 /// Get a notecard line. 12190 /// Get a notecard line.
12191 /// </summary> 12191 /// </summary>
12192 /// <param name="assetID"></param> 12192 /// <param name="assetID"></param>
12193 /// <param name="lineNumber">Lines start at index 0</param> 12193 /// <param name="lineNumber">Lines start at index 0</param>
12194 /// <returns></returns> 12194 /// <returns></returns>
12195 public static string GetLine(UUID assetID, int lineNumber) 12195 public static string GetLine(UUID assetID, int lineNumber)
12196 { 12196 {
12197 if (lineNumber < 0) 12197 if (lineNumber < 0)
12198 return ""; 12198 return "";
12199   12199  
12200 string data; 12200 string data;
12201   12201  
12202 if (!IsCached(assetID)) 12202 if (!IsCached(assetID))
12203 return ""; 12203 return "";
12204   12204  
12205 lock (m_Notecards) 12205 lock (m_Notecards)
12206 { 12206 {
12207 m_Notecards[assetID].lastRef = DateTime.Now; 12207 m_Notecards[assetID].lastRef = DateTime.Now;
12208   12208  
12209 if (lineNumber >= m_Notecards[assetID].text.Length) 12209 if (lineNumber >= m_Notecards[assetID].text.Length)
12210 return "\n\n\n"; 12210 return "\n\n\n";
12211   12211  
12212 data = m_Notecards[assetID].text[lineNumber]; 12212 data = m_Notecards[assetID].text[lineNumber];
12213   12213  
12214 return data; 12214 return data;
12215 } 12215 }
12216 } 12216 }
12217   12217  
12218 /// <summary> 12218 /// <summary>
12219 /// Get a notecard line. 12219 /// Get a notecard line.
12220 /// </summary> 12220 /// </summary>
12221 /// <param name="assetID"></param> 12221 /// <param name="assetID"></param>
12222 /// <param name="lineNumber">Lines start at index 0</param> 12222 /// <param name="lineNumber">Lines start at index 0</param>
12223 /// <param name="maxLength"> 12223 /// <param name="maxLength">
12224 /// Maximum length of the returned line. 12224 /// Maximum length of the returned line.
12225 /// </param> 12225 /// </param>
12226 /// <returns> 12226 /// <returns>
12227 /// If the line length is longer than <paramref name="maxLength"/>, 12227 /// If the line length is longer than <paramref name="maxLength"/>,
12228 /// the return string will be truncated. 12228 /// the return string will be truncated.
12229 /// </returns> 12229 /// </returns>
12230 public static string GetLine(UUID assetID, int lineNumber, int maxLength) 12230 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
12231 { 12231 {
12232 string line = GetLine(assetID, lineNumber); 12232 string line = GetLine(assetID, lineNumber);
12233   12233  
12234 if (line.Length > maxLength) 12234 if (line.Length > maxLength)
12235 line = line.Substring(0, maxLength); 12235 line = line.Substring(0, maxLength);
12236   12236  
12237 return line; 12237 return line;
12238 } 12238 }
12239   12239  
12240 public static void CheckCache() 12240 public static void CheckCache()
12241 { 12241 {
12242 lock (m_Notecards) 12242 lock (m_Notecards)
12243 { 12243 {
12244 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 12244 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
12245 { 12245 {
12246 Notecard nc = m_Notecards[key]; 12246 Notecard nc = m_Notecards[key];
12247 if (nc.lastRef.AddSeconds(30) < DateTime.Now) 12247 if (nc.lastRef.AddSeconds(30) < DateTime.Now)
12248 m_Notecards.Remove(key); 12248 m_Notecards.Remove(key);
12249 } 12249 }
12250 } 12250 }
12251 } 12251 }
12252 } 12252 }
12253 } 12253 }
12254   12254