예제 #1
0
        public static bool Hit(Character attacker, Character defender, bool magic)
        {
            float acuRoll = Random.Float(attacker.AttackSkill(defender));
            float defRoll = Random.Float(defender.DefenseSkill(attacker));

            return((magic ? acuRoll * 2 : acuRoll) >= defRoll);
        }
예제 #2
0
        protected internal virtual void PaintGrass()
        {
            var grass = Grass();

            if (feeling == Feeling.GRASS)
            {
                foreach (var room in Rooms.Where(room => room.type != RoomType.NULL && room.type != RoomType.PASSAGE && room.type != RoomType.TUNNEL))
                {
                    grass[(room.Left + 1) + (room.Top + 1) * Width]     = true;
                    grass[(room.Right - 1) + (room.Top + 1) * Width]    = true;
                    grass[(room.Left + 1) + (room.Bottom - 1) * Width]  = true;
                    grass[(room.Right - 1) + (room.Bottom - 1) * Width] = true;
                }
            }

            for (var i = Width + 1; i < Length - Width - 1; i++)
            {
                if (map[i] != Terrain.EMPTY || !grass[i])
                {
                    continue;
                }

                var count = 1 + NEIGHBOURS8.Count(n => grass[i + n]);
                map[i] = (Random.Float() < count / 12f) ? Terrain.HIGH_GRASS : Terrain.GRASS;
            }
        }
예제 #3
0
        protected internal override void CreateItems()
        {
#if DEBUG
            return;
#endif
            var nItems = 3;
            while (Random.Float() < 0.3f)
            {
                nItems++;
            }

            for (var i = 0; i < nItems; i++)
            {
                Heap.Type type;
                switch (Random.Int(20))
                {
                case 0:
                    type = Heap.Type.Skeleton;
                    break;

                case 1:
                case 2:
                case 3:
                case 4:
                    type = Heap.Type.Chest;
                    break;

                default:
                    type = Heap.Type.Heap;
                    break;
                }
                Drop(Generator.Random(), RandomDropCell()).HeapType = type;
            }

            foreach (var itemToSpawn in itemsToSpawn)
            {
                var cell = RandomDropCell();
                if (itemToSpawn is ScrollOfUpgrade)
                {
                    while (map[cell] == Terrain.FIRE_TRAP || map[cell] == Terrain.SECRET_FIRE_TRAP)
                    {
                        cell = RandomDropCell();
                    }
                }

                Drop(itemToSpawn, cell).HeapType = Heap.Type.Heap;
            }

            var item = Bones.Get();
            if (item != null)
            {
                Drop(item, RandomDropCell()).HeapType = Heap.Type.Skeleton;
            }
        }
예제 #4
0
        private static bool Chance(int[] quota, int number)
        {
            for (var i = 0; i < quota.Length; i += 2)
            {
                var qDepth = quota[i];
                if (Depth > qDepth)
                {
                    continue;
                }

                var qNumber = quota[i + 1];
                return(Random.Float() < (float)(qNumber - number) / (qDepth - Depth + 1));
            }

            return(false);
        }
예제 #5
0
파일: Hero.cs 프로젝트: zvinch/SharpDungeon
        public override void Move(int step)
        {
            base.Move(step);

            if (Flying)
            {
                return;
            }

            if (Level.water[pos])
            {
                Sample.Instance.Play(Assets.SND_WATER, 1, 1, Random.Float(0.8f, 1.25f));
            }
            else
            {
                Sample.Instance.Play(Assets.SND_STEP);
            }

            Dungeon.Level.Press(pos, this);
        }
예제 #6
0
        protected internal virtual void Split(Rect rect)
        {
            var w = rect.Width();
            var h = rect.Height();

            if (w > MaxRoomSize && h < MinRoomSize)
            {
                var vw = Random.Int(rect.Left + 3, rect.Right - 3);
                Split(new Rect(rect.Left, rect.Top, vw, rect.Bottom));
                Split(new Rect(vw, rect.Top, rect.Right, rect.Bottom));
            }
            else
            if (h > MaxRoomSize && w < MinRoomSize)
            {
                var vh = Random.Int(rect.Top + 3, rect.Bottom - 3);
                Split(new Rect(rect.Left, rect.Top, rect.Right, vh));
                Split(new Rect(rect.Left, vh, rect.Right, rect.Bottom));
            }
            else if ((new System.Random(1).NextDouble() <= (MinRoomSize * MinRoomSize / rect.Square()) && w <= MaxRoomSize && h <= MaxRoomSize) || w < MinRoomSize || h < MinRoomSize)
            {
                Rooms.Add((Room) new Room().Set(rect));
            }
            else
            {
                if (Random.Float() < (float)(w - 2) / (w + h - 4))
                {
                    var vw = Random.Int(rect.Left + 3, rect.Right - 3);
                    Split(new Rect(rect.Left, rect.Top, vw, rect.Bottom));
                    Split(new Rect(vw, rect.Top, rect.Right, rect.Bottom));
                }
                else
                {
                    var vh = Random.Int(rect.Top + 3, rect.Bottom - 3);
                    Split(new Rect(rect.Left, rect.Top, rect.Right, vh));
                    Split(new Rect(rect.Left, vh, rect.Right, rect.Bottom));
                }
            }
        }
예제 #7
0
        public override void Update()
        {
            base.Update();

            if (Target != null)
            {
                FocusOn(Target);
            }

            if ((_shakeTime -= Game.Elapsed) > 0)
            {
                var damping = _shakeTime / _shakeDuration;
                ShakeX = Random.Float(-_shakeMagX, +_shakeMagX) * damping;
                ShakeY = Random.Float(-_shakeMagY, +_shakeMagY) * damping;
            }
            else
            {
                ShakeX = 0;
                ShakeY = 0;
            }

            UpdateMatrix();
        }
예제 #8
0
        public virtual bool Attack(Character enemy)
        {
            var visibleFight = Dungeon.Visible[pos] || Dungeon.Visible[enemy.pos];

            if (Hit(this, enemy, false))
            {
                if (visibleFight)
                {
                    GLog.Information(TxtHit, Name, enemy.Name);
                }

                // FIXME
                var dr = this is Hero && ((Hero)this).RangedWeapon != null && ((Hero)this).subClass == HeroSubClass.SNIPER ? 0 : Random.IntRange(0, enemy.Dr());

                var dmg             = DamageRoll();
                var effectiveDamage = Math.Max(dmg - dr, 0);

                effectiveDamage = AttackProc(enemy, effectiveDamage);
                effectiveDamage = enemy.DefenseProc(this, effectiveDamage);
                enemy.Damage(effectiveDamage, this);

                if (visibleFight)
                {
                    Sample.Instance.Play(Assets.SND_HIT, 1, 1, Random.Float(0.8f, 1.25f));
                }

                if (enemy == Dungeon.Hero)
                {
                    Dungeon.Hero.Interrupt();
                }

                enemy.Sprite.BloodBurstA(Sprite.Center(), effectiveDamage);
                enemy.Sprite.Flash();

                if (!enemy.IsAlive && visibleFight)
                {
                    if (enemy == Dungeon.Hero)
                    {
                        if (Dungeon.Hero.KillerGlyph != null)
                        {
                            Dungeon.Fail(Utils.Format(ResultDescriptions.GLYPH, Dungeon.Hero.KillerGlyph.Name(), Dungeon.Depth));
                            GLog.Negative(TxtKill, Dungeon.Hero.KillerGlyph.Name());
                        }
                        else
                        {
                            if (Bestiary.IsUnique(this))
                            {
                                Dungeon.Fail(Utils.Format(ResultDescriptions.BOSS, Name, Dungeon.Depth));
                            }
                            else
                            {
                                Dungeon.Fail(Utils.Format(ResultDescriptions.MOB, Utils.Indefinite(Name), Dungeon.Depth));
                            }

                            GLog.Negative(TxtKill, Name);
                        }
                    }
                    else
                    {
                        GLog.Information(TxtDefeat, Name, enemy.Name);
                    }
                }

                return(true);
            }

            if (!visibleFight)
            {
                return(false);
            }

            var defense = enemy.DefenseVerb();

            enemy.Sprite.ShowStatus(CharSprite.Neutral, defense);
            if (this == Dungeon.Hero)
            {
                GLog.Information(TxtYouMissed, enemy.Name, defense);
            }
            else
            {
                GLog.Information(TxtSmbMissed, enemy.Name, defense, Name);
            }

            Sample.Instance.Play(Assets.SND_MISS);

            return(false);
        }
예제 #9
0
파일: Hero.cs 프로젝트: zvinch/SharpDungeon
        public virtual bool Search(bool intentional)
        {
            var smthFound = false;

            var positive = 0;
            var negative = 0;

            foreach (var bonus in Buffs <RingOfDetection.Detection>().Select(buff => buff.Level))
            {
                if (bonus > positive)
                {
                    positive = bonus;
                }
                else if (bonus < 0)
                {
                    negative += bonus;
                }
            }

            var distance = 1 + positive + negative;

            var level = intentional ? (2 * Awareness - Awareness * Awareness) : Awareness;

            if (distance <= 0)
            {
                level   /= 2 - distance;
                distance = 1;
            }

            var cx = pos % Level.Width;
            var cy = pos / Level.Width;
            var ax = cx - distance;

            if (ax < 0)
            {
                ax = 0;
            }
            var bx = cx + distance;

            if (bx >= Level.Width)
            {
                bx = Level.Width - 1;
            }
            var ay = cy - distance;

            if (ay < 0)
            {
                ay = 0;
            }
            var by = cy + distance;

            if (by >= Level.Height)
            {
                by = Level.Height - 1;
            }

            for (var y = ay; y <= by; y++)
            {
                for (int x = ax, p = ax + y * Level.Width; x <= bx; x++, p++)
                {
                    if (!Dungeon.Visible[p])
                    {
                        continue;
                    }

                    if (intentional)
                    {
                        Sprite.Parent.AddToBack(new CheckedCell(p));
                    }

                    if (!Level.secret[p] || (!intentional && !(Random.Float() < level)))
                    {
                        continue;
                    }

                    var oldValue = Dungeon.Level.map[p];

                    GameScene.DiscoverTile(p, oldValue);

                    Level.Set(p, Terrain.discover(oldValue));

                    GameScene.UpdateMap(p);

                    ScrollOfMagicMapping.Discover(p);

                    smthFound = true;
                }
            }


            if (intentional)
            {
                Sprite.ShowStatus(CharSprite.Default, TxtSearch);
                Sprite.DoOperate(pos);

                if (smthFound)
                {
                    SpendAndNext(Random.Float() < level ? TimeToSearch : TimeToSearch * 2);
                }
                else
                {
                    SpendAndNext(TimeToSearch);
                }
            }

            if (!smthFound)
            {
                return(false);
            }

            GLog.Warning(TxtNoticedSmth);
            Sample.Instance.Play(Assets.SND_SECRET);
            Interrupt();

            return(true);
        }
예제 #10
0
        protected override bool Build()
        {
            if (!InitRooms())
            {
                return(false);
            }

            int distance;
            var retry       = 0;
            var minDistance = (int)Math.Sqrt(Rooms.Count);

            do
            {
                do
                {
                    RoomEntrance = Random.Element(Rooms);
                }while (RoomEntrance.Width() < 4 || RoomEntrance.Height() < 4);

                do
                {
                    RoomExit = Random.Element(Rooms);
                }while (RoomExit == RoomEntrance || RoomExit.Width() < 4 || RoomExit.Height() < 4);

                Graph.BuildDistanceMap(Rooms, RoomExit);
                distance = RoomEntrance.Distance();

                if (retry++ > 10)
                {
                    return(false);
                }
            }while (distance < minDistance);

            RoomEntrance.type = RoomType.ENTRANCE;
            RoomExit.type     = RoomType.EXIT;

            var connected = new List <Room>();

            connected.Add(RoomEntrance);

            Graph.BuildDistanceMap(Rooms, RoomExit);
            var path = Graph.BuildPath(Rooms, RoomEntrance, RoomExit);

            var room = RoomEntrance;

            foreach (var next in path)
            {
                room.Connect(next);
                room = next;
                connected.Add(room);
            }

            Graph.SetPrice(path, RoomEntrance.distance);

            Graph.BuildDistanceMap(Rooms, RoomExit);
            path = Graph.BuildPath(Rooms, RoomEntrance, RoomExit);

            room = RoomEntrance;
            foreach (var next in path)
            {
                room.Connect(next);
                room = next;
                connected.Add(room);
            }

            var nConnected = (int)(Rooms.Count * Random.Float(0.5f, 0.7f));

            while (connected.Count < nConnected)
            {
                var cr = Random.Element(connected);
                var or = Random.Element(cr.Neigbours);

                if (connected.Contains(or))
                {
                    continue;
                }

                cr.Connect(or);
                connected.Add(or);
            }

            if (Dungeon.ShopOnLevel())
            {
                var shop = RoomEntrance.Connected.Keys.FirstOrDefault(r => r.Connected.Count == 1 && r.Width() >= 5 && r.Height() >= 5);

                if (shop == null)
                {
                    return(false);
                }
                shop.type = RoomType.SHOP;
            }

            Specials = new List <RoomType>(levels.Room.SPECIALS);
            if (Dungeon.BossLevel(Dungeon.Depth + 1))
            {
                Specials.Remove(RoomType.WEAK_FLOOR);
            }
            AssignRoomType();

            Paint();
            PaintWater();
            PaintGrass();

            PlaceTraps();

            return(true);
        }