- [+] monster: triclops. perception. vuln to light.
- [+] flying creatures shoudl fall to the ground when unconscious - [+] (this might kill them) - [+] animate statue - bring statue to life - [+] excavate - radial, obliterate walls + obs, doesn't affect lfs - [+] test unicode wall glyph! 0x2588 - [+] use unicode for gas - [+] change f_glyph so that v1 = symbol, instead of text = symbol - [+] change code - [+] change definitions (macro) - [+] test - [+] implement puff = UNI_SHADELIGHT - [+] implement cloud = bolded - [+] if good, extend to staem etc - [+] blue background for lfs in the water - [+] prone in water means effective lower height - [+] glass/ice cells not shattering properly - [+] make magic barriers be solid too - [+] combine lockpick code in io.c and objects.c into the lockpick() function. - [+] first ask what to use (if required) - [+] then ask what dir (if required) - [+] then ask what to unlock (if reuiqred) - [+] then do it - [+] locked containers - [+] picklocks prompts to try them. - [+] in addob, use non-inheritable f_lockedchance for both doors and chests? - [+] v0 = chance v1 = mod per depth - [+] doors: - [+] base 20% chance locked - [+] every 5 levels, add 10% chance - [+] add this to chests / safeboxes - [+] operate doesn't let you open them - [+] bugs in linkexits and linkexit - [+] linkexits: wasn't checking the correct exit cell!!! - [+] lnkexit: wasn't blanking the startcell GRATINGS: - [+] flags: - [+] addflag(lastot->flags, F_OPPOSITESTAIRS, OT_HOLEINROOF, NA, NA, NULL); - [+] climbable d_down NA - [+] BUT you can't climb it if it's locked. - [+] usestairs() - if you climb a grating and it has no maplink: - [+] use createregionlink(map, cell, grating_object, NULL, RG_SEWER, map->region) - [+] make stench affect enhancedsmell creatures more. - [+] excavate should only affect SOLID matter. - [+] going down a drain: - [+] "You walk down a staircase" should be "climb down a drain" - [+] deep slime in sewers sohuldn't spread - [+] deep slime should spread to a slime puddle if it does.... - [+] fix background glyph colour for slime - [+] killed by drowning should really be "drowned in %s" SEWER HABITAT - [+] permenant stench - [+] if you're in a sewer cell and are not nauseated, add it. - [+] nauseated doesn't expire in sewers. - [+] add RG_SEWER - [+] new regiontype - RG_SEWER - [+] map: - [+] pick size 2 - 5 - [+] start at x=2,y=2 - [+] add square 3x3 rooms in gridlike layout (but need space for 5) - [+] connect rooms to orthogonally adjacent ones with passages - [+] use addexits(). no exits on outer walls. - [+] fill all empty cells with low floor and water (but NOt the one with the exit!) - [+] any solid with orthogonally adjacent water changes to a walkway - [+] cope with different x/y room counts - [+] cope with differnet vert/horz corridor sizes. - [+] horz = 2 - [+] vert = 1 - [+] random room size - [+] allow objectclasses to have f_rarity - [+] modify getrandomobcalss - [+] but DONT make objects inherit it!!! - [+] this is used to override selection hased on habitat - modify getrandomobcalss appropriately - [+] random objects/treasure: - [+] add these only in non-water cells?? - [+] move all obs from water clls to random land cells - [+] frequent - [+] vomit - [+] soggy paper - [+] rotted food (add f_tainted to it) - [+] common - [+] wep/arm - [+] all wep/arm are shoddy in sewers - [+] uncommon - [+] rings (higher than normal chance - they were lost down sinks) - [+] occasional tech - [+] bug: playerstart3 vault filled with walls when made randomly! - [+] death speech text for intelligent monsters - [+] 'aaargh!' - [+] 'this isn't over!' - [+] BUG: linkexits() - gettings exits in the wrong place. maybe not taking rotation into account??? - [+] for example in playerstart_5 vault, found an 'exit' at the x: - [+] this comes from the map flag f_roomexit, x, y - [+] the flag may have bene added from autodoors() - [+] have changed code so that f_roomexti uses text field to say who added it
This commit is contained in:
parent
c522cac6c0
commit
6c26901e75
12
attack.c
12
attack.c
|
@ -1112,17 +1112,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
// if victim was flying and took >= 40% of its hit points, it drops to the ground.
|
||||
if (isphysicaldam(damtype[i]) && (dam[i] >= pctof(40, lf->maxhp))) {
|
||||
int willfall = B_FALSE,willinjure = B_FALSE,n;
|
||||
getflags(victim->flags, retflag, &nretflags, F_FLYING, F_LEVITATING, F_NONE);
|
||||
for (n = 0; n < nretflags; n++) {
|
||||
if (!istransitoryflag(retflag[n]) || (retflag[n]->lifetime == FROMRACE)) {
|
||||
if (retflag[n]->id == F_FLYING) willinjure = B_TRUE;
|
||||
willfall = B_TRUE;
|
||||
killflag(retflag[n]);
|
||||
}
|
||||
}
|
||||
if (willfall) fall(victim, NULL, B_TRUE);
|
||||
if (willinjure) injure(victim, getrandomcorebp(victim), DT_BASH);
|
||||
fall_from_air(lf);
|
||||
}
|
||||
// if victim can still move...
|
||||
if (hasfreeaction(victim)) {
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
35
defs.h
35
defs.h
|
@ -12,7 +12,7 @@
|
|||
#define PCTCH_PILLAR 5
|
||||
|
||||
// Text
|
||||
#define TEXT_WARN_ATTACK_NOXP "You cannot gain experience until you train. Really attack?"
|
||||
#define TEXT_WARN_ATTACK_NOXP "You will not gain experience until you train. Really attack?"
|
||||
|
||||
// Defaults
|
||||
#define DEF_AIFOLLOWTIME (50) // if target lf is out of view
|
||||
|
@ -38,6 +38,13 @@
|
|||
// lifeform defaults
|
||||
#define DEF_HITDICE "1d4"
|
||||
|
||||
// unicode chars
|
||||
#define UNI_SOLID 0x2588
|
||||
#define UNI_SHADELIGHT 0x2591
|
||||
#define UNI_SHADEMED 0x2592
|
||||
#define UNI_SHADEDARK 0x2593
|
||||
//#define UNI_SOLID '#'
|
||||
|
||||
// getrandomemptycell() params
|
||||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
|
@ -138,6 +145,9 @@
|
|||
#define MINCLEARINGRADIUS 2
|
||||
#define MAXCLEARINGRADIUS 5
|
||||
|
||||
|
||||
#define MAXMAPROOMS 80
|
||||
|
||||
#define MINROOMS 5
|
||||
#define MAXROOMS 10
|
||||
#define MIN_ROOMH 4
|
||||
|
@ -373,6 +383,7 @@ enum COLOUR {
|
|||
C_DARKGREY = 15,
|
||||
};
|
||||
#define BLUEBG 50
|
||||
#define GREENBG 100
|
||||
|
||||
enum CASTTYPE {
|
||||
CT_NORMAL = 0,
|
||||
|
@ -423,12 +434,12 @@ enum QUADRANT {
|
|||
enum SAYPHRASE {
|
||||
SP_ALLY_ATTACK,
|
||||
SP_ALLY_ATTACKUNSEEN,
|
||||
SP_ALLY_DIE,
|
||||
SP_ALLY_INPAIN,
|
||||
SP_ALLY_TARGETKILL,
|
||||
SP_BEG,
|
||||
SP_BEGATTACK,
|
||||
SP_BEGTHANKS,
|
||||
SP_DIE,
|
||||
SP_DRUNK,
|
||||
SP_PAYWARN,
|
||||
SP_PAYTHREAT,
|
||||
|
@ -650,6 +661,7 @@ enum CELLTYPE {
|
|||
CT_GRASS,
|
||||
CT_LOOPCORRIDOR,
|
||||
CT_LOWFLOOR,
|
||||
CT_VLOWFLOOR,
|
||||
// rooms
|
||||
CT_ROOM,
|
||||
};
|
||||
|
@ -866,6 +878,7 @@ enum RACE {
|
|||
R_SHADOWCAT,
|
||||
R_SPRITEFIRE,
|
||||
R_SPRITEICE,
|
||||
R_TRICLOPS,
|
||||
R_TROGLODYTE,
|
||||
R_TROLL,
|
||||
R_VAMPIRE,
|
||||
|
@ -1016,6 +1029,8 @@ enum OBTYPE {
|
|||
OT_NONE,
|
||||
// dungeon features
|
||||
OT_BOULDER,
|
||||
OT_GRATINGFLOOR,
|
||||
OT_GRATINGROOF,
|
||||
OT_ICICLE,
|
||||
OT_STATUE,
|
||||
OT_DOORWOOD,
|
||||
|
@ -1293,7 +1308,7 @@ enum OBTYPE {
|
|||
OT_S_STUNMASS,
|
||||
OT_S_TELEKINESIS,
|
||||
// -- modification
|
||||
OT_S_ANIMATESTONE,
|
||||
OT_S_ANIMATESTATUE,
|
||||
OT_S_DARKNESS,
|
||||
OT_S_ENCHANT,
|
||||
OT_S_GASEOUSFORM,
|
||||
|
@ -1320,6 +1335,7 @@ enum OBTYPE {
|
|||
OT_S_DIG,
|
||||
OT_S_EARTHQUAKE,
|
||||
OT_S_EVAPORATE,
|
||||
OT_S_EXCAVATE,
|
||||
OT_S_WEB,
|
||||
OT_S_ENDUREELEMENTS,
|
||||
OT_S_ENTANGLE,
|
||||
|
@ -1519,6 +1535,7 @@ enum OBTYPE {
|
|||
OT_ACIDSPLASH,
|
||||
OT_ACIDPUDDLE,
|
||||
OT_ACIDPOOL,
|
||||
OT_SLIMEPUDDLE,
|
||||
OT_SLIMEPOOL,
|
||||
OT_VOMITPOOL,
|
||||
OT_BLOODSTAIN,
|
||||
|
@ -2040,6 +2057,9 @@ enum FLAG {
|
|||
// v0 = base pct chance
|
||||
// v1 = extra pct chance every 5 levels
|
||||
// v2 = max trap chance
|
||||
F_CANBELOCKED, // this object might start off locked
|
||||
// v0 = base pct chance
|
||||
// v1 = extra pct chance every 5 levels
|
||||
F_TRAPPED, // this object HAS a trap.
|
||||
// v0 is the trap object type
|
||||
// v1 - 'curtime' when this trap was last triggered
|
||||
|
@ -2077,7 +2097,8 @@ 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.
|
||||
// OPTIONAL v1 = id of regiontype to link to.
|
||||
// (ie. RG_xxx)
|
||||
F_PIT, // this is a pit which we can fall down.
|
||||
// v0 = up/down
|
||||
//F_STAIRDIR//, // val0 = direcion
|
||||
|
@ -3058,6 +3079,7 @@ enum REGIONTYPE {
|
|||
RG_FIRSTDUNGEON,
|
||||
RG_HEAVEN,
|
||||
RG_PIT,
|
||||
RG_SEWER,
|
||||
};
|
||||
|
||||
enum HABITAT {
|
||||
|
@ -3066,7 +3088,8 @@ enum HABITAT {
|
|||
H_HEAVEN = 3,
|
||||
H_PIT = 4,
|
||||
H_VILLAGE = 5,
|
||||
H_SWAMP = 6,
|
||||
H_SEWER = 6,
|
||||
H_SWAMP = 7,
|
||||
H_ALL = 999
|
||||
};
|
||||
|
||||
|
@ -3140,7 +3163,7 @@ typedef struct map_s {
|
|||
region_t *region;
|
||||
int depth;
|
||||
int lit;
|
||||
struct room_s room[MAXROOMS];
|
||||
struct room_s room[MAXMAPROOMS];
|
||||
int nrooms; // how many rooms on this map
|
||||
char *name; // name of this map
|
||||
habitat_t *habitat;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@ = human
|
||||
: = timid animal
|
||||
{ = water
|
||||
{ = fountain
|
||||
UNI_SOLID = deep water
|
||||
} = gas
|
||||
^ = trap / dangerous thing
|
||||
) = weapon
|
||||
|
@ -52,7 +53,9 @@ hybrid human animal?
|
|||
~ = deep liquid (water / lava)
|
||||
] = tool
|
||||
[ = armour
|
||||
} = gas
|
||||
} = fire / effect
|
||||
UNI_SHADEMED = dense gas
|
||||
UNI_SHADELIGHT = light gas
|
||||
, = small puddle
|
||||
{ = large puddle/pool
|
||||
( = barrel/container
|
||||
|
|
5
flag.c
5
flag.c
|
@ -1019,6 +1019,11 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
return;
|
||||
}
|
||||
|
||||
// always nauseated in the sewer
|
||||
if ((f->id == F_NAUSEATED) && f->pile->owner && f->pile->owner->cell && (f->pile->owner->cell->habitat->id == H_SEWER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) {
|
||||
// special case - fast metabolism speeds up poison too.
|
||||
if (f->id == F_POISONED) {
|
||||
|
|
76
io.c
76
io.c
|
@ -3316,7 +3316,8 @@ void drawscreen(void) {
|
|||
|
||||
if (statdirty) {
|
||||
drawstatus();
|
||||
wrefresh(statwin);
|
||||
//wrefresh(statwin);
|
||||
wnoutrefresh(statwin);
|
||||
statdirty = B_FALSE;
|
||||
didstatus = B_TRUE;
|
||||
}
|
||||
|
@ -3329,6 +3330,7 @@ void drawscreen(void) {
|
|||
}
|
||||
|
||||
if (didstatus && !didredraw) {
|
||||
doupdate();
|
||||
drawcursor();
|
||||
}
|
||||
}
|
||||
|
@ -6594,54 +6596,6 @@ void doquaff(obpile_t *op) {
|
|||
}
|
||||
}
|
||||
|
||||
void dolockpick(obpile_t *op) {
|
||||
object_t *o;
|
||||
char ch;
|
||||
int dir;
|
||||
|
||||
if (!hasobwithflag(player->pack, F_PICKLOCKS)) {
|
||||
msg("You have nothing to use for lockpicking!");
|
||||
return;
|
||||
}
|
||||
|
||||
// ask direction
|
||||
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
|
||||
dir = chartodir(ch);
|
||||
if (dir == D_NONE) {
|
||||
clearmsg();
|
||||
return;
|
||||
} else {
|
||||
cell_t *c;
|
||||
c = getcellindir(player->cell, dir);
|
||||
if (c) {
|
||||
object_t *targ;
|
||||
// something to lockpick there?
|
||||
targ = hasobwithflag(c->obpile, F_LOCKED);
|
||||
if (targ) {
|
||||
// ask which object to use
|
||||
o = askobjectwithflag(op, "Lockpick using what", NULL, 'p', AO_NONE, F_PICKLOCKS);
|
||||
if (o) {
|
||||
if (hasflag(o->flags, F_PICKLOCKS)) {
|
||||
lockpick(player, targ, o);
|
||||
} else {
|
||||
msg("That can't be used to pick locks!");
|
||||
}
|
||||
} else {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// fail
|
||||
msg("There is nothing locked there!");
|
||||
}
|
||||
} else {
|
||||
clearmsg();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void donextguntarget(void) {
|
||||
object_t *gun;
|
||||
char gunname[BUFLEN];
|
||||
|
@ -7028,9 +6982,11 @@ void drawglyph(glyph_t *g, int x, int y) {
|
|||
void drawcursor(void) {
|
||||
// move cursor to player position
|
||||
wmove(gamewin, player->cell->y - viewy, player->cell->x - viewx);
|
||||
wrefresh(gamewin);
|
||||
//wrefresh(gamewin);
|
||||
// turn on cursor
|
||||
curs_set(1);
|
||||
wnoutrefresh(gamewin);
|
||||
doupdate();
|
||||
}
|
||||
|
||||
void drawlevelfor(lifeform_t *lf) {
|
||||
|
@ -7185,6 +7141,22 @@ void initgfx(void) {
|
|||
init_pair(BLUEBG+C_BOLDGREEN, COLOR_GREEN, COLOR_BLUE);
|
||||
init_pair(BLUEBG+C_ORANGE, COLOR_RED, COLOR_BLUE);
|
||||
|
||||
init_pair(GREENBG+C_BLACK, COLOR_BLACK, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_RED, COLOR_RED, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_GREEN, COLOR_GREEN, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BROWN, COLOR_YELLOW, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_YELLOW, COLOR_YELLOW, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BLUE, COLOR_BLUE, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_MAGENTA, COLOR_MAGENTA, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_CYAN, COLOR_CYAN, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_GREY, COLOR_WHITE, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_YELLOW, COLOR_YELLOW, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_WHITE, COLOR_WHITE, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BOLDCYAN, COLOR_CYAN, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BOLDBLUE, COLOR_BLUE, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BOLDMAGENTA, COLOR_MAGENTA, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_BOLDGREEN, COLOR_GREEN, COLOR_GREEN);
|
||||
init_pair(GREENBG+C_ORANGE, COLOR_RED, COLOR_GREEN);
|
||||
|
||||
noecho();
|
||||
// TODO: change back to raw mode, or make this a switch
|
||||
|
@ -7692,7 +7664,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
ch = getch();
|
||||
}
|
||||
|
||||
if ((ch >= '0') && (ch <= '9')) { // shortcut
|
||||
if (useshortcuts && ((ch >= '0') && (ch <= '9'))) { // shortcut
|
||||
flag_t *f;
|
||||
// autofill from the shortcut
|
||||
f = lfhasflagval(player, F_SHORTCUT, ch - '0', NA, NA, NULL);
|
||||
|
@ -8225,7 +8197,7 @@ void handleinput(void) {
|
|||
break;
|
||||
case 'p': // pick lock
|
||||
addflag(player->flags, F_LASTCMD, NA, NA, NA, temp);
|
||||
dolockpick(player->pack);
|
||||
lockpick(player, NULL, NULL, NULL);
|
||||
break;
|
||||
case 'P': // Pour
|
||||
dopour(player->pack);
|
||||
|
|
1
io.h
1
io.h
|
@ -60,7 +60,6 @@ void domsghist(void);
|
|||
void dooffer(void);
|
||||
void dooperate(obpile_t *op);
|
||||
int dopickup(obpile_t *op, int forceask);
|
||||
void dolockpick(obpile_t *op);
|
||||
void donextguntarget(void);
|
||||
void dopour(obpile_t *op);
|
||||
void doquit(void);
|
||||
|
|
226
lf.c
226
lf.c
|
@ -1874,6 +1874,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
limit(&damamt, 1, NA);
|
||||
|
||||
if (damamt >= lf->hp) {
|
||||
char obname[BUFLEN];
|
||||
if (isplayer(lf)) {
|
||||
msg("^BYou drown.");
|
||||
didsomething = B_TRUE;
|
||||
|
@ -1885,8 +1886,11 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
lf->hp = 0;
|
||||
setlastdam(lf, "drowning");
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
|
||||
setlastdam(lf, obname);
|
||||
setkillverb(lf, "Drowned");
|
||||
} else {
|
||||
char obname[BUFLEN];
|
||||
if (isplayer(lf)) {
|
||||
msg("^BYou are drowning!");
|
||||
didsomething = B_TRUE;
|
||||
|
@ -1896,7 +1900,10 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
msg("^%c%s is drowning!", getlfcol(lf, CC_VBAD), lfname);
|
||||
didsomething = B_TRUE;
|
||||
}
|
||||
losehp(lf, damamt, DT_DIRECT, NULL, "drowning");
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_TRUE);
|
||||
losehp(lf, damamt, DT_DIRECT, NULL, obname);
|
||||
setlastdam(lf, obname);
|
||||
setkillverb(lf, "Drowned");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2270,6 +2277,21 @@ void die(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// intelligent monsters will say something
|
||||
if (ispetof(lf, player)) {
|
||||
if (cantalk(lf) && canhear(player, lf->cell, 4)) {
|
||||
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL);
|
||||
} else if (cantalk(lf)) {
|
||||
warn("You feel a profound sense of loss.");
|
||||
more();
|
||||
//} else {
|
||||
// makenoise(lf, N_DIE);
|
||||
}
|
||||
} else if (cantalk(lf)) {
|
||||
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL);
|
||||
}
|
||||
|
||||
if (!hasflag(lf->flags, F_NODEATHANNOUNCE)) {
|
||||
if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
|
@ -2309,20 +2331,6 @@ void die(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// announce pet death
|
||||
if (ispetof(lf, player)) {
|
||||
if (cantalk(lf) && canhear(player, lf->cell, 4)) {
|
||||
sayphrase(lf, SP_ALLY_DIE, SV_SHOUT, NA, NULL);
|
||||
} else if (cantalk(lf)) {
|
||||
warn("You feel a profound sense of loss.");
|
||||
//} else {
|
||||
// makenoise(lf, N_DIE);
|
||||
}
|
||||
}
|
||||
if (ispetof(lf, player)) {
|
||||
more();
|
||||
}
|
||||
|
||||
// drop/kill all objects
|
||||
if (willbecomeghost || !isplayer(lf)) {
|
||||
while (lf->pack->first) {
|
||||
|
@ -3794,7 +3802,9 @@ int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) {
|
|||
loseconcentration(lf);
|
||||
interrupt(lf);
|
||||
|
||||
killtransitoryflags(lf->flags, F_FLYING);
|
||||
// falling asleep while flying = fall!
|
||||
fall_from_air(lf);
|
||||
|
||||
killflagsofid(lf->flags, F_RAGE);
|
||||
killflagsofid(lf->flags, F_TRAINING);
|
||||
|
||||
|
@ -3802,6 +3812,27 @@ int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns true if you fell
|
||||
int fall_from_air(lifeform_t *lf) {
|
||||
int willfall = B_FALSE,willinjure = B_FALSE, n;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0;
|
||||
getflags(lf->flags, retflag, &nretflags, F_FLYING, F_LEVITATING, F_NONE);
|
||||
for (n = 0; n < nretflags; n++) {
|
||||
if (!istransitoryflag(retflag[n]) || (retflag[n]->lifetime == FROMRACE)) {
|
||||
if (retflag[n]->id == F_FLYING) willinjure = B_TRUE;
|
||||
willfall = B_TRUE;
|
||||
killflag(retflag[n]);
|
||||
}
|
||||
}
|
||||
if (willfall) fall(lf, NULL, B_TRUE);
|
||||
if (willinjure) injure(lf, getrandomcorebp(lf), DT_BASH);
|
||||
if (willfall || willinjure) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// make 'lf' respond to damage
|
||||
void fightback(lifeform_t *lf, lifeform_t *attacker) {
|
||||
interrupt(lf);
|
||||
|
@ -6263,21 +6294,29 @@ char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer) {
|
|||
|
||||
glyph_t *getlfglyph(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
|
||||
if (lfhasflag(lf, F_FEIGNINGDEATH)) {
|
||||
// look like a corpse
|
||||
tempglyph.ch = '%';
|
||||
tempglyph.colour = lf->race->glyph.colour;
|
||||
|
||||
return &tempglyph;
|
||||
} else if ((f = lfhasflag(lf, F_GLYPH)) != NULL) {
|
||||
tempglyph.ch = f->val[1];
|
||||
} else {
|
||||
tempglyph = lf->race->glyph;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_GLYPH);
|
||||
if (f) {
|
||||
tempglyph.ch = f->text[0];
|
||||
return &tempglyph;
|
||||
if (lf->cell && (getcellwaterdepth(lf->cell, player) >= DP_WAIST)) {
|
||||
object_t *o;
|
||||
o = hasobwithflag(lf->cell->obpile, F_DEEPWATER);
|
||||
switch (o->type->material->id) {
|
||||
case MT_WATER: tempglyph.colour += BLUEBG; break;
|
||||
case MT_SLIME: tempglyph.colour += GREENBG; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return &lf->race->glyph;
|
||||
//return &lf->race->glyph;
|
||||
return &tempglyph;
|
||||
}
|
||||
|
||||
enum MATERIAL getlfmaterial(lifeform_t *lf) {
|
||||
|
@ -7112,7 +7151,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
race_t *poss[MAXRANDOMLFCANDIDATES];
|
||||
int nposs = 0;
|
||||
int selidx;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
int depth;
|
||||
int hdmin,hdmax;
|
||||
enum RARITY wantrr = RR_FREQUENT;
|
||||
|
@ -9152,15 +9191,93 @@ int lfproduceslight(lifeform_t *lf) {
|
|||
return radius;
|
||||
}
|
||||
|
||||
// if you pass in 'target', then you don't need 'targcell'
|
||||
// return true on failure
|
||||
int lockpick(lifeform_t *lf, object_t *target, object_t *device) {
|
||||
int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *device) {
|
||||
flag_t *f,*lockflag;
|
||||
char lfname[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
int faileffect;
|
||||
int difficulty = 20; // default, never used though
|
||||
int bonus = 0;
|
||||
char ch;
|
||||
|
||||
// TODO: for now, only players can lockpick
|
||||
if (!isplayer(lf)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// what will we use?
|
||||
if (!device) {
|
||||
if (!hasobwithflag(lf->pack, F_PICKLOCKS)) {
|
||||
msg("You have nothing to use for lockpicking!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// ask which object to use
|
||||
device = askobjectwithflag(lf->pack, "Lockpick using what", NULL, 'p', AO_NONE, F_PICKLOCKS);
|
||||
if (!device) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
} else if (!hasflag(device->flags, F_PICKLOCKS)) {
|
||||
msg("That can't be used to pick locks!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
object_t *poss[MAXCANDIDATES],*o;
|
||||
int nposs = 0,i;
|
||||
if (!targcell) {
|
||||
int dir;
|
||||
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
|
||||
if ((ch == '-') || (ch == '\0')) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
}
|
||||
dir = chartodir(ch);
|
||||
if (dir == D_NONE) {
|
||||
targcell = lf->cell;
|
||||
} else {
|
||||
targcell = getcellindir(lf->cell, dir);
|
||||
}
|
||||
if (!targcell) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// get a list of lockpickable obejcts there
|
||||
for (o = targcell->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_LOCKED)) {
|
||||
poss[nposs++] = o;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nposs) {
|
||||
msg("There is nothing here to lockpick!");
|
||||
return B_TRUE;
|
||||
} else if (nposs == 1) {
|
||||
target = poss[0];
|
||||
} else {
|
||||
// ask which one
|
||||
initprompt(&prompt, "What will you try to unlock?");
|
||||
ch = 'a';
|
||||
for (i = 0 ; i < nposs; i++) {
|
||||
char obname[BUFLEN];
|
||||
getobname(poss[i], obname, 1);
|
||||
addchoice(&prompt, ch++, obname, NULL, poss[i], NULL);
|
||||
}
|
||||
prompt.maycancel = B_TRUE;
|
||||
ch = getchoice(&prompt);
|
||||
if (ch != '\0') target = (object_t *)prompt.result;
|
||||
if (!target) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we should now have both 'device' and 'target' filled in.
|
||||
lockflag = hasflag(target->flags, F_LOCKED);
|
||||
if (lockflag) {
|
||||
difficulty = lockflag->val[1];
|
||||
|
@ -10619,7 +10736,7 @@ lifeform_t *makezombie(object_t *o) {
|
|||
lf = addlf(where, r->id, 1);
|
||||
|
||||
addflag(lf->flags, F_LFSUFFIX, B_TRUE, NA, NA, "zombie");
|
||||
addflag(lf->flags, F_GLYPH, C_GREY, NA, NA, "Z");
|
||||
addflag(lf->flags, F_GLYPH, C_GREY, 'Z', NA, NULL);
|
||||
addflag(lf->flags, F_UNDEAD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
|
||||
|
@ -11570,7 +11687,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
default: break;
|
||||
}
|
||||
|
||||
|
||||
// special case
|
||||
if (lf->race->id == R_DREAMFUNGUS) {
|
||||
if (cansee(player, lf)) {
|
||||
|
@ -11707,8 +11823,10 @@ int makenauseated(lifeform_t *lf, int amt, int howlong) {
|
|||
flag_t *f;
|
||||
|
||||
if (isundead(lf)) return B_TRUE;
|
||||
|
||||
if (!hasbp(lf, BP_HEAD)) return B_TRUE; // can't smell with no head
|
||||
if (lfhasflag(lf, F_STENCH)) return B_TRUE; // your own smell makes you used to it
|
||||
|
||||
if (lfhasflag(lf, F_ENHANCESMELL)) amt += 2;
|
||||
|
||||
//if (!lfhasflag(lf, F_HUMANOID)) return B_TRUE;
|
||||
|
||||
|
@ -13357,17 +13475,6 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
|||
free(p);
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_ALLY_DIE:
|
||||
switch (rnd(1,3)) {
|
||||
case 1:
|
||||
getplayername(buf2);
|
||||
snprintf(buf, BUFLEN, "Avenge me, %s!", buf2);
|
||||
break;
|
||||
case 2: snprintf(buf, BUFLEN, "Argh!"); break;
|
||||
case 3: snprintf(buf, BUFLEN, "Nooooo!"); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_ALLY_INPAIN:
|
||||
switch (rnd(1,3)) {
|
||||
case 1: snprintf(buf, BUFLEN, "I'm hurting here!"); break;
|
||||
|
@ -13411,6 +13518,22 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
|||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_DIE:
|
||||
switch (rnd(1,4)) {
|
||||
case 1:
|
||||
if (ispetof(lf, player)) {
|
||||
getplayername(buf2);
|
||||
snprintf(buf, BUFLEN, "Avenge me, %s!", buf2);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "My death will be avenged!");
|
||||
}
|
||||
break;
|
||||
case 2: snprintf(buf, BUFLEN, "Argh!"); break;
|
||||
case 3: snprintf(buf, BUFLEN, "Nooooo!"); break;
|
||||
case 4: snprintf(buf, BUFLEN, "This isn't over!"); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_DRUNK:
|
||||
// random blurred speech
|
||||
strcpy(buf, "");
|
||||
|
@ -14658,6 +14781,12 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// get nauseated if in the sewer
|
||||
if (lf->cell && (lf->cell->habitat->id == H_SEWER)) {
|
||||
makenauseated(lf, 2, 2);
|
||||
}
|
||||
|
||||
// get more hungry
|
||||
modhunger(lf, 1);
|
||||
|
||||
|
@ -16304,8 +16433,19 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// locked?
|
||||
if (hasflag(o->flags, F_LOCKED)) {
|
||||
if (isplayer(lf)) msg("The %s seems to be locked.", noprefix(obname));
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
curmap = obcell->map;
|
||||
|
||||
if ((o->type->id == OT_GRATINGFLOOR) && !hasflag(o->flags, F_MAPLINK)) {
|
||||
createregionlink(curmap, obcell, o, NULL, RG_SEWER, curmap->region);
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
assert(f);
|
||||
dir = f->val[0];
|
||||
|
@ -16341,7 +16481,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
return B_TRUE;
|
||||
}
|
||||
} else if (dir == D_UP) {
|
||||
if (hasflagval(o->flags, F_PIT, D_UP, NA, NA, NULL)) {
|
||||
if (hasflagval(o->flags, F_PIT, D_UP, NA, NA, NULL) || (o->type->id == OT_GRATINGROOF)) {
|
||||
// can only go up if you have a rope or are flying/levitating
|
||||
if (lfhasflag(lf, F_LEVITATING) || lfhasflag(lf, F_FLYING)) {
|
||||
// ok.
|
||||
|
@ -16369,8 +16509,8 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s enters %s...", lfname, obname);
|
||||
}
|
||||
} else if (hasflag(o->flags, F_PIT)) {
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
} else if (hasflag(o->flags, F_PIT) || (o->type->id == OT_GRATINGFLOOR) || (o->type->id == OT_GRATINGROOF)) {
|
||||
//f = hasflag(o->flags, F_PIT);
|
||||
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
msg("%s %s %s the %s...", lfname, getpitverb(lf, dir,onpurpose, climb), getdirname(dir), noprefix(obname));
|
||||
|
|
3
lf.h
3
lf.h
|
@ -88,6 +88,7 @@ void extinguishlf(lifeform_t *lf);
|
|||
object_t *eyesshaded(lifeform_t *lf);
|
||||
int fall(lifeform_t *lf, lifeform_t *fromlf, int announce);
|
||||
int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong);
|
||||
int fall_from_air(lifeform_t *lf);
|
||||
void fightback(lifeform_t *lf, lifeform_t *attacker);
|
||||
job_t *findjob(enum JOB jobid);
|
||||
job_t *findjobbyname(char *name);
|
||||
|
@ -257,7 +258,7 @@ flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2
|
|||
flag_t *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
|
||||
flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, /*@null@*/ char *text);
|
||||
int lfproduceslight(lifeform_t *lf);
|
||||
int lockpick(lifeform_t *lf, object_t *target, object_t *device);
|
||||
int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *device);
|
||||
void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
||||
int hasbp(lifeform_t *lf, enum BODYPART bp);
|
||||
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid);
|
||||
|
|
404
map.c
404
map.c
|
@ -792,7 +792,7 @@ void adjustcellglyphforlight(cell_t *c, glyph_t *g) {
|
|||
case L_TEMP: // lit by a light source
|
||||
if (g->colour < 8) {
|
||||
g->colour = g->colour + 8; // ie. make bold
|
||||
if (g->colour >= C_DARKGREY) g->colour = C_WHITE;
|
||||
if (g->colour >= C_GREY) g->colour = C_WHITE;
|
||||
}
|
||||
break;
|
||||
case L_PERMLIGHT:
|
||||
|
@ -1108,7 +1108,6 @@ int doelementspread(cell_t *c) {
|
|||
thisdepth = getcellwaterdepth(c, NULL);
|
||||
|
||||
if (thisdepth) {
|
||||
|
||||
// count surrounding cells of lower depth
|
||||
for (i = DC_N; i <= DC_NW; i++) {
|
||||
cell_t *newc;
|
||||
|
@ -1399,7 +1398,7 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
|||
g->ch = ' ';
|
||||
}
|
||||
// out of LOS - show as dark
|
||||
// TODO: if terminal supports it, use C_DARKGREY instead.
|
||||
// TODO: if terminal supports it, use C_GREY instead.
|
||||
g->colour = C_BLUE;
|
||||
}
|
||||
break;
|
||||
|
@ -2070,7 +2069,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
}
|
||||
}
|
||||
// just do a normal room
|
||||
createroom(map, map->nrooms, NA, NA, DEF_VAULTMARGIN, DEF_VAULTMARGIN, NULL, NULL, NULL, NULL, 50, B_FALSE);
|
||||
calcposandmakeroom(map, map->nrooms, NA, NA, DEF_VAULTMARGIN, DEF_VAULTMARGIN, NULL, NULL, NULL, NULL, 50, B_FALSE);
|
||||
//roomvault[i] = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2374,9 +2373,13 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
case H_PIT:
|
||||
createpit(map, depth, parentmap, exitdir, entryob);
|
||||
break;
|
||||
default:
|
||||
case H_SEWER:
|
||||
createsewer(map, depth, parentmap, exitdir, entryob);
|
||||
break;
|
||||
case H_ALL:
|
||||
dblog("ERROR - createhabitat with invalid habitat!");
|
||||
msg("ERROR - createhabitat with invalid habitat!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2857,7 +2860,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
object_t *o;
|
||||
c = getcellat(map, x, y);
|
||||
o = hasobwithflag(c->obpile, F_CLIMBABLE);
|
||||
if (o && !getstairdestination(o, NULL)) {
|
||||
if (o && (o->type->id != OT_PORTAL) && !getstairdestination(o, NULL)) {
|
||||
// this will join these stairs to existing ones on
|
||||
// existing adjacent maps
|
||||
if (!linkstairs(o, NULL)) {
|
||||
|
@ -2939,6 +2942,228 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (db) dblog(" Map creation finished.");
|
||||
}
|
||||
|
||||
void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
object_t *o,*nexto;
|
||||
cell_t *c;
|
||||
flag_t *f;
|
||||
int i;
|
||||
int startx,starty,x,y,rx,ry;
|
||||
int maxroomsx,maxroomsy;
|
||||
int roomcountx,roomcounty;
|
||||
//int corridorsizex = 3;
|
||||
//int corridorsizey = 2;
|
||||
int corridorsize; // length of corridors between rooms
|
||||
int roomfullsize; // room size including walls
|
||||
int roomsize; // room size without walls
|
||||
int sectionsize; // a section is a room+corridor
|
||||
int *roomon,*rowfirst,*rowlast,*colfirst,*collast;
|
||||
int numon = 0;
|
||||
char buf[BUFLEN];
|
||||
|
||||
// select room size
|
||||
//roomsize = 5;
|
||||
sectionsize = rnd(5,9);
|
||||
// must be an odd number
|
||||
if ((sectionsize % 2) == 0) sectionsize++;
|
||||
|
||||
// subtract corridor size
|
||||
corridorsize = rnd(2,3);
|
||||
roomfullsize = sectionsize - corridorsize;
|
||||
roomsize = roomsize - 2; // ie. don't include outer walls
|
||||
|
||||
// select how many very/horz rooms
|
||||
maxroomsx = (map->w - 1) / (sectionsize);
|
||||
maxroomsy = (map->h - 1) / (sectionsize);
|
||||
roomcountx = maxroomsx;
|
||||
roomcounty = maxroomsy;
|
||||
|
||||
|
||||
// fill entire maze with walls
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
addcell(map, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
roomon = malloc((roomcountx * roomcounty) * sizeof(int));
|
||||
rowfirst = malloc(roomcounty * sizeof(int));
|
||||
rowlast = malloc(roomcounty * sizeof(int));
|
||||
colfirst = malloc(roomcountx * sizeof(int));
|
||||
collast = malloc(roomcountx * sizeof(int));
|
||||
numon = 0;
|
||||
while (numon == 0) {
|
||||
for (ry = 0; ry < roomcounty; ry++) {
|
||||
for (rx = 0; rx < roomcountx; rx++) {
|
||||
i = rx * ry;
|
||||
|
||||
if (pctchance(66)) {
|
||||
roomon[i] = B_TRUE;
|
||||
numon++;
|
||||
} else {
|
||||
roomon[i] = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now figure first/last rooms in each row
|
||||
for (ry = 0; ry < roomcounty; ry++) {
|
||||
rowfirst[ry] = -1;
|
||||
for (rx = 0; rx < roomcountx; rx++) {
|
||||
i = rx * ry;
|
||||
if (roomon[i]) {
|
||||
if (rowfirst[ry] == -1) {
|
||||
rowfirst[ry] = rx;
|
||||
}
|
||||
rowlast[ry] = rx;
|
||||
}
|
||||
}
|
||||
}
|
||||
// now figure first/last rooms in each column
|
||||
for (rx = 0; rx < roomcountx; rx++) {
|
||||
colfirst[rx] = -1;
|
||||
for (ry = 0; ry < roomcounty; ry++) {
|
||||
i = rx * ry;
|
||||
if (roomon[i]) {
|
||||
if (colfirst[rx] == -1) {
|
||||
colfirst[rx] = ry;
|
||||
}
|
||||
collast[rx] = ry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dblog("SEWER debug:");
|
||||
for (ry = 0; ry < roomcounty; ry++) {
|
||||
char buf2[BUFLEN];
|
||||
strcpy(buf, "");
|
||||
for (rx = 0; rx < roomcountx; rx++) {
|
||||
if (roomon[rx*ry]) {
|
||||
strcat(buf, "#");
|
||||
} else {
|
||||
strcat(buf, "-");
|
||||
}
|
||||
}
|
||||
sprintf(buf2, " (rowfirst is %d, rowlast is %d)", rowfirst[ry], rowlast[ry]);
|
||||
dblog("%s%s", buf, buf2);
|
||||
}
|
||||
|
||||
|
||||
// start at top left corner of top left room
|
||||
startx = 1;
|
||||
starty = 1;
|
||||
x = startx;
|
||||
y = starty;
|
||||
// add square rooms in a gridlike layout
|
||||
for (ry = 0; ry < roomcounty; ry++) {
|
||||
for (rx = 0; rx < roomcountx; rx++) {
|
||||
if (roomon[rx*ry]) {
|
||||
int thisid;
|
||||
int x2,y2;
|
||||
thisid = map->nrooms;
|
||||
// add a room here
|
||||
x2 = x+roomfullsize-1;
|
||||
y2 = y+roomfullsize-1;
|
||||
createroom(map, thisid, x, y, x2, y2, B_TRUE);
|
||||
// define exit locations
|
||||
if (ry != colfirst[rx]) addflag(map->flags, F_ROOMEXIT, thisid, x+(roomfullsize/2), y, NULL); // N
|
||||
if (ry != collast[rx]) addflag(map->flags, F_ROOMEXIT, thisid, x+(roomfullsize/2), y2, NULL); // S
|
||||
if (rx != rowfirst[ry]) addflag(map->flags, F_ROOMEXIT, thisid, x, y+(roomfullsize/2), NULL); // W
|
||||
if (rx != rowlast[ry]) addflag(map->flags, F_ROOMEXIT, thisid, x2, y+(roomfullsize/2), NULL); // E
|
||||
}
|
||||
// move on to next room position
|
||||
x += sectionsize;
|
||||
assert(x < map->w);
|
||||
}
|
||||
x = startx;
|
||||
y += sectionsize;
|
||||
assert(y < map->h);
|
||||
}
|
||||
free(roomon);
|
||||
free(rowfirst);
|
||||
free(rowlast);
|
||||
free(colfirst);
|
||||
free(collast);
|
||||
dblog("END SEWER debug");
|
||||
|
||||
// link rooms with corridors
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
linkexits(map, map->room[i].id);
|
||||
}
|
||||
|
||||
|
||||
// replace all empty cells with slime (except the exit one)
|
||||
for (i = 0; i < (map->w*map->h); i++){
|
||||
c = map->cell[i];
|
||||
if (!c->type->solid) {
|
||||
setcelltype(c, CT_LOWFLOOR);
|
||||
addob(c->obpile, "waist-deep slime");
|
||||
}
|
||||
}
|
||||
|
||||
// any solid cell with orthogonally-adjacent water (except the exit one)
|
||||
// now turns into a walkway
|
||||
for (i = 0; i < (map->w*map->h); i++){
|
||||
cell_t *c2;
|
||||
c = map->cell[i];
|
||||
if (c->type->solid) {
|
||||
int dir,makewalkway = B_FALSE;
|
||||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
c2 = getcellindir(c, dir);
|
||||
if (c2 && (c2->type->id == CT_LOWFLOOR)) {
|
||||
makewalkway = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (makewalkway) setcelltype(c, c->habitat->emptycelltype);
|
||||
} else if (c->type->id == CT_LOWFLOOR) {
|
||||
int dir,surrounded = B_TRUE;
|
||||
for (dir = D_N; dir <= D_W; dir++) {
|
||||
c2 = getcellindir(c, dir);
|
||||
if (c2 && (c2->type->id != CT_LOWFLOOR)) {
|
||||
surrounded = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (surrounded) {
|
||||
setcelltype(c, CT_VLOWFLOOR);
|
||||
setwaterdepth(c, DP_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// any water cell orthogonally surrounded by water becomes very deep
|
||||
|
||||
|
||||
// now move all objects out of the water
|
||||
for (i = 0; i < (map->w*map->h); i++){
|
||||
c = map->cell[i];
|
||||
if (c->type->id == CT_LOWFLOOR) {
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (o->type->id != OT_SLIMEPOOL) {
|
||||
cell_t *c2;
|
||||
c2 = getrandomcelloftype(map, c->habitat->emptycelltype);
|
||||
moveob(o, c2->obpile, ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add the exit. make sure it's next to a wall so it's possible to climb to.
|
||||
c = NULL;
|
||||
while (!c || (countadjwalls(c) == 0)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
assert(c);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_GRATINGROOF);
|
||||
// have to force these stairs to go back to a different region.
|
||||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
f->val[1] = map->region->parentregion->id;
|
||||
linkstairs(o, NULL);
|
||||
|
||||
}
|
||||
|
||||
void createswamp(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
|
@ -3000,7 +3225,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
// - we don't do autodoors (will handle this further down) -------------
|
||||
minw = f->val[0];
|
||||
minh = f->val[1];
|
||||
if (createroom(map, roomid, minw, minh, xmargin, ymargin, &minx, &miny, &w, &h, B_NODOORS, B_TRUE)) {
|
||||
if (calcposandmakeroom(map, roomid, minw, minh, xmargin, ymargin, &minx, &miny, &w, &h, B_NODOORS, B_TRUE)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (db) dblog("made random vault %s at pos %d,%d on map %s", v->id, minx, miny, map->name);
|
||||
|
@ -3462,6 +3687,13 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
c = getcellindir(c, whichway);
|
||||
}
|
||||
}
|
||||
|
||||
// now make sure the START cell is empty too!
|
||||
if (startcell->type->solid) {
|
||||
setcelltype(startcell, startcell->habitat->emptycelltype);
|
||||
}
|
||||
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -3521,15 +3753,16 @@ int linkexits(map_t *m, int roomid) {
|
|||
}
|
||||
}
|
||||
|
||||
if (db) dblog("%d doors/exits found.",nposs);
|
||||
if (db) dblog("%d exit positions found.",nposs);
|
||||
|
||||
// for each door, make sure it links to at least one cell which isn't
|
||||
// for each exit position, make sure it links to at least one cell which isn't
|
||||
// part of this room
|
||||
for (i = 0; i < nposs; i++) {
|
||||
int ncorridors = 0,d;
|
||||
|
||||
if (db) dblog("exit at %d,%d:",poss[i]->x, poss[i]->y);
|
||||
// if exit is solid and COMPLETELY surrounded by solid, ignore it.
|
||||
if (c->type->solid && (countcellexits(c, DT_ORTH) == 0)){
|
||||
if (poss[i]->type->solid && (countcellexits(poss[i], DT_ORTH) == 0)){
|
||||
if (db) dblog("cell is solid and surrounded by solids. ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
@ -3584,7 +3817,7 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO
|
|||
region_t *r;
|
||||
// create a new region
|
||||
r = addregion(newregiontype, m->region, -1);
|
||||
// add stairs to new region
|
||||
// add stairs going to the new region, if required
|
||||
if (!c) {
|
||||
c = NULL;
|
||||
while (!c || !cellwalkable(NULL, c, NULL)) {
|
||||
|
@ -3666,10 +3899,46 @@ void createriver(map_t *m) {
|
|||
}
|
||||
}
|
||||
|
||||
// room w/h are returned in *w and *h if given.
|
||||
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls) {
|
||||
void createroom(map_t *map, int roomid, int x1, int y1, int x2, int y2, int forcewalls) {
|
||||
int x,y;
|
||||
room_t *thisroom = NULL;
|
||||
cell_t *cell;
|
||||
map->room[map->nrooms].id = roomid;
|
||||
map->room[map->nrooms].x1 = x1;
|
||||
map->room[map->nrooms].y1 = y1;
|
||||
map->room[map->nrooms].x2 = x2;
|
||||
map->room[map->nrooms].y2 = y2;
|
||||
map->room[map->nrooms].vault = NULL;
|
||||
map->room[map->nrooms].exitslinked = B_FALSE;
|
||||
thisroom = &(map->room[map->nrooms]);
|
||||
map->nrooms++;
|
||||
|
||||
for (y = y1; y <= y2; y++) {
|
||||
for (x = x1; x <= x2; x++) {
|
||||
cell = getcellat(map, x, y);
|
||||
if (cell) {
|
||||
// kill contents, EXCEPT for staircases!
|
||||
clearcell_exceptflags(cell, F_CLIMBABLE, F_NONE);
|
||||
// make it a border or room
|
||||
if ((y == y1) || (y == y2) ||
|
||||
(x == x1) || (x == x2)) {
|
||||
// ie. if you haven't forced walls then if this room overlaps
|
||||
// with another one, no walls will be created.
|
||||
if (forcewalls || (!forcewalls && cell->type->solid)) {
|
||||
setcelltype(cell, CT_ROOMWALL);
|
||||
}
|
||||
//}
|
||||
} else {
|
||||
setcelltype(cell, CT_ROOM);
|
||||
}
|
||||
cell->room = thisroom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// room w/h are returned in *w and *h if given.
|
||||
int calcposandmakeroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls) {
|
||||
int minx,miny;
|
||||
int maxx,maxy;
|
||||
int w,h;
|
||||
|
@ -3677,7 +3946,6 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
|
|||
int minroomh = MIN_ROOMH;
|
||||
int maxroomw = MAX_ROOMW;
|
||||
int maxroomh = MAX_ROOMH;
|
||||
room_t *thisroom = NULL;
|
||||
|
||||
if (overrideminw != NA) {
|
||||
minroomw = overrideminw;
|
||||
|
@ -3709,38 +3977,8 @@ int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int x
|
|||
maxx = minx + (w-1);
|
||||
maxy = miny + (h-1);
|
||||
|
||||
map->room[map->nrooms].id = roomid;
|
||||
map->room[map->nrooms].x1 = minx;
|
||||
map->room[map->nrooms].y1 = miny;
|
||||
map->room[map->nrooms].x2 = maxx;
|
||||
map->room[map->nrooms].y2 = maxy;
|
||||
map->room[map->nrooms].vault = NULL;
|
||||
map->room[map->nrooms].exitslinked = B_FALSE;
|
||||
thisroom = &(map->room[map->nrooms]);
|
||||
map->nrooms++;
|
||||
|
||||
for (y = miny; y <= maxy; y++) {
|
||||
for (x = minx; x <= maxx; x++) {
|
||||
cell = getcellat(map, x, y);
|
||||
if (cell) {
|
||||
// kill contents, EXCEPT for staircases!
|
||||
clearcell_exceptflags(cell, F_CLIMBABLE, F_NONE);
|
||||
// make it a border or room
|
||||
if ((y == miny) || (y == maxy) ||
|
||||
(x == minx) || (x == maxx)) {
|
||||
// ie. if you haven't forced walls then if this room overlaps
|
||||
// with another one, no walls will be created.
|
||||
if (forcewalls || (!forcewalls && cell->type->solid)) {
|
||||
setcelltype(cell, CT_ROOMWALL);
|
||||
}
|
||||
//}
|
||||
} else {
|
||||
setcelltype(cell, CT_ROOM);
|
||||
}
|
||||
cell->room = thisroom;
|
||||
}
|
||||
}
|
||||
}
|
||||
// actually make the room now.
|
||||
createroom(map, roomid, minx,miny,maxx,maxy, forcewalls);
|
||||
|
||||
// add doors
|
||||
if (doorpct) {
|
||||
|
@ -4417,8 +4655,8 @@ char *getregionname(char *buf, map_t *m, int withlevel) {
|
|||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit L%d", m->depth);
|
||||
break;
|
||||
default:
|
||||
strcpy(buf, "?unknownregiontype??");
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer L%d", m->depth);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -4435,8 +4673,8 @@ char *getregionname(char *buf, map_t *m, int withlevel) {
|
|||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit");
|
||||
break;
|
||||
default:
|
||||
strcpy(buf, "?unknownregiontype??");
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4814,15 +5052,17 @@ void initmap(void) {
|
|||
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALL, 0, 0, 0, MAXVISRANGE);
|
||||
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5);
|
||||
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE);
|
||||
addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE);
|
||||
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE);
|
||||
|
||||
// cell types
|
||||
// cell types - solid
|
||||
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0);
|
||||
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0);
|
||||
addcelltype(CT_ROOMWALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
// cell types - non-solid
|
||||
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_WALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", '#', C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 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_FLOORWOOD, "wood floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0);
|
||||
|
@ -4831,12 +5071,14 @@ void initmap(void) {
|
|||
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);
|
||||
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2);
|
||||
|
||||
// region types
|
||||
addregiontype(RG_WORLDMAP, "World map", H_FOREST, 10, 0, D_NONE, B_TRUE);
|
||||
addregiontype(RG_FIRSTDUNGEON, "First Dungeon", H_DUNGEON, 10, 3, D_DOWN, B_TRUE);
|
||||
addregiontype(RG_HEAVEN, "Realm of Gods", H_HEAVEN, 1, 0, D_NONE, B_FALSE);
|
||||
addregiontype(RG_PIT, "Pit", H_PIT, 1, 1, D_DOWN, B_FALSE);
|
||||
addregiontype(RG_SEWER, "Sewer", H_SEWER, 1, 0, D_NONE, B_FALSE);
|
||||
|
||||
// MAPMAPMAPMAP
|
||||
// region definitions (outlines)
|
||||
|
@ -5381,38 +5623,30 @@ void makedoor(cell_t *cell, int openchance) {
|
|||
strcpy(doorbuf, "wooden door");
|
||||
}
|
||||
|
||||
// addob will determine whether the door is locked. if so,
|
||||
// don't open it!
|
||||
o = addob(cell->obpile, doorbuf);
|
||||
if (o && (rnd(1,100) <= openchance)) {
|
||||
opendoor(NULL, o);
|
||||
} else {
|
||||
int chance;
|
||||
// door is closed - lock it?
|
||||
if (o) {
|
||||
if (!hasflag(o->flags, F_LOCKED) && (rnd(1,100) <= openchance)) {
|
||||
opendoor(NULL, o);
|
||||
} else {
|
||||
int chance;
|
||||
// door might be secret?
|
||||
chance = rolldie(1,6) - (m->depth / 10);
|
||||
|
||||
// ie. at dungeon lev 10, chance is 2 in 6
|
||||
// at dungeon lev 20, chance is 3 in 6
|
||||
// ...
|
||||
// at dungeon lev 50, chance is 5 in 6
|
||||
chance = rolldie(1,6) - (m->depth / 10);
|
||||
|
||||
|
||||
if (chance <= 1) {
|
||||
addflag(o->flags, F_LOCKED, B_TRUE, getdoorlockdiff(m->depth), NA, NULL);
|
||||
}
|
||||
|
||||
// make it secret?
|
||||
chance = rolldie(1,6) - (m->depth / 10);
|
||||
|
||||
// difficulty:
|
||||
// l1 = 20
|
||||
// l10 = 25
|
||||
// l20 = 30
|
||||
if (chance <= 1) {
|
||||
addflag(o->flags, F_SECRET, getdoorsecretdiff(m->depth), NA, NA, NULL);
|
||||
// difficulty:
|
||||
// l1 = 20
|
||||
// l10 = 25
|
||||
// l20 = 30
|
||||
if (chance <= 1) {
|
||||
addflag(o->flags, F_SECRET, getdoorsecretdiff(m->depth), NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
|
||||
// don't override permenant light with temp light!
|
||||
//if ((c->lit == L_PERMLIGHT) && (how == L_TEMP)) {
|
||||
|
@ -5697,6 +5931,7 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
|
|||
}
|
||||
// shatter solid glass cells
|
||||
if (c->type->solid && willshatter(c->type->material->id)) {
|
||||
enum MATERIAL origmat;
|
||||
rv = B_TRUE;
|
||||
// announce
|
||||
if (haslos(player, c)) {
|
||||
|
@ -5714,16 +5949,19 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
|
|||
losehp(target, rnd(1,100), DT_SLASH, fromlf, damstring); // BIG damage
|
||||
}
|
||||
|
||||
// remember original material
|
||||
origmat = c->type->material->id;
|
||||
|
||||
// change cell type
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
|
||||
// place shards
|
||||
if (c->type->material->id == MT_GLASS) {
|
||||
if (origmat == MT_GLASS) {
|
||||
int numshards;
|
||||
numshards = rnd(50,100);
|
||||
snprintf(buf, BUFLEN, "%d pieces of broken glass",numshards);
|
||||
addob(c->obpile, buf);
|
||||
} else if (c->type->material->id == MT_ICE) {
|
||||
} else if (origmat == MT_ICE) {
|
||||
int numshards;
|
||||
numshards = rnd(50,100);
|
||||
snprintf(buf, BUFLEN, "%d chunks of ice",numshards);
|
||||
|
|
4
map.h
4
map.h
|
@ -56,7 +56,9 @@ void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *e
|
|||
void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIONTYPE newregiontype, region_t *parent);
|
||||
void createregionthing(map_t *map, regionthing_t *rt);
|
||||
void createriver(map_t *m);
|
||||
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
|
||||
void createroom(map_t *map, int roomid, int x1, int y1, int x2, int y2, int forcewalls);
|
||||
int calcposandmakeroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
|
||||
void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createswamp(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety);
|
||||
int dirtox(int dt, int dir);
|
||||
|
|
2
nexus.c
2
nexus.c
|
@ -526,7 +526,7 @@ int main(int argc, char **argv) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
celltype_t *addcelltype(int id, char *name, char glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight) {
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight) {
|
||||
celltype_t *a;
|
||||
|
||||
// add to the end of the list
|
||||
|
|
2
nexus.h
2
nexus.h
|
@ -1,6 +1,6 @@
|
|||
#include "defs.h"
|
||||
|
||||
celltype_t *addcelltype(int id, char *name, char glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight);
|
||||
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight);
|
||||
warning_t *addwarning(char *text);
|
||||
void checkdeath(void);
|
||||
void checkendgame(void);
|
||||
|
|
280
objects.c
280
objects.c
|
@ -445,6 +445,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
int wantlit = B_FALSE;
|
||||
int wantrarity = RR_NONE;
|
||||
int wantgoodness = G_NA;
|
||||
int wantfoodtaint = B_FALSE;
|
||||
enum LFSIZE wantarmsize = SZ_ANY;
|
||||
enum MATERIAL wantdiffmat = MT_NOTHING;
|
||||
map_t *targetmap = NULL; // for portals
|
||||
|
@ -457,6 +458,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
int ndoorflags = 0;
|
||||
char *signtext = NULL;
|
||||
int trapchance = 0;
|
||||
int lockchance = 0;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0;
|
||||
|
||||
|
@ -622,7 +624,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
donesomething = B_TRUE;
|
||||
// door flags
|
||||
} else if (strstarts(p, "locked ")) {
|
||||
doorflag[ndoorflags++] = F_LOCKED;
|
||||
doorflag[ndoorflags++] = F_LOCKED; // for doors
|
||||
lockchance = 100; // for other objects like chests
|
||||
p += strlen("locked ");
|
||||
donesomething = B_TRUE;
|
||||
} else if (strstarts(p, "jammed ")) {
|
||||
|
@ -695,6 +698,11 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
trapchance = 100;
|
||||
p += strlen("trapped ");
|
||||
donesomething = B_TRUE;
|
||||
// food
|
||||
} else if (strstarts(p, "tainted ")) {
|
||||
wantfoodtaint = B_TRUE;
|
||||
p += strlen("tainted ");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,19 +890,28 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
////////////////////////////////////
|
||||
|
||||
|
||||
if ((gamemode != GM_LOADING) && hasflag(ot->flags, F_ONEPERCELL)) {
|
||||
if (hasob(where, ot->id)) {
|
||||
if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name);
|
||||
nretobs = 0;
|
||||
return NULL;
|
||||
if (gamemode != GM_LOADING) {
|
||||
if (hasflag(ot->flags, F_ONEPERCELL)) {
|
||||
if (hasob(where, ot->id)) {
|
||||
if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name);
|
||||
nretobs = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// water ob onto dirt -> mud
|
||||
if (where->where) {
|
||||
if ((ot->material->id == MT_WATER) || (ot->id == OT_SPLASHWATER)) {
|
||||
if (where->where->type->id == CT_DIRT) {
|
||||
ot = findot(OT_MUDPOOL);
|
||||
// water ob onto dirt -> mud
|
||||
if (where->where) {
|
||||
if ((ot->material->id == MT_WATER) || (ot->id == OT_SPLASHWATER)) {
|
||||
if (where->where->type->id == CT_DIRT) {
|
||||
ot = findot(OT_MUDPOOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ot->obclass->id == OC_SPELL) {
|
||||
if (where->owner || where->where) {
|
||||
if (db) dblog("DB: Cannot give a spell object to a player, or a cell! object name '%s'", ot->name );
|
||||
nretobs = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -911,13 +928,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (ot->obclass->id == OC_SPELL) {
|
||||
if (where->owner || where->where) {
|
||||
if (db) dblog("DB: Cannot give a spell object to a player, or a cell! object name '%s'", ot->name );
|
||||
nretobs = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// override canstack if required
|
||||
if (!hasflag(ot->flags, F_STACKABLE)) {
|
||||
|
@ -1197,6 +1207,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
}
|
||||
|
||||
|
||||
// food flags
|
||||
if ((ot->obclass->id == OC_FOOD) && wantfoodtaint) {
|
||||
addflag(o->flags, F_TAINTED, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
// tool flags
|
||||
if (o && hasflag(o->flags, F_LIGHTSOURCE) && wantlit) {
|
||||
turnon(NULL, o);
|
||||
|
@ -1444,12 +1458,14 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
cf->val[1] = sizetonutrition(rf->val[0]);
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f && (f->val[0] != wantdepth)) {
|
||||
f->val[0] = wantdepth;
|
||||
}
|
||||
}
|
||||
|
||||
// depth
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f && (f->val[0] != wantdepth)) {
|
||||
f->val[0] = wantdepth;
|
||||
}
|
||||
|
||||
// chance of masterwork based on wantgoodness
|
||||
switch (wantgoodness) {
|
||||
case G_GREAT:
|
||||
|
@ -1607,6 +1623,20 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// locked?
|
||||
if (!lockchance) {
|
||||
f = hasflag(o->flags, F_CANBELOCKED);
|
||||
if (f) {
|
||||
lockchance = f->val[0] + (f->val[1] * (obloc->map->depth/5));
|
||||
limit(&lockchance, f->val[0], 100);
|
||||
}
|
||||
}
|
||||
if (lockchance && pctchance(lockchance)) {
|
||||
addflag(o->flags, F_LOCKED, B_TRUE, getdoorlockdiff(obloc->map->depth), NA, NULL);
|
||||
}
|
||||
|
||||
// trapped? l1=10%, l5=20%, l10=30%, l15=40%, l20+=60%
|
||||
if (!trapchance) {
|
||||
f = hasflag(o->flags, F_CANBETRAPPED);
|
||||
|
@ -1615,15 +1645,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
limit(&trapchance, f->val[0], f->val[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (trapchance) {
|
||||
if (pctchance(trapchance)) {
|
||||
enum OBTYPE traptype;
|
||||
// get a random trap
|
||||
//
|
||||
traptype = getrandomtrapforob();
|
||||
addflag(o->flags, F_TRAPPED, traptype, NA, NA, NULL);
|
||||
}
|
||||
if (trapchance && pctchance(trapchance)) {
|
||||
enum OBTYPE traptype;
|
||||
// get a random trap
|
||||
//
|
||||
traptype = getrandomtrapforob();
|
||||
addflag(o->flags, F_TRAPPED, traptype, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1808,6 +1835,8 @@ objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material,
|
|||
a->flags = addflagpile(NULL, NULL);
|
||||
// inherit flags from object class
|
||||
copyflags(a->flags, a->obclass->flags, NA);
|
||||
// ...but don'to inherit rarity
|
||||
killflagsofid(a->flags, F_RARITY);
|
||||
if (a->material) {
|
||||
// inherit flags from material
|
||||
copyflags(a->flags, a->material->flags, FROMMAT);
|
||||
|
@ -2534,16 +2563,11 @@ void colourmatchob(object_t *o, lifeform_t *lf) {
|
|||
|
||||
f = hasflag(o->flags, F_GLYPH);
|
||||
if (f) {
|
||||
|
||||
f->val[0] = lfglyph->colour;
|
||||
f->val[1] = lfglyph->colour;
|
||||
} else {
|
||||
glyph_t *obglyph;
|
||||
char buf[2];
|
||||
|
||||
obglyph = getglyph(o);
|
||||
buf[0] = obglyph->ch;
|
||||
buf[1] = '\0';
|
||||
addflag(o->flags, F_GLYPH, lfglyph->colour, NA, NA, buf);
|
||||
addflag(o->flags, F_GLYPH, lfglyph->colour, obglyph->ch, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3095,7 +3119,7 @@ int getfirearmspeed(object_t *o) {
|
|||
glyph_t *getglyph(object_t *o) {
|
||||
flag_t *f;
|
||||
int isopen;
|
||||
char g = ' '; // default
|
||||
int g = ' '; // default
|
||||
int col = C_GREY;
|
||||
cell_t *obloc;
|
||||
obloc = getoblocation(o);
|
||||
|
@ -3115,7 +3139,7 @@ glyph_t *getglyph(object_t *o) {
|
|||
|
||||
f = hasflag(o->flags, F_GLYPH);
|
||||
if (f) {
|
||||
g = f->text[0];
|
||||
g = f->val[1];
|
||||
if (f->val[0] != NA) {
|
||||
col = f->val[0];
|
||||
}
|
||||
|
@ -3127,21 +3151,24 @@ glyph_t *getglyph(object_t *o) {
|
|||
}
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_WATERDEEP) {
|
||||
if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
cell_t *loc;
|
||||
loc = getoblocation(o);
|
||||
// override colour
|
||||
if (getobdepth(o, player) >= DP_HEAD) {
|
||||
//if (getobdepth(o, player) >= DP_HEAD) {
|
||||
|
||||
/*
|
||||
if (getcellwaterdepth(loc, player) >= DP_HEAD) {
|
||||
col = C_BOLDBLUE;
|
||||
} else {
|
||||
col = C_BLUE;
|
||||
}
|
||||
loc = getoblocation(o);
|
||||
*/
|
||||
if (getcellwaterdepth(loc, player) >= DP_WAIST) {
|
||||
g = '{';
|
||||
g = UNI_SOLID;
|
||||
} else {
|
||||
g = '~';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tempglyph.ch = g;
|
||||
|
@ -4117,7 +4144,17 @@ enum DEPTH getobdepth(object_t *o, lifeform_t *lf) {
|
|||
depth = f->val[0];
|
||||
if (lf) {
|
||||
int mod;
|
||||
mod = (SZ_HUMAN - getlfsize(lf)) * DP_CALF;
|
||||
int lfsize;
|
||||
lfsize = getlfsize(lf);
|
||||
if (isprone(lf)) {
|
||||
lfsize -= 2;
|
||||
limit(&lfsize, SZ_MINI, NA);
|
||||
}
|
||||
|
||||
mod = (SZ_HUMAN - lfsize);
|
||||
limit(&mod, SZ_MINI, NA);
|
||||
mod *= DP_CALF;
|
||||
|
||||
depth += mod;
|
||||
limit(&depth, DP_NONE, DP_HEAD);
|
||||
}
|
||||
|
@ -4184,8 +4221,8 @@ char *getobdesc(object_t *o, char *buf) {
|
|||
} else {
|
||||
snprintf(buf, BUFLEN, "%s", o->type->desc);
|
||||
}
|
||||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
snprintf(buf, BUFLEN, "%s water.", getwaterdepthname(getobdepth(o, player)));
|
||||
} else if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
snprintf(buf, BUFLEN, "%s %s.", getwaterdepthname(getobdepth(o, player)), o->type->name);
|
||||
capitalise(buf);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s", o->type->desc);
|
||||
|
@ -4458,8 +4495,8 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
} else {
|
||||
sprintf(basename, "abandoned temple");
|
||||
}
|
||||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
snprintf(basename, BUFLEN, "%s water", getwaterdepthname(getobdepth(o, player)));
|
||||
} else if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
snprintf(basename, BUFLEN, "%s %s", getwaterdepthname(getobdepth(o, player)), o->type->name);
|
||||
} else {
|
||||
strcpy(basename, "");
|
||||
|
||||
|
@ -4969,7 +5006,11 @@ char *getobconditionname(object_t *o, char *buf) {
|
|||
if (isrotting(o) &&
|
||||
( (iqb >= AT_GTAVERAGE) || getskill(player, SK_COOKING)) ) {
|
||||
if (strlen(buf)) strcat(buf, " ");
|
||||
strcat(buf, "rotting");
|
||||
if (hasflag(o->flags, F_ISMEAT)) {
|
||||
strcat(buf, "rotting");
|
||||
} else {
|
||||
strcat(buf, "mouldy");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -5054,7 +5095,7 @@ float getobunitweight(object_t *o) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (o->type->id == OT_WATERDEEP) {
|
||||
if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
weight = 75 * getobdepth(o, NULL);
|
||||
} else {
|
||||
weight = o->weight;
|
||||
|
@ -5190,7 +5231,7 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
|
|||
|
||||
// no obclass given? pick one randomly.
|
||||
if (!nwantclass) {
|
||||
wantclass[0] = getrandomobclass();
|
||||
wantclass[0] = getrandomobclass(hab->id);
|
||||
nwantclass = 1;
|
||||
}
|
||||
|
||||
|
@ -5421,16 +5462,28 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
|
|||
}
|
||||
}
|
||||
}
|
||||
om = NULL;
|
||||
if (noms) {
|
||||
// pick a random one to maybe apply
|
||||
f = omposs[rnd(0,noms-1)];
|
||||
if (rnd(1,100) <= f->val[1]) {
|
||||
om = findobmod(f->val[0]);
|
||||
if (om) {
|
||||
strcat(cursestr, om->prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!om) {
|
||||
// in sewers, everythinng is shoddy
|
||||
if ((map->habitat->id == H_SEWER) && hasflagval(ot->flags, F_CANHAVEOBMOD, OM_SHODDY, NA, NA, NULL)) {
|
||||
om = findobmod(OM_SHODDY);
|
||||
}
|
||||
}
|
||||
if (om) {
|
||||
strcat(cursestr, om->prefix);
|
||||
strcat(cursestr, " ");
|
||||
}
|
||||
|
||||
if ((map->habitat->id == H_SEWER) && (ot->obclass->id == OC_FOOD)) {
|
||||
strcat(cursestr, "tainted ");
|
||||
}
|
||||
|
||||
// get random chance of having a brand (1% per depth)...
|
||||
// if so...
|
||||
|
@ -5468,14 +5521,26 @@ char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod
|
|||
return real_getrandomob(map, buf, getmapdifficulty(map) + depthmod, NA, SZ_MAX, B_FALSE, cid, OC_NONE, DT_NONE);
|
||||
}
|
||||
|
||||
enum OBCLASS getrandomobclass(void) {
|
||||
enum OBCLASS getrandomobclass(enum HABITAT hab) {
|
||||
enum RARITY wantrr;
|
||||
objectclass_t *oc,*poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
||||
|
||||
wantrr = pickrr(TT_OBJECT);
|
||||
while (!nposs) {
|
||||
for (oc = objectclass ; oc ; oc = oc->next) {
|
||||
enum RARITY thisrarity = RR_NONE;
|
||||
// if we were given a map, check the objectclass for specific
|
||||
// rarity flag for the maps' habitat.
|
||||
if (hab != H_ALL) {
|
||||
flag_t *f;
|
||||
f = hasflagval(oc->flags, F_RARITY, hab, NA, NA, NULL);
|
||||
if (f) thisrarity = f->val[2];
|
||||
}
|
||||
// otherwise just use the default objectclass rarity
|
||||
if (thisrarity == RR_NONE) thisrarity = oc->rarity;
|
||||
|
||||
if (oc->rarity == wantrr) {
|
||||
poss[nposs++] = oc;
|
||||
}
|
||||
|
@ -5602,15 +5667,21 @@ void setwaterdepth(cell_t *c, int depth) {
|
|||
}
|
||||
} else {
|
||||
int nkilled = 0;
|
||||
enum MATERIAL killedmat = MT_NOTHING;
|
||||
// water depth is now zero.
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
while (o) {
|
||||
if (killedmat == MT_NOTHING) killedmat = o->material->id;
|
||||
killob(o);
|
||||
nkilled++;
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
}
|
||||
if (nkilled) {
|
||||
addob(c->obpile, "large puddle of water");
|
||||
if (killedmat == MT_WATER) {
|
||||
addob(c->obpile, "large puddle of water");
|
||||
} else if (killedmat == MT_SLIME) {
|
||||
addob(c->obpile, "puddle of slime");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7735,6 +7806,10 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
if (hasflag(o->flags, F_CONTAINER) && !hasflag(o->flags, F_SHOP)) { // loot it
|
||||
if (isplayer(lf)) { // only player can loot.
|
||||
char ch;
|
||||
if (hasflag(o->flags, F_LOCKED)) {
|
||||
msg("The %s seems to be locked.", noprefix(obname));
|
||||
return B_TRUE;
|
||||
}
|
||||
snprintf(buf, BUFLEN, "Looting %s. Will you:",obname);
|
||||
initprompt(&prompt, buf);
|
||||
if (countobs(lf->pack, B_FALSE)) {
|
||||
|
@ -8206,32 +8281,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
} else if ((o->type->id == OT_LOCKPICK)
|
||||
|| (o->type->id == OT_PAPERCLIP)
|
||||
|| (o->type->id == OT_CREDITCARD)) {
|
||||
char ch;
|
||||
int dir;
|
||||
// ask direction
|
||||
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
|
||||
dir = chartodir(ch);
|
||||
if (dir == D_NONE) {
|
||||
clearmsg();
|
||||
return B_TRUE;
|
||||
} else {
|
||||
cell_t *c;
|
||||
c = getcellindir(player->cell, dir);
|
||||
if (c) {
|
||||
object_t *targ;
|
||||
// something to lockpick there?
|
||||
targ = hasobwithflag(c->obpile, F_LOCKED);
|
||||
if (targ) {
|
||||
lockpick(player, targ, o);
|
||||
} else {
|
||||
// fail
|
||||
msg("There is nothing locked there!");
|
||||
}
|
||||
} else {
|
||||
clearmsg();
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
lockpick(lf, NULL, NULL, o);
|
||||
} else if (o->type->id == OT_LOCKHACKER) {
|
||||
char ch;
|
||||
int dir;
|
||||
|
@ -8249,30 +8299,28 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
// lock/unlock everything there
|
||||
for (oo = c->obpile->first ; oo ; oo = nextoo) {
|
||||
nextoo = oo->next;
|
||||
if (hasflag(oo->flags, F_LOCKABLE)) {
|
||||
flag_t *f;
|
||||
f = hasflag(oo->flags, F_LOCKED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s beeps.", noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s %s beeps.", lfname, getpossessive(lfname),
|
||||
noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
addflag(oo->flags, F_LOCKED, B_TRUE, 20, NA, NULL);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s buzzes.", noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s %s buzzes.", lfname, getpossessive(lfname),
|
||||
noprefix(obname));
|
||||
}
|
||||
}
|
||||
flag_t *f;
|
||||
f = hasflag(oo->flags, F_LOCKED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s beeps.", noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s %s beeps.", lfname, getpossessive(lfname),
|
||||
noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
addflag(oo->flags, F_LOCKED, B_TRUE, 20, NA, NULL);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s buzzes.", noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s %s buzzes.", lfname, getpossessive(lfname),
|
||||
noprefix(obname));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -10055,11 +10103,7 @@ int sethiddenname(objecttype_t *ot, char *text) {
|
|||
if (gf) {
|
||||
gf->val[0] = colour[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, colour[n].col, NA, NA, buf);
|
||||
addflag(ot->flags, F_GLYPH, colour[n].col, ot->obclass->glyph.ch, NA, NULL);
|
||||
gotcolour = B_TRUE;
|
||||
//dblog("assigning colour %s to %s (%s)",colour[n].name, text, ot->name);
|
||||
break;
|
||||
|
@ -10075,11 +10119,7 @@ int sethiddenname(objecttype_t *ot, char *text) {
|
|||
if (gf) {
|
||||
gf->val[0] = gemtype[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, gemtype[n].col, NA, NA, buf);
|
||||
addflag(ot->flags, F_GLYPH, gemtype[n].col, ot->obclass->glyph.ch, NA, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ char *getrandomob(map_t *map, char *buf);
|
|||
char *getrandomobofsize(map_t *map, char *buf, enum LFSIZE maxsize);
|
||||
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf);
|
||||
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod);
|
||||
enum OBCLASS getrandomobclass(void);
|
||||
enum OBCLASS getrandomobclass(enum HABITAT hab);
|
||||
int getobrarity(object_t *o, enum RARITY *rr);
|
||||
enum SPELLSCHOOL getschool(enum OBTYPE sid);
|
||||
char *getschoolname(enum SPELLSCHOOL sch);
|
||||
|
|
31
spell.c
31
spell.c
|
@ -3263,7 +3263,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_ANIMATESTONE) {
|
||||
} else if (spellid == OT_S_ANIMATESTATUE) {
|
||||
object_t *o;
|
||||
target = targcell->lf;
|
||||
if (target) {
|
||||
|
@ -4682,7 +4682,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int nseen = 0;
|
||||
int nsteamseen = 0;
|
||||
// don't need line of fire!
|
||||
|
||||
getradiuscells(targcell, power, DT_ORTH, B_FALSE, LOF_NEED, B_TRUE, cell, &ncells, B_FALSE);
|
||||
for (i = 0; i < ncells; i++) {
|
||||
object_t *o,*nexto;
|
||||
|
@ -5400,6 +5399,34 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// is broken and vines will vanish.
|
||||
setobcreatedby(o, caster);
|
||||
|
||||
} else if (spellid == OT_S_EXCAVATE) {
|
||||
cell_t *retcell[MAXRETCELLS],*c;
|
||||
int nretcells,i,radius,seenwalls = 0, seenobs = 0;
|
||||
radius = power;
|
||||
limit(&radius, 3, NA);
|
||||
getradiuscells(caster->cell, radius, DT_ORTH, B_FALSE, LOF_DONTNEED, B_FALSE, retcell, &nretcells, 0);
|
||||
for (i = 0; i < nretcells; i++) {
|
||||
object_t *o, *nexto;
|
||||
c = retcell[i];
|
||||
if (c->type->solid) {
|
||||
if (haslos(player, c)) seenwalls++;
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
addob(c->obpile, "10-20 piles of ash");
|
||||
}
|
||||
// impassable objects here are destroyed
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if ((o->type->id != OT_ASH) && (getmaterialstate(o->material->id) == MS_SOLID)) {
|
||||
killob(o);
|
||||
addobfast(c->obpile, OT_ASH);
|
||||
if (haslos(player, c)) seenobs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seenobs || seenwalls || cansee(player, caster)) {
|
||||
msg("A shockwave of destructive force rips through the air!");
|
||||
setlosdirty(player);
|
||||
}
|
||||
} else if (spellid == OT_S_FLIGHT) {
|
||||
flag_t *f;
|
||||
// always targetted at caster
|
||||
|
|
4
text.c
4
text.c
|
@ -1101,7 +1101,9 @@ char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra)
|
|||
if (!strcmp(p, "you")) {
|
||||
strcpy(retbuf, "Committed suicide.");
|
||||
} else {
|
||||
snprintf(retbuf, BUFLEN, "%s by %s.",killverb, p);
|
||||
snprintf(retbuf, BUFLEN, "%s %s %s.",killverb,
|
||||
streq(killverb, "Drowned") ? "in" : "by",
|
||||
p);
|
||||
}
|
||||
if (wantextra) {
|
||||
p = strtok_r(NULL, "^", &dummy);
|
||||
|
|
Loading…
Reference in New Issue