- [+] prevent ALL overlapping rooms!
- [+] stop running for any non-cosmetic object. - [ ] echoing? - [+] OPTIONS - [+] option_t - [+] id - [+] letter - [+] text - [+] int enabled - [+] int default - [+] next/prev - [+] addoption() - [+] getoption() - [+] dooptions() - [+] list them all (with 'more' for multipages) - [+] pressing a letter toggles it. - [+] "display trails" - [+] make scents be "cosmetic"! - [+] increaes skeleton's vulnerability to falling - [+] missing announcement for bleed() - [+] let rapid ivy cast entangle - [+] caves - [+] new regiontype - [+] new link - [+] new habitat - [+] objectlass rarities - [+] assign obs/mons to habitat - [+] code to dig caves - [+] stairs linking to cave region - [+] when learning random skills: - [+] prefer lower-level skills - [+] onyl learn up to adept level - [+] animate dead crashes if there is no space to place the lifeform! - [+] increase range of charge ability - [+] when you gain techusage, check held objects for conferred flags. - [+] bug: motion scanner working even though i have no tech usage! - [+] warn player before climbing without climb skill (if wisdom is >= average) - [+] regions should have depthmod. - [+] regionthings should be based on DEPTH, not difficulty! - [+] rename firstdungeon to maindungeon - [+] announcearrival broken -always saying 'new area' - [+] don't use ranged attacks when feigning death if target is adjacent - [+] don't say 'argh' if you were beheaded. - [+] The bear cub bites a wooden door with a teeth.--More-- - [+] random levelup skills - only select from skills which we have used? - [+] need to chance f_hasskill to use f->val[2] = used_this_level - [+] when you gain a skill, set f>val[2] = b_false or NA - [+] add setskillused for all skills! - [+] make random levleup only pick from used skills. - [+] TEST - [+] knowledge skills - practice them when you see a new lf of this type. - [+] slithering shoudl hardly ever awaken you - make listen check harder. - [+] don't put fireplaces in corridors. F_ONLYINROOM ? - [+] bug: acid trails from slug disappearing or never appearing? - [+] snails/slugs - [+] killed by salt - [+] vslow - [+] snails have vhigh armourrating - [+] slugs have lots of hp and do more damage - [+] brown/grey 'j' ? - [+] leave slime/acid trails?
This commit is contained in:
parent
8d0d14b8dc
commit
adb066d31a
5
ai.c
5
ai.c
|
@ -302,6 +302,11 @@ object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK
|
|||
if (ra) *ra = RA_NONE;
|
||||
return NULL;
|
||||
}
|
||||
if (lfhasflag(lf, F_FEIGNINGDEATH) && target && (getcelldist(lf->cell, target->cell) == 1)) {
|
||||
if (db) dblog(".oO { no ranged attack because i am feigning death and adj to my target }");
|
||||
if (ra) *ra = RA_NONE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
if (iqb <= IQ_ANIMAL) {
|
||||
|
|
6
attack.c
6
attack.c
|
@ -881,7 +881,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// blocked by defender's shield?
|
||||
sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
|
||||
//difficulty = 20 + ((gethitdice(lf) - gethitdice(victim)) );
|
||||
difficulty = 20 + gethitdice(lf);
|
||||
//difficulty = 20 + gethitdice(lf);
|
||||
difficulty = 20 + (gethitdice(lf)*2) - gethitdice(victim);
|
||||
if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname)) {
|
||||
blocked = B_TRUE;
|
||||
break; // stop processing damage now.
|
||||
|
@ -1283,6 +1284,9 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
maxhp = 1;
|
||||
}
|
||||
|
||||
if (hasflag(wep->flags, F_UNARMEDWEP)) {
|
||||
isunarmed = B_TRUE;
|
||||
}
|
||||
getobname(wep, wepname, 1);
|
||||
|
||||
|
||||
|
|
3
data.h
3
data.h
|
@ -1,12 +1,15 @@
|
|||
#include "defs.h"
|
||||
|
||||
void addbonustext(flagpile_t *fp, enum FLAG fid, char *text);
|
||||
option_t *addoption(enum OPTION id, char *text, int def);
|
||||
command_t *addcommand(enum COMMAND id, char c, char *desc);
|
||||
void initcommands(void);
|
||||
void initjobs(void);
|
||||
void initobjects(void);
|
||||
void initoptions(void);
|
||||
void initrace(void);
|
||||
void initskills(void);
|
||||
void killcommand(command_t *cmd);
|
||||
void killoption(option_t *o);
|
||||
void make_basic_shop(flagpile_t *fp);
|
||||
void sortcommands(void);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
58
defs.h
58
defs.h
|
@ -17,6 +17,7 @@
|
|||
|
||||
// Text
|
||||
#define TEXT_WARN_ATTACK_NOXP "You will not gain experience until you train. Really attack?"
|
||||
#define TEXT_WARN_CLIMB "Really attempt to climb without Climbing skill?"
|
||||
|
||||
// Defaults
|
||||
#define DEF_AIFOLLOWTIME (50) // if target lf is out of view
|
||||
|
@ -663,11 +664,12 @@ enum CELLTYPE {
|
|||
CT_NONE = 0,
|
||||
// walls
|
||||
CT_WALL,
|
||||
CT_WALLFLESH,
|
||||
CT_WALLGLASS,
|
||||
CT_WALLMETAL,
|
||||
CT_WALLWOOD,
|
||||
CT_ROOMWALL,
|
||||
CT_WALLDIRT,
|
||||
CT_WALLFLESH,
|
||||
CT_WALLGLASS,
|
||||
CT_WALLMETAL,
|
||||
CT_WALLWOOD,
|
||||
CT_ROOMWALL,
|
||||
// empty
|
||||
CT_CORRIDOR,
|
||||
CT_DIRT,
|
||||
|
@ -1087,6 +1089,8 @@ enum OBTYPE {
|
|||
OT_HOLEINROOF,
|
||||
OT_STAIRSDOWN,
|
||||
OT_STAIRSUP,
|
||||
OT_TUNNELDOWN,
|
||||
OT_TUNNELUP,
|
||||
OT_PORTAL,
|
||||
OT_STOMACHEXIT,
|
||||
// buildings - rememebr to update MAXBUILDINGTYPES!
|
||||
|
@ -1980,6 +1984,7 @@ enum FLAG {
|
|||
F_BEINGUSED, // this object is currently being used
|
||||
F_DEAD, // object will be removed
|
||||
F_ONEPERCELL, // only one of these objects can exist per cell
|
||||
F_ONLYINROOM, // object nay only appear in rooms (not corridors)
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
F_CREATEDBYSPELL, // object was made by spell id v0
|
||||
F_ENCHANTABLE, // object can get +1/-1 ect
|
||||
|
@ -2078,9 +2083,9 @@ enum FLAG {
|
|||
F_HASBRAND, // has the object mod v0 (ie. OM_FLAMESTRIKE)
|
||||
F_HOLDCONFER, // gives flag v0+v1 when carried. v2 specifies if it must be id'd.
|
||||
F_EQUIPCONFER, // gives flag v0+v1 when weilded/worn. v2 specifies if it must be id'd.
|
||||
F_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
|
||||
F_ACTIVATEPREFIX, // when activated, prefix this objects name with
|
||||
// text
|
||||
F_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
|
||||
|
||||
F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit
|
||||
F_HITCONFER, // hitting with this gives flagid=v0
|
||||
|
@ -2859,7 +2864,11 @@ enum FLAG {
|
|||
F_NOTIME, // this lf's actions don't take time
|
||||
// skills
|
||||
F_HASSKILL, // lf has skill v0 at level v1
|
||||
F_PRACTICINGSKILL, // lf is pract skill v0
|
||||
// if v2 is B_TRUE, it means we've used this
|
||||
// skill since gaining/increasing it.
|
||||
// (ie. it's a candidate for a random increase
|
||||
// at levelup)
|
||||
F_PRACTICINGSKILL, // lf is practicing skill v0
|
||||
// COMBAT
|
||||
F_MAXATTACKS, // v0 = min # attacks this lf can make per round
|
||||
// v1 = max # attacks this lf can make per round
|
||||
|
@ -3209,9 +3218,23 @@ typedef struct warning_s {
|
|||
struct warning_s *next, *prev;
|
||||
} warning_t;
|
||||
|
||||
enum OPTION {
|
||||
OPT_ALWAYSSHOWTRAILS,
|
||||
};
|
||||
|
||||
typedef struct option_s {
|
||||
enum OPTION id;
|
||||
char *text;
|
||||
int letter;
|
||||
int enabled;
|
||||
int def;
|
||||
struct option_s *next, *prev;
|
||||
} option_t;
|
||||
|
||||
enum REGIONTYPE {
|
||||
RG_CAVE,
|
||||
RG_WORLDMAP,
|
||||
RG_FIRSTDUNGEON,
|
||||
RG_MAINDUNGEON,
|
||||
RG_HEAVEN,
|
||||
RG_PIT,
|
||||
RG_SEWER,
|
||||
|
@ -3219,14 +3242,15 @@ enum REGIONTYPE {
|
|||
};
|
||||
|
||||
enum HABITAT {
|
||||
H_DUNGEON = 1,
|
||||
H_FOREST = 2,
|
||||
H_HEAVEN = 3,
|
||||
H_PIT = 4,
|
||||
H_VILLAGE = 5,
|
||||
H_SEWER = 6,
|
||||
H_STOMACH = 7,
|
||||
H_SWAMP = 8,
|
||||
H_CAVE = 1,
|
||||
H_DUNGEON = 2,
|
||||
H_FOREST = 3,
|
||||
H_HEAVEN = 4,
|
||||
H_PIT = 5,
|
||||
H_VILLAGE = 6,
|
||||
H_SEWER = 7,
|
||||
H_STOMACH = 8,
|
||||
H_SWAMP = 9,
|
||||
H_ALL = 999
|
||||
};
|
||||
|
||||
|
@ -3238,6 +3262,7 @@ typedef struct regiontype_s {
|
|||
int stairsperlev;
|
||||
int deeperdir;
|
||||
int majorbranch;
|
||||
int depthmod;
|
||||
struct regiontype_s *next, *prev;
|
||||
} regiontype_t;
|
||||
|
||||
|
@ -3274,6 +3299,7 @@ typedef struct region_s {
|
|||
regionoutline_t *outline;
|
||||
struct region_s *parentregion;
|
||||
int nthings; // is this used???
|
||||
int depthmod;
|
||||
struct region_s *next, *prev;
|
||||
} region_t;
|
||||
|
||||
|
|
|
@ -4,5 +4,12 @@ defs.h:
|
|||
map.c:
|
||||
initmap: define via addhabitat()
|
||||
|
||||
|
||||
make a new function to create this kind of habitat
|
||||
|
||||
|
||||
text.c:
|
||||
update getregionname()
|
||||
|
||||
io.c:
|
||||
update announcearrival()
|
||||
|
|
103
io.c
103
io.c
|
@ -71,6 +71,7 @@ extern objectclass_t *objectclass;
|
|||
extern knowledge_t *knowledge;
|
||||
extern objecttype_t *objecttype;
|
||||
extern command_t *firstcommand;
|
||||
extern option_t *firstoption,*lastoption;
|
||||
extern vault_t *firstvault;
|
||||
extern skill_t *firstskill;
|
||||
|
||||
|
@ -1121,8 +1122,8 @@ char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def)
|
|||
|
||||
void announcearrival(lifeform_t *lf, map_t *newmap) {
|
||||
if (isplayer(lf)) {
|
||||
if (newmap->region == RG_WORLDMAP) {
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
if (newmap->region->rtype->id == RG_WORLDMAP) {
|
||||
if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
msg("You arrive in a new area.");
|
||||
} else {
|
||||
msg("You arrive at the surface.");
|
||||
|
@ -1135,6 +1136,15 @@ void announcearrival(lifeform_t *lf, map_t *newmap) {
|
|||
(newmap->lastplayervisit == -1) ? "" : "back ",
|
||||
newmap->depth);
|
||||
break;
|
||||
case H_CAVE:
|
||||
if ((newmap->depth == 1) && (newmap->lastplayervisit == -1)) {
|
||||
msg("You arrive at the goblin caves.");
|
||||
} else {
|
||||
msg("You arrive %sat level %d of the goblin caves.",
|
||||
(newmap->lastplayervisit == -1) ? "" : "back ",
|
||||
newmap->depth);
|
||||
}
|
||||
break;
|
||||
case H_SWAMP:
|
||||
msg("You arrive %sat a swamp.",
|
||||
(newmap->lastplayervisit == -1) ? "" : "back ");
|
||||
|
@ -2321,7 +2331,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
break;
|
||||
case F_SPIDERCLIMB:
|
||||
if (isplayer(lf)) {
|
||||
msg("Your skin is no longet adhesive.");
|
||||
msg("Your skin is no longer adhesive.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -4375,21 +4385,28 @@ void dolook(cell_t *where, int onpurpose) {
|
|||
numobs = 0;
|
||||
numtrails = 0;
|
||||
|
||||
|
||||
// first search for any non-trail objects.
|
||||
for (o = where->obpile->first ; o ; o = o->next) {
|
||||
if (!canseeob(player, o)) continue;
|
||||
if (hasflag(o->flags, F_COSMETIC)) continue;
|
||||
if (hasflag(o->flags, F_COSMETIC) && !onpurpose) continue;
|
||||
// footprints/scents only count if there are no other obs here
|
||||
if (!hasflag(o->flags, F_TRAIL)) {
|
||||
// found a non-trail object
|
||||
includetrails = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// now go through eech object...
|
||||
for (o = where->obpile->first ; o ; o = o->next) {
|
||||
if (!canseeob(player, o)) continue;
|
||||
//if (hasflag(o->flags, F_SECRET)) continue;
|
||||
if (hasflag(o->flags, F_COSMETIC)) continue;
|
||||
if (!includetrails && hasflag(o->flags, F_TRAIL)) continue;
|
||||
if (hasflag(o->flags, F_COSMETIC) && !onpurpose) continue;
|
||||
if (hasflag(o->flags, F_TRAIL)) {
|
||||
if (!includetrails) continue;
|
||||
// ignore it if we're have 'show trails' turned off
|
||||
if (!onpurpose && !getoption(OPT_ALWAYSSHOWTRAILS)) continue;
|
||||
//if (!onpurpose) continue;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_THEREISHERE);
|
||||
if (f) {
|
||||
|
@ -4473,7 +4490,7 @@ void dolook(cell_t *where, int onpurpose) {
|
|||
seensomething = B_TRUE;
|
||||
}
|
||||
|
||||
if (!seensomething) {
|
||||
if (!seensomething && onpurpose) {
|
||||
// just clear the message buffer
|
||||
//clearmsg();
|
||||
if (isblind(player)) {
|
||||
|
@ -6696,6 +6713,65 @@ void dooperate(obpile_t *op) {
|
|||
if (o) {
|
||||
operate(player, o, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void dooptions(void) {
|
||||
char buf[BUFLEN];
|
||||
char part1[BUFLEN];
|
||||
char promptstr[BUFLEN],cmdchars[BUFLENSMALL];
|
||||
char ch;
|
||||
int y,h,done = B_FALSE;
|
||||
option_t *opt;
|
||||
|
||||
|
||||
h = getmaxy(mainwin);
|
||||
|
||||
sprintf(promptstr, "Press letters to toggle options or ESC when done");
|
||||
strcpy(cmdchars, "");
|
||||
for (opt = firstoption ; opt ; opt = opt->next) {
|
||||
char thislet[2];
|
||||
sprintf(thislet, "%c", opt->letter);
|
||||
strcat(cmdchars, thislet);
|
||||
}
|
||||
|
||||
curs_set(0);
|
||||
|
||||
while (!done) {
|
||||
cls();
|
||||
centre(mainwin,C_WHITE, 0, "OPTIONS");
|
||||
y = 2;
|
||||
ch = '\0';
|
||||
for (opt = firstoption ; opt ; opt = opt->next) {
|
||||
sprintf(part1, "%c - %s", opt->letter, opt->text);
|
||||
sprintf(buf, "%-40s%s", part1, opt->enabled ? " ^gEnabled^n" : " ^BDisabled^n");
|
||||
if (opt->enabled == opt->def) strcat(buf, " (default)");
|
||||
wmove(mainwin, y, 0);
|
||||
textwithcol(mainwin, buf);
|
||||
if (opt->next && downline(&y, h, "INVENTORY", NULL, promptstr, cmdchars, &ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ch) {
|
||||
centre(mainwin, C_WHITE, h-1, promptstr);
|
||||
ch = getch();
|
||||
}
|
||||
if (ch == 27) {
|
||||
done = B_TRUE;
|
||||
} else {
|
||||
// find option with this letter
|
||||
for (opt = firstoption ; opt ; opt = opt->next) {
|
||||
if (opt->letter == ch) {
|
||||
// toggle it.
|
||||
if (opt->enabled) opt->enabled = B_FALSE;
|
||||
else opt->enabled = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curs_set(1);
|
||||
restoregamewindows();
|
||||
}
|
||||
|
||||
int dopickup(obpile_t *op, int forceask) {
|
||||
|
@ -8356,9 +8432,7 @@ void handleinput(void) {
|
|||
|
||||
// certain objects in the current cell will stop us from running.
|
||||
for (o = player->cell->obpile->first ; o ; o = o->next) {
|
||||
if ( !hasflag(o->flags, F_NOPICKUP) ||
|
||||
hasflag(o->flags, F_SHOP) ||
|
||||
hasflag(o->flags, F_CLIMBABLE) ) {
|
||||
if ( !hasflag(o->flags, F_COSMETIC)) {
|
||||
stopnow = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -8738,6 +8812,9 @@ void handleinput(void) {
|
|||
dooffer();
|
||||
break;
|
||||
// GAME FUNCTIONS
|
||||
case '=': // options
|
||||
dooptions();
|
||||
break;
|
||||
case 'Q': // quit
|
||||
doquit();
|
||||
break;
|
||||
|
@ -10265,7 +10342,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
unsetcol(mainwin, lorecol);
|
||||
} else {
|
||||
setcol(mainwin, lorecol);
|
||||
wrapprint(mainwin, &y, &x, "You would never be able to kill it. ");
|
||||
wrapprint(mainwin, &y, &x, "You probably couldn't kill it. ");
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
if (hitstokillyou) {
|
||||
|
@ -10275,7 +10352,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
unsetcol(mainwin, lorecol);
|
||||
} else {
|
||||
setcol(mainwin, lorecol);
|
||||
wrapprint(mainwin, &y, &x, "It would never be able to kill you. ");
|
||||
wrapprint(mainwin, &y, &x, "It probably couldn't kill you. ");
|
||||
unsetcol(mainwin, lorecol);
|
||||
}
|
||||
}
|
||||
|
|
1
io.h
1
io.h
|
@ -59,6 +59,7 @@ void domemmagic(void);
|
|||
void domsghist(void);
|
||||
void dooffer(void);
|
||||
void dooperate(obpile_t *op);
|
||||
void dooptions(void);
|
||||
int dopickup(obpile_t *op, int forceask);
|
||||
void donextguntarget(void);
|
||||
void dopour(obpile_t *op);
|
||||
|
|
121
lf.c
121
lf.c
|
@ -1410,6 +1410,10 @@ int cantalk(lifeform_t *lf) {
|
|||
if (getattr(lf, A_IQ) <= AT_VLOW) {
|
||||
return B_FALSE;
|
||||
}
|
||||
// beheaded?
|
||||
if (lfhasflag(lf, F_BEHEADED)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -3407,15 +3411,25 @@ void enhancerandomskill(lifeform_t *lf) {
|
|||
enum SKILL poss[MAXSKILLS];
|
||||
int nposs = 0;
|
||||
int sel;
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if ((f->id == F_HASSKILL) && !ismaxedskill(lf, f->val[0])) {
|
||||
poss[nposs] = f->val[0];
|
||||
nposs++;
|
||||
enum SKILLLEVEL wantlev;
|
||||
|
||||
// enhance lower level skills first, and only up to PR_ADEPT.
|
||||
for (wantlev = PR_NOVICE; wantlev <= PR_BEGINNER; wantlev++) {
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if ((f->id == F_HASSKILL) && !ismaxedskill(lf, f->val[0]) && (f->val[1] == wantlev)) {
|
||||
if (isplayer(lf) && (f->val[2] != B_TRUE)) {
|
||||
// for player - select only from skills which we have used since last levelup.
|
||||
} else {
|
||||
poss[nposs] = f->val[0];
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nposs > 0) {
|
||||
sel = rnd(0,nposs-1);
|
||||
giveskill(lf, poss[sel]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nposs > 0) {
|
||||
sel = rnd(0,nposs-1);
|
||||
giveskill(lf, poss[sel]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3673,13 +3687,13 @@ void enhanceskills(lifeform_t *lf) {
|
|||
f = levelabilityready(lf);
|
||||
while (f) {
|
||||
if (f->id == F_LEVABIL) {
|
||||
addflag(lf->flags, F_CANWILL, f->val[1], f->val[2], f->val[2], f->text);
|
||||
addtempflag(lf->flags, F_CANWILL, f->val[1], f->val[2], f->val[2], f->text, FROMJOB);
|
||||
} else if (f->id == F_LEVFLAG) {
|
||||
addflag(lf->flags, f->val[1], f->val[2], NA, NA, f->text);
|
||||
addtempflag(lf->flags, f->val[1], f->val[2], NA, NA, f->text, FROMJOB);
|
||||
} else if (f->id == F_LEVSKILL) {
|
||||
giveskill(lf, f->val[1]);
|
||||
} else if (f->id == F_LEVSPELL) {
|
||||
addflag(lf->flags, F_CANCAST, f->val[1], NA, NA, NULL);
|
||||
addtempflag(lf->flags, F_CANCAST, f->val[1], NA, NA, NULL, FROMJOB);
|
||||
} else if (f->id == F_LEVSPELLSCHOOL) { // select a spell from school
|
||||
if (isplayer(lf)) {
|
||||
int done = B_FALSE;
|
||||
|
@ -3693,7 +3707,7 @@ void enhanceskills(lifeform_t *lf) {
|
|||
ot = prompt.result;
|
||||
if (ot) {
|
||||
if (prompt.whichq == 0) { // learn the spell
|
||||
addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL);
|
||||
addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB);
|
||||
done = B_TRUE;
|
||||
} else {
|
||||
describespell(ot);
|
||||
|
@ -3712,7 +3726,7 @@ void enhanceskills(lifeform_t *lf) {
|
|||
// pick one randomly
|
||||
ot = (objecttype_t *)prompt.choice[rnd(0,prompt.nchoices)].data;
|
||||
if (ot) {
|
||||
addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL);
|
||||
addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8312,6 +8326,10 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
|
|||
int held = B_FALSE, equipped = B_FALSE,activated = B_FALSE;
|
||||
int lifetimeval;
|
||||
|
||||
if (gettechlevel(o->type->id) > getskill(lf, SK_TECHUSAGE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (o->pile->owner == lf) held = B_TRUE;
|
||||
|
||||
if (held) {
|
||||
|
@ -8404,6 +8422,17 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
|
|||
flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
||||
flag_t *f = NULL, *newf;
|
||||
skill_t *sk;
|
||||
int markasused = B_FALSE;
|
||||
|
||||
switch (id) {
|
||||
case SK_CARTOGRAPHY:
|
||||
case SK_PERCEPTION:
|
||||
markasused = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (lfhasflagval(lf, F_NOSKILL, id, NA, NA, NULL)) {
|
||||
return NULL;
|
||||
|
@ -8419,6 +8448,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
// already have the skill - make it better
|
||||
if (f->val[1] < PR_MASTER) {
|
||||
f->val[1]++;
|
||||
f->val[2] = markasused;
|
||||
}
|
||||
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
|
||||
msg("^gYou have learned the %s %s skill!", getskilllevelname(f->val[1]), getskillname(sk->id));
|
||||
|
@ -8427,7 +8457,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
statdirty = B_TRUE; // in case skill changes your stats
|
||||
} else {
|
||||
// gaining a new skill
|
||||
f = addflag(lf->flags, F_HASSKILL, id, PR_NOVICE, NA, NULL);
|
||||
f = addflag(lf->flags, F_HASSKILL, id, PR_NOVICE, markasused, NULL);
|
||||
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
|
||||
msg("^gYou have learned the %s %s skill!", getskilllevelname(PR_NOVICE), getskillname(sk->id));
|
||||
more();
|
||||
|
@ -8628,15 +8658,24 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
// if objecttype has a tech level , and it is
|
||||
// lower (or equal to) our tech knowledge...
|
||||
if (tf && !isknownot(ot) && (tf->val[0] <= f->val[1])) {
|
||||
object_t *o;
|
||||
// then make it known!
|
||||
makeknown(ot->id);
|
||||
if (isplayer(lf)) {
|
||||
object_t *o;
|
||||
o = hasob(lf->pack, ot->id);
|
||||
if (o) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
msgnocap("%c - %s", o->letter, buf);
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (o->type->id == ot->id) {
|
||||
if (isplayer(lf)) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
msgnocap("%c - %s", o->letter, buf);
|
||||
}
|
||||
// now confer effects...
|
||||
giveobflags(lf, o, F_HOLDCONFER);
|
||||
if (isactivated(o)) {
|
||||
giveobflags(lf, o, F_ACTIVATECONFER);
|
||||
}
|
||||
if (isequipped(o)) {
|
||||
giveobflags(lf, o, F_EQUIPCONFER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9661,7 +9700,6 @@ int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *devic
|
|||
// take time
|
||||
taketime(lf, getactspeed(lf) );
|
||||
|
||||
|
||||
if (skillcheck(lf, SC_OPENLOCKS, difficulty, bonus )) {
|
||||
// success!
|
||||
// announce
|
||||
|
@ -9705,8 +9743,10 @@ int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *devic
|
|||
msg("%s fail%s to unlock %s.",lfname, isplayer(lf) ? "" : "s", obname);
|
||||
}
|
||||
}
|
||||
practice(lf, SK_LOCKPICKING, 1);
|
||||
return B_TRUE;
|
||||
}
|
||||
practice(lf, SK_LOCKPICKING, 1);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -11148,6 +11188,7 @@ lifeform_t *makezombie(object_t *o) {
|
|||
if (!cellwalkable(NULL, where, NULL)) {
|
||||
where = getrandomadjcell(where, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
}
|
||||
if (!where) return NULL;
|
||||
lf = addlf(where, r->id, 1);
|
||||
|
||||
addflag(lf->flags, F_LFSUFFIX, B_TRUE, NA, NA, "zombie");
|
||||
|
@ -12814,7 +12855,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
if (f) {
|
||||
// can't hear while unconscious
|
||||
if (f->val[1] == ST_KO) continue;
|
||||
lbonus -= 4;
|
||||
lbonus -= 6;
|
||||
limit(&lbonus, 0, NA);
|
||||
}
|
||||
|
||||
|
@ -12934,7 +12975,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
if (f->lifetime > 0) { // ie. temporary
|
||||
timeeffectsflag(f, volume + rnd(1,3));
|
||||
} else if (f->lifetime == PERMENANT) {
|
||||
if (f->val[2] == NA) { // ie asleep rather than 'resting'
|
||||
if (f->val[2] == NA) {
|
||||
// ie asleep rather than 'resting'
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
msg("^wA nearby noise awakens you!");
|
||||
|
@ -13275,6 +13317,10 @@ void practice(lifeform_t *lf, enum SKILL skid, int amt) {
|
|||
sk = findskill(skid);
|
||||
if (!sk) return;
|
||||
|
||||
// do this even if the skill is not 'trainable'
|
||||
setskillused(lf, skid);
|
||||
|
||||
|
||||
slev = getskill(lf, skid);
|
||||
|
||||
timeneeded = sk->traintime * (getskill(lf, skid)+1);
|
||||
|
@ -13284,7 +13330,6 @@ void practice(lifeform_t *lf, enum SKILL skid, int amt) {
|
|||
if (!canlearn(lf, skid)) return;
|
||||
|
||||
if (!slev || onein(slev)) {
|
||||
|
||||
// practice a little bit...
|
||||
f = lfhasflagval(lf, F_PRACTICINGSKILL, skid, NA, NA, NULL);
|
||||
if (f) {
|
||||
|
@ -13747,6 +13792,14 @@ void relinklf(lifeform_t *src, map_t *dst) {
|
|||
sortlf(dst, src);
|
||||
}
|
||||
|
||||
void setskillused(lifeform_t *lf, enum SKILL skid) {
|
||||
flag_t *f;
|
||||
f = lfhasflagval(lf, F_HASSKILL, skid, NA, NA, NULL);
|
||||
if (f) {
|
||||
f->val[2] = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
int startclimbing(lifeform_t *lf) {
|
||||
cell_t *where;
|
||||
char lfname[BUFLEN];
|
||||
|
@ -13816,9 +13869,11 @@ int startclimbing(lifeform_t *lf) {
|
|||
} else if (cansee(player, lf)) {
|
||||
msg("%s tries to start climbing, but fails.", lfname);
|
||||
}
|
||||
practice(lf, SK_CLIMBING, 1);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
practice(lf, SK_CLIMBING, 1);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -16753,7 +16808,22 @@ int tryclimb(lifeform_t *lf, cell_t *where, char *towhat) {
|
|||
// to climb up
|
||||
int adjwalls;
|
||||
char lfname[BUFLEN];
|
||||
|
||||
// climbing without climb skill?
|
||||
if (isplayer(lf) &&
|
||||
!getskill(lf, SK_CLIMBING) &&
|
||||
!lfhasflag(lf, F_SPIDERCLIMB) &&
|
||||
!hasobwithflag(lf->pack, F_HELPSCLIMB)) {
|
||||
// you are about to do something foolish!
|
||||
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) {
|
||||
if (!warnabout(TEXT_WARN_CLIMB)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
adjwalls = countadjwalls(where);
|
||||
if (adjwalls || hasobwithflag(lf->pack, F_HELPSCLIMB)) {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -17704,6 +17774,7 @@ int rest(lifeform_t *lf, int onpurpose) {
|
|||
if (isplayer(lf)) {
|
||||
pleasegodmaybe(R_GODMERCY, 1);
|
||||
}
|
||||
practice(lf, SK_FIRSTAID, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
lf.h
1
lf.h
|
@ -365,6 +365,7 @@ int recruit(lifeform_t *lf);
|
|||
void refreshlevelabilities(lifeform_t *lf);
|
||||
void relinklf(lifeform_t *src, map_t *dst);
|
||||
int rest(lifeform_t *lf, int onpurpose);
|
||||
void setskillused(lifeform_t *lf, enum SKILL skid);
|
||||
int startclimbing(lifeform_t *lf);
|
||||
int startresting(lifeform_t *lf, int willtrain);
|
||||
int rollattr(enum ATTRBRACKET bracket);
|
||||
|
|
341
map.c
341
map.c
|
@ -676,7 +676,7 @@ void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy,
|
|||
}
|
||||
|
||||
// if outlineid is -1, it's automatically assigned
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid) {
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid, int depthmod) {
|
||||
region_t *a;
|
||||
regionoutline_t *ro,*poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
@ -707,6 +707,7 @@ region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid) {
|
|||
a->id = id;
|
||||
a->rtype = findregiontype(rtype);
|
||||
a->parentregion = parent;
|
||||
a->depthmod = depthmod;
|
||||
|
||||
if (outlineid == -1) {
|
||||
// randomly assign a regionoutline
|
||||
|
@ -781,7 +782,7 @@ regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum
|
|||
return rt;
|
||||
}
|
||||
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major) {
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod) {
|
||||
regiontype_t *a;
|
||||
|
||||
// add to the end of the list
|
||||
|
@ -807,6 +808,7 @@ regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT default
|
|||
a->stairsperlev = stairsperlev;
|
||||
a->deeperdir = deeperdir;
|
||||
a->majorbranch = major;
|
||||
a->depthmod = depthmod;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -1496,6 +1498,7 @@ flag_t *getmapcoords(map_t *m, int *x, int *y) {
|
|||
|
||||
int getmapdifficulty(map_t *m) {
|
||||
int diff = 1;
|
||||
|
||||
if (m) {
|
||||
if (isoutdoors(m)) {
|
||||
int x,y;
|
||||
|
@ -1505,6 +1508,10 @@ int getmapdifficulty(map_t *m) {
|
|||
} else {
|
||||
diff = m->depth;
|
||||
}
|
||||
if (m->region) {
|
||||
diff += m->region->rtype->depthmod;
|
||||
diff += m->region->depthmod;
|
||||
}
|
||||
} else {
|
||||
diff = rnd(1,MAXDEPTH);
|
||||
}
|
||||
|
@ -1653,7 +1660,7 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
int nposs = 0;
|
||||
cell_t *cell;
|
||||
int sel;
|
||||
int db = B_TRUE;
|
||||
int db = B_FALSE;
|
||||
int foundvalid = B_FALSE;
|
||||
|
||||
// init coords list
|
||||
|
@ -1692,6 +1699,7 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
if (hasobwithflag(cell->obpile, F_CLIMBABLE)) {
|
||||
valid = B_FALSE;
|
||||
}
|
||||
/*
|
||||
// - overlap the inside of an existing room
|
||||
if (cellwalkable(NULL, cell, NULL) && isroom(cell)) {
|
||||
valid = B_FALSE;
|
||||
|
@ -1700,6 +1708,11 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
if (cell->room && cell->room->vault) {
|
||||
valid = B_FALSE;
|
||||
}
|
||||
*/
|
||||
// - overlap any part of an existing room/vault
|
||||
if (cell->room) {
|
||||
valid = B_FALSE;
|
||||
}
|
||||
|
||||
// is this cell adjacent to an empty cell and not a
|
||||
// corner (ie. a valid door location)
|
||||
|
@ -1897,6 +1910,153 @@ int countmapobs(map_t *m, enum OBTYPE oid) {
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
int wantrooms = B_TRUE;
|
||||
int x,y,i;
|
||||
int numrooms = 0;
|
||||
int entrylinked = B_FALSE;
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
//int db = B_TRUE;
|
||||
enum CELLTYPE emptycell,solidcell;
|
||||
|
||||
// parameters
|
||||
int minrooms = 0;
|
||||
int maxrooms = 3;
|
||||
int numstartpos = 5;
|
||||
int numpasses = 50;
|
||||
|
||||
|
||||
// fill entire maze with walls
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
addcell(map, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// is the map lit?
|
||||
if (depth == 1) {
|
||||
map->lit = B_TRUE;
|
||||
} else {
|
||||
int darkchance;
|
||||
darkchance = depth*15; // ie. level 2 = 30% chance of being dark, level 6 = 90% chance
|
||||
if (pctchance(darkchance)) {
|
||||
map->lit = B_FALSE;
|
||||
} else {
|
||||
map->lit = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// what kind of cells will 'empty' ones be?
|
||||
emptycell = map->habitat->emptycelltype;
|
||||
solidcell = map->habitat->solidcelltype;
|
||||
|
||||
// pick initial random points
|
||||
for (i = 0; i < numstartpos; i++) {
|
||||
c = getrandomcell(map);
|
||||
setcelltype(c, emptycell);
|
||||
}
|
||||
|
||||
expand_cave(map, numpasses);
|
||||
|
||||
// adjust min/maxrooms based on fixed vaults
|
||||
minrooms -= map->nfixedrooms;
|
||||
maxrooms -= map->nfixedrooms;
|
||||
limit(&minrooms, 0, NA);
|
||||
limit(&maxrooms, 0, NA);
|
||||
|
||||
// create rooms
|
||||
if (wantrooms && (maxrooms > 0)) {
|
||||
numrooms = rnd(minrooms, maxrooms);
|
||||
|
||||
for (i = 0; i < numrooms; i++) {
|
||||
// maybe make it a special room
|
||||
if (rnd(1,100) <= map->habitat->randvaultpct) {
|
||||
vault_t *v;
|
||||
v = getvaulttype(map);
|
||||
if (!createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
|
||||
// success
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// just do a normal room
|
||||
calcposandmakeroom(map, map->nrooms, NA, NA, DEF_VAULTMARGIN, DEF_VAULTMARGIN, NULL, NULL, NULL, NULL, 50, B_FALSE);
|
||||
//roomvault[i] = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// link up room exits
|
||||
/*
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
int wantlink = B_FALSE;
|
||||
if (!map->room[i].exitslinked) {
|
||||
if (map->room[i].vault && hasflag(map->room[i].vault->flags, F_VAULTNOLINK)) {
|
||||
} else {
|
||||
wantlink = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (wantlink) {
|
||||
linkexits(map, map->room[i].id);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// UP STAIRS
|
||||
for (i = 0; i < map->region->rtype->stairsperlev; i++) {
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_TUNNELUP);
|
||||
assert(o);
|
||||
if (entryob && !entrylinked) { // first cave level
|
||||
linkstairs(o, entryob);
|
||||
entrylinked = B_TRUE;
|
||||
} else {
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
// make sure we have at least one up stairs
|
||||
assert(findobinmap(map, OT_TUNNELUP));
|
||||
|
||||
// DOWN STAIRS
|
||||
if (map->depth < map->region->rtype->maxdepth) {
|
||||
for (i = 0; i < map->region->rtype->stairsperlev; i++) {
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_TUNNELDOWN);
|
||||
assert(o);
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// now do a border
|
||||
y = 0;
|
||||
for (x = 0; x < map->w; x++) {
|
||||
// n
|
||||
c = getcellat(map, x, 0);
|
||||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
// s
|
||||
c = getcellat(map, x, map->h-1);
|
||||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
}
|
||||
for (y = 1; y < map->h-1; y++) {
|
||||
// w
|
||||
c = getcellat(map, 0, y);
|
||||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
// e
|
||||
c = getcellat(map, map->w-1, y);
|
||||
clearcell(c);
|
||||
setcelltype(c,solidcell);
|
||||
}
|
||||
}
|
||||
//
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
int wantrooms = B_TRUE;
|
||||
|
@ -2158,13 +2318,17 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
c = getrandomroomcell(map, ANYROOM);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_STAIRSUP);
|
||||
// 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);
|
||||
if (entryob) {
|
||||
linkstairs(o, entryob);
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
|
||||
// special case: first dungeon level has barriers over the exit stairs
|
||||
if (map->region->rtype->id == RG_FIRSTDUNGEON) {
|
||||
if (map->region->rtype->id == RG_MAINDUNGEON) {
|
||||
if (c->lf) killlf(c->lf);
|
||||
addobfast(c->obpile, OT_MAGICBARRIER);
|
||||
// also clear all the cells around it to prevent reachability errors
|
||||
|
@ -2177,7 +2341,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
} else {
|
||||
for (i = 0; i < map->region->rtype->stairsperlev; i++) {
|
||||
c = NULL;
|
||||
while (!isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
if (!c) {
|
||||
// ANY cell at all, doesn't have to be a room.
|
||||
|
@ -2288,10 +2452,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
|
||||
|
||||
// river?
|
||||
// TODO FIX
|
||||
//if ((depth >= 4) && pctchance(20)) {
|
||||
//if (depth > 1) {
|
||||
if (0) {
|
||||
if ((depth >= 4) && pctchance(20)) {
|
||||
createriver(map);
|
||||
}
|
||||
|
||||
|
@ -2416,6 +2577,9 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
case H_DUNGEON:
|
||||
createdungeon(map, depth, parentmap, exitdir, entryob);
|
||||
break;
|
||||
case H_CAVE:
|
||||
createcave(map, depth, parentmap, exitdir, entryob);
|
||||
break;
|
||||
case H_FOREST:
|
||||
createforest(map, depth, parentmap, exitdir, entryob, rnd(0,5));
|
||||
break;
|
||||
|
@ -2683,7 +2847,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
matched = B_TRUE;
|
||||
}
|
||||
} else { // match on depth
|
||||
if (region->outline->thing[i].depth == getmapdifficulty(map)) {
|
||||
if (region->outline->thing[i].depth == map->depth) {
|
||||
matched = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -2784,7 +2948,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
if (!failed) {
|
||||
if (fix_reachability(map)) {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
|
@ -2795,6 +2959,12 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
if (map->habitat->id == H_CAVE) {
|
||||
// expand the cave a little more now that we've fixed reachability.
|
||||
// this will help make any new corridors look more 'cave-like'.
|
||||
expand_cave(map, 2);
|
||||
}
|
||||
|
||||
// special cases
|
||||
// village - add town walls and clear it out
|
||||
if (db) dblog(" finalising village creation...");
|
||||
|
@ -2967,16 +3137,29 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
// add random objects and monsters
|
||||
// add random objects and monsters , and remove
|
||||
// bad objects
|
||||
if (db) dblog(" adding random objects+monsters");
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
cell_t *c;
|
||||
c = getcellat(map, x, y);
|
||||
// no random obs in vaults
|
||||
if (c && isempty(c) && !getcellvault(c)) {
|
||||
if (rnd(1,100) <= c->habitat->randthingpct) {
|
||||
addrandomthing(c, c->habitat->randobpct, NULL);
|
||||
if (c) {
|
||||
// add random obs, but not in vaults
|
||||
if (isempty(c) && !getcellvault(c)) {
|
||||
if (rnd(1,100) <= c->habitat->randthingpct) {
|
||||
addrandomthing(c, c->habitat->randobpct, NULL);
|
||||
}
|
||||
}
|
||||
// remove bad objects
|
||||
if (!c->room) {
|
||||
object_t *o,*nexto;
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (hasflag(o->flags, F_ONLYINROOM)) {
|
||||
killob(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3257,7 +3440,6 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
|
|||
assert(f);
|
||||
f->val[1] = map->region->parentregion->id;
|
||||
linkstairs(o, entryob);
|
||||
|
||||
}
|
||||
|
||||
void createstomach(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
|
||||
|
@ -4013,8 +4195,12 @@ 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) {
|
||||
flag_t *f;
|
||||
region_t *r;
|
||||
// create a new region
|
||||
r = addregion(newregiontype, m->region, -1);
|
||||
int basedepth = 0;
|
||||
if (newregiontype != RG_MAINDUNGEON) {
|
||||
basedepth = getmapdifficulty(m);
|
||||
}
|
||||
// create a new region.
|
||||
r = addregion(newregiontype, m->region, -1, basedepth);
|
||||
// add stairs going to the new region, if required
|
||||
if (!c) {
|
||||
c = NULL;
|
||||
|
@ -4298,7 +4484,7 @@ void dumpoutlines(void) {
|
|||
if (rt->whatkind == RT_REGIONLINK) {
|
||||
regiontype_t *rtype;
|
||||
rtype = findregiontype(rt->value);
|
||||
dblog(" at %s: link to %s",loctext, rtype->name);
|
||||
dblog(" at %s: link to %s (%s)",loctext, rtype->name, rt->what);
|
||||
} else if (rt->whatkind == RT_HABITAT) {
|
||||
habitat_t *h;
|
||||
h = findhabitat(rt->value);
|
||||
|
@ -4380,6 +4566,31 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
}
|
||||
}
|
||||
|
||||
void expand_cave(map_t *map, int numpasses) {
|
||||
int n,x,y,dir;
|
||||
cell_t *c;
|
||||
for (n = 0; n < numpasses; n++) {
|
||||
// for each dug map cell, 25% chance of clearing each adjacent cell
|
||||
for (y = 0; y < map->h; y++) {
|
||||
for (x = 0; x < map->w; x++) {
|
||||
c = getcellat(map, x, y);
|
||||
if (!c->type->solid && !c->visited) { // cell is empty and not processed already?
|
||||
cell_t *c2;
|
||||
// check for surrounding solid cells
|
||||
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||
c2 = getcellindir(c, dir);
|
||||
if (c2 && c2->type->solid && pctchance(25)) {
|
||||
setcelltype(c2, map->habitat->emptycelltype);
|
||||
}
|
||||
}
|
||||
// mark cell as processed
|
||||
c->visited = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this should never be called directly - only from explodecells().
|
||||
// (otherwise knockback effect won't happen)
|
||||
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre) {
|
||||
|
@ -4827,66 +5038,6 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
|
|||
}
|
||||
|
||||
|
||||
char *getregionname(char *buf, map_t *m, int withlevel) {
|
||||
region_t *r;
|
||||
|
||||
r = m->region;
|
||||
|
||||
if (withlevel) {
|
||||
flag_t *f;
|
||||
int x,y;
|
||||
f = hasflag(m->flags, F_MAPCOORDS);
|
||||
if (f) {
|
||||
x = f->val[0];
|
||||
y = f->val[1];
|
||||
} else {
|
||||
x = NA;
|
||||
y = NA;
|
||||
}
|
||||
switch (r->rtype->id) {
|
||||
case RG_WORLDMAP:
|
||||
snprintf(buf, BUFLEN, "the surface(%d,%d)",x,y);
|
||||
break;
|
||||
case RG_FIRSTDUNGEON:
|
||||
snprintf(buf, BUFLEN, "dungeon L%d", m->depth);
|
||||
break;
|
||||
case RG_HEAVEN:
|
||||
snprintf(buf, BUFLEN, "the realm of gods");
|
||||
break;
|
||||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit L%d", m->depth);
|
||||
break;
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer L%d", m->depth);
|
||||
break;
|
||||
case RG_STOMACH:
|
||||
snprintf(buf, BUFLEN, "a stomach");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (r->rtype->id) {
|
||||
case RG_WORLDMAP:
|
||||
strcpy(buf, "the surface");
|
||||
break;
|
||||
case RG_FIRSTDUNGEON:
|
||||
strcpy(buf, "the dungeon");
|
||||
break;
|
||||
case RG_HEAVEN:
|
||||
snprintf(buf, BUFLEN, "the realm of gods");
|
||||
break;
|
||||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit");
|
||||
break;
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer");
|
||||
break;
|
||||
case RG_STOMACH:
|
||||
snprintf(buf, BUFLEN, "a stomach");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) {
|
||||
return real_getrandomadjcell(c, wantempty, allowexpand, LOF_NEED, NULL, NULL);
|
||||
|
@ -5270,6 +5421,7 @@ void initmap(void) {
|
|||
// habitats
|
||||
// thingchance, obchance, vaultchance, maxvisrange
|
||||
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 30, 6);
|
||||
addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 5, 60, 10, 6);
|
||||
addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALL, 3, 75, 0, MAXVISRANGE);
|
||||
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALL, 0, 0, 0, MAXVISRANGE);
|
||||
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5);
|
||||
|
@ -5281,6 +5433,7 @@ void initmap(void) {
|
|||
// cell types - solid
|
||||
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0, 100);
|
||||
addcelltype(CT_ROOMWALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0, 100);
|
||||
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 50);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 50);
|
||||
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 50);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 150);
|
||||
|
@ -5299,18 +5452,19 @@ void initmap(void) {
|
|||
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1);
|
||||
|
||||
// region types
|
||||
addregiontype(RG_WORLDMAP, "World map", H_FOREST, 10, 0, D_NONE, B_TRUE);
|
||||
addregiontype(RG_FIRSTDUNGEON, "First Dungeon", H_DUNGEON, 25, 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);
|
||||
addregiontype(RG_STOMACH, "Stomach", H_STOMACH, 1, 0, D_NONE, B_FALSE);
|
||||
addregiontype(RG_WORLDMAP, "World map", H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
|
||||
addregiontype(RG_MAINDUNGEON, "First Dungeon", H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
|
||||
addregiontype(RG_CAVE, "Goblin Caves", H_CAVE, 6, 1, D_DOWN, B_TRUE, 5);
|
||||
addregiontype(RG_HEAVEN, "Realm of Gods", H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
|
||||
addregiontype(RG_PIT, "Pit", H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
|
||||
addregiontype(RG_SEWER, "Sewer", H_SEWER, 1, 0, D_NONE, B_FALSE, 2);
|
||||
addregiontype(RG_STOMACH, "Stomach", H_STOMACH, 1, 0, D_NONE, B_FALSE, 0);
|
||||
|
||||
// MAPMAPMAPMAP
|
||||
// region definitions (outlines)
|
||||
addregionoutline(RG_WORLDMAP);
|
||||
// link to first dungeon
|
||||
addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_FIRSTDUNGEON, "staircase going down");
|
||||
addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_MAINDUNGEON, "staircase going down");
|
||||
// four villages
|
||||
for (i = 0; i < 4; i++) {
|
||||
vx[i] = 0; vy[i] = 0;
|
||||
|
@ -5337,8 +5491,10 @@ void initmap(void) {
|
|||
//vx = 0; vy = -1;
|
||||
|
||||
|
||||
addregionoutline(RG_FIRSTDUNGEON);
|
||||
addregionoutline(RG_MAINDUNGEON);
|
||||
addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL);
|
||||
// l2-4: goblin caves
|
||||
addregionthing(lastregionoutline, rnd(2,4), NA, NA, RT_REGIONLINK, RG_CAVE, "tunnel leading down");
|
||||
// l6: jimbo's lair
|
||||
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");
|
||||
// l7 - 10: swamp
|
||||
|
@ -5355,6 +5511,7 @@ void initmap(void) {
|
|||
addregionthing(lastregionoutline, rnd(17,19), NA, NA, RT_OBJECT, NA, "random building");
|
||||
addregionthing(lastregionoutline, rnd(20,22), NA, NA, RT_OBJECT, NA, "random building");
|
||||
addregionthing(lastregionoutline, rnd(23,25), NA, NA, RT_OBJECT, NA, "random building");
|
||||
addregionoutline(RG_CAVE);
|
||||
}
|
||||
|
||||
int isadjacent(cell_t *src, cell_t *dst) {
|
||||
|
|
7
map.h
7
map.h
|
@ -7,10 +7,10 @@ map_t *addmap(void);
|
|||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int jobok, int amt, int autogen, int *nadded);
|
||||
object_t *addrandomob(cell_t *c);
|
||||
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid);
|
||||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid, int depthmod);
|
||||
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, char *name, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod);
|
||||
void adjustcellglyphforlight(cell_t *c, glyph_t *col);
|
||||
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);
|
||||
|
@ -46,6 +46,7 @@ int countadjwalls(cell_t *cell);
|
|||
int countcellexits(cell_t *cell, int dirtype);
|
||||
int countcellexitsfor(lifeform_t *lf);
|
||||
int countmapobs(map_t *m, enum OBTYPE oid);
|
||||
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createfakes(map_t *map, cell_t *cell);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings);
|
||||
|
@ -65,6 +66,7 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
int dirtox(int dt, int dir);
|
||||
int dirtoy(int dt, int dir);
|
||||
void dumpmap(map_t *map, int showrooms);
|
||||
void expand_cave(map_t *map, int numpasses);
|
||||
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre);
|
||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce);
|
||||
celltype_t *findcelltype(enum CELLTYPE cid);
|
||||
|
@ -89,7 +91,6 @@ vault_t *getcellvault(cell_t *c);
|
|||
cell_t *getclosestroomcell(lifeform_t *lf, int roomid);
|
||||
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 getthingchance(int habitat);
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, lifeform_t *preferlos);
|
||||
|
|
17
move.c
17
move.c
|
@ -72,7 +72,7 @@ int ispossiblemove(lifeform_t *lf, int dir) {
|
|||
object_t *inway = NULL;
|
||||
switch (error) {
|
||||
case E_OFFMAP:
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
if (lf->cell->map->region->id == RG_WORLDMAP) {
|
||||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -852,7 +852,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
// failed to move
|
||||
switch (reason) {
|
||||
case E_OFFMAP:
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
if (lf->cell->map->region->id == RG_WORLDMAP) {
|
||||
if (!walkoffmap(lf, dir, B_FALSE)) {
|
||||
// successful
|
||||
break;
|
||||
|
@ -1021,7 +1021,7 @@ int moveeffects(lifeform_t *lf) {
|
|||
int didmsg = B_FALSE;
|
||||
|
||||
if (lfhasflagval(lf, F_INJURY, IJ_HAMSTRUNG, NA, NA, NULL)) {
|
||||
if (!skillcheck(lf, SC_FALL, 20, 0)) {
|
||||
if (!skillcheck(lf, SC_FALL, 18, 0)) {
|
||||
fall(lf, NULL, B_TRUE);
|
||||
if (isplayer(lf)) didmsg = B_TRUE;
|
||||
}
|
||||
|
@ -1034,6 +1034,7 @@ int moveeffects(lifeform_t *lf) {
|
|||
if (isbleeding(lf)) {
|
||||
if (hasbleedinginjury(lf, BP_LEGS)) {
|
||||
if (!bleedfrom(lf, BP_LEGS, B_FALSE)) {
|
||||
if (isplayer(lf)) msg("^BYou bleed!");
|
||||
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
|
||||
}
|
||||
} else {
|
||||
|
@ -1050,6 +1051,7 @@ int moveeffects(lifeform_t *lf) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->lifetime == FROMRACE) {
|
||||
if (!bleedfrom(lf, BP_WINGS, B_FALSE)) {
|
||||
if (isplayer(lf)) msg("^BYou bleed!");
|
||||
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
|
||||
}
|
||||
}
|
||||
|
@ -1415,7 +1417,14 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
dointerrupt = B_TRUE;
|
||||
// mark the observed race as known.
|
||||
lf->race->known = B_TRUE;
|
||||
if (!lf->race->known) {
|
||||
raceclass_t *rc;
|
||||
lf->race->known = B_TRUE;
|
||||
rc = findraceclass(lf->race->raceclass->id);
|
||||
if (rc) {
|
||||
practice(lf, getskill(lf, rc->skill), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isplayer(lf)) {
|
||||
if (areallies(lf, l)) {
|
||||
|
|
21
nexus.c
21
nexus.c
|
@ -48,6 +48,7 @@ buildingusage_t buildingusage[MAXBUILDINGTYPES];
|
|||
int nbuildingusage = 0;
|
||||
|
||||
warning_t *firstwarning = NULL,*lastwarning = NULL;
|
||||
option_t *firstoption = NULL,*lastoption = NULL;
|
||||
|
||||
int maxmonhitdice = 0; // highest number of hitdice for any monster
|
||||
|
||||
|
@ -244,17 +245,17 @@ int main(int argc, char **argv) {
|
|||
newworld = B_TRUE;
|
||||
|
||||
// create world map.
|
||||
wregion = addregion(RG_WORLDMAP, NULL, -1);
|
||||
wregion = addregion(RG_WORLDMAP, NULL, -1, 0);
|
||||
assert(wregion);
|
||||
addmap();
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE, NULL);
|
||||
// create first dungeon
|
||||
dregion = findregionbytype(RG_FIRSTDUNGEON);
|
||||
dregion = findregionbytype(RG_MAINDUNGEON);
|
||||
assert(dregion);
|
||||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL);
|
||||
// create heaven
|
||||
hregion = addregion(RG_HEAVEN, NULL, -1);
|
||||
hregion = addregion(RG_HEAVEN, NULL, -1, 0);
|
||||
assert(hregion);
|
||||
heaven = addmap();
|
||||
createmap(heaven, 1, hregion, NULL, D_NONE, NULL);
|
||||
|
@ -656,8 +657,9 @@ void cleanup(void) {
|
|||
fclose(logfile);
|
||||
cleanupgfx();
|
||||
|
||||
// free commands
|
||||
// free commands & options
|
||||
while (firstcommand) killcommand(firstcommand);
|
||||
while (firstoption) killoption(firstoption);
|
||||
// free maps (this will kill its lifeforms & obs & cells too)
|
||||
while (firstmap) killmap(firstmap);
|
||||
// free knowledge
|
||||
|
@ -998,6 +1000,16 @@ void gethitdicerange(int depth, int *min, int *max, int range, int oodok) {
|
|||
*max = mid + range; limit(max, *min, maxmonhitdice);
|
||||
}
|
||||
|
||||
int getoption(enum OPTION id) {
|
||||
option_t *opt;
|
||||
for (opt = firstoption ; opt ; opt = opt->next) {
|
||||
if (opt->id == id) {
|
||||
if (opt->enabled) return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
enum COLOUR getpctcol(float num, float max) {
|
||||
float pct;
|
||||
pct = (num / max) * 100;
|
||||
|
@ -1084,6 +1096,7 @@ int init(void) {
|
|||
// load npc names
|
||||
loadnpcnames();
|
||||
|
||||
initoptions();
|
||||
initcommands();
|
||||
initobjects();
|
||||
initskills();
|
||||
|
|
1
nexus.h
1
nexus.h
|
@ -12,6 +12,7 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in
|
|||
void donextturn(map_t *map);
|
||||
warning_t *findwarning(char *text);
|
||||
void gethitdicerange(int depth, int *min, int *max, int range, int oodok);
|
||||
int getoption(enum OPTION id);
|
||||
enum COLOUR getpctcol(float num, float max);
|
||||
char getpctletter(float num, float max);
|
||||
void getrarityrange(int depth, int *min, int *max, int range, int oodok);
|
||||
|
|
11
objects.c
11
objects.c
|
@ -1861,7 +1861,7 @@ void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int all
|
|||
|
||||
ot = findotn(name);
|
||||
if (!ot) return;
|
||||
getradiuscells(centre, radius, DT_ORTH, B_FALSE, LOF_WALLSTOP, B_FALSE, cell, &ncells, B_FALSE);
|
||||
getradiuscells(centre, radius, DT_ORTH, B_FALSE, LOF_WALLSTOP, (radius == 0) ? B_TRUE : B_FALSE, cell, &ncells, B_FALSE);
|
||||
|
||||
for (i = 0; i < ncells; i++) {
|
||||
c = cell[i];
|
||||
|
@ -3538,6 +3538,7 @@ int getobspellpower(object_t *o, lifeform_t *lf) {
|
|||
slev = getskill(lf, SK_CHANNELING);
|
||||
power += slev;
|
||||
if (slev >= PR_ADEPT) power += (slev - 2);
|
||||
setskillused(lf, SK_CHANNELING);
|
||||
}
|
||||
// blessed objects are more powerful
|
||||
if (isblessed(o)) power += 4;
|
||||
|
@ -8211,6 +8212,9 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
} // end if techtype affected by gremlins
|
||||
|
||||
if (o->type->obclass->id == OC_TECH) {
|
||||
setskillused(lf, SK_TECHUSAGE);
|
||||
}
|
||||
|
||||
// mark obejct as tried
|
||||
if (isplayer(lf)) maketried(o->type->id);
|
||||
|
@ -8317,6 +8321,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
|
||||
// increase based on your magic item usage skill
|
||||
chanlev = getskill(lf, SK_CHANNELING);
|
||||
setskillused(lf, SK_CHANNELING);
|
||||
power += chanlev;
|
||||
if (chanlev >= PR_ADEPT) power += (chanlev - 2);
|
||||
|
||||
|
@ -8661,7 +8666,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->rtype->id == RG_FIRSTDUNGEON) && (m->depth == 1)) {
|
||||
if ((m->region->rtype->id == RG_MAINDUNGEON) && (m->depth == 1)) {
|
||||
cell_t *cell[MAXCANDIDATES];
|
||||
int ncells,i;
|
||||
getradiuscells(lf->cell, 1, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_TRUE, cell, &ncells, B_FALSE);
|
||||
|
@ -11716,6 +11721,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
announcedmiss = B_TRUE;
|
||||
}
|
||||
practice(target, SK_EVASION, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11786,7 +11792,6 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
dam = pctof(150, dam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// special case
|
||||
if (o->type->id == OT_RUBBERBULLET) {
|
||||
|
|
5
save.c
5
save.c
|
@ -625,6 +625,7 @@ int loadregions(void) {
|
|||
int rtid,nthings,i,n;
|
||||
int numoutlines,numregions;
|
||||
int db = B_FALSE;
|
||||
int depthmod;
|
||||
|
||||
// TODO: check that map dir exists
|
||||
snprintf(filename, BUFLEN, "%s/regions.dat",MAPDIR);
|
||||
|
@ -674,8 +675,9 @@ int loadregions(void) {
|
|||
fscanf(f, " outline:%d\n",&outlineid);
|
||||
fscanf(f, " parentregion:%d\n",&parentid);
|
||||
fscanf(f, " nthings:%d\n",&nthings);
|
||||
fscanf(f, " depthmod:%d\n",&depthmod);
|
||||
fscanf(f, "endregion\n");
|
||||
r = addregion(rtid, (parentid == -1) ? NULL : findregion(parentid), outlineid);
|
||||
r = addregion(rtid, (parentid == -1) ? NULL : findregion(parentid), outlineid, depthmod);
|
||||
r->nthings = nthings;
|
||||
if (db) dblog("Loaded region #%d / %d",n+1, numregions);
|
||||
}
|
||||
|
@ -1059,6 +1061,7 @@ int saveregions(void) {
|
|||
fprintf(f, " outline:%d\n",r->outline ? r->outline->id : -1);
|
||||
fprintf(f, " parentregion:%d\n",r->parentregion ? r->parentregion->id : -1);
|
||||
fprintf(f, " nthings:%d\n",r->nthings);
|
||||
fprintf(f, " depthmod:%d\n",r->depthmod);
|
||||
fprintf(f, "endregion\n");
|
||||
}
|
||||
fclose(f);
|
||||
|
|
3
shops.c
3
shops.c
|
@ -362,6 +362,7 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
|
|||
newob = moveob(o, vm->contents, count);
|
||||
newob->letter = let;
|
||||
(*ndonated)++;
|
||||
practice(player, SK_SPEECH, 1);
|
||||
}
|
||||
|
||||
if ((vm->type->id == OT_TEMPLE) && goldgiven) {
|
||||
|
@ -698,6 +699,7 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
|
|||
getobname(o, obname, shopamt);
|
||||
snprintf(toptext, BUFLEN, "Purchased: %c - %s", o->letter, obname);
|
||||
if (npurchased) (*npurchased)++;
|
||||
practice(player, SK_SPEECH, 1);
|
||||
} else {
|
||||
msg("You don't seem to have any money..."); more();
|
||||
o = NULL;
|
||||
|
@ -724,6 +726,7 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
|
|||
getobname(o, obname, shopamt);
|
||||
snprintf(toptext, BUFLEN, "Stolen: %c - %s", o->letter, obname);
|
||||
|
||||
practice(player, SK_THIEVERY, 1);
|
||||
pleasegodmaybe(R_GODTHIEVES, (value/50));
|
||||
o = NULL;
|
||||
} else {
|
||||
|
|
28
spell.c
28
spell.c
|
@ -128,12 +128,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
if (!range) {
|
||||
int movespeed;
|
||||
// get max range - based on speed.
|
||||
range = (int) (((float)SP_NORMAL / (float)getmovespeed(user)) * 2.5);
|
||||
if (range <= 1) {
|
||||
movespeed = getmovespeed(user);
|
||||
if (movespeed > SP_NORMAL) {
|
||||
if (isplayer(user)) msg("You are too slow to charge!");
|
||||
return B_TRUE;
|
||||
}
|
||||
range = 3 + ((SP_NORMAL - movespeed)/5);
|
||||
}
|
||||
|
||||
if (!targcell) {
|
||||
|
@ -636,6 +638,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// takes longer
|
||||
taketime(user, getactspeed(user) * (ncooked-1));
|
||||
}
|
||||
practice(user, SK_COOKING, 1);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -694,9 +697,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
msgnocap("%c - %s", o->letter, obname);
|
||||
// take some time
|
||||
taketime(user, getactspeed(user));
|
||||
practice(user, SK_COOKING, 1);
|
||||
} else {
|
||||
// pack full?
|
||||
msg("You have space to cook!");
|
||||
msg("You have no space to cook!");
|
||||
}
|
||||
}
|
||||
} else if (abilid == OT_A_DARKWALK) {
|
||||
|
@ -1398,6 +1402,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
fall(user, NULL, B_TRUE);
|
||||
}
|
||||
}
|
||||
practice(user, SK_ATHLETICS, 1);
|
||||
} else if (abilid == OT_A_PICKLOCK) {
|
||||
lockpick(user, NULL, NULL, NULL);
|
||||
} else if (abilid == OT_A_RAGE) {
|
||||
|
@ -1513,6 +1518,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
buf, withbuf);
|
||||
}
|
||||
|
||||
practice(user, SK_METALWORK, 1);
|
||||
practice(user, SK_SEWING, 1);
|
||||
// TODO: make this like eating/resting/etc ?
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_RESIZE) {
|
||||
|
@ -1624,7 +1631,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
more();
|
||||
msgnocap("%c - %s", o->letter, obname);
|
||||
|
||||
|
||||
practice(user, SK_METALWORK, 1);
|
||||
practice(user, SK_SEWING, 1);
|
||||
// TODO: make this like eating/resting/etc ?
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_SHIELDBASH) {
|
||||
|
@ -2036,7 +2044,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// this map will be destroyed when you leave it.
|
||||
r = findregionbytype(RG_STOMACH);
|
||||
if (!r) {
|
||||
r = addregion(RG_STOMACH, NULL, -1);
|
||||
r = addregion(RG_STOMACH, NULL, -1, 0);
|
||||
}
|
||||
// create stomach map
|
||||
newmap = addmap();
|
||||
|
@ -2501,6 +2509,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
practice(user, SK_ATHLETICS, 1);
|
||||
} else if (abilid == OT_A_POLYREVERT) {
|
||||
flag_t *f;
|
||||
if (!target) target = user;
|
||||
|
@ -2928,6 +2937,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
getobname(o, obname, o->amt);
|
||||
msgnocap("%c - %s", o->letter, obname);
|
||||
|
||||
practice(user, SK_METALWORK, 1);
|
||||
practice(user, SK_SEWING, 1);
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_EXPOSEDSTRIKE) {
|
||||
flag_t *f;
|
||||
|
@ -3248,6 +3260,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// start hiding
|
||||
addflag(user->flags, F_HIDING, penalty, NA, NA, NULL);
|
||||
|
||||
// even though it's untrainable - this will
|
||||
// still mark it as used.
|
||||
practice(user, SK_STEALTH, 1);
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_INSPECT) {
|
||||
object_t *o;
|
||||
|
@ -5943,7 +5959,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
getlfname(target, targname);
|
||||
if (cansee(player, target)) {
|
||||
msg("Magical vines grasp %s!",targname);
|
||||
msg("Entangling vines rise up and grasp %s!",targname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
|
|
67
text.c
67
text.c
|
@ -925,6 +925,73 @@ char *getrarityname(enum RARITY rr) {
|
|||
return "?unknownrarity?";
|
||||
}
|
||||
|
||||
char *getregionname(char *buf, map_t *m, int withlevel) {
|
||||
region_t *r;
|
||||
|
||||
r = m->region;
|
||||
|
||||
if (withlevel) {
|
||||
flag_t *f;
|
||||
int x,y;
|
||||
f = hasflag(m->flags, F_MAPCOORDS);
|
||||
if (f) {
|
||||
x = f->val[0];
|
||||
y = f->val[1];
|
||||
} else {
|
||||
x = NA;
|
||||
y = NA;
|
||||
}
|
||||
switch (r->rtype->id) {
|
||||
case RG_CAVE:
|
||||
snprintf(buf, BUFLEN, "goblin caves L%d", m->depth);
|
||||
break;
|
||||
case RG_WORLDMAP:
|
||||
snprintf(buf, BUFLEN, "the surface(%d,%d)",x,y);
|
||||
break;
|
||||
case RG_MAINDUNGEON:
|
||||
snprintf(buf, BUFLEN, "dungeon L%d", m->depth);
|
||||
break;
|
||||
case RG_HEAVEN:
|
||||
snprintf(buf, BUFLEN, "the realm of gods");
|
||||
break;
|
||||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit L%d", m->depth);
|
||||
break;
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer L%d", m->depth);
|
||||
break;
|
||||
case RG_STOMACH:
|
||||
snprintf(buf, BUFLEN, "a stomach");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (r->rtype->id) {
|
||||
case RG_CAVE:
|
||||
strcpy(buf, "the goblin caves");
|
||||
break;
|
||||
case RG_WORLDMAP:
|
||||
strcpy(buf, "the surface");
|
||||
break;
|
||||
case RG_MAINDUNGEON:
|
||||
strcpy(buf, "the dungeon");
|
||||
break;
|
||||
case RG_HEAVEN:
|
||||
snprintf(buf, BUFLEN, "the realm of gods");
|
||||
break;
|
||||
case RG_PIT:
|
||||
snprintf(buf, BUFLEN, "a pit");
|
||||
break;
|
||||
case RG_SEWER:
|
||||
snprintf(buf, BUFLEN, "a sewer");
|
||||
break;
|
||||
case RG_STOMACH:
|
||||
snprintf(buf, BUFLEN, "a stomach");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *getreldirname(int reldir) {
|
||||
switch (reldir) {
|
||||
case RD_FORWARDS:
|
||||
|
|
1
text.h
1
text.h
|
@ -27,6 +27,7 @@ char *getinjuredbpname(enum BODYPART bp);
|
|||
char *getinjuryname(enum DAMTYPE dt);
|
||||
char *getinjurydesc(enum BODYPART bp, enum DAMTYPE dt);
|
||||
char *getrarityname(enum RARITY rr);
|
||||
char *getregionname(char *buf, map_t *m, int withlevel);
|
||||
char *getreldirname(int reldir);
|
||||
char *getsizetext(enum LFSIZE sz);
|
||||
char *gettimetext(char *retbuf);
|
||||
|
|
Loading…
Reference in New Issue