aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs470
1 files changed, 463 insertions, 7 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7225ae0..f521630 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -34,6 +34,7 @@ using System.Threading;
34using Nini.Config; 34using Nini.Config;
35using Axiom.Math; 35using Axiom.Math;
36using libsecondlife; 36using libsecondlife;
37using libsecondlife.Packets;
37using OpenSim; 38using OpenSim;
38using OpenSim.Framework; 39using OpenSim.Framework;
39using OpenSim.Framework.Communications.Cache; 40using OpenSim.Framework.Communications.Cache;
@@ -4563,6 +4564,316 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4563 m_host.AddScriptLPS(1); 4564 m_host.AddScriptLPS(1);
4564 return Util.Md5Hash(src + ":" + nonce.ToString()); 4565 return Util.Md5Hash(src + ":" + nonce.ToString());
4565 } 4566 }
4567
4568 private ObjectShapePacket.ObjectDataBlock SetPrimitiveShapeParams(int holeshape, LSL_Types.Vector3 cut, float hollow, LSL_Types.Vector3 twist)
4569 {
4570 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
4571
4572 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
4573 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
4574 holeshape != (int)ScriptBaseClass.PRIM_HOLE_SQUARE &&
4575 holeshape != (int)ScriptBaseClass.PRIM_HOLE_TRIANGLE)
4576 {
4577 holeshape = (int)ScriptBaseClass.PRIM_HOLE_DEFAULT;
4578 }
4579 shapeBlock.ProfileCurve = (byte)holeshape;
4580 if (cut.x < 0f)
4581 {
4582 cut.x = 0f;
4583 }
4584 if (cut.x > 1f)
4585 {
4586 cut.x = 1f;
4587 }
4588 if (cut.y < 0f)
4589 {
4590 cut.y = 0f;
4591 }
4592 if (cut.y > 1f)
4593 {
4594 cut.y = 1f;
4595 }
4596 if (cut.y - cut.x < 0.05f)
4597 {
4598 cut.x = cut.y - 0.05f;
4599 }
4600 shapeBlock.ProfileBegin = (ushort)(50000 * cut.x);
4601 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - cut.y));
4602 if (hollow < 0f)
4603 {
4604 hollow = 0f;
4605 }
4606 if (hollow > 0.95)
4607 {
4608 hollow = 0.95f;
4609 }
4610 shapeBlock.ProfileHollow = (ushort)(50000 * hollow);
4611 if (twist.x < -0.5f)
4612 {
4613 twist.x = -0.5f;
4614 }
4615 if (twist.x > 0.5f)
4616 {
4617 twist.x = 0.5f;
4618 }
4619 if (twist.y < -0.5f)
4620 {
4621 twist.y = -0.5f;
4622 }
4623 if (twist.y > 0.5f)
4624 {
4625 twist.y = 0.5f;
4626 }
4627 shapeBlock.PathTwistBegin = (sbyte)(200 * twist.x);
4628 shapeBlock.PathTwist = (sbyte)(200 * twist.y);
4629
4630 shapeBlock.ObjectLocalID = m_host.LocalId;
4631
4632 // retain pathcurve
4633 shapeBlock.PathCurve = m_host.Shape.PathCurve;
4634
4635 return shapeBlock;
4636 }
4637
4638 private void SetPrimitiveShapeParams(int holeshape, LSL_Types.Vector3 cut, float hollow, LSL_Types.Vector3 twist, LSL_Types.Vector3 taper_b, LSL_Types.Vector3 topshear, byte fudge)
4639 {
4640 ObjectShapePacket.ObjectDataBlock shapeBlock;
4641
4642 shapeBlock = SetPrimitiveShapeParams(holeshape, cut, hollow, twist);
4643
4644 shapeBlock.ProfileCurve += fudge;
4645
4646 if (taper_b.x < 0f)
4647 {
4648 taper_b.x = 0f;
4649 }
4650 if (taper_b.x > 2f)
4651 {
4652 taper_b.x = 2f;
4653 }
4654 if (taper_b.y < 0f)
4655 {
4656 taper_b.y = 0f;
4657 }
4658 if (taper_b.y > 2f)
4659 {
4660 taper_b.y = 2f;
4661 }
4662 shapeBlock.PathScaleX = (byte)(100 * taper_b.x);
4663 shapeBlock.PathScaleY = (byte)(100 * taper_b.y);
4664 if (topshear.x < -0.5f)
4665 {
4666 topshear.x = -0.5f;
4667 }
4668 if (topshear.x > 0.5f)
4669 {
4670 topshear.x = 0.5f;
4671 }
4672 if (topshear.y < -0.5f)
4673 {
4674 topshear.y = -0.5f;
4675 }
4676 if (topshear.y > 0.5f)
4677 {
4678 topshear.y = 0.5f;
4679 }
4680 shapeBlock.PathShearX = (byte)(100 * topshear.x);
4681 shapeBlock.PathShearY = (byte)(100 * topshear.y);
4682
4683 m_host.UpdateShape(shapeBlock);
4684 }
4685
4686 private void SetPrimitiveShapeParams(int holeshape, LSL_Types.Vector3 cut, float hollow, LSL_Types.Vector3 twist, LSL_Types.Vector3 dimple, byte fudge)
4687 {
4688 ObjectShapePacket.ObjectDataBlock shapeBlock;
4689
4690 shapeBlock = SetPrimitiveShapeParams(holeshape, cut, hollow, twist);
4691
4692 // profile/path swapped for a sphere
4693 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
4694 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
4695
4696 shapeBlock.ProfileCurve += fudge;
4697
4698 shapeBlock.PathScaleX = 100;
4699 shapeBlock.PathScaleY = 100;
4700
4701 if (dimple.x < 0f)
4702 {
4703 dimple.x = 0f;
4704 }
4705 if (dimple.x > 1f)
4706 {
4707 dimple.x = 1f;
4708 }
4709 if (dimple.y < 0f)
4710 {
4711 dimple.y = 0f;
4712 }
4713 if (dimple.y > 1f)
4714 {
4715 dimple.y = 1f;
4716 }
4717 if (dimple.y - cut.x < 0.05f)
4718 {
4719 dimple.x = cut.y - 0.05f;
4720 }
4721 shapeBlock.ProfileBegin = (ushort)(50000 * dimple.x);
4722 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - dimple.y));
4723
4724 m_host.UpdateShape(shapeBlock);
4725 }
4726
4727 private void SetPrimitiveShapeParams(int holeshape, LSL_Types.Vector3 cut, float hollow, LSL_Types.Vector3 twist, LSL_Types.Vector3 holesize, LSL_Types.Vector3 topshear, LSL_Types.Vector3 profilecut, LSL_Types.Vector3 taper_a, float revolutions, float radiusoffset, float skew, byte fudge)
4728 {
4729 ObjectShapePacket.ObjectDataBlock shapeBlock;
4730
4731 shapeBlock = SetPrimitiveShapeParams(holeshape, cut, hollow, twist);
4732
4733 shapeBlock.ProfileCurve += fudge;
4734
4735 // profile/path swapped for a torrus, tube, ring
4736 shapeBlock.PathBegin = shapeBlock.ProfileBegin;
4737 shapeBlock.PathEnd = shapeBlock.ProfileEnd;
4738
4739 if (holesize.x < 0.05f)
4740 {
4741 holesize.x = 0.05f;
4742 }
4743 if (holesize.x > 1f)
4744 {
4745 holesize.x = 1f;
4746 }
4747 if (holesize.y < 0.05f)
4748 {
4749 holesize.y = 0.05f;
4750 }
4751 if (holesize.y > 0.5f)
4752 {
4753 holesize.y = 0.5f;
4754 }
4755 shapeBlock.PathScaleX = (byte)(100 * (2 - holesize.x));
4756 shapeBlock.PathScaleY = (byte)(100 * (2 - holesize.y));
4757 if (topshear.x < -0.5f)
4758 {
4759 topshear.x = -0.5f;
4760 }
4761 if (topshear.x > 0.5f)
4762 {
4763 topshear.x = 0.5f;
4764 }
4765 if (topshear.y < -0.5f)
4766 {
4767 topshear.y = -0.5f;
4768 }
4769 if (topshear.y > 0.5f)
4770 {
4771 topshear.y = 0.5f;
4772 }
4773 shapeBlock.PathShearX = (byte)(100 * topshear.x);
4774 shapeBlock.PathShearY = (byte)(100 * topshear.y);
4775 if (profilecut.x < 0f)
4776 {
4777 profilecut.x = 0f;
4778 }
4779 if (profilecut.x > 1f)
4780 {
4781 profilecut.x = 1f;
4782 }
4783 if (profilecut.y < 0f)
4784 {
4785 profilecut.y = 0f;
4786 }
4787 if (profilecut.y > 1f)
4788 {
4789 profilecut.y = 1f;
4790 }
4791 if (profilecut.y - cut.x < 0.05f)
4792 {
4793 profilecut.x = cut.y - 0.05f;
4794 }
4795 shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x);
4796 shapeBlock.ProfileEnd = (ushort)(50000 * (1 - profilecut.y));
4797 if (taper_a.x < -1f)
4798 {
4799 taper_a.x = -1f;
4800 }
4801 if (taper_a.x > 1f)
4802 {
4803 taper_a.x = 1f;
4804 }
4805 if (taper_a.y < -1f)
4806 {
4807 taper_a.y = -1f;
4808 }
4809 if (taper_a.y > 1f)
4810 {
4811 taper_a.y = 1f;
4812 }
4813 shapeBlock.PathTaperX = (sbyte)(100 * taper_a.x);
4814 shapeBlock.PathTaperY = (sbyte)(100 * taper_a.y);
4815 if (revolutions < 1f)
4816 {
4817 revolutions = 1f;
4818 }
4819 if (revolutions > 4f)
4820 {
4821 revolutions = 4f;
4822 }
4823 shapeBlock.PathRevolutions = (byte)(100 * revolutions);
4824 // limits on radiusoffset depend on revolutions and hole size (how?) seems like the maximum range is 0 to 1
4825 if (radiusoffset < 0f)
4826 {
4827 radiusoffset = 0f;
4828 }
4829 if (radiusoffset > 1f)
4830 {
4831 radiusoffset = 1f;
4832 }
4833 shapeBlock.PathRadiusOffset = (sbyte)(100 * radiusoffset);
4834 if (skew < -0.95f)
4835 {
4836 skew = -0.95f;
4837 }
4838 if (skew > 0.95f)
4839 {
4840 skew = 0.95f;
4841 }
4842 shapeBlock.PathSkew = (sbyte)(100 * skew);
4843
4844 m_host.UpdateShape(shapeBlock);
4845 }
4846
4847 private void SetPrimitiveShapeParams(string map, int type)
4848 {
4849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
4850 LLUUID sculptId;
4851
4852 if (!LLUUID.TryParse(map, out sculptId))
4853 {
4854 llSay(0, "Could not parse key " + map);
4855 return;
4856 }
4857
4858 shapeBlock.ObjectLocalID = m_host.LocalId;
4859 shapeBlock.PathScaleX = 100;
4860 shapeBlock.PathScaleY = 150;
4861
4862 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER &&
4863 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE &&
4864 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE &&
4865 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS)
4866 {
4867 // default
4868 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
4869 }
4870
4871 // retain pathcurve
4872 shapeBlock.PathCurve = m_host.Shape.PathCurve;
4873
4874 m_host.Shape.SetSculptData((byte)type, sculptId);
4875 m_host.UpdateShape(shapeBlock);
4876 }
4566 4877
4567 public void llSetPrimitiveParams(LSL_Types.list rules) 4878 public void llSetPrimitiveParams(LSL_Types.list rules)
4568 { 4879 {
@@ -4607,7 +4918,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4607 4918
4608 switch (code) 4919 switch (code)
4609 { 4920 {
4610 case 6: // PRIM_POSITION 4921 case (int)ScriptBaseClass.PRIM_POSITION:
4611 if (remain < 1) 4922 if (remain < 1)
4612 return; 4923 return;
4613 4924
@@ -4615,7 +4926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4615 SetPos(part, v); 4926 SetPos(part, v);
4616 4927
4617 break; 4928 break;
4618 case 7: // PRIM_SIZE 4929 case (int)ScriptBaseClass.PRIM_SIZE:
4619 if (remain < 1) 4930 if (remain < 1)
4620 return; 4931 return;
4621 4932
@@ -4623,7 +4934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4623 SetScale(part, v); 4934 SetScale(part, v);
4624 4935
4625 break; 4936 break;
4626 case 8: // PRIM_ROTATION 4937 case (int)ScriptBaseClass.PRIM_ROTATION:
4627 if (remain < 1) 4938 if (remain < 1)
4628 return; 4939 return;
4629 4940
@@ -4631,8 +4942,153 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4631 SetRot(part, q); 4942 SetRot(part, q);
4632 4943
4633 break; 4944 break;
4945
4946 case (int)ScriptBaseClass.PRIM_TYPE:
4947 if (remain < 3)
4948 return;
4949
4950 code = Convert.ToInt32(rules.Data[idx++]);
4951
4952 remain = rules.Length - idx;
4953 float hollow;
4954 LSL_Types.Vector3 twist;
4955 LSL_Types.Vector3 taper_b;
4956 LSL_Types.Vector3 topshear;
4957 float revolutions;
4958 float radiusoffset;
4959 float skew;
4960 LSL_Types.Vector3 holesize;
4961 LSL_Types.Vector3 profilecut;
4962
4963 switch(code)
4964 {
4965 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
4966 if (remain < 6)
4967 return;
4968
4969 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
4970 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // cut
4971 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
4972 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4973 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4974 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4975 m_host.Shape.PathCurve = (byte) Extrusion.Straight;
4976 SetPrimitiveShapeParams(face, v, hollow, twist, taper_b, topshear, 1);;
4977 break;
4978
4979 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
4980 if (remain < 6)
4981 return;
4982
4983 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
4984 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // cut
4985 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
4986 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4987 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4988 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
4989 m_host.Shape.ProfileShape = ProfileShape.Circle;
4990 m_host.Shape.PathCurve = (byte) Extrusion.Straight;
4991 SetPrimitiveShapeParams(face, v, hollow, twist, taper_b, topshear, 0);
4992 break;
4993
4994 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
4995 if (remain < 6)
4996 return;
4997
4998 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
4999 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); //cut
5000 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
5001 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5002 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5003 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5004 m_host.Shape.PathCurve = (byte) Extrusion.Straight;
5005 SetPrimitiveShapeParams(face, v, hollow, twist, taper_b, topshear, 3);
5006 break;
4634 5007
4635 case 17: // PRIM_TEXTURE 5008 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
5009 if (remain < 5)
5010 return;
5011
5012 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
5013 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // cut
5014 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
5015 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5016 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // dimple
5017 m_host.Shape.PathCurve = (byte) Extrusion.Curve1;
5018 SetPrimitiveShapeParams(face, v, hollow, twist, taper_b, 5);
5019 break;
5020
5021 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
5022 if (remain < 11)
5023 return;
5024
5025 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
5026 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); //cut
5027 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
5028 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5029 holesize = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5030 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5031 profilecut = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5032 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // taper_a
5033 revolutions = (float)Convert.ToDouble(rules.Data[idx++]);
5034 radiusoffset = (float)Convert.ToDouble(rules.Data[idx++]);
5035 skew = (float)Convert.ToDouble(rules.Data[idx++]);
5036 m_host.Shape.PathCurve = (byte) Extrusion.Curve1;
5037 SetPrimitiveShapeParams(face, v, hollow, twist, holesize, topshear, profilecut, taper_b, revolutions, radiusoffset, skew, 0);
5038 break;
5039
5040 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
5041 if (remain < 11)
5042 return;
5043
5044 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
5045 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); //cut
5046 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
5047 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5048 holesize = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5049 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5050 profilecut = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5051 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // taper_a
5052 revolutions = (float)Convert.ToDouble(rules.Data[idx++]);
5053 radiusoffset = (float)Convert.ToDouble(rules.Data[idx++]);
5054 skew = (float)Convert.ToDouble(rules.Data[idx++]);
5055 m_host.Shape.PathCurve = (byte) Extrusion.Curve1;
5056 SetPrimitiveShapeParams(face, v, hollow, twist, holesize, topshear, profilecut, taper_b, revolutions, radiusoffset, skew, 1);
5057 break;
5058
5059 case (int)ScriptBaseClass.PRIM_TYPE_RING:
5060 if (remain < 11)
5061 return;
5062
5063 face = Convert.ToInt32(rules.Data[idx++]); // holeshape
5064 v = new LSL_Types.Vector3(rules.Data[idx++].ToString()); //cut
5065 hollow = (float)Convert.ToDouble(rules.Data[idx++]);
5066 twist = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5067 holesize = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5068 topshear = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5069 profilecut = new LSL_Types.Vector3(rules.Data[idx++].ToString());
5070 taper_b = new LSL_Types.Vector3(rules.Data[idx++].ToString()); // taper_a
5071 revolutions = (float)Convert.ToDouble(rules.Data[idx++]);
5072 radiusoffset = (float)Convert.ToDouble(rules.Data[idx++]);
5073 skew = (float)Convert.ToDouble(rules.Data[idx++]);
5074 m_host.Shape.PathCurve = (byte) Extrusion.Curve1;
5075 SetPrimitiveShapeParams(face, v, hollow, twist, holesize, topshear, profilecut, taper_b, revolutions, radiusoffset, skew, 3);
5076 break;
5077
5078 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
5079 if (remain < 2)
5080 return;
5081
5082 string map = rules.Data[idx++].ToString();
5083 face = Convert.ToInt32(rules.Data[idx++]); // type
5084 m_host.Shape.PathCurve = (byte) Extrusion.Curve1;
5085 SetPrimitiveShapeParams(map, face);
5086 break;
5087 }
5088
5089 break;
5090
5091 case (int)ScriptBaseClass.PRIM_TEXTURE:
4636 if (remain < 5) 5092 if (remain < 5)
4637 return; 5093 return;
4638 5094
@@ -4649,7 +5105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4649 5105
4650 break; 5106 break;
4651 5107
4652 case 18: // PRIM_COLOR 5108 case (int)ScriptBaseClass.PRIM_COLOR:
4653 if (remain < 3) 5109 if (remain < 3)
4654 return; 5110 return;
4655 5111
@@ -4661,7 +5117,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4661 SetAlpha(part, alpha, face); 5117 SetAlpha(part, alpha, face);
4662 5118
4663 break; 5119 break;
4664 case 21: // PRIM_FLEXI 5120 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
4665 if (remain < 7) 5121 if (remain < 7)
4666 return; 5122 return;
4667 5123
@@ -4676,7 +5132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4676 SetFlexi(part, (flexi == 1), softness, gravity, friction, wind, tension, force); 5132 SetFlexi(part, (flexi == 1), softness, gravity, friction, wind, tension, force);
4677 5133
4678 break; 5134 break;
4679 case 23: // PRIM_POINT_LIGHT 5135 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
4680 if (remain < 5) 5136 if (remain < 5)
4681 return; 5137 return;
4682 int light = Convert.ToInt32(rules.Data[idx++]); 5138 int light = Convert.ToInt32(rules.Data[idx++]);