diff --git a/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs b/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs new file mode 100644 index 0000000000..f77d29a2a0 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Animation/MovementAnimationOverrides.cs @@ -0,0 +1,81 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Xml; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using System.Timers; +using Timer = System.Timers.Timer; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Region.Framework.Scenes.Types; +using OpenSim.Region.Physics.Manager; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Services.Interfaces; +using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags; + +namespace OpenSim.Region.Framework.Scenes +{ + public class MovementAnimationOverrides + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Dictionary m_overrides = new Dictionary(); + public void SetOverride(string state, UUID animID) + { + if (animID == UUID.Zero) + { + m_overrides.Remove(state); + return; + } + + m_log.DebugFormat("Setting override for {0} to {1}", state, animID); + + lock (m_overrides) + m_overrides[state] = animID; + } + + public UUID GetOverriddenAnimation(string state) + { + lock (m_overrides) + { + if (m_overrides.ContainsKey(state)) + return m_overrides[state]; + } + + return UUID.Zero; + } + } +} diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index fdadd32726..9fd5e645d5 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -196,7 +196,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation // "[SCENE PRESENCE ANIMATOR]: Setting movement animation {0} for {1}", // anim, m_scenePresence.Name); - if (m_animations.TrySetDefaultAnimation( + UUID overridenAnim = m_scenePresence.Overrides.GetOverriddenAnimation(anim); + if (overridenAnim != UUID.Zero) + { + m_animations.SetDefaultAnimation(overridenAnim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID); + m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); + SendAnimPack(); + ret = true; + } + else if (m_animations.TrySetDefaultAnimation( anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { // m_log.DebugFormat( diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f3e6e89c7e..4aa38bec6d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -239,6 +239,11 @@ namespace OpenSim.Region.Framework.Scenes /// public ScenePresenceAnimator Animator { get; private set; } + /// + /// Server Side Animation Override + /// + public MovementAnimationOverrides Overrides { get; private set; } + /// /// Attachments recorded on this avatar. /// @@ -967,6 +972,7 @@ namespace OpenSim.Region.Framework.Scenes IsLoggingIn = false; m_sendCoarseLocationsMethod = SendCoarseLocationsDefault; Animator = new ScenePresenceAnimator(this); + Overrides = new MovementAnimationOverrides(); PresenceType = type; DrawDistance = world.DefaultDrawDistance; RegionHandle = world.RegionInfo.RegionHandle; @@ -6028,6 +6034,7 @@ namespace OpenSim.Region.Framework.Scenes public void SetAnimationOverride(string animState, UUID animID) { + Overrides.SetOverride(animState, animID); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1fb4c1ba53..ef8f0ed274 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -13508,7 +13508,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (m_item.PermsGranter == UUID.Zero) + { + llShout(ScriptBaseClass.DEBUG_CHANNEL, "No permission to override animations"); return; + } if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_OVERRIDE_ANIMATIONS) == 0) { @@ -13521,11 +13524,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (presence == null) return; - UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); - if (animID == UUID.Zero) + UUID animID; + if (animState == anim) { - llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found"); - return; + animID = UUID.Zero; + } + else if (MovementAnimationsForLSL.ContainsKey(anim)) + { + animID = DefaultAvatarAnimations.AnimsUUID[MovementAnimationsForLSL[anim]]; + } + else + { + animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation); + if (animID == UUID.Zero) + { + llShout(ScriptBaseClass.DEBUG_CHANNEL, "Animation not found"); + return; + } } presence.SetAnimationOverride(state, animID);