소스 검색

better MobLook method in AIComponent

WangJun 8 년 전
부모
커밋
97dcfb94dd

+ 33 - 1
src/MineCase.Core/World/Position.cs

@@ -240,7 +240,7 @@ namespace MineCase.World
         }
     }
 
-    public struct EntityWorldPos
+    public struct EntityWorldPos : IEquatable<EntityWorldPos>
     {
         public float X { get; set; }
 
@@ -265,6 +265,16 @@ namespace MineCase.World
             return new EntityWorldPos(pos.X, pos.Y, pos.Z);
         }
 
+        public static bool operator != (EntityWorldPos lhs, EntityWorldPos rhs)
+        {
+            return lhs.X != rhs.X || lhs.Y != rhs.Y || lhs.Z != rhs.Z;
+        }
+
+        public static bool operator ==(EntityWorldPos lhs, EntityWorldPos rhs)
+        {
+            return lhs.X == rhs.X && lhs.Y == rhs.Y && lhs.Z == rhs.Z;
+        }
+
         public ChunkWorldPos ToChunkWorldPos()
         {
             float chunkX = (float)Math.Floor((double)X / ChunkConstants.BlockEdgeWidthInSection);
@@ -318,6 +328,28 @@ namespace MineCase.World
             float z = pos1.Z - pos2.Z;
             return Math.Sqrt(x * x + y * y + z * z);
         }
+
+        public override bool Equals(object obj)
+        {
+            return obj is EntityWorldPos && Equals((EntityWorldPos)obj);
+        }
+
+        public bool Equals(EntityWorldPos other)
+        {
+            return X == other.X &&
+                   Y == other.Y &&
+                   Z == other.Z;
+        }
+
+        public override int GetHashCode()
+        {
+            var hashCode = -307843816;
+            hashCode = hashCode * -1521134295 + base.GetHashCode();
+            hashCode = hashCode * -1521134295 + X.GetHashCode();
+            hashCode = hashCode * -1521134295 + Y.GetHashCode();
+            hashCode = hashCode * -1521134295 + Z.GetHashCode();
+            return hashCode;
+        }
     }
 
     public struct EntityChunkPos

+ 26 - 16
src/MineCase.Server.Grains/Game/Entities/Components/EntityAiComponent.cs

@@ -130,19 +130,9 @@ namespace MineCase.Server.Game.Entities.Components
 
         private Task ActionStop()
         {
-            float theta = (float)(random.NextDouble() * 360);
             float yaw = AttachedObject.GetValue(EntityLookComponent.YawProperty);
-            if (random.Next(20) == 0)
-            {
-                AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, theta);
-                AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, theta);
-            }
-            else
-            {
-                // AttachedObject.SetLocalValue(EntityLookComponent.YawProperty, yaw);
-                AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, yaw);
-            }
-
+            AttachedObject.SetLocalValue(EntityLookComponent.HeadYawProperty, yaw);
+            AttachedObject.SetLocalValue(EntityLookComponent.PitchProperty, 0);
             return Task.CompletedTask;
         }
 
@@ -251,21 +241,41 @@ namespace MineCase.Server.Game.Entities.Components
             return Task.CompletedTask;
         }
 
-        private async Task GenerateEvent()
+        private async Task<CreatureEvent> GenerateEvent()
         {
             // get state
             var state = _ai.State;
             var nextEvent = CreatureEvent.Nothing;
 
             // player approaching event
-            if (state == CreatureState.Stop)
             {
                 IChunkTrackingHub tracker = GrainFactory.GetGrain<IChunkTrackingHub>(AttachedObject.GetAddressByPartitionKey());
                 var list = await tracker.GetTrackedPlayers();
-                if (list.Count != 0)
+                EntityWorldPos entityPos = AttachedObject.GetValue(EntityWorldPositionComponent.EntityWorldPositionProperty);
+                bool hasPlayerNearby = false;
+                foreach (IPlayer each in list)
+                {
+                    EntityWorldPos playerPosition = await each.GetPosition();
+
+                    // players in three blocks
+                    if (EntityWorldPos.Distance(playerPosition, entityPos) < 3)
+                    {
+                        hasPlayerNearby = true;
+                        break;
+                    }
+                }
+
+                if (hasPlayerNearby)
                 {
                     nextEvent = CreatureEvent.PlayerApproaching;
                 }
+                else
+                {
+                    if (state == CreatureState.Stop)
+                        nextEvent = CreatureEvent.Nothing;
+                    else
+                        nextEvent = CreatureEvent.Stop;
+                }
             }
 
             // random walk
@@ -314,7 +324,7 @@ namespace MineCase.Server.Game.Entities.Components
             // action.Action(AttachedObject);
             if (e.worldAge % 16 == 0)
             {
-                await GenerateEvent();
+                var nextEvent = await GenerateEvent();
 
             // get state
             var newState = AiType.State;

+ 12 - 3
src/MineCase.Server.Grains/Game/Entities/Components/SyncMobStateComponent.cs

@@ -41,7 +41,10 @@ namespace MineCase.Server.Game.Entities.Components
         {
             uint eid = AttachedObject.GetValue(EntityIdComponent.EntityIdProperty);
             byte headyaw = (byte)(AttachedObject.GetValue(EntityLookComponent.HeadYawProperty) / 360 * 255);
-            return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityHeadLook(eid, headyaw);
+            if (e.NewValue != e.OldValue)
+                return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityHeadLook(eid, headyaw);
+            else
+                return Task.CompletedTask;
         }
 
         private Task OnYawChanged(object sender, PropertyChangedEventArgs<float> e)
@@ -66,7 +69,10 @@ namespace MineCase.Server.Game.Entities.Components
             bool onGround = AttachedObject.GetValue(EntityOnGroundComponent.IsOnGroundProperty);
 
             // return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityLook(eid, yaw, pitch, onGround);
-            return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityLookAndRelativeMove(eid, 0, 0, 0, yaw, pitch, onGround);
+            if (e.NewValue != e.OldValue)
+                return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityLookAndRelativeMove(eid, 0, 0, 0, yaw, pitch, onGround);
+            else
+                return Task.CompletedTask;
         }
 
         private Task OnPositionChanged(object sender, PropertyChangedEventArgs<EntityWorldPos> e)
@@ -79,7 +85,10 @@ namespace MineCase.Server.Game.Entities.Components
             byte pitch = (byte)(AttachedObject.GetValue(EntityLookComponent.PitchProperty) / 360 * 255);
             bool isOnGround = AttachedObject.GetValue(EntityOnGroundComponent.IsOnGroundProperty);
 
-            return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityLookAndRelativeMove(eid, x, y, z, yaw, pitch, isOnGround);
+            if (e.NewValue != e.OldValue)
+                return AttachedObject.GetComponent<ChunkEventBroadcastComponent>().GetGenerator().EntityLookAndRelativeMove(eid, x, y, z, yaw, pitch, isOnGround);
+            else
+                return Task.CompletedTask;
         }
     }
 }