- [+] bug in skillpoint % display in @@

- [+] make detect life last longer
- [+] stirge should have enhacnesmell
- [+] plants should never "turn to face you". 
    - [+]  they should be able to see in all dirs.
    - [+] don't announce "turns to face" if the lf has f_awareness
- [+] AGAIN: walk on to a dark place and i can still see my own cell! 
      needed >= instead of > in celllitfor
- [+] don't show sacrifice text if you can't see
- [+] butterflies shouldn't produce light.
- [+] peaceful things shouldn't turn to face you all the time (only low
      % chance)
- [+] CRASHES when killing flags
    - [+] killflag() was dereferencing f-> after freeing it.
- [+] skill which aren't ready not showing up in 'm' list
    - [+] i think a previous fix for spells broke this...
    - [+] whatever it was, it shoudl only apply to spells, not
          abilities.
- [+] don't show @G if you're looking at someone else.
- [+] sunrise code didn't work - i immediately went to full fov!
    - [+] was a bug in isnighttime().
- [+] jimbo needs more hp
- [+] diningroom should have a fridge, instead of all food being on
      ground.
- [+] bug: "it is pitch black" as soon as you use stairs....... need to
      recalc light 
- [+] show temp lit areas as bold
    - [+] do it.
    - [+] test.......
- [+] notification of being followed to other maps/stairs:
    - [+] "you walk up the stairs. xxx follows you."
    - [+] implement.
- [+] move sacrifice code to god.c
- [+] change twoewapon->master to make your second weapon act like a
      shield
    - [+] ie. getshield() returns it.
    - [+] act like low level shield skill. special case in
          SC_SHIELDBLOCK
- [+] make twoweaponers only be able to use secondary weapons in which
      they are skilled.
This commit is contained in:
Rob Pearce 2011-09-15 01:40:26 +00:00
parent da656dfa52
commit 5bd96d7e5a
16 changed files with 286 additions and 164 deletions

4
ai.c
View File

@ -506,6 +506,10 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
if (db) {
dblog(".oO { starting aimovetolf }");
}
targetflag = lfhasflagval(lf, F_PETOF, target->id, NA, NA, NULL);
if (targetflag) {
ismaster = B_TRUE;

Binary file not shown.

5
defs.h
View File

@ -108,6 +108,7 @@
#define MAXDIR_ORTH 4
#define MAXDIR_COMPASS 8
#define MAXFLAGS 500
#define MAXFOLLOWLFS 15 // max # of lfs who will follow you up/down stairs
#define MAXHISTORY 20 // max lines of history to keep
#define MAX_MAPW 80
#define MAX_MAPH 20
@ -1308,6 +1309,7 @@ enum OBTYPE {
OT_BLINDFOLD,
OT_BUGLAMP,
OT_CANDLE,
OT_FRIDGE,
OT_GUNPOWDER,
OT_LAMPOIL,
OT_LANTERNOIL,
@ -1803,7 +1805,8 @@ enum FLAG {
F_OPERONOFF, // operating this will just turn it on/off
F_OPERUSECHARGE, // operating this will use 1 charge
F_OPERNEEDTARGET, // need to ask for a target of type val0 when opering
// v0 is target requirements (los/lof)
// v1 is bitmask of:
// TR_NEEDLOS, TR_NEEDLOF, TR_NONE
// text is prompt
F_OPERNEEDDIR, // need to ask a direction when operating this. text is prompt

View File

@ -4,7 +4,7 @@
} = gas
^ = trap / dangerous thing
) = weapon
ooo
------------------------------------------------
A = avian / bird
a = ant
B = bat

20
flag.c
View File

@ -696,6 +696,7 @@ int killflagsofid(flagpile_t *fp, enum FLAG fid) {
void killflag(flag_t *f) {
flag_t *nextone, *lastone;
flagpile_t *pile;
lifeform_t *lf;
map_t *redolight = NULL;
cell_t *redolos = NULL;
@ -801,6 +802,10 @@ void killflag(flag_t *f) {
}
}
// remember the pile so that we can re-index
pile = f->pile;
// free mem
if (f->text) free(f->text);
if (f->altval) {
@ -827,7 +832,14 @@ void killflag(flag_t *f) {
lastone->next = nextone;
}
updatefpindex(f->pile);
//////////////////////////////////////////
// "f" is now gone. don't reference it
// anymore!
//////////////////////////////////////////
f = NULL;
// re-index the pile
updatefpindex(pile);
if (gamemode == GM_GAMESTARTED) {
for (i = 0; i < ngodlfs; i++) {
@ -839,10 +851,10 @@ void killflag(flag_t *f) {
// - if this was a lf's flag, they recalc their los.
// - if it was an object flag, then everyone who can see
// its cell recalcs their los.
if (f->pile->owner) {
setlosdirty(f->pile->owner);
if (lf) {
setlosdirty(lf);
//precalclos(f->pile->owner);
if (isplayer(f->pile->owner)) redoscreen = B_TRUE;
if (isplayer(lf)) redoscreen = B_TRUE;
} else {
// everyone who can see this cell recalcs their los
lifeform_t *l;

69
god.c
View File

@ -251,6 +251,73 @@ void angergodmaybe(enum RACE rid, int amt) {
}
}
void dooffer(void) {
object_t *o, *nexto;
lifeform_t *god;
flag_t *retflag[MAXCANDIDATES];
int nretflags,pietyplus = 0;
// which god?
god = askgod("To whom will you sacrifice?");
if (!god) {
msg("Cancelled.");
return;
}
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_NONE);
if (nretflags == 0) {
msg("%s does not accept sacrifices.", god->race->name);
return;
}
// anything here to offer?
for (o = player->cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
// does the god want this?
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_NONE);
int i;
for (i = 0; i < nretflags; i++) {
int ok = B_FALSE;
int thispiety = 0;
flag_t *f;
f = retflag[i];
if ((f->id == F_SACRIFICEOB) && (f->val[0] == o->type->id)) {
ok = B_TRUE;
thispiety = f->val[2];
} else if ((f->id == F_SACRIFICEOBCLASS) && (f->val[0] == o->type->obclass->id)) {
ok = B_TRUE;
thispiety = f->val[2];
} else if ((f->id == F_SACRIFICEOBWITHFLAG) && hasflag(o->flags, f->val[0])) {
ok = B_TRUE;
thispiety = f->val[2];
}
if (ok) {
char *p;
char obname[BUFLEN];
if (haslos(player, player->cell)) {
getobname(o, obname, ALL);
p = strdup(f->text);
p = strrep(p, "OB", obname, NULL);
if (o->amt == 1) {
p = strrep(p, "IS", "is", NULL);
} else {
p = strrep(p, "IS", "are", NULL);
}
msg("%s", p);
free(p);
}
removeob(o, ALL);
pietyplus += thispiety;
}
}
}
if (pietyplus) {
pleasegod(god->race->id, pietyplus);
} else {
nothinghappens();
}
taketime(player, getactspeed(player));
}
lifeform_t *findgod(enum RACE rid) {
lifeform_t *lf;
// search heaven first
@ -558,7 +625,7 @@ int godgiftmaybe(enum RACE rid) {
//setpiety(rid, 101);
modpiety(rid, -50);
} // end if (pctchance enough to get a gift)
} // end if (piety > 100)
} // end if (piety > 200)
return gotgift;
}

1
god.h
View File

@ -2,6 +2,7 @@
void angergod(enum RACE rid, int amt);
void angergodmaybe(enum RACE rid, int amt);
void dooffer(void);
lifeform_t *findgod(enum RACE rid);
int getpiety(enum RACE rid);
enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness);

81
io.c
View File

@ -5105,10 +5105,9 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
} else {
snprintf(mpdesc[nposs], BUFLEN, "(%d/%d)",f->val[1],f->val[2]);
validspell[nposs] = B_FALSE;
err[nposs] = E_TOOPOWERFUL;
err[nposs] = E_NOTREADY;
}
}
nposs++;
}
}
@ -5217,7 +5216,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
if (validspell[i]) {
strcpy(costbuf, "");
} else {
strcpy(costbuf, "(NOT CASTABLE) ");
sprintf(costbuf, "(NOT %s) ", (ot->obclass->id == OC_SPELL) ? "CASTABLE" : "USABLE");
}
strcat(costbuf, mpdesc[i]);
@ -5229,6 +5228,8 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2,
addit = B_TRUE;
} else if ((err[i] == E_TOOPOWERFUL) && wanttoohard) {
addit = B_TRUE;
} else if (err[i] == E_NOTREADY) {
addit = B_TRUE;
}
if (addit) {
@ -5352,70 +5353,6 @@ void domsghist(void) {
restoregamewindows();
}
void dooffer(void) {
object_t *o, *nexto;
lifeform_t *god;
flag_t *retflag[MAXCANDIDATES];
int nretflags,pietyplus = 0;
// which god?
god = askgod("To whom will you sacrifice?");
if (!god) {
msg("Cancelled.");
return;
}
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_NONE);
if (nretflags == 0) {
msg("%s does not accept sacrifices.", god->race->name);
return;
}
// anything here to offer?
for (o = player->cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
// does the god want this?
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_NONE);
int i;
for (i = 0; i < nretflags; i++) {
int ok = B_FALSE;
int thispiety = 0;
flag_t *f;
f = retflag[i];
if ((f->id == F_SACRIFICEOB) && (f->val[0] == o->type->id)) {
ok = B_TRUE;
thispiety = f->val[2];
} else if ((f->id == F_SACRIFICEOBCLASS) && (f->val[0] == o->type->obclass->id)) {
ok = B_TRUE;
thispiety = f->val[2];
} else if ((f->id == F_SACRIFICEOBWITHFLAG) && hasflag(o->flags, f->val[0])) {
ok = B_TRUE;
thispiety = f->val[2];
}
if (ok) {
char *p;
char obname[BUFLEN];
getobname(o, obname, ALL);
p = strdup(f->text);
p = strrep(p, "OB", obname, NULL);
if (o->amt == 1) {
p = strrep(p, "IS", "is", NULL);
} else {
p = strrep(p, "IS", "are", NULL);
}
msg("%s", p);
free(p);
removeob(o, ALL);
pietyplus += thispiety;
}
}
}
if (pietyplus) {
pleasegod(god->race->id, pietyplus);
} else {
nothinghappens();
}
taketime(player, getactspeed(player));
}
void dooperate(obpile_t *op) {
object_t *o;
@ -8177,9 +8114,10 @@ void showlfstats(lifeform_t *lf, int showall) {
}
if (showall) {
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects ^WG^nods %s^W?^n=help ^WESC^n=quit^h]",
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects %s%s^W?^n=help ^WESC^n=quit^h]",
isplayer(lf) ? "^WG^nods " : "",
isplayer(lf) ? "" : "^WI^ntems " );
snprintf(cmdchars, BUFLEN, "@asmeg%s",isplayer(lf) ? "" : "i");
snprintf(cmdchars, BUFLEN, "@asme%s%s",isplayer(lf) ? "g" : "", isplayer(lf) ? "" : "i");
} else {
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats %s ESC=quit]", isplayer(lf) ? "" : "^WI^ntems ");
snprintf(cmdchars, BUFLEN, "@i");
@ -8294,9 +8232,12 @@ void showlfstats(lifeform_t *lf, int showall) {
if (isplayer(lf)) {
int attpoints;
int pct;
long amtneeded;
attpoints = getattpoints(lf);
amtneeded = getspforpoint(lf);
doheadingsmall(mainwin, y, 0, ftext, "Skill Pts");
pct = ((float)lf->skillxp / (float)SKILLXPPERPOINT) * 100.0;
pct = ((float)lf->skillxp / (float)amtneeded) * 100.0;
limit(&pct, 0, 100);
if (lf->skillpoints || attpoints ) {
/*

97
lf.c
View File

@ -1440,7 +1440,7 @@ int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange) {
// outside the range of our light, and not lit
if ((nightvisrange != UNLIMITED) && !islit(c)) {
if (dist > nightvisrange) {
if (dist >= nightvisrange) {
return B_FALSE;
} else {
// inside our nightvis range and magically dark
@ -3933,10 +3933,8 @@ void gainxp(lifeform_t *lf, long amt) {
// skill xp
if (isplayer(lf)) {
int amtneeded;
int mod;
mod = getstatmod(lf, A_IQ);
amtneeded = pctof(100 + mod, SKILLXPPERPOINT);
amtneeded = getspforpoint(lf);
lf->skillxp += amt;
assert(lf->skillxp >= 0);
@ -4239,7 +4237,7 @@ int getadjenemies(lifeform_t *who, lifeform_t **adjlf, int *nadjlfs) {
// include allies or enemies which will follow you up/down stairs etc
// ie. allies within LOS
// ie. adjacent enemies
void getwhowillfollow(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *nadjallies) {
void getwhowillfollow(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *seen, int *nadjallies) {
int x,y;
for (y = 0; y < lf->cell->map->h; y++) {
for (x = 0; x < lf->cell->map->w; x++) {
@ -4266,7 +4264,9 @@ void getwhowillfollow(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, i
if (ok) { // still ok?
adjally[*nadjallies] = c->lf;
if (seen) seen[*nadjallies] = cansee(lf, c->lf);
(*nadjallies)++;
if (*nadjallies >= MAXFOLLOWLFS) return;
}
}
}
@ -6081,9 +6081,13 @@ object_t *getsecmeleeweapon(lifeform_t *lf) {
object_t *getshield(lifeform_t *lf) {
object_t *o;
o = getequippedob(lf->pack, BP_SECWEAPON);
if (o && isshield(o)) {
if (o) {
if (isshield(o)) return o;
// master two-weaponers can use their second weapon as a shield.
if ((getskill(lf, SK_TWOWEAPON) >= PR_MASTER) && isweapon(o) && getweaponskill(lf, o)) {
return o;
}
}
return NULL;
}
@ -6584,6 +6588,14 @@ char *getspeednameshort(int speed, char *buf) {
return buf;
}
long getspforpoint(lifeform_t *lf) {
float mod;
long amtneeded;
mod = getstatmod(lf, A_IQ);
amtneeded = pctof(100 - mod, SKILLXPPERPOINT);
return amtneeded;
}
// returns a pct addition for things like:
// accuracy, evasion, lockpicking
// result will be between -50 and 50
@ -6907,6 +6919,17 @@ object_t *getweapon(lifeform_t *lf) {
return NULL;
}
enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o) {
skill_t *sk;
sk = getobskill(o);
if (sk) {
enum SKILLLEVEL weplev;
weplev = getskill(lf, sk->id);
return weplev;
}
return PR_INEPT;
}
long getxpforlev(int level) {
long needxp = 0;
// 2.8
@ -9079,7 +9102,7 @@ void initrace(void) {
addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+2");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+20");
//addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
//addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d4");
@ -11499,7 +11522,6 @@ void initrace(void) {
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addrace(R_GIANTFLY, "giant fly", 1, 'i', C_GREY, MT_FLESH, RC_INSECT);
@ -11559,6 +11581,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, "");
addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, "");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+1");
addflag(lastrace->flags, F_ENHANCESMELL, 2, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3");
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
@ -14424,15 +14447,18 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
if (willrespond) {
// turn to face the sound
turntoface(l, c);
if (isplayer(noisemaker) && cansee(player, l)) {
if (isplayer(noisemaker) && cansee(player, l) && cansee(l, player) && !lfhasflag(l, F_AWARENESS)) {
// peaceful things only turn sometimes
if (!ispeaceful(l) || onein(6)) {
char lfname[BUFLEN];
turntoface(l, c);
getlfname(l, lfname);
msg("%s turns to face you.", lfname);
}
}
}
}
}
} else { // can't hear the sound.
}
} // end for each lf on map
@ -15896,7 +15922,7 @@ void initskills(void) {
addskilldesc(SK_TRAPS, PR_NOVICE, "^gYou gain the 'disarm traps' ability.", B_FALSE);
addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50);
addskilldesc(SK_TWOWEAPON, PR_NOVICE, "^gYou can now weild two weapons at once.", B_TRUE);
addskilldesc(SK_TWOWEAPON, PR_ADEPT, "gYou no longer suffer an accuracy penalty when weilding two weapons.", B_TRUE);
addskilldesc(SK_TWOWEAPON, PR_ADEPT, "^gYou no longer suffer an accuracy penalty when weilding two weapons.", B_TRUE);
addskilldesc(SK_TWOWEAPON, PR_SKILLED, "^gFollow-up attacks with your second weapon are now more accurate.", B_TRUE);
addskilldesc(SK_TWOWEAPON, PR_EXPERT, "^gYou gain the 'flurry attack' ability.", B_FALSE);
addskilldesc(SK_TWOWEAPON, PR_MASTER, "^gYou can now deflect attacks with your second weapon.", B_TRUE);
@ -16301,7 +16327,21 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
othermod += 10;
}
} else if (ct == SC_SHIELDBLOCK) {
switch (getskill(lf, SK_SHIELDS)) {
object_t *shield;
enum SKILLLEVEL slev;
shield = getshield(lf);
if (shield) {
if (isshield(shield)) {
slev = getskill(lf, SK_SHIELDS);
} else {
// twoweaponer using their weapon
slev = PR_NOVICE;
}
} else {
// should never happen!!!
slev = PR_INEPT;
}
switch (slev) {
case PR_NOVICE: othermod = 4; break;
case PR_BEGINNER: othermod = 7; break;
case PR_ADEPT: othermod = 10; break;
@ -18144,7 +18184,8 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
char lfname[BUFLEN];
char obname[BUFLEN];
int isportal = B_FALSE;
lifeform_t *adjally[8];
lifeform_t *adjally[MAXFOLLOWLFS];
int seen[MAXFOLLOWLFS];
int nadjallies = 0;
int falling = B_FALSE;
int madenewmap = B_FALSE;
@ -18247,7 +18288,15 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
// find adjacent allies or enemies which will follow you
// (getwhowillfollow will handle following through pits)
if (isplayer(lf)) {
getwhowillfollow(lf, o, adjally, &nadjallies);
int n;
getwhowillfollow(lf, o, adjally, seen, &nadjallies);
for (n = 0; n < nadjallies; n++) {
if (seen[n]) {
char lname[BUFLEN];
real_getlfname(adjally[n], lname, B_FALSE);
msg("%s follows you.", lname);
}
}
}
// do stairs go somewhere?
@ -18338,13 +18387,14 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
if (c) {
if (!initiatemove(adjally[n], NULL, NULL)) {
int climbtime;
stopsprinting(adjally[n]);
movelf(adjally[n], c);
climbtime = getmovespeed(adjally[n]);
if ((dir == D_UP) && !isairborne(adjally[n])) {
if (onpurpose) taketime(adjally[n], getmovespeed(adjally[n])*2); // takes longer to climb
} else {
if (onpurpose) taketime(adjally[n], getmovespeed(adjally[n]));
climbtime *= 2;
}
if (onpurpose) taketime(adjally[n], climbtime);
}
}
}
@ -19208,16 +19258,27 @@ int weild(lifeform_t *lf, object_t *o) {
if (!twohanded && hasbp(lf, otherloc)) {
oo = getequippedob(lf->pack, weildloc);
if (getskill(lf, SK_TWOWEAPON) && oo && !hasflag(oo->flags, F_TWOHANDED)) {
char buf2[BUFLEN];
char ch;
if (isplayer(lf)) {
char buf2[BUFLEN];
snprintf(buf2, BUFLEN, "Weild %s in your left hand?",buf);
ch = askchar(buf2, "yn","y", B_TRUE);
} else {
if (getweaponskill(lf, o)) ch = 'y';
else ch = 'n';
}
if (ch == 'y') {
// make sure we are skiled in 2nd weapon
if (getweaponskill(lf, o)) {
enum BODYPART temp;
// swap locations.
temp = weildloc;
weildloc = otherloc;
otherloc = temp;
} else {
msg("You are not skilled enough to use this weapon in your left hand.");
return B_TRUE;
}
}
}
}

4
lf.h
View File

@ -101,7 +101,7 @@ 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);
int getactspeed(lifeform_t *lf);
int getadjenemies(lifeform_t *lf, lifeform_t **adjlf, int *nadjlfs);
void getwhowillfollow(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *nadjallies);
void getwhowillfollow(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *seen, int *nadjallies);
enum ALIGNMENT getalignment(lifeform_t *lf);
enum ALLEGIENCE getallegiance(lifeform_t *lf);
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
@ -201,6 +201,7 @@ int getskilllevcost(enum SKILLLEVEL slev);
int getsounddist(int volume);
char *getspeedname(int speed, char *buf);
char *getspeednameshort(int speed, char *buf);
long getspforpoint(lifeform_t *lf);
float getstatmod(lifeform_t *lf, enum ATTRIB att);
char *getskilldesc(enum SKILL id );
char *getskillname(enum SKILL id );
@ -209,6 +210,7 @@ int getthrowspeed(int str);
int getturnspeed(lifeform_t *lf);
void getwantdistance(lifeform_t *lf, int *min, int *max, int attacking);
object_t *getweapon(lifeform_t *lf);
enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o);
long getxpforlev(int level);
void givejob(lifeform_t *lf, enum JOB jobid);
int givemoney(lifeform_t *from, lifeform_t *to, int amt);

28
map.c
View File

@ -739,6 +739,24 @@ regiontype_t *addregiontype(enum REGIONTYPE id, char *name, enum HABITAT default
}
void adjustcellglyphforlight(cell_t *c, glyph_t *g) {
if (g->ch == ' ') return;
switch (c->lit) {
case L_PERMDARK:
case L_NOTLIT:
g->colour = C_BLUE;
break;
case L_TEMP: // lit by a light source
if (g->colour < 8) {
g->colour = g->colour + 8; // ie. make bold
if (g->colour >= C_DARKGREY) g->colour = C_WHITE;
}
break;
case L_PERMLIGHT:
break;
}
}
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance) {
int i,d;
cell_t *poss[MAXCANDIDATES], *cell[MAXCANDIDATES]; // TODO: should this be maxroomw * maxroomh ?
@ -1256,17 +1274,13 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
} else {
// objects here, but we can't see them. draw the cell.
*g = c->type->glyph;
if (!islit(c)) {
g->colour = C_BLUE;
}
adjustcellglyphforlight(c, g);
}
} else {
// draw cell normally
//drawcell(cell, x, y);
*g = c->type->glyph;
if (!islit(c)) {
g->colour = C_BLUE;
}
adjustcellglyphforlight(c, g);
}
} else { // can't see the cell
void *thing;
@ -4699,7 +4713,7 @@ int isnewcellok(cell_t *cell, char *err) {
int isnighttime(void) {
int hours,mins,secs;
splittime(&hours,&mins,&secs);
if ((hours < 5) || (hours >= 19)) {
if ((hours < 7) || (hours >= 19)) {
return B_TRUE;
}
return B_FALSE;

1
map.h
View File

@ -11,6 +11,7 @@ region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid);
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);
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);
void clearcell(cell_t *c);

16
move.c
View File

@ -1044,7 +1044,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
newcell->lf = lf;
// update light
if (lfproduceslight(lf)) {
if ((isplayer(lf) && changedlev) || lfproduceslight(lf)) {
calclight(lf->cell->map);
}
setlosdirty(lf);
@ -2550,7 +2550,8 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
map_t *adjmap = NULL, *thismap;
cell_t *dst = NULL;
lifeform_t *adjally[8];
lifeform_t *adjally[MAXFOLLOWLFS];
int seen[MAXFOLLOWLFS];
int nadjallies = 0;
int n;
@ -2600,10 +2601,15 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
return B_TRUE;
}
if (onpurpose) {
if (onpurpose && isplayer(lf)) {
// get list of adjacent allies
if (isplayer(lf)) {
getwhowillfollow(lf, NULL, adjally, &nadjallies);
getwhowillfollow(lf, NULL, adjally, seen, &nadjallies);
for (n = 0; n < nadjallies; n++) {
if (seen[n]) {
char lname[BUFLEN];
real_getlfname(adjally[n], lname, B_FALSE);
msg("%s follows you.", lname);
}
}
}

View File

@ -3110,13 +3110,10 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder) {
acc += (getobbonus(wep)*5);
if (weilder) {
skill_t *sk;
// modify for weilder's skill
sk = getobskill(wep);
if (sk) {
enum SKILLLEVEL slev;
// modify for weilder's skill
slev = getskill(weilder, sk->id);
slev = getweaponskill(weilder, wep);
if (hasflag(wep->flags, F_MASTERWORK)) {
if (slev < PR_ADEPT) slev++;
}
@ -3142,7 +3139,6 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder) {
break;
}
}
}
// modify for attacker's level
if (wep->pile->owner) {
@ -6340,7 +6336,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addot(OT_STUMP, "stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA, SZ_LARGE);
addot(OT_STUMP, "tree stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "'");
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL);
@ -7852,7 +7848,7 @@ void initobjects(void) {
addot(OT_WAND_LIGHT, "wand of light", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, 3, NA, NULL);
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, TR_NEEDLOF, NA, NULL);
addot(OT_WAND_REVEALHIDDEN, "wand of reveal hidden", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL);
@ -7970,6 +7966,23 @@ void initobjects(void) {
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
addot(OT_FRIDGE, "refrigerator", "An insulated household appliance, made for storing food.", MT_METAL, 80, OC_TOOLS, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "]");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder.", MT_METAL, 0.5, OC_TOOLS, SZ_TINY);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of black powder");
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
@ -11736,7 +11749,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (isplayer(lf)) msg("You can't see there!");
return B_TRUE;
}
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf->cell, where, B_TRUE, &newwhere)) {
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf->cell, where, LOF_NEED, &newwhere)) {
if (newwhere) {
// update destination
where = newwhere;
@ -16202,15 +16215,11 @@ int getcritchance(lifeform_t *lf, object_t *o, lifeform_t *victim) {
if (lf) {
enum SKILLLEVEL weplev = PR_INEPT;
skill_t *wepsk = NULL;
wepsk = getobskill(o);
if (wepsk) {
weplev = getskill(lf, wepsk->id);
weplev = getweaponskill(lf, o);
if (weplev != PR_INEPT) {
chance += (weplev*5); // ie. up to 30% bonus
}
}
}
// double crit chance if victim is vulnerable to this weapon
if (victim && lfhasflagval(victim, F_MATVULN, o->material->id, NA, NA, NULL)) {

10
spell.c
View File

@ -3386,11 +3386,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (o = caster->pack->first ; o ; o = o->next) {
if (o->blessed == B_BLESSED) {
getobname(o, obname, o->amt);
msg("Your %s flash%s white!", noprefix(obname), (o->amt == 1) ? "es" : "");
msg("You sense a holy aura from your %s!", noprefix(obname));
somethinghappened = B_TRUE;
} else if (o->blessed == B_CURSED) {
getobname(o, obname, o->amt);
msg("Your %s flash%s black!", noprefix(obname), (o->amt == 1) ? "es" : "");
msg("Your sense an evil aura from your %s!", noprefix(obname));
somethinghappened = B_TRUE;
}
}
@ -3399,11 +3399,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (o = caster->cell->obpile->first ; o ; o = o->next) {
if (o->blessed == B_BLESSED) {
getobname(o, obname, o->amt);
msg("%s flash%s white!", obname, (o->amt == 1) ? "es" : "");
msg("You sense a holy aura from %s!", obname);
somethinghappened = B_TRUE;
} else if (o->blessed == B_CURSED) {
getobname(o, obname, o->amt);
msg("%s flash%s black!", obname, (o->amt == 1) ? "es" : "");
msg("You sense an evil aura from %s!", obname);
somethinghappened = B_TRUE;
}
}
@ -3550,7 +3550,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
target = caster;
if (isplayer(caster)) {
int howlong,radius;
howlong = getspellduration(10,20,blessed) + (power*2);
howlong = getspellduration(40,80,blessed) + (power*2);
radius = power * 10;
addtempflag(target->flags, F_DETECTLIFE, 10, (power >= 8) ? B_TRUE : NA, NA, NULL, howlong);
} else {

View File

@ -14,7 +14,8 @@ autopop
! tables & chairs
scatter(1,1,-2,-2) ob:wooden table:20%
scatter(1,1,-2,-2) ob:wooden footstool:20%
scatter(1,1,-2,-2) ob:random food:5-10
scatter(1,1,-2,-2) ob:random food:1-2
scatter(1,1,-2,-2) ob:refrigerator:1
scatter(1,1,-2,-2) ob:steak knife:1-5
! mayrotate
! mayscale