- [+] chat->all allies command.
- [+] replace 'step carefully' key to free up 's' - OT_A_TIPTOE - [+] 's' = 'shut door' (replace 'c') - [+] 'c' = 'chat to single' - [+] rewrite docomms() to use other funcs - [+] 'C' = 'command all allies' - [+] only possible for single person: - [+] 'o' donate - [+] 'i' tell me about this area - [+] 'j' join me - [+] 'k' trade knowledge - [+] 'm' mercy - [+] 't' trade - [+] 'x' dangers nearby? - [+] make a list of all commands which are valid for EVERYONE - [+] send command to everyone. - [+] docommslf() - [+] test with single target - [+] test with multiple targets - [+] hitconfer lifetime for wight/contagion zombie should only happen on fatal hits - [+] makezombie() should be able to call petify() - [+] bug: mosnters never using HIDE ability. - [+] monsters which pretend to be objects (ie. gargoyle) - [+] F_ISMONSTER v0=raceid v1=objectid, v2 = spot check difficulty - [+] when generating, add contents->first as objectid v1 - [+] getobname -> if you have f_mosnters, use contents->first - [+] getobdesc -> if you have f_mosnters, use contents->first - [+] mosnters won't walk onto it - [+] if you are next to them and can't see them... reveal then attack! - [+] F_ISMONSTER - must always be impassable to everyone!!! - [+] if you try to walk onto it: - [+] "the xxx starts to move!" - [+] kill ob - [+] add lf - [+] they get a free attack - [+] if it takes damage - [+] ... convert. - [+] spot checks to see them. - [+] ...convert. - [+] F_PRETENDSTOBE - mosnters will revert if unseen. - [+] reveal hidden should show them. - [+] gargoyle - [+] stone statues - [+] winged - [+] large - [+] ~37hp - [+] start off as an obejct - [+] wight - [+] rare. - [+] ~26 hp ...TR5 - [+] silent move - [+] dr4 attack (low damage) but.... - [+] any humans killed rise as a wight . - [+] (hitconfer revive). how can i limit hitconfer to a race? maybe f_hitconferrace - [+] bones file - [+] tested ok. - [+] 1 leveldrain per hit - [+] skillcheck to avoid - [+] wight gains +5 hp
This commit is contained in:
parent
ae01d1bbfa
commit
234d70b099
107
ai.c
107
ai.c
|
@ -1336,7 +1336,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
|
||||
// need to train skills?
|
||||
if (!enraged) {
|
||||
if (readytotrain(lf) && safetorest(lf)) {
|
||||
if (readytotrain(lf) && safetorest(lf, NULL)) {
|
||||
// special case - monsters don't need to actually rest to gain
|
||||
// skills, although they DO still need to wait until the player
|
||||
// is out of sight.
|
||||
|
@ -1375,11 +1375,44 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
|
|||
///////////////////////////////////////////////
|
||||
|
||||
if (!enraged) {
|
||||
// hide?
|
||||
if (!ispetof(lf, player) && cancast(lf, OT_A_HIDE, NULL) && aispellok(lf, OT_A_HIDE, lf, F_AICASTTOFLEE)) {
|
||||
if (db) dblog(".oO { trying to hide. }");
|
||||
if (!useability(lf, OT_A_HIDE, lf, lf->cell)) {
|
||||
if (db) dblog(".oO { success! }");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
// need to heal?
|
||||
if (needstorest(lf, NULL) && safetorest(lf) && !hasflag(lf->flags, F_RAGE)) {
|
||||
if (db) dblog(".oO { resting to heal }");
|
||||
rest(lf, B_TRUE);
|
||||
return B_TRUE;
|
||||
if (needstorest(lf, NULL) && !hasflag(lf->flags, F_RAGE)) {
|
||||
enum ERROR why;
|
||||
if (safetorest(lf, &why) || (why == E_TOOSOON)) {
|
||||
if (db) dblog(".oO { resting to heal }");
|
||||
rest(lf, B_TRUE);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
// pretending to be an object? revert.
|
||||
f = lfhasflag(lf, F_PRETENDSTOBE);
|
||||
if (f) {
|
||||
if (safetorest(lf, NULL)) {
|
||||
object_t *oo;
|
||||
oo = addobfast(lf->cell->obpile, f->val[0]);
|
||||
if (oo) {
|
||||
killflagsofid(oo->flags, F_SIZE);
|
||||
addflag(oo->flags, F_SIZE, getlfsize(lf), NA, NA, NULL);
|
||||
// replace contents object
|
||||
if (oo->contents->first && strlen(f->text)) {
|
||||
killob(oo->contents->first);
|
||||
addob(oo->contents, f->text);
|
||||
}
|
||||
// kill original monster
|
||||
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
lf->hp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1540,7 @@ int ai_healing(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// feigning death with enemies in sight, and hurt?
|
||||
if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) {
|
||||
if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf, NULL)) {
|
||||
if (islowhp(lf)) {
|
||||
if (db) dblog(".oO { i am feigning death and bleeding (hp=%d/%d), skipping turn. }",lf->hp,lf->maxhp);
|
||||
// just wait...
|
||||
|
@ -1532,7 +1565,7 @@ int ai_healing(lifeform_t *lf) {
|
|||
} else if (cansleep(lf)) {
|
||||
// don't have or can't use our healing items
|
||||
// no enemies in sight?
|
||||
if (safetorest(lf)) {
|
||||
if (safetorest(lf, NULL)) {
|
||||
// gods will only sleep/meditate if they are in the realm of gods
|
||||
if (isgod(lf) && (lf->cell->habitat->id != H_HEAVEN)) {
|
||||
} else {
|
||||
|
@ -1898,15 +1931,41 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
if (cansee(lf, target)) {
|
||||
int dist,wantdistmin,wantdistmax;
|
||||
int attackok;
|
||||
flag_t *f;
|
||||
enum OBTYPE spell;
|
||||
object_t *rangedob = NULL;
|
||||
enum RANGEATTACK rangedattack = RA_NONE;
|
||||
int shootrange = 0;
|
||||
int movefailed = B_FALSE;
|
||||
int closethrowok = B_FALSE;
|
||||
object_t *rangedob = NULL;
|
||||
int spellchance = 0;
|
||||
|
||||
if (db) dblog(".oO { can see my target }");
|
||||
|
||||
// see if we have a ranged attack. if so, adjust wantdist
|
||||
// to maintain distance.
|
||||
rangedob = aigetrangedattack(lf, target, &rangedattack, &shootrange);
|
||||
|
||||
// try spells first.
|
||||
// can we attack with spells (ie. ones which target the victim)?
|
||||
// if target is adjacent, we will normally just attack rather than try a spell.
|
||||
|
||||
// random chance of casting a spell
|
||||
f = lfhasflag(lf, F_CASTCHANCE);
|
||||
if (f) spellchance = f->val[0];
|
||||
else spellchance = 30;
|
||||
|
||||
// some attacks can always happen
|
||||
if (cancast(lf, OT_A_THRUST, NULL) && (dist == 2) && haslofknown(lf->cell, target->cell, LOF_NEED, NULL)) {
|
||||
spellchance = 100;
|
||||
}
|
||||
|
||||
if (pctchance(spellchance)) {
|
||||
spell = aigetattackspell(lf, target);
|
||||
} else {
|
||||
spell = OT_NONE;
|
||||
}
|
||||
|
||||
// pet movement
|
||||
if (ismaster) {
|
||||
if (isresting(target)) {
|
||||
|
@ -1943,7 +2002,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
if (wantattack) {
|
||||
if (dist == 1) {
|
||||
attackok = B_TRUE;
|
||||
} else if (!lfhasflag(lf, F_HIDING)) {
|
||||
} else if (!lfhasflag(lf, F_HIDING) || rangedob || (spell != OT_NONE)) {
|
||||
attackok = B_TRUE;
|
||||
} else if (!lfhasflag(lf, F_FEIGNINGDEATH)) {
|
||||
attackok = B_TRUE;
|
||||
|
@ -1952,33 +2011,12 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
|
||||
if (attackok) {
|
||||
objecttype_t *st;
|
||||
flag_t *f;
|
||||
int spellchance = 0;
|
||||
// drink boost potions
|
||||
if (!useitemwithflag(lf, F_AIBOOSTITEM)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// try spells first.
|
||||
// can we attack with spells (ie. ones which target the victim)?
|
||||
// if target is adjacent, we will normally just attack rather than try a spell.
|
||||
|
||||
// random chance of casting a spell
|
||||
f = lfhasflag(lf, F_CASTCHANCE);
|
||||
if (f) spellchance = f->val[0];
|
||||
else spellchance = 30;
|
||||
|
||||
// some attacks can always happen
|
||||
if (cancast(lf, OT_A_THRUST, NULL) && (dist == 2) && haslofknown(lf->cell, target->cell, LOF_NEED, NULL)) {
|
||||
spellchance = 100;
|
||||
}
|
||||
|
||||
if (pctchance(spellchance)) {
|
||||
spell = aigetattackspell(lf, target);
|
||||
} else {
|
||||
spell = OT_NONE;
|
||||
}
|
||||
st = findot(spell);
|
||||
|
||||
if ( (spell != OT_NONE) && // found a valid spell/ability to use
|
||||
// AND one of these:
|
||||
((dist != 1) || // there is distance between us and target
|
||||
|
@ -2065,10 +2103,6 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
}
|
||||
}
|
||||
|
||||
// see if we have a ranged attack. if so, adjust wantdist
|
||||
// to maintain distance.
|
||||
rangedob = aigetrangedattack(lf, target, &rangedattack, &shootrange);
|
||||
|
||||
// for firearms/projectiles, chance to fire/throw depends on accuracy.
|
||||
if ((rangedattack == RA_GUN) || (rangedattack == RA_THROW)) {
|
||||
int chance;
|
||||
|
@ -3057,11 +3091,12 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
}
|
||||
if (ot->id == OT_A_HIDE) {
|
||||
enum ERROR why;
|
||||
if (lfhasflag(lf, F_HIDING)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (lfhasflag(lf, F_FEIGNINGDEATH)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (!safetorest(lf)) {
|
||||
} else if (!safetorest(lf, &why) && (why != E_TOOSOON)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (lfproduceslight(lf, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
|
|
42
attack.c
42
attack.c
|
@ -1621,11 +1621,14 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
makewet(wep, 1);
|
||||
}
|
||||
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
|
||||
// confer flags from weapon
|
||||
wepeffects(wep->flags, victim->cell, damflag, dam[0], isunarmed);
|
||||
// confer flags from attacker themselves
|
||||
wepeffects(lf->flags, victim->cell, damflag, dam[0], isunarmed);
|
||||
}
|
||||
if (!isdead(victim) && !blocked && !dodged) {
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
|
||||
wepeffects(wep->flags, victim->cell, damflag, dam[0], isunarmed);
|
||||
}
|
||||
f = lfhasflag(lf, F_FREEZINGTOUCH);
|
||||
if (f) {
|
||||
int diff;
|
||||
|
@ -1646,10 +1649,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
criticalhit(lf, victim, critpos, wep, dam[0], damtype[0]);
|
||||
}
|
||||
|
||||
// confer flags from attacker?
|
||||
if (dam[0]) {
|
||||
wepeffects(lf->flags, victim->cell, damflag, dam[0], isunarmed);
|
||||
}
|
||||
|
||||
// special lifeform-based effects
|
||||
if ((lf->race->id == R_COCKATRICE) && dam[0]) {
|
||||
|
@ -3306,18 +3305,25 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
}
|
||||
}
|
||||
|
||||
getflags(fp, retflag, &nretflags, F_AUTOTANGLE, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_RACESLAY, F_REVENGE, F_RUSTED, F_NONE);
|
||||
getflags(fp, retflag, &nretflags, F_AUTOTANGLE, F_DRAINONHIT, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER,
|
||||
F_RACESLAY, F_REVENGE, F_RUSTED, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->id == F_AUTOTANGLE) {
|
||||
if ((f->id == F_AUTOTANGLE) && victim && !isdead(victim)) {
|
||||
if (pctchance(f->val[0]) && !hasob(where->obpile, OT_VINE)) {
|
||||
dospelleffects(owner, OT_S_ENTANGLE, f->val[1], victim, NULL, where, B_UNCURSED,
|
||||
NULL, B_FALSE, NULL);
|
||||
f->known = B_KNOWN;
|
||||
}
|
||||
} else if ((f->id == F_DRAINONHIT) && victim && !isdead(victim)) {
|
||||
if (!leveldrain(victim, f->val[0], f->val[1], f->val[2], owner)) {
|
||||
if (strlen(f->text)) {
|
||||
gainhp(owner, roll(f->text));
|
||||
}
|
||||
}
|
||||
} else if (f->id == F_FLAMESTRIKE) {
|
||||
if (!hasob(where->obpile, OT_FIRESMALL)) {
|
||||
// ignite!
|
||||
// ignite
|
||||
addobfast(where->obpile, OT_FIRESMALL);
|
||||
// announce
|
||||
if (haslos(player, where)) {
|
||||
|
@ -3412,6 +3418,18 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
continue;
|
||||
}
|
||||
|
||||
// sometimes we can only hitconfer against certain races
|
||||
if (hasflag(fp, F_HITCONFERRC)) {
|
||||
if (!hasflagval(fp, F_HITCONFERRC, getraceclass(victim), NA, NA, NULL)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (hasflag(fp, F_HITCONFERDEADONLY)) {
|
||||
if (!isdead(victim)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// the f_poisoned flag stacks, others don't.
|
||||
if (!lfhasflag(victim, fid) || (fid == F_POISONED)) {
|
||||
int passedcheck = B_FALSE;
|
||||
|
@ -3482,7 +3500,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
addflag(owner->flags, F_USEDPOISON, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
} else if ((f->id == F_RUSTED) && victim ) {
|
||||
} else if ((f->id == F_RUSTED) && victim && !isdead(victim) ) {
|
||||
int pct;
|
||||
pct = f->val[0] * 10;
|
||||
if (pctchance(pct)) {
|
||||
|
|
118
data.c
118
data.c
|
@ -177,8 +177,9 @@ void initcommands(void) {
|
|||
addcommand(CMD_AGAIN, 'g', "Repeat last action.");
|
||||
addcommand(CMD_REST, '.', "Rest once.");
|
||||
addcommand(CMD_PICKUP, ',', "Pick up something from the ground.");
|
||||
addcommand(CMD_CLOSE, 'c', "Close a door.");
|
||||
addcommand(CMD_COMMS, 'C', "Chat/Communicate with someone.");
|
||||
addcommand(CMD_COMMS, 'c', "Chat/Communicate with someone.");
|
||||
addcommand(CMD_COMMSALL, 'C', "Command all allies.");
|
||||
//addcommand(CMD_COMMS, 'C', "Chat/Communicate with someone.");
|
||||
//addcommand(CMD_DROP, 'd', "Drop an item.");
|
||||
addcommand(CMD_DROPMULTI, 'd', "Drop one or more items.");
|
||||
addcommand(CMD_EAT, 'e', "Eat something.");
|
||||
|
@ -190,7 +191,7 @@ void initcommands(void) {
|
|||
addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion.");
|
||||
addcommand(CMD_READ, 'r', "Read a scroll/book.");
|
||||
addcommand(CMD_RESTFULL, 'R', "Rest until healed, or train your skills.");
|
||||
addcommand(CMD_SLOWWALK, 's', "Step carefully.");
|
||||
addcommand(CMD_CLOSE, 's', "Shut a door.");
|
||||
addcommand(CMD_THROW, 't', "Throw an object.");
|
||||
addcommand(CMD_TAKEOFF, 'T', "Take off an item of clothing/jewelery.");
|
||||
addcommand(CMD_WEILD, 'w', "Weild a weapon.");
|
||||
|
@ -2138,7 +2139,7 @@ void initobjects(void) {
|
|||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addoc(OC_FLORA, "Plants", "Some kind of plant/foliage.", ',', C_GREEN, RR_FREQUENT);
|
||||
addocnoun(lastobjectclass, "plant");
|
||||
addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_GREY, RR_FREQUENT);
|
||||
addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks or plants.", '*', C_STONE, RR_FREQUENT);
|
||||
addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY, RR_FREQUENT);
|
||||
addocnoun(lastobjectclass, "food");
|
||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -2822,6 +2823,15 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
||||
|
||||
// traps - hiding monsters
|
||||
addot(OT_GARGOYLE, "gargoyle", "A sneaky hidden gargoyle!", MT_STONE, 80, OC_TRAP, SZ_HUMAN);
|
||||
addflag(lastot->flags, F_GLYPH, C_STONE, '\'', NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ISMONSTER, R_GARGOYLE, OT_STATUE, 140, "3"); // reveal if within 3 cells
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// traps - object only
|
||||
addot(OT_TRAPNEEDLEP, "poison needle trap", "A springed needle coated with poison.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
|
||||
|
@ -2991,7 +3001,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_FOREST, NA, RR_RARE, "");
|
||||
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_STONE, '\'', NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); // will be overridden
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5903,6 +5913,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 2, NA, NA, NULL);
|
||||
addot(OT_A_TIPTOE, "tiptoe", "Walk carefully to avoid obstacles or slippery floors.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_TRIPLF, "trip", "Attempt to trip your opponent over.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
|
@ -6857,7 +6869,6 @@ void initobjects(void) {
|
|||
// tech - l6 ???
|
||||
|
||||
// misc
|
||||
|
||||
addot(OT_TUSK, "ivory tusk", "A large ivory tusk from a slain elephant. Could be used as weapon by very large creatures.", MT_BONE, 61, OC_MISC, SZ_HUMAN);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 450, NA, NA, NULL);
|
||||
|
@ -12514,6 +12525,47 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
|
||||
|
||||
addrace(R_GARGOYLE, "gargoyle", 220, '\'', C_STONE, MT_STONE, RC_MAGIC, "Gargoyles are winged statues which have been imbued with magical life. These evil creatures delight in tricking unsuspecting adventurers by pretending to be ordinary statues.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addbodypart(lastrace, BP_TAIL, NULL);
|
||||
addbodypart(lastrace, BP_WINGS, NULL);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat");
|
||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_EXHIGH, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SWOOPRANGE, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
|
||||
addflag(lastrace->flags, F_PRETENDSTOBE, OT_GARGOYLE, NA, NA, NULL);
|
||||
|
||||
|
||||
addrace(R_GIANTHILL, "mountain giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID, "Enormous humanoids who dwell in the mountains, using their grat strength to leap between valleys and pelt their prey with enormous boulders.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
|
@ -12897,6 +12949,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTHIDDENPCT, 75, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ATTACKRANGE, 2, 5, NA, NULL); // maintain distance
|
||||
|
@ -19038,6 +19091,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "screechs^an other-wordly screech");
|
||||
|
||||
// undead
|
||||
|
||||
addrace(R_ZOMBIE, "zombie", 50, 'Z', C_BLUE, MT_FLESH, RC_UNDEAD, "The re-animated corpse of a once living entity, zombies seek to consume the brains of living creatures in an attempt to regain their soul.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
|
@ -19074,7 +19128,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "groans^a gutteral groan");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "gurgles^a gurgle");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "growls^a growl");
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
|
||||
|
@ -19107,6 +19160,9 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFER, F_REVIVETIMER, NA, 0, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie");
|
||||
addflag(lastrace->flags, F_HITCONFERDEADONLY, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RANDOMTALKPCT, 20, NA, NA, NULL);
|
||||
|
@ -19116,10 +19172,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "groans^a gutteral groan");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "gurgles^a gurgle");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "growls^a growl");
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFER, F_REVIVETIMER, SC_POISON, 165, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie");
|
||||
|
||||
addrace(R_SKELETON, "skeleton", 20, 'Z', C_BONE, MT_BONE, RC_UNDEAD, "A walking set of bones, animated through the use of necromancy. Due to their lack of soft flesh, they have little to fear from edged weapons.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
|
@ -19161,7 +19214,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_DTVULN, DT_FALL, NA, NA, "1d3+3");
|
||||
addflag(lastrace->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FOLLOWTIME, 0, NA, NA, NULL);
|
||||
|
||||
|
@ -19202,7 +19254,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_DTVULN, DT_FALL, NA, NA, "1d3+3");
|
||||
addflag(lastrace->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
addrace(R_SKELLION, "skellion", 10, 'r', C_RED, MT_BONE, RC_UNDEAD, "A floating skull, immersed in flames. Skellions are often created when attempting to animate a beheaded corpse.");
|
||||
|
@ -19236,6 +19287,36 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FOLLOWTIME, 10, NA, NA, NULL);
|
||||
|
||||
addrace(R_WIGHT, "wight", 50, 'Z', C_LIGHTBLUE, MT_FLESH, RC_UNDEAD, "A twisted and misshappen creature of evil, vague recognisable as humanoid.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
|
||||
addflag(lastrace->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHNECROTIC, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFER, F_REVIVETIMER, NA, 0, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFERVALS, 0, 1, R_WIGHT, "rises up as a wight");
|
||||
addflag(lastrace->flags, F_HITCONFERRC, RC_HUMANOID, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITCONFERDEADONLY, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DRAINONHIT, 1, SC_CON, 100, "1d0+5");
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
|
||||
addrace(R_WRAITHBOG, "bog wraith", 20, 'Z', C_BROWN, MT_PLANT, RC_UNDEAD, "Bog wraiths take the form of vaguely humanoid blobs of putrid mud.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
|
@ -19264,7 +19345,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "undulates");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screech");
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
@ -19335,7 +19415,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NONCORPOREAL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -19366,7 +19445,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
addrace(R_GHOST, "ghost", 50, 'p', C_GREY, MT_FLESH, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit
|
||||
|
@ -19438,7 +19516,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
|
@ -19507,7 +19584,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FOLLOWTIME, 30, NA, NA, NULL);
|
||||
|
||||
|
@ -19548,11 +19624,10 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FOLLOWTIME, 50, NA, NA, NULL);
|
||||
|
||||
addrace(R_REVENANT, "revenant", 60, 'Z', C_LIGHTBLUE, MT_FLESH, RC_UNDEAD, "A powerful zombie which retains full memory of its former life and abilities.");
|
||||
addrace(R_REVENANT, "revenant", 60, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD, "A powerful zombie which retains full memory of its former life and abilities.");
|
||||
setbodytype(lastrace, BT_HUMANOID);
|
||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
|
||||
|
@ -19855,7 +19930,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -19886,7 +19960,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -19917,7 +19990,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -19941,7 +20013,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -20087,6 +20158,7 @@ void initrace(void) {
|
|||
addflag(r->flags, F_NORESTHEAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
|
||||
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// +/- 15 accuracy during day/night
|
||||
addflag(r->flags, F_NIGHTBOOST, 15, NA, NA, NULL);
|
||||
addflag(r->flags, F_DAYBOOST, -15, NA, NA, NULL);
|
||||
|
|
35
defs.h
35
defs.h
|
@ -111,6 +111,9 @@
|
|||
|
||||
#define B_BLINDABLE (-1)
|
||||
|
||||
#define B_ALLOWEXTRA (-1)
|
||||
#define B_NOEXTRA (0)
|
||||
|
||||
#define B_ADD 1
|
||||
#define B_REMOVE -1
|
||||
|
||||
|
@ -709,6 +712,7 @@ enum COLOUR {
|
|||
C_CARPET1,
|
||||
C_CARPET2,
|
||||
C_SMOKE,
|
||||
C_STONE,
|
||||
C_WOOD,
|
||||
// dark colours
|
||||
C_DARKCYAN,
|
||||
|
@ -1295,6 +1299,7 @@ enum RACE {
|
|||
R_DRYAD,
|
||||
R_EFREETI,
|
||||
R_EYEBAT,
|
||||
R_GARGOYLE,
|
||||
R_GIANTHILL,
|
||||
R_GIANTFIRE,
|
||||
R_GIANTFIREFC,
|
||||
|
@ -1512,6 +1517,7 @@ enum RACE {
|
|||
R_SKELETONFIRE,
|
||||
R_SKELLION,
|
||||
R_VAMPIRE,
|
||||
R_WIGHT,
|
||||
R_WRAITHBOG,
|
||||
R_WRAITHICE,
|
||||
R_ZOMBIE,
|
||||
|
@ -1717,6 +1723,8 @@ enum OBTYPE {
|
|||
OT_TRAPTELEPORT,
|
||||
OT_TRAPTRIP,
|
||||
OT_TRAPWIND,
|
||||
// traps - hiding monsters
|
||||
OT_GARGOYLE,
|
||||
// rocks
|
||||
OT_ASH,
|
||||
OT_ASHLARGE,
|
||||
|
@ -2177,6 +2185,7 @@ enum OBTYPE {
|
|||
OT_A_SUCKBLOOD,
|
||||
OT_A_SWALLOW,
|
||||
OT_A_SWOOP,
|
||||
OT_A_TIPTOE,
|
||||
OT_A_TRIPLF, // trip an opponent
|
||||
OT_A_EMPLOY,
|
||||
OT_A_EXPOSEDSTRIKE,
|
||||
|
@ -2960,6 +2969,15 @@ enum FLAG {
|
|||
F_CORPSEOF, // this is a corpse of montype val0.
|
||||
// v1 is its level when it died
|
||||
// text is how it died.
|
||||
F_ISMONSTER, // this object is really a mosnter staying still to
|
||||
// trick you!
|
||||
// v0 = race id of monster
|
||||
// v1 = object id to hide as
|
||||
// v2 = spot check difficulty (or NA)
|
||||
// text = reveal ourselves if prey <= this distance
|
||||
//
|
||||
// Also see: F_PRETENDSTOBE
|
||||
|
||||
F_REVIVETIMER, // v0 = cur, v1 = max. v0 incremenets each tick.
|
||||
// when v0 == v1, this object changes into lf of race
|
||||
// v2.
|
||||
|
@ -2998,6 +3016,10 @@ enum FLAG {
|
|||
// text
|
||||
|
||||
F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit
|
||||
F_DRAINONHIT, // victims hit by this lf get v0 xplevs drained unless
|
||||
// they pass a skillcheck of type v1, diff v2.
|
||||
// v1 can be NA.
|
||||
// if successful, lf gains 'text' hp (in dice format)
|
||||
F_HITCONFER, // hitting with this gives flagid=v0
|
||||
// with timeleft = text ("min-max"
|
||||
// or NULL for permenant)
|
||||
|
@ -3005,6 +3027,9 @@ enum FLAG {
|
|||
// if val1 = NA, no check.
|
||||
// MUST ALSO HAVE HITCONFERVALS.
|
||||
F_HITCONFERVALS,// specifies values for conferred flag.
|
||||
F_HITCONFERRC, // hitconfer only works against victims of raceclass
|
||||
// v0
|
||||
F_HITCONFERDEADONLY, // hitconfer only works on fatal hits
|
||||
F_ACTIVATED, // val0 = is this object turned on?
|
||||
F_GRENADE, // this object will drain charge when activated, then die
|
||||
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
|
||||
|
@ -4139,6 +4164,13 @@ enum FLAG {
|
|||
F_PARALYZED,// cannot do anything
|
||||
F_PARANOIA, // mosnters randomly appear out of sight, or random
|
||||
// noises happen from behind you.
|
||||
F_PRETENDSTOBE, // this lf will pretend to be object v0.
|
||||
// when bored, revert to an ob of type v0.
|
||||
//
|
||||
// if 'text' is set, then v0's contents object
|
||||
// should be this.
|
||||
//
|
||||
// Also see: F_ISMONSTER
|
||||
F_PRONE, // lying on the ground
|
||||
F_FROZEN, // made of ice
|
||||
F_HEAVENARM, // prevent the next v0 damage received.
|
||||
|
@ -4469,6 +4501,7 @@ enum ERROR {
|
|||
E_OBINWAY,
|
||||
E_TOOHEAVY,
|
||||
E_TOOHARD,
|
||||
E_TOOSOON,
|
||||
E_NOHANDS,
|
||||
E_NOPACK,
|
||||
E_INSUBSTANTIAL,
|
||||
|
@ -4565,6 +4598,7 @@ enum COMMAND {
|
|||
CMD_AIM,
|
||||
CMD_CLOSE,
|
||||
CMD_COMMS,
|
||||
CMD_COMMSALL,
|
||||
CMD_DOWN,
|
||||
CMD_DROP,
|
||||
CMD_DROPMULTI,
|
||||
|
@ -4597,7 +4631,6 @@ enum COMMAND {
|
|||
CMD_REST,
|
||||
CMD_RESTFULL,
|
||||
CMD_SAVEQUIT,
|
||||
CMD_SLOWWALK,
|
||||
CMD_TAKEOFF,
|
||||
CMD_THROW,
|
||||
CMD_UP,
|
||||
|
|
2
god.c
2
god.c
|
@ -737,7 +737,7 @@ void dooffer(void) {
|
|||
if ((god->race->id == R_GODNATURE) &&
|
||||
(o->type->obclass->id == OC_FLORA) &&
|
||||
newcell) {
|
||||
addmonster(player->cell, R_BUTTERFLY, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
addmonster(player->cell, R_BUTTERFLY, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
}
|
||||
|
||||
if (o->type->obclass->id == OC_FLORA) {
|
||||
|
|
349
io.c
349
io.c
|
@ -4441,160 +4441,30 @@ void doclose(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void docomms(lifeform_t *lf) {
|
||||
cell_t *where = NULL;
|
||||
int i;
|
||||
int askforob = B_FALSE;
|
||||
void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
|
||||
char lfname[BUFLEN], lfname2[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
char ch;
|
||||
//int moneyowing = 0;
|
||||
enum ATTRBRACKET iqb;
|
||||
flag_t *f;
|
||||
cell_t *c;
|
||||
lifeform_t *lf2 = NULL;
|
||||
char lfname2[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
int count;
|
||||
int alignmod = 0;
|
||||
cell_t *c;
|
||||
flag_t *f;
|
||||
object_t *o, *givenob = NULL;
|
||||
object_t *godstone = NULL;
|
||||
if (!lf) {
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
}
|
||||
if (!lf) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
int askforob = B_FALSE;
|
||||
|
||||
alignmod = getalignmod(lf);
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
|
||||
snprintf(buf, BUFLEN, "What will you say to %s?",lfname);
|
||||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
|
||||
// are they friendly?
|
||||
if (ispetof(lf, player)) {
|
||||
if ((iqb >= IQ_ANIMAL) || isundead(lf)) {
|
||||
addchoice(&prompt, 'a', "Attack something", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (!isadjacent(lf->cell, player->cell)) {
|
||||
addchoice(&prompt, 'c', "Come here", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
addchoice(&prompt, 'g', "Go somewhere", NULL, NULL, NULL);
|
||||
|
||||
if (isadjacent(lf->cell, player->cell) && !lfhasflag(lf, F_NOPACK)) {
|
||||
addchoice(&prompt, 't', "Trade items with me", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (iqb >= IQ_ANIMAL) {
|
||||
f = isresting(lf);
|
||||
if (f) {
|
||||
addchoice(&prompt, 'r', "Stop resting.", NULL, NULL, NULL);
|
||||
} else {
|
||||
addchoice(&prompt, 'r', "Rest until you are healed.", NULL, NULL, NULL);
|
||||
}
|
||||
addchoice(&prompt, '<', "Stay close.", NULL, NULL, NULL);
|
||||
addchoice(&prompt, '>', "Keep your distance.", NULL, NULL, NULL);
|
||||
}
|
||||
} else if (ishirable(lf) ) {
|
||||
if (lfhasflag(lf, F_ISPRISONER)) {
|
||||
addchoice(&prompt, 'j', "Join me, and I will help you escape.", NULL, NULL, NULL);
|
||||
} else if (getskill(player, SK_SPEECH) >= PR_EXPERT) {
|
||||
addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isgod(lf) && ispeaceful(lf) && cantalk(lf)) {
|
||||
enum SKILLLEVEL slev;
|
||||
job_t *j;
|
||||
slev = getskill(player, SK_SPEECH);
|
||||
// same race or job?
|
||||
j = getjob(player);
|
||||
if ((slev != PR_MASTER) && j && (j == getjob(lf))) slev++;
|
||||
if ((slev != PR_MASTER) && (player->race->id == lf->race->id)) slev++;
|
||||
if (slev >= PR_NOVICE) {
|
||||
addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
|
||||
}
|
||||
if (slev >= PR_BEGINNER) {
|
||||
addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL);
|
||||
}
|
||||
if (!areallies(player, lf)) {
|
||||
if (slev >= PR_SKILLED) {
|
||||
addchoice(&prompt, 'k', "Care to trade knowledge?", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isadjacent(lf->cell, player->cell)) {
|
||||
if (areenemies(player, lf)) {
|
||||
addchoice(&prompt, 'm', "Have mercy!", NULL, NULL, NULL);
|
||||
}
|
||||
// if you are allies, use 'trade items' instead
|
||||
if (!areallies(player, lf)) {
|
||||
if (isgod(lf)) {
|
||||
// may only donate the godstone
|
||||
godstone = hasob(player->pack, getopposinggodstone(lf->race->id));
|
||||
if (godstone) {
|
||||
char buf[BUFLEN],obname[BUFLEN];
|
||||
getobname(godstone, obname, 1);
|
||||
sprintf(buf, "(offer %s)", obname);
|
||||
addchoice(&prompt, 'o', buf, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
addchoice(&prompt, 'o', "(offer a bribe)", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
f = lfhasflag(lf, F_OWNSSHOP);
|
||||
if (f) {
|
||||
int shopid;
|
||||
shopid = f->val[0];
|
||||
moneyowing = getowing(player, shopid, NULL);
|
||||
if (moneyowing > 0) {
|
||||
snprintf(buf, BUFLEN, "(pay $%d to the shopkeeper)",moneyowing);
|
||||
addchoice(&prompt, 'p', buf, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'n', "(nothing)", NULL, NULL, NULL);
|
||||
|
||||
ch = getchoice(&prompt);
|
||||
if ((ch == 'n') || (ch == '\0')) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
if (lf2) {
|
||||
getlfname(lf2, lfname2);
|
||||
} else {
|
||||
strcpy(lfname2, "?noone?");
|
||||
}
|
||||
|
||||
// process command
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
snprintf(buf, BUFLEN, "Tell %s to attack who?",lfname);
|
||||
snprintf(buf2, BUFLEN, "%s->Attack->",lfname);
|
||||
c = askcoords(buf, buf2, TT_MONSTER, lf, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && c->lf) {
|
||||
lf2 = c->lf;
|
||||
}
|
||||
if (!lf2) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
getlfname(lf2, lfname2);
|
||||
msg("You say \"Attack %s!\" to %s.",isplayer(lf2) ? "me" : lfname2, lfname);
|
||||
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4624,7 +4494,6 @@ void docomms(lifeform_t *lf) {
|
|||
}
|
||||
break;
|
||||
case 'c':
|
||||
msg("You say \"Come here!\" to %s.",lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4857,17 +4726,8 @@ void docomms(lifeform_t *lf) {
|
|||
|
||||
break;
|
||||
case 'g':
|
||||
snprintf(buf, BUFLEN, "Tell %s to go where?",lfname);
|
||||
snprintf(buf2, BUFLEN, "%s->Goto->",lfname);
|
||||
c = askcoords(buf, buf2, TT_NONE, lf, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && cellwalkable(lf, c, NULL) ) {
|
||||
} else {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
// stop attacking all current targets first...
|
||||
killflagsofid(lf->flags, F_TARGETLF);
|
||||
msg("You say \"Go over there!\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4876,10 +4736,9 @@ void docomms(lifeform_t *lf) {
|
|||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
}
|
||||
aigoto(lf, c, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
|
||||
aigoto(lf, targc, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
|
||||
break;
|
||||
case 'i':
|
||||
msg("You say \"What can you tell me about this area?\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_PHANTASM)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4891,7 +4750,6 @@ void docomms(lifeform_t *lf) {
|
|||
break;
|
||||
case 'j':
|
||||
// charisma check to see if they'll join you.
|
||||
msg("You say \"Join me on my quest!\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4903,7 +4761,6 @@ void docomms(lifeform_t *lf) {
|
|||
recruit(lf);
|
||||
break;
|
||||
case 'k': // trade Knowledge
|
||||
msg("You say \"Care to trade knowledge?\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_PHANTASM)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4911,7 +4768,6 @@ void docomms(lifeform_t *lf) {
|
|||
tradeknowledge(lf);
|
||||
break;
|
||||
case 'm': // mercy
|
||||
msg("You say \"Have mercy!\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_PHANTASM)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4982,7 +4838,6 @@ void docomms(lifeform_t *lf) {
|
|||
break;
|
||||
*/
|
||||
case 'r':
|
||||
msg("You say \"Get some rest.\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -4996,7 +4851,8 @@ void docomms(lifeform_t *lf) {
|
|||
stopresting(lf);
|
||||
} else {
|
||||
if (needstorest(lf, NULL)) {
|
||||
if (safetorest(lf)) {
|
||||
enum ERROR why;
|
||||
if (safetorest(lf, &why) || (why == E_TOOSOON)) {
|
||||
addflag(lf->flags, F_RESTUNTILBETTER, B_TRUE, NA, NA, NULL);
|
||||
startresting(lf, B_FALSE);
|
||||
} else {
|
||||
|
@ -5040,7 +4896,6 @@ void docomms(lifeform_t *lf) {
|
|||
}
|
||||
break;
|
||||
case 'x':
|
||||
msg("You say \"Any dangers nearby that I should look out for?\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_PHANTASM)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -5051,11 +4906,9 @@ void docomms(lifeform_t *lf) {
|
|||
}
|
||||
break;
|
||||
case 'y':
|
||||
msg("You shout at %s!", lfname);
|
||||
noise(where, player, NC_OTHER, 3, "someone shouting!", NULL);
|
||||
noise(player->cell, player, NC_OTHER, 3, "someone shouting!", NULL);
|
||||
break;
|
||||
case '<':
|
||||
msg("You say \"Stay close!\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -5067,7 +4920,6 @@ void docomms(lifeform_t *lf) {
|
|||
setfollowdistance(lf, 1, 3);
|
||||
break;
|
||||
case '>':
|
||||
msg("You say \"Keep your distance!\" to %s.", lfname);
|
||||
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
|
||||
msg("%s doesn't respond.", lfname);
|
||||
break;
|
||||
|
@ -5079,9 +4931,173 @@ void docomms(lifeform_t *lf) {
|
|||
setfollowdistance(lf, 3, 5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void docommsmulti(void) {
|
||||
lifeform_t *ally[MAX_MAPW*MAX_MAPH],*l,*lfarg;
|
||||
cell_t *cellarg,*origc = NULL;
|
||||
int nallies = 0,i;
|
||||
char buf[BUFLEN],ch;
|
||||
|
||||
snprintf(buf, BUFLEN, "What will you command your allies to do?");
|
||||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
|
||||
// find all allies on the map who can hear the player
|
||||
for (l = player->cell->map->lf ; l ; l = l->next) {
|
||||
if ((l != player) && (getallegiance(l) == AL_FRIENDLY)) {
|
||||
ally[nallies] = l;
|
||||
nallies++;
|
||||
// add options to say to this person
|
||||
makecommslist(&prompt, l, B_TRUE);
|
||||
}
|
||||
}
|
||||
// ask what to say to them all
|
||||
ch = getchoice(&prompt);
|
||||
if ((ch == 'n') || (ch == '\0')) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (getcommsopts(ch, "Allies", &lfarg, &cellarg)) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
announcecomms(ch, "your allies", lfarg, cellarg);
|
||||
|
||||
origc = cellarg;
|
||||
for (i = 0; i < nallies; i++) {
|
||||
docommslf(ally[i], ch, lfarg, cellarg);
|
||||
if (ch == 'g') {
|
||||
// pick a new cell
|
||||
cellarg = getrandomadjcell(cellarg, &ccwalkable, B_ALLOWEXPAND);
|
||||
if (!cellarg) cellarg = origc;
|
||||
|
||||
}
|
||||
}
|
||||
taketime(player, getactspeed(player));
|
||||
}
|
||||
|
||||
void announcecomms(char ch, char *talkto, lifeform_t *lfarg, cell_t *cellarg) {
|
||||
char lfname2[BUFLEN];
|
||||
if (lfarg) {
|
||||
getlfname(lfarg, lfname2);
|
||||
}
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
msg("You say \"Attack %s!\" to %s.",isplayer(lfarg) ? "me" : lfname2, talkto);
|
||||
break;
|
||||
case 'c':
|
||||
msg("You say \"Come here!\" to %s.",talkto);
|
||||
break;
|
||||
case 'g':
|
||||
msg("You say \"Go over there!\" to %s.", talkto);
|
||||
break;
|
||||
case 'i':
|
||||
msg("You say \"What can you tell me about this area?\" to %s.", talkto);
|
||||
break;
|
||||
case 'j':
|
||||
msg("You say \"Join me on my quest!\" to %s.", talkto);
|
||||
break;
|
||||
case 'k': // trade Knowledge
|
||||
msg("You say \"Care to trade knowledge?\" to %s.", talkto);
|
||||
break;
|
||||
case 'm': // mercy
|
||||
msg("You say \"Have mercy!\" to %s.", talkto);
|
||||
break;
|
||||
case 'r':
|
||||
msg("You say \"Get some rest.\" to %s.", talkto);
|
||||
break;
|
||||
case 'x':
|
||||
msg("You say \"Any dangers nearby that I should look out for?\" to %s.", talkto);
|
||||
break;
|
||||
case 'y':
|
||||
msg("You shout at %s!", talkto);
|
||||
break;
|
||||
case '<':
|
||||
msg("You say \"Stay close!\" to %s.", talkto);
|
||||
break;
|
||||
case '>':
|
||||
msg("You say \"Keep your distance!\" to %s.", talkto);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void docomms(lifeform_t *lf) {
|
||||
cell_t *where = NULL;
|
||||
char buf[BUFLEN],lfname[BUFLEN];
|
||||
char ch;
|
||||
lifeform_t *lfarg;
|
||||
cell_t *cellarg;
|
||||
//int moneyowing = 0;
|
||||
if (!lf) {
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
}
|
||||
if (!lf) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
snprintf(buf, BUFLEN, "What will you say to %s?",lfname);
|
||||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
|
||||
|
||||
makecommslist(&prompt, lf, B_FALSE);
|
||||
|
||||
ch = getchoice(&prompt);
|
||||
if ((ch == 'n') || (ch == '\0')) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
|
||||
getcommsopts(ch, lfname, &lfarg, &cellarg);
|
||||
|
||||
announcecomms(ch, lfname, lfarg, cellarg);
|
||||
docommslf(lf, ch, lfarg, cellarg);
|
||||
|
||||
taketime(player, getactspeed(player));
|
||||
}
|
||||
|
||||
// return true on error
|
||||
int getcommsopts(char ch, char *talkto, lifeform_t **retlf, cell_t **retcell) {
|
||||
cell_t *c;
|
||||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
|
||||
*retlf = NULL;
|
||||
*retcell = NULL;
|
||||
|
||||
// get other options for comms...
|
||||
switch (ch) {
|
||||
case 'a': // who to attack?
|
||||
snprintf(buf, BUFLEN, "Tell %s to attack who?",talkto);
|
||||
snprintf(buf2, BUFLEN, "%s->Attack->",talkto);
|
||||
c = askcoords(buf, buf2, TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && c->lf) {
|
||||
*retlf = c->lf;
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
case 'g': // go where?
|
||||
snprintf(buf, BUFLEN, "Tell %s to go where?",talkto);
|
||||
snprintf(buf2, BUFLEN, "%s->Goto->",talkto);
|
||||
*retcell = askcoords(buf, buf2, TT_NONE, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (! (*retcell)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// lf is the person (if any) who you are talking to
|
||||
void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf) {
|
||||
int x,y,ndone;
|
||||
|
@ -9682,6 +9698,7 @@ void initgfx(void) {
|
|||
initcol(C_CARPET1, 560, 280, 136);
|
||||
initcol(C_CARPET2, 360, 80, 36);
|
||||
initcol(C_SMOKE, 250, 250, 300);
|
||||
initcol(C_STONE, 800, 800, 800);
|
||||
initcol(C_WOOD, 384, 244, 64);
|
||||
// dark cols
|
||||
initcol(C_DARKCYAN, 0, 500, 500);
|
||||
|
@ -10783,9 +10800,6 @@ void handleinput(void) {
|
|||
drawscreen();
|
||||
}
|
||||
break;
|
||||
case CMD_SLOWWALK: // slowwalk
|
||||
trysneak(player, D_NONE);
|
||||
break;
|
||||
case CMD_REST: // wait
|
||||
addflag(player->flags, F_LASTCMD, NA, NA, NA, temp);
|
||||
if (count > 1) {
|
||||
|
@ -10878,6 +10892,9 @@ void handleinput(void) {
|
|||
case CMD_COMMS: // communicate
|
||||
docomms(NULL);
|
||||
break;
|
||||
case CMD_COMMSALL: // communicate
|
||||
docommsmulti();
|
||||
break;
|
||||
case CMD_EAT: // eat
|
||||
doeat(player->pack);
|
||||
break;
|
||||
|
|
3
io.h
3
io.h
|
@ -14,6 +14,7 @@ void animradial(cell_t *src, int radius, int ch, int colour, int dirtype, char *
|
|||
void animsky(cell_t *src, char ch, int colour);
|
||||
//void announceob(enum OBTYPE oid);
|
||||
void announcearrival(lifeform_t *lf, map_t *newmap);
|
||||
void announcecomms(char ch, char *talkto, lifeform_t *lfarg, cell_t *cellarg);
|
||||
int announceflaggain(lifeform_t *lf, flag_t *f);
|
||||
int announceflagloss(lifeform_t *lf, flag_t *f);
|
||||
int announceobflaggain(object_t *o, flag_t *f);
|
||||
|
@ -51,6 +52,7 @@ void describespell(objecttype_t *ot);
|
|||
void doattackcell(int dir);
|
||||
void doclose(void);
|
||||
void docomms(lifeform_t *target);
|
||||
void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc);
|
||||
void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf);
|
||||
void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf);
|
||||
void dodrop(obpile_t *op, int wantmulti, obpile_t *dst);
|
||||
|
@ -103,6 +105,7 @@ void forceredraw(void);
|
|||
enum COLOUR getattrcolour(enum ATTRBRACKET brack);
|
||||
char getchoice(prompt_t *prompt);
|
||||
char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart);
|
||||
int getcommsopts(char ch, char *talkto, lifeform_t **retlf, cell_t **retcell);
|
||||
int getkey(int escseqok);
|
||||
enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev);
|
||||
void handle_ctrl_y(int arg);
|
||||
|
|
304
lf.c
304
lf.c
|
@ -516,7 +516,10 @@ int calcxp(lifeform_t *lf) {
|
|||
|
||||
// extra 'spells'
|
||||
if (hasflag(lf->race->flags, F_INDUCEFEAR)) {
|
||||
spells += 10;
|
||||
spells += 5;
|
||||
}
|
||||
if (hasflag(lf->race->flags, F_DRAINONHIT)) {
|
||||
spells += 15;
|
||||
}
|
||||
|
||||
// TOTAL:
|
||||
|
@ -2644,9 +2647,10 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
int check_rest_ok(lifeform_t *lf) {
|
||||
if (!safetorest(lf)) {
|
||||
enum ERROR why;
|
||||
if (!safetorest(lf, &why)) {
|
||||
if (isplayer(lf)) {
|
||||
switch (reason) {
|
||||
switch (why) {
|
||||
case E_LEVITATING:
|
||||
msg("You cannot rest while levitating in mid-air!");
|
||||
break;
|
||||
|
@ -2671,7 +2675,7 @@ int check_rest_ok(lifeform_t *lf) {
|
|||
|
||||
lifeform_t *clonelf(lifeform_t *src, cell_t *where) {
|
||||
lifeform_t *lf;
|
||||
lf = addmonster(where, src->race->id, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
lf = addmonster(where, src->race->id, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
if (lf) {
|
||||
killflagsofid(lf->flags, F_XPVAL);
|
||||
addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
|
@ -3403,6 +3407,59 @@ void die(lifeform_t *lf) {
|
|||
}
|
||||
more(); drawmsg();
|
||||
|
||||
if (!vaporised) {
|
||||
flag_t *retflag[MAXCANDIDATES], *f;
|
||||
int nretflags,i;
|
||||
|
||||
|
||||
f = hasflag(lf->flags, F_REVIVETIMER);
|
||||
if (f) {
|
||||
race_t *r;
|
||||
r = findrace(f->val[2]);
|
||||
if (f) {
|
||||
strcpy(reanimateas, r->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlen(reanimateas)) {
|
||||
// killed by a vampire = vampire.
|
||||
if (killer) {
|
||||
switch (killer->race->id) {
|
||||
case R_VAMPIRE: sprintf(reanimateas, "vampire"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// died by eating your own race = ghoul.
|
||||
// died by eating a vampire corpse = vampire.
|
||||
if (!strlen(reanimateas)) {
|
||||
getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->val[2] == R_VAMPIRE) {
|
||||
sprintf(reanimateas, "vampire");
|
||||
} else if (retflag[i]->val[2] == lf->race->baseid) {
|
||||
sprintf(reanimateas, "ghoul");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hecta-worshippers often get reanimated.
|
||||
if (!strlen(reanimateas) && thisisplayer && godprayedto(R_GODDEATH)) {
|
||||
if (onein(3)) {
|
||||
switch (rnd(1,2)) {
|
||||
case 1:
|
||||
sprintf(reanimateas, "zombie");
|
||||
break;
|
||||
case 2:
|
||||
sprintf(reanimateas, "skeleton");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// god effects...
|
||||
if (!vaporised) {
|
||||
god = getrandomprayedgod();
|
||||
|
@ -3968,53 +4025,16 @@ void die(lifeform_t *lf) {
|
|||
addflag(lf->flags, F_LIFEOB, NA, 5, 2, cid);
|
||||
}
|
||||
} else {
|
||||
// Will the dead lf get reanimated up as a monster ?
|
||||
// Will the dead player get reanimated up as a monster in bones files?
|
||||
//
|
||||
if (!vaporised) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags,i;
|
||||
// killed by a vampire = vampire.
|
||||
if (killer) {
|
||||
switch (killer->race->id) {
|
||||
case R_VAMPIRE: sprintf(reanimateas, "vampire"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// died by eating your own race = ghoul.
|
||||
// died by eating a vampire corpse = vampire.
|
||||
if (!strlen(reanimateas)) {
|
||||
getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->val[2] == R_VAMPIRE) {
|
||||
sprintf(reanimateas, "vampire");
|
||||
} else if (retflag[i]->val[2] == lf->race->baseid) {
|
||||
sprintf(reanimateas, "ghoul");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hecta-worshippers often get reanimated.
|
||||
if (!strlen(reanimateas) && thisisplayer && godprayedto(R_GODDEATH)) {
|
||||
if (onein(3)) {
|
||||
switch (rnd(1,2)) {
|
||||
case 1:
|
||||
sprintf(reanimateas, "zombie");
|
||||
break;
|
||||
case 2:
|
||||
sprintf(reanimateas, "skeleton");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// announce
|
||||
if (strlen(reanimateas)) {
|
||||
if (thisisplayer || cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("^%c%s%s corpse rises up as %s %s!^n",
|
||||
C_MAGENTA,
|
||||
getlfcol(player, CC_VBAD),
|
||||
lfname, getpossessive(lfname),
|
||||
needan(reanimateas) ? "an" : "a", reanimateas);
|
||||
}
|
||||
|
@ -4034,7 +4054,7 @@ void die(lifeform_t *lf) {
|
|||
// UNLESS WE ARE _SURE_ IT IS THE PLAYER (ie. thisisplayer = true)
|
||||
if (createrace != R_NONE) {
|
||||
lifeform_t *newlf;
|
||||
newlf = addmonster(where, createrace, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
newlf = addmonster(where, createrace, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
if (newlf) {
|
||||
// no xp for killing
|
||||
killflagsofid(newlf->flags, F_XPVAL);
|
||||
|
@ -4047,7 +4067,7 @@ void die(lifeform_t *lf) {
|
|||
// add two new worms nearby, with less hp.
|
||||
for (i = 0;i < 2; i++) {
|
||||
lifeform_t *newlf;
|
||||
newlf = addmonster(dividecell[i], dividerace, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
newlf = addmonster(dividecell[i], dividerace, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
if (newlf) {
|
||||
// half hp
|
||||
f = hasflag(newlf->flags, F_HITDICE);
|
||||
|
@ -4090,7 +4110,7 @@ void die(lifeform_t *lf) {
|
|||
// remove the corpse...
|
||||
if (corpse) killob(corpse);
|
||||
// add the reanimated monster
|
||||
addmonster(c, R_SPECIFIED, reanimateas, B_FALSE, 1, B_FALSE, NULL);
|
||||
addmonster(c, R_SPECIFIED, reanimateas, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4867,7 +4887,7 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
setlastdam(lf, "merging with a corpse");
|
||||
lf->lastdamtype = DT_DIRECT;
|
||||
lf->hp = 0;
|
||||
newlf = makezombie(o, 0, "rises from the dead");
|
||||
newlf = makezombie(o, 0, "rises from the dead", NULL);
|
||||
if (newlf) {
|
||||
addflag(newlf->flags, F_CORPSELF, R_LINGPARASITE, NA, NA, NULL);
|
||||
}
|
||||
|
@ -10639,10 +10659,14 @@ enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker) {
|
|||
return selbp;
|
||||
}
|
||||
|
||||
race_t *getrandomcorpserace(cell_t *c) {
|
||||
race_t *getrandomcorpserace(cell_t *c, enum LFSIZE wantsize) {
|
||||
condset_t cs;
|
||||
initcondv(&cs, CC_HASCORPSE, B_TRUE, NA, CC_NONE);
|
||||
|
||||
if (wantsize != SZ_ANY) {
|
||||
addcond(&cs, CC_HASSIZE, B_TRUE, wantsize);
|
||||
}
|
||||
|
||||
return getrandomrace(c, NA, &cs);
|
||||
}
|
||||
|
||||
|
@ -11406,6 +11430,8 @@ long getxpforlev(int level) {
|
|||
float multiplier = 13;
|
||||
float constant = 2.8;
|
||||
|
||||
if (level <= 0) return 0;
|
||||
|
||||
// no xp needed for level 1
|
||||
/*
|
||||
for (i = 0; i < level - 1; i++) {
|
||||
|
@ -13506,13 +13532,13 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR
|
|||
|
||||
|
||||
// return TRUE on failure
|
||||
int leveldrain(lifeform_t *lf, int amt, int power, lifeform_t *fromlf) {
|
||||
int leveldrain(lifeform_t *lf, int amt, enum CHECKTYPE sctype, int scdiff, lifeform_t *fromlf) {
|
||||
int resisted = B_FALSE;
|
||||
if (isimmuneto(lf->flags, DT_NECROTIC, B_FALSE)) resisted = B_TRUE;
|
||||
if (!resisted && isresistantto(lf->flags, DT_NECROTIC, B_FALSE) && onein(2)) resisted = B_TRUE;
|
||||
|
||||
// fit check
|
||||
if (!resisted && skillcheck(lf, SC_CON, 100+(power*6), 0 )) {
|
||||
if (!resisted && skillcheck(lf, sctype, scdiff, 0 )) {
|
||||
resisted = B_TRUE;
|
||||
}
|
||||
if (resisted) {
|
||||
|
@ -14975,7 +15001,6 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
|||
assert(!cell->type->solid);
|
||||
}
|
||||
|
||||
|
||||
m = cell->map;
|
||||
|
||||
// add to the end of the list
|
||||
|
@ -15564,7 +15589,7 @@ void makepeaceful(lifeform_t *who, lifeform_t *causedby) {
|
|||
|
||||
// 'power' is 0-10, determines how poewrful the zombie is.
|
||||
// if 0, don't do any special changes.
|
||||
lifeform_t *makezombie(object_t *o, int power, char *description) {
|
||||
lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *master) {
|
||||
flag_t *f;
|
||||
race_t *r;
|
||||
lifeform_t *lf;
|
||||
|
@ -15671,6 +15696,10 @@ lifeform_t *makezombie(object_t *o, int power, char *description) {
|
|||
msg("^W%s %s!", obname, description);
|
||||
}
|
||||
|
||||
if (master) {
|
||||
petify(lf, master);
|
||||
}
|
||||
|
||||
return lf;
|
||||
}
|
||||
|
||||
|
@ -17364,7 +17393,7 @@ void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) {
|
|||
statdirty = B_TRUE;
|
||||
drawstatus();
|
||||
wrefresh(statwin);
|
||||
msg("^%cWelcome back to level %d.",getlfcol(lf, CC_BAD), lf->level);
|
||||
msg("^%cWelcome back to level %d.",getlfcol(lf, CC_VBAD), lf->level);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17486,6 +17515,107 @@ void magicwoods_angry(lifeform_t *who) {
|
|||
}
|
||||
}
|
||||
|
||||
// make a list of choices for player to talk to a lf
|
||||
//
|
||||
// 'multiple' means 'we're talking to multiple people,not just one'
|
||||
void makecommslist(prompt_t *p, lifeform_t *lf, int multiple) {
|
||||
flag_t *f;
|
||||
object_t *godstone;
|
||||
enum ATTRBRACKET iqb;
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
// are they friendly?
|
||||
if (ispetof(lf, player)) {
|
||||
if ((iqb >= IQ_ANIMAL) || isundead(lf)) {
|
||||
if (!haschoice(p, 'a')) addchoice(p, 'a', "Attack something", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (!isadjacent(lf->cell, player->cell)) {
|
||||
if (!haschoice(p, 'c')) addchoice(p, 'c', "Come here", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (!haschoice(p, 'g')) addchoice(p, 'g', "Go somewhere", NULL, NULL, NULL);
|
||||
|
||||
if (isadjacent(lf->cell, player->cell) && !lfhasflag(lf, F_NOPACK) && !multiple) {
|
||||
if (!haschoice(p, 't')) addchoice(p, 't', "Trade items with me", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (iqb >= IQ_ANIMAL) {
|
||||
f = isresting(lf);
|
||||
if (f) {
|
||||
if (!haschoice(p, 'r')) addchoice(p, 'r', "Stop resting.", NULL, NULL, NULL);
|
||||
} else {
|
||||
if (!haschoice(p, 'r')) addchoice(p, 'r', "Rest until you are healed.", NULL, NULL, NULL);
|
||||
}
|
||||
if (!haschoice(p, '"')) addchoice(p, '<', "Stay close.", NULL, NULL, NULL);
|
||||
if (!haschoice(p, '"')) addchoice(p, '>', "Keep your distance.", NULL, NULL, NULL);
|
||||
}
|
||||
} else if (ishirable(lf) && !multiple) {
|
||||
if (lfhasflag(lf, F_ISPRISONER)) {
|
||||
if (!haschoice(p, 'j')) addchoice(p, 'j', "Join me, and I will help you escape.", NULL, NULL, NULL);
|
||||
} else if (getskill(player, SK_SPEECH) >= PR_EXPERT) {
|
||||
if (!haschoice(p, 'j')) addchoice(p, 'j', "Join me on my quest!", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isgod(lf) && ispeaceful(lf) && cantalk(lf) && !multiple) {
|
||||
enum SKILLLEVEL slev;
|
||||
job_t *j;
|
||||
slev = getskill(player, SK_SPEECH);
|
||||
// same race or job?
|
||||
j = getjob(player);
|
||||
if ((slev != PR_MASTER) && j && (j == getjob(lf))) slev++;
|
||||
if ((slev != PR_MASTER) && (player->race->id == lf->race->id)) slev++;
|
||||
if (slev >= PR_NOVICE) {
|
||||
if (!haschoice(p, 'x')) addchoice(p, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
|
||||
}
|
||||
if (slev >= PR_BEGINNER) {
|
||||
if (!haschoice(p, 'i')) addchoice(p, 'i', "What can you tell me about this area?", NULL, NULL, NULL);
|
||||
}
|
||||
if (!areallies(player, lf)) {
|
||||
if (slev >= PR_SKILLED) {
|
||||
if (!haschoice(p, 'k')) addchoice(p, 'k', "Care to trade knowledge?", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isadjacent(lf->cell, player->cell) && !multiple) {
|
||||
if (areenemies(player, lf)) {
|
||||
if (!haschoice(p, 'm')) addchoice(p, 'm', "Have mercy!", NULL, NULL, NULL);
|
||||
}
|
||||
// if you are allies, use 'trade items' instead
|
||||
if (!areallies(player, lf)) {
|
||||
if (isgod(lf)) {
|
||||
// may only donate the godstone
|
||||
godstone = hasob(player->pack, getopposinggodstone(lf->race->id));
|
||||
if (godstone) {
|
||||
char buf[BUFLEN],obname[BUFLEN];
|
||||
getobname(godstone, obname, 1);
|
||||
sprintf(buf, "(offer %s)", obname);
|
||||
if (!haschoice(p, 'o')) addchoice(p, 'o', buf, NULL, NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
if (!haschoice(p, 'o')) addchoice(p, 'o', "(offer a bribe)", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
f = lfhasflag(lf, F_OWNSSHOP);
|
||||
if (f) {
|
||||
int shopid;
|
||||
shopid = f->val[0];
|
||||
moneyowing = getowing(player, shopid, NULL);
|
||||
if (moneyowing > 0) {
|
||||
snprintf(buf, BUFLEN, "(pay $%d to the shopkeeper)",moneyowing);
|
||||
addchoice(p, 'p', buf, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (!multiple && !haschoice(p, 'y')) addchoice(p, 'y', "Yeeeeeaaaargh!", NULL, NULL, NULL);
|
||||
if (!haschoice(p, 'n')) addchoice(p, 'n', "(nothing)", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void makefriendly(lifeform_t *who, int howlong) {
|
||||
char lfname[BUFLEN];
|
||||
|
||||
|
@ -19921,12 +20051,12 @@ int rollstat(lifeform_t *lf, enum ATTRIB attr) {
|
|||
}
|
||||
|
||||
// safe to rest?
|
||||
int safetorest(lifeform_t *lf) {
|
||||
int safetorest(lifeform_t *lf, enum ERROR *why) {
|
||||
lifeform_t *l;
|
||||
reason = E_OK;
|
||||
if (why) *why = E_OK;
|
||||
|
||||
if (lfhasflag(lf, F_STASIS)) {
|
||||
reason = E_STASIS;
|
||||
if (why) *why = E_STASIS;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -19946,7 +20076,7 @@ int safetorest(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
if (monsternearby) {
|
||||
reason = E_MONSTERNEARBY;
|
||||
if (why) *why = E_MONSTERNEARBY;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -19954,7 +20084,7 @@ int safetorest(lifeform_t *lf) {
|
|||
|
||||
if (getlftemp(lf) <= T_VCOLD) {
|
||||
if (!isimmuneto(lf->flags, DT_COLD, B_FALSE) && !isresistantto(lf->flags, DT_COLD, B_FALSE)) {
|
||||
reason = E_TOOCOLD;
|
||||
if (why) *why = E_TOOCOLD;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -19969,6 +20099,7 @@ int safetorest(lifeform_t *lf) {
|
|||
|
||||
f = lfhasflag(lf, F_TURNSINPEACE);
|
||||
if (!f || (f->val[0] < timeneeded)) {
|
||||
if (why) *why = E_TOOSOON;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -22566,7 +22697,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
// create the monster directly behind you
|
||||
if (monisreal) {
|
||||
// set autogen to false, we don't want minions appearing too.
|
||||
mon = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
mon = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
} else {
|
||||
mon = addlf(c, r->id, 1);
|
||||
}
|
||||
|
@ -23025,7 +23156,32 @@ void startlfturn(lifeform_t *lf) {
|
|||
practice(lf, SK_ENGINEERING, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// object which is really a monster
|
||||
f = hasflag(o->flags, F_ISMONSTER);
|
||||
if (f && (f->val[2] != NA)) {
|
||||
int diff;
|
||||
diff = f->val[2] + distmod;
|
||||
if (skillcheck(lf, SC_SEARCH, diff, mod)) {
|
||||
lifeform_t *newlf;
|
||||
// reveal it
|
||||
newlf = reveal_pretendob(o);
|
||||
if (newlf && cansee(player, newlf)) {
|
||||
char obname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
capitalise(obname);
|
||||
getlfnamea(newlf, lfname);
|
||||
msg("^wHey! %s %s really %s!",obname, (o->amt == 1) ? "is" : "are",lfname);
|
||||
more();
|
||||
interrupt(lf);
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
// train skills
|
||||
practice(lf, SK_PERCEPTION, 1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24118,7 +24274,7 @@ lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, char *ra
|
|||
lifeform_t *newlf = NULL;
|
||||
char buf[BUFLEN];
|
||||
|
||||
newlf = addmonster(c, rid, racename, B_TRUE, 1, B_FALSE, NULL);
|
||||
newlf = addmonster(c, rid, racename, B_TRUE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
if (newlf) {
|
||||
if (haslos(player, c)) {
|
||||
//char *newbuf;
|
||||
|
@ -24790,6 +24946,32 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
lifeform_t *reveal_pretendob(object_t *o) {
|
||||
enum RACE rid;
|
||||
flag_t *f;
|
||||
cell_t *c;
|
||||
lifeform_t *lf;
|
||||
c = getoblocation(o);
|
||||
f = hasflag(o->flags, F_ISMONSTER);
|
||||
assert(f);
|
||||
rid = f->val[0];
|
||||
|
||||
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
|
||||
lf = addmonster(c, rid, NULL, B_TRUE, 1, B_FALSE, B_FALSE, NULL);
|
||||
if (lf) {
|
||||
f = lfhasflag(lf, F_PRETENDSTOBE);
|
||||
if (f) {
|
||||
char obname[BUFLEN];
|
||||
// replace text
|
||||
getobnametruebase(o, obname, 1);
|
||||
free(f->text);
|
||||
f->text = strdup(obname);
|
||||
}
|
||||
}
|
||||
return lf;
|
||||
}
|
||||
|
||||
void turntoface(lifeform_t *lf, cell_t *dstcell) {
|
||||
if (isdead(lf)) return;
|
||||
if (lfhasflag(lf, F_AUTOROTATE)) return;
|
||||
|
|
10
lf.h
10
lf.h
|
@ -281,7 +281,7 @@ int getracerarity(enum HABITAT hab, enum RACE rid, enum RARITY *rr);
|
|||
object_t *getrandomarmour(lifeform_t *lf, lifeform_t *attacker);
|
||||
enum BEHAVIOUR getrandombehaviour(void);
|
||||
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker);
|
||||
race_t *getrandomcorpserace(cell_t *c);
|
||||
race_t *getrandomcorpserace(cell_t *c, enum LFSIZE wantsize);
|
||||
job_t *getrandomjob(int onlyplayerjobs);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
race_t *getrandomrace(cell_t *c, int forcedepth, condset_t *cs);
|
||||
|
@ -336,7 +336,7 @@ flag_t *hasname(lifeform_t *lf);
|
|||
int hassoul(lifeform_t *lf);
|
||||
void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch);
|
||||
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJURY forcetype);
|
||||
int leveldrain(lifeform_t *lf, int amt, int power, lifeform_t *fromlf);
|
||||
int leveldrain(lifeform_t *lf, int amt, enum CHECKTYPE sctype, int scdiff, lifeform_t *fromlf);
|
||||
int lfcanbekod(lifeform_t *lf);
|
||||
int lfcanbestoned(lifeform_t *lf);
|
||||
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
|
||||
|
@ -432,13 +432,14 @@ void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf);
|
|||
void loseskill(lifeform_t *lf, enum SKILL skid);
|
||||
void magicwoods_angry(lifeform_t *who);
|
||||
void magicwoods_warn(lifeform_t *who);
|
||||
void makecommslist(prompt_t *p, lifeform_t *lf, int multiple);
|
||||
void makefriendly(lifeform_t *lf, int howlong);
|
||||
void makeheard(lifeform_t *listener, lifeform_t *noisemaker, int showglyph, char *noisetext, int howlong);
|
||||
int makelearnable(lifeform_t *lf, enum SKILL skid);
|
||||
int makenauseated(lifeform_t *lf, int amt, int howlong, enum ERROR *why);
|
||||
void makenoise(lifeform_t *lf, enum NOISETYPE nid);
|
||||
void makepeaceful(lifeform_t *lf, lifeform_t *causedby);
|
||||
lifeform_t *makezombie(object_t *o, int power, char *description);
|
||||
lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *master);
|
||||
void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how, int overridepower);
|
||||
int meetsallattreqs(lifeform_t *lf, object_t *o);
|
||||
int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *modpct);
|
||||
|
@ -487,7 +488,7 @@ int startclimbing(lifeform_t *lf);
|
|||
int startresting(lifeform_t *lf, int willtrain);
|
||||
int rollattr(enum ATTRBRACKET bracket);
|
||||
int rollstat(lifeform_t *lf, enum ATTRIB attr);
|
||||
int safetorest(lifeform_t *lf);
|
||||
int safetorest(lifeform_t *lf, enum ERROR *why);
|
||||
int say(lifeform_t *lf, char *text, int volume);
|
||||
int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text, lifeform_t *talkingto);
|
||||
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
|
||||
|
@ -537,6 +538,7 @@ int tradeknowledge(lifeform_t *lf);
|
|||
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat, int onpurpose);
|
||||
int touch(lifeform_t *lf, object_t *o);
|
||||
int real_touch(lifeform_t *lf, object_t *o, int onpurpose);
|
||||
lifeform_t *reveal_pretendob(object_t *o);
|
||||
void turntoface(lifeform_t *lf, cell_t *dstcell);
|
||||
void unequipeffects(lifeform_t *lf, object_t *o);
|
||||
void unpoison(lifeform_t *lf);
|
||||
|
|
99
map.c
99
map.c
|
@ -21,6 +21,8 @@
|
|||
|
||||
int enteringmap = B_FALSE;
|
||||
|
||||
extern void *rdata;
|
||||
|
||||
extern habitat_t *firsthabitat,*lasthabitat;
|
||||
extern job_t *firstjob;
|
||||
extern map_t *firstmap,*lastmap;
|
||||
|
@ -251,21 +253,27 @@ map_t *addmap(void) {
|
|||
// if "rid" R_SPECIFIED, parse racename to get the race.
|
||||
// rid can also be R_RANDOM.
|
||||
// otherwise just use the given race.
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded) {
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int allowextras, int *nadded) {
|
||||
lifeform_t *lf = NULL;
|
||||
race_t *r;
|
||||
int db = B_FALSE;
|
||||
flagpile_t *wantflags = NULL;
|
||||
enum JOB wantjob = J_NONE;
|
||||
enum BEHAVIOUR wantbehaviour = BH_NONE;
|
||||
enum ERROR why;
|
||||
|
||||
if (nadded) *nadded = 0;
|
||||
|
||||
/*if gamemode == GM_GAMESTARTED checkallflags(player->cell->map); */
|
||||
|
||||
// ie. don't create mosnters on closed doors!
|
||||
if (!cellwalkable(NULL, c, NULL)) {
|
||||
return NULL;
|
||||
if (!cellwalkable(NULL, c, &why)) {
|
||||
object_t *o;
|
||||
o = (object_t *)rdata;
|
||||
if ((why == E_OBINWAY) && o && hasflag(o->flags, F_ISMONSTER)) {
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wantflags = addflagpile(NULL, NULL);
|
||||
|
@ -450,50 +458,50 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
|
||||
// appears in groups?
|
||||
if (db) dblog("handling groups");
|
||||
if (autogen) {
|
||||
if (autogen && allowextras) {
|
||||
f = hasflag(lf->flags, F_NUMAPPEAR);
|
||||
if (f) {
|
||||
// override amount
|
||||
amt = rnd(f->val[0], f->val[1]);
|
||||
}
|
||||
if (amt > 1) {
|
||||
int idx = 0;
|
||||
cell_t *adjcell;
|
||||
amt--; // we've already added one
|
||||
}
|
||||
if (amt > 1) {
|
||||
int idx = 0;
|
||||
cell_t *adjcell;
|
||||
amt--; // we've already added one
|
||||
|
||||
//adjcell = c;
|
||||
for ( ; amt > 0; amt--, idx++) {
|
||||
lifeform_t *newlf;
|
||||
// find an adjacent cell to one of the newly added monsters,
|
||||
// starting with the first one
|
||||
adjcell = real_getrandomadjcell(c, &ccwalkable, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL);
|
||||
// did we find one?
|
||||
if (!adjcell) break;
|
||||
//adjcell = c;
|
||||
for ( ; amt > 0; amt--, idx++) {
|
||||
lifeform_t *newlf;
|
||||
// find an adjacent cell to one of the newly added monsters,
|
||||
// starting with the first one
|
||||
adjcell = real_getrandomadjcell(c, &ccwalkable, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL);
|
||||
// did we find one?
|
||||
if (!adjcell) break;
|
||||
|
||||
newlf = addlf(adjcell, r->id, getrandommonlevel(r, adjcell->map));
|
||||
if (!newlf) {
|
||||
break;
|
||||
}
|
||||
if (nadded) (*nadded)++;
|
||||
newlf->born = B_FALSE;
|
||||
|
||||
|
||||
finalisemonster(newlf, lf, wantflags, idx, BH_NONE);
|
||||
|
||||
newlf->born = B_TRUE;
|
||||
|
||||
// match alignment
|
||||
setalignment(newlf, getalignment(lf));
|
||||
// match hostility
|
||||
if (lfhasflag(lf, F_HOSTILE)) {
|
||||
if (!lfhasflag(newlf, F_HOSTILE)) addflag(newlf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
} else {
|
||||
killflagsofid(newlf->flags, F_HOSTILE);
|
||||
}
|
||||
|
||||
// initial monster should remember its minions
|
||||
addflag(lf->flags, F_MINION, newlf->id, NA, NA, NULL);
|
||||
newlf = addlf(adjcell, r->id, getrandommonlevel(r, adjcell->map));
|
||||
if (!newlf) {
|
||||
break;
|
||||
}
|
||||
if (nadded) (*nadded)++;
|
||||
newlf->born = B_FALSE;
|
||||
|
||||
|
||||
finalisemonster(newlf, lf, wantflags, idx, BH_NONE);
|
||||
|
||||
newlf->born = B_TRUE;
|
||||
|
||||
// match alignment
|
||||
setalignment(newlf, getalignment(lf));
|
||||
// match hostility
|
||||
if (lfhasflag(lf, F_HOSTILE)) {
|
||||
if (!lfhasflag(newlf, F_HOSTILE)) addflag(newlf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
} else {
|
||||
killflagsofid(newlf->flags, F_HOSTILE);
|
||||
}
|
||||
|
||||
// initial monster should remember its minions
|
||||
addflag(lf->flags, F_MINION, newlf->id, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
|
@ -501,7 +509,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
|
|||
// minons?
|
||||
// appears in groups?
|
||||
if (db) dblog("handling minions");
|
||||
if (autogen) {
|
||||
if (autogen && allowextras) {
|
||||
f = hasflag(lf->flags, F_MINIONS);
|
||||
if (f) {
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
|
@ -636,7 +644,7 @@ int addrandomthing(cell_t *c, int obchance, int *nadded) {
|
|||
lifeform_t *lf;
|
||||
// monster
|
||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||
lf = addmonster(c, R_RANDOM, NULL, B_TRUE, 1, B_TRUE, nadded);
|
||||
lf = addmonster(c, R_RANDOM, NULL, B_TRUE, 1, B_TRUE, B_ALLOWEXTRA, nadded);
|
||||
if (lf) {
|
||||
rv = TT_MONSTER;
|
||||
}
|
||||
|
@ -2606,7 +2614,7 @@ int fix_unreach_via_doors(map_t *m) {
|
|||
setcelltype(c, getmapempty(m));
|
||||
makedoor(c, 0);
|
||||
setcellreason(c, "making door to link seperated areas");
|
||||
dblog(" successfully fixed by creating a door.");
|
||||
dblog(" successfully fixed by creating a door at %d,%d.",c->x, c->y);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -4527,7 +4535,7 @@ void createheaven(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
|
|||
c = map->cell[i];
|
||||
}
|
||||
// place god
|
||||
lf = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
lf = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
assert(lf);
|
||||
// add to god list
|
||||
godlf[ngodlfs++] = lf;
|
||||
|
@ -4964,7 +4972,8 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
c = getcell_cond(map, &ccwalkableroom);
|
||||
if (!c) c = getrandomcell(map);
|
||||
c = real_getrandomadjcell(c, &ccwalkable, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL);
|
||||
addmonster(c, R_SPECIFIED, thing[i]->what, B_FALSE, thing[i]->value, B_TRUE, NULL);
|
||||
addmonster(c, R_SPECIFIED, thing[i]->what, B_FALSE, thing[i]->value, B_TRUE,
|
||||
B_ALLOWEXTRA, NULL);
|
||||
break;
|
||||
case RT_BRANCHLINK:
|
||||
if (db) dblog(" adding branchlink");
|
||||
|
@ -9850,7 +9859,7 @@ void mapentereffects(map_t *m) {
|
|||
//c = getrandomroomcell(m, m->room[i].id, WE_WALKABLE);
|
||||
c = getcell_cond(m, &cs);
|
||||
if (c && !hasobflagwithin(c, F_STAIRS, 15, DT_COMPASS)) {
|
||||
addmonster(c, R_RANDOM, NULL, B_TRUE, 1, B_TRUE, NULL);
|
||||
addmonster(c, R_RANDOM, NULL, B_TRUE, 1, B_TRUE, B_ALLOWEXTRA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
map.h
2
map.h
|
@ -4,7 +4,7 @@ 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, int stairsinrooms, enum TEMPERATURE temp);
|
||||
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);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int allowextras, int *nadded);
|
||||
object_t *addrandomob(cell_t *c);
|
||||
int addrandomthing(cell_t *c, int obchance, int *nadded);
|
||||
region_t *addregion(enum BRANCH rtype, region_t *parent, int outlineid, int depthmod, int createdby);
|
||||
|
|
26
move.c
26
move.c
|
@ -3286,6 +3286,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
if (door) {
|
||||
msg("^gThere seems to be a secret door here!");
|
||||
killflagsofid(door->flags, F_SECRET);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
}
|
||||
//if (isblind(lf) || !haslos(lf, cell)) {
|
||||
|
@ -3366,6 +3367,24 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
break;
|
||||
case E_OBINWAY:
|
||||
inway = (object_t *)rdata;
|
||||
// walked into someone who was feigning death?
|
||||
if (inway && hasflag(inway->flags, F_ISMONSTER)) {
|
||||
lifeform_t *newlf;
|
||||
if (haslos(lf, cell)) {
|
||||
char inwayname[BUFLEN];
|
||||
getobname(inway, inwayname, 1);
|
||||
msg("^B%s starts to move!", inwayname);
|
||||
more();
|
||||
}
|
||||
// reaveal
|
||||
newlf = reveal_pretendob(inway);
|
||||
if (newlf) {
|
||||
turntoface(newlf, lf->cell);
|
||||
aiattack(newlf, lf, aigetchasetime(newlf));
|
||||
}
|
||||
if (onpurpose || fleeing) taketime(lf, getmovespeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
// can we push this?
|
||||
if (ispushable(inway)) {
|
||||
if (canpush(lf, inway, dir)) {
|
||||
|
@ -3764,6 +3783,13 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// mosnters will never move on top of other monsters
|
||||
// pretending to be objects (ie. gargoyles)
|
||||
if (hasobwithflag(cell->obpile, F_ISMONSTER)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (celldangerous(lf, cell, B_TRUE, error)) {
|
||||
// if lfs are fleeing and have below average wisdom,
|
||||
// they will walk onto dangerous cells
|
||||
|
|
2
nexus.c
2
nexus.c
|
@ -307,6 +307,7 @@ int main(int argc, char **argv) {
|
|||
addtempflag(player->flags, F_CANWILL, OT_A_CHECKSTAIRS, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_PRAY, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_TRAIN, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_TIPTOE, NA, NA, NULL, FROMGAMESTART);
|
||||
addtempflag(player->flags, F_CANWILL, OT_A_DEBUG, NA, NA, NULL, FROMGAMESTART); /////////
|
||||
|
||||
// make the initial level
|
||||
|
@ -1932,6 +1933,7 @@ int roll(char *string) {
|
|||
int rolldie(int ndice, int sides) {
|
||||
int i;
|
||||
int res = 0;
|
||||
if (sides <= 0) return 0;
|
||||
for (i = 0; i < ndice; i++) {
|
||||
res += rnd(1,sides);
|
||||
}
|
||||
|
|
88
objects.c
88
objects.c
|
@ -1571,6 +1571,14 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
}
|
||||
}
|
||||
|
||||
// hiding monsters?
|
||||
f = hasflag(o->flags, F_ISMONSTER);
|
||||
if (f) {
|
||||
object_t *oo;
|
||||
oo = addobfast(o->contents, f->val[1]);
|
||||
assert(oo);
|
||||
}
|
||||
|
||||
// extra chance of bone items being cursed
|
||||
if (o->type->material->id == MT_BONE) {
|
||||
if (pctchance(15)) {
|
||||
|
@ -1966,7 +1974,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
|
||||
if (!corpserace || hasflag(corpserace->flags, F_NOCORPSE)) {
|
||||
// random one.
|
||||
corpserace = getrandomcorpserace(NULL);
|
||||
corpserace = getrandomcorpserace(NULL, wantarmsize);
|
||||
}
|
||||
|
||||
o->weight = corpserace->weight;
|
||||
|
@ -2027,13 +2035,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (!corpserace) {
|
||||
cell_t *where;
|
||||
where = getoblocation(o);
|
||||
// select random race
|
||||
// select random race, or correct size.
|
||||
if (where) {
|
||||
corpserace = getrandomcorpserace(where);
|
||||
corpserace = getrandomcorpserace(where, wantarmsize);
|
||||
}
|
||||
if (!corpserace) {
|
||||
// ie. vending machine, or inside another object/fake cell?
|
||||
corpserace = getrandomcorpserace(NULL);
|
||||
corpserace = getrandomcorpserace(NULL, wantarmsize);
|
||||
}
|
||||
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
|
||||
}
|
||||
|
@ -2090,7 +2098,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
}
|
||||
} else if (o->type->id == OT_JERKY) {
|
||||
if (!corpserace) {
|
||||
corpserace = getrandomcorpserace(NULL);
|
||||
corpserace = getrandomcorpserace(NULL, wantarmsize);
|
||||
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
|
||||
}
|
||||
addflag(o->flags, F_LINKRACE, corpserace->id, NA, NA, NULL);
|
||||
|
@ -2099,7 +2107,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
|
||||
if (!corpserace || hasflag(corpserace->flags, F_NOCORPSE)) {
|
||||
// random one.
|
||||
corpserace = getrandomcorpserace(NULL);
|
||||
corpserace = getrandomcorpserace(NULL, wantarmsize);
|
||||
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
|
||||
}
|
||||
|
||||
|
@ -5503,6 +5511,11 @@ char *getobdesc(object_t *o, char *buf) {
|
|||
int blind = B_FALSE;
|
||||
int known = B_FALSE;
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (hasflag(o->flags, F_ISMONSTER)) {
|
||||
if (o->contents->first) {
|
||||
o = o->contents->first;
|
||||
}
|
||||
}
|
||||
// can't see the object ?
|
||||
if (o->pile->owner == player) {
|
||||
if (!haslos(player, player->cell) || isblind(player)) {
|
||||
|
@ -5814,6 +5827,13 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
|
||||
where = getoblocation(o);
|
||||
|
||||
if (hasflag(o->flags, F_ISMONSTER)) {
|
||||
if (o->contents->first) {
|
||||
o = o->contents->first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_TRAIL);
|
||||
if (f) {
|
||||
race_t *r = NULL;
|
||||
|
@ -10465,7 +10485,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
|
||||
where = getrandomadjcell(lf->cell, &ccwalkable, B_ALLOWEXPAND);
|
||||
if (where) {
|
||||
mon = addmonster(where, f->val[0], NULL, B_TRUE, 1, B_FALSE, NULL);
|
||||
mon = addmonster(where, f->val[0], NULL, B_TRUE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
}
|
||||
if (mon) {
|
||||
char monname[BUFLEN];
|
||||
|
@ -10612,7 +10632,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
case 0: // butterflies around user
|
||||
willid = B_TRUE;
|
||||
where = getrandomadjcell(lf->cell, &ccwalkable, B_ALLOWEXPAND);
|
||||
addmonster(where, R_BUTTERFLY, NULL, B_FALSE, rnd(10,20), B_FALSE, NULL);
|
||||
addmonster(where, R_BUTTERFLY, NULL, B_FALSE, rnd(10,20), B_FALSE, B_NOEXTRA, NULL);
|
||||
if (haslos(player, where)) {
|
||||
msg("A swarm of butterflies appears!");
|
||||
}
|
||||
|
@ -12383,7 +12403,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
break;
|
||||
case OT_POT_EXPERIENCE:
|
||||
if (potblessed == B_CURSED) {
|
||||
leveldrain(lf, 1, 99, NULL);
|
||||
leveldrain(lf, 1, SC_CON, 999, NULL);
|
||||
} else {
|
||||
// gain xp!
|
||||
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) {
|
||||
|
@ -14281,6 +14301,17 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif
|
|||
return 0;
|
||||
}
|
||||
|
||||
// monster pretending to be object?
|
||||
if (hasflag(o->flags, F_ISMONSTER)) {
|
||||
lifeform_t *newlf;
|
||||
newlf = reveal_pretendob(o);
|
||||
if (newlf && attacker) {
|
||||
turntoface(newlf, attacker->cell);
|
||||
aiattack(newlf, attacker, aigetchasetime(newlf));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// update lastdamtype
|
||||
f = hasflag(o->flags, F_LASTDAMTYPE);
|
||||
if (f) {
|
||||
|
@ -15420,6 +15451,26 @@ void timeeffectsob(object_t *o) {
|
|||
killflagsofid(o->flags, F_FILLPOT);
|
||||
}
|
||||
|
||||
// mosnters pretending to be objects?
|
||||
if (onground && hasflag(o->flags, F_ISMONSTER)) {
|
||||
f = hasflag(o->flags, F_ISMONSTER);
|
||||
if (strlen(f->text)) {
|
||||
int dist;
|
||||
dist = atoi(f->text);
|
||||
|
||||
// player within reveal distance?
|
||||
if ((getcelldist(player->cell, location) <= dist) && !haslos(player, location)) {
|
||||
lifeform_t *newlf;
|
||||
newlf = reveal_pretendob(o);
|
||||
if (newlf) {
|
||||
turntoface(newlf, player->cell);
|
||||
aiattack(newlf, player, aigetchasetime(newlf));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// expire flags
|
||||
timeeffectsflags(o->flags);
|
||||
checkflagpile(o->flags);
|
||||
|
@ -16010,7 +16061,7 @@ void timeeffectsob(object_t *o) {
|
|||
contagious = B_TRUE;
|
||||
}
|
||||
// turn into a zombified version of itself.
|
||||
lf = makezombie(o, 10, revivetext);
|
||||
lf = makezombie(o, 10, revivetext, lf); // this will do the announcement
|
||||
if (lf && contagious) {
|
||||
addflag(lf->flags, F_HITCONFER, F_REVIVETIMER, SC_POISON, 165, NULL);
|
||||
addflag(lf->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie!");
|
||||
|
@ -16018,7 +16069,7 @@ void timeeffectsob(object_t *o) {
|
|||
addflag(lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
|
||||
} else {
|
||||
// revive!
|
||||
lf = addmonster(lfloc, f->val[2], NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
lf = addmonster(lfloc, f->val[2], NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
// gain flags form corpse
|
||||
copyflag(lf->flags, o->flags, F_CANWILL);
|
||||
copyflag(lf->flags, o->flags, F_CANCAST);
|
||||
|
@ -16029,11 +16080,11 @@ void timeeffectsob(object_t *o) {
|
|||
|
||||
// corpse vanishes
|
||||
removeob(o, o->amt);
|
||||
}
|
||||
// announce
|
||||
if (haslos(player, lfloc) || haslos(player, obloc)) {
|
||||
msg("^W%s %s!^n", obname, revivetext);
|
||||
interrupt(player);
|
||||
// announce
|
||||
if (haslos(player, lfloc) || haslos(player, obloc)) {
|
||||
msg("^W%s %s!^n", obname, revivetext);
|
||||
interrupt(player);
|
||||
}
|
||||
}
|
||||
free(revivetext);
|
||||
return;
|
||||
|
@ -16838,6 +16889,11 @@ int validateobs(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (hasflag(ot->flags, F_ISMONSTER) && !hasflag(ot->flags, F_IMPASSABLE)) {
|
||||
printf("ERROR in object '%s' - objects with f_ismonster MUST also have f_impassable too!\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
|
||||
// remember buildings
|
||||
if (ot->obclass->id == OC_BUILDING) {
|
||||
if (hasflag(ot->flags, F_RARITY)) {
|
||||
|
|
40
spell.c
40
spell.c
|
@ -2720,6 +2720,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// do the first one right away
|
||||
rest(user, B_TRUE);
|
||||
}
|
||||
} else if (abilid == OT_A_TIPTOE) {
|
||||
if (isswimming(user)) {
|
||||
if (isplayer(user)) msg("You can't tiptoe while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isairborne(user, NULL)) {
|
||||
if (isplayer(user)) msg("You can't tiptoe while airborne!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isclimbing(user)) {
|
||||
if (isplayer(user)) msg("You can't tiptoe while climbing!");
|
||||
return B_TRUE;
|
||||
}
|
||||
trysneak(user, D_NONE);
|
||||
} else if (abilid == OT_A_TRIPLF) {
|
||||
object_t *wep;
|
||||
int skillmod = 0;
|
||||
|
@ -3719,7 +3733,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
if (isplayer(user)) {
|
||||
if (!safetorest(user)) {
|
||||
if (!safetorest(user, NULL)) {
|
||||
if (getattrbracket(getattr(user, A_WIS), A_WIS, NULL) >= AT_GTAVERAGE) {
|
||||
if (askchar("Really try to hide while in view of enemies?", "yn", "n", B_TRUE, B_FALSE) != 'y') {
|
||||
return B_TRUE;
|
||||
|
@ -4387,9 +4401,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int sel,n;
|
||||
sel = rnd(0,nposs-1);
|
||||
o = poss[sel];
|
||||
newlf = makezombie(o, power, "rises from the dead");
|
||||
newlf = makezombie(o, power, "rises from the dead", target);
|
||||
if (newlf) {
|
||||
petify(newlf, target);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
// remove from list
|
||||
|
@ -4482,7 +4495,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// add it!
|
||||
getobname(o, obname, 1);
|
||||
removeob(o, ALL);
|
||||
lf = addmonster(targcell, f->val[0], NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
lf = addmonster(targcell, f->val[0], NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
setlfmaterial(lf, MT_STONE, B_FALSE);
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s comes to life!",obname);
|
||||
|
@ -4528,7 +4541,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
getobname(o, obname, 1);
|
||||
removeob(o, ALL);
|
||||
lf = addmonster(targcell, rid, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
lf = addmonster(targcell, rid, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s comes to life!",obname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -11420,6 +11433,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_REVEALHIDDEN) {
|
||||
int i;
|
||||
int seen = B_FALSE;
|
||||
|
||||
if (!isplayer(caster)) return B_TRUE;
|
||||
|
||||
if (!target) target = caster;
|
||||
for (i = 0 ; i < target->nlos; i++ ){
|
||||
targcell = target->los[i];
|
||||
|
@ -11434,9 +11450,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char obname[BUFLEN];
|
||||
killflag(f);
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s is magically revealed!", obname);
|
||||
msg("^G%s is magically revealed!", obname);
|
||||
seen = B_TRUE;
|
||||
}
|
||||
if (hasflag(o->flags, F_ISMONSTER)) {
|
||||
lifeform_t *newlf;
|
||||
newlf = reveal_pretendob(o);
|
||||
if (newlf) {
|
||||
char lfname[BUFLEN];
|
||||
getlfnamea(newlf, lfname);
|
||||
msg("^G%s is magically revealed!", lfname);
|
||||
seen = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15283,7 +15309,7 @@ int summonlfs(lifeform_t *caster, cell_t *where, enum RACE wantrace, enum RACECL
|
|||
r = findrace(poss[rnd(0,nposs-1)]);
|
||||
if (r) {
|
||||
// add it!
|
||||
newlf = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
newlf = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, B_NOEXTRA, NULL);
|
||||
// not worth any xp
|
||||
killflagsofid(newlf->flags, F_XPVAL);
|
||||
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
|
|
1
text.c
1
text.c
|
@ -1012,6 +1012,7 @@ char *getcolname(enum COLOUR c) {
|
|||
case C_CARPET2: return "carpet2";
|
||||
case C_METAL: return "metal";
|
||||
case C_SMOKE: return "smoke";
|
||||
case C_STONE: return "stone";
|
||||
case C_WOOD: return "wood";
|
||||
case C_DARKCYAN: return "darkcyan";
|
||||
case C_DARKBLUE: return "darkblue";
|
||||
|
|
2
vault.c
2
vault.c
|
@ -416,7 +416,7 @@ int addvaultthing(cell_t *c, vault_t *v, enum VAULTTHING vt, char *what) {
|
|||
|
||||
break;
|
||||
case VT_LF:
|
||||
lf = addmonster(c, R_SPECIFIED, what, B_TRUE, 1, B_TRUE, NULL);
|
||||
lf = addmonster(c, R_SPECIFIED, what, B_TRUE, 1, B_TRUE, B_NOEXTRA, NULL);
|
||||
if (!lf) {
|
||||
dblog("invalid racename '%s' in vault %s", what, v->id);
|
||||
msg("invalid racename '%s' in vault %s", what, v->id);
|
||||
|
|
Loading…
Reference in New Issue