- [+] 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
This commit is contained in:
Rob Pearce 2011-05-16 02:03:25 +00:00
parent 858a264b07
commit 300f1637b3
14 changed files with 578 additions and 350 deletions

27
defs.h
View File

@ -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;

4
doc/regions Normal file
View File

@ -0,0 +1,4 @@
special region ids:
0 = main world
1 = first dungeon

137
io.c
View File

@ -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");
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);
}
cell = getcellat(map, x, y);
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);

6
io.h
View File

@ -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);

116
lf.c
View File

@ -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)) {
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;
}

1
lf.h
View File

@ -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);

12
log.txt
View File

@ -4,15 +4,3 @@
====== NEW LOGFILE ====
givejob() starting.
x
x
x
x
x
x
x
x
x
x
x
x

461
map.c
View File

@ -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,9 +602,20 @@ void calclight(map_t *map) {
object_t *o;
// lit based on depth
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?
// TODO: has dark producing object?
@ -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;
@ -783,29 +792,6 @@ void createmap(map_t *map, int depth, int habitat) {
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;

7
map.h
View File

@ -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);

14
move.c
View File

@ -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];
if (haslos(lf, cell)) {
getobname(inway, obname, 1);
} else {
strcpy(obname, "something");
}
msg("There is %s in your way.",obname);
}
}

View File

@ -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()) {

View File

@ -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);
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)) {
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");
}
}

13
spell.c
View File

@ -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;
}
// 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,8 +4196,12 @@ 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]));
}
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) {
if (seenbyplayer) *seenbyplayer = B_TRUE;

2
text.c
View File

@ -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);