Пример #1
0
        public override void Update(float deltaTime)
        {
            base.Update(deltaTime);

            if (burstCounter > 0)
            {
                burstTimer -= deltaTime;
                if (burstTimer <= 0f)
                {
                    Assets.pew.Play(1f, (float)rand.NextDouble() - 0.5f, 0f);

                    Vector3 direction = Vector3.Normalize(Camera.CameraPos - Position);
                    float   delta     = (float)rand.NextDouble() * 0.125f - 0.0625f;
                    direction = Vector3.Transform(direction, Mathg.RotationMatrix(delta));

                    Fire(direction);
                    burstCounter--;
                    if (burstCounter > 0)
                    {
                        burstTimer = burstDelay;
                    }
                    else
                    {
                        burstTimer = 0f;
                    }
                }
            }
        }
Пример #2
0
            public bool CheckMovement(Vector3 from, Vector3 direction, float radius, int layerMask)
            {
                Vector2 from2      = new Vector2(from.X, from.Z);
                Vector2 direction2 = new Vector2(direction.X, direction.Z);
                Vector2 to2        = from2 + direction2;

                foreach (Obstacle obstacle in obstacles)
                {
                    if (ObstacleLayerMask.CheckMask(layerMask, obstacle.Layer))
                    {
                        Vector2 v0      = obstacle.Start;
                        Vector2 v1      = obstacle.End;
                        Vector2 normal2 = Vector2.Normalize(new Vector2((v1 - v0).Y, -(v1 - v0).X));
                        if (Mathg.Cross2D(v1 - v0, from2 - v0) > 0)
                        {
                            normal2 *= -1;
                        }
                        v0 += normal2 * radius;
                        v1 += normal2 * radius;

                        if (Mathg.Cross2D(v1 - v0, from2 - v0) * Mathg.Cross2D(v1 - v0, to2 - v0) < 0 &&
                            Mathg.Cross2D(to2 - from2, v0 - from2) * Mathg.Cross2D(to2 - from2, v1 - from2) < 0)
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            }
Пример #3
0
        protected override PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags)
        {
            PopulateRoomResults results = new PopulateRoomResults
            {
                GenerateFloor = true
            };

            float   left       = x * tileSize - size * tileSize / 2;
            float   right      = left + tileSize;
            float   bottom     = y * tileSize - size * tileSize / 2;
            float   top        = bottom + tileSize;
            Vector3 roomCenter = new Vector3((left + right) / 2, 0f, (top + bottom) / 2);

            if (!flags.IsSpecial)
            {
                int monsterCount = rand.Next(flags.ClearCenter ? 1 : 2, monstersPerRoom + 1);
                game.PlayerStats.totalMonsters += monsterCount;
                Vector2 shift       = monsterCount == 1 ? Vector2.Zero : new Vector2(30f, 0f);
                float   angleOffset = (float)(rand.NextDouble() * Math.PI * 2f);
                for (int i = 0; i < monsterCount; i++)
                {
                    Vector2 position = new Vector2(roomCenter.X, roomCenter.Z);
                    position += Vector2.Transform(shift, Mathg.RotationMatrix2D(angleOffset + i * (float)Math.PI * 2f / monsterCount));
                    Vector3 position3 = new Vector3(position.X, -1f, position.Y);

                    Monster monster = Mathg.DiscreteChoiceFn(rand, new Func <Monster>[]
                    {
                        () => new BasicMonster(position3, monsterHP, monsterDamage),
                        () => new IceMonster(position3, monsterHP, monsterDamage * 0.3f),
                        () => new ShotgunDude(position3, monsterHP, monsterDamage),
                        () => new IceShotgunDude(position3, monsterHP, monsterDamage * 0.3f),
                        () => new SpinnyBoi(position3, monsterHP * 2, monsterDamage),
                        () => new Spooper(position3, monsterHP * 1.5f, monsterDamage)
                    }, monsterChances);

                    scene.AddGameObject(monster);
                }

                if (monsterCount != 1)
                {
                    flags.ClearPerimeter = false;
                }
                else
                {
                    flags.ClearCenter = false;
                }
            }

            if (rand.Next(4) == 0 || (flags.ClearPerimeter && rand.Next(2) == 0)) // special room
            {
                PopulateSpecialRoom(scene, zone, roomCenter, flags, ref results);
            }
            else
            {
                PopulateRoomCenter(scene, zone, roomCenter, flags);
                PopulateRoomWalls(scene, zone, roomCenter, flags);
            }

            return(results);
        }
Пример #4
0
        protected override void Attack(Vector3 towardsTarget)
        {
            Assets.pew.Play(1f, 0f, 0f);
            Assets.pew.Play(1f, -0.5f, 0f);
            Assets.pew.Play(1f, -1f, 0f);

            for (int i = -5; i <= 5; i++)
            {
                float   delta     = i * 0.4f / 5;
                Vector3 direction = Vector3.Transform(towardsTarget, Mathg.RotationMatrix(delta));
                Fire(direction);
            }
        }
Пример #5
0
        protected override void Attack(Vector3 towardsTarget)
        {
            counter++;
            Assets.btsch.Play();
            float dispersion = (float)Math.Atan(0.75f);

            for (int i = 0; i < 16; i++)
            {
                float   delta     = i * 2f * (float)Math.PI / 16f + (counter % 3 - 1) * dispersion;
                Vector3 direction = Vector3.Transform(towardsTarget, Mathg.RotationMatrix(delta));
                Fire(direction, 20f);
            }
        }
Пример #6
0
        // Given start position and movement vector, return the real movement vector taking into account collisions
        public Vector3 SmoothMovement(Vector3 from, Vector3 direction, float radius, int layerMask)
        {
            Vector3 ret = direction;

            while (!CheckMovement(from, ret, radius, layerMask, out Vector3 normal, out float relativeLength))
            {
                relativeLength *= 0.9f;
                if (relativeLength < 0.01f)
                {
                    relativeLength = 0f;
                }
                ret = relativeLength * ret + Mathg.OrthogonalComponent((1f - relativeLength) * ret, normal);
            }

            return(ret);
        }
Пример #7
0
            public bool CheckMovement(Vector3 from, Vector3 direction, float radius, int layerMask, out Vector3 normal, out float relativeLength)
            {
                normal         = Vector3.Zero;
                relativeLength = float.MaxValue;
                bool ret = true;

                Vector2 from2      = new Vector2(from.X, from.Z);
                Vector2 direction2 = new Vector2(direction.X, direction.Z);
                Vector2 to2        = from2 + direction2;

                foreach (Obstacle obstacle in obstacles)
                {
                    if (ObstacleLayerMask.CheckMask(layerMask, obstacle.Layer))
                    {
                        Vector2 v0      = obstacle.Start;
                        Vector2 v1      = obstacle.End;
                        Vector2 normal2 = Vector2.Normalize(new Vector2((v1 - v0).Y, -(v1 - v0).X));
                        Vector2 orth    = new Vector2(normal2.Y, -normal2.X);
                        v0 += (normal2 + orth) * radius;
                        v1 += (normal2 - orth) * radius;

                        if (Mathg.Cross2D(v1 - v0, from2 - v0) * Mathg.Cross2D(v1 - v0, to2 - v0) < 0 &&
                            Mathg.Cross2D(to2 - from2, v0 - from2) * Mathg.Cross2D(to2 - from2, v1 - from2) < 0 &&
                            Vector2.Dot(normal2, Vector2.Normalize(direction2)) < 0.1f)
                        {
                            float t = Vector2.Dot(v0 - from2, normal2) / Vector2.Dot(direction2, normal2);
                            if (t < relativeLength)
                            {
                                relativeLength = t;
                                normal         = new Vector3(normal2.X, 0f, normal2.Y);
                            }
                            ret = false;
                        }
                    }
                }

                return(ret);
            }
Пример #8
0
        protected override PopulateRoomResults PopulateRoom(Scene scene, Zone zone, int x, int y, PopulateSchemeFlags flags)
        {
            PopulateRoomResults results = new PopulateRoomResults
            {
                GenerateFloor = true
            };

            float   left       = x * tileSize - size * tileSize / 2;
            float   right      = left + tileSize;
            float   bottom     = y * tileSize - size * tileSize / 2;
            float   top        = bottom + tileSize;
            Vector3 roomCenter = new Vector3((left + right) / 2, 0f, (top + bottom) / 2);

            bool[] roomCorridors = Enumerable.Range(0, 4).Select(t => corridorLayout[x, y, t]).ToArray();

            if ((x != exitRoom.X || y != exitRoom.Y) && (x != size / 2 || y != size / 2))
            {
                int monsterCount = rand.Next(2, monstersPerRoom + 1);
                game.PlayerStats.totalMonsters += monsterCount;
                List <Vector3> spawnPoints = new List <Vector3>();
                Vector2        shift       = monsterCount == 1 ? Vector2.Zero : new Vector2(30f, 0f);
                float          angleOffset = (float)(rand.NextDouble() * Math.PI * 2f);
                for (int i = 0; i < monsterCount; i++)
                {
                    Vector2 position = new Vector2(roomCenter.X, roomCenter.Z);
                    position += Vector2.Transform(shift, Mathg.RotationMatrix2D(angleOffset + i * (float)Math.PI * 2f / monsterCount));
                    Vector3 position3 = new Vector3(position.X, -1f, position.Y);

                    Monster monster = Mathg.DiscreteChoiceFn(rand, new Func <Monster>[]
                    {
                        () => new BasicMonster(position3, monsterHP, monsterDamage),
                        () => new BasicMonster(position3, monsterHP, monsterDamage),
                        () => new ShotgunDude(position3, monsterHP, monsterDamage),
                        () => new SpinnyBoi(position3, monsterHP * 2, monsterDamage),
                        () => new Spooper(position3, monsterHP * 1.5f, monsterDamage)
                    }, monsterChances);

                    scene.AddGameObject(monster);
                }
            }



            if (rand.Next(7) == 0)
            {
                SceneStructures.PitWithBridges(FloorTexture, WallTexture, FloorTexture, roomCorridors).Invoke(scene, zone, roomCenter);
                SceneGenUtils.AddFloor(zone, -50f * Vector2.One, 50f * Vector2.One, -10f, Assets.lavaTexture, true, roomCenter, 75f);
                results.GenerateFloor = false;
            }
            else if (rand.Next(3) == 0)
            {
                if (x != size / 2 || y != size / 2)
                {
                    SpawnPools(scene, x, y, roomCenter, flags);
                }

                List <Generator> generators = new List <Generator>
                {
                    SceneStructures.Pillars4Inner(WallTexture),
                    SceneStructures.Pillars4Outer(WallTexture)
                };

                if (flags.ClearCenter)
                {
                    generators.Add(SceneStructures.PillarBig(WallTexture));
                    generators.Add(SceneStructures.PillarSmall(WallTexture));
                }

                Mathg.DiscreteChoice(rand, generators).Invoke(scene, zone, roomCenter);
            }

            return(results);
        }