aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs516
1 files changed, 260 insertions, 256 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index ba41499..33e34fb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1928,7 +1928,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1928 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent"); 1928 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent");
1929 if (userAgent.IndexOf("SecondLife") < 0) 1929 if (userAgent.IndexOf("SecondLife") < 0)
1930 return; // Not the embedded browser. Is this check good enough? 1930 return; // Not the embedded browser. Is this check good enough?
1931 1931
1932 // Use the IP address of the client and check against the request 1932 // Use the IP address of the client and check against the request
1933 // seperate logins from the same IP will allow all of them to get non-text/plain as long 1933 // seperate logins from the same IP will allow all of them to get non-text/plain as long
1934 // as the owner is in the region. Same as SL! 1934 // as the owner is in the region. Same as SL!
@@ -2174,9 +2174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2174 foreach (SceneObjectPart part in parts) 2174 foreach (SceneObjectPart part in parts)
2175 SetAlpha(part, alpha, face); 2175 SetAlpha(part, alpha, face);
2176 } 2176 }
2177 finally 2177 finally { }
2178 {
2179 }
2180 } 2178 }
2181 } 2179 }
2182 2180
@@ -2366,10 +2364,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2366 foreach (SceneObjectPart part in parts) 2364 foreach (SceneObjectPart part in parts)
2367 SetTexture(part, texture, face); 2365 SetTexture(part, texture, face);
2368 } 2366 }
2369 finally 2367 finally { }
2370 { 2368 }
2371 }
2372 }
2373 ScriptSleep(m_sleepMsOnSetLinkTexture); 2369 ScriptSleep(m_sleepMsOnSetLinkTexture);
2374 } 2370 }
2375 2371
@@ -2736,13 +2732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2736 public void llSetRot(LSL_Rotation rot) 2732 public void llSetRot(LSL_Rotation rot)
2737 { 2733 {
2738 m_host.AddScriptLPS(1); 2734 m_host.AddScriptLPS(1);
2739 2735
2740
2741 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2742 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2743 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2744 // RootPart != null should shortcircuit
2745
2746 // try to let this work as in SL... 2736 // try to let this work as in SL...
2747 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart)) 2737 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2748 { 2738 {
@@ -2781,7 +2771,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2781 2771
2782 // keep using physactor ideia of isphysical 2772 // keep using physactor ideia of isphysical
2783 // it should be SOP ideia of that 2773 // it should be SOP ideia of that
2784 // not much of a issue with ubitODE 2774 // not much of a issue with ubOde
2785 if (pa != null && pa.IsPhysical) 2775 if (pa != null && pa.IsPhysical)
2786 isphys = true; 2776 isphys = true;
2787 else 2777 else
@@ -2923,6 +2913,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2923 return force; 2913 return force;
2924 } 2914 }
2925 2915
2916 public void llSetVelocity(LSL_Vector vel, int local)
2917 {
2918 m_host.AddScriptLPS(1);
2919 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2920 }
2921
2922 public void llSetAngularVelocity(LSL_Vector avel, int local)
2923 {
2924 m_host.AddScriptLPS(1);
2925 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2926 }
2926 public LSL_Integer llTarget(LSL_Vector position, double range) 2927 public LSL_Integer llTarget(LSL_Vector position, double range)
2927 { 2928 {
2928 m_host.AddScriptLPS(1); 2929 m_host.AddScriptLPS(1);
@@ -3000,11 +3001,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3000 llSetTorque(torque, local); 3001 llSetTorque(torque, local);
3001 } 3002 }
3002 3003
3003 public void llSetVelocity(LSL_Vector vel, int local)
3004 {
3005 m_host.AddScriptLPS(1);
3006 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
3007 }
3008 3004
3009 public LSL_Vector llGetVel() 3005 public LSL_Vector llGetVel()
3010 { 3006 {
@@ -3033,12 +3029,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3033 return new LSL_Vector(m_host.Acceleration); 3029 return new LSL_Vector(m_host.Acceleration);
3034 } 3030 }
3035 3031
3036 public void llSetAngularVelocity(LSL_Vector avel, int local)
3037 {
3038 m_host.AddScriptLPS(1);
3039 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
3040 }
3041
3042 public LSL_Vector llGetOmega() 3032 public LSL_Vector llGetOmega()
3043 { 3033 {
3044 m_host.AddScriptLPS(1); 3034 m_host.AddScriptLPS(1);
@@ -3700,6 +3690,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3700 { 3690 {
3701 // Unregister controls from Presence 3691 // Unregister controls from Presence
3702 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3692 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3693 // Remove Take Control permission.
3694 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3703 } 3695 }
3704 } 3696 }
3705 } 3697 }
@@ -4289,9 +4281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4289 foreach (SceneObjectPart part in parts) 4281 foreach (SceneObjectPart part in parts)
4290 part.SetFaceColorAlpha(face, color, null); 4282 part.SetFaceColorAlpha(face, color, null);
4291 } 4283 }
4292 finally 4284 finally { }
4293 {
4294 }
4295 } 4285 }
4296 } 4286 }
4297 4287
@@ -4428,10 +4418,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4428 parentPrim.DelinkFromGroup(part.LocalId, true); 4418 parentPrim.DelinkFromGroup(part.LocalId, true);
4429 } 4419 }
4430 } 4420 }
4431 finally 4421 finally { }
4432 { 4422 }
4433 }
4434 }
4435 4423
4436 parentPrim.HasGroupChanged = true; 4424 parentPrim.HasGroupChanged = true;
4437 parentPrim.ScheduleGroupForFullUpdate(); 4425 parentPrim.ScheduleGroupForFullUpdate();
@@ -4450,10 +4438,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4450 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4438 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4451 } 4439 }
4452 } 4440 }
4453 finally 4441 finally { }
4454 {
4455 }
4456
4457 4442
4458 newRoot.ParentGroup.HasGroupChanged = true; 4443 newRoot.ParentGroup.HasGroupChanged = true;
4459 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4444 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
@@ -4847,24 +4832,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4847 4832
4848 switch (data) 4833 switch (data)
4849 { 4834 {
4850 case 1: // DATA_ONLINE (0|1) 4835 case ScriptBaseClass.DATA_ONLINE: // DATA_ONLINE (0|1)
4851 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4836 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4852 reply = "1"; 4837 reply = "1";
4853 else 4838 else
4854 reply = "0"; 4839 reply = "0";
4855 break; 4840 break;
4856 case 2: // DATA_NAME (First Last) 4841 case ScriptBaseClass.DATA_NAME: // DATA_NAME (First Last)
4857 reply = account.FirstName + " " + account.LastName; 4842 reply = account.FirstName + " " + account.LastName;
4858 break; 4843 break;
4859 case 3: // DATA_BORN (YYYY-MM-DD) 4844 case ScriptBaseClass.DATA_BORN: // DATA_BORN (YYYY-MM-DD)
4860 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4845 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4861 born = born.AddSeconds(account.Created); 4846 born = born.AddSeconds(account.Created);
4862 reply = born.ToString("yyyy-MM-dd"); 4847 reply = born.ToString("yyyy-MM-dd");
4863 break; 4848 break;
4864 case 4: // DATA_RATING (0,0,0,0,0,0) 4849 case ScriptBaseClass.DATA_RATING: // DATA_RATING (0,0,0,0,0,0)
4865 reply = "0,0,0,0,0,0"; 4850 reply = "0,0,0,0,0,0";
4866 break; 4851 break;
4867 case 8: // DATA_PAYINFO (0|1|2|3) 4852 case 7: // DATA_USERLEVEL (integer). This is not available in LL and so has no constant.
4853 reply = account.UserLevel.ToString();
4854 break;
4855 case ScriptBaseClass.DATA_PAYINFO: // DATA_PAYINFO (0|1|2|3)
4868 reply = "0"; 4856 reply = "0";
4869 break; 4857 break;
4870 default: 4858 default:
@@ -5025,22 +5013,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5025 5013
5026 ScenePresence presence = World.GetScenePresence(agentId); 5014 ScenePresence presence = World.GetScenePresence(agentId);
5027 5015
5016 if (presence == null || presence.PresenceType == PresenceType.Npc)
5017 return;
5018
5028 // Can't TP sitting avatars 5019 // Can't TP sitting avatars
5029 if (presence.ParentID != 0) // Sitting 5020 if (presence.ParentID != 0) // Sitting
5030 return; 5021 return;
5031 5022
5032 if (presence != null && presence.PresenceType != PresenceType.Npc) 5023 if (m_item.PermsGranter == agentId)
5033 { 5024 {
5034 if (m_item.PermsGranter == agentId) 5025 // If attached using llAttachToAvatarTemp, cowardly refuse
5035 { 5026 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
5036 // If attached using llAttachToAvatarTemp, cowardly refuse 5027 return;
5037 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
5038 return;
5039 5028
5040 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0) 5029 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
5041 { 5030 {
5042 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 5031 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
5043 }
5044 } 5032 }
5045 } 5033 }
5046 } 5034 }
@@ -8583,6 +8571,142 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8583 } 8571 }
8584 } 8572 }
8585 8573
8574 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
8575 {
8576 SceneObjectGroup group = m_host.ParentGroup;
8577
8578 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
8579 return;
8580 if (group.IsAttachment)
8581 return;
8582
8583 if (frames.Data.Length > 0) // We are getting a new motion
8584 {
8585 if (group.RootPart.KeyframeMotion != null)
8586 group.RootPart.KeyframeMotion.Delete();
8587 group.RootPart.KeyframeMotion = null;
8588
8589 int idx = 0;
8590
8591 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
8592 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
8593
8594 while (idx < options.Data.Length)
8595 {
8596 int option = (int)options.GetLSLIntegerItem(idx++);
8597 int remain = options.Data.Length - idx;
8598
8599 switch (option)
8600 {
8601 case ScriptBaseClass.KFM_MODE:
8602 if (remain < 1)
8603 break;
8604 int modeval = (int)options.GetLSLIntegerItem(idx++);
8605 switch(modeval)
8606 {
8607 case ScriptBaseClass.KFM_FORWARD:
8608 mode = KeyframeMotion.PlayMode.Forward;
8609 break;
8610 case ScriptBaseClass.KFM_REVERSE:
8611 mode = KeyframeMotion.PlayMode.Reverse;
8612 break;
8613 case ScriptBaseClass.KFM_LOOP:
8614 mode = KeyframeMotion.PlayMode.Loop;
8615 break;
8616 case ScriptBaseClass.KFM_PING_PONG:
8617 mode = KeyframeMotion.PlayMode.PingPong;
8618 break;
8619 }
8620 break;
8621 case ScriptBaseClass.KFM_DATA:
8622 if (remain < 1)
8623 break;
8624 int dataval = (int)options.GetLSLIntegerItem(idx++);
8625 data = (KeyframeMotion.DataFormat)dataval;
8626 break;
8627 }
8628 }
8629
8630 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
8631
8632 idx = 0;
8633
8634 int elemLength = 2;
8635 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
8636 elemLength = 3;
8637
8638 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
8639 while (idx < frames.Data.Length)
8640 {
8641 int remain = frames.Data.Length - idx;
8642
8643 if (remain < elemLength)
8644 break;
8645
8646 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
8647 frame.Position = null;
8648 frame.Rotation = null;
8649
8650 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
8651 {
8652 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
8653 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
8654 }
8655 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
8656 {
8657 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
8658 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
8659 q.Normalize();
8660 frame.Rotation = q;
8661 }
8662
8663 float tempf = (float)frames.GetLSLFloatItem(idx++);
8664 frame.TimeMS = (int)(tempf * 1000.0f);
8665
8666 keyframes.Add(frame);
8667 }
8668
8669 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
8670 group.RootPart.KeyframeMotion.Start();
8671 }
8672 else
8673 {
8674 if (group.RootPart.KeyframeMotion == null)
8675 return;
8676
8677 if (options.Data.Length == 0)
8678 {
8679 group.RootPart.KeyframeMotion.Stop();
8680 return;
8681 }
8682
8683 int idx = 0;
8684
8685 while (idx < options.Data.Length)
8686 {
8687 int option = (int)options.GetLSLIntegerItem(idx++);
8688
8689 switch (option)
8690 {
8691 case ScriptBaseClass.KFM_COMMAND:
8692 int cmd = (int)options.GetLSLIntegerItem(idx++);
8693 switch (cmd)
8694 {
8695 case ScriptBaseClass.KFM_CMD_PLAY:
8696 group.RootPart.KeyframeMotion.Start();
8697 break;
8698 case ScriptBaseClass.KFM_CMD_STOP:
8699 group.RootPart.KeyframeMotion.Stop();
8700 break;
8701 case ScriptBaseClass.KFM_CMD_PAUSE:
8702 group.RootPart.KeyframeMotion.Pause();
8703 break;
8704 }
8705 break;
8706 }
8707 }
8708 }
8709 }
8586 8710
8587 public LSL_List llGetPhysicsMaterial() 8711 public LSL_List llGetPhysicsMaterial()
8588 { 8712 {
@@ -8682,7 +8806,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8682 if (remain < 1) 8806 if (remain < 1)
8683 return new LSL_List(); 8807 return new LSL_List();
8684 8808
8685 v=rules.GetVector3Item(idx++); 8809 try
8810 {
8811 v = rules.GetVector3Item(idx++);
8812 }
8813 catch(InvalidCastException)
8814 {
8815 if(code == ScriptBaseClass.PRIM_POSITION)
8816 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POSITION: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1));
8817 else
8818 Error(originFunc, string.Format("Error running rule #{0} -> PRIM_POS_LOCAL: arg #{1} - parameter 1 must be vector", rulesParsed, idx - idxStart - 1));
8819 return new LSL_List();
8820 }
8686 if (part.IsRoot && !part.ParentGroup.IsAttachment) 8821 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8687 currentPosition = GetSetPosTarget(part, v, currentPosition, true); 8822 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8688 else 8823 else
@@ -10444,6 +10579,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10444 return result; 10579 return result;
10445 } 10580 }
10446 10581
10582 /// <summary>
10583 /// Helper to calculate bounding box of an avatar.
10584 /// </summary>
10585 private void BoundingBoxOfScenePresence(ScenePresence sp, out Vector3 lower, out Vector3 upper)
10586 {
10587 // Adjust from OS model
10588 // avatar height = visual height - 0.2, bounding box height = visual height
10589 // to SL model
10590 // avatar height = visual height, bounding box height = visual height + 0.2
10591 float height = sp.Appearance.AvatarHeight + m_avatarHeightCorrection;
10592
10593 // According to avatar bounding box in SL 2015-04-18:
10594 // standing = <-0.275,-0.35,-0.1-0.5*h> : <0.275,0.35,0.1+0.5*h>
10595 // groundsitting = <-0.3875,-0.5,-0.05-0.375*h> : <0.3875,0.5,0.5>
10596 // sitting = <-0.5875,-0.35,-0.35-0.375*h> : <0.1875,0.35,-0.25+0.25*h>
10597
10598 // When avatar is sitting
10599 if (sp.ParentPart != null)
10600 {
10601 lower = new Vector3(m_lABB1SitX0, m_lABB1SitY0, m_lABB1SitZ0 + m_lABB1SitZ1 * height);
10602 upper = new Vector3(m_lABB2SitX0, m_lABB2SitY0, m_lABB2SitZ0 + m_lABB2SitZ1 * height);
10603 }
10604 // When avatar is groundsitting
10605 else if (sp.Animator.Animations.ImplicitDefaultAnimation.AnimID == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
10606 {
10607 lower = new Vector3(m_lABB1GrsX0, m_lABB1GrsY0, m_lABB1GrsZ0 + m_lABB1GrsZ1 * height);
10608 upper = new Vector3(m_lABB2GrsX0, m_lABB2GrsY0, m_lABB2GrsZ0 + m_lABB2GrsZ1 * height);
10609 }
10610 // When avatar is standing or flying
10611 else
10612 {
10613 lower = new Vector3(m_lABB1StdX0, m_lABB1StdY0, m_lABB1StdZ0 + m_lABB1StdZ1 * height);
10614 upper = new Vector3(m_lABB2StdX0, m_lABB2StdY0, m_lABB2StdZ0 + m_lABB2StdZ1 * height);
10615 }
10616 }
10617
10618
10447 public LSL_Vector llGetGeometricCenter() 10619 public LSL_Vector llGetGeometricCenter()
10448 { 10620 {
10449 return new LSL_Vector(m_host.GetGeometricCenter()); 10621 return new LSL_Vector(m_host.GetGeometricCenter());
@@ -10560,6 +10732,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10560 res.Add(GetPartRot(part)); 10732 res.Add(GetPartRot(part));
10561 break; 10733 break;
10562 10734
10735 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
10736 res.Add(new LSL_Integer((int)part.PhysicsShapeType));
10737 break;
10738
10563 case (int)ScriptBaseClass.PRIM_TYPE: 10739 case (int)ScriptBaseClass.PRIM_TYPE:
10564 // implementing box 10740 // implementing box
10565 PrimitiveBaseShape Shape = part.Shape; 10741 PrimitiveBaseShape Shape = part.Shape;
@@ -12116,17 +12292,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12116 int width = 0; 12292 int width = 0;
12117 int height = 0; 12293 int height = 0;
12118 12294
12119 uint commandToSend = 0; 12295 ParcelMediaCommandEnum? commandToSend = null;
12120 float time = 0.0f; // default is from start 12296 float time = 0.0f; // default is from start
12121 12297
12122 ScenePresence presence = null; 12298 ScenePresence presence = null;
12123 12299
12124 for (int i = 0; i < commandList.Data.Length; i++) 12300 for (int i = 0; i < commandList.Data.Length; i++)
12125 { 12301 {
12126 uint command = (uint)(commandList.GetLSLIntegerItem(i)); 12302 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i];
12127 switch (command) 12303 switch (command)
12128 { 12304 {
12129 case (uint)ParcelMediaCommandEnum.Agent: 12305 case ParcelMediaCommandEnum.Agent:
12130 // we send only to one agent 12306 // we send only to one agent
12131 if ((i + 1) < commandList.Length) 12307 if ((i + 1) < commandList.Length)
12132 { 12308 {
@@ -12143,25 +12319,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12143 } 12319 }
12144 break; 12320 break;
12145 12321
12146 case (uint)ParcelMediaCommandEnum.Loop: 12322 case ParcelMediaCommandEnum.Loop:
12147 loop = 1; 12323 loop = 1;
12148 commandToSend = command; 12324 commandToSend = command;
12149 update = true; //need to send the media update packet to set looping 12325 update = true; //need to send the media update packet to set looping
12150 break; 12326 break;
12151 12327
12152 case (uint)ParcelMediaCommandEnum.Play: 12328 case ParcelMediaCommandEnum.Play:
12153 loop = 0; 12329 loop = 0;
12154 commandToSend = command; 12330 commandToSend = command;
12155 update = true; //need to send the media update packet to make sure it doesn't loop 12331 update = true; //need to send the media update packet to make sure it doesn't loop
12156 break; 12332 break;
12157 12333
12158 case (uint)ParcelMediaCommandEnum.Pause: 12334 case ParcelMediaCommandEnum.Pause:
12159 case (uint)ParcelMediaCommandEnum.Stop: 12335 case ParcelMediaCommandEnum.Stop:
12160 case (uint)ParcelMediaCommandEnum.Unload: 12336 case ParcelMediaCommandEnum.Unload:
12161 commandToSend = command; 12337 commandToSend = command;
12162 break; 12338 break;
12163 12339
12164 case (uint)ParcelMediaCommandEnum.Url: 12340 case ParcelMediaCommandEnum.Url:
12165 if ((i + 1) < commandList.Length) 12341 if ((i + 1) < commandList.Length)
12166 { 12342 {
12167 if (commandList.Data[i + 1] is LSL_String) 12343 if (commandList.Data[i + 1] is LSL_String)
@@ -12174,7 +12350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12174 } 12350 }
12175 break; 12351 break;
12176 12352
12177 case (uint)ParcelMediaCommandEnum.Texture: 12353 case ParcelMediaCommandEnum.Texture:
12178 if ((i + 1) < commandList.Length) 12354 if ((i + 1) < commandList.Length)
12179 { 12355 {
12180 if (commandList.Data[i + 1] is LSL_String) 12356 if (commandList.Data[i + 1] is LSL_String)
@@ -12187,7 +12363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12187 } 12363 }
12188 break; 12364 break;
12189 12365
12190 case (uint)ParcelMediaCommandEnum.Time: 12366 case ParcelMediaCommandEnum.Time:
12191 if ((i + 1) < commandList.Length) 12367 if ((i + 1) < commandList.Length)
12192 { 12368 {
12193 if (commandList.Data[i + 1] is LSL_Float) 12369 if (commandList.Data[i + 1] is LSL_Float)
@@ -12199,7 +12375,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12199 } 12375 }
12200 break; 12376 break;
12201 12377
12202 case (uint)ParcelMediaCommandEnum.AutoAlign: 12378 case ParcelMediaCommandEnum.AutoAlign:
12203 if ((i + 1) < commandList.Length) 12379 if ((i + 1) < commandList.Length)
12204 { 12380 {
12205 if (commandList.Data[i + 1] is LSL_Integer) 12381 if (commandList.Data[i + 1] is LSL_Integer)
@@ -12213,7 +12389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12213 } 12389 }
12214 break; 12390 break;
12215 12391
12216 case (uint)ParcelMediaCommandEnum.Type: 12392 case ParcelMediaCommandEnum.Type:
12217 if ((i + 1) < commandList.Length) 12393 if ((i + 1) < commandList.Length)
12218 { 12394 {
12219 if (commandList.Data[i + 1] is LSL_String) 12395 if (commandList.Data[i + 1] is LSL_String)
@@ -12226,7 +12402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12226 } 12402 }
12227 break; 12403 break;
12228 12404
12229 case (uint)ParcelMediaCommandEnum.Desc: 12405 case ParcelMediaCommandEnum.Desc:
12230 if ((i + 1) < commandList.Length) 12406 if ((i + 1) < commandList.Length)
12231 { 12407 {
12232 if (commandList.Data[i + 1] is LSL_String) 12408 if (commandList.Data[i + 1] is LSL_String)
@@ -12239,7 +12415,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12239 } 12415 }
12240 break; 12416 break;
12241 12417
12242 case (uint)ParcelMediaCommandEnum.Size: 12418 case ParcelMediaCommandEnum.Size:
12243 if ((i + 2) < commandList.Length) 12419 if ((i + 2) < commandList.Length)
12244 { 12420 {
12245 if (commandList.Data[i + 1] is LSL_Integer) 12421 if (commandList.Data[i + 1] is LSL_Integer)
@@ -12309,7 +12485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12309 } 12485 }
12310 } 12486 }
12311 12487
12312 if (commandToSend != 0) 12488 if (commandToSend != null)
12313 { 12489 {
12314 // the commandList contained a start/stop/... command, too 12490 // the commandList contained a start/stop/... command, too
12315 if (presence == null) 12491 if (presence == null)
@@ -12320,16 +12496,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12320 if (sp.currentParcelUUID == landData.GlobalID) 12496 if (sp.currentParcelUUID == landData.GlobalID)
12321 { 12497 {
12322 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12498 sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12323 (ParcelMediaCommandEnum)commandToSend, 12499 (ParcelMediaCommandEnum)commandToSend, time);
12324 time);
12325 } 12500 }
12326 }); 12501 });
12327 } 12502 }
12328 else if (!presence.IsChildAgent) 12503 else if (!presence.IsChildAgent)
12329 { 12504 {
12330 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? 12505 presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this?
12331 (ParcelMediaCommandEnum)commandToSend, 12506 (ParcelMediaCommandEnum)commandToSend, time);
12332 time);
12333 } 12507 }
12334 } 12508 }
12335 ScriptSleep(m_sleepMsOnParcelMediaCommandList); 12509 ScriptSleep(m_sleepMsOnParcelMediaCommandList);
@@ -13815,6 +13989,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13815 return result; 13989 return result;
13816 } 13990 }
13817 13991
13992 public void print(string str)
13993 {
13994 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print
13995 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL");
13996 if (ossl != null)
13997 {
13998 ossl.CheckThreatLevel(ThreatLevel.High, "print");
13999 m_log.Info("LSL print():" + str);
14000 }
14001 }
14002
13818 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 14003 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
13819 { 14004 {
13820 List<SceneObjectPart> parts = GetLinkParts(link); 14005 List<SceneObjectPart> parts = GetLinkParts(link);
@@ -14384,47 +14569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
14384 14569
14385 return list; 14570 return list;
14386 } 14571 }
14387
14388
14389 // this is wrong, except on a few trivial cases
14390 // keeping it for now just for raycast v3
14391 14572
14392 /// <summary>
14393 /// Helper to calculate bounding box of an avatar.
14394 /// </summary>
14395 private void BoundingBoxOfScenePresence(ScenePresence sp, out Vector3 lower, out Vector3 upper)
14396 {
14397 // Adjust from OS model
14398 // avatar height = visual height - 0.2, bounding box height = visual height
14399 // to SL model
14400 // avatar height = visual height, bounding box height = visual height + 0.2
14401 float height = sp.Appearance.AvatarHeight + m_avatarHeightCorrection;
14402
14403 // According to avatar bounding box in SL 2015-04-18:
14404 // standing = <-0.275,-0.35,-0.1-0.5*h> : <0.275,0.35,0.1+0.5*h>
14405 // groundsitting = <-0.3875,-0.5,-0.05-0.375*h> : <0.3875,0.5,0.5>
14406 // sitting = <-0.5875,-0.35,-0.35-0.375*h> : <0.1875,0.35,-0.25+0.25*h>
14407
14408 // When avatar is sitting
14409 if (sp.ParentPart != null)
14410 {
14411 lower = new Vector3(m_lABB1SitX0, m_lABB1SitY0, m_lABB1SitZ0 + m_lABB1SitZ1 * height);
14412 upper = new Vector3(m_lABB2SitX0, m_lABB2SitY0, m_lABB2SitZ0 + m_lABB2SitZ1 * height);
14413 }
14414 // When avatar is groundsitting
14415 else if (sp.Animator.Animations.ImplicitDefaultAnimation.AnimID == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
14416 {
14417 lower = new Vector3(m_lABB1GrsX0, m_lABB1GrsY0, m_lABB1GrsZ0 + m_lABB1GrsZ1 * height);
14418 upper = new Vector3(m_lABB2GrsX0, m_lABB2GrsY0, m_lABB2GrsZ0 + m_lABB2GrsZ1 * height);
14419 }
14420 // When avatar is standing or flying
14421 else
14422 {
14423 lower = new Vector3(m_lABB1StdX0, m_lABB1StdY0, m_lABB1StdZ0 + m_lABB1StdZ1 * height);
14424 upper = new Vector3(m_lABB2StdX0, m_lABB2StdY0, m_lABB2StdZ0 + m_lABB2StdZ1 * height);
14425 }
14426 }
14427
14428 14573
14429 /// <summary> 14574 /// <summary>
14430 /// Implementation of llCastRay similar to SL 2015-04-21. 14575 /// Implementation of llCastRay similar to SL 2015-04-21.
@@ -15547,145 +15692,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
15547 15692
15548 #endregion 15693 #endregion
15549 15694
15550 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
15551 {
15552 SceneObjectGroup group = m_host.ParentGroup;
15553
15554 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
15555 return;
15556 if (group.IsAttachment)
15557 return;
15558
15559 if (frames.Data.Length > 0) // We are getting a new motion
15560 {
15561 if (group.RootPart.KeyframeMotion != null)
15562 group.RootPart.KeyframeMotion.Delete();
15563 group.RootPart.KeyframeMotion = null;
15564
15565 int idx = 0;
15566
15567 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
15568 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
15569
15570 while (idx < options.Data.Length)
15571 {
15572 int option = (int)options.GetLSLIntegerItem(idx++);
15573 int remain = options.Data.Length - idx;
15574
15575 switch (option)
15576 {
15577 case ScriptBaseClass.KFM_MODE:
15578 if (remain < 1)
15579 break;
15580 int modeval = (int)options.GetLSLIntegerItem(idx++);
15581 switch(modeval)
15582 {
15583 case ScriptBaseClass.KFM_FORWARD:
15584 mode = KeyframeMotion.PlayMode.Forward;
15585 break;
15586 case ScriptBaseClass.KFM_REVERSE:
15587 mode = KeyframeMotion.PlayMode.Reverse;
15588 break;
15589 case ScriptBaseClass.KFM_LOOP:
15590 mode = KeyframeMotion.PlayMode.Loop;
15591 break;
15592 case ScriptBaseClass.KFM_PING_PONG:
15593 mode = KeyframeMotion.PlayMode.PingPong;
15594 break;
15595 }
15596 break;
15597 case ScriptBaseClass.KFM_DATA:
15598 if (remain < 1)
15599 break;
15600 int dataval = (int)options.GetLSLIntegerItem(idx++);
15601 data = (KeyframeMotion.DataFormat)dataval;
15602 break;
15603 }
15604 }
15605
15606 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
15607
15608 idx = 0;
15609
15610 int elemLength = 2;
15611 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
15612 elemLength = 3;
15613
15614 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
15615 while (idx < frames.Data.Length)
15616 {
15617 int remain = frames.Data.Length - idx;
15618
15619 if (remain < elemLength)
15620 break;
15621
15622 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
15623 frame.Position = null;
15624 frame.Rotation = null;
15625
15626 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
15627 {
15628 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
15629 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
15630 }
15631 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
15632 {
15633 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
15634 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
15635 q.Normalize();
15636 frame.Rotation = q;
15637 }
15638
15639 float tempf = (float)frames.GetLSLFloatItem(idx++);
15640 frame.TimeMS = (int)(tempf * 1000.0f);
15641
15642 keyframes.Add(frame);
15643 }
15644
15645 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
15646 group.RootPart.KeyframeMotion.Start();
15647 }
15648 else
15649 {
15650 if (group.RootPart.KeyframeMotion == null)
15651 return;
15652
15653 if (options.Data.Length == 0)
15654 {
15655 group.RootPart.KeyframeMotion.Stop();
15656 return;
15657 }
15658
15659 int code = (int)options.GetLSLIntegerItem(0);
15660
15661 int idx = 0;
15662
15663 while (idx < options.Data.Length)
15664 {
15665 int option = (int)options.GetLSLIntegerItem(idx++);
15666 int remain = options.Data.Length - idx;
15667
15668 switch (option)
15669 {
15670 case ScriptBaseClass.KFM_COMMAND:
15671 int cmd = (int)options.GetLSLIntegerItem(idx++);
15672 switch (cmd)
15673 {
15674 case ScriptBaseClass.KFM_CMD_PLAY:
15675 group.RootPart.KeyframeMotion.Start();
15676 break;
15677 case ScriptBaseClass.KFM_CMD_STOP:
15678 group.RootPart.KeyframeMotion.Stop();
15679 break;
15680 case ScriptBaseClass.KFM_CMD_PAUSE:
15681 group.RootPart.KeyframeMotion.Pause();
15682 break;
15683 }
15684 break;
15685 }
15686 }
15687 }
15688 }
15689 15695
15690 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed) 15696 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
15691 { 15697 {
@@ -16104,8 +16110,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
16104 return new LSL_List(); 16110 return new LSL_List();
16105 } 16111 }
16106 16112
16107
16108
16109 public void llSetAnimationOverride(LSL_String animState, LSL_String anim) 16113 public void llSetAnimationOverride(LSL_String animState, LSL_String anim)
16110 { 16114 {
16111 string state = String.Empty; 16115 string state = String.Empty;