From 300f1637b36e1d7cb7abe92d76b1c87afc6c88e1 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Mon, 16 May 2011 02:03:25 +0000 Subject: [PATCH] - [+] can't go up to forest now!!!! * [+] implement points: * [+] listobs() printing nothign when i die... - [+] use nextmap again. - [+] make 'grass' cells burn to dirt - [+] bug in checking screen chars. - [+] NOW why isn't screen clearing after exiting inventory? * [+] in drawlevelfor() - [+] CRASH going down stairs to dlev 2. - [+] outside light - 6pm -> 6am = DARK - [+] outside 6pm-7pm = getting dark - [+] outside 6am-7am = getting light. - Initial forest implementation - [+] all grass - [+] lots of random trees - [+] add monsters / objects * [+] more forest objects --- defs.h | 27 ++- doc/regions | 4 + io.c | 139 ++++++++++------ io.h | 6 +- lf.c | 122 ++++++++++---- lf.h | 1 + log.txt | 12 -- map.c | 467 +++++++++++++++++++++++++++------------------------- map.h | 7 +- move.c | 16 +- nexus.c | 4 +- objects.c | 104 ++++++++++-- spell.c | 17 +- text.c | 2 + 14 files changed, 578 insertions(+), 350 deletions(-) create mode 100644 doc/regions diff --git a/defs.h b/defs.h index 3740594..13050f8 100644 --- a/defs.h +++ b/defs.h @@ -107,6 +107,8 @@ enum SKILLLEVEL { #define NOBODY (-1) #define ALLCONFERRED (-9873) +#define AUTO (-7654) + enum GAMEMODE { GM_FIRST, @@ -378,15 +380,22 @@ enum LOFTYPE { #define D_DOWN 13 #define D_IN 14 +#define MAXDIR_MAP 15 + // Cell types enum CELLTYPE { + // walls CT_WALL, CT_ROOMWALL, + // empty CT_CORRIDOR, - CT_ROOM, + CT_DIRT, + CT_GRASS, CT_LOOPCORRIDOR, + // rooms + CT_ROOM, }; @@ -513,6 +522,7 @@ enum OBCLASS { OC_TOOLS, OC_TECH, OC_MISC, + OC_FLORA, OC_SPELL, OC_ABILITY, OC_EFFECT, @@ -529,6 +539,7 @@ enum BLESSTYPE { enum HABITAT { H_DUNGEON = 1, + H_FOREST = 2, H_ALL = 999 }; @@ -605,7 +616,6 @@ enum RACE { R_CACTUS, R_DREAMFUNGUS, R_SAWGRASS, - R_TREE, // animals R_ANT, R_ANTS, @@ -729,7 +739,7 @@ enum OBTYPE { OT_TRAPFIRE, OT_TRAPMINE, OT_TRAPTRIP, - // rocks + // rocks / plants OT_GOLD, OT_STONE, OT_ASH, @@ -737,6 +747,12 @@ enum OBTYPE { OT_ASHCONCEAL, OT_ASHSLEEP, OT_GEMOFSEEING, + // flora + OT_FLOWER, + OT_LEAF, + OT_SHRUB, + OT_STUMP, + OT_TREE, // food OT_BERRY, OT_NUT, @@ -2171,16 +2187,19 @@ typedef struct command_s { struct command_s *next, *prev; } command_t; +#define RG_WORLDMAP 0 +#define RG_FIRSTDUNGEON 1 typedef struct map_s { int id; + int region; int depth; char *name; // name of this map enum HABITAT habitat; // eg. dungeon, forest, etc unsigned int seed; int w,h; // width/height of this map struct cell_s *cell[MAX_MAPW*MAX_MAPH]; // list of cells in this map - int nextmap[MAXDIR_ORTH]; // which map is in each direction + int nextmap[MAXDIR_MAP]; // which map is in each direction int beingcreated; struct lifeform_s *lf,*lastlf; diff --git a/doc/regions b/doc/regions new file mode 100644 index 0000000..cade3d4 --- /dev/null +++ b/doc/regions @@ -0,0 +1,4 @@ +special region ids: + +0 = main world +1 = first dungeon diff --git a/io.c b/io.c index 39c3297..42ba4f5 100644 --- a/io.c +++ b/io.c @@ -1875,11 +1875,11 @@ void announceobflagloss(object_t *o, flag_t *f) { object_t *askobject(obpile_t *op, char *prompt, int *count, long opts) { - return doaskobject(op, prompt, count, B_TRUE, opts, F_NONE); + return doaskobject(op, prompt, count, B_TRUE, B_FALSE, opts, F_NONE); } object_t *askobjectwithflag(obpile_t *op, char *prompt, int *count, long opts, enum FLAG withflag) { - return doaskobject(op, prompt, count, B_TRUE, opts, withflag, F_NONE); + return doaskobject(op, prompt, count, B_TRUE, B_FALSE, opts, withflag, F_NONE); } /* @@ -1899,7 +1899,7 @@ int contains(enum OBCLASS *array, int nargs, enum OBCLASS want) { return B_FALSE; } -void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup) { +void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints) { int lastclass = OC_NULL; int i; int useobletters = B_TRUE; @@ -1912,6 +1912,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi char obname[BUFLEN]; char infobuf[BUFLEN]; char equipbuf[BUFLEN]; + char pointsbuf[BUFLEN]; if (mylist[i]->type->obclass->id != lastclass) { // print class heading wattron(win, A_STANDOUT); @@ -1942,6 +1943,14 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi obname); } + if (showpoints && (mylist[i]->type->id != OT_GOLD)) { + long points; + points = getobvalue(mylist[i]); + sprintf(pointsbuf, " [%ld points]", points); + } else { + strcpy(pointsbuf, ""); + } + setobcolour(win, mylist[i], B_TRUE); getobextrainfo(mylist[i], infobuf); @@ -1956,13 +1965,19 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi wprintw(win, "%s", equipbuf); unsetcol(win, C_BROWN); } + + if (strlen(pointsbuf)) { + setcol(win, C_WHITE); + wprintw(win, "%s", pointsbuf); + unsetcol(win, C_WHITE); + } (*y)++; } *counter = i; } -object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, long opts, ...) { +object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int showpoints, long opts, ...) { int c,i; object_t *mylist[MAXPILEOBS+1]; char myletters[MAXPILEOBS+1]; @@ -2088,7 +2103,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, lon // list the objects y = 2; - listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters , forpickup); + listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters , forpickup, showpoints); if (mylist[i] == NULL) { nextpage = -1; @@ -2150,6 +2165,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, lon needredraw = B_TRUE; clearmsg(); drawscreen(); + restoregamewindows(); return o; } } else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing @@ -2180,9 +2196,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, lon } // display game windows again - needredraw = B_TRUE; - clearmsg(); - drawscreen(); + restoregamewindows(); return NULL; } @@ -2218,9 +2232,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { centre(mainwin, getmaxy(mainwin)-1, "[Press any key]"); getch(); - needredraw = B_TRUE; - clearmsg(); - drawscreen(); + restoregamewindows(); return B_TRUE; } @@ -2278,7 +2290,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { // list the objects y = 2; - listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters , B_TRUE); + listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters , B_TRUE, B_FALSE); if (mylist[i] == NULL) { nextpage = -1; @@ -2355,9 +2367,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { reason = E_SELNOTHING; nretobs = 0; // display game windows again - needredraw = B_TRUE; - clearmsg(); - drawscreen(); + restoregamewindows(); return B_TRUE; } else if (ch == ',') { // toggle all/none int val; @@ -2407,8 +2417,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { clearmsg(); // display game windows again - needredraw = B_TRUE; - drawscreen(); + restoregamewindows(); if (nretobs <= 0) { return B_TRUE; } @@ -3737,10 +3746,6 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { } killobpile(op); - - needredraw = B_TRUE; - drawscreen(); - real_clearmsg(B_TRUE); } @@ -3823,9 +3828,7 @@ void doknowledgelist(void) { wrefresh(mainwin); getch(); - needredraw = B_TRUE; - clearmsg(); - drawscreen(); + restoregamewindows(); } void dolook(cell_t *where, int onpurpose) { @@ -4178,10 +4181,7 @@ void domsghist(void) { wrefresh(mainwin); getch(); // restore screen - //cls(); - needredraw = B_TRUE; - drawscreen(); - real_clearmsg(B_TRUE); + restoregamewindows(); } void dooperate(obpile_t *op) { @@ -4278,6 +4278,7 @@ void doenter(lifeform_t *lf) { // try to go down dostairs(D_DOWN); } + restoregamewindows(); } void doexplain(char *question) { @@ -4307,16 +4308,17 @@ void doexplain(char *question) { } } msg("Done."); + restoregamewindows(); } void dofinaloblist(obpile_t *op) { object_t *o; - o = askobject(op, "Your final possessions were", NULL, AO_NONE); + o = doaskobject(op, "Your final possessions were", NULL, B_FALSE, B_TRUE, AO_NONE, F_NONE); while (o) { // describe it describeob(o); // ask for another one - o = askobject(op, "Your final possessions were", NULL, AO_NONE); + o = doaskobject(op, "Your final possessions were", NULL, B_FALSE, B_TRUE, AO_NONE, F_NONE); } real_clearmsg(B_TRUE); } @@ -4366,9 +4368,7 @@ void dohelp(void) { centre(mainwin, h-1, "[Press any key]"); getch(); - needredraw = B_TRUE; - drawscreen(); - real_clearmsg(B_TRUE); + restoregamewindows(); } void doinventory(obpile_t *op) { @@ -4891,6 +4891,10 @@ void drawlevelfor(lifeform_t *lf) { int x,y; cell_t *cell; map_t *map; + int ndrawn = 0; + int db = B_FALSE; + int w,h; + map = lf->cell->map; needredraw = B_FALSE; @@ -4899,32 +4903,56 @@ void drawlevelfor(lifeform_t *lf) { // turn off cursor curs_set(0); - wclear(gamewin); - for (y = viewy; y < viewy + viewh; y++) { - for (x = viewx; x < viewx + vieww; x++) { - if ((x == lf->cell->x + 1) && (y == lf->cell->y)) { - dblog("x"); - } - cell = getcellat(map, x, y); + if (db) dblog("starting DRAWLEVEL"); + //wclear(gamewin); + //for (y = viewy; y < viewy + viewh; y++) { + // for (x = viewx; x < viewx + vieww; x++) { + getmaxyx(gamewin, h, w); + if (db) { + dblog("first x,y checked was %d,%d",0+viewx,0+viewy); + } + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + cell = getcellat(map, x + viewx, y + viewy); if (cell) { glyph_t glyph,screenglyph; - getcellglyph(&glyph, cell, lf); + int needdraw = B_FALSE; + + getcellglyph(&glyph, cell, player); //drawglyph(&glyph, x - viewx, y - viewy); // only draw if screen char/colour is different - screenglyph.ch = mvwinch(gamewin, y - viewy, x - viewx) & A_CHARTEXT; + /* + if (cell == player->cell) { + dblog("test"); + } + */ + screenglyph.ch = mvwinch(gamewin, y, x) & A_CHARTEXT; if (screenglyph.ch != glyph.ch) { - drawglyph(&glyph, x - viewx, y - viewy); + needdraw = B_TRUE; } else { - screenglyph.colour = mvwinch(gamewin, y - viewy, x - viewx) & A_COLOR; + screenglyph.colour = PAIR_NUMBER(mvwinch(gamewin, y, x) & A_COLOR); if (screenglyph.colour != glyph.colour) { - drawglyph(&glyph, x - viewx, y - viewy); + needdraw = B_TRUE; } } - + if (needdraw) { + drawglyph(&glyph, x, y); + if (db) { + dblog(" drawing char '%lc'/%d at %d,%d (screenglyph was '%lc'/%d)\n\n", + glyph.ch, glyph.ch, + x,y, + screenglyph.ch, screenglyph.ch); + } + ndrawn++; + } } } } + if (db) { + dblog("last x,y checked was %d,%d",x+viewx,y+viewy); + } + if (db) dblog("ending DRAWLEVEL"); // move cursor to the player's position and blit drawcursor(); } @@ -5168,6 +5196,7 @@ char getchoice(prompt_t *prompt) { wrefresh(mainwin); } curs_set(0); + restoregamewindows(); // return NUL or result char if (ch == 27) { return '\0'; @@ -5426,6 +5455,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) { wrefresh(mainwin); } curs_set(0); + restoregamewindows(); // return NUL or result char if (ch == 27) { return '\0'; @@ -6374,6 +6404,14 @@ void redraw(void) { wrefresh(gamewin); } +void restoregamewindows(void) { + needredraw = B_TRUE; + statdirty = B_TRUE; + clearmsg(); + wclear(gamewin); + drawscreen(); +} + void setcol(WINDOW *win, enum COLOUR col) { if (needsbold(col)) { wattron(win, A_BOLD); @@ -6493,9 +6531,7 @@ void showlfarmour(lifeform_t *lf) { */ getch(); - needredraw = B_TRUE; - drawscreen(); - real_clearmsg(B_TRUE); + restoregamewindows(); } void showlfstats(lifeform_t *lf, int showall) { @@ -8023,6 +8059,8 @@ void showlfstats(lifeform_t *lf, int showall) { } } // end while !done + restoregamewindows(); + /* statdirty = B_TRUE; needredraw = B_TRUE; @@ -8033,6 +8071,7 @@ void showlfstats(lifeform_t *lf, int showall) { wrefresh(statwin); real_clearmsg(B_TRUE); + */ //redraw(); } @@ -8052,7 +8091,7 @@ void tombstone(lifeform_t *lf) { y = 1; centre(mainwin, y, "R.I.P."); y++; //printf("%s\n",lf->name); - centre(mainwin, y, "%s",pname); y++; + centre(mainwin, y, "%s (%ld points)",pname, calcscore(lf)); y++; centre(mainwin, y, "Died on level %d of the dungeon.", lf->cell->map->depth); y++; p = strtok_r(lf->lastdam,"^", &dummy); diff --git a/io.h b/io.h index 5896550..4371f3d 100644 --- a/io.h +++ b/io.h @@ -15,7 +15,7 @@ int announceobflaggain(object_t *o, flag_t *f); void announceobflagloss(object_t *o, flag_t *f); object_t *askobject(obpile_t *op, char *title, int *count, long opts); object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag); -object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, long opts, ...); +object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...); int askobjectmulti(obpile_t *op, char *prompt, long opts); char askchar(char *prompt, char *validchars, char *def, int showchars); cell_t *askcoords(char *prompt, int targettype); @@ -82,7 +82,7 @@ void doheading(WINDOW *win, int *y, int x, char *what); void initgfx(void); void initprompt(prompt_t *p, char *q1); int keycodetokey(int keycode); -void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup); +void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints); void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantinvalid); void more(void); void warn(char *format, ... ); @@ -93,7 +93,7 @@ int needsbold(enum COLOUR col); void nothinghappens(void); void dblog(char *format, ... ); void redraw(void); -int savequit(void); +void restoregamewindows(void); void setcol(WINDOW *win, enum COLOUR col); void unsetcol(WINDOW *win, enum COLOUR col); void setobcolour(WINDOW *win, object_t *o, int set); diff --git a/lf.c b/lf.c index 970cab3..e8a21d5 100644 --- a/lf.c +++ b/lf.c @@ -186,6 +186,20 @@ void breakallgrabs(lifeform_t *lf) { } } } + +long calcscore(lifeform_t *lf) { + long points = 0; + object_t *o; + // objects + for (o = lf->pack->first ; o ; o = o->next) { + points += getobvalue(o); + } + // points for xp + points += (lf->xp / 10); + + return points; +} + // figure out how much xp a race is worth int calcxp(lifeform_t *lf) { float multiplier = 1; @@ -3857,6 +3871,25 @@ int getvisrange(lifeform_t *lf) { range = MAXVISRANGE; } + // modify for darkness outside ? + if ((range > 0) && isoutdoors(lf->cell->map)) { + int hours,mins,secs; + float pct; + splittime(&hours,&mins,&secs); + pct = ((float)mins/59.0) * 100.0; + if (hours == 6) { // ie. 6am - 7am + // getting lighter. as minutes approach 59, + // visrange gets closer to maximum. + range = pctof( pct, range); + limit(&range, 1, NA); + } else if (hours == 18) { // ie. 6pm-7pm + // getting darker. as minutes approach 59, + // visrange gets closer to zero. + range = pctof( 100 - pct, range); + limit(&range, 1, NA); + } + } + // modifications? for (f = lf->flags->first ; f ; f = f->next) { if (f->id == F_VISRANGEMOD) { @@ -6147,7 +6180,6 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "knife"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of magic"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of experience"); /* addflag(lastjob->flags, F_IFPLAYER, NA, NA, NA, NULL); addflag(lastjob->flags, F_IFPCT, 50, NA, NA, NULL); @@ -7244,6 +7276,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addrace(R_DREAMFUNGUS, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_METAL, RC_PLANT); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 70, NA, ""); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_VEGETABLE, NA, NULL); @@ -7267,6 +7300,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_VEGETABLE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); @@ -7290,34 +7324,12 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); - addrace(R_TREE, "tree", 140, 'F', C_BROWN, MT_WOOD, RC_PLANT); - addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); - addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HITDICE, 8, NA, NA, ""); - addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_EYES, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); - addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); // end plants // animals addrace(R_BAT, "giant bat", 3, 'B', C_BROWN, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 95, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); @@ -7339,6 +7351,7 @@ void initrace(void) { addrace(R_BEAR, "black bear", 150, 'q', C_BLUE, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 63, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, 3, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -7357,6 +7370,7 @@ void initrace(void) { addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_BROWN, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 52, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 52, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 5, 5, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -7378,6 +7392,7 @@ void initrace(void) { lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, 0, NA, NULL); @@ -7397,6 +7412,7 @@ void initrace(void) { lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 65, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL); @@ -7418,6 +7434,7 @@ void initrace(void) { lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 60, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); @@ -7441,6 +7458,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 77, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 77, NA, ""); addflag(lastrace->flags, F_HITDICE, 4, 0, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_MAXATTACKS, 1, NA, NA, NULL); @@ -7462,6 +7480,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 60, NA, ""); addflag(lastrace->flags, F_HITDICE, 2, 1, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d10"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d10"); @@ -7486,6 +7505,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 83, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 83, NA, ""); addflag(lastrace->flags, F_HITDICE, 2, 2, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "2d4"); addflag(lastrace->flags, F_MAXATTACKS, 1, NA, NA, NULL); @@ -7502,6 +7522,7 @@ void initrace(void) { addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, IQ_AVERAGE, NA, NULL); @@ -7720,6 +7741,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addrace(R_SNAKETREE, "tree snake", 3, 's', C_GREEN, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7742,6 +7764,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addrace(R_SNAKECOBRA, "giant cobra", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 78, NA, ""); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7766,6 +7789,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addrace(R_SNAKECONSTRICTOR, "constrictor", 3, 's', C_MAGENTA, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 68, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 68, NA, ""); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7790,6 +7814,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addrace(R_SPIDER, "giant spider", 5, 'S', C_GREY, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -7813,6 +7838,7 @@ void initrace(void) { addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL); lastrace->baseid = R_SPIDER; addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 63, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -7838,6 +7864,7 @@ void initrace(void) { addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL); lastrace->baseid = R_SPIDER; addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 78, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -7867,6 +7894,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, ""); addflag(lastrace->flags, F_HITDICE, 2, 2, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, NA, NA, NULL); @@ -7887,6 +7915,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_HITDICE, 3, 3, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d5"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d5"); @@ -7905,6 +7934,7 @@ void initrace(void) { // insects addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); @@ -7933,6 +7963,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); addflag(lastrace->flags, F_HITDICE, 1, 0, NA, ""); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); @@ -7955,6 +7986,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_HITDICE, 2, 1, NA, ""); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); @@ -7976,6 +8008,7 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 90, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_HITDICE, 1, 1, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); @@ -7993,6 +8026,7 @@ void initrace(void) { addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -8021,6 +8055,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); + addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, ""); addflag(lastrace->flags, F_HITDICE, 1, 0, NA, ""); addflag(lastrace->flags, F_EVASION, 60, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, NA, NA, "1d2-1"); @@ -9363,10 +9398,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml } // occasionally drop blood - if ((damtype != DT_POISON) && (damtype != DT_POISONGAS)) { - if (onein(3)) { - bleed(lf); - } + switch (damtype) { + case DT_POISON: + case DT_POISONGAS: + case DT_WATER: + break; + default: + if (onein(3)) { + bleed(lf); + } + break; } if (hasflag(lf->flags, F_DEBUG)) { @@ -12524,9 +12565,10 @@ int usestairs(lifeform_t *lf, object_t *o) { // find adjacent allies or enemies which will follow you if (isplayer(lf)) { - for (dir = DC_N; dir <= DC_NW; dir++) { + int d; + for (d = DC_N; d <= DC_NW; d++) { cell_t *c; - c = getcellindir(lf->cell, dir); + c = getcellindir(lf->cell, d); if (c && c->lf) { if (areallies(lf, c->lf) || areenemies(lf, c->lf)) { if (!isimmobile(c->lf)) { @@ -12546,14 +12588,20 @@ int usestairs(lifeform_t *lf, object_t *o) { if (isplayer(lf)) msg("This portal doesn't seem to go anywhere."); } else { // is there already a level of the correct depth? - newmap = findmapofdepth(newdepth); + newmap = findregionmap(lf->cell->map->region, newdepth); if (newmap) { dblog("ERROR - unlinked stairs!\n"); msg("ERROR - unlinked stairs!\n"); } else { // generate a new map! this will fill in the destination of our stairs newmap = addmap(); - createmap(newmap, newdepth, curmap->habitat); + if (newdepth == 0) { + createmap(newmap, newdepth, RG_WORLDMAP, AUTO, curmap, dir); + } else { + createmap(newmap, newdepth, lf->cell->map->region, AUTO, curmap, dir); + } + // link our stairs to the new map. + //linkstairs(o); // NOW our stairs should have a destination newcell = getstairdestination(o); @@ -12581,7 +12629,15 @@ int usestairs(lifeform_t *lf, object_t *o) { } // announce if (isplayer(lf)) { - msg("You arrive at level %d.", newcell->map->depth); + if (newcell->map->region == RG_WORLDMAP) { + if (lf->cell->map->region == RG_WORLDMAP) { + msg("You arrive in a new area."); + } else { + msg("You arrive at the surface."); + } + } else if (newcell->map->habitat == H_DUNGEON) { + msg("You arrive at dungeon level %d.", newcell->map->depth); + } f = hasflag(o->flags, F_MAPLINK); if (f) f->known = B_KNOWN; } diff --git a/lf.h b/lf.h index 72e67f3..615b497 100644 --- a/lf.h +++ b/lf.h @@ -17,6 +17,7 @@ int appearsrandomly(enum RACE rid); void awardxpfor(lifeform_t *killed, float pct); void bleed(lifeform_t *lf); void breakallgrabs(lifeform_t *lf); +long calcscore(lifeform_t *lf); int calcxp(lifeform_t *lf); int calcxprace(enum RACE rid); int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost); diff --git a/log.txt b/log.txt index 7d606d5..9ed9d1f 100644 --- a/log.txt +++ b/log.txt @@ -4,15 +4,3 @@ ====== NEW LOGFILE ==== givejob() starting. -x -x -x -x -x -x -x -x -x -x -x -x diff --git a/map.c b/map.c index 04115b2..5833ec4 100644 --- a/map.c +++ b/map.c @@ -123,6 +123,10 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto } else { r = findrace(raceid); } + if (!r) { + r = getreallyrandomrace(); + } + assert(r); if (db) dblog("adding rand lf %s to cell %d,%d",r->name,c->x,c->y); @@ -429,7 +433,8 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) { glyph_t tempgl; // default - g->ch = '\0'; + g->ch = ' '; + g->colour = C_RED; if (haslos(viewer, c)) { // show cell contents @@ -520,6 +525,8 @@ enum CELLTYPE getemptycelltype(enum HABITAT hab) { switch (hab) { case H_DUNGEON: return CT_CORRIDOR; + case H_FOREST: + return CT_GRASS; default: break; } @@ -595,8 +602,19 @@ void calclight(map_t *map) { object_t *o; // lit based on depth - if ((map->depth <= 5) && (c->lit != L_PERMDARK)) { - makelit(c, L_PERMLIGHT, -1); + if (isoutdoors(map)) { + int hours,mins,secs; + splittime(&hours,&mins,&secs); + if ((hours < 5) || (hours >= 19)) { + // ie. nighttime, after 7pm or before 5am + } else { + // ie. daytime + makelit(c, L_PERMLIGHT, -1); + } + } else { + if ((map->depth <= 5) && (c->lit != L_PERMDARK)) { + makelit(c, L_PERMLIGHT, -1); + } } // TODO: has dark producing lf? @@ -741,18 +759,10 @@ int countcellexits(cell_t *cell) { return exits; } -/* - seed = random number seed - turnpct = percentage change of a corridor turning - sparseness = how many times to chop off dead ends - looppct = percentage change of turning dead-end into loop - maxrooms = max # of rooms -*/ -void createmap(map_t *map, int depth, int habitat) { - char buf[BUFLEN]; +void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) { int wantrooms = B_TRUE; - int x,y; int d; + int x,y; int i; int done,unused; int dir; @@ -770,7 +780,6 @@ void createmap(map_t *map, int depth, int habitat) { cell_t *cell, *c; object_t *o; int db = B_FALSE; - lifeform_t *lf; // parameters int turnpct = DEF_TURNPCT; @@ -782,30 +791,7 @@ void createmap(map_t *map, int depth, int habitat) { int moved = 0; enum CELLTYPE emptycell; - - //int db = B_TRUE; - - map->beingcreated = B_TRUE; - - sprintf(buf, "Map %d",map->id); - map->name = strdup(buf); - map->habitat = habitat; - - for (i = 0; i < MAXDIR_ORTH; i++) { - map->nextmap[i] = -1; - } - - map->w = MAX_MAPW; - map->h = MAX_MAPH; - - // map depth? - map->depth = depth; - - // rememebr seed - //map->seed = 11734; - map->seed = rand() % 65535; - srand(map->seed); - + // fill entire maze with walls for (y = 0; y < map->h; y++) { for (x = 0; x < map->w; x++) { @@ -819,7 +805,6 @@ void createmap(map_t *map, int depth, int habitat) { // pick initial random spot cell = getrandomcell(map); - setcelltype(cell, emptycell); cell->visited = B_TRUE; //if (db) printf("- Starting (%d,%d)\n",cell->x, cell->y); @@ -1024,7 +1009,7 @@ void createmap(map_t *map, int depth, int habitat) { } - // add staircases + // add staircases - dungeons alway shave an up and down stairs for (i = 0; i < 3; i++) { // add up stairs c = NULL; @@ -1042,187 +1027,6 @@ void createmap(map_t *map, int depth, int habitat) { linkstairs(o); } - /* void around map - // N - if (wreck->mazelev[0].type == W_WRECK) { - for (x = 0; x < MAZEW; x++) { - y = 0; - while (getfloor(x,y,curz) == C_SOLID) { - // change to void - wreck->mazelev[curz].maze[y*MAZEW+x].floor = C_VOID; - wreck->mazelev[curz].maze[y*MAZEW+x].floorver = rand() % MAXVOIDVER; - // make exits breakable or remove them. - for (d = D_NORTH ; d <= D_WEST; d++) { - int extype = getexit(x,y,curz,d); - int newx,newy; - newx = x + dirtox(d); - newy = y + dirtoy(d); - if (isonmap(newx, newy, curz)) { - if (issolid(newx,newy,curz)) { - // remove it - setexit(x,y,curz,d,EX_CORRIDOR); - } else { - object_t *o; - // make it vulnerable - if (isbreakableexit(extype)) { - setexit(x,y,curz,d,extype); - } - // add warning sign - o = addobject(&wreck->mazelev[curz].maze[newy*MAZEW+newx].floorobs, O_SIGNWARNING); - o->dir = diropposite(d); - } - } - } - y++; - } - } - // S - for (x = 0; x < MAZEW; x++) { - y = MAZEH-1; - while (getfloor(x,y,curz) == C_SOLID) { - // change to void - wreck->mazelev[curz].maze[y*MAZEW+x].floor = C_VOID; - wreck->mazelev[curz].maze[y*MAZEW+x].floorver = rand() % MAXVOIDVER; - // make exits breakable. - for (d = D_NORTH ; d <= D_WEST; d++) { - int extype = getexit(x,y,curz,d); - int newx,newy; - newx = x + dirtox(d); - newy = y + dirtoy(d); - if (isonmap(newx, newy, curz)) { - if (issolid(newx,newy,curz)) { - // remove it - setexit(x,y,curz,d,EX_CORRIDOR); - } else { - object_t *o; - // make it vulnerable - if (isbreakableexit(extype)) { - setexit(x,y,curz,d,extype); - } - // add warning sign - o = addobject(&wreck->mazelev[curz].maze[newy*MAZEW+newx].floorobs, O_SIGNWARNING); - o->dir = diropposite(d); - } - } - } - y--; - } - } - // E - for (y = 0; y < MAZEH; y++) { - x = 0; - while (getfloor(x,y,curz) == C_SOLID) { - // change to void - wreck->mazelev[curz].maze[y*MAZEW+x].floor = C_VOID; - wreck->mazelev[curz].maze[y*MAZEW+x].floorver = rand() % MAXVOIDVER; - // make exits breakable. - for (d = D_NORTH ; d <= D_WEST; d++) { - int extype = getexit(x,y,curz,d); - int newx,newy; - newx = x + dirtox(d); - newy = y + dirtoy(d); - if (isonmap(newx, newy, curz)) { - if (issolid(newx,newy,curz)) { - // remove it - setexit(x,y,curz,d,EX_CORRIDOR); - } else { - object_t *o; - // make it vulnerable - if (isbreakableexit(extype)) { - setexit(x,y,curz,d,extype); - } - // add warning sign - o = addobject(&wreck->mazelev[curz].maze[newy*MAZEW+newx].floorobs, O_SIGNWARNING); - o->dir = diropposite(d); - } - } - } - x++; - } - } - // W - for (y = 0; y < MAZEH; y++) { - x = MAZEW-1; - while (getfloor(x,y,curz) == C_SOLID) { - // change to void - wreck->mazelev[curz].maze[y*MAZEW+x].floor = C_VOID; - wreck->mazelev[curz].maze[y*MAZEW+x].floorver = rand() % MAXVOIDVER; - // make exits breakable. - for (d = D_NORTH ; d <= D_WEST; d++) { - int extype = getexit(x,y,curz,d); - int newx,newy; - newx = x + dirtox(d); - newy = y + dirtoy(d); - if (isonmap(newx, newy, curz)) { - if (issolid(newx,newy,curz)) { - // remove it - setexit(x,y,curz,d,EX_CORRIDOR); - } else { - object_t *o; - // make it vulnerable - if (isbreakableexit(extype)) { - setexit(x,y,curz,d,extype); - } - // add warning sign - o = addobject(&wreck->mazelev[curz].maze[newy*MAZEW+newx].floorobs, O_SIGNWARNING); - o->dir = diropposite(d); - } - } - } - x--; - } - } - } - */ - - /* - // add windows to map - for (y = 0; y < MAZEH; y++) { - for (x = 0; x < MAZEW; x++) { - int dir,chance = windowchance; - // increase chance for adjacent windows - for (dir = D_NORTH ; dir <= D_WEST ; dir++) { - int adjx,adjy; - adjx = x + dirtox(dir); - adjy = y + dirtoy(dir); - if (isonmap(adjx,adjy,curz)) { - // extra chance per adjacent window - chance += (hasexitoftype(adjx,adjy,curz,EX_WINDOW)*10); - } - } - for (dir = D_NORTH ; dir <= D_WEST ; dir++) { - int etype,newx,newy,thisfloor,newfloor; - etype = getexit(x,y,curz,dir); - newx = x + dirtox(dir); - newy = y + dirtoy(dir); - if (isonmap(newx,newy,curz)) { - thisfloor = wreck->mazelev[curz].maze[y*MAZEW+x].floor; - newfloor = wreck->mazelev[curz].maze[newy*MAZEW+newx].floor; - if ((etype == EX_WALL) && canhavewindow(thisfloor) && canhavewindow(newfloor)) { - if (getrand(1,100) <= chance) { - setexit(x,y,curz,dir,EX_WINDOW); - } - - } - } - } - } - } - */ - - // add objects and monsters to dead ends - for (y = 0; y < map->h; y++) { - for (x = 0; x < map->w; x++) { - cell_t *c; - c = getcellat(map, x, y); - if (c && isempty(c)) { - if (rnd(1,100) <= getobchance(map->habitat)) { - addrandomthing(c, 50); - } - } - } - } - if (wantrooms && (numrooms > 0)) { // add pillars & objects & monsters to rooms for (i = 0; i < numrooms; i++) { @@ -1293,13 +1097,184 @@ void createmap(map_t *map, int depth, int habitat) { } if (db) dblog("Finished adding objects."); +} +void createforest(map_t *map, int depth, map_t *parentmap, int exitdir) { + int x,y; + enum CELLTYPE emptycell; + int i; + int ntrees; + int density; + cell_t *c; + //object_t *o; + + // what kind of cells will 'empty' ones be? + emptycell = getemptycelltype(map->habitat); + // fill entire maze with walls + for (y = 0; y < map->h; y++) { + for (x = 0; x < map->w; x++) { + c = addcell(map, x, y); + setcelltype(c, emptycell); + } + } + + + // determine density + density = rnd(40,70); + // add a plant to density percent of cells + ntrees = (int)(((float)density/100.0) * (float)(map->w*map->h)); + for (i = 0; i < ntrees; i++) { + c = getrandomcell(map); + while (c->lf) { + c = getrandomcell(map); + } + addob(c->obpile, "tree"); + } + + // add monsters +} + +/* + seed = random number seed + turnpct = percentage change of a corridor turning + sparseness = how many times to chop off dead ends + looppct = percentage change of turning dead-end into loop + maxrooms = max # of rooms +*/ +void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir) { + lifeform_t *lf; + char buf[BUFLEN]; + int i,x,y; + // determine habitat? + if (habitat == AUTO) { + if (depth > 0) { + habitat = H_DUNGEON; + } else if (depth == 0) { + habitat = H_FOREST; + } + } + + map->beingcreated = B_TRUE; + + map->depth = depth; + map->region = region; + + sprintf(buf, "Region %d (#%d)",map->region, map->id); + map->name = strdup(buf); + map->habitat = habitat; + + // link to other maps if required. + // default to no links + for (i = D_UP; i <= D_DOWN; i++) { + map->nextmap[i] = -1; + } + + // look for adjacent maps in this region + for (i = depth-1; i <= depth+1; i += 2) { + map_t *othermap; + othermap = findregionmap(map->region, i); + if (othermap) { + if (i == (depth-1)) { + map->nextmap[D_UP] = othermap->id; + } else { + map->nextmap[D_DOWN] = othermap->id; + } + } + } + + // did we come from a previous map? + if (parentmap) { + parentmap->nextmap[exitdir] = map->id; + for (i = 0; i < MAXDIR_ORTH; i++) { + if (parentmap && (i == diropposite(exitdir)) ) { + map->nextmap[i] = parentmap->id; + } else { + map->nextmap[i] = -1; + } + } + } + + map->w = MAX_MAPW; + map->h = MAX_MAPH; + + // map depth? + map->depth = depth; + + // rememebr seed + map->seed = rand() % 65535; + srand(map->seed); + + // build it... + if (habitat == H_DUNGEON) { + createdungeon(map, depth, parentmap, exitdir); + } else if (habitat == H_FOREST) { + createforest(map, depth, parentmap, exitdir); + } // add home objects for (lf = map->lf ; lf ; lf = lf->next) { addhomeobs(lf); } + // if this is the first world map, add stairs to the dungeon + if (region == RG_WORLDMAP) { + map_t *m; + int found = B_FALSE; + + for (m = firstmap ; m ; m = m->next) { + if ((m != map) && (m->region == 0)) { + found = B_TRUE; + break; + } + } + if (!found) { + map_t *firstdungeon; + + // link to first dungeon map + firstdungeon = findregionmap(RG_FIRSTDUNGEON, 1); + assert(firstdungeon); + map->nextmap[D_DOWN] = firstdungeon->id; + + // add stairs going down to dungeon + for (i = 0; i < 3; i++) { + cell_t *c; + object_t *o; + c = NULL; + while (!c || !cellwalkable(NULL, c, NULL)) { + c = getrandomcell(map); + } + o = addob(c->obpile, "staircase going down"); + linkstairs(o); + } + } + } + + // join up any unlinked staircases + for (y = 0; y < map->h; y++) { + for (x = 0; x < map->w; x++) { + cell_t *c; + object_t *o; + c = getcellat(map, x, y); + o = hasobwithflag(c->obpile, F_CLIMBABLE); + if (o && !getstairdestination(o)) { + linkstairs(o); + } + } + } + + // add random objects and monsters + for (y = 0; y < map->h; y++) { + for (x = 0; x < map->w; x++) { + cell_t *c; + c = getcellat(map, x, y); + if (c && isempty(c)) { + if (rnd(1,100) <= getthingchance(map->habitat)) { + addrandomthing(c, getobchance(map->habitat)); + } + } + } + } + map->beingcreated = B_FALSE; } @@ -1671,6 +1646,14 @@ cell_t *findobinmap(map_t *m, enum OBCLASS oid) { return NULL; } +map_t *findregionmap(int region, int depth) { + map_t *m; + for (m = firstmap ; m ; m = m->next) { + if ((m->depth == depth) && (m->region == region)) return m; + } + return NULL; +} + void forgetcells(map_t *map, int amt) { int amtleft; //int totcells; @@ -1844,11 +1827,24 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) { return dir; } -// chance of each empty cell in a map has of getting an object +// chance of a random thing being an object (as opposed to a monster) int getobchance(int habitat) { + switch (habitat) { + case H_DUNGEON: + return 50; + case H_FOREST: + return 75; + } + // default of no objects + return 0; +} +// chance of each empty cell in a map has of getting an object/monster +int getthingchance(int habitat) { switch (habitat) { case H_DUNGEON: return 3; + case H_FOREST: + return 5; } // default of no objects return 0; @@ -2322,6 +2318,13 @@ int isonmap(map_t *map, int x, int y) { return B_TRUE; } +int isoutdoors(map_t *m) { + if (m->region == RG_WORLDMAP) { + return B_TRUE; + } + return B_FALSE; +} + int iswallindir(cell_t *cell, int dir) { cell_t *newcell; newcell = getcellindir(cell, dir); @@ -2336,10 +2339,11 @@ int iswallindir(cell_t *cell, int dir) { return B_FALSE; } -// link the staircase 'o' to a free one in map 'othermap' +// link the staircase 'o' to a free one in adjacent maps. // returns TRUE if it failed because othermap doesn't exist. int linkstairs(object_t *o) { map_t *othermap; + int othermapid; object_t *o2; map_t *stairmap; cell_t *staircell; @@ -2364,11 +2368,17 @@ int linkstairs(object_t *o) { } else { dblog("ERROR: stair object has no f_climbable!"); msg("ERROR: stair object has no f_climbable!"); - exit(1); + assert(0 == 1); } - othermap = findmapofdepth(stairmap->depth + dir); + //othermap = findmapofdepth(stairmap->depth + dir); + othermapid = stairmap->nextmap[f->val[0]]; + othermap = findmap(othermapid); + if (!othermap) { + // find next map based on depth... + othermap = findregionmap(stairmap->region, stairmap->depth+dir); + } if (othermap) { // find an empty staircase in other map for (n = 0; n < othermap->w*othermap->h; n++) { @@ -2388,9 +2398,10 @@ int linkstairs(object_t *o) { } } if (!found) { - dblog("ERROR - stairs link to existing map #%d, but it has no free stairs.",othermap->id); - msg("ERROR - stairs link to existing map #%d, but it has no free stairs.",othermap->id); - exit(1); + dblog("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id); + msg("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id); + more(); + assert(0 == 1); } } else { return B_TRUE; diff --git a/map.h b/map.h index b947304..e9a7356 100644 --- a/map.h +++ b/map.h @@ -19,7 +19,9 @@ int calcroompos(map_t *map, int w, int h, int *bx, int *by); int countadjcellsoftype(cell_t *cell, int id); int countadjcellswithflag(cell_t *cell, enum FLAG fid); int countcellexits(cell_t *cell); -void createmap(map_t *map, int depth, int habitat); +void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir); +void createforest(map_t *map, int depth, map_t *parentmap, int exitdir); +void createmap(map_t *map, int dungeonid, int depth, int habitat, map_t *parentmap, int exitdir); void createroom(map_t *map, int minx, int miny, int w, int h, int roomid); int dirtox(int dt, int dir); int dirtoy(int dt, int dir); @@ -31,10 +33,12 @@ map_t *findmap(int mid); map_t *findmapofdepth(int depth); object_t *findobidinmap(map_t *m, long id); cell_t *findobinmap(map_t *m, enum OBCLASS oid); +map_t *findregionmap(int region, int depth); void forgetcells(map_t *map, int amt); cell_t *getcellindir(cell_t *cell, int dir); int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved); int getobchance(int habitat); +int getthingchance(int habitat); cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand); cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum OBTYPE *dontwantob); cell_t *getrandomcell(map_t *map); @@ -58,6 +62,7 @@ int islit(cell_t *c); int isloopdirok(cell_t *cell, int dir); int isnewcellok(cell_t *cell, char *err); int isonmap(map_t *map, int x, int y); +int isoutdoors(map_t *m); int iswallindir(cell_t *cell, int dir); int linkstairs(object_t *o); void makedoor(cell_t *cell); diff --git a/move.c b/move.c index b097cdc..fc859d6 100644 --- a/move.c +++ b/move.c @@ -24,6 +24,8 @@ extern enum GAMEMODE gamemode; extern enum ERROR reason; extern void *rdata; +extern WINDOW *gamewin; + int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error) { if (isplayer(lf)) { if (canmove(lf, dir, error)) { @@ -59,6 +61,10 @@ int canmove(lifeform_t *lf, int dir, enum ERROR *error) { } cell = getcellindir(lf->cell, dir); + if (!cell) { + if (error) *error = E_OFFMAP; + return B_FALSE; + } f = lfhasflag(lf, F_GRABBEDBY); if (f) { @@ -684,6 +690,10 @@ int movelf(lifeform_t *lf, cell_t *newcell) { statdirty = B_TRUE; } relinklf(lf, newcell->map); + if (isplayer(lf)) { + // clear map to force redraw. + wclear(gamewin); + } } // update lifeform @@ -1741,7 +1751,11 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) { } else { // somethign random is in the way if (isplayer(lf) && inway) { char obname[BUFLEN]; - getobname(inway, obname, 1); + if (haslos(lf, cell)) { + getobname(inway, obname, 1); + } else { + strcpy(obname, "something"); + } msg("There is %s in your way.",obname); } } diff --git a/nexus.c b/nexus.c index f1c4bba..1f01144 100644 --- a/nexus.c +++ b/nexus.c @@ -115,7 +115,7 @@ int main(int argc, char **argv) { if (!firstmap) { newworld = B_TRUE; addmap(); - createmap(firstmap, 1, H_DUNGEON); + createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE); } if (!knowledge) { @@ -706,6 +706,8 @@ int init(void) { addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE); addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE); addcelltype(CT_ROOM, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE); + addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT); + addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE); gamemode = GM_VALIDATION; if (validateobs()) { diff --git a/objects.c b/objects.c index 59c78c3..ed1ea41 100644 --- a/objects.c +++ b/objects.c @@ -68,6 +68,7 @@ enum OBCLASS sortorder[] = { OC_TOOLS, OC_BOOK, OC_ROCK, + OC_FLORA, OC_DFEATURE, OC_MISC, // omitting OC_SPELL and OC_JUMP because it shouldn't ever be displayed @@ -2077,6 +2078,7 @@ objecttype_t *findotn(char *name) { modname = strrep(modname, "chunks ", "chunk ", NULL); modname = strrep(modname, "flasks ", "flask ", NULL); modname = strrep(modname, "gems ", "gem ", NULL); + modname = strrep(modname, "leaves ", "leaf ", NULL); modname = strrep(modname, "loaves ", "load ", NULL); modname = strrep(modname, "lumps ", "lump ", NULL); modname = strrep(modname, "pieces ", "piece ", NULL); @@ -4351,6 +4353,7 @@ void initobjects(void) { addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy"); addflag(lastmaterial->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); addmaterial(MT_SILK, "silk", 1); + addflag(lastmaterial->flags, F_FLAMMABLE, 6, NA, NA, NULL); addflag(lastmaterial->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); // doesn't catch on fire, but IS vulnerable to it addflag(lastmaterial->flags, F_DTVULN, DT_ACID, NA, NA, NULL); addmaterial(MT_FLESH, "flesh", 2); @@ -4441,7 +4444,9 @@ void initobjects(void) { addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); - addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks.", '*', C_GREY); + addoc(OC_FLORA, "Plants", "All kinds of plants and foliage", ',', C_GREEN); + addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_GREY); addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY); addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -4683,22 +4688,70 @@ void initobjects(void) { addflag(lastot->flags, F_HOLDCONFER, F_DETECTMAGIC, B_TRUE, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); + // flora + addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); + addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, ","); + addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); + addot(OT_LEAF, "leaf", "A fallen leaf from a tree.", MT_PLANT, 0.01, OC_FLORA); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); + addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ","); + addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); + addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 40, OC_FLORA); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); + addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); + addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); + addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); + addot(OT_STUMP, "stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); + addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "'"); + addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); + addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); + addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); + addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "#"); + addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL); + addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_BLOCKSTHROW, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); + addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); + addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); // food addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 8, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, ""); addot(OT_NUT, "peanut", "A species in the legume family.", MT_FOOD, 0.1, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 12, NA, ""); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, ""); addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 80, NA, NULL); addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%"); @@ -4710,9 +4763,11 @@ void initobjects(void) { addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL); addot(OT_MUSHROOM, "mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addot(OT_BREADSTALE, "loaf of stale bread", "A small loaf of old, stale bread.", MT_FOOD, 0.5, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); @@ -4737,6 +4792,7 @@ void initobjects(void) { addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 65, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_EXTRALUCK, 1, NA, NULL); addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); @@ -6456,6 +6512,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ","); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL); addflag(lastot->flags, F_REDUCEMOVEMENT, 2, NA, NA, NULL); @@ -6468,6 +6525,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice"); addflag(lastot->flags, F_DTCONVERT, DT_FIRE, NA, NA, "puff of steam"); @@ -6481,6 +6539,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice"); addflag(lastot->flags, F_DTCONVERT, DT_FIRE, NA, NA, "cloud of steam"); @@ -6565,6 +6624,7 @@ void initobjects(void) { addot(OT_BONE, "bone", "A bone from an unknown creature.", MT_BONE, 0.1, OC_MISC); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); @@ -6738,6 +6798,7 @@ void initobjects(void) { addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "^"); addflag(lastot->flags, F_RESTRICTMOVEMENT, 30, B_FALSE, NA, NULL);// the value here will be filled in by the spell. @@ -6752,6 +6813,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 86, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 88, NA, NULL); addflag(lastot->flags, F_RESTRICTMOVEMENT, 25, B_TRUE, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -6925,7 +6987,7 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); + addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); @@ -7592,6 +7654,7 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addot(OT_STICK, "stick", "A sturdy wooden stick.", MT_WOOD, 0.5, OC_WEAPON); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -9441,17 +9504,25 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } } else if (o->type->id == OT_POCKETWATCH) { if (isplayer(lf)) { - // TODO: if above ground, use wantpm (ie. can see the sun) - gettimetextfuzzy(buf, B_FALSE); - msg("It is currently %s.",buf); + if (haslos(lf, lf->cell)) { + // if above ground, use wantpm (ie. can see the sun) + gettimetextfuzzy(buf, isoutdoors(lf->cell->map) ? B_TRUE : B_FALSE); + msg("It is currently %s.",buf); + } else { + msg("You cannot see!"); + } } else if (cansee(player, lf)) { getlfname(lf, buf); msg("%s looks at %s.",buf, obname); } } else if (o->type->id == OT_DIGITALWATCH) { if (isplayer(lf)) { - gettimetext(buf); - msg("It is currently %s.",buf); + if (haslos(lf, lf->cell)) { + gettimetext(buf); + msg("It is currently %s.",buf); + } else { + msg("You cannot see!"); + } } else if (cansee(player, lf)) { getlfname(lf, buf); capitalise(buf); @@ -11856,13 +11927,20 @@ void timeeffectsob(object_t *o) { // does object's material change cell type? if (o->material->id == MT_FIRE) { if (hasflag(location->type->material->flags, F_FLAMMABLE)) { - // burn! - // TODO: change to celltype of nearby floor - // OR to default map empty type. - if (haslos(player, location)) { - msg("The %s burns!", location->type->name); + int changed = B_FALSE; + // burn by changing celltype... + switch (location->type->id) { + case CT_GRASS: + setcelltype(location, CT_DIRT); + break; + default: + break; } - setcelltype(location, CT_CORRIDOR); + if (changed && haslos(player, location)) { + msg("The %s burns!", location->type->name); + needredraw = B_TRUE; + } + //setcelltype(location, CT_CORRIDOR); addob(location->obpile, "pile of ash"); } } diff --git a/spell.c b/spell.c index 99fb1d4..582dba5 100644 --- a/spell.c +++ b/spell.c @@ -201,7 +201,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - o = doaskobject(user->pack, "What will you cook?", NULL, AO_EDIBLE, F_CORPSEOF); + o = doaskobject(user->pack, "What will you cook?", NULL, B_FALSE, B_FALSE, AO_EDIBLE, F_CORPSEOF); if (!o) { msg("Cancelled."); return B_TRUE; @@ -1591,7 +1591,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (seenbyplayer) *seenbyplayer = B_TRUE; } - losehp(target, rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); + // outdoors? + if (isoutdoors(target->cell->map)) { + losehp(target, rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); + } else { + losehp(target, rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); + } } else { failed = B_TRUE; } @@ -3932,7 +3937,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (!newmap) { // create new map newmap = addmap(); - createmap(newmap, newdepth, caster->cell->map->habitat); + createmap(newmap, newdepth, caster->cell->map->region, AUTO, NULL, D_NONE); } @@ -4191,7 +4196,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ getlfname(targ[i],targname); msg("%s %s struck by a bolt of lightning!",targname, is(targ[i])); } - losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); + if (isoutdoors(target->cell->map)) { + losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); + } else { + losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); + } } if (seen) { diff --git a/text.c b/text.c index 57d7266..96e3af0 100644 --- a/text.c +++ b/text.c @@ -328,6 +328,8 @@ char *makeplural(char *text) { if (rv) return newtext; newtext = strrep(newtext, "gem ", "gems ", &rv); if (rv) return newtext; + newtext = strrep(newtext, "leaf ", "leaves ", &rv); + if (rv) return newtext; newtext = strrep(newtext, "loaf ", "loaves ", &rv); if (rv) return newtext; newtext = strrep(newtext, "lump ", "lumps ", &rv);