From acd641ebc0dd193e3d713a1f6cf0308211e81e26 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Sat, 7 Apr 2012 07:18:56 +0000 Subject: [PATCH] - [+] add territorial to monsters!!! - [+] wolf - [+] hawk - [+] bear - [+] worker ant (but not soldier ant) - [+] player shouldn't know if mosnters are peaceful or not - [+] ie. no warnings when attacking them - [+] no swapping places - [+] don't show "(peaceful)" in io.c askcoords() - [+] need isknownpeaceful() - [+] lv1 negotiation will fix this. maybe rename it though: - [+] psychology - [+] psionic spells: - [+] boost confidence - [+] wild spells: - [+] pyrotechnics - [+] absorb metal should give you hp if you already have ful lmana --- attack.c | 22 +++++++++++++------- data.c | 45 +++++++++++++++++++++++++++-------------- defs.h | 4 +++- io.c | 7 +++++-- lf.c | 9 +++++++++ lf.h | 1 + move.c | 15 +++++++------- objects.c | 3 +-- shops.c | 4 ++-- spell.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 134 insertions(+), 36 deletions(-) diff --git a/attack.c b/attack.c index b63936e..d15118f 100644 --- a/attack.c +++ b/attack.c @@ -195,15 +195,21 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } } - if (!areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT) && cansee(lf, c->lf) - && !lfhasflag(lf, F_RAGE)) { + if (!areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT) && + cansee(lf, c->lf) && + !lfhasflag(lf, F_RAGE) + ) { char ch; char victimname[BUFLEN]; char buf[BUFLEN]; getlfname(c->lf, victimname); + strcpy(buf, ""); switch (getallegiance(c->lf)) { case AL_PEACEFUL: - snprintf(buf, BUFLEN, "Really attack the peaceful %s?",noprefix(victimname)); + if (getlorelevel(lf, getraceclass(c->lf) >= PR_NOVICE) || + getskill(lf, SK_SPEECH)) { // need this to KNOW whether they're peaceful + snprintf(buf, BUFLEN, "Really attack the peaceful %s?",noprefix(victimname)); + } break; case AL_FRIENDLY: snprintf(buf, BUFLEN, "Really attack the allied %s?",noprefix(victimname)); @@ -212,10 +218,12 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { snprintf(buf, BUFLEN, "Really attack the allied %s?",noprefix(victimname)); break; } - ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); - if (ch == 'n') { - // cancel. - return B_TRUE; + if (strlen(buf)) { + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); + if (ch == 'n') { + // cancel. + return B_TRUE; + } } attackedpeaceful = B_TRUE; // non-evil players get no xp for attacking peaceful lfs diff --git a/data.c b/data.c index a8db2b3..dd26faf 100644 --- a/data.c +++ b/data.c @@ -4021,6 +4021,12 @@ void initobjects(void) { // mental/psionic /////////////////// // l1 + addot(OT_S_BOOSTCONFIDENCE, "boost confidence", "Instils the target with infinite courage, allowing them to (perhaps foolishly) continue fighting even when all seems lost.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_ALLY, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); @@ -4438,6 +4444,12 @@ void initobjects(void) { // wild /////////////////// // l1 + addot(OT_S_FIREWORKS, "pyrotechnics", "Launches up to ^power^n bursts of dazzling fireworks around the caster, stunning those who view them.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d4 magical damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); @@ -13108,9 +13120,9 @@ void initrace(void) { addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL); - addrace(R_BEAR, "black bear", 150, 'Q', C_BLUE, MT_FLESH, RC_ANIMAL, "A medium sized omnivore bear."); + addrace(R_BEAR, "black bear", 150, 'Q', C_BLUE, MT_FLESH, RC_ANIMAL, "A medium sized omnivorous bear."); setbodytype(lastrace, BT_QUADRAPED); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); @@ -13206,7 +13218,7 @@ void initrace(void) { addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "Giant ants are enormous (for an ant, anyway), and keen to take avenge their smaller ancestors who were crushed by small children."); setbodytype(lastrace, BT_QUADRAPED); lastrace->baseid = R_ANT; - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 3, NA , NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); @@ -13628,7 +13640,7 @@ void initrace(void) { setbodytype(lastrace, BT_BIRD); lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -13663,6 +13675,7 @@ void initrace(void) { setbodytype(lastrace, BT_BIRD); lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 3, NA , NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -13697,7 +13710,7 @@ void initrace(void) { setbodytype(lastrace, BT_BIRD); lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 5, NA , NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -13727,6 +13740,7 @@ void initrace(void) { addrace(R_HAWKFROST, "frost hawk", 1, 'A', C_CYAN, MT_FLESH, RC_ANIMAL, "A hawk imbued with the power of ice. Frost hawks can release a powerufl blast of freezing air when threatened."); // 'A' for Avian setbodytype(lastrace, BT_BIRD); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 6, NA , NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -14536,7 +14550,7 @@ void initrace(void) { addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Immature wolves."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -14569,7 +14583,7 @@ void initrace(void) { addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Highly intelligent members of the canine family."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_TERRITORIAL, 3, NA , NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -16871,15 +16885,16 @@ void initskills(void) { 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_MASTER, "^gShield accuracy penalties are reduced by 6.^n", B_FALSE); - addskill(SK_SPEECH, "Negotiation", "Your skill at haggling prices, or swaying others through speech.", 50); + addskill(SK_SPEECH, "Psychology", "Your skill at reading others, haggling prices, and negotiation.", 50); addskilldesc(SK_SPEECH, PR_INEPT, "- Each skill level reduces shop prices by 5%.", B_TRUE); - addskilldesc(SK_SPEECH, PR_NOVICE, "^gYou can now question people about nearby traps or monsters.", B_TRUE); - addskilldesc(SK_SPEECH, PR_NOVICE, "^gYou can now offer gems as payment in shops.", B_TRUE); - addskilldesc(SK_SPEECH, PR_BEGINNER, "^gYou can now question people about items on the current level.", B_TRUE); - addskilldesc(SK_SPEECH, PR_ADEPT, "^gYou can now recognise which items others desire.", B_TRUE); - addskilldesc(SK_SPEECH, PR_SKILLED, "^gYou can now trade knowledge and spells with other people.", B_TRUE); - addskilldesc(SK_SPEECH, PR_EXPERT, "^gYou can now persuade people to join to as followers.", B_TRUE); - addskilldesc(SK_SPEECH, PR_MASTER, "^gYou can now choose which skills to learn from people.", B_TRUE); + addskilldesc(SK_SPEECH, PR_NOVICE, "^gYou can determine when others are peaceful.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_NOVICE, "^gYou can now question people about nearby traps or monsters.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_BEGINNER, "^gYou can now offer gems as payment in shops.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_BEGINNER, "^gYou can now question people about items on the current level.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_ADEPT, "^gYou can now recognise which items others desire.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_SKILLED, "^gYou can now trade knowledge and spells with other people.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_EXPERT, "^gYou can now persuade people to join to as followers.^n", B_TRUE); + addskilldesc(SK_SPEECH, PR_MASTER, "^gYou can now choose which skills to learn from people.^n", B_TRUE); addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50); addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE); addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE); diff --git a/defs.h b/defs.h index b26a467..9bfcd36 100644 --- a/defs.h +++ b/defs.h @@ -1650,6 +1650,7 @@ enum OBTYPE { // -- mental / psionic OT_S_ANTICIPATE, OT_S_BAFFLE, + OT_S_BOOSTCONFIDENCE, OT_S_CHARM, OT_S_DISORIENT, OT_S_HUNGER, @@ -1745,8 +1746,9 @@ enum OBTYPE { OT_S_TELEPORT, OT_S_TRAVEL, OT_S_TWIDDLE, - // -- wild + // -- wild magic OT_S_ALARM, + OT_S_FIREWORKS, OT_S_MANASPIKE, OT_S_DETONATE, OT_S_DETONATEDELAY, diff --git a/io.c b/io.c index eba79d9..ac1061a 100644 --- a/io.c +++ b/io.c @@ -759,8 +759,11 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t } break; case AL_PEACEFUL: - if (strlen(extrainfo)) strcat(extrainfo, ", "); - strcat(extrainfo, "peaceful"); + if ((getlorelevel(player, getraceclass(c->lf)) >= PR_NOVICE) || + getskill(player, SK_SPEECH)) { + if (strlen(extrainfo)) strcat(extrainfo, ", "); + strcat(extrainfo, "peaceful"); + } break; case AL_HOSTILE: break; diff --git a/lf.c b/lf.c index 4a670a3..2a3ca64 100644 --- a/lf.c +++ b/lf.c @@ -10062,6 +10062,7 @@ void givebehaviour(lifeform_t *lf, enum BEHAVIOUR bid) { case BH_DRUGGED: killflagsofid(lf->flags, F_FLEEONDAM); killflagsofid(lf->flags, F_FLEEONHPPCT); + killflagsofid(lf->flags, F_FLEEFROM); break; case BH_DRUNK: addflag(lf->flags, F_DRUNK, rnd(2,5), NA, NA, NULL); @@ -13071,6 +13072,14 @@ int ispeaceful(lifeform_t *lf) { } return B_TRUE; } +int isknownpeaceful(lifeform_t *lf) { + if ((getlorelevel(player, getraceclass(lf)) >= PR_NOVICE) || + (getskill(player, SK_SPEECH)) ) { + return B_FALSE; + } + return ispeaceful(lf); +} + int ispetof(lifeform_t *lf, lifeform_t *owner) { if (!lf || !owner) return B_FALSE; diff --git a/lf.h b/lf.h index bceaa86..2a2e9b3 100644 --- a/lf.h +++ b/lf.h @@ -342,6 +342,7 @@ int isspellskill(enum SKILL skid); int ismadeofice(lifeform_t *lf); int ismaxedskill(lifeform_t *lf, enum SKILL skid); int ispeaceful(lifeform_t *lf); +int isknownpeaceful(lifeform_t *lf); int ispetof(lifeform_t *lf, lifeform_t *owner); flag_t *ispetortarget(lifeform_t *lf, lifeform_t *ownertarget); int isplayer(lifeform_t *lf); diff --git a/move.c b/move.c index c5ccf67..a571a25 100644 --- a/move.c +++ b/move.c @@ -118,7 +118,6 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) { if (isplayer(lf2)) { return B_FALSE; } - // mosnters don't swap with people who have F_NOSWAP. if (!isplayer(lf) && lfhasflag(lf2, F_NOSWAP)) { return B_FALSE; @@ -139,10 +138,12 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) { return B_TRUE; } if (isplayer(lf) && !areenemies(lf, lf2)) { - // player can swap with peaceful lgs - // if they are a lot smaller - if (getlfsize(lf) - getlfsize(lf2) >= 2) { - return B_TRUE; + if (isknownpeaceful(lf2)) { + // player can swap with peaceful lgs + // if they are a lot smaller + if (getlfsize(lf) - getlfsize(lf2) >= 2) { + return B_TRUE; + } } } return B_FALSE; @@ -1519,8 +1520,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) { //precalclos(l); } - if (isplayer(l)) { // player saw someone move - if (areenemies(lf, l) && !isplayer(lf)) { + if (isplayer(l) && !isplayer(lf)) { // player saw someone move + if (areenemies(lf, l) || !isknownpeaceful(lf) ) { if (!preseenbyplayer) { // TODO: also check for isresting(l), if we have allies standing watch getlfnamea(lf, lfname); diff --git a/objects.c b/objects.c index 1ffa778..70da048 100644 --- a/objects.c +++ b/objects.c @@ -12335,8 +12335,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) { } adjustdamob(o, &howmuch, damtype); - assert(howmuch < 1000); - + //assert(howmuch < 1000); // effects which have to happen before damage is applied... // explodes? diff --git a/shops.c b/shops.c index a3f6496..41aacfb 100644 --- a/shops.c +++ b/shops.c @@ -90,7 +90,7 @@ float applyshoppricemod(float origprice, lifeform_t *lf, object_t *shop, enum SH int canafford(lifeform_t *lf, int amt) { int goldamt = 0,gemamt = 0; goldamt = countmoney(lf->pack); - if (getskill(lf, SK_SPEECH) >= PR_NOVICE) { + if (getskill(lf, SK_SPEECH) >= PR_BEGINNER) { gemamt = applyshoppricemod(counthighestobflagvalue(lf->pack, F_GEM), lf, NULL, SA_BUY); // adjust using charisma etc } if ((goldamt >= amt ) || (gemamt >= amt) || hasob(lf->pack, OT_CREDITCARD)) { @@ -788,7 +788,7 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top // only list gold if you have enough if (getobvalue(oo) >= value) valid = B_TRUE; strcpy(fullname, moneyname); - } else if ((slev >= PR_NOVICE) && hasflag(oo->flags, F_GEM)) { + } else if ((slev >= PR_BEGINNER) && hasflag(oo->flags, F_GEM)) { // only list gems which are worth enough int thisval; thisval = applyshoppricemod(getobvalue(oo), player, vm, SA_SELL); diff --git a/spell.c b/spell.c index 1463ab3..035ec84 100644 --- a/spell.c +++ b/spell.c @@ -3675,6 +3675,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (totalmass > 0) { float max; + int mptoheal; // heal 1 mp per kilo howmuch = floor(totalmass); @@ -3683,7 +3684,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (howmuch > max) howmuch = max; + mptoheal = getmaxmp(caster) - caster->mp; + gainmp(caster, howmuch); + + // any left? heal hp with half the remaining amt now. + howmuch -= mptoheal; + howmuch /= 2; + if (howmuch > 0) { + gainhp(caster, howmuch); + } } else { fizzle(caster); return B_TRUE; @@ -4283,6 +4293,29 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(caster->flags, F_SLOWMOVE, 5, NA, NA, NULL, FROMSPELL); f->obfrom = spellid; } + } else if (spellid == OT_S_BOOSTCONFIDENCE) { + flag_t *f; + if (!target) { + target = targcell->lf; + } + if (!target) { + fizzle(caster); + return B_TRUE; + } + + if (isplayer(target)){ + msg("You suddenly feel supremely confident!"); + } else if (cansee(player, target)) { + char targname[BUFLEN]; + getlfname(target, targname); + msg("%s looks more confident!", targname); + } + killflagsofid(target->flags, F_FLEEONDAM); + killflagsofid(target->flags, F_FLEEONHPPCT); + killflagsofid(target->flags, F_FLEEFROM); + killflagsofid(target->flags, F_TIMID); + addflag(target->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); + f = lfhasflag(target, F_MORALE); if (f) f->val[0] = 30; } else if (spellid == OT_S_BURNINGFEET) { char killertext[BUFLEN]; if (!target) { @@ -6137,6 +6170,33 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } + } else if (spellid == OT_S_FIREWORKS) { + lifeform_t *poss[MAXCANDIDATES]; + int nposs = 0; + if (isplayer(caster)) { + msg("A burst of fireworks explodes around you!"); + } else if (cansee(player, caster)) { + msg("A burst of fireworks explodes around %s!", castername); + } + for (target = caster->cell->map->lf ; target ; target = target->next) { + if (target == caster) continue; + if (haslos(target, caster->cell)) { + poss[nposs] = target; + nposs++; + if (nposs >= MAXCANDIDATES) break; + } + } + if (nposs) { + int i,n,idx; + for (i = 0; (i < power) && nposs; i++) { + idx = rnd(0,nposs-1); + stun(poss[idx], 2); + for (n = idx; n < nposs-1; n++) { + poss[n] = poss[n+1]; + } + nposs--; + } + } } else if (spellid == OT_S_FLASH) { if (isplayer(caster) || cansee(player, caster)) { if (seenbyplayer) *seenbyplayer = B_TRUE;