- [+] don't place draininge grates on low floor!!
- [+] gate spell should always take you to a location wihtout water!! - [+] enhance speak with dead spell (SPEAKDEAD) - [+] may ask "how did you die" plus one of the below: - [+] tell me about the area - [+] mark stairs on the map - [+] mark shops on the map - [+] tell about very rare objects - [+] tell me about nearby dangers - [+] tell about odd monsters - [+] tell about traps - [+] test - [+] let you ask peaceful lfs about the surroundings too - [+] move code into io.c "askaboutarea(char *who)" - [+] test - [+] the first time you ask someone for info, randomly determine whether they know about: - [+] stairs (high chance) - [+] shops (medium chance) - [+] traps (low chance) - [+] areacomms_danger should include out of depth monsters - need isoutofdepth(lf) - [+] room floors should take the entry type from the habitat, NOT just use ct_room!!!! - [+] sometimes generate fixed SEWER regionthings - [+] done - [+] BUG: canT enter goblin caves again!!!! - [+] getting "ERROR - can't find opposite end of stairs/portal!" - [+] FAILED to link stiars: 'tunnel leading up' - [+] make maps direct you to regionthings. - [+] region things need unique IDs !!! - [+] change F_MAPTO - [+] v0 = src region id - [+] v1 = src depth - [+] v2 = regionthing with whatkind = RT_REGIONLINK - [+] when generating map objects, fill in a random branch entry - [+] fix getobname code for unknown maps. - [+] TEST - [+] with "map to the goblin caves" - [+] with "map" - [+] with "map to" - [+] use "the goblin caves are to the north", not "is to the north" - [+] is - [+] isn't - [+] test reading a map when on the wrong branch - [+] test reading a map when on the wrong level - [+] test reading a map when on the right level - [+] move staircase generation to END of map create - [+] finalisemap() - [+] countobswithflagval(obpile, flagid, val0...) - [+] countmapobswithflagval(map, flagid, v0...) - [+] jimbo's map should lead you to one of the major branches. - [+] crit pos shouldn't be higher than you can reach! - [+] same size or bigger = can reach anything - [+] 1 size smaller = you can't reach the head - [+] 2 sizes smaller = can't reach head or hands - [+] 3 sizes smaller = can't reach head, hands or body - [+] jimbo's room should contain all the staircases - [+] make you have to pass a speech check before people will tell you about the area - [+] bug in recruitment skillchecks - using wrong attribute, and too easy. - [+] rename dwarf to delver - [+] somtimes say "dons" instead of "puts on"
This commit is contained in:
parent
c9a8866870
commit
040b9bf052
2
attack.c
2
attack.c
|
@ -672,7 +672,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (critical) {
|
||||
object_t *armour;
|
||||
char noun[BUFLEN];
|
||||
critpos = getrandomcorebp(victim);
|
||||
critpos = getrandomcorebp(victim, lf);
|
||||
if (critpos != BP_NONE) {
|
||||
armour = getequippedob(victim->pack, critpos);
|
||||
if (armour) {
|
||||
|
|
8
data.c
8
data.c
|
@ -2340,6 +2340,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
|
||||
|
||||
addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, 4, NA, NULL);
|
||||
|
@ -6973,7 +6976,8 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "armour");
|
||||
//addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "dungeon exit orb");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "map");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "dungeon exit orb");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "concealing powder");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_POLEARMS, PR_ADEPT, NA, NULL);
|
||||
|
@ -7154,7 +7158,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL);
|
||||
|
||||
|
||||
addrace(R_DWARF, "dwarf", 60, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Dwarves are short, hardy creatures who generally spend their entire lives mining underground. As such they have great fitness and enhanced low-light vision, but generally lack great reasoning skills and magical ability.");
|
||||
addrace(R_DWARF, "delver", 60, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Delvers are short, hardy creatures who generally spend their entire lives mining underground. As such they have great fitness and enhanced low-light vision, but generally lack great reasoning skills and magical ability.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
|
||||
|
|
44
defs.h
44
defs.h
|
@ -132,7 +132,11 @@
|
|||
#define B_BIG (-1)
|
||||
|
||||
// Limits
|
||||
#define MAXCANDIDATES 400 // must be >= max # of spells/abilities
|
||||
|
||||
// must be >= max # of spells/abilities AND
|
||||
// >= max # of cells on the map
|
||||
#define MAXCANDIDATES 2048
|
||||
|
||||
#define MAXCHOICES 400
|
||||
#define MAXDEPTH 25 // max dungeon depth
|
||||
#define MAXDIR_ORTH 4
|
||||
|
@ -456,6 +460,11 @@ enum SAYPHRASE {
|
|||
SP_DIE,
|
||||
SP_DRUNK,
|
||||
SP_MERCYACCEPT,
|
||||
SP_INFO_ACCEPT,
|
||||
SP_INFO_ASKPRICE,
|
||||
SP_INFO_REFUSE,
|
||||
SP_INFO_REFUSE_AGAIN,
|
||||
SP_INFO_DECLINE_WONTPAY,
|
||||
SP_PAYWARN,
|
||||
SP_PAYTHREAT,
|
||||
SP_PAYTHANKS,
|
||||
|
@ -1859,20 +1868,20 @@ enum BODYPART {
|
|||
BP_SECWEAPON = 1,
|
||||
BP_EARS = 2,
|
||||
BP_EYES = 3,
|
||||
BP_HEAD = 4,
|
||||
BP_HEAD = 4, // <- core bodypart
|
||||
BP_SHOULDERS = 5,
|
||||
BP_BODY = 6,
|
||||
BP_HANDS = 7,
|
||||
BP_BODY = 6, // <- core bodypart
|
||||
BP_HANDS = 7, // <- core bodypart
|
||||
BP_WAIST = 8,
|
||||
BP_LEGS = 9,
|
||||
BP_LEGS = 9, // <- core bodypart
|
||||
BP_FEET = 10,
|
||||
BP_RIGHTFINGER = 11,
|
||||
BP_LEFTFINGER = 12,
|
||||
// others...
|
||||
BP_BACKLEGS = 13,
|
||||
BP_FRONTLEGS = 14,
|
||||
BP_WINGS = 15,
|
||||
BP_TAIL = 16,
|
||||
BP_WINGS = 15, // <- core bodypart
|
||||
BP_TAIL = 16, // <- core bodypart
|
||||
};
|
||||
#define MAXBODYPARTS (17)
|
||||
|
||||
|
@ -1995,9 +2004,11 @@ enum FLAG {
|
|||
F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold)
|
||||
F_CONTAINSOB, // for vending machiens. v0 is ob letter
|
||||
// text is an object it contains.
|
||||
F_MAPTO, // this object is a map to the world map at xy=v0/v1.
|
||||
// optional v2 = obtypeid of target
|
||||
// text = what this is a map to ie. "the nearest village"
|
||||
F_MAPTO, // this object is a map to a regionlink.:
|
||||
// v0=region containing entrance
|
||||
// v1=depth of entrance
|
||||
// v2=regionthing ID of RT_REGIONLINK thing
|
||||
// text = what this is a map to ie. "the goblin caves"
|
||||
F_SIGNTEXT, // for 'sign' objects. f->text is what is says.
|
||||
F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc
|
||||
F_STARTBLESSED, // v0 = b_blessed or b_cursed
|
||||
|
@ -2211,8 +2222,7 @@ enum FLAG {
|
|||
// stairs / teleporters / portals
|
||||
F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in
|
||||
// also use this for portals
|
||||
// OPTIONAL v1 = id of regiontype to link to.
|
||||
// (ie. RG_xxx)
|
||||
// OPTIONAL v1 = id of region to link to.
|
||||
F_PIT, // this is a pit which we can fall down.
|
||||
// v0 = up/down
|
||||
//F_STAIRDIR//, // val0 = direcion
|
||||
|
@ -2564,6 +2574,13 @@ enum FLAG {
|
|||
// must pass SC_SPEECH of difficulty v0
|
||||
F_HIREPRICE, // how much it costs to hire this lf.
|
||||
F_NOHIRE, // this lf will not be hired.
|
||||
F_INFOPRICE, // v0=price this lf wants to share info
|
||||
F_NOINFO, // this lf will NOT share info
|
||||
F_KNOWSABOUT, // text is a list of things this lf knows about:
|
||||
// e = exits
|
||||
// s = shops
|
||||
// t = traps
|
||||
// eg: text=="st" means they know of shops+traps
|
||||
F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc
|
||||
F_LASTDIR, // this is the last direction we moved.
|
||||
//F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
|
||||
|
@ -3258,6 +3275,7 @@ typedef struct regiontype_s {
|
|||
enum REGIONTYPE id;
|
||||
enum HABITAT defaulthabitat;
|
||||
char *name;
|
||||
int pluralname;
|
||||
int maxdepth;
|
||||
int stairsperlev;
|
||||
int deeperdir;
|
||||
|
@ -3276,6 +3294,8 @@ enum REGIONTHING {
|
|||
};
|
||||
|
||||
typedef struct regionthing_s {
|
||||
struct regionoutline_s *parent;
|
||||
int id;
|
||||
int depth; // only need depth OR x,y
|
||||
int x,y;
|
||||
enum REGIONTHING whatkind;
|
||||
|
|
178
io.c
178
io.c
|
@ -3712,6 +3712,14 @@ void docomms(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: allow you to ask this of allies, but only on the level they started on.
|
||||
if (!areallies(player, lf)) {
|
||||
if (ispeaceful(lf) && cantalk(lf)) {
|
||||
addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (areenemies(player, lf)) {
|
||||
addchoice(&prompt, 'm', "Have mercy!", NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -3945,6 +3953,13 @@ void docomms(lifeform_t *lf) {
|
|||
}
|
||||
aigoto(lf, c, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
|
||||
break;
|
||||
case 'i':
|
||||
msg("You say \"What can you tell me about this area?\" to %s.", lfname);
|
||||
if (askforinfo(lf)) {
|
||||
genareaknowledge(lf->flags, 0);
|
||||
docomms_areainfo(lfname, lf->flags, lf);
|
||||
}
|
||||
break;
|
||||
case 'j':
|
||||
// charisma check to see if they'll join you.
|
||||
msg("You say \"Join me on my quest!\" to %s.", lfname);
|
||||
|
@ -4069,6 +4084,13 @@ void docomms(lifeform_t *lf) {
|
|||
return;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
msg("You say \"Any dangers nearby that I should look out for?\" to %s.", lfname);
|
||||
if (askforinfo(lf)) {
|
||||
genareaknowledge(lf->flags, 0);
|
||||
docomms_areadangers(lfname, lf->flags, lf);
|
||||
}
|
||||
break;
|
||||
case 'y':
|
||||
msg("You shout at %s!", lfname);
|
||||
noise(where, player, NC_OTHER, 3, "someone shouting!", NULL);
|
||||
|
@ -4093,6 +4115,154 @@ void docomms(lifeform_t *lf) {
|
|||
taketime(player, getactspeed(player));
|
||||
}
|
||||
|
||||
// lf is the person (if any) who you are talking to
|
||||
void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf) {
|
||||
int x,y,ndone;
|
||||
object_t *o;
|
||||
cell_t *c;
|
||||
flag_t *f,*knowflag;
|
||||
|
||||
knowflag = hasflag(fp, F_KNOWSABOUT);
|
||||
if (!knowflag) {
|
||||
// should never happen
|
||||
msg("\"I don't know anything about that!\"");
|
||||
return;
|
||||
}
|
||||
|
||||
// shops
|
||||
if (strchr(knowflag->text, 's')) {
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
if (hasobwithflag(c->obpile, F_SHOP)) {
|
||||
setcellknownradius(c, PR_BEGINNER, 3, DT_ORTH);
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndone) {
|
||||
needredraw = B_TRUE;
|
||||
msg("\"There are some shops nearby...\""); more();
|
||||
}
|
||||
}
|
||||
// veryrare objects
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_SHOP)) continue; // shops were already handled
|
||||
f = hasflag(o->type->flags, F_RARITY);
|
||||
if (f && (f->val[2] == RR_VERYRARE)) {
|
||||
msg("\"I hear there is a rare %s nearby...\"", o->type->name); more();
|
||||
setcellknown(c, PR_MASTER);
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndone) needredraw = B_TRUE;
|
||||
// staircases
|
||||
if (strchr(knowflag->text, 'e')) {
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
if (hasobwithflag(c->obpile, F_CLIMBABLE)) {
|
||||
setcellknownradius(c, PR_BEGINNER, 3, DT_ORTH);
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndone) {
|
||||
needredraw = B_TRUE;
|
||||
msg("\"I can show you the ways out of this level...\""); more();
|
||||
}
|
||||
}
|
||||
msg("\"That's all I know about this area.\"");
|
||||
}
|
||||
|
||||
// lf is the person (if any) who you are talking to
|
||||
void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) {
|
||||
int ndone = 0;
|
||||
int totdone = 0;
|
||||
int x,y,min,max;
|
||||
cell_t *c;
|
||||
flag_t *f,*knowflag;
|
||||
object_t *o;
|
||||
|
||||
knowflag = hasflag(fp, F_KNOWSABOUT);
|
||||
if (!knowflag) {
|
||||
// should never happen
|
||||
msg("\"I don't know anything about that!\"");
|
||||
return;
|
||||
}
|
||||
|
||||
// traps or trapped objects
|
||||
if (strchr(knowflag->text, 't')) {
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (killflagsofid(o->flags, F_TRAP)) {
|
||||
setcellknown(c, PR_MASTER);
|
||||
ndone++;
|
||||
} else {
|
||||
f = hasflag(o->flags, F_TRAPPED);
|
||||
if (f && (f->val[2] != B_TRUE)) {
|
||||
f->val[2] = B_TRUE;
|
||||
setcellknown(c, PR_MASTER);
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndone) {
|
||||
needredraw = B_TRUE;
|
||||
msg("\"There are hidden traps nearby...\""); more();
|
||||
}
|
||||
totdone += ndone;
|
||||
}
|
||||
// veryrare monsters
|
||||
gethitdicerange(getmapdifficulty(player->cell->map), &min,&max, RARITYVARIANCELF, B_FALSE);
|
||||
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
if (c->lf && !isplayer(c->lf) && (c->lf != lf) && areenemies(c->lf, player)) {
|
||||
int showit = B_FALSE;
|
||||
enum RARITY rr;
|
||||
getracerarity(NULL, c->lf->race->id, &rr);
|
||||
if (rr == RR_VERYRARE) {
|
||||
showit = B_TRUE;
|
||||
} else {
|
||||
// out of depth monsters?
|
||||
int hd;
|
||||
hd = gethitdicerace(c->lf->race);
|
||||
if (hd > max) {
|
||||
showit = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (showit) {
|
||||
char lfname[BUFLEN];
|
||||
real_getlfnamea(c->lf, lfname, B_FALSE);
|
||||
msg("\"There is %s living nearby...\"", lfname); more();
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
totdone += ndone;
|
||||
|
||||
|
||||
msg("\"I know of no %sdangers in this area.\"", (totdone) ? "other " : "");
|
||||
}
|
||||
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
|
||||
object_t *o;
|
||||
char buf[BUFLEN];
|
||||
|
@ -8432,7 +8602,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_COSMETIC)) {
|
||||
if ( !hasflag(o->flags, F_COSMETIC) && !hasflag(o->flags, F_TRAIL)) {
|
||||
stopnow = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -9461,7 +9631,7 @@ void drawstatus(void) {
|
|||
|
||||
//wprintw(statwin, "DLev:%d", player->cell->map->depth);
|
||||
setcol(statwin, C_BROWN);
|
||||
getregionname(buf, player->cell->map, B_TRUE);
|
||||
getregionname(buf, player->cell->map, NULL, B_TRUE);
|
||||
capitalise(buf);
|
||||
wprintw(statwin, "%s", buf);
|
||||
unsetcol(statwin, C_BROWN);
|
||||
|
@ -11773,10 +11943,10 @@ void tombstone(lifeform_t *lf) {
|
|||
centre(mainwin, C_GREY, y, "%s (%ld points)",pname, playerscore); y++;
|
||||
|
||||
if (player->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
getregionname(buf, player->cell->map, B_TRUE);
|
||||
getregionname(buf, player->cell->map, NULL, B_TRUE);
|
||||
centre(mainwin, C_GREY, y, "Died on %s.", buf); y++;
|
||||
} else {
|
||||
getregionname(buf, player->cell->map, B_FALSE);
|
||||
getregionname(buf, player->cell->map, NULL, B_FALSE);
|
||||
centre(mainwin, C_GREY, y, "Died on level %d of %s.", player->cell->map->depth, buf); y++;
|
||||
}
|
||||
|
||||
|
|
2
io.h
2
io.h
|
@ -44,6 +44,8 @@ void describespell(objecttype_t *ot);
|
|||
void doattackcell(char dirch);
|
||||
void doclose(void);
|
||||
void docomms(lifeform_t *target);
|
||||
void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf);
|
||||
void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf);
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst);
|
||||
void doeat(obpile_t *op);
|
||||
void doenter(lifeform_t *lf);
|
||||
|
|
337
lf.c
337
lf.c
|
@ -994,6 +994,8 @@ int canquaff(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// can lf reach victim to attack them?
|
||||
int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty) {
|
||||
enum LFSIZE sizetoreach = SZ_ANY;
|
||||
// harder to hit flying/levitating enemies, unless you are
|
||||
|
@ -1030,6 +1032,71 @@ int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// can lf reach victim's bodypart bp?
|
||||
int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) {
|
||||
int howmuchsmaller;
|
||||
int lfsize, victimsize;
|
||||
|
||||
// can't reach them at all!
|
||||
if (!canreach(lf, victim, NULL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
lfsize = getlfsize(lf);
|
||||
switch (isairborne(lf)) {
|
||||
case F_FLYING: lfsize += 2; break;
|
||||
case F_LEVITATING: lfsize++; break;
|
||||
default: break;
|
||||
}
|
||||
victimsize = getlfsize(victim);
|
||||
switch (isairborne(victim)) {
|
||||
case F_FLYING: victimsize += 2; break;
|
||||
case F_LEVITATING: victimsize++; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
howmuchsmaller = victimsize - lfsize;
|
||||
if (howmuchsmaller <= 0) return B_TRUE;
|
||||
|
||||
switch (bp) {
|
||||
// upper
|
||||
case BP_EYES:
|
||||
case BP_HEAD:
|
||||
case BP_EARS:
|
||||
case BP_SHOULDERS:
|
||||
if (howmuchsmaller >= 1) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
case BP_WEAPON:
|
||||
case BP_SECWEAPON:
|
||||
case BP_HANDS:
|
||||
case BP_RIGHTFINGER:
|
||||
case BP_LEFTFINGER:
|
||||
if (howmuchsmaller >= 2) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
case BP_BODY:
|
||||
case BP_WAIST:
|
||||
case BP_WINGS:
|
||||
case BP_TAIL:
|
||||
if (howmuchsmaller >= 3) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
case BP_LEGS:
|
||||
case BP_FEET:
|
||||
case BP_BACKLEGS:
|
||||
case BP_FRONTLEGS:
|
||||
if (howmuchsmaller >= 4) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
int cansee(lifeform_t *viewer, lifeform_t *viewee) {
|
||||
return cansee_real(viewer, viewee, B_TRUE);
|
||||
}
|
||||
|
@ -1449,6 +1516,9 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
case E_LOWIQ:
|
||||
msg("You are not smart enough to cast spells.");
|
||||
break;
|
||||
case E_NOTREADY:
|
||||
msg("This ability is not recharged yet.");
|
||||
break;
|
||||
case E_PRONE:
|
||||
msg("You can't cast spells while prone.");
|
||||
break;
|
||||
|
@ -2499,6 +2569,9 @@ void die(lifeform_t *lf) {
|
|||
colourmatchob(corpse, lf);
|
||||
}
|
||||
|
||||
// inherit lifeform knowledge in case we raise it
|
||||
copyflag(corpse->flags, lf->flags, F_KNOWSABOUT);
|
||||
|
||||
// corpse of a player pet?
|
||||
if (ispetof(lf, player)) {
|
||||
addflag(corpse->flags, F_PETOF, player->id, NA, NA, NULL);
|
||||
|
@ -2622,6 +2695,28 @@ void dumpmonsters(void) {
|
|||
dblog("END MONSTER DUMP (%d found)",count);
|
||||
}
|
||||
|
||||
void genareaknowledge(flagpile_t *fp, int chancemod) {
|
||||
char knownstuff[BUFLENSMALL];
|
||||
|
||||
if (hasflag(fp, F_KNOWSABOUT)) return;
|
||||
|
||||
strcpy(knownstuff, "");
|
||||
// determine what someone knows about
|
||||
// stairs? (high chance)
|
||||
if (pctchance(75 + chancemod)) {
|
||||
strcat(knownstuff, "e");
|
||||
}
|
||||
// shops? (med chance)
|
||||
if (pctchance(50 + chancemod)) {
|
||||
strcat(knownstuff, "s");
|
||||
}
|
||||
// traps? (low chance)
|
||||
if (pctchance(25 + chancemod)) {
|
||||
strcat(knownstuff, "t");
|
||||
}
|
||||
addflag(fp, F_KNOWSABOUT, NA, NA, NA, knownstuff);
|
||||
}
|
||||
|
||||
void genxplist(void) {
|
||||
race_t *r;
|
||||
race_t *racetemp;
|
||||
|
@ -2673,7 +2768,7 @@ void dumpxp(void) {
|
|||
// dump
|
||||
dblog("%-10s%-30s%s","XP", "Race", "Rarity");
|
||||
for (i = 0; i < xplistlen; i++) {
|
||||
dblog("%-10d%-30s%d",xpposs[i], raceposs[i]->name,getracerarity(NULL, raceposs[i]->id));
|
||||
dblog("%-10d%-30s%d",xpposs[i], raceposs[i]->name,getracerarity(NULL, raceposs[i]->id, NULL));
|
||||
}
|
||||
|
||||
// free mem
|
||||
|
@ -3920,7 +4015,7 @@ int fall_from_air(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
if (willfall) fall(lf, NULL, B_TRUE);
|
||||
if (willinjure) injure(lf, getrandomcorebp(lf), DT_BASH);
|
||||
if (willinjure) injure(lf, getrandomcorebp(lf, NULL), DT_BASH);
|
||||
if (willfall || willinjure) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -7230,9 +7325,13 @@ int getraceclass(lifeform_t *lf) {
|
|||
return lf->race->raceclass->id;
|
||||
}
|
||||
|
||||
int getracerarity(map_t *map, enum RACE rid) {
|
||||
// returns rarity number. if optional rr is passed, this is will be returned too.
|
||||
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr) {
|
||||
race_t *r;
|
||||
int rarity = -1;
|
||||
|
||||
if (rr) *rr = RR_NONE;
|
||||
|
||||
r = findrace(rid);
|
||||
if (r) {
|
||||
flag_t *f = NULL;
|
||||
|
@ -7253,10 +7352,10 @@ int getracerarity(map_t *map, enum RACE rid) {
|
|||
if (f) {
|
||||
// ignore habitat for now!
|
||||
rarity = f->val[1];
|
||||
if (rr) *rr = f->val[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return rarity;
|
||||
}
|
||||
|
||||
|
@ -7297,16 +7396,47 @@ object_t *getrandomarmour(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// pick a random major body part
|
||||
// ie. head, body, arms/hands, legs
|
||||
enum BODYPART getrandomcorebp(lifeform_t *lf) {
|
||||
// ie. head, body, arms/hands, legs, wings, tail
|
||||
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker) {
|
||||
int cutoff[4],nparts = 0,i,max = 0,num;
|
||||
enum BODYPART bp[4],selbp = BP_NONE;
|
||||
if (hasbp(lf, BP_BODY)) bp[nparts++] = BP_BODY;
|
||||
if (hasbp(lf, BP_HANDS)) bp[nparts++] = BP_HANDS;
|
||||
if (hasbp(lf, BP_HEAD)) bp[nparts++] = BP_HEAD;
|
||||
|
||||
if (hasbp(lf, BP_BODY)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_BODY)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_BODY;
|
||||
}
|
||||
}
|
||||
if (hasbp(lf, BP_HANDS)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_HANDS)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_HANDS;
|
||||
}
|
||||
}
|
||||
if (hasbp(lf, BP_HEAD)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_HEAD)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_HEAD;
|
||||
}
|
||||
}
|
||||
if (hasbp(lf, BP_LEGS) || hasbp(lf, BP_FRONTLEGS) || hasbp(lf, BP_BACKLEGS)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_LEGS)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_LEGS;
|
||||
}
|
||||
}
|
||||
if (hasbp(lf, BP_WINGS)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_WINGS)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_WINGS;
|
||||
}
|
||||
}
|
||||
if (hasbp(lf, BP_TAIL)) {
|
||||
if (attacker && !canreachbp(attacker, lf, BP_TAIL)) {
|
||||
} else {
|
||||
bp[nparts++] = BP_TAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nparts) {
|
||||
return BP_NONE;
|
||||
|
@ -9018,30 +9148,12 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
|
|||
killflagsofid(fp, F_STARTOBCLASS);
|
||||
killflagsofid(fp, F_STARTOBWEPSK);
|
||||
|
||||
// SPECIAL CASES
|
||||
if (lf) {
|
||||
/*
|
||||
// SPECIAL CASES GO HERE.
|
||||
if (lf->race->id == R_JAILER) {
|
||||
regionoutline_t *ro;
|
||||
region_t *r;
|
||||
regionthing_t *rt = NULL;
|
||||
int i;
|
||||
o = addobfast(lf->pack, OT_MAP);
|
||||
o = addob(lf->pack, "map to the goblin caves");
|
||||
assert(o);
|
||||
// find first worldmap village
|
||||
r = findregion(RG_WORLDMAP);
|
||||
ro = r->outline;
|
||||
for (i = 0; i < ro->nthings; i++) {
|
||||
regionthing_t *thisthing;
|
||||
thisthing = &ro->thing[i];
|
||||
if ((thisthing->whatkind == RT_HABITAT) && (thisthing->value == H_VILLAGE)) {
|
||||
rt = thisthing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
addflag(o->flags, F_MAPTO, rt->x, rt->y, OT_GATEWOOD, "a village");
|
||||
}
|
||||
*/
|
||||
|
||||
// make sure lf doesn't start off burdened!
|
||||
while (isburdened(lf)) {
|
||||
|
@ -11415,6 +11527,96 @@ int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// returns TRUE if 'lf' agrees to share knowledge with the player
|
||||
int askforinfo(lifeform_t *lf) {
|
||||
if (lfhasflag(lf, F_NOINFO)) {
|
||||
// refusing to give info
|
||||
sayphrase(lf, SP_INFO_REFUSE_AGAIN, SV_TALK, NA, NULL);
|
||||
return B_FALSE;
|
||||
} else {
|
||||
int doinfo = B_FALSE;
|
||||
int askingprice = -1;
|
||||
char lfname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
if (areallies(player, lf)) {
|
||||
askingprice = 0;
|
||||
} else {
|
||||
// they will consider it - now negotiate a price
|
||||
f = lfhasflag(lf, F_INFOPRICE);
|
||||
if (f) {
|
||||
askingprice = f->val[0];
|
||||
} else {
|
||||
int result;
|
||||
int difficulty;
|
||||
|
||||
difficulty = 20 + ((gethitdice(player) - gethitdice(lf))*2);
|
||||
if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) {
|
||||
askingprice = 0;
|
||||
// passed - free!
|
||||
} else {
|
||||
if (difficulty - result >= 10) {
|
||||
// will not help!
|
||||
askingprice = -1;
|
||||
} else {
|
||||
// will help for gold
|
||||
askingprice = rnd(gethitdice(lf)*5, gethitdice(lf)*15 );
|
||||
}
|
||||
}
|
||||
|
||||
if (askingprice == -1) {
|
||||
addflag(lf->flags, F_NOINFO, B_TRUE, NA, NA, NULL);
|
||||
sayphrase(lf, SP_INFO_REFUSE, SV_TALK, NA, NULL);
|
||||
return B_FALSE;
|
||||
} else {
|
||||
addflag(lf->flags, F_INFOPRICE, askingprice, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (askingprice != 0) {
|
||||
// modify for same job
|
||||
if (getjob(player) == getjob(lf)) {
|
||||
askingprice = pctof(50, askingprice);
|
||||
} else if (player->race->baseid == lf->race->baseid) { // modify for same race
|
||||
askingprice = pctof(80, askingprice);
|
||||
}
|
||||
// modify by charisma
|
||||
askingprice = pctof(100 - getstatmod(player, A_CHA), askingprice);
|
||||
limit(&askingprice, 0, NA);
|
||||
}
|
||||
|
||||
if (askingprice > 0) {
|
||||
char ch;
|
||||
sayphrase(lf, SP_INFO_ASKPRICE, SV_TALK, askingprice, NULL);
|
||||
more();
|
||||
|
||||
if (askingprice > countmoney(player->pack)) {
|
||||
msg("You can't afford to pay $%d.", askingprice);
|
||||
return B_FALSE;
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "Pay $%d for information", askingprice);
|
||||
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
|
||||
if (ch == 'y') {
|
||||
doinfo = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
doinfo = B_TRUE;
|
||||
}
|
||||
|
||||
if (doinfo) {
|
||||
sayphrase(lf, SP_INFO_ACCEPT, SV_TALK, NA, NULL);
|
||||
return B_TRUE;
|
||||
} else {
|
||||
sayphrase(lf, SP_INFO_DECLINE_WONTPAY, SV_TALK, askingprice, NULL);
|
||||
}
|
||||
} // end if !nohire
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int askforpayment(lifeform_t *shk, lifeform_t *lf) {
|
||||
char saybuf[BUFLEN];
|
||||
|
@ -13080,6 +13282,8 @@ void petify(lifeform_t *lf, lifeform_t *owner) {
|
|||
makefriendly(lf, PERMENANT);
|
||||
addflag(lf->flags, F_PETOF, owner->id, owner->cell->x, owner->cell->y, NULL);
|
||||
killflagsofid(lf->flags, F_STAYINROOM);
|
||||
killflagsofid(lf->flags, F_NOINFO);
|
||||
killflagsofid(lf->flags, F_INFOPRICE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -13651,8 +13855,8 @@ int recruit(lifeform_t *lf) {
|
|||
int result;
|
||||
int difficulty;
|
||||
int minmult,maxmult;
|
||||
difficulty = 20 + ((gethitdice(player) - gethitdice(lf))*2);
|
||||
if (real_skillcheck(player, A_CHA, difficulty, 0, &result)) {
|
||||
difficulty = 25 + ((gethitdice(player) - gethitdice(lf))*2);
|
||||
if (real_skillcheck(player, SC_SPEECH, difficulty, 0, &result)) {
|
||||
minmult = 10;
|
||||
maxmult = 20;
|
||||
// passed
|
||||
|
@ -14200,6 +14404,69 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
|||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_INFO_ACCEPT:
|
||||
switch (rnd(1,2)) {
|
||||
case 1: snprintf(buf, BUFLEN, "Okay, here's what I know..."); break;
|
||||
case 2: snprintf(buf, BUFLEN, "Listen carefully..."); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_INFO_ASKPRICE:
|
||||
switch (rnd(1,3)) {
|
||||
case 1:
|
||||
snprintf(buf, BUFLEN, "I'll tell you for $%d...",val0);
|
||||
break;
|
||||
case 2:
|
||||
snprintf(buf, BUFLEN, "Is the info worth $%d to you?",val0);
|
||||
break;
|
||||
case 3:
|
||||
snprintf(buf, BUFLEN, "$%d and I'll tell you...",val0);
|
||||
break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_INFO_REFUSE:
|
||||
switch (rnd(1,4)) {
|
||||
case 1:
|
||||
snprintf(buf, BUFLEN, "What do you think I am, a library?");
|
||||
break;
|
||||
case 2:
|
||||
snprintf(buf, BUFLEN, "Can't help, sorry.");
|
||||
break;
|
||||
case 3:
|
||||
snprintf(buf, BUFLEN, "Get lost!");
|
||||
break;
|
||||
case 4:
|
||||
snprintf(buf, BUFLEN, "No time to talk!");
|
||||
break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_INFO_REFUSE_AGAIN:
|
||||
switch (rnd(1,3)) {
|
||||
case 1:
|
||||
snprintf(buf, BUFLEN, "Asking twice isn't going to change the answer!");
|
||||
break;
|
||||
case 2:
|
||||
snprintf(buf, BUFLEN, "Still can't help, sorry.");
|
||||
break;
|
||||
case 3:
|
||||
snprintf(buf, BUFLEN, "I already told you to go away!");
|
||||
break;
|
||||
case 4:
|
||||
snprintf(buf, BUFLEN, "Stop pestering me!");
|
||||
break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_INFO_DECLINE_WONTPAY:
|
||||
switch (rnd(1,3)) {
|
||||
case 1: snprintf(buf, BUFLEN, "Cheapskate."); break;
|
||||
case 2: snprintf(buf, BUFLEN, "Well, I'll be here if you change your mind."); break;
|
||||
case 3: snprintf(buf, BUFLEN, "Your loss."); break;
|
||||
}
|
||||
rv = say(lf, buf, volume);
|
||||
break;
|
||||
case SP_PAYWARN:
|
||||
switch (rnd(1,3)) {
|
||||
case 1: snprintf(buf, BUFLEN, "Hey! Where do you think you're going?"); break;
|
||||
|
@ -16793,6 +17060,7 @@ void timeeffectslf(lifeform_t *lf) {
|
|||
|
||||
if (willfall) {
|
||||
usestairs(lf, o, B_FALSE, B_FALSE);
|
||||
taketime(lf, getactspeed(lf)); // to avoid infinte loops
|
||||
donesomething = B_TRUE;
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, dir, NA, NA, NULL);
|
||||
}
|
||||
|
@ -18163,9 +18431,14 @@ int wear(lifeform_t *lf, object_t *o) {
|
|||
msg("You are now wearing %s.", obname);
|
||||
}
|
||||
} else if (cansee(player, lf)) {
|
||||
char verb[BUFLEN];
|
||||
getlfname(lf, buf);
|
||||
capitalise(buf);
|
||||
msg("%s puts on %s.", buf, obname);
|
||||
switch (rnd(1,2)) {
|
||||
case 1: strcpy(verb, "puts on"); break;
|
||||
case 2: strcpy(verb, "dons"); break;
|
||||
}
|
||||
msg("%s %s %s.", buf, obname);
|
||||
|
||||
}
|
||||
|
||||
|
|
7
lf.h
7
lf.h
|
@ -17,6 +17,7 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o);
|
|||
int areallies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason);
|
||||
int askforinfo(lifeform_t *lf);
|
||||
int askforpayment(lifeform_t *shk, lifeform_t *lf);
|
||||
char *assignnpcname(lifeform_t *lf);
|
||||
void autoskill(lifeform_t *lf);
|
||||
|
@ -48,6 +49,7 @@ int canpolymorphto(enum RACE rid);
|
|||
int canpush(lifeform_t *lf, object_t *o, int dir);
|
||||
int canquaff(lifeform_t *lf, object_t *o);
|
||||
int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty);
|
||||
int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp);
|
||||
int cansee(lifeform_t *viewer, lifeform_t *viewee);
|
||||
int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos);
|
||||
int cansleep(lifeform_t *lf);
|
||||
|
@ -110,6 +112,7 @@ void gainhp(lifeform_t *lf, int amt);
|
|||
void gainlevel(lifeform_t *lf, int autotrain);
|
||||
void gainmp(lifeform_t *lf, int amt);
|
||||
void gainxp(lifeform_t *lf, long amt);
|
||||
void genareaknowledge(flagpile_t *fp, int chancemod);
|
||||
void genxplist(void);
|
||||
int get_adjacent_quadrants(int dir, enum QUADRANT *start, enum QUADRANT *end);
|
||||
int get_circular_fov_endpoints(lifeform_t *lf, int maxvisrange, int *endx, int *endy, int *nendcells);
|
||||
|
@ -214,9 +217,9 @@ char *getpoisondesc(enum POISONTYPE ptype);
|
|||
char *getpoisonname(enum POISONTYPE ptype);
|
||||
enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
|
||||
int getraceclass(lifeform_t *lf);
|
||||
int getracerarity(map_t *map, enum RACE rid);
|
||||
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
enum BODYPART getrandomcorebp(lifeform_t *lf);
|
||||
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker);
|
||||
race_t *getrandomcorpserace(cell_t *c);
|
||||
job_t *getrandomjob(int onlyplayerjobs);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
|
|
400
map.c
400
map.c
|
@ -31,6 +31,8 @@ extern race_t *firstrace;
|
|||
extern int viewx,viewy,vieww,viewh;
|
||||
extern lifeform_t *player;
|
||||
|
||||
extern int nextregionthingid;
|
||||
|
||||
extern lifeform_t *godlf[];
|
||||
extern int ngodlfs;
|
||||
|
||||
|
@ -761,6 +763,9 @@ 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) {
|
||||
regionthing_t *rt;
|
||||
rt = &(ro->thing[ro->nthings]);
|
||||
rt->id = nextregionthingid;
|
||||
nextregionthingid++;
|
||||
rt->parent = ro;
|
||||
rt->depth = depth;
|
||||
rt->x = x;
|
||||
rt->y = y;
|
||||
|
@ -782,7 +787,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, int depthmod) {
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod) {
|
||||
regiontype_t *a;
|
||||
|
||||
// add to the end of the list
|
||||
|
@ -803,6 +808,7 @@ regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT default
|
|||
// props
|
||||
a->id = id;
|
||||
a->name = strdup(name);
|
||||
a->pluralname = pluralname;
|
||||
a->defaulthabitat = defaulthabitat;
|
||||
a->maxdepth = maxdepth;
|
||||
a->stairsperlev = stairsperlev;
|
||||
|
@ -1910,14 +1916,51 @@ int countmapobs(map_t *m, enum OBTYPE oid) {
|
|||
return count;
|
||||
}
|
||||
|
||||
int countmapobswithflag(map_t *m, enum FLAG flagid) {
|
||||
cell_t *c;
|
||||
int count = 0,x,y;
|
||||
|
||||
for (y = 0; y < m->h; y++) {
|
||||
for (x = 0; x < m->w; x++) {
|
||||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
count += countobswithflag(c->obpile, flagid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text) {
|
||||
cell_t *c;
|
||||
int count = 0,x,y;
|
||||
|
||||
for (y = 0; y < m->h; y++) {
|
||||
for (x = 0; x < m->w; x++) {
|
||||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
count += countobswithflagval(c->obpile, flagid, val0, val1, val2, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int countstairs(map_t *m, int dir) {
|
||||
int count;
|
||||
count = countmapobswithflagval(m, F_CLIMBABLE, dir, NA, NA, NULL);
|
||||
// don't include pits
|
||||
count -= countmapobswithflagval(m, F_PIT, dir, NA, NA, NULL);
|
||||
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 entrylinked = B_FALSE;
|
||||
//object_t *o;
|
||||
//int db = B_TRUE;
|
||||
enum CELLTYPE emptycell,solidcell;
|
||||
|
||||
|
@ -2003,37 +2046,6 @@ void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *
|
|||
}
|
||||
*/
|
||||
|
||||
// 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++) {
|
||||
|
@ -2068,7 +2080,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
int lastdir;
|
||||
int numrooms = 0;
|
||||
cell_t *cell, *c;
|
||||
object_t *o;
|
||||
//object_t *o;
|
||||
int db = B_TRUE;
|
||||
int digdb = B_FALSE;
|
||||
|
||||
|
@ -2305,70 +2317,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
}
|
||||
}
|
||||
|
||||
// add staircases.
|
||||
// first dungeon level has 1 up stairs, 3 down.
|
||||
// subsequent levels always have 3 up and down stairs
|
||||
|
||||
// UP STAIRS
|
||||
if (map->depth == 1) {
|
||||
flag_t *f;
|
||||
// first region level. just one exit stairs
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_STAIRSUP);
|
||||
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_MAINDUNGEON) {
|
||||
if (c->lf) killlf(c->lf);
|
||||
addobfast(c->obpile, OT_MAGICBARRIER);
|
||||
// also clear all the cells around it to prevent reachability errors
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
cell_t *c2;
|
||||
c2 = getcellindir(c, d);
|
||||
if (c2) setcelltype(c2, map->habitat->emptycelltype);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < map->region->rtype->stairsperlev; i++) {
|
||||
c = NULL;
|
||||
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.
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
}
|
||||
o = addobfast(c->obpile, OT_STAIRSUP);
|
||||
assert(o);
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
// make sure we have at least one up stairs
|
||||
assert(findobinmap(map, OT_STAIRSUP));
|
||||
|
||||
// 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 = getrandomroomcell(map, ANYROOM);
|
||||
}
|
||||
o = addobfast(c->obpile, OT_STAIRSDOWN);
|
||||
assert(o);
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// add pillars & objects & monsters to rooms
|
||||
if (wantrooms && (numrooms > 0)) {
|
||||
for (i = 0; i < map->nrooms; i++) {
|
||||
|
@ -2683,7 +2631,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
map->region = region;
|
||||
|
||||
if (db) {
|
||||
getregionname(buf, map, B_FALSE);
|
||||
getregionname(buf, map, NULL, B_FALSE);
|
||||
dblog("Creating new map of region '%s'",buf);
|
||||
}
|
||||
map->habitat = findhabitat(habitat);
|
||||
|
@ -2821,7 +2769,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
||||
// we now have the map name!
|
||||
getregionname(buf2, map, B_TRUE);
|
||||
getregionname(buf2, map, NULL, B_TRUE);
|
||||
snprintf(buf, BUFLEN, "%s (id #%d)",buf2, map->id);
|
||||
map->name = strdup(buf);
|
||||
|
||||
|
@ -2959,12 +2907,16 @@ 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);
|
||||
}
|
||||
|
||||
// add any required stairs
|
||||
finalisemap(map, entryob);
|
||||
|
||||
// special cases
|
||||
// village - add town walls and clear it out
|
||||
if (db) dblog(" finalising village creation...");
|
||||
|
@ -3119,7 +3071,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
} else {
|
||||
if (db) {
|
||||
dblog(" FAILED to link stiars: '%s'",o->type->name);
|
||||
dblog(" FAILED to link stairs: '%s'",o->type->name);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4199,12 +4151,13 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO
|
|||
if (newregiontype != RG_MAINDUNGEON) {
|
||||
basedepth = getmapdifficulty(m);
|
||||
}
|
||||
// does the new region exist yet ?
|
||||
// create a new region.
|
||||
r = addregion(newregiontype, m->region, -1, basedepth);
|
||||
// add stairs going to the new region, if required
|
||||
if (!c) {
|
||||
c = NULL;
|
||||
while (!c || !cellwalkable(NULL, c, NULL)) {
|
||||
while (!c || !cellwalkable(NULL, c, NULL) || getcellwaterdepth(c, NULL)) {
|
||||
c = getrandomcell(m);
|
||||
}
|
||||
}
|
||||
|
@ -4290,6 +4243,7 @@ void createroom(map_t *map, int roomid, int x1, int y1, int x2, int y2, int forc
|
|||
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;
|
||||
|
@ -4312,11 +4266,11 @@ void createroom(map_t *map, int roomid, int x1, int y1, int x2, int y2, int forc
|
|||
// 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);
|
||||
setcelltype(cell, cell->habitat->solidcelltype);
|
||||
}
|
||||
//}
|
||||
} else {
|
||||
setcelltype(cell, CT_ROOM);
|
||||
setcelltype(cell, cell->habitat->emptycelltype);
|
||||
}
|
||||
cell->room = thisroom;
|
||||
}
|
||||
|
@ -4554,7 +4508,6 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
// critical hit? 100% chance in middle, 60 at one cell, 20 at two cells
|
||||
critchance = 100 - (mydist*40);
|
||||
if (pctchance(critchance)) {
|
||||
//criticalhit(NULL, cc->lf, getrandomcorebp(cc->lf), DT_EXPLOSION);
|
||||
criticalhit(NULL, cc->lf, BP_HANDS, pctof(critchance, dam), DT_EXPLOSIVE);
|
||||
}
|
||||
|
||||
|
@ -4622,6 +4575,108 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
|
|||
}
|
||||
}
|
||||
|
||||
void finalisemap(map_t *map, object_t *entryob) {
|
||||
enum OBTYPE upstairtype, downstairtype;
|
||||
int i,d;
|
||||
int linkedentry = B_FALSE;
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
// add staircases.
|
||||
// first dungeon level has 1 up stairs, 3 down.
|
||||
// subsequent levels always have 3 up and down stairs
|
||||
switch (map->habitat->id) {
|
||||
case H_CAVE:
|
||||
upstairtype = OT_TUNNELUP;
|
||||
downstairtype = OT_TUNNELDOWN;
|
||||
break;
|
||||
case H_DUNGEON:
|
||||
upstairtype = OT_STAIRSUP;
|
||||
downstairtype = OT_STAIRSDOWN;
|
||||
break;
|
||||
default:
|
||||
upstairtype = OT_NONE;
|
||||
downstairtype = OT_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
// UP STAIRS
|
||||
if (upstairtype != OT_NONE) {
|
||||
if ((map->habitat->id == H_DUNGEON) && (map->depth == 1)) {
|
||||
flag_t *f;
|
||||
// first dungeon level. just one exit stairs
|
||||
c = NULL;
|
||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||
c = getrandomroomcell(map, ANYROOM);
|
||||
}
|
||||
o = addobfast(c->obpile, upstairtype);
|
||||
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_MAINDUNGEON) {
|
||||
if (c->lf) killlf(c->lf);
|
||||
addobfast(c->obpile, OT_MAGICBARRIER);
|
||||
// also clear all the cells around it to prevent reachability errors
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
cell_t *c2;
|
||||
c2 = getcellindir(c, d);
|
||||
if (c2) setcelltype(c2, map->habitat->emptycelltype);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// up stairs on all other levels
|
||||
int nneeded;
|
||||
nneeded = map->region->rtype->stairsperlev - countstairs(map, D_UP);
|
||||
for (i = 0; i < nneeded; i++) {
|
||||
c = NULL;
|
||||
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.
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
}
|
||||
o = addobfast(c->obpile, upstairtype);
|
||||
assert(o);
|
||||
if (entryob && !linkedentry) {
|
||||
linkstairs(o, entryob);
|
||||
linkedentry = B_TRUE;
|
||||
} else {
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
// make sure we have at least one up stairs
|
||||
assert(findobinmap(map, upstairtype));
|
||||
}
|
||||
|
||||
// DOWN STAIRS
|
||||
if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) {
|
||||
int nneeded;
|
||||
nneeded = map->region->rtype->stairsperlev - countstairs(map, D_DOWN);
|
||||
for (i = 0; i < nneeded; i++) {
|
||||
c = NULL;
|
||||
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.
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
}
|
||||
o = addobfast(c->obpile, downstairtype);
|
||||
assert(o);
|
||||
linkstairs(o, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
celltype_t *findcelltype(enum CELLTYPE cid) {
|
||||
celltype_t *ct;
|
||||
for (ct = firstcelltype ; ct ; ct = ct->next) {
|
||||
|
@ -4670,6 +4725,40 @@ map_t *findmapofdepth(int depth) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
object_t *findmapobwithflag(map_t *m, enum FLAG flagid) {
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < m->h; y++) {
|
||||
for (x = 0; x < m->w; x++) {
|
||||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
o = hasobwithflag(c->obpile, flagid);
|
||||
if (o) return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
object_t *findmapobwithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text) {
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
int x,y;
|
||||
|
||||
for (y = 0; y < m->h; y++) {
|
||||
for (x = 0; x < m->w; x++) {
|
||||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
o = hasobwithflagval(c->obpile, flagid, val0, val1, val2, text);
|
||||
if (o) return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
||||
int x,y,xinc,yinc;
|
||||
|
||||
|
@ -4774,6 +4863,21 @@ regionoutline_t *findoutline(int id) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
regiontype_t *findrandomregiontypewithname(char *name) {
|
||||
regiontype_t *rt,*poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
char buf[BUFLEN];
|
||||
for (rt = firstregiontype ; rt ; rt = rt->next) {
|
||||
if (streq(buf, rt->name)) {
|
||||
poss[nposs++] = rt;
|
||||
}
|
||||
}
|
||||
if (nposs) {
|
||||
return poss[rnd(0,nposs-1)];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
region_t *findregion(int regionid) {
|
||||
region_t *r;
|
||||
for (r = firstregion ; r ; r = r->next) {
|
||||
|
@ -4792,7 +4896,6 @@ region_t *findregionbytype(enum REGIONTYPE rtid) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
map_t *findregionmap(int regionid, int depth) {
|
||||
map_t *m;
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
|
@ -4801,6 +4904,42 @@ map_t *findregionmap(int regionid, int depth) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// returns the RT_REGIONLINK regionthing which links to region type rtid (eg. RG_CAVE)
|
||||
regionthing_t *findregionlink(enum REGIONTYPE rtid) {
|
||||
region_t *r;
|
||||
regionthing_t *rt;
|
||||
int i;
|
||||
for (r = firstregion ; r ; r = r->next) {
|
||||
if (!r->outline) continue;
|
||||
for (i = 0; i < r->outline->nthings; i++ ){
|
||||
rt = &r->outline->thing[i];
|
||||
if ((rt->whatkind == RT_REGIONLINK) && (rt->value == rtid)) {
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// find the region thing with the given id.
|
||||
// if optional 'retregion' is supplied, fill it in with the region which contains the thing.
|
||||
regionthing_t *findregionthing(int id, region_t **retregion) {
|
||||
region_t *r;
|
||||
regionthing_t *rt;
|
||||
int i;
|
||||
for (r = firstregion ; r ; r = r->next) {
|
||||
if (!r->outline) continue;
|
||||
for (i = 0; i < r->outline->nthings; i++ ){
|
||||
rt = &r->outline->thing[i];
|
||||
if (rt->id == id) {
|
||||
if (retregion) *retregion = r;
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
regiontype_t *findregiontype(enum REGIONTYPE rtype) {
|
||||
regiontype_t *rt;
|
||||
for (rt = firstregiontype ; rt ; rt = rt->next) {
|
||||
|
@ -4809,6 +4948,14 @@ regiontype_t *findregiontype(enum REGIONTYPE rtype) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
regiontype_t *findregiontypebyname(char *name) {
|
||||
regiontype_t *rt;
|
||||
for (rt = firstregiontype ; rt ; rt = rt->next) {
|
||||
if (!strcasecmp(rt->name, name)) return rt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
room_t *findroom(map_t *m, int roomid) {
|
||||
int i;
|
||||
for (i = 0; i < m->nrooms; i++) {
|
||||
|
@ -5432,7 +5579,6 @@ 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);
|
||||
|
@ -5445,20 +5591,19 @@ void initmap(void) {
|
|||
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
|
||||
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, B_EMPTY, B_TRANS, MT_FLESH, 0, -1);
|
||||
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
|
||||
addcelltype(CT_ROOM, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT, 0, -1);
|
||||
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -1, -1);
|
||||
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, 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);
|
||||
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
|
||||
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
|
||||
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 6, 1, D_DOWN, B_TRUE, 5);
|
||||
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
|
||||
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
|
||||
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2);
|
||||
addregiontype(RG_STOMACH, "A Stomach", B_FALSE, H_STOMACH, 1, 0, D_NONE, B_FALSE, 0);
|
||||
|
||||
// MAPMAPMAPMAP
|
||||
// region definitions (outlines)
|
||||
|
@ -5502,6 +5647,15 @@ void initmap(void) {
|
|||
// l25: last level
|
||||
addregionthing(lastregionoutline, 25, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISSHRINE, NULL); // godstone on last floor
|
||||
|
||||
// 1-3 fixed sewers
|
||||
addregionthing(lastregionoutline, rnd(1,25), NA, NA, RT_REGIONLINK, RG_SEWER, "drainage grate");
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (onein(2)) {
|
||||
addregionthing(lastregionoutline, rnd(1,25), NA, NA, RT_REGIONLINK, RG_SEWER, "drainage grate");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// forced shops:
|
||||
addregionthing(lastregionoutline, rnd(2,4), NA, NA, RT_OBJECT, NA, "random building");
|
||||
addregionthing(lastregionoutline, rnd(5,7), NA, NA, RT_OBJECT, NA, "random building");
|
||||
|
@ -5512,6 +5666,10 @@ void initmap(void) {
|
|||
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);
|
||||
|
||||
// add initial regions
|
||||
addregion(RG_WORLDMAP, NULL, -1, 0);
|
||||
addregion(RG_HEAVEN, NULL, -1, 0);
|
||||
}
|
||||
|
||||
int isadjacent(cell_t *src, cell_t *dst) {
|
||||
|
@ -5534,8 +5692,12 @@ int isdark(cell_t *c) {
|
|||
|
||||
int isdiggable(cell_t *c) {
|
||||
switch (c->type->id) {
|
||||
case CT_WALL: return B_TRUE;
|
||||
case CT_ROOMWALL: return B_TRUE;
|
||||
case CT_WALLFLESH:
|
||||
case CT_WALLDIRT:
|
||||
case CT_WALL:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -5879,7 +6041,7 @@ object_t *linkportal(object_t *srcportal, int wantdepth) {
|
|||
|
||||
// find a random cell there
|
||||
newcell = getrandomcell(newmap);
|
||||
while (!cellwalkable(NULL, newcell, NULL) || hasenterableobject(newcell)) {
|
||||
while (!cellwalkable(NULL, newcell, NULL) || hasenterableobject(newcell) || getcellwaterdepth(newcell, NULL)) {
|
||||
newcell = getrandomcell(newmap);
|
||||
}
|
||||
// add the dst portal
|
||||
|
|
12
map.h
12
map.h
|
@ -10,7 +10,7 @@ int addrandomthing(cell_t *c, int obchance, int *nadded);
|
|||
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, int depthmod);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, 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,9 @@ 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);
|
||||
int countmapobswithflag(map_t *m, enum FLAG flagid);
|
||||
int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
||||
int countstairs(map_t *m, int dir);
|
||||
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);
|
||||
|
@ -69,20 +72,27 @@ 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);
|
||||
void finalisemap(map_t *map, object_t *entryob);
|
||||
celltype_t *findcelltype(enum CELLTYPE cid);
|
||||
celltype_t *findcelltypebyname(char *name);
|
||||
habitat_t *findhabitat(enum HABITAT id);
|
||||
habitat_t *findhabitatbyname(char *name);
|
||||
map_t *findmap(int mid);
|
||||
map_t *findmapofdepth(int depth);
|
||||
object_t *findmapobwithflag(map_t *m, enum FLAG flagid);
|
||||
object_t *findmapobwithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
||||
object_t *findobidinmap(map_t *m, long id);
|
||||
cell_t *findobinmap(map_t *m, enum OBTYPE oid);
|
||||
regionoutline_t *findoutline(int id);
|
||||
regiontype_t *findrandomregiontypewithname(char *name);
|
||||
region_t *findregion(int regionid);
|
||||
region_t *findregionbytype(enum REGIONTYPE rtid);
|
||||
regionthing_t *findregionlink(enum REGIONTYPE rtid);
|
||||
map_t *findregionmap(int regionid, int depth);
|
||||
regionthing_t *findregionthing(int id, region_t **retregion);
|
||||
regiontype_t *findregiontype(enum REGIONTYPE rtype);
|
||||
regiontype_t *findregiontypebyname(char *name);
|
||||
room_t *findroom(map_t *m, int roomid);
|
||||
map_t *findsurfaceexitmap(map_t *m);
|
||||
void forgetcells(map_t *map, int amt);
|
||||
|
|
2
move.c
2
move.c
|
@ -876,7 +876,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
i = howfar;
|
||||
// don't fall
|
||||
mightfall = B_FALSE;
|
||||
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf), dam, DT_BASH);
|
||||
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf, NULL), dam, DT_BASH);
|
||||
break;
|
||||
case E_SWIMMING:
|
||||
case E_LFINWAY:
|
||||
|
|
6
nexus.c
6
nexus.c
|
@ -44,6 +44,8 @@ hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
|||
npcname_t *npcname;
|
||||
int numnpcnames;
|
||||
|
||||
int nextregionthingid = 0;
|
||||
|
||||
buildingusage_t buildingusage[MAXBUILDINGTYPES];
|
||||
int nbuildingusage = 0;
|
||||
|
||||
|
@ -245,7 +247,7 @@ int main(int argc, char **argv) {
|
|||
newworld = B_TRUE;
|
||||
|
||||
// create world map.
|
||||
wregion = addregion(RG_WORLDMAP, NULL, -1, 0);
|
||||
wregion = findregionbytype(RG_WORLDMAP);
|
||||
assert(wregion);
|
||||
addmap();
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE, NULL);
|
||||
|
@ -255,7 +257,7 @@ int main(int argc, char **argv) {
|
|||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL);
|
||||
// create heaven
|
||||
hregion = addregion(RG_HEAVEN, NULL, -1, 0);
|
||||
hregion = findregionbytype(RG_HEAVEN);
|
||||
assert(hregion);
|
||||
heaven = addmap();
|
||||
createmap(heaven, 1, hregion, NULL, D_NONE, NULL);
|
||||
|
|
338
objects.c
338
objects.c
|
@ -27,6 +27,7 @@ extern obmod_t *firstobmod,*lastobmod;
|
|||
extern material_t *material,*lastmaterial;
|
||||
extern recipe_t *firstrecipe,*lastrecipe;
|
||||
extern skill_t *firstskill, *lastskill;
|
||||
extern region_t *firstregion;
|
||||
|
||||
extern buildingusage_t buildingusage[];
|
||||
extern int nbuildingusage;
|
||||
|
@ -453,6 +454,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
brand_t *br;
|
||||
obmod_t *om;
|
||||
obmod_t *wantom[MAXOBMODS];
|
||||
regionthing_t *wantregionthing = NULL;
|
||||
int bonus = 0;
|
||||
int nom = 0;
|
||||
int n;
|
||||
|
@ -766,6 +768,22 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
|
||||
corpserace = findracebyname(racename);
|
||||
ot = findot(OT_CORPSE);
|
||||
} else if (strstr(p, "map to ")) {
|
||||
regiontype_t *rt;
|
||||
char regionname[BUFLEN];
|
||||
p2 = strstr(p, "map to ");
|
||||
p2 += strlen("map to");
|
||||
p2++; // go past the space
|
||||
// grab name of region this map leads to
|
||||
strcpy(regionname, p2);
|
||||
// find the regiontype which matches this.
|
||||
// if not found, it'll be randoml selected later.
|
||||
rt = findregiontypebyname(regionname);
|
||||
if (rt) {
|
||||
// find the regionthing ID of the RT_REGIONLINK entrance
|
||||
wantregionthing = findregionlink(rt->id);
|
||||
}
|
||||
ot = findot(OT_MAP);
|
||||
} else if (strstr(p, "statue of ")) {
|
||||
char racename[BUFLEN];
|
||||
|
||||
|
@ -931,6 +949,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
}
|
||||
}
|
||||
|
||||
// don't put floor gratings on low floors
|
||||
if (ot->id == OT_GRATINGFLOOR) {
|
||||
if (where->where && (where->where->type->id == CT_LOWFLOOR)) {
|
||||
setcelltype(where->where, where->where->map->habitat->emptycelltype);
|
||||
}
|
||||
}
|
||||
|
||||
if (gamemode != GM_LOADING) {
|
||||
if (hasflag(ot->flags, F_ONEPERCELL)) {
|
||||
if (hasob(where, ot->id)) {
|
||||
|
@ -1429,6 +1454,49 @@ 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_MAP) {
|
||||
region_t *srcregion;
|
||||
regiontype_t *dstrt = NULL;
|
||||
int srcdepth;
|
||||
char buf[BUFLEN];
|
||||
// fill in map destination.
|
||||
if (!wantregionthing) {
|
||||
region_t *r;
|
||||
regionthing_t *rthing,*poss[MAXCANDIDATES];
|
||||
int nposs = 0,i;
|
||||
|
||||
for (r = firstregion ; r ; r = r->next) {
|
||||
if (!r->outline) continue;
|
||||
for (i = 0; i < r->outline->nthings; i++ ){
|
||||
// pick a random regionlink thing.
|
||||
rthing = &r->outline->thing[i];
|
||||
if (rthing->whatkind == RT_REGIONLINK) {
|
||||
regiontype_t *rtype;
|
||||
rtype = findregiontype(rthing->value);
|
||||
if ( (rtype->id != RG_MAINDUNGEON) &&
|
||||
(rtype->id != RG_WORLDMAP)) {
|
||||
poss[nposs++] = rthing;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nposs) {
|
||||
wantregionthing = poss[rnd(0,nposs-1)];
|
||||
}
|
||||
}
|
||||
assert(wantregionthing);
|
||||
// we now have the destination regionlink thing which the
|
||||
// map will lead to.
|
||||
|
||||
// just using this to fill in srcregion
|
||||
findregionthing(wantregionthing->id, &srcregion);
|
||||
srcdepth = wantregionthing->depth;
|
||||
dstrt = findregiontype(wantregionthing->value);
|
||||
|
||||
strcpy(buf, dstrt->name);
|
||||
makelowercase(buf);
|
||||
|
||||
addflag(o->flags, F_MAPTO, srcregion->id, srcdepth, wantregionthing->id, buf);
|
||||
} else if (o->type->id == OT_STATUE) {
|
||||
flag_t *f, *rf;
|
||||
float ratio;
|
||||
|
@ -2724,6 +2792,24 @@ int countobsoftype(obpile_t *op, enum OBTYPE oid) {
|
|||
return count;
|
||||
}
|
||||
|
||||
int countobswithflag(obpile_t *op, enum FLAG flagid) {
|
||||
object_t *o;
|
||||
int count = 0;
|
||||
for (o = op->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, flagid)) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int countobswithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text) {
|
||||
object_t *o;
|
||||
int count = 0;
|
||||
for (o = op->first ; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, flagid, val0, val1, val2, text)) count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int countnoncosmeticobs(obpile_t *op, int onlyifknown) {
|
||||
object_t *o;
|
||||
|
||||
|
@ -4597,7 +4683,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
} // end if sight/smell
|
||||
} else if ((o->type->id == OT_SIGN) && !hasflag(o->flags, F_SIGNTEXT)) {
|
||||
strcpy(basename, "blank sign");
|
||||
} else if (o->type->id == OT_MAP) {
|
||||
} else if ((o->type->id == OT_MAP) && isknown(o)) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_MAPTO);
|
||||
if (f && getskill(player, SK_CARTOGRAPHY)) {
|
||||
|
@ -5008,7 +5094,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
} else {
|
||||
char buf2[BUFLEN];
|
||||
strcat(localbuf, " to ");
|
||||
getregionname(buf2, newmap, B_FALSE);
|
||||
getregionname(buf2, newmap, NULL, B_FALSE);
|
||||
strcat(localbuf, buf2);
|
||||
}
|
||||
}
|
||||
|
@ -10056,162 +10142,146 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
} else if (o->type->id == OT_MAP) {
|
||||
if (isplayer(lf)) {
|
||||
if (!getskill(lf, SK_CARTOGRAPHY)) {
|
||||
msg("You can't comprehend this map.");
|
||||
} else if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
int lfmx,lfmy,tmx,tmy;
|
||||
int dist;
|
||||
cell_t *c;
|
||||
enum SKILLLEVEL slev;
|
||||
|
||||
region_t *srcregion = NULL;
|
||||
regionthing_t *destthing = NULL;
|
||||
regiontype_t *destregiontype = NULL;
|
||||
int srcdepth = -1, plural = B_FALSE;
|
||||
char isare[BUFLENSMALL];
|
||||
f = hasflag(o->flags, F_MAPTO);
|
||||
getmapcoords(lf->cell->map, &lfmx, &lfmy);
|
||||
tmx = f->val[0];
|
||||
tmy = f->val[1];
|
||||
|
||||
dist = abs(tmx - lfmx) + abs(tmy - lfmy);
|
||||
if (f) {
|
||||
srcregion = findregion(f->val[0]);
|
||||
srcdepth = f->val[1];
|
||||
destthing = findregionthing(f->val[2], NULL);
|
||||
destregiontype = findregiontype(destthing->value);
|
||||
plural = destregiontype->pluralname;
|
||||
if (plural) {
|
||||
strcpy(isare, "are");
|
||||
} else {
|
||||
strcpy(isare, "is");
|
||||
}
|
||||
}
|
||||
if (f && srcregion) {
|
||||
enum SKILLLEVEL slev;
|
||||
slev = getskill(lf, SK_CARTOGRAPHY);
|
||||
switch (slev) {
|
||||
default:
|
||||
if (!slev) {
|
||||
msg("You can't comprehend this map.");
|
||||
break;
|
||||
} else {
|
||||
if (lf->cell->map->region == srcregion) {
|
||||
if (lf->cell->map->depth == srcdepth) {
|
||||
// on the correct map. at this point the f_climbable flag should
|
||||
// have been filled in correctly, and the destination region created.
|
||||
cell_t *destcell;
|
||||
object_t *destob;
|
||||
char distbuf[BUFLEN],distbufbad[BUFLEN];
|
||||
char dirbuf[BUFLEN];
|
||||
region_t *destregion = NULL;
|
||||
int dist;
|
||||
destregion = findregionbytype(destthing->value);
|
||||
|
||||
destob = findmapobwithflagval(lf->cell->map, F_CLIMBABLE, NA, destregion->id, NA, NULL);
|
||||
destcell = getoblocation(destob);
|
||||
dist = getcelldist(lf->cell, destcell);
|
||||
getdisttext(lf->cell, destcell, distbuf, distbufbad, dirbuf);
|
||||
|
||||
switch (slev) {
|
||||
default: break; // should never happen
|
||||
case PR_NOVICE:
|
||||
// here/not here
|
||||
if (dist == 0) {
|
||||
msg("%s is in this area!", f->text);
|
||||
} else {
|
||||
msg("%s isn't in this area.", f->text);
|
||||
}
|
||||
msg("%s %s in this area!", f->text, isare);
|
||||
break;
|
||||
case PR_BEGINNER:
|
||||
// near/far dist to that map
|
||||
if (dist == 0) {
|
||||
msg("%s is in this area!", f->text);
|
||||
} else if (dist == 1) {
|
||||
msg("%s is very nearby.", f->text);
|
||||
} else {
|
||||
msg("%s isn't nearby.", f->text);
|
||||
}
|
||||
// direction to cell
|
||||
msg("%s %s to the %s.", f->text, isare, dirbuf);
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
// x areas away
|
||||
if (dist == 0) {
|
||||
msg("%s is in this area!", f->text);
|
||||
} else if (dist == 1) {
|
||||
msg("%s is one area away.", f->text);
|
||||
// direction +
|
||||
// near/far dist to cell
|
||||
msg("%s %s %s to the %s.", f->text, isare, distbufbad, dirbuf);
|
||||
break;
|
||||
case PR_SKILLED:
|
||||
// direction +
|
||||
// good dist to cell
|
||||
msg("%s %s %s to the %s.", f->text, isare, distbuf, dirbuf);
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
// direction +
|
||||
// exact dist to cell
|
||||
msg("%s %s %d metres away to the %s.", f->text, isare, dist, dirbuf);
|
||||
break;
|
||||
case PR_MASTER:
|
||||
// reveal it
|
||||
msg("You have located %s in this area.", f->text);
|
||||
setcellknownradius(destcell, PR_MASTER, 5, DT_ORTH);
|
||||
needredraw = B_TRUE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
msg("%s is %d areas away.", f->text, dist);
|
||||
// correct region, wrong map
|
||||
int dist;
|
||||
char buf[BUFLEN];
|
||||
dist = abs(lf->cell->map->depth - srcdepth);
|
||||
switch (slev) {
|
||||
default: break; // should never happen
|
||||
case PR_NOVICE:
|
||||
case PR_BEGINNER:
|
||||
// here/not here
|
||||
msg("%s %s in this area.", f->text, plural ? "aren't" : "isn't");
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
// up/down
|
||||
if (lf->cell->map->depth > srcdepth) {
|
||||
msg("%s %s somewhere above you.", f->text, isare);
|
||||
} else {
|
||||
msg("%s %s somewhere below you.", f->text, isare);
|
||||
}
|
||||
break;
|
||||
case PR_SKILLED:
|
||||
// x areas away
|
||||
// plus direction.
|
||||
if (dist == 0) {
|
||||
msg("%s is in this area!", f->text);
|
||||
} else {
|
||||
char dirbuf[BUFLEN];
|
||||
// up/down and how far
|
||||
if (dist == 1) {
|
||||
snprintf(buf, BUFLEN, "%s is one area away to the ", f->text);
|
||||
strcpy(buf, "just");
|
||||
} else if (dist <= 3) {
|
||||
strcpy(buf, "somewhere");
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s is %d areas away to the ", f->text, dist);
|
||||
}
|
||||
strcpy(dirbuf, "");
|
||||
if (tmy < lfmy) {
|
||||
strcpy(dirbuf, "north");
|
||||
} else if (tmy > lfmy) {
|
||||
strcpy(dirbuf, "south");
|
||||
}
|
||||
if (tmx > lfmx) {
|
||||
strcat(dirbuf, "east");
|
||||
} else if (tmx < lfmx) {
|
||||
strcat(dirbuf, "west");
|
||||
}
|
||||
strcat(buf, dirbuf);
|
||||
strcat(buf, ".");
|
||||
msg("%s", buf);
|
||||
strcpy(buf, "very far");
|
||||
}
|
||||
msg("%s %s %s %s you.", f->text, isare, buf,
|
||||
(lf->cell->map->depth > srcdepth) ? "above" : "below");
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
// x areas away
|
||||
// plus direction.
|
||||
// plus distance within area.
|
||||
if (dist == 0) {
|
||||
int dist2;
|
||||
char distbuf[BUFLEN];
|
||||
c = findobinmap(lf->cell->map, f->val[2]);
|
||||
dist2 = getcelldist(lf->cell, c);
|
||||
if (dist2 >= 20) {
|
||||
strcpy(distbuf, "(very far away)");
|
||||
} else if (dist2 >= 10) {
|
||||
strcpy(distbuf, "(far away)");
|
||||
} else if (dist2 >= 5) {
|
||||
strcpy(distbuf, "(nearby)");
|
||||
} else {
|
||||
strcpy(distbuf, "(very nearby)");
|
||||
}
|
||||
msg("%s is in this area %s!", f->text, distbuf);
|
||||
} else {
|
||||
char dirbuf[BUFLEN];
|
||||
if (dist == 1) {
|
||||
snprintf(buf, BUFLEN, "%s is one area away to the ", f->text);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s is %d areas away to the ", f->text, dist);
|
||||
}
|
||||
strcpy(dirbuf, "");
|
||||
if (tmy < lfmy) {
|
||||
strcpy(dirbuf, "north");
|
||||
} else if (tmy > lfmy) {
|
||||
strcpy(dirbuf, "south");
|
||||
}
|
||||
if (tmx > lfmx) {
|
||||
strcat(dirbuf, "east");
|
||||
} else if (tmx < lfmx) {
|
||||
strcat(dirbuf, "west");
|
||||
}
|
||||
strcat(buf, dirbuf);
|
||||
strcat(buf, ".");
|
||||
msg("%s", buf);
|
||||
}
|
||||
break;
|
||||
case PR_MASTER:
|
||||
// x,y coords.
|
||||
// plus direction.
|
||||
// plus show on map if in area.
|
||||
if (dist == 0) {
|
||||
msg("You have located %s in this area.", f->text);
|
||||
c = findobinmap(lf->cell->map, f->val[2]);
|
||||
setcellknownradius(c, slev, 5, DT_ORTH);
|
||||
} else {
|
||||
char dirbuf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
snprintf(buf, BUFLEN, "%s is at %d,%d",f->text, tmx,tmy);
|
||||
if (dist == 1) {
|
||||
snprintf(buf2, BUFLEN, " (one area away to the ");
|
||||
} else {
|
||||
snprintf(buf2, BUFLEN, " (%d areas away to the ", dist);
|
||||
}
|
||||
strcpy(dirbuf, "");
|
||||
if (tmy < lfmy) {
|
||||
strcpy(dirbuf, "north");
|
||||
} else if (tmy > lfmy) {
|
||||
strcpy(dirbuf, "south");
|
||||
}
|
||||
if (tmx > lfmx) {
|
||||
strcat(dirbuf, "east");
|
||||
} else if (tmx < lfmx) {
|
||||
strcat(dirbuf, "west");
|
||||
}
|
||||
strcat(buf2, dirbuf);
|
||||
strcat(buf2, ")");
|
||||
|
||||
msg("%s%s", buf, buf2);
|
||||
}
|
||||
// level number
|
||||
msg("%s %s on level %d.", f->text, isare, srcdepth);
|
||||
break;
|
||||
}
|
||||
} // end correct map or not?
|
||||
} else {
|
||||
msg("You need to be outside to get your bearings first.");
|
||||
// wrong region and wrong map
|
||||
switch (slev) {
|
||||
default: break; // should never happen
|
||||
case PR_NOVICE:
|
||||
case PR_BEGINNER:
|
||||
// here/not here
|
||||
msg("%s %s in this area.", f->text, plural ? "aren't" : "isn't");
|
||||
break;
|
||||
case PR_ADEPT:
|
||||
case PR_SKILLED:
|
||||
// tell which area it is in (without level)
|
||||
getregionname(buf, NULL, srcregion, B_FALSE);
|
||||
msg("%s %s somewhere within %s.", f->text, isare, buf);
|
||||
break;
|
||||
case PR_EXPERT:
|
||||
case PR_MASTER:
|
||||
// which area it is in, plus which floor
|
||||
getregionname(buf, NULL, srcregion, B_TRUE);
|
||||
msg("%s %s in %s.", f->text, isare, buf);
|
||||
break;
|
||||
}
|
||||
} // end if correct region etc
|
||||
} // if slev
|
||||
} else {
|
||||
msg("This map doesn't seem to be finished.");
|
||||
}
|
||||
} //end if isplayer
|
||||
} else if (o->type->id == OT_SCR_AWARENESS) {
|
||||
addtempflag(lf->flags, F_AWARENESS, B_TRUE, NA, NA, NULL, getspellduration(30,60,o->blessed));
|
||||
if (isplayer(lf)) msg("The scroll crumbles to dust.");
|
||||
|
|
|
@ -42,6 +42,8 @@ int countmoney(obpile_t *op);
|
|||
int countnames(char **list);
|
||||
int countobs(obpile_t *op, int onlyifknown);
|
||||
int countobsoftype(obpile_t *op, enum OBTYPE oid);
|
||||
int countobswithflag(obpile_t *op, enum FLAG flagid);
|
||||
int countobswithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
||||
int countnoncosmeticobs(obpile_t *op, int onlyifknown);
|
||||
int curseob(object_t *o);
|
||||
void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype);
|
||||
|
|
8
save.c
8
save.c
|
@ -637,16 +637,18 @@ int loadregions(void) {
|
|||
fscanf(f, "numoutlines:%d\n",&numoutlines);
|
||||
if (db) dblog("Found %d region outlines.\n",numoutlines);
|
||||
for (n = 0; n < numoutlines; n++) {
|
||||
regionthing_t *thing;
|
||||
fscanf(f, "startro\n");
|
||||
fscanf(f, "rtypeid:%d\n",&rtid); // region type id
|
||||
addregionoutline(rtid);
|
||||
|
||||
fscanf(f, "nthings:%d\n",&nthings);
|
||||
for (i = 0; i < nthings; i++) {
|
||||
int depth,x,y,val;
|
||||
int depth,x,y,val,id;
|
||||
enum REGIONTHING whatkind;
|
||||
char buf[BUFLEN],*p;
|
||||
fscanf(f, "startthing\n");
|
||||
fscanf(f, " thingid:%d\n",&id);
|
||||
fscanf(f, " thingdepth:%d,%d,%d\n",&depth, &x, &y);
|
||||
fscanf(f, " thingkind:%d\n",(int *)&whatkind);
|
||||
fscanf(f, " thingval:%d\n",&val);
|
||||
|
@ -657,7 +659,8 @@ int loadregions(void) {
|
|||
for (p = buf ; *p; p++) {
|
||||
if (*p == '^') *p = ' ';
|
||||
}
|
||||
addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf);
|
||||
thing = addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf);
|
||||
thing->id = id;
|
||||
}
|
||||
fscanf(f, "endro\n");
|
||||
if (db) dblog("Loaded regionoutline #%d / %d",n+1, numoutlines);
|
||||
|
@ -1028,6 +1031,7 @@ int saveregions(void) {
|
|||
fprintf(f, "nthings:%d\n",ro->nthings);
|
||||
for (i = 0; i < ro->nthings; i++) {
|
||||
fprintf(f, "startthing\n");
|
||||
fprintf(f, " thingid:%d\n",(int)ro->thing[i].id);
|
||||
fprintf(f, " thingdepth:%d,%d,%d\n",ro->thing[i].depth, ro->thing[i].x, ro->thing[i].y);
|
||||
fprintf(f, " thingkind:%d\n",(int)ro->thing[i].whatkind);
|
||||
fprintf(f, " thingval:%d\n",(int)ro->thing[i].value);
|
||||
|
|
33
spell.c
33
spell.c
|
@ -5537,7 +5537,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(target, targetname);
|
||||
msg("Unseen forces rip into %s%s flesh!", targetname, getpossessive(targetname));
|
||||
}
|
||||
criticalhit(caster, target, getrandomcorebp(target), rnd(1,6), DT_SLASH);
|
||||
criticalhit(caster, target, getrandomcorebp(target, NULL), rnd(1,6), DT_SLASH);
|
||||
pleasegodmaybe(R_GODDEATH, 3);
|
||||
} else if (spellid == OT_S_GLYPHWARDING) {
|
||||
char buf[BUFLEN];
|
||||
|
@ -7829,7 +7829,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char ch = 'a';
|
||||
char mapname[BUFLEN];
|
||||
|
||||
getregionname(mapname, m, B_TRUE);
|
||||
getregionname(mapname, m, NULL, B_TRUE);
|
||||
capitalise(mapname);
|
||||
|
||||
if (m->habitat->id == H_HEAVEN) continue;
|
||||
|
@ -9038,20 +9038,28 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (corpse) {
|
||||
char buf[BUFLEN],corpsename[BUFLEN];
|
||||
char ch;
|
||||
int done = B_FALSE;
|
||||
getobname(corpse, corpsename, 1);
|
||||
msg("An ghostly spirit rises from %s!", corpsename); more();
|
||||
while (!done) {
|
||||
snprintf(buf, BUFLEN, "What will you ask %s?", corpsename);
|
||||
initprompt(&prompt, buf);
|
||||
addchoice(&prompt, 'a', "How did you die?", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'b', "Tell me about this area", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'c', "Are there any hidden dangers nearby?", NULL, NULL, NULL);
|
||||
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
|
||||
prompt.maycancel = B_TRUE;
|
||||
|
||||
|
||||
ch = getchoice(&prompt);
|
||||
if ((ch != '\0') && (ch != '-')) {
|
||||
snprintf(buf, BUFLEN, "%s whispers:", corpsename);
|
||||
msg(buf);
|
||||
}
|
||||
if (ch == 'a') {
|
||||
flag_t *f;
|
||||
char *p;
|
||||
|
||||
snprintf(buf, BUFLEN, "%s whispers:", corpsename);
|
||||
msg(buf);
|
||||
|
||||
f = hasflag(corpse->flags, F_CORPSEOF);
|
||||
if (f && strlen(f->text)) {
|
||||
char killer[BUFLEN];
|
||||
|
@ -9072,7 +9080,22 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
msg("\"I do not know what killed me.\"");
|
||||
}
|
||||
} else if (ch == 'b') {
|
||||
genareaknowledge(corpse->flags, 50);
|
||||
docomms_areainfo(corpsename, corpse->flags, NULL);
|
||||
done = B_TRUE;
|
||||
} else if (ch == 'c') {
|
||||
genareaknowledge(corpse->flags, 50);
|
||||
docomms_areadangers(corpsename, corpse->flags, NULL);
|
||||
done = B_TRUE;
|
||||
} else {
|
||||
done = B_TRUE;
|
||||
}
|
||||
} // end while !done
|
||||
|
||||
// destroy the corpse.
|
||||
msg("%s crumbles to dust.", corpsename);
|
||||
removeob(corpse, ALL);
|
||||
}
|
||||
} else if (spellid == OT_S_STENCH) {
|
||||
int howlong;
|
||||
|
|
21
text.c
21
text.c
|
@ -925,12 +925,15 @@ char *getrarityname(enum RARITY rr) {
|
|||
return "?unknownrarity?";
|
||||
}
|
||||
|
||||
char *getregionname(char *buf, map_t *m, int withlevel) {
|
||||
region_t *r;
|
||||
|
||||
// pass in EITHER m or r, not both.
|
||||
//
|
||||
// if withlevel is TRUE, "m" should be passed.
|
||||
char *getregionname(char *buf, map_t *m, region_t *r, int withlevel) {
|
||||
if (!r) {
|
||||
r = m->region;
|
||||
}
|
||||
|
||||
if (withlevel) {
|
||||
if (withlevel && m) {
|
||||
flag_t *f;
|
||||
int x,y;
|
||||
f = hasflag(m->flags, F_MAPCOORDS);
|
||||
|
@ -1187,6 +1190,16 @@ char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra)
|
|||
return retbuf;
|
||||
}
|
||||
|
||||
char *makelowercase(char *text) {
|
||||
if (strlen(text) > 0) {
|
||||
char *p;
|
||||
for (p = text ; *p; p++) {
|
||||
*p = tolower(*p);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// allocates and returns new string
|
||||
char *makeplural(char *text) {
|
||||
char lastlet;
|
||||
|
|
3
text.h
3
text.h
|
@ -27,7 +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 *getregionname(char *buf, map_t *m, region_t *r, int withlevel);
|
||||
char *getreldirname(int reldir);
|
||||
char *getsizetext(enum LFSIZE sz);
|
||||
char *gettimetext(char *retbuf);
|
||||
|
@ -38,6 +38,7 @@ char *is(lifeform_t *lf);
|
|||
int isvowel(char c);
|
||||
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf);
|
||||
char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra);
|
||||
char *makelowercase(char *text);
|
||||
char *makeplural(char *text);
|
||||
char *makethrowaccstring(lifeform_t *lf, cell_t *c, flag_t *throwflag, char *retbuf);
|
||||
char *makeuppercase(char *text);
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
@map
|
||||
############
|
||||
#....c...|,#
|
||||
#....-/-.###
|
||||
+......@.|,#
|
||||
#..-/-...###
|
||||
#....c...|,#
|
||||
#>+..c...|,#
|
||||
###..-/-.###
|
||||
X......@>|,#
|
||||
###-/-...###
|
||||
#>+..c...|,#
|
||||
############
|
||||
@end
|
||||
|
||||
|
@ -16,8 +16,10 @@
|
|||
|:ob:locked iron gate
|
||||
,:ob:1-4 bones:50
|
||||
,:mon:prisoner:50
|
||||
X:ob:wooden door
|
||||
X:exit
|
||||
>:ob:staircase going down
|
||||
+:ob:wooden door
|
||||
+:exit
|
||||
/:ob:wooden table
|
||||
-:ob:wooden footstool
|
||||
c:ob:lit candelabrum
|
||||
|
|
Loading…
Reference in New Issue