mirror of
https://github.com/opensim/opensim.git
synced 2026-05-15 03:15:41 +08:00
add llGetStartString and limited llRezObjectWithParams for testing
This commit is contained in:
@@ -58,6 +58,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using AssetLandmark = OpenSim.Framework.AssetLandmark;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using MappingType = OpenMetaverse.MappingType;
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
@@ -3321,7 +3322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, wrot, vel, param, atRoot);
|
||||
|
||||
// If either of these are null, then there was an unknown error.
|
||||
if (new_groups == null)
|
||||
if (new_groups == null || new_groups.Count == 0)
|
||||
return;
|
||||
|
||||
bool notAttachment = !m_host.ParentGroup.IsAttachment;
|
||||
@@ -3341,14 +3342,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
if (notAttachment)
|
||||
{
|
||||
float groupmass = group.GetMass();
|
||||
|
||||
PhysicsActor pa = group.RootPart.PhysActor;
|
||||
|
||||
//Recoil.
|
||||
if (pa != null && pa.IsPhysical && !((Vector3)vel).IsZero())
|
||||
{
|
||||
Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
|
||||
Vector3 recoil = -vel * group.GetMass() * m_recoilScaleFactor;
|
||||
if (!recoil.IsZero())
|
||||
{
|
||||
llApplyImpulse(recoil, 0);
|
||||
@@ -3367,6 +3366,514 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
doObjectRez(inventory, pos, vel, rot, param, false);
|
||||
}
|
||||
|
||||
public LSL_Key llRezObjectWithParams(string inventory, LSL_List lparam)
|
||||
{
|
||||
/* flags not supported
|
||||
* REZ_FLAG_DIE_ON_NOENTRY
|
||||
* REZ_FLAG_NO_COLLIDE_OWNER
|
||||
* REZ_FLAG_NO_COLLIDE_FAMILY
|
||||
*
|
||||
* parameters not supported
|
||||
* REZ_ACCEL
|
||||
* REZ_DAMAGE
|
||||
* REZ_DAMAGE_TYPE
|
||||
* REZ_OMEGA only does viewer side lltargetomega
|
||||
*/
|
||||
|
||||
if (string.IsNullOrEmpty(inventory))
|
||||
return LSL_Key.NullKey;
|
||||
|
||||
TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory);
|
||||
if (item == null)
|
||||
{
|
||||
Error("llRezObjectWithParams", "Can't find object '" + inventory + "'");
|
||||
return LSL_Key.NullKey;
|
||||
}
|
||||
|
||||
if (item.InvType != (int)InventoryType.Object)
|
||||
{
|
||||
Error("llRezObjectWithParams", "Can't create requested object; object is missing from database");
|
||||
return LSL_Key.NullKey;
|
||||
}
|
||||
|
||||
int flags = 0;
|
||||
Vector3 pos = Vector3.Zero;
|
||||
Vector3 vel = Vector3.Zero;
|
||||
Quaternion rot = Quaternion.Identity;
|
||||
Vector3 acel = Vector3.Zero;
|
||||
Vector3 omega = Vector3.Zero;
|
||||
float omegaSpin = 0;
|
||||
float omegaGain = 0;
|
||||
|
||||
float damage = 0;
|
||||
|
||||
string sound = null;
|
||||
float soundVol = 0;
|
||||
bool soundLoop = false;
|
||||
|
||||
string collisionSound = null;
|
||||
float CollisionSoundVol = 0;
|
||||
|
||||
int param = 0;
|
||||
|
||||
Vector3 lockAxis = Vector3.Zero;
|
||||
|
||||
string stringparam = null;
|
||||
bool atRoot = false;
|
||||
|
||||
if(lparam != null && lparam.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
int idx = 0;
|
||||
while (idx < lparam.Length)
|
||||
{
|
||||
int rezrelative = 0;
|
||||
int code = lparam.GetIntegerItem(idx++);
|
||||
switch(code)
|
||||
{
|
||||
case ScriptBaseClass.REZ_PARAM:
|
||||
try
|
||||
{
|
||||
param = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must a integer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_FLAGS:
|
||||
try
|
||||
{
|
||||
flags = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must a integer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_POS:
|
||||
try
|
||||
{
|
||||
pos = lparam.GetVector3Item(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be vector");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
rezrelative = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
idx++;
|
||||
int rezAtRot = 0;
|
||||
try
|
||||
{
|
||||
rezAtRot = lparam.GetIntegerItem(idx);
|
||||
atRoot = rezAtRot != 0;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
if(rezrelative != 0)
|
||||
{
|
||||
if(pos.LengthSquared() > m_Script10mDistanceSquare)
|
||||
return LSL_Key.NullKey;
|
||||
pos += m_host.GetWorldPosition();
|
||||
}
|
||||
else if ((pos + m_host.GetWorldPosition()).LengthSquared() > m_Script10mDistanceSquare)
|
||||
return LSL_Key.NullKey;
|
||||
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_ROT:
|
||||
try
|
||||
{
|
||||
rot = lparam.GetQuaternionItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be rotation");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
rezrelative = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
if(rezrelative > 0)
|
||||
rot *= m_host.GetWorldRotation();
|
||||
|
||||
rot.Normalize();
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_VEL:
|
||||
try
|
||||
{
|
||||
pos = lparam.GetVector3Item(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be vector");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
rezrelative = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
idx++;
|
||||
int addVel = 0;
|
||||
try
|
||||
{
|
||||
addVel = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
if(rezrelative > 0)
|
||||
vel *= m_host.GetWorldRotation();
|
||||
if(addVel > 0)
|
||||
vel += m_host.ParentGroup.Velocity;
|
||||
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_ACCEL:
|
||||
try
|
||||
{
|
||||
acel = lparam.GetVector3Item(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be vector");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
rezrelative = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_OMEGA:
|
||||
try
|
||||
{
|
||||
omega = lparam.GetVector3Item(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be vector");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
rezrelative = lparam.GetIntegerItem(idx);
|
||||
if(rezrelative > 0)
|
||||
omega *= m_host.GetWorldRotation();
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
omegaSpin = lparam.GetFloatItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be float");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
omegaGain = lparam.GetFloatItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be float");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_DAMAGE:
|
||||
try
|
||||
{
|
||||
damage = lparam.GetFloatItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be float");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_SOUND:
|
||||
try
|
||||
{
|
||||
sound = lparam.GetStringItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be string");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
soundVol = lparam.GetFloatItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be float");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
soundLoop = lparam.GetIntegerItem(idx) > 0;
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_SOUND_COLLIDE:
|
||||
try
|
||||
{
|
||||
collisionSound = lparam.GetStringItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be string");
|
||||
}
|
||||
|
||||
idx++;
|
||||
try
|
||||
{
|
||||
CollisionSoundVol = lparam.GetFloatItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be float");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_LOCK_AXES:
|
||||
try
|
||||
{
|
||||
lockAxis = lparam.GetVector3Item(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be vector");
|
||||
}
|
||||
break;
|
||||
case ScriptBaseClass.REZ_DAMAGE_TYPE:
|
||||
try
|
||||
{
|
||||
int damageType = lparam.GetIntegerItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be integer");
|
||||
}
|
||||
break;
|
||||
|
||||
case ScriptBaseClass.REZ_PARAM_STRING:
|
||||
try
|
||||
{
|
||||
stringparam = lparam.GetStringItem(idx);
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
throw new InvalidCastException($"arg #{idx} must be string");
|
||||
}
|
||||
|
||||
_ = Utils.osUTF8GetBytesCount(stringparam, 1024, out int maxsourcelen);
|
||||
if(maxsourcelen < stringparam.Length)
|
||||
stringparam = stringparam[..maxsourcelen];
|
||||
break;
|
||||
|
||||
default:
|
||||
Error("llRezObjectWithParams", $"Unknown parameter {code} at {idx}");
|
||||
return LSL_Key.NullKey;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Error("llRezObjectWithParams", "error " + e.Message);
|
||||
return LSL_Key.NullKey;
|
||||
}
|
||||
}
|
||||
|
||||
UUID newID = UUID.Random();
|
||||
|
||||
Util.FireAndForget(x =>
|
||||
{
|
||||
SceneObjectGroup sog = m_host.Inventory.GetSingleRezReadySceneObject(item, m_host.OwnerID, m_host.GroupID);
|
||||
if(sog is null)
|
||||
return;
|
||||
|
||||
int totalPrims = sog.PrimCount;
|
||||
|
||||
if (!World.Permissions.CanRezObject(totalPrims, m_host.OwnerID, pos))
|
||||
return;
|
||||
|
||||
if (!World.Permissions.BypassPermissions())
|
||||
{
|
||||
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
||||
m_host.Inventory.RemoveInventoryItem(item.ItemID);
|
||||
}
|
||||
|
||||
// position adjust
|
||||
if (!atRoot && totalPrims > 1) // nothing to do on a single prim
|
||||
{
|
||||
pos -= sog.GetGeometricCenter() * rot;
|
||||
}
|
||||
|
||||
if (sog.IsAttachment == false && sog.RootPart.Shape.State != 0)
|
||||
{
|
||||
sog.RootPart.AttachedPos = sog.AbsolutePosition;
|
||||
sog.RootPart.Shape.LastAttachPoint = (byte)sog.AttachmentPoint;
|
||||
}
|
||||
|
||||
sog.RezzerID = m_host.UUID;
|
||||
sog.UUID = newID;
|
||||
|
||||
// We can only call this after adding the scene object, since the scene object references the scene
|
||||
// to find out if scripts should be activated at all.
|
||||
|
||||
SceneObjectPart groot = sog.RootPart;
|
||||
|
||||
if(groot.PhysActor != null)
|
||||
groot.PhysActor.Building = true;
|
||||
|
||||
// objects rezzed with this method are die_at_edge by default.
|
||||
groot.SetDieAtEdge(true);
|
||||
|
||||
if((flags & ScriptBaseClass.REZ_FLAG_TEMP) != 0)
|
||||
groot.AddFlag(PrimFlags.TemporaryOnRez);
|
||||
else
|
||||
groot.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
||||
if(!sog.IsVolumeDetect && (flags & ScriptBaseClass.REZ_FLAG_PHYSICAL) != 0)
|
||||
{
|
||||
groot.KeyframeMotion?.Stop();
|
||||
groot.KeyframeMotion = null;
|
||||
groot.AddFlag(PrimFlags.Physics);
|
||||
}
|
||||
else
|
||||
groot.RemFlag(PrimFlags.Physics);
|
||||
|
||||
if((flags & ScriptBaseClass.REZ_FLAG_PHANTOM) != 0)
|
||||
groot.AddFlag(PrimFlags.Phantom);
|
||||
else if (!sog.IsVolumeDetect)
|
||||
groot.RemFlag(PrimFlags.Phantom);
|
||||
|
||||
sog.BlockGrabOverride = (flags & ScriptBaseClass.REZ_FLAG_BLOCK_GRAB_OBJECT) != 0;
|
||||
|
||||
if(groot.PhysActor != null)
|
||||
groot.PhysActor.Building = false;
|
||||
|
||||
sog.RezStringParameter = stringparam;
|
||||
|
||||
sog.InvalidateEffectivePerms();
|
||||
if(omegaGain > 1e-6)
|
||||
{
|
||||
groot.UpdateAngularVelocity(omega * omegaSpin);
|
||||
}
|
||||
|
||||
if(lockAxis.IsNotZero())
|
||||
{
|
||||
byte axislock = 0;
|
||||
if(lockAxis.X != 0)
|
||||
axislock = 2;
|
||||
if(lockAxis.Y != 0)
|
||||
axislock |= 4;
|
||||
if(lockAxis.X != 0)
|
||||
axislock |= 8;
|
||||
groot.RotationAxisLocks = axislock;
|
||||
}
|
||||
|
||||
if(collisionSound != null)
|
||||
{
|
||||
UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, collisionSound, AssetType.Sound);
|
||||
if(soundID.IsNotZero())
|
||||
{
|
||||
groot.CollisionSoundType = 1;
|
||||
groot.CollisionSoundVolume = CollisionSoundVol;
|
||||
groot.CollisionSound = soundID;
|
||||
}
|
||||
else
|
||||
groot.CollisionSoundType = -1;
|
||||
}
|
||||
|
||||
World.AddNewSceneObject(sog, true, pos, rot, vel);
|
||||
|
||||
sog.CreateScriptInstances(param, true, m_ScriptEngine.ScriptEngineName, 3);
|
||||
sog.ResumeScripts();
|
||||
|
||||
sog.ScheduleGroupForUpdate(PrimUpdateFlags.FullUpdatewithAnimMatOvr);
|
||||
|
||||
m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
|
||||
"object_rez",
|
||||
[
|
||||
new LSL_String(groot.UUID.ToString())
|
||||
],
|
||||
Array.Empty<DetectParams>()));
|
||||
|
||||
if(soundVol > 0 && !string.IsNullOrEmpty(sound) && m_SoundModule is not null)
|
||||
{
|
||||
UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound);
|
||||
if(soundID.IsNotZero())
|
||||
{
|
||||
if(soundLoop)
|
||||
m_SoundModule.LoopSound(groot, soundID, soundVol, false, false);
|
||||
else
|
||||
m_SoundModule.SendSound(groot, soundID, soundVol, false, 0, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
}, null, "LSL_Api.ObjectRezWithParam");
|
||||
|
||||
ScriptSleep(m_sleepMsOnRezAtRoot);
|
||||
return new(newID.ToString());
|
||||
}
|
||||
|
||||
public void llLookAt(LSL_Vector target, double strength, double damping)
|
||||
{
|
||||
SceneObjectGroup sog = m_host.ParentGroup;
|
||||
@@ -3965,6 +4472,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return m_ScriptEngine.GetStartParameter(m_item.ItemID);
|
||||
}
|
||||
|
||||
public LSL_String llGetStartString()
|
||||
{
|
||||
if(string.IsNullOrEmpty(m_host.ParentGroup.RezStringParameter))
|
||||
return LSL_String.Empty;
|
||||
return new(m_host.ParentGroup.RezStringParameter);
|
||||
}
|
||||
|
||||
public void llRequestPermissions(string agent, int perm)
|
||||
{
|
||||
if (!UUID.TryParse(agent, out UUID agentID) || agentID.IsZero())
|
||||
|
||||
@@ -1049,5 +1049,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
public const int SOUND_LOOP = 1;
|
||||
public const int SOUND_TRIGGER = 2;
|
||||
public const int SOUND_SYNC = 4;
|
||||
|
||||
//llRezObjectWithParams Parameters
|
||||
public const int REZ_PARAM = 0;
|
||||
public const int REZ_FLAGS = 1;
|
||||
|
||||
//rez flags vlaues
|
||||
public const int REZ_FLAG_TEMP = 0x0001;
|
||||
public const int REZ_FLAG_PHYSICAL = 0x0002;
|
||||
public const int REZ_FLAG_PHANTOM = 0x0004;
|
||||
public const int REZ_FLAG_DIE_ON_COLLIDE = 0x0008;
|
||||
public const int REZ_FLAG_DIE_ON_NOENTRY = 0x0010;
|
||||
public const int REZ_FLAG_NO_COLLIDE_OWNER = 0x0020;
|
||||
public const int REZ_FLAG_NO_COLLIDE_FAMILY = 0x0040;
|
||||
public const int REZ_FLAG_BLOCK_GRAB_OBJECT = 0x0080;
|
||||
|
||||
public const int REZ_POS = 2;
|
||||
public const int REZ_ROT = 3;
|
||||
public const int REZ_VEL = 4;
|
||||
public const int REZ_ACCEL = 5;
|
||||
public const int REZ_OMEGA = 7;
|
||||
public const int REZ_DAMAGE = 8;
|
||||
public const int REZ_SOUND = 9;
|
||||
public const int REZ_SOUND_COLLIDE = 10;
|
||||
public const int REZ_LOCK_AXES = 11;
|
||||
public const int REZ_DAMAGE_TYPE = 12;
|
||||
public const int REZ_PARAM_STRING = 13;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2814,5 +2814,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
{
|
||||
return m_LSL_Functions.llDerezObject(objectUUID, flag);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public LSL_Key llRezObjectWithParams(string inventory, LSL_List lparam)
|
||||
{
|
||||
return m_LSL_Functions.llRezObjectWithParams(inventory, lparam);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public LSL_String llGetStartString()
|
||||
{
|
||||
return m_LSL_Functions.llGetStartString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user