* Now we have boxes. Yay!
* Removed unused SendPrimitiveToClient that didn't have rot.afrisby
parent
9bdeb8af6f
commit
95de99ff0a
|
@ -199,8 +199,7 @@ namespace OpenSim.Framework.Interfaces
|
|||
void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity);
|
||||
|
||||
void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint);
|
||||
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLQuaternion rotation, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem);
|
||||
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem);
|
||||
void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation);
|
||||
void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation);
|
||||
|
||||
void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List<InventoryItemBase> items);
|
||||
|
|
|
@ -130,8 +130,7 @@ namespace OpenSim.Framework
|
|||
public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity){}
|
||||
|
||||
public virtual void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint){}
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLQuaternion rotation, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem){}
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem){}
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation){}
|
||||
public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation){}
|
||||
|
||||
public virtual void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List<InventoryItemBase> items){}
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace OpenSim.Framework.Types
|
|||
PathCurve = 16;
|
||||
ProfileCurve = 1;
|
||||
PCode = 9;
|
||||
PathScaleX = 100;
|
||||
PathScaleY = 100;
|
||||
}
|
||||
|
||||
public static BoxShape Default
|
||||
|
@ -104,10 +106,6 @@ namespace OpenSim.Framework.Types
|
|||
|
||||
boxShape.Scale = new LLVector3(0.5f, 0.5f, 0.5f);
|
||||
|
||||
//boxShape.PathTaperX = 1;
|
||||
//boxShape.PathTaperY = 1;
|
||||
boxShape.PathSkew = 1;
|
||||
|
||||
return boxShape;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -673,6 +673,8 @@ namespace OpenSim.Region.ClientStack
|
|||
OutPacket(loadURL);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Appearance/ Wearables Methods
|
||||
|
||||
/// <summary>
|
||||
|
@ -817,44 +819,33 @@ namespace OpenSim.Region.ClientStack
|
|||
this.OutPacket(attach);
|
||||
}
|
||||
|
||||
public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLQuaternion rotation, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem)
|
||||
public void SendPrimitiveToClient(
|
||||
ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags,
|
||||
LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation)
|
||||
{
|
||||
ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
|
||||
outPacket.RegionData.RegionHandle = regionHandle;
|
||||
outPacket.RegionData.TimeDilation = timeDilation;
|
||||
outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
|
||||
outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primShape, flags);
|
||||
|
||||
outPacket.ObjectData[0].ID = localID;
|
||||
outPacket.ObjectData[0].FullID = objectID;
|
||||
outPacket.ObjectData[0].OwnerID = ownerID;
|
||||
outPacket.ObjectData[0].Text = Helpers.StringToField( text );
|
||||
outPacket.ObjectData[0].ParentID = parentID;
|
||||
outPacket.ObjectData[0].PSBlock = particleSystem;
|
||||
|
||||
byte[] pb = pos.GetBytes();
|
||||
Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
|
||||
|
||||
byte[] rot = rotation.GetBytes();
|
||||
Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 36, rot.Length);
|
||||
OutPacket(outPacket);
|
||||
}
|
||||
|
||||
public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem)
|
||||
{
|
||||
ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
|
||||
outPacket.RegionData.RegionHandle = regionHandle;
|
||||
outPacket.RegionData.TimeDilation = timeDilation;
|
||||
outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
|
||||
outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primShape, flags);
|
||||
outPacket.ObjectData[0].ID = localID;
|
||||
outPacket.ObjectData[0].FullID = objectID;
|
||||
outPacket.ObjectData[0].OwnerID = ownerID;
|
||||
outPacket.ObjectData[0].Text = Helpers.StringToField( text );
|
||||
outPacket.ObjectData[0].ParentID = parentID;
|
||||
outPacket.ObjectData[0].PSBlock = particleSystem;
|
||||
byte[] pb = pos.GetBytes();
|
||||
Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
|
||||
|
||||
OutPacket(outPacket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -876,8 +867,6 @@ namespace OpenSim.Region.ClientStack
|
|||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos, LLVector3 velocity)
|
||||
|
@ -1163,8 +1152,6 @@ namespace OpenSim.Region.ClientStack
|
|||
objdata.ObjectData[64] = 189;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SendNameReply(LLUUID profileId, string firstname, string lastname)
|
||||
{
|
||||
UUIDNameReplyPacket packet = new UUIDNameReplyPacket();
|
||||
|
@ -1177,5 +1164,8 @@ namespace OpenSim.Region.ClientStack
|
|||
|
||||
OutPacket( packet );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,30 +218,7 @@ namespace OpenSim.Region.ClientStack
|
|||
if (OnAddPrim != null)
|
||||
{
|
||||
ObjectAddPacket addPacket = (ObjectAddPacket) Pack ;
|
||||
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
||||
|
||||
shape.PCode = addPacket.ObjectData.PCode;
|
||||
shape.PathBegin = addPacket.ObjectData.PathBegin;
|
||||
shape.PathEnd = addPacket.ObjectData.PathEnd;
|
||||
shape.PathScaleX = addPacket.ObjectData.PathScaleX;
|
||||
shape.PathScaleY = addPacket.ObjectData.PathScaleY;
|
||||
shape.PathShearX = addPacket.ObjectData.PathShearX;
|
||||
shape.PathShearY = addPacket.ObjectData.PathShearY;
|
||||
shape.PathSkew = addPacket.ObjectData.PathSkew;
|
||||
shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
|
||||
shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
|
||||
shape.Scale = addPacket.ObjectData.Scale;
|
||||
shape.PathCurve = addPacket.ObjectData.PathCurve;
|
||||
shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
|
||||
shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
|
||||
shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
|
||||
shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
|
||||
shape.PathTaperX = addPacket.ObjectData.PathTaperX;
|
||||
shape.PathTaperY = addPacket.ObjectData.PathTaperY;
|
||||
shape.PathTwist = addPacket.ObjectData.PathTwist;
|
||||
shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
|
||||
LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005"));
|
||||
shape.TextureEntry = ntex.ToBytes();
|
||||
PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket);
|
||||
|
||||
OnAddPrim(this.AgentId, addPacket.ObjectData.RayEnd, shape);
|
||||
}
|
||||
|
@ -624,5 +601,34 @@ namespace OpenSim.Region.ClientStack
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
|
||||
{
|
||||
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
||||
|
||||
shape.PCode = addPacket.ObjectData.PCode;
|
||||
shape.PathBegin = addPacket.ObjectData.PathBegin;
|
||||
shape.PathEnd = addPacket.ObjectData.PathEnd;
|
||||
shape.PathScaleX = addPacket.ObjectData.PathScaleX;
|
||||
shape.PathScaleY = addPacket.ObjectData.PathScaleY;
|
||||
shape.PathShearX = addPacket.ObjectData.PathShearX;
|
||||
shape.PathShearY = addPacket.ObjectData.PathShearY;
|
||||
shape.PathSkew = addPacket.ObjectData.PathSkew;
|
||||
shape.ProfileBegin = addPacket.ObjectData.ProfileBegin;
|
||||
shape.ProfileEnd = addPacket.ObjectData.ProfileEnd;
|
||||
shape.Scale = addPacket.ObjectData.Scale;
|
||||
shape.PathCurve = addPacket.ObjectData.PathCurve;
|
||||
shape.ProfileCurve = addPacket.ObjectData.ProfileCurve;
|
||||
shape.ProfileHollow = addPacket.ObjectData.ProfileHollow;
|
||||
shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
|
||||
shape.PathRevolutions = addPacket.ObjectData.PathRevolutions;
|
||||
shape.PathTaperX = addPacket.ObjectData.PathTaperX;
|
||||
shape.PathTaperY = addPacket.ObjectData.PathTaperY;
|
||||
shape.PathTwist = addPacket.ObjectData.PathTwist;
|
||||
shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
|
||||
LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005"));
|
||||
shape.TextureEntry = ntex.ToBytes();
|
||||
return shape;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,8 +438,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
LLQuaternion lRot;
|
||||
lRot = RotationOffset;
|
||||
|
||||
remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalID, m_shape, lPos, lRot, this.ObjectFlags, m_uuid,
|
||||
OwnerID, m_text, ParentID, this.m_particleSystem);
|
||||
remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalID, m_shape, lPos, this.ObjectFlags, m_uuid, OwnerID,
|
||||
m_text, ParentID, this.m_particleSystem, lRot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
public uint EveryoneMask = 0;//FULL_MASK_PERMISSIONS;
|
||||
public uint BaseMask = 0;//FULL_MASK_PERMISSIONS;
|
||||
|
||||
private PrimitiveBaseShape m_Shape;
|
||||
private PrimitiveBaseShape m_shape;
|
||||
private byte[] m_particleSystem = new byte[0];
|
||||
|
||||
public SceneObject m_RootParent;
|
||||
|
@ -83,7 +83,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
public PrimitiveBaseShape Shape
|
||||
{
|
||||
get { return m_Shape; }
|
||||
get { return m_shape; }
|
||||
}
|
||||
|
||||
public LLVector3 WorldPos
|
||||
|
@ -112,8 +112,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
public LLVector3 Scale
|
||||
{
|
||||
set { m_Shape.Scale = value; }
|
||||
get { return m_Shape.Scale; }
|
||||
set { m_shape.Scale = value; }
|
||||
get { return m_shape.Scale; }
|
||||
}
|
||||
|
||||
private string m_sitName = "";
|
||||
|
@ -195,7 +195,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
dupe.m_inventoryItems = m_inventoryItems;
|
||||
dupe.m_children = new List<EntityBase>();
|
||||
dupe.m_Shape = m_Shape.Copy();
|
||||
dupe.m_shape = m_shape.Copy();
|
||||
dupe.m_regionHandle = m_regionHandle;
|
||||
dupe.m_scene = m_scene;
|
||||
|
||||
|
@ -288,7 +288,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
m_uuid = LLUUID.Random();
|
||||
m_localId = (uint)(localID);
|
||||
|
||||
m_Shape = shape;
|
||||
m_shape = shape;
|
||||
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="scale"></param>
|
||||
public void ResizeGoup(LLVector3 scale)
|
||||
{
|
||||
m_Shape.Scale = scale;
|
||||
m_shape.Scale = scale;
|
||||
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
|
@ -545,24 +545,24 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="shapeBlock"></param>
|
||||
public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock)
|
||||
{
|
||||
m_Shape.PathBegin = shapeBlock.PathBegin;
|
||||
m_Shape.PathEnd = shapeBlock.PathEnd;
|
||||
m_Shape.PathScaleX = shapeBlock.PathScaleX;
|
||||
m_Shape.PathScaleY = shapeBlock.PathScaleY;
|
||||
m_Shape.PathShearX = shapeBlock.PathShearX;
|
||||
m_Shape.PathShearY = shapeBlock.PathShearY;
|
||||
m_Shape.PathSkew = shapeBlock.PathSkew;
|
||||
m_Shape.ProfileBegin = shapeBlock.ProfileBegin;
|
||||
m_Shape.ProfileEnd = shapeBlock.ProfileEnd;
|
||||
m_Shape.PathCurve = shapeBlock.PathCurve;
|
||||
m_Shape.ProfileCurve = shapeBlock.ProfileCurve;
|
||||
m_Shape.ProfileHollow = shapeBlock.ProfileHollow;
|
||||
m_Shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
|
||||
m_Shape.PathRevolutions = shapeBlock.PathRevolutions;
|
||||
m_Shape.PathTaperX = shapeBlock.PathTaperX;
|
||||
m_Shape.PathTaperY = shapeBlock.PathTaperY;
|
||||
m_Shape.PathTwist = shapeBlock.PathTwist;
|
||||
m_Shape.PathTwistBegin = shapeBlock.PathTwistBegin;
|
||||
m_shape.PathBegin = shapeBlock.PathBegin;
|
||||
m_shape.PathEnd = shapeBlock.PathEnd;
|
||||
m_shape.PathScaleX = shapeBlock.PathScaleX;
|
||||
m_shape.PathScaleY = shapeBlock.PathScaleY;
|
||||
m_shape.PathShearX = shapeBlock.PathShearX;
|
||||
m_shape.PathShearY = shapeBlock.PathShearY;
|
||||
m_shape.PathSkew = shapeBlock.PathSkew;
|
||||
m_shape.ProfileBegin = shapeBlock.ProfileBegin;
|
||||
m_shape.ProfileEnd = shapeBlock.ProfileEnd;
|
||||
m_shape.PathCurve = shapeBlock.PathCurve;
|
||||
m_shape.ProfileCurve = shapeBlock.ProfileCurve;
|
||||
m_shape.ProfileHollow = shapeBlock.ProfileHollow;
|
||||
m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset;
|
||||
m_shape.PathRevolutions = shapeBlock.PathRevolutions;
|
||||
m_shape.PathTaperX = shapeBlock.PathTaperX;
|
||||
m_shape.PathTaperY = shapeBlock.PathTaperY;
|
||||
m_shape.PathTwist = shapeBlock.PathTwist;
|
||||
m_shape.PathTwistBegin = shapeBlock.PathTwistBegin;
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
|
@ -580,18 +580,18 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
|
||||
public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
|
||||
{
|
||||
this.m_Shape.ExtraParams = new byte[data.Length + 7];
|
||||
this.m_shape.ExtraParams = new byte[data.Length + 7];
|
||||
int i =0;
|
||||
uint length = (uint) data.Length;
|
||||
this.m_Shape.ExtraParams[i++] = 1;
|
||||
this.m_Shape.ExtraParams[i++] = (byte)(type % 256);
|
||||
this.m_Shape.ExtraParams[i++] = (byte)((type >> 8) % 256);
|
||||
this.m_shape.ExtraParams[i++] = 1;
|
||||
this.m_shape.ExtraParams[i++] = (byte)(type % 256);
|
||||
this.m_shape.ExtraParams[i++] = (byte)((type >> 8) % 256);
|
||||
|
||||
this.m_Shape.ExtraParams[i++] = (byte)(length % 256);
|
||||
this.m_Shape.ExtraParams[i++] = (byte)((length >> 8) % 256);
|
||||
this.m_Shape.ExtraParams[i++] = (byte)((length >> 16) % 256);
|
||||
this.m_Shape.ExtraParams[i++] = (byte)((length >> 24) % 256);
|
||||
Array.Copy(data, 0, this.m_Shape.ExtraParams, i, data.Length);
|
||||
this.m_shape.ExtraParams[i++] = (byte)(length % 256);
|
||||
this.m_shape.ExtraParams[i++] = (byte)((length >> 8) % 256);
|
||||
this.m_shape.ExtraParams[i++] = (byte)((length >> 16) % 256);
|
||||
this.m_shape.ExtraParams[i++] = (byte)((length >> 24) % 256);
|
||||
Array.Copy(data, 0, this.m_shape.ExtraParams, i, data.Length);
|
||||
|
||||
this.ScheduleFullUpdate();
|
||||
}
|
||||
|
@ -604,7 +604,7 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
/// <param name="textureEntry"></param>
|
||||
public void UpdateTextureEntry(byte[] textureEntry)
|
||||
{
|
||||
m_Shape.TextureEntry = textureEntry;
|
||||
m_shape.TextureEntry = textureEntry;
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
|
@ -648,8 +648,8 @@ namespace OpenSim.Region.Environment.Scenes
|
|||
LLQuaternion lRot;
|
||||
lRot = new LLQuaternion(Rotation.x, Rotation.y, Rotation.z, Rotation.w);
|
||||
|
||||
remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalId, m_Shape, lPos, lRot, m_flags, m_uuid,
|
||||
OwnerID, m_text, ParentID, this.m_particleSystem);
|
||||
remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalId, m_shape, lPos, m_flags, m_uuid, OwnerID,
|
||||
m_text, ParentID, this.m_particleSystem, lRot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -145,8 +145,7 @@ namespace SimpleApp
|
|||
|
||||
public virtual void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint) { }
|
||||
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, LLQuaternion rotation, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem) { }
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem) { }
|
||||
public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation) { }
|
||||
public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation) { }
|
||||
|
||||
public virtual void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List<InventoryItemBase> items) { }
|
||||
|
|
Loading…
Reference in New Issue