diff --git a/data.c b/data.c index f394a2d..218b4af 100644 --- a/data.c +++ b/data.c @@ -4119,7 +4119,7 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); - addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks.", MT_METAL, 0.05, OC_TOOLS, SZ_TINY); + addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks. Even those unskilled in lockpicking can attempt to use this item, although success in this case may be unlikely.", MT_METAL, 0.05, OC_TOOLS, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_VALUE, 10, NA, NA, NULL); diff --git a/data/hiscores.db b/data/hiscores.db index f332c3a..f67c49e 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/flag.c b/flag.c index 896796f..20d3da9 100644 --- a/flag.c +++ b/flag.c @@ -613,6 +613,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) { case F_HASNEWLEVEL: case F_HIDING: case F_ICESLIDE: + case F_INJURY: case F_INVISIBLE: case F_LEVITATING: case F_PARALYZED: diff --git a/io.c b/io.c index de8ddd3..a2e5cbe 100644 --- a/io.c +++ b/io.c @@ -9377,6 +9377,11 @@ void drawstatus(void) { wprintw(statwin, " Blind"); unsetcol(statwin, C_RED); } + if (lfhasflag(player, F_INJURY)) { + setcol(statwin, C_RED); + wprintw(statwin, " Injured"); + unsetcol(statwin, C_RED); + } if (lfhasflag(player, F_GRAVBOOSTED)) { setcol(statwin, C_RED); diff --git a/lf.c b/lf.c index ec570e9..0cbfd2d 100644 --- a/lf.c +++ b/lf.c @@ -8925,7 +8925,7 @@ flag_t *giveskilllev(lifeform_t *lf, enum SKILL id, enum SKILLLEVEL slev) { // give start objects from a particular flagpile // only give EITHER lf OR targob void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { - object_t *o; + object_t *o = NULL; flag_t *f; char buf[BUFLEN],buf2[BUFLEN]; int db = B_FALSE; @@ -9157,9 +9157,11 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { if (o) { if (!obfits(o, op)) { killob(o); + o = NULL; } else if (op->parentob && hasflag(o->flags, F_CONTAINER)) { // don't put containers in other containers killob(o); + o = NULL; } } @@ -14199,6 +14201,8 @@ int startresting(lifeform_t *lf, int willtrain) { // stop all spells stopallspells(lf); + stopsprinting(lf); + killflagsofid(lf->flags, F_INTERRUPTED); if (willtrain) { diff --git a/map.c b/map.c index f00ed04..014b690 100644 --- a/map.c +++ b/map.c @@ -4847,22 +4847,25 @@ void finalisemap(map_t *map, object_t *entryob) { c = getcellat(map, x, y); for (o = c->obpile->first ; o ; o = nexto) { nexto = o->next; - // doors which go nowhere? - if (isdoor(o, NULL)) { - int dir, ok = B_FALSE; - cell_t *c2; - // check all directions for a cell which isn't - // part of this room. - for (dir = DC_N; dir <= DC_NW; dir++) { - c2 = getcellindir(c, dir); - if (c2 && cellwalkable(NULL, c2, NULL) && getroomid(c2) != getroomid(c)) { - ok = B_TRUE; - break; + if (c->room && c->room->vault) { + } else { + // doors which go nowhere? + if (isdoor(o, NULL)) { + int dir, ok = B_FALSE; + cell_t *c2; + // check all directions for a cell which isn't + // part of this room. + for (dir = DC_N; dir <= DC_NW; dir++) { + c2 = getcellindir(c, dir); + if (c2 && cellwalkable(NULL, c2, NULL) && getroomid(c2) != getroomid(c)) { + ok = B_TRUE; + break; + } + } + if (!ok) { + killob(o); + continue; } - } - if (!ok) { - killob(o); - continue; } } // unlinked stairs? ie ones added from vaults. if so, link them. diff --git a/move.c b/move.c index ba9fa0d..fca360b 100644 --- a/move.c +++ b/move.c @@ -1109,71 +1109,85 @@ int movelf(lifeform_t *lf, cell_t *newcell) { getlfname(lf, lfname); - if (isplayer(lf) || cansee(player, lf)) { - needredraw = B_TRUE; - } - - if (newcell->map != lf->cell->map) { - changedlev = B_TRUE; - if (isplayer(lf)) { - // remember the time which we exitted this map. - lf->cell->map->lastplayervisit = curtime; + if (gamemode == GM_GAMESTARTED) { + if (isplayer(lf) || cansee(player, lf)) { + needredraw = B_TRUE; } - } - // special effects when the player moves to a new map - if (changedlev && isplayer(lf)) { - object_t *o; - long barrierid = -1; - // mapentereffects will give all monster on the new map - // a bunch of turns to simulate time passing while the player - // was away. to prevent them from blocking off the staircase cell - // where the player is about to arrive, place a magic barrier over it. - o = addobfast(newcell->obpile, OT_MAGICBARRIER); - if (o) barrierid = o->id; - - mapentereffects(newcell->map); + if (newcell->map != lf->cell->map) { + changedlev = B_TRUE; + if (isplayer(lf)) { + // remember the time which we exitted this map. + lf->cell->map->lastplayervisit = curtime; + } + } - // now remove the barrier - o = hasobid(newcell->obpile, barrierid); - if (o) killob(o); - } + // special effects when the player moves to a new map + if (changedlev && isplayer(lf)) { + object_t *o; + long barrierid = -1; + // mapentereffects will give all monster on the new map + // a bunch of turns to simulate time passing while the player + // was away. to prevent them from blocking off the staircase cell + // where the player is about to arrive, place a magic barrier over it. + o = addobfast(newcell->obpile, OT_MAGICBARRIER); + if (o) barrierid = o->id; + + mapentereffects(newcell->map); - // remember current cell + room id - prespeed = getmovespeed(lf); - preroom = lf->cell->room; - v = getcellvault(lf->cell); - if (v && hasflag(v->flags, F_VAULTISSHOP)) { - preshop = getroomid(lf->cell); + // now remove the barrier + o = hasobid(newcell->obpile, barrierid); + if (o) killob(o); + } + + // remember current cell + room id + prespeed = getmovespeed(lf); + preroom = lf->cell->room; + v = getcellvault(lf->cell); + if (v && hasflag(v->flags, F_VAULTISSHOP)) { + preshop = getroomid(lf->cell); + } + // getting out of water? + if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { + prewater = B_TRUE; + } + + if (!isplayer(lf) && cansee(player, lf)) { + preseenbyplayer = B_TRUE; + } + } else { + prespeed = SP_NORMAL; + preroom = NULL; + preshop = B_FALSE; + prewater = B_FALSE; + preseenbyplayer = B_FALSE; } - // getting out of water? - if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { - prewater = B_TRUE; - } - - if (!isplayer(lf) && cansee(player, lf)) { - preseenbyplayer = B_TRUE; - } // move out... lf->cell->lf = NULL; // if required, relink lifeform to new map if (newcell->map != lf->cell->map) { - if (isplayer(lf)) { - statdirty = B_TRUE; + if (gamemode == GM_GAMESTARTED) { + if (isplayer(lf)) { + statdirty = B_TRUE; + } } relinklf(lf, newcell->map); - if (isplayer(lf)) { - // clear map to force redraw. - wclear(gamewin); + if (gamemode == GM_GAMESTARTED) { + if (isplayer(lf)) { + // clear map to force redraw. + wclear(gamewin); + } } } - // remember previous cells - lf->prevcell[1] = lf->prevcell[0]; - lf->prevcell[0] = lf->cell; + if (gamemode == GM_GAMESTARTED) { + // remember previous cells + lf->prevcell[1] = lf->prevcell[0]; + lf->prevcell[0] = lf->cell; + } // update lifeform lf->cell = newcell; @@ -1182,208 +1196,210 @@ int movelf(lifeform_t *lf, cell_t *newcell) { assert(!newcell->lf); // remember new room... - postroom = lf->cell->room; - postspeed = getmovespeed(lf); + if (gamemode == GM_GAMESTARTED) { + postroom = lf->cell->room; + postspeed = getmovespeed(lf); + } // update new cell newcell->lf = lf; - - // update light - if ((isplayer(lf) && changedlev) || lfproduceslight(lf)) { - calclight(lf->cell->map); - } setlosdirty(lf); - //precalclos(lf); - - if (isplayer(lf) || cansee(player, lf)) { - needredraw = B_TRUE; - } - - didmsg = moveeffects(lf); - - killflagsofid(lf->flags, F_HIDING); - - // remove grabs (but not attached things) - // Note: only remove this from the person _being grabbed_. - // if the grabb_er_ moves away, they'll drag the grabee with them. - f = lfhasflag(lf, F_GRABBEDBY); - if (f) { - lifeform_t *grabber; - grabber = findlf(NULL, f->val[0]); - assert(grabber); - if (getcelldist(lf->cell, grabber->cell) > 1) { - killflagsofid(grabber->flags, F_GRABBING); - killflagsofid(lf->flags, F_GRABBEDBY); - } - } - - // passwall ends when you walk onto a non-solid cell. - f = lfhasflag(lf, F_NONCORPOREAL); - if (f && (f->obfrom == OT_S_PASSWALL)) { - enum ERROR err; - cellwalkable(lf, lf->cell, &err); - if (err == E_OK) { - stopspell(lf, OT_S_PASSWALL); - killflag(f); - if (isplayer(lf)) { - didmsg = B_TRUE; - } - } - } - - - if (isplayer(lf)) { - if (prewater && !hasobwithflag(newcell->obpile, F_DEEPWATER)) { - // getitng out of water? - statdirty = B_TRUE; - } - } - - // check ground objects - if (!isairborne(lf)) { - for (o = newcell->obpile->first ; o ; o = nexto ) { - nexto = o->next; - - f = hasflag(o->flags, F_DEEPWATER); - if (f) { - if (checkfordrowning(lf, o)) { - didmsg = B_TRUE; - if (isdead(lf)) return B_TRUE; - } - // did you just enter the water? - if (!prewater) { - if ((getobdepth(o, lf) >= DP_WAIST) && getskill(lf, SK_SWIMMING)) { - if (isplayer(lf)) { - msg("You start swimming."); - didmsg = B_TRUE; - statdirty = B_TRUE; - } else if (cansee(player, lf)) { - msg("%s starts swimming.", lfname); - didmsg = B_TRUE; - } - // put out fires - extinguishlf(lf); - - // stop sprinting - stopsprinting(lf); - - noise(lf->cell, NULL, NC_OTHER, SV_TALK, "a splash.", NULL); - } - } - } - - f = hasflag(o->flags, F_SHARP); - if (f && hasbp(lf, BP_FEET) && !lfhasflag(lf, F_SNEAK)) { - object_t *boots; - // has boots on? - boots = getequippedob(lf->pack, BP_FEET); - if (!boots) { - // take damage - getobname(o, obname, 1); - if (isplayer(lf)) { - msg("Ow - you step on %s!",obname); - didmsg = B_TRUE; - } else if (haslos(player, newcell)) { - msg("%s steps on %s!",lfname, obname); - didmsg = B_TRUE; - } - snprintf(buf, BUFLEN, "stepping on %s", obname); - losehp(lf, rnd(f->val[0],f->val[1]), DT_SLASH, NULL, buf); - } - } - - f = hasflag(o->flags, F_CRUSHABLE); - if (f && !lfhasflag(lf, F_SNEAK)) { - enum LFSIZE crushsize; - crushsize = f->val[0]; - - if (getlfsize(lf) >= crushsize) { - // crunch it broken glass - getobname(o, obname, 1); - - // special case - if (o->type->id == OT_BROKENGLASS) { - if (o->amt > 1) { - char *newname; - // we want 'xx steps on some pieces of broken glass' - // not 'xx steps on 5 pieces of broken glass' - newname = makeplural(obname); - newname = strrep(newname, "a ", "some ", NULL); - strcpy(obname, newname); - free(newname); - } - } - - if (isplayer(lf)) { - msg("You crush %s underfoot.",obname); - didmsg = B_TRUE; - } else if (haslos(player, newcell)) { - msg("%s crushes %s.",lfname, obname); - didmsg = B_TRUE; - } - // kill object which is being crushed. - removeob(o, o->amt); - continue; - } - } // end if crushable - - if ((o->type->id == OT_VINE) && !hasjob(lf, J_DRUID)) { - char obname[BUFLEN]; - getobname(o,obname,o->amt); - if (isplayer(lf)) { - msg("%s grab%s you!",obname,OBS1(o)); - } else if (cansee(player, lf)) { - msg("%s grab%s %s!",obname, OBS1(o), lfname); - } - } - } // end foreach object in cell - } // end if !flying - - // update where player knows - // (but without a map you will then slowly forget it) - if (isplayer(lf)) { - updateknowncells(); - - // TODO: not sure about this next bit yet... - // it definitely won't work for non-square rooms - // or rooms with pillars. would be better to fix - // haslos() code to handle looking along walls - // instead. - // if you walked into a new fully lit room, which - // ISNT a vault, reveal it. - // - - /* - if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) { - if ((postroom > 0) && (postroom != preroom)) { - cell_t *c[MAX_MAPW*MAX_MAPH]; - int ncells; - int i,alllit = B_TRUE,allknown = B_TRUE; - - // is the whole room lit? - getroomcells(lf->cell->map, postroom, c, &ncells); - for (i = 0; i < ncells; i++) { - if (!islit(c[i])) { - alllit = B_FALSE; - } - if (!c[i]->known) { - allknown = B_FALSE; - } - } - - if (alllit && !allknown) { - // make the all known - for (i = 0; i < ncells; i++) { - setcellknown(c[i], B_FALSE); - } - } - - } - } - */ - } if (gamemode == GM_GAMESTARTED) { + // update light + if ((isplayer(lf) && changedlev) || lfproduceslight(lf)) { + calclight(lf->cell->map); + } + //precalclos(lf); + + if (isplayer(lf) || cansee(player, lf)) { + needredraw = B_TRUE; + } + + didmsg = moveeffects(lf); + + killflagsofid(lf->flags, F_HIDING); + + // remove grabs (but not attached things) + // Note: only remove this from the person _being grabbed_. + // if the grabb_er_ moves away, they'll drag the grabee with them. + f = lfhasflag(lf, F_GRABBEDBY); + if (f) { + lifeform_t *grabber; + grabber = findlf(NULL, f->val[0]); + assert(grabber); + if (getcelldist(lf->cell, grabber->cell) > 1) { + killflagsofid(grabber->flags, F_GRABBING); + killflagsofid(lf->flags, F_GRABBEDBY); + } + } + + // passwall ends when you walk onto a non-solid cell. + f = lfhasflag(lf, F_NONCORPOREAL); + if (f && (f->obfrom == OT_S_PASSWALL)) { + enum ERROR err; + cellwalkable(lf, lf->cell, &err); + if (err == E_OK) { + stopspell(lf, OT_S_PASSWALL); + killflag(f); + if (isplayer(lf)) { + didmsg = B_TRUE; + } + } + } + + + if (isplayer(lf)) { + if (prewater && !hasobwithflag(newcell->obpile, F_DEEPWATER)) { + // getitng out of water? + statdirty = B_TRUE; + } + } + + // check ground objects + if (!isairborne(lf)) { + for (o = newcell->obpile->first ; o ; o = nexto ) { + nexto = o->next; + + f = hasflag(o->flags, F_DEEPWATER); + if (f) { + if (checkfordrowning(lf, o)) { + didmsg = B_TRUE; + if (isdead(lf)) return B_TRUE; + } + // did you just enter the water? + if (!prewater) { + if ((getobdepth(o, lf) >= DP_WAIST) && getskill(lf, SK_SWIMMING)) { + if (isplayer(lf)) { + msg("You start swimming."); + didmsg = B_TRUE; + statdirty = B_TRUE; + } else if (cansee(player, lf)) { + msg("%s starts swimming.", lfname); + didmsg = B_TRUE; + } + // put out fires + extinguishlf(lf); + + // stop sprinting + stopsprinting(lf); + + noise(lf->cell, NULL, NC_OTHER, SV_TALK, "a splash.", NULL); + } + } + } + + f = hasflag(o->flags, F_SHARP); + if (f && hasbp(lf, BP_FEET) && !lfhasflag(lf, F_SNEAK)) { + object_t *boots; + // has boots on? + boots = getequippedob(lf->pack, BP_FEET); + if (!boots) { + // take damage + getobname(o, obname, 1); + if (isplayer(lf)) { + msg("Ow - you step on %s!",obname); + didmsg = B_TRUE; + } else if (haslos(player, newcell)) { + msg("%s steps on %s!",lfname, obname); + didmsg = B_TRUE; + } + snprintf(buf, BUFLEN, "stepping on %s", obname); + losehp(lf, rnd(f->val[0],f->val[1]), DT_SLASH, NULL, buf); + } + } + + f = hasflag(o->flags, F_CRUSHABLE); + if (f && !lfhasflag(lf, F_SNEAK)) { + enum LFSIZE crushsize; + crushsize = f->val[0]; + + if (getlfsize(lf) >= crushsize) { + // crunch it broken glass + getobname(o, obname, 1); + + // special case + if (o->type->id == OT_BROKENGLASS) { + if (o->amt > 1) { + char *newname; + // we want 'xx steps on some pieces of broken glass' + // not 'xx steps on 5 pieces of broken glass' + newname = makeplural(obname); + newname = strrep(newname, "a ", "some ", NULL); + strcpy(obname, newname); + free(newname); + } + } + + if (isplayer(lf)) { + msg("You crush %s underfoot.",obname); + didmsg = B_TRUE; + } else if (haslos(player, newcell)) { + msg("%s crushes %s.",lfname, obname); + didmsg = B_TRUE; + } + // kill object which is being crushed. + removeob(o, o->amt); + continue; + } + } // end if crushable + + if ((o->type->id == OT_VINE) && !hasjob(lf, J_DRUID)) { + char obname[BUFLEN]; + getobname(o,obname,o->amt); + if (isplayer(lf)) { + msg("%s grab%s you!",obname,OBS1(o)); + } else if (cansee(player, lf)) { + msg("%s grab%s %s!",obname, OBS1(o), lfname); + } + } + } // end foreach object in cell + } // end if !flying + + // update where player knows + // (but without a map you will then slowly forget it) + if (isplayer(lf)) { + updateknowncells(); + + // TODO: not sure about this next bit yet... + // it definitely won't work for non-square rooms + // or rooms with pillars. would be better to fix + // haslos() code to handle looking along walls + // instead. + // if you walked into a new fully lit room, which + // ISNT a vault, reveal it. + // + + /* + if ((getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) && (!lf->cell->vault)) { + if ((postroom > 0) && (postroom != preroom)) { + cell_t *c[MAX_MAPW*MAX_MAPH]; + int ncells; + int i,alllit = B_TRUE,allknown = B_TRUE; + + // is the whole room lit? + getroomcells(lf->cell->map, postroom, c, &ncells); + for (i = 0; i < ncells; i++) { + if (!islit(c[i])) { + alllit = B_FALSE; + } + if (!c[i]->known) { + allknown = B_FALSE; + } + } + + if (alllit && !allknown) { + // make the all known + for (i = 0; i < ncells; i++) { + setcellknown(c[i], B_FALSE); + } + } + + } + } + */ + } + if (isplayer(lf) && !isblind(lf)) { // see the vault if (!preroom && postroom && postroom->vault) { @@ -1399,7 +1415,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) { for (l = newcell->map->lf ; l ; l = l->next) { if (l != lf) { flag_t *alarm; - //if (haslos(l, newcell)) { if (cansee(l, lf)) { int dointerrupt = B_FALSE; @@ -1412,11 +1427,9 @@ int movelf(lifeform_t *lf, cell_t *newcell) { if (isplayer(l)) { if (areenemies(lf, l) && !isplayer(lf)) { if (!preseenbyplayer) { - //if (lfhasflag(l, F_RUNNING) || lfhasflag(l, F_TRAINING)) { // TODO: also check for isresting(l), if we have allies standing watch getlfnamea(lf, lfname); msg("%s comes into view.", lfname); - //} } dointerrupt = B_TRUE; // mark the observed race as known. @@ -1483,19 +1496,17 @@ int movelf(lifeform_t *lf, cell_t *newcell) { } } } - } - - if (preseenbyplayer && !cansee(player, lf) && !changedlev) { - if (areenemies(player, lf)) { - real_getlfnamea(lf, lfname, B_FALSE); - msg("%s moves out of view.", lfname); + if (preseenbyplayer && !cansee(player, lf) && !changedlev) { + if (areenemies(player, lf)) { + real_getlfnamea(lf, lfname, B_FALSE); + msg("%s moves out of view.", lfname); + } } - } - - // status bar - if ((prespeed != postspeed) && isplayer(lf)) { - statdirty = B_TRUE; - } + // status bar + if ((prespeed != postspeed) && isplayer(lf)) { + statdirty = B_TRUE; + } + } // end if gamestarted return didmsg; } diff --git a/nexus.c b/nexus.c index db6d663..b9c010b 100644 --- a/nexus.c +++ b/nexus.c @@ -462,7 +462,6 @@ int main(int argc, char **argv) { for (x = 0; x < player->cell->map->w; x++) { c = getcellat(player->cell->map, x, y); if (c && (haslos(player, c) || haslof(player->cell, c, LOF_WALLSTOP, NULL))) { - setcellknown(c, slev); if (c->lf && !isplayer(c->lf) && !ispetof(c->lf, player)) { killlf(c->lf); } @@ -480,18 +479,21 @@ int main(int argc, char **argv) { calclight(player->cell->map); // make player face the direction which gives them the most visibility + // as we check, set all cells around us to start off known. if (newworld) { int bestdir = D_NONE; int bestlos = -1; for (i = DC_N; i <= DC_NW; i++) { setfacing(player, i); precalclos(player); + updateknowncells(); if (player->nlos > bestlos) { bestlos = player->nlos; bestdir = i; } } player->facing = bestdir; + precalclos(player); } diff --git a/objects.c b/objects.c index beb2542..6f3c9ca 100644 --- a/objects.c +++ b/objects.c @@ -4511,7 +4511,7 @@ char *getobextrainfo(object_t *o, char *buf) { } else if (ismagical(o) && (getskill(player, SK_CHANNELING) >= PR_MASTER)) { flagknown = B_TRUE; } - if (!hasflag(o->flags, F_DONTSHOWCHARGES)) { + if (flagknown && !hasflag(o->flags, F_DONTSHOWCHARGES)) { char chargestr[BUFLEN]; if (o->type->obclass->id == OC_GODSTONE) { if (f->val[0] == f->val[1]) { diff --git a/shops.c b/shops.c index 684ed96..699d083 100644 --- a/shops.c +++ b/shops.c @@ -763,7 +763,7 @@ enum SHOPRETURN shopresize(lifeform_t *lf, object_t *vm, int starty, char *topte mvwprintw(mainwin, y, 0, "For just $%d per item, we can resize weapons or armour to fit you.", resizecost); y ++; mvwprintw(mainwin, y, 0, "(item quality will not be affected)"); y += 2; if (countmoney(player->pack) < resizecost) { - msg("Sadly, you cannot afford the resizing fee.", resizecost); + mvwprintw(mainwin, y, 0, "Sadly, you cannot afford the resizing fee."); getch(); return SR_BACK; } else { diff --git a/spell.c b/spell.c index 1fe1d68..e595ec7 100644 --- a/spell.c +++ b/spell.c @@ -5772,10 +5772,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // check if it hits if (skillcheck(target, SC_DODGE, 20 + (power*2), 0)) { // miss - msg("A dart of flame misses %s.",lfname); + if (isplayer(target) || cansee(player, target)) { + msg("A dart of flame misses %s.",lfname); + } } else { // hit - if (cansee(player, target)) { + if (isplayer(target) || cansee(player, target)) { msg("A dart of flame hits %s.",lfname); } losehp(target, rnd(1,6) + power, DT_FIRE, caster, "a dart of flame");