static public void Wield(THING t) { THING oW; //old weapon string sp; oW = Agent.CurrWeapon; if (!Item.IsDetachable(Agent.CurrWeapon)) { Agent.CurrWeapon = oW; return; } Agent.CurrWeapon = oW; sp = Item.GetDescription(t); Agent.CurrWeapon = t; if (!Agent.Terse) { R14.addmsg("You are now "); } R14.AddToLog("wielding {0} ({1})", sp, t.CharInPack); }
// Called to put a monster to death static public void killed(THING tp, bool pr) { string mname; Agent.Plyr.Stats.Xp += tp.Stats.Xp; // if the monster was a venus flytrap, un-hold him switch (tp.MonsType) { case 'F': Agent.Plyr.t_flags &= ~Mob.ISHELD; Agent.NumTimesFlytrapHasHit = 0; monsters['F' - 'A'].Stats.Dmg = "000x0"; break; case 'L': { THING gold; if (Weapon.PickRndPosAroundYX(tp.t_pos, tp.CurrRoom.GoldPos) && Agent.LevelOfMap >= Agent.dyn___max_level) { gold = new THING(); gold.ItemType = Char.GOLD; gold.o_goldval = GOLDCALC(); if (save(VS_MAGIC)) { gold.o_goldval += GOLDCALC() + GOLDCALC() + GOLDCALC() + GOLDCALC(); } attach(ref tp.Pack, gold); } } break; } // get rid of the monster mname = R14.GetMonsterName(tp); remove_mon(tp.t_pos, tp, true); if (pr) { if (!Agent.Terse) { addmsg("you have "); } addmsg("defeated "); R14.AddToLog(mname); } Agent.LevelUpPlayerMaybe(Agent.Pos); }
//find what room coords are in. NULL means they aren't in any public static room roomin(Coord cp) { int fp; fp = flat(cp.y, cp.x); if ((fp & F_PASS) != 0) { return(passages[fp & F_PNUM]); } foreach (var rp in rooms) { if (cp.x <= rp.PosUL.x + rp.Size.x && rp.PosUL.x <= cp.x && cp.y <= rp.PosUL.y + rp.Size.y && rp.PosUL.y <= cp.y) { return(rp); } } R14.AddToLog("in some bizarre place ({0}, {1})", cp.y, cp.x); return(null); }
//{identifying} what a certain object is public static void Identify(THING t) { if (Agent.Plyr.Pack == null) { S.Log("You don't have anything in your pack to identify", Color.red); return; } if (t == null) { return; } switch (t.ItemType) { case Char.SCROLL: set_know(t, Scroll.Data); break; case Char.POTION: set_know(t, Potion.Data); break; case Char.STICK: set_know(t, Stick.Data); break; case Char.WEAPON: case Char.ARMOUR: t.o_flags |= ISKNOW; break; case Char.RING: set_know(t, Ring.Data); break; } R14.AddToLog(Item.GetDescription(t)); }
static public void Read(THING t) { S.Log("Reading scroll: " + t.Name); bool discardit = false; PLACE pp; int y, x; int ch; int i; room cur_room; THING orig_obj; Coord mp = new Coord(); if (t == null) { return; } //calculate the effect it has on the poor guy if (t == Agent.CurrWeapon) { Agent.CurrWeapon = null; } discardit = (bool)(t.Count == 1); R14.leave_pack(t, false, false); orig_obj = t; switch (t.Which) { case S_CONFUSE: /* * Scroll of monster confusion. Give him that power. */ Agent.Plyr.t_flags |= Mob.CANHUH; S.Log("Your hands begin to glow " + Potion.GetColor("red")); break; case S_ARMOR: if (Agent.cur_armor != null) { Agent.cur_armor.Ac--; Agent.cur_armor.o_flags &= ~Item.IsCursed; R14.AddToLog("Your armor glows {0} for a moment", Potion.GetColor("silver")); } break; case S_HOLD: /* * Hold monster scroll. Stop all monsters within two spaces * from chasing after the hero. */ ch = '\0'; for (x = R14.hero.x - 2; x <= R14.hero.x + 2; x++) { if (x >= 0 && x < R14.NUMCOLS) { for (y = R14.hero.y - 2; y <= R14.hero.y + 2; y++) { if (y >= 0 && y <= R14.NUMLINES - 1) { if ((t = Dungeon.GetMonster(y, x)) != null && R14.on(t, Mob.ISRUN)) { t.t_flags &= ~Mob.ISRUN; t.t_flags |= Mob.ISHELD; ch++; } } } } } if (ch != '\0') { R14.addmsg("the monster"); if (ch > 1) { R14.addmsg("s around you"); } R14.addmsg(" freeze"); if (ch == 1) { R14.addmsg("s"); } Data[S_HOLD].Know = true; } else { S.Log("You feel a strange sense of loss"); } break; case S_SLEEP: //makes you fall asleep Data[S_SLEEP].Know = true; Agent.NumTurnsAsleep += R14.rnd(R14.SLEEPTIME) + 4; Agent.Plyr.t_flags &= ~Mob.ISRUN; S.Log("You fall asleep"); break; case S_CREATE: /* * Create a monster: * First look in a circle around him, next try his room * otherwise give up */ i = 0; for (y = R14.hero.y - 1; y <= R14.hero.y + 1; y++) { for (x = R14.hero.x - 1; x <= R14.hero.x + 1; x++) { //don't put on top of player if (y == R14.hero.y && x == R14.hero.x) { continue; } /* * Or anything else nasty */ else if (Dungeon.walkable___step_ok((char)(ch = Dungeon.GetMonsterAppearance(y, x)))) { if (ch == Char.SCROLL && Dungeon.find_obj(y, x).Which == S_SCARE) { continue; } else if (R14.rnd(++i) == 0) { mp.y = y; mp.x = x; } } } } if (i == 0) { S.Log("You hear a faint cry of anguish in the distance"); //S.Audio.Play("cry_of_anguish_:)"); } else { t = new THING(); R14.new_monster(t, R14.randmonster(false), mp); } break; case S_ID_POTION: case S_ID_SCROLL: case S_ID_WEAPON: case IdentifyArmour: case IdentifyRingOrStick: { Data[t.Which].Know = true; R14.AddToLog("this scroll is an {0} scroll", Data[t.Which].Name); Item.Identify(t); } break; case S_MAP: /* * Scroll of magic mapping. */ Data[S_MAP].Know = true; S.Log("oh, now this scroll has a map on it"); //take all the things we want to keep hidden out of the window for (y = 1; y < R14.NUMLINES - 1; y++) { for (x = 0; x < R14.NUMCOLS; x++) { pp = Dungeon.PlaceAt(y, x); switch (ch = pp.p_ch) { case Char.DOOR: case Char.STAIRS: break; case Char.WALL_HORI: case Char.WALL_VERT: if (!((pp.p_flags & Dungeon.F_REAL) != 0)) { ch = pp.p_ch = Char.DOOR; pp.p_flags |= Dungeon.F_REAL; } break; case ' ': if ((pp.p_flags & Dungeon.F_REAL) != 0) { goto def; } pp.p_flags |= Dungeon.F_REAL; ch = pp.p_ch = Char.PASSAGE; goto case Char.PASSAGE; case Char.PASSAGE: pass: if (!((pp.p_flags & Dungeon.F_REAL) != 0)) { pp.p_ch = Char.PASSAGE; } pp.p_flags |= (Dungeon.F_SEEN | Dungeon.F_REAL); ch = Char.PASSAGE; break; case Char.FLOOR: if ((pp.p_flags & Dungeon.F_REAL) != 0) { ch = ' '; } else { ch = Char.TRAP; pp.p_ch = Char.TRAP; pp.p_flags |= (Dungeon.F_SEEN | Dungeon.F_REAL); } break; default: def: if ((pp.p_flags & Dungeon.F_PASS) != 0) { goto pass; } ch = ' '; break; } if (ch != ' ') { if ((t = pp.p_monst) != null) { t.t_oldch = (char)ch; } //if no monster or player can't see invisible, draw floor if (t == null || !R14.on(Agent.Plyr, Mob.CanSeeInvisible)) { ; //R12.MvAddCh(y, x, ch); } } } } break; case S_FDET: ch = 0; S.Log("Should be showing food indicators, but..... ALPHA testing and all!"); //arrows at the edges of screen for offscreen food, and some highlighted effect for onscreen"); //could maybe send out lots of particles from foods towards player. //they'd startout stupid fast & slow down as they get farther away from spawn, or to the player. //giving a visual sense of distance for (t = Dungeon.ItemList; t != null; t = R14.next(t)) { if (t.ItemType == Char.FOOD) { ch = 1; //move(ItemPos); //addch(Char.FOOD); } } if (ch != 0) { Data[S_FDET].Know = true; S.Log("Your nose tingles and you smell food."); } else { S.Log("Your nose tingles"); } break; case S_TELEP: /* * Scroll of teleportation: * Make him dissapear and reappear */ { cur_room = Agent.Plyr.CurrRoom; Teleport(); if (cur_room != Agent.Plyr.CurrRoom) //if teleported to another room, we obviously know its a Teleport scroll { Scroll.Data[S_TELEP].Know = true; } } break; case S_ENCH: if (Agent.CurrWeapon == null || Agent.CurrWeapon.ItemType != Char.WEAPON) { S.Log("You feel a strange sense of loss"); } else { Agent.CurrWeapon.o_flags &= ~Item.IsCursed; if (R14.rnd(2) == 0) { Agent.CurrWeapon.PlusToHit++; } else { Agent.CurrWeapon.PlusToDmg++; } S.Log(string.Format("Your {0} glows {0} for a moment", Weapon.Data[Agent.CurrWeapon.Which].Name, Potion.GetColor("blue"))); } break; case S_SCARE: //reading it is a mistake and produces laughter at her poor boo boo S.Log("You hear maniacal laughter in the distance"); //S.Audio.Play("laugh"); //FIXME add laughter break; case S_REMOVE: uncurse(Agent.cur_armor); uncurse(Agent.CurrWeapon); uncurse(Agent.cur_ring[Ring.LEFT]); uncurse(Agent.cur_ring[Ring.RIGHT]); S.Log(R14.choose_str("You feel in touch with the Universal Onenes", "You feel as if somebody is watching over you")); break; case S_AGGR: /* * This scroll aggravates all the monsters on the current * level and sets them running towards the hero */ Dungeon.aggravate(); S.Log("You hear a high pitched humming noise"); //fixme: play hum sound break; case S_PROTECT: if (Agent.cur_armor != null) { Agent.cur_armor.o_flags |= Item.ISPROT; S.Log(string.Format("Your armor is covered by a shimmering {0} shield", Potion.GetColor("gold"))); } else { S.Log("You feel a strange sense of loss"); } break; } t = orig_obj; R14.glanceAroundHero___look(true); /* put the result of the scroll on the screen */ Item.UpdateGuess(Data[t.Which]); }
static public bool PlayerAttacks(Coord mp, THING weap, bool thrown) { THING tp; bool did_hit = true; string mname; char ch; /* * Find the monster we want to fight */ tp = Dungeon.GetMonster(mp.y, mp.x); //since we are fighting, things are not Quiet... so no healing takes place Agent.Quiet = 0; Mob.runto(mp); //if it was really a xeroc, let him know ch = '\0'; if (tp.MonsType == 'X' && tp.t_disguise != 'X' && !on(Agent.Plyr, Mob.ISBLIND)) { tp.t_disguise = 'X'; S.Log(choose_str( "heavy! That's a nasty critter!", "wait! That's a xeroc!")); if (!thrown) { return(false); } } mname = GetMonsterName(tp); did_hit = false; if (roll_em(Agent.Plyr, tp, weap, thrown)) { did_hit = false; if (thrown) { hitRanged(weap, mname, Agent.Terse); } else { hitMelee(null, mname, Agent.Terse); } if (on(Agent.Plyr, Mob.CANHUH)) { did_hit = true; tp.t_flags |= Mob.ISHUH; Agent.Plyr.t_flags &= ~Mob.CANHUH; R14.AddToLog("your hands stop glowing {0}", Potion.GetColor("red")); } if (tp.Stats.Hp <= 0) { killed(tp, true); } else if (did_hit && !on(Agent.Plyr, Mob.ISBLIND)) { R14.AddToLog("{0} appears confused", mname); } did_hit = true; } else if (thrown) { missRanged(weap, mname, Agent.Terse); } else { missMelee(null, mname, Agent.Terse); } return(did_hit); }
// The monster attacks the player static public int AttackPlayerWith(THING monst) { string mname; int oldhp; //since this is an attack, stop running and any healing that was going on at the time Agent.running = false; Agent.Quiet = 0; if (monst.MonsType == 'X' && monst.t_disguise != 'X' && !on(Agent.Plyr, Mob.ISBLIND)) { monst.t_disguise = 'X'; } mname = GetMonsterName(monst); oldhp = Agent.Plyr.Stats.Hp; if (roll_em(monst, Agent.Plyr, null, false)) { if (monst.MonsType != 'I') { addmsg(". "); hitMelee(mname, null, false); } if (Agent.Plyr.Stats.Hp <= 0) { death(monst.MonsType); /* Bye bye life ... */ } else { oldhp -= Agent.Plyr.Stats.Hp; } if (!on(monst, Mob.ISCANC)) { switch (monst.MonsType) { case 'A': /* * If an aquator hits, you can lose armor class. */ RustMaybe(Agent.cur_armor); break; case 'I': /* * The ice monster freezes you */ Agent.Plyr.t_flags &= ~Mob.ISRUN; if (Agent.NumTurnsAsleep == 0) { addmsg("you are frozen"); if (!Agent.Terse) { addmsg(" by the {0}", mname); } } Agent.NumTurnsAsleep += rnd(2) + 2; if (Agent.NumTurnsAsleep > BORE_LEVEL) { death('h'); } break; case 'R': //rattlesnakes have poisonous bites if (!save(VS_POISON)) { if (!Ring.ISWEARING(Ring.R_SUSTSTR)) { ModifyStrength(-1); if (!Agent.Terse) { S.Log("you feel a bite in your leg and now feel weaker"); } else { S.Log("a bite has weakened you"); } } else { if (!Agent.Terse) { S.Log("a bite momentarily weakens you"); } else { S.Log("bite has no effect"); } } } break; case 'W': case 'V': /* * Wraiths might drain energy levels, and Vampires * can steal max_hp */ if (rnd(100) < (monst.MonsType == 'W' ? 15 : 30)) { int fewer; if (monst.MonsType == 'W') { if (Agent.Plyr.Stats.Xp == 0) { death('W'); /* All levels gone */ } if (--Agent.Plyr.Stats.Level == 0) { Agent.Plyr.Stats.Xp = 0; Agent.Plyr.Stats.Level = 1; } else { Agent.Plyr.Stats.Xp = Agent.ExperienceGoals[Agent.Plyr.Stats.Level - 1] + 1; } fewer = RollDice(1, 10); } else { fewer = RollDice(1, 3); } Agent.Plyr.Stats.Hp -= fewer; Agent.Plyr.Stats.HpMax -= fewer; if (Agent.Plyr.Stats.Hp <= 0) { Agent.Plyr.Stats.Hp = 1; } if (Agent.Plyr.Stats.HpMax <= 0) { death(monst.MonsType); } S.Log("you suddenly feel weaker"); } break; case 'F': //venus Flytrap stops the poor guy from moving Agent.Plyr.t_flags |= Mob.ISHELD; monsters['F' - 'A'].Stats.Dmg = string.Format("{0}x1", ++Agent.NumTimesFlytrapHasHit); if (--Agent.Plyr.Stats.Hp <= 0) { death('F'); } break; case 'L': { //leprechaun steals some gold int lastpurse; lastpurse = Agent.purse; Agent.purse -= GOLDCALC(); if (!save(VS_MAGIC)) { Agent.purse -= GOLDCALC() + GOLDCALC() + GOLDCALC() + GOLDCALC(); } if (Agent.purse < 0) { Agent.purse = 0; } remove_mon(monst.t_pos, monst, false); monst = null; if (Agent.purse != lastpurse) { S.Log("your purse feels lighter"); } } break; case 'N': { THING obj, steal; int nobj; //nymph's steal a magic item. look through the pack and pick out one she likes steal = null; for (nobj = 0, obj = Agent.Plyr.Pack; obj != null; obj = next(obj)) { if (obj != Agent.cur_armor && obj != Agent.CurrWeapon && obj != Agent.cur_ring[Ring.LEFT] && obj != Agent.cur_ring[Ring.RIGHT] && Item.IsMagic(obj) && rnd(++nobj) == 0) { steal = obj; } } if (steal != null) { remove_mon(monst.t_pos, Dungeon.GetMonster(monst.t_pos.y, monst.t_pos.x), false); monst = null; leave_pack(steal, false, false); R14.AddToLog("she stole {0}!", Item.GetDescription(steal)); } } break; default: break; } } } else if (monst.MonsType != 'I') { addmsg(". "); if (monst.MonsType == 'F') { Agent.Plyr.Stats.Hp -= Agent.NumTimesFlytrapHasHit; if (Agent.Plyr.Stats.Hp <= 0) { death(monst.MonsType); /* Bye bye life ... */ } } missMelee(mname, null, false); } if (monst == null) { return(-1); } else { return(0); } }
// Draw a corridor from a room in a certain direction. static void conn(int r1, int r2) { room rpf, rpt = null; int rmt; int distance = 0, turn_spot, turn_distance = 0; int rm; char direc; if (r1 < r2) { rm = r1; if (r1 + 1 == r2) { direc = 'r'; } else { direc = 'd'; } } else { rm = r2; if (r2 + 1 == r1) { direc = 'r'; } else { direc = 'd'; } } rpf = rooms[rm]; /* * Set up the movement variables, in two cases: * first drawing one down. */ if (direc == 'd') { rmt = rm + 3; /* room # of dest */ rpt = rooms[rmt]; /* room pointer of dest */ del.x = 0; /* direction of move */ del.y = 1; spos.x = rpf.PosUL.x; /* start of move */ spos.y = rpf.PosUL.y; epos.x = rpt.PosUL.x; /* end of move */ epos.y = rpt.PosUL.y; if (!((rpf.Flags & Room.ISGONE) == Room.ISGONE)) /* if not gone pick door pos */ { do { spos.x = rpf.PosUL.x + R14.rnd(rpf.Size.x - 2) + 1; spos.y = rpf.PosUL.y + rpf.Size.y - 1; } while (((rpf.Flags & Room.ISMAZE) == Room.ISMAZE) && !((flat(spos.y, spos.x) & F_PASS) == F_PASS)); } if (!((rpt.Flags & Room.ISGONE) == Room.ISGONE)) { do { epos.x = rpt.PosUL.x + R14.rnd(rpt.Size.x - 2) + 1; } while (((rpt.Flags & Room.ISMAZE) == Room.ISMAZE) && !((flat(epos.y, epos.x) & F_PASS) == F_PASS)); } distance = Math.Abs(spos.y - epos.y) - 1; /* distance to move */ turn_delta.y = 0; /* direction to turn */ turn_delta.x = (spos.x < epos.x ? 1 : -1); turn_distance = Math.Abs(spos.x - epos.x); /* how far to turn */ } else if (direc == 'r') /* setup for moving right */ { rmt = rm + 1; rpt = rooms[rmt]; del.x = 1; del.y = 0; spos.x = rpf.PosUL.x; spos.y = rpf.PosUL.y; epos.x = rpt.PosUL.x; epos.y = rpt.PosUL.y; if (!((rpf.Flags & Room.ISGONE) == Room.ISGONE)) { do { spos.x = rpf.PosUL.x + rpf.Size.x - 1; spos.y = rpf.PosUL.y + R14.rnd(rpf.Size.y - 2) + 1; } while (((rpf.Flags & Room.ISMAZE) == Room.ISMAZE) && !((flat(spos.y, spos.x) & F_PASS) == F_PASS)); } if (!((rpt.Flags & Room.ISGONE) == Room.ISGONE)) { do { epos.y = rpt.PosUL.y + R14.rnd(rpt.Size.y - 2) + 1; } while (((rpt.Flags & Room.ISMAZE) == Room.ISMAZE) && !((flat(epos.y, epos.x) & F_PASS) == F_PASS)); } distance = Math.Abs(spos.x - epos.x) - 1; turn_delta.y = (spos.y < epos.y ? 1 : -1); turn_delta.x = 0; turn_distance = Math.Abs(spos.y - epos.y); } turn_spot = R14.rnd(distance - 1) + 1; /* where turn starts */ /* * Draw in the doors on either side of the passage or just put #'s * if the rooms are gone. */ if (!((rpf.Flags & Room.ISGONE) == Room.ISGONE)) { door(rpf, spos); } else { putpass(spos); } if (!((rpt.Flags & Room.ISGONE) == Room.ISGONE)) { door(rpt, epos); } else { putpass(epos); } /* * Get ready to move... */ curr.x = spos.x; curr.y = spos.y; while (distance > 0) { /* * Move to new pos */ curr.x += del.x; curr.y += del.y; /* * Check if we are at the turn place, if so do the turn */ if (distance == turn_spot) { while (turn_distance-- > 0) { putpass(curr); curr.x += turn_delta.x; curr.y += turn_delta.y; } } /* * Continue digging along */ putpass(curr); distance--; } curr.x += del.x; curr.y += del.y; if (!TheseShareCoords(curr, epos)) { R14.AddToLog("warning, connectivity problem on this level"); } }