SOPObject.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  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.Generic;
  29. using System.Security;
  30. using OpenMetaverse;
  31. using OpenMetaverse.Packets;
  32. using OpenSim.Framework;
  33. using OpenSim.Region.Framework.Interfaces;
  34. using OpenSim.Region.Framework.Scenes;
  35. using OpenSim.Region.OptionalModules.Scripting.Minimodule.Object;
  36. using OpenSim.Region.Physics.Manager;
  37. using PrimType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.PrimType;
  38. using SculptType=OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType;
  39. namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
  40. {
  41. class SOPObject : MarshalByRefObject, IObject, IObjectPhysics, IObjectShape, IObjectSound
  42. {
  43. private readonly Scene m_rootScene;
  44. private readonly uint m_localID;
  45. private readonly ISecurityCredential m_security;
  46. [Obsolete("Replace with 'credential' constructor [security]")]
  47. public SOPObject(Scene rootScene, uint localID)
  48. {
  49. m_rootScene = rootScene;
  50. m_localID = localID;
  51. }
  52. public SOPObject(Scene rootScene, uint localID, ISecurityCredential credential)
  53. {
  54. m_rootScene = rootScene;
  55. m_localID = localID;
  56. m_security = credential;
  57. }
  58. /// <summary>
  59. /// This needs to run very, very quickly.
  60. /// It is utilized in nearly every property and method.
  61. /// </summary>
  62. /// <returns></returns>
  63. private SceneObjectPart GetSOP()
  64. {
  65. return m_rootScene.GetSceneObjectPart(m_localID);
  66. }
  67. private bool CanEdit()
  68. {
  69. if (!m_security.CanEditObject(this))
  70. {
  71. throw new SecurityException("Insufficient Permission to edit object with UUID [" + GetSOP().UUID + "]");
  72. }
  73. return true;
  74. }
  75. #region OnTouch
  76. private event OnTouchDelegate _OnTouch;
  77. private bool _OnTouchActive = false;
  78. public event OnTouchDelegate OnTouch
  79. {
  80. add
  81. {
  82. if (CanEdit())
  83. {
  84. if (!_OnTouchActive)
  85. {
  86. GetSOP().Flags |= PrimFlags.Touch;
  87. _OnTouchActive = true;
  88. m_rootScene.EventManager.OnObjectGrab += EventManager_OnObjectGrab;
  89. }
  90. _OnTouch += value;
  91. }
  92. }
  93. remove
  94. {
  95. _OnTouch -= value;
  96. if (_OnTouch == null)
  97. {
  98. GetSOP().Flags &= ~PrimFlags.Touch;
  99. _OnTouchActive = false;
  100. m_rootScene.EventManager.OnObjectGrab -= EventManager_OnObjectGrab;
  101. }
  102. }
  103. }
  104. void EventManager_OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
  105. {
  106. if (_OnTouchActive && m_localID == localID)
  107. {
  108. TouchEventArgs e = new TouchEventArgs();
  109. e.Avatar = new SPAvatar(m_rootScene, remoteClient.AgentId, m_security);
  110. e.TouchBiNormal = surfaceArgs.Binormal;
  111. e.TouchMaterialIndex = surfaceArgs.FaceIndex;
  112. e.TouchNormal = surfaceArgs.Normal;
  113. e.TouchPosition = surfaceArgs.Position;
  114. e.TouchST = new Vector2(surfaceArgs.STCoord.X, surfaceArgs.STCoord.Y);
  115. e.TouchUV = new Vector2(surfaceArgs.UVCoord.X, surfaceArgs.UVCoord.Y);
  116. IObject sender = this;
  117. if (_OnTouch != null)
  118. _OnTouch(sender, e);
  119. }
  120. }
  121. #endregion
  122. public bool Exists
  123. {
  124. get { return GetSOP() != null; }
  125. }
  126. public uint LocalID
  127. {
  128. get { return m_localID; }
  129. }
  130. public UUID GlobalID
  131. {
  132. get { return GetSOP().UUID; }
  133. }
  134. public string Name
  135. {
  136. get { return GetSOP().Name; }
  137. set
  138. {
  139. if (CanEdit())
  140. GetSOP().Name = value;
  141. }
  142. }
  143. public string Description
  144. {
  145. get { return GetSOP().Description; }
  146. set
  147. {
  148. if (CanEdit())
  149. GetSOP().Description = value;
  150. }
  151. }
  152. public UUID OwnerId
  153. {
  154. get { return GetSOP().OwnerID;}
  155. }
  156. public UUID CreatorId
  157. {
  158. get { return GetSOP().CreatorID;}
  159. }
  160. public IObject[] Children
  161. {
  162. get
  163. {
  164. SceneObjectPart my = GetSOP();
  165. IObject[] rets = null;
  166. int total = my.ParentGroup.PrimCount;
  167. rets = new IObject[total];
  168. int i = 0;
  169. foreach (SceneObjectPart part in my.ParentGroup.Parts)
  170. {
  171. rets[i++] = new SOPObject(m_rootScene, part.LocalId, m_security);
  172. }
  173. return rets;
  174. }
  175. }
  176. public IObject Root
  177. {
  178. get { return new SOPObject(m_rootScene, GetSOP().ParentGroup.RootPart.LocalId, m_security); }
  179. }
  180. public IObjectMaterial[] Materials
  181. {
  182. get
  183. {
  184. SceneObjectPart sop = GetSOP();
  185. IObjectMaterial[] rets = new IObjectMaterial[getNumberOfSides(sop)];
  186. for (int i = 0; i < rets.Length; i++)
  187. {
  188. rets[i] = new SOPObjectMaterial(i, sop);
  189. }
  190. return rets;
  191. }
  192. }
  193. public Vector3 Scale
  194. {
  195. get { return GetSOP().Scale; }
  196. set
  197. {
  198. if (CanEdit())
  199. GetSOP().Scale = value;
  200. }
  201. }
  202. public Quaternion WorldRotation
  203. {
  204. get { throw new System.NotImplementedException(); }
  205. set { throw new System.NotImplementedException(); }
  206. }
  207. public Quaternion OffsetRotation
  208. {
  209. get { throw new System.NotImplementedException(); }
  210. set { throw new System.NotImplementedException(); }
  211. }
  212. public Vector3 WorldPosition
  213. {
  214. get { return GetSOP().AbsolutePosition; }
  215. set
  216. {
  217. if (CanEdit())
  218. {
  219. SceneObjectPart pos = GetSOP();
  220. pos.UpdateOffSet(value - pos.AbsolutePosition);
  221. }
  222. }
  223. }
  224. public Vector3 OffsetPosition
  225. {
  226. get { return GetSOP().OffsetPosition; }
  227. set
  228. {
  229. if (CanEdit())
  230. {
  231. GetSOP().OffsetPosition = value;
  232. }
  233. }
  234. }
  235. public Vector3 SitTarget
  236. {
  237. get { return GetSOP().SitTargetPosition; }
  238. set
  239. {
  240. if (CanEdit())
  241. {
  242. GetSOP().SitTargetPosition = value;
  243. }
  244. }
  245. }
  246. public string SitTargetText
  247. {
  248. get { return GetSOP().SitName; }
  249. set
  250. {
  251. if (CanEdit())
  252. {
  253. GetSOP().SitName = value;
  254. }
  255. }
  256. }
  257. public string TouchText
  258. {
  259. get { return GetSOP().TouchName; }
  260. set
  261. {
  262. if (CanEdit())
  263. {
  264. GetSOP().TouchName = value;
  265. }
  266. }
  267. }
  268. public string Text
  269. {
  270. get { return GetSOP().Text; }
  271. set
  272. {
  273. if (CanEdit())
  274. {
  275. GetSOP().SetText(value,new Vector3(1.0f,1.0f,1.0f),1.0f);
  276. }
  277. }
  278. }
  279. public bool IsRotationLockedX
  280. {
  281. get { throw new System.NotImplementedException(); }
  282. set { throw new System.NotImplementedException(); }
  283. }
  284. public bool IsRotationLockedY
  285. {
  286. get { throw new System.NotImplementedException(); }
  287. set { throw new System.NotImplementedException(); }
  288. }
  289. public bool IsRotationLockedZ
  290. {
  291. get { throw new System.NotImplementedException(); }
  292. set { throw new System.NotImplementedException(); }
  293. }
  294. public bool IsSandboxed
  295. {
  296. get { throw new System.NotImplementedException(); }
  297. set { throw new System.NotImplementedException(); }
  298. }
  299. public bool IsImmotile
  300. {
  301. get { throw new System.NotImplementedException(); }
  302. set { throw new System.NotImplementedException(); }
  303. }
  304. public bool IsAlwaysReturned
  305. {
  306. get { throw new System.NotImplementedException(); }
  307. set { throw new System.NotImplementedException(); }
  308. }
  309. public bool IsTemporary
  310. {
  311. get { throw new System.NotImplementedException(); }
  312. set { throw new System.NotImplementedException(); }
  313. }
  314. public bool IsFlexible
  315. {
  316. get { throw new System.NotImplementedException(); }
  317. set { throw new System.NotImplementedException(); }
  318. }
  319. public PhysicsMaterial PhysicsMaterial
  320. {
  321. get { throw new System.NotImplementedException(); }
  322. set { throw new System.NotImplementedException(); }
  323. }
  324. public IObjectPhysics Physics
  325. {
  326. get { return this; }
  327. }
  328. public IObjectShape Shape
  329. {
  330. get { return this; }
  331. }
  332. public IObjectInventory Inventory
  333. {
  334. get { return new SOPObjectInventory(m_rootScene, GetSOP().TaskInventory); }
  335. }
  336. #region Public Functions
  337. public void Say(string msg)
  338. {
  339. if (!CanEdit())
  340. return;
  341. SceneObjectPart sop = GetSOP();
  342. m_rootScene.SimChat(msg, ChatTypeEnum.Say, sop.AbsolutePosition, sop.Name, sop.UUID, false);
  343. }
  344. public void Say(string msg,int channel)
  345. {
  346. if (!CanEdit())
  347. return;
  348. SceneObjectPart sop = GetSOP();
  349. m_rootScene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,channel, sop.AbsolutePosition, sop.Name, sop.UUID, false);
  350. }
  351. public void Dialog(UUID avatar, string message, string[] buttons, int chat_channel)
  352. {
  353. if (!CanEdit())
  354. return;
  355. IDialogModule dm = m_rootScene.RequestModuleInterface<IDialogModule>();
  356. if (dm == null)
  357. return;
  358. if (buttons.Length < 1)
  359. {
  360. Say("ERROR: No less than 1 button can be shown",2147483647);
  361. return;
  362. }
  363. if (buttons.Length > 12)
  364. {
  365. Say("ERROR: No more than 12 buttons can be shown",2147483647);
  366. return;
  367. }
  368. foreach (string button in buttons)
  369. {
  370. if (button == String.Empty)
  371. {
  372. Say("ERROR: button label cannot be blank",2147483647);
  373. return;
  374. }
  375. if (button.Length > 24)
  376. {
  377. Say("ERROR: button label cannot be longer than 24 characters",2147483647);
  378. return;
  379. }
  380. }
  381. dm.SendDialogToUser(
  382. avatar, GetSOP().Name, GetSOP().UUID, GetSOP().OwnerID,
  383. message, new UUID("00000000-0000-2222-3333-100000001000"), chat_channel, buttons);
  384. }
  385. #endregion
  386. #region Supporting Functions
  387. // Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
  388. private static void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
  389. out bool hasDimple, out bool hasProfileCut)
  390. {
  391. if (primType == (int)PrimType.Box
  392. ||
  393. primType == (int)PrimType.Cylinder
  394. ||
  395. primType == (int)PrimType.Prism)
  396. hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
  397. else
  398. hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
  399. hasHollow = shape.ProfileHollow > 0;
  400. hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
  401. hasProfileCut = hasDimple; // is it the same thing?
  402. }
  403. private static int getScriptPrimType(PrimitiveBaseShape primShape)
  404. {
  405. if (primShape.SculptEntry)
  406. return (int) PrimType.Sculpt;
  407. if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square)
  408. {
  409. if (primShape.PathCurve == (byte) Extrusion.Straight)
  410. return (int) PrimType.Box;
  411. if (primShape.PathCurve == (byte) Extrusion.Curve1)
  412. return (int) PrimType.Tube;
  413. }
  414. else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Circle)
  415. {
  416. if (primShape.PathCurve == (byte) Extrusion.Straight)
  417. return (int) PrimType.Cylinder;
  418. if (primShape.PathCurve == (byte) Extrusion.Curve1)
  419. return (int) PrimType.Torus;
  420. }
  421. else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.HalfCircle)
  422. {
  423. if (primShape.PathCurve == (byte) Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2)
  424. return (int) PrimType.Sphere;
  425. }
  426. else if ((primShape.ProfileCurve & 0x07) == (byte) ProfileShape.EquilateralTriangle)
  427. {
  428. if (primShape.PathCurve == (byte) Extrusion.Straight)
  429. return (int) PrimType.Prism;
  430. if (primShape.PathCurve == (byte) Extrusion.Curve1)
  431. return (int) PrimType.Ring;
  432. }
  433. return (int) PrimType.NotPrimitive;
  434. }
  435. private static int getNumberOfSides(SceneObjectPart part)
  436. {
  437. int ret;
  438. bool hasCut;
  439. bool hasHollow;
  440. bool hasDimple;
  441. bool hasProfileCut;
  442. int primType = getScriptPrimType(part.Shape);
  443. hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
  444. switch (primType)
  445. {
  446. default:
  447. case (int) PrimType.Box:
  448. ret = 6;
  449. if (hasCut) ret += 2;
  450. if (hasHollow) ret += 1;
  451. break;
  452. case (int) PrimType.Cylinder:
  453. ret = 3;
  454. if (hasCut) ret += 2;
  455. if (hasHollow) ret += 1;
  456. break;
  457. case (int) PrimType.Prism:
  458. ret = 5;
  459. if (hasCut) ret += 2;
  460. if (hasHollow) ret += 1;
  461. break;
  462. case (int) PrimType.Sphere:
  463. ret = 1;
  464. if (hasCut) ret += 2;
  465. if (hasDimple) ret += 2;
  466. if (hasHollow)
  467. ret += 1; // GOTCHA: LSL shows 2 additional sides here.
  468. // This has been fixed, but may cause porting issues.
  469. break;
  470. case (int) PrimType.Torus:
  471. ret = 1;
  472. if (hasCut) ret += 2;
  473. if (hasProfileCut) ret += 2;
  474. if (hasHollow) ret += 1;
  475. break;
  476. case (int) PrimType.Tube:
  477. ret = 4;
  478. if (hasCut) ret += 2;
  479. if (hasProfileCut) ret += 2;
  480. if (hasHollow) ret += 1;
  481. break;
  482. case (int) PrimType.Ring:
  483. ret = 3;
  484. if (hasCut) ret += 2;
  485. if (hasProfileCut) ret += 2;
  486. if (hasHollow) ret += 1;
  487. break;
  488. case (int) PrimType.Sculpt:
  489. ret = 1;
  490. break;
  491. }
  492. return ret;
  493. }
  494. #endregion
  495. #region IObjectPhysics
  496. public bool Enabled
  497. {
  498. get { throw new System.NotImplementedException(); }
  499. set { throw new System.NotImplementedException(); }
  500. }
  501. public bool Phantom
  502. {
  503. get { throw new System.NotImplementedException(); }
  504. set { throw new System.NotImplementedException(); }
  505. }
  506. public bool PhantomCollisions
  507. {
  508. get { throw new System.NotImplementedException(); }
  509. set { throw new System.NotImplementedException(); }
  510. }
  511. public double Density
  512. {
  513. get { return (GetSOP().PhysActor.Mass/Scale.X*Scale.Y/Scale.Z); }
  514. set { throw new NotImplementedException(); }
  515. }
  516. public double Mass
  517. {
  518. get { return GetSOP().PhysActor.Mass; }
  519. set { throw new NotImplementedException(); }
  520. }
  521. public double Buoyancy
  522. {
  523. get { return GetSOP().PhysActor.Buoyancy; }
  524. set { GetSOP().PhysActor.Buoyancy = (float)value; }
  525. }
  526. public Vector3 GeometricCenter
  527. {
  528. get
  529. {
  530. Vector3 tmp = GetSOP().PhysActor.GeometricCenter;
  531. return tmp;
  532. }
  533. }
  534. public Vector3 CenterOfMass
  535. {
  536. get
  537. {
  538. Vector3 tmp = GetSOP().PhysActor.CenterOfMass;
  539. return tmp;
  540. }
  541. }
  542. public Vector3 RotationalVelocity
  543. {
  544. get
  545. {
  546. Vector3 tmp = GetSOP().PhysActor.RotationalVelocity;
  547. return tmp;
  548. }
  549. set
  550. {
  551. if (!CanEdit())
  552. return;
  553. GetSOP().PhysActor.RotationalVelocity = value;
  554. }
  555. }
  556. public Vector3 Velocity
  557. {
  558. get
  559. {
  560. Vector3 tmp = GetSOP().PhysActor.Velocity;
  561. return tmp;
  562. }
  563. set
  564. {
  565. if (!CanEdit())
  566. return;
  567. GetSOP().PhysActor.Velocity = value;
  568. }
  569. }
  570. public Vector3 Torque
  571. {
  572. get
  573. {
  574. Vector3 tmp = GetSOP().PhysActor.Torque;
  575. return tmp;
  576. }
  577. set
  578. {
  579. if (!CanEdit())
  580. return;
  581. GetSOP().PhysActor.Torque = value;
  582. }
  583. }
  584. public Vector3 Acceleration
  585. {
  586. get
  587. {
  588. Vector3 tmp = GetSOP().PhysActor.Acceleration;
  589. return tmp;
  590. }
  591. }
  592. public Vector3 Force
  593. {
  594. get
  595. {
  596. Vector3 tmp = GetSOP().PhysActor.Force;
  597. return tmp;
  598. }
  599. set
  600. {
  601. if (!CanEdit())
  602. return;
  603. GetSOP().PhysActor.Force = value;
  604. }
  605. }
  606. public bool FloatOnWater
  607. {
  608. set
  609. {
  610. if (!CanEdit())
  611. return;
  612. GetSOP().PhysActor.FloatOnWater = value;
  613. }
  614. }
  615. public void AddForce(Vector3 force, bool pushforce)
  616. {
  617. if (!CanEdit())
  618. return;
  619. GetSOP().PhysActor.AddForce(force, pushforce);
  620. }
  621. public void AddAngularForce(Vector3 force, bool pushforce)
  622. {
  623. if (!CanEdit())
  624. return;
  625. GetSOP().PhysActor.AddAngularForce(force, pushforce);
  626. }
  627. public void SetMomentum(Vector3 momentum)
  628. {
  629. if (!CanEdit())
  630. return;
  631. GetSOP().PhysActor.SetMomentum(momentum);
  632. }
  633. #endregion
  634. #region Implementation of IObjectShape
  635. private UUID m_sculptMap = UUID.Zero;
  636. public UUID SculptMap
  637. {
  638. get { return m_sculptMap; }
  639. set
  640. {
  641. if (!CanEdit())
  642. return;
  643. m_sculptMap = value;
  644. SetPrimitiveSculpted(SculptMap, (byte) SculptType);
  645. }
  646. }
  647. private SculptType m_sculptType = Object.SculptType.Default;
  648. public SculptType SculptType
  649. {
  650. get { return m_sculptType; }
  651. set
  652. {
  653. if (!CanEdit())
  654. return;
  655. m_sculptType = value;
  656. SetPrimitiveSculpted(SculptMap, (byte) SculptType);
  657. }
  658. }
  659. public HoleShape HoleType
  660. {
  661. get { throw new System.NotImplementedException(); }
  662. set { throw new System.NotImplementedException(); }
  663. }
  664. public double HoleSize
  665. {
  666. get { throw new System.NotImplementedException(); }
  667. set { throw new System.NotImplementedException(); }
  668. }
  669. public PrimType PrimType
  670. {
  671. get { return (PrimType)getScriptPrimType(GetSOP().Shape); }
  672. set { throw new System.NotImplementedException(); }
  673. }
  674. private void SetPrimitiveSculpted(UUID map, byte type)
  675. {
  676. ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
  677. SceneObjectPart part = GetSOP();
  678. UUID sculptId = map;
  679. shapeBlock.ObjectLocalID = part.LocalId;
  680. shapeBlock.PathScaleX = 100;
  681. shapeBlock.PathScaleY = 150;
  682. // retain pathcurve
  683. shapeBlock.PathCurve = part.Shape.PathCurve;
  684. part.Shape.SetSculptProperties((byte)type, sculptId);
  685. part.Shape.SculptEntry = true;
  686. part.UpdateShape(shapeBlock);
  687. }
  688. #endregion
  689. #region Implementation of IObjectSound
  690. public IObjectSound Sound
  691. {
  692. get { return this; }
  693. }
  694. public void Play(UUID asset, double volume)
  695. {
  696. if (!CanEdit())
  697. return;
  698. GetSOP().SendSound(asset.ToString(), volume, true, 0, 0, false, false);
  699. }
  700. #endregion
  701. }
  702. }