diff --git a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs index e4b48c4305..2e9d14740d 100644 --- a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs +++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs @@ -282,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.LightShare }); } - public void WindlightRefresh(IScenePresence isp, int interpolate) + public void WindlightRefreshForced(IScenePresence isp, int interpolate) { List ls = null; @@ -298,18 +298,11 @@ namespace OpenSim.Region.CoreModules.World.LightShare ScenePresence sp = isp as ScenePresence; ILandObject lo = m_scene.LandChannel.GetLandObject(sp.AbsolutePosition.X, sp.AbsolutePosition.Y); if (lo != null && lo.LandData != null && lo.LandData.Environment != null) - { lo.SendLandUpdateToClient(client); - if (sp.Environment != null) - m_estateModule.HandleRegionInfoRequest(client); - } - else - m_estateModule.HandleRegionInfoRequest(client); + m_estateModule.HandleRegionInfoRequest(client); } - else if ((vflags & 0x4000) != 0) m_eventQueue.WindlightRefreshEvent(interpolate, client.AgentId); - else { if (ls == null) diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs index 75483f1a15..060f1b91db 100644 --- a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces RegionLightShareData ToLightShare(); byte[] GetDefaultAssetData(int type); void WindlightRefresh(int interpolate, bool notforparcel = true); - void WindlightRefresh(IScenePresence sp, int interpolate); + void WindlightRefreshForced(IScenePresence sp, int interpolate); ViewerEnvironment GetRegionEnvironment(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ce9b7cc5a6..f59ed2a22e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -100,7 +100,7 @@ namespace OpenSim.Region.Framework.Scenes else { if(EnvironmentVersion <= 0) - EnvironmentVersion = 0x7000000; + EnvironmentVersion = 0x7000000 | Util.RandomClass.Next(); else ++EnvironmentVersion; m_environment.version = EnvironmentVersion; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 378351e766..caa1d9ec22 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5899,7 +5899,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if(string.IsNullOrEmpty(daycycle) || daycycle == UUID.Zero.ToString()) { sp.Environment = null; - m_envModule.WindlightRefresh(sp, transition); + m_envModule.WindlightRefreshForced(sp, transition); return 1; } @@ -5918,15 +5918,182 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if(!VEnv.CycleFromOSD(oenv)) return -3; sp.Environment = VEnv; - m_envModule.WindlightRefresh(sp, transition); + m_envModule.WindlightRefreshForced(sp, transition); } catch { sp.Environment = null; - m_envModule.WindlightRefresh(sp, transition); + m_envModule.WindlightRefreshForced(sp, transition); return -9; } return 1; } + + public LSL_Integer osReplaceParcelEnvironment(LSL_Integer transition, LSL_String daycycle) + { + m_host.AddScriptLPS(1); + + if (!World.RegionInfo.EstateSettings.AllowEnvironmentOverride) + return -1; + + ILandObject parcel = World.LandChannel.GetLandObject(m_host.GetWorldPosition().X, m_host.GetWorldPosition().Y); + if (parcel == null) + return -2; + + if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, parcel, (GroupPowers.AllowEnvironment | GroupPowers.LandEdit), true)) + return -3; + + ViewerEnvironment VEnv; + if (parcel.LandData.Environment == null) + VEnv = m_envModule.GetRegionEnvironment().Clone(); + else + VEnv = parcel.LandData.Environment; + + bool changed = false; + if (!string.IsNullOrEmpty(daycycle) || !(daycycle == UUID.Zero.ToString())) + { + + UUID envID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, daycycle); + if (envID == UUID.Zero) + return -4; + + AssetBase asset = World.AssetService.Get(envID.ToString()); + if (asset == null || asset.Type != (byte)AssetType.Settings) + return -4; + // cant use stupid broken asset flags for subtype + try + { + OSD oenv = OSDParser.Deserialize(asset.Data); + if (!VEnv.CycleFromOSD(oenv)) + return -5; + changed = true; + } + catch + { + return -5; + } + } + + if (changed) + { + parcel.StoreEnvironment(VEnv); + m_envModule.WindlightRefresh(transition, false); + } + + return 1; + } + + public LSL_Integer osReplaceRegionEnvironment(LSL_Integer transition, LSL_String daycycle, + LSL_Float daylen, LSL_Float dayoffset, + LSL_Float altitude1, LSL_Float altitude2, LSL_Float altitude3) + { + m_host.AddScriptLPS(1); + + if (!World.Permissions.CanIssueEstateCommand(m_host.OwnerID, true)) + return -3; + + ViewerEnvironment VEnv = m_envModule.GetRegionEnvironment().Clone(); + + bool changed = false; + if (!string.IsNullOrEmpty(daycycle) || !(daycycle == UUID.Zero.ToString())) + { + + UUID envID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, daycycle); + if (envID == UUID.Zero) + return -4; + + AssetBase asset = World.AssetService.Get(envID.ToString()); + if (asset == null || asset.Type != (byte)AssetType.Settings) + return -4; + // cant use stupid broken asset flags for subtype + try + { + OSD oenv = OSDParser.Deserialize(asset.Data); + if (!VEnv.CycleFromOSD(oenv)) + return -5; + changed = true; + } + catch + { + return -5; + } + } + + if (daylen >= 4 && daylen <= 24 * 7) + { + int ll = VEnv.DayLength; + VEnv.DayLength = (int)(daylen * 3600f); + changed = ll != VEnv.DayLength; + } + + if (dayoffset >= -11.5 && dayoffset <= 11.5) + { + int lo = VEnv.DayLength; + if (dayoffset <= 0) + dayoffset+= 24; + VEnv.DayLength = (int)(dayoffset * 3600f); + changed = lo != VEnv.DayOffset; + } + + bool needSort = false; + if (altitude1 > 0 && altitude1 < 4000 && VEnv.Altitudes[0] != (float)altitude1) + { + VEnv.Altitudes[0] = (float)altitude1; + needSort = true; + } + if (altitude2 > 0 && altitude2 < 4000 && VEnv.Altitudes[1] != (float)altitude2) + { + VEnv.Altitudes[1] = (float)altitude2; + needSort = true; + } + if (altitude3 > 0 && altitude2 < 4000 && VEnv.Altitudes[2] != (float)altitude3) + { + VEnv.Altitudes[2] = (float)altitude3; + needSort = true; + } + if(needSort) + { + VEnv.SortAltitudes(); + changed = true; + } + + if(changed) + { + m_envModule.StoreOnRegion(VEnv); + m_envModule.WindlightRefresh(transition); + } + return 1; + } + + public LSL_Integer osResetEnvironment(LSL_Integer parcelOrRegion, LSL_Integer transition) + { + m_host.AddScriptLPS(1); + + if (parcelOrRegion > 0) + { + if (!World.RegionInfo.EstateSettings.AllowEnvironmentOverride) + return -1; + + ILandObject parcel = World.LandChannel.GetLandObject(m_host.GetWorldPosition().X, m_host.GetWorldPosition().Y); + if (parcel == null) + return -2; + + if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, parcel, (GroupPowers.AllowEnvironment | GroupPowers.LandEdit), true)) + return -3; + if (parcel.LandData.Environment == null) + return 1; + + parcel.StoreEnvironment(null); + m_envModule.WindlightRefresh(transition, false); + return 1; + } + + if (!World.Permissions.CanIssueEstateCommand(m_host.OwnerID, true)) + return -3; + + m_envModule.StoreOnRegion(null); + m_envModule.WindlightRefresh(transition); + return 1; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 5dadf0886c..6be5022d50 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -580,5 +580,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osGetApparentRegionTimeString(LSL_Integer format24); LSL_Integer osReplaceAgentEnvironment(LSL_Key agentkey, LSL_Integer transition, LSL_String daycycle); + LSL_Integer osReplaceParcelEnvironment(LSL_Integer transition, LSL_String daycycle); + LSL_Integer osReplaceRegionEnvironment(LSL_Integer transition, LSL_String daycycle, + LSL_Float daylen, LSL_Float dayoffset, LSL_Float altitude1, LSL_Float altitude2, LSL_Float altitude3); + LSL_Integer osResetEnvironment(LSL_Integer parcelOrRegion, LSL_Integer transition); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index e0498efda0..c0d7def32c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1506,5 +1506,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osReplaceAgentEnvironment(agentkey, transition, daycycle); } + + public LSL_Integer osReplaceParcelEnvironment(LSL_Integer transition, LSL_String daycycle) + { + return m_OSSL_Functions.osReplaceParcelEnvironment(transition, daycycle); + } + + public LSL_Integer osReplaceRegionEnvironment(LSL_Integer transition, LSL_String daycycle, + LSL_Float daylen, LSL_Float dayoffset, LSL_Float altitude1, LSL_Float altitude2, LSL_Float altitude3) + { + return m_OSSL_Functions.osReplaceRegionEnvironment(transition, daycycle, daylen, + dayoffset, altitude1, altitude2, altitude3); + } + + public LSL_Integer osResetEnvironment(LSL_Integer parcelOrRegion, LSL_Integer transition) + { + return m_OSSL_Functions.osResetEnvironment(parcelOrRegion, transition); + } } }