- [+] djin and efreeti should hate each other
- [+] 'G' isn't remembering direction anymore - [+] beginner athletics: give skill where misisng in a melee attack doesn't cost stamina - [+] klikirak shoudl like ALL obejct desctruction, but PREFER via fire. - [+] insects shoudl ahve infinite stamina - [+] replace DIECONVERT planks of wood type code - [+] instead, materials have dieconvert values based on damage. - [+] getsmallbreakob(material,damtype) - [+] getlargebreakob(material, damtype) - [+] when an object dies, lookup its material and obejct size - [+] ie. large wooden objects turn into "x planks of wood" - [+] small ones turn into "x shards of wood" - [+] then remove TODO: code from changemat() in objects.c - [+] allow for hardcoded getsmallbrekaob, getbigbreakob - [+] F_BREAKOB, v0=damtype, v1=howmany, text = what - [+] remove specific code, like fire damage = pile of ash. ice+bash = shards, etc. - [+] can use shards/planks of wood as (poor) weapons. - [+] jackhammer shoudl be tech, not tool./ - [+] digging tools should make noise - [+] remove freezing touch spell/scroll - [+] better listen check when asleep - slithering should very rarely wake you up - [+] use adjusted volume value based on sleeping etc. - [+] breaking locks by bashing should now work. - [+] I'm often getting "The hollow tree seems to be blocked." when going to the sylvan woods. - [+] there is a tree in the way! - [+] fixed. - [+] bug: evil players not getting xp for killing helpless. fixed. - [+] bug: pullobto() not doing correct impassable check. - [+] another bug: insylvan woods, stairs were on top of water!!! - [+] ERROR - couldnt find pos for down stairs while making habitat forest.--More-- - [+] repairing should make noise too - [+] new flag - USENOISE - [+] EATCONFER on clove of garlic isn't working - [+] it's because i'm only checking this if we have MUTABLE. - [+] use EATMUTATE instead for mutations. then eatconfer works with everything. - [+] more crush bugs - [+] You crush some pieces of broken glass underfoot. You see 28 pieces of broken glass here. - [+] You crush some pieces of broken glass underfoot. You see 28 pieces of broken glass here. - [+] anything with natural flight sohuld still make noise when flying. otherwise it's too powerful. - [+] "wing flapping" . NV FLY - [+] NOISETEXT NV_FLY - [+] magical flight can still be silent. - [+] make how high you can fly depend on the "Flight" or "Natural Flight" skill. - [+] F_FLYING v0 = height. - [+] without this skill, flight is dependant on spell power. - [+] assign sk_flying to races. - [+] remove F_FLIGHTEVASION from races. skill now does this instead. - [+] validaterace: - [+] canwill ot_a_flight = need flight skill - [+] each rank = +1 size level of height. - [+] if you get the skill while already flying, adjust the flag - [+] fall from flying if burduned. - [+] skill also affacts how much your evasion while flying is boosted. - [+] this extra EV bonus from flight sohuld only work against NON flying creatures! - [+] 5 EV per rank - [+] have a differnet fly ability - [+] ability = flight or fly (use flying skill for height) - [+] implement - [+] replace monster flight with ability. - [+] spell = enchanted flight (use spell power for ehgiht) - [+] check all occurences of FROMSPELL, cope with FROMABIL too. - [+] don't regenerate stamina when doing natural flight. - [+] ai: if flying and no stamina left, stop flying. - [+] ai: only start flying if we have >= 80% stamina. - [+] how did a nutter miss a mammoan from point blank range? - [+] the nutter is throwing a peanut - acc = 64, speed = 2 - [+] maybe fixed now. - [+] felix should like using poison. - [+] when asking whether you accept a god's offer, give a '?' option, to give help on that god. - [+] also have F_GODDECLINE text. - [+] pipes of peace - calms everyone around you. charges.
This commit is contained in:
parent
2867b4488f
commit
e30d5f334f
22
ai.c
22
ai.c
|
@ -1452,9 +1452,11 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
|
|||
// flying monsters not flying?
|
||||
if (!isprone(lf)) {
|
||||
if (hasflag(lf->race->flags, F_NATURALFLIGHT) && !lfhasflag(lf, F_FLYING)) {
|
||||
if (cancast(lf, OT_S_FLIGHT, NULL)) {
|
||||
if (!castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL)) {
|
||||
return B_TRUE;
|
||||
if (cancast(lf, OT_A_FLY, NULL) && !isburdened(lf)) {
|
||||
if (getstaminapct(lf) >= 80) {
|
||||
if (!useability(lf, OT_A_FLY, lf, lf->cell)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1464,6 +1466,14 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
|
|||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// flying and out of stamina?
|
||||
if (isflyingwithwings(lf) && isexhausted(lf)) {
|
||||
// stop flying.
|
||||
if (!useability(lf, OT_A_FLY, lf, lf->cell)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -3099,7 +3109,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if (lfhasflag(lf, F_SPRINTING) || !getstamina(lf) || (getstamina(lf) <= (getmaxstamina(lf)/2))) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if (isairborne(lf)) {
|
||||
if (isairborne(lf, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -3148,13 +3158,13 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
|
||||
if (ot->id == OT_A_TRIPLF) {
|
||||
if (isairborne(victim)) {
|
||||
if (isairborne(victim, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ot->id == OT_A_TUMBLE) || (ot->id == OT_A_JUMP)) {
|
||||
if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) || isairborne(lf)) {
|
||||
if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) || isairborne(lf, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
89
attack.c
89
attack.c
|
@ -33,10 +33,10 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
|||
int damtaken = 0;
|
||||
|
||||
// first of all, only apply some of the damage
|
||||
dam /= 2;
|
||||
if (dam == 0) {
|
||||
return 0;
|
||||
}
|
||||
//dam /= 2;
|
||||
//if (dam == 0) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// special case - missiles always hit flak jacket
|
||||
if (damtype == DT_PROJECTILE) {
|
||||
|
@ -193,6 +193,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
int attackedfriend = B_FALSE;
|
||||
int attackedpeaceful = B_FALSE;
|
||||
enum SKILLLEVEL slev;
|
||||
int dostamloss = B_TRUE;
|
||||
|
||||
// warn if attacking will cause injury
|
||||
if (!force && isplayer(lf) && haslos(lf, c)) {
|
||||
|
@ -256,7 +257,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
}
|
||||
attackedpeaceful = B_TRUE;
|
||||
// non-evil players get no xp for attacking peaceful lfs
|
||||
if ((isplayer(lf) || areallies(player, lf)) && (getalignment(lf) != AL_EVIL)) {
|
||||
if ((isplayer(lf) || areallies(player, lf)) && (getalignment(player) != AL_EVIL)) {
|
||||
killflagsofid(c->lf->flags, F_XPVAL);
|
||||
addflag(c->lf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
real_warnabout(TEXT_WARN_NOXP_GOODVSPEACEFUL, PERMENANT, B_FALSE);
|
||||
|
@ -812,13 +813,21 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
}
|
||||
}
|
||||
|
||||
//if (isplayer(lf)) {
|
||||
dostamloss = B_TRUE; // default
|
||||
|
||||
slev = getskill(lf, SK_COMBAT);
|
||||
if (slev != PR_MASTER) {
|
||||
if (!pctchance(slev * 10)) {
|
||||
// lose a bit of stamina
|
||||
modstamina(lf, -getattackstamloss(lf));
|
||||
}
|
||||
if (slev == PR_MASTER) {
|
||||
dostamloss = B_FALSE;
|
||||
} else if (lfhasflagval(lf, F_LASTATTACKHIT, B_FALSE, NA, NA, NULL) &&
|
||||
(getskill(lf, SK_ATHLETICS) >= PR_BEGINNER)) {
|
||||
// missed, and we have balance via athletics skill
|
||||
dostamloss = B_FALSE;
|
||||
} else if (pctchance(slev * 10)) {
|
||||
dostamloss = B_FALSE;
|
||||
}
|
||||
if (dostamloss) {
|
||||
// lose a bit of stamina
|
||||
modstamina(lf, -getattackstamloss(lf));
|
||||
}
|
||||
//}
|
||||
|
||||
|
@ -1222,6 +1231,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
if (ndam > 0) {
|
||||
flag_t *f;
|
||||
// hit!
|
||||
|
||||
killflagsofid(lf->flags, F_LASTATTACKHIT);
|
||||
addflag(lf->flags, F_LASTATTACKHIT, B_TRUE, NA, NA, NULL);
|
||||
|
||||
for (i = 0; i < ndam; i++) {
|
||||
int damreducedbyarmour = 0;
|
||||
int backstab = B_FALSE;
|
||||
|
@ -1285,8 +1299,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// damaged during the call to criticalhit() later on.
|
||||
if ((dam[i] > 0) && !backstab && !critical && ismeleedam(damtype[i])) {
|
||||
// modify for defender's armour
|
||||
// first figure out how much to reduce the damage by.
|
||||
damreducedbyarmour = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
|
||||
|
||||
// now actually reduce the damage amount
|
||||
applyarmourdamreduction(victim, wep, damreducedbyarmour, &dam[i], damtype[i]);
|
||||
}
|
||||
|
||||
|
@ -1590,21 +1605,19 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
|
||||
wepeffects(wep->flags, victim->cell, damflag, dam[0], isunarmed);
|
||||
}
|
||||
if (isunarmed) {
|
||||
f = lfhasflag(lf, F_FREEZINGTOUCH);
|
||||
if (f) {
|
||||
int diff;
|
||||
diff = f->val[2]*20;
|
||||
if (isimmuneto(victim->flags, DT_COLD, B_FALSE) || skillcheck(victim, SC_RESISTMAG, diff, 0)) {
|
||||
if (isplayer(victim)) {
|
||||
msg("You feel mildly chilly.");
|
||||
}
|
||||
} else {
|
||||
// victim turns to ice for a while!
|
||||
freezelf(victim, lf, f->val[1]);
|
||||
f = lfhasflag(lf, F_FREEZINGTOUCH);
|
||||
if (f) {
|
||||
int diff;
|
||||
diff = f->val[2]*20;
|
||||
if (isimmuneto(victim->flags, DT_COLD, B_FALSE) || skillcheck(victim, SC_RESISTMAG, diff, 0)) {
|
||||
if (isplayer(victim)) {
|
||||
msg("You feel mildly chilly.");
|
||||
}
|
||||
killflag(f);
|
||||
} else {
|
||||
// victim turns to ice for a while!
|
||||
freezelf(victim, lf, f->val[1]);
|
||||
}
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
// critical hit effects
|
||||
|
@ -1696,6 +1709,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
} else { // miss!
|
||||
if (aidb) dblog(".oO { i missed! }");
|
||||
killflagsofid(lf->flags, F_LASTATTACKHIT);
|
||||
addflag(lf->flags, F_LASTATTACKHIT, B_FALSE, NA, NA, NULL);
|
||||
// announce it
|
||||
if (weppassthrough) {
|
||||
if (cansee(player, lf)) {
|
||||
|
@ -1995,13 +2010,14 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
|
||||
// still not dead? more checks
|
||||
if (!isdeadob(o)) {
|
||||
object_t *oo;
|
||||
f = hasflag(o->flags, F_TRAPPED);
|
||||
if (f && pctchance(75)) {
|
||||
doobtraps(o, lf);
|
||||
} else {
|
||||
// if a trap didn't go off, you might break the lock
|
||||
f = hasflag(o->flags, F_LOCKED);
|
||||
if (f && (damtype[i] == DT_BASH)) {
|
||||
if (f && (damtype[0] == DT_BASH)) {
|
||||
int difficulty;
|
||||
int unlockit = B_FALSE;
|
||||
difficulty = f->val[1];
|
||||
|
@ -2022,6 +2038,17 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
}
|
||||
}
|
||||
|
||||
// objects inside might smash
|
||||
for (oo = o->contents->first ;oo ; oo = oo->next) {
|
||||
if (willshatter(oo->material->id) && onein(2)) {
|
||||
if (isplayer(lf)) {
|
||||
// since the sound won't work.
|
||||
msg("You hear shattering glass from inside %s.", obname);
|
||||
}
|
||||
// damstring should never be used...
|
||||
shatter(oo, B_FALSE, "shattering damage", lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -3025,6 +3052,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical,
|
|||
} else {
|
||||
int myroll;
|
||||
int reachpenalty = 0;
|
||||
int vicheight = 0;
|
||||
// actually roll...
|
||||
baseacc = getlfaccuracy(lf, wep);
|
||||
acc = baseacc;
|
||||
|
@ -3079,7 +3107,14 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical,
|
|||
}
|
||||
|
||||
acc -= ev;
|
||||
if (db) dblog("%s: minus victim's evaion (%d) -> %d", lfname, ev, acc);
|
||||
if (db) dblog("%s: minus victim's evasion (%d) -> %d", lfname, ev, acc);
|
||||
|
||||
// modify if victim is flying and we're not
|
||||
if (isairborne(victim,&vicheight)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
acc -= (5 * vicheight);
|
||||
}
|
||||
}
|
||||
|
||||
// modify if we can't see the victim
|
||||
if (!cansee(lf, victim)) {
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
27
defs.h
27
defs.h
|
@ -568,6 +568,7 @@ enum SHOPACTION {
|
|||
#define FROMPOISON (-9862)
|
||||
#define FROMLYCANTHROPY (-9861)
|
||||
#define FROMGAMESTART (-9860)
|
||||
#define FROMABIL (-9859)
|
||||
|
||||
#define IMPOSSIBLE (9999)
|
||||
|
||||
|
@ -746,6 +747,7 @@ enum SKILL {
|
|||
SK_COOKING,
|
||||
SK_EVASION,
|
||||
SK_FIRSTAID,
|
||||
SK_FLIGHT,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_METALWORK,
|
||||
|
@ -795,7 +797,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 56
|
||||
#define MAXSKILLS 57
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -2004,6 +2006,7 @@ enum OBTYPE {
|
|||
OT_A_FEIGNDEATH,
|
||||
OT_A_FLIP,
|
||||
OT_A_FLURRY,
|
||||
OT_A_FLY,
|
||||
OT_A_FULLSHIELD,
|
||||
OT_A_GRAB,
|
||||
OT_A_CHARGE,
|
||||
|
@ -2081,6 +2084,7 @@ enum OBTYPE {
|
|||
OT_LANTERNOIL,
|
||||
OT_LOCKPICK,
|
||||
OT_PANPIPES,
|
||||
OT_PEACEPIPES,
|
||||
OT_PICKAXE,
|
||||
OT_ROPE,
|
||||
OT_SACK,
|
||||
|
@ -2182,6 +2186,7 @@ enum OBTYPE {
|
|||
OT_FLESHCHUNK,
|
||||
OT_TUSK,
|
||||
OT_WOODPLANK,
|
||||
OT_WOODSHARD,
|
||||
OT_METALSHEET,
|
||||
// trail objects
|
||||
OT_FOOTPRINT,
|
||||
|
@ -2787,6 +2792,10 @@ enum FLAG {
|
|||
// v0 = radius to scatter new object in
|
||||
// (0 or NA means just convert the object)
|
||||
// v1 = dirtype for radius
|
||||
F_BREAKOB, // if killed by damtype v0, change to
|
||||
// object 'text'.
|
||||
// IMPORTANT: can only have up to 2 of these per
|
||||
// damage type.
|
||||
F_NOBLESS, // can't be blessed or cursed
|
||||
F_NOQUALITY, // can't be masterwork / shoddy
|
||||
F_NOSTEAL, // this object can't be stolen, blown away, etc.
|
||||
|
@ -2883,6 +2892,7 @@ enum FLAG {
|
|||
F_CHARGEOUTMSG, // text = msg when charges are gone
|
||||
F_HELPSCLIMB, // object gives v0 bonus to sc_climb checks.
|
||||
F_HELPSDIG, // object can dig. does v0 dam to cells.
|
||||
// also makes noise 'text' at volume v1
|
||||
F_HELPSDISARM, // object gives v0 bonus to disarm trap checks.
|
||||
F_HELPSREPAIR, // object gives v1 bonus to repairing obejcts
|
||||
// made of material v0. Also decreases the
|
||||
|
@ -2918,6 +2928,8 @@ enum FLAG {
|
|||
F_DRINKABLE, // you can drink this. val1 = nutrition. 100 = a meal
|
||||
// -1 means "nutrition is weight x abs(val1)"
|
||||
// if v2=DONTKILL, this object does NOT die when drunk.
|
||||
F_OPERSOUND, // v0 = volume of sound when operating this
|
||||
// text = noise
|
||||
F_OPERABLE, // can operate?
|
||||
F_OPERWITHOUTHANDS, // can operate without having hands or being
|
||||
// humanoid
|
||||
|
@ -3230,6 +3242,8 @@ enum FLAG {
|
|||
// with vals v1,v2,text.
|
||||
// OR
|
||||
// eating this object gives it.
|
||||
F_EATMUTATE, // same as eatconfer, but only works if you have
|
||||
// f_mutable.
|
||||
// player only flags
|
||||
F_AICONTROLLED, // player will be controlled by the computer
|
||||
F_DONEBURNMSG, // tells the game not to say 'the {celltype} burns!'
|
||||
|
@ -3282,6 +3296,7 @@ enum FLAG {
|
|||
// power. if not given, power comes from depth.
|
||||
F_NOSMELL, // lf can't smell. not affected by stench, and
|
||||
// can't get enhancesmell.
|
||||
F_NOSTAM, // this lf has infinite stamina
|
||||
F_NOTALK, // override ability to talk
|
||||
F_NOGIVECRITS, // monsters can't take critical hits
|
||||
F_NOTAKECRITS, // monsters can't take critical hits
|
||||
|
@ -3290,7 +3305,6 @@ enum FLAG {
|
|||
// v0 = max time allowed to rest before checkout
|
||||
// v1 = total time rested
|
||||
// text = obid of hotel
|
||||
F_FLIGHTEVASION,// +v0 evasion if flying
|
||||
F_SWIMEVASION, // +v0 evasion if swimming
|
||||
F_ALIGNMENT, // v0 = al_good, al_neutral, al_evil. default neutral.
|
||||
// if al_none is selected for the player, they
|
||||
|
@ -3537,6 +3551,10 @@ enum FLAG {
|
|||
// eg: text=="st" means they know of shops+traps
|
||||
F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc
|
||||
F_LASTDIR, // this is the last direction we moved.
|
||||
F_LASTATTACKHIT, // did our last attack hit or miss?
|
||||
// v0 = B_TRUE = hit
|
||||
// v0 = B_FALSE = miss
|
||||
|
||||
//F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
|
||||
// when we could see them.
|
||||
F_ISPRISONER, // this lf wants to escape to the surface
|
||||
|
@ -3677,6 +3695,7 @@ enum FLAG {
|
|||
F_GODGIFTTEXT, // text = what the god says when you get a gift
|
||||
F_GODASK1, // text = how the god asks you to join them
|
||||
F_GODASK2, // text = how the god asks you to join them (2nd line)
|
||||
F_GODDECLINE, // text = what the god says if you decline offer to join
|
||||
F_GODTEXTAPPEAR, // text = godname ->xxxxx<- (when they teleport in)
|
||||
F_GODOF, // text = what this lf is the god of. use capitals.
|
||||
F_GODLIKES, // text = something this god likes (ie. incs piety)
|
||||
|
@ -3876,7 +3895,7 @@ enum FLAG {
|
|||
// lower chance of rare monsters
|
||||
F_EXTRAMP, // lf has +v0 % extra maxmp
|
||||
F_FEIGNINGDEATH, // lf is pretending to be dead
|
||||
F_FLYING, // lf is flying
|
||||
F_FLYING, // lf is flying. v0 = feet height
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMETAB, // hunger counter increases faster, poison cures faster.
|
||||
// v0 is multiplier.
|
||||
|
@ -4016,6 +4035,7 @@ enum FLAG {
|
|||
F_EATING, // lf is eating obid v0
|
||||
F_DIGGING, // v0/v1 = cell where lf is digging.
|
||||
// v2 is how much to dig per turn.
|
||||
// text = obid of tool we are using to dig.
|
||||
F_REPAIRING, // text = obid of held item we are repairing.
|
||||
F_TRAINING, // are we training? cleared on any action other than rest.
|
||||
// v0 = current training amount
|
||||
|
@ -4556,6 +4576,7 @@ typedef struct habitat_s {
|
|||
int randvaultpct; // % chance that a room will be a vault
|
||||
//int maxvisrange;
|
||||
enum OBTYPE upstairtype, downstairtype;
|
||||
int stairsinrooms;
|
||||
enum CELLTYPE emptycelltype,solidcelltype;
|
||||
struct habitat_s *next, *prev;
|
||||
} habitat_t;
|
||||
|
|
31
god.c
31
god.c
|
@ -536,17 +536,24 @@ void askforworship(enum RACE rid) {
|
|||
say(god, getflagtext(god->flags, F_GODASK1), SV_TALK); more();
|
||||
msg("\"%s\"", getflagtext(god->flags, F_GODASK2)); more();
|
||||
|
||||
yn = askchar("Will you accept", "yn", "n", B_TRUE, B_FALSE);
|
||||
if (yn == 'y') {
|
||||
// should never be true, but check just in case...
|
||||
if (!godprayedto(rid)) {
|
||||
addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL);
|
||||
yn = '?';
|
||||
while (yn == '?') {
|
||||
yn = askchar("Will you accept", "yn?", "n", B_TRUE, B_FALSE);
|
||||
if (yn == '?') {
|
||||
describegod(god);
|
||||
} else if (yn == 'y') {
|
||||
// should never be true, but check just in case...
|
||||
if (!godprayedto(rid)) {
|
||||
addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
// always get a gift, but announce it first.
|
||||
say(god, getflagtext(god->flags, F_GODGIFTTEXT), SV_TALK); more();
|
||||
godgiftmaybe(rid, B_TRUE, B_FALSE);
|
||||
// increment piety so that it doesn't remain around the border.
|
||||
modpiety(rid, PIETYPRAYLOSS);
|
||||
} else { // ie. no
|
||||
msg("\"%s\"", getflagtext(god->flags, F_GODDECLINE)); more();
|
||||
}
|
||||
// always get a gift, but announce it first.
|
||||
say(god, getflagtext(god->flags, F_GODGIFTTEXT), SV_TALK); more();
|
||||
godgiftmaybe(rid, B_TRUE, B_FALSE);
|
||||
// increment piety so that it doesn't remain around the border.
|
||||
modpiety(rid, PIETYPRAYLOSS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1550,10 +1557,12 @@ int godgiftmaybe(enum RACE rid, int fromtemple, int announce) {
|
|||
wep = getweapon(player);
|
||||
if (wep && !hasflag(wep->flags, F_HASBRAND)) {
|
||||
char obname[BUFLEN];
|
||||
flag_t *f;
|
||||
getobname(wep,obname,1);
|
||||
// announce
|
||||
msg("Your %s vibrates, and you suddenly thirst for vengeance!", noprefix(obname));
|
||||
addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL);
|
||||
f = addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL);
|
||||
f->known = B_TRUE;
|
||||
} else {
|
||||
switch (rnd(1,7)) {
|
||||
case 1:
|
||||
|
|
31
io.c
31
io.c
|
@ -742,6 +742,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
object_t *wep,*o;
|
||||
char extrainfo[BIGBUFLEN];
|
||||
enum SKILLLEVEL lorelev;
|
||||
int height = 0;
|
||||
lorelev = getlorelevel(player, c->lf->race->raceclass->id);
|
||||
strcpy(extrainfo, "");
|
||||
getlfnamea(c->lf, buf);
|
||||
|
@ -819,10 +820,12 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
// prevent showing 'prone' and 'asleep'
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "prone");
|
||||
} else if (isairborne(c->lf)) {
|
||||
} else if (isairborne(c->lf, &height)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
if (lfhasflag(c->lf, F_FLYING)) {
|
||||
strcat(extrainfo, "flying");
|
||||
char fbuf[BUFLEN];
|
||||
sprintf(fbuf, "flying:%d",height);
|
||||
strcat(extrainfo, fbuf);
|
||||
} else if (lfhasflag(c->lf, F_LEVITATING)) {
|
||||
strcat(extrainfo, "levitating");
|
||||
} else {
|
||||
|
@ -1693,6 +1696,14 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_FREEZINGTOUCH:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("Your hands begin to glow blue!");
|
||||
} else {
|
||||
msg("%s%s hands begin to glow blue!", lfname, getpossessive(lfname));
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FULLSHIELD:
|
||||
o = hasobid(lf->pack, atol(f->text));
|
||||
assert(o);
|
||||
|
@ -2539,6 +2550,14 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FREEZINGTOUCH:
|
||||
if (isplayer(lf)) {
|
||||
msg("Your hands are no longer glowing blue.");
|
||||
} else {
|
||||
msg("%s%s hands are no longer glowing blue.", lfname, getpossessive(lfname));
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FULLSHIELD:
|
||||
msg("%s %s no longer fully shielded.", lfname, isplayer(lf) ? "are" : "is");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -3292,7 +3311,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
|
|||
long points;
|
||||
points = getobpoints(mylist[i]);
|
||||
if (points > 0) {
|
||||
snprintf(pointsbuf, BUFLEN, " [%ld points]", points);
|
||||
snprintf(pointsbuf, BUFLEN, " [%ld point%s]", points, (points == 1) ? "" : "s");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7725,7 +7744,6 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
break;
|
||||
case F_ENHANCESMELL: if (lorelev >= PR_BEGINNER) sprintf(buf, "Enhanced sense of smell (range %d)", f->val[0]); break;
|
||||
case F_FEARLESS: if (lorelev >= PR_BEGINNER) sprintf(buf, "Fearless"); break;
|
||||
case F_FLIGHTEVASION: if (lorelev >= PR_BEGINNER) sprintf(buf, "%d%% evasion while flying", f->val[0]); break;
|
||||
case F_FLYING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can fly at will"); break;
|
||||
case F_HEAVYBLOW: if (lorelev >= PR_ADEPT) sprintf(buf, "Attacks will knock enemies backwards"); break;
|
||||
case F_HITCONFER:
|
||||
|
@ -11071,6 +11089,7 @@ void drawstatus(void) {
|
|||
enum ATTRIB a;
|
||||
int myatt[MAXATTS];
|
||||
int xpleft;
|
||||
int height;
|
||||
|
||||
curs_set(0);
|
||||
wclear(statwin);
|
||||
|
@ -11213,10 +11232,10 @@ void drawstatus(void) {
|
|||
unsetcol(statwin, C_BOLDBLUE);
|
||||
}
|
||||
|
||||
if (isairborne(player)) {
|
||||
if (isairborne(player, &height)) {
|
||||
if (lfhasflag(player, F_FLYING)) {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
wprintw(statwin, " Fly");
|
||||
wprintw(statwin, " Fly:%d",height);
|
||||
unsetcol(statwin, C_BOLDBLUE);
|
||||
} else if (lfhasflag(player, F_LEVITATING)) {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
|
|
388
lf.c
388
lf.c
|
@ -660,6 +660,7 @@ int canbuild(lifeform_t *lf, objecttype_t *ot, char *needtext, enum OBTYPE *need
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// can lf cast spell/use ability 'oid'
|
||||
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||
int castable = B_FALSE;
|
||||
flag_t *f;
|
||||
|
@ -1236,8 +1237,8 @@ int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty) {
|
|||
|
||||
// harder to hit flying/levitating enemies, or ones climbing
|
||||
// (ie they are higher than you)
|
||||
lffootheight = getlfheight(lf);
|
||||
victimfootheight = getlfheight(victim);
|
||||
lffootheight = getfeetheight(lf);
|
||||
victimfootheight = getfeetheight(victim);
|
||||
|
||||
diff = victimfootheight - (getlfsize(lf) + lffootheight);
|
||||
|
||||
|
@ -1298,7 +1299,7 @@ int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) {
|
|||
|
||||
// your reach is defined as anywhere between your feet and just over your
|
||||
// head. flying creatures have more leeway.
|
||||
if (isairborne(lf)) {
|
||||
if (isairborne(lf, NULL)) {
|
||||
topthresh = 3;
|
||||
bottomthresh = 2;
|
||||
} else {
|
||||
|
@ -1343,7 +1344,7 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) {
|
|||
}
|
||||
dist = getcelldist(viewer->cell, viewee->cell);
|
||||
f = lfhasflag(viewer, F_TREMORSENSE);
|
||||
if (f && !isairborne(viewee) && !isairborne(viewer)) {
|
||||
if (f && !isairborne(viewee, NULL) && !isairborne(viewer, NULL)) {
|
||||
if (f->val[0] > 0) {
|
||||
tremordist = f->val[0];
|
||||
} else {
|
||||
|
@ -1441,7 +1442,7 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) {
|
|||
}
|
||||
// viewee underwater and more than 1 cell away?
|
||||
if ((getobdepth(o, viewee) >= DP_HEAD) && (dist > 1)) {
|
||||
if (!isairborne(viewee)) {
|
||||
if (!isairborne(viewee, NULL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2071,7 +2072,8 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
if (targlf && (f->val[2] == B_APPENDYOU)) {
|
||||
char targname[BUFLEN];
|
||||
if (targlf == lf) {
|
||||
strcpy(targname, "itself");
|
||||
strcpy(targname, it(lf));
|
||||
strcat(targname, "self");
|
||||
} else {
|
||||
getlfname(targlf, targname);
|
||||
}
|
||||
|
@ -2506,7 +2508,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
flag_t *f;
|
||||
enum SKILLLEVEL slev;
|
||||
|
||||
if (isairborne(lf)) {
|
||||
if (isairborne(lf, NULL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2725,6 +2727,7 @@ void copycorpseflags(flagpile_t *dst, flagpile_t *src) {
|
|||
int continuedigging(lifeform_t *lf) {
|
||||
cell_t *c;
|
||||
flag_t *f = NULL;
|
||||
object_t *digob = NULL;
|
||||
int digpower;
|
||||
int stopnow = B_FALSE;
|
||||
|
||||
|
@ -2736,6 +2739,18 @@ int continuedigging(lifeform_t *lf) {
|
|||
if (!f) {
|
||||
stopnow = B_TRUE;
|
||||
}
|
||||
|
||||
if (!stopnow && strlen(f->text)) {
|
||||
long obid;
|
||||
// do we still ahve the object we were using to dig?
|
||||
obid = atol(f->text);
|
||||
|
||||
digob = hasobid(lf->pack, obid);
|
||||
if (!digob) {
|
||||
stopnow = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stopnow) {
|
||||
c = getcellat(lf->cell->map, f->val[0], f->val[1]);
|
||||
if (!c) {
|
||||
|
@ -2748,6 +2763,8 @@ int continuedigging(lifeform_t *lf) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (digob) makeopersound(lf->cell,digob);
|
||||
|
||||
digpower = f->val[2];
|
||||
c->hp -= digpower;
|
||||
if (c->hp <= 0) {
|
||||
|
@ -2867,6 +2884,8 @@ int continuerepairing(lifeform_t *lf, flag_t *repairflag) {
|
|||
}
|
||||
|
||||
|
||||
if (helpob) makeopersound(lf->cell,helpob);
|
||||
|
||||
// take some time.
|
||||
taketime(lf, getactspeed(lf));
|
||||
|
||||
|
@ -4353,8 +4372,16 @@ int digcell(lifeform_t *lf, cell_t *c, object_t *o) {
|
|||
if (c->type->solid) {
|
||||
turntoface(lf, c);
|
||||
if (isdiggable(c)) {
|
||||
char digoid[BUFLEN];
|
||||
// start digging!
|
||||
addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, NULL);
|
||||
if (o) {
|
||||
sprintf(digoid, "%ld",o->id);
|
||||
} else {
|
||||
strcpy(digoid,"");
|
||||
}
|
||||
|
||||
addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, digoid);
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You start digging into %s %s.", needan(c->type->name) ? "an" : "a", c->type->name);
|
||||
needredraw = B_TRUE;
|
||||
|
@ -4491,7 +4518,7 @@ int digup(lifeform_t *lf, object_t *o) {
|
|||
|
||||
// if digging with an object, you must be able to reach the roof
|
||||
if (o) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
|
@ -4984,6 +5011,9 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
if (fullyeaten) {
|
||||
// special cases
|
||||
if (!hasflag(o->flags, F_TAINTED)) {
|
||||
flag_t *mutable = NULL;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
if (hasflagval(o->flags, F_CORPSEOF, R_NEWT, NA, NA, NULL)) {
|
||||
// think "eye of newt"
|
||||
gainmp(lf, 2);
|
||||
|
@ -5005,65 +5035,63 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
// most eat effects only happen if you have f_MUTABLE.
|
||||
if (lfhasflag(lf, F_MUTABLE)) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
getflags(o->flags, retflag, &nretflags, F_EATCONFER, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->val[0] != F_MUTABLE) {
|
||||
int chance;
|
||||
int luckmod = 0;
|
||||
chance = atoi(f->text);
|
||||
sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL);
|
||||
chance += (luckmod*5);
|
||||
limit(&chance, 0, 100);
|
||||
if (pctchance(chance)) {
|
||||
enum FLAG fid;
|
||||
int val[2];
|
||||
fid = f->val[0];
|
||||
val[0] = f->val[1];
|
||||
val[1] = f->val[2];
|
||||
// already got this?
|
||||
mutable = lfhasflag(lf, F_MUTABLE);
|
||||
|
||||
getflags(o->flags, retflag, &nretflags, F_EATCONFER, F_EATMUTATE, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
int chance;
|
||||
int luckmod = 0;
|
||||
f = retflag[i];
|
||||
if ((f->id == F_EATMUTATE) && !mutable) continue;
|
||||
|
||||
chance = atoi(f->text);
|
||||
sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL);
|
||||
chance += (luckmod*5);
|
||||
limit(&chance, 0, 100);
|
||||
if (pctchance(chance)) {
|
||||
enum FLAG fid;
|
||||
int val[2];
|
||||
fid = f->val[0];
|
||||
val[0] = f->val[1];
|
||||
val[1] = f->val[2];
|
||||
// already got this?
|
||||
if (lfhasflag(lf, fid)) {
|
||||
int changed = B_FALSE;
|
||||
// sometimes improve it
|
||||
switch (fid) {
|
||||
case F_DTRESIST: fid = F_DTIMMUNE; changed = B_TRUE; break;
|
||||
case F_SEEINDARK:
|
||||
case F_PRODUCESLIGHT:
|
||||
break; // can have multiple.
|
||||
default: fid = F_NONE; break;
|
||||
}
|
||||
// still got the new one?
|
||||
if (changed && (fid != F_NONE)) {
|
||||
if (lfhasflag(lf, fid)) {
|
||||
int changed = B_FALSE;
|
||||
// sometimes improve it
|
||||
switch (fid) {
|
||||
case F_DTRESIST: fid = F_DTIMMUNE; changed = B_TRUE; break;
|
||||
case F_SEEINDARK:
|
||||
case F_PRODUCESLIGHT:
|
||||
break; // can have multiple.
|
||||
default: fid = F_NONE; break;
|
||||
}
|
||||
// still got the new one?
|
||||
if (changed && (fid != F_NONE)) {
|
||||
if (lfhasflag(lf, fid)) {
|
||||
fid = F_NONE;
|
||||
}
|
||||
}
|
||||
fid = F_NONE;
|
||||
}
|
||||
if (fid != F_NONE) {
|
||||
// lose half your max hp!
|
||||
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL,
|
||||
"the shock of mutation",
|
||||
B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS,
|
||||
BP_NONE);
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou convulse in agony as your body mutates!",
|
||||
getlfcol(lf, CC_BAD));
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("^%c%s convulses in agony as its body mutates!",
|
||||
getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
// still alive? you gain the ability!
|
||||
if (!isdead(lf)) {
|
||||
addflag(lf->flags, fid, val[0], val[1], NA, NULL);
|
||||
}
|
||||
}
|
||||
} // end if pctchance
|
||||
} // end if v0 not f_mutable
|
||||
} // end foreach f_eatconfer flag
|
||||
} // end if lf has f_mutable
|
||||
}
|
||||
}
|
||||
if (fid != F_NONE) {
|
||||
// lose half your max hp!
|
||||
losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL,
|
||||
"the shock of mutation",
|
||||
B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS,
|
||||
BP_NONE);
|
||||
if (isplayer(lf)) {
|
||||
msg("^%cYou convulse in agony as your body mutates!",
|
||||
getlfcol(lf, CC_BAD));
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("^%c%s convulses in agony as its body mutates!",
|
||||
getlfcol(lf, CC_BAD), lfname);
|
||||
}
|
||||
// still alive? you gain the ability!
|
||||
if (!isdead(lf)) {
|
||||
addflag(lf->flags, fid, val[0], val[1], NA, NULL);
|
||||
}
|
||||
}
|
||||
} // end if pctchance
|
||||
} // end foreach f_eatconfer flag
|
||||
} // end if !tainted
|
||||
|
||||
// special cases for object types
|
||||
|
@ -5903,7 +5931,7 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) {
|
|||
|
||||
if (isdead(lf)) return B_TRUE;
|
||||
if (isprone(lf)) return B_TRUE;
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
if ((lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET))) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -7833,10 +7861,10 @@ int getevasion(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// flightevasion creatures get extra evasion while flying
|
||||
f = lfhasflag(lf, F_FLIGHTEVASION);
|
||||
if (f && (isairborne(lf) == F_FLYING)) {
|
||||
ev += f->val[0];
|
||||
}
|
||||
//f = lfhasflag(lf, F_FLIGHTEVASION);
|
||||
//if (f && (isairborne(lf) == F_FLYING)) {
|
||||
// ev += f->val[0];
|
||||
// }
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// now negative modifiers
|
||||
|
@ -8677,32 +8705,27 @@ enum LFCONDITION getlfcondition(lifeform_t *lf) {
|
|||
|
||||
// returns a value representing 'lf's height off the ground.
|
||||
// higher value means higher
|
||||
int getlfheight(lifeform_t *lf) {
|
||||
int getfeetheight(lifeform_t *lf) {
|
||||
int height = 0;
|
||||
switch (isairborne(lf)) {
|
||||
case F_FLYING:
|
||||
height += SZ_HUMAN;
|
||||
break;
|
||||
case F_LEVITATING:
|
||||
height += SZ_MEDIUM;
|
||||
break;
|
||||
default:
|
||||
// climbing a wall?
|
||||
if (isclimbing(lf)) {
|
||||
if (height < SZ_LARGE) height = SZ_LARGE;
|
||||
} else {
|
||||
object_t *o;
|
||||
// is lf climbing on top of something, or on a wall?
|
||||
o = hasobwithflag(lf->cell->obpile, F_CLIMBOBSTACLE);
|
||||
if (o) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_IMPASSABLE);
|
||||
if (f && (f->val[0] > 0)) {
|
||||
height += f->val[0];
|
||||
}
|
||||
int temph;
|
||||
if (isairborne(lf, &temph)) {
|
||||
height += temph;
|
||||
} else {
|
||||
// climbing a wall?
|
||||
if (isclimbing(lf)) {
|
||||
if (height < SZ_LARGE) height = SZ_LARGE;
|
||||
} else {
|
||||
object_t *o;
|
||||
// is lf climbing on top of something, or on a wall?
|
||||
o = hasobwithflag(lf->cell->obpile, F_CLIMBOBSTACLE);
|
||||
if (o) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_IMPASSABLE);
|
||||
if (f && (f->val[0] > 0)) {
|
||||
height += f->val[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
@ -8728,16 +8751,6 @@ int getlistendetectrange(lifeform_t *lf) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getfeetheight(lifeform_t *lf) {
|
||||
int howmuch = 0;
|
||||
switch (isairborne(lf)) {
|
||||
case F_FLYING: howmuch = SZ_HUMAN; break;
|
||||
case F_LEVITATING: howmuch = SZ_SMALL; break;
|
||||
default: break;
|
||||
}
|
||||
return howmuch;
|
||||
}
|
||||
|
||||
int getmasterid(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
f = lfhasflag(lf, F_PETOF);
|
||||
|
@ -8813,6 +8826,19 @@ int getmorale(lifeform_t *lf) {
|
|||
return gettr(lf);
|
||||
}
|
||||
|
||||
int getnaturalflightheight(lifeform_t *lf) {
|
||||
switch (getskill(lf, SK_FLIGHT)) {
|
||||
case PR_NOVICE: return SZ_SMALL;
|
||||
case PR_BEGINNER: return SZ_MEDIUM;
|
||||
case PR_ADEPT: return SZ_HUMAN;
|
||||
case PR_SKILLED: return SZ_LARGE;
|
||||
case PR_EXPERT: return SZ_HUGE;
|
||||
case PR_MASTER: return SZ_ENORMOUS;
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getnextshortcut(lifeform_t *lf) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i,min = 0;
|
||||
|
@ -9523,7 +9549,7 @@ int getmovespeed(lifeform_t *lf) {
|
|||
} else if (f->id == F_HIDING) {
|
||||
speed += 10;
|
||||
} else if (f->id == F_INJURY) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
switch (f->val[0]) {
|
||||
case IJ_LEGBROKEN:
|
||||
case IJ_HAMSTRUNG:
|
||||
|
@ -9533,7 +9559,7 @@ int getmovespeed(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
} else if (f->id == F_SPRINTING) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
speed -= 10;
|
||||
}
|
||||
}
|
||||
|
@ -10103,11 +10129,21 @@ int getstamina(lifeform_t *lf) {
|
|||
return (int)floor(lf->stamina);
|
||||
}
|
||||
|
||||
int getstaminapct(lifeform_t *lf) {
|
||||
float max;
|
||||
max = getmaxstamina(lf);
|
||||
if ((max == 0) || lfhasflag(lf, F_NOSTAM)) return 100;
|
||||
return ((float)lf->stamina / max) * 100.0;
|
||||
}
|
||||
|
||||
float getstamregen(lifeform_t *lf) {
|
||||
float regenrate = STAMREGEN;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
|
||||
// flying with wings?
|
||||
if (isflyingwithwings(lf)) return 0;
|
||||
|
||||
if (lfhasflag(lf, F_TRAINING)) {
|
||||
// don't regain stamina while training!
|
||||
return 0;
|
||||
|
@ -10122,9 +10158,11 @@ float getstamregen(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
getflags(lf->flags, retflag, &nretflags, F_STAMREGEN, F_NONE);
|
||||
getflags(lf->flags, retflag, &nretflags, F_STAMREGEN, F_FLYING, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
regenrate += atof(retflag[i]->text);
|
||||
if (retflag[i]->id == F_STAMREGEN) {
|
||||
regenrate += atof(retflag[i]->text);
|
||||
}
|
||||
}
|
||||
limitf(®enrate, 0, NA);
|
||||
|
||||
|
@ -11823,6 +11861,17 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
}
|
||||
}
|
||||
|
||||
if (id == SK_FLIGHT) {
|
||||
flag_t *f;
|
||||
int h;
|
||||
// adjust flight height if we're already flying.
|
||||
h = getnaturalflightheight(lf);
|
||||
f = lfhasflag(lf, F_FLYING);
|
||||
if (f && (f->val[0] < h)) {
|
||||
f->val[0] = h;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == SK_ARMOUR) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (isplayer(lf)) pleasegodmaybe(R_GODBATTLE, 5);
|
||||
|
@ -13784,13 +13833,23 @@ int haslos_fast(lifeform_t *viewer, cell_t *dest) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
enum FLAG isairborne(lifeform_t *lf) {
|
||||
enum FLAG isairborne(lifeform_t *lf, int *height) {
|
||||
flag_t *f;
|
||||
|
||||
if (height) *height = 0;
|
||||
|
||||
if (!lf) return B_FALSE;
|
||||
if (lfhasflag(lf, F_FLYING)) {
|
||||
f = lfhasflag(lf, F_FLYING);
|
||||
if (f) {
|
||||
if (height) *height = f->val[0];
|
||||
return F_FLYING;
|
||||
} else if (lfhasflag(lf, F_LEVITATING)) {
|
||||
}
|
||||
if (lfhasflag(lf, F_LEVITATING)) {
|
||||
if (height) *height = SZ_MEDIUM;
|
||||
return F_LEVITATING;
|
||||
} else if (lfhasflag(lf, F_ICESLIDE)) {
|
||||
}
|
||||
if (lfhasflag(lf, F_ICESLIDE)) {
|
||||
if (height) *height = SZ_MEDIUM;
|
||||
return F_LEVITATING;
|
||||
}
|
||||
return F_NONE;
|
||||
|
@ -14037,6 +14096,18 @@ flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom) {
|
|||
return lfhasflagval(lf, F_FLEEFROM, runfrom->id, NA, NA, NULL);
|
||||
}
|
||||
|
||||
int isflyingwithwings(lifeform_t *lf) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
getflags(lf->flags, retflag, &nretflags, F_FLYING, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->lifetime == FROMABIL) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp) {
|
||||
if (hasobwithflagval(lf->pack, F_EQUIPPED, bp, NA, NA, NULL)) return B_FALSE;
|
||||
|
||||
|
@ -14882,7 +14953,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
|
||||
// footprints first
|
||||
if (doprints) {
|
||||
if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) {
|
||||
if (!isairborne(lf, NULL) && !lfhasflag(lf, F_NONCORPOREAL)) {
|
||||
int fpdir;
|
||||
if (getskill(lf, SK_PERCEPTION) >= PR_EXPERT) {
|
||||
// no footprints!
|
||||
|
@ -14926,7 +14997,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
void adjustspeedforwater(lifeform_t *lf, int *speed) {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
for (o = lf->cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f) {
|
||||
|
@ -15862,7 +15933,7 @@ int isswimming(lifeform_t *lf) {
|
|||
if (gamemode != GM_GAMESTARTED) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if (!isairborne(lf) && (getcellwaterdepth(lf->cell, lf) >= DP_WAIST) &&
|
||||
if (!isairborne(lf, NULL) && (getcellwaterdepth(lf->cell, lf) >= DP_WAIST) &&
|
||||
getskill(lf, SK_SWIMMING)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -16640,7 +16711,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
|
|||
noise(lf->cell, NULL, NC_OTHER, SV_CAR, "arcing electricity", NULL);
|
||||
for (i = 0 ; i < nretcells; i++) {
|
||||
if (retcell[i]->lf && (retcell[i]->lf != lf)) {
|
||||
if (!isairborne(retcell[i]->lf)) {
|
||||
if (!isairborne(retcell[i]->lf, NULL)) {
|
||||
losehp_real(retcell[i]->lf, dam, DT_ELECTRIC, fromlf, "an electric shock", B_TRUE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
|
||||
}
|
||||
}
|
||||
|
@ -17488,16 +17559,8 @@ void modstamina(lifeform_t *lf, float howmuch) {
|
|||
|
||||
if (howmuch == 0) return;
|
||||
|
||||
// some raceclasses have infinite stamina
|
||||
switch (getraceclass(lf)) {
|
||||
case RC_PLANT:
|
||||
case RC_ROBOT:
|
||||
case RC_GOD:
|
||||
case RC_MAGIC:
|
||||
case RC_SLIME:
|
||||
case RC_DEMON:
|
||||
return;
|
||||
default: break;
|
||||
if (lfhasflag(lf, F_NOSTAM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isundead(lf)) return;
|
||||
|
@ -17643,14 +17706,19 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
int dist;
|
||||
int difficulty;
|
||||
int lbonus;
|
||||
int myvol;
|
||||
int nwalls = 0;
|
||||
flag_t *f;
|
||||
flag_t *sleepflag;
|
||||
|
||||
if (l == noisemaker) continue;
|
||||
|
||||
// ie. if this lf is in the process of swapping places
|
||||
if (!l->cell) continue;
|
||||
|
||||
sleepflag = lfhasflag(l, F_ASLEEP);
|
||||
// can't hear while unconscious
|
||||
if (sleepflag && (sleepflag->val[1] == ST_KO)) continue;
|
||||
|
||||
dist = getcelldist(l->cell, c);
|
||||
|
||||
// listen check difficulty is based on sound distance vs max hearing distance
|
||||
|
@ -17666,19 +17734,23 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
difficulty = (int) ( ((float) dist / ((float)gethearingrange(l) + volume)) * 75);
|
||||
}
|
||||
|
||||
if (sleepflag) {
|
||||
myvol = volume - 1;
|
||||
} else {
|
||||
myvol = volume;
|
||||
}
|
||||
limit(&myvol, 0, NA);
|
||||
|
||||
// listen bonus is based on sound volume
|
||||
lbonus = volume;
|
||||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f) {
|
||||
// can't hear while unconscious
|
||||
if (f->val[1] == ST_KO) continue;
|
||||
lbonus -= 6;
|
||||
lbonus = myvol;
|
||||
if (sleepflag) {
|
||||
lbonus -= 5;
|
||||
limit(&lbonus, 0, NA);
|
||||
}
|
||||
|
||||
// skillcheck to hear this
|
||||
if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing"
|
||||
(canhear(l, c, volume, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) {
|
||||
(canhear(l, c, myvol, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) {
|
||||
flag_t *f;
|
||||
// announce?
|
||||
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
|
||||
|
@ -17824,8 +17896,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
practice(l, SK_LISTEN, 1);
|
||||
}
|
||||
// migraine?
|
||||
if ((volume > 1) && lfhasflagval(l, F_POISONED, P_MIGRAINE, NA, NA, NULL)) {
|
||||
losehp(l, (volume-1), DT_SONIC, NULL, "a migraine");
|
||||
if ((myvol > 1) && lfhasflagval(l, F_POISONED, P_MIGRAINE, NA, NA, NULL)) {
|
||||
losehp(l, (myvol-1), DT_SONIC, NULL, "a migraine");
|
||||
if (isplayer(l)) {
|
||||
msg("Your head explodes in pain at the sound!");
|
||||
}
|
||||
|
@ -17837,7 +17909,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
f = lfhasflag(l, F_ASLEEP);
|
||||
if (f && (f->val[1] != ST_KO)) {
|
||||
if (f->lifetime > 0) { // ie. temporary
|
||||
timeeffectsflag(f, volume + rnd(1,3));
|
||||
timeeffectsflag(f, myvol + rnd(1,3));
|
||||
} else if (f->lifetime == PERMENANT) {
|
||||
if (f->val[2] == NA) {
|
||||
// ie asleep rather than 'resting'
|
||||
|
@ -17850,7 +17922,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
} else {
|
||||
// ie resting on purpose via 'R'
|
||||
// only wake up if the sound if very close
|
||||
if (volume >= getcelldist(c, l->cell)) {
|
||||
if (myvol >= getcelldist(c, l->cell)) {
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
char wakenoise[BUFLEN];
|
||||
|
@ -17906,7 +17978,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
}
|
||||
if (targlf && (targlf->cell)) { // ie. not swapping places
|
||||
if (getcelldist(l->cell, c) < getcelldist(l->cell, targlf->cell)) {
|
||||
if ((volume >= 4) && onein(2)) {
|
||||
if ((myvol >= 4) && onein(2)) {
|
||||
willrespond = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -17953,7 +18025,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
} else {
|
||||
int chasetime;
|
||||
// if NOT within lof, go and investigate
|
||||
chasetime = volume * 10;
|
||||
chasetime = myvol * 10;
|
||||
aigoto(l, c, MR_SOUND, NULL, chasetime);
|
||||
}
|
||||
}
|
||||
|
@ -19181,7 +19253,7 @@ int startresting(lifeform_t *lf, int willtrain) {
|
|||
|
||||
// player can't rest while in the air, unless you're in a motel room
|
||||
if (isplayer(lf)) {
|
||||
if (isairborne(lf) && !lfhasflag(lf, F_RESTINGINMOTEL)) {
|
||||
if (isairborne(lf, NULL) && !lfhasflag(lf, F_RESTINGINMOTEL)) {
|
||||
msg("You can't %s while airborne!", willtrain ? "train" : "rest");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -20548,7 +20620,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
|
||||
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
|
||||
|
||||
if (lfhasflag(lf, F_NATURALFLIGHT) && !isairborne(lf)) {
|
||||
if (lfhasflag(lf, F_NATURALFLIGHT) && !isairborne(lf, NULL)) {
|
||||
if (cancast(lf, OT_S_FLIGHT, NULL)) {
|
||||
notime = B_TRUE;
|
||||
castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL);
|
||||
|
@ -21401,7 +21473,7 @@ int slipon(lifeform_t *lf, object_t *o) {
|
|||
char obname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
|
||||
if (lfhasflag(lf, F_NONCORPOREAL) || isairborne(lf)) {
|
||||
if (lfhasflag(lf, F_NONCORPOREAL) || isairborne(lf, NULL)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -21542,6 +21614,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
int movedlastturn = B_FALSE;
|
||||
object_t *bloodamu = NULL;
|
||||
enum TIMEPHASE tp;
|
||||
enum FLAG inair = F_NONE;
|
||||
tp = gettimephase();
|
||||
|
||||
map = lf->cell->map;
|
||||
|
@ -21627,11 +21700,11 @@ void startlfturn(lifeform_t *lf) {
|
|||
killflagsofid(lf->flags, F_DONELISTEN);
|
||||
killflagsofid(lf->flags, F_DONEBURNMSG);
|
||||
killflagsofid(lf->flags, F_NOSWAP);
|
||||
killflagsofid(lf->flags, F_LASTATTACKHIT);
|
||||
movedlastturn = 0;
|
||||
movedlastturn += killflagsofid(lf->flags, F_HASBEENMOVED);
|
||||
movedlastturn += killflagsofid(lf->flags, F_MOVED);
|
||||
|
||||
|
||||
// if we didn't turn lsat move, kill our turncounter
|
||||
if (!killflagsofid(lf->flags, F_TURNED)) {
|
||||
lf->turncounter = 0;
|
||||
|
@ -22467,8 +22540,13 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// if you are stunned and flying, you fall
|
||||
if (isairborne(lf) && lfhasflag(lf, F_STUNNED)) {
|
||||
fall_from_air(lf);
|
||||
inair = isairborne(lf, NULL);
|
||||
if (inair) {
|
||||
if (lfhasflag(lf, F_STUNNED)) {
|
||||
fall_from_air(lf);
|
||||
} else if (isburdened(lf)) {
|
||||
fall_from_air(lf);
|
||||
}
|
||||
}
|
||||
|
||||
getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE);
|
||||
|
@ -22848,7 +22926,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->id == F_WALKDAMBP) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
object_t *armour;
|
||||
int dam;
|
||||
enum BODYPART bp;
|
||||
|
@ -23677,7 +23755,7 @@ void timeeffectslf(lifeform_t *lf) {
|
|||
while (o && donesomething) {
|
||||
int willfall = B_FALSE;
|
||||
donesomething = B_FALSE;
|
||||
if ((dir == D_DOWN) && !isairborne(lf)) {
|
||||
if ((dir == D_DOWN) && !isairborne(lf, NULL)) {
|
||||
object_t *amu;
|
||||
|
||||
willfall = B_TRUE;
|
||||
|
@ -24061,7 +24139,7 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
if (isplayer(lf)) {
|
||||
msg("^bOw! You burn your hands on %s.",obname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s burns itself on %s.",lfname, obname);
|
||||
msg("%s burns %sself on %s.",lfname, it(lf), obname);
|
||||
}
|
||||
snprintf(buf, BUFLEN, "touching %s",obname);
|
||||
if (f->id == F_ONFIRE) {
|
||||
|
@ -24553,7 +24631,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
// if we just climbed up through a hole, and are not flying, we want to
|
||||
// end up adjacent to the hole in the ground. otherwise we'll just fall
|
||||
// straight back down!
|
||||
if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf)) {
|
||||
if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf, NULL)) {
|
||||
cell_t *noholecell;
|
||||
noholecell = real_getrandomadjcell(newcell, &ccwalkable, B_ALLOWEXPAND, LOF_NEED, NULL, NULL );
|
||||
if (noholecell) {
|
||||
|
@ -24585,7 +24663,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
moveto(lf, newcell, onpurpose, B_TRUE);
|
||||
|
||||
// take time
|
||||
if ((dir == D_UP) && !isairborne(lf)) {
|
||||
if ((dir == D_UP) && !isairborne(lf, NULL)) {
|
||||
stopsprinting(lf); // you can sprint down stairs, but not up
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf)*2); // takes longer to climb
|
||||
} else {
|
||||
|
@ -24602,7 +24680,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
stopsprinting(adjally[n]);
|
||||
movelf(adjally[n], c, B_TRUE);
|
||||
climbtime = getmovespeed(adjally[n]);
|
||||
if ((dir == D_UP) && !isairborne(adjally[n])) {
|
||||
if ((dir == D_UP) && !isairborne(adjally[n], NULL)) {
|
||||
climbtime *= 2;
|
||||
}
|
||||
if (onpurpose) taketime(adjally[n], climbtime);
|
||||
|
@ -24809,7 +24887,13 @@ int validateraces(void) {
|
|||
if (!hasflag(r->flags, F_TR)) {
|
||||
printf("ERROR in race '%s' - missing F_TR (threat level).\n", r->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
|
||||
if (hasflagval(r->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL)) {
|
||||
if (!getskill(lf,SK_FLIGHT)) {
|
||||
printf("ERROR in race '%s' - has flight but no flight skill.\n", r->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasflag(r->flags, F_CANCAST) && !hasflag(r->flags, F_CASTWITHOUTIQ)) {
|
||||
|
|
8
lf.h
8
lf.h
|
@ -207,14 +207,14 @@ 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 getlfheight(lifeform_t *lf);
|
||||
int getlistendetectrange(lifeform_t *lf);
|
||||
int getfeetheight(lifeform_t *lf);
|
||||
int getlistendetectrange(lifeform_t *lf);
|
||||
int getmasterid(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);
|
||||
int getmorale(lifeform_t *lf);
|
||||
int getnaturalflightheight(lifeform_t *lf);
|
||||
int getnextshortcut(lifeform_t *lf);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, flag_t *noiseflag, char *heartext,char *seetext, int *volume, flag_t **returnedflag);
|
||||
|
@ -259,6 +259,7 @@ int getallshields(lifeform_t *lf, enum DAMTYPE damtype, object_t **retob, int *c
|
|||
int getshieldblockmod(lifeform_t *lf, object_t *o);
|
||||
int getspellspeed(lifeform_t *lf);
|
||||
int getstamina(lifeform_t *lf);
|
||||
int getstaminapct(lifeform_t *lf);
|
||||
float getstamregen(lifeform_t *lf);
|
||||
char *getplayername(char *buf);
|
||||
char *getplayernamefull(char *buf);
|
||||
|
@ -348,7 +349,7 @@ 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);
|
||||
void interrupt(lifeform_t *lf);
|
||||
enum FLAG isairborne(lifeform_t *lf);
|
||||
enum FLAG isairborne(lifeform_t *lf, int *height);
|
||||
int isaquatic(lifeform_t *lf);
|
||||
flag_t *isasleep(lifeform_t *lf);
|
||||
int isbehind(lifeform_t *lf, lifeform_t *otherlf);
|
||||
|
@ -362,6 +363,7 @@ int isdeaf(lifeform_t *lf);
|
|||
object_t *isdualweilding(lifeform_t *lf);
|
||||
flag_t *isfleeing(lifeform_t *lf);
|
||||
flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom);
|
||||
int isflyingwithwings(lifeform_t *lf);
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||
int isfriendly(lifeform_t *lf);
|
||||
int isfullyhealed(lifeform_t *lf);
|
||||
|
|
57
map.c
57
map.c
|
@ -98,7 +98,7 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
return cell;
|
||||
}
|
||||
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype) {
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype, int stairsinrooms) {
|
||||
habitat_t *a;
|
||||
// add to the end of the list
|
||||
if (firsthabitat == NULL) {
|
||||
|
@ -126,6 +126,7 @@ habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum
|
|||
//a->maxvisrange = maxvisrange;
|
||||
a->upstairtype = upstairtype;
|
||||
a->downstairtype = downstairtype;
|
||||
a->stairsinrooms = stairsinrooms;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -3089,6 +3090,10 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
|||
if (cell->lf && isplayer(cell->lf)) {
|
||||
valid = B_FALSE; continue;
|
||||
}
|
||||
// - overlap a cell with an important object
|
||||
if (hasobwithflag(cell->obpile, F_IMPORTANT)) {
|
||||
valid = B_FALSE; continue;
|
||||
}
|
||||
/*
|
||||
// - overlap the inside of an existing room
|
||||
if (cellwalkable(NULL, cell, NULL) && isroom(cell)) {
|
||||
|
@ -5051,7 +5056,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
for (x = 0; x < map->w; x++) {
|
||||
cell_t *c;
|
||||
c = getcellat(map, x, y);
|
||||
if (c) {
|
||||
if (c && !hasobwithflag(c->obpile, F_IMPORTANT)) {
|
||||
// add random obs, but not in vaults
|
||||
if (isempty(c)) {
|
||||
if (!getcellvault(c) || (c->habitat->id == H_HEAVEN)) {
|
||||
|
@ -7079,8 +7084,10 @@ int finalisemap(map_t *map, object_t *entryob, int exitdir) {
|
|||
|
||||
initcondv(&okforstairs, CC_EMPTY, B_TRUE, NA,
|
||||
CC_OKFORSTAIRS, B_TRUE, NA,
|
||||
CC_ISROOM, B_TRUE, NA,
|
||||
CC_NONE);
|
||||
if (map->habitat->stairsinrooms) {
|
||||
addcond(&okforstairs, CC_ISROOM, B_TRUE, NA);
|
||||
}
|
||||
|
||||
// make sure this map has sufficient up/down staircases as defined by its
|
||||
// region type.
|
||||
|
@ -7403,9 +7410,10 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags,
|
|||
killflagsofid(lf->flags, F_HIDING);
|
||||
} else {
|
||||
if (hasflag(lf->race->flags, F_NATURALFLIGHT) && !lfhasflag(lf, F_FLYING)) {
|
||||
if (cancast(lf, OT_S_FLIGHT, NULL)) {
|
||||
if (cancast(lf, OT_A_FLY, NULL) && !isburdened(lf)) {
|
||||
notime = B_TRUE;
|
||||
castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL);
|
||||
//castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL);
|
||||
useability(lf, OT_A_FLY, lf, lf->cell);
|
||||
notime = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -8447,19 +8455,19 @@ object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tfl
|
|||
|
||||
void initmap(void) {
|
||||
// habitats
|
||||
// thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype
|
||||
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 5, 60, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN);
|
||||
addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 10, 45, 20, 6, OT_TUNNELUP, OT_TUNNELDOWN);
|
||||
addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALLTREE, 5, 75, 0, MAXVISRANGE, OT_TREEUP, OT_TREEDOWN);
|
||||
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE);
|
||||
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 5, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_SEWER, "sewer", CT_MOSSROCK, CT_WALL, 10, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE);
|
||||
addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE);
|
||||
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN);
|
||||
addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE);
|
||||
addhabitat(H_ANTNEST, "ant nest", CT_DIRT, CT_WALLDIRT, 10, 40, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN);
|
||||
addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 10, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN);
|
||||
// thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype, stairs_in_rooms
|
||||
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 5, 60, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN, B_TRUE);
|
||||
addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 10, 45, 20, 6, OT_TUNNELUP, OT_TUNNELDOWN, B_FALSE);
|
||||
addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALLTREE, 5, 75, 0, MAXVISRANGE, OT_TREEUP, OT_TREEDOWN, B_FALSE);
|
||||
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE);
|
||||
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE, B_FALSE);
|
||||
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 5, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE);
|
||||
addhabitat(H_SEWER, "sewer", CT_MOSSROCK, CT_WALL, 10, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE, B_FALSE);
|
||||
addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE);
|
||||
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN, B_FALSE);
|
||||
addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE, B_FALSE);
|
||||
addhabitat(H_ANTNEST, "ant nest", CT_DIRT, CT_WALLDIRT, 10, 40, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN, B_FALSE);
|
||||
addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 10, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN, B_FALSE);
|
||||
|
||||
// cell types - solid
|
||||
// floorheight, hp, volmod, absorbant
|
||||
|
@ -9779,15 +9787,24 @@ int remove_deadends(map_t *m, int howmuch) {
|
|||
cell_t *c;
|
||||
c = m->cell[n];
|
||||
if (!c->room) {
|
||||
int exits;
|
||||
exits = countcellexits(c, DT_ORTH);
|
||||
//if ((countcellexits(c, DT_ORTH) == 1) ||
|
||||
// (countcellexits(c, DT_COMPASS) == 1)) {
|
||||
if (countcellexits(c, DT_ORTH) == 1) {
|
||||
if (exits == 1) {
|
||||
// erase this cell
|
||||
clearcell(c);
|
||||
setcelltype(c, solidcell);
|
||||
setcellreason(c, "dead-end removed.");
|
||||
count++;
|
||||
thiscount++;
|
||||
} else if (exits == 0) {
|
||||
// erase this cell
|
||||
clearcell(c);
|
||||
setcelltype(c, solidcell);
|
||||
setcellreason(c, "zero-exit deadend removed.");
|
||||
count++;
|
||||
thiscount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10253,7 +10270,7 @@ void updateknowncells(void) {
|
|||
|
||||
// you don't remember cells when you're flying, unless you
|
||||
// have a magic map or photographic memory.
|
||||
if (isairborne(player) && !lfhasflag(player, F_PHOTOMEM)) {
|
||||
if (isairborne(player, NULL) && !lfhasflag(player, F_PHOTOMEM)) {
|
||||
return;
|
||||
}
|
||||
if (lfhasflag(player, F_RAGE)) {
|
||||
|
|
2
map.h
2
map.h
|
@ -1,7 +1,7 @@
|
|||
#include "defs.h"
|
||||
|
||||
cell_t *addcell(map_t *map, int x, int y);
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype);
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype, int stairsinrooms);
|
||||
void addhomeobs(lifeform_t *lf, int dolevelobs);
|
||||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded);
|
||||
|
|
40
move.c
40
move.c
|
@ -227,7 +227,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
}
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
if (f && (f->val[0] == D_DOWN)) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
|
@ -238,7 +238,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f) {
|
||||
// non swimming creature in water?
|
||||
if (!isairborne(lf) && !lfhasflag(lf, F_AQUATIC)) {
|
||||
if (!isairborne(lf, NULL) && !lfhasflag(lf, F_AQUATIC)) {
|
||||
if ((getobdepth(o, lf) >= DP_HEAD)) {
|
||||
if (getskill(lf, SK_SWIMMING) - isburdened(lf) <= 0) {
|
||||
if (error) {
|
||||
|
@ -925,7 +925,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
msg("%s stagger%s %s but hold%s %s %s.",lfname,isplayer(lf) ? "" : "s",
|
||||
getreldirname(getrelativedir(lf, dir)),
|
||||
isplayer(lf) ? "" : "s", isplayer(lf) ? "your" : "its",
|
||||
isairborne(lf) ? "position" : "ground");
|
||||
isairborne(lf, NULL) ? "position" : "ground");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1404,7 +1404,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
}
|
||||
|
||||
// check ground objects
|
||||
flying = isairborne(lf);
|
||||
flying = isairborne(lf, NULL);
|
||||
if (flying == F_NONE) {
|
||||
for (o = newcell->obpile->first ; o ; o = nexto ) {
|
||||
nexto = o->next;
|
||||
|
@ -1471,6 +1471,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
|
||||
if (!lfhasflag(lf, F_CAREFULMOVE)) {
|
||||
if (cancrush(lf, o)) {
|
||||
int maxhp;
|
||||
// crush it
|
||||
getobname(o, obname, 1);
|
||||
|
||||
|
@ -1495,9 +1496,16 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
didmsg = B_TRUE;
|
||||
}
|
||||
// kill object which is being crushed.
|
||||
removeob(o, o->amt);
|
||||
//removeob(o, o->amt);
|
||||
getobhp(o, &maxhp);
|
||||
if (maxhp) {
|
||||
takedamage(o, maxhp, DT_CRUSH, lf);
|
||||
} else {
|
||||
removeob(o, ALL);
|
||||
}
|
||||
if (isplayer(lf)) {
|
||||
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
|
||||
pleasegodmaybe(R_GODFIRE, 2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -1717,7 +1725,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
// will we cause damage to ground objects ?
|
||||
if (!isairborne(lf) || (f->val[2] == B_TRUE)) {
|
||||
if (!isairborne(lf, NULL) || (f->val[2] == B_TRUE)) {
|
||||
damageallobs(NULL, lf->cell->obpile, f->val[0], f->val[1], lf);
|
||||
}
|
||||
}
|
||||
|
@ -1859,14 +1867,14 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
// (stealth check to avoid this)
|
||||
willmakenoise = B_TRUE;
|
||||
if (lfhasflag(lf, F_HIDING)) {
|
||||
if (skillcheck(lf, SC_STEALTH, 70, isairborne(lf) ? 25 : 0)) {
|
||||
if (skillcheck(lf, SC_STEALTH, 70, isairborne(lf, NULL) ? 10 : 0)) {
|
||||
willmakenoise = B_FALSE;
|
||||
}
|
||||
}
|
||||
// swapping places?
|
||||
|
||||
if (willmakenoise) {
|
||||
if (isairborne(lf)) {
|
||||
if (isairborne(lf, NULL)) {
|
||||
makenoise(lf, N_FLY);
|
||||
} else {
|
||||
makenoise(lf, N_WALK);
|
||||
|
@ -1874,7 +1882,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
}
|
||||
|
||||
// slip on blood in new cell?
|
||||
if (!isairborne(lf) && !isswimming(lf)) {
|
||||
if (!isairborne(lf, NULL) && !isswimming(lf)) {
|
||||
int slip;
|
||||
object_t *slipob;
|
||||
|
||||
|
@ -1892,7 +1900,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
nexto = o->next;
|
||||
f = hasflag(o->flags, F_TRAP);
|
||||
if (f) {
|
||||
if (strstr(f->text, "ground") && isairborne(lf)) {
|
||||
if (strstr(f->text, "ground") && isairborne(lf, NULL)) {
|
||||
// nothing happens
|
||||
} else {
|
||||
triggertrap(lf, NULL, o, lf->cell);
|
||||
|
@ -1957,7 +1965,7 @@ int move_will_hurt(lifeform_t *lf) {
|
|||
if (f->id == F_INJURY) {
|
||||
switch (f->val[0]) {
|
||||
case IJ_LEGBLEED:
|
||||
if (!isairborne(lf)) return B_TRUE;
|
||||
if (!isairborne(lf, NULL)) return B_TRUE;
|
||||
break;
|
||||
case IJ_WINGBLEED:
|
||||
getflags(lf->flags, retflag2, &nretflags2, F_FLYING, F_NONE);
|
||||
|
@ -1973,7 +1981,7 @@ int move_will_hurt(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
if (hasbleedinginjury(lf, BP_LEGS) && !isairborne(lf)) {
|
||||
if (hasbleedinginjury(lf, BP_LEGS) && !isairborne(lf, NULL)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
|
@ -2430,7 +2438,7 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
|
|||
char buf[BUFLEN];
|
||||
getlfname(lf, buf);
|
||||
msg("%s %s pulled %s!", buf, is(lf),
|
||||
isairborne(lf) ? "through the air" :
|
||||
isairborne(lf, NULL) ? "through the air" :
|
||||
"along the ground");
|
||||
}
|
||||
movelf(lf, dst, B_FALSE);
|
||||
|
@ -2561,7 +2569,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
|
|||
|
||||
|
||||
if (o->type->id == OT_WEB) {
|
||||
if (isairborne(lf)) {
|
||||
if (isairborne(lf, NULL)) {
|
||||
checkmod -= 5;
|
||||
}
|
||||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
|
@ -2636,7 +2644,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
|
|||
|
||||
// slipping on something before moving?
|
||||
if (!attacking && onpurpose) {
|
||||
if (!isairborne(lf)) {
|
||||
if (!isairborne(lf, NULL)) {
|
||||
int slip;
|
||||
object_t *slipob;
|
||||
|
||||
|
@ -2665,7 +2673,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
|
|||
for (o = cell->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (!isplayer(lf)) {
|
||||
if ((o->blessed == B_CURSED) && (getraceclass(lf) == RC_ANIMAL) && !isairborne(lf)) {
|
||||
if ((o->blessed == B_CURSED) && (getraceclass(lf) == RC_ANIMAL) && !isairborne(lf, NULL)) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf,lfname);
|
||||
|
|
229
objects.c
229
objects.c
|
@ -4162,6 +4162,143 @@ object_t *getbestcontainer(obpile_t *op) {
|
|||
return poss2[rnd(0,nposs2-1)];
|
||||
}
|
||||
|
||||
// returns TRUE if an break obejct was found.
|
||||
int getbreakob(object_t *o, char *bigobname, char *smallobname) {
|
||||
enum MATERIAL mid;
|
||||
enum DAMTYPE dt;
|
||||
enum OBTYPE bigoid = OT_NONE,smalloid = OT_NONE;
|
||||
objecttype_t *big = NULL,*small = NULL;
|
||||
flag_t *f;
|
||||
int nsmall = 0,nbig = 0;
|
||||
double weight;
|
||||
char bigadj[BUFLEN],smalladj[BUFLEN];
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0,i;
|
||||
int found = B_FALSE;
|
||||
|
||||
mid = o->material->id;
|
||||
dt = oblastdamtype(o);
|
||||
|
||||
// name to return.
|
||||
strcpy(bigobname, "");
|
||||
strcpy(smallobname, "");
|
||||
|
||||
|
||||
// flag overrides code below
|
||||
found = 0;
|
||||
getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f && (f->val[0] == dt)) {
|
||||
if (found == 0) {
|
||||
strcpy(bigobname, f->text);
|
||||
} else if (found == 1) {
|
||||
strcpy(smallobname, f->text);
|
||||
} else {
|
||||
msg("ERROR - too many F_BREAKOB flags in %s",o->type->name);
|
||||
dblog("ERROR - too many F_BREAKOB flags in %s",o->type->name);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// adjectives
|
||||
strcpy(bigadj, "");
|
||||
strcpy(smalladj, "");
|
||||
switch (mid) {
|
||||
case MT_WOOD:
|
||||
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
|
||||
bigoid = OT_WOODPLANK;
|
||||
smalloid = OT_WOODSHARD;
|
||||
} else {
|
||||
switch (dt) {
|
||||
case DT_FIRE:
|
||||
case DT_HEAT:
|
||||
case DT_ACID:
|
||||
bigoid = OT_ASH;
|
||||
smalloid = OT_ASH;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_GLASS:
|
||||
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
|
||||
bigoid = OT_BROKENGLASS;
|
||||
smalloid = OT_BROKENGLASS;
|
||||
break;
|
||||
} else {
|
||||
switch (dt) {
|
||||
case DT_FIRE:
|
||||
case DT_HEAT:
|
||||
case DT_ACID:
|
||||
bigoid = OT_ASH;
|
||||
smalloid = OT_ASH;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_ICE:
|
||||
if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) {
|
||||
bigoid = OT_ICECHUNK;
|
||||
smalloid = OT_ICECHUNK;
|
||||
break;
|
||||
} else {
|
||||
switch (dt) {
|
||||
case DT_FIRE:
|
||||
case DT_HEAT:
|
||||
bigoid = OT_PUDDLEWATERL;
|
||||
smalloid = OT_PUDDLEWATER;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MT_FLESH:
|
||||
switch (dt) {
|
||||
case DT_FIRE:
|
||||
bigoid = OT_ASH;
|
||||
smalloid = OT_ASH;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
big = findot(bigoid);
|
||||
small = findot(smalloid);
|
||||
|
||||
// now find out how many big obejcts make up the wight.
|
||||
// NOTE: purposesly not using getobweight() here since
|
||||
// we don't case about whther it is in water, etc.
|
||||
weight = getobweight(o);
|
||||
if (big) {
|
||||
nbig = weight / big->weight;
|
||||
weight -= (nbig*big->weight);
|
||||
}
|
||||
if (small){
|
||||
nsmall = weight / small->weight;
|
||||
weight -= (nsmall*small->weight);
|
||||
}
|
||||
|
||||
if (nbig) {
|
||||
sprintf(bigobname, "%d %s",nbig,big->name);
|
||||
}
|
||||
if (nsmall) {
|
||||
sprintf(smallobname, "%d %s",nsmall,small->name);
|
||||
}
|
||||
|
||||
if (strlen(bigobname) || strlen(smallobname)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns -1 if object doesn't have the flag
|
||||
int getchargeinfo(object_t *o, int *cur, int *max) {
|
||||
flag_t *f;
|
||||
|
@ -7677,7 +7814,7 @@ int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) {
|
|||
|
||||
if ((lfsize >= blockmin) && (lfsize <= blockmax)) {
|
||||
// exception - if you're flying over it
|
||||
if (getlfheight(lf) >= blockmax) {
|
||||
if (getfeetheight(lf) >= blockmax) {
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -7735,6 +7872,7 @@ int ismagicalobtype(objecttype_t *ot) {
|
|||
case OT_SHILLELAGH:
|
||||
case OT_WIZARDSTAFF:
|
||||
case OT_ARMOURTHORN:
|
||||
case OT_PEACEPIPES:
|
||||
return B_TRUE;
|
||||
default: break;
|
||||
}
|
||||
|
@ -8544,6 +8682,14 @@ void makeknownobclass(enum OBCLASS ocid, enum RARITY rrlev) {
|
|||
}
|
||||
}
|
||||
|
||||
void makeopersound(cell_t *c, object_t *o) {
|
||||
flag_t *df;
|
||||
df = hasflag(o->flags, F_OPERSOUND);
|
||||
if (df) {
|
||||
noise(c, NULL, NC_OTHER, df->val[0], df->text, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void maketemporary(object_t *o, int howlong, char *obdietext) {
|
||||
addflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(o->flags, F_OBHP, howlong, howlong, NA, NULL);
|
||||
|
@ -9204,6 +9350,17 @@ void obdie(object_t *o) {
|
|||
snprintf(bonestr, BUFLEN, "%d-%d bones",minbones,maxbones);
|
||||
addob(o->pile, bonestr);
|
||||
}
|
||||
} else {
|
||||
char bigbreak[BUFLEN],smallbreak[BUFLEN];
|
||||
// maybe create broken object based on material
|
||||
getbreakob(o, bigbreak, smallbreak);
|
||||
|
||||
if (strlen(smallbreak)) {
|
||||
addob(loc->obpile, smallbreak);
|
||||
}
|
||||
if (strlen(bigbreak)) {
|
||||
addob(loc->obpile, bigbreak);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9227,6 +9384,13 @@ void obdie(object_t *o) {
|
|||
magicwoods_angry(killer);
|
||||
}
|
||||
|
||||
if (killer && isplayer(killer)) {
|
||||
if (oblastdamtype(o) == DT_FIRE) {
|
||||
pleasegodmaybe(R_GODFIRE, 5);
|
||||
} else {
|
||||
pleasegodmaybe(R_GODFIRE, 2);
|
||||
}
|
||||
}
|
||||
killob(o);
|
||||
}
|
||||
|
||||
|
@ -9430,7 +9594,7 @@ flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf) {
|
|||
if (lf) {
|
||||
if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) {
|
||||
} else if ((o->type->id == OT_VINE) && hasjob(lf, J_DRUID)) {
|
||||
} else if (isairborne(lf) && (f->val[2] != B_TRUE)) {
|
||||
} else if (isairborne(lf, NULL) && (f->val[2] != B_TRUE)) {
|
||||
} else {
|
||||
return f;
|
||||
}
|
||||
|
@ -10816,8 +10980,30 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
if (isplayer(lf)) {
|
||||
msg("You play a few notes on your panpipes.");
|
||||
} else {
|
||||
noise(lf->cell, lf, NC_OTHER, SV_CAR, "the sound of panpipes.", "plays a tune on its panpipes.");
|
||||
char nbuf[BUFLEN];
|
||||
sprintf(nbuf, "plays a tune on %ss panpipes.", it(lf));
|
||||
noise(lf->cell, lf, NC_OTHER, SV_SHOUT, "the sound of panpipes.", nbuf);
|
||||
}
|
||||
} else if (o->type->id == OT_PEACEPIPES) {
|
||||
lifeform_t *l;
|
||||
if (isplayer(lf)) {
|
||||
msg("You play an enchanting melody on your panpipes!");
|
||||
} else {
|
||||
char nbuf[BUFLEN];
|
||||
sprintf(nbuf, "plays a calming melody on %ss panpipes.", it(lf));
|
||||
noise(lf->cell, lf, NC_OTHER, SV_SHOUT, "an eerily calming melody.", nbuf);
|
||||
}
|
||||
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
||||
if (l == lf) continue;
|
||||
if (iscursed(o)) {
|
||||
// enrage
|
||||
enrage(l, DEF_RAGETIME*2);
|
||||
} else {
|
||||
// calm
|
||||
makepeaceful(l, lf);
|
||||
}
|
||||
}
|
||||
makeknown(o->type->id);
|
||||
} else if (hasflag(o->flags, F_HELPSDIG)) {
|
||||
int ch,dir;
|
||||
cell_t *c;
|
||||
|
@ -11873,7 +12059,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
// remove damaging objects underneath
|
||||
if (killobswithflag(lf->cell->obpile, F_WALKDAM, B_FALSE)) {
|
||||
if (haslos(player, lf->cell)) {
|
||||
msg("Some nearby objecst disappear!");
|
||||
msg("Some nearby objects disappear!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13030,7 +13216,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
}
|
||||
|
||||
// announce
|
||||
if (haslos(player, where)) {
|
||||
if (haslos(player, where) && !o->pile->parentob) {
|
||||
char prefix[BUFLEN];
|
||||
|
||||
if (o->pile->owner) {
|
||||
|
@ -13049,7 +13235,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
noise(where, NULL, NC_OTHER, SV_SHOUT, "shattering glass.", NULL);
|
||||
}
|
||||
|
||||
if (target) {
|
||||
if (target && !o->pile->parentob) {
|
||||
shatterdam = getshatterdam(o);
|
||||
if (shatterdam && !isdead(target)) {
|
||||
// extra glass damage
|
||||
|
@ -13067,7 +13253,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
numshards = getnumshards(o);
|
||||
// place glass shards
|
||||
snprintf(buf, BUFLEN, "%d pieces of broken glass",numshards);
|
||||
addob(where->obpile, buf);
|
||||
addob(o->pile, buf);
|
||||
} else if (o->material->id == MT_ICE) {
|
||||
int numshards;
|
||||
numshards = getnumshards(o) / 15;
|
||||
|
@ -13075,7 +13261,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
|
||||
// ice
|
||||
snprintf(buf, BUFLEN, "%d chunks of ice",numshards);
|
||||
addob(where->obpile, buf);
|
||||
addob(o->pile, buf);
|
||||
}
|
||||
|
||||
// potion effects (only if you hit)?
|
||||
|
@ -13197,7 +13383,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
}
|
||||
//TODO: holy water blesses everything?
|
||||
// everything here takes water damage
|
||||
for (oo = where->obpile->first ; oo ; oo = nextoo) {
|
||||
for (oo = o->pile->first ; oo ; oo = nextoo) {
|
||||
nextoo = oo->next;
|
||||
takedamage(oo, 0, DT_WATER, fromlf);
|
||||
}
|
||||
|
@ -13641,22 +13827,6 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif
|
|||
meat->weight = o->weight;
|
||||
copyflag(meat->flags, o->flags, F_CORPSEOF);
|
||||
}
|
||||
// fire turns things to ash
|
||||
addob(o->pile, "pile of ash");
|
||||
} else if (damtype == DT_BASH) {
|
||||
if (o->material->id == MT_GLASS) { // bashing damage breaks glass
|
||||
int nshards;
|
||||
char buf[BUFLEN];
|
||||
nshards = getnumshards(o);
|
||||
snprintf(buf, BUFLEN, "%d pieces of broken glass", nshards);
|
||||
addob(o->pile, buf);
|
||||
} else if (o->material->id == MT_ICE) { // bashing breaks ice
|
||||
int nshards;
|
||||
char buf[BUFLEN];
|
||||
nshards = getnumshards(o) / 15;
|
||||
snprintf(buf, BUFLEN, "%d chunks of ice", nshards);
|
||||
addob(o->pile, buf);
|
||||
}
|
||||
}
|
||||
|
||||
// object dies!
|
||||
|
@ -14445,7 +14615,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
// will the missile trip them over?
|
||||
f = hasflag(o->flags, F_TANGLEMISSILE);
|
||||
if (f) {
|
||||
if (isairborne(target) || !skillcheck(target, SC_SLIP, f->val[0], 0)) {
|
||||
if (isairborne(target, NULL) || !skillcheck(target, SC_SLIP, f->val[0], 0)) {
|
||||
willtangle = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -14587,6 +14757,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
|
|||
shatter(newob, youhit, dambuf, thrower);
|
||||
if (thrower && isplayer(thrower)) {
|
||||
angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT);
|
||||
pleasegodmaybe(R_GODFIRE, 1);
|
||||
}
|
||||
} else if (hasflag(newob->flags, F_MISSILEALWAYSDIES)) {
|
||||
killob(newob);
|
||||
|
@ -15207,9 +15378,11 @@ void timeeffectsob(object_t *o) {
|
|||
} else {
|
||||
damtype = f->val[1];
|
||||
}
|
||||
// special case - corpses don't decay when on ice
|
||||
// special case - corpses don't decay when on ice or on fire.
|
||||
if (o->type->id == OT_CORPSE) {
|
||||
if (hasobofmaterial(o->pile, MT_ICE)) {
|
||||
if (hasflag(o->flags, F_ONFIRE)) {
|
||||
doit = B_FALSE;
|
||||
} else if (hasobofmaterial(o->pile, MT_ICE)) {
|
||||
doit = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ void genhiddennames(void);
|
|||
enum LFSIZE getarmoursize(object_t *o);
|
||||
enum RARITY getavgrarity(flagpile_t *fp);
|
||||
object_t *getbestcontainer(obpile_t *op);
|
||||
int getbreakob(object_t *o, char *bigobname, char *smallobname);
|
||||
int getchargeinfo(object_t *o, int *cur, int *max);
|
||||
int getcharges(object_t *o);
|
||||
enum SKILL getclassloreskill(enum OBCLASS oc);
|
||||
|
@ -247,6 +248,7 @@ int makeduller(object_t *o, int howmuch);
|
|||
void makehot(object_t *o, int howmuch, int howlong);
|
||||
void makeknown(enum OBTYPE otid);
|
||||
void makeknownobclass(enum OBCLASS ocid, enum RARITY rrlev);
|
||||
void makeopersound(cell_t *c, object_t *o);
|
||||
void maketemporary(object_t *o, int howlong, char *obdietext);
|
||||
void maketried(enum OBTYPE otid, char *triedon);
|
||||
void makewet(object_t *o, int amt);
|
||||
|
|
174
spell.c
174
spell.c
|
@ -131,7 +131,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (isstuck(user)) {
|
||||
if (isplayer(user)) msg("You can't build anything while stuck!");
|
||||
return B_TRUE;
|
||||
} else if (isairborne(user)) {
|
||||
} else if (isairborne(user, NULL)) {
|
||||
if (isplayer(user)) msg("You can't build anything while airborne!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1214,7 +1214,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
msg("There is nothing to dismantle there.");
|
||||
return B_TRUE;
|
||||
} else if (!o) {
|
||||
if (slev >= PR_SKILLED) {
|
||||
if (slev >= PR_ADEPT) {
|
||||
// you can dismantle doors too...
|
||||
o = hasdoor(c);
|
||||
}
|
||||
|
@ -1258,6 +1258,36 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
addflag(target->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
target->hp = 0;
|
||||
killallobs(target->pack);
|
||||
} else if (abilid == OT_A_FLY) {
|
||||
flag_t *retflag[MAXCANDIDATES],*f;
|
||||
int nretflags,i;
|
||||
|
||||
// already flying? stop.
|
||||
getflags(user->flags, retflag, &nretflags, F_FLYING, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->lifetime == FROMABIL) {
|
||||
killflag(f);
|
||||
taketime(user, getactspeed(user));
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isimmobile(user)) {
|
||||
if (isplayer(user)) msg("You can't move!");
|
||||
return B_TRUE;
|
||||
} else if (isstuck(user)) {
|
||||
if (isplayer(user)) msg("You can't start flying while stuck!");
|
||||
return B_TRUE;
|
||||
} else if (isburdened(user)) {
|
||||
if (isplayer(user)) msg("You can't flying while burdened!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// start flying
|
||||
addtempflag(user->flags, F_FLYING, getnaturalflightheight(user), NA, NA, NULL, FROMABIL);
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
} else if (abilid == OT_A_FEIGNDEATH) {
|
||||
lifeform_t *lf;
|
||||
if (hasflag(user->flags, F_FEIGNINGDEATH)) {
|
||||
|
@ -1580,7 +1610,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't jump while swimming!");
|
||||
return B_TRUE;
|
||||
} else if (isairborne(user)) {
|
||||
} else if (isairborne(user, NULL)) {
|
||||
if (isplayer(user)) msg("You can't jump while airbourne!");
|
||||
return B_TRUE;
|
||||
} else if (hasflag(user->flags, F_GRAVBOOSTED)) {
|
||||
|
@ -2174,7 +2204,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (isairborne(user)) {
|
||||
if (isairborne(user, NULL)) {
|
||||
if (isplayer(user)) msg("You can't sprint while airborne!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -2707,7 +2737,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) msg("There is nobody there to trip!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isairborne(target)) {
|
||||
if (isairborne(target, NULL)) {
|
||||
if (isplayer(user)) msg("You can't trip someone in the air!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -2757,7 +2787,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't tumble while swimming!");
|
||||
return B_TRUE;
|
||||
} else if (isairborne(user)) {
|
||||
} else if (isairborne(user, NULL)) {
|
||||
if (isplayer(user)) msg("You can't tumble while airbourne!");
|
||||
return B_TRUE;
|
||||
} else if (lfhasflag(user, F_GRABBING)) {
|
||||
|
@ -6164,7 +6194,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (cansee(player, c2->lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(c2->lf, lfname);
|
||||
msg("%s %s showered with debris!", lfname, isplayer(c2->lf) ? "are" : "is");
|
||||
msg("^%c%s %s showered with debris!",
|
||||
getlfcol(c2->lf, CC_BAD),
|
||||
lfname, isplayer(c2->lf) ? "are" : "is");
|
||||
}
|
||||
losehp(c2->lf, dam, DT_PROJECTILE, NULL, "flying debris");
|
||||
}
|
||||
|
@ -7428,131 +7460,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_FLIGHT) {
|
||||
flag_t *f;
|
||||
int height;
|
||||
// always targetted at caster
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_FLYING, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
height = (power/2)+1;
|
||||
limit(&height, SZ_MEDIUM, NA);
|
||||
|
||||
f = addtempflag(caster->flags, F_FLYING, height, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_FREEZEOB) {
|
||||
object_t *o;
|
||||
|
||||
if (targob) {
|
||||
o = targob;
|
||||
} else {
|
||||
// rings?
|
||||
o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTFINGER, NA, NA, NULL);
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTFINGER, NA, NA, NULL);
|
||||
// gloves?
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_HANDS, NA, NA, NULL);
|
||||
// weapon?
|
||||
if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_WEAPON, NA, NA, NULL);
|
||||
if (o) {
|
||||
// at high power, warn...
|
||||
if (isplayer(caster) && (power > 5)) {
|
||||
char obname[BUFLEN];
|
||||
char ch;
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s %s start%s glowing bright blue!",
|
||||
(o->pile->owner == caster) ? "Your" : "",
|
||||
(o->pile->owner == caster) ? noprefix(obname) : obname,
|
||||
OBS1(o));
|
||||
more();
|
||||
ch = askchar("Abort your spell?", "yn","y", B_TRUE, B_FALSE);
|
||||
if (ch == 'y') {
|
||||
msg("You release your spell into the air.");
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// next thing touched
|
||||
addflag(caster->flags, F_FREEZINGTOUCH, 1, power, 10+power, NULL);
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands begin to glow blue!");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (cansee(player, caster)) {
|
||||
getlfname(caster, buf);
|
||||
msg("%s's hands begin to glow blue!", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!o) {
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands feel freezing cold for a moment.");
|
||||
}
|
||||
if (lfhasflag(caster, F_FREEZINGTOUCH)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// object will turn to ice immediately...
|
||||
if (o->material->id == MT_ICE) { // already made of ice?
|
||||
cell_t *loc;
|
||||
flag_t *f;
|
||||
loc = getoblocation(o);
|
||||
// announce
|
||||
if (haslos(player, loc)) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s %s freeze%s some more.",
|
||||
(o->pile->owner == caster) ? "Your" : "",
|
||||
(o->pile->owner == caster) ? noprefix(obname) : obname,
|
||||
OBS1(o));
|
||||
}
|
||||
// restore it
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (f) {
|
||||
f->val[0] = f->val[1];
|
||||
}
|
||||
return B_TRUE;
|
||||
} else {
|
||||
int rv;
|
||||
getobname(o, buf, o->amt);
|
||||
if (isimmuneto(o->flags, DT_COLD, B_FALSE)) {
|
||||
rv = E_NOEFFECT;
|
||||
} else {
|
||||
rv = changemat(o, MT_ICE);
|
||||
}
|
||||
if (rv) {
|
||||
if (rv == E_NOEFFECT) {
|
||||
if (o->pile->owner) {
|
||||
if (isplayer(o->pile->owner)) {
|
||||
msg("Your %s glows blue for a moment.",noprefix(buf));
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (haslos(player, o->pile->owner->cell)) {
|
||||
char buf2[BUFLEN];
|
||||
getlfname(o->pile->owner, buf2);
|
||||
msg("%s%s %s glows blue for a moment.", noprefix(buf2),getpossessive(buf2), buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (haslos(player, o->pile->where)) {
|
||||
msg("%s glows blue for a moment.", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
if (isplayer(caster)) {
|
||||
nothinghappens();
|
||||
}
|
||||
}
|
||||
return B_TRUE;
|
||||
} else {
|
||||
if (o->pile->owner) {
|
||||
if (isplayer(o->pile->owner)) {
|
||||
msg("Your %s turn%s to ice!",noprefix(buf), OBS1(o));
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (haslos(player, o->pile->owner->cell)) {
|
||||
getlfname(o->pile->owner, buf);
|
||||
msg("A small cloud of vapour rises up from %s.", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (haslos(player, o->pile->where)) {
|
||||
msg("%s turns to ice!", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// next thing touched
|
||||
addflag(caster->flags, F_FREEZINGTOUCH, 1, power, 10+power, NULL);
|
||||
return B_FALSE;
|
||||
} else if (spellid == OT_S_FROSTBITE) {
|
||||
char lfname[BUFLEN];
|
||||
int exposedlimbs,dam;
|
||||
|
@ -14737,7 +14665,7 @@ void pullobto(object_t *o, lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// can we pick up the object?
|
||||
if (hasflag(o->flags, F_NOPICKUP) || hasflag(o->flags, F_IMPASSABLE) || !canpickup(lf, o, ALL)) {
|
||||
if (hasflag(o->flags, F_NOPICKUP) || isimpassableob(o, lf, getlfsize(lf)) || !canpickup(lf, o, ALL)) {
|
||||
char buf[BUFLEN];
|
||||
int dir;
|
||||
cell_t *obloc,*newcell;
|
||||
|
|
Loading…
Reference in New Issue