PageRenderTime 81ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 3ms

/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs

https://bitbucket.org/VirtualReality/taiga
C# | 9875 lines | 7634 code | 1335 blank | 906 comment | 1522 complexity | 9d58dbb8308e89849bbb9002ad59e5bb MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  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
  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
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Runtime.Remoting.Lifetime;
  31. using System.Text;
  32. using System.Threading;
  33. using System.Text.RegularExpressions;
  34. using Nini.Config;
  35. using log4net;
  36. using OpenMetaverse;
  37. using OpenMetaverse.Packets;
  38. using OpenSim;
  39. using OpenSim.Framework;
  40. using OpenSim.Framework.Communications.Cache;
  41. using OpenSim.Region.CoreModules;
  42. using OpenSim.Region.CoreModules.World.Land;
  43. using OpenSim.Region.CoreModules.World.Terrain;
  44. using OpenSim.Region.Framework.Interfaces;
  45. using OpenSim.Region.Framework.Scenes;
  46. using OpenSim.Region.Framework.Scenes.Animation;
  47. using OpenSim.Region.Physics.Manager;
  48. using OpenSim.Region.ScriptEngine.Shared;
  49. using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
  50. using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
  51. using OpenSim.Region.ScriptEngine.Interfaces;
  52. using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
  53. using OpenSim.Services.Interfaces;
  54. using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
  55. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  56. using AssetLandmark = OpenSim.Framework.AssetLandmark;
  57. using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
  58. using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
  59. using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  60. using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
  61. using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
  62. using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  63. using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
  64. using System.Reflection;
  65. namespace OpenSim.Region.ScriptEngine.Shared.Api
  66. {
  67. /// <summary>
  68. /// Contains all LSL ll-functions. This class will be in Default AppDomain.
  69. /// </summary>
  70. public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
  71. {
  72. //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  73. protected IScriptEngine m_ScriptEngine;
  74. protected SceneObjectPart m_host;
  75. protected uint m_localID;
  76. protected UUID m_itemID;
  77. protected bool throwErrorOnNotImplemented = true;
  78. protected AsyncCommandManager AsyncCommands = null;
  79. protected float m_ScriptDelayFactor = 1.0f;
  80. protected float m_ScriptDistanceFactor = 1.0f;
  81. protected float m_MinTimerInterval = 0.5f;
  82. protected DateTime m_timer = DateTime.Now;
  83. protected bool m_waitingForScriptAnswer = false;
  84. protected bool m_automaticLinkPermission = false;
  85. protected IMessageTransferModule m_TransferModule = null;
  86. protected int m_notecardLineReadCharsMax = 255;
  87. protected int m_scriptConsoleChannel = 0;
  88. protected bool m_scriptConsoleChannelEnabled = false;
  89. protected IUrlModule m_UrlModule = null;
  90. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
  91. {
  92. m_ScriptEngine = ScriptEngine;
  93. m_host = host;
  94. m_localID = localID;
  95. m_itemID = itemID;
  96. m_ScriptDelayFactor =
  97. m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
  98. m_ScriptDistanceFactor =
  99. m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f);
  100. m_MinTimerInterval =
  101. m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.5f);
  102. m_automaticLinkPermission =
  103. m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false);
  104. m_notecardLineReadCharsMax =
  105. m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
  106. if (m_notecardLineReadCharsMax > 65535)
  107. m_notecardLineReadCharsMax = 65535;
  108. m_TransferModule =
  109. m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
  110. m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
  111. if (m_UrlModule != null)
  112. {
  113. m_ScriptEngine.OnScriptRemoved += m_UrlModule.ScriptRemoved;
  114. m_ScriptEngine.OnObjectRemoved += m_UrlModule.ObjectRemoved;
  115. }
  116. AsyncCommands = new AsyncCommandManager(ScriptEngine);
  117. }
  118. public override Object InitializeLifetimeService()
  119. {
  120. ILease lease = (ILease)base.InitializeLifetimeService();
  121. if (lease.CurrentState == LeaseState.Initial)
  122. {
  123. lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
  124. // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
  125. // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
  126. }
  127. return lease;
  128. }
  129. protected virtual void ScriptSleep(int delay)
  130. {
  131. delay = (int)((float)delay * m_ScriptDelayFactor);
  132. if (delay == 0)
  133. return;
  134. System.Threading.Thread.Sleep(delay);
  135. }
  136. public Scene World
  137. {
  138. get { return m_ScriptEngine.World; }
  139. }
  140. public void state(string newState)
  141. {
  142. m_ScriptEngine.SetState(m_itemID, newState);
  143. }
  144. /// <summary>
  145. /// Reset the named script. The script must be present
  146. /// in the same prim.
  147. /// </summary>
  148. public void llResetScript()
  149. {
  150. m_host.AddScriptLPS(1);
  151. m_ScriptEngine.ApiResetScript(m_itemID);
  152. }
  153. public void llResetOtherScript(string name)
  154. {
  155. UUID item;
  156. m_host.AddScriptLPS(1);
  157. if ((item = ScriptByName(name)) != UUID.Zero)
  158. m_ScriptEngine.ResetScript(item);
  159. else
  160. ShoutError("llResetOtherScript: script "+name+" not found");
  161. }
  162. public LSL_Integer llGetScriptState(string name)
  163. {
  164. UUID item;
  165. m_host.AddScriptLPS(1);
  166. if ((item = ScriptByName(name)) != UUID.Zero)
  167. {
  168. return m_ScriptEngine.GetScriptState(item) ?1:0;
  169. }
  170. ShoutError("llGetScriptState: script "+name+" not found");
  171. // If we didn't find it, then it's safe to
  172. // assume it is not running.
  173. return 0;
  174. }
  175. public void llSetScriptState(string name, int run)
  176. {
  177. UUID item;
  178. m_host.AddScriptLPS(1);
  179. // These functions are supposed to be robust,
  180. // so get the state one step at a time.
  181. if ((item = ScriptByName(name)) != UUID.Zero)
  182. {
  183. m_ScriptEngine.SetScriptState(item, run == 0 ? false : true);
  184. }
  185. else
  186. {
  187. ShoutError("llSetScriptState: script "+name+" not found");
  188. }
  189. }
  190. public List<SceneObjectPart> GetLinkParts(int linkType)
  191. {
  192. List<SceneObjectPart> ret = new List<SceneObjectPart>();
  193. ret.Add(m_host);
  194. switch (linkType)
  195. {
  196. case ScriptBaseClass.LINK_SET:
  197. if (m_host.ParentGroup != null)
  198. return new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
  199. return ret;
  200. case ScriptBaseClass.LINK_ROOT:
  201. if (m_host.ParentGroup != null)
  202. {
  203. ret = new List<SceneObjectPart>();
  204. ret.Add(m_host.ParentGroup.RootPart);
  205. return ret;
  206. }
  207. return ret;
  208. case ScriptBaseClass.LINK_ALL_OTHERS:
  209. if (m_host.ParentGroup == null)
  210. return new List<SceneObjectPart>();
  211. ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
  212. if (ret.Contains(m_host))
  213. ret.Remove(m_host);
  214. return ret;
  215. case ScriptBaseClass.LINK_ALL_CHILDREN:
  216. if (m_host.ParentGroup == null)
  217. return new List<SceneObjectPart>();
  218. ret = new List<SceneObjectPart>(m_host.ParentGroup.Children.Values);
  219. if (ret.Contains(m_host.ParentGroup.RootPart))
  220. ret.Remove(m_host.ParentGroup.RootPart);
  221. return ret;
  222. case ScriptBaseClass.LINK_THIS:
  223. return ret;
  224. default:
  225. if (linkType < 0 || m_host.ParentGroup == null)
  226. return new List<SceneObjectPart>();
  227. SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
  228. if (target == null)
  229. return new List<SceneObjectPart>();
  230. ret = new List<SceneObjectPart>();
  231. ret.Add(target);
  232. return ret;
  233. }
  234. }
  235. protected UUID InventorySelf()
  236. {
  237. UUID invItemID = new UUID();
  238. lock (m_host.TaskInventory)
  239. {
  240. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  241. {
  242. if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
  243. {
  244. invItemID = inv.Key;
  245. break;
  246. }
  247. }
  248. }
  249. return invItemID;
  250. }
  251. protected UUID InventoryKey(string name, int type)
  252. {
  253. m_host.AddScriptLPS(1);
  254. lock (m_host.TaskInventory)
  255. {
  256. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  257. {
  258. if (inv.Value.Name == name)
  259. {
  260. if (inv.Value.Type != type)
  261. return UUID.Zero;
  262. return inv.Value.AssetID;
  263. }
  264. }
  265. }
  266. return UUID.Zero;
  267. }
  268. protected UUID InventoryKey(string name)
  269. {
  270. m_host.AddScriptLPS(1);
  271. lock (m_host.TaskInventory)
  272. {
  273. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  274. {
  275. if (inv.Value.Name == name)
  276. {
  277. return inv.Value.AssetID;
  278. }
  279. }
  280. }
  281. return UUID.Zero;
  282. }
  283. /// <summary>
  284. /// accepts a valid UUID, -or- a name of an inventory item.
  285. /// Returns a valid UUID or UUID.Zero if key invalid and item not found
  286. /// in prim inventory.
  287. /// </summary>
  288. /// <param name="k"></param>
  289. /// <returns></returns>
  290. protected UUID KeyOrName(string k)
  291. {
  292. UUID key = UUID.Zero;
  293. // if we can parse the string as a key, use it.
  294. if (UUID.TryParse(k, out key))
  295. {
  296. return key;
  297. }
  298. // else try to locate the name in inventory of object. found returns key,
  299. // not found returns UUID.Zero which will translate to the default particle texture
  300. else
  301. {
  302. return InventoryKey(k);
  303. }
  304. }
  305. // convert a LSL_Rotation to a Quaternion
  306. protected Quaternion Rot2Quaternion(LSL_Rotation r)
  307. {
  308. Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
  309. q.Normalize();
  310. return q;
  311. }
  312. //These are the implementations of the various ll-functions used by the LSL scripts.
  313. public LSL_Float llSin(double f)
  314. {
  315. m_host.AddScriptLPS(1);
  316. return (double)Math.Sin(f);
  317. }
  318. public LSL_Float llCos(double f)
  319. {
  320. m_host.AddScriptLPS(1);
  321. return (double)Math.Cos(f);
  322. }
  323. public LSL_Float llTan(double f)
  324. {
  325. m_host.AddScriptLPS(1);
  326. return (double)Math.Tan(f);
  327. }
  328. public LSL_Float llAtan2(double x, double y)
  329. {
  330. m_host.AddScriptLPS(1);
  331. return (double)Math.Atan2(x, y);
  332. }
  333. public LSL_Float llSqrt(double f)
  334. {
  335. m_host.AddScriptLPS(1);
  336. return (double)Math.Sqrt(f);
  337. }
  338. public LSL_Float llPow(double fbase, double fexponent)
  339. {
  340. m_host.AddScriptLPS(1);
  341. return (double)Math.Pow(fbase, fexponent);
  342. }
  343. public LSL_Integer llAbs(int i)
  344. {
  345. // changed to replicate LSL behaviour whereby minimum int value is returned untouched.
  346. m_host.AddScriptLPS(1);
  347. if (i == Int32.MinValue)
  348. return i;
  349. else
  350. return (int)Math.Abs(i);
  351. }
  352. public LSL_Float llFabs(double f)
  353. {
  354. m_host.AddScriptLPS(1);
  355. return (double)Math.Abs(f);
  356. }
  357. public LSL_Float llFrand(double mag)
  358. {
  359. m_host.AddScriptLPS(1);
  360. lock (Util.RandomClass)
  361. {
  362. return Util.RandomClass.NextDouble() * mag;
  363. }
  364. }
  365. public LSL_Integer llFloor(double f)
  366. {
  367. m_host.AddScriptLPS(1);
  368. return (int)Math.Floor(f);
  369. }
  370. public LSL_Integer llCeil(double f)
  371. {
  372. m_host.AddScriptLPS(1);
  373. return (int)Math.Ceiling(f);
  374. }
  375. // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven)
  376. public LSL_Integer llRound(double f)
  377. {
  378. m_host.AddScriptLPS(1);
  379. return (int)Math.Round(f, MidpointRounding.AwayFromZero);
  380. }
  381. //This next group are vector operations involving squaring and square root. ckrinke
  382. public LSL_Float llVecMag(LSL_Vector v)
  383. {
  384. m_host.AddScriptLPS(1);
  385. return LSL_Vector.Mag(v);
  386. }
  387. public LSL_Vector llVecNorm(LSL_Vector v)
  388. {
  389. m_host.AddScriptLPS(1);
  390. double mag = LSL_Vector.Mag(v);
  391. LSL_Vector nor = new LSL_Vector();
  392. nor.x = v.x / mag;
  393. nor.y = v.y / mag;
  394. nor.z = v.z / mag;
  395. return nor;
  396. }
  397. public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
  398. {
  399. m_host.AddScriptLPS(1);
  400. double dx = a.x - b.x;
  401. double dy = a.y - b.y;
  402. double dz = a.z - b.z;
  403. return Math.Sqrt(dx * dx + dy * dy + dz * dz);
  404. }
  405. //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
  406. // Utility function for llRot2Euler
  407. // normalize an angle between -PI and PI (-180 to +180 degrees)
  408. protected double NormalizeAngle(double angle)
  409. {
  410. if (angle > -Math.PI && angle < Math.PI)
  411. return angle;
  412. int numPis = (int)(Math.PI / angle);
  413. double remainder = angle - Math.PI * numPis;
  414. if (numPis % 2 == 1)
  415. return Math.PI - angle;
  416. return remainder;
  417. }
  418. // Old implementation of llRot2Euler, now normalized
  419. public LSL_Vector llRot2Euler(LSL_Rotation r)
  420. {
  421. m_host.AddScriptLPS(1);
  422. //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke
  423. LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s);
  424. double m = (t.x + t.y + t.z + t.s);
  425. if (m == 0) return new LSL_Vector();
  426. double n = 2 * (r.y * r.s + r.x * r.z);
  427. double p = m * m - n * n;
  428. if (p > 0)
  429. return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))),
  430. NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
  431. NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))));
  432. else if (n > 0)
  433. return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)));
  434. else
  435. return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)));
  436. }
  437. /* From wiki:
  438. The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes
  439. in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation,
  440. a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting
  441. vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis.
  442. */
  443. /* How we arrived at this llEuler2Rot
  444. *
  445. * Experiment in SL to determine conventions:
  446. * llEuler2Rot(<PI,0,0>)=<1,0,0,0>
  447. * llEuler2Rot(<0,PI,0>)=<0,1,0,0>
  448. * llEuler2Rot(<0,0,PI>)=<0,0,1,0>
  449. *
  450. * Important facts about Quaternions
  451. * - multiplication is non-commutative (a*b != b*a)
  452. * - http://en.wikipedia.org/wiki/Quaternion#Basis_multiplication
  453. *
  454. * Above SL experiment gives (c1,c2,c3,s1,s2,s3 as defined in our llEuler2Rot):
  455. * Qx = c1+i*s1
  456. * Qy = c2+j*s2;
  457. * Qz = c3+k*s3;
  458. *
  459. * Rotations applied in order (from above) Z, Y, X
  460. * Q = (Qz * Qy) * Qx
  461. * ((c1+i*s1)*(c2+j*s2))*(c3+k*s3)
  462. * (c1*c2+i*s1*c2+j*c1*s2+ij*s1*s2)*(c3+k*s3)
  463. * (c1*c2+i*s1*c2+j*c1*s2+k*s1*s2)*(c3+k*s3)
  464. * 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
  465. * 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
  466. * regroup: x=i*(s1*c2*c3+c1*s2*s3)
  467. * y=j*(c1*s2*c3-s1*c2*s3)
  468. * z=k*(s1*s2*c3+c1*c2*s3)
  469. * s= c1*c2*c3-s1*s2*s3
  470. *
  471. * This implementation agrees with the functions found here:
  472. * http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions
  473. * And with the results in SL.
  474. *
  475. * It's also possible to calculate llEuler2Rot by direct multiplication of
  476. * the Qz, Qy, and Qx vectors (as above - and done in the "accurate" function
  477. * from the wiki).
  478. * Apparently in some cases this is better from a numerical precision perspective?
  479. */
  480. public LSL_Rotation llEuler2Rot(LSL_Vector v)
  481. {
  482. m_host.AddScriptLPS(1);
  483. double x,y,z,s;
  484. double c1 = Math.Cos(v.x * 0.5);
  485. double c2 = Math.Cos(v.y * 0.5);
  486. double c3 = Math.Cos(v.z * 0.5);
  487. double s1 = Math.Sin(v.x * 0.5);
  488. double s2 = Math.Sin(v.y * 0.5);
  489. double s3 = Math.Sin(v.z * 0.5);
  490. x = s1 * c2 * c3 + c1 * s2 * s3;
  491. y = c1 * s2 * c3 - s1 * c2 * s3;
  492. z = s1 * s2 * c3 + c1 * c2 * s3;
  493. s = c1 * c2 * c3 - s1 * s2 * s3;
  494. return new LSL_Rotation(x, y, z, s);
  495. }
  496. public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
  497. {
  498. m_host.AddScriptLPS(1);
  499. double s;
  500. double tr = fwd.x + left.y + up.z + 1.0;
  501. if (tr >= 1.0)
  502. {
  503. s = 0.5 / Math.Sqrt(tr);
  504. return new LSL_Rotation(
  505. (left.z - up.y) * s,
  506. (up.x - fwd.z) * s,
  507. (fwd.y - left.x) * s,
  508. 0.25 / s);
  509. }
  510. else
  511. {
  512. double max = (left.y > up.z) ? left.y : up.z;
  513. if (max < fwd.x)
  514. {
  515. s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0);
  516. double x = s * 0.5;
  517. s = 0.5 / s;
  518. return new LSL_Rotation(
  519. x,
  520. (fwd.y + left.x) * s,
  521. (up.x + fwd.z) * s,
  522. (left.z - up.y) * s);
  523. }
  524. else if (max == left.y)
  525. {
  526. s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0);
  527. double y = s * 0.5;
  528. s = 0.5 / s;
  529. return new LSL_Rotation(
  530. (fwd.y + left.x) * s,
  531. y,
  532. (left.z + up.y) * s,
  533. (up.x - fwd.z) * s);
  534. }
  535. else
  536. {
  537. s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0);
  538. double z = s * 0.5;
  539. s = 0.5 / s;
  540. return new LSL_Rotation(
  541. (up.x + fwd.z) * s,
  542. (left.z + up.y) * s,
  543. z,
  544. (fwd.y - left.x) * s);
  545. }
  546. }
  547. }
  548. public LSL_Vector llRot2Fwd(LSL_Rotation r)
  549. {
  550. m_host.AddScriptLPS(1);
  551. double x, y, z, m;
  552. m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
  553. // m is always greater than zero
  554. // if m is not equal to 1 then Rotation needs to be normalized
  555. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  556. {
  557. m = 1.0 / Math.Sqrt(m);
  558. r.x *= m;
  559. r.y *= m;
  560. r.z *= m;
  561. r.s *= m;
  562. }
  563. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  564. x = r.x * r.x - r.y * r.y - r.z * r.z + r.s * r.s;
  565. y = 2 * (r.x * r.y + r.z * r.s);
  566. z = 2 * (r.x * r.z - r.y * r.s);
  567. return (new LSL_Vector(x, y, z));
  568. }
  569. public LSL_Vector llRot2Left(LSL_Rotation r)
  570. {
  571. m_host.AddScriptLPS(1);
  572. double x, y, z, m;
  573. m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
  574. // m is always greater than zero
  575. // if m is not equal to 1 then Rotation needs to be normalized
  576. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  577. {
  578. m = 1.0 / Math.Sqrt(m);
  579. r.x *= m;
  580. r.y *= m;
  581. r.z *= m;
  582. r.s *= m;
  583. }
  584. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  585. x = 2 * (r.x * r.y - r.z * r.s);
  586. y = -r.x * r.x + r.y * r.y - r.z * r.z + r.s * r.s;
  587. z = 2 * (r.x * r.s + r.y * r.z);
  588. return (new LSL_Vector(x, y, z));
  589. }
  590. public LSL_Vector llRot2Up(LSL_Rotation r)
  591. {
  592. m_host.AddScriptLPS(1);
  593. double x, y, z, m;
  594. m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
  595. // m is always greater than zero
  596. // if m is not equal to 1 then Rotation needs to be normalized
  597. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  598. {
  599. m = 1.0 / Math.Sqrt(m);
  600. r.x *= m;
  601. r.y *= m;
  602. r.z *= m;
  603. r.s *= m;
  604. }
  605. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  606. x = 2 * (r.x * r.z + r.y * r.s);
  607. y = 2 * (-r.x * r.s + r.y * r.z);
  608. z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;
  609. return (new LSL_Vector(x, y, z));
  610. }
  611. public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
  612. {
  613. //A and B should both be normalized
  614. m_host.AddScriptLPS(1);
  615. double dotProduct = LSL_Vector.Dot(a, b);
  616. LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
  617. double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
  618. double angle = Math.Acos(dotProduct / magProduct);
  619. LSL_Vector axis = LSL_Vector.Norm(crossProduct);
  620. double s = Math.Sin(angle / 2);
  621. double x = axis.x * s;
  622. double y = axis.y * s;
  623. double z = axis.z * s;
  624. double w = Math.Cos(angle / 2);
  625. if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
  626. return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
  627. return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
  628. }
  629. public void llWhisper(int channelID, string text)
  630. {
  631. m_host.AddScriptLPS(1);
  632. if (text.Length > 1023)
  633. text = text.Substring(0, 1023);
  634. World.SimChat(Utils.StringToBytes(text),
  635. ChatTypeEnum.Whisper, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
  636. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  637. if (wComm != null)
  638. wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
  639. }
  640. public void llSay(int channelID, string text)
  641. {
  642. m_host.AddScriptLPS(1);
  643. if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
  644. {
  645. Console.WriteLine(text);
  646. }
  647. else
  648. {
  649. if (text.Length > 1023)
  650. text = text.Substring(0, 1023);
  651. World.SimChat(Utils.StringToBytes(text),
  652. ChatTypeEnum.Say, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, false);
  653. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  654. if (wComm != null)
  655. wComm.DeliverMessage(ChatTypeEnum.Say, channelID, m_host.Name, m_host.UUID, text);
  656. }
  657. }
  658. public void llShout(int channelID, string text)
  659. {
  660. m_host.AddScriptLPS(1);
  661. if (text.Length > 1023)
  662. text = text.Substring(0, 1023);
  663. World.SimChat(Utils.StringToBytes(text),
  664. ChatTypeEnum.Shout, channelID, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
  665. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  666. if (wComm != null)
  667. wComm.DeliverMessage(ChatTypeEnum.Shout, channelID, m_host.Name, m_host.UUID, text);
  668. }
  669. public void llRegionSay(int channelID, string text)
  670. {
  671. if (channelID == 0)
  672. {
  673. LSLError("Cannot use llRegionSay() on channel 0");
  674. return;
  675. }
  676. if (text.Length > 1023)
  677. text = text.Substring(0, 1023);
  678. m_host.AddScriptLPS(1);
  679. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  680. if (wComm != null)
  681. wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
  682. }
  683. public LSL_Integer llListen(int channelID, string name, string ID, string msg)
  684. {
  685. m_host.AddScriptLPS(1);
  686. UUID keyID;
  687. UUID.TryParse(ID, out keyID);
  688. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  689. if (wComm != null)
  690. return wComm.Listen(m_localID, m_itemID, m_host.UUID, channelID, name, keyID, msg);
  691. else
  692. return -1;
  693. }
  694. public void llListenControl(int number, int active)
  695. {
  696. m_host.AddScriptLPS(1);
  697. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  698. if (wComm != null)
  699. wComm.ListenControl(m_itemID, number, active);
  700. }
  701. public void llListenRemove(int number)
  702. {
  703. m_host.AddScriptLPS(1);
  704. IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
  705. if (wComm != null)
  706. wComm.ListenRemove(m_itemID, number);
  707. }
  708. public void llSensor(string name, string id, int type, double range, double arc)
  709. {
  710. m_host.AddScriptLPS(1);
  711. UUID keyID = UUID.Zero;
  712. UUID.TryParse(id, out keyID);
  713. AsyncCommands.SensorRepeatPlugin.SenseOnce(m_localID, m_itemID, name, keyID, type, range, arc, m_host);
  714. }
  715. public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate)
  716. {
  717. m_host.AddScriptLPS(1);
  718. UUID keyID = UUID.Zero;
  719. UUID.TryParse(id, out keyID);
  720. AsyncCommands.SensorRepeatPlugin.SetSenseRepeatEvent(m_localID, m_itemID, name, keyID, type, range, arc, rate, m_host);
  721. }
  722. public void llSensorRemove()
  723. {
  724. m_host.AddScriptLPS(1);
  725. AsyncCommands.SensorRepeatPlugin.UnSetSenseRepeaterEvents(m_localID, m_itemID);
  726. }
  727. public string resolveName(UUID objecUUID)
  728. {
  729. // try avatar username surname
  730. CachedUserInfo profile = World.CommsManager.UserProfileCacheService.GetUserDetails(objecUUID);
  731. if (profile != null && profile.UserProfile != null)
  732. {
  733. string avatarname = profile.UserProfile.FirstName + " " + profile.UserProfile.SurName;
  734. return avatarname;
  735. }
  736. // try an scene object
  737. SceneObjectPart SOP = World.GetSceneObjectPart(objecUUID);
  738. if (SOP != null)
  739. {
  740. string objectname = SOP.Name;
  741. return objectname;
  742. }
  743. EntityBase SensedObject;
  744. World.Entities.TryGetValue(objecUUID, out SensedObject);
  745. if (SensedObject == null)
  746. {
  747. IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
  748. if (groups != null)
  749. {
  750. GroupRecord gr = groups.GetGroupRecord(objecUUID);
  751. if (gr != null)
  752. return gr.GroupName;
  753. }
  754. return String.Empty;
  755. }
  756. return SensedObject.Name;
  757. }
  758. public LSL_String llDetectedName(int number)
  759. {
  760. m_host.AddScriptLPS(1);
  761. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  762. if (detectedParams == null)
  763. return String.Empty;
  764. return detectedParams.Name;
  765. }
  766. public LSL_String llDetectedKey(int number)
  767. {
  768. m_host.AddScriptLPS(1);
  769. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  770. if (detectedParams == null)
  771. return String.Empty;
  772. return detectedParams.Key.ToString();
  773. }
  774. public LSL_String llDetectedOwner(int number)
  775. {
  776. m_host.AddScriptLPS(1);
  777. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  778. if (detectedParams == null)
  779. return String.Empty;
  780. return detectedParams.Owner.ToString();
  781. }
  782. public LSL_Integer llDetectedType(int number)
  783. {
  784. m_host.AddScriptLPS(1);
  785. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  786. if (detectedParams == null)
  787. return 0;
  788. return new LSL_Integer(detectedParams.Type);
  789. }
  790. public LSL_Vector llDetectedPos(int number)
  791. {
  792. m_host.AddScriptLPS(1);
  793. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  794. if (detectedParams == null)
  795. return new LSL_Vector();
  796. return detectedParams.Position;
  797. }
  798. public LSL_Vector llDetectedVel(int number)
  799. {
  800. m_host.AddScriptLPS(1);
  801. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  802. if (detectedParams == null)
  803. return new LSL_Vector();
  804. return detectedParams.Velocity;
  805. }
  806. public LSL_Vector llDetectedGrab(int number)
  807. {
  808. m_host.AddScriptLPS(1);
  809. DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number);
  810. if (parms == null)
  811. return new LSL_Vector(0, 0, 0);
  812. return parms.OffsetPos;
  813. }
  814. public LSL_Rotation llDetectedRot(int number)
  815. {
  816. m_host.AddScriptLPS(1);
  817. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  818. if (detectedParams == null)
  819. return new LSL_Rotation();
  820. return detectedParams.Rotation;
  821. }
  822. public LSL_Integer llDetectedGroup(int number)
  823. {
  824. m_host.AddScriptLPS(1);
  825. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
  826. if (detectedParams == null)
  827. return new LSL_Integer(0);
  828. if (m_host.GroupID == detectedParams.Group)
  829. return new LSL_Integer(1);
  830. return new LSL_Integer(0);
  831. }
  832. public LSL_Integer llDetectedLinkNumber(int number)
  833. {
  834. m_host.AddScriptLPS(1);
  835. DetectParams parms = m_ScriptEngine.GetDetectParams(m_itemID, number);
  836. if (parms == null)
  837. return new LSL_Integer(0);
  838. return new LSL_Integer(parms.LinkNum);
  839. }
  840. /// <summary>
  841. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchBinormal for details
  842. /// </summary>
  843. public LSL_Vector llDetectedTouchBinormal(int index)
  844. {
  845. m_host.AddScriptLPS(1);
  846. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  847. if (detectedParams == null)
  848. return new LSL_Vector();
  849. return detectedParams.TouchBinormal;
  850. }
  851. /// <summary>
  852. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchFace for details
  853. /// </summary>
  854. public LSL_Integer llDetectedTouchFace(int index)
  855. {
  856. m_host.AddScriptLPS(1);
  857. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  858. if (detectedParams == null)
  859. return new LSL_Integer(-1);
  860. return new LSL_Integer(detectedParams.TouchFace);
  861. }
  862. /// <summary>
  863. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchNormal for details
  864. /// </summary>
  865. public LSL_Vector llDetectedTouchNormal(int index)
  866. {
  867. m_host.AddScriptLPS(1);
  868. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  869. if (detectedParams == null)
  870. return new LSL_Vector();
  871. return detectedParams.TouchNormal;
  872. }
  873. /// <summary>
  874. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchPos for details
  875. /// </summary>
  876. public LSL_Vector llDetectedTouchPos(int index)
  877. {
  878. m_host.AddScriptLPS(1);
  879. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  880. if (detectedParams == null)
  881. return new LSL_Vector();
  882. return detectedParams.TouchPos;
  883. }
  884. /// <summary>
  885. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchST for details
  886. /// </summary>
  887. public LSL_Vector llDetectedTouchST(int index)
  888. {
  889. m_host.AddScriptLPS(1);
  890. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  891. if (detectedParams == null)
  892. return new LSL_Vector(-1.0, -1.0, 0.0);
  893. return detectedParams.TouchST;
  894. }
  895. /// <summary>
  896. /// See http://wiki.secondlife.com/wiki/LlDetectedTouchUV for details
  897. /// </summary>
  898. public LSL_Vector llDetectedTouchUV(int index)
  899. {
  900. m_host.AddScriptLPS(1);
  901. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, index);
  902. if (detectedParams == null)
  903. return new LSL_Vector(-1.0, -1.0, 0.0);
  904. return detectedParams.TouchUV;
  905. }
  906. public virtual void llDie()
  907. {
  908. m_host.AddScriptLPS(1);
  909. throw new SelfDeleteException();
  910. }
  911. public LSL_Float llGround(LSL_Vector offset)
  912. {
  913. m_host.AddScriptLPS(1);
  914. Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x,
  915. (float)offset.y,
  916. (float)offset.z);
  917. //Get the slope normal. This gives us the equation of the plane tangent to the slope.
  918. LSL_Vector vsn = llGroundNormal(offset);
  919. // Clamp to valid position
  920. if (pos.X < 0)
  921. pos.X = 0;
  922. else if (pos.X >= World.Heightmap.Width)
  923. pos.X = World.Heightmap.Width - 1;
  924. if (pos.Y < 0)
  925. pos.Y = 0;
  926. else if (pos.Y >= World.Heightmap.Height)
  927. pos.Y = World.Heightmap.Height - 1;
  928. //Get the height for the integer coordinates from the Heightmap
  929. float baseheight = (float)World.Heightmap[(int)pos.X, (int)pos.Y];
  930. //Calculate the difference between the actual coordinates and the integer coordinates
  931. float xdiff = pos.X - (float)((int)pos.X);
  932. float ydiff = pos.Y - (float)((int)pos.Y);
  933. //Use the equation of the tangent plane to adjust the height to account for slope
  934. return (((vsn.x * xdiff) + (vsn.y * ydiff)) / (-1 * vsn.z)) + baseheight;
  935. }
  936. public LSL_Float llCloud(LSL_Vector offset)
  937. {
  938. m_host.AddScriptLPS(1);
  939. float cloudCover = 0f;
  940. ICloudModule module = World.RequestModuleInterface<ICloudModule>();
  941. if (module != null)
  942. {
  943. Vector3 pos = m_host.GetWorldPosition();
  944. int x = (int)(pos.X + offset.x);
  945. int y = (int)(pos.Y + offset.y);
  946. cloudCover = module.CloudCover(x, y, 0);
  947. }
  948. return cloudCover;
  949. }
  950. public LSL_Vector llWind(LSL_Vector offset)
  951. {
  952. m_host.AddScriptLPS(1);
  953. LSL_Vector wind = new LSL_Vector(0, 0, 0);
  954. IWindModule module = World.RequestModuleInterface<IWindModule>();
  955. if (module != null)
  956. {
  957. Vector3 pos = m_host.GetWorldPosition();
  958. int x = (int)(pos.X + offset.x);
  959. int y = (int)(pos.Y + offset.y);
  960. Vector3 windSpeed = module.WindSpeed(x, y, 0);
  961. wind.x = windSpeed.X;
  962. wind.y = windSpeed.Y;
  963. }
  964. return wind;
  965. }
  966. public void llSetStatus(int status, int value)
  967. {
  968. m_host.AddScriptLPS(1);
  969. int statusrotationaxis = 0;
  970. if ((status & ScriptBaseClass.STATUS_PHYSICS) == ScriptBaseClass.STATUS_PHYSICS)
  971. {
  972. if (value != 0)
  973. {
  974. SceneObjectGroup group = m_host.ParentGroup;
  975. if (group == null)
  976. return;
  977. bool allow = true;
  978. foreach (SceneObjectPart part in group.Children.Values)
  979. {
  980. if (part.Scale.X > World.m_maxPhys || part.Scale.Y > World.m_maxPhys || part.Scale.Z > World.m_maxPhys)
  981. {
  982. allow = false;
  983. break;
  984. }
  985. }
  986. if (!allow)
  987. return;
  988. m_host.ScriptSetPhysicsStatus(true);
  989. }
  990. else
  991. m_host.ScriptSetPhysicsStatus(false);
  992. }
  993. if ((status & ScriptBaseClass.STATUS_PHANTOM) == ScriptBaseClass.STATUS_PHANTOM)
  994. {
  995. if (value != 0)
  996. m_host.ScriptSetPhantomStatus(true);
  997. else
  998. m_host.ScriptSetPhantomStatus(false);
  999. }
  1000. if ((status & ScriptBaseClass.STATUS_CAST_SHADOWS) == ScriptBaseClass.STATUS_CAST_SHADOWS)
  1001. {
  1002. m_host.AddFlag(PrimFlags.CastShadows);
  1003. }
  1004. if ((status & ScriptBaseClass.STATUS_ROTATE_X) == ScriptBaseClass.STATUS_ROTATE_X)
  1005. {
  1006. statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_X;
  1007. }
  1008. if ((status & ScriptBaseClass.STATUS_ROTATE_Y) == ScriptBaseClass.STATUS_ROTATE_Y)
  1009. {
  1010. statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Y;
  1011. }
  1012. if ((status & ScriptBaseClass.STATUS_ROTATE_Z) == ScriptBaseClass.STATUS_ROTATE_Z)
  1013. {
  1014. statusrotationaxis |= ScriptBaseClass.STATUS_ROTATE_Z;
  1015. }
  1016. if ((status & ScriptBaseClass.STATUS_BLOCK_GRAB) == ScriptBaseClass.STATUS_BLOCK_GRAB)
  1017. {
  1018. if (value != 0)
  1019. m_host.SetBlockGrab(true);
  1020. else
  1021. m_host.SetBlockGrab(false);
  1022. }
  1023. if ((status & ScriptBaseClass.STATUS_DIE_AT_EDGE) == ScriptBaseClass.STATUS_DIE_AT_EDGE)
  1024. {
  1025. if (value != 0)
  1026. m_host.SetDieAtEdge(true);
  1027. else
  1028. m_host.SetDieAtEdge(false);
  1029. }
  1030. if ((status & ScriptBaseClass.STATUS_RETURN_AT_EDGE) == ScriptBaseClass.STATUS_RETURN_AT_EDGE)
  1031. {
  1032. if (value != 0)
  1033. m_host.SetReturnAtEdge(true);
  1034. else
  1035. m_host.SetReturnAtEdge(false);
  1036. }
  1037. if ((status & ScriptBaseClass.STATUS_SANDBOX) == ScriptBaseClass.STATUS_SANDBOX)
  1038. {
  1039. if (value != 0)
  1040. m_host.SetStatusSandbox(true);
  1041. else
  1042. m_host.SetStatusSandbox(false);
  1043. }
  1044. if (statusrotationaxis != 0)
  1045. {
  1046. m_host.SetAxisRotation(statusrotationaxis, value);
  1047. }
  1048. }
  1049. public LSL_Integer llGetStatus(int status)
  1050. {
  1051. m_host.AddScriptLPS(1);
  1052. // m_log.Debug(m_host.ToString() + " status is " + m_host.GetEffectiveObjectFlags().ToString());
  1053. switch (status)
  1054. {
  1055. case ScriptBaseClass.STATUS_PHYSICS:
  1056. if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) == (uint)PrimFlags.Physics)
  1057. {
  1058. return 1;
  1059. }
  1060. return 0;
  1061. case ScriptBaseClass.STATUS_PHANTOM:
  1062. if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) == (uint)PrimFlags.Phantom)
  1063. {
  1064. return 1;
  1065. }
  1066. return 0;
  1067. case ScriptBaseClass.STATUS_CAST_SHADOWS:
  1068. if ((m_host.GetEffectiveObjectFlags() & (uint)PrimFlags.CastShadows) == (uint)PrimFlags.CastShadows)
  1069. {
  1070. return 1;
  1071. }
  1072. return 0;
  1073. case ScriptBaseClass.STATUS_BLOCK_GRAB:
  1074. if (m_host.GetBlockGrab())
  1075. return 1;
  1076. else
  1077. return 0;
  1078. case ScriptBaseClass.STATUS_DIE_AT_EDGE:
  1079. if (m_host.GetDieAtEdge())
  1080. return 1;
  1081. else
  1082. return 0;
  1083. case ScriptBaseClass.STATUS_RETURN_AT_EDGE:
  1084. if (m_host.GetReturnAtEdge())
  1085. return 1;
  1086. else
  1087. return 0;
  1088. case ScriptBaseClass.STATUS_ROTATE_X:
  1089. if (m_host.GetAxisRotation(2) == 2)
  1090. return 1;
  1091. else
  1092. return 0;
  1093. case ScriptBaseClass.STATUS_ROTATE_Y:
  1094. if (m_host.GetAxisRotation(4) == 4)
  1095. return 1;
  1096. else
  1097. return 0;
  1098. case ScriptBaseClass.STATUS_ROTATE_Z:
  1099. if (m_host.GetAxisRotation(8) == 8)
  1100. return 1;
  1101. else
  1102. return 0;
  1103. case ScriptBaseClass.STATUS_SANDBOX:
  1104. if (m_host.GetStatusSandbox())
  1105. return 1;
  1106. else
  1107. return 0;
  1108. }
  1109. return 0;
  1110. }
  1111. public void llSetScale(LSL_Vector scale)
  1112. {
  1113. m_host.AddScriptLPS(1);
  1114. SetScale(m_host, scale);
  1115. }
  1116. protected void SetScale(SceneObjectPart part, LSL_Vector scale)
  1117. {
  1118. // TODO: this needs to trigger a persistance save as well
  1119. if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
  1120. return;
  1121. if (scale.x < 0.01)
  1122. scale.x = 0.01;
  1123. if (scale.y < 0.01)
  1124. scale.y = 0.01;
  1125. if (scale.z < 0.01)
  1126. scale.z = 0.01;
  1127. if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical)
  1128. {
  1129. if (scale.x > World.m_maxPhys)
  1130. scale.x = World.m_maxPhys;
  1131. if (scale.y > World.m_maxPhys)
  1132. scale.y = World.m_maxPhys;
  1133. if (scale.z > World.m_maxPhys)
  1134. scale.z = World.m_maxPhys;
  1135. }
  1136. if (scale.x > World.m_maxNonphys)
  1137. scale.x = World.m_maxNonphys;
  1138. if (scale.y > World.m_maxNonphys)
  1139. scale.y = World.m_maxNonphys;
  1140. if (scale.z > World.m_maxNonphys)
  1141. scale.z = World.m_maxNonphys;
  1142. Vector3 tmp = part.Scale;
  1143. tmp.X = (float)scale.x;
  1144. tmp.Y = (float)scale.y;
  1145. tmp.Z = (float)scale.z;
  1146. part.Scale = tmp;
  1147. part.SendFullUpdateToAllClients();
  1148. }
  1149. public LSL_Vector llGetScale()
  1150. {
  1151. m_host.AddScriptLPS(1);
  1152. return new LSL_Vector(m_host.Scale.X, m_host.Scale.Y, m_host.Scale.Z);
  1153. }
  1154. public void llSetClickAction(int action)
  1155. {
  1156. m_host.AddScriptLPS(1);
  1157. m_host.ClickAction = (byte)action;
  1158. if (m_host.ParentGroup != null) m_host.ParentGroup.HasGroupChanged = true;
  1159. m_host.ScheduleFullUpdate();
  1160. return;
  1161. }
  1162. public void llSetColor(LSL_Vector color, int face)
  1163. {
  1164. m_host.AddScriptLPS(1);
  1165. if (face == ScriptBaseClass.ALL_SIDES)
  1166. face = SceneObjectPart.ALL_SIDES;
  1167. m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
  1168. }
  1169. public void SetTexGen(SceneObjectPart part, int face,int style)
  1170. {
  1171. Primitive.TextureEntry tex = part.Shape.Textures;
  1172. MappingType textype;
  1173. textype = MappingType.Default;
  1174. if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR)
  1175. textype = MappingType.Planar;
  1176. if (face >= 0 && face < GetNumberOfSides(part))
  1177. {
  1178. tex.CreateFace((uint) face);
  1179. tex.FaceTextures[face].TexMapType = textype;

Large files files are truncated, but you can click here to view the full file