- [+] get rid of "sorcery" skill, and move 'study scrolls' ability to

cmoe from lore:arcana instead
    - [+] rename magic skillls to sorcery:fire etc?
    - [+] adjust spell power calculation to take lack of sorcery skill
          int oaccount
- [+] allow '\' during getchoice() and getchoicestr()
    - [+] so that we can see what we have identified
- [+] lower metabolism while lmeditating
- [+] poisonous mushrooms
    - [+] toadstool - poisonous
    - [+] shiitake - normal
    - [+] recognise via cooking skill
- [+] if you add a blood ob, 1 randmo piece of armour in the pile
      becomes bloodstained
- [+] accuracy boost when attacking something who has grabbedyou
- [+] lessen gravitiy should prvent falls
* [+] bug:
- [+] add job descriptions
- [+] handle ESC in askchar
- [+] You attack the helpless the xat!  You flatten the xat!
    - [+] "the helpless the xat"
    - [+] shoiuldn't use "flatten" sinec we're not killing it
- [+] You attack the helpless xat!  You kill the xat!
    - [+] ...but  it wasn't dead!
- [+] flame pillar scroll no longer works
    - [+] not asking for target.
    - [+] use castspell
- [+] cope with 'ESC' presses during normal travel
- [+] allow "maycancel" in askchar
- [+] make wizards NOT automatically know wild magic
- [+] is F_MPMOD working?  check with elf wizard.......
    - [+] now it is.
- [+] bug: create an elf, go over it, v - CRASH in makedesc_race.
- [+] removeob() should update burdened status
    - [+] ie drinking a potion
- [+] wizards start with a staff and a pointy hat
- [+] don't "stir in your slumber" if meditating
- [+] elves should have higher mp
- [+] dwarves should have lower mp
- [+] when monsters fail to open a door, abandon their targetcell
    - [+] might be able to jsut make failing a dooropen count as a move
          failure.
- [+] HiGrv didn't stop me from moving? i passed the skill check, need
      to have a msg telling me this.
- [+] race descriptions. 
    - [+] add the descriptions
    - [+] ? in @@ shows info on them.
    - [+] (add ?=help in the bottom when in @ mode regardless of
          showall)
- [+] make clouds expand as they disappate
- [+] modify gethitstokill() to take "useevasion" and "usearmour" as a
      parameter
- [+] at adept lore, you get threat comparison.  at skilled level you
      get exact hit turns.
- [+]  make threat calculation use gethitstokill
- [+] TEST new threat calc
* [+] way too easy to notice traps on chests from 4-5 cells away, with
      only novice perception
- [+] make cloudkill create puff of poison gas rather than a cloud
- [+] attacking should count as movement (ie dont regen stamina)
- [+] need more body bash criticals.
    - [+] torso bruised (acc penalty)
    - [+] torso bruised badly (higher acc penalty, low dam penalty)
    - [+] ribs broken (huge acc penalty, med dam penalty)
    - [+] lungs winded (stam=0 onetimeeffect, fit -1, only lasts a 2-3
          turns)
- [+] should stop flying when you lose ocnsciousness...
- [+] warn before moving with f_pain as well. maybe cahnge
      confirm_injiury_action ???
- [+] extra warrior skill:  aimed strike
    - [+] -50%acc
    - [+] auto crit on the part you select (if you hit)
This commit is contained in:
Rob Pearce 2011-10-12 21:15:48 +00:00
parent 4101e7c066
commit 4eeb8cfe43
20 changed files with 1221 additions and 909 deletions

12
ai.c
View File

@ -666,7 +666,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
if (getschool(spell) == SS_ABILITY) {
spellfailed = useability(lf, spell, spelllf, spellcell);
} else {
spellfailed = castspell(lf, spell, spelllf, spellob, spellcell);
spellfailed = castspell(lf, spell, spelllf, spellob, spellcell, NULL, NULL);
}
}
if (spellfailed) {
@ -1161,7 +1161,7 @@ void aiturn(lifeform_t *lf) {
// hurt gods planeshift away
if (lf->race->raceclass->id == RC_GOD) {
if (gethppct(lf) <= 10) {
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell)) {
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) {
return;
}
}
@ -1500,7 +1500,7 @@ void aiturn(lifeform_t *lf) {
if (lf->race->raceclass->id == RC_GOD) {
if (onein(6)) {
// gods will planeshift away
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell)) {
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) {
return;
}
}
@ -1976,7 +1976,7 @@ object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op) {
bp = f->val[0];
// is it better than what we have in that position?
curarm = getarmour(lf, bp);
if (isbetterwepthan(o, curarm)) {
if (isbetterwepthan(o, curarm, lf)) {
return o;
}
}
@ -1989,7 +1989,7 @@ object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op) {
bestwep = getbestweapon(lf);
for (o = op->first ; o ; o = o->next) {
if (isweapon(o) && isbetterwepthan(o, bestwep) && canweild(lf, o)) {
if (isweapon(o) && isbetterwepthan(o, bestwep, lf) && canweild(lf, o)) {
return o;
}
}
@ -2152,7 +2152,7 @@ int lookforobs(lifeform_t *lf) {
if (gothere) {
// cast a spell?
if (cancast(lf, OT_S_CALLWIND, NULL) && haslof(lf->cell, c, LOF_NEED, NULL)) {
if (!castspell(lf, OT_S_CALLWIND, NULL, o, c)) {
if (!castspell(lf, OT_S_CALLWIND, NULL, o, c, NULL, NULL)) {
// successful
return B_TRUE;
}

View File

@ -199,7 +199,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
snprintf(buf, BUFLEN, "Really attack the allied %s?",noprefix(victimname));
break;
}
ch = askchar(buf, "yn","n", B_TRUE);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (ch == 'n') {
// cancel.
return B_TRUE;
@ -220,6 +220,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
}
killflagsofid(c->lf->flags, F_PRONE);
// still counts as a move!
if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL);
taketime(lf, getmovespeed(lf));
return B_FALSE;
}
@ -247,7 +248,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
getobname(priwep, wepname, priwep->amt);
snprintf(buf, BUFLEN, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname));
ch = askchar(buf, "yn","n", B_TRUE);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (ch == 'n') {
// cancel.
return B_TRUE;
@ -360,6 +361,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
}
}
if (maxattacks) {
if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL);
}
attacksdone = 0;
while (attacksdone < maxattacks) {
@ -383,7 +387,12 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
if (isbehind(lf, victim)) {
msg("You attack %s from behind!", vname);
} else {
msg("You attack the helpless %s!", vname);
char *vn;
// strip "the" from "the xxx"
vn = strdup(vname);
vn = strrep(vn, "the ", "", NULL);
msg("You attack the helpless %s!", vn);
free(vn);
}
}
}
@ -714,6 +723,15 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
dam[0] = (int)((float)dam[0] * getstrdammod(lf));
}
// modify for injuries
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
for (i = 0; i < nretflags; i++) {
switch (retflag[i]->val[0]) {
case IJ_TORSOBRUISEDBAD: dam[0] = pctof(90, dam[0]); break;
}
}
// modify for size
modifyforsize(&dam[0], lf, victim, 5, M_PCT);
@ -1954,7 +1972,7 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
}
}
if ((damtype == DT_BASH) && lfhasflag(victim, F_FROZEN)) {
if ((damtype == DT_BASH) && ismadeofice(victim)) {
return "shatter";
}
@ -1968,7 +1986,13 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
if (pct >= 70) {
if (damtype == DT_PIERCE) return "impale";
if (damtype == DT_BASH) return "flatten";
if (damtype == DT_BASH) {
if (isunconscious(victim)) {
return "kill";
} else {
return "flatten";
}
}
if (damtype == DT_BITE) return "gore";
if (damtype == DT_SLASH) {
if (lfhasflagval(victim, F_NOBODYPART, BP_HEAD, NA, NA, NULL)) {
@ -2285,7 +2309,12 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
}
if (lfhasflag(lf, F_AIMEDSTRIKE)) {
acc -= 50;
acc -= 40;
}
// easier to hit things which have grabbed you
if (lfhasflagval(lf, F_GRABBEDBY, victim->id, NA, NA, NULL)) {
acc += 30;
}
// harder to hit flying/levitating enemies, unless you are

530
data.c

File diff suppressed because it is too large Load Diff

Binary file not shown.

22
defs.h
View File

@ -436,7 +436,6 @@ enum SKILL {
SK_SEWING,
SK_SHIELDS,
SK_SPEECH,
SK_SPELLCASTING,
SK_STEALTH,
SK_SWIMMING,
SK_TECHUSAGE,
@ -475,7 +474,7 @@ enum SKILL {
SK_SS_TRANSLOCATION,
SK_SS_WILD,
};
#define MAXSKILLS 53
#define MAXSKILLS 52
// proficiency levels
enum SKILLLEVEL {
@ -801,7 +800,6 @@ enum RACE {
R_GIANTFIRETITAN,
R_GNOLL,
R_GNOLLHM,
R_GNOLLMR,
R_GOBLIN,
R_GOBLINWAR,
R_GOBLINSHOOTER,
@ -813,7 +811,6 @@ enum RACE {
R_LIZARDMAN,
R_MINOTAUR,
R_OGRE,
R_OGRESAVAGE,
R_OGREWARHULK,
R_OOZEGREY,
R_ORC,
@ -954,6 +951,7 @@ enum MATERIAL {
MT_PLANT = 26,
MT_WIRE = 27,
MT_SILVER = 28,
MT_DRAGONWOOD = 29,
};
// Object Types
@ -1019,7 +1017,8 @@ enum OBTYPE {
OT_BANANA,
OT_BANANASKIN, // not really food
OT_APPLE,
OT_MUSHROOM,
OT_MUSHROOMSHI,
OT_MUSHROOMTOAD,
OT_BREADSTALE,
OT_CHEESE,
OT_STEW,
@ -1474,6 +1473,7 @@ enum OBTYPE {
// armour - head
OT_SUNHAT,
OT_PIRATEHAT,
OT_POINTYHAT,
OT_CAP,
OT_HELM,
OT_GASMASK,
@ -1577,6 +1577,7 @@ enum OBTYPE {
OT_BAMBOOSTAFF,
OT_IRONSTAFF,
OT_BLADEDSTAFF,
OT_WIZARDSTAFF,
// clubs
OT_CLUB,
OT_FLAIL,
@ -1799,7 +1800,9 @@ enum FLAG {
F_OBDIETEXT, // text when the object dies
F_DIECONVERTTEXT, // text when the object converts. eg. "melts"
F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt"
F_DIECONVERT, // val0 = what this turns into when dying
F_DIECONVERT, // text = what this turns into when dying
// v0 = radius to scatter new object in (0 or NA means
// just convert the object)
F_NOBLESS, // can't be blessed or cursed
F_NOQUALITY, // can't be masterwork / shoddy
F_CORPSEOF, // this is a corpse of montype val0.
@ -2024,6 +2027,7 @@ enum FLAG {
F_MANUALOF, // val0 = spellschool this book trains
// ob identification flags
F_HASHIDDENNAME, // whether this object class has a hidden name
// text is the name if you don't know what it is
F_IDENTIFIED, // whether this object is fully identified
F_KNOWNBAD, // you know this object is somehow bad
// bad flags
@ -2311,6 +2315,7 @@ enum FLAG {
// v0=slot (0-9)
// text=spell text
// for monsters
F_MPMOD, // this race gains/loses v0 mp each level
F_DOESNTMOVE, // this race doesn't move (but can still attack)
F_AQUATIC, // this race can attack normally in water and suffers no
// movement penalties
@ -2598,8 +2603,12 @@ enum INJURY {
IJ_LEGBROKEN,
IJ_LEGBRUISE,
IJ_NOSEBROKEN,
IJ_RIBBROKEN, // can be from explosive too
IJ_RIBCRACKED, // can be from explosive too
IJ_SHOULDERDISLOCATED,
IJ_TORSOBRUISED,
IJ_TORSOBRUISEDBAD,
IJ_WINDED,
IJ_WINDPIPECRUSHED,
// slashing
IJ_ARTERYPIERCE,
@ -3003,6 +3012,7 @@ typedef struct race_s {
struct raceclass_s *raceclass;
struct material_s *material;
char *name;
char *desc;
struct glyph_s glyph;
float weight;
struct flagpile_s *flags;

View File

@ -1,8 +1,10 @@
defs.h:
define the MT_* enum
objects.c:
data.c:
add an addmaterial() line
objects.c:
update adjustdammaterial() as required
update getmaterialvalue()
update getmaterialstate()

32
god.c
View File

@ -101,8 +101,8 @@ void angergod(enum RACE rid, int amt) {
// minor bad stuff
switch (rid) {
case R_GODDEATH:
castspell(god, OT_S_PAIN, player, NULL, player->cell);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL);
// all undead in sight become hostile
for (l = player->cell->map->lf ; l ; l = l->next) {
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
@ -115,7 +115,7 @@ void angergod(enum RACE rid, int amt) {
case R_GODTHIEVES:
// take a random object
msg("\"Yoink!\"");
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell);
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL);
break;
case R_GODMERCY:
// lower one attribute
@ -153,8 +153,8 @@ void angergod(enum RACE rid, int amt) {
// major bad stuff
switch (god->race->id) {
case R_GODDEATH:
castspell(god, OT_S_PAIN, player, NULL, player->cell);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell);
castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL);
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL);
// all undead in sight become hostile
for (l = player->cell->map->lf ; l ; l = l->next) {
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
@ -167,9 +167,9 @@ void angergod(enum RACE rid, int amt) {
case 1:
msg("\"This will teach you some humility, mortal!\"");
if (getattr(player, A_IQ) > getattr(player, A_STR)) {
castspell(god, OT_S_FEEBLEMIND, player, NULL, player->cell);
castspell(god, OT_S_FEEBLEMIND, player, NULL, player->cell, NULL, NULL);
} else {
castspell(god, OT_S_WEAKEN, player, NULL, player->cell);
castspell(god, OT_S_WEAKEN, player, NULL, player->cell, NULL, NULL);
}
break;
case 2:
@ -183,11 +183,11 @@ void angergod(enum RACE rid, int amt) {
o = getweapon(player);
msg("\"Allow me to lighten your load a little...\"");
if (o) { // take player's weapon
castspell(god, OT_S_CONFISCATE, player, o, player->cell);
castspell(god, OT_S_CONFISCATE, player, o, player->cell, NULL, NULL);
} else { // take 3 objects
int i;
for (i = 0; i < 3; i++) {
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell);
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL);
}
}
break;
@ -809,12 +809,12 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (getalignment(l) == AL_EVIL) {
if (haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL)) {
// smite them
castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell);
castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell, NULL, NULL);
}
}
}
// turn undead
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL);
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL);
break;
case R_GODDEATH:
@ -824,7 +824,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (isundead(l)) {
makepeaceful(l);
} else {
castspell(god, OT_S_PAIN, l, NULL, l->cell);
castspell(god, OT_S_PAIN, l, NULL, l->cell, NULL, NULL);
}
}
}
@ -851,7 +851,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
msg("\"I'll take that...\"");
donesomething = B_TRUE;
}
castspell(god, OT_S_CONFISCATE, l, wep, l->cell);
castspell(god, OT_S_CONFISCATE, l, wep, l->cell, NULL, NULL);
}
}
}
@ -888,17 +888,17 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
case R_GODMERCY:
if (ispoisoned(lf)) {
msg("\"Let thy body be purged of toxins.\"");
castspell(god, OT_S_CUREPOISON, player, NULL, player->cell);
castspell(god, OT_S_CUREPOISON, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE;
}
if (gethungerlevel(gethungerval(player)) >= H_PECKISH) {
msg("\"Let thy stomach be satisfied.\"");
castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell);
castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE;
}
if (isbleeding(lf) || !donesomething) {
msg("\"Let thy wounds be healed.\"");
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell);
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE;
}
break;

356
io.c
View File

@ -33,6 +33,8 @@ int hascolour = B_TRUE;
int noredraw = B_FALSE;
int escok = B_TRUE;
extern int needredraw;
extern int numdraws;
@ -48,6 +50,8 @@ extern void (*precalclos)(lifeform_t *);
extern lifeform_t *godlf[];
extern int ngodlfs;
extern race_t *firstrace;
extern prompt_t prompt;
extern object_t *retobs[MAXPILEOBS+1];
@ -463,7 +467,7 @@ void animsky(cell_t *src, char ch, int colour) {
needredraw = B_TRUE;
}
char askchar(char *prompt, char *validchars, char *def, int showchars) {
char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel) {
char buf[BUFLEN];
char msghistbuf[BUFLEN];
char *p;
@ -501,8 +505,11 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
curs_set(1);
valid = B_FALSE;
while (!valid) {
ch = getkey();
if (strchr(validchars, ch)) {
ch = getkey(B_FALSE);
if ((ch == 27) && maycancel) {
ch = '\0';
valid = B_TRUE;
} else if (strchr(validchars, ch)) {
valid = B_TRUE;
} else if ((ch == 10) && def) { // enter = default
valid = B_TRUE;
@ -513,7 +520,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
curs_set(0);
// update messaage history
sprintf(msghistbuf, "%s%c", buf, ch);
sprintf(msghistbuf, "%s%c", buf, (ch == '\0') ? '-' : '\0');
addmsghist(msghistbuf);
clearmsg();
@ -2343,7 +2350,7 @@ void announceobflagloss(object_t *o, flag_t *f) {
int confirm_badfeeling(object_t *o) {
char ch;
ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE);
ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE, B_FALSE);
if (ch == 'y') return B_TRUE;
if (o && !hasflag(o->flags, F_KNOWNBAD)) {
addflag(o->flags, F_KNOWNBAD, B_TRUE, NA, NA, NULL);
@ -2359,7 +2366,7 @@ int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname) {
if (hasbleedinginjury(player, bp) && willbleedfrom(player, bp)) {
snprintf(ques, BUFLEN, "Your %s injury will cause damage if you %s - continue?",
getinjuredbpname(bp), actionname);
ch = askchar(ques, "yn","n", B_TRUE);
ch = askchar(ques, "yn","n", B_TRUE, B_FALSE);
if (ch == 'n') {
return B_FALSE;
}
@ -2641,7 +2648,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
break;
}
// otherwise look for shift key etc..
ch = keycodetokey(ch);
ch = keycodetokey(ch, B_TRUE);
// then handle input
if (ch == ' ') { // next page
if (nextpage == -1) { // go to first page
@ -2649,6 +2656,8 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
} else {
firstob = nextpage;
}
} else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) {
doknowledgelist();
} else if (isalpha(ch) || (ch == '$')) {
object_t *o;
// describe that object
@ -2856,7 +2865,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
break;
}
// otherwise look for shift key etc..
ch = keycodetokey(ch);
ch = keycodetokey(ch, B_TRUE);
// then handle input
if (ch == ' ') { // next page
if (nextpage == -1) { // go to first page
@ -3211,7 +3220,36 @@ void describeob(object_t *o) {
restoregamewindows();
}
void describeskill(enum SKILL skid) {
void describerace(enum RACE rid) {
char buf[BUFLEN];
char *buf2;
race_t *r;
cls();
r = findrace(rid);
if (!r) return;
// title
snprintf(buf, BUFLEN, "Race::%s",r->name);
wattron(mainwin, A_BOLD);
mvwprintw(mainwin, 0, 0, "%s", buf);
wattroff(mainwin, A_BOLD);
wmove(mainwin, 2, 0);
buf2 = malloc(HUGEBUFLEN * sizeof(char));
makedesc_race(rid, buf2);
textwithcol(mainwin, buf2);
free(buf2);
wrefresh(mainwin);
// wait for key
getch();
real_clearmsg(B_TRUE);
restoregamewindows();
}
void describeskill(enum SKILL skid, enum SKILLLEVEL levhilite) {
char buf[BUFLEN];
char *buf2;
skill_t *sk;
@ -3228,7 +3266,7 @@ void describeskill(enum SKILL skid) {
wmove(mainwin, 2, 0);
buf2 = malloc(HUGEBUFLEN * sizeof(char));
makedesc_skill(skid, buf2);
makedesc_skill(skid, buf2, levhilite);
textwithcol(mainwin, buf2);
free(buf2);
@ -3272,7 +3310,7 @@ void doattackcell(char dirch) {
cell_t *c;
if (dirch == '\0') {
dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
}
@ -3332,7 +3370,7 @@ void doclose(void) {
} else if (adjdoors == 1) {
dir = forcedir;
} else {
ch = askchar("Close door in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
ch = askchar("Close door in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(ch);
}
@ -3499,7 +3537,7 @@ void docomms(lifeform_t *lf) {
say(lf, "Behold mortal! It is I, Yumi!", SV_SHOUT);
say(lf, "For your selfless act, I grant you a wish.", SV_TALK);
// grant a wish.
castspell(lf, OT_S_WISHLIMITED, player, NULL, NULL);
castspell(lf, OT_S_WISHLIMITED, player, NULL, NULL, NULL, NULL);
say(lf, "Until next time, mortal!", SV_TALK);
unsummon(lf, B_TRUE);
} else if (i <= 20) { // identify
@ -3617,7 +3655,7 @@ void docomms(lifeform_t *lf) {
char buf2[BUFLEN];
char ch2;
snprintf(buf2, BUFLEN, "Pay $%d to identify %s?",(int)DEF_SHOPIDENTPRICE, buf);
ch2 = askchar(buf2, "yn","n", B_TRUE);
ch2 = askchar(buf2, "yn","n", B_TRUE, B_FALSE);
if (ch2 == 'y') {
if (givemoney(player, lf, DEF_SHOPIDENTPRICE)) {
angeramt += 25;
@ -3771,7 +3809,7 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
char buf2[BUFLEN];
// take it off first - this takes time.
snprintf(buf2, BUFLEN, "Remove %s",buf);
ch = askchar(buf2, "yn","y", B_TRUE);
ch = askchar(buf2, "yn","y", B_TRUE, B_FALSE);
if (ch == 'y') {
if (takeoff(player, o)) {
// failed to take it off - can't drop it.
@ -3850,7 +3888,7 @@ void doeat(obpile_t *op) {
(o->amt == 1) ? "is" : "are",
obname,
(o->amt == 1) ? "it" : "one");
ch = askchar(buf, "yn","n", B_TRUE);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
eatob = o;
break;
@ -3949,7 +3987,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
// confirm
getobname(o, obname, o->amt);
snprintf(buf, BUFLEN, "Buy %s for $%d?",obname, getobvalue(o));
answer = askchar(buf, "yn","n", B_TRUE);
answer = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (answer == 'y') {
int shopamt;
givemoney(player, NULL, getobvalue(o));
@ -5319,7 +5357,21 @@ char *makedesc_ob(object_t *o, char *retbuf) {
return retbuf;
}
char *makedesc_skill(enum SKILL skid, char *retbuf) {
char *makedesc_race(enum RACE rid, char *retbuf) {
race_t *r;
char buf[HUGEBUFLEN];
strcpy(retbuf, "");
r = findrace(rid);
snprintf(buf, HUGEBUFLEN, "%s\n\n", r->desc);
strncat(retbuf, buf, HUGEBUFLEN);
return retbuf;
}
char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite) {
skill_t *sk;
enum SKILLLEVEL slev;
char buf[BUFLEN];
@ -5340,7 +5392,13 @@ char *makedesc_skill(enum SKILL skid, char *retbuf) {
if (slev == PR_INEPT) {
snprintf(buf, BUFLEN, "%s\n",sk->skilldesctext[i]);
} else {
snprintf(buf, BUFLEN, "At %s level: %s\n",getskilllevelname(sk->skilldesclev[i]), sk->skilldesctext[i]);
int hilitethis = B_FALSE;
if ((levhilite != PR_INEPT) && (slev == levhilite)) {
hilitethis = B_TRUE;
}
snprintf(buf, BUFLEN, "%sAt %s level%s: %s\n",hilitethis ? "^W" : "",
getskilllevelname(sk->skilldesclev[i]), sk->skilldesctext[i],
hilitethis ? "^n" : "");
}
strncat(retbuf, buf, HUGEBUFLEN);
}
@ -5693,7 +5751,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly) {
// should always work...
if (ot->obclass->id == OC_SPELL) {
castspell(player, spellid, targlf, NULL, targcell);
castspell(player, spellid, targlf, NULL, targcell, NULL, NULL);
} else {
useability(player, spellid, targlf, targcell);
}
@ -5716,7 +5774,10 @@ void domemmagic(void) {
msg("You don't have any spells or abilities!");
return;
}
ch = askchar("Memorise in which slot (1-9)", "1234567890","", B_FALSE);
ch = askchar("Memorise in which slot (0-9, n to cancel)", "1234567890n","", B_FALSE, B_TRUE);
if (!isdigit(ch)) {
return;
}
slot = ch - '0';
getchoicestr(&prompt, B_FALSE, B_FALSE);
@ -5768,7 +5829,7 @@ void dooperate(obpile_t *op) {
(o->amt == 1) ? "is" : "are",
obname, verb,
(o->amt == 1) ? "it" : "one");
ch = askchar(buf, "yn","n", B_TRUE);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
operate(player, o, NULL);
return;
@ -5943,6 +6004,7 @@ void dohelp(char helpmode) {
if (helpmode == '?') {
initprompt(&prompt, "What would you like help with (ESC when done)?");
addchoice(&prompt, '?', "Keyboard Commands", NULL, NULL, NULL);
addchoice(&prompt, 'r', "Race Descriptions", NULL, NULL, NULL);
addchoice(&prompt, 's', "Skill Descriptions", NULL, NULL, NULL);
addchoice(&prompt, 'g', "God Descriptions", NULL, NULL, NULL);
addchoice(&prompt, '-', "(done)", NULL, NULL, NULL);
@ -5974,6 +6036,24 @@ void dohelp(char helpmode) {
centre(mainwin,C_WHITE, h-1, "[Press any key]");
getch();
done = B_TRUE;
} else if (helpmode == 'r') {
race_t *r;
centre(mainwin,C_WHITE, 0, "RACE REFERENCE");
y = 2;
initprompt(&prompt, "Describe which race (ESC when done)?");
for (r = firstrace ; r ; r = r->next) {
addchoice(&prompt, 'a', r->name, NULL, r, r->desc);
}
addchoice(&prompt, '\0', "(done)", NULL, NULL, NULL);
prompt.maycancel = B_TRUE;
ch = getchoicestr(&prompt, B_FALSE, B_TRUE);
if (!ch) {
done = B_TRUE;
} else {
r = (race_t *)prompt.result;
describerace(r->id);
}
} else if (helpmode == 's') {
skill_t *sk;
centre(mainwin,C_WHITE, 0, "SKILL REFERENCE");
@ -5990,7 +6070,7 @@ void dohelp(char helpmode) {
done = B_TRUE;
} else {
sk = (skill_t *)prompt.result;
describeskill(sk->id);
describeskill(sk->id, PR_INEPT);
}
} else if (helpmode == 'g') {
lifeform_t *god;
@ -6048,7 +6128,7 @@ void doquaff(obpile_t *op) {
(o->amt == 1) ? "is" : "are",
obname, drink,
(o->amt == 1) ? "it" : "one");
ch = askchar(buf, "yn","n", B_TRUE);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
liquid = o;
break;
@ -6095,7 +6175,7 @@ void dolockpick(obpile_t *op) {
}
// ask direction
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(ch);
if (dir == D_NONE) {
clearmsg();
@ -6200,7 +6280,7 @@ void dopour(obpile_t *op) {
void doquit(void) {
char ch;
ch = askchar("Really quit", "yn","n", B_TRUE);
ch = askchar("Really quit", "yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
addflag(player->flags, F_NOSCORE, B_TRUE, NA, NA, NULL);
setlastdam(player, "quitting");
@ -6237,43 +6317,15 @@ void dorest(void) {
if (check_rest_ok(player)) return;
if (needstorest(player, validchars)) {
/*
if (strchr(validchars, 'h') && strchr(validchars, 'm')) {
strcat(validchars, "bn");
strcpy(ques, "Rest until full Health, Mana, Both, or none");
ch = askchar(ques, validchars, "b", B_TRUE);
if (ch == 'b') {
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
} else if (ch == 'h') {
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
} else if (ch == 'm') {
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
}
} else if (strchr(validchars, 'h')) {
strcpy(ques, "Rest until full Health");
ch = askchar(ques, "yn", "y", B_TRUE);
if (ch == 'y') {
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
}
} else if (strchr(validchars, 'm')) {
strcpy(ques, "Rest until full Mana");
ch = askchar(ques, "yn", "y", B_TRUE);
if (ch == 'y') {
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
}
}
*/
strcpy(ques, "Rest");
ch = askchar(ques, "yn", "y", B_TRUE);
ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
addflag(player->flags, F_RESTUNTILBETTER, B_TRUE, NA, NA, NULL);
}
} else {
if (countnearbyhurtallies(player)) {
strcpy(ques, "Rest until nearby allies are healed?");
ch = askchar(ques, "yn", "y", B_TRUE);
ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
addflag(player->flags, F_RESTUNTILALLIES, B_TRUE, NA, NA, NULL);
}
@ -6390,7 +6442,7 @@ void dothrow(obpile_t *op) {
if (!haslof(player->cell, where, LOF_WALLSTOP, &newwhere)) {
if (newwhere && (newwhere != player->cell)) {
char ch;
ch = askchar("Your line of fire is blocked - really throw here", "yn", "y", B_TRUE);
ch = askchar("Your line of fire is blocked - really throw here", "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
// update destination cell.
where = newwhere;
@ -6695,8 +6747,9 @@ void initgfx(void) {
noecho();
//cbreak();
raw();
// TODO: change back to raw mode, or make this a switch
cbreak();
//raw();
nodelay(mainwin, FALSE);
getmaxyx(mainwin, SCREENH, SCREENW);
@ -6901,6 +6954,8 @@ char getchoice(prompt_t *prompt) {
prompt->result = NULL;
sel = -1;
break;
} else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) {
doknowledgelist();
} else if (ch == ' ') {
if (nextpage == -1) {
first = 0;
@ -7177,6 +7232,8 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
} else if ((ch == 27) && (prompt->maycancel)) { // ESC - cancel
sel = -1;
break;
} else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) {
doknowledgelist();
} else if (ch == '\'') {
if (nextpage == -1) {
first = 0;
@ -7261,7 +7318,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
return prompt->choice[i].ch;
}
int getkey(void) {
int getkey(int escseqok) {
int key_code=0;
key_code = getch();
@ -7282,7 +7339,7 @@ int getkey(void) {
raw();
}
return keycodetokey(key_code);
return keycodetokey(key_code, escseqok);
}
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev) {
@ -7424,7 +7481,7 @@ void handleinput(void) {
}
} else {
gettinginput = B_TRUE;
ch = getkey();
ch = getkey(B_TRUE);
gettinginput = B_FALSE;
}
gotcmd = B_TRUE;
@ -7761,13 +7818,20 @@ void initprompt(prompt_t *p, char *q1) {
}
}
int keycodetokey(int keycode) {
// if escseqok is true, then process escape sequences by
// reading 3 more chars
int keycodetokey(int keycode, int escseqok) {
int keystroke = 0;
if (keycode == -1) return -1;
if (keycode == 27) { // an esc sequence
if (escseqok && (keycode == 27)) { // an esc sequence
timeout(0); // don't block
keycode=getch();
timeout(-1); // resume blocking
if (keycode == ERR) {
return 27; // ESC
}
keystroke=keycode;
keycode=getch();
keystroke=keystroke | (keycode<<8);
@ -8575,9 +8639,11 @@ void showlfstats(lifeform_t *lf, int showall) {
char actbuf[BUFLEN],movebuf[BUFLEN];
int h;
char buf[BUFLEN],buf2[BUFLEN];
char *descbuf = NULL;
job_t *j;
flag_t *f;
char *ftext= "%13s: ";
//char *ftext= "%13s: ";
char *ftext= "%11s: ";
long xpneeded;
object_t *o;
object_t *w[2];
@ -8623,14 +8689,27 @@ void showlfstats(lifeform_t *lf, int showall) {
showall = B_TRUE;
}
if (showall) {
if (isplayer(lf) || showall) {
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, "@asme%s%s",isplayer(lf) ? "g" : "", isplayer(lf) ? "" : "i");
} else {
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects %s ^WESC^n=quit]", isplayer(lf) ? "" : "^WI^ntems ");
snprintf(cmdchars, BUFLEN, "@ie");
snprintf(cmdchars, BUFLEN, "@e?");
// can always see stats & effects
snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects ");
if (!isplayer(lf)) {
snprintf(buf, BUFLEN, "^WI^ntems ");
strcat(promptstr, buf);
strcat(cmdchars, "i");
}
if ((lorelev >= PR_ADEPT) || (getskill(player, SK_LORE_ARCANA) >= PR_ADEPT)) {
snprintf(buf, BUFLEN, "^M^agic ");
strcat(promptstr, buf);
strcat(cmdchars, "m");
}
snprintf(buf, BUFLEN, "^W?^n=help ^WESC^n=quit]");
strcat(promptstr, buf);
}
while (!done) {
@ -8679,16 +8758,20 @@ void showlfstats(lifeform_t *lf, int showall) {
// size
doheadingsmall(mainwin, y, 0, ftext, "Size");
wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++;
if (showall) {
float w;
w = getlfweight(lf, B_NOOBS);
doheadingsmall(mainwin, y, 0, ftext, "Weight");
doheadingsmall(mainwin, y, 0, ftext, "Size/Weight");
getweighttext(w, buf, B_FALSE);
wprintw(mainwin, buf, w); y++;
wprintw(mainwin, "%s (%s)", getsizetext(getlfsize(lf)), buf); y++;
} else {
doheadingsmall(mainwin, y, 0, ftext, "Size");
wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++;
}
if (showall) {
doheadingsmall(mainwin, y, 0, ftext, "Weight");
}
@ -8764,7 +8847,6 @@ void showlfstats(lifeform_t *lf, int showall) {
y++;
}
}
y++; // skip line
for (i = 0; i < MAXATTS; i++) {
int val;
@ -8869,9 +8951,11 @@ void showlfstats(lifeform_t *lf, int showall) {
// get first innate attack weapon.
op = addobpile(NULL, NULL, NULL);
f = hasflag(lf->flags, F_HASATTACK);
w[0] = addobfast(op, f->val[0]);
if (w[0]) {
nweps = 1;
if (f) {
w[0] = addobfast(op, f->val[0]);
if (w[0]) {
nweps = 1;
}
}
}
@ -8939,19 +9023,12 @@ void showlfstats(lifeform_t *lf, int showall) {
if (op) {
killobpile(op);
op = NULL;
}
// skip a line
y2++;
/*
if (showall) {
mvwprintw(mainwin, y2, x2, ftext, "Attack Dmg");
wprintw(mainwin, "%-20s", buf); y2++;
}
*/
// unarmed attacks
op = addobpile(NULL, NULL, NULL);
for (f = lf->flags->first ; f ; f = f->next) {
@ -8993,7 +9070,6 @@ void showlfstats(lifeform_t *lf, int showall) {
} // end if fid == hasattack
} // end for each flag
// no attacks at all?
if ((nweps == 0) && !op->first) {
snprintf(buf, BUFLEN, "N/A");
@ -9004,7 +9080,10 @@ void showlfstats(lifeform_t *lf, int showall) {
// skip line
y2++;
killobpile(op);
if (op) {
killobpile(op);
op = NULL;
}
// ARMOUR STUFF
if (showall || (lorelev >= PR_NOVICE)) {
@ -9015,13 +9094,6 @@ void showlfstats(lifeform_t *lf, int showall) {
//max = pctof(75, arating);
doheadingsmall(mainwin, y2, x2, ftext, "Armour Rating");
/*
if (arating > 0) {
wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++;
} else {
wprintw(mainwin, "%d", arating); y2++;
}
*/
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
getarrange(arating, &min, &max);
if (max <= 0) {
@ -9056,7 +9128,6 @@ void showlfstats(lifeform_t *lf, int showall) {
y2++; // skip line
if (showall) {
f = hasflag(lf->flags, F_HUNGER);
if (f) {
@ -9090,13 +9161,6 @@ void showlfstats(lifeform_t *lf, int showall) {
unsetcol(mainwin, col);
wprintw(mainwin, "]");
y2++;
/*
if (showall) {
wprintw(mainwin, "%-14s (%d)", buf, f->val[0]); y++;
} else {
wprintw(mainwin, "%-14s", buf); y++;
}
*/
}
}
@ -9106,6 +9170,16 @@ void showlfstats(lifeform_t *lf, int showall) {
y = y2 + 1;
}
if (!isplayer(lf)) {
int dummy;
// description first.
descbuf = malloc(HUGEBUFLEN * sizeof(char));
makedesc_race(lf->race->id, descbuf);
mvwprintw(mainwin, y, 0, "%s", descbuf);
free(descbuf);
getyx(mainwin, y, dummy);
}
// knowledge?
if (lf != player) {
char knowstring[BUFLEN];
@ -9146,36 +9220,45 @@ void showlfstats(lifeform_t *lf, int showall) {
}
// extra info from lore?
if (lorelev >= PR_ADEPT) {
if (lorelev >= PR_SKILLED) {
int hitstokillyou,hitstokillit;
hitstokillit = gethitstokill(player, lf);
hitstokillyou = gethitstokill(lf, player);
if (hitstokillit || hitstokillyou) {
if (hitstokillit == hitstokillyou) {
hitstokillit = gethitstokill(player, lf, B_TRUE, B_TRUE);
hitstokillyou = gethitstokill(lf, player, B_TRUE, B_TRUE);
if (hitstokillit == hitstokillyou) {
if (hitstokillit) {
setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, "You could both kill each other in %d hit%s.", hitstokillit,
wrapprint(mainwin, &y, &x, "You could both kill each other in %d hit%s.", hitstokillit,
(hitstokillit == 1) ? "" : "s");
unsetcol(mainwin, lorecol);
y++;
} else {
if (hitstokillit) {
setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, "You could kill it in %d hit%s.", hitstokillit,
(hitstokillit == 1) ? "" : "s");
unsetcol(mainwin, lorecol);
y++;
}
if (hitstokillyou) {
setcol(mainwin, lorecol);
mvwprintw(mainwin, y, 0, "It could kill you in %d hit%s.", hitstokillyou,
(hitstokillyou == 1) ? "" : "s");
unsetcol(mainwin, lorecol);
y++;
}
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, "Neither of you would be able to kill the other.");
unsetcol(mainwin, lorecol);
}
} else {
if (hitstokillit) {
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, "You could kill it in %d hit%s.", hitstokillit,
(hitstokillit == 1) ? "" : "s");
unsetcol(mainwin, lorecol);
} else {
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, "You would never be able to kill it.");
unsetcol(mainwin, lorecol);
}
if (hitstokillyou) {
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, "It could kill you in %d hit%s.", hitstokillyou,
(hitstokillyou == 1) ? "" : "s");
unsetcol(mainwin, lorecol);
} else {
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, "It would never be able to kill you.");
unsetcol(mainwin, lorecol);
}
}
}
if (lorelev >= PR_SKILLED) {
if (lorelev >= PR_ADEPT) {
float rating;
// get threat rating
rating = comparelfs(player, lf);
@ -9191,14 +9274,14 @@ void showlfstats(lifeform_t *lf, int showall) {
} else if (rating >= 0.5) {
snprintf(buf, BUFLEN, "It would be challenging to defeat.");
} else if (rating >= 0.25) {
snprintf(buf, BUFLEN, "It would present a formidable opponent.");
snprintf(buf, BUFLEN, "It would make a formidable opponent.");
} else if (rating >= 0.125) {
snprintf(buf, BUFLEN, "It is very dangerous to you.");
} else {
snprintf(buf, BUFLEN, "It is EXTREMELY dangerous to you.");
}
//mvwprintw(mainwin, y, 0, "Threat rating: %0.1f",comparelfs(player, lf));
mvwprintw(mainwin, y, 0, "%s", buf);
wrapprint(mainwin, &y, &x, "%s", buf);
unsetcol(mainwin, lorecol);
y++;
}
@ -9812,6 +9895,17 @@ void showlfstats(lifeform_t *lf, int showall) {
y++;
}
getflags(lf->flags, retflag, &nretflags, F_CANSEETHROUGHMAT, F_NONE);
for (i = 0; i < nretflags; i++) {
material_t *m;
f = retflag[i];
m = findmaterial(f->val[0]);
if (m) {
mvwprintw(mainwin, y, 0, "%s can see through %s.", you(lf), m->name);
y++;
}
}
// material vulnerbilities
getflags(lf->flags, retflag, &nretflags, F_MATVULN, F_NONE);
for (i = 0; i < nretflags; i++) {
@ -10238,7 +10332,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasflag(lf, F_GRAVLESSENED);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "Gravity is lessened around %s.", you_l(lf));
mvwprintw(mainwin, y, 0, "Gravity is lessened around %s, preventing fall damage and increasing flight speed.", you_l(lf));
y++;
}
f = lfhasknownflag(lf, F_DODGES);
@ -10248,7 +10342,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
f = lfhasknownflag(lf, F_INVULNERABLE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s are protected from all physical harm.", you(lf));
mvwprintw(mainwin, y, 0, "%s %s protected from all physical harm.", you(lf), is(lf));
y++;
}
f = lfhasflag(lf, F_MAGSHIELD);
@ -10455,6 +10549,8 @@ void showlfstats(lifeform_t *lf, int showall) {
dohelp('g');
} else if (mode == 's') { // help on skills
dohelp('s');
} else if (mode == '@') { // help on current race
describerace(lf->race->id);
}
break;
default:
@ -10630,7 +10726,7 @@ void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) {
}
wmove(win, *y, *x);
textwithcol(win, buf);
(*x) += strlen(buf);
//(*x) += strlen(buf);
getyx(win, *y, *x);
}

12
io.h
View File

@ -23,7 +23,7 @@ object_t *askobject(obpile_t *op, char *title, int *count, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag);
object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...);
int askobjectmulti(obpile_t *op, char *prompt, long opts);
char askchar(char *prompt, char *validchars, char *def, int showchars);
char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel);
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
vault_t *askvault(char *prompttext);
@ -38,7 +38,8 @@ void cls(void);
int contains(enum OBCLASS *array, int nargs, enum OBCLASS want);
void describegod(lifeform_t *god);
void describeob(object_t *o);
void describeskill(enum SKILL skid);
void describerace(enum RACE rid);
void describeskill(enum SKILL skid, enum SKILLLEVEL levhilite);
void describespell(objecttype_t *ot);
void doattackcell(char dirch);
void doclose(void);
@ -87,7 +88,7 @@ void dumpspells(void);
enum COLOUR getattrcolour(enum ATTRBRACKET brack);
char getchoice(prompt_t *prompt);
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
int getkey(void);
int getkey(int escseqok);
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev);
void handle_ctrl_y(int arg);
void handleinput(void);
@ -95,11 +96,12 @@ void doheading(WINDOW *win, int *y, int x, char *what);
void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading);
void initgfx(void);
void initprompt(prompt_t *p, char *q1);
int keycodetokey(int keycode);
int keycodetokey(int keycode, int escseqok);
void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints);
char *makedesc_god(lifeform_t *god, char *retbuf);
char *makedesc_ob(object_t *o, char *retbuf);
char *makedesc_skill(enum SKILL skid, char *retbuf);
char *makedesc_race(enum RACE rid, char *retbuf);
char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite);
char *makedesc_spell(objecttype_t *ot, char *retbuf);
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantlowmp, int wanttoohard,int mpcutoff);
void more(void);

569
lf.c

File diff suppressed because it is too large Load Diff

8
lf.h
View File

@ -3,7 +3,7 @@
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
job_t *addjob(enum JOB id, char *name, char *desc);
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass);
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc);
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime);
void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg);
@ -46,9 +46,10 @@ int canuseweapons(lifeform_t *lf);
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
int canweild(lifeform_t *lf, object_t *o);
int cantakeoff(lifeform_t *lf, object_t *o);
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell);
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell, object_t *fromob, int *seen);
int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange);
int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod);
int checkburdened(lifeform_t *lf, int preburdened);
int checkfordrowning(lifeform_t *lf, object_t *o);
int check_rest_ok(lifeform_t *lf);
//void checkxp(enum RACE rid);
@ -136,7 +137,7 @@ int gethearingrange(lifeform_t *lf);
int gethidemodifier(lifeform_t *lf);
int gethitdice(lifeform_t *lf);
int gethitdicerace(race_t *r);
int gethitstokill(lifeform_t *lf, lifeform_t *victim);
int gethitstokill(lifeform_t *lf, lifeform_t *victim, int useevasion, int usearmour);
int gethppct(lifeform_t *lf);
enum COLOUR gethungercol(enum HUNGER hlev);
enum HUNGER gethungerlevel(int hunger);
@ -273,6 +274,7 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
int isinbattle(lifeform_t *lf);
int isingunrange(lifeform_t *lf, cell_t *where);
int isloreskill(enum SKILL skid);
int ismadeofice(lifeform_t *lf);
int ismaxedskill(lifeform_t *lf, enum SKILL skid);
int ispeaceful(lifeform_t *lf);
int ispetof(lifeform_t *lf, lifeform_t *owner);

6
map.c
View File

@ -16,6 +16,8 @@
#include "text.h"
#include "vault.h"
int enteringmap = B_FALSE;
extern habitat_t *firsthabitat,*lasthabitat;
extern job_t *firstjob;
extern map_t *firstmap,*lastmap;
@ -5226,12 +5228,16 @@ void mapentereffects(map_t *m) {
// monsters on the new level now get a bunch of turns to simulate them moving about when the player wasn't there.
if (m->lastplayervisit != -1) {
int nturns;
enteringmap = B_TRUE;
nturns = (curtime - m->lastplayervisit) / TICK_INTERVAL;
limit(&nturns, NA, 20);
//nturns *= countlfs(m);
for (i = 0; i < nturns; i++) {
donextturn(m);
}
enteringmap = B_FALSE;
}
}

63
move.c
View File

@ -1008,19 +1008,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
}
}
// remember current cell + room id
prespeed = getmovespeed(lf);
preroom = lf->cell->room;
v = getcellvault(lf->cell);
if (v && hasflag(v->flags, F_VAULTISSHOP)) {
preshop = getroomid(lf->cell);
}
// getting out of water?
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
prewater = B_TRUE;
}
// special effects when the player moves to a new map
if (changedlev && isplayer(lf)) {
object_t *o;
@ -1039,6 +1026,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (o) killob(o);
}
// remember current cell + room id
prespeed = getmovespeed(lf);
preroom = lf->cell->room;
v = getcellvault(lf->cell);
if (v && hasflag(v->flags, F_VAULTISSHOP)) {
preshop = getroomid(lf->cell);
}
// getting out of water?
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
prewater = B_TRUE;
}
// move out...
lf->cell->lf = NULL;
@ -1203,7 +1202,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
msg("%s crushes %s.",lfname, obname);
didmsg = B_TRUE;
}
// kill object
// kill object which is being crushed.
removeob(o, o->amt);
continue;
}
@ -1373,6 +1372,12 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
int didmsg;
int predark = B_FALSE,postdark = B_FALSE;
// for the player, moving means that we don't regenerate stamina.
// this is the equivilant of losing the same amount of stamina which we
// would regenerate, only it avoids constantly redrawing the status
// bar every single move.
if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL);
if (!onpurpose || !isplayer(lf)) {
dontclearmsg = B_TRUE;
}
@ -1609,7 +1614,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) {
char ch;
snprintf(buf, BUFLEN,"Really open %s?", obname);
ch = askchar(buf,"yn","n", B_TRUE);
ch = askchar(buf,"yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
msg("Cancelled.");
return B_TRUE;
@ -1625,7 +1630,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
char ch;
snprintf(buf, BUFLEN,"%s running water behind %s. Really open it?",
haslos(lf, pastdoorcell) ? "There is" : "You can hear", obname);
ch = askchar(buf,"yn","n", B_TRUE);
ch = askchar(buf,"yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
msg("Cancelled.");
return B_TRUE;
@ -1847,7 +1852,7 @@ int trysneak(lifeform_t *lf, int dir) {
char ques[BUFLEN];
char ch;
snprintf(ques, BUFLEN, "Carefully %s in which direction (- to cancel)", getmoveverb(lf));
ch = askchar(ques, "yuhjklbn.-","-", B_FALSE);
ch = askchar(ques, "yuhjklbn.-","-", B_FALSE, B_TRUE);
dir = chartodir(ch);
if (dir == D_NONE) return B_TRUE;
} else {
@ -1952,7 +1957,12 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
if (!attacking) {
if (lfhasflag(lf, F_GRAVBOOSTED)) {
// make a saving throw to move
if (!skillcheck(lf, SC_STR, 25, 0)) {
if (skillcheck(lf, SC_STR, 25, 0)) {
if (isplayer(lf)) {
msg("You manage to %s despite the strong gravity.", isprone(lf) ? "stand" : "move");
if (didmsg) *didmsg = B_TRUE;
}
} else {
if (isplayer(lf)) {
msg("You try to %s but are unable to %s!",
isprone(lf) ? "stand" : "move",
@ -2173,9 +2183,10 @@ void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int changedir, int onpurpose)
setfacing(lf1, tempfacing);
}
// remember that we just swapped
// remember that we just swapped, and this counts as a move
if (!isplayer(lf1)) {
addflag(lf1->flags, F_NOSWAP, B_TRUE, NA, NA, NULL);
if (isplayer(lf1)) addflag(lf1->flags, F_MOVED, B_TRUE, NA, NA, NULL);
}
}
@ -2330,7 +2341,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
} else {
snprintf(ques, BUFLEN, "Really %s there?", getmoveverb(lf));
}
ch = askchar(ques, "yn","n", B_TRUE);
ch = askchar(ques, "yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
return B_TRUE;
}
@ -2355,13 +2366,6 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
return B_TRUE;
}
// for the player, moving means that we don't regenerate stamina.
// this is the equivilant of losing the same amount of stamina which we
// would regenerate, only it avoids constantly redrawing the status
// bar every single move.
if (isplayer(lf)) {
addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL);
}
reason = E_OK;
@ -2528,7 +2532,10 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
if (isplayer(lf)) {
if (cell->known) {
// try to open it
opendoor(lf, inway);
if (!opendoor(lf, inway)) {
// opening a door counts as a successful move.
reason = E_OK;
}
} else {
msg("Ouch! You %s into a door.", getmoveverb(lf));
setcellknown(cell, B_FALSE);

42
nexus.c
View File

@ -60,6 +60,8 @@ glyph_t playerglyph,tempglyph;
double startticks,lastticks;
struct timeval starttv, tv,newtv;
extern int enteringmap;
// maintains unique lifeform ID numbers
long nextlfid = 0;
@ -201,7 +203,7 @@ int main(int argc, char **argv) {
ch = 'a';
for (r = firstrace ; r ; r = r->next) {
if (hasflag(r->flags, F_PLAYABLE)) {
addchoice(&prompt, ch++, r->name, NULL, r, NULL);
addchoice(&prompt, ch++, r->name, NULL, r, r->desc);
}
}
startrace = NULL;
@ -285,12 +287,14 @@ int main(int argc, char **argv) {
addchoice(&prompt, 'a', getskillname(SK_SS_AIR), NULL, findskill(SK_SS_AIR), NULL);
addchoice(&prompt, 'c', getskillname(SK_SS_COLD), NULL, findskill(SK_SS_COLD), NULL);
addchoice(&prompt, 'f', getskillname(SK_SS_FIRE), NULL, findskill(SK_SS_FIRE), NULL);
addchoice(&prompt, 'w', getskillname(SK_SS_WILD), NULL, findskill(SK_SS_WILD), NULL);
getchoice(&prompt);
sk = (skill_t *) prompt.result;
giveskilllev(player, sk->id, PR_BEGINNER);
switch (sk->id) {
case SK_SS_AIR:
addflag(player->flags, F_CANCAST, OT_S_MIST, NA, NA, NULL);
addflag(player->flags, F_CANSEETHROUGHMAT, MT_GAS, NA, NA, NULL);
break;
case SK_SS_COLD:
addflag(player->flags, F_CANCAST, OT_S_CHILL, NA, NA, NULL);
@ -298,11 +302,15 @@ int main(int argc, char **argv) {
case SK_SS_FIRE:
addflag(player->flags, F_CANCAST, OT_S_SPARK, NA, NA, NULL);
break;
case SK_SS_WILD:
addflag(player->flags, F_CANCAST, OT_S_MANASPIKE, NA, NA, NULL);
break;
default:
break;
}
initprompt(&prompt, "Select your secondary spell school:");
addchoice(&prompt, 'd', getskillname(SK_SS_DIVINATION), NULL, findskill(SK_SS_DIVINATION), NULL);
addchoice(&prompt, 'g', getskillname(SK_SS_GRAVITY), NULL, findskill(SK_SS_GRAVITY), NULL);
addchoice(&prompt, 'm', getskillname(SK_SS_MODIFICATION), NULL, findskill(SK_SS_MODIFICATION), NULL);
addchoice(&prompt, 's', getskillname(SK_SS_SUMMONING), NULL, findskill(SK_SS_SUMMONING), NULL);
addchoice(&prompt, 't', getskillname(SK_SS_TRANSLOCATION), NULL, findskill(SK_SS_TRANSLOCATION), NULL);
@ -313,6 +321,9 @@ int main(int argc, char **argv) {
case SK_SS_DIVINATION:
addflag(player->flags, F_CANCAST, OT_S_SIXTHSENSE, NA, NA, NULL);
break;
case SK_SS_GRAVITY:
addflag(player->flags, F_CANCAST, OT_S_TRUESTRIKE, NA, NA, NULL);
break;
case SK_SS_MODIFICATION:
addflag(player->flags, F_CANCAST, OT_S_HOLDPORTAL, NA, NA, NULL);
break;
@ -377,8 +388,11 @@ int main(int argc, char **argv) {
// start game - this will cause debug messages to now
// go to the log file instead of stdout.
timeleft = 0; // reset game timer
enteringmap = B_FALSE; // no time passes for lfs on a different map to the player.
// calculate initial light
calclight(player->cell->map);
// pre-calc line-of-sight for player
@ -1215,16 +1229,18 @@ int rollhitdice(lifeform_t *lf) {
// modify for fitness/con
myroll = pctof(mod, myroll);
limit(&myroll, 1, NA);
if (db) dblog(" -> modified to: %d",myroll);
limit(&myroll, 1, NA);
return myroll;
}
int rollmpdice(lifeform_t *lf) {
int rollmpdice(lifeform_t *lf, int wantmax) {
flag_t *f;
int ndice, plus;
int roll;
int ndice, plus,roll,i;
float mod;
flag_t *retflag[MAXCANDIDATES];
int nretflags;
f = hasflag(lf->flags, F_MPDICE);
if (f) {
@ -1234,11 +1250,23 @@ int rollmpdice(lifeform_t *lf) {
} else {
return 0;
}
mod = 100 + getstatmod(lf, A_IQ) + (getskill(lf, SK_SPELLCASTING)/2);
roll = rolldie(ndice, 4) + plus;
mod = 100 + getstatmod(lf, A_IQ);
if (wantmax) {
roll = (ndice * 4) + plus;
} else {
roll = rolldie(ndice, 4) + plus;
}
roll = pctof(mod, roll);
// modify via racial flags
getflags(lf->flags, retflag, &nretflags, F_MPMOD, F_NONE);
for (i = 0; i < nretflags; i++) {
roll += retflag[i]->val[0];
}
limit(&roll, 0, NA);
return roll;
}

View File

@ -28,7 +28,7 @@ int rnd(int min, int max);
int roll(char *string);
int rolldie(int ndice, int sides);
int rollhitdice(lifeform_t *lf);
int rollmpdice(lifeform_t *lf);
int rollmpdice(lifeform_t *lf, int wantmax);
//void sortlf(map_t *map);
void timeeffectsworld(map_t *map, int updategametime);
void usage(char *progname);

280
objects.c
View File

@ -1555,15 +1555,30 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
}
}
// apply cost to shop items
if (o->pile->where) {
vault_t *v;
v = getcellvault(o->pile->where);
// apply cost to shop items
if (v && hasflag(v->flags, F_VAULTISSHOP)) {
if (canpickup(NULL, o, 1)) {
addflag(o->flags, F_SHOPITEM, getobvalue(o), getroomid(o->pile->where), NA, NULL);
}
}
// blood will stain things on the ground
if (o->material->id == MT_BLOOD) {
object_t *poss[MAXPILEOBS],*oo;
int nposs = 0;
// bloodstain one piece of armour
for (oo = o->pile->first ; oo ; oo = oo->next) {
if ((oo != o) && isarmour(oo)) {
poss[nposs++] = oo;
}
}
if (nposs) {
oo = poss[rnd(0,nposs-1)];
applyobmod(oo, findobmod(OM_BLOODSTAINED));
}
}
}
@ -1774,6 +1789,20 @@ void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma
*dam = 0;
return;
}
} else if (mat == MT_DRAGONWOOD) {
switch (damtype) {
case DT_FIRE:
case DT_MELT:
case DT_DECAY:
case DT_COLD:
case DT_ELECTRIC:
case DT_HOLY:
case DT_WATER:
*dam = 0;
return;
default:
break;
}
}
// adjust based on damage type
@ -1991,6 +2020,10 @@ void appendinscription(object_t *o, char *text) {
void applyobmod(object_t *o, obmod_t *om) {
flag_t *f;
if (hasobmod(o, om)) {
return;
}
if ((om->id == OM_MASTERWORK) || (om->id == OM_SHODDY)) {
if (hasflag(o->flags, F_NOQUALITY)) {
return;
@ -2516,6 +2549,91 @@ void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype) {
}
}
// returns TRUE if something happened
int doobdieconvert(object_t *o, int wantannounce) {
flag_t *f;
f = hasflag(o->flags, F_DIECONVERT);
if (f) {
flag_t *f2;
object_t *newob;
char desc[BUFLEN];
if (wantannounce && !hasflag(o->flags, F_NODIECONVERTTEXT)) {
char obname[BUFLEN];
// announce the change
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
strcpy(desc, "");
f2 = NULL;
if (o->amt > 1) {
f2 = hasflag(o->flags, F_DIECONVERTTEXTPL);
}
if (!f2) {
f2 = hasflag(o->flags, F_DIECONVERTTEXT);
}
if (f2) {
snprintf(desc, BUFLEN, "%s", f2->text);
} else if (oblastdamtype(o) == DT_DECAY) {
// don't announce devay death while traning
if (!lfhasflag(player, F_TRAINING)) {
snprintf(desc, BUFLEN, "%s completed rotted away", (o->amt == 1) ? "has" : "have");
}
} else {
snprintf(desc, BUFLEN, "%s destroyed", (o->amt == 1) ? "is" : "are");
}
if (strstr(o->type->name, "stain") || (o->type->id == OT_ROASTMEAT)) {
assert(0 == 1);
}
if (strlen(desc)) {
if (o->pile->owner) {
if (isplayer(o->pile->owner)) {
msg("Your %s %s!",noprefix(obname), desc);
} else if (cansee(player, o->pile->owner)) {
// don't announce decay death unless we are holding it
if (oblastdamtype(o) != DT_DECAY) {
char monname[BUFLEN];
getlfname(o->pile->owner, monname);
msg("%s's %s %s!",monname, noprefix(obname), desc);
}
}
} else if (haslos(player, o->pile->where)) {
// don't announce decay death unless we are holding it
if (oblastdamtype(o) != DT_DECAY) {
capitalise(obname);
msg("%s %s.",obname, desc);
}
}
} // end if desc != ""
}
// change into something else
newob = addob(o->pile, f->text);
// only set amt if text wasn't "x-y somethings"
if (newob && !strchr(f->text, '-')) {
newob->amt = o->amt;
}
if (f->val[0] > 0) {
cell_t *centre;
centre = getoblocation(o);
if (centre) {
cell_t *cell[MAXCANDIDATES];
int ncells,i;
getradiuscells(centre, f->val[0], DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, cell, &ncells, B_FALSE);
for (i = 0; i < ncells; i++) {
newob = addob(cell[i]->obpile, f->text);
if (newob && !strchr(f->text, '-')) {
newob->amt = o->amt;
}
}
}
}
return B_TRUE;
}
return B_FALSE;
}
int doobtraps(object_t *o, lifeform_t *lf) {
flag_t *f;
f = hasflag(o->flags, F_TRAPPED);
@ -3705,6 +3823,7 @@ int getmaterialvalue(enum MATERIAL mat) {
case MT_SILVER:
return 6;
case MT_GOLD:
case MT_DRAGONWOOD:
return 7;
}
// default
@ -5523,7 +5642,7 @@ int isbetterarmourthan(object_t *a, object_t *b) {
}
// compare weapons using max damage
int isbetterwepthan(object_t *a, object_t *b) {
int isbetterwepthan(object_t *a, object_t *b, lifeform_t *owner) {
//flag_t *f;
int dama,damb;
float acca,accb;
@ -5559,15 +5678,15 @@ int isbetterwepthan(object_t *a, object_t *b) {
}
// modify with accuracy
acca = getobaccuracy(a, a->pile->owner);
accb = getobaccuracy(b, b->pile->owner);
acca = getobaccuracy(a, owner);
accb = getobaccuracy(b, owner);
if (db) {
msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
}
dama = (int)((float)dama * (acca/100));
damb = (int)((float)damb * (accb/100));
dama = pctof(acca, dama);
damb = pctof(accb, damb);
if (db) {
msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
@ -5836,8 +5955,11 @@ int ismagical(object_t *o) {
if (hasflag(o->flags, F_ENCHANTABLE) && hasflag(o->flags, F_BONUS)) {
return B_TRUE;
}
if (o->type->id == OT_SHILLELAGH) {
return B_TRUE;
switch (o->type->id) {
case OT_SHILLELAGH:
case OT_WIZARDSTAFF:
return B_TRUE;
default: break;
}
return B_FALSE;
@ -6605,13 +6727,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
// did this make us burdened?
if (isplayer(dst->owner)) {
if (isburdened(dst->owner) != preburdened) {
if (preburdened == BR_NONE) {
msg("^wThe weight of your possessions is burdening you!");
} else {
msg("^wThe weight of your possessions is burdening you even more!");
}
}
checkburdened(dst->owner, preburdened);
}
// in case you picked up money, something which changes your AR, etc
@ -6708,70 +6824,8 @@ void obdie(object_t *o) {
char obname[BUFLEN];
flag_t *f;
f = hasflag(o->flags, F_DIECONVERT);
if (f) {
flag_t *f2;
object_t *newob;
char desc[BUFLEN];
if (!hasflag(o->flags, F_NODIECONVERTTEXT)) {
// announce the change
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
strcpy(desc, "");
f2 = NULL;
if (o->amt > 1) {
f2 = hasflag(o->flags, F_DIECONVERTTEXTPL);
}
if (!f2) {
f2 = hasflag(o->flags, F_DIECONVERTTEXT);
}
if (f2) {
snprintf(desc, BUFLEN, "%s", f2->text);
} else if (oblastdamtype(o) == DT_DECAY) {
// don't announce devay death while traning
if (!lfhasflag(player, F_TRAINING)) {
snprintf(desc, BUFLEN, "%s completed rotted away", (o->amt == 1) ? "has" : "have");
}
} else {
snprintf(desc, BUFLEN, "%s destroyed", (o->amt == 1) ? "is" : "are");
}
if (strstr(o->type->name, "stain") || (o->type->id == OT_ROASTMEAT)) {
assert(0 == 1);
}
if (strlen(desc)) {
if (o->pile->owner) {
if (isplayer(o->pile->owner)) {
msg("Your %s %s!",noprefix(obname), desc);
} else if (cansee(player, o->pile->owner)) {
// don't announce decay death unless we are holding it
if (oblastdamtype(o) != DT_DECAY) {
char monname[BUFLEN];
getlfname(o->pile->owner, monname);
msg("%s's %s %s!",monname, noprefix(obname), desc);
}
}
} else if (haslos(player, o->pile->where)) {
// don't announce decay death unless we are holding it
if (oblastdamtype(o) != DT_DECAY) {
capitalise(obname);
msg("%s %s.",obname, desc);
}
}
} // end if desc != ""
}
// change into something else
newob = addob(o->pile, f->text);
if (newob) {
// only set amt if text wasn't "x-y somethings"
if (!strchr(f->text, '-')) {
newob->amt = o->amt;
}
}
} else {
// handle object conversion
if (!doobdieconvert(o, B_TRUE)) {
char desc[BUFLEN];
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
@ -7129,7 +7183,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) {
char ch;
snprintf(buf, BUFLEN,"Really operate %s?", obname);
ch = askchar(buf,"yn","n", B_TRUE);
ch = askchar(buf,"yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
msg("Cancelled.");
return B_TRUE;
@ -7216,8 +7270,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
char ch;
int dir;
// ask direction
ch = askchar(f->text, "yuhjklbn-","-", B_FALSE);
if (ch == '-') {
ch = askchar(f->text, "yuhjklbn-","-", B_FALSE, B_TRUE);
if ((ch == '-') || !ch) {
msg("Cancelled.");
return B_TRUE;
} else {
@ -7551,7 +7605,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
object_t *newob;
getobname(oo, liquidname, 1);
snprintf(ques, BUFLEN, "Fill your %s from %s?", noprefix(obname), liquidname);
ch = askchar(ques, "yn", "y", B_TRUE);
ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
char newobname[BUFLEN];
if (oo->type->id == OT_FOUNTAIN) {
@ -7702,7 +7756,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
char ch;
int dir;
// ask direction
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(ch);
if (dir == D_NONE) {
clearmsg();
@ -7729,7 +7783,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
char ch;
int dir;
// ask direction
ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(ch);
if (dir == D_NONE) {
clearmsg();
@ -7783,8 +7837,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} else if (o->type->id == OT_PICKAXE) {
int ch,dir;
cell_t *c;
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn><-","-", B_FALSE);
if (ch == '-') {
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn><-","-", B_FALSE, B_TRUE);
if ((ch == '-') || !ch) {
// cancel
clearmsg();
return B_TRUE;
@ -7821,7 +7875,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (!isopen) { // ie. if closed.
f = hasflag(o->flags, F_JAMMED);
if (f) {
ch = askchar("The hinges seem jammed. Loosen them", "yn", "y", B_TRUE);
ch = askchar("The hinges seem jammed. Loosen them", "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
char obname[BUFLEN];
getobname(o, obname, 1);
@ -7834,7 +7888,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
char obname[BUFLEN];
getobname(o, obname, 1);
snprintf(buf, BUFLEN, "Tighten the hinges on %s",obname);
ch = askchar(buf, "yn", "y", B_TRUE);
ch = askchar(buf, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
msg("You tighten the hinges on %s.", obname);
addflag(o->flags, F_JAMMED, rnd(1,10), NA, NA, NULL);
@ -7987,7 +8041,7 @@ int pour(lifeform_t *lf, object_t *o) {
door = hasobwithflag(c->obpile, F_DOOR);
if (door) {
snprintf(buf, BUFLEN, "Pour %s onto the door to the %s", obname, getdirname(d));
ch = askchar(buf, "yn", "n", B_TRUE);
ch = askchar(buf, "yn", "n", B_TRUE, B_FALSE);
if (ch == 'y') {
// finished asking where to pour
doneask = B_TRUE;
@ -8002,7 +8056,7 @@ int pour(lifeform_t *lf, object_t *o) {
if (!doneask) {
// tip onto what?
snprintf(buf, BUFLEN, "Pour %s onto the ground", obname);
ch = askchar(buf, "yn", "y", B_TRUE);
ch = askchar(buf, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') {
dst = NULL;
} else {
@ -8160,17 +8214,13 @@ int pour(lifeform_t *lf, object_t *o) {
takedamage(dst, 0, DT_WATER);
}
} else {
flag_t *f;
// pour onto ground
if (isplayer(lf)) {
msg("You pour %s onto the ground.", obname);
} else if (haslos(player, lf->cell)) {
msg("%s pours %s onto the ground.", lfname, obname);
}
f = hasflag(o->flags, F_DIECONVERT);
if (f) {
addob(lf->cell->obpile, f->text);
} else {
if (!doobdieconvert(o, B_FALSE)) {
if (haslos(player, lf->cell)) {
msg("The contents evaporate.");
}
@ -8936,9 +8986,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
f = hasflag(o->flags, F_LINKSPELL);
if (f) {
int seen = B_FALSE;
int power;
power = getobspellpower(o, lf);
int noeffect = B_FALSE;
// for unidentified scrolls which target an object,
// let player select ANY object (even if it won't
@ -8948,12 +8996,21 @@ int readsomething(lifeform_t *lf, object_t *o) {
f2 = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL);
targob = askobject(lf->pack, "Target which object", NULL, AO_NONE);
killflag(f2);
if (!targob) {
noeffect = B_TRUE;
}
}
dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE);
if (seen) {
// id the scroll now
makeknown(o->type->id); o->blessknown = B_TRUE;
if (!noeffect) {
castspell(lf, f->val[0], NULL, targob, NULL, o, &seen);
/*
dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE);
*/
if (seen) {
// id the scroll now
makeknown(o->type->id); o->blessknown = B_TRUE;
}
}
// removeob one of the object
@ -9325,18 +9382,31 @@ void removedeadobs(obpile_t *op) {
// returns the amount left
int removeob(object_t *o,int howmany) {
int preburdened = B_FALSE;
int rv = 0;
lifeform_t *owner;
owner = o->pile->owner;
if (owner) {
preburdened = isburdened(o->pile->owner);
}
if (howmany == ALL) {
howmany = o->amt;
}
if (howmany >= o->amt) {
killob(o);
return 0;
rv = 0;
} else {
o->amt -= howmany;
rv = o->amt;
}
return o->amt;
// did this make us burdened?
if (owner && isplayer(owner)) checkburdened(owner, preburdened);
return rv;
}
void rrtorarity(enum RARITY r, int *minr, int *maxr) {

View File

@ -43,6 +43,7 @@ int countobsoftype(obpile_t *op, enum OBTYPE oid);
int countnoncosmeticobs(obpile_t *op, int onlyifknown);
int curseob(object_t *o);
void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype);
int doobdieconvert(object_t *o, int wantannounce);
int doobtraps(object_t *o, lifeform_t *lf);
void dumpobrarity(void);
void explodeob(object_t *o, flag_t *f, int bigness);
@ -151,7 +152,7 @@ int isammofor(objecttype_t *ammo, object_t *gun);
int isbadfood(object_t *o);
int isunknownbadobject(object_t *o);
int isbetterarmourthan(object_t *a, object_t *b);
int isbetterwepthan(object_t *a, object_t *b);
int isbetterwepthan(object_t *a, object_t *b, lifeform_t *owner);
int isblessed(object_t *o);
int isblessknown(object_t *o);
int iscorpse(object_t *o);

125
spell.c
View File

@ -330,8 +330,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
int dirch;
dirch = askchar("Disarm trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
if (dirch == '-') {
dirch = askchar("Disarm trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if ((dirch == '-') || !dirch) {
if (isplayer(user)) msg("Cancelled.");
return B_TRUE ;
}
@ -482,7 +482,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
char dirch;
dirch = askchar("Flip from which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Flip from which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
if (isplayer(user)) msg("You can't flip yourself!");
return B_TRUE;
@ -580,7 +580,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (targcell) {
dir = getdirtowards(user->cell, targcell, NULL, B_FALSE, DT_ORTH);
} else {
dirch = askchar("Flurry in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
dirch = askchar("Flurry in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(dirch);
if (dir == D_NONE) {
if (isplayer(user)) msg("Cancelled.");
@ -629,7 +629,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
dirch = askchar("Grab in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Grab in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
if (isplayer(user)) msg("You can't grab yourself!");
return B_TRUE;
@ -1055,7 +1055,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
dirch = askchar("Shield bash in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Shield bash in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
// yourself!
targcell = user->cell;
@ -1147,7 +1147,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (isplayer(user)) {
int dir,dirch;
dirch = askchar("Sprint in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Sprint in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
msg("Cancelled.");
return B_TRUE;
@ -1419,7 +1419,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
dir = getdirtowards(user->cell, targcell, NULL, B_FALSE, DT_ORTH);
} else {
char dirch;
dirch = askchar("Tumble in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Tumble in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
dir = chartodir(dirch);
if (dir == D_NONE) {
if (isplayer(user)) msg("Cancelled.");
@ -1613,9 +1613,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
ch = 'a';
for (sk = firstskill ; sk ; sk = sk->next) {
char buf2[HUGEBUFLEN];
snprintf(buf, BUFLEN, "%s (%s)",getskillname(sk->id), getskilldesc(sk->id));
makedesc_skill(sk->id, buf2);
addchoice(&prompt, ch++, getskillname(sk->id), buf, sk, buf2);
enum SKILLLEVEL curlev;
curlev = getskill(user, sk->id);
if (curlev != PR_MASTER) {
snprintf(buf, BUFLEN, "%s (%s)",getskillname(sk->id), getskilldesc(sk->id));
makedesc_skill(sk->id, buf2, curlev+1);
addchoice(&prompt, ch++, getskillname(sk->id), buf, sk, buf2);
}
}
getchoicestr(&prompt, B_FALSE, B_TRUE);
sk = (skill_t *)prompt.result;
@ -1680,7 +1684,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
dirch = askchar("Aimed strike in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Aimed strike in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
// yourself!
targcell = user->cell;
@ -1752,7 +1756,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
while (!c) {
char ques[BUFLEN];
snprintf(ques, BUFLEN,"%s combination in which direction (- to cancel)", nhits ? "Continue" : "Start");
dirch = askchar("%s combination in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
dirch = askchar(ques, "yuhjklbn-","-", B_FALSE, B_TRUE);
if (dirch == '-') {
break;
} else {
@ -1827,7 +1831,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (where && where->lf) {
char ch;
enum ATTRIB att;
ch = askchar("Enhance which stat (n for none)?", "sacin",NULL, B_TRUE);
ch = askchar("Enhance which stat (n for none)?", "sacin",NULL, B_TRUE, B_FALSE);
switch (ch) {
case 's': att = A_STR; break;
case 'a': att = A_AGI; break;
@ -1879,7 +1883,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
dirch = askchar("Heavy blow in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Heavy blow in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
// yourself!
targcell = user->cell;
@ -1924,7 +1928,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
dirch = askchar("Quivering Palm in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Quivering Palm in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if (dirch == '.') {
// yourself!
targcell = user->cell;
@ -1968,7 +1972,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (isroom(user->cell) && hasobwithflagval(user->cell->obpile, F_SHOPITEM, NA, getroomid(user->cell), NA, NULL)) {
// stealing from a shop
char yn;
yn = askchar("Steal something from this shop?", "yn","n", B_TRUE);
yn = askchar("Steal something from this shop?", "yn","n", B_TRUE, B_FALSE);
if (yn == 'y') {
object_t *o;
flag_t *f;
@ -2017,7 +2021,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask for direction
if (!targcell) {
int dir;
dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
dir = chartodir(dirch);
if (dir == D_NONE) {
if (isplayer(user)) msg("Cancelled.");
@ -2481,7 +2485,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS);
} else {
int dirch;
dirch = askchar("Airblast in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
dirch = askchar("Airblast in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if ((dirch == '.') || (dirch == '-')) {
fizzle(caster);
return B_TRUE;
@ -2700,25 +2704,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->obfrom = spellid;
} else if (spellid == OT_S_BLADEBURN) {
object_t *wep;
enum DAMTYPE dt;
if (!targcell) {
targcell = caster->cell;
}
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_FALSE;
}
// does caster have a bladed weapon?
// does caster have a weapon?
wep = getweapon(target);
if (!wep) {
fizzle(caster);
return B_FALSE;
}
dt = getdamtype(wep);
if ((dt != DT_PIERCE) && (dt != DT_SLASH) && (dt != DT_CHOP)) {
fizzle(caster);
return B_FALSE;
}
if (isplayer(target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) {
@ -3169,10 +3169,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
radius = (power/4)+1;
addobburst(targcell, radius, DT_COMPASS, "cloud of poison gas", caster, LOF_WALLSTOP);
addobburst(targcell, radius, DT_COMPASS, "puff of poison gas", caster, LOF_WALLSTOP);
if (haslos(player, targcell)) {
msg("A cloud of poison gas appears!");
msg("A puff of poison gas appears!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else if (spellid == OT_S_CHARM) {
@ -3534,7 +3534,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("BAM! A vault has appeared nearby."); more();
needredraw = B_TRUE;
ch = askchar("Teleport to the new vault", "yn","y", B_TRUE);
ch = askchar("Teleport to the new vault", "yn","y", B_TRUE, B_FALSE);
if (ch == 'y') {
int x,y;
// find it
@ -3740,8 +3740,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
// don't need line of fire OR sight!
//if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE;
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn.-<>","-", B_FALSE);
if ((ch == '.') || (ch == '-')) {
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn.-<>","-", B_FALSE, B_TRUE);
if ((ch == '.') || (ch == '-') || !ch) {
fizzle(caster);
return B_TRUE;
} else if (ch == '<') {
@ -4689,7 +4689,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
(o->pile->owner == caster) ? noprefix(obname) : obname,
(o->amt == 1) ? "s" : "");
more();
ch = askchar("Abort your spell?", "yn","y", B_TRUE);
ch = askchar("Abort your spell?", "yn","y", B_TRUE, B_FALSE);
if (ch == 'y') {
msg("You release your spell into the air.");
return B_FALSE;
@ -5666,7 +5666,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char ch;
snprintf(buf, BUFLEN, "You may be stuck in %s%s body - proceed?", targname,
getpossessive(targname));
ch = askchar(buf, "yn", "n", B_TRUE);
ch = askchar(buf, "yn", "n", B_TRUE, B_FALSE);
if (ch != 'y') {
cancel = B_TRUE;
}
@ -7636,11 +7636,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE;
} else if (!c->known) {
// confirm
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE);
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE, B_FALSE);
if (ch != 'y') c = NULL;
} else if (c->type->solid) {
// confirm
ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE);
ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE, B_FALSE);
if (ch != 'y') c = NULL;
}
}
@ -7654,8 +7654,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int xmax,ymax;
// semicontrolled
// ask for dir
dirch = askchar("Teleport in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE);
if ((dirch == '.') || (dirch == '-')) {
dirch = askchar("Teleport in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE);
if ((dirch == '.') || (dirch == '-') || !dirch) {
fizzle(caster);
return B_TRUE;
} else {
@ -7891,12 +7891,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(target->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp thorns", FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_TRUESTRIKE) {
flag_t *f;
if (!targcell) targcell = caster->cell;
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_FALSE;
}
addflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL);
f = addtempflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
f = addtempflag(caster->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_TURNUNDEAD) {
int i;
lifeform_t *lf;
@ -8023,6 +8028,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (o) {
if (canweild(target, o)) {
flag_t *f;
object_t *oldwep;
// unweild current weapon
oldwep = getweapon(target);
if (oldwep) {
if (iscursed(oldwep)) setblessed(oldwep, B_UNCURSED);
unweild(target, oldwep);
}
// announce
if (isplayer(target)) {
msg("A blade of pure energy forms in your hands!");
@ -8231,7 +8244,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
dam = roll("1d6");
}
takedamage(o, dam, DT_DIRECT);
takedamage(o, dam, DT_DECAY);
if (haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
@ -8506,7 +8519,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
enum SPELLSCHOOL school;
skill_t *poss2[MAXSKILLS],*sk;
int nposs2 = 0;
giveskill(target, SK_SPELLCASTING);
for (school = SS_AIR; school < SS_LAST; school++) {
sk = findskill(getschoolskill(school));
poss2[nposs2++] = sk;
@ -8635,6 +8647,7 @@ objecttype_t *findspelln(char *buf) {
}
void fizzle(lifeform_t *caster) {
if (!caster) return;
if (isplayer(caster)) {
if (lfhasflag(caster, F_CASTINGSPELL)) {
msg("Your spell fizzles.");
@ -8905,10 +8918,9 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) {
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
int power = 0;
int spelllev;
enum SKILLLEVEL spellcastskill,schoolskill;
enum SKILLLEVEL schoolskill;
enum SPELLSCHOOL school;
int db = B_FALSE;
int usesorcery = B_FALSE;
flag_t *f;
if (db) {
@ -8937,7 +8949,6 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
// get spell details
school = getspellschoolknown(lf, spellid);
schoolskill = getskill(lf, getschoolskill(school));
spellcastskill = getskill(lf, SK_SPELLCASTING);
spelllev = getspelllevel(spellid);
// for most spell schools, your skill in the school determines which
@ -8948,9 +8959,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
int maxspelllevel = MAXSPELLLEV;
if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) {
} else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) {
// dont need spellcasting skill for mental/allomancy
} else {
usesorcery = B_TRUE;
switch (schoolskill) {
case PR_INEPT: maxspelllevel = 0; break;
case PR_NOVICE: maxspelllevel = 1; break;
@ -8975,23 +8984,9 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
// HOW POWERFUL IS THIS SPELL?
////////////////////////////////////
if (isplayer(lf)) {
if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) {
// always okay
usesorcery = B_FALSE;
} else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) {
// dont need spellcasting skill for mental/allomancy
usesorcery = B_FALSE;
} else {
usesorcery = B_TRUE;
}
power = 1; // base power of 1.
// plus either your hitdice/3 OR your sorcery skill
if (usesorcery) {
power += spellcastskill;
} else {
power += (gethitdice(lf)/3);
}
// plus your hitdice/3
power += (gethitdice(lf)/3);
// plus intelligence modifier
if (school == SS_MENTAL) {
@ -9581,7 +9576,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
if (isplayer(caster) && !frompot) {
// warn!
int ch;
ch = askchar("Your have no clear line of fire - really target here?","yn","n", B_TRUE);
ch = askchar("Your have no clear line of fire - really target here?","yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
where = newwhere;
} else {
@ -9619,7 +9614,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
getlfname(where->lf, lfname);
snprintf(ques, BUFLEN, "Really target %s", lfname);
}
ch = askchar(ques,"yn","n", B_TRUE);
ch = askchar(ques,"yn","n", B_TRUE, B_FALSE);
if (ch != 'y') {
where = NULL;
}
@ -9649,7 +9644,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
char ques[BUFLEN];
int ch;
snprintf(ques, BUFLEN, "Abandon your %s?", (sp->obclass->id == OC_SPELL) ? "spell" : "ability");
ch = askchar(ques,"yn","n", B_TRUE);
ch = askchar(ques,"yn","n", B_TRUE, B_FALSE);
if (ch == 'y') {
return NULL;
}

14
text.c
View File

@ -158,11 +158,15 @@ char *getaccuracyname(int accpct) {
if (accpct >= 200) {
return "incredible";
} else if (accpct >= 150) {
return "very good";
return "excellent";
} else if (accpct >= 120) {
return "great";
} else if (accpct >= 100) {
return "good";
} else if (accpct >= 70) {
} else if (accpct >= 80) {
return "average";
} else if (accpct >= 70) {
return "mediocre";
} else if (accpct >= 50) {
return "poor";
} else if (accpct >= 30) {
@ -174,6 +178,10 @@ char *getaccuracyname(int accpct) {
}
}
int getaccuracymodnum(int accpctmod) {
return accpctmod / 5;
}
int getaccuracynum(int accpct) {
int num;
num = (accpct - 100) / 5; //
@ -211,7 +219,7 @@ char *getattrname(enum ATTRIB att) {
case A_AGI:
return "agility";
case A_IQ:
return "intelligence";
return "intellect";
case A_STR:
return "strength";
case A_WIS:

1
text.h
View File

@ -7,6 +7,7 @@ enum COLOUR chartocol(char ch);
char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf);
int flip(int ch);
char *getaccuracyname(int accpct);
int getaccuracymodnum(int accmodpct);
int getaccuracynum(int accpct);
char *getattrabbrev(enum ATTRIB att);
char *getattrname(enum ATTRIB att);