- [+] fullshield block: ("raise shield") ?
- [+] gain it at beginner level shields - [+] make ai use it - [+] if i've been hit by a ranged attack. - [+] if intelligent: if my target has a ranged weapon AND i'm not adjacent AND i'm in range. - [+] make ai stop using it - [+] if i'm adjacent to my target - [+] OR - [+] if i have no target - [+] OR - [+] if i'm not in battle - [+] don't show 'bloodstained' if blind - [+] dusur digs hole in floor - [+] CRASH. who->timespent == 0 - [+] when portalling to same levle, don't say 'you arrive back at levl xx' - [+] instead: 'you arrive elsewhere in level xx' - [+] maybe: when exhausted: - [+] you can still attack, but... - [+] attacks deal 0.75% damage - [+] attack speed lowered. - [+] change of fumbling your attack if you miss. - [+] ...then monsters can have stamina again. - [+] the %s looks exhausted. - [+] if ai is exhausted, wait.
This commit is contained in:
parent
db635b50db
commit
64412035bb
80
ai.c
80
ai.c
|
@ -1157,12 +1157,15 @@ flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int t
|
||||||
int ai_attack_existing_target(lifeform_t *lf) {
|
int ai_attack_existing_target(lifeform_t *lf) {
|
||||||
lifeform_t *target;
|
lifeform_t *target;
|
||||||
int db = B_FALSE;
|
int db = B_FALSE;
|
||||||
|
enum ATTRBRACKET iqb;
|
||||||
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
||||||
|
|
||||||
// do we already have a target we are attacking?
|
// do we already have a target we are attacking?
|
||||||
target = gettargetlf(lf);
|
target = gettargetlf(lf);
|
||||||
if (!target) return B_FALSE;
|
if (!target) return B_FALSE;
|
||||||
|
|
||||||
|
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||||
|
|
||||||
if (db) dblog(".oO { i have a target: lfid %d (%s). }", target->id, target->race->name);
|
if (db) dblog(".oO { i have a target: lfid %d (%s). }", target->id, target->race->name);
|
||||||
|
|
||||||
// target dead or unconscious?
|
// target dead or unconscious?
|
||||||
|
@ -1174,22 +1177,26 @@ int ai_attack_existing_target(lifeform_t *lf) {
|
||||||
real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE);
|
real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE);
|
||||||
sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text, target);
|
sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text, target);
|
||||||
}
|
}
|
||||||
} else {
|
return B_FALSE;
|
||||||
// aquatic grabbers will try to drag their prey into the water
|
}
|
||||||
if (lfhasflagval(lf, F_GRABBING, target->id, NA, NA, NULL) && isaquatic(lf) ) {
|
|
||||||
if ( hasobwithflag(lf->cell->obpile, F_DEEPWATER) &&
|
|
||||||
!hasobwithflag(target->cell->obpile, F_DEEPWATER)) {
|
// aquatic grabbers will try to drag their prey into the water
|
||||||
// move away!
|
if (lfhasflagval(lf, F_GRABBING, target->id, NA, NA, NULL) && isaquatic(lf) ) {
|
||||||
if (!moveawayfrom(lf, target->cell, DT_ORTH, B_FALSE, B_TRUE, B_ONPURPOSE)) {
|
if ( hasobwithflag(lf->cell->obpile, F_DEEPWATER) &&
|
||||||
return B_TRUE;
|
!hasobwithflag(target->cell->obpile, F_DEEPWATER)) {
|
||||||
}
|
// move away!
|
||||||
|
if (!moveawayfrom(lf, target->cell, DT_ORTH, B_FALSE, B_TRUE, B_ONPURPOSE)) {
|
||||||
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try to move towards them.
|
}
|
||||||
if (!aimovetolf(lf, target, B_TRUE)) {
|
|
||||||
// success
|
|
||||||
return B_TRUE;
|
// try to move towards them.
|
||||||
}
|
if (!aimovetolf(lf, target, B_TRUE)) {
|
||||||
|
// success
|
||||||
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1582,6 +1589,12 @@ int ai_healing(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no stamina left?
|
||||||
|
if (isexhausted(lf) && !isinbattle(lf, B_FALSE, B_FALSE)) {
|
||||||
|
rest(lf, B_TRUE);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2829,6 +2842,45 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ot->id == OT_A_FULLSHIELD) {
|
||||||
|
object_t *targun,*sh;
|
||||||
|
int dist;
|
||||||
|
if (lfhasflag(lf, F_FULLSHIELD)) {
|
||||||
|
// turn off fullshield if:
|
||||||
|
// - i have no target
|
||||||
|
// - i have an adjacent target
|
||||||
|
if (!lfhasflag(lf, F_AIHITBYRANGED)) {
|
||||||
|
if (!victim || isinbattle(lf, B_FALSE, B_FALSE) ||
|
||||||
|
!isinbattle(lf, B_TRUE, B_FALSE)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// turn on fullshield if:
|
||||||
|
//
|
||||||
|
// - I've recently been hit by a ranged attack.
|
||||||
|
// - I'm quite intelligent
|
||||||
|
// AND
|
||||||
|
// My target has a ranged weapon AND i'm not adjacent AND i'm in range.
|
||||||
|
sh = getshield(lf, DT_ALL);
|
||||||
|
if (sh) {
|
||||||
|
if (lfhasflag(lf, F_AIHITBYRANGED)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else {
|
||||||
|
enum ATTRBRACKET iqb;
|
||||||
|
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||||
|
if (iqb >= AT_GTAVERAGE) {
|
||||||
|
targun = getfirearm(victim);
|
||||||
|
dist = getcelldist(lf->cell, victim->cell);
|
||||||
|
if (targun && getammo(targun) &&
|
||||||
|
haslof(victim->cell, lf->cell, LOF_NEED, NULL) &&
|
||||||
|
(dist > 1) && (dist <= getfirearmrange(targun)) ) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (ot->id == OT_A_JUMP) {
|
} else if (ot->id == OT_A_JUMP) {
|
||||||
cell_t *cell[MAXCANDIDATES],*c;
|
cell_t *cell[MAXCANDIDATES],*c;
|
||||||
int ncells,i;
|
int ncells,i;
|
||||||
|
|
35
attack.c
35
attack.c
|
@ -192,6 +192,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
int attackedhelpless = B_FALSE;
|
int attackedhelpless = B_FALSE;
|
||||||
int attackedfriend = B_FALSE;
|
int attackedfriend = B_FALSE;
|
||||||
int attackedpeaceful = B_FALSE;
|
int attackedpeaceful = B_FALSE;
|
||||||
|
enum SKILLLEVEL slev;
|
||||||
|
|
||||||
// warn if attacking will cause injury
|
// warn if attacking will cause injury
|
||||||
if (!force && isplayer(lf) && haslos(lf, c)) {
|
if (!force && isplayer(lf) && haslos(lf, c)) {
|
||||||
|
@ -505,7 +506,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
if (!canattack(lf)) {
|
if (!canattack(lf)) {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case E_NOSTAM: msg("You are too tired to fight at the moment."); break;
|
//case E_NOSTAM: msg("You are too tired to fight at the moment."); break;
|
||||||
case E_STUNNED: msg("You are too stunned to fight at the moment."); break;
|
case E_STUNNED: msg("You are too stunned to fight at the moment."); break;
|
||||||
case E_IMPOSSIBLE: msg("You have no way of attacking!"); break;
|
case E_IMPOSSIBLE: msg("You have no way of attacking!"); break;
|
||||||
default: msg("For some reason, you cannot attack."); break;
|
default: msg("For some reason, you cannot attack."); break;
|
||||||
|
@ -811,16 +812,15 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isplayer(lf)) {
|
//if (isplayer(lf)) {
|
||||||
enum SKILLLEVEL slev;
|
slev = getskill(lf, SK_COMBAT);
|
||||||
slev = getskill(lf, SK_COMBAT);
|
if (slev != PR_MASTER) {
|
||||||
if (slev != PR_MASTER) {
|
if (!pctchance(slev * 10)) {
|
||||||
if (!pctchance(slev * 10)) {
|
// lose a bit of stamina
|
||||||
// lose a bit of stamina
|
modstamina(lf, -getattackstamloss(lf));
|
||||||
modstamina(lf, -getattackstamloss(lf));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
// stop sprinting
|
// stop sprinting
|
||||||
stopsprinting(lf);
|
stopsprinting(lf);
|
||||||
|
@ -1140,6 +1140,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
||||||
}
|
}
|
||||||
if (aidb) dblog("rolled dam[%d] = %d",0,dam[0]);
|
if (aidb) dblog("rolled dam[%d] = %d",0,dam[0]);
|
||||||
|
|
||||||
|
// half damage if exhausted
|
||||||
|
if (isexhausted(lf)) {
|
||||||
|
dam[0] = pctof(75, dam[0]);
|
||||||
|
}
|
||||||
|
|
||||||
if (dam[0] < 0) {
|
if (dam[0] < 0) {
|
||||||
willheal = B_TRUE;
|
willheal = B_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2201,12 +2206,16 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
|
||||||
getallshields(victim, damtype, shield, checkmod, &nshields);
|
getallshields(victim, damtype, shield, checkmod, &nshields);
|
||||||
for (i = 0; i < nshields; i++) {
|
for (i = 0; i < nshields; i++) {
|
||||||
int blocked = B_FALSE;
|
int blocked = B_FALSE;
|
||||||
int fullbonus = 0;
|
// did f_fuillblock skill work?
|
||||||
if (fflag && ranged && (shield[i]->id == shid)) {
|
if (fflag && ranged && (shield[i]->id == shid)) {
|
||||||
fullbonus = 40 + (getobsize(shield[i])*5);
|
int fullchance;
|
||||||
|
fullchance = 40 + (getobsize(shield[i])*5);
|
||||||
|
if (pctchance(fullchance)) {
|
||||||
|
blocked = B_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// did we block with this object?
|
// did we block with this object?
|
||||||
if (skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i] + fullbonus)) {
|
if (!blocked && skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i])) {
|
||||||
blocked = B_TRUE;
|
blocked = B_TRUE;
|
||||||
}
|
}
|
||||||
if (blocked) {
|
if (blocked) {
|
||||||
|
@ -3100,7 +3109,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fumble && !gothit) {
|
if (fumble && !gothit) {
|
||||||
if ((baseacc <= 60) || !getweaponskill(lf, wep)) {
|
if (isexhausted(lf) || (baseacc <= 60) || !getweaponskill(lf, wep)) {
|
||||||
int nfailed = 0, i;
|
int nfailed = 0, i;
|
||||||
int nrolls = 1;
|
int nrolls = 1;
|
||||||
// chance to fumble
|
// chance to fumble
|
||||||
|
|
4
data.c
4
data.c
|
@ -5550,10 +5550,11 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||||
addot(OT_A_FULLSHIELD, "fullshield", "Raise your shield to (almost) completely cover your body.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
addot(OT_A_FULLSHIELD, "fullshield", "Fully raise your shield to almost completely protect against ranged attacks.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "While in fullshield mode your vision, evasion and accuracy are greatly lowered.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "While in fullshield mode your vision, evasion and accuracy are greatly lowered.");
|
||||||
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
||||||
addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||||
|
@ -19169,6 +19170,7 @@ void initskills(void) {
|
||||||
addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gShield accuracy penalties are reduced by 2.^n", B_FALSE);
|
addskilldesc(SK_SHIELDS, PR_BEGINNER, "^gShield accuracy penalties are reduced by 2.^n", B_FALSE);
|
||||||
addskillabil(SK_SHIELDS, PR_BEGINNER, OT_A_SHIELDBASH, NA, NULL, B_TRUE);
|
addskillabil(SK_SHIELDS, PR_BEGINNER, OT_A_SHIELDBASH, NA, NULL, B_TRUE);
|
||||||
addskilldesc(SK_SHIELDS, PR_ADEPT, "^gShield accuracy penalties are reduced by 3.^n", B_FALSE);
|
addskilldesc(SK_SHIELDS, PR_ADEPT, "^gShield accuracy penalties are reduced by 3.^n", B_FALSE);
|
||||||
|
addskillabil(SK_SHIELDS, PR_ADEPT, OT_A_FULLSHIELD, NA, NULL, B_TRUE);
|
||||||
addskilldesc(SK_SHIELDS, PR_SKILLED, "^gShield accuracy penalties are reduced by 4.^n", B_FALSE);
|
addskilldesc(SK_SHIELDS, PR_SKILLED, "^gShield accuracy penalties are reduced by 4.^n", B_FALSE);
|
||||||
addskilldesc(SK_SHIELDS, PR_EXPERT, "^gShield accuracy penalties are reduced by 5.^n", B_FALSE);
|
addskilldesc(SK_SHIELDS, PR_EXPERT, "^gShield accuracy penalties are reduced by 5.^n", B_FALSE);
|
||||||
addskilldesc(SK_SHIELDS, PR_MASTER, "^gShield accuracy penalties are reduced by 6.^n", B_FALSE);
|
addskilldesc(SK_SHIELDS, PR_MASTER, "^gShield accuracy penalties are reduced by 6.^n", B_FALSE);
|
||||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
3
defs.h
3
defs.h
|
@ -3510,6 +3510,9 @@ enum FLAG {
|
||||||
// x,y-x,y-x,y-x,y...
|
// x,y-x,y-x,y-x,y...
|
||||||
//
|
//
|
||||||
// v0/v1 = x/y of end cell
|
// v0/v1 = x/y of end cell
|
||||||
|
F_AIHITBYRANGED, // ai lf has been hit by a ranged attack.
|
||||||
|
// used to figure out when to use our
|
||||||
|
// fullshield ability
|
||||||
F_TARGETLF, // lf will attack lfid v0. lastknown x/y is v1/v2
|
F_TARGETLF, // lf will attack lfid v0. lastknown x/y is v1/v2
|
||||||
// optional text is last known movement dir.
|
// optional text is last known movement dir.
|
||||||
F_IGNORECELL, // won't accept targetcells of v0=x v1=y
|
F_IGNORECELL, // won't accept targetcells of v0=x v1=y
|
||||||
|
|
3
flag.c
3
flag.c
|
@ -1654,6 +1654,9 @@ void updatefpindex(flagpile_t *fp) {
|
||||||
|
|
||||||
fp->nitems = 0;
|
fp->nitems = 0;
|
||||||
for (f = fp->first ;f ; f = f->next) {
|
for (f = fp->first ;f ; f = f->next) {
|
||||||
|
if (f->next) {
|
||||||
|
assert(f->next->prev == f);
|
||||||
|
}
|
||||||
fp->item[fp->nitems] = f;
|
fp->item[fp->nitems] = f;
|
||||||
fp->nitems++;
|
fp->nitems++;
|
||||||
assert(fp->nitems < MAXFLAGS);
|
assert(fp->nitems < MAXFLAGS);
|
||||||
|
|
27
io.c
27
io.c
|
@ -1240,6 +1240,15 @@ char *askstring(char *prompt, char punc, char *retbuf, int retBUFLEN, char *def)
|
||||||
|
|
||||||
void announcearrival(lifeform_t *lf, map_t *newmap) {
|
void announcearrival(lifeform_t *lf, map_t *newmap) {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
|
char backtext[BUFLEN];
|
||||||
|
if (lf->cell->map == newmap) {
|
||||||
|
strcpy(backtext, "elsewhere ");
|
||||||
|
} else if (newmap->lastplayervisit == -1) {
|
||||||
|
// never been here before
|
||||||
|
strcpy(backtext, "");
|
||||||
|
} else {
|
||||||
|
strcpy(backtext, "back ");
|
||||||
|
}
|
||||||
if (newmap->region->rtype->id == BH_WORLDMAP) {
|
if (newmap->region->rtype->id == BH_WORLDMAP) {
|
||||||
if (lf->cell->map->region->rtype->id == BH_WORLDMAP) {
|
if (lf->cell->map->region->rtype->id == BH_WORLDMAP) {
|
||||||
msg("You arrive in a new area.");
|
msg("You arrive in a new area.");
|
||||||
|
@ -1250,29 +1259,24 @@ void announcearrival(lifeform_t *lf, map_t *newmap) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
switch (newmap->habitat->id) {
|
switch (newmap->habitat->id) {
|
||||||
case H_ANTNEST:
|
case H_ANTNEST:
|
||||||
msg("You find yourself %sin a giant ant's nest.",
|
msg("You find yourself %sin a giant ant's nest.", backtext);
|
||||||
(newmap->lastplayervisit == -1) ? "" : "back ");
|
|
||||||
break;
|
break;
|
||||||
case H_CAVE:
|
case H_CAVE:
|
||||||
if ((newmap->depth == 1) && (newmap->lastplayervisit == -1)) {
|
if ((newmap->depth == 1) && (newmap->lastplayervisit == -1)) {
|
||||||
msg("You arrive at the goblin caves.");
|
msg("You arrive at the goblin caves.");
|
||||||
} else {
|
} else {
|
||||||
msg("You arrive %sat level %d of the goblin caves.",
|
msg("You arrive %sat level %d of the goblin caves.",
|
||||||
(newmap->lastplayervisit == -1) ? "" : "back ",
|
backtext, newmap->depth);
|
||||||
newmap->depth);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case H_DUNGEON:
|
case H_DUNGEON:
|
||||||
msg("You arrive %sat dungeon level %d.",
|
msg("You arrive %sat dungeon level %d.", backtext, newmap->depth);
|
||||||
(newmap->lastplayervisit == -1) ? "" : "back ",
|
|
||||||
newmap->depth);
|
|
||||||
break;
|
break;
|
||||||
case H_FOREST:
|
case H_FOREST:
|
||||||
if ((newmap->depth == 1) && (newmap->lastplayervisit == -1)) {
|
if ((newmap->depth == 1) && (newmap->lastplayervisit == -1)) {
|
||||||
msg("You arrive in the sylvan woods.");
|
msg("You arrive in the sylvan woods.");
|
||||||
} else {
|
} else {
|
||||||
msg("You arrive %sat level %d of the sylvan woods.",
|
msg("You arrive %sat level %d of the sylvan woods.", backtext,
|
||||||
(newmap->lastplayervisit == -1) ? "" : "back ",
|
|
||||||
newmap->depth);
|
newmap->depth);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1285,8 +1289,7 @@ void announcearrival(lifeform_t *lf, map_t *newmap) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case H_SWAMP:
|
case H_SWAMP:
|
||||||
msg("You arrive %sat a swamp.",
|
msg("You arrive %sat a swamp.", backtext);
|
||||||
(newmap->lastplayervisit == -1) ? "" : "back ");
|
|
||||||
break;
|
break;
|
||||||
case H_SEWER:
|
case H_SEWER:
|
||||||
msg("You find yourself in a sewer.");
|
msg("You find yourself in a sewer.");
|
||||||
|
@ -1681,7 +1684,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
||||||
msg("You are now cowering behind your %s.", noprefix(obname));
|
msg("You are now cowering behind your %s.", noprefix(obname));
|
||||||
donesomething = B_TRUE;
|
donesomething = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
msg("%s is now cowering behind %s.", lfname, obname);
|
msg("%s starts cowering behind %s.", lfname, obname);
|
||||||
donesomething = B_TRUE;
|
donesomething = B_TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
44
lf.c
44
lf.c
|
@ -593,10 +593,12 @@ void callguards(lifeform_t *caller, lifeform_t *victim) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int canattack(lifeform_t *lf) {
|
int canattack(lifeform_t *lf) {
|
||||||
|
/*
|
||||||
if (!getstamina(lf)) {
|
if (!getstamina(lf)) {
|
||||||
reason = E_NOSTAM;
|
reason = E_NOSTAM;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
} else if (lfhasflag(lf, F_STUNNED)) {
|
} else */
|
||||||
|
if (lfhasflag(lf, F_STUNNED)) {
|
||||||
reason = E_STUNNED;
|
reason = E_STUNNED;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
} else if (lfhasflag(lf, F_NOATTACK)) {
|
} else if (lfhasflag(lf, F_NOATTACK)) {
|
||||||
|
@ -6359,6 +6361,9 @@ int flee(lifeform_t *lf) {
|
||||||
|
|
||||||
if (db) dblog("%s - fleeing from %s", lfname, fleefrom->race->name);
|
if (db) dblog("%s - fleeing from %s", lfname, fleefrom->race->name);
|
||||||
|
|
||||||
|
// lower our shield
|
||||||
|
killflagsofid(lf->flags, F_FULLSHIELD);
|
||||||
|
|
||||||
breakgrabs(lf, B_TRUE, B_FALSE); // stop grabbing anyone
|
breakgrabs(lf, B_TRUE, B_FALSE); // stop grabbing anyone
|
||||||
|
|
||||||
// ways of fleeing other than movement?
|
// ways of fleeing other than movement?
|
||||||
|
@ -7275,6 +7280,10 @@ int getattackspeed(lifeform_t *lf) {
|
||||||
del = getobattackdelay(w);
|
del = getobattackdelay(w);
|
||||||
speed = pctof(del, speed);
|
speed = pctof(del, speed);
|
||||||
}
|
}
|
||||||
|
// 50% longer to attack if exhausted
|
||||||
|
if (isexhausted(lf)) {
|
||||||
|
speed = pctof(150, speed);
|
||||||
|
}
|
||||||
|
|
||||||
return (int)speed;
|
return (int)speed;
|
||||||
}
|
}
|
||||||
|
@ -9612,6 +9621,12 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
|
||||||
strcat(descstring, "headless ");
|
strcat(descstring, "headless ");
|
||||||
dobehaviour = B_FALSE;
|
dobehaviour = B_FALSE;
|
||||||
}
|
}
|
||||||
|
if (!isplayer(lf) && isexhausted(lf) && cansee(player, lf)) {
|
||||||
|
if (lorelev >= PR_NOVICE) {
|
||||||
|
strcat(descstring, "exhausted ");
|
||||||
|
dobehaviour = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dobehaviour) {
|
if (dobehaviour) {
|
||||||
f = lfhasflag(lf, F_BEHAVIOUR);
|
f = lfhasflag(lf, F_BEHAVIOUR);
|
||||||
|
@ -13794,6 +13809,11 @@ int isfullyhealed(lifeform_t *lf) {
|
||||||
return healed;
|
return healed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isexhausted(lifeform_t *lf) {
|
||||||
|
if (!getstamina(lf)) return B_TRUE;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int isgenius(lifeform_t *lf) {
|
int isgenius(lifeform_t *lf) {
|
||||||
enum ATTRBRACKET iqb;
|
enum ATTRBRACKET iqb;
|
||||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||||
|
@ -16113,12 +16133,23 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
||||||
if (fromlf && (getallegiance(fromlf) == AL_FRIENDLY)) {
|
if (fromlf && (getallegiance(fromlf) == AL_FRIENDLY)) {
|
||||||
addflag(lf->flags, F_KILLEDBYPLAYER, B_TRUE, NA, NA, NULL);
|
addflag(lf->flags, F_KILLEDBYPLAYER, B_TRUE, NA, NA, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doeffects || ko) {
|
if (doeffects || ko) {
|
||||||
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp, bodypart);
|
losehpeffects(lf, amt, damtype, fromlf, fromob, retaliate, ko, waskod, prelowhp, bodypart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((lf->hp > 0) && !ko && fromlf && (getcelldist(lf->cell, fromlf->cell) > 1)) {
|
||||||
|
int lifetimeinc;
|
||||||
|
lifetimeinc = rnd(2,6);
|
||||||
|
f = lfhasflag(lf, F_AIHITBYRANGED);
|
||||||
|
if (f) {
|
||||||
|
f->lifetime += lifetimeinc;
|
||||||
|
} else {
|
||||||
|
addtempflag(lf->flags, F_AIHITBYRANGED, B_TRUE, NA, NA, NULL, lifetimeinc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!predead) {
|
if (!predead) {
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
// Figure out death text for tombstone.
|
// Figure out death text for tombstone.
|
||||||
|
@ -17126,19 +17157,18 @@ void modstamina(lifeform_t *lf, float howmuch) {
|
||||||
statdirty = B_TRUE;
|
statdirty = B_TRUE;
|
||||||
drawstatus();
|
drawstatus();
|
||||||
updatestatus();
|
updatestatus();
|
||||||
if (getstamina(lf) == 0) {
|
if (isexhausted(lf)) {
|
||||||
msg("^BYou are exhausted.");
|
msg("^BYou are exhausted.");
|
||||||
} else if (orig == 0) {
|
} else if (orig == 0) {
|
||||||
msg("You feel less exhausted now.");
|
msg("You feel less exhausted now.");
|
||||||
}
|
}
|
||||||
}
|
} else if (cansee(player, lf)) {
|
||||||
/*else if (cansee(player, lf)) {
|
if (isexhausted(lf)) {
|
||||||
if (getstamina(lf) == 0) {
|
|
||||||
char lfname[BUFLEN];
|
char lfname[BUFLEN];
|
||||||
getlfname(lf, lfname);
|
getlfname(lf, lfname);
|
||||||
msg("%s looks exhausted.", lfname);
|
msg("%s looks exhausted.", lfname);
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getstamina(lf) == 0) {
|
if (getstamina(lf) == 0) {
|
||||||
|
|
1
lf.h
1
lf.h
|
@ -354,6 +354,7 @@ flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom);
|
||||||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||||
int isfriendly(lifeform_t *lf);
|
int isfriendly(lifeform_t *lf);
|
||||||
int isfullyhealed(lifeform_t *lf);
|
int isfullyhealed(lifeform_t *lf);
|
||||||
|
int isexhausted(lifeform_t *lf);
|
||||||
int isgenius(lifeform_t *lf);
|
int isgenius(lifeform_t *lf);
|
||||||
int isgod(lifeform_t *lf);
|
int isgod(lifeform_t *lf);
|
||||||
int ishelplessvictim(lifeform_t *victim, lifeform_t *attacker, enum HELPLESSTYPE *how);
|
int ishelplessvictim(lifeform_t *victim, lifeform_t *attacker, enum HELPLESSTYPE *how);
|
||||||
|
|
14
map.c
14
map.c
|
@ -9226,6 +9226,20 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns TRUE if we shuffled down.
|
||||||
|
int shuffledown(map_t *map) {
|
||||||
|
lifeform_t *l;
|
||||||
|
int firsttime;
|
||||||
|
firsttime = map->lf->timespent;
|
||||||
|
if (firsttime == 0) return B_FALSE;
|
||||||
|
for (l = map->lf ; l ; l = l->next) {
|
||||||
|
//dblog("shuffling id %d %s timespent=%d -> %d",l->id,l->race->name, l->timespent, l->timespent - firstlftime);
|
||||||
|
l->timespent -= firsttime;
|
||||||
|
assert(l->timespent >= 0);
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int unlinkstairsto(map_t *unlinkmap) {
|
int unlinkstairsto(map_t *unlinkmap) {
|
||||||
map_t *m;
|
map_t *m;
|
||||||
object_t *o;
|
object_t *o;
|
||||||
|
|
1
map.h
1
map.h
|
@ -201,6 +201,7 @@ void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
|
||||||
void setcellreason(cell_t *c, char *why, ...);
|
void setcellreason(cell_t *c, char *why, ...);
|
||||||
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
void setcelltype(cell_t *cell, enum CELLTYPE id);
|
||||||
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
|
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
|
||||||
|
int shuffledown(map_t *map);
|
||||||
int unlinkstairsto(map_t *unlinkmap);
|
int unlinkstairsto(map_t *unlinkmap);
|
||||||
void unmakemap(map_t *map);
|
void unmakemap(map_t *map);
|
||||||
void updateknowncells(void);
|
void updateknowncells(void);
|
||||||
|
|
2
move.c
2
move.c
|
@ -2438,7 +2438,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
|
||||||
// climbing along a wall?
|
// climbing along a wall?
|
||||||
if (isplayer(lf) && isclimbing(lf)) {
|
if (isplayer(lf) && isclimbing(lf)) {
|
||||||
if (cell != getcellindir(lf->cell, lf->facing)) { // not dropping off the wall
|
if (cell != getcellindir(lf->cell, lf->facing)) { // not dropping off the wall
|
||||||
if (!getstamina(lf)) {
|
if (isexhausted(lf)) {
|
||||||
// this shouldn't be able to happen, since if you run out
|
// this shouldn't be able to happen, since if you run out
|
||||||
// of stamina while on a wall you'll fall off during startlfturn().
|
// of stamina while on a wall you'll fall off during startlfturn().
|
||||||
msg("You are too tired to climb!");
|
msg("You are too tired to climb!");
|
||||||
|
|
22
nexus.c
22
nexus.c
|
@ -911,6 +911,11 @@ void donextturn(map_t *map) {
|
||||||
if (who) {
|
if (who) {
|
||||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||||
|
|
||||||
|
if (who->timespent > 0) {
|
||||||
|
// shuffling lf times...
|
||||||
|
shuffledown(map);
|
||||||
|
}
|
||||||
|
|
||||||
assert(who->timespent == 0);
|
assert(who->timespent == 0);
|
||||||
|
|
||||||
if (getoption(OPT_TIMEDEBUG)) {
|
if (getoption(OPT_TIMEDEBUG)) {
|
||||||
|
@ -2041,23 +2046,10 @@ void timeeffectsworld(map_t *map, int updategametime) {
|
||||||
|
|
||||||
//if (db) dblog("timespent = %d\n", timespent);
|
//if (db) dblog("timespent = %d\n", timespent);
|
||||||
if (db) dblog("firstlftime = %d\n", firstlftime);
|
if (db) dblog("firstlftime = %d\n", firstlftime);
|
||||||
|
|
||||||
if (firstlftime > 0) {
|
if (firstlftime > 0) {
|
||||||
if (db) dblog("making firstlf timespent = 0 (currently %d):", firstlftime);
|
if (db) dblog("making firstlf timespent = 0 (currently %d):", firstlftime);
|
||||||
//dumplf();
|
shuffledown(map);
|
||||||
for (l = map->lf ; l ; l = l->next) {
|
|
||||||
//dblog("shuffling id %d %s timespent=%d -> %d",l->id,l->race->name, l->timespent, l->timespent - firstlftime);
|
|
||||||
l->timespent -= firstlftime;
|
|
||||||
assert(l->timespent >= 0);
|
|
||||||
/*
|
|
||||||
if (isplayer(l)) {
|
|
||||||
statdirty = B_TRUE;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
//dblog("after shuffle:");
|
|
||||||
//dumplf();
|
|
||||||
} else {
|
} else {
|
||||||
if (db) dblog("firstlf timespent is not greater than 0. no shuffle.");
|
if (db) dblog("firstlf timespent is not greater than 0. no shuffle.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5737,7 +5737,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
||||||
|
|
||||||
// include mods
|
// include mods
|
||||||
// ie. a blessed damaged ->flaming<- +5 silver sword of pyromania
|
// ie. a blessed damaged ->flaming<- +5 silver sword of pyromania
|
||||||
if (wantpremods) {
|
if (wantpremods && (!isblind(player) || !adjustforblind)) {
|
||||||
obmod_t *om;
|
obmod_t *om;
|
||||||
for (om = firstobmod ; om; om = om->next) {
|
for (om = firstobmod ; om; om = om->next) {
|
||||||
if (hasobmod(o, om)) {
|
if (hasobmod(o, om)) {
|
||||||
|
|
43
text.c
43
text.c
|
@ -227,7 +227,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
|
||||||
|
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
char extradambuf[BUFLEN];
|
char extradambuf[BUFLEN];
|
||||||
char withwep[BUFLEN];
|
char withwep[BUFLEN],adjective[BUFLEN],hitwhere[BUFLEN];
|
||||||
char *verb;
|
char *verb;
|
||||||
int needfree = B_FALSE;
|
int needfree = B_FALSE;
|
||||||
int knownnodam = B_FALSE;
|
int knownnodam = B_FALSE;
|
||||||
|
@ -277,10 +277,24 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
|
||||||
} else {
|
} else {
|
||||||
col = C_BROWN; // normal hit
|
col = C_BROWN; // normal hit
|
||||||
}
|
}
|
||||||
snprintf(retbuf, BUFLEN, "^%dYou %s%s %s%s%s%s", col,
|
|
||||||
usecrittext ? "critically " : "", verb,
|
strcpy(adjective, "");
|
||||||
usecrittext ? victimbpname : locvictimname, withwep,extradambuf,
|
if (isexhausted(lf)) {
|
||||||
(fatal || backstab) ? "!" : ".");
|
if (onein(2)) strcat(adjective, "tiredly ");
|
||||||
|
else strcat(adjective, "wearily ");
|
||||||
|
}
|
||||||
|
if (usecrittext) {
|
||||||
|
if (strlen(adjective)) {
|
||||||
|
strcat(adjective, "but critically ");
|
||||||
|
} else {
|
||||||
|
strcat(adjective, "critically ");
|
||||||
|
}
|
||||||
|
strcpy(hitwhere, victimbpname);
|
||||||
|
} else {
|
||||||
|
strcpy(hitwhere, locvictimname);
|
||||||
|
}
|
||||||
|
snprintf(retbuf, BUFLEN, "^%dYou %s%s %s%s%s%s", col, adjective, verb,
|
||||||
|
hitwhere, withwep,extradambuf, (fatal || backstab) ? "!" : ".");
|
||||||
|
|
||||||
if (needfree) {
|
if (needfree) {
|
||||||
free(verb);
|
free(verb);
|
||||||
|
@ -289,7 +303,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
|
||||||
if (cansee(player, lf) || (victim && isplayer(victim))) {
|
if (cansee(player, lf) || (victim && isplayer(victim))) {
|
||||||
int needfree = B_FALSE;
|
int needfree = B_FALSE;
|
||||||
char *verb;
|
char *verb;
|
||||||
char withwep[BUFLEN];
|
char withwep[BUFLEN],adjective[BUFLEN],hitwhere[BUFLEN];
|
||||||
char nodamstr[BUFLEN];
|
char nodamstr[BUFLEN];
|
||||||
int nodam = B_FALSE;
|
int nodam = B_FALSE;
|
||||||
int col;
|
int col;
|
||||||
|
@ -334,11 +348,18 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
|
||||||
} else {
|
} else {
|
||||||
col = C_GREY;
|
col = C_GREY;
|
||||||
}
|
}
|
||||||
snprintf(retbuf, BUFLEN, "^%d%s %s%s%s %s%s%s%c", col, buf,
|
|
||||||
usecrittext ? "critically " : "", verb,
|
strcpy(adjective, "");
|
||||||
needses(verb) ? "es" : "s",
|
if (usecrittext) {
|
||||||
usecrittext ? victimbpname : locvictimname,withwep, nodamstr,
|
strcat(adjective, "critically ");
|
||||||
backstab ? '!' : '.');
|
strcpy(hitwhere, victimbpname);
|
||||||
|
} else {
|
||||||
|
strcpy(hitwhere, locvictimname);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(retbuf, BUFLEN, "^%d%s %s%s%s %s%s%s%c", col, buf, adjective,
|
||||||
|
verb, needses(verb) ? "es" : "s",
|
||||||
|
hitwhere, withwep, nodamstr, backstab ? '!' : '.');
|
||||||
if (needfree) {
|
if (needfree) {
|
||||||
free(verb);
|
free(verb);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue