void movemon() { struct monst *mtmp; int fr; warnlevel = 0; while(1) { int flag = 0; /* * Find a monster that we haven't treated yet * Note: That mtmp or mtmp->nmon might get killed * while mtmp moves, so we cannot just walk * down the chain (even new monsters might * get created!") */ for(mtmp = fmon; mtmp != NULL; mtmp = mtmp->nmon) { if(mtmp->mlstmv < moves) { flag = 1; break; } } if(flag == 0) { /* Treated all monsters */ break; } mtmp->mlstmv = moves; if(mtmp->mblinded != 0) { --mtmp->mblinded; if(mtmp->mblinded != 0) { mtmp->mcansee = 1; } } if(mtmp->mimic) { continue; } if((mtmp->mspeed != MSLOW) || ((moves % 2) == 0)) { /* Continue if the monster died fighting */ fr = -1; if((Conflict != 0) && (cansee(mtmp->mx, mtmp->my) != 0)) { fr = fightm(mtmp); if(fr == 2) { continue; } } if((fr < 0) && (dochugw(mtmp) != 0)) { continue; } } if((mtmp->mspeed == MFAST) && (dochugw(mtmp) != 0)) { continue; } } warnlevel -= u.ulevel; if(warnlevel >= SIZE(warnings)) { warnlevel = SIZE(warnings) - 1; } if(warnlevel >= 0) { if((warnlevel > lastwarnlev) || (moves > (lastwarntime + 5))) { char *rr; switch(Warning & (LEFT_RING | RIGHT_RING)) { case LEFT_RING: rr = "Your left ring glows"; break; case RIGHT_RING: rr = "Your right ring glows"; break; case LEFT_RING | RIGHT_RING: rr = "Both your rings glow"; break; default: rr = "You fingertips glow"; } pline("%s %s!", rr, warnings[warnlevel]); lastwarntime = moves; lastwarnlev = warnlevel; } } /* Remove all dead monsters */ dmonsfree(); }
void freedynamicdata(void) { int i; struct level *lev; if (!objects) return; /* no cleanup necessary */ unload_qtlist(); free_invbuf(); /* let_to_name (invent.c) */ free_youbuf(); /* You_buf,&c (pline.c) */ tmp_at(DISP_FREEMEM, 0); /* temporary display effects */ # define free_animals() mon_animal_list(FALSE) for (i = 0; i < MAXLINFO; i++) { lev = levels[i]; levels[i] = NULL; if (!lev) continue; /* level-specific data */ dmonsfree(lev); /* release dead monsters */ free_timers(lev); free_light_sources(lev); free_monchn(lev->monlist); free_worm(lev); /* release worm segment information */ freetrapchn(lev->lev_traps); free_objchn(lev->objlist); free_objchn(lev->buriedobjlist); free_objchn(lev->billobjs); free_engravings(lev); freedamage(lev); free(lev); } /* game-state data */ free_objchn(invent); free_objchn(migrating_objs); free_monchn(migrating_mons); free_monchn(mydogs); /* ascension or dungeon escape */ free_animals(); free_oracles(); freefruitchn(); freenames(); free_waterlevel(); free_dungeon(); free_history(); if (iflags.ap_rules) { free(iflags.ap_rules->rules); iflags.ap_rules->rules = NULL; free(iflags.ap_rules); } iflags.ap_rules = NULL; free(artilist); free(objects); objects = NULL; artilist = NULL; if (active_birth_options) free_optlist(active_birth_options); active_birth_options = NULL; return; }
movemon() { register struct monst *mtmp; register int fr; warnlevel = 0; while(1) { /* find a monster that we haven't treated yet */ /* note that mtmp or mtmp->nmon might get killed while mtmp moves, so we cannot just walk down the chain (even new monsters might get created!) */ for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->mlstmv < moves) goto next_mon; /* treated all monsters */ break; next_mon: mtmp->mlstmv = moves; /* most monsters drown in pools */ { boolean inpool, iseel; inpool = (levl[mtmp->mx][mtmp->my].typ == POOL); iseel = (mtmp->data->mlet == ';'); if(inpool && !iseel) { if(cansee(mtmp->mx,mtmp->my)) pline("%s drowns.", Monnam(mtmp)); mondead(mtmp); continue; } /* but eels have a difficult time outside */ if(iseel && !inpool) { if(mtmp->mhp > 1) mtmp->mhp--; mtmp->mflee = 1; mtmp->mfleetim += 2; } } if(mtmp->mblinded && !--mtmp->mblinded) mtmp->mcansee = 1; if(mtmp->mfleetim && !--mtmp->mfleetim) mtmp->mflee = 0; if(mtmp->mimic) continue; if(mtmp->mspeed != MSLOW || !(moves%2)){ /* continue if the monster died fighting */ fr = -1; if(Conflict && cansee(mtmp->mx,mtmp->my) && (fr = fightm(mtmp)) == 2) continue; if(fr<0 && dochugw(mtmp)) continue; } if(mtmp->mspeed == MFAST && dochugw(mtmp)) continue; } warnlevel -= u.ulevel; if(warnlevel >= SIZE(warnings)) warnlevel = SIZE(warnings)-1; if(warnlevel >= 0) if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ register char *rr; /* KLUDGE -- can't switch on longs!! switch(Warning & (LEFT_RING | RIGHT_RING)){ case LEFT_RING: rr = "Your left ring glows"; break; case RIGHT_RING: rr = "Your right ring glows"; break; case LEFT_RING | RIGHT_RING: rr = "Both your rings glow"; break; default: rr = "Your fingertips glow"; break; } */ long swtval = Warning & (LEFT_RING | RIGHT_RING); if(swtval == LEFT_RING) rr = "Your left ring glows"; else if(swtval == RIGHT_RING) rr = "Your right ring glows"; else if(swtval == LEFT_RING | RIGHT_RING) rr = "Both your rings glow"; else rr = "Your fingertips glow"; pline("%s %s!", rr, warnings[warnlevel]); lastwarntime = moves; lastwarnlev = warnlevel; } dmonsfree(); /* remove all dead monsters */ }
void savelev(struct memfile *mf, xchar levnum) { int x, y; unsigned int lflags; struct level *lev = levels[levnum]; if (iflags.purge_monsters) { /* purge any dead monsters (necessary if we're starting * a panic save rather than a normal one, or sometimes * when changing levels without taking time -- e.g. * create statue trap then immediately level teleport) */ dmonsfree(lev); } mfmagic_set(mf, LEVEL_MAGIC); mwrite8(mf, lev->z.dnum); mwrite8(mf, lev->z.dlevel); mwrite(mf, lev->levname, sizeof(lev->levname)); for (x = 0; x < COLNO; x++) for (y = 0; y < ROWNO; y++) save_location(mf, &lev->locations[x][y]); mwrite32(mf, lev->lastmoves); mwrite(mf, &lev->upstair, sizeof(stairway)); mwrite(mf, &lev->dnstair, sizeof(stairway)); mwrite(mf, &lev->upladder, sizeof(stairway)); mwrite(mf, &lev->dnladder, sizeof(stairway)); mwrite(mf, &lev->sstairs, sizeof(stairway)); mwrite(mf, &lev->updest, sizeof(dest_area)); mwrite(mf, &lev->dndest, sizeof(dest_area)); mwrite8(mf, lev->flags.nfountains); mwrite8(mf, lev->flags.nsinks); lflags = (lev->flags.has_shop << 31) | (lev->flags.has_vault << 30) | (lev->flags.has_zoo << 29) | (lev->flags.has_court << 28) | (lev->flags.has_morgue << 27) | (lev->flags.has_beehive << 26) | (lev->flags.has_barracks << 25) | (lev->flags.has_temple << 24) | (lev->flags.has_swamp << 23) | (lev->flags.noteleport << 22) | (lev->flags.hardfloor << 21) | (lev->flags.nommap << 20) | (lev->flags.hero_memory << 19) | (lev->flags.shortsighted << 18) | (lev->flags.graveyard << 17) | (lev->flags.is_maze_lev << 16) | (lev->flags.is_cavernous_lev << 15) | (lev->flags.arboreal << 14) | (lev->flags.forgotten << 13); mwrite32(mf, lflags); mwrite(mf, lev->doors, sizeof(lev->doors)); save_rooms(mf, lev); /* no dynamic memory to reclaim */ /* must be saved before mons, objs, and buried objs */ save_timers(mf, lev, RANGE_LEVEL); save_light_sources(mf, lev, RANGE_LEVEL); savemonchn(mf, lev->monlist); save_worm(mf, lev); /* save worm information */ savetrapchn(mf, lev->lev_traps); saveobjchn(mf, lev->objlist); saveobjchn(mf, lev->buriedobjlist); saveobjchn(mf, lev->billobjs); save_engravings(mf, lev); savedamage(mf, lev); save_regions(mf, lev); }