예제 #1
0
        /**
         * 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);
        }
예제 #2
0
        /*
         * 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);
        }
예제 #3
0
        /*
         * 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);
        }
예제 #4
0
        /**
         * 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;
        }
예제 #5
0
        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);
        }
예제 #6
0
        /*
         * 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);
        }
예제 #7
0
        /*
         * 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);
        }
예제 #8
0
        /*
         * 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);
                    //}
                }
            }
        }
예제 #9
0
        /*
         * 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);
        }
예제 #10
0
        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);
        }