/// <summary>
        /// move using the entities heading
        /// </summary>
        /// <returns></returns>
        private BehaviorReturnCode moveViaHeading()
        {
            Heading  heading  = (Heading)w_HeadingMapper.get(w_ThisEntity);
            Position position = (Position)w_PositionMapper.get(w_ThisEntity);
            Velocity velocity = (Velocity)w_VelocityMapper.get(w_ThisEntity);


            Vector2 pos = position.Pos;// +position.Offset;

            pos += heading.getHeading() * velocity.Vel;

            position.Pos = pos;

            w_Moved = true;

            SpatialPartition spatial = (SpatialPartition)w_SpatialMapper.get(w_Spatial);

            if (w_LastNode != null)
            {
                w_LastNode.Contents.Remove(w_ThisEntity);
            }

            w_LastNode = spatial.QuadTree.setContentAtLocation(w_ThisEntity, pos + new Vector2(16, 16));


            return(BehaviorReturnCode.Success);
        }
        /// <summary>
        /// perform all needed initialization
        /// </summary>
        /// <returns>whether initialization was a success or not</returns>
        private BehaviorReturnCode initialize()
        {
            Position position = (Position)w_PositionMapper.get(w_ThisEntity);

            w_Spatial = w_ECSInstance.tag_manager.get_entity_by_tag("SPATIAL");
            SpatialPartition spatial = (SpatialPartition)w_SpatialMapper.get(w_Spatial);

            Vector2 pos = position.Pos;

            Vector2 dir = new Vector2((float)w_Random.NextDouble() * 2 - 1, (float)w_Random.NextDouble() * 2 - 1);

            dir.Normalize();

            Heading heading = (Heading)w_HeadingMapper.get(w_ThisEntity);

            heading.setHeading(dir);

            w_LastNode = spatial.QuadTree.setContentAtLocation(w_ThisEntity, pos + new Vector2(16, 16));

            w_Camera = w_ECSInstance.tag_manager.get_entity_by_tag("CAMERA");

            w_EntityFaction = (Factions)w_FactionMapper.get(w_ThisEntity);

            return(BehaviorReturnCode.Success);
        }
Beispiel #3
0
        public EntityThread(ulong threadIndex, EntityThreadRepository entityThreadRepository,
                            ClientThreadRepository clientThreadRepository,
                            SpatialPartition spatialPartition, int syncRate, bool netOwnerEvents,
                            Action <IClient, IEntity, LinkedList <string> > onEntityCreate, Action <IClient, IEntity> onEntityRemove,
                            Action <IClient, IEntity, LinkedList <string> > onEntityDataChange,
                            Action <IClient, IEntity, Vector3> onEntityPositionChange, Action <IClient, IEntity> onEntityClearCache,
                            Action <IClient, IEntity, bool> onEntityNetOwnerChange)
        {
            this.threadIndex = threadIndex;

            this.entityThreadRepository = entityThreadRepository ??
                                          throw new ArgumentException("entityThreadRepository should not be null.");
            this.clientThreadRepository = clientThreadRepository;
            this.spatialPartition       =
                spatialPartition ?? throw new ArgumentException("spatialPartition should not be null.");
            this.syncRate           = syncRate;
            this.netOwnerEvents     = netOwnerEvents;
            this.onEntityCreate     = onEntityCreate ?? throw new ArgumentException("onEntityCreate should not be null.");
            this.onEntityRemove     = onEntityRemove ?? throw new ArgumentException("onEntityRemove should not be null.");
            this.onEntityDataChange = onEntityDataChange ??
                                      throw new ArgumentException("onEntityDataChange should not be null.");
            this.onEntityPositionChange = onEntityPositionChange ??
                                          throw new ArgumentException("onEntityPositionChange should not be null.");
            this.onEntityClearCache = onEntityClearCache ??
                                      throw new ArgumentException("onEntityPositionChange should not be null.");
            this.onEntityNetOwnerChange = onEntityNetOwnerChange ??
                                          throw new ArgumentException("onEntityNetOwnerChange should not be null.");

            thread = new Thread(OnLoop)
            {
                IsBackground = true
            };
            thread.Start();
        }
Beispiel #4
0
        public EntityThread(EntityThreadRepository entityThreadRepository,
                            ClientThreadRepository clientThreadRepository,
                            SpatialPartition spatialPartition, int syncRate,
                            Action <IClient, IEntity, LinkedList <string> > onEntityCreate, Action <IClient, IEntity> onEntityRemove,
                            Action <IClient, IEntity, LinkedList <string> > onEntityDataChange,
                            Action <IClient, IEntity, Vector3> onEntityPositionChange, Action <IClient, IEntity> onEntityClearCache)
        {
            if (spatialPartition == null)
            {
                throw new ArgumentException("spatialPartition should not be null.");
            }

            if (entityThreadRepository == null)
            {
                throw new ArgumentException("entityThreadRepository should not be null.");
            }

            if (onEntityCreate == null)
            {
                throw new ArgumentException("onEntityCreate should not be null.");
            }

            if (onEntityRemove == null)
            {
                throw new ArgumentException("onEntityRemove should not be null.");
            }

            if (onEntityDataChange == null)
            {
                throw new ArgumentException("onEntityDataChange should not be null.");
            }

            if (onEntityPositionChange == null)
            {
                throw new ArgumentException("onEntityPositionChange should not be null.");
            }

            if (onEntityClearCache == null)
            {
                throw new ArgumentException("onEntityPositionChange should not be null.");
            }

            thread = new Thread(OnLoop)
            {
                IsBackground = true
            };
            thread.Start();
            this.entityThreadRepository = entityThreadRepository;
            this.clientThreadRepository = clientThreadRepository;
            this.spatialPartition       = spatialPartition;
            this.syncRate               = syncRate;
            this.onEntityCreate         = onEntityCreate;
            this.onEntityRemove         = onEntityRemove;
            this.onEntityDataChange     = onEntityDataChange;
            this.onEntityPositionChange = onEntityPositionChange;
            this.onEntityClearCache     = onEntityClearCache;
        }
Beispiel #5
0
    // Use this for initialization
    void Start()
    {
        if (instance == null)
        {
            instance = this;
        }

        GenerateSpatialPartition();
    }
        internal static void GetAdjacentTiles(List <PartitionTile> tileList, Vector2 position, bool includeLargeObjects = true)
        {
            SpatialPartition p = FetchPartition(position);

            p?.GetAdjacentTiles(tileList, position - p.Position);
            if (includeLargeObjects)
            {
                tileList.Add(largeObjectTile);
            }
        }
        private static SpatialPartition CreateNewPartition(Point position, bool active = false)
        {
            Point     newPos = ToPartitionPoint(position);
            Rectangle bounds = new Rectangle(newPos.X, newPos.Y, PartitionSize, PartitionSize);

            SpatialPartition partition = new SpatialPartition(TileSize, bounds);

            partitionPool.Add(partition);
            return(active ? TakeFromPool(position) : partition);
        }
 public ParticleLightManager(
     ParticleSystem <T> system,
     IEnumerable <LightingEnvironment> lightingEnvironments,
     UpdaterDelegate updater
     )
 {
     System               = system;
     _Partition           = new SpatialPartition <Sector>(system.Subdivision, (sectorIndex) => new Sector(this, sectorIndex));
     LightingEnvironments = lightingEnvironments;
     Updater              = updater;
 }
Beispiel #9
0
    public SpatialPartition GeneratePlanetPartition()
    {
        var icosahedron =  Utils.GenerateIcosahedron();

        // TODO: Change these 1000s with a global scale;
        for (var i = 0; i < icosahedron.faces.Count; ++i)
        {
            var face = icosahedron.faces[i];
            var p0 = icosahedron.nodes[face.n[0]].p /** 1000*/;
            var p1 = icosahedron.nodes[face.n[1]].p /** 1000*/;
            var p2 = icosahedron.nodes[face.n[2]].p /** 1000*/;
            var center = (p0 + p1 + p2) / 3;
            var radius = Math.Max(Vector3.Distance(center, p0), Math.Max(Vector3.Distance(center, p2), Vector3.Distance(center, p2)));
            face.sphereCenter = center;
            face.sphereRadius = radius;
            face.children = new List<Tile>();
        }

        var unparentedTiles = new List<Tile>();
        var maxDistanceFromOrigin = 0f;

        for(var i = 0; i < this.tiles.Count; ++i)
        {
            var tile = this.tiles[i];
            maxDistanceFromOrigin = Math.Max(maxDistanceFromOrigin, tile.averagePosition.magnitude + tile.radius);

            var parentFound = false;
            for (var j = 0; j < icosahedron.faces.Count; ++j)
            {
                var face = icosahedron.faces[j];
                var distance = Vector3.Distance(tile.averagePosition, face.sphereCenter) + tile.radius;
                if (distance < face.sphereRadius)
                {
                    face.children.Add(tile);
                    parentFound = true;
                    break;
                }
            }
            if (!parentFound)
            {
                unparentedTiles.Add(tile);
            }
        }

        SpatialPartition rootPartition = new SpatialPartition(Vector3.zero, maxDistanceFromOrigin, new List<SpatialPartition>(), unparentedTiles);
        for(var i = 0; i < icosahedron.faces.Count; ++i)
        {
            var face = icosahedron.faces[i];
            rootPartition.partitions.Add(new SpatialPartition(face.sphereCenter, face.sphereRadius, new List<SpatialPartition>(), face.children));
        }

        this.partition = rootPartition;
        return rootPartition;
    }
        private static void ReturnToPool(SpatialPartition partition)
        {
            partitions.Remove(partition);

            // Return the partition to the pool, if there's enough room.
            if (partitionPool.Count + 1 < MaxPoolSize)
            {
                partitionPool.Add(partition);
            }
            partition.IsActive = false;
        }
 public static void GetFromRegionRaw <T>(QuickList <IPartitionObject> existingList, Rectangle regionBounds) where T : IPartitionObject
 {
     for (int i = 0; i < partitions.Count; i++)
     {
         SpatialPartition partition = partitions.Array[i];
         if (partition.Bounds.Intersects(regionBounds))
         {
             partition.GetFromRegionRaw <T>(existingList, ConvertToLocal(regionBounds, partition));
         }
     }
     largeObjectTile.GetRaw <T>(existingList);
 }
 public static void Update()
 {
     for (int i = 0; i < partitions.Count; i++)
     {
         SpatialPartition partition = partitions.Array[i];
         partition.Update();
         if (partition.NeedsPrune)
         {
             ReturnToPool(partition);
             partition.NeedsPrune = false;
         }
     }
 }
Beispiel #13
0
        private BehaviorReturnCode initializePathfinder()
        {
            Position start  = (Position)f_PositionMapper.get(f_ThisEntity);
            Position finish = (Position)f_PositionMapper.get(f_Target);

            f_Map = s_EcsInstance.tag_manager.get_entity_by_tag("MAP");
            GameMap map = (GameMap)f_GameMapMapper.get(f_Map);

            f_Camera = s_EcsInstance.tag_manager.get_entity_by_tag("CAMERA");
            ViewPort viewport = (ViewPort)f_ViewPortMapper.get(f_Camera);

            f_Spatial = s_EcsInstance.tag_manager.get_entity_by_tag("SPATIAL");
            SpatialPartition spatial = (SpatialPartition)f_SpatialMapper.get(f_Spatial);

            spatial.QuadTree.setContentAtLocation(f_ThisEntity, start.Pos);
            s_LastNode = spatial.QuadTree.locateNode(start.Pos);

            Vector2 sVec, fVec;

            //s_Center = viewport.getDimensions() / 2;

            sVec = (start.Pos) / f_TileSize;
            fVec = (finish.Pos + finish.Offset) / f_TileSize;

            /*
             * sVec = (start.Pos + s_Center) / s_TileSize;
             * fVec = (finish.Pos + s_Center) / s_TileSize;
             */

            s_TargetCell.Position  = fVec;
            s_CurrentCell.Position = sVec;

            //findPath = new FindPathAction(s_EcsInstance,sVec,fVec, map);
            APath path = (APath)f_PathMapper.get(f_ThisEntity);

            path.Start     = sVec;
            path.Finish    = fVec;
            path.Map       = map;
            path.PathState = PathState.Idle;

            s_TargetCurrentPosition = finish.Pos + s_Offset;

            //convert to map position
            s_TargetCurrentPosition  = new Vector2((int)s_TargetCurrentPosition.X / f_TileSize, (int)s_TargetCurrentPosition.Y / f_TileSize);
            s_TargetPreviousPosition = s_TargetCurrentPosition;

            f_BeginPathingAndMovement = true;

            return(BehaviorReturnCode.Success);
        }
        public ParticleSystem(ITimeProvider timeProvider, object userData = null, float subdivision = 128.0f)
        {
            TimeProvider = timeProvider;
            Subdivision  = subdivision;

            Particles = new SpatialPartition <ParticleCollection>(Subdivision, (index) => new ParticleCollection(index, Particles.GetSectorBounds(index)));

            UpdateArgs = new ParticleUpdateArgs(this);
            RenderArgs = new ParticleRenderArgs(this);

            var temporaryInstance = Activator.CreateInstance <T>();

            temporaryInstance.InitializeSystem(userData, out Updater, out Renderer, out GetPosition, this);
        }
        public static void Initialize(int tileSize, int partitionSize)
        {
            largeObjectTile = new PartitionTile(Rectangle.Empty);
            TileSize        = tileSize;
            PartitionSize   = partitionSize;

            // Initialize pool.
            for (int i = 0; i < InitialPoolSize; i++)
            {
                Rectangle        bounds    = new Rectangle(0, 0, PartitionSize, PartitionSize);
                SpatialPartition partition = new SpatialPartition(TileSize, bounds);
                ReturnToPool(partition);
            }
        }
Beispiel #16
0
        public static void createSpatialPartition(Vector2 ul, Vector2 lr, int tiers)
        {
            Entity e = ecs_instance.create();

            SpatialPartition spatial = new SpatialPartition();

            spatial.QuadTree = new QuadTree <Entity>(ul, lr);
            spatial.QuadTree.buildQuadTree(tiers);

            ecs_instance.add_component(e, spatial);

            ecs_instance.tag_manager.tag_entity("SPATIAL", e);

            ecs_instance.resolve(e);
        }
 internal static void GetTilesFromRegion(QuickList <PartitionTile> tilesList, Rectangle regionBounds, bool includeLargeObjectTile = true)
 {
     for (int i = 0; i < partitions.Count; i++)
     {
         SpatialPartition partition = partitions.Array[i];
         if (partition.Bounds.Intersects(regionBounds))
         {
             partition.GetTilesFromRegion(tilesList, ConvertToLocal(regionBounds, partition));
         }
     }
     if (includeLargeObjectTile)
     {
         tilesList.Add(largeObjectTile);
     }
 }
Beispiel #18
0
        /// <summary>
        /// move toward the current cell
        /// </summary>
        /// <returns></returns>
        private BehaviorReturnCode moveTowardsCell()
        {
            //get positions, velocity, and heading
            Position mePos     = (Position)s_PositionMapper.get(s_ThisEntity);
            Velocity meVel     = (Velocity)s_VelocityMapper.get(s_ThisEntity);
            Heading  meHeading = (Heading)s_HeadingMapper.get(s_ThisEntity);

            //get current pos
            Vector2 pos = mePos.Pos;// +s_Offset;

            Vector2 vec = new Vector2(s_CurrentCell.Position.X * s_TileSize, s_CurrentCell.Position.Y * s_TileSize);

            //check for condition that could cause a not-a-number exception
            //if ((vec - s_Center) == pos)
            if ((vec) == pos)
            {
                return(BehaviorReturnCode.Success);
            }

            //create heading from this entityt to targetNode
            //vec = Vector2.Subtract(vec - s_Center, pos);
            vec = Vector2.Subtract(vec, pos);
            vec.Normalize();

            //set heading
            meHeading.setHeading(Vector2.Multiply(vec, meVel.Vel));

            //update position
            pos      += meHeading.getHeading();
            mePos.Pos = pos;

            s_moved = true;

            SpatialPartition spatial = (SpatialPartition)s_SpatialMapper.get(s_Spatial);

            //remove old reference
            if (s_LastNode != null)
            {
                s_LastNode.Contents.Remove(s_ThisEntity);
            }
            //set new position and get new reference
            spatial.QuadTree.setContentAtLocation(s_ThisEntity, pos);
            s_LastNode = spatial.QuadTree.locateNode(pos);


            return(BehaviorReturnCode.Success);
        }
Beispiel #19
0
        protected override void process(Entity entity)
        {
            Position         position = (Position)q_PositionMapper.get(entity);
            ViewPort         camera   = (ViewPort)q_ViewPortMapper.get(q_Camera);
            SpatialPartition spatial  = (SpatialPartition)q_SpatialMapper.get(q_Spatial);

            Vector2           pos    = position.Pos + position.Offset;
            Vector2           origin = camera.getOrigin();
            QuadNode <Entity> node   = spatial.QuadTree.locateNode(pos);

            int width  = (int)(node.LRCorner.X - node.ULCorner.X);
            int height = (int)(node.LRCorner.Y - node.ULCorner.Y);

            Rectangle rec = new Rectangle((int)(node.ULCorner.X - origin.X), (int)(node.ULCorner.Y - origin.Y), width, height);

            _sprite_batch.Draw(q_Texture, rec, new Color(1f, 0f, 0f, 0f));
        }
        private static SpatialPartition TakeFromPool(Point position)
        {
            // Create new partition if there's none in the pool.
            if (partitionPool.Count < 1)
            {
                return(CreateNewPartition(position, true));
            }

            // Otherwise, return a partition that's in the pool.
            SpatialPartition partition = partitionPool.Array[partitionPool.Count - 1];

            partitions.Add(partition);
            partitionPool.Remove(partition);
            partition.UpdatePosition(position);
            partition.IsActive = true;
            return(partition);
        }
        public static void Insert(IPartitionObject obj)
        {
            if (obj is Component c && !c.Enabled)
            {
                return;
            }

            if (obj is GameObject go)
            {
                InsertGameObject(go);
            }
            else
            {
                SpatialPartition tile = FetchPartition(obj.PartitionPosition)
                                        ?? TakeFromPool(ToPartitionPoint(obj.PartitionPosition));
                tile.Insert(obj);
            }
        }
        private static void InsertGameObject(GameObject go)
        {
            if (!go.Enabled || go.IgnoreCulling)
            {
                return;
            }

            RectangleF bounds = go.Bounds;

            if (bounds.Width > TileSize || bounds.Height > TileSize)
            {
                largeObjectTile.Insert(go);
            }
            else
            {
                SpatialPartition tile = FetchPartition(go.PartitionPosition)
                                        ?? TakeFromPool(ToPartitionPoint(go.PartitionPosition));
                tile.Insert(go);
            }
        }
Beispiel #23
0
        protected override void process(Entity entity)
        {
            Position         position  = (Position)p_PositionMapper.get(entity);
            Velocity         velocity  = (Velocity)p_VelocityMapper.get(entity);
            Heading          heading   = (Heading)p_HeadingMapper.get(entity);
            Position         mPosition = (Position)p_PositionMapper.get(p_Mouse);
            Transform        transform = (Transform)p_TransformMapper.get(entity);
            Character        character = (Character)p_CharacterMapper.get(entity);
            SpatialPartition spatial   = (SpatialPartition)p_SpatialMapper.get(p_Spatial);

            if (p_FirstRun)
            {
                spatial.QuadTree.setContentAtLocation(entity, position.Pos);
                p_LastNode = spatial.QuadTree.locateNode(position.Pos + position.Offset);
                p_FirstRun = false;
            }

            Vector2 pos  = position.Pos;
            float   vel  = velocity.Vel;
            Vector2 head = heading.getHeading();

            //reset direction
            int dirCount = 0;

            //reset animation
            //sprite.Column = 0;
            p_Moved = false;

            //toggle light?
            if (InputManager.isKeyToggled(Keys.L))
            {
                Light light = (Light)p_LightMapper.get(p_Mouse);
                if (light.IsEnabled)
                {
                    light.IsEnabled = false;
                }
                else
                {
                    light.IsEnabled = true;
                }
            }



            //move up?
            if (InputManager.isKeyPressed(Keys.W))
            {
                Vector2 dir = new Vector2(0, -1);

                head += dir;
                dirCount++;

                //sprite.Y = MOVE_UP;
                //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime);
                p_Moved = true;
            }

            //move down?
            if (InputManager.isKeyPressed(Keys.S))
            {
                Vector2 dir = new Vector2(0, 1);

                head += dir;
                dirCount++;

                //sprite.Y = MOVE_DOWN;
                //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime);
                p_Moved = true;
            }

            //move left?
            if (InputManager.isKeyPressed(Keys.A))
            {
                Vector2 dir = new Vector2(-1, 0);

                head += dir;
                dirCount++;

                //sprite.Y = MOVE_LEFT;
                //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime);
                p_Moved = true;
            }

            //move right?
            if (InputManager.isKeyPressed(Keys.D))
            {
                Vector2 dir = new Vector2(1, 0);

                head += dir;
                dirCount++;

                //sprite.Y = MOVE_RIGHT;
                //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime);
                p_Moved = true;
            }

            //move according to the correct speed
            if (dirCount > 1)
            {
                position.Pos = pos + head * vel * (float)Math.Sqrt(2) / 2;
            }
            else
            {
                position.Pos = pos + head * vel;
            }

            /*
             * Vector2 test = (mPosition.Pos + mPosition.Offset) - pos;
             * test.Normalize();
             *
             * float angle = VectorHelper.getAngle(new Vector2(1,0), test);
             *
             * if (angle >= 0.393f && angle < 1.178f) { sprite.Row = MOVE_UPRIGHT; }
             * else if (angle >= 1.178f && angle < 1.963f) { sprite.Row = MOVE_UP; }
             * else if (angle >= 1.963f && angle < 2.749f) { sprite.Row = MOVE_UPLEFT; }
             * else if (angle >= 2.749f && angle < 3.534f) { sprite.Row = MOVE_LEFT; }
             * else if (angle >= 3.534f && angle < 4.320f) { sprite.Row = MOVE_DOWNLEFT; }
             * else if (angle >= 4.320f && angle < 5.105f) { sprite.Row = MOVE_DOWN; }
             * else if (angle >= 5.105f && angle < 5.890f) { sprite.Row = MOVE_DOWNRIGHT; }
             * else if (angle >= 5.890f || angle < .393f) { sprite.Row = MOVE_RIGHT; }
             *
             * if(p_Moved)
             * sprite.Column = p_Movement.updateFrame(ecs_instance.ElapsedTime);
             */

            if (p_Moved)
            {
                character.CurrentAnimtaion = "MOVING";
            }

            //transform.Rotation = getAngle(pos, mPosition.getPosition());



            /*
             * if (InputManager.isLeftButtonClicked())
             * {
             *  EntityFactory ef = new EntityFactory(ecs_instance);
             *
             *  Vector2 dir = mPosition.getPosition() + mPosition.Offset - new Vector2(16) - pos;
             *
             *  dir.Normalize();
             *
             *  Transform trans = new Transform();
             *  trans.Rotation = -VectorHelper.getAngle(new Vector2(1, 0), dir);
             *  trans.RotationOrigin = new Vector2(16);
             *
             *  ef.createCollidingProjectile(pos + dir * 16, dir, 10f, 1000, ef.createLight(true, 35, new Vector3(pos + position.Offset, 10), 0.7f, Color.Purple.ToVector4()), trans, entity);
             *
             *  UtilFactory uf = new UtilFactory(ecs_instance);
             *  uf.createSound("audio\\effects\\fire", true,0.5f);
             * }*/

            p_LastFired += ecs_instance.ElapsedTime;

            if (InputManager.isLeftButtonDown() && (p_LastFired >= 3 * p_FireRate))
            {
                Target target = (Target)p_TargetMapper.get(p_Target);
                if (target.Active)
                {
                    p_LastFired = 0;

                    Position targetPos = (Position)p_PositionMapper.get(p_Target);

                    Vector2 dir = targetPos.Pos + targetPos.Offset - new Vector2(16) - pos;
                    dir.Normalize();

                    Transform trans = new Transform();
                    trans.Rotation       = -VectorHelper.getAngle(new Vector2(1, 0), dir);
                    trans.RotationOrigin = new Vector2(0, 16);

                    UtilFactory.createMeleeAction(pos + dir * 16, dir, trans, entity);
                }
            }

            if (InputManager.isRightButtonDown() && (p_LastFired >= p_FireRate))
            {
                Target target = (Target)p_TargetMapper.get(p_Target);
                if (target.Active)
                {
                    p_LastFired = 0;

                    Position targetPos = (Position)p_PositionMapper.get(p_Target);

                    Vector2 dir = targetPos.Pos + targetPos.Offset - new Vector2(16) - pos;
                    //Vector2 dir = mPosition.Pos + mPosition.Offset - new Vector2(16) - pos;// +new Vector2(-20 + (float)rand.NextDouble() * 40, -20 + (float)rand.NextDouble() * 40);

                    dir = VectorHelper.rotateVectorRadians(dir, -0.08726f + (float)rand.NextDouble() * 0.1745f);

                    dir.Normalize();

                    Transform trans = new Transform();
                    trans.Rotation       = -VectorHelper.getAngle(new Vector2(1, 0), dir);
                    trans.RotationOrigin = new Vector2(16);

                    EntityFactory.createCollidingProjectile(pos + dir * 16, dir, 10f, 1000, EntityFactory.createLight(true, 2, new Vector3(pos + position.Offset, 10), 0.7f, Color.OrangeRed.ToVector4()), trans, entity);

                    UtilFactory.createSound("audio\\effects\\fire", true, 0.5f);
                }
            }

            if (InputManager.isKeyToggled(Keys.B))
            {
                if (!p_StatWindowOpen)
                {
                    p_StatWindow = UIFactory.createStatWindow(entity, new Point(100, 100), new Point(300, 315), 20);

                    p_StatWindowOpen = true;
                }
                else
                {
                    ecs_instance.delete_entity(p_StatWindow);
                    p_StatWindowOpen = false;
                }
            }

            if (InputManager.isKeyToggled(Keys.I))
            {
                if (!p_InvWindowOpen)
                {
                    p_InvWindow     = UIFactory.createInventoryWindow(entity, new Point(300, 100), new Point(300, 300), 20, 10, 10);
                    p_InvWindowOpen = true;
                }
                else
                {
                    ecs_instance.delete_entity(p_InvWindow);
                    p_InvWindowOpen = false;
                }
            }


            if (InputManager.isKeyToggled(Keys.R))
            {
                List <Entity> locals = spatial.QuadTree.findAllWithinRange(pos, 300);
                if (locals.Count > 1)
                {
                    Target target = (Target)p_TargetMapper.get(p_Target);
                    Sprite sprite = (Sprite)p_SpriteMapper.get(p_Target);
                    sprite.Visible = true;
                    target.Active  = true;

                    Entity closest = null;
                    float  min     = float.MaxValue;

                    for (int i = 0; i < locals.Count; i++)
                    {
                        if (locals[i] == entity)
                        {
                            continue;
                        }

                        Position p = (Position)p_PositionMapper.get(locals[i]);

                        if (p == null)
                        {
                            continue;
                        }

                        float dist = Vector2.Distance(p.Pos, position.Pos);
                        if (dist < min)
                        {
                            closest = locals[i];
                            min     = dist;
                        }
                    }

                    target.TargetEntity = closest;
                }
            }

            if (!p_Moved)
            {
                p_Movement.reset();
                character.CurrentAnimtaion = "IDLE";
            }
            else
            {
                if (p_LastNode != null)
                {
                    p_LastNode.Contents.Remove(entity);
                }

                p_LastNode = spatial.QuadTree.setContentAtLocation(entity, pos + new Vector2(16, 16));
            }

            //TEST FUNCTIONS PAST HERE

            if (InputManager.isKeyPressed(Keys.Up))
            {
                transform.Rotation += 0.1f;
            }

            if (InputManager.isKeyPressed(Keys.Down))
            {
                transform.Rotation -= 0.1f;
            }

            if (InputManager.isKeyPressed(Keys.Left))
            {
                transform.RotationOrigin = new Vector2(16, 32);
            }

            if (InputManager.isKeyPressed(Keys.Right))
            {
                transform.RotationOrigin = new Vector2(0);
            }

            if (InputManager.isKeyPressed(Keys.P))
            {
                NPCFactory ef = new NPCFactory(ecs_instance);
                ef.createFollower(mPosition.Pos + mPosition.Offset - new Vector2(16), entity, rand.Next(50, 300));
            }

            if (InputManager.isKeyToggled(Keys.O))
            {
                NPCFactory ef = new NPCFactory(ecs_instance);
                //ef.createBatEnemy(mPosition.Pos + mPosition.Offset - new Vector2(16),15);
                CharacterDef cDef = GameConfig.CharacterDefs["BAT"];
                cDef.SkillLevel = 15;
                ef.createCharacter(cDef, mPosition.Pos + mPosition.Offset - new Vector2(16));
            }

            if (InputManager.isKeyToggled(Keys.U))
            {
                ActionDef def = GameConfig.ActionDefs["TEST_DMG"];
                ActionFactory.createAction(def, entity, entity);
            }
        }
 private static Point ConvertToLocal(Point worldPoint, SpatialPartition localPartition)
 => new Point(worldPoint.X - localPartition.Bounds.X, worldPoint.Y - localPartition.Bounds.Y);
 private static Rectangle ConvertToLocal(Rectangle worldBounds, SpatialPartition localPartition)
 => new Rectangle(worldBounds.X - localPartition.Bounds.X,
                  worldBounds.Y - localPartition.Bounds.Y,
                  worldBounds.Width,
                  worldBounds.Height);
Beispiel #26
0
        protected override void process(Entity entity)
        {
            Projectile projectile = (Projectile)p_ProjectileMapper.get(entity);

            projectile.ElapsedTime += ecs_instance.ElapsedTime;

            //is it time for the projectile to die?
            if (projectile.ElapsedTime >= projectile.LifeTime)
            {
                ecs_instance.delete_entity(entity);
                return;
            }

            Position         position = (Position)p_PositionMapper.get(entity);
            Velocity         velocity = (Velocity)p_VelocityMapper.get(entity);
            Heading          heading  = (Heading)p_HeadingMapper.get(entity);
            SpatialPartition spatial  = (SpatialPartition)p_SpatialMapper.get(p_Spatial);

            Vector2 pos = position.Pos;

            //List<Entity> locals = spatial.QuadTree.retrieveContentsAtLocation(pos);
            List <Entity> locals = spatial.QuadTree.findAllWithinRange(pos, 32);

            //anything retrieved?
            if (locals != null)
            {   //anyone aruond?
                if (locals.Count > 0)
                {
                    //for all the locals see if we should do anything
                    for (int i = 0; i < locals.Count; i++)
                    {
                        //dont interact with whom fired you
                        if (locals[i] == projectile.Originator)
                        {
                            continue;
                        }

                        Life life = (Life)p_LifeMapper.get(locals[i]);

                        //if no life, uh, don't check for it...
                        if (life == null)
                        {
                            continue;
                        }

                        //if target is dead, dont worry
                        if (!life.IsAlive)
                        {
                            continue;
                        }


                        //is there an interaction available?
                        Interactable interaction = (Interactable)p_InteractionMapper.get(locals[i]);
                        if (interaction != null)
                        {
                            //get this local's position
                            Position localPosition = (Position)p_PositionMapper.get(locals[i]);

                            //are we close to it?
                            //23 - minimal radial distance for collision to occur
                            if (Vector2.Distance(pos + position.Offset, localPosition.Pos + localPosition.Offset) < 23)
                            {
                                //can we do anything to it?
                                if (interaction.SupportedInteractions.PROJECTILE_COLLIDABLE &&
                                    interaction.SupportedInteractions.ATTACKABLE)
                                {
                                    Factions lfactions = (Factions)p_FactionMapper.get(locals[i]);
                                    Factions pfactions = (Factions)p_FactionMapper.get(projectile.Originator);

                                    if (lfactions.OwnerFaction.FactionType == pfactions.OwnerFaction.FactionType)
                                    {
                                        continue;
                                    }

                                    //UtilFactory.createAttack(projectile.Originator, locals[i], AttackType.Projectile);
                                    ActionDef def = GameConfig.ActionDefs["RANGED_DMG"];
                                    ActionFactory.createAction(def, projectile.Originator, locals[i]);


                                    //destory yourself
                                    ecs_instance.delete_entity(entity);
                                    return;
                                }
                            }
                        }
                    }
                }
            }

            MapCollidable mapCollide = (MapCollidable)p_MapCollidableMapper.get(entity);

            if (mapCollide != null)
            {
                if (mapCollide.Collided)
                {
                    /*
                     * Vector2 norm = mapCollide.ResponseVector;
                     * norm.Normalize();
                     * Vector2 reflect = Vector2.Reflect(heading.getHeading(), norm);
                     * reflect.Normalize();
                     *
                     * //Transform trans = (Transform)p_TransformMapper.get(entity);
                     *
                     * //trans.Rotation = -VectorHelper.getAngle2(new Vector2(1,0), reflect);
                     *
                     * heading.setHeading(reflect);
                     */

                    UtilFactory.createSound("audio\\effects\\hitwall", true, 0.5f);

                    ecs_instance.delete_entity(entity);
                }
            }

            pos += heading.getHeading() * velocity.Vel;

            position.Pos = pos;
        }
        /// <summary>
        /// checks for nearby enemy factions
        /// </summary>
        /// <returns>true if hostile was detected</returns>
        private bool hasDetectedHostile()
        {
            if (w_LastNode == null)
            {
                return(false);
            }

            SpatialPartition spatial  = (SpatialPartition)w_SpatialMapper.get(w_Spatial);
            Position         position = (Position)w_PositionMapper.get(w_ThisEntity);
            List <Entity>    locals   = spatial.QuadTree.findAllWithinRange(position.Pos, 100f);


            //nothing to detect
            if (locals.Count == 0)
            {
                return(false);
            }

            for (int i = 0; i < locals.Count; i++)
            {
                //dont look at yourself
                if (locals[i] == w_ThisEntity)
                {
                    continue;
                }

                Factions factions = (Factions)w_FactionMapper.get(locals[i]);

                if (factions == null)
                {
                    continue;
                }

                //is this local known to this entity
                if (factions.KnownFactions.ContainsKey(w_EntityFaction.OwnerFaction.Name))
                {
                    //should this entity be hostile towards this local?
                    if (factions.KnownFactions[w_EntityFaction.OwnerFaction.Name].Value < 0)
                    {
                        Position pos  = (Position)w_PositionMapper.get(w_ThisEntity);
                        Position tPos = (Position)w_PositionMapper.get(locals[i]);

                        if (Vector2.Distance(pos.Pos + pos.Offset, tPos.Pos + tPos.Offset) <= 200f)
                        {
                            //go hostile against it
                            w_Target = locals[i];

                            Aggrivation aggro = (Aggrivation)w_AggroMapper.get(w_ThisEntity);
                            aggro.Target = w_Target;

                            return(true);
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }

            return(false);
        }
    public SpatialPartition GeneratePlanetPartition()
    {
        var icosahedron =  Utils.GenerateIcosahedron();

        // TODO: Change these 1000s with a global scale;
        for (var i = 0; i < icosahedron.faces.Count; ++i)
        {
            var face = icosahedron.faces[i];
            var p0 = icosahedron.nodes[face.n[0]].p /** 1000*/;
            var p1 = icosahedron.nodes[face.n[1]].p /** 1000*/;
            var p2 = icosahedron.nodes[face.n[2]].p /** 1000*/;
            var center = (p0 + p1 + p2) / 3;
            var radius = Math.Max(Vector3.Distance(center, p0), Math.Max(Vector3.Distance(center, p2), Vector3.Distance(center, p2)));
            face.sphereCenter = center;
            face.sphereRadius = radius;
            face.children = new List<Tile>();
        }

        var unparentedTiles = new List<Tile>();
        var maxDistanceFromOrigin = 0f;

        for(var i = 0; i < this.tiles.Count; ++i)
        {
			var tile = this.tiles[i];
			maxDistanceFromOrigin = Math.Max(maxDistanceFromOrigin, tile.averagePosition.magnitude + tile.radius);
			
			var parentFound = false;
			for (var j = 0; j < icosahedron.faces.Count; ++j)
			{
				var face = icosahedron.faces[j];
				var distance = Vector3.Distance(tile.averagePosition, face.sphereCenter) + tile.radius;
				if (distance < face.sphereRadius)
				{
					face.children.Add(tile);
					parentFound = true;
					break;
				}
			}
			if (!parentFound)
			{
				unparentedTiles.Add(tile);
			}
        }

        SpatialPartition rootPartition = new SpatialPartition(Vector3.zero, maxDistanceFromOrigin, new List<SpatialPartition>(), unparentedTiles);
        for(var i = 0; i < icosahedron.faces.Count; ++i)
        {
            var face = icosahedron.faces[i];
            rootPartition.partitions.Add(new SpatialPartition(face.sphereCenter, face.sphereRadius, new List<SpatialPartition>(), face.children));
        }

        this.partition = rootPartition;
        return rootPartition;
    }
Beispiel #29
0
        protected override void process(Entity entity)
        {
            MeleeAction      action   = (MeleeAction)m_MeleeActionMapper.get(entity);
            Position         position = (Position)m_PositionMapper.get(entity);
            SpatialPartition spatial  = (SpatialPartition)m_SpatialMapper.get(m_Spatial);

            action.ElapsedTime += ecs_instance.ElapsedTime;

            //is it time for the melee action to die?
            if (action.ElapsedTime >= action.Lifetime)
            {
                ecs_instance.delete_entity(entity);
                return;
            }

            //retrieve all local entities
            //List<Entity> locals = spatial.QuadTree.retrieveContentsAtLocation(position.Pos);
            List <Entity> locals = spatial.QuadTree.findAllWithinRange(position.Pos, action.Range);

            //is the location good?
            if (locals != null)
            {
                //is there anyone here?
                if (locals.Count > 0)
                {
                    for (int i = 0; i < locals.Count; i++)
                    {
                        //dont attempt to melee owner
                        if (locals[i] == action.Owner)
                        {
                            continue;
                        }

                        if (action.HitByAction.Contains(locals[i]))
                        {
                            continue;
                        }

                        Life life = (Life)m_LifeMapper.get(locals[i]);

                        //if no life, dont bother
                        if (life == null)
                        {
                            continue;
                        }

                        //if not alive, dont bother
                        if (!life.IsAlive)
                        {
                            continue;
                        }

                        //interaction available?
                        Interactable interactions = (Interactable)m_InteractionMapper.get(locals[i]);
                        if (interactions != null)
                        {
                            Position lPosition = (Position)m_PositionMapper.get(locals[i]);

                            Position oPosition = (Position)m_PositionMapper.get(action.Owner);
                            Vector2  lToO      = (oPosition.Pos + oPosition.Offset) - (lPosition.Pos + lPosition.Offset); //local to owner
                            Heading  head      = (Heading)m_HeadingMapper.get(entity);                                    //get the weapon heading
                            bool     facing    = (Vector2.Dot(head.getHeading(), lToO) < 0);                              //is the weapon facing the local?

                            //if you're facing, are you within range?
                            if (facing && (Vector2.Distance(lPosition.Pos + lPosition.Offset, position.Pos + position.Offset) <= action.Range))
                            {
                                //does it support this interaction?
                                if (interactions.SupportedInteractions.MELEE_ACTIONABLE &&
                                    interactions.SupportedInteractions.ATTACKABLE)
                                {
                                    Factions lfactions = (Factions)m_FactionMapper.get(locals[i]);
                                    Factions pfactions = (Factions)m_FactionMapper.get(action.Owner);

                                    //dont attack allies
                                    if (lfactions.OwnerFaction.FactionType == pfactions.OwnerFaction.FactionType)
                                    {
                                        continue;
                                    }

                                    //add to hit-list so we dont attack it again on swing follow-through
                                    action.HitByAction.Add(locals[i]);

                                    //create melee attack
                                    UtilFactory.createAttack(action.Owner, locals[i], AttackType.Melee);

                                    //destroy melee action
                                    //ecs_instance.delete_entity(entity);
                                    //return;
                                }
                            }
                        }
                    }
                }
            }

            //get info for rotation update
            Heading   heading   = (Heading)m_HeadingMapper.get(entity);
            Transform transform = (Transform)m_TransformMapper.get(entity);

            //rotate melee by degrees over the melee arc
            float rot = (((float)action.Animation.updateFrame(ecs_instance.ElapsedTime) / (float)action.Animation.Frames) * action.ArcDegrees) - (action.ArcDegrees / 2f);

            transform.Rotation = rot * (((float)Math.PI) / 180f) - VectorHelper.getAngle(new Vector2(1, 0), heading.getHeading());

            //adjust the arc based on current position (i.e., move with the player)
            Position ownerPos = (Position)m_PositionMapper.get(action.Owner);
            Vector2  pos      = ownerPos.Pos + new Vector2(16, 0);// +ownerPos.getOffset();
            Vector2  dir      = heading.getHeading();

            dir.Normalize();
            position.Pos = pos + dir * 10;
        }