VAULTS
* [+] vaiultlegend_t * [+] vaultdef_t - [+] implement addlegend() - [+] implement addvault() - [+] function to read in a vault from a data file - [+] vs_noid - [+] vs_loadingmap - [+] vs_loadinglegend - [+] vs_loadingflags - [+] vs_loading - [+] load all vaultdefs in at start - [+] change createroom to calculate the posistion - [+] for each room, give a %chance of haivng a vault. (based on habitat?) * [+] createvault(map_t, roomid?, char *vaultid) - [+] mapdata with letters * [+] MSG up vault errors on load. - [+] Select job _before_ generating first map. * [+] make addob() handle door flags: * [+] addob() improvements * [+] wish bug: first object goes in pack, rest on ground. - [+] genericise getroomedge() - [+] finish 'autodoors' (at the end, add doors if none already done) - [+] at(x,y):type:what:pct -> f_vaultob / vaultlf / vaultcell, v0=x, v1=y, v2=pct text=what * [+] "what" can be: * [+] scatter:y1:x2:y2:what:chance%:howmany * [+] some way to make the @map bit just say 'random room at least 2x4' - [+] make "scatter" able to take range instead of count. - [+] make "scatter"able to take x% instead of count. - [+] upsidedown chars no longer working with winch() - [+] ensure no DUPE ids - [+] make legend take percentages (optional) - [+] make "at" take negative values... OPTIONS - [+] autodoors - put doors on edges like with normal dungeon rooms. * [+] autopop - fill with obs/monsters like normal rooms VAULT FILES - [+] flooded room - [+] labyrinth - [+] vault (lots of money, locked secret doors) - [+] monster zoos (money and monsters) - [+] diningroom - lots of tables and chairs - [+] circleroom - [+] pillared room - [+] glass pillared room - [+] cockatrice lair (statues) - [+] traproom - need "random trap". need OC_TRAP. - [+] BUG: piranhas walking out of water sometimes....... - [+] add startatt x-y rather than just a bracket. use text field. - [+] make teleport auto move away form lfs - [+] add minotaur
This commit is contained in:
parent
af0d8f244d
commit
11c03d71cf
4
Makefile
4
Makefile
|
@ -1,2 +1,2 @@
|
||||||
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h flag.c flag.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h
|
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h flag.c flag.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h vault.c vault.h
|
||||||
gcc -Wall -g -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c -lncurses
|
gcc -Wall -g -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c vault.c vault.h -lncurses
|
||||||
|
|
104
defs.h
104
defs.h
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __DEFS_H
|
#ifndef __DEFS_H
|
||||||
#define __DEFS_H
|
#define __DEFS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MACROS
|
// MACROS
|
||||||
#define MAXOF(a,b) (a > b ? a : b)
|
#define MAXOF(a,b) (a > b ? a : b)
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ enum SKILLLEVEL {
|
||||||
// save/load
|
// save/load
|
||||||
#define MAPDIR "data/maps"
|
#define MAPDIR "data/maps"
|
||||||
#define SAVEDIR "data/save"
|
#define SAVEDIR "data/save"
|
||||||
|
#define VAULTDIR "vaults"
|
||||||
#define DUMMYCELLTYPE 0xabcd
|
#define DUMMYCELLTYPE 0xabcd
|
||||||
|
|
||||||
// SPECIAL NUMBERS/CONSTANTS
|
// SPECIAL NUMBERS/CONSTANTS
|
||||||
|
@ -110,10 +113,10 @@ enum SKILLLEVEL {
|
||||||
#define NA (-9874)
|
#define NA (-9874)
|
||||||
#define NOBODY (-1)
|
#define NOBODY (-1)
|
||||||
#define ALLCONFERRED (-9873)
|
#define ALLCONFERRED (-9873)
|
||||||
|
#define PCT (65432) // must be POSITIVE
|
||||||
|
|
||||||
#define AUTO (-7654)
|
#define AUTO (-7654)
|
||||||
|
|
||||||
|
|
||||||
enum GAMEMODE {
|
enum GAMEMODE {
|
||||||
GM_FIRST,
|
GM_FIRST,
|
||||||
GM_INIT,
|
GM_INIT,
|
||||||
|
@ -407,8 +410,11 @@ enum LOFTYPE {
|
||||||
|
|
||||||
// Cell types
|
// Cell types
|
||||||
enum CELLTYPE {
|
enum CELLTYPE {
|
||||||
|
CT_NONE = 0,
|
||||||
// walls
|
// walls
|
||||||
CT_WALL,
|
CT_WALL,
|
||||||
|
CT_WALLGLASS,
|
||||||
|
CT_WALLMETAL,
|
||||||
CT_ROOMWALL,
|
CT_ROOMWALL,
|
||||||
// empty
|
// empty
|
||||||
CT_CORRIDOR,
|
CT_CORRIDOR,
|
||||||
|
@ -419,12 +425,6 @@ enum CELLTYPE {
|
||||||
CT_ROOM,
|
CT_ROOM,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SPECIALROOMTYPE {
|
|
||||||
RT_NONE = 0,
|
|
||||||
RT_FLOODED,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum SPELLSCHOOL {
|
enum SPELLSCHOOL {
|
||||||
SS_NONE,
|
SS_NONE,
|
||||||
SS_DIVINE,
|
SS_DIVINE,
|
||||||
|
@ -573,17 +573,24 @@ enum HABITAT {
|
||||||
#define RARITYVARIANCELF (5)
|
#define RARITYVARIANCELF (5)
|
||||||
#define RARITYVARIANCEOB (10)
|
#define RARITYVARIANCEOB (10)
|
||||||
|
|
||||||
/*
|
|
||||||
enum RARITY {
|
enum RARITY {
|
||||||
RR_UNIQUE = 7,
|
RR_UNIQUE = 6,
|
||||||
RR_NEVER = 6,
|
RR_NEVER = 5,
|
||||||
RR_VERYRARE = 5,
|
RR_VERYRARE = 4,
|
||||||
RR_RARE = 4,
|
RR_RARE = 3,
|
||||||
RR_UNCOMMON = 3,
|
RR_UNCOMMON = 2,
|
||||||
RR_COMMON = 2,
|
RR_COMMON = 1,
|
||||||
RR_FREQUENT = 1,
|
RR_NONE = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// for genericising weapons, etc
|
||||||
|
enum GOODNESS {
|
||||||
|
G_NA = 0,
|
||||||
|
G_AVERAGE,
|
||||||
|
G_GOOD,
|
||||||
|
G_GREAT,
|
||||||
|
G_EXCELLENT,
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
enum RACECLASS {
|
enum RACECLASS {
|
||||||
RC_ANY, // not actually ever defined
|
RC_ANY, // not actually ever defined
|
||||||
|
@ -627,6 +634,7 @@ enum RACE {
|
||||||
R_KOBOLD,
|
R_KOBOLD,
|
||||||
R_LIZARDMAN,
|
R_LIZARDMAN,
|
||||||
R_LURKINGHORROR,
|
R_LURKINGHORROR,
|
||||||
|
R_MINOTAUR,
|
||||||
R_OGRE,
|
R_OGRE,
|
||||||
R_OGRESAVAGE,
|
R_OGRESAVAGE,
|
||||||
R_OGREWARHULK,
|
R_OGREWARHULK,
|
||||||
|
@ -1735,7 +1743,7 @@ enum FLAG {
|
||||||
F_HASHIDDENNAME, // whether this object class has a hidden name
|
F_HASHIDDENNAME, // whether this object class has a hidden name
|
||||||
F_IDENTIFIED, // whether this object is fully identified
|
F_IDENTIFIED, // whether this object is fully identified
|
||||||
// bad flags
|
// bad flags
|
||||||
F_DEEPWATER, // v0 = depth.oooooooooooo
|
F_DEEPWATER, // v0 = depth.
|
||||||
F_WALKDAM, // val0 = damtype, text = dam per sec
|
F_WALKDAM, // val0 = damtype, text = dam per sec
|
||||||
F_WALKDAMBP, // v0 = bodypart, v1 = damtype, text = dam per sec
|
F_WALKDAMBP, // v0 = bodypart, v1 = damtype, text = dam per sec
|
||||||
// if v2 == FALLTHRU, damage falls through to lf if
|
// if v2 == FALLTHRU, damage falls through to lf if
|
||||||
|
@ -1805,6 +1813,10 @@ enum FLAG {
|
||||||
// calculation
|
// calculation
|
||||||
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
|
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
|
||||||
F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS)
|
F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS)
|
||||||
|
// if text is set, it overrides val0.
|
||||||
|
// text can be:
|
||||||
|
// x (single number)
|
||||||
|
// x-y (range)
|
||||||
F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will
|
F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will
|
||||||
// start off hidden
|
// start off hidden
|
||||||
F_CORPSETYPE, // text field specifies what corpse obtype to leave
|
F_CORPSETYPE, // text field specifies what corpse obtype to leave
|
||||||
|
@ -2088,7 +2100,20 @@ enum FLAG {
|
||||||
F_LEVFLAG, // at level v0, this job gains flagid v1, flagval0=v2,
|
F_LEVFLAG, // at level v0, this job gains flagid v1, flagval0=v2,
|
||||||
// flagtext = text
|
// flagtext = text
|
||||||
|
|
||||||
//
|
// vault flags
|
||||||
|
F_AUTODOORS, // automatically create at least one door
|
||||||
|
F_AUTOPOPULATE, // fill this vault with obs/mons/pillars like normal rooms
|
||||||
|
F_VAULTATOB, // v0/1=x/y, v1=pctchance, text=obname
|
||||||
|
F_VAULTATLF, // v0/1=x/y, v1=pctchance, text=lfname
|
||||||
|
F_VAULTATCELL, // v0/1=x/y, v1=pctchance, text=cellname
|
||||||
|
F_VAULTBOX, // v0=thingtype, v1=pctchance, v2=fill?, text=x1,y1,x2,y2,thingname
|
||||||
|
F_VAULTSCATTER, // v0=thingtype, v1=pctchance
|
||||||
|
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
||||||
|
// if maxcount is PCT, mincount is a percentage
|
||||||
|
// of the total space.
|
||||||
|
F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is
|
||||||
|
// v0/1 can be NA.
|
||||||
|
// just a normal random room
|
||||||
F_NULL = -1
|
F_NULL = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2325,6 +2350,46 @@ typedef struct map_s {
|
||||||
struct map_s *next, *prev;
|
struct map_s *next, *prev;
|
||||||
} map_t; //////////////// remember to modify save/load for new props!!
|
} map_t; //////////////// remember to modify save/load for new props!!
|
||||||
|
|
||||||
|
#define MAXVAULTARGS 10
|
||||||
|
|
||||||
|
enum VAULTSTATE {
|
||||||
|
VS_ALLOCATED,
|
||||||
|
VS_NOID,
|
||||||
|
VS_LOADING,
|
||||||
|
VS_LOADINGMAP,
|
||||||
|
VS_LOADINGLEGEND,
|
||||||
|
VS_LOADINGFLAGS,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum VAULTTHING {
|
||||||
|
VT_NONE,
|
||||||
|
VT_OB,
|
||||||
|
VT_LF,
|
||||||
|
VT_CELL,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct vlegend_s {
|
||||||
|
char ch;
|
||||||
|
enum VAULTTHING tt;
|
||||||
|
char *what;
|
||||||
|
int pct;
|
||||||
|
struct vault_s *vault;
|
||||||
|
struct vlegend_s *next, *prev;
|
||||||
|
} vlegend_t;
|
||||||
|
|
||||||
|
typedef struct vault_s {
|
||||||
|
char *filename;
|
||||||
|
char *id;
|
||||||
|
int valid;
|
||||||
|
int state;
|
||||||
|
char map[MAX_MAPW*MAX_MAPH];
|
||||||
|
int mlen;
|
||||||
|
int w,h;
|
||||||
|
struct vlegend_s *legend, *lastlegend;
|
||||||
|
struct vault_s *next, *prev;
|
||||||
|
struct flagpile_s *flags;
|
||||||
|
} vault_t;
|
||||||
|
|
||||||
typedef struct glyph_s {
|
typedef struct glyph_s {
|
||||||
int ch;
|
int ch;
|
||||||
int colour;
|
int colour;
|
||||||
|
@ -2513,10 +2578,13 @@ typedef struct job_s {
|
||||||
struct job_s *next, *prev;
|
struct job_s *next, *prev;
|
||||||
} job_t;
|
} job_t;
|
||||||
|
|
||||||
|
#define MAXOCNOUNS 5
|
||||||
typedef struct objectclass_s {
|
typedef struct objectclass_s {
|
||||||
enum OBCLASS id;
|
enum OBCLASS id;
|
||||||
char *name;
|
char *name;
|
||||||
char *desc;
|
char *desc;
|
||||||
|
char *noun[MAXOCNOUNS];
|
||||||
|
int nnouns;
|
||||||
glyph_t glyph;
|
glyph_t glyph;
|
||||||
struct flagpile_s *flags;
|
struct flagpile_s *flags;
|
||||||
struct objectclass_s *next, *prev;
|
struct objectclass_s *next, *prev;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
General format:
|
||||||
|
@id:textual_name
|
||||||
|
@map
|
||||||
|
EITHER
|
||||||
|
map definition
|
||||||
|
OR
|
||||||
|
random(minw,minh)
|
||||||
|
@end
|
||||||
|
@legend
|
||||||
|
k:mon:kobold
|
||||||
|
s:ob:50:short sword
|
||||||
|
#:cell:stone wall
|
||||||
|
@end
|
||||||
|
@flags
|
||||||
|
...
|
||||||
|
@end
|
||||||
|
|
||||||
|
Legend is:
|
||||||
|
c:type:what[:pct]
|
||||||
|
|
||||||
|
c = any letter
|
||||||
|
type = ob, mon or cell
|
||||||
|
pct = optional pct chance of appearing
|
||||||
|
what = text of what this letter represents
|
||||||
|
|
||||||
|
Flags can be:
|
||||||
|
at(x,y) type:what[:pct] // put what at position x,y
|
||||||
|
'type' can be: ob, mon, cell
|
||||||
|
coords can be negative ("count back from right/bottom")
|
||||||
|
|
||||||
|
box(x,y,x2,y2) type:what[:pct] // outline box with what
|
||||||
|
fill(x,y,x2,y2) type:what[:pct] // filled box with what
|
||||||
|
coords can be negative ("count back from right/bottom")
|
||||||
|
|
||||||
|
scatter(x,y,x2,y2) type:what:howmany[:pct] // scatter what within region
|
||||||
|
howmany can be:
|
||||||
|
- a number (x)
|
||||||
|
- a range (x-y)
|
||||||
|
- a pct of the total region cells (x%)
|
||||||
|
coords can be negative ("count back from right/bottom")
|
||||||
|
|
||||||
|
|
||||||
|
autodoors // automatically add at least one door to the edges of
|
||||||
|
// this room.
|
||||||
|
|
||||||
|
autopop // automatically add obs/mons/pillars to this room
|
||||||
|
|
||||||
|
NOTES:
|
||||||
|
when adding lfs/objects, "random" creates a random one.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
8
io.c
8
io.c
|
@ -5038,8 +5038,12 @@ void drawglyph(glyph_t *g, int x, int y) {
|
||||||
col = g->colour;
|
col = g->colour;
|
||||||
}
|
}
|
||||||
setcol(gamewin, col);
|
setcol(gamewin, col);
|
||||||
//mvwprintw(gamewin, y, x, "%lc", g->ch);
|
if (g->ch > 255) {
|
||||||
mvwaddch(gamewin, y, x, g->ch);
|
// note: much slower
|
||||||
|
mvwprintw(gamewin, y, x, "%lc", g->ch);
|
||||||
|
} else {
|
||||||
|
mvwaddch(gamewin, y, x, g->ch);
|
||||||
|
}
|
||||||
unsetcol(gamewin, col);
|
unsetcol(gamewin, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
lf.c
57
lf.c
|
@ -6875,7 +6875,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
|
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
|
||||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||||
|
|
||||||
addrace(R_GIANTHILL, "hill giant", 160, 'H', C_BROWN, MT_FLESH, RC_HUMANOID);
|
addrace(R_GIANTHILL, "hill giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID);
|
||||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
|
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
|
||||||
|
@ -7348,6 +7348,34 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
addrace(R_MINOTAUR, "minotaur", 130, 'H', C_BROWN, MT_FLESH, RC_HUMANOID);
|
||||||
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 62, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HATESRACE, R_GNOLL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HITDICE, 6, 3, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_IQ, NA, NA, "5-7");
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_STR, ST_TITANIC, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4");
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "+2 heavy flail");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "greataxe");
|
||||||
|
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HASSKILL, SK_TRACKING, PR_EXPERT, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;");
|
||||||
|
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roar");
|
||||||
|
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
|
|
||||||
addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID);
|
addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID);
|
||||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||||
|
@ -11391,7 +11419,27 @@ int rollstat(lifeform_t *lf, enum ATTRIB attr) {
|
||||||
|
|
||||||
f = hasflagval(lf->flags, F_STARTATT, attr, NA, NA, NULL);
|
f = hasflagval(lf->flags, F_STARTATT, attr, NA, NA, NULL);
|
||||||
if (f) {
|
if (f) {
|
||||||
bracket = f->val[1];
|
if (strlen(f->text)) {
|
||||||
|
int val;
|
||||||
|
if (strchr(f->text, '-')) {
|
||||||
|
int min,max;
|
||||||
|
char *p;
|
||||||
|
char buf[BUFLENSMALL];
|
||||||
|
// text is a range
|
||||||
|
p = readuntil(buf, f->text, '-');
|
||||||
|
min = atoi(buf);
|
||||||
|
p = readuntil(buf, p, '-');
|
||||||
|
max = atoi(buf);
|
||||||
|
val = rnd(min,max);
|
||||||
|
} else {
|
||||||
|
val = atoi(f->text);
|
||||||
|
}
|
||||||
|
lf->att[attr] = val;
|
||||||
|
return B_FALSE;
|
||||||
|
} else {
|
||||||
|
bracket = f->val[1];
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
switch (attr) {
|
switch (attr) {
|
||||||
case A_STR:
|
case A_STR:
|
||||||
|
@ -13686,6 +13734,11 @@ int validateraces(void) {
|
||||||
printf("ERROR in race '%s' - F_HITCONFER, but no HITCONFERVALS defined.\n", r->name);
|
printf("ERROR in race '%s' - F_HITCONFER, but no HITCONFERVALS defined.\n", r->name);
|
||||||
goterror = B_TRUE;
|
goterror = B_TRUE;
|
||||||
}
|
}
|
||||||
|
} else if (f->id == F_STARTATT) {
|
||||||
|
if (strlen(f->text) && (f->val[1] != NA)) {
|
||||||
|
printf("ERROR in race '%s' - F_STARTATT has both text range and val1.", r->name);
|
||||||
|
goterror = B_TRUE;
|
||||||
|
}
|
||||||
} else if (f->id == F_NOISETEXT) {
|
} else if (f->id == F_NOISETEXT) {
|
||||||
if (f->val[0] == N_FLY) {
|
if (f->val[0] == N_FLY) {
|
||||||
if (!hasflag(r->flags, F_FLYING) && !hasflag(r->flags, F_LEVITATING)) {
|
if (!hasflag(r->flags, F_FLYING) && !hasflag(r->flags, F_LEVITATING)) {
|
||||||
|
|
725
map.c
725
map.c
|
@ -12,6 +12,7 @@
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
#include "vault.h"
|
||||||
|
|
||||||
extern map_t *firstmap,*lastmap;
|
extern map_t *firstmap,*lastmap;
|
||||||
extern celltype_t *firstcelltype, *lastcelltype;
|
extern celltype_t *firstcelltype, *lastcelltype;
|
||||||
|
@ -169,12 +170,6 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
||||||
|
|
||||||
if (autogen) {
|
if (autogen) {
|
||||||
// sometimes start off asleep in new maps
|
// sometimes start off asleep in new maps
|
||||||
if (!lfhasflag(lf, F_DEAF) && cansleep(lf)) {
|
|
||||||
// TODO: base this on the time, and whether monster is nocturnal
|
|
||||||
if (rnd(1,2) == 1) {
|
|
||||||
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f = lfhasflag(lf, F_STARTHIDDENPCT);
|
f = lfhasflag(lf, F_STARTHIDDENPCT);
|
||||||
if (f) {
|
if (f) {
|
||||||
if (rnd(1,100) <= f->val[0]) {
|
if (rnd(1,100) <= f->val[0]) {
|
||||||
|
@ -184,6 +179,12 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
||||||
addflag(lf->flags, F_HIDING, 0, NA, NA, NULL);
|
addflag(lf->flags, F_HIDING, 0, NA, NA, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!lfhasflag(lf, F_HIDING) && !lfhasflag(lf, F_DEAF) && cansleep(lf)) {
|
||||||
|
// TODO: base this on the time, and whether monster is nocturnal
|
||||||
|
if (rnd(1,2) == 1) {
|
||||||
|
addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// appears in groups?
|
// appears in groups?
|
||||||
|
@ -358,6 +359,134 @@ int addrandomthing(cell_t *c, int obchance, int *nadded) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// whichside should be D_ORTH
|
||||||
|
// for now, this function will NOT include room corners
|
||||||
|
void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells) {
|
||||||
|
int x,y;
|
||||||
|
*ncells = 0;
|
||||||
|
if (whichside == D_N) {
|
||||||
|
y = miny;
|
||||||
|
for (x = minx+1; x <= maxx-1; x++) {
|
||||||
|
retcell[*ncells] = getcellat(map, x, y);
|
||||||
|
(*ncells)++;
|
||||||
|
}
|
||||||
|
} else if (whichside == D_S) {
|
||||||
|
y = maxy;
|
||||||
|
for (x = minx+1; x <= maxx-1; x++) {
|
||||||
|
retcell[*ncells] = getcellat(map, x, y);
|
||||||
|
(*ncells)++;
|
||||||
|
}
|
||||||
|
} else if (whichside == D_W) {
|
||||||
|
x = minx;
|
||||||
|
for (y = miny+1; y <= maxy-1; y++) {
|
||||||
|
retcell[*ncells] = getcellat(map, x, y);
|
||||||
|
(*ncells)++;
|
||||||
|
}
|
||||||
|
} else if (whichside == D_E) {
|
||||||
|
x = maxx;
|
||||||
|
for (y = miny+1; y <= maxy-1; y++) {
|
||||||
|
retcell[*ncells] = getcellat(map, x, y);
|
||||||
|
(*ncells)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy) {
|
||||||
|
int i,d;
|
||||||
|
cell_t *poss[MAXCANDIDATES], *cell[MAXCANDIDATES]; // TODO: should this be maxroomw * maxroomh ?
|
||||||
|
int ncells = 0, npossible = 0;
|
||||||
|
int doorsadded = 0;
|
||||||
|
|
||||||
|
// for each side, make list of all possible door locations
|
||||||
|
// then pick one randomly.
|
||||||
|
// BUT if the nearby corridor only has one exit, always
|
||||||
|
// place a door.
|
||||||
|
for (d = D_N; d <= D_W; d++) {
|
||||||
|
npossible = 0;
|
||||||
|
getroomedge(map, roomid, minx, miny, maxx, maxy, d, cell, &ncells);
|
||||||
|
for (i = 0; i < ncells; i++) {
|
||||||
|
cell_t *newcell;
|
||||||
|
// is there empty space on the other side of this wall segment?
|
||||||
|
newcell = getcellindir(cell[i], d);
|
||||||
|
if (newcell && !newcell->type->solid) {
|
||||||
|
int doorcount;
|
||||||
|
// if so, make sure there are no other adjacent doors
|
||||||
|
doorcount = countadjcellswithflag(cell[i], F_DOOR);
|
||||||
|
if (doorcount == 0) {
|
||||||
|
// if there is only one way out of the adjacent empty cell, and
|
||||||
|
// walls to either side of the potential door location, then
|
||||||
|
// always add a door
|
||||||
|
if ((countcellexits(newcell) == 1) && wallstoleftright(newcell, d)) {
|
||||||
|
if (onein(2)) {
|
||||||
|
makedoor(cell[i]);
|
||||||
|
} else {
|
||||||
|
setcelltype(cell[i], getemptycelltype(map->habitat));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// otherwise mark this as a _potential_ door location.
|
||||||
|
poss[npossible] = cell[i];
|
||||||
|
npossible++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have potential door locations, add one somewhere along this wall.
|
||||||
|
if (npossible > 0) {
|
||||||
|
int sel;
|
||||||
|
sel = rnd(0,npossible-1);
|
||||||
|
makedoor(poss[sel]);
|
||||||
|
doorsadded++;
|
||||||
|
}
|
||||||
|
} // end foreach direction
|
||||||
|
|
||||||
|
|
||||||
|
if (doorsadded == 0) {
|
||||||
|
int i,d,used[MAXDIR_ORTH],poss[MAXDIR_ORTH];
|
||||||
|
int dodoor[MAXDIR_ORTH];
|
||||||
|
int ndodoors = 0;
|
||||||
|
int ndoors,nposs = 0;
|
||||||
|
|
||||||
|
int sel;
|
||||||
|
//
|
||||||
|
for (d = D_N; d <= D_W; d++) {
|
||||||
|
used[d] = B_FALSE;
|
||||||
|
}
|
||||||
|
// no possible door locations - add a random number
|
||||||
|
ndoors = rnd(1,4);
|
||||||
|
|
||||||
|
for (i = 0; i < ndoors; i++) {
|
||||||
|
// find a dir we haven't already used
|
||||||
|
nposs = 0;
|
||||||
|
for (d = D_N; d <= D_W; d++) {
|
||||||
|
if (!used[d]) poss[nposs++] = d;
|
||||||
|
}
|
||||||
|
if (nposs <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sel = rnd(0,nposs-1);
|
||||||
|
used[poss[sel]] = B_TRUE;
|
||||||
|
dodoor[ndodoors++] = poss[sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually make the doors
|
||||||
|
for (i = 0; i < ndodoors; i++) {
|
||||||
|
int sel;
|
||||||
|
d = dodoor[i];
|
||||||
|
getroomedge(map, roomid, minx, miny, maxx, maxy, d, cell, &ncells);
|
||||||
|
sel = rnd(0,ncells-1);
|
||||||
|
|
||||||
|
if (onein(2)) {
|
||||||
|
makedoor(cell[sel]);
|
||||||
|
} else {
|
||||||
|
setcelltype(cell[sel], getemptycelltype(map->habitat));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cellhaslos(cell_t *c1, cell_t *dest) {
|
int cellhaslos(cell_t *c1, cell_t *dest) {
|
||||||
int deltax, deltay;
|
int deltax, deltay;
|
||||||
int numpixels;
|
int numpixels;
|
||||||
|
@ -579,6 +708,13 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getdoorlockdiff(int depth) {
|
||||||
|
return 19 + depth;
|
||||||
|
}
|
||||||
|
int getdoorsecretdiff(int depth) {
|
||||||
|
return 20 + (depth / 2);
|
||||||
|
}
|
||||||
|
|
||||||
enum CELLTYPE getemptycelltype(enum HABITAT hab) {
|
enum CELLTYPE getemptycelltype(enum HABITAT hab) {
|
||||||
switch (hab) {
|
switch (hab) {
|
||||||
case H_DUNGEON:
|
case H_DUNGEON:
|
||||||
|
@ -870,13 +1006,10 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
||||||
int lastdir;
|
int lastdir;
|
||||||
int numrooms = 0;
|
int numrooms = 0;
|
||||||
int roomw[MAXROOMS],roomh[MAXROOMS];
|
int roomw[MAXROOMS],roomh[MAXROOMS];
|
||||||
|
vault_t *roomvault[MAXROOMS];
|
||||||
//int roomspecial[MAX_MAPROOMS];
|
//int roomspecial[MAX_MAPROOMS];
|
||||||
int minroomw = MIN_ROOMW;
|
//int bestx,besty;
|
||||||
int minroomh = MIN_ROOMH;
|
//int w,h;
|
||||||
int maxroomw = MAX_ROOMW;
|
|
||||||
int maxroomh = MAX_ROOMH;
|
|
||||||
int bestx,besty;
|
|
||||||
int w,h;
|
|
||||||
//int startdir,forcex,forcey,ntries;
|
//int startdir,forcex,forcey,ntries;
|
||||||
cell_t *cell, *c;
|
cell_t *cell, *c;
|
||||||
object_t *o;
|
object_t *o;
|
||||||
|
@ -1075,40 +1208,24 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
||||||
//printf("using %d rooms\n",numrooms);
|
//printf("using %d rooms\n",numrooms);
|
||||||
//dblog("Adding %d rooms...\n",numrooms);
|
//dblog("Adding %d rooms...\n",numrooms);
|
||||||
for (i = 0; i < numrooms; i++) {
|
for (i = 0; i < numrooms; i++) {
|
||||||
// select random width/height
|
// maybe make it a special room
|
||||||
w = rnd(minroomw, maxroomw);
|
roomvault[i] = NULL;
|
||||||
h = rnd(minroomh, maxroomh);
|
if (rnd(1,100) <= getvaultchance(map)) {
|
||||||
|
vault_t *v;
|
||||||
roomw[i] = w;
|
v = getvaulttype(map);
|
||||||
roomh[i] = h;
|
if (!createvault(map, i, v, &roomw[i],&roomh[i])) {
|
||||||
|
// success
|
||||||
if (calcroompos(map, w, h, &bestx, &besty)) {
|
roomvault[i] = v;
|
||||||
//printf("** couldn't make room!\n");
|
}
|
||||||
} else {
|
}
|
||||||
// we now have the room position - fill it in
|
if (!roomvault[i]) {
|
||||||
createroom(map, bestx,besty, w,h, i);
|
// just do a normal room
|
||||||
|
createroom(map, i, NA, NA, NULL, NULL, &roomw[i],&roomh[i]);
|
||||||
/*
|
roomvault[i] = B_FALSE;
|
||||||
if (getrand(1,100) <= CH_SPECIALROOM) {
|
|
||||||
int curpos;
|
|
||||||
int roomid;
|
|
||||||
roomid = getrandomspecialroom(wreck->mazelev[curz].type);
|
|
||||||
for (y = besty; y <= (besty + (h-1)); y++) {
|
|
||||||
for (x = bestx; x <= (bestx + (w-1)); x++) {
|
|
||||||
curpos = y*MAZEW+x;
|
|
||||||
wreck->mazelev[curz].maze[curpos].floorver = roomid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roomspecial[i] = roomid;
|
|
||||||
} else {
|
|
||||||
roomspecial[i] = B_FALSE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// add staircases - dungeons always have an up and down stairs
|
// add staircases - dungeons always have an up and down stairs
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
// add up stairs
|
// add up stairs
|
||||||
|
@ -1150,84 +1267,76 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
||||||
// add pillars & objects & monsters to rooms
|
// add pillars & objects & monsters to rooms
|
||||||
if (wantrooms && (numrooms > 0)) {
|
if (wantrooms && (numrooms > 0)) {
|
||||||
for (i = 0; i < numrooms; i++) {
|
for (i = 0; i < numrooms; i++) {
|
||||||
int numobsmin,numobsmax,numobs,n;
|
if (!roomvault[i] || hasflag(roomvault[i]->flags, F_AUTOPOPULATE)) {
|
||||||
int maxpillars;
|
int numobsmin,numobsmax,numobs,n;
|
||||||
|
int maxpillars;
|
||||||
|
|
||||||
//dblog("Adding obs to room %d/%d",i+1,numrooms);
|
//dblog("Adding obs to room %d/%d",i+1,numrooms);
|
||||||
maxpillars = (roomw[i] / 4) + (roomh[i] / 4);
|
maxpillars = (roomw[i] / 4) + (roomh[i] / 4);
|
||||||
// add pillars first
|
// add pillars first
|
||||||
if ((maxpillars > 0) && (rnd(1,100) <= CH_PILLAR)) {
|
if ((maxpillars > 0) && (rnd(1,100) <= CH_PILLAR)) {
|
||||||
int n;
|
int n;
|
||||||
int numpillars;
|
int numpillars;
|
||||||
numpillars = rnd(1,maxpillars);
|
numpillars = rnd(1,maxpillars);
|
||||||
if (db) dblog("--> Will add %d pillars",numpillars);
|
if (db) dblog("--> Will add %d pillars",numpillars);
|
||||||
for (n = 0; n < numpillars;n++ ) {
|
for (n = 0; n < numpillars;n++ ) {
|
||||||
//dblog("----> Adding pillar %d/%d",n+1,numpillars);
|
//dblog("----> Adding pillar %d/%d",n+1,numpillars);
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
c = getrandomroomcell(map, i);
|
c = getrandomroomcell(map, i);
|
||||||
|
|
||||||
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||||
setcelltype(cell, CT_WALL);
|
setcelltype(cell, CT_WALL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
numobsmin = 0;
|
||||||
if (roomspecial[i]) {
|
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||||
// chance is increased
|
numobsmax = MAXOF(roomw[i],roomh[i]);
|
||||||
numobsmin = (roomw[i]*roomh[i]) / 4 ;
|
|
||||||
numobsmax = (roomw[i]*roomh[i]) / 2 ;
|
|
||||||
} else {
|
|
||||||
*/
|
|
||||||
numobsmin = 0;
|
|
||||||
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
|
||||||
numobsmax = MAXOF(roomw[i],roomh[i]);
|
|
||||||
|
|
||||||
//}
|
// then objects/monsters
|
||||||
|
if (numobsmax <= numobsmin) {
|
||||||
|
numobs = numobsmin;
|
||||||
|
} else {
|
||||||
|
numobs = rnd(numobsmin,numobsmax);
|
||||||
|
}
|
||||||
|
if (db) dblog("--> Will add %d objects to room %d (of %d)",numobs,i,numrooms);
|
||||||
|
for (n = 0 ; n < numobs; n++) {
|
||||||
|
int ntries = 0;
|
||||||
|
int nmonsters = 0;
|
||||||
|
cell_t *c;
|
||||||
|
done = B_FALSE;
|
||||||
|
while (!done) {
|
||||||
|
c = getrandomroomcell(map, i);
|
||||||
|
// if nothing there
|
||||||
|
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||||
|
int obchance;
|
||||||
|
int nadded = 0;
|
||||||
|
|
||||||
// then objects/monsters
|
// limit # monster per room to depth+1
|
||||||
if (numobsmax <= numobsmin) {
|
if (nmonsters >= (depth+1)) {
|
||||||
numobs = numobsmin;
|
obchance = 100;
|
||||||
} else {
|
} else {
|
||||||
numobs = rnd(numobsmin,numobsmax);
|
// slightly more chance of objects in rooms
|
||||||
}
|
obchance = getobchance(map->habitat) + 10;
|
||||||
if (db) dblog("--> Will add %d objects to room %d (of %d)",numobs,i,numrooms);
|
}
|
||||||
for (n = 0 ; n < numobs; n++) {
|
|
||||||
int ntries = 0;
|
|
||||||
int nmonsters = 0;
|
|
||||||
cell_t *c;
|
|
||||||
done = B_FALSE;
|
|
||||||
while (!done) {
|
|
||||||
c = getrandomroomcell(map, i);
|
|
||||||
// if nothing there
|
|
||||||
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
|
||||||
int obchance;
|
|
||||||
int nadded = 0;
|
|
||||||
|
|
||||||
// limit # monster per room to depth+1
|
if (addrandomthing(c,obchance, &nadded) == TT_MONSTER) {
|
||||||
if (nmonsters >= (depth+1)) {
|
nmonsters += nadded;
|
||||||
obchance = 100;
|
}
|
||||||
|
done = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
// slightly more chance of objects in rooms
|
ntries++;
|
||||||
obchance = getobchance(map->habitat) + 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addrandomthing(c,obchance, &nadded) == TT_MONSTER) {
|
if (ntries >= numobs) {
|
||||||
nmonsters += nadded;
|
break;
|
||||||
}
|
}
|
||||||
done = B_TRUE;
|
|
||||||
} else {
|
|
||||||
ntries++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ntries >= numobs) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // end if !vault
|
||||||
|
} // end foreach room
|
||||||
}
|
} // end if wantrooms & nrooms>0
|
||||||
}
|
|
||||||
|
|
||||||
if (db) dblog("Finished adding objects.");
|
if (db) dblog("Finished adding objects.");
|
||||||
}
|
}
|
||||||
|
@ -1541,12 +1650,194 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
||||||
map->beingcreated = B_FALSE;
|
map->beingcreated = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth) {
|
||||||
|
int w,h,x,y;
|
||||||
|
int minx,miny,maxx,maxy;
|
||||||
|
flag_t *f;
|
||||||
|
if (!v) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = hasflag(v->flags, F_VAULTRANDOMMAP);
|
||||||
|
if (f) {
|
||||||
|
// just make a normal room to start with.
|
||||||
|
if (createroom(map, roomid, f->val[0], f->val[1], &minx, &miny, &w, &h)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
maxx = minx + w - 1;
|
||||||
|
maxy = miny + h - 1;
|
||||||
|
} else {
|
||||||
|
// get width/height from vault
|
||||||
|
w = v->w;
|
||||||
|
h = v->h;
|
||||||
|
if (retw) *retw = w;
|
||||||
|
if (reth) *reth = h;
|
||||||
|
// find vault position
|
||||||
|
if (calcroompos(map, w, h, &minx, &miny)) {
|
||||||
|
dblog("** couldn't make vault room!\n");
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
maxx = minx + (w-1);
|
||||||
|
maxy = miny + (h-1);
|
||||||
|
|
||||||
|
// now make it
|
||||||
|
for (y = miny; y <= maxy; y++) {
|
||||||
|
for (x = minx; x <= maxx; x++) {
|
||||||
|
cell_t *cell;
|
||||||
|
celltype_t *ct;
|
||||||
|
cell = getcellat(map, x, y);
|
||||||
|
|
||||||
|
// set cell type
|
||||||
|
ct = getvaultcelltype(v, x-minx,y-miny);
|
||||||
|
setcelltype(cell, ct ? ct->id : getemptycelltype(cell->map->habitat));
|
||||||
|
// set roomid
|
||||||
|
cell->roomid = roomid;
|
||||||
|
// add objects
|
||||||
|
addvaultcellcontents(cell, v, x-minx,y-miny);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add other stuff to the vault
|
||||||
|
addvaultcontents(map, v, minx, miny, maxx, maxy);
|
||||||
|
|
||||||
|
// auto add doors if required
|
||||||
|
if (hasflag(v->flags, F_AUTODOORS)) {
|
||||||
|
autodoors(map, roomid, minx, miny, maxx, maxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
linkdoors(map, roomid, minx, miny, maxx,maxy);
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure doors in a given room link up to the rest of the map.
|
||||||
|
void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
|
||||||
|
int x,y,i;
|
||||||
|
cell_t *poss[MAXCANDIDATES],*c;
|
||||||
|
int nposs = 0;
|
||||||
|
int db = B_FALSE;
|
||||||
|
|
||||||
|
if (db) dblog("linkdoors for roomid %d", roomid);
|
||||||
|
|
||||||
|
// find all doors // TODO: ...or "exits"
|
||||||
|
for (y = miny; y <= maxy; y++) {
|
||||||
|
for (x = minx; x <= maxx; x++) {
|
||||||
|
c = getcellat(m, x, y);
|
||||||
|
if (!c) continue;
|
||||||
|
|
||||||
|
if (hasobwithflag(c->obpile, F_DOOR)) {
|
||||||
|
if (db) dblog("found door at %d,%d",x,y);
|
||||||
|
poss[nposs++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (db) dblog("%d doors found.",nposs);
|
||||||
|
|
||||||
|
// for each door, make sure it links to at least one cell which isn't
|
||||||
|
// part of this room
|
||||||
|
for (i = 0; i < nposs; i++) {
|
||||||
|
int d;
|
||||||
|
int ncorridors = 0;
|
||||||
|
for (d = DC_N; d <= DC_NW; d++) {
|
||||||
|
c = getcellindir(poss[i], d);
|
||||||
|
if (c && cellwalkable(NULL, c, NULL) && (c->roomid != roomid)) {
|
||||||
|
ncorridors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (db) dblog("Door #%d leads to %d corridors. ",i, ncorridors);
|
||||||
|
|
||||||
|
// no corridors?
|
||||||
|
if (ncorridors == 0) {
|
||||||
|
int poss2[MAXCANDIDATES],nposs2;
|
||||||
|
int dist[MAXDIR_ORTH];
|
||||||
|
int bestdist = 999;
|
||||||
|
if (db) dblog(" Need to link.");
|
||||||
|
// link it. starting from the door, count the number of cells in
|
||||||
|
// each direction until we hit an empty (walkable) cell not of this room.
|
||||||
|
// if we hit a cell of this roomid, mark this dir as invalid.
|
||||||
|
for (d = D_N; d <= D_W; d++) {
|
||||||
|
dist[d] = 0;
|
||||||
|
c = getcellindir(poss[i], d);
|
||||||
|
while (c) {
|
||||||
|
dist[d]++;
|
||||||
|
if (c->roomid == roomid) {
|
||||||
|
// mark dir as invalid
|
||||||
|
dist[d] = 999;
|
||||||
|
break;
|
||||||
|
} else if (cellwalkable(NULL, c, NULL)) {
|
||||||
|
// walkable and not in this vault. finished.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check next cell
|
||||||
|
c = getcellindir(c, d); // getting the same cell!
|
||||||
|
}
|
||||||
|
if (dist[d] < bestdist) bestdist = dist[d];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestdist != 999) {
|
||||||
|
int whichway,sel;
|
||||||
|
// now pick the shortest one
|
||||||
|
// get list of all the maximums and randomly tie-break
|
||||||
|
nposs2 = 0;
|
||||||
|
for (d = D_N; d <= D_W; d++) {
|
||||||
|
if (dist[d] == bestdist) {
|
||||||
|
poss2[nposs2++] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sel = rnd(0,nposs2-1);
|
||||||
|
whichway = poss2[sel];
|
||||||
|
|
||||||
|
// now create a path
|
||||||
|
if (db) dblog(" Linking %s (distance %d).", getdirname(whichway), bestdist);
|
||||||
|
c = getcellindir(poss[i], whichway);
|
||||||
|
while (c && !cellwalkable(NULL, c, NULL)) {
|
||||||
|
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||||
|
c = getcellindir(poss[i], whichway);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end if ncorridors = 0
|
||||||
|
} // end for each door
|
||||||
|
if (db) dblog("linkdoors complete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// room w/h are returned in *w and *h if given.
|
||||||
|
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int *retx, int *rety, int *retw, int *reth) {
|
||||||
int x,y;
|
int x,y;
|
||||||
int poss[MAXOF(MAX_MAPW,MAX_MAPH)];
|
cell_t *cell;
|
||||||
int npossible;
|
int minx,miny;
|
||||||
cell_t *cell, *newcell;
|
|
||||||
int maxx,maxy;
|
int maxx,maxy;
|
||||||
|
int w,h;
|
||||||
|
int minroomw = MIN_ROOMW;
|
||||||
|
int minroomh = MIN_ROOMH;
|
||||||
|
int maxroomw = MAX_ROOMW;
|
||||||
|
int maxroomh = MAX_ROOMH;
|
||||||
|
|
||||||
|
if (overrideminw != NA) {
|
||||||
|
minroomw = overrideminw;
|
||||||
|
}
|
||||||
|
if (overrideminh != NA) {
|
||||||
|
minroomh = overrideminh;
|
||||||
|
}
|
||||||
|
|
||||||
|
// select random width/height
|
||||||
|
w = rnd(minroomw, maxroomw);
|
||||||
|
h = rnd(minroomh, maxroomh);
|
||||||
|
|
||||||
|
if (retw) *retw = w;
|
||||||
|
if (reth) *reth = h;
|
||||||
|
|
||||||
|
// find room position
|
||||||
|
if (calcroompos(map, w, h, &minx, &miny)) {
|
||||||
|
dblog("** couldn't make room!\n");
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retx) *retx = minx;
|
||||||
|
if (rety) *rety = miny;
|
||||||
|
|
||||||
|
// we now have the room position - fill it in
|
||||||
|
|
||||||
//printf("trying to create room at (%d,%d) w=%d,h=%d\n", minx, miny, w, h);
|
//printf("trying to create room at (%d,%d) w=%d,h=%d\n", minx, miny, w, h);
|
||||||
|
|
||||||
|
@ -1556,7 +1847,6 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
for (y = miny; y <= maxy; y++) {
|
for (y = miny; y <= maxy; y++) {
|
||||||
for (x = minx; x <= maxx; x++) {
|
for (x = minx; x <= maxx; x++) {
|
||||||
cell = getcellat(map, x, y);
|
cell = getcellat(map, x, y);
|
||||||
|
|
||||||
// make it a border or room
|
// make it a border or room
|
||||||
if ((y == miny) || (y == maxy) ||
|
if ((y == miny) || (y == maxy) ||
|
||||||
(x == minx) || (x == maxx)) {
|
(x == minx) || (x == maxx)) {
|
||||||
|
@ -1570,172 +1860,13 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add doors
|
||||||
|
autodoors(map, roomid, minx, miny, maxx, maxy);
|
||||||
|
|
||||||
// for each side, make list of all possible door locations
|
return B_FALSE;
|
||||||
// then pick one randomly.
|
|
||||||
// BUT if the nearby corridor only has one exit, always
|
|
||||||
// place a door.
|
|
||||||
|
|
||||||
// N
|
|
||||||
npossible = 0;
|
|
||||||
y = miny;
|
|
||||||
for (x = minx+1; x <= maxx-1; x++) {
|
|
||||||
cell = getcellat(map, x, y);
|
|
||||||
newcell = getcellindir(cell, D_N);
|
|
||||||
if (newcell && !newcell->type->solid) {
|
|
||||||
int doorcount;
|
|
||||||
|
|
||||||
doorcount = countadjcellswithflag(cell, F_DOOR);
|
|
||||||
|
|
||||||
if (doorcount == 0) {
|
|
||||||
if ((countcellexits(newcell) == 1) &&
|
|
||||||
(iswallindir(newcell,D_E)) &&
|
|
||||||
(iswallindir(newcell,D_W))) { // always add door
|
|
||||||
makedoor(cell);
|
|
||||||
} else {
|
|
||||||
poss[npossible] = x;
|
|
||||||
npossible++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npossible > 0) {
|
|
||||||
int sel = rand() % npossible;
|
|
||||||
//printf("adding N door at %d\n",poss[sel]);
|
|
||||||
cell = getcellat(map, poss[sel], y);
|
|
||||||
makedoor(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// S
|
|
||||||
npossible = 0;
|
|
||||||
y = maxy;
|
|
||||||
for (x = minx+1; x <= maxx-1; x++) {
|
|
||||||
cell = getcellat(map, x, y);
|
|
||||||
newcell = getcellindir(cell, D_S);
|
|
||||||
if (newcell && !newcell->type->solid) {
|
|
||||||
int doorcount;
|
|
||||||
|
|
||||||
doorcount = countadjcellswithflag(cell, F_DOOR);
|
|
||||||
|
|
||||||
if (doorcount == 0) {
|
|
||||||
if ((countcellexits(newcell) == 1) &&
|
|
||||||
(iswallindir(newcell,D_E)) &&
|
|
||||||
(iswallindir(newcell,D_W))) { // always add door
|
|
||||||
makedoor(cell);
|
|
||||||
} else {
|
|
||||||
poss[npossible] = x;
|
|
||||||
npossible++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npossible > 0) {
|
|
||||||
int sel = rand() % npossible;
|
|
||||||
//printf("adding S door at %d\n",poss[sel]);
|
|
||||||
cell = getcellat(map, poss[sel], y);
|
|
||||||
makedoor(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// W
|
|
||||||
npossible = 0;
|
|
||||||
x = minx;
|
|
||||||
for (y = miny+1; y <= maxy-1; y++) {
|
|
||||||
cell = getcellat(map, x, y);
|
|
||||||
newcell = getcellindir(cell, D_W);
|
|
||||||
if (newcell && !newcell->type->solid) {
|
|
||||||
int doorcount;
|
|
||||||
doorcount = countadjcellswithflag(cell, F_DOOR);
|
|
||||||
if (doorcount == 0) {
|
|
||||||
if ((countcellexits(newcell) == 1) &&
|
|
||||||
(iswallindir(newcell,D_N)) &&
|
|
||||||
(iswallindir(newcell,D_S))) { // always add door
|
|
||||||
makedoor(cell);
|
|
||||||
} else {
|
|
||||||
poss[npossible] = y;
|
|
||||||
npossible++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npossible > 0) {
|
|
||||||
int sel = rand() % npossible;
|
|
||||||
//printf("adding W door at %d\n",poss[sel]);
|
|
||||||
cell = getcellat(map, x, poss[sel]);
|
|
||||||
makedoor(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// E
|
|
||||||
npossible = 0;
|
|
||||||
x = maxx;
|
|
||||||
for (y = miny+1; y <= maxy-1; y++) {
|
|
||||||
cell = getcellat(map, x, y);
|
|
||||||
newcell = getcellindir(cell, D_E);
|
|
||||||
if (newcell && !newcell->type->solid) {
|
|
||||||
int doorcount;
|
|
||||||
doorcount = countadjcellswithflag(cell, F_DOOR);
|
|
||||||
if (doorcount == 0) {
|
|
||||||
if ((countcellexits(newcell) == 1) &&
|
|
||||||
(iswallindir(newcell,D_N)) &&
|
|
||||||
(iswallindir(newcell,D_S))) { // always add door
|
|
||||||
makedoor(cell);
|
|
||||||
} else {
|
|
||||||
poss[npossible] = y;
|
|
||||||
npossible++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npossible > 0) {
|
|
||||||
int sel = rand() % npossible;
|
|
||||||
//printf("adding E door at %d\n",poss[sel]);
|
|
||||||
cell = getcellat(map, x, poss[sel]);
|
|
||||||
makedoor(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
// maybe make it a special room
|
|
||||||
if (rnd(1,100) <= getspecialroomchance(map)) {
|
|
||||||
enum SPECIALROOMTYPE rt;
|
|
||||||
rt = getspecialroomtype(map);
|
|
||||||
if (rt == RT_FLOODED) {
|
|
||||||
int sx,sy,ex,ey;
|
|
||||||
char wtype[BUFLEN];
|
|
||||||
switch (rnd(1,2)) {
|
|
||||||
case 1: strcpy(wtype, "deep water"); break;
|
|
||||||
case 2: strcpy(wtype, "shallow water"); break;
|
|
||||||
}
|
|
||||||
switch (rnd(1,2)) {
|
|
||||||
case 1: // entire room flooded
|
|
||||||
sx = minx+1;
|
|
||||||
sy = miny+1;
|
|
||||||
ex = maxx-1;
|
|
||||||
ey = maxy-1;
|
|
||||||
break;
|
|
||||||
case 2: // small walkway around the edge
|
|
||||||
sx = minx+2;
|
|
||||||
sy = miny+2;
|
|
||||||
ex = maxx-2;
|
|
||||||
ey = maxy-2;
|
|
||||||
if (sx > ex) sx = ex;
|
|
||||||
if (sy > ey) sy = ey;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (y = sy; y <= ey; y++) {
|
|
||||||
for (x = sx; x <= ex; x++) {
|
|
||||||
cell = getcellat(map, x, y);
|
|
||||||
addob(cell->obpile, wtype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dirtox(int dt, int dir) {
|
int dirtox(int dt, int dir) {
|
||||||
if (dt == DT_ORTH) {
|
if (dt == DT_ORTH) {
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
|
@ -1897,6 +2028,14 @@ celltype_t *findcelltype(enum CELLTYPE cid) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
celltype_t *findcelltypebyname(char *name) {
|
||||||
|
celltype_t *ct;
|
||||||
|
for (ct = firstcelltype ; ct ; ct = ct->next) {
|
||||||
|
if (!strcmp(ct->name, name)) return ct;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
map_t *findmap(int mid) {
|
map_t *findmap(int mid) {
|
||||||
map_t *m;
|
map_t *m;
|
||||||
for (m = firstmap ; m ; m = m->next) {
|
for (m = firstmap ; m ; m = m->next) {
|
||||||
|
@ -2199,10 +2338,10 @@ int getobchance(int habitat) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// chance that a room is a 'special' one
|
// chance that a room is a 'special' one
|
||||||
int getspecialroomchance(map_t *m) {
|
int getvaultchance(map_t *m) {
|
||||||
switch (m->habitat) {
|
switch (m->habitat) {
|
||||||
case H_DUNGEON:
|
case H_DUNGEON:
|
||||||
return 5;
|
return 10;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2210,17 +2349,6 @@ int getspecialroomchance(map_t *m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SPECIALROOMTYPE getspecialroomtype(map_t *m) {
|
|
||||||
if (m->habitat == H_DUNGEON) {
|
|
||||||
/*
|
|
||||||
switch (rnd(1,1)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return RT_FLOODED;
|
|
||||||
}
|
|
||||||
return RT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// chance of each empty cell in a map has of getting an object/monster
|
// chance of each empty cell in a map has of getting an object/monster
|
||||||
|
@ -2844,7 +2972,7 @@ void makedoor(cell_t *cell) {
|
||||||
chance = rolldie(1,6) - (m->depth / 10);
|
chance = rolldie(1,6) - (m->depth / 10);
|
||||||
|
|
||||||
if (chance <= 1) {
|
if (chance <= 1) {
|
||||||
addflag(o->flags, F_LOCKED, B_TRUE, 19 + (m->depth), NA, NULL);
|
addflag(o->flags, F_LOCKED, B_TRUE, getdoorlockdiff(m->depth), NA, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make it secret?
|
// make it secret?
|
||||||
|
@ -2855,7 +2983,7 @@ void makedoor(cell_t *cell) {
|
||||||
// l10 = 25
|
// l10 = 25
|
||||||
// l20 = 30
|
// l20 = 30
|
||||||
if (chance <= 1) {
|
if (chance <= 1) {
|
||||||
addflag(o->flags, F_SECRET, 20 + (m->depth / 2), NA, NA, NULL);
|
addflag(o->flags, F_SECRET, getdoorsecretdiff(m->depth), NA, NA, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2960,6 +3088,9 @@ void setcelltype(cell_t *cell, int id) {
|
||||||
cell->type = findcelltype(id);
|
cell->type = findcelltype(id);
|
||||||
assert(cell->type);
|
assert(cell->type);
|
||||||
cell->roomid = 0;
|
cell->roomid = 0;
|
||||||
|
if ((gamemode == GM_GAMESTARTED) && haslos(player, cell)) {
|
||||||
|
needredraw = B_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2989,3 +3120,19 @@ void updateknowncells(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wallstoleftright(cell_t *c, int dir) {
|
||||||
|
int d1,d2;
|
||||||
|
switch (dir) {
|
||||||
|
case D_N:
|
||||||
|
case D_S:
|
||||||
|
d1 = D_E; d2 = D_W; break;
|
||||||
|
case D_E:
|
||||||
|
case D_W:
|
||||||
|
d1 = D_N; d2 = D_S; break;
|
||||||
|
}
|
||||||
|
if (iswallindir(c,d1) && iswallindir(c,d2)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
14
map.h
14
map.h
|
@ -6,15 +6,19 @@ map_t *addmap(void);
|
||||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded);
|
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded);
|
||||||
object_t *addrandomob(cell_t *c);
|
object_t *addrandomob(cell_t *c);
|
||||||
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
||||||
|
void autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy);
|
||||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||||
cell_t *getcellat(map_t *map, int x, int y);
|
cell_t *getcellat(map_t *map, int x, int y);
|
||||||
int getcelldist(cell_t *src, cell_t *dst);
|
int getcelldist(cell_t *src, cell_t *dst);
|
||||||
int getcelldistorth(cell_t *src, cell_t *dst);
|
int getcelldistorth(cell_t *src, cell_t *dst);
|
||||||
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
||||||
|
int getdoorlockdiff(int depth);
|
||||||
|
int getdoorsecretdiff(int depth);
|
||||||
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
||||||
enum CELLTYPE getwallcelltype(enum HABITAT hab);
|
enum CELLTYPE getwallcelltype(enum HABITAT hab);
|
||||||
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
||||||
int getmapdifficulty(map_t *m);
|
int getmapdifficulty(map_t *m);
|
||||||
|
void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells);
|
||||||
object_t *gettopobject(cell_t *where);
|
object_t *gettopobject(cell_t *where);
|
||||||
void calclight(map_t *map);
|
void calclight(map_t *map);
|
||||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
||||||
|
@ -24,13 +28,15 @@ int countcellexits(cell_t *cell);
|
||||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir);
|
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 createforest(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||||
void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir);
|
void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir);
|
||||||
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid);
|
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int *retx, int *rety, int *retw, int *reth);
|
||||||
|
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth);
|
||||||
int dirtox(int dt, int dir);
|
int dirtox(int dt, int dir);
|
||||||
int dirtoy(int dt, int dir);
|
int dirtoy(int dt, int dir);
|
||||||
void dumpmap(map_t *map);
|
void dumpmap(map_t *map);
|
||||||
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre);
|
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre);
|
||||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce);
|
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce);
|
||||||
celltype_t *findcelltype(enum CELLTYPE cid);
|
celltype_t *findcelltype(enum CELLTYPE cid);
|
||||||
|
celltype_t *findcelltypebyname(char *name);
|
||||||
map_t *findmap(int mid);
|
map_t *findmap(int mid);
|
||||||
map_t *findmapofdepth(int depth);
|
map_t *findmapofdepth(int depth);
|
||||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
||||||
|
@ -41,8 +47,8 @@ void forgetcells(map_t *map, int amt);
|
||||||
cell_t *getcellindir(cell_t *cell, int dir);
|
cell_t *getcellindir(cell_t *cell, int dir);
|
||||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||||
int getobchance(int habitat);
|
int getobchance(int habitat);
|
||||||
int getspecialroomchance(map_t *m);
|
int getvaultchance(map_t *m);
|
||||||
enum SPECIALROOMTYPE getspecialroomtype(map_t *m);
|
char getvaultchar(vault_t *v, int x, int y);
|
||||||
int getthingchance(int habitat);
|
int getthingchance(int habitat);
|
||||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob);
|
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob);
|
||||||
|
@ -70,6 +76,7 @@ int isnewcellok(cell_t *cell, char *err);
|
||||||
int isonmap(map_t *map, int x, int y);
|
int isonmap(map_t *map, int x, int y);
|
||||||
int isoutdoors(map_t *m);
|
int isoutdoors(map_t *m);
|
||||||
int iswallindir(cell_t *cell, int dir);
|
int iswallindir(cell_t *cell, int dir);
|
||||||
|
void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||||
int linkstairs(object_t *o);
|
int linkstairs(object_t *o);
|
||||||
void makedoor(cell_t *cell);
|
void makedoor(cell_t *cell);
|
||||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||||
|
@ -77,3 +84,4 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||||
void setcellknown(cell_t *cell, int forcelev);
|
void setcellknown(cell_t *cell, int forcelev);
|
||||||
void setcelltype(cell_t *cell, int id);
|
void setcelltype(cell_t *cell, int id);
|
||||||
void updateknowncells(void);
|
void updateknowncells(void);
|
||||||
|
int wallstoleftright(cell_t *c, int dir);
|
||||||
|
|
68
move.c
68
move.c
|
@ -143,6 +143,16 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
|
|
||||||
// obvious things that you can see
|
// obvious things that you can see
|
||||||
if (!onlyifknown || (haslos(lf, cell) && !lfhasflag(lf, F_UNDEAD))) {
|
if (!onlyifknown || (haslos(lf, cell) && !lfhasflag(lf, F_UNDEAD))) {
|
||||||
|
// water needing creature out of water?
|
||||||
|
if (lfhasflag(lf, F_NEEDSWATER)) {
|
||||||
|
if (!hasobwithflag(cell->obpile, F_DEEPWATER)) {
|
||||||
|
if (error) {
|
||||||
|
*error = E_DANGEROUS;
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
f = hasflag(o->flags, F_DEEPWATER);
|
f = hasflag(o->flags, F_DEEPWATER);
|
||||||
if (f) {
|
if (f) {
|
||||||
|
@ -156,14 +166,6 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// water needing creature out of water?
|
|
||||||
if (lfhasflag(lf, F_NEEDSWATER)) {
|
|
||||||
if (error) {
|
|
||||||
*error = E_DANGEROUS;
|
|
||||||
}
|
|
||||||
return B_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
f = hasflag(o->flags, F_WALKDAM);
|
f = hasflag(o->flags, F_WALKDAM);
|
||||||
if (f) {
|
if (f) {
|
||||||
|
@ -566,7 +568,6 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
||||||
char newlfname[BUFLEN];
|
char newlfname[BUFLEN];
|
||||||
int seen;
|
int seen;
|
||||||
int mightfall = B_TRUE;
|
int mightfall = B_TRUE;
|
||||||
cell_t *newcell;
|
|
||||||
lifeform_t *newlf;
|
lifeform_t *newlf;
|
||||||
|
|
||||||
// calculate chance of falling
|
// calculate chance of falling
|
||||||
|
@ -600,6 +601,9 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
||||||
trymove(lf, dir, B_FALSE);
|
trymove(lf, dir, B_FALSE);
|
||||||
}
|
}
|
||||||
if (reason != E_OK) {
|
if (reason != E_OK) {
|
||||||
|
char buf[BUFLEN];
|
||||||
|
cell_t *newcell;
|
||||||
|
newcell = getcellindir(lf->cell, dir);
|
||||||
// failed to move
|
// failed to move
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case E_OFFMAP:
|
case E_OFFMAP:
|
||||||
|
@ -611,8 +615,10 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
||||||
}
|
}
|
||||||
// fall through
|
// fall through
|
||||||
case E_WALLINWAY:
|
case E_WALLINWAY:
|
||||||
if (seen) msg("%s slam%s into a wall!",lfname,isplayer(lf) ? "" : "s");
|
if (seen) msg("%s slam%s into a %s!",lfname,isplayer(lf) ? "" : "s",
|
||||||
losehp(lf, rnd(1,6), DT_BASH, pusher, "slamming into a wall");
|
newcell ? newcell->type->name : "wall");
|
||||||
|
sprintf(buf, "slamming into a %s", newcell ? newcell->type->name : "wall");
|
||||||
|
losehp(lf, rnd(1,6), DT_BASH, pusher, buf);
|
||||||
// stop moving
|
// stop moving
|
||||||
i = howfar;
|
i = howfar;
|
||||||
// don't fall
|
// don't fall
|
||||||
|
@ -1313,7 +1319,11 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
||||||
if (amt < 0) amt = 0;
|
if (amt < 0) amt = 0;
|
||||||
|
|
||||||
if (lf && isplayer(lf)) {
|
if (lf && isplayer(lf)) {
|
||||||
msg("You yank on the door but it holds fast.");
|
if (amt > 0) {
|
||||||
|
msg("The door moves slightly but seems jammed.");
|
||||||
|
} else {
|
||||||
|
msg("The door is jammed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// loosen a bit
|
// loosen a bit
|
||||||
if (amt) {
|
if (amt) {
|
||||||
|
@ -1758,10 +1768,14 @@ int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
|
||||||
|
|
||||||
// can't teleport on top of something else
|
// can't teleport on top of something else
|
||||||
if (c->lf) {
|
if (c->lf) {
|
||||||
if (isplayer(lf)) {
|
// go somewhere nearby
|
||||||
msg("You feel a wrenching sensation.");
|
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
|
||||||
|
if (!c) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("You feel a wrenching sensation.");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
return B_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isplayer(lf) && cansee(player, lf)) {
|
if (!isplayer(lf) && cansee(player, lf)) {
|
||||||
|
@ -1953,25 +1967,31 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
||||||
// otherwise fall through...
|
// otherwise fall through...
|
||||||
case E_WALLINWAY:
|
case E_WALLINWAY:
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
msg("Ouch! You %s into a wall.", getmoveverb(lf));
|
msg("Ouch! You %s into a %s.", getmoveverb(lf),
|
||||||
|
cell ? cell->type->name : "wall");
|
||||||
} else if (cansee(player, lf)) {
|
} else if (cansee(player, lf)) {
|
||||||
getlfname(lf, buf);
|
getlfname(lf, buf);
|
||||||
msg("%s %ss into a wall.", buf, getmoveverb(lf));
|
msg("%s %ss into a %s.", buf, getmoveverb(lf),
|
||||||
|
cell ? cell->type->name : "wall");
|
||||||
}
|
}
|
||||||
//if (isblind(lf) || !haslos(lf, cell)) {
|
//if (isblind(lf) || !haslos(lf, cell)) {
|
||||||
if (!haslos(lf, cell)) {
|
if (!cell || !haslos(lf, cell)) {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
// only take damage if we didn't know about this
|
// only take damage if we didn't know about this
|
||||||
if (!cell->known || isdrunk(lf)) {
|
if ((cell && !cell->known) || isdrunk(lf)) {
|
||||||
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
sprintf(buf, "%sing into a %s", getmoveverb(lf),
|
||||||
|
cell ? cell->type->name : "wall");
|
||||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
// we now know there is a wall there.
|
if (cell) {
|
||||||
setcellknown(cell, B_FALSE);
|
// we now know there is a wall there.
|
||||||
|
setcellknown(cell, B_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
sprintf(buf, "%sing into a %s", getmoveverb(lf),
|
||||||
|
cell ? cell->type->name : "wall");
|
||||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||||
}
|
}
|
||||||
|
@ -1997,7 +2017,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
||||||
} else {
|
} else {
|
||||||
if (cansee(player, lf)) {
|
if (cansee(player, lf)) {
|
||||||
getlfname(lf, buf);
|
getlfname(lf, buf);
|
||||||
msg("%s %ss into a wall.", buf, getmoveverb(lf));
|
msg("%s %ss into a door.", buf, getmoveverb(lf));
|
||||||
}
|
}
|
||||||
sprintf(buf, "%sing into a door", getmoveverb(lf));
|
sprintf(buf, "%sing into a door", getmoveverb(lf));
|
||||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
|
|
26
nexus.c
26
nexus.c
|
@ -17,6 +17,7 @@
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
#include "vault.h"
|
||||||
|
|
||||||
material_t *material = NULL,*lastmaterial = NULL;
|
material_t *material = NULL,*lastmaterial = NULL;
|
||||||
objectclass_t *objectclass = NULL,*lastobjectclass = NULL;
|
objectclass_t *objectclass = NULL,*lastobjectclass = NULL;
|
||||||
|
@ -33,6 +34,8 @@ map_t *firstmap = NULL,*lastmap = NULL;
|
||||||
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
||||||
hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
||||||
|
|
||||||
|
extern vault_t *firstvault;
|
||||||
|
|
||||||
glyph_t playerglyph,tempglyph;
|
glyph_t playerglyph,tempglyph;
|
||||||
|
|
||||||
double startticks,lastticks;
|
double startticks,lastticks;
|
||||||
|
@ -86,6 +89,7 @@ int main(int argc, char **argv) {
|
||||||
FILE *playerfile = NULL;
|
FILE *playerfile = NULL;
|
||||||
int x,y;
|
int x,y;
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
|
vault_t *v;
|
||||||
|
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
|
|
||||||
|
@ -117,11 +121,11 @@ int main(int argc, char **argv) {
|
||||||
// init graphics
|
// init graphics
|
||||||
initgfx();
|
initgfx();
|
||||||
|
|
||||||
// if no maps, make the initial level
|
// warn about vault problems.
|
||||||
if (!firstmap) {
|
for (v = firstvault ; v ; v = v->next) {
|
||||||
newworld = B_TRUE;
|
if (!v->valid) {
|
||||||
addmap();
|
msg("warning: invalid vaultfile '%s'",v->filename); more();
|
||||||
createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!knowledge) {
|
if (!knowledge) {
|
||||||
|
@ -169,6 +173,13 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if no maps (ie. ALWAYS now that maps aren't persistent),
|
||||||
|
// make the initial level
|
||||||
|
if (!firstmap) {
|
||||||
|
newworld = B_TRUE;
|
||||||
|
addmap();
|
||||||
|
createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
// find staircase
|
// find staircase
|
||||||
where = findobinmap(firstmap, OT_STAIRSUP);
|
where = findobinmap(firstmap, OT_STAIRSUP);
|
||||||
|
@ -740,6 +751,8 @@ int init(void) {
|
||||||
|
|
||||||
// cell types
|
// cell types
|
||||||
addcelltype(CT_WALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE);
|
addcelltype(CT_WALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE);
|
||||||
|
addcelltype(CT_WALLGLASS, "glass wall", '#', C_CYAN, B_SOLID, B_TRANS, MT_GLASS);
|
||||||
|
addcelltype(CT_WALLMETAL, "metal wall", '#', C_WHITE, B_SOLID, B_OPAQUE, MT_METAL);
|
||||||
addcelltype(CT_ROOMWALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE);
|
addcelltype(CT_ROOMWALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE);
|
||||||
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE);
|
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_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE);
|
||||||
|
@ -759,6 +772,9 @@ int init(void) {
|
||||||
logfile = fopen("log.txt","wt");
|
logfile = fopen("log.txt","wt");
|
||||||
fprintf(logfile, "\n\n\n====== NEW LOGFILE ====\n");
|
fprintf(logfile, "\n\n\n====== NEW LOGFILE ====\n");
|
||||||
|
|
||||||
|
// load in vaults
|
||||||
|
loadvaults();
|
||||||
|
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text);
|
||||||
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
|
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
|
||||||
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
||||||
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour);
|
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour);
|
||||||
|
void addocnoun(objectclass_t *oc, char *text);
|
||||||
object_t *addob(obpile_t *where, char *name);
|
object_t *addob(obpile_t *where, char *name);
|
||||||
object_t *addobject(obpile_t *where, char *name, int canstack);
|
object_t *addobject(obpile_t *where, char *name, int canstack);
|
||||||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof);
|
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof);
|
||||||
|
@ -38,6 +39,7 @@ int countnoncosmeticobs(obpile_t *op, int onlyifknown);
|
||||||
int curseob(object_t *o);
|
int curseob(object_t *o);
|
||||||
void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype);
|
void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype);
|
||||||
void dumprandomobs(int amt);
|
void dumprandomobs(int amt);
|
||||||
|
void dumpobrarity(void);
|
||||||
void explodeob(object_t *o, flag_t *f, int bigness);
|
void explodeob(object_t *o, flag_t *f, int bigness);
|
||||||
void extinguish(object_t *o);
|
void extinguish(object_t *o);
|
||||||
material_t *findmaterial(int id);
|
material_t *findmaterial(int id);
|
||||||
|
@ -64,6 +66,8 @@ int getobvalue(object_t *o);
|
||||||
char *getaccuracyname(int accpct);
|
char *getaccuracyname(int accpct);
|
||||||
object_t *getammo(lifeform_t *lf);
|
object_t *getammo(lifeform_t *lf);
|
||||||
object_t *getrandomammo(lifeform_t *lf);
|
object_t *getrandomammo(lifeform_t *lf);
|
||||||
|
brand_t *getrandombrandfor(objecttype_t *ot);
|
||||||
|
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity);
|
||||||
char *getdamname(enum DAMTYPE damtype);
|
char *getdamname(enum DAMTYPE damtype);
|
||||||
char *getdamnamenoun(enum DAMTYPE damtype);
|
char *getdamnamenoun(enum DAMTYPE damtype);
|
||||||
char *getfillingname(int nutrition);
|
char *getfillingname(int nutrition);
|
||||||
|
@ -193,6 +197,7 @@ int readsomething(lifeform_t *lf, object_t *o);
|
||||||
void removedeadobs(obpile_t *op);
|
void removedeadobs(obpile_t *op);
|
||||||
int removeob(object_t *o, int howmany);
|
int removeob(object_t *o, int howmany);
|
||||||
object_t *relinkob(object_t *src, obpile_t *dst);
|
object_t *relinkob(object_t *src, obpile_t *dst);
|
||||||
|
void rrtorarity(enum RARITY r, int *minr, int *maxr);
|
||||||
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
||||||
void setinscription(object_t *o, char *text);
|
void setinscription(object_t *o, char *text);
|
||||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||||
|
|
93
spell.c
93
spell.c
|
@ -31,6 +31,10 @@ extern objecttype_t *objecttype;
|
||||||
|
|
||||||
extern map_t *firstmap;
|
extern map_t *firstmap;
|
||||||
|
|
||||||
|
extern object_t *retobs[MAXPILEOBS+1];
|
||||||
|
extern int retobscount[MAXPILEOBS+1];
|
||||||
|
extern int nretobs;
|
||||||
|
|
||||||
extern enum ERROR reason;
|
extern enum ERROR reason;
|
||||||
|
|
||||||
extern int needredraw, statdirty;
|
extern int needredraw, statdirty;
|
||||||
|
@ -2238,11 +2242,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
int seenthiscell = B_FALSE;
|
int seenthiscell = B_FALSE;
|
||||||
if (haslos(player, retcell[i])) seenthiscell = B_TRUE;
|
if (haslos(player, retcell[i])) seenthiscell = B_TRUE;
|
||||||
if (retcell[i]->type->solid) {
|
if (retcell[i]->type->solid) {
|
||||||
setcelltype(retcell[i], getemptycelltype(retcell[i]->map->habitat));
|
// can dig through stone, but nothing else.
|
||||||
if (seenthiscell) {
|
if (retcell[i]->type->material->id == MT_STONE) {
|
||||||
ndigs++;
|
setcelltype(retcell[i], getemptycelltype(retcell[i]->map->habitat));
|
||||||
numseen++;
|
if (seenthiscell) {
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
ndigs++;
|
||||||
|
numseen++;
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// stop.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
|
@ -5436,7 +5446,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
// confirm
|
// confirm
|
||||||
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE);
|
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE);
|
||||||
if (ch != 'y') c = NULL;
|
if (ch != 'y') c = NULL;
|
||||||
} else if (!cellwalkable(caster, c, NULL)) {
|
} else if (c->type->solid) {
|
||||||
// confirm
|
// confirm
|
||||||
ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE);
|
ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE);
|
||||||
if (ch != 'y') c = NULL;
|
if (ch != 'y') c = NULL;
|
||||||
|
@ -5544,9 +5554,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
targcell = c;
|
targcell = c;
|
||||||
|
|
||||||
if (!cellwalkable(caster, c, NULL)) {
|
if (c->type->solid) {
|
||||||
fizzle(caster);
|
// ok, but you'll die!
|
||||||
return B_FALSE;
|
} else if (!cellwalkable(caster, c, NULL)) {
|
||||||
|
// go somewhere nearby...
|
||||||
|
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
|
||||||
|
if (!c) {
|
||||||
|
fizzle(caster);
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can take up to 'power-1' allies with us.
|
// we can take up to 'power-1' allies with us.
|
||||||
|
@ -6104,6 +6120,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
if (isplayer(caster)) {
|
if (isplayer(caster)) {
|
||||||
char lfname[BUFLEN];
|
char lfname[BUFLEN];
|
||||||
char question[BUFLEN];
|
char question[BUFLEN];
|
||||||
|
int i;
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
// ask for target
|
// ask for target
|
||||||
if (spellid == OT_S_GIFT) {
|
if (spellid == OT_S_GIFT) {
|
||||||
|
@ -6121,34 +6138,40 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
sprintf(question, "For what do you wish");
|
sprintf(question, "For what do you wish");
|
||||||
}
|
}
|
||||||
askstring(question, '?', buf, BUFLEN, NULL);
|
askstring(question, '?', buf, BUFLEN, NULL);
|
||||||
o = addob(target->cell->obpile, buf);
|
addob(target->cell->obpile, buf);
|
||||||
if (o) {
|
if (nretobs) {
|
||||||
char obname[BUFLEN];
|
for (i = 0; i < nretobs; i++) {
|
||||||
getobname(o, obname, o->amt);
|
char obname[BUFLEN];
|
||||||
if (!hasflag(o->flags, F_IMPASSABLE) && canpickup(target, o, ALL)) {
|
o = retobs[i];
|
||||||
relinkob(o, target->pack); // move to pack
|
getobname(o, obname, o->amt);
|
||||||
if (isplayer(target)) {
|
if (!hasflag(o->flags, F_IMPASSABLE) && canpickup(target, o, ALL)) {
|
||||||
msgnocap("%c - %s.", o->letter, obname);
|
// you gain it.
|
||||||
} else {
|
relinkob(o, target->pack); // move to pack
|
||||||
msg("%s is gifted with %s.", lfname, obname);
|
if (isplayer(target)) {
|
||||||
}
|
msgnocap("%c - %s.", o->letter, obname);
|
||||||
} else {
|
} else {
|
||||||
// couldn't pick it up - try to place on ground!
|
msg("%s is gifted with %s.", lfname, obname);
|
||||||
// impassable?
|
|
||||||
if (hasflag(o->flags, F_IMPASSABLE)) {
|
|
||||||
cell_t *newloc;
|
|
||||||
// if so, don't put it where the player is!
|
|
||||||
newloc = getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
|
||||||
o = relinkob(o, newloc->obpile);
|
|
||||||
}
|
|
||||||
if (o) {
|
|
||||||
noise(caster->cell, NULL, 1, "something hitting the ground.", NULL);
|
|
||||||
if (!isblind(caster)) {
|
|
||||||
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// couldn't make it appear
|
// can't pick this up...
|
||||||
msg("The air in front of %s seems to ripple for a moment.", lfname);
|
|
||||||
|
// impassable? goes in a nearby cell instead of at your feet.
|
||||||
|
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||||
|
cell_t *newloc;
|
||||||
|
// if so, don't put it where the player is!
|
||||||
|
newloc = real_getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL);
|
||||||
|
o = relinkob(o, newloc->obpile);
|
||||||
|
}
|
||||||
|
if (o) {
|
||||||
|
noise(caster->cell, NULL, 1, "something hitting the ground.", NULL);
|
||||||
|
if (!isblind(caster)) {
|
||||||
|
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ob exists but couldn't make it appear
|
||||||
|
msg("The air in front of %s seems to ripple for a moment.", lfname);
|
||||||
|
break; // don't process any more.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
42
text.c
42
text.c
|
@ -208,6 +208,20 @@ char *getdrunktext(flag_t *drunkflag) {
|
||||||
return "??drunk??";
|
return "??drunk??";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *getrarityname(enum RARITY rr) {
|
||||||
|
switch (rr) {
|
||||||
|
case RR_UNIQUE: return "Unique";
|
||||||
|
case RR_NEVER: return "Never";
|
||||||
|
case RR_VERYRARE: return "Very Rare";
|
||||||
|
case RR_RARE: return "Rare";
|
||||||
|
case RR_UNCOMMON: return "Uncommon";
|
||||||
|
case RR_COMMON: return "Common";
|
||||||
|
case RR_NONE: return "None";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "?unknownrarity?";
|
||||||
|
}
|
||||||
|
|
||||||
char *getsizetext(enum LFSIZE sz) {
|
char *getsizetext(enum LFSIZE sz) {
|
||||||
switch (sz) {
|
switch (sz) {
|
||||||
case SZ_ENORMOUS:
|
case SZ_ENORMOUS:
|
||||||
|
@ -458,6 +472,19 @@ char *numtotext(int num, char *buf) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns posiiton AFTER end of copied text, or NULL on failure.
|
||||||
|
char *readuntil(char *retbuf, char *src, char delim) {
|
||||||
|
char *bp,*p;
|
||||||
|
bp = retbuf;
|
||||||
|
for (p=src; *p && (*p != delim); p++) {
|
||||||
|
*bp = *p;
|
||||||
|
bp++;
|
||||||
|
}
|
||||||
|
p++; // go past delimiter
|
||||||
|
*bp = '\0'; // nul-terminate buffer
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// convert number to roman numerals
|
// convert number to roman numerals
|
||||||
// only copes with 1-10
|
// only copes with 1-10
|
||||||
char *roman(int num) {
|
char *roman(int num) {
|
||||||
|
@ -546,6 +573,21 @@ char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv) {
|
||||||
return *out;
|
return *out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int streq(char *a, char *b) {
|
||||||
|
if (!a || !b) return B_FALSE;
|
||||||
|
return !strcmp(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strstarts(char *a, char *prefix) {
|
||||||
|
if (!a || !prefix) return NULL;
|
||||||
|
|
||||||
|
if (strstr(a, prefix) == a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int strpixmatch(char *haystack, char *needle) {
|
int strpixmatch(char *haystack, char *needle) {
|
||||||
int matched = B_FALSE;
|
int matched = B_FALSE;
|
||||||
char *hword, *nword, *hcont,*ncont;
|
char *hword, *nword, *hcont,*ncont;
|
||||||
|
|
4
text.h
4
text.h
|
@ -10,6 +10,7 @@ char *getattrname(enum ATTRIB att);
|
||||||
int gethitconferlifetime(char *text, int *min, int *max);
|
int gethitconferlifetime(char *text, int *min, int *max);
|
||||||
char *getpossessive(char *text);
|
char *getpossessive(char *text);
|
||||||
char *getdrunktext(flag_t *drunkflag);
|
char *getdrunktext(flag_t *drunkflag);
|
||||||
|
char *getrarityname(enum RARITY rr);
|
||||||
char *getsizetext(enum LFSIZE sz);
|
char *getsizetext(enum LFSIZE sz);
|
||||||
char *gettimetext(char *retbuf);
|
char *gettimetext(char *retbuf);
|
||||||
char *gettimetextfuzzy(char *retbuf, int wantpm);
|
char *gettimetextfuzzy(char *retbuf, int wantpm);
|
||||||
|
@ -21,11 +22,14 @@ char *makeuppercase(char *text);
|
||||||
int needses(char *text);
|
int needses(char *text);
|
||||||
char *noprefix(char *obname);
|
char *noprefix(char *obname);
|
||||||
char *numtotext(int num, char *buf);
|
char *numtotext(int num, char *buf);
|
||||||
|
char *readuntil(char *retbuf, char *src, char delim);
|
||||||
char *roman(int num);
|
char *roman(int num);
|
||||||
int speedtokph(int speed);
|
int speedtokph(int speed);
|
||||||
void splittime(int *hours, int *mins, int *secs);
|
void splittime(int *hours, int *mins, int *secs);
|
||||||
char *strrep(char *text, char *oldtok, char *newtok, int *rv);
|
char *strrep(char *text, char *oldtok, char *newtok, int *rv);
|
||||||
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
|
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
|
||||||
|
int streq(char *a, char *b);
|
||||||
|
char *strstarts(char *a, char *prefix);
|
||||||
int strpixmatch(char *haystack, char *needle);
|
int strpixmatch(char *haystack, char *needle);
|
||||||
int texttodice(char *text, int *ndice, int *nsides, int *bonus);
|
int texttodice(char *text, int *ndice, int *nsides, int *bonus);
|
||||||
void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range);
|
void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range);
|
||||||
|
|
Loading…
Reference in New Issue