- [+] fix bug in randomtalk

- [+] fix bug with beggars
- [+] prompt before giving money in C-d
- [+] bug: allies walking into walls
- [+] make your own race / job more likely to kjoin for less gold
- [+] new rarity level: rr_frequent ?
    - [+] add it
    - [+] in swamp, aquatic things are freqentut
- [+] swamp level:
    - [+] createdungeon (but use different h_habitat. how do i do this?)
    - [+] then remove all doors
    - [+] then change all walls into deep water
    - [+] add rarity for monsterss
    - [+] add rarity for objects
- [+] add f_nolink for vaults which aren't linked to rest of map
- [+] fishbowl vault
- [+] change misisle dam calculation - add firespeed rather than
      multiply.
- [+] forced shops at certain level intervals
    - [+] implmement RT_OBJECT text=objectname
    - [+] add buildings at levles 2-4 5- 7 8 - 10 11-13 14-16 17-19
          20-22 23 -25
- [+] split sp_ally_attack into attack and attack_unseen
- [+] base throwspeed on throwin gskill, not strength
- [+] make it much harder to catch thrown missiles
- [+] try to place RT_OBJECTs in rooms
- [+] maybe get rid of sound lowering for 's'lowwalk. this should be
      based on stealth!

- [+] don't let you walk down stairs if there's an impassable object in
      the way.
This commit is contained in:
Rob Pearce 2011-11-17 00:50:33 +00:00
parent 10e4713940
commit 25ca8f3e43
21 changed files with 545 additions and 364 deletions

18
ai.c
View File

@ -97,7 +97,11 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
} else { } else {
strcpy(text, "something"); strcpy(text, "something");
} }
sayphrase(lf, SP_ALLY_ATTACK, SV_SHOUT, NA, text); if (cansee(player, victim)) {
sayphrase(lf, SP_ALLY_ATTACK, SV_SHOUT, NA, text);
} else {
sayphrase(lf, SP_ALLY_ATTACKUNSEEN, SV_SHOUT, NA, text);
}
} else { } else {
makenoise(lf, N_GETANGRY); makenoise(lf, N_GETANGRY);
} }
@ -234,6 +238,11 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
int besttime = -1; int besttime = -1;
int i; int i;
// defaults
if (lastx) *lastx = NA;
if (lasty) *lasty = NA;
if (lastdir) *lastdir = D_NONE;
// check scent/footprints first // check scent/footprints first
for (i = 0; i < lf->nlos; i++) { for (i = 0; i < lf->nlos; i++) {
if (hastrailof(lf->los[i]->obpile, target, NA, &tflag, lf)) { if (hastrailof(lf->los[i]->obpile, target, NA, &tflag, lf)) {
@ -277,9 +286,6 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
return c; return c;
} }
if (lastx) *lastx = NA;
if (lasty) *lasty = NA;
if (lastdir) *lastdir = D_NONE;
return NULL; return NULL;
} }
@ -846,7 +852,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
// move towards their last known location instead // move towards their last known location instead
cell_t *targcell; cell_t *targcell;
int lastx,lasty; int lastx,lasty;
int lastdir; int lastdir = D_NONE;
targcell = aigetlastknownpos(lf, target, &lastx, &lasty, &lastdir); targcell = aigetlastknownpos(lf, target, &lastx, &lasty, &lastdir);
@ -1165,7 +1171,7 @@ void aiturn(lifeform_t *lf) {
int vol; int vol;
f = poss[rnd(0,nposs-1)]; f = poss[rnd(0,nposs-1)];
vol = rnd(f->val[1], f->val[2]); vol = rnd(f->val[1], f->val[2]);
if (f->text) { if (strlen(f->text)) {
say(lf, f->text, vol); say(lf, f->text, vol);
} else { } else {
sayphrase(lf, f->val[0], vol, NA, NULL); sayphrase(lf, f->val[0], vol, NA, NULL);

View File

@ -747,6 +747,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
dam[0] = (int) ( (float)dam[0] * 1.25 ); dam[0] = (int) ( (float)dam[0] * 1.25 );
} }
// modify for weapon skill, strength etc
applylfdammod(&dam[0], lf, wep); applylfdammod(&dam[0], lf, wep);
// modify for size // modify for size

406
data.c

File diff suppressed because it is too large Load Diff

Binary file not shown.

18
defs.h
View File

@ -415,6 +415,7 @@ enum QUADRANT {
enum SAYPHRASE { enum SAYPHRASE {
SP_ALLY_ATTACK, SP_ALLY_ATTACK,
SP_ALLY_ATTACKUNSEEN,
SP_ALLY_INPAIN, SP_ALLY_INPAIN,
SP_ALLY_TARGETKILL, SP_ALLY_TARGETKILL,
SP_BEG, SP_BEG,
@ -759,12 +760,13 @@ enum BLESSTYPE {
#define RARITYVARIANCEOB (10) #define RARITYVARIANCEOB (10)
enum RARITY { enum RARITY {
RR_UNIQUE = 6, RR_UNIQUE = 7,
RR_NEVER = 5, RR_NEVER = 6,
RR_VERYRARE = 4, RR_VERYRARE = 5,
RR_RARE = 3, RR_RARE = 4,
RR_UNCOMMON = 2, RR_UNCOMMON = 3,
RR_COMMON = 1, RR_COMMON = 2,
RR_FREQUENT = 1,
RR_NONE = 0, RR_NONE = 0,
}; };
@ -2757,6 +2759,8 @@ enum FLAG {
// if maxcount is PCT, mincount is a percentage // if maxcount is PCT, mincount is a percentage
// of the total space. // of the total space.
F_VAULTMAYROTATE, // may rotate this vault in 90degree increments. F_VAULTMAYROTATE, // may rotate this vault in 90degree increments.
F_VAULTNOLINK, // this vault doesn't have to be connected to the
// rest of the map.
F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is
// v0/1 can be NA. // v0/1 can be NA.
// just a normal random room // just a normal random room
@ -3003,6 +3007,7 @@ enum HABITAT {
H_HEAVEN = 3, H_HEAVEN = 3,
H_PIT = 4, H_PIT = 4,
H_VILLAGE = 5, H_VILLAGE = 5,
H_SWAMP = 6,
H_ALL = 999 H_ALL = 999
}; };
@ -3019,6 +3024,7 @@ typedef struct regiontype_s {
enum REGIONTHING { enum REGIONTHING {
RT_HABITAT, // val is habitat RT_HABITAT, // val is habitat
RT_OBJECT, // what is object name
RT_REGIONLINK, // val is enum regiontype to link to. RT_REGIONLINK, // val is enum regiontype to link to.
// what is stair object type // what is stair object type
RT_VAULT, // what is vaultname RT_VAULT, // what is vaultname

View File

@ -69,6 +69,9 @@ Flags can be:
mayrotate // vault can be rotated randomly mayrotate // vault can be rotated randomly
nolink // don't try to link this vault up to the rest of
// the map
rarity:xxx // how common this vault is. rarity:xxx // how common this vault is.
// xxx can be: // xxx can be:
// common (default) // common (default)

21
io.c
View File

@ -1398,9 +1398,11 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_INJURY: case F_INJURY:
p = readuntil(buf, f->text, '^'); if (isplayer(lf) || !lfhasflag(lf, F_FEIGNINGDEATH)) {
msg("^%c%s%s %s!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname), buf); p = readuntil(buf, f->text, '^');
donesomething = B_TRUE; msg("^%c%s%s %s!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname), buf);
donesomething = B_TRUE;
}
break; break;
case F_INVISIBLE: case F_INVISIBLE:
if (isplayer(lf)) { if (isplayer(lf)) {
@ -3621,6 +3623,17 @@ void docomms(lifeform_t *lf) {
o = askobject(player->pack, buf, &count, AO_NONE); o = askobject(player->pack, buf, &count, AO_NONE);
if (o) { if (o) {
if (o->type->id == OT_GOLD) { if (o->type->id == OT_GOLD) {
char countbuf[BUFLEN];
// ask how much!
snprintf(buf, BUFLEN, "How much money will you give to %s (0-%d)",
lfname, countmoney(player->pack));
askstring(buf, '?', countbuf, BUFLEN, NULL);
count = atoi(buf);
if (!count) {
msg("Cancelled.");
return;
}
getobname(o, buf, count); getobname(o, buf, count);
givemoney(player, lf, count); givemoney(player, lf, count);
msg("You give %s to %s.", buf, lfname); msg("You give %s to %s.", buf, lfname);
@ -3637,7 +3650,7 @@ void docomms(lifeform_t *lf) {
if (givenob) { if (givenob) {
if ((lf->race->id == R_BEGGAR) && (givenob->type->id == OT_GOLD)) { if ((lf->race->id == R_BEGGAR) && (givenob->type->id == OT_GOLD)) {
// begger effects // begger effects
if (countmoney(lf->pack) == 1) { if (!countmoney(lf->pack)) {
i = rnd(1,100); i = rnd(1,100);
if (i <= 5) { // attack you if (i <= 5) { // attack you
sayphrase(lf, SP_BEGATTACK, SV_SHOUT, NA, NULL); sayphrase(lf, SP_BEGATTACK, SV_SHOUT, NA, NULL);

134
lf.c
View File

@ -2956,7 +2956,7 @@ int eat(lifeform_t *lf, object_t *o) {
} }
} }
// limit // limit
if (nutrition > (HUNGERCONST/4)) nutrition = (HUNGERCONST/4); if (nutrition > (HUNGERCONST/3)) nutrition = (HUNGERCONST/3);
rawmeat = B_TRUE; rawmeat = B_TRUE;
} }
} }
@ -3203,7 +3203,7 @@ int eat(lifeform_t *lf, object_t *o) {
// end of turn effects // end of turn effects
void endlfturn(lifeform_t *lf) { void endlfturn(lifeform_t *lf) {
// lf will complain if in pain // lf will complain if in pain
if (isbleeding(lf) && onein(3)) { if (isbleeding(lf) && onein(3) && !hasflag(lf->flags, F_ASLEEP)) {
// TODO: replace 4 // TODO: replace 4
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
if (!canhear(player, lf->cell, 4)) { if (!canhear(player, lf->cell, 4)) {
@ -5987,10 +5987,6 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
if (nid == N_WALK) { if (nid == N_WALK) {
*volume += getarmournoise(lf); *volume += getarmournoise(lf);
} }
if (lfhasflag(lf, F_SNEAK)) {
*volume -= 2;
limit(volume, 1, NA);
}
return B_FALSE; return B_FALSE;
} else { } else {
// some defaults // some defaults
@ -6036,7 +6032,7 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
if (volume) *volume += getarmournoise(lf); if (volume) *volume += getarmournoise(lf);
if (heartext) strcpy(heartext, movetext); if (heartext) strcpy(heartext, movetext);
if (lfhasflag(lf, F_SNEAK)) { if (lfhasflag(lf, F_SNEAK)) {
*volume -= 2; (*volume)--;
limit(volume, 1, NA); limit(volume, 1, NA);
} }
return B_FALSE; return B_FALSE;
@ -6840,16 +6836,18 @@ int getracerarity(map_t *map, enum RACE rid) {
int rarity = -1; int rarity = -1;
r = findrace(rid); r = findrace(rid);
if (r) { if (r) {
flag_t *f; flag_t *f = NULL;
f = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL); if (map) {
if (!f) { f = hasflagval(r->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
if (map) {
f = hasflagval(r->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
} else {
f = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
}
} }
if (!f) {
f = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
}
/*if (!f) {
f = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
}*/
if (f) { if (f) {
// ignore habitat for now! // ignore habitat for now!
@ -6929,10 +6927,11 @@ enum BODYPART getrandomcorebp(lifeform_t *lf) {
} }
race_t *getrandomcorpserace(cell_t *c) { race_t *getrandomcorpserace(cell_t *c) {
race_t *r; race_t *r = NULL;
r = getrandomrace(c, NA);
while (hasflag(r->flags, F_NOCORPSE)) { while (!r || (hasflag(r->flags, F_NOCORPSE))) {
r = getrandomrace(c, NA); if (c) r = getrandomrace(c, NA);
else r = getreallyrandomrace(RC_ANY);
} }
return r; return r;
} }
@ -6987,7 +6986,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
int db = B_FALSE; int db = B_FALSE;
int depth; int depth;
int hdmin,hdmax; int hdmin,hdmax;
enum RARITY wantrr = RR_COMMON; enum RARITY wantrr = RR_FREQUENT;
// determine rarity of lf to generate // determine rarity of lf to generate
if (forcedepth != NA) { if (forcedepth != NA) {
@ -7018,14 +7017,15 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
valid = B_FALSE; valid = B_FALSE;
} else { } else {
// correct rarity? // correct rarity?
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL); if (c) {
if (!rarflag) { rarflag = hasflagval(r->flags, F_RARITY, c->habitat->id, NA, NA, NULL);
if (c) {
rarflag = hasflagval(r->flags, F_RARITY, c->habitat->id, NA, NA, NULL);
} else {
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
}
} }
if (!rarflag) {
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
}
/*if (!rarflag) {
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
}*/
if (rarflag) { if (rarflag) {
if ((rarflag->val[2] == NA) || (rarflag->val[2] <= wantrr)) { if ((rarflag->val[2] == NA) || (rarflag->val[2] <= wantrr)) {
@ -7488,34 +7488,24 @@ char *getskilllevelname(enum SKILLLEVEL sl) {
// ie. 4 = 64km/h // ie. 4 = 64km/h
// ie. 5 = 125km/h // ie. 5 = 125km/h
// ie. 10 = 1000km/h // ie. 10 = 1000km/h
int getthrowspeed(int str) { int getthrowspeed(lifeform_t *lf) {
enum ATTRBRACKET sb; enum ATTRBRACKET sb;
int speed = 0; int speed = 0;
sb = getattrbracket(str, A_STR, NULL);
// ie. 1 - 4
speed = (getskill(lf, SK_THROWING) / 3) + 1;
sb = getattrbracket(getattr(lf, A_STR), A_STR, NULL);
switch (sb) { switch (sb) {
case AT_EXLOW: default:
case AT_VLOW:
speed = 1;
break;
case AT_LOW:
case AT_LTAVERAGE:
speed = 2;
break;
case AT_AVERAGE:
speed = 3;
break;
case AT_GTAVERAGE:
case AT_HIGH:
speed = 4;
break; break;
case AT_VHIGH: case AT_VHIGH:
speed = 5; speed++;
break; break;
default:
case AT_EXHIGH: case AT_EXHIGH:
speed = 6; speed += 2;
break; break;
// gun is 10 // gun is 15
} }
return speed; return speed;
} }
@ -10498,9 +10488,9 @@ void applylfdammod(int *dam, lifeform_t *lf, object_t *wep) {
// extra damage for being skilled? // extra damage for being skilled?
slev = getweaponskill(lf, wep); slev = getweaponskill(lf, wep);
if (slev > 1) { if (slev >= 3) {
float pctextra; float pctextra;
pctextra = ((slev - 1) * 10); pctextra = ((slev - 2) * 10);
*dam += pctof(pctextra, *dam); *dam += pctof(pctextra, *dam);
} }
} }
@ -12620,6 +12610,12 @@ int recruit(lifeform_t *lf) {
} }
if (askingprice != 0) { 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 // modify by charisma
askingprice = pctof(100 - getstatmod(player, A_CHA), askingprice); askingprice = pctof(100 - getstatmod(player, A_CHA), askingprice);
limit(&askingprice, 0, NA); limit(&askingprice, 0, NA);
@ -13008,29 +13004,29 @@ int say(lifeform_t *lf, char *text, int volume) {
int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text) { int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text) {
int i,rv = B_FALSE; int i,rv = B_FALSE;
char buf[BUFLEN]; char buf[BUFLEN];
char *p;
switch (what) { switch (what) {
case SP_ALLY_ATTACK: case SP_ALLY_ATTACK:
if (cansee(player, lf)) { switch (rnd(1,3)) {
switch (rnd(1,3)) { case 1: snprintf(buf, BUFLEN, "I'm attacking %s!", text); break;
case 1: snprintf(buf, BUFLEN, "I'm attacking %s!", text); break; case 2: snprintf(buf, BUFLEN, "%s is mine!", text);
case 2: snprintf(buf, BUFLEN, "%s is mine!", text); buf[0] = toupper(buf[0]);
buf[0] = toupper(buf[0]); break;
break; case 3: snprintf(buf, BUFLEN, "I'll take care of %s!", text); break;
case 3: snprintf(buf, BUFLEN, "I'll take care of %s!", text); break;
}
} else {
char *p;
p = strdup(text);
strrep(p, "the ","a ", NULL);
switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "There's %s over here!", p); break;
case 2: snprintf(buf, BUFLEN, "I'm attacking %s!", p); break;
case 3: snprintf(buf, BUFLEN, "Beware %s!", p); break;
}
free(p);
} }
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
case SP_ALLY_ATTACKUNSEEN:
p = strdup(text);
strrep(p, "the ","a ", NULL);
switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "There's %s over here!", p); break;
case 2: snprintf(buf, BUFLEN, "I'm attacking %s!", p); break;
case 3: snprintf(buf, BUFLEN, "Beware %s!", p); break;
}
free(p);
rv = say(lf, buf, volume);
break;
case SP_ALLY_INPAIN: case SP_ALLY_INPAIN:
switch (rnd(1,3)) { switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "I'm hurting here!"); break; case 1: snprintf(buf, BUFLEN, "I'm hurting here!"); break;
@ -15415,7 +15411,7 @@ int throwat(lifeform_t *thrower, object_t *o, cell_t *where) {
return B_TRUE; return B_TRUE;
} }
taketime(thrower, getactspeed(thrower)); taketime(thrower, getactspeed(thrower));
return fireat(thrower, o, 1, where, getthrowspeed(getattr(thrower, A_STR)), NULL); return fireat(thrower, o, 1, where, getthrowspeed(thrower), NULL);
} }
// lf effects which happen every xx ticks // lf effects which happen every xx ticks
@ -15991,7 +15987,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
} }
// check noone is in the way // check noone is in the way
if (movelfsoutofway(newcell)) { if (movelfsoutofway(newcell) || !cellwalkable(lf, newcell, NULL)) {
// TODO: handle this differently - ie always allow the player // TODO: handle this differently - ie always allow the player
// go there? // go there?
if (isplayer(lf)) msg("The stairs seem to be blocked."); if (isplayer(lf)) msg("The stairs seem to be blocked.");

2
lf.h
View File

@ -227,7 +227,7 @@ float getstatmod(lifeform_t *lf, enum ATTRIB att);
char *getskilldesc(enum SKILL id ); char *getskilldesc(enum SKILL id );
char *getskillname(enum SKILL id ); char *getskillname(enum SKILL id );
char *getskilllevelname(enum SKILLLEVEL sl); char *getskilllevelname(enum SKILLLEVEL sl);
int getthrowspeed(int str); int getthrowspeed(lifeform_t *lf);
int getturnspeed(lifeform_t *lf); int getturnspeed(lifeform_t *lf);
void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking); void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking);
object_t *getweapon(lifeform_t *lf); object_t *getweapon(lifeform_t *lf);

137
map.c
View File

@ -1247,27 +1247,33 @@ int fix_reachability(map_t *m) {
// any remaining non-filled empty cells? // any remaining non-filled empty cells?
for (i = 0; i < m->w * m->h; i++) { for (i = 0; i < m->w * m->h; i++) {
if (!m->cell[i]->type->solid && !m->cell[i]->filled) { if (!m->cell[i]->type->solid && !m->cell[i]->filled) {
int nadded = 0; vault_t *v;
// found an unreachable cell! link it back to a filled cell. v = getcellvault(m->cell[i]);
if (db) dblog(" found unreachable area at %d,%d. will fix it.", if (v && hasflag(v->flags, F_VAULTNOLINK)) {
m->cell[i]->x, m->cell[i]->y); // don't need to link it.
linkexit(m->cell[i], B_TRUE, &nadded);
if (nadded) {
if (db) dblog(" fixed unreachable area by adding %d cells.", nadded);
} else { } else {
// didn't add anything - fail! int nadded = 0;
if (db) dblog(" fix_reachability failed."); // found an unreachable cell! link it back to a filled cell.
return B_TRUE; if (db) dblog(" found unreachable area at %d,%d. will fix it.",
m->cell[i]->x, m->cell[i]->y);
linkexit(m->cell[i], B_TRUE, &nadded);
if (nadded) {
if (db) dblog(" fixed unreachable area by adding %d cells.", nadded);
} else {
// didn't add anything - fail!
if (db) dblog(" fix_reachability failed.");
return B_TRUE;
}
// now run the test again.
// 'c' will be where the next flood will will happen.
keepgoing = B_TRUE;
c = m->cell[i];
nfixed++;
break;
} }
// now run the test again.
// 'c' will be where the next flood will will happen.
keepgoing = B_TRUE;
c = m->cell[i];
nfixed++;
break;
} }
} }
} }
@ -2074,7 +2080,14 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
// link up room exits // link up room exits
for (i = 0; i < map->nrooms; i++) { for (i = 0; i < map->nrooms; i++) {
int wantlink = B_FALSE;
if (!map->room[i].exitslinked) { 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); linkexits(map, map->room[i].id);
} }
} }
@ -2349,6 +2362,9 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_
case H_FOREST: case H_FOREST:
createforest(map, depth, parentmap, exitdir, entryob, rnd(0,5)); createforest(map, depth, parentmap, exitdir, entryob, rnd(0,5));
break; break;
case H_SWAMP:
createswamp(map, depth, parentmap, exitdir, entryob);
break;
case H_VILLAGE: case H_VILLAGE:
createforest(map, depth, parentmap, exitdir, entryob, 0); createforest(map, depth, parentmap, exitdir, entryob, 0);
break; break;
@ -2647,10 +2663,18 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
if (db) dblog(" adding remembered region outline things..."); if (db) dblog(" adding remembered region outline things...");
for (i = 0; i < nthings ;i++) { for (i = 0; i < nthings ;i++) {
vault_t *v; vault_t *v;
cell_t *c;
// add this thing // add this thing
switch (thing[i]->whatkind) { switch (thing[i]->whatkind) {
case RT_HABITAT: // already handled above case RT_HABITAT: // already handled above
break; break;
case RT_OBJECT:
if (db) dblog(" adding forced regionthing object: %s", thing[i]->what);
c = getrandomroomcell(map, ANYROOM);
if (!c) c = getrandomcell(map);
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL);
addob(c->obpile, thing[i]->what);
break;
case RT_REGIONLINK: case RT_REGIONLINK:
if (db) dblog(" adding regionlink"); if (db) dblog(" adding regionlink");
createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region); createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region);
@ -2915,6 +2939,33 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
if (db) dblog(" Map creation finished."); if (db) dblog(" Map creation finished.");
} }
void createswamp(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int x,y;
cell_t *c;
object_t *o, *nexto;
// first create a normal dungeon
createdungeon(map, depth, parentmap, exitdir, entryob);
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y);
// replace all walls with water
if (c->type->solid) {
setcelltype(c, CT_LOWFLOOR);
addob(c->obpile, "very deep water");
}
// remove all doors
for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (isdoor(o, NULL)) {
killob(o);
}
}
}
}
}
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety) { int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety) {
int w,h,x,y; int w,h,x,y;
int xmargin = DEF_VAULTMARGIN,ymargin = DEF_VAULTMARGIN; // defaults int xmargin = DEF_VAULTMARGIN,ymargin = DEF_VAULTMARGIN; // defaults
@ -3019,7 +3070,9 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
} }
// link up exits from this vault // link up exits from this vault
linkexits(map, roomid); if (!hasflag(v->flags, F_VAULTNOLINK)) {
linkexits(map, roomid);
}
return B_FALSE; return B_FALSE;
} }
@ -4755,12 +4808,13 @@ object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tfl
void initmap(void) { void initmap(void) {
int vx[4],vy[4],i; int vx[4],vy[4],i;
// habitats // habitats
// thingchance, obchance, vaultchance // thingchance, obchance, vaultchance, maxvisrange
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 30, 6); addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 30, 6);
addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALL, 3, 75, 0, MAXVISRANGE); 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_HEAVEN, "heaven", CT_CORRIDOR, CT_WALL, 0, 0, 0, MAXVISRANGE);
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5); addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5);
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE); addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE);
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE);
// cell types // cell types
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0); addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0);
@ -4813,10 +4867,26 @@ void initmap(void) {
addregionthing(lastregionoutline, NA, vx[i], vy[i], RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL); addregionthing(lastregionoutline, NA, vx[i], vy[i], RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL);
} }
//vx = 0; vy = -1; //vx = 0; vy = -1;
addregionoutline(RG_FIRSTDUNGEON); addregionoutline(RG_FIRSTDUNGEON);
addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL); addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL);
// l6: jimbo's lair
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair"); addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");
addregionthing(lastregionoutline, 10, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISSHRINE, NULL); // godstone on last floor // l7 - 10: swamp
addregionthing(lastregionoutline, rnd(7,10), NA, NA, RT_HABITAT, H_SWAMP, NULL);
// l25: last level
addregionthing(lastregionoutline, 25, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISSHRINE, NULL); // godstone on last floor
// 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");
addregionthing(lastregionoutline, rnd(8,10), NA, NA, RT_OBJECT, NA, "random building");
addregionthing(lastregionoutline, rnd(11,13), NA, NA, RT_OBJECT, NA, "random building");
addregionthing(lastregionoutline, rnd(14,16), NA, NA, RT_OBJECT, NA, "random building");
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");
} }
int isadjacent(cell_t *src, cell_t *dst) { int isadjacent(cell_t *src, cell_t *dst) {
@ -5755,33 +5825,46 @@ int validateregions(void) {
} }
int validateregionthing(regionthing_t *thing) { int validateregionthing(regionthing_t *thing) {
cell_t fakecell;
map_t fakemap;
int goterrors = B_FALSE;
object_t *o;
createfakes(&fakemap, &fakecell);
switch (thing->whatkind) { switch (thing->whatkind) {
case RT_HABITAT: case RT_HABITAT:
if (!findhabitat(thing->value)) { if (!findhabitat(thing->value)) {
dblog("Invalid habitat %d specified in regionthing.", thing->value); dblog("Invalid habitat %d specified in regionthing.", thing->value);
return B_TRUE; goterrors = B_TRUE;
}
break;
case RT_OBJECT:
o = addob(fakecell.obpile, thing->what);
if (!o) {
dblog("Invalid object '%s' specified in regionthing.", thing->what);
goterrors = B_TRUE;
} }
break; break;
case RT_REGIONLINK: case RT_REGIONLINK:
if (!findregiontype(thing->value)) { if (!findregiontype(thing->value)) {
dblog("Invalid regionlink to regiontype %d specified in regionthing.", thing->value); dblog("Invalid regionlink to regiontype %d specified in regionthing.", thing->value);
return B_TRUE; goterrors = B_TRUE;
} }
break; break;
case RT_VAULT: case RT_VAULT:
if (!findvault(thing->what)) { if (!findvault(thing->what)) {
dblog("Invalid rt_vault to vaulttype '%s' specified in regionthing.", thing->what); dblog("Invalid rt_vault to vaulttype '%s' specified in regionthing.", thing->what);
return B_TRUE; goterrors = B_TRUE;
} }
break; break;
case RT_RNDVAULTWITHFLAG: case RT_RNDVAULTWITHFLAG:
if (!findvaultwithflag(thing->value)) { if (!findvaultwithflag(thing->value)) {
dblog("Invalid rt_rndvaultwithflag specified in regionthing."); dblog("Invalid rt_rndvaultwithflag specified in regionthing.");
return B_TRUE; goterrors = B_TRUE;
} }
break; break;
} }
return B_FALSE; killfakes(&fakemap, &fakecell);
return goterrors;
} }
int wallstoleftright(cell_t *c, int dir) { int wallstoleftright(cell_t *c, int dir) {

1
map.h
View File

@ -57,6 +57,7 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO
void createregionthing(map_t *map, regionthing_t *rt); void createregionthing(map_t *map, regionthing_t *rt);
void createriver(map_t *m); void createriver(map_t *m);
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls); int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
void createswamp(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety); int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety);
int dirtox(int dt, int dir); int dirtox(int dt, int dir);
int dirtoy(int dt, int dir); int dirtoy(int dt, int dir);

View File

@ -171,7 +171,7 @@ int main(int argc, char **argv) {
job_t *j = NULL; job_t *j = NULL;
race_t *startrace = NULL; race_t *startrace = NULL;
char ch; char ch;
object_t *o; //object_t *o;
cell_t *where; cell_t *where;
int dir; int dir;
flag_t *f; flag_t *f;
@ -271,8 +271,10 @@ int main(int argc, char **argv) {
addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL);
addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL); addflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL);
addflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL); ///////// addflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL); /////////
o = hasob(where->obpile, OT_PLAYERSTART); /*o = hasob(where->obpile, OT_PLAYERSTART);
killob(o); killob(o);*/
killallobs(where->obpile);
addobfast(where->obpile, OT_HOLEINROOF);
user = getenv("USER"); user = getenv("USER");
if (user) { if (user) {

113
objects.c
View File

@ -642,6 +642,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
p += strlen("silver "); p += strlen("silver ");
donesomething = B_TRUE; donesomething = B_TRUE;
// rarity // rarity
} else if (strstarts(p, "frequent ")) {
wantrarity = RR_FREQUENT;
p += strlen("frequent ");
donesomething = B_TRUE;
} else if (strstarts(p, "common ")) { } else if (strstarts(p, "common ")) {
wantrarity = RR_COMMON; wantrarity = RR_COMMON;
p += strlen("common "); p += strlen("common ");
@ -1132,7 +1136,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
if (o->type->id == OT_TEMPLE) { if (o->type->id == OT_TEMPLE) {
lifeform_t *god; lifeform_t *god;
god = getrandomgod(); god = getrandomgod();
addflag(o->flags, F_LINKGOD, god->race->id, NA, NA, NULL); if (god) {
addflag(o->flags, F_LINKGOD, god->race->id, NA, NA, NULL);
}
} }
// fill in door flags // fill in door flags
@ -2797,7 +2803,7 @@ void dumpobrarity(void) {
flag_t *f; flag_t *f;
int min,max; int min,max;
for (rr = RR_COMMON; rr <= RR_VERYRARE; rr++) { for (rr = RR_FREQUENT; rr <= RR_VERYRARE; rr++) {
rrtorarity(rr, &min, &max); rrtorarity(rr, &min, &max);
dblog("Obs with rarity %s:", getrarityname(rr)); dblog("Obs with rarity %s:", getrarityname(rr));
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
@ -3432,7 +3438,7 @@ int getobvalue(object_t *o) {
float price; float price;
flag_t *f; flag_t *f;
int rarity = 0,i; int rarity = 0,i;
enum RARITY rr = RR_COMMON; enum RARITY rr = RR_FREQUENT;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0; int nretflags = 0;
@ -3563,6 +3569,9 @@ int getobvalue(object_t *o) {
case RR_COMMON: case RR_COMMON:
price *= 0.75; price *= 0.75;
break; break;
case RR_FREQUENT:
price *= 0.5;
break;
default: default:
break; break;
} }
@ -5130,7 +5139,7 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
obmod_t *om; obmod_t *om;
flag_t *omposs[MAXCANDIDATES]; flag_t *omposs[MAXCANDIDATES];
int noms = 0; int noms = 0;
enum RARITY wantrr = RR_COMMON; enum RARITY wantrr = RR_FREQUENT;
habitat_t *hab; habitat_t *hab;
char habname[BUFLEN]; char habname[BUFLEN];
@ -5224,19 +5233,21 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
flag_t *rarflag = NULL; flag_t *rarflag = NULL;
// correct rarity number? // correct rarity number?
rarflag = hasflagval(ot->flags, F_RARITY, H_ALL, NA, NA, NULL); if (hab) {
if (!rarflag) { rarflag = hasflagval(ot->flags, F_RARITY, hab->id, NA, NA, NULL);
if (hab) {
rarflag = hasflagval(ot->flags, F_RARITY, hab->id, NA, NA, NULL);
} else {
rarflag = hasflag(ot->flags, F_RARITY);
}
} }
if (!rarflag) {
rarflag = hasflagval(ot->flags, F_RARITY, H_ALL, NA, NA, NULL);
}
/*if (!rarflag) {
rarflag = hasflag(ot->flags, F_RARITY);
}*/
if (rarflag) { if (rarflag) {
if ((rarflag->val[1] >= raritymin) && (rarflag->val[1] <= raritymax)) { if ((rarflag->val[1] >= raritymin) && (rarflag->val[1] <= raritymax)) {
enum RARITY thisrr; enum RARITY thisrr;
thisrr = rarflag->val[2]; thisrr = rarflag->val[2];
if (thisrr == NA) thisrr = RR_COMMON; if (thisrr == NA) thisrr = RR_FREQUENT;
if (thisrr == wantrr) { if (thisrr == wantrr) {
rarok = B_TRUE; rarok = B_TRUE;
@ -5303,7 +5314,7 @@ char *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat,
// already at lowest rarity? // already at lowest rarity?
if ((raritymax >= 100) && (raritymin <= 0)) { if ((raritymax >= 100) && (raritymin <= 0)) {
// now lower wantrr // now lower wantrr
if (wantrr > RR_COMMON) { if (wantrr > RR_FREQUENT) {
if (db) dblog("rarity at min/max and no obs. lowering wantrr to %d.",wantrr); if (db) dblog("rarity at min/max and no obs. lowering wantrr to %d.",wantrr);
wantrr--; wantrr--;
} else { } else {
@ -5452,7 +5463,7 @@ enum OBCLASS getrandomobclass(void) {
} }
} }
if (!nposs) { if (!nposs) {
if (wantrr > RR_COMMON) { if (wantrr > RR_FREQUENT) {
wantrr--; wantrr--;
} else { } else {
// should never happen! // should never happen!
@ -5469,7 +5480,7 @@ int getobrarity(object_t *o, enum RARITY *rr) {
map_t *m = NULL; map_t *m = NULL;
flag_t *f; flag_t *f;
if (rr) *rr = RR_COMMON; if (rr) *rr = RR_FREQUENT;
// check for rarity on this object's map first // check for rarity on this object's map first
c = getoblocation(o); c = getoblocation(o);
@ -5643,29 +5654,17 @@ int getthrowdam(object_t *o) {
// ie. 100 kg object does 20 damage (person) // ie. 100 kg object does 20 damage (person)
// ie. 1 tonne object does 200 damage (car) // ie. 1 tonne object does 200 damage (car)
dam = ceil((double)getobunitweight(o)) / 2; dam = ceil((double)getobunitweight(o)) / 2;
// missile objects do extra damage // non-missile objects do 25% less damage
if (hasflag(o->flags, F_THROWMISSILE)) { if (!hasflag(o->flags, F_THROWMISSILE)) {
dam *= 2; dam = pctof(75, dam);
}
// soft materials do less damage
if (gethardness(o->material->id) < 2) {
dam /= 2;
} }
} }
if (o->type->obclass->id == OC_MISSILE) { //if (dam > 20) dam = 20;
if (dam < 1) dam = 1;
} else {
// adjust for material
switch (o->material->id) {
// soft materials do less damage
case MT_PAPER:
case MT_WETPAPER:
case MT_CLOTH:
dam /= 2;
break;
break;
default:
break;
}
}
if (dam > 20) dam = 20;
// modify for bonus // modify for bonus
f = hasflag(o->flags, F_BONUS); f = hasflag(o->flags, F_BONUS);
@ -8413,7 +8412,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
enum RARITY pickrr(int whatfor) { enum RARITY pickrr(int whatfor) {
enum RARITY wantrr = RR_COMMON; enum RARITY wantrr = RR_FREQUENT;
int chance = 3; int chance = 3;
if ((gamemode == GM_GAMESTARTED) && hasflag(player->flags, F_EXTRALUCK)) { if ((gamemode == GM_GAMESTARTED) && hasflag(player->flags, F_EXTRALUCK)) {
@ -8956,6 +8955,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
case OT_POT_RUM: case OT_POT_RUM:
// kill coffee flags // kill coffee flags
killtransitoryflags(lf->flags, F_CAFFEINATED); killtransitoryflags(lf->flags, F_CAFFEINATED);
if (lfhasflag(lf, F_CAFFEINATED)) { if (lfhasflag(lf, F_CAFFEINATED)) {
// ie. conferred by something equipped etc // ie. conferred by something equipped etc
if (isplayer(lf)) { if (isplayer(lf)) {
@ -8975,6 +8975,10 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, TM_DRUNKTIME); addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, TM_DRUNKTIME);
} }
} }
// also a bit filling
if (potblessed != B_CURSED) {
modhunger(lf, -pctof(25, (float)HUNGERCONST));
}
break; break;
case OT_POT_ELEMENTIMMUNE: case OT_POT_ELEMENTIMMUNE:
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) { if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
@ -9939,6 +9943,10 @@ void rrtorarity(enum RARITY r, int *minr, int *maxr) {
if (minr) *minr = 80; if (minr) *minr = 80;
if (maxr) *maxr = 100; if (maxr) *maxr = 100;
break; break;
case RR_FREQUENT:
if (minr) *minr = 90;
if (maxr) *maxr = 100;
break;
default: default:
if (minr) *minr = 0; if (minr) *minr = 0;
if (maxr) *maxr = 100; // ie. rarity can be anything if (maxr) *maxr = 100; // ie. rarity can be anything
@ -10634,11 +10642,14 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
if (isplayer(o->pile->owner)) { if (isplayer(o->pile->owner)) {
msg("^wYour %s %s!",noprefix(obname), getobhurtname(o, damtype)); msg("^wYour %s %s!",noprefix(obname), getobhurtname(o, damtype));
} else if (cansee(player, o->pile->owner)) { } else if (cansee(player, o->pile->owner)) {
// don't announce decay damage for object you aren't holding // avoid "the goblin corses's armour is damaged"
if (damtype != DT_DECAY) { if (!lfhasflag(o->pile->owner, F_FEIGNINGDEATH)) {
char monname[BUFLEN]; // don't announce decay damage for object you aren't holding
getlfname(o->pile->owner, monname); if (damtype != DT_DECAY) {
msg("%s's %s %s!",monname, noprefix(obname), getobhurtname(o, damtype)); char monname[BUFLEN];
getlfname(o->pile->owner, monname);
msg("%s's %s %s!",monname, noprefix(obname), getobhurtname(o, damtype));
}
} }
} }
} }
@ -10683,7 +10694,6 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
int willcatch = B_FALSE; int willcatch = B_FALSE;
int announcedmiss = B_FALSE; int announcedmiss = B_FALSE;
int outofammo = B_FALSE; int outofammo = B_FALSE;
float multiplier;
obpile_t *op = NULL; obpile_t *op = NULL;
reason = E_OK; reason = E_OK;
@ -10705,8 +10715,6 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
limit(&speed, 1, NA); limit(&speed, 1, NA);
} }
multiplier = speed / 2;
if (firearm) { if (firearm) {
strcpy(throwverbpres, "fire"); strcpy(throwverbpres, "fire");
strcpy(throwverbpast, "fired"); strcpy(throwverbpast, "fired");
@ -11060,9 +11068,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
shield = getshield(target); shield = getshield(target);
if (shield && hasfreeaction(target)) { if (shield && hasfreeaction(target)) {
// block chance based on shield skill // block chance based on shield skill
// ie. AT_AVERAGE = speed3 = 18 if (skillcheck(target, SC_SHIELDBLOCK, 14 + (speed*2), 0)) {
// ie. gun = speed20 = 120 = impossible
if (skillcheck(target, SC_SHIELDBLOCK, speed*6, 0)) {
int throwdam,dam; int throwdam,dam;
if (seen) { if (seen) {
char shname[BUFLEN]; char shname[BUFLEN];
@ -11076,7 +11082,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
} }
// damage shield // damage shield
throwdam = getthrowdam(o); throwdam = getthrowdam(o);
dam = (int)((float)throwdam * multiplier); dam = throwdam + speed;
takedamage(shield, dam, DT_PROJECTILE); takedamage(shield, dam, DT_PROJECTILE);
youhit = B_FALSE; youhit = B_FALSE;
practice(target, SK_SHIELDS, 1); practice(target, SK_SHIELDS, 1);
@ -11111,15 +11117,15 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
catchmod = -6; catchmod = -6;
dodgemod = 2; dodgemod = 2;
} }
// first check to see if you can catch it // first check to see if you can catch it. this is hard!
if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) && if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) &&
lfhasflag(target, F_HUMANOID) && lfhasflag(target, F_HUMANOID) &&
canpickup(target, o, o->amt) && canpickup(target, o, o->amt) &&
!willburden(target, o, o->amt) && !willburden(target, o, o->amt) &&
!isimmobile(target) && !isimmobile(target) &&
skillcheck(target, SC_DEX, 15*speed, catchmod)) { skillcheck(target, SC_DEX, 30 + (speed*5), catchmod)) {
willcatch = B_TRUE; willcatch = B_TRUE;
} else if (!lfhasflag(target, F_CASTINGSPELL) && skillcheck(target, SC_DODGE, 7*speed, dodgemod)) { } else if (!lfhasflag(target, F_CASTINGSPELL) && skillcheck(target, SC_DODGE, 14+(speed*2), dodgemod)) {
// then check if we dodge it... // then check if we dodge it...
if (db) dblog("target passed dodge check."); if (db) dblog("target passed dodge check.");
@ -11188,7 +11194,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
throwdam = getthrowdam(o); throwdam = getthrowdam(o);
dam = (int)((float)throwdam * multiplier); //dam = (int)((float)throwdam * multiplier);
dam = throwdam + speed;
// firearms at pointblank range? +50% damage // firearms at pointblank range? +50% damage
if (firearm) { if (firearm) {
@ -11207,7 +11214,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
dam = 1; dam = 1;
} }
if (db) dblog("fireat(): dam = throwdam(%d) * multi(%d)",throwdam, multiplier); if (db) dblog("fireat(): dam = throwdam(%d) + speed(%d)",throwdam, speed);
if (db) dblog("dealing %d damage", dam); if (db) dblog("dealing %d damage", dam);
// deal extra cutting damage afterwards? // deal extra cutting damage afterwards?

33
spell.c
View File

@ -271,12 +271,31 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
} }
// announce the check, so that the player has feedback
// if map generation takes a while.
if (ch == 'l') {
msg("You sniff %s...",obname);
} else if (ch == 's') { // smell
msg("You listen at %s...",obname);
} else if (ch == 'f') { // footprints
msg("You inspect %s...",obname);
} else if (ch == 'p') { // peek
msg("You peek %s the stairs...", getdirname(stairdir));
}
// find out where the other end goes...
c = getstairdestination(stairs, &madenewmap); c = getstairdestination(stairs, &madenewmap);
// show --more-- after we have the destination
more();
if (!c) { if (!c) {
msg("These stairs don't seem to go anywhere!"); msg("These stairs don't seem to go anywhere!");
return B_TRUE; return B_TRUE;
} }
noredraw = B_TRUE; noredraw = B_TRUE;
// move any lfs at the other end out of the way. // move any lfs at the other end out of the way.
@ -304,9 +323,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
slev = getskill(user, SK_LISTEN); slev = getskill(user, SK_LISTEN);
msg("You listen at %s...",obname);
more();
if (inway) { if (inway) {
// just get the lf in the way // just get the lf in the way
if (getnoisedetails(inway, N_WALK, thismovetext, NULL, &vol)) { if (getnoisedetails(inway, N_WALK, thismovetext, NULL, &vol)) {
@ -388,9 +404,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
race_t *smellrace[MAXCANDIDATES]; race_t *smellrace[MAXCANDIDATES];
int nposs = 0,n,smellcount[MAXCANDIDATES], range = 0; int nposs = 0,n,smellcount[MAXCANDIDATES], range = 0;
msg("You sniff %s...",obname);
more();
f = lfhasflag(user, F_ENHANCESMELL); f = lfhasflag(user, F_ENHANCESMELL);
if (f) { if (f) {
range = f->val[0]; range = f->val[0];
@ -461,9 +474,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
char *fpname[MAXCANDIDATES],thisfpname[BUFLEN]; char *fpname[MAXCANDIDATES],thisfpname[BUFLEN];
int nposs = 0,n,fpcount[MAXCANDIDATES]; int nposs = 0,n,fpcount[MAXCANDIDATES];
msg("You inspect %s...",obname);
more();
if (inway) { if (inway) {
// just do footprints for the lf in the way // just do footprints for the lf in the way
trailob = addtrail(inway, c, inway->facing, B_TRUE, B_FALSE); trailob = addtrail(inway, c, inway->facing, B_TRUE, B_FALSE);
@ -523,7 +533,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
} else if (ch == 'p') { // peek } else if (ch == 'p') { // peek
flag_t *awareness; flag_t *awareness;
msg("You peek %s the stairs...", getdirname(stairdir)); more();
// process light sources for the other end (otherwise new // process light sources for the other end (otherwise new
// maps will be dark by default and you might not see anything) // maps will be dark by default and you might not see anything)
calclight(c->map); calclight(c->map);
@ -5663,13 +5672,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
if ((retflag[i]->id == F_NOBODYPART) && (retflag[i]->val[1] == B_FROMINJURY)) { if ((retflag[i]->id == F_NOBODYPART) && (retflag[i]->val[1] == B_FROMINJURY)) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Your %s grows back!", getbodypartname(target, retflag[0]->val[0])); msg("Your %s grows back!", getbodypartname(target, retflag[i]->val[0]));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char targname[BUFLEN]; char targname[BUFLEN];
getlfname(target, targname); getlfname(target, targname);
msg("%s%s %s grows back!", targname, getpossessive(targname), msg("%s%s %s grows back!", targname, getpossessive(targname),
getbodypartname(target, retflag[0]->val[0])); getbodypartname(target, retflag[i]->val[0]));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
killflag(retflag[i]); killflag(retflag[i]);

1
text.c
View File

@ -918,6 +918,7 @@ char *getrarityname(enum RARITY rr) {
case RR_RARE: return "Rare"; case RR_RARE: return "Rare";
case RR_UNCOMMON: return "Uncommon"; case RR_UNCOMMON: return "Uncommon";
case RR_COMMON: return "Common"; case RR_COMMON: return "Common";
case RR_FREQUENT: return "Frequent";
case RR_NONE: return "None"; case RR_NONE: return "None";
} }

View File

@ -21,6 +21,6 @@
goesin:dungeon goesin:dungeon
autodoors:50 autodoors:50
autopop autopop
rarity:uncommon rarity:frequent
@end @end

View File

@ -16,6 +16,6 @@ x:exit
@flags @flags
goesin:dungeon goesin:dungeon
rarity:uncommon rarity:frequent
@end @end

View File

@ -15,6 +15,6 @@ x:exit
@flags @flags
goesin:dungeon goesin:dungeon
rarity:common rarity:frequent
mayrotate mayrotate
@end @end

View File

@ -16,6 +16,6 @@ x:exit
@flags @flags
goesin:dungeon goesin:dungeon
rarity:uncommon rarity:frequent
@end @end

View File

@ -15,6 +15,6 @@ X:exit
! autoscale ! autoscale
goesin:dungeon goesin:dungeon
mayrotate mayrotate
rarity:common rarity:frequent
@end @end

View File

@ -17,7 +17,8 @@ $:ob:25-200 gold
@flags @flags
goesin:dungeon goesin:dungeon
mayrotate mayrotate
! no auto doors. ie this can be in the middle of nowhere.
rarity:uncommon rarity:uncommon
! don't link to rest of map. ie this can be in the middle of nowhere.
nolink
@end @end