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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
6
io.c
6
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) {
|
||||||
|
// note: much slower
|
||||||
|
mvwprintw(gamewin, y, x, "%lc", g->ch);
|
||||||
|
} else {
|
||||||
mvwaddch(gamewin, y, x, g->ch);
|
mvwaddch(gamewin, y, x, g->ch);
|
||||||
|
}
|
||||||
unsetcol(gamewin, col);
|
unsetcol(gamewin, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
lf.c
55
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) {
|
||||||
|
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];
|
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)) {
|
||||||
|
|
617
map.c
617
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
|
|
||||||
createroom(map, bestx,besty, w,h, i);
|
|
||||||
|
|
||||||
/*
|
|
||||||
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;
|
if (!roomvault[i]) {
|
||||||
} else {
|
// just do a normal room
|
||||||
roomspecial[i] = B_FALSE;
|
createroom(map, i, NA, NA, NULL, NULL, &roomw[i],&roomh[i]);
|
||||||
}
|
roomvault[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,6 +1267,7 @@ 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++) {
|
||||||
|
if (!roomvault[i] || hasflag(roomvault[i]->flags, F_AUTOPOPULATE)) {
|
||||||
int numobsmin,numobsmax,numobs,n;
|
int numobsmin,numobsmax,numobs,n;
|
||||||
int maxpillars;
|
int maxpillars;
|
||||||
|
|
||||||
|
@ -1172,19 +1290,10 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (roomspecial[i]) {
|
|
||||||
// chance is increased
|
|
||||||
numobsmin = (roomw[i]*roomh[i]) / 4 ;
|
|
||||||
numobsmax = (roomw[i]*roomh[i]) / 2 ;
|
|
||||||
} else {
|
|
||||||
*/
|
|
||||||
numobsmin = 0;
|
numobsmin = 0;
|
||||||
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||||
numobsmax = MAXOF(roomw[i],roomh[i]);
|
numobsmax = MAXOF(roomw[i],roomh[i]);
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
// then objects/monsters
|
// then objects/monsters
|
||||||
if (numobsmax <= numobsmin) {
|
if (numobsmax <= numobsmin) {
|
||||||
numobs = numobsmin;
|
numobs = numobsmin;
|
||||||
|
@ -1225,9 +1334,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // 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);
|
||||||
|
|
58
move.c
58
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,11 +1768,15 @@ 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) {
|
||||||
|
// go somewhere nearby
|
||||||
|
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
|
||||||
|
if (!c) {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
msg("You feel a wrenching sensation.");
|
msg("You feel a wrenching sensation.");
|
||||||
}
|
}
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isplayer(lf) && cansee(player, lf)) {
|
if (!isplayer(lf) && cansee(player, lf)) {
|
||||||
getlfname(lf, buf);
|
getlfname(lf, buf);
|
||||||
|
@ -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);
|
||||||
|
if (cell) {
|
||||||
// we now know there is a wall there.
|
// we now know there is a wall there.
|
||||||
setcellknown(cell, B_FALSE);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
483
objects.c
483
objects.c
|
@ -73,6 +73,7 @@ enum OBCLASS sortorder[] = {
|
||||||
OC_ROCK,
|
OC_ROCK,
|
||||||
OC_FLORA,
|
OC_FLORA,
|
||||||
OC_DFEATURE,
|
OC_DFEATURE,
|
||||||
|
OC_TRAP,
|
||||||
OC_MISC,
|
OC_MISC,
|
||||||
// omitting OC_SPELL and OC_JUMP because it shouldn't ever be displayed
|
// omitting OC_SPELL and OC_JUMP because it shouldn't ever be displayed
|
||||||
OC_NULL
|
OC_NULL
|
||||||
|
@ -370,6 +371,7 @@ objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int gl
|
||||||
// props
|
// props
|
||||||
a->id = id;
|
a->id = id;
|
||||||
a->name = strdup(name);
|
a->name = strdup(name);
|
||||||
|
a->nnouns = 0;
|
||||||
a->desc = strdup(desc);
|
a->desc = strdup(desc);
|
||||||
a->glyph.ch = glyph;
|
a->glyph.ch = glyph;
|
||||||
a->glyph.colour = glyphcolour;
|
a->glyph.colour = glyphcolour;
|
||||||
|
@ -378,6 +380,12 @@ objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int gl
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addocnoun(objectclass_t *oc, char *text) {
|
||||||
|
assert (oc->nnouns < MAXOCNOUNS);
|
||||||
|
oc->noun[oc->nnouns] = strdup(text);
|
||||||
|
oc->nnouns++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create a new object, stacking ok
|
// create a new object, stacking ok
|
||||||
|
@ -402,17 +410,27 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
char *localname;
|
char *localname;
|
||||||
int wantblessed = B_UNCURSED;
|
int wantblessed = B_UNCURSED;
|
||||||
race_t *corpserace = NULL;
|
race_t *corpserace = NULL;
|
||||||
|
int dorandombrand = B_FALSE;
|
||||||
|
brand_t *wantbrand = NULL;
|
||||||
brand_t *br;
|
brand_t *br;
|
||||||
obmod_t *om;
|
obmod_t *om;
|
||||||
obmod_t *wantom[MAXOBMODS];
|
obmod_t *wantom[MAXOBMODS];
|
||||||
int nom = 0;
|
int nom = 0;
|
||||||
int n;
|
int n;
|
||||||
int bookcontents = -1;
|
int bookcontents = -1;
|
||||||
|
int wantrarity = RR_NONE;
|
||||||
|
int wantgoodness = G_NA;
|
||||||
|
int donesomething;
|
||||||
|
object_t *addedob[MAXPILEOBS];
|
||||||
|
int nadded = 0;
|
||||||
|
// for doors
|
||||||
|
enum FLAG doorflag[5];
|
||||||
|
int ndoorflags = 0;
|
||||||
|
|
||||||
|
addedob[0] = NULL; // just in case we don't add any
|
||||||
|
|
||||||
localname = strdup(name);
|
localname = strdup(name);
|
||||||
|
|
||||||
|
|
||||||
// check for premods. eg. "flaming xxx" "frozen xxx" etc
|
// check for premods. eg. "flaming xxx" "frozen xxx" etc
|
||||||
for (om = firstobmod ; om ; om = om->next) {
|
for (om = firstobmod ; om ; om = om->next) {
|
||||||
if (db) dblog("DB: checking for '%s' in '%s'",om->prefix, localname);
|
if (db) dblog("DB: checking for '%s' in '%s'",om->prefix, localname);
|
||||||
|
@ -431,6 +449,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
|
|
||||||
if (where->owner && hasflag(where->owner->flags, F_NOPACK)) {
|
if (where->owner && hasflag(where->owner->flags, F_NOPACK)) {
|
||||||
if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name);
|
if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name);
|
||||||
|
nretobs = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,23 +504,94 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
howmany = 1;
|
howmany = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// new objects after the game starts have unknown
|
|
||||||
// blessed/cursed status, so we can never stack them
|
// handle prefixes. strip them off as we go.
|
||||||
// if (gamestarted && !hasflag(player->flags, F_DETECTAURAS)) {
|
donesomething = B_TRUE;
|
||||||
if (strstr(p, "blessed") || strstr(p, "holy water")) {
|
while (donesomething) {
|
||||||
|
donesomething = B_FALSE;
|
||||||
|
if (strstarts(p, "blessed ")) {
|
||||||
if (db) dblog("DB: ob is blessed (%s)",p);
|
if (db) dblog("DB: ob is blessed (%s)",p);
|
||||||
wantblessed = B_BLESSED;
|
wantblessed = B_BLESSED;
|
||||||
//canstack = B_FALSE;
|
p += strlen("blessed ");
|
||||||
} else if (strstr(p, "uncursed")) {
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "uncursed ")) {
|
||||||
if (db) dblog("DB: ob is uncursed (%s)",p);
|
if (db) dblog("DB: ob is uncursed (%s)",p);
|
||||||
wantblessed = B_UNCURSED;
|
wantblessed = B_UNCURSED;
|
||||||
} else if (strstr(p, "cursed") || strstr(p, "incompetence")) {
|
p += strlen("uncursed ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "cursed ")) {
|
||||||
if (db) dblog("DB: ob is cursed (%s)",p);
|
if (db) dblog("DB: ob is cursed (%s)",p);
|
||||||
wantblessed = B_CURSED;
|
wantblessed = B_CURSED;
|
||||||
//canstack = B_FALSE;
|
p += strlen("cursed ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
// door flags
|
||||||
|
} else if (strstarts(p, "locked ")) {
|
||||||
|
doorflag[ndoorflags++] = F_LOCKED;
|
||||||
|
p += strlen("locked ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "jammed ")) {
|
||||||
|
doorflag[ndoorflags++] = F_JAMMED;
|
||||||
|
p += strlen("jammed ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "secret ")) {
|
||||||
|
doorflag[ndoorflags++] = F_SECRET;
|
||||||
|
p += strlen("secret ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
// rarity
|
||||||
|
} else if (strstarts(p, "common ")) {
|
||||||
|
wantrarity = RR_COMMON;
|
||||||
|
p += strlen("common ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "uncommon ")) {
|
||||||
|
wantrarity = RR_UNCOMMON;
|
||||||
|
p += strlen("uncommon ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "rare ")) {
|
||||||
|
wantrarity = RR_RARE;
|
||||||
|
p += strlen("rare ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "very rare ")) {
|
||||||
|
wantrarity = RR_VERYRARE;
|
||||||
|
p += strlen("very rare ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
// weapon "goodness"
|
||||||
|
} else if (strstarts(p, "average ")) {
|
||||||
|
wantgoodness = G_AVERAGE;
|
||||||
|
p += strlen("average ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "good ")) {
|
||||||
|
wantgoodness = G_GOOD;
|
||||||
|
if (onein(4)) wantblessed = B_BLESSED;
|
||||||
|
p += strlen("good ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "great ")) {
|
||||||
|
wantgoodness = G_GREAT;
|
||||||
|
if (onein(3)) wantblessed = B_BLESSED;
|
||||||
|
if (onein(10)) dorandombrand = B_TRUE;
|
||||||
|
p += strlen("great ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
} else if (strstarts(p, "excellent ")) {
|
||||||
|
wantgoodness = G_EXCELLENT;
|
||||||
|
if (onein(2)) wantblessed = B_BLESSED;
|
||||||
|
if (onein(4)) dorandombrand = B_TRUE;
|
||||||
|
p += strlen("excellent ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
// brands
|
||||||
|
} else if (strstarts(p, "branded ")) {
|
||||||
|
dorandombrand = B_TRUE;
|
||||||
|
p += strlen("branded ");
|
||||||
|
donesomething = B_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
|
if (strstr(p, "holy water") || strstr(p, "incompetence")) {
|
||||||
|
if (db) dblog("DB: ob is blessed (%s)",p);
|
||||||
|
wantblessed = B_BLESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////
|
||||||
|
// handle special object names
|
||||||
|
////////////////////////////////////
|
||||||
if (strstr(p, "corpse")) {
|
if (strstr(p, "corpse")) {
|
||||||
int len;
|
int len;
|
||||||
char racename[BUFLEN];
|
char racename[BUFLEN];
|
||||||
|
@ -556,8 +646,41 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ot = findot(OT_MANUAL);
|
ot = findot(OT_MANUAL);
|
||||||
|
////////////////////////////////////
|
||||||
|
// also handle generic names
|
||||||
|
////////////////////////////////////
|
||||||
} else {
|
} else {
|
||||||
// make sure we can find the requested object type
|
objectclass_t *oc;
|
||||||
|
char tempname[BUFLEN];
|
||||||
|
int found = B_FALSE;
|
||||||
|
|
||||||
|
// check for things like "weapon" or "random ring"
|
||||||
|
for (oc = objectclass; oc ; oc = oc->next) {
|
||||||
|
int i;
|
||||||
|
int matched = B_FALSE;
|
||||||
|
for (i = 0; i < oc->nnouns; i++) {
|
||||||
|
sprintf(tempname, "random %s", oc->noun[i]);
|
||||||
|
if (strstarts(p, tempname) || streq(p, oc->noun[i])) {
|
||||||
|
matched = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
int minrarity,maxrarity;
|
||||||
|
// want a specific rarity?
|
||||||
|
rrtorarity(wantrarity, &minrarity, &maxrarity);
|
||||||
|
|
||||||
|
ot = getrandomobofclass(oc->id, minrarity, maxrarity);
|
||||||
|
if (ot) {
|
||||||
|
found = B_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
// look up the object name
|
||||||
if (db) dblog("DB: Looking for object name '%s'", p );
|
if (db) dblog("DB: Looking for object name '%s'", p );
|
||||||
ot = findotn(p);
|
ot = findotn(p);
|
||||||
if (!ot) {
|
if (!ot) {
|
||||||
|
@ -566,8 +689,11 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (db) dblog("DB: FOUND: ot->name = '%s'", ot->name );
|
if (db) dblog("DB: FOUND: ot->name = '%s'", ot->name );
|
||||||
|
|
||||||
|
// we now have the objecttype.
|
||||||
|
|
||||||
// override blessed status from flags...
|
// override blessed status from flags...
|
||||||
f = hasflag(ot->flags, F_STARTBLESSED);
|
f = hasflag(ot->flags, F_STARTBLESSED);
|
||||||
if (f) {
|
if (f) {
|
||||||
|
@ -576,11 +702,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
|
|
||||||
// don't give nopickup objects to lifeforms
|
// don't give nopickup objects to lifeforms
|
||||||
if (hasflag(ot->flags, F_NOPICKUP) && where->owner) {
|
if (hasflag(ot->flags, F_NOPICKUP) && where->owner) {
|
||||||
|
nretobs = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ot->obclass->id == OC_SPELL) {
|
if (ot->obclass->id == OC_SPELL) {
|
||||||
if (db) dblog("DB: Cannot give a spell object! object name '%s'", p );
|
if (db) dblog("DB: Cannot give a spell object! object name '%s'", p );
|
||||||
|
nretobs = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,6 +723,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
// does this unique ob already exist?
|
// does this unique ob already exist?
|
||||||
if (obexists(ot->id)) {
|
if (obexists(ot->id)) {
|
||||||
if (db) dblog("DB: Unique ob %s already exists!", p );
|
if (db) dblog("DB: Unique ob %s already exists!", p );
|
||||||
|
nretobs = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,10 +744,22 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
// does the pile already contain one?
|
// does the pile already contain one?
|
||||||
existob = canstacknewot(where, ot);
|
existob = canstacknewot(where, ot);
|
||||||
if (existob) {
|
if (existob) {
|
||||||
|
int n,found = B_FALSE;
|
||||||
if (db) dblog("DB: STACK FOUND (%d x %s). Adding %d obs to existing stack.",existob->amt, existob->type->name, howmany);
|
if (db) dblog("DB: STACK FOUND (%d x %s). Adding %d obs to existing stack.",existob->amt, existob->type->name, howmany);
|
||||||
existob->amt++;
|
existob->amt++;
|
||||||
added = B_TRUE;
|
added = B_TRUE;
|
||||||
o = existob;
|
o = existob;
|
||||||
|
|
||||||
|
// if this isn't already in our list of added obs, add it
|
||||||
|
for (n = 0; n < nadded; n++) {
|
||||||
|
if (addedob[n] == o) {
|
||||||
|
found = B_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
addedob[nadded++] = o;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (db) dblog("DB: No stacks found.");
|
if (db) dblog("DB: No stacks found.");
|
||||||
}
|
}
|
||||||
|
@ -715,6 +856,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
setblessed(o, wantblessed);
|
setblessed(o, wantblessed);
|
||||||
}
|
}
|
||||||
o->blessknown = B_FALSE;
|
o->blessknown = B_FALSE;
|
||||||
|
|
||||||
|
addedob[nadded++] = o;
|
||||||
|
|
||||||
if (canstack) {
|
if (canstack) {
|
||||||
// stop looping through
|
// stop looping through
|
||||||
break;
|
break;
|
||||||
|
@ -722,6 +866,43 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
need to do the below for _all_ objects added!
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < nadded; i++) {
|
||||||
|
o = addedob[i];
|
||||||
|
|
||||||
|
// fill in door flags
|
||||||
|
if (ndoorflags && isdoor(o, NULL)) {
|
||||||
|
int n;
|
||||||
|
for (n = 0; n < ndoorflags; n++) {
|
||||||
|
cell_t *c;
|
||||||
|
int val[3];
|
||||||
|
c = getoblocation(o);
|
||||||
|
// fill in flag vals
|
||||||
|
switch (doorflag[n]) {
|
||||||
|
case F_LOCKED:
|
||||||
|
val[0] = B_TRUE;
|
||||||
|
val[1] = getdoorlockdiff(c->map->depth);
|
||||||
|
val[2] = NA;
|
||||||
|
break;
|
||||||
|
case F_JAMMED:
|
||||||
|
val[0] = rnd(1,c->map->depth+3);
|
||||||
|
val[1] = NA;
|
||||||
|
val[2] = NA;
|
||||||
|
break;
|
||||||
|
case F_SECRET:
|
||||||
|
val[0] = getdoorsecretdiff(c->map->depth);
|
||||||
|
val[1] = NA;
|
||||||
|
val[2] = NA;
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
addflag(o->flags, doorflag[n], val[0], val[1], val[2], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fill in book types
|
// fill in book types
|
||||||
if (o && (o->type->obclass->id == OC_BOOK)) {
|
if (o && (o->type->obclass->id == OC_BOOK)) {
|
||||||
hiddenname_t *hn,*selhn = NULL;
|
hiddenname_t *hn,*selhn = NULL;
|
||||||
|
@ -916,6 +1097,20 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chance of masterwork based on wantgoodness
|
||||||
|
switch (wantgoodness) {
|
||||||
|
case G_GREAT:
|
||||||
|
if (onein(6)) {
|
||||||
|
wantom[nom++] = findobmod(OM_MASTERWORK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_EXCELLENT:
|
||||||
|
if (onein(3)) {
|
||||||
|
wantom[nom++] = findobmod(OM_MASTERWORK);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
for (n = 0; n < nom; n++) {
|
for (n = 0; n < nom; n++) {
|
||||||
// add flags from obmod
|
// add flags from obmod
|
||||||
applyobmod(o, wantom[n]);
|
applyobmod(o, wantom[n]);
|
||||||
|
@ -1033,6 +1228,30 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
bonus -= atoi(numbuf);
|
bonus -= atoi(numbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if no bonus yet, get one based on 'wantgoodness'
|
||||||
|
if (!bonus) {
|
||||||
|
switch (wantgoodness) {
|
||||||
|
case G_GOOD: // 1 - 2
|
||||||
|
bonus = 1;
|
||||||
|
if (onein(2)) bonus++;
|
||||||
|
break;
|
||||||
|
case G_GREAT: // 1 - 3
|
||||||
|
bonus = 1;
|
||||||
|
while (onein(2) && (bonus < 3)) {
|
||||||
|
bonus++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case G_EXCELLENT: // 1 - 4
|
||||||
|
bonus = 1;
|
||||||
|
while (onein(2) && (bonus < 4)) {
|
||||||
|
bonus++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // no bonus
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bonus) {
|
if (bonus) {
|
||||||
if (hasflag(o->flags, F_ENCHANTABLE)) {
|
if (hasflag(o->flags, F_ENCHANTABLE)) {
|
||||||
// for swords, armour etc
|
// for swords, armour etc
|
||||||
|
@ -1076,24 +1295,31 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for postmods. eg. "xxx of pyromania"
|
// now apply a random brand if we wanted one
|
||||||
|
if (dorandombrand) {
|
||||||
|
wantbrand = getrandombrandfor(ot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for specific brands. eg. "xxx of pyromania"
|
||||||
|
// NOTE: this will override any random brands from "branded"
|
||||||
for (br = firstbrand ; br ; br = br->next) {
|
for (br = firstbrand ; br ; br = br->next) {
|
||||||
if (strstr(name, br->suffix)) {
|
if (strstr(name, br->suffix)) {
|
||||||
// does this brand apply to this objecttype?
|
// does this brand apply to this objecttype?
|
||||||
if (brandappliesto(br, o->type)) {
|
if (brandappliesto(br, o->type)) {
|
||||||
copyflags(o->flags, br->flags, FROMBRAND);
|
wantbrand = br;
|
||||||
addflag(o->flags, F_HASBRAND, br->id, NA, NA, NULL);
|
break;
|
||||||
} else {
|
|
||||||
// doesn't exist!
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wantbrand) {
|
||||||
|
if (brandappliesto(wantbrand, o->type)) {
|
||||||
|
copyflags(o->flags, wantbrand->flags, FROMBRAND);
|
||||||
|
addflag(o->flags, F_HASBRAND, wantbrand->id, NA, NA, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
free(localname);
|
|
||||||
|
|
||||||
if (where->owner) {
|
if (where->owner) {
|
||||||
// new owner gains "hold confer" flags conferred by this object
|
// new owner gains "hold confer" flags conferred by this object
|
||||||
|
@ -1135,9 +1361,22 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||||
needredraw = B_TRUE;
|
needredraw = B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // end foreach added object
|
||||||
|
|
||||||
// return the last object given
|
// don't need the name anymore.
|
||||||
return o;
|
free(localname);
|
||||||
|
|
||||||
|
// populate retobs
|
||||||
|
for (i = 0; i < nadded; i++) {
|
||||||
|
if (addedob[i]) {
|
||||||
|
retobs[i] = addedob[i];
|
||||||
|
retobscount[i] = addedob[i]->amt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nretobs = nadded;
|
||||||
|
|
||||||
|
// return the first object given
|
||||||
|
return addedob[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1225,7 +1464,6 @@ obpile_t *addobpile(lifeform_t *owner, cell_t *where) {
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes) {
|
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes) {
|
||||||
int x,y;
|
int x,y;
|
||||||
objecttype_t *ot;
|
objecttype_t *ot;
|
||||||
|
@ -2082,6 +2320,29 @@ void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dumpobrarity(void) {
|
||||||
|
enum RARITY rr;
|
||||||
|
objecttype_t *ot;
|
||||||
|
flag_t *f;
|
||||||
|
int min,max;
|
||||||
|
|
||||||
|
for (rr = RR_COMMON; rr <= RR_VERYRARE; rr++) {
|
||||||
|
rrtorarity(rr, &min, &max);
|
||||||
|
dblog("Obs with rarity %s:", getrarityname(rr));
|
||||||
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||||
|
if (ot->obclass->id == OC_ARMOUR) {
|
||||||
|
int thisrar;
|
||||||
|
f = hasflag(ot->flags, F_RARITY);
|
||||||
|
if (!f) continue;
|
||||||
|
thisrar = f->val[1];
|
||||||
|
|
||||||
|
if ((thisrar >= min) && (thisrar <= max)) {
|
||||||
|
dblog("\t%s", ot->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void explodeob(object_t *o, flag_t *f, int bigness) {
|
void explodeob(object_t *o, flag_t *f, int bigness) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
|
@ -2672,15 +2933,15 @@ int getobvalue(object_t *o) {
|
||||||
}
|
}
|
||||||
// one-off magical effects (linkspell) - use spell price
|
// one-off magical effects (linkspell) - use spell price
|
||||||
if (f->id == F_LINKSPELL) {
|
if (f->id == F_LINKSPELL) {
|
||||||
// spelllevel^2 * 20
|
|
||||||
price += (pow(getspelllevel(f->val[0]), 2) * 20);
|
|
||||||
// ...and spellbooks then cost triple
|
|
||||||
if (o->type->obclass->id == OC_BOOK) {
|
if (o->type->obclass->id == OC_BOOK) {
|
||||||
price *= 3;
|
price += (pow(getspelllevel(f->val[0]), 2) * 30);
|
||||||
} else if (o->type->obclass->id == OC_SCROLL) {
|
} else if (o->type->obclass->id == OC_SCROLL) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
price += (pow(getspelllevel(f->val[0]), 2) * 2);
|
||||||
|
} else if (o->type->obclass->id == OC_POTION) {
|
||||||
|
price += (pow(getspelllevel(f->val[0]), 2) * 15);
|
||||||
} else if (o->type->obclass->id == OC_WAND) {
|
} else if (o->type->obclass->id == OC_WAND) {
|
||||||
price *= 2.25;
|
price += (pow(getspelllevel(f->val[0]), 2) * 22);
|
||||||
}
|
}
|
||||||
} else if (f->id == F_MANUALOF) {
|
} else if (f->id == F_MANUALOF) {
|
||||||
price *= 124;
|
price *= 124;
|
||||||
|
@ -2756,6 +3017,8 @@ int getobvalue(object_t *o) {
|
||||||
|
|
||||||
// minimum
|
// minimum
|
||||||
if (price < 1) price = 1;
|
if (price < 1) price = 1;
|
||||||
|
|
||||||
|
price = ((int)price * o->amt);
|
||||||
return (int) price;
|
return (int) price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2828,6 +3091,72 @@ object_t *getrandomammo(lifeform_t *lf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brand_t *getrandombrandfor(objecttype_t *ot) {
|
||||||
|
brand_t *br, **poss;
|
||||||
|
brand_t *result = NULL;
|
||||||
|
int numbr;
|
||||||
|
int nposs = 0;
|
||||||
|
|
||||||
|
// count number of brands
|
||||||
|
numbr = 0;
|
||||||
|
for (br = firstbrand ; br ; br = br->next) {
|
||||||
|
numbr++;
|
||||||
|
}
|
||||||
|
poss = malloc(numbr * sizeof(brand_t *));
|
||||||
|
|
||||||
|
for (br = firstbrand ; br ; br = br->next) {
|
||||||
|
if (brandappliesto(br, ot)) {
|
||||||
|
poss[nposs] = br;
|
||||||
|
nposs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nposs > 0) {
|
||||||
|
result = poss[rnd(0,nposs-1)];
|
||||||
|
}
|
||||||
|
free(poss);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity) {
|
||||||
|
objecttype_t *ot;
|
||||||
|
int count = 0,sel,n;
|
||||||
|
flag_t *f;
|
||||||
|
|
||||||
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||||
|
if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) {
|
||||||
|
f = hasflag(ot->flags, F_RARITY);
|
||||||
|
if (f) {
|
||||||
|
if ( ((minrarity == NA) || (f->val[1] >= minrarity)) &&
|
||||||
|
((maxrarity == NA) || (f->val[1] <= maxrarity)) ) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count <= 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
sel = rnd(1,count);
|
||||||
|
n = 0;
|
||||||
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||||
|
if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) {
|
||||||
|
f = hasflag(ot->flags, F_RARITY);
|
||||||
|
if (f) {
|
||||||
|
if ( ((minrarity == NA) || (f->val[1] >= minrarity)) &&
|
||||||
|
((maxrarity == NA) || (f->val[1] <= maxrarity)) ) {
|
||||||
|
n++;
|
||||||
|
if (n == sel) {
|
||||||
|
return ot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char *getdamname(enum DAMTYPE damtype) {
|
char *getdamname(enum DAMTYPE damtype) {
|
||||||
switch (damtype) {
|
switch (damtype) {
|
||||||
case DT_ALL: return "all damage";
|
case DT_ALL: return "all damage";
|
||||||
|
@ -4041,29 +4370,9 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
||||||
// if so...
|
// if so...
|
||||||
strcpy(brandname, "");
|
strcpy(brandname, "");
|
||||||
if (rnd(1,100) <= depth) {
|
if (rnd(1,100) <= depth) {
|
||||||
brand_t *om, **poss;
|
brand_t *br;
|
||||||
int numom;
|
br = getrandombrandfor(ot);
|
||||||
int nposs = 0;
|
if (br) strcpy(brandname, br->suffix);
|
||||||
|
|
||||||
// count number of brands
|
|
||||||
numom = 0;
|
|
||||||
for (om = firstbrand ; om ; om = om->next) {
|
|
||||||
numom++;
|
|
||||||
}
|
|
||||||
poss = malloc(numom * sizeof(brand_t *));
|
|
||||||
|
|
||||||
for (om = firstbrand ; om ; om = om->next) {
|
|
||||||
if (brandappliesto(om, ot)) {
|
|
||||||
poss[nposs] = om;
|
|
||||||
nposs++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nposs > 0) {
|
|
||||||
om = poss[rnd(0,nposs-1)];
|
|
||||||
strcpy(brandname, om->suffix);
|
|
||||||
}
|
|
||||||
free(poss);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4101,13 +4410,13 @@ int getobrarity(object_t *o) {
|
||||||
if (m) {
|
if (m) {
|
||||||
f = hasflagval(o->flags, F_RARITY,m->habitat, NA, NA, NULL);
|
f = hasflagval(o->flags, F_RARITY,m->habitat, NA, NA, NULL);
|
||||||
if (f) {
|
if (f) {
|
||||||
return f->val[0];
|
return f->val[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// any rarity value at all?
|
// any rarity value at all?
|
||||||
f = hasflag(o->flags, F_RARITY);
|
f = hasflag(o->flags, F_RARITY);
|
||||||
if (f) {
|
if (f) {
|
||||||
return f->val[0];
|
return f->val[1];
|
||||||
}
|
}
|
||||||
// ie. doesn't randomly appear
|
// ie. doesn't randomly appear
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4696,8 +5005,11 @@ void initobjects(void) {
|
||||||
// object classes
|
// object classes
|
||||||
addoc(OC_DFEATURE, "Dungeon Features", "Doors, etc.", '\\', C_GREY);
|
addoc(OC_DFEATURE, "Dungeon Features", "Doors, etc.", '\\', C_GREY);
|
||||||
addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY);
|
addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY);
|
||||||
|
addoc(OC_TRAP, "Trap", "Fiendish traps.", '^', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "trap");
|
||||||
addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY);
|
addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY);
|
||||||
addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY);
|
addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "scroll");
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_STACKABLE, 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);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -4707,6 +5019,7 @@ void initobjects(void) {
|
||||||
//addflag(lastobjectclass->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy");
|
//addflag(lastobjectclass->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy");
|
||||||
|
|
||||||
addoc(OC_WAND, "Wands", "A limited-use magical wand which casts the imbued spell.", '/', C_GREY);
|
addoc(OC_WAND, "Wands", "A limited-use magical wand which casts the imbued spell.", '/', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "wand");
|
||||||
addflag(lastobjectclass->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -4714,34 +5027,45 @@ void initobjects(void) {
|
||||||
addflag(lastobjectclass->flags, F_RNDCHARGES, 1, 8, NA, NULL);
|
addflag(lastobjectclass->flags, F_RNDCHARGES, 1, 8, NA, NULL);
|
||||||
|
|
||||||
addoc(OC_POTION, "Potions", "A strange concoction contained within a small flask.", '!', C_GREY);
|
addoc(OC_POTION, "Potions", "A strange concoction contained within a small flask.", '!', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "potion");
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_STACKABLE, 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);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_POURABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_POURABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_RING, "Rings", "A circular band, worn on the finger.", '=', C_GREY);
|
addoc(OC_RING, "Rings", "A circular band, worn on the finger.", '=', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "ring");
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTHAND, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTHAND, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_GOESON, BP_LEFTHAND, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_GOESON, BP_LEFTHAND, NA, NA, NULL);
|
||||||
addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY);
|
addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "weapon");
|
||||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
||||||
addoc(OC_ARMOUR, "Armour/Clothing", "Protective gear.", ']', C_GREY);
|
addoc(OC_ARMOUR, "Armour/Clothing", "Protective gear.", ']', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "armour");
|
||||||
|
addocnoun(lastobjectclass, "clothing");
|
||||||
|
addocnoun(lastobjectclass, "clothes");
|
||||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_BLOODSTAINED, 17, NA, NULL);
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_BLOODSTAINED, 17, NA, NULL);
|
||||||
addoc(OC_MISSILE, "Missiles/Ammunition", "An instrument used for the purpose of causing harm or death.", ';', C_GREY);
|
addoc(OC_MISSILE, "Missiles/Ammunition", "An instrument used for the purpose of causing harm or death.", ';', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "missile");
|
||||||
|
addocnoun(lastobjectclass, "ammo");
|
||||||
|
addocnoun(lastobjectclass, "ammunition");
|
||||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_STACKABLE, 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);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_FLORA, "Plants", "All kinds of plants and foliage", ',', C_GREEN);
|
addoc(OC_FLORA, "Plants", "All kinds of plants and foliage", ',', C_GREEN);
|
||||||
|
addocnoun(lastobjectclass, "plant");
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
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_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_GREY);
|
||||||
addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY);
|
addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "food");
|
||||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY);
|
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY);
|
||||||
|
@ -4751,9 +5075,12 @@ void initobjects(void) {
|
||||||
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_OBHPDRAIN, 1, DT_DECAY, NA, NULL); // ie. corpses last for 50 turns
|
addflag(lastobjectclass->flags, F_OBHPDRAIN, 1, DT_DECAY, NA, NULL); // ie. corpses last for 50 turns
|
||||||
addoc(OC_TECH, "Technology", "A strange piece of futuristic technology.", '~', C_GREY);
|
addoc(OC_TECH, "Technology", "A strange piece of futuristic technology.", '~', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "technology");
|
||||||
|
addocnoun(lastobjectclass, "tech");
|
||||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_TOOLS, "Tools", "Useful items, from the common to the obscure.", '[', C_GREY);
|
addoc(OC_TOOLS, "Tools", "Useful items, from the common to the obscure.", '[', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "tool");
|
||||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_MISC, "Miscellaneous", "This could be anything.", '\\', C_GREY);
|
addoc(OC_MISC, "Miscellaneous", "This could be anything.", '\\', C_GREY);
|
||||||
|
@ -4761,6 +5088,9 @@ void initobjects(void) {
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_BOOK, "Books", "Spellbooks, tomes or manuals.", '+', C_GREY);
|
addoc(OC_BOOK, "Books", "Spellbooks, tomes or manuals.", '+', C_GREY);
|
||||||
|
addocnoun(lastobjectclass, "spellbook");
|
||||||
|
addocnoun(lastobjectclass, "book");
|
||||||
|
addocnoun(lastobjectclass, "tome");
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_SPELL, "Spells", "A magical spell", '&', C_GREY); // this is a "virtual" object class
|
addoc(OC_SPELL, "Spells", "A magical spell", '&', C_GREY); // this is a "virtual" object class
|
||||||
|
@ -4900,7 +5230,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_REDUCEMOVEMENT, 4, NA, NA, NULL);
|
addflag(lastot->flags, F_REDUCEMOVEMENT, 4, NA, NA, NULL);
|
||||||
|
|
||||||
// traps
|
// traps
|
||||||
addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 10, B_FALSE, 20, NULL);
|
addflag(lastot->flags, F_TRAP, 10, B_FALSE, 20, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||||
|
@ -4908,7 +5238,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
||||||
addot(OT_TRAPROCK, "falling rock trap", "A pressure plate which causes heavy rocks to drop from the ceiling.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPROCK, "falling rock trap", "A pressure plate which causes heavy rocks to drop from the ceiling.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 20, B_TRUE, 22, NULL);
|
addflag(lastot->flags, F_TRAP, 20, B_TRUE, 22, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||||
|
@ -4916,7 +5246,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
||||||
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL);
|
||||||
|
@ -4925,7 +5255,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||||
addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||||
|
@ -4934,7 +5264,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||||
addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 27, B_TRUE, NA, NULL);
|
addflag(lastot->flags, F_TRAP, 27, B_TRUE, NA, NULL);
|
||||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||||
|
@ -4943,7 +5273,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||||
addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
|
||||||
|
@ -4952,7 +5282,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||||
addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_MISC);
|
addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_TRAP);
|
||||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||||
|
@ -8761,11 +9091,15 @@ void killobpile(obpile_t *op) {
|
||||||
|
|
||||||
void killoc(objectclass_t *oc) {
|
void killoc(objectclass_t *oc) {
|
||||||
objectclass_t *nextone, *lastone;
|
objectclass_t *nextone, *lastone;
|
||||||
|
int i;
|
||||||
|
|
||||||
// free mem
|
// free mem
|
||||||
free(oc->name);
|
free(oc->name);
|
||||||
free(oc->desc);
|
free(oc->desc);
|
||||||
if (oc->flags) killflagpile(oc->flags);
|
if (oc->flags) killflagpile(oc->flags);
|
||||||
|
for (i = 0; i < oc->nnouns; i++) {
|
||||||
|
free(oc->noun[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// remove from list
|
// remove from list
|
||||||
nextone = oc->next;
|
nextone = oc->next;
|
||||||
|
@ -11313,6 +11647,37 @@ int removeob(object_t *o,int howmany) {
|
||||||
return o->amt;
|
return o->amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rrtorarity(enum RARITY r, int *minr, int *maxr) {
|
||||||
|
switch (r) {
|
||||||
|
case RR_UNIQUE:
|
||||||
|
case RR_NEVER:
|
||||||
|
if (minr) *minr = 0;
|
||||||
|
if (maxr) *maxr = 0;
|
||||||
|
break;
|
||||||
|
case RR_VERYRARE:
|
||||||
|
if (minr) *minr = 0;
|
||||||
|
if (maxr) *maxr = 49;
|
||||||
|
break;
|
||||||
|
case RR_RARE:
|
||||||
|
if (minr) *minr = 50;
|
||||||
|
if (maxr) *maxr = 64;
|
||||||
|
break;
|
||||||
|
case RR_UNCOMMON:
|
||||||
|
if (minr) *minr = 65;
|
||||||
|
if (maxr) *maxr = 79;
|
||||||
|
break;
|
||||||
|
case RR_COMMON:
|
||||||
|
if (minr) *minr = 80;
|
||||||
|
if (maxr) *maxr = 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (minr) *minr = 0;
|
||||||
|
if (maxr) *maxr = 100; // ie. rarity can be anything
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setblessed(object_t *o, enum BLESSTYPE wantbless) {
|
void setblessed(object_t *o, enum BLESSTYPE wantbless) {
|
||||||
o->blessed = wantbless;
|
o->blessed = wantbless;
|
||||||
if (wantbless != B_BLESSED) {
|
if (wantbless != B_BLESSED) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
39
spell.c
39
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,12 +2242,18 @@ 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) {
|
||||||
|
// can dig through stone, but nothing else.
|
||||||
|
if (retcell[i]->type->material->id == MT_STONE) {
|
||||||
setcelltype(retcell[i], getemptycelltype(retcell[i]->map->habitat));
|
setcelltype(retcell[i], getemptycelltype(retcell[i]->map->habitat));
|
||||||
if (seenthiscell) {
|
if (seenthiscell) {
|
||||||
ndigs++;
|
ndigs++;
|
||||||
numseen++;
|
numseen++;
|
||||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// stop.
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
for (o = retcell[i]->obpile->first ; o ; o = o->next) {
|
for (o = retcell[i]->obpile->first ; o ; o = o->next) {
|
||||||
|
@ -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,10 +5554,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
targcell = c;
|
targcell = c;
|
||||||
|
|
||||||
if (!cellwalkable(caster, c, NULL)) {
|
if (c->type->solid) {
|
||||||
|
// ok, but you'll die!
|
||||||
|
} else if (!cellwalkable(caster, c, NULL)) {
|
||||||
|
// go somewhere nearby...
|
||||||
|
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
|
||||||
|
if (!c) {
|
||||||
fizzle(caster);
|
fizzle(caster);
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we can take up to 'power-1' allies with us.
|
// we can take up to 'power-1' allies with us.
|
||||||
if (caster == target) {
|
if (caster == target) {
|
||||||
|
@ -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,11 +6138,14 @@ 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) {
|
||||||
|
for (i = 0; i < nretobs; i++) {
|
||||||
char obname[BUFLEN];
|
char obname[BUFLEN];
|
||||||
|
o = retobs[i];
|
||||||
getobname(o, obname, o->amt);
|
getobname(o, obname, o->amt);
|
||||||
if (!hasflag(o->flags, F_IMPASSABLE) && canpickup(target, o, ALL)) {
|
if (!hasflag(o->flags, F_IMPASSABLE) && canpickup(target, o, ALL)) {
|
||||||
|
// you gain it.
|
||||||
relinkob(o, target->pack); // move to pack
|
relinkob(o, target->pack); // move to pack
|
||||||
if (isplayer(target)) {
|
if (isplayer(target)) {
|
||||||
msgnocap("%c - %s.", o->letter, obname);
|
msgnocap("%c - %s.", o->letter, obname);
|
||||||
|
@ -6133,12 +6153,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
msg("%s is gifted with %s.", lfname, obname);
|
msg("%s is gifted with %s.", lfname, obname);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// couldn't pick it up - try to place on ground!
|
// can't pick this up...
|
||||||
// impassable?
|
|
||||||
|
// impassable? goes in a nearby cell instead of at your feet.
|
||||||
if (hasflag(o->flags, F_IMPASSABLE)) {
|
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||||
cell_t *newloc;
|
cell_t *newloc;
|
||||||
// if so, don't put it where the player is!
|
// if so, don't put it where the player is!
|
||||||
newloc = getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
newloc = real_getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL);
|
||||||
o = relinkob(o, newloc->obpile);
|
o = relinkob(o, newloc->obpile);
|
||||||
}
|
}
|
||||||
if (o) {
|
if (o) {
|
||||||
|
@ -6147,8 +6168,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// couldn't make it appear
|
// ob exists but couldn't make it appear
|
||||||
msg("The air in front of %s seems to ripple for a moment.", lfname);
|
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