/** * Check for resistance to a GF_ attack type. Return codes: * -1 = vulnerability * 0 = no resistance (or resistance plus vulnerability) * 1 = single resistance or opposition (or double resist plus vulnerability) * 2 = double resistance (including opposition) * 3 = total immunity * * \param type is the attack type we are trying to resist * \param flags is the set of flags we're checking * \param real is whether this is a real attack */ public static int check_for_resist(Player.Player p, GF type, Bitflag flags, bool real) { //GF gf_ptr = &gf_table[type]; GF gf_ptr = type; int result = 0; if (gf_ptr.vuln != Object.Object_Flag.NONE && flags.has(gf_ptr.vuln.value)) { result--; } /* If it's not a real attack, we don't check timed status explicitly */ if (real && (int)gf_ptr.opp != 0 && p.timed[(int)gf_ptr.opp] != 0) { result++; } if (gf_ptr.resist != Object.Object_Flag.NONE && flags.has(gf_ptr.resist.value)) { result++; } if (gf_ptr.immunity != Object.Object_Flag.NONE && flags.has(gf_ptr.immunity.value)) { result = 3; } /* Notice flags, if it's a real attack */ if (real && gf_ptr.immunity.value != 0) { Object.Object.wieldeds_notice_flag(p, gf_ptr.immunity.value); } if (real && gf_ptr.resist.value != 0) { Object.Object.wieldeds_notice_flag(p, gf_ptr.resist.value); } if (real && gf_ptr.vuln.value != 0) { Object.Object.wieldeds_notice_flag(p, gf_ptr.vuln.value); } return(result); }
/* * Add an object to a real stores inventory. * * If the object is "worthless", it is thrown away (except in the home). * * If the object cannot be combined with an object already in the inventory, * make a new slot for it, and calculate its "per item" price. Note that * this price will be negative, since the price will not be "fixed" yet. * Adding an object to a "fixed" price stack will not change the fixed price. * * In all cases, return the slot (or -1) where the object was placed */ int carry(Object.Object o_ptr) { int slot; int value, j_value; Object.Object j_ptr; Object_Kind kind = o_ptr.kind; /* Evaluate the object */ value = o_ptr.value(1, false); /* Cursed/Worthless items "disappear" when sold */ if (value <= 0) return (-1); /* Erase the inscription & pseudo-ID bit */ o_ptr.note = null; /* Some item types require maintenance */ switch (o_ptr.tval) { /* Refuel lights to the standard amount */ case TVal.TV_LIGHT: { Bitflag f = new Bitflag(Object_Flag.SIZE); o_ptr.object_flags(ref f); if (!f.has(Object_Flag.NO_FUEL.value)) { if (o_ptr.sval == SVal.SV_LIGHT_TORCH) o_ptr.timeout = Misc.DEFAULT_TORCH; else if (o_ptr.sval == SVal.SV_LIGHT_LANTERN) o_ptr.timeout = Misc.DEFAULT_LAMP; } break; } /* Recharge rods */ case TVal.TV_ROD: { o_ptr.timeout = 0; break; } /* Possibly recharge wands and staves */ case TVal.TV_STAFF: case TVal.TV_WAND: { bool recharge = false; /* Recharge without fail if the store normally carries that type */ for (int i = 0; i < table_num; i++) { if (table[i] == o_ptr.kind) recharge = true; } if (recharge) { int charges = 0; /* Calculate the recharged number of charges */ for (int i = 0; i < o_ptr.number; i++) charges += Random.randcalc(kind.charge, 0, aspect.RANDOMISE); /* Use recharged value only if greater */ if (charges > o_ptr.pval[Misc.DEFAULT_PVAL]) o_ptr.pval[Misc.DEFAULT_PVAL] = (short)charges; } break; } } /* Check each existing object (try to combine) */ for (slot = 0; slot < stock_num; slot++) { /* Get the existing object */ j_ptr = stock[slot]; /* Can the existing items be incremented? */ if (j_ptr.similar(o_ptr, Object.Object.object_stack_t.OSTACK_STORE)) { /* Absorb (some of) the object */ store_object_absorb(ref j_ptr, ref o_ptr); /* All done */ return (slot); } } /* No space? */ if (stock_num >= stock_size) { return (-1); } /* Check existing slots to see if we must "slide" */ for (slot = 0; slot < stock_num; slot++) { /* Get that object */ j_ptr = stock[slot]; /* Objects sort by decreasing type */ if (o_ptr.tval > j_ptr.tval) break; if (o_ptr.tval < j_ptr.tval) continue; /* Objects sort by increasing sval */ if (o_ptr.sval < j_ptr.sval) break; if (o_ptr.sval > j_ptr.sval) continue; /* Evaluate that slot */ j_value = j_ptr.value(1, false); /* Objects sort by decreasing value */ if (value > j_value) break; if (value < j_value) continue; } /* Slide the others up */ for (int i = stock_num; i > slot; i--) { stock[i] = stock[i - 1]; /* Hack -- slide the objects */ //object_copy(&store.stock[i], &store.stock[i-1]); } /* More stuff now */ stock_num++; /* Hack -- Insert the new object */ stock[slot] = o_ptr; //object_copy(&store.stock[slot], o_ptr); /* Return the location */ return (slot); }
/* * Acid has hit the player, attempt to affect some armor. * * Note that the "base armor" of an object never changes. * * If any armor is damaged (or resists), the player takes less damage. */ static bool minus_ac(Player.Player p) { Object.Object o_ptr = null; Bitflag f = new Bitflag(Object.Object_Flag.SIZE); //char o_name[80]; string o_name; /* Avoid crash during monster power calculations */ if (p.inventory == null) return false; /* Pick a (possibly empty) inventory slot */ switch (Random.randint1(6)) { case 1: o_ptr = p.inventory[Misc.INVEN_BODY]; break; case 2: o_ptr = p.inventory[Misc.INVEN_ARM]; break; case 3: o_ptr = p.inventory[Misc.INVEN_OUTER]; break; case 4: o_ptr = p.inventory[Misc.INVEN_HANDS]; break; case 5: o_ptr = p.inventory[Misc.INVEN_HEAD]; break; case 6: o_ptr = p.inventory[Misc.INVEN_FEET]; break; //default: Misc.assert(0); //Nick: DA FUQ is this doing here C??? } /* Nothing to damage */ if (o_ptr.kind == null) return (false); /* No damage left to be done */ if (o_ptr.ac + o_ptr.to_a <= 0) return (false); /* Describe */ o_name = o_ptr.object_desc(Object.Object.Detail.BASE); //object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); /* Extract the flags */ o_ptr.object_flags(ref f); /* Object resists */ if (f.has(Object.Object_Flag.IGNORE_ACID.value)) { Utilities.msg("Your %s is unaffected!", o_name); return (true); } /* Message */ Utilities.msg("Your %s is damaged!", o_name); /* Damage the item */ o_ptr.to_a--; p.update |= Misc.PU_BONUS; p.redraw |= (Misc.PR_EQUIP); /* Item was damaged */ return (true); }
/** * Check for resistance to a GF_ attack type. Return codes: * -1 = vulnerability * 0 = no resistance (or resistance plus vulnerability) * 1 = single resistance or opposition (or double resist plus vulnerability) * 2 = double resistance (including opposition) * 3 = total immunity * * \param type is the attack type we are trying to resist * \param flags is the set of flags we're checking * \param real is whether this is a real attack */ public static int check_for_resist(Player.Player p, GF type, Bitflag flags, bool real) { //GF gf_ptr = &gf_table[type]; GF gf_ptr = type; int result = 0; if (gf_ptr.vuln != Object.Object_Flag.NONE && flags.has(gf_ptr.vuln.value)) result--; /* If it's not a real attack, we don't check timed status explicitly */ if (real && (int)gf_ptr.opp != 0 && p.timed[(int)gf_ptr.opp] != 0) result++; if (gf_ptr.resist != Object.Object_Flag.NONE && flags.has(gf_ptr.resist.value)) result++; if (gf_ptr.immunity != Object.Object_Flag.NONE && flags.has(gf_ptr.immunity.value)) result = 3; /* Notice flags, if it's a real attack */ if (real && gf_ptr.immunity.value != 0) Object.Object.wieldeds_notice_flag(p, gf_ptr.immunity.value); if (real && gf_ptr.resist.value != 0) Object.Object.wieldeds_notice_flag(p, gf_ptr.resist.value); if (real && gf_ptr.vuln.value != 0) Object.Object.wieldeds_notice_flag(p, gf_ptr.vuln.value); return result; }
static void display_resistance_panel(player_flag_record[] resists, int size, Region bounds) { Player.Player p_ptr = Player.Player.instance; int col = bounds.col; int row = bounds.row; Term.putstr(col, row++, RES_COLS, ConsoleColor.White, " abcdefghijkl@"); for (int i = 0; i < size-3; i++, row++) { ConsoleColor name_attr = ConsoleColor.White; Term.gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (int j = Misc.INVEN_WIELD; j <= Misc.INVEN_TOTAL; j++) { Object.Object o_ptr = p_ptr.inventory[j]; Bitflag f = new Bitflag(Object_Flag.SIZE); ConsoleColor[] alternatingcols = new ConsoleColor[]{ ConsoleColor.Gray, ConsoleColor.DarkGray }; ConsoleColor attr = alternatingcols[j % 2]; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ f.wipe(); if (j < Misc.INVEN_TOTAL && o_ptr.kind != null) { o_ptr.object_flags_known(ref f); } else if (j == Misc.INVEN_TOTAL) { Player.Player.player_flags(ref f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (p_ptr.Race.infra > 0) f.on(Object_Flag.INFRA.value); if (p_ptr.Race.r_skills[(int)Skill.DIGGING] > 0) f.on(Object_Flag.TUNNEL.value); } res = f.has(resists[i].res_flag.value); imm = f.has(resists[i].im_flag.value); vuln = f.has(resists[i].vuln_flag.value); if (imm) name_attr = ConsoleColor.DarkGreen; else if (res && name_attr == ConsoleColor.White) name_attr = ConsoleColor.Cyan; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < Misc.INVEN_TOTAL) && o_ptr.kind != null && !o_ptr.object_flag_is_known(resists[i].res_flag.value)) sym = '?'; Term.addch(attr, sym); } Term.putstr(col, row, 6, name_attr, resists[i].name.ToString()); } Term.putstr(col, row++, RES_COLS, ConsoleColor.White, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col+6); }
/* * Special display, part 2c * * How to print out the modifications and sustains. * Positive mods with no sustain will be light green. * Positive mods with a sustain will be dark green. * Sustains (with no modification) will be a dark green 's'. * Negative mods (from a curse) will be red. * Huge mods (>9), like from MICoMorgoth, will be a '*' * No mod, no sustain, will be a slate '.' */ static void display_player_sust_info() { int j, stat; Player.Player p_ptr = Player.Player.instance; Bitflag f = new Bitflag(Object_Flag.SIZE); Object_Flag[] stat_flags = new Object_Flag[(int)Stat.Max]; Object_Flag[] sustain_flags = new Object_Flag[(int)Stat.Max]; ConsoleColor a; char c; /* Row */ int row = 2; /* Column */ int col = 26; /* Build the stat flags tables */ stat_flags[(int)Stat.Str] = Object_Flag.STR; stat_flags[(int)Stat.Int] = Object_Flag.INT; stat_flags[(int)Stat.Wis] = Object_Flag.WIS; stat_flags[(int)Stat.Dex] = Object_Flag.DEX; stat_flags[(int)Stat.Con] = Object_Flag.CON; stat_flags[(int)Stat.Chr] = Object_Flag.CHR; sustain_flags[(int)Stat.Str] = Object_Flag.SUST_STR; sustain_flags[(int)Stat.Int] = Object_Flag.SUST_INT; sustain_flags[(int)Stat.Wis] = Object_Flag.SUST_WIS; sustain_flags[(int)Stat.Dex] = Object_Flag.SUST_DEX; sustain_flags[(int)Stat.Con] = Object_Flag.SUST_CON; sustain_flags[(int)Stat.Chr] = Object_Flag.SUST_CHR; /* Header */ Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row-1, col); /* Process equipment */ for (int i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; ++i) { /* Get the object */ Object.Object o_ptr = p_ptr.inventory[i]; if (o_ptr.kind == null) { col++; continue; } /* Get the "known" flags */ o_ptr.object_flags_known(ref f); /* Initialize color based of sign of pval. */ for (stat = 0; stat < (int)Stat.Max; stat++) { /* Default */ a = ConsoleColor.Gray; c = '.'; /* Boost */ if (f.has(stat_flags[stat].value)) { /* Default */ c = '*'; /* Work out which pval we're talking about */ j = o_ptr.which_pval(stat_flags[stat].value); /* Good */ if (o_ptr.pval[j] > 0) { /* Good */ a = ConsoleColor.Green; /* Label boost */ if (o_ptr.pval[j] < 10) c = (char)Basic.I2D((char)o_ptr.pval[j]); } /* Bad */ if (o_ptr.pval[j] < 0) { /* Bad */ a = ConsoleColor.Red; /* Label boost */ if (o_ptr.pval[j] > -10) c = (char)Basic.I2D((char)-(o_ptr.pval[j])); } } /* Sustain */ if (f.has(sustain_flags[stat].value)) { /* Dark green */ a = ConsoleColor.DarkGreen; /* Convert '.' to 's' */ if (c == '.') c = 's'; } if ((c == '.') && o_ptr.kind != null && !o_ptr.object_flag_is_known(sustain_flags[stat].value)) c = '?'; /* Dump proper character */ Term.putch(col, row+stat, a, c); } /* Advance */ col++; } /* Player flags */ Player.Player.player_flags(ref f); /* Check stats */ for (stat = 0; stat < (int)Stat.Max; ++stat) { /* Default */ a = ConsoleColor.Gray; c = '.'; /* Sustain */ if (f.has(sustain_flags[stat].value)) { /* Dark green "s" */ a = ConsoleColor.DarkGreen; c = 's'; } /* Dump */ Term.putch(col, row+stat, a, c); } /* Column */ col = 26; /* Footer */ Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row+6, col); /* Equippy */ display_player_equippy(row+7, col); }
/* * Acid has hit the player, attempt to affect some armor. * * Note that the "base armor" of an object never changes. * * If any armor is damaged (or resists), the player takes less damage. */ static bool minus_ac(Player.Player p) { Object.Object o_ptr = null; Bitflag f = new Bitflag(Object.Object_Flag.SIZE); //char o_name[80]; string o_name; /* Avoid crash during monster power calculations */ if (p.inventory == null) { return(false); } /* Pick a (possibly empty) inventory slot */ switch (Random.randint1(6)) { case 1: o_ptr = p.inventory[Misc.INVEN_BODY]; break; case 2: o_ptr = p.inventory[Misc.INVEN_ARM]; break; case 3: o_ptr = p.inventory[Misc.INVEN_OUTER]; break; case 4: o_ptr = p.inventory[Misc.INVEN_HANDS]; break; case 5: o_ptr = p.inventory[Misc.INVEN_HEAD]; break; case 6: o_ptr = p.inventory[Misc.INVEN_FEET]; break; //default: Misc.assert(0); //Nick: DA FUQ is this doing here C??? } /* Nothing to damage */ if (o_ptr.kind == null) { return(false); } /* No damage left to be done */ if (o_ptr.ac + o_ptr.to_a <= 0) { return(false); } /* Describe */ o_name = o_ptr.object_desc(Object.Object.Detail.BASE); //object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE); /* Extract the flags */ o_ptr.object_flags(ref f); /* Object resists */ if (f.has(Object.Object_Flag.IGNORE_ACID.value)) { Utilities.msg("Your %s is unaffected!", o_name); return(true); } /* Message */ Utilities.msg("Your %s is damaged!", o_name); /* Damage the item */ o_ptr.to_a--; p.update |= Misc.PU_BONUS; p.redraw |= (Misc.PR_EQUIP); /* Item was damaged */ return(true); }
/* * Handle certain things once every 10 game turns */ static void process_world(Cave c) { int i; int regen_amount; Object.Object o_ptr; /* Every 10 game turns */ if ((Misc.turn % 10) != 0) return; /*** Check the Time ***/ /* Play an ambient sound at regular intervals. */ if ((Misc.turn % ((10L * Cave.TOWN_DAWN) / 4)) == 0) { //play_ambient_sound(); TODO: enable sound } /*** Handle the "town" (stores and sunshine) ***/ /* While in town */ if (Misc.p_ptr.depth == 0) { /* Hack -- Daybreak/Nighfall in town */ if ((Misc.turn % ((10L * Cave.TOWN_DAWN) / 2)) == 0) { bool dawn; /* Check for dawn */ dawn = ((Misc.turn % (10L * Cave.TOWN_DAWN)) == 0); /* Day breaks */ if (dawn) Utilities.msg("The sun has risen."); /* Night falls */ else Utilities.msg("The sun has fallen."); /* Illuminate */ Cave.cave_illuminate(c, dawn); } } /* While in the dungeon */ else { /* Update the stores once a day (while in the dungeon). The changes are not actually made until return to town, to avoid giving details away in the knowledge menu. */ if ((Misc.turn % (10L * Store.TURNS)) == 0) Misc.daycount++; } /*** Process the monsters ***/ /* Check for creature generation */ if (Random.one_in_(Misc.MAX_M_ALLOC_CHANCE)) { /* Make a new monster */ Monster_Make.pick_and_place_distant_monster(Cave.cave, new Loc(Misc.p_ptr.px, Misc.p_ptr.py), Misc.MAX_SIGHT + 5, false, Misc.p_ptr.depth); } /* Hack -- Check for creature regeneration */ if ((Misc.turn % 100) == 0) regen_monsters(); /*** Damage over Time ***/ /* Take damage from poison */ if (Misc.p_ptr.timed[(int)Timed_Effect.POISONED] != 0) { /* Take damage */ Spell.take_hit(Misc.p_ptr, 1, "poison"); } /* Take damage from cuts */ if (Misc.p_ptr.timed[(int)Timed_Effect.CUT] != 0) { /* Mortal wound or Deep Gash */ if (Misc.p_ptr.timed[(int)Timed_Effect.CUT] > 200) i = 3; /* Severe cut */ else if (Misc.p_ptr.timed[(int)Timed_Effect.CUT] > 100) i = 2; /* Other cuts */ else i = 1; /* Take damage */ Spell.take_hit(Misc.p_ptr, i, "a fatal wound"); } /*** Check the Food, and Regenerate ***/ /* Digest normally */ if (Misc.p_ptr.food < Misc.PY_FOOD_MAX) { /* Every 100 game turns */ if ((Misc.turn % 100) == 0) { /* Basic digestion rate based on speed */ i = Misc.extract_energy[Misc.p_ptr.state.speed] * 2; /* Regeneration takes more food */ if (Misc.p_ptr.check_state(Object_Flag.REGEN, Misc.p_ptr.state.flags)) i += 30; /* Slow digestion takes less food */ if (Misc.p_ptr.check_state(Object_Flag.SLOW_DIGEST, Misc.p_ptr.state.flags)) i -= 10; /* Minimal digestion */ if (i < 1) i = 1; /* Digest some food */ Misc.p_ptr.set_food(Misc.p_ptr.food - i); } } /* Digest quickly when gorged */ else { /* Digest a lot of food */ Misc.p_ptr.set_food(Misc.p_ptr.food - 100); } /* Getting Faint */ if (Misc.p_ptr.food < Misc.PY_FOOD_FAINT) { /* Faint occasionally */ if (Misc.p_ptr.timed[(int)Timed_Effect.PARALYZED] == 0 && Random.one_in_(10)) { /* Message */ Utilities.msg("You faint from the lack of food."); Cave.disturb(Misc.p_ptr, 1, 0); /* Faint (bypass free action) */ Misc.p_ptr.inc_timed(Timed_Effect.PARALYZED, 1 + Random.randint0(5), true, false); } } /* Starve to death (slowly) */ if (Misc.p_ptr.food < Misc.PY_FOOD_STARVE) { /* Calculate damage */ i = (Misc.PY_FOOD_STARVE - Misc.p_ptr.food) / 10; /* Take damage */ Spell.take_hit(Misc.p_ptr, i, "starvation"); } /** Regenerate HP **/ /* Default regeneration */ if (Misc.p_ptr.food >= Misc.PY_FOOD_WEAK) regen_amount = Misc.PY_REGEN_NORMAL; else if (Misc.p_ptr.food < Misc.PY_FOOD_STARVE) regen_amount = 0; else if (Misc.p_ptr.food < Misc.PY_FOOD_FAINT) regen_amount = Misc.PY_REGEN_FAINT; else /* if (p_ptr.food < PY_FOOD_WEAK) */ regen_amount = Misc.PY_REGEN_WEAK; /* Various things speed up regeneration */ if (Misc.p_ptr.check_state(Object_Flag.REGEN, Misc.p_ptr.state.flags)) regen_amount *= 2; if (Misc.p_ptr.searching != 0 || Misc.p_ptr.resting != 0) regen_amount *= 2; /* Some things slow it down */ if (Misc.p_ptr.check_state(Object_Flag.IMPAIR_HP, Misc.p_ptr.state.flags)) regen_amount /= 2; /* Various things interfere with physical healing */ if (Misc.p_ptr.timed[(int)Timed_Effect.PARALYZED] != 0) regen_amount = 0; if (Misc.p_ptr.timed[(int)Timed_Effect.POISONED] != 0) regen_amount = 0; if (Misc.p_ptr.timed[(int)Timed_Effect.STUN] != 0) regen_amount = 0; if (Misc.p_ptr.timed[(int)Timed_Effect.CUT] != 0) regen_amount = 0; /* Regenerate Hit Points if needed */ if (Misc.p_ptr.chp < Misc.p_ptr.mhp) regenhp(regen_amount); /** Regenerate SP **/ /* Default regeneration */ regen_amount = Misc.PY_REGEN_NORMAL; /* Various things speed up regeneration */ if (Misc.p_ptr.check_state(Object_Flag.REGEN, Misc.p_ptr.state.flags)) regen_amount *= 2; if (Misc.p_ptr.searching != 0 || Misc.p_ptr.resting != 0) regen_amount *= 2; /* Some things slow it down */ if (Misc.p_ptr.check_state(Object_Flag.IMPAIR_MANA, Misc.p_ptr.state.flags)) regen_amount /= 2; /* Regenerate mana */ if (Misc.p_ptr.csp < Misc.p_ptr.msp) regenmana(regen_amount); /*** Timeout Various Things ***/ decrease_timeouts(); /*** Process Light ***/ /* Check for light being wielded */ o_ptr = Misc.p_ptr.inventory[Misc.INVEN_LIGHT]; /* Burn some fuel in the current light */ if (o_ptr.tval == TVal.TV_LIGHT) { Bitflag f = new Bitflag(Object_Flag.SIZE); bool burn_fuel = true; /* Get the object flags */ o_ptr.object_flags(ref f); /* Turn off the wanton burning of light during the day in the town */ if (Misc.p_ptr.depth == 0 && ((Misc.turn % (10L * Cave.TOWN_DAWN)) < ((10L * Cave.TOWN_DAWN) / 2))) burn_fuel = false; /* If the light has the NO_FUEL flag, well... */ if (f.has(Object_Flag.NO_FUEL.value)) burn_fuel = false; /* Use some fuel (except on artifacts, or during the day) */ if (burn_fuel && o_ptr.timeout > 0) { /* Decrease life-span */ o_ptr.timeout--; /* Hack -- notice interesting fuel steps */ if ((o_ptr.timeout < 100) || ((o_ptr.timeout % 100) == 0)) { /* Redraw stuff */ Misc.p_ptr.redraw |= (Misc.PR_EQUIP); } /* Hack -- Special treatment when blind */ if (Misc.p_ptr.timed[(int)Timed_Effect.BLIND] != 0) { /* Hack -- save some light for later */ if (o_ptr.timeout == 0) o_ptr.timeout++; } /* The light is now out */ else if (o_ptr.timeout == 0) { Cave.disturb(Misc.p_ptr, 0, 0); Utilities.msg("Your light has gone out!"); } /* The light is getting dim */ else if ((o_ptr.timeout < 100) && ((o_ptr.timeout % 10)) == 0) { Cave.disturb(Misc.p_ptr, 0, 0); Utilities.msg("Your light is growing faint."); } } } /* Calculate torch radius */ Misc.p_ptr.update |= (Misc.PU_TORCH); /*** Process Inventory ***/ /* Handle experience draining */ if (Misc.p_ptr.check_state(Object_Flag.DRAIN_EXP, Misc.p_ptr.state.flags)) { throw new NotImplementedException(); //if ((Misc.p_ptr.exp > 0) && Random.one_in_(10)) // player_exp_lose(Misc.p_ptr, 1, false); //wieldeds_notice_flag(Misc.p_ptr, Object_Flag.DRAIN_EXP); } /* Recharge activatable objects and rods */ recharge_objects(); /* Feel the inventory */ Object.Object.sense_inventory(); /*** Involuntary Movement ***/ /* Random teleportation */ if (Misc.p_ptr.check_state(Object_Flag.TELEPORT, Misc.p_ptr.state.flags) && Random.one_in_(100)) { throw new NotImplementedException(); //wieldeds_notice_flag(Misc.p_ptr, OF_TELEPORT); //teleport_player(40); //Cave.disturb(Misc.p_ptr, 0, 0); } /* Delayed Word-of-Recall */ if (Misc.p_ptr.word_recall != 0) { /* Count down towards recall */ Misc.p_ptr.word_recall--; /* Activate the recall */ if (Misc.p_ptr.word_recall == 0) { /* Disturbing! */ Cave.disturb(Misc.p_ptr, 0, 0); throw new NotImplementedException(); ///* Determine the level */ //if (Misc.p_ptr.depth) //{ // msgt(MSG_TPLEVEL, "You feel yourself yanked upwards!"); // dungeon_change_level(0); //} //else //{ // msgt(MSG_TPLEVEL, "You feel yourself yanked downwards!"); // /* New depth - back to max depth or 1, whichever is deeper */ // dungeon_change_level(Misc.p_ptr.max_depth < 1 ? 1: Misc.p_ptr.max_depth); //} } } }
/* * Special display, part 2c * * How to print out the modifications and sustains. * Positive mods with no sustain will be light green. * Positive mods with a sustain will be dark green. * Sustains (with no modification) will be a dark green 's'. * Negative mods (from a curse) will be red. * Huge mods (>9), like from MICoMorgoth, will be a '*' * No mod, no sustain, will be a slate '.' */ static void display_player_sust_info() { int j, stat; Player.Player p_ptr = Player.Player.instance; Bitflag f = new Bitflag(Object_Flag.SIZE); Object_Flag[] stat_flags = new Object_Flag[(int)Stat.Max]; Object_Flag[] sustain_flags = new Object_Flag[(int)Stat.Max]; ConsoleColor a; char c; /* Row */ int row = 2; /* Column */ int col = 26; /* Build the stat flags tables */ stat_flags[(int)Stat.Str] = Object_Flag.STR; stat_flags[(int)Stat.Int] = Object_Flag.INT; stat_flags[(int)Stat.Wis] = Object_Flag.WIS; stat_flags[(int)Stat.Dex] = Object_Flag.DEX; stat_flags[(int)Stat.Con] = Object_Flag.CON; stat_flags[(int)Stat.Chr] = Object_Flag.CHR; sustain_flags[(int)Stat.Str] = Object_Flag.SUST_STR; sustain_flags[(int)Stat.Int] = Object_Flag.SUST_INT; sustain_flags[(int)Stat.Wis] = Object_Flag.SUST_WIS; sustain_flags[(int)Stat.Dex] = Object_Flag.SUST_DEX; sustain_flags[(int)Stat.Con] = Object_Flag.SUST_CON; sustain_flags[(int)Stat.Chr] = Object_Flag.SUST_CHR; /* Header */ Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row - 1, col); /* Process equipment */ for (int i = Misc.INVEN_WIELD; i < Misc.INVEN_TOTAL; ++i) { /* Get the object */ Object.Object o_ptr = p_ptr.inventory[i]; if (o_ptr.kind == null) { col++; continue; } /* Get the "known" flags */ o_ptr.object_flags_known(ref f); /* Initialize color based of sign of pval. */ for (stat = 0; stat < (int)Stat.Max; stat++) { /* Default */ a = ConsoleColor.Gray; c = '.'; /* Boost */ if (f.has(stat_flags[stat].value)) { /* Default */ c = '*'; /* Work out which pval we're talking about */ j = o_ptr.which_pval(stat_flags[stat].value); /* Good */ if (o_ptr.pval[j] > 0) { /* Good */ a = ConsoleColor.Green; /* Label boost */ if (o_ptr.pval[j] < 10) { c = (char)Basic.I2D((char)o_ptr.pval[j]); } } /* Bad */ if (o_ptr.pval[j] < 0) { /* Bad */ a = ConsoleColor.Red; /* Label boost */ if (o_ptr.pval[j] > -10) { c = (char)Basic.I2D((char)-(o_ptr.pval[j])); } } } /* Sustain */ if (f.has(sustain_flags[stat].value)) { /* Dark green */ a = ConsoleColor.DarkGreen; /* Convert '.' to 's' */ if (c == '.') { c = 's'; } } if ((c == '.') && o_ptr.kind != null && !o_ptr.object_flag_is_known(sustain_flags[stat].value)) { c = '?'; } /* Dump proper character */ Term.putch(col, row + stat, a, c); } /* Advance */ col++; } /* Player flags */ Player.Player.player_flags(ref f); /* Check stats */ for (stat = 0; stat < (int)Stat.Max; ++stat) { /* Default */ a = ConsoleColor.Gray; c = '.'; /* Sustain */ if (f.has(sustain_flags[stat].value)) { /* Dark green "s" */ a = ConsoleColor.DarkGreen; c = 's'; } /* Dump */ Term.putch(col, row + stat, a, c); } /* Column */ col = 26; /* Footer */ Utilities.c_put_str(ConsoleColor.White, "abcdefghijkl@", row + 6, col); /* Equippy */ display_player_equippy(row + 7, col); }
static void display_resistance_panel(player_flag_record[] resists, int size, Region bounds) { Player.Player p_ptr = Player.Player.instance; int col = bounds.col; int row = bounds.row; Term.putstr(col, row++, RES_COLS, ConsoleColor.White, " abcdefghijkl@"); for (int i = 0; i < size - 3; i++, row++) { ConsoleColor name_attr = ConsoleColor.White; Term.gotoxy(col + 6, row); /* repeated extraction of flags is inefficient but more natural */ for (int j = Misc.INVEN_WIELD; j <= Misc.INVEN_TOTAL; j++) { Object.Object o_ptr = p_ptr.inventory[j]; Bitflag f = new Bitflag(Object_Flag.SIZE); ConsoleColor[] alternatingcols = new ConsoleColor[] { ConsoleColor.Gray, ConsoleColor.DarkGray }; ConsoleColor attr = alternatingcols[j % 2]; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ f.wipe(); if (j < Misc.INVEN_TOTAL && o_ptr.kind != null) { o_ptr.object_flags_known(ref f); } else if (j == Misc.INVEN_TOTAL) { Player.Player.player_flags(ref f); /* If the race has innate infravision/digging, force the corresponding flag * here. If we set it in player_flags(), then all callers of that * function will think the infravision is caused by equipment. */ if (p_ptr.Race.infra > 0) { f.on(Object_Flag.INFRA.value); } if (p_ptr.Race.r_skills[(int)Skill.DIGGING] > 0) { f.on(Object_Flag.TUNNEL.value); } } res = f.has(resists[i].res_flag.value); imm = f.has(resists[i].im_flag.value); vuln = f.has(resists[i].vuln_flag.value); if (imm) { name_attr = ConsoleColor.DarkGreen; } else if (res && name_attr == ConsoleColor.White) { name_attr = ConsoleColor.Cyan; } if (vuln) { sym = '-'; } else if (imm) { sym = '*'; } else if (res) { sym = '+'; } else if ((j < Misc.INVEN_TOTAL) && o_ptr.kind != null && !o_ptr.object_flag_is_known(resists[i].res_flag.value)) { sym = '?'; } Term.addch(attr, sym); } Term.putstr(col, row, 6, name_attr, resists[i].name.ToString()); } Term.putstr(col, row++, RES_COLS, ConsoleColor.White, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col + 6); }