- [+] askchar - default isnt working.
* [+] implement regions - [+] new vaultflag: norandom (doesn't rnadomly appear) * [+] jimbo's lair * [+] implememnt skill training * [+] still a bug with flooded rooms having no doors! * [+] change f_impassable to be a size _range_ which can't pass it. - [+] metal armour should add to walking volume! - [+] sewing/metalwork skill to repair cloth/metal armour, instead of "armour" skill? - [+] moveob() onto a pit - they fall through! vault options: - [+] dlevmin/max:xx appears at this depth/difficulty - [+] goesin appears in habitat xx (if none of these, can be anywhere) - [+] habitat has to be a struct first, with a name. - [+] norandom (don't randomly generate - only from outline) - [+] pits - [+] only one can exist in a cell - [+] replace getemptycelltype() with entries in habitat_t - [+] make map->habitat a link. * [+] update linkstairs to do pits SPELLS: - [+] shatter (grav/air, break glass, break potions. damage to anyone nearby)
This commit is contained in:
parent
1ab3bd3620
commit
6cd743b9f9
4
ai.c
4
ai.c
|
@ -35,7 +35,9 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
|
||||
// mindless?
|
||||
if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) {
|
||||
return;
|
||||
if (!isundead(lf)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// already targetting this lf?
|
||||
|
|
14
attack.c
14
attack.c
|
@ -742,6 +742,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// victim's armour loses hp
|
||||
if (reduceamt) {
|
||||
applyarmourdamage(victim, wep, reduceamt, damtype[i]);
|
||||
// train armour
|
||||
practice(victim, SK_ARMOUR, 1);
|
||||
}
|
||||
if (backstab) {
|
||||
practice(lf, SK_BACKSTAB, 1);
|
||||
}
|
||||
}
|
||||
} // end foreach damtype
|
||||
|
@ -903,8 +908,13 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
|
||||
// practice?
|
||||
if (wepsk && !getskill(lf, wepsk->id)) {
|
||||
practice(lf, wepsk->id, hit ? 2 : 1);
|
||||
if (hit) {
|
||||
if (wepsk) {
|
||||
practice(lf, wepsk->id, 1);
|
||||
}
|
||||
if (isdualweilding(lf)) {
|
||||
practice(lf, SK_TWOWEAPON, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// induction of fear?
|
||||
|
|
103
defs.h
103
defs.h
|
@ -6,7 +6,7 @@
|
|||
// MACROS
|
||||
#define MAXOF(a,b) (a > b ? a : b)
|
||||
|
||||
#define PRACTICETIME 15 // #attempts it takes to learn new weapon skill
|
||||
// #define PRACTICETIME 15 // #attempts it takes to learn new weapon skill
|
||||
|
||||
#define WETTIME 10 // how long it takes for things to dry
|
||||
#define DRUNKTIME 10 // how long it takes for alcohol to wear off
|
||||
|
@ -47,7 +47,9 @@ enum SKILL {
|
|||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_METALWORK,
|
||||
SK_RANGED,
|
||||
SK_SEWING,
|
||||
SK_SHIELDS,
|
||||
SK_SPELLCASTING,
|
||||
SK_SPOTHIDDEN,
|
||||
|
@ -88,7 +90,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 47
|
||||
#define MAXSKILLS 49
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -572,12 +574,6 @@ enum BLESSTYPE {
|
|||
B_CURSED = -1
|
||||
};
|
||||
|
||||
enum HABITAT {
|
||||
H_DUNGEON = 1,
|
||||
H_FOREST = 2,
|
||||
H_ALL = 999
|
||||
};
|
||||
|
||||
#define RARITYVARIANCELF (5)
|
||||
#define RARITYVARIANCEOB (10)
|
||||
|
||||
|
@ -780,11 +776,14 @@ enum OBTYPE {
|
|||
OT_STATUE,
|
||||
OT_DOORWOOD,
|
||||
OT_DOORIRON,
|
||||
OT_IRONGATE,
|
||||
OT_WOODENTABLE,
|
||||
OT_WOODENBARREL,
|
||||
OT_WOODENSTOOL,
|
||||
OT_HOLYCIRCLE,
|
||||
OT_PENTAGRAM,
|
||||
OT_HOLEINGROUND,
|
||||
OT_HOLEINROOF,
|
||||
OT_STAIRSDOWN,
|
||||
OT_STAIRSUP,
|
||||
OT_VENDINGMACHINE,
|
||||
|
@ -896,6 +895,7 @@ enum OBTYPE {
|
|||
OT_S_METALHEAL,
|
||||
// -- death
|
||||
OT_S_ANIMATEDEAD,
|
||||
OT_S_COMMANDUNDEAD,
|
||||
OT_S_DRAINLIFE,
|
||||
OT_S_FEAR,
|
||||
OT_S_PAIN,
|
||||
|
@ -925,6 +925,7 @@ enum OBTYPE {
|
|||
OT_S_CLOUDKILL,
|
||||
OT_S_GUSTOFWIND,
|
||||
OT_S_MIST,
|
||||
OT_S_SHATTER,
|
||||
OT_S_WINDSHIELD,
|
||||
// -- elemental - fire
|
||||
OT_S_BLADEBURN,
|
||||
|
@ -1370,7 +1371,8 @@ enum NOISETYPE {
|
|||
};
|
||||
|
||||
enum LFSIZE {
|
||||
SZ_ANY = -1,
|
||||
SZ_ANY = -2,
|
||||
SZ_MIN = -1,
|
||||
SZ_MINI = 0, // ie. fly
|
||||
SZ_TINY = 1, // ie. mouse
|
||||
SZ_SMALL = 2, // ie. cat
|
||||
|
@ -1415,6 +1417,7 @@ enum FLAG {
|
|||
F_ONEPERCELL, // only one of these objects can exist per cell
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
F_ENCHANTABLE, // object can get +1/-1 ect
|
||||
F_NOSHATTER, // object will not shatter, even if it's material should.
|
||||
F_STACKABLE, // can stack multiple objects togethr
|
||||
F_NO_PLURAL, // this obname doesn't need an 's' for plurals (eg. gold, money)
|
||||
F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold)
|
||||
|
@ -1447,7 +1450,8 @@ enum FLAG {
|
|||
F_NOGLYPH, // this object doesn't appear normally
|
||||
F_COSMETIC, // this object is mostly cosmetic, don't say 'you see xx'
|
||||
F_NOPICKUP, // cannot pick this up
|
||||
F_IMPASSABLE, // cannot walk past this if your size if v0 or smaller
|
||||
F_IMPASSABLE, // cannot walk past this if your size is between v0 and v1
|
||||
// (inclusive)
|
||||
F_CRUSHABLE, // if you are bigger than size v0, walking on this crushes it
|
||||
F_CAUSESCOUGH, // being in this ob's cell will make you cough unless
|
||||
// immune to gas.
|
||||
|
@ -1537,6 +1541,7 @@ enum FLAG {
|
|||
// v2 = sc_dodge difficulty
|
||||
// doors
|
||||
F_DOOR, // this object is a door - ie. can open it
|
||||
// v0 and v1 are like F_IMPASSABLE
|
||||
F_OPEN, // is this door open?
|
||||
F_LOCKED,// door is locked
|
||||
// v1 is difficulty to disarm
|
||||
|
@ -1547,6 +1552,9 @@ enum FLAG {
|
|||
// stairs / teleporters / portals
|
||||
F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in
|
||||
// also use this for portals
|
||||
// OPTIONAL v1 = id of region to link to.
|
||||
F_PIT, // this is a pit which we can fall down.
|
||||
// v0 = up/down
|
||||
//F_STAIRDIR//, // val0 = direcion
|
||||
F_OPPOSITESTAIRS, // val0 = opposite kind of stairs
|
||||
F_MAPLINK, // val0 = map to link to.
|
||||
|
@ -2022,11 +2030,17 @@ enum FLAG {
|
|||
// v0 is pct chance of door (as opposed to empty
|
||||
// doorway with no door).
|
||||
F_AUTOPOPULATE, // fill this vault with obs/mons/pillars like normal rooms
|
||||
F_NORANDOM, // this vault does not randomly appear
|
||||
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_VAULTDLEVMIN, // v0 = mininum map depth/difficulty for this vault
|
||||
F_VAULTDLEVMAX, // v0 = maximum map depth/difficulty for this vault
|
||||
F_VAULTEXIT, // v0/1=x,y for exit.
|
||||
F_VAULTGOESIN, // this vault randomly appears in habitat type v0.
|
||||
// can be repeated multiple times
|
||||
// if a vault doesnt have this flag, it can go anywhere
|
||||
F_VAULTSCATTER, // v0=thingtype, v1=pctchance
|
||||
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
||||
// if maxcount is PCT, mincount is a percentage
|
||||
|
@ -2067,6 +2081,8 @@ enum HUNGER {
|
|||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
|
||||
#define B_NODOORS (0)
|
||||
|
||||
#define B_DONTKILL (-1)
|
||||
|
||||
#define FALLTHRU (-8765)
|
||||
|
@ -2248,16 +2264,74 @@ typedef struct command_s {
|
|||
struct command_s *next, *prev;
|
||||
} command_t;
|
||||
|
||||
#define RG_WORLDMAP 0
|
||||
#define RG_FIRSTDUNGEON 1
|
||||
enum REGIONTYPE {
|
||||
RG_WORLDMAP,
|
||||
RG_FIRSTDUNGEON,
|
||||
RG_PIT,
|
||||
};
|
||||
|
||||
enum HABITAT {
|
||||
H_DUNGEON = 1,
|
||||
H_FOREST = 2,
|
||||
H_PIT = 3,
|
||||
H_ALL = 999
|
||||
};
|
||||
|
||||
typedef struct regiontype_s {
|
||||
enum REGIONTYPE id;
|
||||
enum HABITAT defaulthabitat;
|
||||
int maxdepth;
|
||||
int stairsperlev;
|
||||
int deeperdir;
|
||||
struct regiontype_s *next, *prev;
|
||||
} regiontype_t;
|
||||
|
||||
enum REGIONTHING {
|
||||
RT_HABITAT, // val is habitat
|
||||
RT_REGIONLINK, // val is enum regiontype to link to.
|
||||
// what is stair object type
|
||||
RT_VAULT, // what is vaultname
|
||||
};
|
||||
|
||||
typedef struct regionthing_s {
|
||||
int depth; // only need depth OR x,y
|
||||
int x,y;
|
||||
enum REGIONTHING whatkind;
|
||||
int value;
|
||||
char *what;
|
||||
} regionthing_t;
|
||||
|
||||
#define MAXOUTLINETHINGS 20
|
||||
typedef struct regionoutline_s {
|
||||
regiontype_t *rtype;
|
||||
regionthing_t thing[MAXOUTLINETHINGS];
|
||||
int nthings;
|
||||
struct regionoutline_s *next, *prev;
|
||||
} regionoutline_t;
|
||||
|
||||
typedef struct region_s {
|
||||
int id;
|
||||
regiontype_t *rtype;
|
||||
regionoutline_t *outline;
|
||||
struct region_s *parentregion;
|
||||
int nthings;
|
||||
struct region_s *next, *prev;
|
||||
} region_t;
|
||||
|
||||
typedef struct habitat_s {
|
||||
enum HABITAT id;
|
||||
char *name;
|
||||
enum CELLTYPE emptycelltype,solidcelltype;
|
||||
struct habitat_s *next, *prev;
|
||||
} habitat_t;
|
||||
|
||||
typedef struct map_s {
|
||||
int id;
|
||||
int region;
|
||||
region_t *region;
|
||||
int depth;
|
||||
int nrooms; // how many rooms on this map
|
||||
char *name; // name of this map
|
||||
enum HABITAT habitat; // eg. dungeon, forest, etc
|
||||
habitat_t *habitat;
|
||||
unsigned int seed;
|
||||
int w,h; // width/height of this map
|
||||
struct cell_s *cell[MAX_MAPW*MAX_MAPH]; // list of cells in this map
|
||||
|
@ -2476,6 +2550,7 @@ typedef struct skill_s {
|
|||
enum SKILL id;
|
||||
char *name;
|
||||
char *desc;
|
||||
int traintime;
|
||||
struct skill_s *next, *prev;
|
||||
} skill_t;
|
||||
|
||||
|
|
|
@ -2,4 +2,7 @@ defs.h:
|
|||
add H_xx enum
|
||||
|
||||
map.c:
|
||||
update getemptycelltype()
|
||||
initmap: define via addhabitat()
|
||||
|
||||
make a new function to create this kind of habitat
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
defs.h:
|
||||
add new RG_xxx entry to enum REGIONTYPE
|
||||
|
||||
map.c:
|
||||
initmap(): define via new "addregiontype()" call
|
||||
OPTIONAL: initmap(): define at least one regionoutline
|
||||
|
||||
create new habitats if required.
|
||||
|
||||
update getregionname()
|
|
@ -44,12 +44,24 @@ Flags can be:
|
|||
- 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
|
||||
autodoors:pct // automatically add at least one door to the edges of
|
||||
// this room.
|
||||
// pct is chance of the exit being a door as opposed
|
||||
// to jsut an opening.
|
||||
|
||||
autopop // automatically add obs/mons/pillars to this room
|
||||
|
||||
dlevmin:xxx // can only randomly appear at or below dungeon
|
||||
// level xxx (or map difficulty xxx for world map)
|
||||
dlevmax:xxx // can only randomly appear at or before dungeon
|
||||
// levle xxx
|
||||
|
||||
goesin:xxx // can only randomly appear in habitat xxx
|
||||
|
||||
norandom // this vault doesn't appear randomly. it will only
|
||||
// appear when specifically requested via a region's
|
||||
// outline.
|
||||
|
||||
NOTES:
|
||||
when adding lfs/objects, "random" creates a random one.
|
||||
|
||||
|
|
48
io.c
48
io.c
|
@ -501,7 +501,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
|
|||
}
|
||||
curs_set(0);
|
||||
clearmsg();
|
||||
if ((ch == 13) && def) {
|
||||
if ((ch == 10) && def) {
|
||||
return def[0];
|
||||
}
|
||||
return ch;
|
||||
|
@ -986,7 +986,7 @@ void announcearrival(lifeform_t *lf, map_t *newmap) {
|
|||
} else {
|
||||
msg("You arrive at the surface.");
|
||||
}
|
||||
} else if (newmap->habitat == H_DUNGEON) {
|
||||
} else if (newmap->habitat->id == H_DUNGEON) {
|
||||
msg("You arrive at dungeon level %d.", newmap->depth);
|
||||
}
|
||||
}
|
||||
|
@ -3616,8 +3616,7 @@ void doclose(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void docomms(void) {
|
||||
lifeform_t *lf = NULL;
|
||||
void docomms(lifeform_t *lf) {
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
|
@ -3626,9 +3625,11 @@ void docomms(void) {
|
|||
flag_t *f;
|
||||
|
||||
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
if (!lf) {
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
}
|
||||
if (!lf) {
|
||||
msg("Cancelled.");
|
||||
|
@ -3644,7 +3645,7 @@ void docomms(void) {
|
|||
|
||||
// are they friendly?
|
||||
if (ispetof(lf, player)) {
|
||||
if (iqb >= IQ_ANIMAL) {
|
||||
if ((iqb >= IQ_ANIMAL) || isundead(lf)) {
|
||||
addchoice(&prompt, 'a', "Attack something", NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -3694,6 +3695,8 @@ void docomms(void) {
|
|||
if (isplayer(lf)) {
|
||||
msg("%s looks confused at your command.", lfname);
|
||||
} else {
|
||||
// stop attacking all current targets first...
|
||||
killflagsofid(lf->flags, F_TARGETLF);
|
||||
aiattack(lf, lf2, AI_FOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
|
@ -3709,11 +3712,13 @@ void docomms(void) {
|
|||
sprintf(buf, "Tell %s to go where?",lfname);
|
||||
sprintf(buf2, "%s->Goto->",lfname);
|
||||
c = askcoords(buf, buf2, TT_NONE, lf, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && cellwalkable(lf, c, NULL) && cansee(lf, c->lf)) {
|
||||
if (c && cellwalkable(lf, c, NULL) ) {
|
||||
} else {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
// stop attacking all current targets first...
|
||||
killflagsofid(lf->flags, F_TARGETLF);
|
||||
msg("You say \"Go over there!\" to %s.", lfname);
|
||||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
break;
|
||||
|
@ -4627,7 +4632,7 @@ void doenter(lifeform_t *lf) {
|
|||
}
|
||||
enterob = hasob(lf->cell->obpile, OT_PORTAL);
|
||||
if (enterob) {
|
||||
usestairs(lf, enterob);
|
||||
usestairs(lf, enterob, B_TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5014,7 +5019,7 @@ void dostairs(int dir) {
|
|||
object_t *o;
|
||||
o = hasobwithflagval(player->cell->obpile, F_CLIMBABLE, dir, NA, NA, NULL);
|
||||
if (o) {
|
||||
usestairs(player, o);
|
||||
usestairs(player, o, B_TRUE);
|
||||
} else {
|
||||
msg("There are no stairs going %s here!", getdirname(dir));
|
||||
}
|
||||
|
@ -6107,7 +6112,7 @@ void handleinput(void) {
|
|||
doclose();
|
||||
break;
|
||||
case 'C': // communicate
|
||||
docomms();
|
||||
docomms(NULL);
|
||||
break;
|
||||
case 'e': // eat
|
||||
doeat(player->pack);
|
||||
|
@ -6653,7 +6658,12 @@ void drawstatus(void) {
|
|||
}
|
||||
}
|
||||
|
||||
wprintw(statwin, "DLev:%d", player->cell->map->depth);
|
||||
//wprintw(statwin, "DLev:%d", player->cell->map->depth);
|
||||
setcol(statwin, C_BROWN);
|
||||
getregionname(buf, player->cell->map, B_TRUE);
|
||||
capitalise(buf);
|
||||
wprintw(statwin, "%s", buf);
|
||||
unsetcol(statwin, C_BROWN);
|
||||
}
|
||||
|
||||
void drawmsg(void) {
|
||||
|
@ -8245,7 +8255,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
f = lfhasflag(lf, F_RAGE);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s enraged.", you(lf), is(lf));
|
||||
mvwprintw(mainwin, y, 0, "%s %s enraged, gaining temporary strength and hit points.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_REGENERATES);
|
||||
|
@ -8419,6 +8429,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
void tombstone(lifeform_t *lf) {
|
||||
char pname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
int y;
|
||||
char *p, *dummy;
|
||||
|
||||
|
@ -8431,10 +8442,13 @@ void tombstone(lifeform_t *lf) {
|
|||
centre(mainwin, y, "R.I.P."); y++;
|
||||
//printf("%s\n",lf->name);
|
||||
centre(mainwin, y, "%s (%ld points)",pname, calcscore(lf)); y++;
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
centre(mainwin, y, "Died in the forest.");
|
||||
|
||||
if (player->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
getregionname(buf, player->cell->map, B_TRUE);
|
||||
centre(mainwin, y, "Died on %s.", buf); y++;
|
||||
} else {
|
||||
centre(mainwin, y, "Died on level %d of the dungeon.", lf->cell->map->depth); y++;
|
||||
getregionname(buf, player->cell->map, B_FALSE);
|
||||
centre(mainwin, y, "Died on level %d of %s.", player->cell->map->depth, buf); y++;
|
||||
}
|
||||
|
||||
p = strtok_r(lf->lastdam,"^", &dummy);
|
||||
|
|
2
io.h
2
io.h
|
@ -37,7 +37,7 @@ void describeob(object_t *o);
|
|||
void describespell(objecttype_t *ot);
|
||||
void doattackcell(char dirch);
|
||||
void doclose(void);
|
||||
void docomms(void);
|
||||
void docomms(lifeform_t *target);
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst);
|
||||
void doeat(obpile_t *op);
|
||||
void doenter(lifeform_t *lf);
|
||||
|
|
528
lf.c
528
lf.c
|
@ -1161,6 +1161,11 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
// stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// successful cast?
|
||||
if (!rv) {
|
||||
practice(lf, SK_SPELLCASTING, 1);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1815,6 +1820,159 @@ void dumpxp(void) {
|
|||
}
|
||||
}
|
||||
|
||||
int digcell(lifeform_t *lf, cell_t *c, object_t *o) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, 1);
|
||||
|
||||
if (!c) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (c->type->solid) {
|
||||
if (isdiggable(c)) {
|
||||
// replace wall
|
||||
setcelltype(c, c->map->habitat->id);
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig through the wall.");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s digs through a wall.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
//drawscreen();
|
||||
// takes extra time
|
||||
taketime(lf, getactspeed(lf)*9);
|
||||
} else {
|
||||
// fail
|
||||
if (isplayer(lf)) {
|
||||
msg("This wall is too hard to dig.");
|
||||
}
|
||||
}
|
||||
} else { // not solid
|
||||
int failed = B_FALSE;
|
||||
object_t *door;
|
||||
|
||||
door = hasobwithflag(c->obpile, F_DOOR);
|
||||
if (door) {
|
||||
int dooropen;
|
||||
// only closed doors!
|
||||
isdoor(door, &dooropen);
|
||||
if (dooropen) {
|
||||
door = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (door) {
|
||||
// TODO: metal doors are immune to CHOP damage
|
||||
if (!isimmuneto(door->flags, DT_CHOP)) {
|
||||
taketime(lf, getactspeed(lf));
|
||||
removeob(door, door->amt);
|
||||
if (isplayer(lf)) {
|
||||
msg("You smash open a door!");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s smashes open a door.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
drawscreen();
|
||||
failed = B_FALSE;
|
||||
}
|
||||
} else if (hasob(c->obpile, OT_STATUE)) {
|
||||
int dam;
|
||||
object_t *so;
|
||||
char statname[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
so = hasob(c->obpile, OT_STATUE);
|
||||
getobname(so, statname, so->amt);
|
||||
|
||||
taketime(lf, getactspeed(lf));
|
||||
|
||||
// statue takes 1/2 damage
|
||||
f = hasflag(so->flags, F_OBHP);
|
||||
if (f) {
|
||||
dam = (f->val[1] / 2); // ie. half max hp
|
||||
} else {
|
||||
dam = 1;
|
||||
}
|
||||
// statue ?
|
||||
if (isplayer(lf)) {
|
||||
msg("You hit %s with your %s.", statname, noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s hits %s with %s.", lfname, statname, obname);
|
||||
}
|
||||
takedamage(so, dam, DT_CHOP);
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You swing your %s through the air.",noprefix(obname));
|
||||
}
|
||||
taketime(lf, getactspeed(lf));
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int digdown(lifeform_t *lf, object_t *o) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
|
||||
// TODO: check if the floor is solid?
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig a hole in the floor.");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s digs a hole in the floor.");
|
||||
}
|
||||
|
||||
addob(lf->cell->obpile, "hole in the ground");
|
||||
|
||||
// takes a lot of time
|
||||
taketime(lf, getactspeed(lf) * 9);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int digup(lifeform_t *lf, object_t *o) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
|
||||
// no roof?
|
||||
if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
if (isplayer(lf)) {
|
||||
msg("There is no roof above you to dig into!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// TODO: check if the roof is solid?
|
||||
|
||||
if (!isairborne(lf)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig a hole in the roof.");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s digs a hole in the roof.");
|
||||
}
|
||||
|
||||
// add some stones here
|
||||
addob(lf->cell->obpile, "20-50 stones");
|
||||
|
||||
addob(lf->cell->obpile, "hole in the roof");
|
||||
|
||||
// takes a LOT of time since gravity is against us
|
||||
taketime(lf, getactspeed(lf) * 18);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// dump which level random things will appear at
|
||||
void dumplev(void) {
|
||||
int i;
|
||||
|
@ -2728,7 +2886,7 @@ int flee(lifeform_t *lf) {
|
|||
// can we flee via stairs?
|
||||
stairs = hasobwithflag(lf->cell->obpile, F_CLIMBABLE);
|
||||
if (stairs) {
|
||||
if (!usestairs(lf, stairs)) {
|
||||
if (!usestairs(lf, stairs, B_TRUE)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -3082,6 +3240,24 @@ object_t *getarmour(lifeform_t *lf, enum BODYPART bp) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int getarmournoise(lifeform_t *lf) {
|
||||
object_t *o;
|
||||
int volmod = 0;
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (isarmour(o) && isequipped(o)) {
|
||||
// heavy metal armour makes noise
|
||||
if (ismetal(o->material->id) && (getobweight(o) >= 4)) {
|
||||
volmod++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
volmod -= getskill(lf, SK_ARMOUR);
|
||||
limit(&volmod, 0, NA);
|
||||
|
||||
return volmod;
|
||||
}
|
||||
|
||||
int getarmourrating(lifeform_t *lf) {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
|
@ -3288,25 +3464,28 @@ int getavgdam(lifeform_t *lf, int forxp) {
|
|||
|
||||
o = addob(op2, f->text);
|
||||
|
||||
getdamrange(hasflag(o->flags, F_DAM), &min,&max);
|
||||
thisavg = ((float)min + (float)max) / 2.0;
|
||||
if (o) {
|
||||
getdamrange(hasflag(o->flags, F_DAM), &min,&max);
|
||||
thisavg = ((float)min + (float)max) / 2.0;
|
||||
|
||||
// confers anything?
|
||||
for (of = o->flags->first ; of ; of = of->next) {
|
||||
if (of->id == F_HITCONFER) {
|
||||
thisavg += 10;
|
||||
// confers anything?
|
||||
for (of = o->flags->first ; of ; of = of->next) {
|
||||
if (of->id == F_HITCONFER) {
|
||||
thisavg += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// modify for accuracy
|
||||
acc = getlfaccuracy(lf, o);
|
||||
thisavg = pctof(acc, thisavg);
|
||||
// modify for accuracy
|
||||
acc = getlfaccuracy(lf, o);
|
||||
thisavg = pctof(acc, thisavg);
|
||||
|
||||
avgdam += thisavg;
|
||||
if (db) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o,obname,1);
|
||||
if (db) dblog("getavgdam: %s: == %d-%d dam, avg is %0.1f",obname, min, max, thisavg);
|
||||
|
||||
avgdam += thisavg;
|
||||
if (db) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o,obname,1);
|
||||
if (db) dblog("getavgdam: %s: == %d-%d dam, avg is %0.1f",obname, min, max, thisavg);
|
||||
}
|
||||
}
|
||||
|
||||
killobpile(op2);
|
||||
|
@ -4345,6 +4524,30 @@ lifeform_t *getnearbypeaceful(lifeform_t *lf) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char *getpitverb(lifeform_t *lf, int dir, int onpurpose) {
|
||||
if (lfhasflag(lf, F_FLYING)) {
|
||||
if (isplayer(lf)) return "fly";
|
||||
else return "flies";
|
||||
} else if (onpurpose) { // TODO: check if we are using a rope
|
||||
if (dir == D_DOWN) {
|
||||
if (isplayer(lf)) return "jump";
|
||||
else return "jumps";
|
||||
} else {
|
||||
if (isplayer(lf)) return "climb";
|
||||
else return "climbs";
|
||||
}
|
||||
} else {
|
||||
if (dir == D_DOWN) {
|
||||
if (isplayer(lf)) return "fall";
|
||||
else return "falls";
|
||||
} else {
|
||||
if (isplayer(lf)) return "rise";
|
||||
else return "rises";
|
||||
}
|
||||
}
|
||||
return "?unkonwnmoveverb?";
|
||||
}
|
||||
|
||||
char *getlfname(lifeform_t *lf, char *buf) {
|
||||
return real_getlfname(lf, buf, B_TRUE);
|
||||
}
|
||||
|
@ -4622,7 +4825,7 @@ int getracerarity(map_t *map, enum RACE rid) {
|
|||
f = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!f) {
|
||||
if (map) {
|
||||
f = hasflagval(r->flags, F_RARITY, map->habitat, NA, NA, NULL);
|
||||
f = hasflagval(r->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
f = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
|
@ -4744,7 +4947,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (c) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->map->habitat, NA, NA, NULL);
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->map->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
|
@ -5464,6 +5667,18 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
} else if (id == SK_LORE_ARCANA) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
} else if (id == SK_METALWORK) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_SEWING) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_THIEVERY) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
|
@ -5482,11 +5697,6 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_ARMOUR) {
|
||||
if (f->val[1] == PR_SKILLED) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_CARTOGRAPHY) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_NOVICE) {
|
||||
|
@ -6109,6 +6319,8 @@ int lockpick(lifeform_t *lf, object_t *target, object_t *device) {
|
|||
gainxp(lf, difficulty/3);
|
||||
}
|
||||
}
|
||||
// training
|
||||
practice(lf, SK_LOCKPICKING, 1);
|
||||
} else {
|
||||
// failed!
|
||||
if (faileffect == B_DIEONFAIL) {
|
||||
|
@ -6553,6 +6765,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LONGBLADES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL);
|
||||
|
@ -6591,6 +6804,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL);
|
||||
|
@ -6636,6 +6850,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SPELLCASTING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SS_FIRE, NA, NA, NULL);
|
||||
|
@ -6659,7 +6874,9 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL);
|
||||
|
@ -6698,6 +6915,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_THIEVERY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL);
|
||||
|
@ -8243,6 +8461,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars");
|
||||
addrace(R_DOGBLINK, "blink dog", 35, 'd', C_YELLOW, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 2, 8, NA, "");
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
|
@ -8250,7 +8469,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 77, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, 77, NA, "");
|
||||
addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 4, 0, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 2, 3, NA, "");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6");
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
|
@ -9710,7 +9929,7 @@ raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum
|
|||
return a;
|
||||
}
|
||||
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc) {
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime) {
|
||||
skill_t *a;
|
||||
|
||||
assert(!findskill(id));
|
||||
|
@ -9735,6 +9954,7 @@ skill_t *addskill(enum SKILL id, char *name, char *desc) {
|
|||
a->id = id;
|
||||
a->name = strdup(name);
|
||||
a->desc = strdup(desc);
|
||||
a->traintime = traintime;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
@ -10606,6 +10826,9 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
|
|||
}
|
||||
|
||||
sprintf(noisetext, "%s.",noun);
|
||||
if (nid == N_WALK) {
|
||||
volume += getarmournoise(lf);
|
||||
}
|
||||
noise(lf->cell, lf, volume, noisetext, verb);
|
||||
} else {
|
||||
// some defaults
|
||||
|
@ -10647,6 +10870,7 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
volume += getarmournoise(lf);
|
||||
if (strlen(movetext)) {
|
||||
noise(lf->cell, lf, volume, movetext, NULL);
|
||||
}
|
||||
|
@ -11011,6 +11235,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seete
|
|||
}
|
||||
// only hear one thing per turn.
|
||||
addflag(l->flags, F_DONELISTEN, B_TRUE, NA, NA, NULL);
|
||||
practice(l, SK_LISTEN, 1);
|
||||
}
|
||||
}
|
||||
// wake up a little
|
||||
|
@ -11279,24 +11504,39 @@ int poisonthreatenslife(lifeform_t *lf, flag_t *f) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// maybe practice a skill
|
||||
void practice(lifeform_t *lf, enum SKILL skid, int amt) {
|
||||
flag_t *f;
|
||||
skill_t *sk;
|
||||
enum SKILLLEVEL slev;
|
||||
int timeneeded;
|
||||
|
||||
// already got the skill?
|
||||
if (getskill(lf, skid)) {
|
||||
return;
|
||||
}
|
||||
// practice a little bit...
|
||||
f = lfhasflagval(lf, F_PRACTICINGSKILL, skid, NA, NA, NULL);
|
||||
if (f) {
|
||||
f->val[1] += amt;
|
||||
if (f->val[1] >= PRACTICETIME) {
|
||||
// learnt it!
|
||||
sk = findskill(skid);
|
||||
if (!sk) return;
|
||||
|
||||
slev = getskill(lf, skid);
|
||||
|
||||
timeneeded = sk->traintime * (getskill(lf, skid)+1);
|
||||
if (!timeneeded) return;
|
||||
|
||||
// can only practice skills which you're capable of learning
|
||||
if (!canlearn(lf, skid)) return;
|
||||
|
||||
if (!slev || onein(slev)) {
|
||||
|
||||
// practice a little bit...
|
||||
f = lfhasflagval(lf, F_PRACTICINGSKILL, skid, NA, NA, NULL);
|
||||
if (f) {
|
||||
f->val[1] += amt;
|
||||
} else {
|
||||
f = addflag(lf->flags, F_PRACTICINGSKILL, skid, amt, NA, NULL);
|
||||
}
|
||||
|
||||
if (f->val[1] >= timeneeded) {
|
||||
// learnt the next rank
|
||||
giveskill(lf, skid);
|
||||
killflag(f);
|
||||
}
|
||||
} else {
|
||||
addflag(lf->flags, F_PRACTICINGSKILL, skid, amt, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12098,55 +12338,57 @@ void setlastdam(lifeform_t *lf, char *buf) {
|
|||
}
|
||||
|
||||
void initskills(void) {
|
||||
addskill(SK_ARMOUR, "Armour", "Lets you repair armour, and reduces evasion penalties from armour.");
|
||||
addskill(SK_ATHLETICS, "Athletics", "Assists with sprinting and exhaustion recovery.");
|
||||
addskill(SK_BACKSTAB, "Backstab", "Lets you inflict massive damage with stabs when unseen.");
|
||||
addskill(SK_CARTOGRAPHY, "Cartography", "Your ability to create and interpret maps.");
|
||||
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.");
|
||||
addskill(SK_FIRSTAID, "First Aid", "Increases your healing rate and reduces duration of poison.");
|
||||
addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.");
|
||||
addskill(SK_LOCKPICKING, "Lockpicking", "Enhances your ability to pick locks.");
|
||||
addskill(SK_CHANNELING, "Channeling", "Lets you make better use of magical items.");
|
||||
addskill(SK_RANGED, "Ranged Weapons", "Your ability to aim a ranged weapon like a bow or gun.");
|
||||
addskill(SK_SHIELDS, "Shields", "Reduces shield accuracy penalty, and raises chance to block projectiles.");
|
||||
addskill(SK_SPELLCASTING, "Sorcery", "Determines your ability to cast spells from all schools.");
|
||||
addskill(SK_SPOTHIDDEN, "Searching", "Helps you to spot hidden traps or creatures.");
|
||||
addskill(SK_STEALTH, "Stealth", "Affects your ability to move silently.");
|
||||
addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.");
|
||||
addskill(SK_TECHUSAGE, "Technology", "Determines your comprehension of modern technological items.");
|
||||
addskill(SK_THIEVERY, "Thievery", "Your ability to pick pockets and steal items.");
|
||||
addskill(SK_TRACKING, "Tracking", "Allows you to track enemies by their footprints.");
|
||||
addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.");
|
||||
addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.");
|
||||
addskill(SK_ARMOUR, "Armour", "Reduces evasion and stealth penalties from wearing armour.", 100);
|
||||
addskill(SK_ATHLETICS, "Athletics", "Assists with sprinting and exhaustion recovery.", 50);
|
||||
addskill(SK_BACKSTAB, "Backstab", "Lets you inflict massive damage with stabs when unseen.", 50);
|
||||
addskill(SK_CARTOGRAPHY, "Cartography", "Your ability to create and interpret maps.", 0); // untrainable
|
||||
addskill(SK_CHANNELING, "Channeling", "Lets you make better use of magical items.", 0); // untrainable
|
||||
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50);
|
||||
addskill(SK_FIRSTAID, "First Aid", "Increases your healing rate and reduces duration of poison.", 0); // untrainable
|
||||
addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.", 100);
|
||||
addskill(SK_LOCKPICKING, "Lockpicking", "Enhances your ability to pick locks.", 50);
|
||||
addskill(SK_METALWORK, "Metalwork", "Lets you repair metal objects.", 100);
|
||||
addskill(SK_RANGED, "Ranged Weapons", "Your ability to aim a ranged weapon like a bow or gun.", 50);
|
||||
addskill(SK_SEWING, "Sewing", "Lets you repair cloth or leather objects.", 100);
|
||||
addskill(SK_SHIELDS, "Shields", "Reduces shield accuracy penalty, and raises chance to block projectiles.", 50);
|
||||
addskill(SK_SPELLCASTING, "Sorcery", "Determines your ability to cast spells from all schools.", 50);
|
||||
addskill(SK_SPOTHIDDEN, "Searching", "Helps you to spot hidden traps or creatures.", 50);
|
||||
addskill(SK_STEALTH, "Stealth", "Affects your ability to move silently.", 0); // untrainable?
|
||||
addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.", 50);
|
||||
addskill(SK_TECHUSAGE, "Technology", "Determines your comprehension of modern technological items.", 0); // untrain
|
||||
addskill(SK_THIEVERY, "Thievery", "Your ability to pick pockets and steal items.", 50);
|
||||
addskill(SK_TRACKING, "Tracking", "Allows you to track enemies by their footprints.", 0); // untrain
|
||||
addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.", 25);
|
||||
addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50);
|
||||
// knowledge
|
||||
addskill(SK_LORE_ARCANA, "Lore:Arcana", "Allows you a chance of recognising magical objects and creatures.");
|
||||
addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.");
|
||||
addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.");
|
||||
addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.");
|
||||
addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.");
|
||||
addskill(SK_LORE_ARCANA, "Lore:Arcana", "Allows you a chance of recognising magical objects and creatures.", 0);
|
||||
addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 0);
|
||||
addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.", 0);
|
||||
addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.", 0);
|
||||
addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.", 0);
|
||||
// weaponry
|
||||
addskill(SK_AXES, "Axes", "Helps you use chopping weapons like axes.");
|
||||
addskill(SK_CLUBS, "Clubs", "Helps you use bashing weapons like maces or clubs.");
|
||||
addskill(SK_LONGBLADES, "Long Blades", "Helps you use long swords, scimitars, etc.");
|
||||
addskill(SK_POLEARMS, "Polearms", "Helps you use long bladed weapons like halberds.");
|
||||
addskill(SK_SHORTBLADES, "Short Blades", "Helps you use daggers, short swords, etc.");
|
||||
addskill(SK_STAVES, "Staves", "Helps you use quarterstaffs, staffs, etc.");
|
||||
addskill(SK_UNARMED, "Unarmed Combat", "Helps you fight using your bare hands.");
|
||||
addskill(SK_AXES, "Axes", "Helps you use chopping weapons like axes.", 50);
|
||||
addskill(SK_CLUBS, "Clubs", "Helps you use bashing weapons like maces or clubs.", 50);
|
||||
addskill(SK_LONGBLADES, "Long Blades", "Helps you use long swords, scimitars, etc.", 50);
|
||||
addskill(SK_POLEARMS, "Polearms", "Helps you use long bladed weapons like halberds.", 50);
|
||||
addskill(SK_SHORTBLADES, "Short Blades", "Helps you use daggers, short swords, etc.", 50);
|
||||
addskill(SK_STAVES, "Staves", "Helps you use quarterstaffs, staffs, etc.", 50);
|
||||
addskill(SK_UNARMED, "Unarmed Combat", "Helps you fight using your bare hands.", 50);
|
||||
// spell schools
|
||||
addskill(SK_SS_ALLOMANCY, "Allomancy", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_AIR, "Air Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_DEATH, "Necromancy", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_DIVINATION, "Divination", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_FIRE, "Fire Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_COLD, "Cold Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_GRAVITY, "Gravitation Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_LIFE, "Life Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_MODIFICATION, "Modification", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_MENTAL, "Psionics", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_NATURE, "Nature Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_SUMMONING, "Summoning", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_TRANSLOCATION, "Translocation", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_WILD, "Wild Magic", "Boosts casting of spells from this school.");
|
||||
addskill(SK_SS_ALLOMANCY, "Allomancy", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_AIR, "Air Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_DEATH, "Necromancy", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_DIVINATION, "Divination", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_FIRE, "Fire Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_COLD, "Cold Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_GRAVITY, "Gravitation Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_LIFE, "Life Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_MODIFICATION, "Modification", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_MENTAL, "Psionics", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_NATURE, "Nature Magic", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_SUMMONING, "Summoning", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_TRANSLOCATION, "Translocation", "Boosts casting of spells from this school.", 50);
|
||||
addskill(SK_SS_WILD, "Wild Magic", "Boosts casting of spells from this school.", 50);
|
||||
}
|
||||
|
||||
void interrupt(lifeform_t *lf) {
|
||||
|
@ -12882,6 +13124,20 @@ void timeeffectslf(lifeform_t *lf) {
|
|||
timeeffectsob(o);
|
||||
}
|
||||
|
||||
// holes in the floor/roof
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
if (o) {
|
||||
if (!isairborne(lf)) {
|
||||
usestairs(lf, o, B_FALSE);
|
||||
}
|
||||
}
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, D_UP, NA, NA, NULL);
|
||||
if (o) {
|
||||
if (lfhasflag(lf, F_LEVITATING)) {
|
||||
usestairs(lf, o, B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
@ -13132,6 +13388,7 @@ void turneffectslf(lifeform_t *lf) {
|
|||
getlfname(lf, lfname);
|
||||
msg("You think %s has spotted you!", lfname);
|
||||
}
|
||||
practice(lf, SK_SPOTHIDDEN, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13162,6 +13419,11 @@ void turneffectslf(lifeform_t *lf) {
|
|||
killflag(f);
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
// train skills
|
||||
practice(lf, SK_SPOTHIDDEN, 1);
|
||||
if (hasflag(o->flags, F_TRAP)) {
|
||||
practice(lf, SK_TRAPS, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13703,7 +13965,7 @@ int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where)
|
|||
}
|
||||
|
||||
|
||||
int usestairs(lifeform_t *lf, object_t *o) {
|
||||
int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
||||
flag_t *f;
|
||||
map_t *curmap;
|
||||
map_t *newmap;
|
||||
|
@ -13715,6 +13977,8 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
int isportal = B_FALSE;
|
||||
lifeform_t *adjally[8];
|
||||
int nadjallies = 0;
|
||||
int falling = B_FALSE;
|
||||
region_t *newregion = NULL;
|
||||
|
||||
// need up update 'dlev:'
|
||||
if (isplayer(lf)) {
|
||||
|
@ -13734,6 +13998,12 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
assert(f);
|
||||
dir = f->val[0];
|
||||
if (f->val[1] == NA) {
|
||||
// use same region
|
||||
newregion = lf->cell->map->region;
|
||||
} else {
|
||||
newregion = findregion(f->val[1]);
|
||||
}
|
||||
|
||||
// depth of new level?
|
||||
if (dir == D_UP) {
|
||||
|
@ -13747,6 +14017,10 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
isportal = B_TRUE;
|
||||
}
|
||||
|
||||
if (!onpurpose) {
|
||||
falling = B_TRUE;
|
||||
}
|
||||
|
||||
// check...
|
||||
if (dir == D_DOWN) {
|
||||
if (lfhasflag(lf, F_LEVITATING)) {
|
||||
|
@ -13755,6 +14029,18 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (dir == D_UP) {
|
||||
if (hasflagval(o->flags, F_PIT, D_UP, NA, NA, NULL)) {
|
||||
// can only go up if you have a rope or are flying/levitating
|
||||
if (lfhasflag(lf, F_LEVITATING) || lfhasflag(lf, F_FLYING)) {
|
||||
// ok.
|
||||
} else { // TODO: if has rope???
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// announce
|
||||
|
@ -13767,18 +14053,27 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s enters %s...", lfname, obname);
|
||||
}
|
||||
} else if (hasflag(o->flags, F_PIT)) {
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
msg("%s %s %s the %s...", lfname, getpitverb(lf, dir,onpurpose), getdirname(dir), noprefix(obname));
|
||||
// move cursor to msgwindow while we create the new level...
|
||||
if (isplayer(lf)) wrefresh(msgwin);
|
||||
}
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You %s %s the staircase...", getmoveverb(lf), getdirname(dir));
|
||||
// move cursor to msgwindow while we create the new level...
|
||||
wrefresh(msgwin);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s %s %s the staircase...", lfname, getmoveverbother(lf), getdirname(dir));
|
||||
msg("%s %s %s the staircase.", lfname, getmoveverbother(lf), getdirname(dir));
|
||||
}
|
||||
}
|
||||
|
||||
// find adjacent allies or enemies which will follow you
|
||||
if (isplayer(lf)) {
|
||||
// (but not into/out of pits)
|
||||
if (isplayer(lf) || !hasflag(o->flags, F_PIT)) {
|
||||
getadjallies(lf, adjally, &nadjallies);
|
||||
}
|
||||
|
||||
|
@ -13790,27 +14085,27 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
if (isplayer(lf)) msg("This portal doesn't seem to go anywhere.");
|
||||
} else {
|
||||
// is there already a level of the correct depth?
|
||||
newmap = findregionmap(lf->cell->map->region, newdepth);
|
||||
newmap = findregionmap(newregion->id, newdepth);
|
||||
if (newmap) {
|
||||
dblog("ERROR - unlinked stairs!\n");
|
||||
msg("ERROR - unlinked stairs!\n");
|
||||
} else {
|
||||
enum HABITAT newhabitat;
|
||||
int newregion;
|
||||
// generate a new map! this will fill in the destination of our stairs
|
||||
newmap = addmap();
|
||||
if (newdepth == 0) {
|
||||
newregion = RG_WORLDMAP;
|
||||
newhabitat = AUTO;
|
||||
} else {
|
||||
newregion = lf->cell->map->region;
|
||||
newhabitat = AUTO;
|
||||
// first map of a newly created region?
|
||||
if (newregion->id != curmap->region->id) {
|
||||
newdepth = 1;
|
||||
}
|
||||
createmap(newmap, newdepth, newregion, newhabitat, curmap, dir);
|
||||
// link our stairs to the new map.
|
||||
//linkstairs(o);
|
||||
createmap(newmap, newdepth, newregion, curmap, dir);
|
||||
// if we stayed within the same region, our stairs should
|
||||
// now have a destination, since createmap() will automatically check
|
||||
// previous/next levels in the same region.
|
||||
|
||||
// NOW our stairs should have a destination
|
||||
// if not, we need to call linkstairs() on the staircase first.
|
||||
if (newmap->region->id != curmap->region->id) {
|
||||
linkstairs(o);
|
||||
}
|
||||
// at this point, stairs should have a destination
|
||||
newcell = getstairdestination(o);
|
||||
}
|
||||
}
|
||||
|
@ -13841,12 +14136,14 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
if (f) f->known = B_KNOWN;
|
||||
}
|
||||
// move player to new map
|
||||
moveto(lf, newcell, B_TRUE, B_TRUE);
|
||||
moveto(lf, newcell, onpurpose, B_TRUE);
|
||||
|
||||
// take time
|
||||
if ((dir == D_UP) && !isairborne(lf)) {
|
||||
stopsprinting(lf); // you can sprint down stairs, but not up
|
||||
taketime(lf, getmovespeed(lf)*2); // takes longer to climb
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf)*2); // takes longer to climb
|
||||
} else {
|
||||
taketime(lf, getmovespeed(lf));
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
}
|
||||
|
||||
// move adjacent allies/monsters too
|
||||
|
@ -13858,9 +14155,9 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
stopsprinting(adjally[n]);
|
||||
movelf(adjally[n], c);
|
||||
if ((dir == D_UP) && !isairborne(adjally[n])) {
|
||||
taketime(adjally[n], getmovespeed(adjally[n])*2); // takes longer to climb
|
||||
if (onpurpose) taketime(adjally[n], getmovespeed(adjally[n])*2); // takes longer to climb
|
||||
} else {
|
||||
taketime(adjally[n], getmovespeed(adjally[n]));
|
||||
if (onpurpose) taketime(adjally[n], getmovespeed(adjally[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13871,6 +14168,29 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (falling) {
|
||||
if (dir == D_DOWN) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You slam into the ground!");
|
||||
} else if (cansee(player, lf)){
|
||||
msg("%s slams into the ground!", lfname);
|
||||
}
|
||||
// take fall damage
|
||||
losehp(lf, roll("2d6"), DT_FALL, NULL, "falling");
|
||||
// fall over
|
||||
fall(lf, NULL, B_FALSE);
|
||||
} else {
|
||||
// TODO: if you are outside, DIE!
|
||||
if (isplayer(lf)) {
|
||||
msg("You slam into the roof!");
|
||||
} else if (cansee(player, lf)){
|
||||
msg("%s slams into the roof!", lfname);
|
||||
}
|
||||
// take hitting roof damage
|
||||
losehp(lf, roll("1d4"), DT_FALL, NULL, "slamming into the roof");
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
statdirty = B_TRUE;
|
||||
needredraw = B_TRUE;
|
||||
|
|
9
lf.h
9
lf.h
|
@ -5,7 +5,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
|
|||
job_t *addjob(enum JOB id, char *name);
|
||||
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass);
|
||||
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime);
|
||||
void addtrail(lifeform_t *lf, int dir);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
||||
|
@ -48,6 +48,9 @@ int countnearbyhurtallies(lifeform_t *lf);
|
|||
void debug(lifeform_t *lf);
|
||||
int demandbribe(lifeform_t *lf);
|
||||
void die(lifeform_t *lf);
|
||||
int digcell(lifeform_t *lf, cell_t *c, object_t *o);
|
||||
int digdown(lifeform_t *lf, object_t *o);
|
||||
int digup(lifeform_t *lf, object_t *o);
|
||||
void dumplev(void);
|
||||
void dumplf(void);
|
||||
void dumpxp(void);
|
||||
|
@ -80,6 +83,7 @@ void getadjallies(lifeform_t *lf, lifeform_t **adjally, int *nadjallies);
|
|||
enum ALLEGIENCE getallegiance(lifeform_t *lf);
|
||||
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
|
||||
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||
int getarmournoise(lifeform_t *lf);
|
||||
int getarmourrating(lifeform_t *lf);
|
||||
int getattackspeed(lifeform_t *lf);
|
||||
int getattpoints(lifeform_t *lf);
|
||||
|
@ -131,6 +135,7 @@ int getmovespeed(lifeform_t *lf);
|
|||
char *getmoveverb(lifeform_t *lf);
|
||||
char *getmoveverbother(lifeform_t *lf);
|
||||
lifeform_t *getnearbypeaceful(lifeform_t *lf);
|
||||
char *getpitverb(lifeform_t *lf, int dir, int onpurpose);
|
||||
char *getlfname(lifeform_t *lf, char *buf);
|
||||
char *real_getlfname(lifeform_t *lf, char *buf, int usevis);
|
||||
char *getlfnamea(lifeform_t *lf, char *buf);
|
||||
|
@ -297,7 +302,7 @@ void unsummon(lifeform_t *lf, int vanishobs);
|
|||
int unweild(lifeform_t *lf, object_t *o);
|
||||
int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where);
|
||||
int useringofmiracles(lifeform_t *lf, int charges);
|
||||
int usestairs(lifeform_t *lf, object_t *o);
|
||||
int usestairs(lifeform_t *lf, object_t *o, int onpurpose);
|
||||
int validateraces(void);
|
||||
int wear(lifeform_t *lf, object_t *o);
|
||||
int weild(lifeform_t *lf, object_t *o);
|
||||
|
|
34
map.h
34
map.h
|
@ -1,12 +1,17 @@
|
|||
#include "defs.h"
|
||||
|
||||
cell_t *addcell(map_t *map, int x, int y);
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell);
|
||||
void addhomeobs(lifeform_t *lf);
|
||||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded);
|
||||
object_t *addrandomob(cell_t *c);
|
||||
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
||||
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct);
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent);
|
||||
regionoutline_t *addregionoutline(enum REGIONTYPE rtype);
|
||||
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir);
|
||||
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
void clearcell(cell_t *c);
|
||||
int dowaterspread(cell_t *c);
|
||||
|
@ -17,21 +22,22 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
|||
enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf);
|
||||
int getdoorlockdiff(int depth);
|
||||
int getdoorsecretdiff(int depth);
|
||||
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
||||
enum CELLTYPE getwallcelltype(enum HABITAT hab);
|
||||
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
||||
int getmapdifficulty(map_t *m);
|
||||
void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells);
|
||||
void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid);
|
||||
object_t *gettopobject(cell_t *where, int forglyph);
|
||||
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, int force);
|
||||
int countadjcellsoftype(cell_t *cell, int id);
|
||||
int countadjcellswithflag(cell_t *cell, enum FLAG fid);
|
||||
int countcellexits(cell_t *cell);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir);
|
||||
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir);
|
||||
void createpit(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIONTYPE newregiontype, region_t *parent);
|
||||
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth);
|
||||
int dirtox(int dt, int dir);
|
||||
|
@ -41,16 +47,23 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
|
|||
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 *findcelltypebyname(char *name);
|
||||
habitat_t *findhabitat(enum HABITAT id);
|
||||
habitat_t *findhabitatbyname(char *name);
|
||||
map_t *findmap(int mid);
|
||||
map_t *findmapofdepth(int depth);
|
||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
||||
object_t *findobidinmap(map_t *m, long id);
|
||||
cell_t *findobinmap(map_t *m, enum OBCLASS oid);
|
||||
map_t *findregionmap(int region, int depth);
|
||||
region_t *findregion(int regionid);
|
||||
region_t *findregionbytype(enum REGIONTYPE rtid);
|
||||
map_t *findregionmap(int regionid, int depth);
|
||||
regiontype_t *findregiontype(enum REGIONTYPE rtype);
|
||||
map_t *findsurfaceexitmap(map_t *m);
|
||||
void forgetcells(map_t *map, int amt);
|
||||
cell_t *getcellindir(cell_t *cell, int dir);
|
||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||
int getobchance(int habitat);
|
||||
char *getregionname(char *buf, map_t *m, int withlevel);
|
||||
int getvaultchance(map_t *m);
|
||||
char getvaultchar(vault_t *v, int x, int y);
|
||||
int getthingchance(int habitat);
|
||||
|
@ -69,6 +82,7 @@ lifeform_t *haslf(cell_t *c);
|
|||
int hasknownobject(cell_t *c);
|
||||
int hasobject(cell_t *c);
|
||||
object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tflag, lifeform_t *viewer);
|
||||
void initmap(void);
|
||||
int isadjacent(cell_t *src, cell_t *dst);
|
||||
int isdark(cell_t *c);
|
||||
int isdiggable(cell_t *c);
|
||||
|
@ -82,11 +96,15 @@ int isonmap(map_t *map, int x, int y);
|
|||
int isoutdoors(map_t *m);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||
void linkholes(map_t *map);
|
||||
int linkstairs(object_t *o);
|
||||
void makedoor(cell_t *cell);
|
||||
void makedoor(cell_t *cell, int openchance);
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||
void setcellknown(cell_t *cell, int forcelev);
|
||||
void setcelltype(cell_t *cell, int id);
|
||||
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
||||
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
|
||||
void updateknowncells(void);
|
||||
int validateregions(void);
|
||||
int validateregionthing(regionthing_t *thing);
|
||||
int wallstoleftright(cell_t *c, int dir);
|
||||
|
|
21
move.c
21
move.c
|
@ -1202,7 +1202,9 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
// just clear the message buffer
|
||||
if (!didmsg) clearmsg();
|
||||
} else { // tell player what is here
|
||||
dolook(newcell, B_FALSE);
|
||||
if (onpurpose) {
|
||||
dolook(newcell, B_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1348,7 +1350,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
// locked?
|
||||
if (hasflag(o->flags, F_LOCKED)) {
|
||||
if (lf && isplayer(lf)) {
|
||||
msg("The door is locked.");
|
||||
msg("The %s is locked.", noprefix(obname));
|
||||
}
|
||||
return B_TRUE;
|
||||
} else {
|
||||
|
@ -1361,9 +1363,9 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
|
||||
if (lf && isplayer(lf)) {
|
||||
if (amt > 0) {
|
||||
msg("The door moves slightly but seems jammed.");
|
||||
msg("The %s moves slightly but seems jammed.", noprefix(obname));
|
||||
} else {
|
||||
msg("The door is jammed.");
|
||||
msg("The %s is jammed.", noprefix(obname));
|
||||
}
|
||||
}
|
||||
// loosen a bit
|
||||
|
@ -1491,7 +1493,9 @@ int closedoor(lifeform_t *lf, object_t *o) {
|
|||
} else {
|
||||
// close it
|
||||
killflag(f);
|
||||
addflag(o->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
||||
f = hasflag(o->flags, F_DOOR);
|
||||
addflag(o->flags, F_IMPASSABLE, f->val[0], f->val[1], f->val[2], f->text);
|
||||
|
||||
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
|
||||
if (lf) {
|
||||
|
@ -2009,6 +2013,11 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// train
|
||||
if (isswimming(lf)) {
|
||||
practice(lf, SK_SWIMMING, 1);
|
||||
}
|
||||
} else {
|
||||
object_t *inway = NULL;
|
||||
int door, dooropen;
|
||||
|
@ -2236,7 +2245,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (!adjmap) {
|
||||
// make one
|
||||
adjmap = addmap();
|
||||
createmap(adjmap, thismap->depth, thismap->region, AUTO, thismap, dir);
|
||||
createmap(adjmap, thismap->depth, thismap->region, thismap, dir);
|
||||
}
|
||||
|
||||
if (adjmap) {
|
||||
|
|
36
nexus.c
36
nexus.c
|
@ -30,7 +30,11 @@ race_t *firstrace = NULL,*lastrace = NULL;
|
|||
raceclass_t *firstraceclass = NULL,*lastraceclass = NULL;
|
||||
job_t *firstjob = NULL,*lastjob = NULL;
|
||||
skill_t *firstskill = NULL,*lastskill = NULL;
|
||||
habitat_t *firsthabitat = NULL,*lasthabitat = NULL;
|
||||
map_t *firstmap = NULL,*lastmap = NULL;
|
||||
region_t *firstregion = NULL,*lastregion = NULL;
|
||||
regionoutline_t *firstregionoutline = NULL,*lastregionoutline = NULL;
|
||||
regiontype_t *firstregiontype = NULL,*lastregiontype = NULL;
|
||||
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
||||
hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
||||
|
||||
|
@ -145,6 +149,7 @@ int main(int argc, char **argv) {
|
|||
cell_t *where;
|
||||
int dir;
|
||||
flag_t *f;
|
||||
map_t *dmap;
|
||||
|
||||
// read from input file if required
|
||||
if (playerfile) {
|
||||
|
@ -178,13 +183,21 @@ int main(int argc, char **argv) {
|
|||
// if no maps (ie. ALWAYS now that maps aren't persistent),
|
||||
// make the initial level
|
||||
if (!firstmap) {
|
||||
region_t *wregion, *dregion;
|
||||
newworld = B_TRUE;
|
||||
// create world map.
|
||||
wregion = addregion(RG_WORLDMAP, NULL);
|
||||
addmap();
|
||||
createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE);
|
||||
//createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
||||
// create first dungeon
|
||||
dregion = findregionbytype(RG_FIRSTDUNGEON);
|
||||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, NULL, D_NONE);
|
||||
}
|
||||
|
||||
// find staircase
|
||||
where = findobinmap(firstmap, OT_STAIRSUP);
|
||||
where = findobinmap(dmap, OT_STAIRSUP);
|
||||
assert(where);
|
||||
// make sure no lifeforms are there
|
||||
if (where->lf) {
|
||||
|
@ -752,17 +765,7 @@ int init(void) {
|
|||
initjobs();
|
||||
initrace();
|
||||
|
||||
// cell types
|
||||
addcelltype(CT_WALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", '#', C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0);
|
||||
addcelltype(CT_WALLMETAL, "metal wall", '#', C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0);
|
||||
addcelltype(CT_ROOMWALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_ROOM, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT, 0);
|
||||
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -1);
|
||||
initmap();
|
||||
|
||||
gamemode = GM_VALIDATION;
|
||||
if (validateobs()) {
|
||||
|
@ -779,6 +782,12 @@ int init(void) {
|
|||
// load in vaults
|
||||
loadvaults();
|
||||
|
||||
// validate regions
|
||||
if (validateregions()) {
|
||||
printf("Errors found in map outlines - check log for details. Bailing out.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -927,6 +936,7 @@ int limitf(float *what, float min, float max) {
|
|||
}
|
||||
|
||||
int onein(int howmany) {
|
||||
if (howmany <= 0) return B_FALSE;
|
||||
if (rnd(1,howmany) == 1) return B_TRUE;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
|
358
objects.c
358
objects.c
|
@ -982,6 +982,57 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
}
|
||||
|
||||
|
||||
// link holes to adjacent maps
|
||||
if (o && hasflag(o->flags, F_PIT)) {
|
||||
cell_t *c;
|
||||
map_t *adjmap = NULL;
|
||||
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
|
||||
c = getoblocation(o);
|
||||
if ((c->map->region->rtype->id == RG_WORLDMAP) && (f->val[0] == D_DOWN)) {
|
||||
// ie. going down from the surface. MUST be down because holes
|
||||
// going up make no sense!
|
||||
createregionlink(c->map, c, o, NULL, RG_PIT, c->map->region);
|
||||
} else {
|
||||
// create linked holes on any existing adjacent maps
|
||||
if (f->val[0] == D_DOWN) {
|
||||
adjmap = findregionmap(c->map->region->id, c->map->depth+1);
|
||||
} else if (f->val[0] == D_UP) {
|
||||
if ((c->map->region->rtype->id != RG_WORLDMAP) &&
|
||||
(c->map->depth == 1) &&
|
||||
(c->map->region->rtype->deeperdir == D_DOWN)) {
|
||||
cell_t *newcell;
|
||||
object_t *newob;
|
||||
char buf[BUFLEN];
|
||||
// ie. digging up to the surface
|
||||
adjmap = findsurfaceexitmap(c->map);
|
||||
// make a hole here. don't use linkholes since it can't
|
||||
// cross regions.
|
||||
newcell = getcellat(adjmap, c->x, c->y);
|
||||
if (newcell->type->solid) {
|
||||
newcell = real_getrandomadjcell(newcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, &(o->type->id));
|
||||
}
|
||||
|
||||
newob = addob(newcell->obpile, "hole in the ground");
|
||||
sprintf(buf, "%ld", o->id);
|
||||
addflag(newob->flags, F_MAPLINK, c->map->id, NA, NA, buf);
|
||||
|
||||
sprintf(buf, "%ld", newob->id);
|
||||
addflag(o->flags, F_MAPLINK, adjmap->id, NA, NA, buf);
|
||||
|
||||
// don't call linkholes
|
||||
adjmap = NULL;
|
||||
} else {
|
||||
adjmap = findregionmap(c->map->region->id, c->map->depth-1);
|
||||
}
|
||||
}
|
||||
if (adjmap) {
|
||||
linkholes(adjmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// other special changes we need to make based on what was
|
||||
// asked for
|
||||
if ((gamemode != GM_LOADING) && o) {
|
||||
|
@ -1064,7 +1115,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
if (f) {
|
||||
rf = hasflag(corpserace->flags, F_SIZE);
|
||||
if (rf) {
|
||||
f->val[0] = rf->val[0];
|
||||
f->val[0] = SZ_MIN;
|
||||
f->val[1] = rf->val[0];
|
||||
} else {
|
||||
killflag(f);
|
||||
}
|
||||
|
@ -2666,7 +2718,7 @@ glyph_t *getglyph(object_t *o) {
|
|||
|
||||
if (isdoor(o, &isopen)) {
|
||||
if (issecretdoor(o)) {
|
||||
return &(findcelltype(getwallcelltype(obloc->map->habitat))->glyph);
|
||||
return &(findcelltype(obloc->map->habitat->solidcelltype)->glyph);
|
||||
} else {
|
||||
if (isopen) {
|
||||
g = '-';
|
||||
|
@ -4017,13 +4069,24 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
|
||||
// show portal/stair destination
|
||||
f = hasflag(o->flags, F_MAPLINK);
|
||||
if (f && f->known) {
|
||||
if (f && f->known && !hasflag(o->flags, F_PIT)) {
|
||||
cell_t *thiscell;
|
||||
map_t *thismap;
|
||||
map_t *newmap;
|
||||
thiscell = getoblocation(o);
|
||||
thismap = thiscell->map;
|
||||
newmap = findmap(f->val[0]);
|
||||
if (newmap) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, " to level %d", newmap->depth);
|
||||
strcat(localbuf, buf2);
|
||||
if (newmap->region == thismap->region) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, " to level %d", newmap->depth);
|
||||
strcat(localbuf, buf2);
|
||||
} else {
|
||||
char buf2[BUFLEN];
|
||||
strcat(localbuf, " to ");
|
||||
getregionname(buf2, newmap, B_FALSE);
|
||||
strcat(localbuf, buf2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4300,7 +4363,7 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
rarflag = hasflagval(ot->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (map) {
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, map->habitat, NA, NA, NULL);
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
|
@ -4479,7 +4542,7 @@ int getobrarity(object_t *o, enum RARITY *rr) {
|
|||
m = c->map;
|
||||
}
|
||||
if (m) {
|
||||
f = hasflagval(o->flags, F_RARITY,m->habitat, NA, NA, NULL);
|
||||
f = hasflagval(o->flags, F_RARITY,m->habitat->id, NA, NA, NULL);
|
||||
if (f) {
|
||||
if (rr) {
|
||||
*rr = (f->val[2] == NA) ? RR_COMMON : f->val[2];
|
||||
|
@ -5197,8 +5260,8 @@ void initobjects(void) {
|
|||
// dungeon features
|
||||
addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 150, OC_DFEATURE);
|
||||
// GLYPH here is a special case in getglyph
|
||||
addflag(lastot->flags, F_DOOR, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5210,8 +5273,8 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE);
|
||||
// GLYPH here is a special case in getglyph
|
||||
addflag(lastot->flags, F_DOOR, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5222,11 +5285,25 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
// blocks movement, but you can see and fire through them.
|
||||
addot(OT_IRONGATE, "iron gate", "A gate comprised of a series of vertical iron bars.", MT_METAL, 0, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "|");
|
||||
addflag(lastot->flags, F_DOOR, SZ_MEDIUM, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 120, 120, NA, NULL);
|
||||
addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
|
||||
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5237,9 +5314,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones");
|
||||
|
||||
|
||||
addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "'");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5249,7 +5327,7 @@ void initobjects(void) {
|
|||
addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); // will be overridden
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5258,6 +5336,25 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "20-50 stones");
|
||||
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "a statue");
|
||||
|
||||
addot(OT_HOLEINGROUND, "hole in the ground", "A gaping hole in the ground.", MT_NOTHING, 0, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "^");
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_HOLEINROOF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_HOLEINROOF, "hole in the roof", "A gaping hole in the roof.", MT_NOTHING, 0, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "<");
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PIT, D_UP, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_HOLEINGROUND, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_STAIRSDOWN, "staircase going down", "A stone staircase winding downwards.", MT_STONE, 3000, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ">");
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
|
||||
|
@ -5472,7 +5569,7 @@ void initobjects(void) {
|
|||
addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 40, OC_FLORA);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MEDIUM, NA, NULL);
|
||||
addflag(lastot->flags, F_REDUCEMOVEMENT, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5482,7 +5579,7 @@ void initobjects(void) {
|
|||
addot(OT_STUMP, "stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "'");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
||||
|
@ -5491,7 +5588,7 @@ void initobjects(void) {
|
|||
addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "#");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5814,6 +5911,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_COMMANDUNDEAD, "command undead", "Compels an undead creature to follow a single simple command.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_FEAR, "cause fear", "Causes intense fear in the target.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
|
@ -5943,6 +6044,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||
addot(OT_S_SHATTER, "shatter", "Instantly shatters all glass in the target location.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_AIRBLAST, "airblast", "Knocks enemies back with a powerful blast of air.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
|
@ -6553,7 +6660,7 @@ void initobjects(void) {
|
|||
addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
||||
addot(OT_A_REPAIR, "repair armour", "Repair damage done to your armour.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addot(OT_A_REPAIR, "repair equipment", "Repair damage done to your equipment.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
|
@ -6931,6 +7038,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SHARP, 1, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_CALTROP, "caltrop", "Connected metal spikes arranged such that one will always point upwards.", MT_METAL, 0.2, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
|
||||
|
@ -6963,6 +7071,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
||||
|
@ -7167,7 +7276,7 @@ void initobjects(void) {
|
|||
addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 20, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "(");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_HUGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7178,7 +7287,7 @@ void initobjects(void) {
|
|||
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "\\");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7376,14 +7485,15 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_ICEWALL, "wall of ice", "A wall made of solid ice.", MT_ICE, 0, OC_EFFECT);
|
||||
addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "#");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 100, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
||||
addot(OT_MAGICBARRIER, "magical barrier", "A glowing, impassable barrier of magical energy.", MT_MAGIC, 0, OC_EFFECT);
|
||||
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "#");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
|
||||
|
@ -7589,7 +7699,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
||||
addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_METAL, 1, OC_ARMOUR);
|
||||
addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_METAL, 3.5, OC_ARMOUR);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
||||
|
@ -8639,14 +8749,15 @@ int isimpassableob(object_t *o, lifeform_t *lf) {
|
|||
f = hasflag(o->flags, F_IMPASSABLE);
|
||||
if (f) {
|
||||
enum LFSIZE lfsize;
|
||||
enum LFSIZE blocksize;
|
||||
enum LFSIZE blockmin, blockmax;
|
||||
|
||||
if (!lf) return B_TRUE;
|
||||
|
||||
lfsize = getlfsize(lf);
|
||||
blocksize = f->val[0];
|
||||
|
||||
if (lfsize <= blocksize) {
|
||||
blockmin = f->val[0];
|
||||
blockmax = f->val[1];
|
||||
|
||||
if ((lfsize >= blockmin) && (lfsize <= blockmax)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -9274,6 +9385,18 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
|
|||
|
||||
reason = E_OK;
|
||||
|
||||
// adjust destination for pits
|
||||
if (dst->where) {
|
||||
object_t *pit;
|
||||
pit = hasobwithflagval(dst->where->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
if (pit) {
|
||||
cell_t *newcell;
|
||||
newcell = getstairdestination(pit);
|
||||
if (newcell) {
|
||||
dst = newcell->obpile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (db) dblog("DB: moveob() - moving %d x %s",howmany, src->type->name);
|
||||
if (stackok) {
|
||||
|
@ -9354,6 +9477,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
|
|||
killflagsofid(o->flags, F_SECRET);
|
||||
if (!hasflag(o->flags, F_OPEN)) {
|
||||
addflag(o->flags, F_OPEN, B_TRUE, NA, NA, NULL);
|
||||
killflagsofid(o->flags, F_IMPASSABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10124,7 +10248,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
} else if (o->type->id == OT_ORBDUNGEONEXIT) {
|
||||
map_t *m;
|
||||
m = lf->cell->map;
|
||||
if ((m->region == RG_FIRSTDUNGEON) && (m->depth == 1)) {
|
||||
if ((m->region->rtype->id == RG_FIRSTDUNGEON) && (m->depth == 1)) {
|
||||
cell_t *cell[MAXCANDIDATES];
|
||||
int ncells,i;
|
||||
getradiuscells(lf->cell, 1, DT_COMPASS, B_FALSE, B_TRUE, cell, &ncells);
|
||||
|
@ -10255,101 +10379,30 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
} else if (o->type->id == OT_PICKAXE) {
|
||||
int ch,dir;
|
||||
cell_t *c;
|
||||
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
||||
dir = chartodir(ch);
|
||||
c = getcellindir(player->cell, dir);
|
||||
|
||||
if (!c) {
|
||||
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn><-","-", B_FALSE);
|
||||
if (ch == '-') {
|
||||
// cancel
|
||||
clearmsg();
|
||||
return B_TRUE;
|
||||
}
|
||||
if (c->type->solid) {
|
||||
if (isdiggable(c)) {
|
||||
// replace wall
|
||||
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig through the wall.");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s digs through a wall.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
//drawscreen();
|
||||
// takes extra time
|
||||
taketime(lf, getactspeed(lf)*9);
|
||||
} else {
|
||||
// fail
|
||||
if (isplayer(lf)) {
|
||||
msg("This wall is too hard to dig.");
|
||||
}
|
||||
} else if (ch == '>') {
|
||||
if (digdown(lf, o)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
} else { // not solid
|
||||
int failed = B_FALSE;
|
||||
object_t *door;
|
||||
|
||||
door = hasobwithflag(c->obpile, F_DOOR);
|
||||
if (door) {
|
||||
int dooropen;
|
||||
// only closed doors!
|
||||
isdoor(door, &dooropen);
|
||||
if (dooropen) {
|
||||
door = NULL;
|
||||
}
|
||||
} else if (ch == '<') {
|
||||
if (digup(lf, o)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
} else {
|
||||
dir = chartodir(ch);
|
||||
c = getcellindir(lf->cell, dir);
|
||||
|
||||
if (door) {
|
||||
// TODO: metal doors are immune to CHOP damage
|
||||
if (!isimmuneto(door->flags, DT_CHOP)) {
|
||||
taketime(lf, getactspeed(lf));
|
||||
removeob(door, door->amt);
|
||||
if (isplayer(lf)) {
|
||||
msg("You smash open a door!");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s smashes open a door.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
drawscreen();
|
||||
failed = B_FALSE;
|
||||
}
|
||||
} else if (hasob(c->obpile, OT_STATUE)) {
|
||||
int dam;
|
||||
object_t *so;
|
||||
char statname[BUFLEN];
|
||||
|
||||
so = hasob(c->obpile, OT_STATUE);
|
||||
getobname(so, statname, so->amt);
|
||||
|
||||
taketime(lf, getactspeed(lf));
|
||||
|
||||
// statue takes 1/2 damage
|
||||
f = hasflag(so->flags, F_OBHP);
|
||||
if (f) {
|
||||
dam = (f->val[1] / 2); // ie. half max hp
|
||||
} else {
|
||||
dam = 1;
|
||||
}
|
||||
// statue ?
|
||||
if (isplayer(lf)) {
|
||||
msg("You hit %s with your %s.", statname, noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s hits %s with %s.", lfname, statname, obname);
|
||||
}
|
||||
takedamage(so, dam, DT_CHOP);
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You swing your %s through the air.",noprefix(obname));
|
||||
}
|
||||
taketime(lf, getactspeed(lf));
|
||||
if (digcell(lf, c, o)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
} // end if ch is a direction
|
||||
} else if (o->type->id == OT_SPANNER) {
|
||||
int donesomething = B_FALSE;
|
||||
if (!where) {
|
||||
|
@ -11671,7 +11724,8 @@ void setobcreatedby(object_t *o, lifeform_t *lf) {
|
|||
}
|
||||
|
||||
|
||||
void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
||||
// returns TRUE if it did shatter
|
||||
int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
||||
int shatterdam;
|
||||
cell_t *where = NULL;
|
||||
lifeform_t *target = NULL;
|
||||
|
@ -11680,6 +11734,10 @@ void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
char targetname[BUFLEN];
|
||||
int seen = B_FALSE;
|
||||
|
||||
if (hasflag(o->flags, F_NOSHATTER)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
getobname(o,obname,o->amt);
|
||||
where = getoblocation(o);
|
||||
|
||||
|
@ -11695,13 +11753,20 @@ void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
|
||||
// announce
|
||||
if (haslos(player, where)) {
|
||||
char *obcaps;
|
||||
obcaps = strdup(obname);
|
||||
capitalise(obcaps);
|
||||
obcaps = strrep(obcaps, "An ", "The ", NULL);
|
||||
obcaps = strrep(obcaps, "A ", "The ", NULL);
|
||||
msg("%s shatter%s!",obcaps, (o->amt == 1) ? "s" : "");
|
||||
free(obcaps);
|
||||
char prefix[BUFLEN];
|
||||
|
||||
if (o->pile->owner) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(o->pile->owner, lfname);
|
||||
sprintf(prefix, "%s%s ", lfname, getpossessive(lfname));
|
||||
// ie. "the kobold's"
|
||||
} else {
|
||||
strcpy(prefix, "");
|
||||
}
|
||||
|
||||
|
||||
msg("%s%s shatter%s!",prefix, strlen(prefix) ? noprefix(obname) : obname,
|
||||
(o->amt == 1) ? "s" : "");
|
||||
|
||||
seen = B_TRUE;
|
||||
} else {
|
||||
|
@ -11873,6 +11938,8 @@ void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
// object is dead.
|
||||
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
addflag(o->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// randomizes hidden names
|
||||
|
@ -12101,14 +12168,14 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
|
||||
// special cases....
|
||||
if (damtype == DT_FIRE) {
|
||||
if (o->material->id == MT_FLESH) { // fire roasts flesh
|
||||
if ((o->material->id == MT_FLESH) && rnd(1,3)) { // fire sometimes roasts flesh
|
||||
object_t *meat;
|
||||
meat = addob(o->pile, "chunk of roast meat");
|
||||
// purposely don't use getweight!
|
||||
meat->weight = o->weight;
|
||||
} else { // fire turns other things to ash
|
||||
addob(o->pile, "pile of ash");
|
||||
}
|
||||
// fire turns things to ash
|
||||
addob(o->pile, "pile of ash");
|
||||
} else if (damtype == DT_BASH) {
|
||||
if (o->material->id == MT_GLASS) { // bashing damage breaks glass
|
||||
int nshards;
|
||||
|
@ -12194,7 +12261,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
char throwverbpast[BUFLEN];
|
||||
char throwverbpres[BUFLEN];
|
||||
int acc;
|
||||
int youhit;
|
||||
int youhit = B_FALSE;
|
||||
object_t *newob;
|
||||
cell_t *newloc;
|
||||
int db = B_TRUE;
|
||||
|
@ -12537,6 +12604,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
dam = (int)((float)throwdam * multiplier);
|
||||
takedamage(shield, dam, DT_PROJECTILE);
|
||||
youhit = B_FALSE;
|
||||
practice(target, SK_SHIELDS, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12640,6 +12708,10 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
|
||||
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam);
|
||||
|
||||
if (firearm) {
|
||||
practice(thrower, SK_RANGED, 1);
|
||||
}
|
||||
}
|
||||
} else { // ie. if !youhit
|
||||
if (!announcedmiss) {
|
||||
|
@ -12672,8 +12744,11 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
sprintf(dambuf, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
shatter(newob, youhit, dambuf, thrower);
|
||||
} else {
|
||||
// don't announce damage to the thrown object
|
||||
real_takedamage(newob, speed-1, DT_BASH, B_FALSE);
|
||||
// object only gets damaged if it hit someone
|
||||
if (youhit) {
|
||||
// don't announce damage to the thrown object
|
||||
real_takedamage(newob, speed-1, DT_BASH, B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
|
@ -13154,7 +13229,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf) {
|
|||
} else if (oid == OT_TRAPTELEPORT) {
|
||||
cell_t *newc;
|
||||
// move somewhere else!
|
||||
newc = getrandomcelloftype(lf->cell->map, getemptycelltype(lf->cell->map->habitat));
|
||||
newc = getrandomcelloftype(lf->cell->map, lf->cell->map->habitat->id);
|
||||
if (newc) {
|
||||
teleportto(lf, newc, B_TRUE);
|
||||
}
|
||||
|
@ -13486,6 +13561,25 @@ int validateobs(void) {
|
|||
printf("ERROR in object '%s' - has f_thereishere but no ->text.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
f = hasflag(ot->flags, F_IMPASSABLE);
|
||||
if (f && ((f->val[0] == NA) || (f->val[1] == NA)) ) {
|
||||
printf("ERROR in object '%s' - f_impassable missing either min or max.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
f = hasflag(ot->flags, F_DOOR);
|
||||
if (f) {
|
||||
flag_t *f2;
|
||||
f2 = hasflag(ot->flags, F_IMPASSABLE);
|
||||
if (f2) {
|
||||
if ((f->val[0] != f2->val[0]) || (f->val[1] != f2->val[1])) {
|
||||
printf("ERROR in object '%s' - f_door vals don't match f_impassable vals.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
printf("ERROR in object '%s' - has f_door but not f_impassable.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -204,7 +204,7 @@ void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
|||
int sethiddenname(objecttype_t *o, char *text);
|
||||
void setinscription(object_t *o, char *text);
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||
void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
void shufflehiddennames(void);
|
||||
object_t *splitob(object_t *o);
|
||||
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||
|
|
6
save.c
6
save.c
|
@ -256,6 +256,7 @@ map_t *loadmap(char *basefile) {
|
|||
int i;
|
||||
int x,y;
|
||||
int db = B_TRUE;
|
||||
enum HABITAT habitatid;
|
||||
lifeform_t *l;
|
||||
object_t *o;
|
||||
map_t *m;
|
||||
|
@ -284,7 +285,8 @@ map_t *loadmap(char *basefile) {
|
|||
fgets(buf, BUFLEN, f); // map name
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
m->name = strdup(buf + 5); // after 'name:'
|
||||
fscanf(f, "habitat:%d\n",(int *)&m->habitat); // habitat
|
||||
fscanf(f, "habitat:%d\n",(int *)habitatid); // habitat
|
||||
m->habitat = findhabitat(habitatid);
|
||||
fscanf(f, "seed:%d\n",&m->seed); // seed
|
||||
fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons
|
||||
fscanf(f, "nextmaps:\n");
|
||||
|
@ -724,7 +726,7 @@ int savemap(map_t *m) {
|
|||
fprintf(f, "id:%d\n",m->id); // map id
|
||||
fprintf(f, "depth:%d\n",m->depth); // map depth
|
||||
fprintf(f, "name:%s\n",m->name); // map name
|
||||
fprintf(f, "habitat:%d\n",m->habitat); // habitat
|
||||
fprintf(f, "habitat:%d\n",m->habitat->id); // habitat
|
||||
fprintf(f, "seed:%d\n",m->seed); // seed
|
||||
fprintf(f, "dims:%d,%d\n",m->w, m->h); // map dimensons
|
||||
fprintf(f, "nextmaps:\n");
|
||||
|
|
138
spell.c
138
spell.c
|
@ -249,6 +249,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
|
||||
getobname(o, buf, o->amt);
|
||||
msgnocap("%c - %s", o->letter, buf);
|
||||
practice(user, SK_COOKING, 1);
|
||||
} else {
|
||||
msg("Your cooking attempt fails (maybe your pack was too full?).");
|
||||
}
|
||||
|
@ -371,6 +372,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user) && hasjob(user, J_ROGUE)) {
|
||||
gainxp(user, trapflag->val[0]);
|
||||
}
|
||||
practice(user, SK_TRAPS, 1);
|
||||
} else {
|
||||
// failed. another check to see if it goes off
|
||||
if ((trapflag->val[1] == B_TRUE) && !skillcheck(user, SC_DISARM, trapflag->val[0], 0)) {
|
||||
|
@ -693,29 +695,69 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (abilid == OT_A_REPAIR) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
int cutoffpct = 0;
|
||||
slev = getskill(user, SK_ARMOUR);
|
||||
switch (slev) {
|
||||
default:
|
||||
if (isplayer(user)) {
|
||||
msg("You are too unskilled to repair your armour.");
|
||||
}
|
||||
return B_TRUE;
|
||||
case PR_SKILLED: cutoffpct = 50; break;
|
||||
case PR_EXPERT: cutoffpct = 75; break;
|
||||
case PR_MASTER: cutoffpct = 100; break;
|
||||
enum MATERIAL repairablemats[MAXCANDIDATES];
|
||||
int repaircutoff = 0;
|
||||
int cutoffpct[MAXCANDIDATES];
|
||||
int nmats = 0;
|
||||
int i;
|
||||
|
||||
// get list of repairable materials
|
||||
slev = getskill(user, SK_METALWORK);
|
||||
if (slev) {
|
||||
int cutoff;
|
||||
switch (slev) {
|
||||
case PR_NOVICE: cutoff = 33; break;
|
||||
case PR_BEGINNER: cutoff = 40; break;
|
||||
case PR_ADEPT: cutoff = 50; break;
|
||||
case PR_SKILLED: cutoff = 65; break;
|
||||
case PR_EXPERT: cutoff = 80; break;
|
||||
case PR_MASTER: cutoff = 100; break;
|
||||
default: cutoff = 0; break;
|
||||
}
|
||||
repairablemats[nmats] = MT_METAL;
|
||||
cutoffpct[nmats] = cutoff;
|
||||
nmats++;
|
||||
}
|
||||
slev = getskill(user, SK_SEWING);
|
||||
if (slev) {
|
||||
int cutoff;
|
||||
switch (slev) {
|
||||
case PR_NOVICE: cutoff = 33; break;
|
||||
case PR_BEGINNER: cutoff = 40; break;
|
||||
case PR_ADEPT: cutoff = 50; break;
|
||||
case PR_SKILLED: cutoff = 65; break;
|
||||
case PR_EXPERT: cutoff = 80; break;
|
||||
case PR_MASTER: cutoff = 100; break;
|
||||
default: cutoff = 0; break;
|
||||
}
|
||||
repairablemats[nmats] = MT_CLOTH;
|
||||
cutoffpct[nmats] = cutoff;
|
||||
nmats++;
|
||||
repairablemats[nmats] = MT_LEATHER;
|
||||
cutoffpct[nmats] = cutoff;
|
||||
nmats++;
|
||||
}
|
||||
|
||||
|
||||
// 1.compile a list of repairable objects
|
||||
// sk_armour lets you repair armour up to xx% (depends on skill)
|
||||
initprompt(&prompt, "Repair which object?");
|
||||
addchoice(&prompt, '-', "Cancel", buf, o);
|
||||
addchoice(&prompt, '-', "Cancel", "Cancel", o);
|
||||
for (o = user->pack->first ; o ; o = o->next) {
|
||||
if (isarmour(o) && isdamaged(o)) {
|
||||
int ok = B_FALSE;
|
||||
int cutoff = 0;
|
||||
for (i = 0; i < nmats; i++) {
|
||||
if (o->material->id == repairablemats[i]) {
|
||||
ok = B_TRUE;
|
||||
cutoff = cutoffpct[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ok && isdamaged(o)) {
|
||||
float pct;
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
pct = ((float)f->val[0] /(float) f->val[1]) * 100;
|
||||
if (pct < cutoffpct) {
|
||||
if (pct < cutoff) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
// we can repair this object
|
||||
|
@ -747,9 +789,19 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// select cutoff hp
|
||||
repaircutoff = 0;
|
||||
for (i = 0; i < nmats; i++) {
|
||||
if (o->material->id == repairablemats[i]) {
|
||||
repaircutoff = cutoffpct[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(repaircutoff != 0);
|
||||
|
||||
// repair it!
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
f->val[0] = pctof(cutoffpct, f->val[1]);
|
||||
f->val[0] = pctof(repaircutoff, f->val[1]);
|
||||
if (isplayer(user)) {
|
||||
char buf[BUFLEN];
|
||||
real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
||||
|
@ -815,6 +867,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
addtempflag(user->flags, F_SPRINTING, B_TRUE, NA, NA, NULL, howlong);
|
||||
practice(user, SK_ATHLETICS, 1);
|
||||
} else if (abilid == OT_A_STINGACID) {
|
||||
validateabillf(user, abilid, &target);
|
||||
if (!target) return B_TRUE;
|
||||
|
@ -1259,6 +1312,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (cansee(player, user)) {
|
||||
msg("%s tries to steal from %s, but fails.", username, targetname);
|
||||
}
|
||||
} else {
|
||||
practice(user, SK_THIEVERY, 1);
|
||||
}
|
||||
} else if (abilid == OT_A_WARCRY) {
|
||||
// announce
|
||||
|
@ -2324,6 +2379,43 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
damageallobs(NULL, retcell[i]->obpile, 0, DT_COLD);
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_COMMANDUNDEAD) {
|
||||
// mosnters won't cast this.
|
||||
if (!isplayer(caster)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
if (!target || !isundead(target)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// saving throw
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
char tname[BUFLEN];
|
||||
getlfname(target, tname);
|
||||
msg("%s resists.",tname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// they get angry!
|
||||
if (!isplayer(target) && cansee(target, caster)) {
|
||||
fightback(target, caster);
|
||||
}
|
||||
} else {
|
||||
flag_t *f;
|
||||
if (isplayer(caster) || cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// it worked. temporarily make them a pet so that you
|
||||
// can command them.
|
||||
f = addflag(target->flags, F_PETOF, caster->id, NA, NA, NULL);
|
||||
docomms(target);
|
||||
killflag(f);
|
||||
|
||||
}
|
||||
} else if (spellid == OT_S_CREATEMONSTER) {
|
||||
lifeform_t *newlf;
|
||||
job_t *forcejob = NULL;
|
||||
|
@ -2512,7 +2604,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
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], retcell[i]->map->habitat->emptycelltype);
|
||||
if (seenthiscell) {
|
||||
ndigs++;
|
||||
numseen++;
|
||||
|
@ -2700,7 +2792,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
// destroy objects right away
|
||||
removedeadobs(targcell->lf->pack);
|
||||
removedeadobs(targcell->obpile);
|
||||
|
||||
// explosion, based on size...
|
||||
if (totalmass > 0) {
|
||||
|
@ -4118,7 +4210,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
int howlong = 7;
|
||||
howlong = getspellduration(3,5,blessed) + (power/2);
|
||||
addtempflag(target->flags, F_PAIN, DT_MAGIC, NA, NA, "2d4+2", howlong);
|
||||
addtempflag(target->flags, F_PAIN, DT_MAGIC, NA, NA, "1d3", howlong);
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
|
@ -4467,7 +4559,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!newmap) {
|
||||
// create new map
|
||||
newmap = addmap();
|
||||
createmap(newmap, newdepth, caster->cell->map->region, AUTO, NULL, D_NONE);
|
||||
createmap(newmap, newdepth, caster->cell->map->region, NULL, D_NONE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5461,6 +5553,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_SHATTER) {
|
||||
char buf[BUFLEN];
|
||||
if (!validatespellcell(caster, &targcell,TT_NONE, spellid, power, frompot)) return B_TRUE;
|
||||
|
||||
sprintf(buf, "%s%s shatter spell", castername, getpossessive(castername));
|
||||
if (!shattercell(targcell, caster, buf)) {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_SLEEP) {
|
||||
int howlong;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
|
|
|
@ -8,6 +8,7 @@ random(4,4)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:25
|
||||
autopop
|
||||
scatter(1,1,-2,-2) ob:boulder:25%
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
@end
|
||||
|
|
|
@ -8,6 +8,7 @@ random(4,4)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:75
|
||||
autopop
|
||||
! tables & chairs
|
||||
|
|
|
@ -9,6 +9,7 @@ random(5,5)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
! 100% chance of doors - don't want the water escaping
|
||||
autodoors:100
|
||||
autopop
|
||||
|
|
|
@ -8,6 +8,7 @@ random(5,5)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
fill(2,2,-3,-3) cell:low rock floor:100
|
||||
|
|
|
@ -24,6 +24,7 @@ m:mon:minotaur
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
! the reward
|
||||
at(7,7) ob:200-450 gold
|
||||
at(7,7) ob:good weapon
|
||||
|
|
|
@ -8,6 +8,7 @@ random(5,5)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
! don't want cockatrice escaping
|
||||
autodoors:100
|
||||
scatter(1,1,-2,-2) ob:statue:25%
|
||||
|
|
|
@ -9,6 +9,7 @@ random(4,4)
|
|||
|
||||
@flags
|
||||
autodoors:100
|
||||
goesin:dungeon
|
||||
! every cell in here has 1-3 objects and a monster
|
||||
scatter(1,1,-2,-2) mon:random:100%
|
||||
scatter(1,1,-2,-2) ob:random:100%
|
||||
|
|
|
@ -10,6 +10,7 @@ random(4,4)
|
|||
@flags
|
||||
autodoors:50
|
||||
autopop
|
||||
goesin:dungeon
|
||||
! add mud to 50% of room cells
|
||||
scatter(1,1,-2,-2) ob:pool of mud:50%
|
||||
@end
|
||||
|
|
|
@ -7,6 +7,7 @@ random(5,5)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
scatter(1,1,-2,-2) cell:rock wall:25%
|
||||
|
|
|
@ -8,6 +8,7 @@ random(5,5)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
scatter(1,1,-2,-2) cell:glass wall:25%
|
||||
|
|
|
@ -8,6 +8,7 @@ random(3,3)
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:100
|
||||
! half the cells are trapped!
|
||||
scatter(1,1,-2,-2) ob:random trap:50%
|
||||
|
|
|
@ -15,6 +15,7 @@ $:ob:25-200 gold
|
|||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
! no auto doors. ie this can be in the middle of nowhere.
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in New Issue