Exemple #1
0
 // The main loop of the program.  Loop until the game is over,
 // refreshing things and looking at the proper times.
 void playit()
 {
     oldpos = new coord();
     oldpos.CopyFrom(hero);
     oldrp = roomin(hero);
     while (playing)
         command();			/* Command execution */
     endit(0);
 }
Exemple #2
0
 // The main loop of the program.  Loop until the game is over,
 // refreshing things and looking at the proper times.
 void playit()
 {
     oldpos = new coord();
     oldpos.CopyFrom(hero);
     oldrp = roomin(hero);
     while (playing)
     {
         command();                  /* Command execution */
     }
     endit(0);
 }
Exemple #3
0
    static coord ret = new coord();  /* what we will be returning */

    // Move in a random direction if the monster/person is confused
    coord rndmove(THING who)
    {
        THING obj;
        int   x, y;
        char  ch;

        y = ret.y = who.t_pos.y + rnd(3) - 1;
        x = ret.x = who.t_pos.x + rnd(3) - 1;

        /*
         * Now check to see if that's a legal move.  If not, don't move.
         * (I.e., bump into the wall or whatever)
         */
        if (y == who.t_pos.y && x == who.t_pos.x)
        {
            return(ret);
        }
        if (!diag_ok(who.t_pos, ret))
        {
            goto bad;
        }
        else
        {
            ch = winat(y, x);
            if (!step_ok(ch))
            {
                goto bad;
            }
            if (ch == SCROLL)
            {
                for (obj = lvl_obj; obj != null; obj = next(obj))
                {
                    if (y == obj.o_pos.y && x == obj.o_pos.x)
                    {
                        break;
                    }
                }
                if (obj != null && obj.o_which == S_SCARE)
                {
                    goto bad;
                }
            }
        }
        return(ret);

bad:
        ret.CopyFrom(who.t_pos);
        return(ret);
    }
Exemple #4
0
    // Find the spot for the chaser(er) to move closer to the
    // chasee(ee).  Returns TRUE if we want to keep on chasing later
    // FALSE if we reach the goal.
    bool chase(THING tp, coord ee)
    {
        THING obj;
        int   x, y;
        int   curdist, thisdist;
        coord er = tp.t_pos;
        char  ch;
        int   plcnt = 1;

        /*
         * If the thing is confused, let it move randomly. Invisible
         * Stalkers are slightly confused all of the time, and bats are
         * quite confused all the time
         */
        if ((on(tp, ISHUH) && rnd(5) != 0) || (tp.t_type == 'P' && rnd(5) == 0) || (tp.t_type == 'B' && rnd(2) == 0))
        {
            /*
             * get a valid random move
             */
            ch_ret.CopyFrom(rndmove(tp));
            curdist = dist_cp(ch_ret, ee);

            /*
             * Small chance that it will become un-confused
             */
            if (rnd(20) == 0)
            {
                tp.t_flags &= ~ISHUH;
            }
        }

        /*
         * Otherwise, find the empty spot next to the chaser that is
         * closest to the chasee.
         */
        else
        {
            int ey, ex;

            /*
             * This will eventually hold where we move to get closer
             * If we can't find an empty spot, we stay where we are.
             */
            curdist = dist_cp(er, ee);
            ch_ret.CopyFrom(er);

            ey = er.y + 1;
            if (ey >= NUMLINES - 1)
            {
                ey = NUMLINES - 2;
            }
            ex = er.x + 1;
            if (ex >= NUMCOLS)
            {
                ex = NUMCOLS - 1;
            }

            for (x = er.x - 1; x <= ex; x++)
            {
                if (x < 0)
                {
                    continue;
                }
                tryp.x = x;
                for (y = er.y - 1; y <= ey; y++)
                {
                    tryp.y = y;
                    if (!diag_ok(er, tryp))
                    {
                        continue;
                    }
                    ch = winat(y, x);
                    if (step_ok(ch))
                    {
                        /*
                         * If it is a scroll, it might be a scare monster scroll
                         * so we need to look it up to see what type it is.
                         */
                        if (ch == SCROLL)
                        {
                            for (obj = lvl_obj; obj != null; obj = next(obj))
                            {
                                if (y == obj.o_pos.y && x == obj.o_pos.x)
                                {
                                    break;
                                }
                            }
                            if (obj != null && obj.o_which == S_SCARE)
                            {
                                continue;
                            }
                        }

                        /*
                         * It can also be a Xeroc, which we shouldn't step on
                         */
                        if ((obj = moat(y, x)) != null && obj.t_type == 'X')
                        {
                            continue;
                        }

                        /*
                         * If we didn't find any scrolls at this place or it
                         * wasn't a scare scroll, then this place counts
                         */
                        thisdist = dist(y, x, ee.y, ee.x);
                        if (thisdist < curdist)
                        {
                            plcnt = 1;
                            ch_ret.CopyFrom(tryp);
                            curdist = thisdist;
                        }
                        else if (thisdist == curdist && rnd(++plcnt) == 0)
                        {
                            ch_ret.CopyFrom(tryp);
                            curdist = thisdist;
                        }
                    }
                }
            }
        }
        return((bool)(curdist != 0 && !ce(ch_ret, hero)));
    }
Exemple #5
0
    static coord thisCoord = new coord();                       /* Temporary destination for chaser */

    // Make one thing chase another.
    int do_chase(THING th)
    {
        coord cp;
        room  rer, ree;        /* room of chaser, room of chasee */
        int   mindist = 32767, curdist;
        bool  stoprun = false; /* TRUE means we are there */
        bool  door;
        THING obj;

        rer = th.t_room;                /* Find room of chaser */
        if (on(th, ISGREED) && rer.r_goldval == 0)
        {
            th.t_dest = hero;   /* If gold has been taken, run after hero */
        }
        if (th.t_dest == hero)  /* Find room of chasee */
        {
            ree = proom;
        }
        else
        {
            ree = roomin(th.t_dest);
        }

        /*
         * We don't count doors as inside rooms for this routine
         */
        door = (chat(th.t_pos.y, th.t_pos.x) == DOOR);

        /*
         * If the object of our desire is in a different room,
         * and we are not in a corridor, run to the door nearest to
         * our goal.
         */
over:
        if (rer != ree)
        {
            for (int i = 0; i < rer.r_nexits; i++)
            {
                cp      = rer.r_exit[i];
                curdist = dist_cp(th.t_dest, cp);
                if (curdist < mindist)
                {
                    thisCoord.CopyFrom(cp);
                    mindist = curdist;
                }
            }
            if (door)
            {
                rer  = passages[flat(th.t_pos.y, th.t_pos.x) & F_PNUM];
                door = false;
                goto over;
            }
        }
        else
        {
            thisCoord.CopyFrom(th.t_dest);

            /*
             * For dragons check and see if (a) the hero is on a straight
             * line from it, and (b) that it is within shooting distance,
             * but outside of striking range.
             */
            if (th.t_type == 'D' && (th.t_pos.y == hero.y || th.t_pos.x == hero.x ||
                                     Math.Abs(th.t_pos.y - hero.y) == Math.Abs(th.t_pos.x - hero.x)) &&
                dist_cp(th.t_pos, hero) <= BOLT_LENGTH * BOLT_LENGTH &&
                !on(th, ISCANC) && rnd(DRAGONSHOT) == 0)
            {
                delta.y = Math.Sign(hero.y - th.t_pos.y);
                delta.x = Math.Sign(hero.x - th.t_pos.x);
                if (has_hit)
                {
                    endmsg();
                }
                fire_bolt(th.t_pos, delta, "flame");
                running = false;
                count   = 0;
                quiet   = 0;
                if (to_death && !on(th, ISTARGET))
                {
                    to_death = false;
                    kamikaze = false;
                }
                return(0);
            }
        }

        /*
         * This now contains what we want to run to this time
         * so we run to it.  If we hit it we either want to fight it
         * or stop running
         */
        if (!chase(th, thisCoord))
        {
            if (ce(thisCoord, hero))
            {
                return(attack(th));
            }
            else if (ce(thisCoord, th.t_dest))
            {
                for (obj = lvl_obj; obj != null; obj = next(obj))
                {
                    if (th.t_dest == obj.o_pos)
                    {
                        detach(ref lvl_obj, obj);
                        attach(ref th.t_pack, obj);
                        chat(obj.o_pos.y, obj.o_pos.x, (th.t_room.r_flags & ISGONE) != 0 ? PASSAGE : FLOOR);
                        th.t_dest = find_dest(th);
                        break;
                    }
                }
                if (th.t_type != 'F')
                {
                    stoprun = true;
                }
            }
        }
        else
        {
            if (th.t_type == 'F')
            {
                return(0);
            }
        }
        relocate(th, ch_ret);

        /*
         * And stop running if need be
         */
        if (stoprun && ce(th.t_pos, th.t_dest))
        {
            th.t_flags &= ~ISRUN;
        }
        return(0);
    }
Exemple #6
0
    // Fire a bolt in a given direction from a specific starting place
    void fire_bolt(coord start, coord dir, string name)
    {
        int   c1, c2;
        THING tp;
        char  dirch = (char)0, ch;
        bool  hit_hero, used, changed;
        coord pos = new coord();

        coord[] spotpos = new coord[BOLT_LENGTH];
        THING   bolt    = new THING();

        bolt.o_type              = WEAPON;
        bolt.o_which             = FLAME;
        bolt.o_hurldmg           = "6x6";
        bolt.o_hplus             = 100;
        bolt.o_dplus             = 0;
        bolt.o_launch            = -1;
        weap_info[FLAME].oi_name = name;
        switch (dir.y + dir.x)
        {
        case 0: dirch = '/'; break;

        case 1:
        case -1: dirch = (dir.y == 0 ? '-' : '|'); break;

        case 2:
        case -2: dirch = '\\'; break;
        }
        pos.CopyFrom(start);
        hit_hero = (bool)(start != hero);
        used     = false;
        changed  = false;
        for (c1 = 0; c1 <= BOLT_LENGTH - 1 && !used; c1++)
        {
            pos.y      += dir.y;
            pos.x      += dir.x;
            spotpos[c1] = new coord(pos.y, pos.x);
            ch          = winat(pos.y, pos.x);
            switch (ch)
            {
            case DOOR:
                /*
                 * this code is necessary if the hero is on a door
                 * and he fires at the wall the door is in, it would
                 * otherwise loop infinitely
                 */
                if (ce(hero, pos))
                {
                    goto def;
                }
                /* FALLTHROUGH */
                goto case '|';

            case '|':
            case '-':
            case ' ':
                if (!changed)
                {
                    hit_hero = !hit_hero;
                }
                changed = false;
                dir.y   = -dir.y;
                dir.x   = -dir.x;
                c1--;
                msg("the {0} bounces", name);
                break;

            default:
def:
                if (!hit_hero && (tp = moat(pos.y, pos.x)) != null)
                {
                    hit_hero   = true;
                    changed    = !changed;
                    tp.t_oldch = chat(pos.y, pos.x);
                    if (!save_throw(VS_MAGIC, tp))
                    {
                        bolt.o_pos = pos;
                        used       = true;
                        if (tp.t_type == 'D' && name == "flame")
                        {
                            addmsg("the flame bounces");
                            if (!terse)
                            {
                                addmsg(" off the dragon");
                            }
                            endmsg();
                        }
                        else
                        {
                            hit_monster(pos.y, pos.x, bolt);
                        }
                    }
                    else if (ch != 'M' || tp.t_disguise == 'M')
                    {
                        if (start == hero)
                        {
                            runto(pos);
                        }
                        if (terse)
                        {
                            msg("{0} misses", name);
                        }
                        else
                        {
                            msg("the {0} whizzes past {1}", name, set_mname(tp));
                        }
                    }
                }
                else if (hit_hero && ce(pos, hero))
                {
                    hit_hero = false;
                    changed  = !changed;
                    if (!save(VS_MAGIC))
                    {
                        if ((pstats.s_hpt -= roll(6, 6)) <= 0)
                        {
                            if (start == hero)
                            {
                                death('b');
                            }
                            else
                            {
                                death(moat(start.y, start.x).t_type);
                            }
                        }
                        used = true;
                        if (terse)
                        {
                            msg("the {0} hits", name);
                        }
                        else
                        {
                            msg("you are hit by the {0}", name);
                        }
                    }
                    else
                    {
                        msg("the {0} whizzes by you", name);
                    }
                }
                mvaddch(pos.y, pos.x, dirch);
                refresh();
                break;
            }
        }
        for (c2 = 0; c2 < c1; c2++)
        {
            mvaddch(spotpos[c2].y, spotpos[c2].x, chat(spotpos[c2].y, spotpos[c2].x));
        }
    }