- [+] replace "fireplace" with "brazier"
- [+] make non-lethal kills (ie. knockouts) display in grey rather than green - [+] ability: merciful fighting? always does bashing damage, always ko. - [+] done - [+] Chatting to gods shouldn't work - [+] bug: when running with shift+dir, i'm running past corridors. - [+] when announcing skill gains, say if they are from a level. - [+] set lifetime to FROMJOB when giving them. - [+] if lifetime = FROMJOB, ""you can now use the ability 'xxx' (warrior skill)" - [+] grenade/c4 explosions should be able to damage cells! - [+] change grenades to have bigger radius (dtorth 1) - [+] automatically call "fireat" for grenades - [+] impement this - [+] make the timer shorter! - [+] add extra checks to stop monsters from attacking allies - [+] replace "insane"monster behaviour with F_TERRITORIAL v0=range. - [+] will atatck anything else visible within range xxx - [+] grave sprite should be able to see in the dark - [+] instead of saying "An orc [drunk]", change getlfname to return "a drunken orc" etc - [+] when you throw an object at someone in a wall, it should fall onto the ground in front, NOT the wall itself! - [+] show how MUCH high/low str/agi will affect weapon damage/accuracy - [+] different shoddy/masterwork text based on weapon types - [+] bug: monsters never bleed from injuries! - [+] another bug in getavgdam - negative accuracy returns negative damage since we modify damage by accuracy! - [+] within this function, limit accuracy to range 0-100 - [+] bug with options - opt->id never being initialised! - [+] don't apply "behaviours" to anythuing other than humanoids. - [+] increase missile accuracy if you are above your target - [+] (ie you are flying higher them them) - [+] getflightsizemod()
This commit is contained in:
parent
db0b726088
commit
849e567b43
14
ai.c
14
ai.c
|
@ -759,6 +759,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
}
|
||||
|
||||
if (pctchance(chance)) {
|
||||
flag_t *f;
|
||||
if (lfhasflag(lf, F_HATESALL) || lfhasflag(lf, F_RAGE)) {
|
||||
if (nhateposs < MAXCANDIDATES) {
|
||||
if (db) dblog(".oO { hate everything - found lfid %d (%s) ! }",who->id, who->race->name);
|
||||
|
@ -767,11 +768,18 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
break;
|
||||
} else if (lfhasflagval(lf, F_HATESRACE, who->race->id, NA, NA, NULL) ||
|
||||
lfhasflagval(lf, F_HATESRACE, who->race->baseid, NA, NA, NULL) ) {
|
||||
if (nhateposs < MAXCANDIDATES) {
|
||||
if ((nhateposs < MAXCANDIDATES) && !areallies(lf, who)) {
|
||||
if (db) dblog(".oO { found a hated target - lfid %d (%s) ! }",who->id, who->race->name);
|
||||
hateposs[nhateposs++] = who;
|
||||
}
|
||||
break;
|
||||
} else if ( ((f = lfhasflag(lf, F_TERRITORIAL)) != NULL) &&
|
||||
(getcelldist(who->cell, lf->cell) <= f->val[0]) ) {
|
||||
if ((nhateposs < MAXCANDIDATES) && !areallies(lf, who)) {
|
||||
if (db) dblog(".oO { territorial and found target in range - lfid %d (%s) ! }",who->id, who->race->name);
|
||||
hateposs[nhateposs++] = who;
|
||||
}
|
||||
break;
|
||||
} else if (!nhateposs && areenemies(lf, who)) { // dont check if we've already found a hated target
|
||||
if (nposs < MAXCANDIDATES) {
|
||||
if (db) dblog(".oO { found an enemy target - lfid %d (%s) ! }",who->id, who->race->name);
|
||||
|
@ -780,7 +788,9 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
} else {
|
||||
getflags(lf->flags, retflag, &nretflags, F_HATESRACEWITHFLAG, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (lfhasflag(who, retflag[i]->id)) {
|
||||
if (lfhasflag(who, retflag[i]->id) &&
|
||||
!areallies(lf, who)) {
|
||||
|
||||
if (db) dblog(".oO { found a target with hated flags - lfid %d (%s) ! }",who->id, who->race->name);
|
||||
hateposs[nhateposs++] = who;
|
||||
}
|
||||
|
|
31
attack.c
31
attack.c
|
@ -1542,38 +1542,11 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
|
|||
dam[i] += rnd(1,6);
|
||||
}
|
||||
|
||||
// adjust dam
|
||||
adjustdammaterial(&dam[i], damtype[i], c->type->material->id);
|
||||
|
||||
if (dam[i] > 0) {
|
||||
// wall loses hp
|
||||
c->hp -= dam[i];
|
||||
if (c->hp <= 0) {
|
||||
char cellname[BUFLEN];
|
||||
int shattered = B_FALSE;
|
||||
enum MATERIAL cellmat;
|
||||
// remember cell properties
|
||||
sprintf(cellname, "%s %s", needan(c->type->name) ? "An" : "A", c->type->name);
|
||||
cellmat = c->type->material->id;
|
||||
// cell dies (have to do this before calling fragments())
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
// announce
|
||||
if (haslos(player, c)) {
|
||||
msg("%s %s!", cellname, willshatter(cellmat) ? "shatters" : "is destroyed");
|
||||
}
|
||||
// shatter?
|
||||
if (willshatter(cellmat)) {
|
||||
char what[BUFLEN];
|
||||
shattered = B_TRUE;
|
||||
noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL);
|
||||
if (getshardobname(cellmat, what)) {
|
||||
fragments(c, what, 3, 3);
|
||||
}
|
||||
}
|
||||
damagecell(c, dam[i], damtype[i]);
|
||||
// don't deal any more damage types
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // end foreach damtype
|
||||
|
||||
// no special weapon effects on cells.
|
||||
|
|
20
data.c
20
data.c
|
@ -67,6 +67,7 @@ option_t *addoption(enum OPTION id, char *text, int def) {
|
|||
a->next = NULL;
|
||||
|
||||
// set props
|
||||
a->id = id;
|
||||
a->text = strdup(text);
|
||||
a->def = def;
|
||||
a->enabled = def;
|
||||
|
@ -490,6 +491,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_RANGED, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_THROWING, PR_NOVICE, NA, NULL);
|
||||
// learnable skills
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL);
|
||||
|
@ -1425,8 +1427,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TUNNELUP, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "a strange echoing.");
|
||||
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "an echoing drip.");
|
||||
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "a strange echoing.");
|
||||
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "an echoing drip.");
|
||||
addot(OT_TUNNELUP, "tunnel leading up", "A wide tunnel leading upwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, '<', NA, NULL);
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL);
|
||||
|
@ -3908,6 +3910,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
||||
addot(OT_A_STUDYSCROLL, "study scroll", "Attempt to learn a spell directly from a scroll.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_STRIKETOKO, "merciful fighting", "Try to knock out your opponents rather than killing them.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_SUCKBLOOD, "suck blood", "You can suck the blood from enemies after attaching to them.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
|
@ -4422,8 +4426,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, NA, B_IFACTIVATED, "8d2");
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, B_IFACTIVATED, "5d2");
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, 1, B_IFACTIVATED, "16d2");
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, NA, 1, B_IFACTIVATED, "13d2");
|
||||
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4457,7 +4461,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, B_BIG, B_IFACTIVATED, "90d2"); // 90 - 180 damage
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, 2, B_IFACTIVATED, "90d2"); // 90 - 180 damage
|
||||
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4946,7 +4950,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
||||
|
||||
addot(OT_FIREPLACE, "fireplace", "A roaring fireplace.", MT_STONE, 200, OC_FURNITURE, SZ_LARGE);
|
||||
addot(OT_FIREPLACE, "brazier", "A heavy iron bowl filled with fire.", MT_METAL, 200, OC_FURNITURE, SZ_LARGE);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_RED, '\\', NA, NULL);
|
||||
|
@ -6154,6 +6158,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, 10, NULL);
|
||||
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
|
||||
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_CAVE, 70, NA, NULL);
|
||||
|
@ -7001,6 +7006,7 @@ void initobjects(void) {
|
|||
|
||||
void initoptions(void) {
|
||||
addoption(OPT_ALWAYSSHOWTRAILS, "always show trail objects", B_FALSE);
|
||||
addoption(OPT_AUTORELOAD, "automatically reload empty firearms", B_TRUE);
|
||||
addoption(OPT_STOPRUNONNOISE, "stop running if sound heard", B_TRUE);
|
||||
}
|
||||
|
||||
|
@ -8975,6 +8981,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
|
||||
|
||||
addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC, "A small magical creature made from freezing ice.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
|
@ -11756,6 +11763,7 @@ void initskills(void) {
|
|||
if (isweaponskill(sk->id) || (sk->id == SK_UNARMED)) {
|
||||
addskilldesc(sk->id, PR_INEPT, "This skill increases your accuracy and damage when using matching weapons.", B_FALSE);
|
||||
addskilldesc(sk->id, PR_NOVICE, "^g-2 accuracy penalty.^n", B_FALSE);
|
||||
if (sk->id == SK_CLUBS) addskilldesc(sk->id, PR_NOVICE, "^gYou gain the 'merciful fighting' ability.^n", B_FALSE);
|
||||
addskilldesc(sk->id, PR_BEGINNER, "^g-1 accuracy penalty^n", B_FALSE);
|
||||
addskilldesc(sk->id, PR_BEGINNER, "^gYou gain the 'wild strike' ability.^n", B_FALSE);
|
||||
addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE);
|
||||
|
|
8
defs.h
8
defs.h
|
@ -1503,6 +1503,7 @@ enum OBTYPE {
|
|||
OT_A_SPRINT,
|
||||
OT_A_STUDYSCROLL,
|
||||
OT_A_STINGACID, // need to define dam in f_canwill
|
||||
OT_A_STRIKETOKO,
|
||||
OT_A_SUCKBLOOD,
|
||||
OT_A_SWALLOW,
|
||||
OT_A_SWOOP,
|
||||
|
@ -2125,12 +2126,12 @@ enum FLAG {
|
|||
F_ACTIVATED, // val0 = is this object turned on?
|
||||
F_GRENADE, // this object will drain charge when activated, then die
|
||||
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
|
||||
// val1 = BIG means hit surrounding cells
|
||||
// val1 = explosion radius (dtorth)
|
||||
// val2 = ifactivated, only explodes if activated.
|
||||
F_EXPLODEONDAM, // explodes when it is damaged, deals TEXT damage.
|
||||
// v0 = damage type which makes it explode.
|
||||
// NA means 'any damage type'
|
||||
// val1 = BIG means hit surrounding cells
|
||||
// val1 = explosion radius (dtorth)
|
||||
// val2 = ifactivated, only explodes if activated.
|
||||
F_FLASHONDEATH, // produce a bright flash when it dies,v0=range
|
||||
F_FLASHONDAM, // produces a bright flash when it is damaged,v0=range,v2=ifacctivated
|
||||
|
@ -2638,6 +2639,7 @@ enum FLAG {
|
|||
F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on
|
||||
// sight
|
||||
F_HATESRACEWITHFLAG, // lf will attack lfs with flag v0 on sight
|
||||
F_TERRITORIAL, // lf will attack ALL other visible lfs within range v0
|
||||
F_HARMLESS, // it is safe to rest around this lf
|
||||
F_RNDHOSTILE, // v0% chance of being hostile.
|
||||
F_HOSTILE, // lf will attack the player if in sight
|
||||
|
@ -2772,6 +2774,7 @@ enum FLAG {
|
|||
F_COMBOSTRIKE, // lf is performing a combination strike
|
||||
F_HEAVYBLOW, // next attack is a heavy blow
|
||||
F_QUIVERINGPALM, // your next strike will be a quivpalm attack
|
||||
F_STRIKETOKO, // your attacks will never kill, just KO.
|
||||
F_TKTHROW, // when you throw an object, use your
|
||||
// attrib = v0 and skilltype = v1
|
||||
// rather than AGI and SK_THROWING like normal
|
||||
|
@ -3287,6 +3290,7 @@ typedef struct warning_s {
|
|||
|
||||
enum OPTION {
|
||||
OPT_ALWAYSSHOWTRAILS,
|
||||
OPT_AUTORELOAD,
|
||||
OPT_STOPRUNONNOISE,
|
||||
};
|
||||
|
||||
|
|
74
io.c
74
io.c
|
@ -775,16 +775,6 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
strcat(extrainfo, buf2);
|
||||
}
|
||||
|
||||
|
||||
// need a certain amount of race knowledge to recognise ai traits
|
||||
if (lorelev >= PR_SKILLED) {
|
||||
f = lfhasflag(c->lf, F_BEHAVIOUR);
|
||||
if (f) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, f->text);
|
||||
}
|
||||
}
|
||||
|
||||
if ((getallegiance(c->lf) == AL_HOSTILE) &&
|
||||
(lorelev >= PR_ADEPT)) {
|
||||
char dangerbuf[BUFLEN];
|
||||
|
@ -960,7 +950,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
cell_t *newcell;
|
||||
int bad = B_FALSE;
|
||||
if (srclf) {
|
||||
if (!haslof_real(srclf->cell, c, LOFTYPE, &newcell, srclf)) {
|
||||
if (!haslof_real(srclf->cell, c, LOFTYPE, &newcell, srclf, B_TRUE)) {
|
||||
bad = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
|
@ -1346,8 +1336,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
if (ot) {
|
||||
enum SPELLSCHOOL school;
|
||||
school = getspellschoolknown(lf, ot->id);
|
||||
msg("^gYou have learned the %s '%s'.",
|
||||
(school == SS_MENTAL) ? "psionic power" : "spell", ot->name);
|
||||
msg("^gYou have learned the %s '%s'%s.",
|
||||
(school == SS_MENTAL) ? "psionic power" : "spell", ot->name,
|
||||
getflagsourcetext(f));
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1358,7 +1349,8 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
ot = findot(f->val[0]);
|
||||
if (ot && (!hasflag(ot->flags, F_NOANNOUNCE))) {
|
||||
char buf[BUFLEN];
|
||||
snprintf(buf, BUFLEN, "^gYou have gained the ability '%s'.", ot->name);
|
||||
snprintf(buf, BUFLEN, "^gYou have gained the ability '%s'%s.", ot->name,
|
||||
getflagsourcetext(f));
|
||||
/*
|
||||
if (f->val[2] != NA) {
|
||||
char turnbuf[BUFLEN];
|
||||
|
@ -1758,6 +1750,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s start%s emitting a foul odour!",lfname, isplayer(lf) ? "" : "s" );
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_STRIKETOKO:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("Your attacks will now be non-lethal.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_STUNNED:
|
||||
msg("%s %s stunned!",lfname, is(lf));
|
||||
donesomething = B_TRUE;
|
||||
|
@ -2353,6 +2351,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s no longer smell%s bad.",lfname, isplayer(lf) ? "" : "s" );
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_STRIKETOKO:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("Your attacks will no longer be non-lethal.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_STUNNED:
|
||||
msg("%s %s no longer stunned.",lfname, is(lf));
|
||||
donesomething = B_TRUE;
|
||||
|
@ -6012,14 +6016,19 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
|
||||
if (usable && isweapon(o)) {
|
||||
if (pctmod > 0) {
|
||||
sprintf(buf, "^%dYour high %s will increase your %s with this weapon.^n\n", C_GREEN,
|
||||
sprintf(buf, "^%dYour high %s will increase your %s with this weapon by %d%s.^n\n",
|
||||
C_GREEN,
|
||||
getattrname(f->val[0]),
|
||||
(f->val[0] == A_AGI) ? "accuracy" : "damage");
|
||||
(f->val[0] == A_AGI) ? "accuracy" : "damage",
|
||||
(f->val[0] == A_AGI) ? getaccuracynum(pctmod) : pctmod,
|
||||
(f->val[0] == A_AGI) ? "" : "%");
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
} else if (pctmod < 0) {
|
||||
sprintf(buf, "^%dYour low %s will decrease your %s with this weapon.^n\n", C_BROWN,
|
||||
sprintf(buf, "^%dYour low %s will decrease your %s with this weapon by %d%s.^n\n", C_BROWN,
|
||||
getattrname(f->val[0]),
|
||||
(f->val[0] == A_AGI) ? "accuracy" : "damage");
|
||||
(f->val[0] == A_AGI) ? "accuracy" : "damage",
|
||||
(f->val[0] == A_AGI) ? getaccuracynum(abs(pctmod)) : abs(pctmod),
|
||||
(f->val[0] == A_AGI) ? "" : "%");
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
}
|
||||
|
@ -7513,18 +7522,21 @@ int dotakeoff(obpile_t *op) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
void dothrow(obpile_t *op) {
|
||||
object_t *o;
|
||||
// specify EITHER op or o.
|
||||
// returns B_TRUE on failure.
|
||||
int dothrow(obpile_t *op, object_t *o) {
|
||||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
if (!hasbp(player, BP_HANDS)) {
|
||||
msg("You have no hands to throw with!");
|
||||
return;
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// ask which object to throw
|
||||
if (!o) {
|
||||
o = askobject(op, "Throw what", NULL, 't', AO_NONE);
|
||||
}
|
||||
if (o) {
|
||||
int maxdist;
|
||||
char subprompt[BUFLEN],oidbuf[BUFLENSMALL];
|
||||
|
@ -7534,7 +7546,7 @@ void dothrow(obpile_t *op) {
|
|||
f = hasflag(o->flags, F_EQUIPPED);
|
||||
if (f && (f->val[0] != BP_WEAPON)) {
|
||||
msg("You'll need to take it off first.");
|
||||
return;
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// calculate throw range
|
||||
|
@ -7558,14 +7570,14 @@ void dothrow(obpile_t *op) {
|
|||
if (ch == 'y') {
|
||||
// update destination cell.
|
||||
where = newwhere;
|
||||
} else return;
|
||||
} else return B_TRUE;
|
||||
} else {
|
||||
if (reason == E_NOLOS) {
|
||||
msg("You can't see there!");
|
||||
} else { // ie. E_NOLOF and no new cell
|
||||
msg("You don't have a clear line of fire to there.");
|
||||
}
|
||||
return;
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7577,9 +7589,11 @@ void dothrow(obpile_t *op) {
|
|||
}
|
||||
} else {
|
||||
throwat(player, o, where);
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// returns TRUE if escape pressed
|
||||
|
@ -8683,8 +8697,8 @@ void handleinput(void) {
|
|||
|
||||
// something here?
|
||||
if (stopnow) {
|
||||
} else if (!ihaveturned && moveclear(player, lastdir, NULL)) {
|
||||
// haven't turned yet?
|
||||
} else if (!ihaveturned && moveclear(player, lastdir, NULL) && isroom(player->cell)) {
|
||||
// haven't turned yet and in a room?
|
||||
// if walls to our l+r have changed...
|
||||
if (getleftrightwalls(player) != walls) {
|
||||
stopnow = B_TRUE;
|
||||
|
@ -9040,7 +9054,7 @@ void handleinput(void) {
|
|||
doquaff(player->pack);
|
||||
break;
|
||||
case 't': // throw
|
||||
dothrow(player->pack);
|
||||
dothrow(player->pack, NULL);
|
||||
break;
|
||||
case 'P': // Pour
|
||||
dopour(player->pack);
|
||||
|
@ -11771,6 +11785,12 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_STRIKETOKO);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s attacking in a non-lethal manner.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_STUNNED);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s stunned and cannot attack, cast spells or use abilities.", you(lf), is(lf));
|
||||
|
|
2
io.h
2
io.h
|
@ -72,7 +72,7 @@ void dorest(void);
|
|||
int doselguntarget(void);
|
||||
void dostairs(int dir);
|
||||
int dotakeoff(obpile_t *op);
|
||||
void dothrow(obpile_t *op);
|
||||
int dothrow(obpile_t *op, object_t *o);
|
||||
int dowear(obpile_t *op);
|
||||
int doweild(obpile_t *op);
|
||||
int downline(int *y, int h, char *heading, char *subheading, char *bottomstring, char *cmdchars, char *retchar);
|
||||
|
|
201
lf.c
201
lf.c
|
@ -765,6 +765,17 @@ int caneat(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
int canhaverandombehaviour(lifeform_t *lf) {
|
||||
if (isundead(lf)) return B_FALSE;
|
||||
if (isgod(lf)) return B_FALSE;
|
||||
if (getraceclass(lf) == RC_HUMANOID) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// ie. will sound from 'dest' reach the ears of 'lf'
|
||||
int canhear(lifeform_t *lf, cell_t *dest, int volume) {
|
||||
int numpixels;
|
||||
int i;
|
||||
|
@ -1049,17 +1060,9 @@ int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) {
|
|||
}
|
||||
|
||||
lfsize = getlfsize(lf);
|
||||
switch (isairborne(lf)) {
|
||||
case F_FLYING: lfsize += 2; break;
|
||||
case F_LEVITATING: lfsize++; break;
|
||||
default: break;
|
||||
}
|
||||
lfsize += getflightsizemod(lf);
|
||||
victimsize = getlfsize(victim);
|
||||
switch (isairborne(victim)) {
|
||||
case F_FLYING: victimsize += 2; break;
|
||||
case F_LEVITATING: victimsize++; break;
|
||||
default: break;
|
||||
}
|
||||
victimsize += getflightsizemod(victim);
|
||||
|
||||
howmuchsmaller = victimsize - lfsize;
|
||||
if (howmuchsmaller <= 0) return B_TRUE;
|
||||
|
@ -5421,6 +5424,7 @@ int getavgdam(lifeform_t *lf, int forxp) {
|
|||
|
||||
// modify for accuracy
|
||||
acc = getlfaccuracy(lf, o);
|
||||
limitf(&acc, 0, 100);
|
||||
thisavg = pctof(acc, thisavg);
|
||||
|
||||
avgdam += thisavg;
|
||||
|
@ -5899,8 +5903,13 @@ int getguntargetid(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
int gethearingrange(lifeform_t *lf) {
|
||||
int range = 8; // deafult
|
||||
range = 2 + (getskill(lf, SK_LISTEN)*2);
|
||||
int range = 2; // default
|
||||
|
||||
if (!isasleep(lf)) {
|
||||
// if awake, your listen skills helps
|
||||
range += (getskill(lf, SK_LISTEN)*2);
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
|
@ -6326,6 +6335,17 @@ enum LFCONDITION getlfcondition(lifeform_t *lf) {
|
|||
return C_DEAD;
|
||||
}
|
||||
|
||||
// how much taller are you due to your flight?
|
||||
int getflightsizemod(lifeform_t *lf) {
|
||||
int howmuch = 0;
|
||||
switch (isairborne(lf)) {
|
||||
case F_FLYING: howmuch += 2; break;
|
||||
case F_LEVITATING: howmuch++; break;
|
||||
default: break;
|
||||
}
|
||||
return howmuch;
|
||||
}
|
||||
|
||||
enum SKILLLEVEL getmaxskilllevel(lifeform_t *lf, enum SKILL skid) {
|
||||
flag_t *f;
|
||||
enum SKILLLEVEL maxlev = PR_MASTER;
|
||||
|
@ -7098,6 +7118,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
job_t *j;
|
||||
flag_t *f;
|
||||
enum LFSIZE size,racesize;
|
||||
int dobehaviour = B_TRUE;
|
||||
|
||||
|
||||
// 'the' or 'your' ?
|
||||
|
@ -7133,11 +7154,27 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
strcat(descstring, " ");
|
||||
}
|
||||
|
||||
|
||||
// need a certain amount of race knowledge to recognise ai traits
|
||||
if (getlorelevel(player, lf->race->raceclass->id) < PR_SKILLED) {
|
||||
dobehaviour = B_FALSE;
|
||||
}
|
||||
// frozen/headless trump behavioural descriptions like "insane"
|
||||
if (lfhasflag(lf, F_FROZEN)) {
|
||||
strcat(descstring, "frozen ");
|
||||
dobehaviour = B_FALSE;
|
||||
}
|
||||
if (lfhasflag(lf, F_HEADLESS)) {
|
||||
strcat(descstring, "headless ");
|
||||
dobehaviour = B_FALSE;
|
||||
}
|
||||
|
||||
if (dobehaviour) {
|
||||
f = lfhasflag(lf, F_BEHAVIOUR);
|
||||
if (f) {
|
||||
strcat(descstring, f->text);
|
||||
strcat(descstring, " ");
|
||||
}
|
||||
}
|
||||
|
||||
// construct job string
|
||||
|
@ -8778,14 +8815,17 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
if (id == SK_ATHLETICS) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_CLIMBING) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_CLIMB, NA, NA, NULL);
|
||||
if (!newf || (newf->lifetime > 0)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_CLIMB, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_CLIMB, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_CLUBS) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STRIKETOKO, NA, NA, NULL);
|
||||
if (!newf || (newf->lifetime > 0)) {
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_STRIKETOKO, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_COOKING) {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -8795,42 +8835,35 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
}
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_LORE_ARCANA) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_LOCKPICKING) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_PICKLOCK, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_PICKLOCK, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_PICKLOCK, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_METALWORK) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_SEWING) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_THIEVERY) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_TRAPS) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
|
||||
// learning a new spell school skill will grant you a random first level spell from
|
||||
|
@ -8867,20 +8900,17 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
|
||||
if (id == SK_ATHLETICS) {
|
||||
if (f->val[1] == PR_ADEPT) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_TUMBLE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_TUMBLE, NA, NA, NULL, FROMSKILL);
|
||||
} else if (f->val[1] == PR_EXPERT) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_CARTOGRAPHY) {
|
||||
if (f->val[1] == PR_SKILLED) {
|
||||
addflag(lf->flags, F_PHOTOMEM, B_TRUE, NA, NA, NULL);
|
||||
addtempflag(lf->flags, F_PHOTOMEM, B_TRUE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
if (f->val[1] == PR_MASTER) {
|
||||
if (!hasflagval(lf->flags, F_CANWILL, OT_S_MAPPING, NA, NA, NULL)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_S_MAPPING, 50, 50, "pw:1;");
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_S_MAPPING, 50, 50, "pw:1;", FROMSKILL);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_COOKING) {
|
||||
|
@ -8893,16 +8923,14 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
} else if (id == SK_EVASION) {
|
||||
if (f->val[1] == PR_ADEPT) {
|
||||
if (isplayer(lf)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_SNATCH, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_SNATCH, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_LORE_ARCANA) {
|
||||
if (f->val[1] == PR_ADEPT) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_LORE_NATURE) {
|
||||
|
@ -8916,14 +8944,12 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
if (f->val[1] == PR_SKILLED) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (f->val[1] == PR_MASTER) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_PERCEPTION) {
|
||||
|
@ -8936,25 +8962,21 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
if (f->val[1] == PR_SKILLED) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_RESIZE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (f->val[1] == PR_MASTER) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL);
|
||||
if (!newf) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_ENHANCEOB, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_SHIELDS) {
|
||||
if (f->val[1] == PR_BEGINNER) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_SHIELDBASH, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_SHIELDBASH, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_STEALTH) {
|
||||
if (f->val[1] == PR_BEGINNER) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (id == SK_TECHUSAGE) {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -9008,21 +9030,19 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
*/
|
||||
}
|
||||
|
||||
|
||||
if (isweaponskill(id)) {
|
||||
if (f->val[1] == PR_BEGINNER) {
|
||||
if (!hasflagval(lf->flags, F_CANWILL, OT_A_EXPOSEDSTRIKE, NA, NA, NULL)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_EXPOSEDSTRIKE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_EXPOSEDSTRIKE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (f->val[1] == PR_ADEPT) {
|
||||
if (!hasflagval(lf->flags, F_CANWILL, OT_A_ALTERATTACK, NA, NA, NULL)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_ALTERATTACK, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_ALTERATTACK, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
} else if (f->val[1] == PR_MASTER) {
|
||||
if (!hasflagval(lf->flags, F_CANWILL, OT_A_COMBOSTRIKE, NA, NA, NULL)) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_COMBOSTRIKE, NA, NA, NULL);
|
||||
newf->lifetime = FROMSKILL;
|
||||
newf = addtempflag(lf->flags, F_CANWILL, OT_A_COMBOSTRIKE, NA, NA, NULL, FROMSKILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9412,11 +9432,14 @@ int gotosleep(lifeform_t *lf, int onpurpose) {
|
|||
flag_t *hasbleedinginjury(lifeform_t *lf, enum BODYPART bp) {
|
||||
flag_t *f, *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
getflags(player->flags, retflag, &nretflags, F_INJURY, F_NONE);
|
||||
getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE);
|
||||
for (i = 0;i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
// only temporary flags count - not permenant ones
|
||||
if ((f->lifetime > 0) && (f->val[1] == bp) && (f->val[2] == DT_SLASH)) {
|
||||
if (isplayer(lf) && (f->lifetime < 0)) {
|
||||
// for the player, only temporary flags count - not permenant ones
|
||||
// this is so that losing a whole finger etc doesn't completely
|
||||
// cripple you by making you always bleed.
|
||||
} else if ((f->val[1] == bp) && (f->val[2] == DT_SLASH)) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
@ -10127,13 +10150,16 @@ flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid) {
|
|||
}
|
||||
|
||||
int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest) {
|
||||
return haslof_real(src, dest, loftype, newdest, NULL);
|
||||
return haslof_real(src, dest, loftype, newdest, NULL, B_TRUE);
|
||||
}
|
||||
|
||||
// got line of fire to dest? if lof is blocked, return last cell in 'newdest'
|
||||
// if 'srclf' is set, we are checking whether 'srclf' THINKS they have line of fire. ie invisible/unseed
|
||||
// lifeforms don't block lof.
|
||||
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf) {
|
||||
//
|
||||
// if 'walllfsok' is set, then we ARE allowed to have lineoffire to walls (ie. solid cells) if there is a lifeform
|
||||
// there.
|
||||
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf, int walllfsok) {
|
||||
int numpixels;
|
||||
int i;
|
||||
int x1,y1,x2,y2;
|
||||
|
@ -10192,7 +10218,7 @@ int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdes
|
|||
if (cell->type->solid) {
|
||||
if (i == 0) {
|
||||
// ok
|
||||
} else if (cell->lf && (i == (numpixels-1)) ) {
|
||||
} else if (walllfsok && cell->lf && (i == (numpixels-1)) ) {
|
||||
// ok
|
||||
} else {
|
||||
reason = E_NOLOF;
|
||||
|
@ -11497,6 +11523,7 @@ void makepeaceful(lifeform_t *who) {
|
|||
killflagsofid(who->flags, F_HOSTILE);
|
||||
killflagsofid(who->flags, F_HATESALL);
|
||||
killflagsofid(who->flags, F_HATESRACE);
|
||||
killflagsofid(who->flags, F_TERRITORIAL);
|
||||
killflagsofid(who->flags, F_HATESRACEWITHFLAG);
|
||||
loseaitargets(who);
|
||||
}
|
||||
|
@ -12446,7 +12473,6 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
if (fromob) {
|
||||
f = hasflag(fromob->flags, F_MERCIFUL);
|
||||
if (f && (amt >= lf->hp)) {
|
||||
amt = lf->hp - 1; // ie end up at 1hp
|
||||
ko = B_TRUE;
|
||||
if (fromob->pile->owner && cansee(player, fromob->pile->owner)) {
|
||||
f->known = B_TRUE;
|
||||
|
@ -12463,12 +12489,24 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
if ((lf->hp > 1) && (hpleftafterdam >= -5) && (hpleftafterdam <= 0)) {
|
||||
if (onein(2)) {
|
||||
ko = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ko) {
|
||||
if (fromlf && lfhasflag(fromlf, F_STRIKETOKO)) {
|
||||
if (cansee(fromlf, lf)) {
|
||||
ko = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just knock them out.
|
||||
if (ko) {
|
||||
amt = lf->hp - 1; // ie end up at 1hp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// large damage will be stopped by a ring of miracles
|
||||
if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) {
|
||||
|
@ -12648,8 +12686,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
}
|
||||
|
||||
// low hitpoint warning
|
||||
if (amt > 0) {
|
||||
if (isplayer(lf)) {
|
||||
if (isplayer(lf) && (amt > 0)) {
|
||||
int warnthresh;
|
||||
warnthresh = (int)((float)0.25 * (float)lf->maxhp);
|
||||
if ((lf->hp <= warnthresh) && (lf->hp > 0)) {
|
||||
|
@ -12657,15 +12694,16 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
more();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ko) {
|
||||
if (!isunconscious(lf)) {
|
||||
// you are knocked unconscious for a _long_ time
|
||||
fallasleep(lf, ST_KO, rnd(50,100));
|
||||
if (fromlf && isplayer(fromlf)) {
|
||||
pleasegodmaybe(R_GODMERCY, 5);
|
||||
}
|
||||
breakgrabs(lf, B_TRUE, B_FALSE);
|
||||
}
|
||||
} else {
|
||||
// you wake up if you were hit, unless you were unconscious!
|
||||
f = lfhasflag(lf, F_ASLEEP);
|
||||
|
@ -13284,8 +13322,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
|
||||
dist = getcelldist(l->cell, c);
|
||||
|
||||
|
||||
|
||||
// listen check difficulty is based on sound distance vs max hearing distance
|
||||
if ((nclass == NC_SPEECH) && isplayer(l)) {
|
||||
// you always hear it, as long as you're in range
|
||||
|
@ -13296,7 +13332,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
difficulty = 9999;
|
||||
} else {
|
||||
//difficulty = (int) ( ((float)getcelldist(l->cell, c) / (float)gethearingrange(l)) * 20);
|
||||
difficulty = (int) ( ((float)getcelldist(l->cell, c) / ((float)gethearingrange(l) + volume)) * 14);
|
||||
difficulty = (int) ( ((float) dist / ((float)gethearingrange(l) + volume)) * 14);
|
||||
}
|
||||
|
||||
// listen bonus is based on sound volume
|
||||
|
@ -15400,6 +15436,8 @@ int shoot(lifeform_t *lf) {
|
|||
|
||||
fireat(lf, ammo, 1, targ->cell, firespeed, gun);
|
||||
if (!getammo(gun)) {
|
||||
if (!isplayer(lf) || getoption(OPT_AUTORELOAD)) {
|
||||
// automatically try to reload our empty firearm/ranged weapon.
|
||||
if (loadfirearmfast(lf, B_FALSE)) {
|
||||
if (isplayer(lf)) {
|
||||
char obname[BUFLEN];
|
||||
|
@ -15408,6 +15446,7 @@ int shoot(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -16650,7 +16689,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
// effects for/on your own flags
|
||||
getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
|
||||
F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY,
|
||||
F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||
F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
// remove impossible flags
|
||||
|
@ -16752,6 +16791,15 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
if (f->id == F_STRIKETOKO) {
|
||||
skill_t *sk;
|
||||
sk = getobskill(getweapon(lf));
|
||||
if (!sk || (sk->id != SK_CLUBS)) {
|
||||
killflag(f);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// recharge abilities
|
||||
if (f->id == F_CANWILL) {
|
||||
if (f->val[2] != NA) {
|
||||
|
@ -16760,6 +16808,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove invalid targets
|
||||
if ((f->id == F_TARGETLF) || (f->id == F_TARGETCELL)) {
|
||||
lifeform_t *targ = NULL;
|
||||
|
|
4
lf.h
4
lf.h
|
@ -40,6 +40,7 @@ int cancook(lifeform_t *lf, recipe_t *rec, enum ERROR *reason);
|
|||
int canclimb(lifeform_t *lf, enum ERROR *reason);
|
||||
int candrink(lifeform_t *lf, object_t *o);
|
||||
int caneat(lifeform_t *lf, object_t *o);
|
||||
int canhaverandombehaviour(lifeform_t *lf);
|
||||
int canhear(lifeform_t *lf, cell_t *c, int volume);
|
||||
int canlearn(lifeform_t *lf, enum SKILL skid);
|
||||
int canmakerecipe(lifeform_t *lf, recipe_t *rec);
|
||||
|
@ -165,6 +166,7 @@ int getleftrightwalls(lifeform_t *lf);
|
|||
int getlfaccuracy(lifeform_t *lf, object_t *wep);
|
||||
char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc);
|
||||
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||
int getflightsizemod(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);
|
||||
|
@ -273,7 +275,7 @@ void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
|||
int hasbp(lifeform_t *lf, enum BODYPART bp);
|
||||
flag_t *hasactivespell(lifeform_t *lf, enum OBTYPE sid);
|
||||
int haslof(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest);
|
||||
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf);
|
||||
int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdest, lifeform_t *srclf, int walllfsok);
|
||||
int haslos(lifeform_t *viewer, cell_t *dest);
|
||||
int haslosdark(lifeform_t *viewer, cell_t *dest);
|
||||
int haslos_fast(lifeform_t *viewer, cell_t *dest);
|
||||
|
|
53
map.c
53
map.c
|
@ -1154,6 +1154,41 @@ void clearcell_exceptflags(cell_t *c, ... ) {
|
|||
}
|
||||
}
|
||||
|
||||
int damagecell(cell_t *c, int amt, enum DAMTYPE damtype) {
|
||||
if (!c->type->solid) return B_TRUE;
|
||||
// adjust dam
|
||||
adjustdammaterial(&amt, damtype, c->type->material->id);
|
||||
if (amt <= 0) return B_TRUE;
|
||||
|
||||
// wall loses hp
|
||||
c->hp -= amt;
|
||||
if (c->hp <= 0) {
|
||||
char cellname[BUFLEN];
|
||||
int shattered = B_FALSE;
|
||||
enum MATERIAL cellmat;
|
||||
c->hp = 0;
|
||||
// remember cell properties
|
||||
sprintf(cellname, "%s %s", needan(c->type->name) ? "An" : "A", c->type->name);
|
||||
cellmat = c->type->material->id;
|
||||
// cell dies (have to do this before calling fragments())
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
// announce
|
||||
if (haslos(player, c)) {
|
||||
msg("%s %s!", cellname, willshatter(cellmat) ? "shatters" : "is destroyed");
|
||||
}
|
||||
// shatter?
|
||||
if (willshatter(cellmat)) {
|
||||
char what[BUFLEN];
|
||||
shattered = B_TRUE;
|
||||
noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL);
|
||||
if (getshardobname(cellmat, what)) {
|
||||
fragments(c, what, 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns true if something happened
|
||||
int doelementspread(cell_t *c) {
|
||||
float thisdepth;
|
||||
|
@ -4707,11 +4742,12 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
inrange = B_TRUE;
|
||||
}
|
||||
if (inrange) {
|
||||
cell_t *stopcell = NULL;
|
||||
//cell_t *stopcell = NULL;
|
||||
// if a door stops the explosion, the door will
|
||||
// take the damage.
|
||||
haslof(c, cc, LOF_WALLSTOP, &stopcell);
|
||||
explodesinglecell(stopcell, dam, killwalls, o, c);
|
||||
//haslof(c, cc, LOF_WALLSTOP, &stopcell);
|
||||
// don't check LOF for explosions.
|
||||
explodesinglecell(cc, dam, killwalls, o, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4789,10 +4825,7 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
|
|||
|
||||
if (killwalls) {
|
||||
if (c->type->solid) {
|
||||
// make it empty!
|
||||
setcelltype(c, c->habitat->emptycelltype);
|
||||
// add some rubble
|
||||
addob(c->obpile, "10-50 stones");
|
||||
damagecell(c, dam, DT_EXPLOSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5010,11 +5043,11 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags)
|
|||
}
|
||||
|
||||
// random monster behaviours
|
||||
if (!isundead(lf) && !isgod(lf) && onein(4)) {
|
||||
if (canhaverandombehaviour(lf) && onein(6)) {
|
||||
switch (rnd(0,6)) {
|
||||
case 0: // insane
|
||||
addflag(lf->flags, F_BEHAVIOUR, NA, NA, NA, "insane");
|
||||
addflag(lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_TERRITORIAL, 2, NA, NA, NULL); // attack anything within 1 cells
|
||||
break;
|
||||
case 1: // hungry
|
||||
addflag(lf->flags, F_BEHAVIOUR, NA, NA, NA, "hungry");
|
||||
|
@ -5974,7 +6007,7 @@ void initmap(void) {
|
|||
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 50);
|
||||
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 50);
|
||||
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 50);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 150);
|
||||
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 25);
|
||||
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 200);
|
||||
// cell types - non-solid
|
||||
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
|
||||
|
|
1
map.h
1
map.h
|
@ -18,6 +18,7 @@ int cellisfixedvaultwall(cell_t *c);
|
|||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom);
|
||||
void clearcell(cell_t *c);
|
||||
void clearcell_exceptflags(cell_t *c, ...);
|
||||
int damagecell(cell_t *c, int amt, enum DAMTYPE damtype);
|
||||
int doelementspread(cell_t *c);
|
||||
int fix_reachability(map_t *m);
|
||||
int fix_unreachable_cell(cell_t *badcell);
|
||||
|
|
49
objects.c
49
objects.c
|
@ -3062,7 +3062,7 @@ void explodeob(object_t *o, flag_t *f, int bigness) {
|
|||
} else if (haslos(player, c)) {
|
||||
msg("%s explode%s!", obname,OBS1(o));
|
||||
}
|
||||
explodecells(c, dam * o->amt, bigness ? B_TRUE : B_FALSE, o, bigness ? 1 : 0, DT_COMPASS, B_FALSE);
|
||||
explodecells(c, dam * o->amt, bigness ? B_TRUE : B_FALSE, o, bigness , DT_ORTH, B_FALSE);
|
||||
|
||||
// object dies.
|
||||
removeob(o, o->amt);
|
||||
|
@ -7901,10 +7901,10 @@ void obdie(object_t *o) {
|
|||
if (f) {
|
||||
if (f->val[2] == B_IFACTIVATED) {
|
||||
if (isactivated(o)) {
|
||||
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
||||
explodeob(o, f, f->val[1]);
|
||||
}
|
||||
} else {
|
||||
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
||||
explodeob(o, f, f->val[1]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -10828,6 +10828,8 @@ int sethiddenname(objecttype_t *ot, char *text) {
|
|||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
} else if (strstr(text, "luminous")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
} else if (strstr(text, "sparkling")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// set colour based on hiddenname
|
||||
|
@ -11360,7 +11362,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
|
|||
} else {
|
||||
// explode
|
||||
if ((f->val[0] == NA) || (f->val[0] == damtype)) {
|
||||
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
||||
explodeob(o, f, f->val[1]);
|
||||
return howmuch;
|
||||
}
|
||||
}
|
||||
|
@ -11372,7 +11374,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
|
|||
} else {
|
||||
if ((f->val[0] == NA) || (f->val[0] == damtype)) {
|
||||
// explode
|
||||
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
||||
explodeob(o, f, f->val[1]);
|
||||
return howmuch;
|
||||
}
|
||||
}
|
||||
|
@ -11888,7 +11890,17 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
}
|
||||
}
|
||||
if (db && thrower) {
|
||||
dblog("%s is throwing %s - acc = %d, speed = %d\n", realthrowername, obname, acc, speed);
|
||||
char fatext[BUFLEN];
|
||||
|
||||
if (firearm) {
|
||||
char faname[BUFLEN];
|
||||
getobname(firearm, faname, 1);
|
||||
sprintf(fatext," (from %s)",faname);
|
||||
} else {
|
||||
strcpy(fatext,"");
|
||||
}
|
||||
dblog("%s is %s %s%s - acc = %d, speed = %d\n", realthrowername,
|
||||
firearm ? "firing" : "throwing", obname, fatext, acc, speed);
|
||||
}
|
||||
|
||||
// roll for hit
|
||||
|
@ -12178,6 +12190,16 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
}
|
||||
}
|
||||
|
||||
// if we were throwing at a lifeform inside a wall, we need to make sure we don't
|
||||
// now place the object inside the wall.
|
||||
if (where->type->solid) {
|
||||
newloc = NULL;
|
||||
haslof_real(srcloc, where, LOF_NEED, &newloc, NULL, B_FALSE);
|
||||
if (newloc) {
|
||||
where = newloc;
|
||||
}
|
||||
}
|
||||
|
||||
// move the object to the cell then take dam or kill it. don't stack.
|
||||
newob = real_moveob(o, where->obpile, amt, B_FALSE);
|
||||
// fake its birth time so that it can be damaged
|
||||
|
@ -13062,12 +13084,18 @@ void turnon(lifeform_t *lf, object_t *o) {
|
|||
addflag(newob->flags, F_ACTIVATED, B_TRUE, NA, NA, NULL);
|
||||
getobname(newob, newobname, 1);
|
||||
if (lf && isplayer(lf)) {
|
||||
// announce.
|
||||
if (held) {
|
||||
msgnocap("%c - %s [activated].",newob->letter, newobname);
|
||||
more();
|
||||
// ask where to throw it
|
||||
dothrow(NULL, newob);
|
||||
} else {
|
||||
msgnocap("You activate %s.",newob->letter, newobname);
|
||||
}
|
||||
}
|
||||
|
||||
o = newob;
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You don't have room for an activated %s!",noprefix(obname));
|
||||
|
@ -13671,6 +13699,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
|
||||
acc -= (cellpenalty*howfar);
|
||||
|
||||
// modify based on attributes
|
||||
if (whichatt != A_NONE) {
|
||||
int mod;
|
||||
mod = getstatmod(thrower, whichatt); // -50 to 50
|
||||
|
@ -13693,6 +13722,14 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
if (where->lf && isprone(where->lf)) {
|
||||
acc -= 30;
|
||||
}
|
||||
|
||||
// 10% bonus for being higher than your target
|
||||
if (where->lf) {
|
||||
if (getflightsizemod(thrower) > getflightsizemod(where->lf)) {
|
||||
acc += 15;
|
||||
}
|
||||
}
|
||||
|
||||
limit(&acc, 0, NA);
|
||||
return acc;
|
||||
}
|
||||
|
|
14
spell.c
14
spell.c
|
@ -1893,6 +1893,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// now kill the scroll
|
||||
msg("The scroll crumbles to dust.");
|
||||
removeob(o, 1);
|
||||
} else if (abilid == OT_A_STRIKETOKO) {
|
||||
skill_t *sk;
|
||||
sk = getobskill(getweapon(user));
|
||||
if (!sk || (sk->id != SK_CLUBS)) {
|
||||
if (isplayer(user)) msg("You can only use bashing weapons to fight mercifully.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (lfhasflag(user, F_STRIKETOKO)) {
|
||||
killflagsofid(user->flags, F_STRIKETOKO);
|
||||
} else {
|
||||
addflag(user->flags, F_STRIKETOKO, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
// note: takes no time.
|
||||
} else if (abilid == OT_A_SUCKBLOOD) {
|
||||
int dam = 0;
|
||||
|
||||
|
|
112
text.c
112
text.c
|
@ -131,6 +131,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
|
|||
needfree = B_TRUE;
|
||||
} else if (fatal) {
|
||||
verb = getkillverb(victim, wep, damtype, dam, maxhp);
|
||||
if (strstr(verb, "knock out") && !isplayer(victim)) knownnodam = B_TRUE;
|
||||
} else {
|
||||
if (!victim || // atacking an object
|
||||
(getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) || // know about the race
|
||||
|
@ -682,6 +683,21 @@ void getdisttext(cell_t *src, cell_t *dst,char *distbuf, char *distbufapprox, ch
|
|||
|
||||
}
|
||||
|
||||
char *getflagsourcetext(flag_t *f) {
|
||||
switch (f->lifetime) {
|
||||
case FROMSKILL: return " (skill perk)";
|
||||
case FROMJOB: return " (job perk)";
|
||||
case FROMOBEQUIP:
|
||||
case FROMOBHOLD:
|
||||
case FROMOBACTIVATE:
|
||||
return " (conferred perk)";
|
||||
case FROMGODGIFT:
|
||||
return " (god gift)";
|
||||
default: break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int gethitconferlifetime(char *text, int *min, int *max) {
|
||||
int howlong;
|
||||
int localmin = -1,localmax = -1;
|
||||
|
@ -721,7 +737,9 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
|
|||
if (wep && hasflag(wep->flags, F_MERCIFUL)) {
|
||||
return "knock out";
|
||||
}
|
||||
|
||||
if (wep && wep->pile->owner && lfhasflag(wep->pile->owner, F_STRIKETOKO)) {
|
||||
return "knock out";
|
||||
}
|
||||
if (victim->race->id == R_DANCINGWEAPON) {
|
||||
return "defeat";
|
||||
}
|
||||
|
@ -942,6 +960,98 @@ char *getobmodprefix(object_t *o, obmod_t *om) {
|
|||
default: return "rotted ";
|
||||
}
|
||||
}
|
||||
} else if (isweapon(o)) {
|
||||
flag_t *f = NULL;
|
||||
skill_t *sk;
|
||||
sk = getobskill(o);
|
||||
if (sk) {
|
||||
if (om->id == OM_MASTERWORK) {
|
||||
switch (sk->id) {
|
||||
case SK_CLUBS:
|
||||
case SK_STAVES:
|
||||
return "reinforced ";
|
||||
default: break;
|
||||
}
|
||||
} else if (om->id == OM_SHODDY) {
|
||||
switch (sk->id) {
|
||||
case SK_LONGBLADES:
|
||||
case SK_SHORTBLADES:
|
||||
case SK_AXES:
|
||||
return "blunted ";
|
||||
case SK_CLUBS:
|
||||
return "cracked ";
|
||||
case SK_POLEARMS:
|
||||
return "notched ";
|
||||
case SK_STAVES:
|
||||
return "blunted ";
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f) return f->text;
|
||||
} else if (isshield(o)) {
|
||||
if (om->id == OM_MASTERWORK) {
|
||||
switch (o->material->id) {
|
||||
case MT_LEATHER:
|
||||
return "studded ";
|
||||
case MT_METAL:
|
||||
case MT_WOOD:
|
||||
case MT_DRAGONWOOD:
|
||||
return "reinforced ";
|
||||
default: break;
|
||||
}
|
||||
} else if (om->id == OM_SHODDY) {
|
||||
switch (o->material->id) {
|
||||
case MT_LEATHER:
|
||||
case MT_RUBBER:
|
||||
case MT_PAPER:
|
||||
return "torn ";
|
||||
case MT_CLOTH:
|
||||
case MT_SILK:
|
||||
return "frayed ";
|
||||
case MT_GLASS:
|
||||
case MT_STONE:
|
||||
case MT_BONE:
|
||||
return "chipped ";
|
||||
case MT_METAL:
|
||||
return "dented ";
|
||||
case MT_WOOD:
|
||||
case MT_DRAGONWOOD:
|
||||
return "splintered ";
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
} else if (isarmour(o)) {
|
||||
if (om->id == OM_MASTERWORK) {
|
||||
switch (o->material->id) {
|
||||
case MT_LEATHER:
|
||||
return "studded ";
|
||||
case MT_CLOTH:
|
||||
case MT_SILK:
|
||||
return "tailored ";
|
||||
default: break;
|
||||
}
|
||||
} else if (om->id == OM_SHODDY) {
|
||||
switch (o->material->id) {
|
||||
case MT_LEATHER:
|
||||
case MT_RUBBER:
|
||||
case MT_PAPER:
|
||||
return "torn ";
|
||||
case MT_CLOTH:
|
||||
case MT_SILK:
|
||||
return "frayed ";
|
||||
case MT_GLASS:
|
||||
case MT_STONE:
|
||||
case MT_BONE:
|
||||
return "chipped ";
|
||||
case MT_METAL:
|
||||
return "dented ";
|
||||
case MT_WOOD:
|
||||
case MT_DRAGONWOOD:
|
||||
return "splintered ";
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return om->prefix;
|
||||
}
|
||||
|
|
1
text.h
1
text.h
|
@ -16,6 +16,7 @@ char *getattrname(enum ATTRIB att);
|
|||
char *getdirname(int dir);
|
||||
char *getdirnameshort(int dir);
|
||||
void getdisttext(cell_t *src, cell_t *dst,char *distbuf, char *distbufapprox, char *dirbuf);
|
||||
char *getflagsourcetext(flag_t *f);
|
||||
int gethitconferlifetime(char *text, int *min, int *max);
|
||||
char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
|
||||
char *getpoisondamverb(enum POISONTYPE ptype);
|
||||
|
|
|
@ -14,7 +14,7 @@ p:cell:shop floor
|
|||
+:cell:dirt
|
||||
+:ob:wooden door
|
||||
s:ob:sign "Village Pub"
|
||||
f:ob:fireplace
|
||||
f:ob:brazier
|
||||
@end
|
||||
|
||||
@flags
|
||||
|
|
Loading…
Reference in New Issue