- [+] BUG: arrows shouldn't be able to trigger arrow traps!!!
- [+] king piranhas shouldn't leap out of the water! - [+] don't catch thrown missiles if it will burden us - [+] in @@, show "accuracy" as a seperate line, not with your weapon. - [+] higher chance of learning psionics on level up. - [+] fix up monster hp - too easy to kill most things in one hit with dam = 4-12, 2 attacks (ie. l6 monk) - [+] dump out all mosnters sorted by hit dice (show avg hp) - [+] fix them up - [+] vault->entertext - ie "you enter a dining room" - [+] make random monster generation go by hitdice AND rarity rr_. IGNORE rarity value. - [+] start with hd = level. sometimes incrase - [+] remove all rarity values from monsters - [+] disorient might need to be higher level than stun - [+] make psionic spell mp cost be level, rather than level^2? - [+] ai bug: - [+] .oO { looking for a target . } .oO { found an enemy target - lfid 256 (human) ! } .oO { default - moving randomly } - [+] reduce cost for higher levle spells agian. - [+] prevent player from eating an ice sheid! - [+] bug when eating from the floor with multiple food items there - [+] assassin's blink spell - teleport behind and facing someone. medium level translocation. - [+] make "chunk of roast meat" be "chunk of roast goblin meat" - [+] and base nutrition on corpse type - [+] highlevel sixth sense should let you turn to face it * [+] add prompt text to msg hist: - [+] sixth sense should only pick up hostile monsters - [+] need a good reason that wizards can't wear armour. - [+] if isplayer(), failure chance depends on any arm/shield penalties - [+] show f_impassable in describeob() - [+] no walking backwards/sideways if you're stuck in a web/vine. can only turn. - [+] objects for protection: - [+] eyeglasses (+vision) - [+] safety goggles - [+] ERROR - stairs link to existing map 0('the surface(0,0) (id #0)', depth 1), but it has no free stairs. - [+] when we restart map regeneration, must first REMOVE referenecs to this map!!! - [+] implemented. - [+] fixed bug with sleep interruption - [+] You attack the helpless the dwarf monk! You flatten the dwarf monk! The dwarf monk loses consciousness. damage's robe protects it. - [+] add stamina cost to other abilities - [+] add descriptions to lore skills - [+] make athletics skill give you more stamina? * [+] monstesr stopping fleeing when they can't see player
This commit is contained in:
parent
2db53bca61
commit
5cb8b05817
21
ai.c
21
ai.c
|
@ -37,21 +37,27 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
}
|
||||
|
||||
if (!canattack(lf)) {
|
||||
dblog(".oO { canattack() is false }");
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// mindless?
|
||||
/*
|
||||
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) {
|
||||
if (!isundead(lf)) {
|
||||
if (!isundead(lf) && (lf->race->raceclass->id != RC_PLANT)) {
|
||||
dblog(".oO { i am mindless and not undead }");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// already targetting this lf?
|
||||
f = lfhasflagval(lf, F_TARGETLF, victim->id, NA, NA, NULL);
|
||||
if (f) {
|
||||
dblog(".oO { i am already targetting this lf }");
|
||||
if ((f->lifetime > 0) && (f->lifetime < timelimit)) {
|
||||
f->lifetime = timelimit;
|
||||
dblog(".oO { (flag lifetime updated) }");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -62,7 +68,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
penalty = (getcelldist(lf->cell, victim->cell)-1);
|
||||
if (penalty < 0) penalty = 0;
|
||||
penalty *= 3;
|
||||
if (!skillcheckvs(lf, SC_WILL, -penalty, victim, SC_WILL, 0)) {
|
||||
if (!skillcheckvs(lf, SC_WILL, -penalty, victim, SC_WILL, 5)) {
|
||||
dblog(".oO { attempted target fooled me with feign death. ignoring. }");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1426,6 +1432,7 @@ void aiturn(lifeform_t *lf) {
|
|||
if (aiattack(lf, newtarget, DEF_AIFOLLOWTIME)) {
|
||||
// failed for some reason. maybe target was feigning
|
||||
// death?
|
||||
if (db) dblog(".oO { setting a new target via aiattack failed! }");
|
||||
} else {
|
||||
// then move towards them...
|
||||
if (db) dblog(".oO { moving towards my new target (%d,%d) -> (%d,%d) }", lf->cell->x, lf->cell->y,
|
||||
|
@ -1790,8 +1797,8 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
}
|
||||
if ((ot->id == OT_A_SWOOP) || (ot->id == OT_A_CHARGE)) {
|
||||
flag_t *willflag;
|
||||
flag_t *srflag;
|
||||
cell_t *adjcell;
|
||||
flag_t *willflag, *srflag;
|
||||
int srange = 5;
|
||||
|
||||
willflag = lfhasflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
|
||||
|
@ -1805,8 +1812,10 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
srange = srflag->val[0];
|
||||
}
|
||||
|
||||
|
||||
if (!haslof(lf->cell, victim->cell, LOF_NEED,NULL)) {
|
||||
adjcell = get_closest_adjcell(lf->cell, victim->cell);
|
||||
if (!adjcell || celldangerous(lf, adjcell, B_TRUE, NULL)) { // don't charge into dangerous cells
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (!haslof(lf->cell, victim->cell, LOF_NEED,NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (isimmobile(lf)) {
|
||||
specificcheckok = B_FALSE;
|
||||
|
|
5
attack.c
5
attack.c
|
@ -1454,6 +1454,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (isplayer(victim)) {
|
||||
msg("Your %s protects you.", noprefix(obname));
|
||||
} else if (cansee(player, victim)) {
|
||||
getlfname(victim, victimname);
|
||||
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
|
@ -1483,6 +1484,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (isplayer(victim)) {
|
||||
msg("Your %s protects you.", noprefix(obname));
|
||||
} else if (cansee(player, victim)) {
|
||||
getlfname(victim, victimname);
|
||||
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
|
||||
}
|
||||
}
|
||||
|
@ -1496,6 +1498,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (isplayer(victim)) {
|
||||
msg("Your %s protects you.", noprefix(obname));
|
||||
} else if (cansee(player, victim)) {
|
||||
getlfname(victim, victimname);
|
||||
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
|
@ -1515,6 +1518,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (isplayer(victim)) {
|
||||
msg("Your %s protects you.", noprefix(obname));
|
||||
} else if (cansee(player, victim)) {
|
||||
getlfname(victim, victimname);
|
||||
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
|
@ -1528,6 +1532,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
|
|||
if (isplayer(victim)) {
|
||||
msg("Your %s protects you.", noprefix(obname));
|
||||
} else if (cansee(player, victim)) {
|
||||
getlfname(victim, victimname);
|
||||
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
20
defs.h
20
defs.h
|
@ -29,6 +29,9 @@
|
|||
#define DEF_TURNPCT 40
|
||||
#define DEF_WINDOWPCT 5
|
||||
|
||||
// lifeform defaults
|
||||
#define DEF_HITDICE "1d4"
|
||||
|
||||
// getrandomemptycell() params
|
||||
#define WE_WALKABLE 1
|
||||
#define WE_EMPTY 2
|
||||
|
@ -39,6 +42,8 @@
|
|||
// Booleans
|
||||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
#define B_ONPURPOSE (-1)
|
||||
#define B_CHANGEDIR (-1)
|
||||
#define B_VIS (1)
|
||||
#define B_UNKNOWN (0)
|
||||
#define B_NOVIS (-1)
|
||||
|
@ -596,6 +601,7 @@ enum CELLTYPE {
|
|||
CT_CORRIDOR,
|
||||
CT_DIRT,
|
||||
CT_VILLAGEGROUND,
|
||||
CT_FAKE,
|
||||
CT_FLOORSHOP,
|
||||
CT_FLOORWOOD,
|
||||
CT_GRASS,
|
||||
|
@ -711,7 +717,7 @@ enum BLESSTYPE {
|
|||
B_CURSED = -1
|
||||
};
|
||||
|
||||
#define RARITYVARIANCELF (5)
|
||||
#define RARITYVARIANCELF (1)
|
||||
#define RARITYVARIANCEOB (10)
|
||||
|
||||
enum RARITY {
|
||||
|
@ -1232,6 +1238,7 @@ enum OBTYPE {
|
|||
// -- translocation
|
||||
OT_S_APPORTATION,
|
||||
OT_S_BLINK,
|
||||
OT_S_BLINKASS,
|
||||
OT_S_DISPERSAL,
|
||||
OT_S_GATE,
|
||||
OT_S_PLANESHIFT,
|
||||
|
@ -1456,8 +1463,10 @@ enum OBTYPE {
|
|||
// armour - ears
|
||||
OT_EARPLUGS,
|
||||
// armour - eyes
|
||||
OT_SUNGLASSES,
|
||||
OT_SAFETYGLASSES,
|
||||
OT_SPECTACLES,
|
||||
OT_EYEPATCH,
|
||||
OT_SUNGLASSES,
|
||||
// armour - shields
|
||||
OT_BUCKLER,
|
||||
OT_SHIELD,
|
||||
|
@ -2304,7 +2313,7 @@ enum FLAG {
|
|||
// ie 'magic armour', 'force field'
|
||||
// v0 is power left.
|
||||
F_ASLEEP, // lf is asleep.
|
||||
// if v1 is set, means we are 'meditating' instead
|
||||
// v1 is enum sleeptype st_xxx
|
||||
// if v2 is set, means we are sleeping on
|
||||
// purpose and will wake up when at full hp/mp/etc.
|
||||
F_ATTACHEDTO, // you are attached to lf id v0, and will move with it
|
||||
|
@ -2493,6 +2502,7 @@ enum FLAG {
|
|||
F_VAULTATONEOF, // v0=thingtype, v1 = pctchance
|
||||
// text=(x,y)(x,y)(x,y)...(x,y) thingname
|
||||
F_VAULTBOX, // v0=thingtype, v1=pctchance, v2=fill?, text=x1,y1,x2,y2,thingname
|
||||
F_VAULTENTERTEXT, // text = what to show when player enters
|
||||
F_VAULTDLEVMIN, // v0 = mininum map depth/difficulty for this vault
|
||||
F_VAULTDLEVMAX, // v0 = maximum map depth/difficulty for this vault
|
||||
F_VAULTEXIT, // v0/1=x,y for exit.
|
||||
|
@ -2548,7 +2558,7 @@ enum INJURY {
|
|||
IJ_LEGBROKEN,
|
||||
IJ_LEGBRUISE,
|
||||
IJ_NOSEBROKEN,
|
||||
IJ_RIBCRACKED,
|
||||
IJ_RIBCRACKED, // can be from explosive too
|
||||
IJ_SHOULDERDISLOCATED,
|
||||
IJ_WINDPIPECRUSHED,
|
||||
// slashing
|
||||
|
@ -2562,7 +2572,9 @@ enum INJURY {
|
|||
IJ_EYELIDSCRAPED,
|
||||
IJ_EYEDESTROYED,
|
||||
// explosive
|
||||
IJ_EARSRINGING,
|
||||
IJ_HANDMISSING,
|
||||
IJ_LUNGCOLLAPSED,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@ Flags can be:
|
|||
dlevmax:xxx // can only randomly appear at or before dungeon
|
||||
// levle xxx
|
||||
|
||||
entertext:xxx // show xxx when a non-blind player enters
|
||||
|
||||
goesin:xxx // can only randomly appear in habitat xxx
|
||||
|
||||
margin:x,y // must be x/y away from edges of map
|
||||
|
|
251
io.c
251
io.c
|
@ -465,6 +465,7 @@ void animsky(cell_t *src, char ch, int colour) {
|
|||
|
||||
char askchar(char *prompt, char *validchars, char *def, int showchars) {
|
||||
char buf[BUFLEN];
|
||||
char msghistbuf[BUFLEN];
|
||||
char *p;
|
||||
char temp[2];
|
||||
char ch;
|
||||
|
@ -510,6 +511,11 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
|
|||
}
|
||||
}
|
||||
curs_set(0);
|
||||
|
||||
// update messaage history
|
||||
sprintf(msghistbuf, "%s%c", buf, ch);
|
||||
addmsghist(msghistbuf);
|
||||
|
||||
clearmsg();
|
||||
if ((ch == 10) && def) {
|
||||
return def[0];
|
||||
|
@ -771,7 +777,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
}
|
||||
// hp
|
||||
if (isgenius(player) || (getseenlfconditioncutoff(player) == C_HEALTHY) ||
|
||||
(getlorelevel(player, c->lf->race->raceclass->id) >= PR_ADEPT)
|
||||
(getlorelevel(player, c->lf->race->raceclass->id) >= PR_SKILLED)
|
||||
) {
|
||||
char buf2[BUFLEN];
|
||||
// show actual hp
|
||||
|
@ -1013,7 +1019,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
// retbuf must already be allocated
|
||||
// "def" is optional
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def) {
|
||||
char buf[BUFLEN];
|
||||
char buf[BUFLEN],msghistbuf[BUFLEN];
|
||||
char *ending;
|
||||
|
||||
more();
|
||||
|
@ -1040,6 +1046,10 @@ char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def)
|
|||
if (def && (strlen(retbuf) == 0)) {
|
||||
strcpy(retbuf, def);
|
||||
}
|
||||
|
||||
snprintf(msghistbuf, BUFLEN, "%s%s",buf,retbuf);
|
||||
addmsghist(msghistbuf);
|
||||
|
||||
drawcursor();
|
||||
return retbuf;
|
||||
}
|
||||
|
@ -1915,6 +1925,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
break;
|
||||
case F_FLEEFROM:
|
||||
msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
|
||||
if (!isplayer(lf)) {
|
||||
dblog("xx");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FRIENDLY:
|
||||
|
@ -2466,7 +2479,8 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
int c,i;
|
||||
object_t *mylist[MAXPILEOBS+1];
|
||||
char myletters[MAXPILEOBS+1];
|
||||
char numstring[BUFLEN];
|
||||
char msghistbuf[BUFLEN],numstring[BUFLEN],fullprompt[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
int firstob = 0;
|
||||
int nextpage = -1;
|
||||
int lastline = SCREENH-4;
|
||||
|
@ -2581,13 +2595,16 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
}
|
||||
// draw prompt
|
||||
if (strlen(numstring) > 0) {
|
||||
mvwprintw(mainwin, 0, 0, "%s (%sESC to quit) [%s]: ",prompt,
|
||||
snprintf(fullprompt, BUFLEN, "%s (%sESC to quit) [%s]: ",prompt,
|
||||
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : "",
|
||||
numstring);
|
||||
} else {
|
||||
mvwprintw(mainwin, 0, 0, "%s (%sESC to quit): ", prompt,
|
||||
snprintf(fullprompt, BUFLEN, "%s (%sESC to quit): ", prompt,
|
||||
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : "");
|
||||
}
|
||||
|
||||
mvwprintw(mainwin, 0, 0, "%s", fullprompt);
|
||||
|
||||
if (nextpage != -1) {
|
||||
mvwprintw(mainwin, y, 0, MORESTRING);
|
||||
}
|
||||
|
@ -2633,12 +2650,19 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
// display game windows again
|
||||
clearmsg();
|
||||
restoregamewindows();
|
||||
|
||||
|
||||
getobname(o, obname, count ? *count : o->amt);
|
||||
sprintf(msghistbuf, "%s%s",fullprompt,obname);
|
||||
addmsghist(msghistbuf);
|
||||
return o;
|
||||
}
|
||||
} else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing
|
||||
reason = E_SELNOTHING;
|
||||
// display game windows again
|
||||
restoregamewindows();
|
||||
sprintf(msghistbuf, "%s-",fullprompt);
|
||||
addmsghist(msghistbuf);
|
||||
return NULL;
|
||||
} else if (isdigit(ch) && count) {
|
||||
char temp[2];
|
||||
|
@ -2660,6 +2684,8 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
}
|
||||
}
|
||||
|
||||
sprintf(msghistbuf, "%s-",fullprompt);
|
||||
addmsghist(msghistbuf);
|
||||
// display game windows again
|
||||
restoregamewindows();
|
||||
return NULL;
|
||||
|
@ -2671,7 +2697,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
|
|||
int selected[MAXPILEOBS+1];
|
||||
int selcount[MAXPILEOBS+1];
|
||||
char myletters[MAXPILEOBS+1];
|
||||
char numstring[BUFLEN];
|
||||
char msghistbuf[BUFLEN],numstring[BUFLEN];
|
||||
char pbuf[BUFLEN];
|
||||
int firstob = 0;
|
||||
int nextpage = -1;
|
||||
|
@ -2706,8 +2732,6 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
|
|||
useobletters = B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// construct a list of objects
|
||||
c = 0;
|
||||
i = 0;
|
||||
|
@ -2857,6 +2881,8 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
|
|||
reason = E_SELNOTHING;
|
||||
nretobs = 0;
|
||||
// display game windows again
|
||||
sprintf(msghistbuf, "%s-", pbuf);
|
||||
addmsghist(msghistbuf);
|
||||
restoregamewindows();
|
||||
return B_TRUE;
|
||||
} else if (ch == ',') { // toggle all/none
|
||||
|
@ -2906,6 +2932,9 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
|
|||
// clear msg bar
|
||||
clearmsg();
|
||||
|
||||
sprintf(msghistbuf, "%s", pbuf);
|
||||
addmsghist(msghistbuf);
|
||||
|
||||
// display game windows again
|
||||
restoregamewindows();
|
||||
if (nretobs <= 0) {
|
||||
|
@ -3801,6 +3830,7 @@ void doeat(obpile_t *op) {
|
|||
ch = askchar(buf, "yn","n", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
eatob = o;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4272,6 +4302,17 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((f = hasflag(o->flags, F_IMPASSABLE)) != NULL) {
|
||||
if ((f->val[0] == SZ_MIN) && (f->val[1] == SZ_MAX)) {
|
||||
snprintf(buf, BUFLEN, "It is %simpassable.\n", hasflag(o->flags, F_DOOR) ? "currently " : "");
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "It is %simpassable for %s to %s sized creatures.\n",
|
||||
hasflag(o->flags, F_DOOR) ? "currently " : "",
|
||||
getsizetext(f->val[0]), getsizetext(f->val[1]));
|
||||
}
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
|
||||
if (isedible(o)) {
|
||||
int basenutr;
|
||||
basenutr = getnutritionbase(o);
|
||||
|
@ -5164,10 +5205,20 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) {
|
|||
// properties
|
||||
f = hasflag(ot->flags, F_SPELLLEVEL);
|
||||
if (f) {
|
||||
flag_t *sf;
|
||||
sf = hasflag(ot->flags, F_SPELLSCHOOL);
|
||||
assert(sf);
|
||||
sprintf(buf, "It is a level %d %s spell.\n",f->val[0], getschoolname(sf->val[0]));
|
||||
char schoollist[BUFLEN];
|
||||
strcpy(schoollist, "");
|
||||
getflags(ot->flags, retflag, &nretflags, F_SPELLSCHOOL, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (streq(schoollist, "")) { // first one
|
||||
strcpy(schoollist, getschoolname(retflag[i]->val[0]));
|
||||
} else {
|
||||
strcat(schoollist, "/");
|
||||
strcat(schoollist, getschoolname(retflag[i]->val[0]));
|
||||
}
|
||||
}
|
||||
assert(strlen(schoollist));
|
||||
|
||||
sprintf(buf, "It is a level %d %s spell.\n",f->val[0], schoollist);
|
||||
strncat(retbuf, buf, BUFLEN);
|
||||
}
|
||||
|
||||
|
@ -6606,7 +6657,7 @@ enum COLOUR getattrcolour(enum ATTRBRACKET brack) {
|
|||
char getchoice(prompt_t *prompt) {
|
||||
int i;
|
||||
int y;
|
||||
char ch;
|
||||
char ch,msghistbuf[BUFLEN],fullprompt[BUFLEN];
|
||||
int sel;
|
||||
int gotheadings;
|
||||
int first= 0;
|
||||
|
@ -6657,8 +6708,9 @@ char getchoice(prompt_t *prompt) {
|
|||
}
|
||||
|
||||
// display prompt question
|
||||
mvwprintw(mainwin, 0, 0, "%s %s", prompt->q[prompt->whichq],
|
||||
prompt->maycancel ? "[ESC to cancel] " : "");
|
||||
|
||||
snprintf(fullprompt, BUFLEN, "%s %s", prompt->q[prompt->whichq], prompt->maycancel ? "[ESC to cancel] " : "");
|
||||
mvwprintw(mainwin, 0, 0, "%s", fullprompt);
|
||||
wrefresh(mainwin);
|
||||
|
||||
// ask for choice...
|
||||
|
@ -6699,6 +6751,10 @@ char getchoice(prompt_t *prompt) {
|
|||
}
|
||||
curs_set(0);
|
||||
restoregamewindows();
|
||||
|
||||
snprintf(msghistbuf, BUFLEN, "%s%s",fullprompt,prompt->choice[i].desc);
|
||||
addmsghist(msghistbuf);
|
||||
|
||||
// return NUL or result char
|
||||
if (ch == 27) {
|
||||
return '\0';
|
||||
|
@ -6717,6 +6773,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
int lastline = SCREENH - 4;
|
||||
char inpstring[BUFLEN];
|
||||
char curheading[BUFLEN];
|
||||
char msghistbuf[BUFLEN];
|
||||
int doneheading;
|
||||
int nvalid;
|
||||
char promptstr[BUFLEN];
|
||||
|
@ -7007,6 +7064,14 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
restoregamewindows();
|
||||
}
|
||||
|
||||
snprintf(promptstr, BUFLEN, "%s [%s%s] ",
|
||||
prompt->q[prompt->whichq],
|
||||
prompt->maycancel ? "ESC," : "",
|
||||
showall ? "'=next page,?=toggle" : "?=list" );
|
||||
snprintf(msghistbuf, BUFLEN, "%s%s",promptstr,prompt->choice[i].text);
|
||||
addmsghist(msghistbuf);
|
||||
|
||||
// return NUL or result char
|
||||
if (ch == 27) {
|
||||
return '\0';
|
||||
|
@ -7648,7 +7713,8 @@ void msg_real(char *format, ... ) {
|
|||
assert(2 == 3);
|
||||
}
|
||||
|
||||
assert(!strchr(buf, '#'));
|
||||
//assert(!strchr(buf, '#'));
|
||||
|
||||
// ie. can the message buffer fit:
|
||||
// what is already there + 2 spaces + the new text + '--more--' ?
|
||||
//if (strlen(msgbuf) + 2 + strlen(buf) + strlen(MORESTRING) >= SCREENW) {
|
||||
|
@ -8440,13 +8506,13 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
if (showall ||
|
||||
(getseenlfconditioncutoff(player) == C_HEALTHY) ||
|
||||
(lorelev >= PR_ADEPT)) {
|
||||
(lorelev >= PR_SKILLED)) {
|
||||
int xx,yy;
|
||||
|
||||
doheadingsmall(mainwin, y, 0, ftext, "HP");
|
||||
if (lorelev >= PR_ADEPT) setcol(mainwin, lorecol);
|
||||
if (lorelev >= PR_SKILLED) setcol(mainwin, lorecol);
|
||||
wprintw(mainwin, "%d/%d ", lf->hp , lf->maxhp);
|
||||
if (lorelev >= PR_ADEPT) unsetcol(mainwin, lorecol);
|
||||
if (lorelev >= PR_SKILLED) unsetcol(mainwin, lorecol);
|
||||
|
||||
getyx(mainwin, yy, xx);
|
||||
doheadingsmall(mainwin, y, xx, "%5s:", "Stam");
|
||||
|
@ -8598,7 +8664,6 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y2++;
|
||||
|
||||
// current weapon + dam
|
||||
|
||||
nweps = 0;
|
||||
|
||||
o = getweapon(lf);
|
||||
|
@ -8613,70 +8678,83 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nweps; i++) {
|
||||
if (w[i]) {
|
||||
int mindam,maxdam;
|
||||
int bonus,speed;
|
||||
|
||||
// weapon
|
||||
if (showall) {
|
||||
char buf2[BUFLEN];
|
||||
// calculate damage
|
||||
f = hasflag(w[i]->flags, F_BONUS);
|
||||
if (f && f->known) {
|
||||
// only tell player about bonuses if they are known.!
|
||||
bonus = f->val[0];
|
||||
if (nweps == 0) {
|
||||
int speed;
|
||||
// no weapon
|
||||
snprintf(buf, BUFLEN, "(innate attack)");
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
// attack speed
|
||||
acc = getlfaccuracy(lf, NULL);
|
||||
speed = getattackspeed(lf);
|
||||
getspeedname(speed, buf2);
|
||||
capitalise(buf2);
|
||||
snprintf(buf, BUFLEN, "%s, %d%%",buf2,acc);
|
||||
mvwprintw(mainwin, y2, x2, "%14s", " ");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
} else {
|
||||
for (i = 0; i < nweps; i++) {
|
||||
if (w[i]) {
|
||||
int mindam,maxdam;
|
||||
int bonus,speed;
|
||||
|
||||
// weapon
|
||||
if (showall) {
|
||||
char buf2[BUFLEN];
|
||||
// calculate damage
|
||||
f = hasflag(w[i]->flags, F_BONUS);
|
||||
if (f && f->known) {
|
||||
// only tell player about bonuses if they are known.!
|
||||
bonus = f->val[0];
|
||||
} else {
|
||||
bonus = 0;
|
||||
}
|
||||
|
||||
f = hasflag(w[i]->flags, F_DAM);
|
||||
if (f) {
|
||||
getdamrange(f, &mindam, &maxdam);
|
||||
} else {
|
||||
mindam = 0;
|
||||
maxdam = 0;
|
||||
}
|
||||
|
||||
mindam += bonus;
|
||||
maxdam += bonus;
|
||||
|
||||
// apply damage mod for strength
|
||||
if (!hasflag(w[i]->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
mindam = (int)((float)mindam * dammod);
|
||||
maxdam = (int)((float)maxdam * dammod);
|
||||
}
|
||||
|
||||
if (mindam < 0) mindam = 0;
|
||||
if (maxdam < 0) maxdam = 0;
|
||||
|
||||
|
||||
snprintf(buf, BUFLEN, "%s (%d-%d dmg)", w[i]->type->name,(int)mindam,(int)maxdam);
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
// attack speed
|
||||
acc = getlfaccuracy(lf, w[i]);
|
||||
speed = getattackspeed(lf);
|
||||
getspeedname(speed, buf2);
|
||||
capitalise(buf2);
|
||||
snprintf(buf, BUFLEN, "%s, %d%%",buf2,acc);
|
||||
mvwprintw(mainwin, y2, x2, "%14s", " ");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
} else {
|
||||
bonus = 0;
|
||||
// just show weapon name
|
||||
snprintf(buf, BUFLEN, "%s", w[i]->type->name);
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
}
|
||||
|
||||
f = hasflag(w[i]->flags, F_DAM);
|
||||
if (f) {
|
||||
getdamrange(f, &mindam, &maxdam);
|
||||
} else {
|
||||
mindam = 0;
|
||||
maxdam = 0;
|
||||
}
|
||||
|
||||
mindam += bonus;
|
||||
maxdam += bonus;
|
||||
|
||||
// apply damage mod for strength
|
||||
if (!hasflag(w[i]->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
mindam = (int)((float)mindam * dammod);
|
||||
maxdam = (int)((float)maxdam * dammod);
|
||||
}
|
||||
|
||||
if (mindam < 0) mindam = 0;
|
||||
if (maxdam < 0) maxdam = 0;
|
||||
|
||||
|
||||
snprintf(buf, BUFLEN, "%s (%d-%d dmg)", w[i]->type->name,(int)mindam,(int)maxdam);
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
// attack speed
|
||||
acc = getlfaccuracy(lf, w[i]);
|
||||
speed = getattackspeed(lf);
|
||||
getspeedname(speed, buf2);
|
||||
capitalise(buf2);
|
||||
snprintf(buf, BUFLEN, "%s, %d%%",buf2,acc);
|
||||
mvwprintw(mainwin, y2, x2, "%14s", " ");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
|
||||
} else {
|
||||
// just show weapon name
|
||||
snprintf(buf, BUFLEN, "%s", w[i]->type->name);
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
}
|
||||
} else {
|
||||
// no weapon
|
||||
snprintf(buf, BUFLEN, "N/A");
|
||||
doheadingsmall(mainwin, y2, x2, ftext, "Current Weapon");
|
||||
wprintw(mainwin, "%-20s", buf); y2++;
|
||||
}
|
||||
} // end for each weapon
|
||||
} // end for each weapon
|
||||
}
|
||||
|
||||
// skip a line
|
||||
y2++;
|
||||
|
@ -9482,6 +9560,15 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_CANCAST)) {
|
||||
int chance;
|
||||
chance = getmiscastchance(lf);
|
||||
if (chance) {
|
||||
mvwprintw(mainwin, y, 0, "%s spells have a %d%% chance of failing due to cumbersome armour.", your(lf), chance);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
// flags which aren't really intrinsics
|
||||
if (lfhasflag(lf, F_AQUATIC)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s aquatic, and move normally through water.", you(lf), is(lf));
|
||||
|
@ -9564,8 +9651,8 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s %s confused.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_DEAF);
|
||||
if (f) {
|
||||
|
||||
if (isdeaf(lf)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s deaf.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
|
|
266
lf.c
266
lf.c
|
@ -25,6 +25,8 @@ extern FILE *logfile;
|
|||
|
||||
extern void (*precalclos)(lifeform_t *);
|
||||
|
||||
extern int noredraw;
|
||||
|
||||
extern map_t *firstmap;
|
||||
extern race_t *firstrace, *lastrace;
|
||||
extern raceclass_t *firstraceclass, *lastraceclass;
|
||||
|
@ -36,6 +38,8 @@ extern lifeform_t *player;
|
|||
extern glyph_t playerglyph;
|
||||
extern glyph_t tempglyph;
|
||||
|
||||
extern int maxmonhitdice;
|
||||
|
||||
extern npcname_t *npcname;
|
||||
extern int numnpcnames;
|
||||
|
||||
|
@ -684,7 +688,7 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
|
|||
|
||||
// can't hear if you are deaf or have no ears
|
||||
if (!hasbp(lf, BP_EARS)) return B_FALSE;
|
||||
if (lfhasflag(lf, F_DEAF)) return B_FALSE;
|
||||
if (isdeaf(lf)) return B_FALSE;
|
||||
|
||||
// can't hear when training
|
||||
if (lfhasflag(lf, F_TRAINING)) return B_FALSE;
|
||||
|
@ -1293,6 +1297,15 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
// lose mp
|
||||
losemp(lf, cost);
|
||||
|
||||
// miscast chance?
|
||||
if (isplayer(lf)) {
|
||||
if (pctchance(getmiscastchance(lf))) {
|
||||
msg("^WYour cumbersome armour makes you miscast your spell!");
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (power > 1) {
|
||||
// half strength
|
||||
|
@ -1300,7 +1313,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
if (power <= 1) power = 1;
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("^wYour magic resistance interferes with your spell!");
|
||||
msg("^wYour magic resistance lowers your spell's power.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2209,6 +2222,33 @@ void dumplf(void) {
|
|||
dblog("END LIFEFORM DUMP (%d found)",count);
|
||||
}
|
||||
|
||||
void dumpmonsters(void) {
|
||||
race_t *r;
|
||||
flag_t *f;
|
||||
int count = 0,wanthd;
|
||||
|
||||
dblog("START MONSTER DUMP:");
|
||||
for (wanthd = 0; wanthd < maxmonhitdice ; wanthd++) {
|
||||
dblog("%d HIT DICE MONSTERS:",wanthd);
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
int thishd;
|
||||
|
||||
thishd = gethitdicerace(r);
|
||||
if (thishd == wanthd) {
|
||||
int ndice,nsides,bonus,min,max;
|
||||
f = hasflag(r->flags, F_HITDICE);
|
||||
texttodice(f->text ? f->text : DEF_HITDICE, &ndice,&nsides,&bonus);
|
||||
|
||||
min = ndice + bonus;
|
||||
max = (ndice*nsides) + bonus;
|
||||
dblog("\t%s (%d avg hp)",r->name, (min+max)/2);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dblog("END MONSTER DUMP (%d found)",count);
|
||||
}
|
||||
|
||||
void genxplist(void) {
|
||||
race_t *r;
|
||||
race_t *racetemp;
|
||||
|
@ -2488,37 +2528,34 @@ void dumplev(void) {
|
|||
race_t *r;
|
||||
objecttype_t *ot;
|
||||
flag_t *f;
|
||||
dblog("Start monster dump");
|
||||
dblog("Start lev monster dump");
|
||||
dblog("------------------\n");
|
||||
// NOTE: this code copied from getrandomrace(), which is used by addmonster().
|
||||
for (i = 1; i <= 25; i++) {
|
||||
int min,max,prevmin,prevmax;
|
||||
getrarityrange(i-1, &prevmin, &prevmax, RARITYVARIANCELF, B_FALSE);
|
||||
getrarityrange(i, &min, &max, RARITYVARIANCELF, B_FALSE);
|
||||
fprintf(logfile, "Dlev %d (rar >= %d): ",i,min);
|
||||
gethitdicerange(i-1, &prevmin, &prevmax, RARITYVARIANCELF, B_FALSE);
|
||||
gethitdicerange(i, &min, &max, RARITYVARIANCELF, B_FALSE);
|
||||
fprintf(logfile, "Dlev %d (hd >= %d): ",i,min);
|
||||
for (r = firstrace ; r; r = r->next) {
|
||||
int rarity = 0;
|
||||
f = hasflagval(r->flags, F_RARITY, H_DUNGEON, NA, NA, NULL);
|
||||
if (f) {
|
||||
rarity = f->val[1];
|
||||
// ok this lev?
|
||||
if ((rarity >= min) && (rarity <= max)) {
|
||||
char buf[BUFLEN];
|
||||
strcpy(buf, "");
|
||||
// ok on previous lev too?
|
||||
if ((rarity >= prevmin) && (rarity <= prevmax)) {
|
||||
// only print if dlev is 1
|
||||
if (i == 1) {
|
||||
snprintf(buf, BUFLEN, "%s, ", r->name);
|
||||
}
|
||||
} else {
|
||||
// ie. new mosnter for this lev
|
||||
//snprintf(buf, BUFLEN, "*%s*, ", r->name);
|
||||
//makeuppercase(buf);
|
||||
int hd = 0;
|
||||
hd = gethitdicerace(r);
|
||||
// ok this lev?
|
||||
if ((hd >= min) && (hd <= max)) {
|
||||
char buf[BUFLEN];
|
||||
strcpy(buf, "");
|
||||
// ok on previous lev too?
|
||||
if ((hd >= prevmin) && (hd <= prevmax)) {
|
||||
// only print if dlev is 1
|
||||
if (i == 1) {
|
||||
snprintf(buf, BUFLEN, "%s, ", r->name);
|
||||
}
|
||||
fprintf(logfile, "%s", buf);
|
||||
}
|
||||
} else {
|
||||
// ie. new mosnter for this lev
|
||||
//snprintf(buf, BUFLEN, "*%s*, ", r->name);
|
||||
//makeuppercase(buf);
|
||||
snprintf(buf, BUFLEN, "%s, ", r->name);
|
||||
}
|
||||
fprintf(logfile, "%s", buf);
|
||||
}
|
||||
}
|
||||
fprintf(logfile, "\n");
|
||||
|
@ -2527,7 +2564,6 @@ void dumplev(void) {
|
|||
|
||||
dblog("Start object dump");
|
||||
dblog("------------------\n");
|
||||
// NOTE: this code copied from getrandomrace(), which is used by addmonster().
|
||||
for (i = 1; i <= 25; i++) {
|
||||
int min,max,prevmin,prevmax;
|
||||
getrarityrange(i-1, &prevmin, &prevmax, RARITYVARIANCEOB, B_FALSE);
|
||||
|
@ -3280,7 +3316,7 @@ void enhanceskills(lifeform_t *lf) {
|
|||
|
||||
// psionics sometimes lets you learn spells
|
||||
slev = getskill(lf, SK_SS_MENTAL);
|
||||
if (pctchance(slev*10)) {
|
||||
if (pctchance(slev*20)) {
|
||||
// construct list of castable mental spells
|
||||
makespellchoicelist(&prompt, lf, "Learn which new psionic power:","Describe which psionic power:", SS_MENTAL, B_TRUE, B_FALSE, B_FALSE, player->maxmp);
|
||||
if (prompt.nchoices > 0) {
|
||||
|
@ -3347,7 +3383,7 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) {
|
|||
}
|
||||
}
|
||||
}
|
||||
taketime(lf, SP_NORMAL*2);
|
||||
//taketime(lf, SP_NORMAL*2);
|
||||
|
||||
addflag(lf->flags, F_PRONE, B_TRUE, NA, NA, NULL);
|
||||
loseconcentration(lf);
|
||||
|
@ -3626,20 +3662,21 @@ int flee(lifeform_t *lf) {
|
|||
if (!nretflags) return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// now determine who to flee from.
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->id == F_FLEEFROM) {
|
||||
lifeform_t *thisone;
|
||||
thisone = findlf(lf->cell->map, f->val[0]);
|
||||
if (thisone) {
|
||||
if (cansee(lf, thisone)) {
|
||||
// TODO: this really means that the monster is cheating
|
||||
if (haslof(lf->cell, thisone->cell, LOF_WALLSTOP, NULL)) {
|
||||
// if not fleeing from anyone, or this one is closer...
|
||||
if (!fleefrom || getcelldist(lf->cell, thisone->cell) < getcelldist(lf->cell, fleefrom->cell)) {
|
||||
fleefrom = thisone;
|
||||
}
|
||||
} else {
|
||||
// if we can't see the person we're running from, and it's not enforced for
|
||||
// if we don't have LOF to the person we're running from, and it's not enforced for
|
||||
// a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing.
|
||||
if (f->lifetime == PERMENANT) {
|
||||
// player let something flee?
|
||||
|
@ -3653,6 +3690,8 @@ int flee(lifeform_t *lf) {
|
|||
fleefrom = thisone;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5084,6 +5123,17 @@ int gethitdice(lifeform_t *lf) {
|
|||
return (lf->maxhp / 4);
|
||||
}
|
||||
|
||||
int gethitdicerace(race_t *r) {
|
||||
flag_t *f;
|
||||
f = hasflag(r->flags, F_HITDICE);
|
||||
if (f) {
|
||||
int ndice,nsides,bonus;
|
||||
texttodice(f->text ? f->text : DEF_HITDICE, &ndice,&nsides,&bonus);
|
||||
return ((ndice*nsides)+bonus) / 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int gethppct(lifeform_t *lf) {
|
||||
float pct;
|
||||
pct = (int)(((float)lf->hp / (float)lf->maxhp) * 100);
|
||||
|
@ -5218,7 +5268,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
|
|||
if (wep) {
|
||||
acc = getobaccuracy(wep, lf);
|
||||
} else {
|
||||
acc = 100; // fists
|
||||
acc = 100; // innate attack
|
||||
}
|
||||
|
||||
// dual weilding?
|
||||
|
@ -5415,6 +5465,18 @@ int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions) {
|
|||
return *nminions;
|
||||
}
|
||||
|
||||
int getmiscastchance(lifeform_t *lf) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
int chance = 0;
|
||||
getflags(lf->flags, retflag, &nretflags, F_ARMOURPENALTY, F_SHIELDPENALTY, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->val[0] != NA) chance += retflag[i]->val[0];
|
||||
if (retflag[i]->val[1] != NA) chance += retflag[i]->val[1];
|
||||
}
|
||||
return chance;
|
||||
}
|
||||
|
||||
int getnightvisrange(lifeform_t *lf) {
|
||||
int range = 0; // default
|
||||
flag_t *f;
|
||||
|
@ -5704,7 +5766,13 @@ float getmaxpushweight(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
float getmaxstamina(lifeform_t *lf) {
|
||||
return (getattr(lf, A_CON) / 2);
|
||||
int stam = 0;
|
||||
if (lfhasflagval(lf, F_INJURY, IJ_LUNGCOLLAPSED, NA, NA, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
stam = (getattr(lf, A_CON) / 2);
|
||||
stam += (getskill(lf, SK_ATHLETICS)*2);
|
||||
return stam;
|
||||
}
|
||||
|
||||
int getmr(lifeform_t *lf) {
|
||||
|
@ -6352,7 +6420,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
int selidx;
|
||||
int db = B_FALSE;
|
||||
int depth;
|
||||
int raritymin,raritymax;
|
||||
int hdmin,hdmax;
|
||||
enum RARITY wantrr = RR_COMMON;
|
||||
|
||||
// determine rarity of lf to generate
|
||||
|
@ -6362,7 +6430,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
depth = getmapdifficulty((c && c->map) ? c->map : NULL);
|
||||
}
|
||||
|
||||
getrarityrange(depth, &raritymin, &raritymax, RARITYVARIANCELF, B_TRUE);
|
||||
gethitdicerange(depth, &hdmin, &hdmax, RARITYVARIANCELF, B_TRUE);
|
||||
|
||||
// pick rr...
|
||||
wantrr = RR_COMMON;
|
||||
|
@ -6370,7 +6438,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
wantrr++;
|
||||
}
|
||||
|
||||
if (db) dblog("finding random lf with rarity val %d-%d and rr <= %d\n",raritymin,raritymax, wantrr);
|
||||
if (db) dblog("finding random lf with hitdice %d-%d and rr <= %d\n",hdmin,hdmax, wantrr);
|
||||
|
||||
// try to find a lf of this type which will
|
||||
// fit in the map's habitat
|
||||
|
@ -6378,23 +6446,31 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
while (nposs == 0) {
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
int valid = B_FALSE;
|
||||
int thishd;
|
||||
enum RARITY thisrr = RR_NEVER;
|
||||
flag_t *rarflag = NULL;
|
||||
|
||||
// correct rarity?
|
||||
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (c) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
thishd = gethitdicerace(r);
|
||||
if ((thishd < hdmin) || (thishd > hdmax)) {
|
||||
valid = B_FALSE;
|
||||
} else {
|
||||
// correct rarity?
|
||||
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (c) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rarflag) {
|
||||
if ((rarflag->val[1] >= raritymin) && (rarflag->val[1] <= raritymax)) {
|
||||
if (rarflag) {
|
||||
if ((rarflag->val[2] == NA) || (rarflag->val[2] <= wantrr)) {
|
||||
valid = B_TRUE;
|
||||
thisrr = rarflag->val[2];
|
||||
}
|
||||
} else {
|
||||
valid = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6415,7 +6491,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
}
|
||||
|
||||
if (valid) {
|
||||
if (db) dblog("-> possibility: %s, rarity=%d",r->name, rarflag->val[1]);
|
||||
if (db) dblog("-> possibility: %s, hitdice=%d, rarity=%s",r->name, thishd, getrarityname(thisrr));
|
||||
poss[nposs] = r;
|
||||
nposs++;
|
||||
if (nposs >= MAXRANDOMLFCANDIDATES) break;
|
||||
|
@ -6424,17 +6500,17 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
|
||||
// nothing found?
|
||||
if (nposs == 0) {
|
||||
// already at lowest rarity?
|
||||
if ((raritymax >= 100) && (raritymin <= 0)) {
|
||||
// already at lowest hitdice?
|
||||
if ((hdmax >= maxmonhitdice) && (hdmin <= 0)) {
|
||||
// give up
|
||||
if (db) dblog("no possible lf at all! giving up.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// expand range and try again
|
||||
raritymax += 10; if (raritymax > 100) raritymax = 100;
|
||||
raritymin -= 10; if (raritymin < 0) raritymin = 0;
|
||||
if (db) dblog("no possible lfs like this. trying again with rarity %d-%d\n",raritymin,raritymax);
|
||||
hdmax ++; if (hdmax > maxmonhitdice) hdmax = maxmonhitdice;
|
||||
hdmin --; if (hdmin < 0) hdmin = 0;
|
||||
if (db) dblog("no possible lfs like this. trying again with hitdice %d-%d\n",hdmin,hdmax);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7893,13 +7969,13 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
|||
switch (where) {
|
||||
case BP_BODY:
|
||||
switch (rnd(1,2)) {
|
||||
case 1:
|
||||
break;
|
||||
case 1: // collapsed lung
|
||||
inj = IJ_LUNGCOLLAPSED;
|
||||
desc = strdup("lungs have collapsed^lose all stamina points");
|
||||
case 2:
|
||||
inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break;
|
||||
break;
|
||||
}
|
||||
// massive burns
|
||||
// collapsed lung
|
||||
break;
|
||||
case BP_HANDS:
|
||||
// lose limb
|
||||
|
@ -7936,8 +8012,15 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
|||
}
|
||||
break;
|
||||
case BP_HEAD:
|
||||
// ringing ears
|
||||
// burnt eyes
|
||||
switch (rnd(1,2)) {
|
||||
case 1: // ringing ears
|
||||
inj = IJ_EARSRINGING;
|
||||
desc = strdup("ears are ringing^cannot hear sounds");
|
||||
case 2: // blinded
|
||||
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(50,100));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BP_LEGS:
|
||||
// lose limb
|
||||
|
@ -8651,6 +8734,12 @@ void killlf(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
int isdeaf(lifeform_t *lf) {
|
||||
if (lfhasflag(lf, F_DEAF)) return B_TRUE;
|
||||
if (lfhasflagval(lf, F_INJURY, IJ_EARSRINGING, NA, NA, NULL)) return B_TRUE;
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// returns second weapon if you are dual weilding
|
||||
object_t *isdualweilding(lifeform_t *lf) {
|
||||
object_t *priwep,*secwep;
|
||||
|
@ -9102,7 +9191,6 @@ race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcol
|
|||
lastrace = a;
|
||||
a->next = NULL;
|
||||
|
||||
|
||||
// props
|
||||
a->id = id;
|
||||
a->baseid = id; // default
|
||||
|
@ -10807,14 +10895,14 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
|
|||
// adjust it if you're deaf
|
||||
strcpy(realseetext, seetext);
|
||||
quotepos = strchr(realseetext, '\"');
|
||||
if (lfhasflag(l, F_DEAF) && quotepos) {
|
||||
if (isdeaf(l) && quotepos) {
|
||||
*quotepos = '\0';
|
||||
strcat(realseetext, "something");
|
||||
}
|
||||
msg("%s %s.", lfname, realseetext);
|
||||
rv = B_TRUE;
|
||||
}
|
||||
} else if (text && !lfhasflag(l, F_DEAF) && ((nt != NC_WALK) || !lfhasflag(l, F_DONELISTEN))) {
|
||||
} else if (text && !isdeaf(l) && ((nt != NC_WALK) || !lfhasflag(l, F_DONELISTEN))) {
|
||||
// this means you can only hear one 'walk' sound per turn
|
||||
char textnopunc[BUFLEN];
|
||||
char punc;
|
||||
|
@ -11070,8 +11158,7 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int want
|
|||
|
||||
if (!failed) {
|
||||
// warn if it is too heavy
|
||||
if (isplayer(lf) && !isburdened(lf) &&
|
||||
(getobpileweight(lf->pack) + (getobunitweight(what)*howmany) > getmaxcarryweight(lf)) ) {
|
||||
if (isplayer(lf) && !isburdened(lf) && willburden(lf, what, howmany)) {
|
||||
char ch,buf[BUFLEN];
|
||||
snprintf(buf, BUFLEN, "Picking up %s will burden you. Continue", obname);
|
||||
ch = askchar(buf, "yn","n", B_TRUE);
|
||||
|
@ -11281,6 +11368,8 @@ void precalclos_new(lifeform_t *lf) {
|
|||
enum SKILLLEVEL plev;
|
||||
flag_t *missingeye;
|
||||
|
||||
if (lf->cell->type->id == CT_FAKE) return;
|
||||
|
||||
f = hasflag(lf->flags, F_XRAYVIS);
|
||||
if (f) {
|
||||
startxray = f->val[0];
|
||||
|
@ -12450,7 +12539,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
break;
|
||||
case SC_LISTEN:
|
||||
// if you are asleep, listen check doesn't help.
|
||||
if (lfhasflag(lf, F_ASLEEP) || lfhasflag(lf, F_DEAF)) {
|
||||
if (lfhasflag(lf, F_ASLEEP) || isdeaf(lf)) {
|
||||
attrib = 0;
|
||||
} else {
|
||||
attrib = getskill(lf, SK_LISTEN);
|
||||
|
@ -12983,7 +13072,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
int nretcells;
|
||||
getradiuscells(lf->cell, 2, DT_COMPASS, LOF_WALLSTOP, B_FALSE, retcell, &nretcells, 0);
|
||||
for (i = 0; i < nretcells; i++) {
|
||||
if (retcell[i]->lf && !areallies(lf, retcell[i]->lf)) {
|
||||
if (retcell[i]->lf && areenemies(lf, retcell[i]->lf)) {
|
||||
int dir,reldir;
|
||||
dir = getdirtowards(lf->cell, retcell[i], NULL, B_FALSE, DT_ORTH);
|
||||
reldir = getrelativedir(lf, dir);
|
||||
|
@ -12991,7 +13080,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
if (isplayer(lf)) {
|
||||
if (f->val[2] >= 5) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(retcell[i]->lf, buf);
|
||||
real_getlfnamea(retcell[i]->lf, buf, B_FALSE);
|
||||
warn("^WYour sixth sense warns you of %s %s you!", buf,
|
||||
(reldir == RD_BACKWARDS) ? "behind" : "beside" );
|
||||
} else if (f->val[2] >= 3) {
|
||||
|
@ -13003,7 +13092,15 @@ void startlfturn(lifeform_t *lf) {
|
|||
warn("^WYour sixth sense warns you of something %s you!",
|
||||
(reldir == RD_BACKWARDS) ? "behind" : "beside" );
|
||||
}
|
||||
more();
|
||||
if (f->val[2] >= 7) {
|
||||
char ch;
|
||||
ch = askchar("Turn to face the threat", "yn","y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
turntoface(lf, retcell[i]);
|
||||
}
|
||||
} else {
|
||||
more();
|
||||
}
|
||||
}
|
||||
stopspell(lf, OT_S_SIXTHSENSE);
|
||||
break;
|
||||
|
@ -13166,7 +13263,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
if (!lfhasflag(lf, F_TRAINING) && haslos(lf, l->cell)) {
|
||||
int bonus = 0;
|
||||
int dist;
|
||||
if (!lfhasflag(l, F_SILENTMOVE) && !lfhasflag(lf, F_DEAF)) {
|
||||
if (!lfhasflag(l, F_SILENTMOVE) && !isdeaf(lf)) {
|
||||
bonus += getskill(lf, SK_LISTEN);
|
||||
}
|
||||
|
||||
|
@ -13744,14 +13841,14 @@ void stopresting(lifeform_t *lf) {
|
|||
// stop resting!
|
||||
f = isresting(lf);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s is interrupted!", (f->val[1] == ST_MEDITATING) ? "meditation" : "rest");
|
||||
} else if (cansee(player, lf)) {
|
||||
char buf[BUFLEN];
|
||||
getlfname(lf, buf);
|
||||
msg("%s stops %s.",buf, (f->val[1] == NA) ? "resting" : "meditating");
|
||||
msg("%s stops %s.",buf, (f->val[1] == ST_MEDITATING) ? "meditating" : "resting");
|
||||
}
|
||||
killflag(f);
|
||||
statdirty = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -14689,21 +14786,23 @@ int validateraces(void) {
|
|||
// generate xp list
|
||||
genxplist();
|
||||
|
||||
|
||||
// make a fake cell
|
||||
fakemap.lf = NULL;
|
||||
fakemap.lastlf = NULL;
|
||||
setcelltype(&fakecell, CT_CORRIDOR);
|
||||
fakecell.lf = NULL;
|
||||
fakecell.map = &fakemap;
|
||||
createfakes(&fakemap, &fakecell);
|
||||
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
lifeform_t *lf;
|
||||
int thishd;
|
||||
|
||||
// add a fake lf
|
||||
lf = addlf(&fakecell, r->id, 1);
|
||||
givestartskills(lf, lf->flags);
|
||||
|
||||
// remember max. hitdice for use in dumpmonsters()
|
||||
thishd = gethitdice(lf);
|
||||
if (thishd > maxmonhitdice) {
|
||||
maxmonhitdice = thishd;
|
||||
}
|
||||
|
||||
|
||||
if (!hasflag(r->flags, F_SIZE)) {
|
||||
printf("ERROR in race '%s' - missing F_SIZE.\n", r->name);
|
||||
goterror = B_TRUE;
|
||||
|
@ -14804,6 +14903,10 @@ int validateraces(void) {
|
|||
}
|
||||
}
|
||||
|
||||
killfakes(&fakemap, &fakecell);
|
||||
|
||||
noredraw = B_FALSE;
|
||||
|
||||
return goterror;
|
||||
}
|
||||
|
||||
|
@ -15610,6 +15713,15 @@ int willbleedfrom(lifeform_t *lf, enum BODYPART bp) {
|
|||
}
|
||||
|
||||
|
||||
// if lf picks up 'o', will they be burdened afterwards?
|
||||
// (if they are _already_ burdened, then stil return true)
|
||||
int willburden(lifeform_t *lf, object_t *o, int howmany) {
|
||||
if (getobpileweight(lf->pack) + (getobunitweight(o)*howmany) > getmaxcarryweight(lf) ) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// will the lf flee after taking damage?
|
||||
int willflee(lifeform_t *lf) {
|
||||
enum ATTRBRACKET iqb;
|
||||
|
|
5
lf.h
5
lf.h
|
@ -67,6 +67,7 @@ int digup(lifeform_t *lf, object_t *o);
|
|||
void do_eyesight_adjust(lifeform_t *lf);
|
||||
void dumplev(void);
|
||||
void dumplf(void);
|
||||
void dumpmonsters(void);
|
||||
void dumpxp(void);
|
||||
int eat(lifeform_t *lf, object_t *o);
|
||||
void endlfturn(lifeform_t *lf);
|
||||
|
@ -132,6 +133,7 @@ int getguntargetid(lifeform_t *lf);
|
|||
int gethearingrange(lifeform_t *lf);
|
||||
int gethidemodifier(lifeform_t *lf);
|
||||
int gethitdice(lifeform_t *lf);
|
||||
int gethitdicerace(race_t *r);
|
||||
int gethppct(lifeform_t *lf);
|
||||
enum COLOUR gethungercol(enum HUNGER hlev);
|
||||
enum HUNGER gethungerlevel(int hunger);
|
||||
|
@ -144,6 +146,7 @@ char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc);
|
|||
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||
enum SKILLLEVEL getmaxskilllevel(lifeform_t *lf, enum SKILL skid);
|
||||
int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions);
|
||||
int getmiscastchance(lifeform_t *lf);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
char *getlfconditionname(enum LFCONDITION cond);
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||
|
@ -247,6 +250,7 @@ int isblind(lifeform_t *lf);
|
|||
enum BURDENED isburdened(lifeform_t *lf);
|
||||
int ischarmable(lifeform_t *lf);
|
||||
int isdead(lifeform_t *lf);
|
||||
int isdeaf(lifeform_t *lf);
|
||||
object_t *isdualweilding(lifeform_t *lf);
|
||||
int isfleeing(lifeform_t *lf);
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||
|
@ -366,5 +370,6 @@ int validateraces(void);
|
|||
int wear(lifeform_t *lf, object_t *o);
|
||||
int weild(lifeform_t *lf, object_t *o);
|
||||
int willbleedfrom(lifeform_t *lf, enum BODYPART bp);
|
||||
int willburden(lifeform_t *lf, object_t *o, int howmany);
|
||||
int willflee(lifeform_t *lf);
|
||||
//int youhear(cell_t *c, char *text);
|
||||
|
|
111
map.c
111
map.c
|
@ -1352,6 +1352,20 @@ enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf) {
|
|||
}
|
||||
|
||||
|
||||
// returns the closest cell next to 'dst', when coming from 'src'
|
||||
// ie. if you start walking from src to dst, where will you end up?
|
||||
cell_t *get_closest_adjcell(cell_t *src, cell_t *dst) {
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell,i;
|
||||
calcbresnham(src->map, src->x, src->y, dst->x, dst->y, retcell, &nretcell);
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
if (retcell[i] == dst) {
|
||||
return retcell[i-1];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getdoorlockdiff(int depth) {
|
||||
return 19 + depth;
|
||||
}
|
||||
|
@ -2144,6 +2158,18 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
|
|||
}
|
||||
}
|
||||
|
||||
void createfakes(map_t *map, cell_t *cell) {
|
||||
map->region = NULL;
|
||||
map->lf = NULL;
|
||||
map->lastlf = NULL;
|
||||
map->name = strdup("fake map");
|
||||
map->habitat = findhabitat(H_DUNGEON);
|
||||
setcelltype(cell, CT_FAKE);
|
||||
cell->lf = NULL;
|
||||
cell->map = map;
|
||||
cell->obpile = addobpile(NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
|
||||
int x,y;
|
||||
enum CELLTYPE emptycell;
|
||||
|
@ -2302,7 +2328,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
enum HABITAT habitat;
|
||||
regionthing_t *thing[MAXOUTLINETHINGS];
|
||||
int nthings = 0,failed;
|
||||
int db = B_FALSE;
|
||||
int db = B_TRUE;
|
||||
|
||||
// determine habitat based on region
|
||||
// note: we might override this later based on our region outline
|
||||
|
@ -2569,6 +2595,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
if (failed) {
|
||||
dblog("********* got errors - restarting map creation. *********");
|
||||
unlinkstairsto(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2905,6 +2932,11 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void killfakes(map_t *map, cell_t *cell) {
|
||||
killobpile(cell->obpile);
|
||||
free(map->name);
|
||||
}
|
||||
|
||||
// link a single cell up to the rest of the map.
|
||||
// make sure it links to an empty cell of a DIFFERENT roomid.
|
||||
// if 'wantfilled' is set, only link to "filled" cells.
|
||||
|
@ -4516,6 +4548,7 @@ void initmap(void) {
|
|||
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE);
|
||||
|
||||
// cell types
|
||||
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0);
|
||||
addcelltype(CT_WALL, "rock wall", '#', C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", '#', C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", '#', C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0);
|
||||
|
@ -4951,8 +4984,10 @@ int linkstairs(object_t *o, object_t *o2) {
|
|||
}
|
||||
}
|
||||
if (!found) {
|
||||
dblog("ERROR - stairs link to existing map %d(depth %d), but it has no free stairs.",othermap->id, othermap->depth);
|
||||
msg("ERROR - stairs link to existing map %d(depth %d), but it has no free stairs.",othermap->id, othermap->depth);
|
||||
dblog("ERROR - stairs link to existing map %d('%s', depth %d), but it has no free stairs.",othermap->id,
|
||||
othermap->name, othermap->depth);
|
||||
msg("ERROR - stairs link to existing map %d('%s', depth %d), but it has no free stairs.",othermap->id,
|
||||
othermap->name, othermap->depth);
|
||||
more();
|
||||
}
|
||||
} // end if othermap
|
||||
|
@ -5352,6 +5387,76 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
int unlinkstairsto(map_t *unlinkmap) {
|
||||
map_t *m;
|
||||
object_t *o;
|
||||
cell_t *c;
|
||||
long badid[MAXCANDIDATES];
|
||||
int x,y,nbadids = 0,nretflags,i;
|
||||
int db = B_TRUE;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
|
||||
if (db) dblog("starting unlinkstairsto for unlikmap='%s'",unlinkmap->name);
|
||||
// get a list of all stair object ids on this unlinkmap.
|
||||
for (y = 0; y < unlinkmap->h; y++) {
|
||||
for (x = 0; x < unlinkmap->w; x++) {
|
||||
c = getcellat(unlinkmap, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_MAPLINK)) {
|
||||
badid[nbadids++] = o->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db) dblog(" found %d stairs on unlinkmap.",nbadids);
|
||||
|
||||
// go through all maps and remove any stairs which link to unlinkmap
|
||||
if (db) dblog(" searching other maps for stairs linking to unlinkmap.");
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
for (y = 0; y < m->h; y++) {
|
||||
for (x = 0; x < m->w; x++) {
|
||||
c = getcellat(m, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
getflags(o->flags, retflag, &nretflags, F_MAPLINK, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
int killit = B_FALSE,n;
|
||||
if (retflag[i]->val[0] == unlinkmap->id) {
|
||||
|
||||
if (db) dblog(" on map '%s': found '%s' linking to unlinkmap's id.", m->name,o->type->name);
|
||||
killit = B_TRUE;
|
||||
} else {
|
||||
for (n = 0; n < nbadids; n++) {
|
||||
if (atol(retflag[i]->text) == badid[n]) {
|
||||
killit = B_TRUE;
|
||||
if (db) dblog(" on map '%s': found '%s' linking to obid of stairs on unlinkmap.", m->name,o->type->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (killit) {
|
||||
killflag(retflag[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now remove all links from stairs on unlinkmap
|
||||
if (db) dblog(" removing maplinks from stairs on unlinkmap.");
|
||||
for (y = 0; y < unlinkmap->h; y++) {
|
||||
for (x = 0; x < unlinkmap->w; x++) {
|
||||
c = getcellat(unlinkmap, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
killflagsofid(o->flags, F_MAPLINK);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db) dblog("finished unlinkstairsto for unlikmap='%s'",unlinkmap->name);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void updateknowncells(void) {
|
||||
int x,y;
|
||||
map_t *map;
|
||||
|
|
4
map.h
4
map.h
|
@ -25,6 +25,7 @@ int getcelldist(cell_t *src, cell_t *dst);
|
|||
int getcelldistorth(cell_t *src, cell_t *dst);
|
||||
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
||||
enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf);
|
||||
cell_t *get_closest_adjcell(cell_t *src, cell_t *dst);
|
||||
int getdoorlockdiff(int depth);
|
||||
int getdoorsecretdiff(int depth);
|
||||
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
||||
|
@ -45,6 +46,7 @@ int countcellexits(cell_t *cell);
|
|||
int countcellexitsfor(lifeform_t *lf);
|
||||
int countmapobs(map_t *m, enum OBTYPE oid);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createfakes(map_t *map, cell_t *cell);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings);
|
||||
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createheaven(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
|
@ -114,6 +116,7 @@ int isonmap(map_t *map, int x, int y);
|
|||
int isoutdoors(map_t *m);
|
||||
int isroom(cell_t *c);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
void killfakes(map_t *map, cell_t *cell);
|
||||
int linkexit(cell_t *c, int wantfilled, int *ncellsadded);
|
||||
int linkexits(map_t *m, int roomid);
|
||||
int linkholes(map_t *map);
|
||||
|
@ -129,6 +132,7 @@ void setcellknown(cell_t *cell, int forcelev);
|
|||
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
|
||||
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
||||
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
|
||||
int unlinkstairsto(map_t *unlinkmap);
|
||||
void updateknowncells(void);
|
||||
int validateregions(void);
|
||||
int validateregionthing(regionthing_t *thing);
|
||||
|
|
54
move.c
54
move.c
|
@ -962,7 +962,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
int didmsg = B_FALSE;
|
||||
flag_t *f;
|
||||
int changedlev = B_FALSE;
|
||||
int preroom = -1, postroom = -1;
|
||||
room_t *preroom = NULL, *postroom = NULL;
|
||||
int preshop = -1;
|
||||
int prespeed = B_FALSE, postspeed = B_FALSE;
|
||||
int prewater = B_FALSE;
|
||||
|
@ -986,7 +986,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
|
||||
// remember current cell + room id
|
||||
prespeed = getmovespeed(lf);
|
||||
preroom = getroomid(lf->cell);
|
||||
preroom = lf->cell->room;
|
||||
v = getcellvault(lf->cell);
|
||||
if (v && hasflag(v->flags, F_VAULTISSHOP)) {
|
||||
preshop = getroomid(lf->cell);
|
||||
|
@ -1042,7 +1042,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
assert(!newcell->lf);
|
||||
|
||||
// remember new room...
|
||||
postroom = getroomid(lf->cell);
|
||||
postroom = lf->cell->room;
|
||||
postspeed = getmovespeed(lf);
|
||||
|
||||
// update new cell
|
||||
|
@ -1241,8 +1241,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
*/
|
||||
}
|
||||
|
||||
// does anyone else see you?
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (isplayer(lf) && !isblind(lf)) {
|
||||
// see the vault
|
||||
if (!preroom && postroom && postroom->vault) {
|
||||
f = hasflag(postroom->vault->flags, F_VAULTENTERTEXT);
|
||||
if (f) {
|
||||
msg("%s", f->text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// does anyone else see you?
|
||||
for (l = newcell->map->lf ; l ; l = l->next) {
|
||||
if (l != lf) {
|
||||
flag_t *alarm;
|
||||
|
@ -1408,8 +1418,8 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
}
|
||||
}
|
||||
|
||||
// see objects on ground
|
||||
if (isplayer(lf)) {
|
||||
// see/feel objects on ground
|
||||
int numobs;
|
||||
numobs = countnoncosmeticobs(newcell->obpile, B_TRUE);
|
||||
if ((numobs == 0) && !newcell->writing) {
|
||||
|
@ -1915,7 +1925,6 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
|||
for (o = lf->cell->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
|
||||
|
||||
f = obrestrictsmovement(o, lf);
|
||||
if (f) {
|
||||
char lfname[BUFLEN];
|
||||
|
@ -2067,7 +2076,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose) {
|
||||
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int changedir, int onpurpose) {
|
||||
cell_t *cell1,*cell2;
|
||||
|
||||
cell1 = lf1->cell;
|
||||
|
@ -2084,6 +2093,13 @@ void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose) {
|
|||
lf2->cell = cell1;
|
||||
cell1->lf = lf2;
|
||||
|
||||
if (changedir) {
|
||||
int tempfacing;
|
||||
tempfacing = lf2->facing;
|
||||
setfacing(lf2, lf1->facing);
|
||||
setfacing(lf1, tempfacing);
|
||||
}
|
||||
|
||||
// remember that we just swapped
|
||||
if (!isplayer(lf1)) {
|
||||
addflag(lf1->flags, F_NOSWAP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -2179,17 +2195,24 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
|
||||
reldir = getrelativedir(lf, dir);
|
||||
|
||||
// if the given dir is behind us, just turn.
|
||||
if (onpurpose && !strafe) {
|
||||
if (reldir != RD_FORWARDS) {
|
||||
if (!lfhasflag(lf, F_AWARENESS)) {
|
||||
if (onpurpose) {
|
||||
if ((reldir != RD_FORWARDS) && !lfhasflag(lf, F_AWARENESS)) {
|
||||
// if the given dir is behind us, just turn.
|
||||
if (!strafe) {
|
||||
setfacing(lf, dir);
|
||||
taketime(lf, getturnspeed(lf));
|
||||
return B_FALSE;
|
||||
} else {
|
||||
// player can't strafe while stuck.
|
||||
if (isstuck(lf) && isplayer(lf)) {
|
||||
msg("You can't move %s while stuck!", (reldir == RD_BACKWARDS) ? "backwards" : "sideways");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f = lfhasflag(lf, F_DRUNK);
|
||||
if (f) {
|
||||
if (!hasjob(lf, J_PIRATE)) {
|
||||
|
@ -2476,15 +2499,16 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
// otherwise swap locations.
|
||||
lfinway = cell->lf;
|
||||
|
||||
swapplaces(lf, lfinway, onpurpose);
|
||||
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
|
||||
if (isplayer(lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lfinway, lfname);
|
||||
msg("You swap places with %s.", lfname);
|
||||
}
|
||||
|
||||
swapplaces(lf, lfinway, B_FALSE, onpurpose);
|
||||
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
|
||||
} else {
|
||||
if (!onpurpose || canandwillmove(lf, dir, &errcode)) {
|
||||
return attackcell(lf, cell, B_FALSE);
|
||||
|
|
2
move.h
2
move.h
|
@ -27,7 +27,7 @@ int pullnextto(lifeform_t *lf, cell_t *c);
|
|||
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg);
|
||||
int isorthogonal(int dir);
|
||||
int ispossiblemove(lifeform_t *lf, int dir);
|
||||
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose);
|
||||
void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int changedir, int onpurpose);
|
||||
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke);
|
||||
void triggertrap(lifeform_t *lf, object_t *o, object_t *trapob, cell_t *where);
|
||||
int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe);
|
||||
|
|
21
nexus.c
21
nexus.c
|
@ -43,6 +43,8 @@ hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL;
|
|||
npcname_t *npcname;
|
||||
int numnpcnames;
|
||||
|
||||
int maxmonhitdice = 0; // highest number of hitdice for any monster
|
||||
|
||||
double presin[360];
|
||||
double precos[360];
|
||||
|
||||
|
@ -810,6 +812,23 @@ void donextturn(map_t *map) {
|
|||
}
|
||||
}
|
||||
|
||||
void gethitdicerange(int depth, int *min, int *max, int range, int oodok) {
|
||||
int mid;
|
||||
|
||||
// adjust depth for out-of-depth monsters
|
||||
if (oodok && (onein(6))) {
|
||||
depth++;
|
||||
// repeated chances of incing level
|
||||
while (onein(6)) {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
mid = (depth/2);
|
||||
|
||||
*min = mid - range; limit(min, 0, maxmonhitdice);
|
||||
*max = mid + range; limit(max, *min, maxmonhitdice);
|
||||
}
|
||||
|
||||
enum COLOUR getpctcol(float num, float max) {
|
||||
float pct;
|
||||
|
@ -1180,7 +1199,7 @@ int rollhitdice(lifeform_t *lf) {
|
|||
ndice = 1;
|
||||
nsides = 4;
|
||||
plus = 0;
|
||||
myroll = roll("1d4");
|
||||
myroll = roll(DEF_HITDICE);
|
||||
}
|
||||
|
||||
mod = 100 + getstatmod(lf, A_CON);
|
||||
|
|
1
nexus.h
1
nexus.h
|
@ -9,6 +9,7 @@ void dbtimeend(char *text);
|
|||
void dbtimestart(char *text);
|
||||
void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, int dinc2, int *xinc, int *yinc, int *dinc);
|
||||
void donextturn(map_t *map);
|
||||
void gethitdicerange(int depth, int *min, int *max, int range, int oodok);
|
||||
enum COLOUR getpctcol(float num, float max);
|
||||
void getrarityrange(int depth, int *min, int *max, int range, int oodok);
|
||||
int init(void);
|
||||
|
|
151
objects.c
151
objects.c
|
@ -680,7 +680,15 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
////////////////////////////////////
|
||||
// handle special object names
|
||||
////////////////////////////////////
|
||||
if (strstr(p, "corpse")) {
|
||||
if (strstr(p, "chunk of roast ") || strstr(p, "roast meat")) {
|
||||
char racename[BUFLEN];
|
||||
p2 = strstr(p, "roast");
|
||||
p2 += 6;
|
||||
p2 = readuntil(racename, p2, ' ');
|
||||
|
||||
corpserace = findracebyname(racename);
|
||||
ot = findot(OT_ROASTMEAT);
|
||||
} else if (strstr(p, "corpse")) {
|
||||
int len;
|
||||
char racename[BUFLEN];
|
||||
p2 = strstr(p, "corpse");
|
||||
|
@ -1226,32 +1234,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
if (rf) {
|
||||
cf = hasflag(o->flags, F_EDIBLE);
|
||||
if (cf) {
|
||||
switch (rf->val[0]) {
|
||||
case SZ_MINI:
|
||||
cf->val[1] = 1;
|
||||
break;
|
||||
case SZ_TINY:
|
||||
cf->val[1] = 10;
|
||||
break;
|
||||
case SZ_SMALL:
|
||||
cf->val[1] = 25;
|
||||
break;
|
||||
case SZ_MEDIUM:
|
||||
cf->val[1] = 75;
|
||||
break;
|
||||
case SZ_HUMAN:
|
||||
cf->val[1] = 120;
|
||||
break;
|
||||
case SZ_LARGE:
|
||||
cf->val[1] = 150;
|
||||
break;
|
||||
case SZ_HUGE:
|
||||
cf->val[1] = 200;
|
||||
break;
|
||||
case SZ_ENORMOUS:
|
||||
cf->val[1] = 250;
|
||||
break;
|
||||
}
|
||||
cf->val[1] = sizetonutrition(rf->val[0]);
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_STATUE) {
|
||||
|
@ -1264,8 +1247,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
// select random race
|
||||
if (where) {
|
||||
corpserace = getrandomrace(where, NA);
|
||||
} else {
|
||||
// ie. vending machine
|
||||
}
|
||||
if (!corpserace) {
|
||||
// ie. vending machine, or inside another object/fake cell?
|
||||
corpserace = getrandomrace(NULL, NA);
|
||||
}
|
||||
}
|
||||
|
@ -1300,7 +1284,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
f->val[1] = maxhp;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (o->type->id == OT_HEAD) {
|
||||
flag_t *rf, *cf;
|
||||
|
||||
|
@ -1318,35 +1301,30 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
if (rf) {
|
||||
cf = hasflag(o->flags, F_EDIBLE);
|
||||
if (cf) {
|
||||
switch (rf->val[0]) {
|
||||
case SZ_MINI:
|
||||
cf->val[1] = 1;
|
||||
break;
|
||||
case SZ_TINY:
|
||||
cf->val[1] = 2;
|
||||
break;
|
||||
case SZ_SMALL:
|
||||
cf->val[1] = 5;
|
||||
break;
|
||||
case SZ_MEDIUM:
|
||||
cf->val[1] = 25;
|
||||
break;
|
||||
case SZ_HUMAN:
|
||||
cf->val[1] = 50;
|
||||
break;
|
||||
case SZ_LARGE:
|
||||
cf->val[1] = 75;
|
||||
break;
|
||||
case SZ_HUGE:
|
||||
cf->val[1] = 100;
|
||||
break;
|
||||
case SZ_ENORMOUS:
|
||||
cf->val[1] = 150;
|
||||
break;
|
||||
}
|
||||
cf->val[1] = sizetonutrition(rf->val[0]) / 3;
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_ROASTMEAT) {
|
||||
flag_t *rf, *cf;
|
||||
|
||||
if (!corpserace) {
|
||||
// random one.
|
||||
corpserace = getrandomrace(NULL, NA);
|
||||
}
|
||||
|
||||
o->weight = corpserace->weight / 2;
|
||||
|
||||
// remember the race type
|
||||
addflag(o->flags, F_CORPSEOF, corpserace->id, NA, NA, NULL);
|
||||
|
||||
// override ot_roastmeat nutrition flag based on race's size
|
||||
rf = hasflag(corpserace->flags, F_SIZE);
|
||||
if (rf) {
|
||||
cf = hasflag(o->flags, F_EDIBLE);
|
||||
if (cf) {
|
||||
cf->val[1] = sizetonutrition(rf->val[0]);
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f && (f->val[0] != wantdepth)) {
|
||||
|
@ -2177,8 +2155,12 @@ int canseeob(lifeform_t *lf, object_t *o) {
|
|||
// can't see
|
||||
return B_FALSE;
|
||||
}
|
||||
if (o->pile->where && hasobwithflag(o->pile, F_BLOCKSVIEW)) {
|
||||
return B_FALSE;
|
||||
if (o->pile->where) {
|
||||
object_t *blockob;
|
||||
blockob = hasobwithflag(o->pile, F_BLOCKSVIEW);
|
||||
if (blockob && (blockob != o)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_TRAIL);
|
||||
|
@ -2305,7 +2287,7 @@ int changemat(object_t *o, enum MATERIAL mat) {
|
|||
o->material = m;
|
||||
|
||||
// inherit flags from new material
|
||||
copyflags(m->flags, o->flags, FROMMAT);
|
||||
copyflags(o->flags, m->flags, FROMMAT);
|
||||
|
||||
if (mat == MT_ICE) {
|
||||
obmod_t *om;
|
||||
|
@ -3864,6 +3846,16 @@ char *getobdesc(object_t *o, char *buf) {
|
|||
} else {
|
||||
snprintf(buf, BUFLEN, "%s", o->type->desc);
|
||||
}
|
||||
} else if (o->type->id == OT_ROASTMEAT) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_CORPSEOF);
|
||||
if (f) {
|
||||
race_t *corpserace;
|
||||
corpserace = findrace(f->val[0]);
|
||||
snprintf(buf, BUFLEN, "A chunk of flame-roasted flesh from %s %s.", isvowel(corpserace->name[0]) ? "an" : "a", corpserace->name);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s", o->type->desc);
|
||||
}
|
||||
} else if (o->type->id == OT_STATUE) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_CORPSEOF);
|
||||
|
@ -4094,7 +4086,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
if (who) {
|
||||
char lfname[BUFLEN];
|
||||
real_getlfnamea(who, lfname, B_FALSE);
|
||||
snprintf(buf, BUFLEN, "%s%s%s %sscent",adjective,lfname,getpossessive(lfname));
|
||||
snprintf(buf, BUFLEN, "a %s%s scent",adjective,r->name);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "%s%s scent",adjective, r->name );
|
||||
}
|
||||
|
@ -4245,6 +4237,13 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
snprintf(basename, BUFLEN, "%s %s",corpserace->name, o->type->name);
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_ROASTMEAT) {
|
||||
f = hasflag(o->flags, F_CORPSEOF);
|
||||
if (f) {
|
||||
race_t *corpserace;
|
||||
corpserace = findrace(f->val[0]);
|
||||
snprintf(basename, BUFLEN, "chunk of roast %s meat",corpserace->name);
|
||||
}
|
||||
} else if (o->type->id == OT_FOUNTAIN) {
|
||||
objecttype_t *ot;
|
||||
// find out what kind of fountain this is
|
||||
|
@ -5045,9 +5044,9 @@ char *getschoolname(enum SPELLSCHOOL sch) {
|
|||
case SS_ENCHANTMENT: return "Enchantments";
|
||||
case SS_WILD: return "Wild Magic";
|
||||
case SS_MENTAL: return "Psionic Powers";
|
||||
case SS_AIR: return "Elemental/Air Magic";
|
||||
case SS_FIRE: return "Elemental/Fire Magic";
|
||||
case SS_COLD: return "Elemental/Cold Magic";
|
||||
case SS_AIR: return "Air Magic";
|
||||
case SS_FIRE: return "Fire Magic";
|
||||
case SS_COLD: return "Cold Magic";
|
||||
case SS_MODIFICATION: return "Modification Magic";
|
||||
case SS_DEATH: return "Necromancy";
|
||||
case SS_NATURE: return "Nature";
|
||||
|
@ -5646,6 +5645,7 @@ int isdrinkable(object_t *o) {
|
|||
}
|
||||
|
||||
int isedible(object_t *o) {
|
||||
if (hasflag(o->flags, F_CREATEDBYSPELL)) return B_FALSE;
|
||||
if (hasflag(o->flags, F_EDIBLE)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -9713,6 +9713,29 @@ void shufflehiddennames(void) {
|
|||
}
|
||||
}
|
||||
|
||||
int sizetonutrition(enum LFSIZE size) {
|
||||
switch (size) {
|
||||
case SZ_MINI:
|
||||
return 1;
|
||||
case SZ_TINY:
|
||||
return 10;
|
||||
case SZ_SMALL:
|
||||
return 25;
|
||||
case SZ_MEDIUM:
|
||||
return 75;
|
||||
case SZ_HUMAN:
|
||||
return 120;
|
||||
case SZ_LARGE:
|
||||
return 150;
|
||||
case SZ_HUGE:
|
||||
return 200;
|
||||
case SZ_ENORMOUS:
|
||||
return 250;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
object_t *splitob(object_t *o) {
|
||||
object_t *newob;
|
||||
// decrease count on original stack temporarily, in case we
|
||||
|
@ -9946,6 +9969,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
meat = addob(o->pile, "chunk of roast meat");
|
||||
// purposely don't use getweight!
|
||||
meat->weight = o->weight;
|
||||
copyflag(meat->flags, o->flags, F_CORPSEOF);
|
||||
}
|
||||
// fire turns things to ash
|
||||
addob(o->pile, "pile of ash");
|
||||
|
@ -10430,6 +10454,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) &&
|
||||
lfhasflag(target, F_HUMANOID) &&
|
||||
canpickup(target, o, o->amt) &&
|
||||
!willburden(target, o, o->amt) &&
|
||||
!isimmobile(target) &&
|
||||
skillcheck(target, SC_DEX, 15*speed, catchmod)) {
|
||||
willcatch = B_TRUE;
|
||||
|
|
|
@ -232,6 +232,7 @@ void setobcreatedby(object_t *o, lifeform_t *lf);
|
|||
void setwaterdepth(cell_t *c, int depth);
|
||||
int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
void shufflehiddennames(void);
|
||||
int sizetonutrition(enum LFSIZE size);
|
||||
object_t *splitob(object_t *o);
|
||||
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce);
|
||||
|
|
53
spell.c
53
spell.c
|
@ -112,9 +112,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (abilid == OT_A_CHARGE) {
|
||||
cell_t *adjcell = NULL,*origcell;
|
||||
char targetname[BUFLEN];
|
||||
int i;
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell;
|
||||
|
||||
if (isimmobile(user)) {
|
||||
if (isplayer(user)) msg("You can't move!");
|
||||
|
@ -134,7 +131,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!targcell) {
|
||||
if (isplayer(user)) {
|
||||
snprintf(buf, BUFLEN, "Charge who (max range %d)?",range);
|
||||
|
@ -167,13 +163,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
getlfname(target, targetname);
|
||||
|
||||
// find cell on the way...
|
||||
calcbresnham(user->cell->map, user->cell->x, user->cell->y, targcell->x, targcell->y, retcell, &nretcell);
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
if (retcell[i] == targcell) {
|
||||
adjcell = retcell[i-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
adjcell = get_closest_adjcell(user->cell, targcell);
|
||||
if (!adjcell) {
|
||||
if (isplayer(user)) {
|
||||
msg("There is no space nearby for you to attack!");
|
||||
|
@ -1900,6 +1890,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
addchoice(&prompt, o->letter, buf, NULL, o, NULL);
|
||||
}
|
||||
}
|
||||
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
|
||||
|
||||
if (prompt.nchoices == 1) {
|
||||
msg("You don't have anything which you can inspect.");
|
||||
return B_TRUE;
|
||||
}
|
||||
getchoice(&prompt);
|
||||
o = (object_t *)prompt.result;
|
||||
if (!o) {
|
||||
|
@ -2498,6 +2494,24 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
targcell = poss[rnd(0,nposs-1)];
|
||||
}
|
||||
teleportto(caster, targcell, B_TRUE);
|
||||
} else if (spellid == OT_S_BLINKASS) {
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// find cell behind caster
|
||||
targcell = getcellindir(targcell, diropposite(target->facing));
|
||||
if (!cellwalkable(caster, targcell, NULL)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
teleportto(caster, targcell, B_TRUE);
|
||||
setfacing(caster, target->facing);
|
||||
} else if (spellid == OT_S_LOWERMETAB) {
|
||||
flag_t *f;
|
||||
// ie. 2 - 4
|
||||
|
@ -3335,8 +3349,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
wear(target, o);
|
||||
// set its values
|
||||
f = hasflag(o->flags, F_ARMOURRATING);
|
||||
if (f) f->val[0] = power;
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (f) {
|
||||
f->val[0] = power*5;
|
||||
|
@ -7649,7 +7661,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (cansee(player, caster)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
swapplaces(caster, target, B_FALSE);
|
||||
swapplaces(caster, target, B_CHANGEDIR, B_ONPURPOSE);
|
||||
} else if ((spellid == OT_S_SUMMONANIMALSSM) ||
|
||||
(spellid == OT_S_SUMMONANIMALSMD) ||
|
||||
(spellid == OT_S_SUMMONANIMALSLG) ||
|
||||
|
@ -8406,10 +8418,21 @@ int getmpcost(lifeform_t *lf, enum OBTYPE oid) {
|
|||
if (f) {
|
||||
cost = f->val[0];
|
||||
} else {
|
||||
cost = getspelllevel(oid);
|
||||
/*
|
||||
f = hasflag(ot->flags, F_SPELLLEVEL);
|
||||
if (f) {
|
||||
cost = f->val[0] * f->val[0];
|
||||
switch (getspellschool(oid)) {
|
||||
case SS_MENTAL:
|
||||
case SS_ALLOMANCY:
|
||||
cost = f->val[0];
|
||||
break;
|
||||
default:
|
||||
cost = f->val[0] * f->val[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
return cost;
|
||||
}
|
||||
|
|
2
text.c
2
text.c
|
@ -384,6 +384,7 @@ char *getrarityname(enum RARITY rr) {
|
|||
|
||||
char *getsizetext(enum LFSIZE sz) {
|
||||
switch (sz) {
|
||||
case SZ_MAX:
|
||||
case SZ_ENORMOUS:
|
||||
return "enormous";
|
||||
case SZ_HUGE:
|
||||
|
@ -398,6 +399,7 @@ char *getsizetext(enum LFSIZE sz) {
|
|||
return "small";
|
||||
case SZ_TINY:
|
||||
return "tiny";
|
||||
case SZ_MIN:
|
||||
case SZ_MINI:
|
||||
return "miniscule";
|
||||
default:
|
||||
|
|
|
@ -11,6 +11,7 @@ random(4,4)
|
|||
goesin:dungeon
|
||||
autodoors:25
|
||||
autopop
|
||||
entertext:It looks like the roof here has collapsed.
|
||||
scatter(1,1,-2,-2) ob:boulder:25%
|
||||
scatter(1,1,-2,-2) ob:25-75 stones:50%
|
||||
rarity:uncommon
|
||||
|
|
|
@ -9,6 +9,7 @@ random(4,4)
|
|||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
entertext:You enter a dining room.
|
||||
autodoors:75
|
||||
autopop
|
||||
! tables & chairs
|
||||
|
|
|
@ -21,6 +21,7 @@ m:ob:landmine trap
|
|||
@end
|
||||
|
||||
@flags
|
||||
entertext:You enter an ornate shrine.
|
||||
shrine
|
||||
norandom
|
||||
mayrotate
|
||||
|
|
|
@ -11,6 +11,7 @@ random(5,5)
|
|||
goesin:dungeon
|
||||
autodoors:25
|
||||
autopop
|
||||
entertext:You enter a small shrubbery.
|
||||
scatter(1,1,-2,-2) ob:fountain:1:75
|
||||
scatter(1,1,-2,-2) ob:tree:25%
|
||||
scatter(1,1,-2,-2) ob:shrub:50%
|
||||
|
|
|
@ -27,6 +27,7 @@ m:mon:minotaur
|
|||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
entertext:You enter a labyrinth.
|
||||
! the reward
|
||||
at(7,7) ob:200-450 gold
|
||||
at(7,7) ob:good weapon
|
||||
|
|
|
@ -14,6 +14,6 @@ autodoors:100
|
|||
scatter(1,1,-2,-2) ob:statue:25%
|
||||
scatter(1,1,-2,-2) mon:cockatrice:1
|
||||
scatter(1,1,-2,-2) ob:1-10 stones:1-5
|
||||
rarity:rare
|
||||
rarity:vrare
|
||||
@end
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ random(4,4)
|
|||
@flags
|
||||
autodoors:50
|
||||
autopop
|
||||
entertext:It seems very muddy here!
|
||||
goesin:dungeon
|
||||
! add mud to 50% of room cells
|
||||
scatter(1,1,-2,-2) ob:pool of mud:50%
|
||||
|
|
Loading…
Reference in New Issue