public void OnSelect(int?target) { if (target == null) { return; } if (!Level.fieldOfView[target.Value] || !(Level.passable[target.Value] || Level.avoid[target.Value]) || Actor.FindChar(target.Value) != null) { GLog.Warning(TXT_FOV); return; } CurUser.HP -= (CurUser.HP / 3); foreach (var mob in Dungeon.Level.mobs.Where(mob => Level.fieldOfView[mob.pos])) { Buff.Prolong <Blindness>(mob, 2); mob.State = mob.WANDERING; mob.Sprite.Emitter().Burst(Speck.Factory(Speck.LIGHT), 4); } WandOfBlink.Appear(CurUser, target.Value); CellEmitter.Get(target.Value).Burst(Speck.Factory(Speck.WOOL), 10); Sample.Instance.Play(Assets.SND_PUFF); Dungeon.Level.Press(target.Value, CurUser); Dungeon.Observe(); CurUser.SpendAndNext(Actor.Tick); }
public virtual void Open(Hero hero) { switch (HeapType) { case Type.Tomb: Wraith.SpawnAround(hero.pos); break; case Type.Skeleton: CellEmitter.Center(Pos).Start(Speck.Factory(Speck.RATTLE), 0.1f, 3); if (Items.Any(item => item.cursed)) { if (Wraith.SpawnAt(Pos) == null) { hero.Sprite.Emitter().Burst(ShadowParticle.Curse, 6); hero.Damage(hero.HP / 2, this); } Sample.Instance.Play(Assets.SND_CURSED); } break; } HeapType = Type.Heap; Sprite.Link(); Sprite.Drop(); }
public static void Affect(int cell, Fire fire) { var ch = Actor.FindChar(cell); if (ch != null) { Buff.Prolong <Frost>(ch, Frost.duration(ch) * pdsharp.utils.Random.Float(1.0f, 1.5f)); } if (fire != null) { fire.Clear(cell); } var heap = Dungeon.Level.heaps[cell]; if (heap != null) { heap.Freeze(); } if (Dungeon.Visible[cell]) { CellEmitter.Get(cell).Start(SnowParticle.Factory, 0.2f, 6); } }
public override void Press(int cell, Character hero) { base.Press(cell, hero); if (enteredArena || !outsideEntraceRoom(cell) || hero != Dungeon.Hero) { return; } enteredArena = true; var boss = Bestiary.Mob(Dungeon.Depth); boss.State = boss.HUNTING; do { boss.pos = Random.Int(Length); }while (!passable[boss.pos] || !outsideEntraceRoom(boss.pos) || Dungeon.Visible[boss.pos]); GameScene.Add(boss); Set(arenaDoor, Terrain.WALL); GameScene.UpdateMap(arenaDoor); Dungeon.Observe(); CellEmitter.Get(arenaDoor).Start(Speck.Factory(Speck.ROCK), 0.07f, 10); Camera.Main.Shake(3, 0.7f); Sample.Instance.Play(Assets.SND_ROCKS); }
// 00x66CCEE public static void Trigger(int pos, Character ch) { if (ch != null) { ch.Damage(Math.Max(1, Random.Int(ch.HP / 3, 2 * ch.HP / 3)), LIGHTNING); if (ch == Dungeon.Hero) { Camera.Main.Shake(2, 0.3f); if (!ch.IsAlive) { Dungeon.Fail(Utils.Format(ResultDescriptions.TRAP, name, Dungeon.Depth)); GLog.Negative("You were killed by a discharge of a lightning trap..."); } else { ((Hero)ch).Belongings.Charge(false); } } var points = new int[2]; points[0] = pos - Level.Width; points[1] = pos + Level.Width; ch.Sprite.Parent.Add(new Lightning(points, 2, null)); points[0] = pos - 1; points[1] = pos + 1; ch.Sprite.Parent.Add(new Lightning(points, 2, null)); } CellEmitter.Center(pos).Burst(SparkParticle.Factory, Random.IntRange(3, 4)); }
public void Call() { CellEmitter.Center(_pos).Burst(Speck.Factory(Speck.STAR), 7); Sample.Instance.Play(Assets.SND_EVOKE); Level.Set(_pos, Terrain.WALL); GameScene.UpdateMap(_pos); var gold = new DarkGold(); if (gold.DoPickUp(Dungeon.Hero)) { GLog.Information(Hero.TxtYouNowHave, gold.Name); } else { Dungeon.Level.Drop(gold, Dungeon.Hero.pos).Sprite.Drop(); } var hunger = Dungeon.Hero.Buff <Hunger>(); if (hunger != null && !hunger.IsStarving) { hunger.Satisfy(Hunger.Starving / 10 * -1); BuffIndicator.RefreshHero(); } Dungeon.Hero.OnOperateComplete(); }
protected internal override void OnZap(int cell) { var terrainAffected = false; var localLevel = Level; var maxDistance = Distance(); Ballistica.Distance = Math.Min(Ballistica.Distance, maxDistance); var chars = new List <Character>(); for (var i = 1; i < Ballistica.Distance; i++) { var c = Ballistica.Trace[i]; Character ch; if ((ch = Actor.FindChar(c)) != null) { chars.Add(ch); } var terr = Dungeon.Level.map[c]; switch (terr) { case Terrain.BARRICADE: case Terrain.DOOR: levels.Level.Set(c, Terrain.EMBERS); GameScene.UpdateMap(c); terrainAffected = true; break; case Terrain.HIGH_GRASS: levels.Level.Set(c, Terrain.GRASS); GameScene.UpdateMap(c); terrainAffected = true; break; } CellEmitter.Center(c).Burst(PurpleParticle.Burst, pdsharp.utils.Random.IntRange(1, 2)); } if (terrainAffected) { Dungeon.Observe(); } var lvl = localLevel + chars.Count; var dmgMin = lvl; var dmgMax = 8 + lvl * lvl / 3; foreach (var ch in chars) { ch.Damage(pdsharp.utils.Random.NormalIntRange(dmgMin, dmgMax), this); ch.Sprite.CenterEmitter().Burst(PurpleParticle.Burst, pdsharp.utils.Random.IntRange(1, 2)); ch.Sprite.Flash(); } }
public override void Interact() { ((Character)this).Sprite.TurnTo(pos, Dungeon.Hero.pos); Sample.Instance.Play(Assets.SND_GHOST); if (Quest.given) { Item item; if (Quest.alternative) { item = Dungeon.Hero.Belongings.GetItem <RatSkull>(); } else { item = Dungeon.Hero.Belongings.GetItem <DriedRose>(); } if (item != null) { GameScene.Show(new WndSadGhost(this, item)); } else { GameScene.Show(new WndQuest(this, Quest.alternative ? TxtRat2 : TxtRose2)); var newPos = -1; for (var i = 0; i < 10; i++) { newPos = Dungeon.Level.RandomRespawnCell(); if (newPos != -1) { break; } } if (newPos == -1) { return; } FreeCell(pos); CellEmitter.Get(pos).Start(Speck.Factory(Speck.LIGHT), 0.2f, 3); pos = newPos; ((Character)this).Sprite.Place(pos); ((Character)this).Sprite.Visible = Dungeon.Visible[pos]; } } else { GameScene.Show(new WndQuest(this, Quest.alternative ? TxtRat1 : TxtRose1)); Quest.given = true; Journal.Add(Journal.Feature.GHOST); } }
// 0xBB66EE public static void Trigger(int pos, Character ch) { if (ch != null) { Buff.Affect <Poison>(ch).Set(Poison.DurationFactor(ch) * (4 + Dungeon.Depth / 2)); } CellEmitter.Center(pos).Burst(PoisonParticle.Splash, 3); }
protected internal override void OnZap(int cell) { var localLevel = Level; var n = localLevel + 2; if (Actor.FindChar(cell) != null && Ballistica.Distance > 2) { cell = Ballistica.Trace[Ballistica.Distance - 2]; } var passable = BArray.or(levels.Level.passable, levels.Level.avoid, null); foreach (var actor in Actor.All.OfType <Character>()) { passable[(actor).pos] = false; } PathFinder.BuildDistanceMap(cell, passable, n); var dist = 0; if (Actor.FindChar(cell) != null) { PathFinder.Distance[cell] = int.MaxValue; dist = 1; } float lifespan = localLevel + 3; sheepLabel: for (var i = 0; i < n; i++) { do { for (var j = 0; j < levels.Level.Length; j++) { if (PathFinder.Distance[j] != dist) { continue; } var sheep = new Sheep(); sheep.Lifespan = lifespan; sheep.pos = j; GameScene.Add(sheep); Dungeon.Level.MobPress(sheep); CellEmitter.Get(j).Burst(Speck.Factory(Speck.WOOL), 4); PathFinder.Distance[j] = int.MaxValue; goto sheepLabel; } dist++; } while (dist < n); } }
public override void Activate(Character ch) { base.Activate(ch); GameScene.Add(Blob.Seed(Pos, 2, typeof(Fire))); if (Dungeon.Visible[Pos]) { CellEmitter.Get(Pos).Burst(FlameParticle.Factory, 5); } }
protected internal virtual void Flee() { foreach (var heap in Dungeon.Level.heaps.Values.Where(heap => heap.HeapType == Heap.Type.ForSale)) { CellEmitter.Get(heap.Pos).Burst(ElmoParticle.Factory, 4); heap.Destroy(); } Destroy(); Sprite.KillAndErase(); CellEmitter.Get(pos).Burst(ElmoParticle.Factory, 6); }
protected internal override void Flee() { foreach (var heap in Dungeon.Level.heaps.Values.Where(heap => heap.HeapType == Heap.Type.ForSale)) { CellEmitter.Get(heap.Pos).Burst(ElmoParticle.Factory, 4); heap.Destroy(); } Destroy(); Sprite.Emitter().Burst(Speck.Factory(Speck.WOOL), 15); Sprite.KillAndErase(); }
public override void Activate(Character ch) { base.Activate(ch); if (ch != null) { Buff.Affect <Poison>(ch).Set(Poison.DurationFactor(ch) * (4 + Dungeon.Depth / 2)); } if (Dungeon.Visible[Pos]) { CellEmitter.Center(Pos).Burst(PoisonParticle.Splash, 3); } }
public override void Activate(Character ch) { base.Activate(ch); if (ch != null) { Buff.Affect <Health>(ch); } if (Dungeon.Visible[Pos]) { CellEmitter.Get(Pos).Start(ShaftParticle.Factory, 0.2f, 3); } }
// 0xDD3333 public static void Trigger(int pos, Character ch) { foreach (var mob in Dungeon.Level.mobs.Where(mob => mob != ch)) { mob.Beckon(pos); } if (Dungeon.Visible[pos]) { GLog.Warning("The trap emits a piercing sound that echoes throughout the dungeon!"); CellEmitter.Center(pos).Start(Speck.Factory(Speck.SCREAM), 0.3f, 3); } Sample.Instance.Play(Assets.SND_ALERT); }
public override int Proc(Armor armor, Character attacker, Character defender, int damage) { var level = Math.Max(0, armor.level); if (pdsharp.utils.Random.Int(4) != 0) { return(damage); } Buff.Prolong <Roots>(defender, 5 - level / 5); Buff.Affect <Earthroot.Armor>(defender).Level = 5 * (level + 1); CellEmitter.Bottom(defender.pos).Start(EarthParticle.Factory, 0.05f, 8); Camera.Main.Shake(1, 0.4f); return(damage); }
protected internal override void OnZap(int cell) { Sample.Instance.Play(Assets.SND_ROCKS); var localLevel = Level; Ballistica.Distance = Math.Min(Ballistica.Distance, 8 + localLevel); var size = 1 + localLevel / 3; PathFinder.BuildDistanceMap(cell, BArray.not(levels.Level.solid, null), size); for (var i = 0; i < levels.Level.Length; i++) { int d = PathFinder.Distance[i]; if (d >= int.MaxValue) { continue; } var ch = Actor.FindChar(i); if (ch != null) { ch.Sprite.Flash(); ch.Damage(pdsharp.utils.Random.Int(2, 6 + (size - d) * 2), this); if (ch.IsAlive && pdsharp.utils.Random.Int(2 + d) == 0) { Buff.Prolong <Paralysis>(ch, pdsharp.utils.Random.IntRange(2, 6)); } } CellEmitter.Get(i).Start(Speck.Factory(Speck.ROCK), 0.07f, 3 + (size - d)); Camera.Main.Shake(3, 0.07f * (3 + (size - d))); } if (CurUser.IsAlive) { return; } Dungeon.Fail(Utils.Format(ResultDescriptions.WAND, name, Dungeon.Depth)); GLog.Negative("You killed yourself with your own Wand of Avalanche..."); }
public override int Proc(Armor armor, Character attacker, Character defender, int damage) { var level = Math.Max(0, armor.level); if (!Level.Adjacent(attacker.pos, defender.pos) || pdsharp.utils.Random.Int(level + 6) < 5) { return(damage); } Buff.Prolong <Frost>(attacker, Frost.duration(attacker) * pdsharp.utils.Random.Float(1f, 1.5f)); CellEmitter.Get(attacker.pos).Start(SnowParticle.Factory, 0.2f, 6); Buff.Affect <Burning>(defender).Reignite(defender); defender.Sprite.Emitter().Burst(FlameParticle.Factory, 5); return(damage); }
public override void Activate(Character ch) { base.Activate(ch); if (ch != null) { Buff.Affect <Armor>(ch).Level = ch.HT; } if (!Dungeon.Visible[Pos]) { return; } CellEmitter.Bottom(Pos).Start(effects.particles.EarthParticle.Factory, 0.05f, 8); Camera.Main.Shake(1, 0.4f); }
public override Heap Drop(Item item, int cell) { if (keyDropped || !(item is SkeletonKey)) { return(base.Drop(item, cell)); } keyDropped = true; CellEmitter.Get(arenaDoor).Start(Speck.Factory(Speck.ROCK), 0.07f, 10); Set(arenaDoor, Terrain.EMPTY_DECO); GameScene.UpdateMap(arenaDoor); Dungeon.Observe(); return(base.Drop(item, cell)); }
public void Call() { _warriorArmor.CurUser.Move(_dest); Dungeon.Level.Press(_dest, _warriorArmor.CurUser); Dungeon.Observe(); foreach (var neighbour in Level.NEIGHBOURS8) { var mob = Actor.FindChar(_warriorArmor.CurUser.pos + neighbour); if (mob != null && mob != _warriorArmor.CurUser) { Buff.Prolong <Paralysis>(mob, WarriorArmor.ShockTime); } } CellEmitter.Center(_dest).Burst(Speck.Factory(Speck.DUST), 10); Camera.Main.Shake(2, 0.5f); _warriorArmor.CurUser.SpendAndNext(WarriorArmor.LeapTime); }
public virtual void Drop() { if (heap.IsEmpty) { return; } dropInterval = DROP_INTERVAL; Speed.Set(0, -100); Acc.Set(0, -Speed.Y / DROP_INTERVAL * 2); if (IsVisible && heap != null && heap.Peek() is Gold) { CellEmitter.Center(heap.Pos).Burst(Speck.Factory(Speck.COIN), 5); Sample.Instance.Play(Assets.SND_GOLD, 1, 1, pdsharp.utils.Random.Float(0.9f, 1.1f)); } }
protected internal override bool AffectHero(Hero hero) { Sample.Instance.Play(Assets.SND_DRINK); PotionOfHealing.Heal(hero); hero.Belongings.UncurseEquipped(); hero.Buff <Hunger>().Satisfy(Hunger.Starving); CellEmitter.Get(Pos).Start(ShaftParticle.Factory, 0.2f, 3); Dungeon.Hero.Interrupt(); GLog.Positive(TxtProcced); Journal.Remove(Journal.Feature.WELL_OF_HEALTH); return(true); }
public static void Trample(Level level, int pos, Character ch) { Level.Set(pos, Terrain.GRASS); GameScene.UpdateMap(pos); if (!Dungeon.IsChallenged(Challenges.NO_HERBALISM)) { var herbalismLevel = 0; if (ch != null) { var herbalism = ch.Buff <RingOfHerbalism.Herbalism>(); if (herbalism != null) { herbalismLevel = herbalism.Level; } } // Seed if (herbalismLevel >= 0 && pdsharp.utils.Random.Int(18) <= pdsharp.utils.Random.Int(herbalismLevel + 1)) { level.Drop(Generator.Random(Generator.Category.SEED), pos).Sprite.Drop(); } // Dew if (herbalismLevel >= 0 && pdsharp.utils.Random.Int(6) <= pdsharp.utils.Random.Int(herbalismLevel + 1)) { level.Drop(new Dewdrop(), pos).Sprite.Drop(); } } var leaves = 4; // Barkskin var hero = ch as Hero; if (hero != null && hero.subClass == HeroSubClass.WARDEN) { Buff.Affect <Barkskin>(hero).Level(hero.HT / 3); leaves = 8; } CellEmitter.Get(pos).Burst(LeafParticle.LevelSpecific, leaves); Dungeon.Observe(); }
public override void Move(int step) { base.Move(step); if (Dungeon.Level.map[step] == Terrain.INACTIVE_TRAP && HP < HT) { HP += pdsharp.utils.Random.Int(1, HT - HP); Sprite.Emitter().Burst(ElmoParticle.Factory, 5); if (Dungeon.Visible[step] && Dungeon.Hero.IsAlive) { GLog.Negative("DM-300 repairs itself!"); } } int[] cells = { step - 1, step + 1, step - Level.Width, step + Level.Width, step - 1 - Level.Width, step - 1 + Level.Width, step + 1 - Level.Width, step + 1 + Level.Width }; var cell = cells[pdsharp.utils.Random.Int(cells.Length)]; if (Dungeon.Visible[cell]) { CellEmitter.Get(cell).Start(Speck.Factory(Speck.ROCK), 0.07f, 10); Camera.Main.Shake(3, 0.7f); Sample.Instance.Play(Assets.SND_ROCKS); if (Level.water[cell]) { GameScene.Ripple(cell); } else if (Dungeon.Level.map[cell] == Terrain.EMPTY) { Level.Set(cell, Terrain.EMPTY_DECO); GameScene.UpdateMap(cell); } } var ch = FindChar(cell); if (ch != null && ch != this) { buffs.Buff.Prolong <Paralysis>(ch, 2); } }
public override void Activate(Character ch) { base.Activate(ch); var hero = ch as Hero; if (hero != null) { ScrollOfTeleportation.TeleportHero(hero); hero.curAction = null; } else if (ch is Mob) { // Why do I try to choose a new position 10 times? // I don't remember... var count = 10; int newPos; do { newPos = Dungeon.Level.RandomRespawnCell(); if (count-- <= 0) { break; } } while (newPos == -1); if (newPos != -1) { ch.pos = newPos; ch.Sprite.Place(ch.pos); ch.Sprite.Visible = Dungeon.Visible[Pos]; } } if (Dungeon.Visible[Pos]) { CellEmitter.Get(Pos).Start(Speck.Factory(Speck.LIGHT), 0.2f, 3); } }
private void Jump() { _timeToJump = JumpDelay; for (var i = 0; i < 4; i++) { int trapPos; do { trapPos = pdsharp.utils.Random.Int(Level.Length); }while (!Level.fieldOfView[trapPos] || !Level.passable[trapPos]); if (Dungeon.Level.map[trapPos] != Terrain.INACTIVE_TRAP) { continue; } Level.Set(trapPos, Terrain.POISON_TRAP); GameScene.UpdateMap(trapPos); ScrollOfMagicMapping.Discover(trapPos); } int newPos; do { newPos = pdsharp.utils.Random.Int(Level.Length); }while (!Level.fieldOfView[newPos] || !Level.passable[newPos] || Level.Adjacent(newPos, Enemy.pos) || FindChar(newPos) != null); Sprite.Move(pos, newPos); Move(newPos); if (Dungeon.Visible[newPos]) { CellEmitter.Get(newPos).Burst(Speck.Factory(Speck.WOOL), 6); Sample.Instance.Play(Assets.SND_PUFF); } Spend(1 / Speed()); }
protected internal override void Fx(int cell, ICallback callback) { _nPoints = 0; _points[_nPoints++] = Dungeon.Hero.pos; var ch = Actor.FindChar(cell); if (ch != null) { _affected.Clear(); var lvl = Level; Hit(ch, pdsharp.utils.Random.Int(5 + lvl / 2, 10 + lvl)); } else { _points[_nPoints++] = cell; CellEmitter.Center(cell).Burst(SparkParticle.Factory, 3); } CurUser.Sprite.Parent.Add(new Lightning(_points, _nPoints, callback)); }
public override bool Attack(Character enemy) { for (var i = 1; i < Ballistica.Distance; i++) { var localPos = Ballistica.Trace[i]; var ch = FindChar(localPos); if (ch == null) { continue; } if (Hit(this, ch, true)) { ch.Damage(pdsharp.utils.Random.NormalIntRange(14, 20), this); if (Dungeon.Visible[localPos]) { ch.Sprite.Flash(); CellEmitter.Center(localPos).Burst(PurpleParticle.Burst, pdsharp.utils.Random.IntRange(1, 2)); } if (ch.IsAlive || ch != Dungeon.Hero) { continue; } Dungeon.Fail(Utils.Format(ResultDescriptions.MOB, Utils.Indefinite(Name), Dungeon.Depth)); GLog.Negative(TxtDeathgazeKilled, Name); } else { ch.Sprite.ShowStatus(CharSprite.Neutral, ch.DefenseVerb()); } } return(true); }