diff --git a/ai.c b/ai.c index 9bc3c2d..8874cc8 100644 --- a/ai.c +++ b/ai.c @@ -442,6 +442,18 @@ void aiturn(lifeform_t *lf) { master = findlf(lf->cell->map, mf->val[0]); } + /////////////////////////////////////////////// + // emergencies + /////////////////////////////////////////////// + if (iqb >= IQ_AVERAGE) { + if (celldangerous(lf, lf->cell, B_TRUE, NULL)) { + // if our cell is dangerous, move away! + if (!dorandommove(lf, B_NOBADMOVES, B_FALSE)) { + return; + } + } + } + /////////////////////////////////////////////// // housekeeping - weapon changes, drop/pickup, @@ -992,14 +1004,14 @@ void aiturn(lifeform_t *lf) { // - either move towards them or randomly if (isadjacent(lf->cell, master->cell)) { if (db) dblog(".oO { i can see my master - moving randomly }"); - dorandommove(lf, B_NOBADMOVES); + dorandommove(lf, B_NOBADMOVES, B_TRUE); } else { // move towards master if not adjacent if (db) dblog(".oO { i can see my master - moving towards them }"); if (movetowards(lf, master->cell, DT_ORTH)) { // failed if (db) dblog(".oO { failed. moving randomly }"); - dorandommove(lf, B_NOBADMOVES); + dorandommove(lf, B_NOBADMOVES, B_TRUE); } else { // success if (db) dblog(".oO { success. }"); @@ -1036,11 +1048,11 @@ void aiturn(lifeform_t *lf) { aimovetotargetcell(lf, movetoflag); } else { if (db) dblog(".oO { cannot see my master and aigoto last known loc/dir failed. randommove. }"); - dorandommove(lf, B_NOBADMOVES); + dorandommove(lf, B_NOBADMOVES, B_TRUE); } } else { if (db) dblog(".oO { cannot see my master and dont have a last known location. randommove. }"); - dorandommove(lf, B_NOBADMOVES); + dorandommove(lf, B_NOBADMOVES, B_TRUE); } return; } @@ -1059,7 +1071,7 @@ void aiturn(lifeform_t *lf) { // DEFAULT - try to move in a random direction if (db) dblog(".oO { default - moving randomly }"); - dorandommove(lf, B_NOBADMOVES); // this function will call rest() if we cant move + dorandommove(lf, B_NOBADMOVES, B_TRUE); // this function will call rest() if we cant move } diff --git a/defs.h b/defs.h index 902047c..05a0fd0 100644 --- a/defs.h +++ b/defs.h @@ -1595,6 +1595,7 @@ enum FLAG { F_ACCURACYMOD, // modify your accuracy by val0 F_VEGETARIAN, // this lf will not eat meat. F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry' + F_CARNIVORE, // this lf will only eat meat. F_SHIELDPENALTY, // lower your accuracy by val0 due to a cumbersome // shield F_LEVRACE, // at level v0, this race is promoted to race v1 @@ -2041,8 +2042,9 @@ enum ERROR { // E_NOBP = 48, E_VEGETARIAN = 49, - E_PARTVEGETARIAN= 50, - E_NOOB = 51, + E_PARTVEGETARIAN = 50, + E_CARNIVORE = 51, + E_NOOB = 52, }; diff --git a/io.c b/io.c index 651f399..86a1aef 100644 --- a/io.c +++ b/io.c @@ -6676,7 +6676,7 @@ void showlfstats(lifeform_t *lf, int showall) { getspeedname(speed, buf2); capitalise(buf2); sprintf(buf, "%s, %d%%",buf2,acc); - mvwprintw(mainwin, y2, x2, ftext, "Speed/Acc"); + mvwprintw(mainwin, y2, x2, "%14s", " "); wprintw(mainwin, "%-20s", buf); y2++; } else { diff --git a/lf.c b/lf.c index f165840..82d683d 100644 --- a/lf.c +++ b/lf.c @@ -489,6 +489,11 @@ int caneat(lifeform_t *lf, object_t *o) { reason = E_VEGETARIAN; return B_FALSE; } + if (lfhasflag(lf, F_CARNIVORE) && (o->material->id != MT_FLESH)) { + reason = E_CARNIVORE; + return B_FALSE; + } + if (lfhasflag(lf, F_PARTVEGETARIAN) && (o->material->id == MT_FLESH)) { if (gethungerlevel(gethungerval(player)) < H_HUNGRY) { reason = E_PARTVEGETARIAN; @@ -1655,6 +1660,9 @@ int eat(lifeform_t *lf, object_t *o) { case E_UNDEAD: msg("You are undead and don't need to eat."); break; + case E_CARNIVORE: + msg("The thought of eating plant matter disgusts you."); + break; case E_VEGETARIAN: msg("The thought of eating flesh disgusts you."); break; @@ -5726,7 +5734,6 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spellbook of flame dart"); for (i = 1; i < MAXSKILLS; i++) { addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); } @@ -7569,6 +7576,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, 8, 8, NULL); @@ -7590,6 +7598,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, 5, 5, NULL); @@ -7783,6 +7792,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHPARALYZE2, NA, NA, "0d1+0"); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); @@ -7824,6 +7834,7 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d5+3"); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHPARALYZE, NA, NA, "0d1+0"); + addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); @@ -12506,6 +12517,7 @@ int rest(lifeform_t *lf, int onpurpose) { getlfname(lf, lfname); msg("%s finishes resting.",lfname); } + if (isplayer(lf)) statdirty = B_TRUE; killflag(rf); wantclearmsg = B_FALSE; } diff --git a/log.txt b/log.txt index 9ed9d1f..b7ea667 100644 --- a/log.txt +++ b/log.txt @@ -4,3 +4,50 @@ ====== NEW LOGFILE ==== givejob() starting. +fireat(): dam = throwdam(2) * speed(3) = 6 +fireat(): dam = throwdam(2) * speed(3) = 6 +fireat(): dam = throwdam(3) * speed(3) = 9 +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +fireat(): dam = throwdam(2) * speed(2) = 4 +xxx +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +fireat(): dam = throwdam(3) * speed(2) = 6 +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast charge - specific spell check failed } +.oO { cant cast charge - specific spell check failed } +fireat(): dam = throwdam(2) * speed(2) = 4 +fireat(): dam = throwdam(2) * speed(3) = 6 +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +.oO { cant cast suck blood - targetting conditions cannot be met } +xxx +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +fireat(): dam = throwdam(2) * speed(3) = 6 +fireat(): dam = throwdam(3) * speed(3) = 9 +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +.oO { cant cast grab - targetting conditions cannot be met } +xxx diff --git a/move.c b/move.c index 500b831..b714248 100644 --- a/move.c +++ b/move.c @@ -268,7 +268,9 @@ int diropposite(int dir) { return dir; } -void dorandommove(lifeform_t *lf, int badmovesok) { +// restonfail means "if we can't find any valid moves, just rest" +// returns true on error +int dorandommove(lifeform_t *lf, int badmovesok, int restonfail) { int dir; int tries = 0; int moveok; @@ -294,8 +296,10 @@ void dorandommove(lifeform_t *lf, int badmovesok) { // try next direction... if (++dir > DC_NW) dir = DC_N; if (++tries >= MAXDIR_COMPASS) { - rest(lf, B_TRUE); - return; + if (restonfail) { + rest(lf, B_TRUE); + } + return B_TRUE; } // check this direction... @@ -311,7 +315,7 @@ void dorandommove(lifeform_t *lf, int badmovesok) { } } } - trymove(lf, dir, B_TRUE); + return trymove(lf, dir, B_TRUE); } @@ -581,7 +585,7 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype ) { int rv = B_TRUE; if (isblind(lf)) { - dorandommove(lf, B_TRUE); + dorandommove(lf, B_TRUE, B_TRUE); return B_FALSE; } @@ -1006,7 +1010,7 @@ int movetowards(lifeform_t *lf, cell_t *dst, int dirtype) { int rv = B_TRUE; if (isblind(lf)) { - dorandommove(lf, B_TRUE); + dorandommove(lf, B_TRUE, B_TRUE); return B_FALSE; } diff --git a/move.h b/move.h index 79d5369..a2cc4be 100644 --- a/move.h +++ b/move.h @@ -8,7 +8,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error); int closedoorat(lifeform_t *lf, cell_t *c); int closedoor(lifeform_t *lf, object_t *o); int diropposite(int dir); -void dorandommove(lifeform_t *lf, int badmovesok); +int dorandommove(lifeform_t *lf, int badmovesok, int restonfail); int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype); int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype); int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff); diff --git a/objects.c b/objects.c index 1ab0e80..33d1af7 100644 --- a/objects.c +++ b/objects.c @@ -5736,7 +5736,7 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // tools - addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_ARMOUR); + addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_TOOLS); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_HELPSREST, 10, NA, NA, NULL);