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); }
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; } }
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; } }
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); }
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); }
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)); } } }
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(); }
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); }
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); }
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); }