Esempio n. 1
0
static
void ghack_save_game(GtkWidget *widget, int button)
{
    gtk_widget_hide(widget);
    if (button == 0) {
        if(dosave0()) {
            /* make sure they see the Saving message */
            display_nhwindow(WIN_MESSAGE, TRUE);
            gnome_exit_nhwindows("Be seeing you...");
        } else (void)doredraw();
    }
}
Esempio n. 2
0
/*
 * rloc_to()
 *
 * Pulls a monster from its current position and places a monster at a new x and
 * y.  If oldx is COLNO, then the monster was not in the levels.monsters array.
 * However, if oldx is COLNO, oldy may still have a value because mtmp is a
 * migrating_mon.  Worm tails are always placed randomly around the head of the
 * worm.  This only works for monsters on the current level.
 */
void
rloc_to(struct monst *mtmp, int x, int y)
{
    int oldx = mtmp->mx, oldy = mtmp->my;
    boolean resident_shk = mtmp->isshk && inhishop(mtmp);

    if (x == mtmp->mx && y == mtmp->my) /* that was easy */
        return;

    if (oldx != COLNO) { /* "pick up" monster */
        if (mtmp->wormno)
            remove_worm(mtmp);
        else {
            remove_monster(mtmp->dlevel, oldx, oldy);
            if (mtmp->dlevel == level)
                newsym(oldx, oldy); /* update old location */
        }
    }

    place_monster(mtmp, x, y);  /* put monster down */
    update_monster_region(mtmp);

    if (mtmp->wormno)   /* now put down tail */
        place_worm_tail_randomly(mtmp, x, y, rng_main);

    if (u.ustuck == mtmp) { /* implies mtmp->dlevel == level */
        if (Engulfed) {
            u.ux = x;
            u.uy = y;
            doredraw();
        } else
            u.ustuck = 0;
    }

    if (mtmp->dlevel == level)
        newsym(x, y);       /* update new location */
    set_apparxy(mtmp);  /* orient monster */

    /* In some cases involving migration, the player and monster are currently
       on the same square. One of them will move, but we don't want the monster
       to have itself in its muxy. */
    if (mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my) {
        mtmp->mux = COLNO;
        mtmp->muy = ROWNO;
    }

    /* shopkeepers will only teleport if you zap them with a wand of
       teleportation or if they've been transformed into a jumpy monster; the
       latter only happens if you've attacked them with polymorph */
    if (resident_shk && !inhishop(mtmp))
        make_angry_shk(mtmp, oldx, oldy);
}
Esempio n. 3
0
File: save.c Progetto: mbi/NitroHack
int dosave(void)
{
	if (yn("Really save?") == 'n') {
		if (multi > 0) nomul(0, NULL);
	} else {
		pline("Saving...");
		if (dosave0(FALSE)) {
			program_state.something_worth_saving = 0;
			u.uhp = -1;		/* universal game's over indicator */
			terminate();
		} else doredraw();
	}
	return 0;
}
Esempio n. 4
0
/*
 * rloc_to()
 *
 * Pulls a monster from its current position and places a monster at
 * a new x and y.  If oldx is 0, then the monster was not in the levels.monsters
 * array.  However, if oldx is 0, oldy may still have a value because mtmp is a
 * migrating_mon.  Worm tails are always placed randomly around the head of
 * the worm.
 */
void
rloc_to(struct monst *mtmp, int x, int y)
{
    int oldx = mtmp->mx, oldy = mtmp->my;
    boolean resident_shk = mtmp->isshk && inhishop(mtmp);

    if (x == mtmp->mx && y == mtmp->my) /* that was easy */
        return;

    if (oldx) { /* "pick up" monster */
        if (mtmp->wormno)
            remove_worm(mtmp);
        else {
            remove_monster(level, oldx, oldy);
            newsym(oldx, oldy); /* update old location */
        }
    }

    place_monster(mtmp, x, y);  /* put monster down */
    update_monster_region(mtmp);

    if (mtmp->wormno)   /* now put down tail */
        place_worm_tail_randomly(mtmp, x, y);

    if (u.ustuck == mtmp) {
        if (u.uswallow) {
            u.ux = x;
            u.uy = y;
            doredraw();
        } else
            u.ustuck = 0;
    }

    newsym(x, y);       /* update new location */
    set_apparxy(mtmp);  /* orient monster */

    /* shopkeepers will only teleport if you zap them with a wand of
       teleportation or if they've been transformed into a jumpy monster; the
       latter only happens if you've attacked them with polymorph */
    if (resident_shk && !inhishop(mtmp))
        make_angry_shk(mtmp, oldx, oldy);
}
Esempio n. 5
0
int
dosave()
{
	clear_nhwindow(WIN_MESSAGE);
	if(yn("Really save?") == 'n') {
		clear_nhwindow(WIN_MESSAGE);
		if(multi > 0) nomul(0);
	} else {
		clear_nhwindow(WIN_MESSAGE);
		pline("Saving...");
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
		program_state.done_hup = 0;
#endif
		if(dosave0()) {
			program_state.something_worth_saving = 0;
			u.uhp = -1;		/* universal game's over indicator */
			/* make sure they see the Saving message */
			display_nhwindow(WIN_MESSAGE, TRUE);
			exit_nhwindows("Be seeing you...");
			terminate(EXIT_SUCCESS);
		} else (void)doredraw();
	}
	return 0;
}
Esempio n. 6
0
void
teleds(int nux, int nuy, boolean allow_drag)
{
    boolean ball_active = (Punished &&
                           uball->where != OBJ_FREE), ball_still_in_range =
        FALSE;

    /* If they have to move the ball, then drag if allow_drag is true;
       otherwise they are teleporting, so unplacebc(). If they don't have to
       move the ball, then always "drag" whether or not allow_drag is true,
       because we are calling that function, not to drag, but to move the
       chain.  *However* there are some dumb special cases: 0 0 _X move east
       -----> X_ @ @ These are permissible if teleporting, but not if dragging.
       As a result, drag_ball() needs to know about allow_drag and might end up
       dragging the ball anyway.  Also, drag_ball() might find that dragging
       the ball is completely impossible (ball in range but there's rock in the
       way), in which case it teleports the ball on its own. */
    if (ball_active) {
        if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2)
            ball_still_in_range = TRUE; /* don't have to move the ball */
        else {
            /* have to move the ball */
            if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
                /* we should not have dist > 1 and allow_drag at the same time,
                   but just in case, we must then revert to teleport. */
                allow_drag = FALSE;
                unplacebc();
            }
        }
    }
    u.utrap = 0;
    u.ustuck = 0;
    u.ux0 = u.ux;
    u.uy0 = u.uy;

    if (hides_under(youmonst.data))
        u.uundetected = OBJ_AT(nux, nuy);
    else if (youmonst.data->mlet == S_EEL)
        u.uundetected = is_pool(level, nux, nuy);
    else {
        u.uundetected = 0;
        /* mimics stop being unnoticed */
        if (youmonst.data->mlet == S_MIMIC)
            youmonst.m_ap_type = M_AP_NOTHING;
    }

    if (Engulfed) {
        u.uswldtim = Engulfed = 0;
        if (Punished && !ball_active) {
            /* ensure ball placement, like unstuck */
            ball_active = TRUE;
            allow_drag = FALSE;
        }
        doredraw();
    }
    if (ball_active) {
        if (ball_still_in_range || allow_drag) {
            int bc_control;
            xchar ballx, bally, chainx, chainy;
            boolean cause_delay;

            if (drag_ball
                (nux, nuy, &bc_control, &ballx, &bally, &chainx, &chainy,
                 &cause_delay, allow_drag))
                move_bc(0, bc_control, ballx, bally, chainx, chainy);
        }
    }
    /* must set u.ux, u.uy after drag_ball(), which may need to know the old
       position if allow_drag is true... */
    u.ux = nux;
    u.uy = nuy;
    fill_pit(level, u.ux0, u.uy0);
    if (ball_active) {
        if (!ball_still_in_range && !allow_drag)
            placebc();
    }
    initrack(); /* teleports mess up tracking monsters without this */
    update_player_regions(level);
    /* Move your steed, too */
    if (u.usteed) {
        u.usteed->mx = nux;
        u.usteed->my = nuy;
    }

    /*
     *  Make sure the hero disappears from the old location.  This will
     *  not happen if she is teleported within sight of her previous
     *  location.  Force a full vision recalculation because the hero
     *  is now in a new location.
     */
    newsym(u.ux0, u.uy0);
    see_monsters(FALSE);
    turnstate.vision_full_recalc = TRUE;
    action_interrupted();
    vision_recalc(0);   /* vision before effects */
    spoteffects(TRUE);
    invocation_message();
}
Esempio n. 7
0
/* returns 0 if something was detected		*/
int food_detect(struct obj *sobj, boolean *scr_known)
{
    struct obj *obj;
    struct monst *mtmp;
    int ct = 0, ctu = 0;
    boolean confused = (Confusion || (sobj && sobj->cursed)), stale;
    char oclass = confused ? POTION_CLASS : FOOD_CLASS;
    const char *what = confused ? "something" : "food";
    int uw = u.uinwater;

    stale = clear_stale_map(oclass, 0);

    for (obj = level->objlist; obj; obj = obj->nobj)
	if (o_in(obj, oclass)) {
	    if (obj->ox == u.ux && obj->oy == u.uy) ctu++;
	    else ct++;
	}
    for (mtmp = level->monlist; mtmp && !ct; mtmp = mtmp->nmon) {
	/* no DEADMONSTER(mtmp) check needed since dmons never have inventory */
	for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (o_in(obj, oclass)) {
		ct++;
		break;
	    }
    }
    
    if (!ct && !ctu) {
	*scr_known = stale && !confused;
	if (stale) {
	    doredraw();
	    pline("You sense a lack of %s nearby.", what);
	    if (sobj && sobj->blessed) {
		if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE));
		u.uedibility = 1;
	    }
	} else if (sobj) {
	    char buf[BUFSZ];
	    sprintf(buf, "Your %s twitches%s.", body_part(NOSE),
			(sobj->blessed && !u.uedibility) ? " then starts to tingle" : "");
	    if (sobj->blessed && !u.uedibility) {
		boolean savebeginner = flags.beginner;	/* prevent non-delivery of */
		flags.beginner = FALSE;			/* 	message            */
		strange_feeling(sobj, buf);
		flags.beginner = savebeginner;
		u.uedibility = 1;
	    } else
		strange_feeling(sobj, buf);
	}
	return !stale;
    } else if (!ct) {
	*scr_known = TRUE;
	pline("You %s %s nearby.", sobj ? "smell" : "sense", what);
	if (sobj && sobj->blessed) {
		if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE));
		u.uedibility = 1;
	}
    } else {
	struct obj *temp;
	*scr_known = TRUE;
	cls();
	u.uinwater = 0;
	for (obj = level->objlist; obj; obj = obj->nobj)
	    if ((temp = o_in(obj, oclass)) != 0) {
		if (temp != obj) {
		    temp->ox = obj->ox;
		    temp->oy = obj->oy;
		}
		map_object(temp,1);
	    }
	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon)
	    /* no DEADMONSTER(mtmp) check needed since dmons never have inventory */
	    for (obj = mtmp->minvent; obj; obj = obj->nobj)
		if ((temp = o_in(obj, oclass)) != 0) {
		    temp->ox = mtmp->mx;
		    temp->oy = mtmp->my;
		    map_object(temp,1);
		    break;	/* skip rest of this monster's inventory */
		}
	newsym(u.ux,u.uy);
	if (sobj) {
	    if (sobj->blessed) {
	    	pline("Your %s %s to tingle and you smell %s.", body_part(NOSE),
	    		u.uedibility ? "continues" : "starts", what);
		u.uedibility = 1;
	    } else
		pline("Your %s tingles and you smell %s.", body_part(NOSE), what);
	}
	else pline("You sense %s.", what);
	win_pause_output(P_MAP);
	exercise(A_WIS, TRUE);
	doredraw();
	u.uinwater = uw;
	if (Underwater) under_water(2);
	if (u.uburied) under_ground(2);
    }
    return 0;
}
Esempio n. 8
0
/* look for gold, on the floor or in monsters' possession */
int gold_detect(struct obj *sobj, boolean *scr_known)
{
    struct obj *obj;
    struct monst *mtmp;
    int uw = u.uinwater;
    struct obj *temp;
    boolean stale;

    *scr_known = stale = clear_stale_map(COIN_CLASS, sobj->blessed ? GOLD : 0);

    /* look for gold carried by monsters (might be in a container) */
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably not needed in this case but... */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    *scr_known = TRUE;
	    goto outgoldmap;	/* skip further searching */
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && o_material(obj, GOLD)) {
	    	*scr_known = TRUE;
	    	goto outgoldmap;
	    } else if (o_in(obj, COIN_CLASS)) {
		*scr_known = TRUE;
		goto outgoldmap;	/* skip further searching */
	    }
    }
    
    /* look for gold objects */
    for (obj = level->objlist; obj; obj = obj->nobj) {
	if (sobj->blessed && o_material(obj, GOLD)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	} else if (o_in(obj, COIN_CLASS)) {
	    *scr_known = TRUE;
	    if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
	}
    }

    if (!*scr_known) {
	/* no gold found on floor or monster's inventory.
	   adjust message if you have gold in your inventory */
	char buf[BUFSZ];
	if (youmonst.data == &mons[PM_GOLD_GOLEM]) {
		sprintf(buf, "You feel like a million %s!", currency(2L));
	} else if (hidden_gold() || money_cnt(invent))
		strcpy(buf, "You feel worried about your future financial situation.");
	else
		strcpy(buf, "You feel materially poor.");
	strange_feeling(sobj, buf);
	return 1;
    }
    /* only under me - no separate display required */
    if (stale) doredraw();
    pline("You notice some gold between your %s.", makeplural(body_part(FOOT)));
    return 0;

outgoldmap:
    cls();

    u.uinwater = 0;
    /* Discover gold locations. */
    for (obj = level->objlist; obj; obj = obj->nobj) {
    	if (sobj->blessed && (temp = o_material(obj, GOLD))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	} else if ((temp = o_in(obj, COIN_CLASS))) {
	    if (temp != obj) {
		temp->ox = obj->ox;
		temp->oy = obj->oy;
	    }
	    map_object(temp,1);
	}
    }
    for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
    	if (DEADMONSTER(mtmp)) continue;	/* probably overkill here */
	if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
	    struct obj gold;

	    gold.otyp = GOLD_PIECE;
	    gold.ox = mtmp->mx;
	    gold.oy = mtmp->my;
	    map_object(&gold,1);
	} else for (obj = mtmp->minvent; obj; obj = obj->nobj)
	    if (sobj->blessed && (temp = o_material(obj, GOLD))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    } else if ((temp = o_in(obj, COIN_CLASS))) {
		temp->ox = mtmp->mx;
		temp->oy = mtmp->my;
		map_object(temp,1);
		break;
	    }
    }
    
    newsym(u.ux,u.uy);
    pline("You feel very greedy, and sense gold!");
    exercise(A_WIS, TRUE);
    win_pause_output(P_MAP);
    doredraw();
    u.uinwater = uw;
    if (Underwater) under_water(2);
    if (u.uburied) under_ground(2);
    return 0;
}
Esempio n. 9
0
void
EditClipping(void)
{
    int i;
    long mflags;
    static int sizes[] = { 8, 16, 20, 24, 28, 32, 36 };
    char buf[40];
    int done = 0, okay = 0;
    long code, qual, class;
    register struct Gadget *gd, *dgad;
    register struct Window *nw;
    register struct IntuiMessage *imsg;
    register struct PropInfo *pip;
    register struct Screen *scrn;
    long aidx;
    int lmxsize = mxsize, lmysize = mysize;
    int lxclipbord = xclipbord, lyclipbord = yclipbord;
    int msx, msy;
    int drag = 0;
    static int once = 0;

    scrn = HackScreen;

    if (!once) {
        SetBorder(&ClipOkay);
        SetBorder(&ClipCancel);
        once = 1;
    }
    ClipNewWindowStructure1.Screen = scrn;
#ifdef INTUI_NEW_LOOK
    if (IntuitionBase->LibNode.lib_Version >= 37) {
        ((struct PropInfo *) ClipXSIZE.SpecialInfo)->Flags |= PROPNEWLOOK;
        ((struct PropInfo *) ClipYSIZE.SpecialInfo)->Flags |= PROPNEWLOOK;
        ((struct PropInfo *) ClipXCLIP.SpecialInfo)->Flags |= PROPNEWLOOK;
        ((struct PropInfo *) ClipYCLIP.SpecialInfo)->Flags |= PROPNEWLOOK;
    }
#endif
    if (WINVERS_AMIV || WINVERS_AMII) {
#ifdef INTUI_NEW_LOOK
        ClipNewWindowStructure1.Extension = wintags;
        ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED;
#ifdef __GNUC__
        fillhook.h_Entry = (void *) &LayerFillHook;
#else
        fillhook.h_Entry = (ULONG (*) ()) LayerFillHook;
#endif
        fillhook.h_Data = (void *) -2;
        fillhook.h_SubEntry = 0;
#endif
    }

    nw = OpenWindow((void *) &ClipNewWindowStructure1);

    if (nw == NULL) {
        DisplayBeep(NULL);
        return;
    }

    ShowClipValues(nw);
    mflags = AUTOKNOB | FREEHORIZ;
#ifdef INTUI_NEW_LOOK
    if (IntuitionBase->LibNode.lib_Version >= 37) {
        mflags |= PROPNEWLOOK;
    }
#endif

    for (i = 0; i < 7; ++i) {
        if (mxsize <= sizes[i])
            break;
    }
    NewModifyProp(&ClipXSIZE, nw, NULL, mflags, (i * MAXPOT) / 6, 0,
                  MAXPOT / 6, 0, 1);
    for (i = 0; i < 7; ++i) {
        if (mysize <= sizes[i])
            break;
    }
    NewModifyProp(&ClipYSIZE, nw, NULL, mflags, (i * MAXPOT) / 6, 0,
                  MAXPOT / 6, 0, 1);

    NewModifyProp(&ClipXCLIP, nw, NULL, mflags,
                  ((xclipbord - 2) * MAXPOT) / 6, 0, MAXPOT / 6, 0, 1);
    NewModifyProp(&ClipYCLIP, nw, NULL, mflags,
                  ((yclipbord - 2) * MAXPOT) / 6, 0, MAXPOT / 6, 0, 1);

    while (!done) {
        WaitPort(nw->UserPort);

        while (imsg = (struct IntuiMessage *) GetMsg(nw->UserPort)) {
            gd = (struct Gadget *) imsg->IAddress;
            code = imsg->Code;
            class = imsg->Class;
            qual = imsg->Qualifier;
            msx = imsg->MouseX;
            msy = imsg->MouseY;

            ReplyMsg((struct Message *) imsg);

            switch (class) {
            case VANILLAKEY:
                if (code == '\33')
                    okay = 0, done = 1;
                else if (code == 'v' && qual == AMIGALEFT)
                    okay = done = 1;
                else if (code == 'b' && qual == AMIGALEFT)
                    okay = 0, done = 1;
                else if (code == 'o' || code == 'O')
                    okay = done = 1;
                else if (code == 'c' || code == 'C')
                    okay = 0, done = 1;
                break;

            case CLOSEWINDOW:
                done = 1;
                break;

            case GADGETUP:
                drag = 0;
                if (gd->GadgetID == XSIZE || gd->GadgetID == YSIZE
                    || gd->GadgetID == XCLIP || gd->GadgetID == YCLIP) {
                    pip = (struct PropInfo *) gd->SpecialInfo;
                    aidx = pip->HorizPot / (MAXPOT / 6);
                    if (gd->GadgetID == XSIZE) {
                        mxsize = sizes[aidx];
                    } else if (gd->GadgetID == YSIZE) {
                        mysize = sizes[aidx];
                    } else if (gd->GadgetID == XCLIP) {
                        xclipbord = aidx + 2;
                    } else if (gd->GadgetID == YCLIP) {
                        yclipbord = aidx + 2;
                    }
                    ShowClipValues(nw);
#ifdef OPT_DISPMAP
                    dispmap_sanity();
#endif
                } else if (gd->GadgetID == GADOKAY) {
                    done = 1;
                    okay = 1;
                } else if (gd->GadgetID == GADCANCEL) {
                    done = 1;
                    okay = 0;
                }
                ReportMouse(0, nw);
                reclip = 2;
                doredraw();
                flush_glyph_buffer(amii_wins[WIN_MAP]->win);
                reclip = 0;
                break;

            case GADGETDOWN:
                drag = 1;
                dgad = gd;
                ReportMouse(1, nw);
                break;

            case MOUSEMOVE:
                if (!drag)
                    break;
                pip = (struct PropInfo *) dgad->SpecialInfo;
                aidx = pip->HorizPot / (MAXPOT / 6);
                Move(nw->RPort,
                     dgad->LeftEdge + (nw->Width + dgad->Width) + 8,
                     dgad->TopEdge + nw->RPort->TxBaseline);
                if (dgad->GadgetID == XSIZE) {
                    mxsize = sizes[aidx];
                    sprintf(buf, "%d ", lmxsize);
                } else if (dgad->GadgetID == YSIZE) {
                    mysize = sizes[aidx];
                    sprintf(buf, "%d ", mysize);
                } else if (dgad->GadgetID == XCLIP) {
                    xclipbord = aidx + 2;
                    sprintf(buf, "%d ", xclipbord);
                } else if (dgad->GadgetID == YCLIP) {
                    yclipbord = aidx + 2;
                    sprintf(buf, "%d ", yclipbord);
                }
                SetAPen(nw->RPort, 5);
                SetBPen(nw->RPort, amii_otherBPen);
                SetDrMd(nw->RPort, JAM2);
                Text(nw->RPort, buf, strlen(buf));
#ifdef OPT_DISPMAP
                dispmap_sanity();
#endif
                break;
            }
        }
    }

    CloseWindow(nw);

    /* Restore oldvalues if cancelled. */
    if (!okay) {
        mxsize = lmxsize;
        mysize = lmysize;
        xclipbord = lxclipbord;
        yclipbord = lyclipbord;
    }
}
Esempio n. 10
0
int
dosave()
{
#ifdef KEEP_SAVE
	/*WAC for reloading*/
	register int fd;
#endif

	clear_nhwindow(WIN_MESSAGE);
	if(yn("Really save?") == 'n') {
		clear_nhwindow(WIN_MESSAGE);
		if(multi > 0) nomul(0);
	} else {
		clear_nhwindow(WIN_MESSAGE);
		pline("Saving...");
#if defined(UNIX) || defined(VMS) || defined(__EMX__)
		program_state.done_hup = 0;
#endif
#ifdef KEEP_SAVE
                saverestore = FALSE;
                if (flags.keep_savefile)
                        if(yn("Really quit?") == 'n') saverestore = TRUE;
                if(dosave0() && !saverestore) {
#else
		if(dosave0()) {
#endif
			program_state.something_worth_saving = 0;
			u.uhp = -1;		/* universal game's over indicator */
			/* make sure they see the Saving message */
			display_nhwindow(WIN_MESSAGE, TRUE);
			exit_nhwindows("Be seeing you...");
			terminate(EXIT_SUCCESS);
	}
/*WAC redraw later
		else (void)doredraw();*/
	}
#ifdef KEEP_SAVE
	if (saverestore) {
/*WAC pulled this from pcmain.c - restore game from the file just saved*/
		fd = create_levelfile(0);
		if (fd < 0) {
			raw_print("Cannot create lock file");
		} else {
			hackpid = 1;
			write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
			close(fd);
		}
#ifdef MFLOPPY
		level_info[0].where = ACTIVE;
#endif

		fd = restore_saved_game();
		if (fd >= 0) dorecover(fd);
		check_special_room(FALSE);
		flags.move = 0;
/*WAC correct these after restore*/
		if(flags.moonphase == FULL_MOON)
			change_luck(1);         
		if(flags.friday13)
			change_luck(-1);
		if(iflags.window_inited)
			clear_nhwindow(WIN_MESSAGE);
	}
	saverestore = FALSE;
#endif
	(void)doredraw();
	return 0;
}


#if defined(UNIX) || defined(VMS) || defined (__EMX__) || defined(WIN32)
/*ARGSUSED*/
void
hangup(sig_unused)  /* called as signal() handler, so sent at least one arg */
int sig_unused;
{
# ifdef NOSAVEONHANGUP
	(void) signal(SIGINT, SIG_IGN);
	clearlocks();
#  ifndef VMS
	terminate(EXIT_FAILURE);
#  endif
# else	/* SAVEONHANGUP */
	if (!program_state.done_hup++) {
	    if (program_state.something_worth_saving)
		(void) dosave0();
#  ifdef VMS
	    /* don't call exit when already within an exit handler;
	       that would cancel any other pending user-mode handlers */
	    if (!program_state.exiting)
#  endif
	    {
		clearlocks();
		terminate(EXIT_FAILURE);
	    }
	}
# endif
	return;
}
#endif

/* returns 1 if save successful */
int
dosave0()
{
	const char *fq_save;
	register int fd, ofd;
	xchar ltmp;
	d_level uz_save;
	char whynot[BUFSZ];

	if (!SAVEF[0])
		return 0;
	fq_save = fqname(SAVEF, SAVEPREFIX, 1);	/* level files take 0 */

#if defined(UNIX) || defined(VMS)
	(void) signal(SIGHUP, SIG_IGN);
#endif
#ifndef NO_SIGNAL
	(void) signal(SIGINT, SIG_IGN);
#endif

#if defined(MICRO) && defined(MFLOPPY)
	if (!saveDiskPrompt(0)) return 0;
#endif

	HUP if (iflags.window_inited) {
	    uncompress_area(fq_save, SAVEF);
	    fd = open_savefile();
	    if (fd > 0) {
		(void) close(fd);
		clear_nhwindow(WIN_MESSAGE);
		There("seems to be an old save file.");
		if (yn("Overwrite the old file?") == 'n') {
		    compress_area(fq_save, SAVEF);
#ifdef KEEP_SAVE
/*WAC don't restore if you didn't save*/
			saverestore = FALSE;
#endif
		    return 0;
		}
	    }
	}

	HUP mark_synch();	/* flush any buffered screen output */

	fd = create_savefile();
	if(fd < 0) {
		HUP pline("Cannot open save file.");
		(void) delete_savefile();	/* ab@unido */
		return(0);
	}

	vision_recalc(2);	/* shut down vision to prevent problems
				   in the event of an impossible() call */
	
	/* undo date-dependent luck adjustments made at startup time */
	if(flags.moonphase == FULL_MOON)	/* ut-sally!fletcher */
		change_luck(-1);		/* and unido!ab */
	if(flags.friday13)
		change_luck(1);
	if(iflags.window_inited)
	    HUP clear_nhwindow(WIN_MESSAGE);

#if defined(MICRO) && defined(TTY_GRAPHICS)
	if (!strncmpi("tty", windowprocs.name, 3)) {
	dotcnt = 0;
	dotrow = 2;
	curs(WIN_MAP, 1, 1);
	  putstr(WIN_MAP, 0, "Saving:");
	}
#endif
#ifdef MFLOPPY
	/* make sure there is enough disk space */
	if (iflags.checkspace) {
	    long fds, needed;

	    savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
	    savegamestate(fd, COUNT_SAVE);
	    needed = bytes_counted;

	    for (ltmp = 1; ltmp <= maxledgerno(); ltmp++)
		if (ltmp != ledger_no(&u.uz) && level_info[ltmp].where)
		    needed += level_info[ltmp].size + (sizeof ltmp);
	    fds = freediskspace(fq_save);
	    if (needed > fds) {
		HUP {
		    There("is insufficient space on SAVE disk.");
		    pline("Require %ld bytes but only have %ld.", needed, fds);
		}
		flushout();
		(void) close(fd);
		(void) delete_savefile();
		return 0;
	    }

	    co_false();
	}
Esempio n. 11
0
void
ghack_reinit_map_window()
{
    GnomeCanvasImage *bg;
    double width, height, x, y;
    int i;

    /* ghack_map_clear(NULL, NULL); */

    width = COLNO * ghack_glyph_width();
    height = ROWNO * ghack_glyph_height();

    gnome_canvas_set_scroll_region(GNOME_CANVAS(ghack_map.canvas), 0, 0,
                                   width + 2 * ghack_glyph_width(),
                                   height + 2 * ghack_glyph_height());

    /* remove everything currently in the canvas map */
    gtk_object_destroy(GTK_OBJECT(myCanvasGroup));

    /* Put some groups back */
    myCanvasGroup = GNOME_CANVAS_GROUP(gnome_canvas_item_new(
                                           gnome_canvas_root(GNOME_CANVAS(ghack_map.canvas)),
                                           gnome_canvas_group_get_type(), "x", 0.0, "y", 0.0, NULL));

    /* Tile the map background with a pretty image */
    if (background != NULL) {
        /* Tile the map background */
        for (y = 0; y < height + background->rgb_height;
                y += background->rgb_height) {
            for (x = 0; x < width + background->rgb_width;
                    x += background->rgb_width) {
                bg = GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                                            myCanvasGroup, gnome_canvas_image_get_type(), "x",
                                            (double) x, "y", (double) y, "width",
                                            (double) background->rgb_width, "height",
                                            (double) background->rgb_height, "image", background,
                                            "anchor", (GtkAnchorType) GTK_ANCHOR_CENTER, NULL));
                gnome_canvas_item_lower_to_bottom(GNOME_CANVAS_ITEM(bg));
            }
        }
    }

    /* ghack_map.map is an array of canvas images.  Each cell of
     * the array will contain one tile.  Here, we create the
     * space for the cells and then create the cells for easy
     * access later.
    */
    for (i = 0, y = 0; y < height; y += ghack_glyph_height()) {
        for (x = 0; x < width; x += ghack_glyph_width()) {
            ghack_map.map[i++] = GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                    myCanvasGroup, gnome_canvas_image_get_type(), "x", (double) x,
                    "y", (double) y, "width", (double) ghack_glyph_width(),
                    "height", (double) ghack_glyph_height(), "anchor",
                    GTK_ANCHOR_NORTH_WEST, NULL));
        }
    }

    if (petmark != NULL) {
        /* ghack_map.overlay is an array of canvas images used to
         * overlay tile images...
        */
        for (i = 0, y = 0; y < height; y += ghack_glyph_height()) {
            for (x = 0; x < width; x += ghack_glyph_width()) {
                ghack_map.overlay[i] =
                    GNOME_CANVAS_IMAGE(gnome_canvas_item_new(
                                           myCanvasGroup, gnome_canvas_image_get_type(), "x",
                                           (double) x, "y", (double) y, "width",
                                           (double) petmark->rgb_width, "height",
                                           (double) petmark->rgb_height, "image", petmark,
                                           "anchor", GTK_ANCHOR_NORTH_WEST, NULL));
                gnome_canvas_item_lower_to_bottom(
                    GNOME_CANVAS_ITEM(ghack_map.overlay[i++]));
            }
        }
    }

    ghack_map_cliparound(NULL, u.ux, u.uy, NULL);
    ghack_map_cursor_to(NULL, u.ux, u.uy, NULL);
    gnome_canvas_update_now(ghack_map.canvas);
    doredraw();
}
Esempio n. 12
0
enum nh_restore_status nh_restore_game(int fd, struct nh_window_procs *rwinprocs,
				       boolean force_replay)
{
    int playmode, irole, irace, igend, ialign;
    char namebuf[PL_NSIZ];
    
    /* some compilers can't cope with the fact that all subsequent stores to error
     * are not dead, but become important if the error handler longjumps back
     * volatile is required to prevent invalid optimization based on that wrong
     * assumption. */
    volatile enum nh_restore_status error = GAME_RESTORED;
    
    if (fd == -1)
	return ERR_BAD_ARGS;
    
    switch (nh_get_savegame_status(fd, NULL)) {
	case LS_INVALID:	return ERR_BAD_FILE;
	case LS_DONE:		return ERR_GAME_OVER;
	case LS_CRASHED:	force_replay = TRUE; break;
	case LS_IN_PROGRESS:	return ERR_IN_PROGRESS;
	case LS_SAVED:		break; /* default, everything is A-OK */
    }
    
    if (!api_entry_checkpoint())
	goto error_out;
    
    error = ERR_BAD_FILE;
    replay_set_logfile(fd); /* store the fd and try to get a lock or exit */
    replay_begin();

    program_state.restoring = TRUE;
    iflags.disable_log = TRUE; /* don't log any of the commands, they're already in the log */

    /* Read the log header for this game. */
    replay_read_newgame(&turntime, &playmode, namebuf,
			&irole, &irace, &igend, &ialign);

    /* set special windowprocs which will autofill requests for user input
     * with data from the log file */
    replay_setup_windowprocs(rwinprocs);

    startup_common(namebuf, playmode);
    u.initrole = irole;
    u.initrace = irace;
    u.initgend = igend;
    u.initalign = ialign;

    if (!force_replay) {
	error = ERR_RESTORE_FAILED;
	replay_run_cmdloop(TRUE, FALSE, TRUE);
	replay_jump_to_endpos();
	if (!dorecover_fd(fd)) {
	    replay_undo_jump_to_endpos();
	    goto error_out2;
	}
	replay_undo_jump_to_endpos();
	wd_message();
	program_state.game_running = 1;
	post_init_tasks();
    } else {
	replay_run_cmdloop(TRUE, TRUE, FALSE); /* option setup only */
	newgame();
	/* try replaying instead */
	error = ERR_REPLAY_FAILED;
	replay_run_cmdloop(FALSE, FALSE, TRUE);
	replay_sync_save();
    }
    
    /* restore standard window procs */
    replay_restore_windowprocs();
    program_state.restoring = FALSE;
    iflags.disable_log = FALSE;

    /* clean up data used for replay */
    replay_end();
    log_truncate();
    log_init(); /* must be called before we start writing to the log */

    /* info might not have reached the ui while alternate window procs were set */
    doredraw();

    /* nh_start_game() does this via newgame(), but since this function doesn't
     * call newgame(), we have to do it here instead. */
    notify_levelchange(NULL);

    bot();
    flush_screen();
    was_on_elbereth = !sengr_at("Elbereth", u.ux, u.uy); /* force botl update later */

    welcome(FALSE);
    realtime_messages(TRUE, TRUE);
    update_inventory();
    
    api_exit();
    return GAME_RESTORED;

error_out2:
    api_exit();
    
error_out:
    replay_restore_windowprocs();
    program_state.restoring = FALSE;
    iflags.disable_log = FALSE;
    replay_end();
    unlock_fd(fd);
    
    if (error == ERR_RESTORE_FAILED) {
	raw_printf("Restore failed. Attempting to replay instead.\n");
	error = nh_restore_game(fd, rwinprocs, TRUE);
    }
    
    return error;
}
Esempio n. 13
0
static void newgame(void)
{
    int i;

    flags.ident = 1;

    for (i = 0; i < NUMMONS; i++)
	    mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;

    init_objects();	/* must be before u_init() */

    flags.pantheon = -1;/* role_init() will reset this */
    role_init();	/* must be before init_dungeons(), u_init(),
			 * and init_artifacts() */

    init_dungeons();	/* must be before u_init() to avoid rndmonst()
			 * creating odd monsters for any tins and eggs
			 * in hero's initial inventory */
    init_artifacts();
    u_init();		/* struct you must have some basic data for mklev to work right */

    load_qtlist();	/* load up the quest text info */

    level = mklev(&u.uz);

    u_init_inv_skills();/* level must be valid to create items */
    u_on_upstairs();
    vision_reset();	/* set up internals for level (after mklev) */
    check_special_room(FALSE);

    iflags.botl = 1;

    /* Move the monster from under you or else
     * makedog() will fail when it calls makemon().
     *			- ucsfcgl!kneller
     */
    if (MON_AT(level, u.ux, u.uy)) mnexto(m_at(level, u.ux, u.uy));
    makedog();
    doredraw();

    if (Role_if(PM_CONVICT)) {
	setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
	setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
	uball->spe = 1;	/* attach the ball to the hero */
	placebc();
    }

    /* help the window port get it's display charset/tiles sorted out */
    notify_levelchange(NULL);

    if (flags.legacy) {
	    flush_screen();
	    com_pager(Role_if(PM_CONVICT) ? 199 : 1);
    }

    /* Stop autoexplore revisiting the entrance stairs (or position). */
    level->locations[u.ux][u.uy].mem_stepped = 1;

    program_state.something_worth_saving++;	/* useful data now exists */
    
    historic_event(FALSE, "entered the Dungeons of Doom to retrieve the Amulet of Yendor!");

    /* Success! */
    welcome(TRUE);
    maybe_tutorial();

    /* Prepare for the first move. */
    flags.move = 0;
    set_wear();
    pickup(1);

    log_command_result();

    program_state.game_running = TRUE;
    youmonst.movement = NORMAL_SPEED;	/* give the hero some movement points */
    realtime_tasks();
    post_init_tasks();

    return;
}