OSDN Git Service

Silence too verbose debug
[radegast/radegast.git] / Radegast / Core / StateManager.cs
index 1ef9da1..4387a57 100644 (file)
@@ -1,6 +1,6 @@
 // 
 // Radegast Metaverse Client
-// Copyright (c) 2009-2012, Radegast Development Team
+// Copyright (c) 2009-2014, Radegast Development Team
 // All rights reserved.
 // 
 // Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,7 @@ using System.Threading;
 
 using OpenMetaverse;
 
-using Radegast.Bot;
+using Radegast.Automation;
 using Radegast.Netcom;
 
 namespace Radegast
@@ -45,6 +45,7 @@ namespace Radegast
         public string ID { get; set; }
         public string Name { get; set; }
         public Quaternion Heading { get; set; }
+
         public KnownHeading(string id, string name, Quaternion heading)
         {
             this.ID = id;
@@ -85,6 +86,8 @@ namespace Radegast
         internal static Random rnd = new Random();
         private System.Threading.Timer lookAtTimer;
 
+        public float FOVVerticalAngle = Utils.TWO_PI - 0.05f;
+
         /// <summary>
         /// Passes walk state
         /// </summary>
@@ -183,6 +186,8 @@ namespace Radegast
         }
 
         public Dictionary<UUID, string> KnownAnimations;
+        public bool CameraTracksOwnAvatar = true;
+        public Vector3 DefaultCameraOffset = new Vector3(-5, 0, 0);
 
         public StateManager(RadegastInstance instance)
         {
@@ -190,6 +195,8 @@ namespace Radegast
             this.instance.ClientChanged += new EventHandler<ClientChangedEventArgs>(instance_ClientChanged);
             KnownAnimations = Animations.ToDictionary();
             autosit = new AutoSit(this.instance);
+            pseudohome = new PseudoHome(this.instance);
+            lslHelper = new LSLHelper(this.instance);
 
             beamTimer = new System.Timers.Timer();
             beamTimer.Enabled = false;
@@ -205,6 +212,7 @@ namespace Radegast
 
         private void RegisterClientEvents(GridClient client)
         {
+            client.Objects.AvatarUpdate += new EventHandler<AvatarUpdateEventArgs>(Objects_AvatarUpdate);
             client.Objects.TerseObjectUpdate += new EventHandler<TerseObjectUpdateEventArgs>(Objects_TerseObjectUpdate);
             client.Objects.AvatarSitChanged += new EventHandler<AvatarSitChangedEventArgs>(Objects_AvatarSitChanged);
             client.Self.AlertMessage += new EventHandler<AlertMessageEventArgs>(Self_AlertMessage);
@@ -215,6 +223,7 @@ namespace Radegast
 
         private void UnregisterClientEvents(GridClient client)
         {
+            client.Objects.AvatarUpdate -= new EventHandler<AvatarUpdateEventArgs>(Objects_AvatarUpdate);
             client.Objects.TerseObjectUpdate -= new EventHandler<TerseObjectUpdateEventArgs>(Objects_TerseObjectUpdate);
             client.Objects.AvatarSitChanged -= new EventHandler<AvatarSitChangedEventArgs>(Objects_AvatarSitChanged);
             client.Self.AlertMessage -= new EventHandler<AlertMessageEventArgs>(Self_AlertMessage);
@@ -243,6 +252,18 @@ namespace Radegast
                 walkTimer.Dispose();
                 walkTimer = null;
             }
+
+            if (autosit != null)
+            {
+                autosit.Dispose();
+                autosit = null;
+            }
+
+            if (lslHelper == null)
+            {
+                lslHelper.Dispose();
+                lslHelper = null;
+            }
         }
 
         void instance_ClientChanged(object sender, ClientChangedEventArgs e)
@@ -255,7 +276,13 @@ namespace Radegast
         {
             if (e.Avatar.LocalID != client.Self.LocalID) return;
 
-            this.sitting = e.SittingOn != 0;
+            sitting = e.SittingOn != 0;
+
+            if (client.Self.SittingOn != 0 && !client.Network.CurrentSim.ObjectsPrimitives.ContainsKey(client.Self.SittingOn))
+            {
+                client.Objects.RequestObject(client.Network.CurrentSim, client.Self.SittingOn);
+            }
+
             if (SitStateChanged != null)
             {
                 SitStateChanged(this, new SitEventArgs(this.sitting));
@@ -271,7 +298,29 @@ namespace Radegast
         public bool TryFindAvatar(UUID person, out Vector3 position)
         {
             Simulator sim;
-            return TryFindAvatar(person, out sim, out position);
+            if (!TryFindAvatar(person, out sim, out position)) return false;
+            // same sim?
+            if (sim == client.Network.CurrentSim) return true;
+            position = ToLocalPosition(sim.Handle, position);
+            return true;
+        }
+
+        public Vector3 ToLocalPosition(ulong handle, Vector3 position)
+        {
+            Vector3d diff = ToVector3D(handle, position) - client.Self.GlobalPosition;
+            position = new Vector3((float) diff.X, (float) diff.Y, (float) diff.Z) - position;
+            return position;
+        }
+
+        public static Vector3d ToVector3D(ulong handle, Vector3 pos)
+        {
+            uint globalX, globalY;
+            Utils.LongToUInts(handle, out globalX, out globalY);
+
+            return new Vector3d(
+                (double)globalX + (double)pos.X,
+                (double)globalY + (double)pos.Y,
+                (double)pos.Z);
         }
 
         /// <summary>
@@ -341,6 +390,7 @@ namespace Radegast
                     if (s.AvatarPositions.ContainsKey(person))
                     {
                         position = s.AvatarPositions[person];
+                        sim = s;
                         break;
                     }
                 }
@@ -352,6 +402,47 @@ namespace Radegast
                 return false;
         }
 
+        public bool TryLocatePrim(Primitive avi, out Simulator sim, out Vector3 position)
+        {
+            Simulator[] Simulators = null;
+            lock (client.Network.Simulators)
+            {
+                Simulators = client.Network.Simulators.ToArray();
+            }
+
+            sim = client.Network.CurrentSim;
+            position = Vector3.Zero;
+            {
+                foreach (var s in Simulators)
+                {
+                    if (s.Handle == avi.RegionHandle)
+                    {
+                        sim = s;
+                        break;
+                    }
+                }
+            }
+            if (avi != null)
+            {
+                if (avi.ParentID == 0)
+                {
+                    position = avi.Position;
+                }
+                else
+                {
+                    Primitive seat;
+                    if (sim.ObjectsPrimitives.TryGetValue(avi.ParentID, out seat))
+                    {
+                        position = seat.Position + avi.Position*seat.Rotation;
+                    }
+                }
+            }
+            if (position.Z > 0.1f)
+                return true;
+            else
+                return false;
+        }
+
         /// <summary>
         /// Move to target position either by walking or by teleporting
         /// </summary>
@@ -401,7 +492,13 @@ namespace Radegast
 
         void Network_SimChanged(object sender, SimChangedEventArgs e)
         {
-            autosit.TrySit();
+            WorkPool.QueueUserWorkItem(sync =>
+            {
+                Thread.Sleep(15 * 1000);
+                autosit.TrySit();
+                pseudohome.ETGoHome();
+            });
+            client.Self.Movement.SetFOVVerticalAngle(FOVVerticalAngle);
         }
 
         private UUID teleportEffect = UUID.Random();
@@ -454,9 +551,23 @@ namespace Radegast
             }
         }
 
+        void Objects_AvatarUpdate(object sender, AvatarUpdateEventArgs e)
+        {
+            if (e.Avatar.LocalID == client.Self.LocalID)
+            {
+                SetDefaultCamera();
+            }
+        }
+
         void Objects_TerseObjectUpdate(object sender, TerseObjectUpdateEventArgs e)
         {
             if (!e.Update.Avatar) return;
+            
+            if (e.Prim.LocalID == client.Self.LocalID)
+            {
+                SetDefaultCamera();
+            }
+
             if (!following) return;
 
             Avatar av;
@@ -487,6 +598,28 @@ namespace Radegast
             }
         }
 
+        public void SetDefaultCamera()
+        {
+            if (CameraTracksOwnAvatar)
+            {
+                if (client.Self.SittingOn != 0 && !client.Network.CurrentSim.ObjectsPrimitives.ContainsKey(client.Self.SittingOn))
+                {
+                    // We are sitting but don't have the information about the object we are sitting on
+                    // Sim seems to ignore RequestMutlipleObjects message
+                    // client.Objects.RequestObject(client.Network.CurrentSim, client.Self.SittingOn);
+                }
+                else
+                {
+                    Vector3 pos = client.Self.SimPosition + DefaultCameraOffset * client.Self.Movement.BodyRotation;
+                    //Logger.Log("Setting camera position to " + pos.ToString(), Helpers.LogLevel.Debug);
+                    client.Self.Movement.Camera.LookAt(
+                        pos,
+                        client.Self.SimPosition
+                    );
+                }
+            }
+        }
+
         public Quaternion AvatarRotation(Simulator sim, UUID avID)
         {
             Quaternion rot = Quaternion.Identity;
@@ -602,6 +735,8 @@ namespace Radegast
 
         void netcom_ChatReceived(object sender, ChatEventArgs e)
         {
+            //somehow it can be too early (when Radegast is loaded from running bot)
+            if (instance.GlobalSettings==null) return;
             if (!instance.GlobalSettings["disable_look_at"]
                 && e.SourceID != client.Self.AgentID
                 && (e.SourceType == ChatSourceType.Agent || e.Type == ChatType.StartTyping))
@@ -633,6 +768,19 @@ namespace Radegast
         {
             WalkTo(GlobalPosition(prim));
         }
+        public double WaitUntilPosition(Vector3d pos, TimeSpan maxWait, double howClose)
+        {
+             
+            DateTime until = DateTime.Now + maxWait;
+            while (until > DateTime.Now)
+            {
+                double dist = Vector3d.Distance(client.Self.GlobalPosition, pos);
+                if (howClose >= dist) return dist;
+                Thread.Sleep(250);
+            }
+            return Vector3d.Distance(client.Self.GlobalPosition, pos);
+            
+        }
 
         public void WalkTo(Vector3d globalPos)
         {
@@ -679,7 +827,7 @@ namespace Radegast
                     EndWalking();
                     return;
                 }
-                walkTimer.Change(walkChekInterval, Timeout.Infinite);
+                if (walkTimer != null) walkTimer.Change(walkChekInterval, Timeout.Infinite);
             }
         }
 
@@ -756,6 +904,7 @@ namespace Radegast
             awayAnim.Add(awayAnimationID, away);
 
             client.Self.Animate(awayAnim, true);
+            if (UseMoveControl) client.Self.Movement.Away = away;
             this.away = away;
         }
 
@@ -830,7 +979,7 @@ namespace Radegast
             }
         }
 
-        public Vector3d GlobalPosition(Simulator sim, Vector3 pos)
+        static public Vector3d GlobalPosition(Simulator sim, Vector3 pos)
         {
             uint globalX, globalY;
             Utils.LongToUInts(sim.Handle, out globalX, out globalY);
@@ -980,7 +1129,11 @@ namespace Radegast
 
         public bool IsAway
         {
-            get { return away; }
+            get
+            {
+                if (UseMoveControl) return client.Self.Movement.Away;
+                return away;
+            }
         }
 
         public bool IsBusy
@@ -990,12 +1143,20 @@ namespace Radegast
 
         public bool IsFlying
         {
-            get { return flying; }
+            get { return client.Self.Movement.Fly; }
         }
 
         public bool IsSitting
         {
-            get { return sitting; }
+            get
+            {
+                if (client.Self.Movement.SitOnGround || client.Self.SittingOn != 0) return true;
+                if (sitting) {
+                    Logger.Log("out of sync sitting", Helpers.LogLevel.Debug);
+                    sitting = false;
+                }
+                return false;
+            }
         }
 
         public bool IsPointing
@@ -1030,6 +1191,24 @@ namespace Radegast
         {
             get { return autosit; }
         }
+
+        private LSLHelper lslHelper;
+        public LSLHelper LSLHelper
+        {
+            get { return lslHelper; }
+        }
+
+        private PseudoHome pseudohome;
+
+        /// <summary>
+        /// Experimental Option that sometimes the Client has more authority than state mananger
+        /// </summary>
+        public static bool UseMoveControl;
+
+        public PseudoHome PseudoHome
+        {
+            get { return pseudohome; }
+        }
     }
 
     public class SitEventArgs : EventArgs
@@ -1041,4 +1220,4 @@ namespace Radegast
             this.Sitting = sitting;
         }
     }
-}
\ No newline at end of file
+}