- [+] better body part handling
- [+] bodypart_t[MAXBODYPARTS] - [+] enum BODYPART id - [+] char *name - [+] add defs to all races - [+] fix quadrapeds - not all have tails! - [+] remove f_bodypartname - use addbodypart instead - [+] update hasbp - [+] remove occurences of F_NOBODYPART in races - [+] fix up getrandombodypart functions - [+] getrandomonbodypart - [+] getcrithitpos - [+] copy with null returns - [+] check all occurences of MAXBODYPARTS, change to "for each bodypart of this lf/race" - [+] show nobodypart differently in io.c - [+] criticals: hindlegs / frontlegs -> legs - [+] makeunusual shaped be part of the body part. then remove F_NOARMOURON - [+] critical hits on new body parts - [+] wing crits - [+] bash - wings are bruised - reduced flight speed - [+] slash - [+] - wings are torn - can't fly. implement in cancast. - [+] bleeding - flying hurts - [+] explosive - [+] destroyed - can't fly! - [+] tail crits - [+] slash - [+] bleeding - [+] bash - [+] bruised - accuracy lowered - [+] fractured - randomly move the wrong way like drunkenness - [+] explosive - [+] lacerated - randomly fall like hamstrung - [+] don't prompt for moving into dangerous cells f moving randomly due to drunkenness etc - [+] bug: double criticals? - [+] You flatten the kobold! The kobold loses consciousness. The kobold's hand is swollen! The kobold's leg is broken! - [+] all f_flying races should have f_canwill ot_s_fly with no spellcasttext
This commit is contained in:
parent
c596623603
commit
c9fcd90a2c
11
ai.c
11
ai.c
|
@ -1098,9 +1098,11 @@ void aiturn(lifeform_t *lf) {
|
||||||
// flying monsters not flying?
|
// flying monsters not flying?
|
||||||
if (!isprone(lf)) {
|
if (!isprone(lf)) {
|
||||||
if (hasflag(lf->race->flags, F_FLYING) && !lfhasflag(lf, F_FLYING)) {
|
if (hasflag(lf->race->flags, F_FLYING) && !lfhasflag(lf, F_FLYING)) {
|
||||||
copyflag(lf->flags, lf->race->flags, F_FLYING);
|
if (cancast(lf, OT_S_FLIGHT, NULL)) {
|
||||||
taketime(lf, getmovespeed(lf));
|
if (!castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hasflag(lf->race->flags, F_LEVITATING) && !lfhasflag(lf, F_LEVITATING)) {
|
if (hasflag(lf->race->flags, F_LEVITATING) && !lfhasflag(lf, F_LEVITATING)) {
|
||||||
copyflag(lf->flags, lf->race->flags, F_LEVITATING);
|
copyflag(lf->flags, lf->race->flags, F_LEVITATING);
|
||||||
|
@ -1321,8 +1323,9 @@ void aiturn(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have better armour?
|
// do we have better armour?
|
||||||
for (bp = BP_RIGHTFINGER ; bp < MAXBODYPARTS; bp++) {
|
for (i = 0; i < lf->race->nbodyparts; i++) {
|
||||||
object_t *curarm;
|
object_t *curarm;
|
||||||
|
bp = lf->race->bodypart[i].id;
|
||||||
curarm = getarmour(lf, bp);
|
curarm = getarmour(lf, bp);
|
||||||
// do we have a better one?
|
// do we have a better one?
|
||||||
for (o = lf->pack->first ; o ; o = o->next) {
|
for (o = lf->pack->first ; o ; o = o->next) {
|
||||||
|
|
33
attack.c
33
attack.c
|
@ -645,20 +645,22 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
||||||
object_t *armour;
|
object_t *armour;
|
||||||
char noun[BUFLEN];
|
char noun[BUFLEN];
|
||||||
critpos = getrandomcorebp(victim);
|
critpos = getrandomcorebp(victim);
|
||||||
armour = getequippedob(victim->pack, critpos);
|
if (critpos != BP_NONE) {
|
||||||
if (armour) {
|
armour = getequippedob(victim->pack, critpos);
|
||||||
char armname[BUFLEN];
|
if (armour) {
|
||||||
real_getobname(armour, armname, 1, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
char armname[BUFLEN];
|
||||||
sprintf(noun, "%s", noprefix(armname));
|
real_getobname(armour, armname, 1, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
||||||
} else {
|
sprintf(noun, "%s", noprefix(armname));
|
||||||
sprintf(noun, "%s", getbodypartname(victim, critpos));
|
} else {
|
||||||
}
|
sprintf(noun, "%s", getbodypartname(victim, critpos));
|
||||||
// replace victicname to include body part
|
}
|
||||||
if ((lf == victim) && !isplayer(lf)) {
|
// replace victicname to include body part
|
||||||
snprintf(victimbpname, BUFLEN, "its %s", noun);
|
if ((lf == victim) && !isplayer(lf)) {
|
||||||
} else {
|
snprintf(victimbpname, BUFLEN, "its %s", noun);
|
||||||
getlfname(victim, buf);
|
} else {
|
||||||
snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), noun);
|
getlfname(victim, buf);
|
||||||
|
snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), noun);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
strcpy(victimbpname, "");
|
strcpy(victimbpname, "");
|
||||||
|
@ -1421,6 +1423,9 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
|
||||||
object_t *o,*armour;
|
object_t *o,*armour;
|
||||||
int protected = B_FALSE;
|
int protected = B_FALSE;
|
||||||
char lfname[BUFLEN],victimname[BUFLEN];
|
char lfname[BUFLEN],victimname[BUFLEN];
|
||||||
|
|
||||||
|
if (hitpos == BP_NONE) return;
|
||||||
|
|
||||||
// replace some dam types
|
// replace some dam types
|
||||||
if (damtype == DT_UNARMED) damtype = DT_BASH;
|
if (damtype == DT_UNARMED) damtype = DT_BASH;
|
||||||
if (damtype == DT_BITE) damtype = DT_SLASH;
|
if (damtype == DT_BITE) damtype = DT_SLASH;
|
||||||
|
|
64
defs.h
64
defs.h
|
@ -1741,21 +1741,27 @@ enum OBTYPE {
|
||||||
|
|
||||||
#define BP_NONE (-1)
|
#define BP_NONE (-1)
|
||||||
enum BODYPART {
|
enum BODYPART {
|
||||||
|
// humanoid parts
|
||||||
BP_WEAPON = 0,
|
BP_WEAPON = 0,
|
||||||
BP_SECWEAPON,
|
BP_SECWEAPON = 1,
|
||||||
BP_EARS,
|
BP_EARS = 2,
|
||||||
BP_EYES,
|
BP_EYES = 3,
|
||||||
BP_HEAD,
|
BP_HEAD = 4,
|
||||||
BP_SHOULDERS,
|
BP_SHOULDERS = 5,
|
||||||
BP_BODY,
|
BP_BODY = 6,
|
||||||
BP_HANDS,
|
BP_HANDS = 7,
|
||||||
BP_WAIST,
|
BP_WAIST = 8,
|
||||||
BP_LEGS,
|
BP_LEGS = 9,
|
||||||
BP_FEET,
|
BP_FEET = 10,
|
||||||
BP_RIGHTFINGER,
|
BP_RIGHTFINGER = 11,
|
||||||
BP_LEFTFINGER,
|
BP_LEFTFINGER = 12,
|
||||||
|
// others...
|
||||||
|
BP_BACKLEGS = 13,
|
||||||
|
BP_FRONTLEGS = 14,
|
||||||
|
BP_WINGS = 15,
|
||||||
|
BP_TAIL = 16,
|
||||||
};
|
};
|
||||||
#define MAXBODYPARTS (13)
|
#define MAXBODYPARTS (17)
|
||||||
|
|
||||||
// depth on a human
|
// depth on a human
|
||||||
|
|
||||||
|
@ -2464,7 +2470,7 @@ enum FLAG {
|
||||||
F_SPELLCASTTEXT, // text is announcement for spellcast
|
F_SPELLCASTTEXT, // text is announcement for spellcast
|
||||||
// if text is empty, then don't announce
|
// if text is empty, then don't announce
|
||||||
// this lf's spell casting at all.
|
// this lf's spell casting at all.
|
||||||
// if v0 is set, only use text for spellid v0
|
// if v0 != OT_NONE, only use text for spellid v0
|
||||||
// if v2 is 'appendyou' " at xxx" will
|
// if v2 is 'appendyou' " at xxx" will
|
||||||
// be appended.
|
// be appended.
|
||||||
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
||||||
|
@ -2517,16 +2523,12 @@ enum FLAG {
|
||||||
F_DOESNTMOVE, // this race doesn't move (but can still attack)
|
F_DOESNTMOVE, // this race doesn't move (but can still attack)
|
||||||
F_AQUATIC, // this race can attack normally in water and suffers no
|
F_AQUATIC, // this race can attack normally in water and suffers no
|
||||||
// movement penalties
|
// movement penalties
|
||||||
F_BODYPARTNAME, // for this race, bodypart v0 is called 'text'
|
|
||||||
F_AVIAN, // this race is an avian
|
F_AVIAN, // this race is an avian
|
||||||
F_CANINE, // this race is a canine
|
F_CANINE, // this race is a canine
|
||||||
F_HUMANOID, // this race can wear armour / use weapons
|
F_HUMANOID, // this race can wear armour / use weapons
|
||||||
F_INSECT, // this race is classed as an insect
|
F_INSECT, // this race is classed as an insect
|
||||||
F_UNDEAD, // this race is classed as undead
|
F_UNDEAD, // this race is classed as undead
|
||||||
F_COLDBLOOD, // this race is coldblooded
|
F_COLDBLOOD, // this race is coldblooded
|
||||||
F_NOARMOURON, // this race can't wear armour on bodypart v0
|
|
||||||
// obviously doesn't make sense to have both this
|
|
||||||
// and f_nobodypart for the same body part.
|
|
||||||
F_NOBODYPART, // this race doesn't have bodypart val0
|
F_NOBODYPART, // this race doesn't have bodypart val0
|
||||||
// if v0 is true or b_frominjury, you can regrow it
|
// if v0 is true or b_frominjury, you can regrow it
|
||||||
// via a healing potion.
|
// via a healing potion.
|
||||||
|
@ -2820,10 +2822,13 @@ enum INJURY {
|
||||||
IJ_RIBBROKEN, // can be from explosive too
|
IJ_RIBBROKEN, // can be from explosive too
|
||||||
IJ_RIBCRACKED, // can be from explosive too
|
IJ_RIBCRACKED, // can be from explosive too
|
||||||
IJ_SHOULDERDISLOCATED,
|
IJ_SHOULDERDISLOCATED,
|
||||||
|
IJ_TAILBRUISED,
|
||||||
|
IJ_TAILBROKEN,
|
||||||
IJ_TORSOBRUISED,
|
IJ_TORSOBRUISED,
|
||||||
IJ_TORSOBRUISEDBAD,
|
IJ_TORSOBRUISEDBAD,
|
||||||
IJ_WINDED,
|
IJ_WINDED,
|
||||||
IJ_WINDPIPECRUSHED,
|
IJ_WINDPIPECRUSHED,
|
||||||
|
IJ_WINGBRUISED,
|
||||||
// slashing
|
// slashing
|
||||||
IJ_ARTERYPIERCE,
|
IJ_ARTERYPIERCE,
|
||||||
IJ_CHESTBLEED,
|
IJ_CHESTBLEED,
|
||||||
|
@ -2834,10 +2839,15 @@ enum INJURY {
|
||||||
IJ_FINGERMISSING,
|
IJ_FINGERMISSING,
|
||||||
IJ_EYELIDSCRAPED,
|
IJ_EYELIDSCRAPED,
|
||||||
IJ_EYEDESTROYED,
|
IJ_EYEDESTROYED,
|
||||||
|
IJ_TAILBLEED,
|
||||||
|
IJ_WINGBLEED,
|
||||||
|
IJ_WINGTORN,
|
||||||
// explosive
|
// explosive
|
||||||
IJ_EARSRINGING,
|
IJ_EARSRINGING,
|
||||||
IJ_HANDMISSING,
|
IJ_HANDMISSING,
|
||||||
IJ_LUNGCOLLAPSED,
|
IJ_LUNGCOLLAPSED,
|
||||||
|
IJ_TAILLACERATED,
|
||||||
|
IJ_WINGDESTROYED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3002,6 +3012,21 @@ typedef struct coord_s {
|
||||||
int x,y;
|
int x,y;
|
||||||
} coord_t;
|
} coord_t;
|
||||||
|
|
||||||
|
enum BODYTYPE {
|
||||||
|
BT_BIRD,
|
||||||
|
BT_FISH,
|
||||||
|
BT_HUMANOID,
|
||||||
|
BT_QUADRAPED,
|
||||||
|
BT_SNAKE,
|
||||||
|
BT_SPIDER,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct bodypart_s {
|
||||||
|
enum BODYPART id;
|
||||||
|
char *name;
|
||||||
|
int armourok;
|
||||||
|
} bodypart_t;
|
||||||
|
|
||||||
// command types
|
// command types
|
||||||
typedef struct command_s {
|
typedef struct command_s {
|
||||||
enum COMMAND id;
|
enum COMMAND id;
|
||||||
|
@ -3246,6 +3271,9 @@ typedef struct race_s {
|
||||||
struct glyph_s glyph;
|
struct glyph_s glyph;
|
||||||
float weight;
|
float weight;
|
||||||
struct flagpile_s *flags;
|
struct flagpile_s *flags;
|
||||||
|
struct bodypart_s bodypart[MAXBODYPARTS];
|
||||||
|
int nbodyparts;
|
||||||
|
|
||||||
// speed modifiers
|
// speed modifiers
|
||||||
// hit dice
|
// hit dice
|
||||||
struct race_s *next, *prev;
|
struct race_s *next, *prev;
|
||||||
|
|
64
io.c
64
io.c
|
@ -31,6 +31,8 @@ WINDOW *statwin;
|
||||||
|
|
||||||
int statdirty = B_TRUE;
|
int statdirty = B_TRUE;
|
||||||
|
|
||||||
|
int inaskcoords = B_FALSE; // are we inside this function?
|
||||||
|
|
||||||
int hascolour = B_TRUE;
|
int hascolour = B_TRUE;
|
||||||
|
|
||||||
int noredraw = B_FALSE;
|
int noredraw = B_FALSE;
|
||||||
|
@ -546,6 +548,11 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
int nretflags;
|
int nretflags;
|
||||||
flag_t *retflag[MAXCANDIDATES];
|
flag_t *retflag[MAXCANDIDATES];
|
||||||
|
|
||||||
|
// rememebr that we're in this function. the main use for this is to ensure
|
||||||
|
// that when adding a fake corpse for lfs who are feigning death, that we don't
|
||||||
|
// do a screen update (due to adding an object in sight of the player)
|
||||||
|
inaskcoords = B_TRUE;
|
||||||
|
|
||||||
iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL);
|
iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL);
|
||||||
|
|
||||||
// remember previously targetted lifeforms
|
// remember previously targetted lifeforms
|
||||||
|
@ -1027,19 +1034,27 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
startlf = c->lf->id;
|
startlf = c->lf->id;
|
||||||
}
|
}
|
||||||
restoregamewindows();
|
restoregamewindows();
|
||||||
|
inaskcoords = B_FALSE;
|
||||||
return c;
|
return c;
|
||||||
} else if (ch == 'v') { // view
|
} else if (ch == 'v') { // view
|
||||||
// todo: show obpile or view lf
|
// todo: show obpile or view lf
|
||||||
if (c->lf && cansee(player, c->lf)) {
|
if (c->lf && cansee(player, c->lf) && (isplayer(c->lf) || !lfhasflag(c->lf, F_FEIGNINGDEATH))) {
|
||||||
showlfstats(c->lf, B_FALSE);
|
showlfstats(c->lf, B_FALSE);
|
||||||
} else if (haslos(player, c)) {
|
} else if (haslos(player, c)) {
|
||||||
object_t *o;
|
object_t *o,*tempob = NULL;
|
||||||
|
// lf feigning death here? put down a fake corpse.
|
||||||
|
if (c->lf && lfhasflag(c->lf, F_FEIGNINGDEATH) && !isplayer(c->lf)) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
sprintf(obname, "%s corpse", c->lf->race->name);
|
||||||
|
tempob = addob(c->obpile, obname);
|
||||||
|
}
|
||||||
// show objects
|
// show objects
|
||||||
o = doaskobject(c->obpile, "Describe which object", NULL, B_FALSE, B_FALSE, '\0', AO_NONE, F_NONE);
|
o = doaskobject(c->obpile, "Describe which object", NULL, B_FALSE, B_FALSE, '\0', AO_NONE, F_NONE);
|
||||||
while (o) {
|
while (o) {
|
||||||
describeob(o);
|
describeob(o);
|
||||||
o = doaskobject(c->obpile, "Describe which object", NULL, B_FALSE, B_FALSE, '\0', AO_NONE, F_NONE);
|
o = doaskobject(c->obpile, "Describe which object", NULL, B_FALSE, B_FALSE, '\0', AO_NONE, F_NONE);
|
||||||
}
|
}
|
||||||
|
if (tempob) killob(tempob);
|
||||||
}
|
}
|
||||||
} else if (ch == 27) { // esc - cancel
|
} else if (ch == 27) { // esc - cancel
|
||||||
finished = B_TRUE;
|
finished = B_TRUE;
|
||||||
|
@ -1062,6 +1077,8 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inaskcoords = B_FALSE;
|
||||||
clearmsg();
|
clearmsg();
|
||||||
restoregamewindows();
|
restoregamewindows();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -9031,7 +9048,7 @@ void showlfarmour(lifeform_t *lf) {
|
||||||
// default
|
// default
|
||||||
strcpy(rhs, "");
|
strcpy(rhs, "");
|
||||||
|
|
||||||
if (!lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
if (hasbp(lf, bp)) {
|
||||||
object_t *outerob;
|
object_t *outerob;
|
||||||
snprintf(buf, BUFLEN, "%13s:%1s",getbodypartname(lf, bp), " ");
|
snprintf(buf, BUFLEN, "%13s:%1s",getbodypartname(lf, bp), " ");
|
||||||
o = getequippedob(lf->pack, bp);
|
o = getequippedob(lf->pack, bp);
|
||||||
|
@ -9908,29 +9925,29 @@ void showlfstats(lifeform_t *lf, int showall) {
|
||||||
}
|
}
|
||||||
|
|
||||||
nmissingbp = 0;
|
nmissingbp = 0;
|
||||||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
getflags(lf->flags, retflag, &nretflags, F_NOBODYPART, F_NONE);
|
||||||
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
for (i = 0; i < nretflags; i++) {
|
||||||
if (bp == BP_RIGHTFINGER) {
|
bp = retflag[i]->val[0];
|
||||||
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
if (bp == BP_RIGHTFINGER) {
|
||||||
missingbp[nmissingbp] = bp;
|
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
||||||
nmissingbp++;
|
|
||||||
}
|
|
||||||
} else if (bp == BP_LEFTFINGER) {
|
|
||||||
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL) &&
|
|
||||||
!lfhasflagval(lf, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL)
|
|
||||||
) {
|
|
||||||
missingbp[nmissingbp] = bp;
|
|
||||||
nmissingbp++;
|
|
||||||
}
|
|
||||||
} else if (bp == BP_SECWEAPON) {
|
|
||||||
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
|
||||||
missingbp[nmissingbp] = bp;
|
|
||||||
nmissingbp++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
missingbp[nmissingbp] = bp;
|
missingbp[nmissingbp] = bp;
|
||||||
nmissingbp++;
|
nmissingbp++;
|
||||||
}
|
}
|
||||||
|
} else if (bp == BP_LEFTFINGER) {
|
||||||
|
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL) &&
|
||||||
|
!lfhasflagval(lf, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL)
|
||||||
|
) {
|
||||||
|
missingbp[nmissingbp] = bp;
|
||||||
|
nmissingbp++;
|
||||||
|
}
|
||||||
|
} else if (bp == BP_SECWEAPON) {
|
||||||
|
if (!lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
||||||
|
missingbp[nmissingbp] = bp;
|
||||||
|
nmissingbp++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
missingbp[nmissingbp] = bp;
|
||||||
|
nmissingbp++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9986,7 +10003,6 @@ void showlfstats(lifeform_t *lf, int showall) {
|
||||||
mt = findmaterial(getlfmaterial(lf));
|
mt = findmaterial(getlfmaterial(lf));
|
||||||
wrapprint(mainwin, &y, &x, "%s %s made out of %s. ",you(lf), is(lf), mt->name);
|
wrapprint(mainwin, &y, &x, "%s %s made out of %s. ",you(lf), is(lf), mt->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (mode == 'a') {
|
} else if (mode == 'a') {
|
||||||
centre(mainwin, C_WHITE, 0, "ABILITIES");
|
centre(mainwin, C_WHITE, 0, "ABILITIES");
|
||||||
y = 2;
|
y = 2;
|
||||||
|
|
281
lf.c
281
lf.c
|
@ -217,6 +217,17 @@ int bleedfrom(lifeform_t *lf, enum BODYPART bp, int splatter) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bpcantakearmour(lifeform_t *lf, enum BODYPART bp) {
|
||||||
|
int i;
|
||||||
|
// unnaturally shaped limbs?
|
||||||
|
for (i = 0; i < lf->race->nbodyparts; i++) {
|
||||||
|
if ((lf->race->bodypart[i].id == bp) && !lf->race->bodypart[i].armourok) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void breakgrabs(lifeform_t *lf, int fromme, int tome) {
|
void breakgrabs(lifeform_t *lf, int fromme, int tome) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
lifeform_t *alf;
|
lifeform_t *alf;
|
||||||
|
@ -547,6 +558,17 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||||
if (f) {
|
if (f) {
|
||||||
int needgrab = B_FALSE;
|
int needgrab = B_FALSE;
|
||||||
|
|
||||||
|
// flying with broken/destroyed wings?
|
||||||
|
if ((oid == OT_S_FLIGHT) && (f->lifetime == FROMRACE)) {
|
||||||
|
if (lfhasflagval(lf, F_INJURY, IJ_WINGTORN, NA, NA, NULL)) {
|
||||||
|
reason = E_INJURED;
|
||||||
|
return B_FALSE;
|
||||||
|
} else if (lfhasflagval(lf, F_NOBODYPART, BP_WINGS, NA, NA, NULL)) {
|
||||||
|
reason = E_INJURED;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// get canwill opts
|
// get canwill opts
|
||||||
texttospellopts(f->text, "needgrab:", &needgrab, NULL);
|
texttospellopts(f->text, "needgrab:", &needgrab, NULL);
|
||||||
|
|
||||||
|
@ -845,12 +867,8 @@ int canmakerecipe(lifeform_t *lf, recipe_t *rec) {
|
||||||
|
|
||||||
int canopendoors(lifeform_t *lf) {
|
int canopendoors(lifeform_t *lf) {
|
||||||
if (lf) {
|
if (lf) {
|
||||||
if (!lfhasflag(lf, F_HUMANOID)) {
|
if (!lfhasflag(lf, F_HUMANOID)) return B_FALSE;
|
||||||
return B_FALSE;
|
if (!hasbp(lf, BP_HANDS)) return B_FALSE;
|
||||||
}
|
|
||||||
if (lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
|
||||||
return B_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
@ -1138,7 +1156,8 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
|
||||||
if (!hasbp(lf, where)) {
|
if (!hasbp(lf, where)) {
|
||||||
reason = E_NOBP;
|
reason = E_NOBP;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
} else if (lfhasflagval(lf, F_NOARMOURON, where, NA, NA, NULL)) {
|
}
|
||||||
|
if (!bpcantakearmour(lf, where)) {
|
||||||
reason = E_DOESNTFIT;
|
reason = E_DOESNTFIT;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1327,7 +1346,7 @@ int canweild(lifeform_t *lf, object_t *o) {
|
||||||
}
|
}
|
||||||
} else if (f->id == F_TWOHANDED) {
|
} else if (f->id == F_TWOHANDED) {
|
||||||
// need both hands free...
|
// need both hands free...
|
||||||
if (lfhasflagval(lf, F_NOBODYPART, otherloc, NA, NA, NULL)) {
|
if (!hasbp(lf, otherloc)) {
|
||||||
reason = E_NOHANDS;
|
reason = E_NOHANDS;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1417,6 +1436,9 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
||||||
case E_NOMP:
|
case E_NOMP:
|
||||||
msg("You don't have enough mana to cast that.");
|
msg("You don't have enough mana to cast that.");
|
||||||
break;
|
break;
|
||||||
|
case E_INJURED:
|
||||||
|
msg("Your injury prevents you from doing that.");
|
||||||
|
break;
|
||||||
case E_LOWIQ:
|
case E_LOWIQ:
|
||||||
msg("You are not smart enough to cast spells.");
|
msg("You are not smart enough to cast spells.");
|
||||||
break;
|
break;
|
||||||
|
@ -1563,7 +1585,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
||||||
// special case
|
// special case
|
||||||
f = lfhasflagval(lf, F_SPELLCASTTEXT, sid, NA, NA, NULL); // specific text for this spell
|
f = lfhasflagval(lf, F_SPELLCASTTEXT, sid, NA, NA, NULL); // specific text for this spell
|
||||||
if (!f) {
|
if (!f) {
|
||||||
f = lfhasflag(lf, F_SPELLCASTTEXT); // generic spellcast
|
f = lfhasflagval(lf, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); // generic spellcast
|
||||||
}
|
}
|
||||||
if (f) {
|
if (f) {
|
||||||
if (strlen(f->text)) {
|
if (strlen(f->text)) {
|
||||||
|
@ -4702,8 +4724,10 @@ enum ALLEGIENCE getallegiance(lifeform_t *lf) {
|
||||||
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs) {
|
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
enum BODYPART bp;
|
enum BODYPART bp;
|
||||||
|
int i;
|
||||||
*nobs = 0;
|
*nobs = 0;
|
||||||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
for (i = 0; i < lf->race->nbodyparts; i++) {
|
||||||
|
bp = lf->race->bodypart[i].id;
|
||||||
o = getouterequippedob(lf, bp);
|
o = getouterequippedob(lf, bp);
|
||||||
if (o) {
|
if (o) {
|
||||||
int n,found = B_FALSE;
|
int n,found = B_FALSE;
|
||||||
|
@ -5297,26 +5321,40 @@ object_t *getbestweapon(lifeform_t *lf) {
|
||||||
|
|
||||||
int getbodyparthitchance(enum BODYPART bp) {
|
int getbodyparthitchance(enum BODYPART bp) {
|
||||||
switch (bp) {
|
switch (bp) {
|
||||||
|
case BP_WEAPON: return 0;
|
||||||
|
case BP_SECWEAPON: return 0;
|
||||||
case BP_EYES: return 1;
|
case BP_EYES: return 1;
|
||||||
case BP_HEAD: return 2;
|
case BP_HEAD: return 2;
|
||||||
case BP_WAIST: return 3;
|
case BP_WAIST: return 3;
|
||||||
case BP_HANDS: return 3;
|
case BP_HANDS: return 3;
|
||||||
case BP_FEET: return 3;
|
case BP_FEET: return 3;
|
||||||
|
case BP_TAIL: return 3;
|
||||||
|
case BP_FRONTLEGS: return 4;
|
||||||
|
case BP_BACKLEGS: return 4;
|
||||||
case BP_LEGS: return 4;
|
case BP_LEGS: return 4;
|
||||||
case BP_SHOULDERS: return 4;
|
case BP_SHOULDERS: return 4;
|
||||||
|
case BP_WINGS: return 4;
|
||||||
case BP_BODY: return 6;
|
case BP_BODY: return 6;
|
||||||
default: break;
|
|
||||||
|
case BP_EARS:
|
||||||
|
case BP_RIGHTFINGER:
|
||||||
|
case BP_LEFTFINGER:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0; // ie rings, ears, weapon
|
return 0; // ie rings, ears, weapon
|
||||||
}
|
}
|
||||||
|
|
||||||
char *getbodypartname(lifeform_t *lf, enum BODYPART bp) {
|
char *getbodypartname(lifeform_t *lf, enum BODYPART bp) {
|
||||||
flag_t *f;
|
|
||||||
|
|
||||||
if (lf) {
|
if (lf) {
|
||||||
f = lfhasflagval(lf, F_BODYPARTNAME, bp, NA, NA, NULL);
|
int i;
|
||||||
if (f) {
|
|
||||||
return f->text;
|
// does this bodypart have a special name?
|
||||||
|
for (i = 0; i < lf->race->nbodyparts; i++) {
|
||||||
|
if (lf->race->bodypart[i].id == bp) {
|
||||||
|
if (strlen(lf->race->bodypart[i].name)) {
|
||||||
|
return lf->race->bodypart[i].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5343,10 +5381,18 @@ char *getbodypartname(lifeform_t *lf, enum BODYPART bp) {
|
||||||
return "shoulders";
|
return "shoulders";
|
||||||
case BP_WAIST:
|
case BP_WAIST:
|
||||||
return "waist";
|
return "waist";
|
||||||
|
case BP_FRONTLEGS:
|
||||||
|
return "front legs";
|
||||||
|
case BP_BACKLEGS:
|
||||||
|
return "back legs";
|
||||||
case BP_LEGS:
|
case BP_LEGS:
|
||||||
return "legs";
|
return "legs";
|
||||||
case BP_FEET:
|
case BP_FEET:
|
||||||
return "feet";
|
return "feet";
|
||||||
|
case BP_TAIL:
|
||||||
|
return "tail";
|
||||||
|
case BP_WINGS:
|
||||||
|
return "wings";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
@ -5362,8 +5408,12 @@ char *getbodypartequipname(enum BODYPART bp) {
|
||||||
case BP_HANDS:
|
case BP_HANDS:
|
||||||
case BP_HEAD:
|
case BP_HEAD:
|
||||||
case BP_BODY:
|
case BP_BODY:
|
||||||
|
case BP_FRONTLEGS:
|
||||||
|
case BP_BACKLEGS:
|
||||||
case BP_LEGS:
|
case BP_LEGS:
|
||||||
case BP_FEET:
|
case BP_FEET:
|
||||||
|
case BP_WINGS:
|
||||||
|
case BP_TAIL:
|
||||||
return "on";
|
return "on";
|
||||||
case BP_EYES:
|
case BP_EYES:
|
||||||
case BP_SHOULDERS:
|
case BP_SHOULDERS:
|
||||||
|
@ -5708,6 +5758,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
|
||||||
case IJ_SHOULDERDISLOCATED:
|
case IJ_SHOULDERDISLOCATED:
|
||||||
acc -= 20; break;
|
acc -= 20; break;
|
||||||
case IJ_RIBBROKEN:
|
case IJ_RIBBROKEN:
|
||||||
|
case IJ_TAILBROKEN:
|
||||||
acc -= 30; break;
|
acc -= 30; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6444,8 +6495,14 @@ int getmovespeed(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// flying in low gravity?
|
// flying in low gravity?
|
||||||
if (lfhasflag(lf, F_GRAVLESSENED) && lfhasflag(lf, F_FLYING)) {
|
f = lfhasflag(lf, F_FLYING);
|
||||||
speed -= 5;
|
if (f) {
|
||||||
|
if (lfhasflag(lf, F_GRAVLESSENED)) {
|
||||||
|
speed -= 5;
|
||||||
|
}
|
||||||
|
if ((f->lifetime == FROMRACE) && lfhasflagval(lf, F_INJURY, IJ_WINGBRUISED, NA, NA, NULL)) {
|
||||||
|
speed += 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (isburdened(lf)) {
|
switch (isburdened(lf)) {
|
||||||
|
@ -6928,8 +6985,15 @@ enum BODYPART getrandomcorebp(lifeform_t *lf) {
|
||||||
enum BODYPART bp[4],selbp = BP_NONE;
|
enum BODYPART bp[4],selbp = BP_NONE;
|
||||||
if (hasbp(lf, BP_BODY)) bp[nparts++] = BP_BODY;
|
if (hasbp(lf, BP_BODY)) bp[nparts++] = BP_BODY;
|
||||||
if (hasbp(lf, BP_HANDS)) bp[nparts++] = BP_HANDS;
|
if (hasbp(lf, BP_HANDS)) bp[nparts++] = BP_HANDS;
|
||||||
if (hasbp(lf, BP_LEGS)) bp[nparts++] = BP_LEGS;
|
|
||||||
if (hasbp(lf, BP_HEAD)) bp[nparts++] = BP_HEAD;
|
if (hasbp(lf, BP_HEAD)) bp[nparts++] = BP_HEAD;
|
||||||
|
if (hasbp(lf, BP_LEGS) || hasbp(lf, BP_FRONTLEGS) || hasbp(lf, BP_BACKLEGS)) {
|
||||||
|
bp[nparts++] = BP_LEGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nparts) {
|
||||||
|
return BP_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0;i < nparts; i++) {
|
for (i = 0;i < nparts; i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
cutoff[i] = getbodyparthitchance(bp[i]);
|
cutoff[i] = getbodyparthitchance(bp[i]);
|
||||||
|
@ -8633,8 +8697,21 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
||||||
object_t *wep = NULL;
|
object_t *wep = NULL;
|
||||||
int howlong;
|
int howlong;
|
||||||
|
|
||||||
|
|
||||||
if (where == BP_NONE) return B_TRUE;
|
if (where == BP_NONE) return B_TRUE;
|
||||||
if (!hasbp(lf, where)) return B_TRUE;
|
|
||||||
|
if (!hasbp(lf, where)) {
|
||||||
|
if (where == BP_LEGS) {
|
||||||
|
// adjust bp_legs into bp_frontlegs/bp_backelgs
|
||||||
|
if (hasbp(lf, BP_FRONTLEGS) || hasbp(lf, BP_BACKLEGS)) {
|
||||||
|
// ok.
|
||||||
|
} else {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (lfhasflag(lf, F_NOINJURIES)) return B_TRUE;
|
if (lfhasflag(lf, F_NOINJURIES)) return B_TRUE;
|
||||||
if (lfhasflagval(lf, F_INJURY, NA, where, NA, NULL)) return B_TRUE;
|
if (lfhasflagval(lf, F_INJURY, NA, where, NA, NULL)) return B_TRUE;
|
||||||
|
|
||||||
|
@ -8702,6 +8779,21 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
||||||
desc = strdup("ankle is swollen^cannot wear/remove boots"); break;
|
desc = strdup("ankle is swollen^cannot wear/remove boots"); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case BP_TAIL:
|
||||||
|
switch (rnd(1,2)) {
|
||||||
|
case 1:
|
||||||
|
inj = IJ_TAILBRUISED;
|
||||||
|
desc = strdup("tail is bruised^accuracy penalty"); break;
|
||||||
|
case 2:
|
||||||
|
inj = IJ_TAILBROKEN;
|
||||||
|
desc = strdup("tail is fractured^occasional random movement"); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BP_WINGS:
|
||||||
|
inj = IJ_WINGBRUISED;
|
||||||
|
desc = strdup("wings are bruised^flight speed lowered"); break;
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
} else if (damtype == DT_SLASH) {
|
} else if (damtype == DT_SLASH) {
|
||||||
|
@ -8787,6 +8879,22 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
||||||
inj = IJ_HAMSTRUNG; desc = strdup("left hamstring is torn^lower move speed, chance of falling");
|
inj = IJ_HAMSTRUNG; desc = strdup("left hamstring is torn^lower move speed, chance of falling");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case BP_TAIL:
|
||||||
|
inj = IJ_TAILBLEED;
|
||||||
|
desc = strdup("tail is bleeding^no additional effects");
|
||||||
|
break;
|
||||||
|
case BP_WINGS:
|
||||||
|
switch (rnd(1,2)) {
|
||||||
|
case 1:
|
||||||
|
inj = IJ_WINGTORN;
|
||||||
|
desc = strdup("wings are torn^cannot fly");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
inj = IJ_WINGBLEED;
|
||||||
|
desc = strdup("wings are bleeding^flying causes damage");
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
} else if (damtype == DT_EXPLOSIVE) {
|
} else if (damtype == DT_EXPLOSIVE) {
|
||||||
|
@ -8851,6 +8959,16 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
||||||
case BP_LEGS:
|
case BP_LEGS:
|
||||||
// lose limb
|
// lose limb
|
||||||
break;
|
break;
|
||||||
|
case BP_TAIL:
|
||||||
|
inj = IJ_TAILLACERATED;
|
||||||
|
desc = strdup("tail is lacerated^chance of falling during movement");
|
||||||
|
howlong = PERMENANT;
|
||||||
|
break;
|
||||||
|
case BP_WINGS:
|
||||||
|
inj = IJ_WINGDESTROYED;
|
||||||
|
desc = strdup("wings are destroyed^cannot fly");
|
||||||
|
howlong = PERMENANT;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8884,6 +9002,12 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
|
||||||
wep = getweapon(lf);
|
wep = getweapon(lf);
|
||||||
if (wep) drop(wep, wep->amt);
|
if (wep) drop(wep, wep->amt);
|
||||||
break;
|
break;
|
||||||
|
case IJ_WINGTORN:
|
||||||
|
killflagsofid(lf->flags, F_FLYING);
|
||||||
|
break;
|
||||||
|
case IJ_WINGDESTROYED:
|
||||||
|
addflag(lf->flags, F_NOBODYPART, BP_WINGS, B_FROMINJURY, NA, NULL);
|
||||||
|
break;
|
||||||
case IJ_WINDED:
|
case IJ_WINDED:
|
||||||
lf->stamina = 0;
|
lf->stamina = 0;
|
||||||
if (isplayer(lf)) statdirty = B_TRUE;
|
if (isplayer(lf)) statdirty = B_TRUE;
|
||||||
|
@ -9094,10 +9218,14 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int hasbp(lifeform_t *lf, enum BODYPART bp) {
|
int hasbp(lifeform_t *lf, enum BODYPART bp) {
|
||||||
|
int i;
|
||||||
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
return B_TRUE;
|
for (i = 0; i < lf->race->nbodyparts; i++) {
|
||||||
|
if (lf->race->bodypart[i].id == bp) return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid) {
|
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid) {
|
||||||
|
@ -9666,6 +9794,8 @@ int isfullyhealed(lifeform_t *lf) {
|
||||||
healed = B_FALSE;
|
healed = B_FALSE;
|
||||||
} else if (getstamina(lf) < getmaxstamina(lf)) {
|
} else if (getstamina(lf) < getmaxstamina(lf)) {
|
||||||
healed = B_FALSE;
|
healed = B_FALSE;
|
||||||
|
} else if (hashealableinjuries(lf)) {
|
||||||
|
healed = B_FALSE;
|
||||||
}
|
}
|
||||||
return healed;
|
return healed;
|
||||||
}
|
}
|
||||||
|
@ -9967,6 +10097,17 @@ job_t *addjob(enum JOB id, char *name, char *desc) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addbodypart(race_t *r, enum BODYPART bp, char *name) {
|
||||||
|
r->bodypart[r->nbodyparts].id = bp;
|
||||||
|
if (name) {
|
||||||
|
r->bodypart[r->nbodyparts].name = strdup(name);
|
||||||
|
} else {
|
||||||
|
r->bodypart[r->nbodyparts].name = strdup("");
|
||||||
|
}
|
||||||
|
r->bodypart[r->nbodyparts].armourok = B_TRUE;
|
||||||
|
r->nbodyparts++;
|
||||||
|
}
|
||||||
|
|
||||||
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level) {
|
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level) {
|
||||||
return real_addlf(cell, rid, level, C_AI);
|
return real_addlf(cell, rid, level, C_AI);
|
||||||
}
|
}
|
||||||
|
@ -10074,7 +10215,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
||||||
|
|
||||||
// set race - this will inherit race flags and material
|
// set race - this will inherit race flags and material
|
||||||
a->race = NULL;
|
a->race = NULL;
|
||||||
|
|
||||||
setrace(a, rid, B_FALSE);
|
setrace(a, rid, B_FALSE);
|
||||||
|
|
||||||
// set stamina AFTER setrace as it depends on your attribs
|
// set stamina AFTER setrace as it depends on your attribs
|
||||||
|
@ -10130,6 +10271,8 @@ race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcol
|
||||||
a->glyph.ch = glyph;
|
a->glyph.ch = glyph;
|
||||||
a->glyph.colour = glyphcolour;
|
a->glyph.colour = glyphcolour;
|
||||||
|
|
||||||
|
a->nbodyparts = 0;
|
||||||
|
|
||||||
a->flags = addflagpile(NULL, NULL);
|
a->flags = addflagpile(NULL, NULL);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -10641,6 +10784,7 @@ int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int askforpayment(lifeform_t *shk, lifeform_t *lf) {
|
int askforpayment(lifeform_t *shk, lifeform_t *lf) {
|
||||||
char saybuf[BUFLEN];
|
char saybuf[BUFLEN];
|
||||||
int totcost = 0;
|
int totcost = 0;
|
||||||
|
@ -11939,6 +12083,16 @@ int needstorest(lifeform_t *lf, char *validchars) {
|
||||||
return need;
|
return need;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void noarmouron(race_t *r, enum BODYPART bp) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < r->nbodyparts; i++) {
|
||||||
|
if (r->bodypart[i].id == bp) {
|
||||||
|
r->bodypart[i].armourok = B_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns TRUE if the player heard it.
|
// returns TRUE if the player heard it.
|
||||||
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char *text, char *seetext) {
|
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char *text, char *seetext) {
|
||||||
lifeform_t *l;
|
lifeform_t *l;
|
||||||
|
@ -13376,6 +13530,61 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setbodypartname(race_t *r, enum BODYPART bp, char *name) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < r->nbodyparts; i++) {
|
||||||
|
if (r->bodypart[i].id == bp) {
|
||||||
|
free(r->bodypart[i].name);
|
||||||
|
r->bodypart[i].name = strdup(name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setbodytype(race_t *r, enum BODYTYPE bt) {
|
||||||
|
int i;
|
||||||
|
switch (bt) {
|
||||||
|
case BT_BIRD:
|
||||||
|
addbodypart(r, BP_EYES, NULL);
|
||||||
|
addbodypart(r, BP_HEAD, NULL);
|
||||||
|
addbodypart(r, BP_BODY, NULL);
|
||||||
|
addbodypart(r, BP_LEGS, NULL);
|
||||||
|
addbodypart(r, BP_FEET, "talons");
|
||||||
|
addbodypart(r, BP_WINGS, NULL);
|
||||||
|
break;
|
||||||
|
case BT_HUMANOID:
|
||||||
|
for (i = BP_WEAPON; i <= BP_LEFTFINGER; i++) {
|
||||||
|
addbodypart(r, i, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BT_QUADRAPED:
|
||||||
|
addbodypart(r, BP_EYES, NULL);
|
||||||
|
addbodypart(r, BP_HEAD, NULL);
|
||||||
|
addbodypart(r, BP_BODY, NULL);
|
||||||
|
addbodypart(r, BP_BACKLEGS, "back legs");
|
||||||
|
addbodypart(r, BP_FRONTLEGS, "front legs");
|
||||||
|
addbodypart(r, BP_FEET, "paws");
|
||||||
|
break;
|
||||||
|
case BT_FISH:
|
||||||
|
addbodypart(r, BP_EYES, NULL);
|
||||||
|
addbodypart(r, BP_HEAD, NULL);
|
||||||
|
addbodypart(r, BP_BODY, NULL);
|
||||||
|
addbodypart(r, BP_TAIL, NULL);
|
||||||
|
break;
|
||||||
|
case BT_SNAKE:
|
||||||
|
addbodypart(r, BP_EYES, NULL);
|
||||||
|
addbodypart(r, BP_HEAD, NULL);
|
||||||
|
addbodypart(r, BP_TAIL, NULL);
|
||||||
|
break;
|
||||||
|
case BT_SPIDER:
|
||||||
|
addbodypart(r, BP_EYES, NULL);
|
||||||
|
addbodypart(r, BP_HEAD, "cephalothorax");
|
||||||
|
addbodypart(r, BP_BODY, "abdomen");
|
||||||
|
addbodypart(r, BP_LEGS, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int setfacing(lifeform_t *lf, int dir) {
|
int setfacing(lifeform_t *lf, int dir) {
|
||||||
if (isclimbing(lf)) { // can't change dir while climbing
|
if (isclimbing(lf)) { // can't change dir while climbing
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
@ -13634,22 +13843,20 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
|
||||||
if (lfhasflagval(lf, F_NOBODYPART, bp, NA, NA, NULL)) {
|
if (!hasbp(lf, bp)) {
|
||||||
for (o = lf->pack->first; o ; o = nexto ) {
|
o = getequippedob(lf->pack, bp);
|
||||||
nexto = o->next;
|
if (o) {
|
||||||
if (hasflagval(o->flags, F_EQUIPPED, bp, NA, NA, NULL)) {
|
char obname[BUFLEN];
|
||||||
char obname[BUFLEN];
|
getobname(o, obname, o->amt);
|
||||||
getobname(o, obname, o->amt);
|
// drop it!
|
||||||
// drop it!
|
if (isplayer(lf)) {
|
||||||
if (isplayer(lf)) {
|
msg("Your %s drops to the ground!",noprefix(obname));
|
||||||
msg("Your %s drops to the ground!",noprefix(obname));
|
} else if (cansee(player, lf)) {
|
||||||
} else if (cansee(player, lf)) {
|
getlfname(lf, buf);
|
||||||
getlfname(lf, buf);
|
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
|
||||||
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
|
noprefix(obname));
|
||||||
noprefix(obname));
|
|
||||||
}
|
|
||||||
moveob(o, lf->cell->obpile, o->amt);
|
|
||||||
}
|
}
|
||||||
|
moveob(o, lf->cell->obpile, o->amt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
lf.h
5
lf.h
|
@ -1,5 +1,6 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
void addbodypart(race_t *r, enum BODYPART bp, char *name);
|
||||||
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
|
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);
|
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
|
||||||
job_t *addjob(enum JOB id, char *name, char *desc);
|
job_t *addjob(enum JOB id, char *name, char *desc);
|
||||||
|
@ -25,6 +26,7 @@ int appearsrandomly(enum RACE rid);
|
||||||
void awardxpfor(lifeform_t *killed, float pct);
|
void awardxpfor(lifeform_t *killed, float pct);
|
||||||
void bleed(lifeform_t *lf, int splatter);
|
void bleed(lifeform_t *lf, int splatter);
|
||||||
int bleedfrom(lifeform_t *lf, enum BODYPART bp, int splatter);
|
int bleedfrom(lifeform_t *lf, enum BODYPART bp, int splatter);
|
||||||
|
int bpcantakearmour(lifeform_t *lf, enum BODYPART bp);
|
||||||
void breakgrabs(lifeform_t *lf, int fromme, int tome);
|
void breakgrabs(lifeform_t *lf, int fromme, int tome);
|
||||||
void breakaitargets(lifeform_t *lf, int onlylowerlev);
|
void breakaitargets(lifeform_t *lf, int onlylowerlev);
|
||||||
long calcscore(lifeform_t *lf);
|
long calcscore(lifeform_t *lf);
|
||||||
|
@ -334,6 +336,7 @@ void modmorale(lifeform_t *lf, int howmuch);
|
||||||
void modstamina(lifeform_t *lf, float howmuch);
|
void modstamina(lifeform_t *lf, float howmuch);
|
||||||
int movecausesnoise(lifeform_t *lf);
|
int movecausesnoise(lifeform_t *lf);
|
||||||
int needstorest(lifeform_t *lf, char *validchars);
|
int needstorest(lifeform_t *lf, char *validchars);
|
||||||
|
void noarmouron(race_t *r, enum BODYPART bp);
|
||||||
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
||||||
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
|
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
|
||||||
void outfitlf(lifeform_t *lf);
|
void outfitlf(lifeform_t *lf);
|
||||||
|
@ -362,6 +365,8 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
|
||||||
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
|
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
|
||||||
//int setammo(lifeform_t *lf, object_t *o);
|
//int setammo(lifeform_t *lf, object_t *o);
|
||||||
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
||||||
|
void setbodypartname(race_t *r, enum BODYPART bp, char *name);
|
||||||
|
void setbodytype(race_t *r, enum BODYTYPE bt);
|
||||||
int setfacing(lifeform_t *lf, int dir);
|
int setfacing(lifeform_t *lf, int dir);
|
||||||
void setfollowdistance(lifeform_t *lf, int min, int max);
|
void setfollowdistance(lifeform_t *lf, int min, int max);
|
||||||
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
||||||
|
|
42
move.c
42
move.c
|
@ -1000,6 +1000,10 @@ int moveeffects(lifeform_t *lf) {
|
||||||
if (isplayer(lf)) didmsg = B_TRUE;
|
if (isplayer(lf)) didmsg = B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (onein(10) && lfhasflagval(lf, F_INJURY, IJ_TAILLACERATED, NA, NA, NULL)) {
|
||||||
|
fall(lf, NULL, B_TRUE);
|
||||||
|
if (isplayer(lf)) didmsg = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (isbleeding(lf)) {
|
if (isbleeding(lf)) {
|
||||||
if (hasbleedinginjury(lf, BP_LEGS)) {
|
if (hasbleedinginjury(lf, BP_LEGS)) {
|
||||||
|
@ -1013,6 +1017,19 @@ int moveeffects(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lfhasflagval(lf, F_INJURY, IJ_WINGBLEED, NA, NA, NULL)) {
|
||||||
|
flag_t *retflag[MAXCANDIDATES];
|
||||||
|
int nretflags,i;
|
||||||
|
getflags(lf->flags, retflag, &nretflags, F_FLYING, F_NONE);
|
||||||
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
if (retflag[i]->lifetime == FROMRACE) {
|
||||||
|
if (!bleedfrom(lf, BP_WINGS, B_FALSE)) {
|
||||||
|
losehp(lf, 1, DT_DIRECT, NULL, "blood loss");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f = lfhasflag(lf, F_PAIN);
|
f = lfhasflag(lf, F_PAIN);
|
||||||
if (f) {
|
if (f) {
|
||||||
if (!lfhasflag(lf, F_DRUNK)) {
|
if (!lfhasflag(lf, F_DRUNK)) {
|
||||||
|
@ -1634,8 +1651,8 @@ int movetowards(lifeform_t *lf, cell_t *dst, int dirtype, int strafe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int move_will_hurt(lifeform_t *lf) {
|
int move_will_hurt(lifeform_t *lf) {
|
||||||
flag_t *retflag[MAXCANDIDATES];
|
flag_t *retflag[MAXCANDIDATES],*retflag2[MAXCANDIDATES];
|
||||||
int nretflags,i;
|
int nretflags,nretflags2,i,n;
|
||||||
|
|
||||||
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_PAIN, F_NONE);
|
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_PAIN, F_NONE);
|
||||||
for (i = 0; i < nretflags; i++) {
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
@ -1645,14 +1662,23 @@ int move_will_hurt(lifeform_t *lf) {
|
||||||
if (f->id == F_INJURY) {
|
if (f->id == F_INJURY) {
|
||||||
switch (f->val[0]) {
|
switch (f->val[0]) {
|
||||||
case IJ_LEGBLEED:
|
case IJ_LEGBLEED:
|
||||||
return B_TRUE;
|
if (!isairborne(lf)) return B_TRUE;
|
||||||
|
break;
|
||||||
|
case IJ_WINGBLEED:
|
||||||
|
getflags(lf->flags, retflag2, &nretflags2, F_FLYING, F_NONE);
|
||||||
|
for (n = 0; n < nretflags2; n++) {
|
||||||
|
if (retflag[n]->lifetime == FROMRACE) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasbleedinginjury(lf, BP_LEGS)) {
|
if (hasbleedinginjury(lf, BP_LEGS) && !isairborne(lf)) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
|
@ -1910,7 +1936,7 @@ int closedoor(lifeform_t *lf, object_t *o) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lf && lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
if (lf && !canopendoors(lf)) {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
msg("You have no hands with which to close the door!");
|
msg("You have no hands with which to close the door!");
|
||||||
}
|
}
|
||||||
|
@ -2491,10 +2517,14 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
||||||
}
|
}
|
||||||
} else if (iswoozy(lf)) {
|
} else if (iswoozy(lf)) {
|
||||||
rndmove = B_TRUE;
|
rndmove = B_TRUE;
|
||||||
|
} else if (lfhasflagval(lf, F_INJURY, IJ_TAILBRUISED, NA, NA, NULL) && onein(6)) {
|
||||||
|
rndmove = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (rndmove) {
|
if (rndmove) {
|
||||||
dir = rnd(DC_N, DC_NW);
|
dir = rnd(DC_N, DC_NW);
|
||||||
|
strafe = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell = getcellindir(lf->cell, dir);
|
cell = getcellindir(lf->cell, dir);
|
||||||
|
@ -2509,7 +2539,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// warn before moving onto dangerous cells
|
// warn before moving onto dangerous cells
|
||||||
if (onpurpose && isplayer(lf) && !lfhasflag(lf, F_SNEAK)) {
|
if (onpurpose && isplayer(lf) && !lfhasflag(lf, F_SNEAK) && !rndmove) {
|
||||||
char ques[BUFLEN];
|
char ques[BUFLEN];
|
||||||
char ch;
|
char ch;
|
||||||
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
|
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
|
||||||
|
|
|
@ -28,6 +28,8 @@ extern material_t *material,*lastmaterial;
|
||||||
extern recipe_t *firstrecipe,*lastrecipe;
|
extern recipe_t *firstrecipe,*lastrecipe;
|
||||||
extern skill_t *firstskill, *lastskill;
|
extern skill_t *firstskill, *lastskill;
|
||||||
|
|
||||||
|
extern int inaskcoords;
|
||||||
|
|
||||||
void (*precalclos)(lifeform_t *);
|
void (*precalclos)(lifeform_t *);
|
||||||
|
|
||||||
extern object_t *retobs[MAXPILEOBS+1];
|
extern object_t *retobs[MAXPILEOBS+1];
|
||||||
|
@ -1651,8 +1653,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((gamemode == GM_GAMESTARTED) && !inaskcoords) {
|
||||||
if (gamemode == GM_GAMESTARTED) {
|
|
||||||
if (o && where->where && !hasflag(o->flags, F_NOGLYPH) && haslos(player, where->where) ) {
|
if (o && where->where && !hasflag(o->flags, F_NOGLYPH) && haslos(player, where->where) ) {
|
||||||
needredraw = B_TRUE;
|
needredraw = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
2
text.c
2
text.c
|
@ -771,7 +771,7 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
|
||||||
}
|
}
|
||||||
if (damtype == DT_BITE) return "gore";
|
if (damtype == DT_BITE) return "gore";
|
||||||
if (damtype == DT_SLASH) {
|
if (damtype == DT_SLASH) {
|
||||||
if (lfhasflagval(victim, F_NOBODYPART, BP_HEAD, NA, NA, NULL)) {
|
if (!hasbp(victim, BP_HEAD)) {
|
||||||
return "bisect";
|
return "bisect";
|
||||||
} else {
|
} else {
|
||||||
if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {
|
if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {
|
||||||
|
|
Loading…
Reference in New Issue