- [+] allies should always give out info without payment
- [+] ....but only about their home level! - [+] f_startmapid - [+] cave entrances should make noise - [+] drip - [+] echoing - [+] cope with multiple f_makesnoise flags on objects (pick one randomly) - [+] showlfstats skill display bug - "MORE" keystroke doesn't fall through. - [+] You impale the chicken! The chicken turns to face you. - [+] shouldn't turn to face if your'e dead! - [+] nulllify spell not populating seenbyplayer - [+] crash in createfakes() - [+] animals hsould still walk onto SHARP objects. - [+] secret doors showing up as empty remembered cells when you look away from them (and have lowish cartography) - [+] don't call remove_deadends on vaults. - [+] when walking down stairs to level 3: - [+] ERROR - stairs link to existing map 3('dungeon L2 (id #3)', depth 2), but it has no free stairs - [+] ie. Level 3 has too many up staircases ? no. 3 on all of them. - [+] FIXED. countstairs() was including too much. now using countmapobs(map, stairtype) instead. - [+] The goblin rogue a half-sized leather armour (null). - [+] fixed crash when you cast rage on someone who is eating. - [+] crash when catching a glowbug in a flask - [+] use canreachbp code when selecting armour to damage as well.... ie newt can't hit your helmet! - [+] BUG: "tunnel doing up" went down! - [+] for monsters:auto raise lf stats to match starting weapons - [+] crash in aigetspelltarget() for CLIMB - [+] should deactiveate all spells on polymorph - [+] allow usage of FEIGNDEATH while prone. - [+] make coprses non-stackable - [+] CRASH in animatedead - [+] shouldn't say 'you attack x from behind' if x has awareness
This commit is contained in:
parent
040b9bf052
commit
060470ac3a
39
ai.c
39
ai.c
|
@ -371,7 +371,7 @@ object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose) {
|
int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose) {
|
||||||
int specialcase = B_FALSE;
|
int specialcase = B_FALSE;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
|
||||||
|
@ -429,6 +429,13 @@ void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victi
|
||||||
poss[nposs++] = lf->los[i];
|
poss[nposs++] = lf->los[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!nposs) {
|
||||||
|
if (spellcell) spellcell = NULL;
|
||||||
|
if (spelllf) *spelllf = NULL;
|
||||||
|
if (spellob) *spellob = NULL;
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (spellcell) {
|
if (spellcell) {
|
||||||
*spellcell = poss[rnd(0,nposs-1)];
|
*spellcell = poss[rnd(0,nposs-1)];
|
||||||
}
|
}
|
||||||
|
@ -541,6 +548,7 @@ void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) {
|
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) {
|
||||||
|
@ -1411,7 +1419,9 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
||||||
spellcell = target->cell;
|
spellcell = target->cell;
|
||||||
} else {
|
} else {
|
||||||
// pick targets based on spell flags
|
// pick targets based on spell flags
|
||||||
aigetspelltarget(lf, st, target, &spelllf, &spellcell, &spellob, F_AICASTTOATTACK);
|
if (aigetspelltarget(lf, st, target, &spelllf, &spellcell, &spellob, F_AICASTTOATTACK)) {
|
||||||
|
spellfailed = B_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spellfailed) {
|
if (spellfailed) {
|
||||||
|
@ -1549,6 +1559,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
||||||
if (db) dblog(".oO { throw failed! }");
|
if (db) dblog(".oO { throw failed! }");
|
||||||
}
|
}
|
||||||
} else if (rangedattack == RA_WAND) {
|
} else if (rangedattack == RA_WAND) {
|
||||||
|
int wandfailed = B_FALSE;
|
||||||
objecttype_t *st;
|
objecttype_t *st;
|
||||||
cell_t *zapcell = NULL;
|
cell_t *zapcell = NULL;
|
||||||
st = getlinkspell(rangedob);
|
st = getlinkspell(rangedob);
|
||||||
|
@ -1559,14 +1570,16 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
||||||
} else {
|
} else {
|
||||||
purpose = F_AICASTTOATTACK;
|
purpose = F_AICASTTOATTACK;
|
||||||
}
|
}
|
||||||
aigetspelltarget(lf, st, target, NULL, &zapcell, NULL, purpose);
|
if (aigetspelltarget(lf, st, target, NULL, &zapcell, NULL, purpose)) {
|
||||||
|
wandfailed = B_TRUE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// no linkspell - just zap it.
|
// no linkspell - just zap it.
|
||||||
zapcell = NULL;
|
zapcell = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// zap it
|
// zap it
|
||||||
|
if (!wandfailed) {
|
||||||
if (!operate(lf, rangedob, zapcell)) {
|
if (!operate(lf, rangedob, zapcell)) {
|
||||||
// succesful
|
// succesful
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
|
@ -1574,6 +1587,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
||||||
if (db) dblog(".oO { zap failed! }");
|
if (db) dblog(".oO { zap failed! }");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} // end if rangedattackok
|
} // end if rangedattackok
|
||||||
} // end if attackok
|
} // end if attackok
|
||||||
|
|
||||||
|
@ -2133,11 +2147,24 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
||||||
specificcheckok = B_FALSE;
|
specificcheckok = B_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ot->id == OT_S_ANIMATEDEAD) {
|
||||||
|
int found = B_FALSE,i;
|
||||||
|
// must be a corpse in sight
|
||||||
|
for (i = 0; i < lf->nlos; i++) {
|
||||||
|
if (hasob(lf->los[0]->obpile, OT_CORPSE)) {
|
||||||
|
found = B_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
specificcheckok = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ot->id == OT_S_ANIMATEMETAL) {
|
if (ot->id == OT_S_ANIMATEMETAL) {
|
||||||
object_t *wep;
|
object_t *wep;
|
||||||
wep = getweapon(lf);
|
wep = getweapon(lf);
|
||||||
if (!wep || !ismetal(wep->material->id)) {
|
if (!wep || !ismetal(wep->material->id)) {
|
||||||
specificcheckok = B_TRUE;
|
specificcheckok = B_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) {
|
if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) {
|
||||||
|
@ -2544,7 +2571,7 @@ int lookforobs(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
} else if ((celldist == 1) && c->lf &&
|
} else if ((celldist == 1) && c->lf &&
|
||||||
(isunconscious(c->lf) || isasleep(c->lf)) &&
|
(isunconscious(c->lf) || isasleep(c->lf)) &&
|
||||||
(getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) > IQ_ANIMAL) && !isundead(lf)) {
|
(getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) > IQ_ANIMAL) && !isundead(lf) && !willeatlf(lf, c->lf)) {
|
||||||
// intelligent enemies will loot unconscious lfs to make sure they are not a threat.
|
// intelligent enemies will loot unconscious lfs to make sure they are not a threat.
|
||||||
//
|
//
|
||||||
// in this case they'll loot more than normal. even if they wouldn't normally pick up
|
// in this case they'll loot more than normal. even if they wouldn't normally pick up
|
||||||
|
|
2
ai.h
2
ai.h
|
@ -6,7 +6,7 @@ enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
|
||||||
enum OBTYPE aigetfleespell(lifeform_t *lf);
|
enum OBTYPE aigetfleespell(lifeform_t *lf);
|
||||||
cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir);
|
cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir);
|
||||||
object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range);
|
object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range);
|
||||||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
||||||
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
|
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
|
||||||
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
|
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
|
||||||
int ai_attack_existing_target(lifeform_t *lf);
|
int ai_attack_existing_target(lifeform_t *lf);
|
||||||
|
|
23
attack.c
23
attack.c
|
@ -20,7 +20,7 @@ extern lifeform_t *player;
|
||||||
|
|
||||||
extern enum ERROR reason;
|
extern enum ERROR reason;
|
||||||
|
|
||||||
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
|
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype, lifeform_t *attacker) {
|
||||||
object_t *armour = NULL;
|
object_t *armour = NULL;
|
||||||
int damtaken = 0;
|
int damtaken = 0;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
||||||
// figure out what bit of armour was hit
|
// figure out what bit of armour was hit
|
||||||
if (!armour) {
|
if (!armour) {
|
||||||
// pick a random piece of armour
|
// pick a random piece of armour
|
||||||
armour = getrandomarmour(lf);
|
armour = getrandomarmour(lf, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (armour) {
|
if (armour) {
|
||||||
|
@ -112,7 +112,7 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
|
||||||
if (dam) {
|
if (dam) {
|
||||||
int ar;
|
int ar;
|
||||||
newdam = *dam;
|
newdam = *dam;
|
||||||
ar = getarmourrating(lf, NULL, NULL, NULL);
|
ar = getarmourrating(lf, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
// if you did at least one damage...
|
// if you did at least one damage...
|
||||||
if ((*dam >= 1) && (reduceamt >= 0)) {
|
if ((*dam >= 1) && (reduceamt >= 0)) {
|
||||||
|
@ -159,6 +159,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
AT_OB = 2,
|
AT_OB = 2,
|
||||||
} attacktype = AT_NONE;
|
} attacktype = AT_NONE;
|
||||||
void *attacktarget;
|
void *attacktarget;
|
||||||
|
int attacklfid = -1;
|
||||||
int nweps = 0;
|
int nweps = 0;
|
||||||
int innateattacks = 0;
|
int innateattacks = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -240,6 +241,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
|
|
||||||
attacktype = AT_LF;
|
attacktype = AT_LF;
|
||||||
attacktarget = c->lf;
|
attacktarget = c->lf;
|
||||||
|
attacklfid = c->lf->id; // remember for later
|
||||||
|
|
||||||
if (areallies(lf, attacktarget)) attackedfriend = B_TRUE;
|
if (areallies(lf, attacktarget)) attackedfriend = B_TRUE;
|
||||||
if (!cansee(attacktarget, lf) || isfleeing(attacktarget)) attackedhelpless = B_TRUE;
|
if (!cansee(attacktarget, lf) || isfleeing(attacktarget)) attackedhelpless = B_TRUE;
|
||||||
|
@ -468,10 +470,15 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
killobpile(op);
|
killobpile(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (attacktype == AT_LF) {
|
||||||
|
// in case the lf disappered....
|
||||||
|
attacktarget = findlf(lf->cell->map, attacklfid);
|
||||||
|
}
|
||||||
|
|
||||||
// now stop hiding
|
// now stop hiding
|
||||||
killflagsofid(lf->flags, F_HIDING);
|
killflagsofid(lf->flags, F_HIDING);
|
||||||
|
|
||||||
if (saysorry) {
|
if (saysorry && attacktarget) {
|
||||||
sayphrase(lf, SP_SORRY, -1, NA, NULL);
|
sayphrase(lf, SP_SORRY, -1, NA, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +490,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// god effects...
|
// god effects...
|
||||||
if ((attacktype == AT_LF) && isplayer(lf)) {
|
if ((attacktype == AT_LF) && isplayer(lf) && attacktarget) {
|
||||||
if (attackedfriend) {
|
if (attackedfriend) {
|
||||||
angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY);
|
angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY);
|
||||||
angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY);
|
angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY);
|
||||||
|
@ -882,7 +889,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
||||||
sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
|
sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
|
||||||
//difficulty = 20 + ((gethitdice(lf) - gethitdice(victim)) );
|
//difficulty = 20 + ((gethitdice(lf) - gethitdice(victim)) );
|
||||||
//difficulty = 20 + gethitdice(lf);
|
//difficulty = 20 + gethitdice(lf);
|
||||||
difficulty = 20 + (gethitdice(lf)*2) - gethitdice(victim);
|
difficulty = 24 + gethitdice(victim) - gethitdice(lf);
|
||||||
if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname)) {
|
if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname)) {
|
||||||
blocked = B_TRUE;
|
blocked = B_TRUE;
|
||||||
break; // stop processing damage now.
|
break; // stop processing damage now.
|
||||||
|
@ -1008,7 +1015,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
||||||
|
|
||||||
// victim's armour loses hp
|
// victim's armour loses hp
|
||||||
if (reduceamt && !critical) {
|
if (reduceamt && !critical) {
|
||||||
applyarmourdamage(victim, wep, dam[i], damtype[i]);
|
applyarmourdamage(victim, wep, dam[i], damtype[i], lf);
|
||||||
// train armour
|
// train armour
|
||||||
practice(victim, SK_ARMOUR, 1);
|
practice(victim, SK_ARMOUR, 1);
|
||||||
}
|
}
|
||||||
|
@ -1646,7 +1653,7 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
|
||||||
reduceamt = 0;
|
reduceamt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ar = getarmourrating(lf, NULL, NULL, NULL);
|
ar = getarmourrating(lf, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
// between 25% and 75% of AR.
|
// between 25% and 75% of AR.
|
||||||
// ie. with AR of 20, all damage is reduced by 5-15.
|
// ie. with AR of 20, all damage is reduced by 5-15.
|
||||||
|
|
2
attack.h
2
attack.h
|
@ -1,6 +1,6 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
|
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype, lifeform_t *attacker);
|
||||||
void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *dam, enum DAMTYPE damtype);
|
void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *dam, enum DAMTYPE damtype);
|
||||||
int attackcell(lifeform_t *lf, cell_t *c, int force);
|
int attackcell(lifeform_t *lf, cell_t *c, int force);
|
||||||
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
|
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
|
||||||
|
|
70
data.c
70
data.c
|
@ -213,14 +213,14 @@ void initjobs(void) {
|
||||||
}
|
}
|
||||||
addflag(lastjob->flags, F_NOSCORE, B_TRUE, NA, NA, NULL);
|
addflag(lastjob->flags, F_NOSCORE, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
addjob(J_ADVENTURER, "Adventurer", "Adventurers are a basic jack-of-all-trades type job. They can learn all skills, and already have basic Cartography and Lore skills. They start the game with three healing potions. Recommended for beginners.");
|
addjob(J_ADVENTURER, "Adventurer", "Adventurers are a versatile jack-of-all-trades type job. They can learn all skills, and already have basic Cartography and Lore skills. They also start the game with three healing potions. Recommended for beginners.");
|
||||||
// stat mods
|
// stat mods
|
||||||
// initial objects
|
// initial objects
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "gladius");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "gladius");
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins");
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing");
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "lockpick");
|
||||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rope");
|
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rope");
|
||||||
// initial skills
|
// initial skills
|
||||||
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL);
|
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL);
|
||||||
|
@ -539,7 +539,7 @@ void initjobs(void) {
|
||||||
// abilities
|
// abilities
|
||||||
addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL);
|
addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
|
||||||
addjob(J_NINJA, "Ninja", "A dark warrior dedicated to the art of ninjutsu. Ninjas are skilled with long blades, and gain special martial arts abilities at higher levels.");
|
addjob(J_NINJA, "Ninja", "A dark warrior dedicated to the art of ninjutsu. Ninjas are skilled with exotic weapons, and gain special martial arts abilities at higher levels.");
|
||||||
// stats
|
// stats
|
||||||
addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL);
|
addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL);
|
||||||
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 1, NA, NULL);
|
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 1, NA, NULL);
|
||||||
|
@ -1242,14 +1242,13 @@ void initobjects(void) {
|
||||||
addflag(lastobjectclass->flags, F_SMELLY, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_SMELLY, B_TRUE, NA, NA, NULL);
|
||||||
addoc(OC_GODSTONE, "Godstones", "Ancient artifacts, created by the elder gods.", '*', C_BOLDMAGENTA, RR_NEVER);
|
addoc(OC_GODSTONE, "Godstones", "Ancient artifacts, created by the elder gods.", '*', C_BOLDMAGENTA, RR_NEVER);
|
||||||
addflag(lastobjectclass->flags, F_UNIQUE, NA, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_UNIQUE, NA, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pulsating purple stone");
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pulsating stone");
|
||||||
addflag(lastobjectclass->flags, F_UNIQUE, NA, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_UNIQUE, NA, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY, RR_NEVER);
|
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY, RR_NEVER);
|
||||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
||||||
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
||||||
|
@ -1414,9 +1413,11 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TUNNELUP, NA, NA, NULL);
|
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TUNNELUP, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "a strange echoing.");
|
||||||
|
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "an echoing drip.");
|
||||||
addot(OT_TUNNELUP, "tunnel leading up", "A wide tunnel leading upwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE);
|
addot(OT_TUNNELUP, "tunnel leading up", "A wide tunnel leading upwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE);
|
||||||
addflag(lastot->flags, F_GLYPH, C_BROWN, '<', NA, NULL);
|
addflag(lastot->flags, F_GLYPH, C_BROWN, '<', NA, NULL);
|
||||||
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
|
addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TUNNELDOWN, NA, NA, NULL);
|
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TUNNELDOWN, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -1930,11 +1931,19 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL);
|
||||||
// godstones
|
// godstones
|
||||||
addot(OT_GODSTONEJ, "Godstone of Justice", "An ancient artifact representing the power of justice.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
|
addot(OT_GODSTONEJ, "Godstone of Justice", "An ancient artifact representing the power of justice.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL);
|
||||||
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
|
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
|
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
|
||||||
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
addot(OT_GODSTONER, "Godstone of Rage", "An ancient artifact representing the power of anger.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL);
|
||||||
|
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
|
||||||
// flora
|
// flora
|
||||||
addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY);
|
addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY);
|
||||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, "");
|
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, "");
|
||||||
|
@ -2104,6 +2113,10 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
||||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
|
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
|
||||||
|
addot(OT_POISONSAC, "venom sac", "A small sac of flesh, filled with potent venom.", MT_FLESH, 0.2, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
|
||||||
|
addflag(lastot->flags, F_GLYPH, C_BLUE, '%', NA, NULL);
|
||||||
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, "");
|
||||||
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||||
addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
|
addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
|
||||||
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
|
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
|
||||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
||||||
|
@ -3016,7 +3029,7 @@ void initobjects(void) {
|
||||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
addot(OT_S_SOFTENEARTH, "soften earth", "Converts earth into mud, slowing down.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
addot(OT_S_SOFTENEARTH, "soften earth", "Converts earth into mud, slowing down all who pass.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much mud will be created.");
|
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much mud will be created.");
|
||||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||||
|
@ -4843,7 +4856,7 @@ void initobjects(void) {
|
||||||
|
|
||||||
addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN);
|
addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN);
|
||||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
|
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
|
||||||
addflag(lastot->flags, F_GLYPH, C_GREY, '\\', NA, NULL);
|
addflag(lastot->flags, F_GLYPH, C_BROWN, '\\', NA, NULL);
|
||||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
@ -6860,6 +6873,10 @@ void initobjects(void) {
|
||||||
OT_MUSHROOMSHI, 1, B_TRUE,
|
OT_MUSHROOMSHI, 1, B_TRUE,
|
||||||
OT_BREADSTALE, 1, B_TRUE,
|
OT_BREADSTALE, 1, B_TRUE,
|
||||||
OT_NONE);
|
OT_NONE);
|
||||||
|
addrecipe(OT_POT_POISON,
|
||||||
|
OT_POISONSAC, 1, B_TRUE,
|
||||||
|
OT_POT_WATER, 1, B_TRUE,
|
||||||
|
OT_NONE);
|
||||||
addrecipe(OT_POT_SOUPCHICKEN,
|
addrecipe(OT_POT_SOUPCHICKEN,
|
||||||
OT_ROASTMEAT, 1, B_TRUE, // special case in getingredients() enforces chicken meat
|
OT_ROASTMEAT, 1, B_TRUE, // special case in getingredients() enforces chicken meat
|
||||||
OT_POT_WATER, 1, B_TRUE,
|
OT_POT_WATER, 1, B_TRUE,
|
||||||
|
@ -7305,7 +7322,7 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, NULL);
|
addflag(lastrace->flags, F_DEMANDSBRIBE, NA, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, 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_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4");
|
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4");
|
||||||
addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
|
addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
|
||||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
@ -8150,6 +8167,39 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL);
|
addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL);
|
||||||
|
|
||||||
|
addrace(R_GOBLINKING, "goblin king", 40, 'g', C_MAGENTA, MT_FLESH, RC_HUMANOID, "On rare occasion a goblin becomes powerful enough to command respect from almost all their peers. Far from standard cowardly goblins, these self-crowned 'kings' are a force to be reckoned with.");
|
||||||
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
|
lastrace->baseid = R_GOBLIN;
|
||||||
|
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "goblin corpse");
|
||||||
|
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL);
|
||||||
|
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+10");
|
||||||
|
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||||
|
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_AXES, NA, "great");
|
||||||
|
addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_AXES, NA, "great");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "golden crown");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great suit of ring mail");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great random armour");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great random armour");
|
||||||
|
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "100-300 gold coins");
|
||||||
|
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||||
|
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_PACKATTACK, 2, DT_SLASH, 3, NULL);
|
||||||
|
addflag(lastrace->flags, F_MINIONS, 90, 4, 6, "goblin");
|
||||||
|
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_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
|
||||||
|
|
||||||
addrace(R_GREMLIN, "gremlin", 20, 'g', C_GREEN, MT_FLESH, RC_HUMANOID, "Small mischievous imps known for their love of sabotage.");
|
addrace(R_GREMLIN, "gremlin", 20, 'g', C_GREEN, MT_FLESH, RC_HUMANOID, "Small mischievous imps known for their love of sabotage.");
|
||||||
setbodytype(lastrace, BT_HUMANOID);
|
setbodytype(lastrace, BT_HUMANOID);
|
||||||
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
|
||||||
|
@ -9705,6 +9755,8 @@ void initrace(void) {
|
||||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:4;");
|
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:4;");
|
||||||
addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;");
|
addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;");
|
||||||
|
addflag(lastrace->flags, F_WANTS, OT_BLOODSPLASH, B_COVETS, NA, NULL);
|
||||||
|
addflag(lastrace->flags, F_WANTS, OT_BLOODPOOL, B_COVETS, NA, NULL);
|
||||||
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
|
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
|
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
|
||||||
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "slither");
|
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "slither");
|
||||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
11
defs.h
11
defs.h
|
@ -886,9 +886,10 @@ enum RACE {
|
||||||
R_GNOLL,
|
R_GNOLL,
|
||||||
R_GNOLLHM,
|
R_GNOLLHM,
|
||||||
R_GOBLIN,
|
R_GOBLIN,
|
||||||
|
R_GOBLINHEXER,
|
||||||
|
R_GOBLINKING,
|
||||||
R_GOBLINWAR,
|
R_GOBLINWAR,
|
||||||
R_GOBLINSHOOTER,
|
R_GOBLINSHOOTER,
|
||||||
R_GOBLINHEXER,
|
|
||||||
R_GREMLIN,
|
R_GREMLIN,
|
||||||
R_HOBGOBLIN,
|
R_HOBGOBLIN,
|
||||||
R_HOBGOBLINWAR,
|
R_HOBGOBLINWAR,
|
||||||
|
@ -1151,6 +1152,7 @@ enum OBTYPE {
|
||||||
OT_GOLD,
|
OT_GOLD,
|
||||||
// godstones
|
// godstones
|
||||||
OT_GODSTONEJ,
|
OT_GODSTONEJ,
|
||||||
|
OT_GODSTONER,
|
||||||
// flora
|
// flora
|
||||||
OT_FLOWER,
|
OT_FLOWER,
|
||||||
OT_LEAF,
|
OT_LEAF,
|
||||||
|
@ -1180,6 +1182,7 @@ enum OBTYPE {
|
||||||
OT_MUSHROOMSTUFFED,
|
OT_MUSHROOMSTUFFED,
|
||||||
OT_NUT,
|
OT_NUT,
|
||||||
OT_PASSIONFRUIT,
|
OT_PASSIONFRUIT,
|
||||||
|
OT_POISONSAC,
|
||||||
OT_ROASTMEAT,
|
OT_ROASTMEAT,
|
||||||
OT_RUMBALL,
|
OT_RUMBALL,
|
||||||
OT_SALT,
|
OT_SALT,
|
||||||
|
@ -2410,6 +2413,7 @@ enum FLAG {
|
||||||
// text = obid of hotel
|
// text = obid of hotel
|
||||||
F_ALIGNMENT, // v0 = al_good, al_neutral, al_evil. default neutral.
|
F_ALIGNMENT, // v0 = al_good, al_neutral, al_evil. default neutral.
|
||||||
F_PIETY, // for god lifeforms - tracks player's piety with them
|
F_PIETY, // for god lifeforms - tracks player's piety with them
|
||||||
|
F_HOMEMAP, // which map did this lf get created on?
|
||||||
F_TOOKACTION, // lf purposely took action in their last turn.
|
F_TOOKACTION, // lf purposely took action in their last turn.
|
||||||
F_MOVED, // lf purposely walked/flew/swum/moved in prev turn
|
F_MOVED, // lf purposely walked/flew/swum/moved in prev turn
|
||||||
F_HASBEENMOVED, // an object moved this lf since their last turn.
|
F_HASBEENMOVED, // an object moved this lf since their last turn.
|
||||||
|
@ -2485,6 +2489,8 @@ enum FLAG {
|
||||||
// v1 = wepskill of object
|
// v1 = wepskill of object
|
||||||
// optional val2 = addition to map depth for rarity
|
// optional val2 = addition to map depth for rarity
|
||||||
// calculation
|
// calculation
|
||||||
|
// optional text = prefix for ob name.
|
||||||
|
// eg "good" "branded" "cursed" etc
|
||||||
F_CONTAINER, // this object is a container - you can use 'o'
|
F_CONTAINER, // this object is a container - you can use 'o'
|
||||||
// to take stuff out or put it in.
|
// to take stuff out or put it in.
|
||||||
F_HOLDING, // this container is a xxx of holding and makes objects
|
F_HOLDING, // this container is a xxx of holding and makes objects
|
||||||
|
@ -2969,6 +2975,8 @@ enum FLAG {
|
||||||
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
||||||
// if maxcount is PCT, mincount is a percentage
|
// if maxcount is PCT, mincount is a percentage
|
||||||
// of the total space.
|
// of the total space.
|
||||||
|
F_VAULTTAG, // vault has tag 'text'. for use with
|
||||||
|
// vt_rndvaultwithtag.
|
||||||
F_VAULTMAYROTATE, // may rotate this vault in 90degree increments.
|
F_VAULTMAYROTATE, // may rotate this vault in 90degree increments.
|
||||||
F_VAULTMAYFLIPX, // may flip this vault horizontally
|
F_VAULTMAYFLIPX, // may flip this vault horizontally
|
||||||
F_VAULTMAYFLIPY, // may flip this vault vertically
|
F_VAULTMAYFLIPY, // may flip this vault vertically
|
||||||
|
@ -3291,6 +3299,7 @@ enum REGIONTHING {
|
||||||
// what is stair object type
|
// what is stair object type
|
||||||
RT_VAULT, // what is vaultname
|
RT_VAULT, // what is vaultname
|
||||||
RT_RNDVAULTWITHFLAG, // val is wantedflag
|
RT_RNDVAULTWITHFLAG, // val is wantedflag
|
||||||
|
RT_RNDVAULTWITHTAG, // what is wanted tag
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct regionthing_s {
|
typedef struct regionthing_s {
|
||||||
|
|
|
@ -92,6 +92,8 @@ Flags can be:
|
||||||
shop // } this vault is a shop/shrine/etc
|
shop // } this vault is a shop/shrine/etc
|
||||||
stomach // }
|
stomach // }
|
||||||
|
|
||||||
|
tag:xxxx // add tag "xxx" to vault(for use with rndvaultwithtag)
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
when adding lfs/objects, "random" creates a random one.
|
when adding lfs/objects, "random" creates a random one.
|
||||||
|
|
||||||
|
|
23
io.c
23
io.c
|
@ -4128,6 +4128,15 @@ void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf) {
|
||||||
msg("\"I don't know anything about that!\"");
|
msg("\"I don't know anything about that!\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
f = hasflag(fp, F_HOMEMAP);
|
||||||
|
if (f) {
|
||||||
|
// (make the assumption that the player is on the
|
||||||
|
// same map as the person they are talking to!)
|
||||||
|
if (f->val[0] != player->cell->map->id) {
|
||||||
|
msg("\"I'm not familiar with this area.\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// shops
|
// shops
|
||||||
if (strchr(knowflag->text, 's')) {
|
if (strchr(knowflag->text, 's')) {
|
||||||
|
@ -4198,6 +4207,15 @@ void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) {
|
||||||
msg("\"I don't know anything about that!\"");
|
msg("\"I don't know anything about that!\"");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
f = hasflag(fp, F_HOMEMAP);
|
||||||
|
if (f) {
|
||||||
|
// (make the assumption that the player is on the
|
||||||
|
// same map as the person they are talking to!)
|
||||||
|
if (f->val[0] != player->cell->map->id) {
|
||||||
|
msg("\"I'm not familiar with this area.\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// traps or trapped objects
|
// traps or trapped objects
|
||||||
if (strchr(knowflag->text, 't')) {
|
if (strchr(knowflag->text, 't')) {
|
||||||
|
@ -9321,7 +9339,7 @@ void drawstatus(void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD);
|
wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD);
|
||||||
snprintf(buf, BUFLEN, "%d ", getarmourrating(player, NULL, NULL, NULL));
|
snprintf(buf, BUFLEN, "%d ", getarmourrating(player, NULL, NULL, NULL, NULL));
|
||||||
wprintw(statwin, buf);
|
wprintw(statwin, buf);
|
||||||
|
|
||||||
wattron(statwin, A_BOLD); wprintw(statwin, "EV:"); wattroff(statwin, A_BOLD);
|
wattron(statwin, A_BOLD); wprintw(statwin, "EV:"); wattroff(statwin, A_BOLD);
|
||||||
|
@ -10351,7 +10369,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
||||||
if (showall || (lorelev >= PR_NOVICE)) {
|
if (showall || (lorelev >= PR_NOVICE)) {
|
||||||
int min,max;
|
int min,max;
|
||||||
//int min,max;
|
//int min,max;
|
||||||
arating = getarmourrating(lf, NULL, NULL, NULL);
|
arating = getarmourrating(lf, NULL, NULL, NULL, NULL);
|
||||||
//min = pctof(25, arating);
|
//min = pctof(25, arating);
|
||||||
//max = pctof(75, arating);
|
//max = pctof(75, arating);
|
||||||
|
|
||||||
|
@ -10953,6 +10971,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (finished) break;
|
||||||
}
|
}
|
||||||
} else if (mode == 'm') {
|
} else if (mode == 'm') {
|
||||||
char subheading[BUFLEN];
|
char subheading[BUFLEN];
|
||||||
|
|
87
lf.c
87
lf.c
|
@ -538,7 +538,7 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||||
reason = E_STUNNED;
|
reason = E_STUNNED;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
if (isprone(lf)) {
|
if (isprone(lf) && (oid != OT_A_FEIGNDEATH)) {
|
||||||
reason = E_PRONE;
|
reason = E_PRONE;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -705,6 +705,11 @@ int caneat(lifeform_t *lf, object_t *o) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isplayer(lf) && lfhasflag(lf, F_RAGE)) {
|
||||||
|
reason = E_WONT;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// ring of hunger overrides most eating checks
|
// ring of hunger overrides most eating checks
|
||||||
if (!hasequippedobid(lf->pack, OT_RING_HUNGER)) {
|
if (!hasequippedobid(lf->pack, OT_RING_HUNGER)) {
|
||||||
// ai won't eat bad food
|
// ai won't eat bad food
|
||||||
|
@ -2571,6 +2576,7 @@ void die(lifeform_t *lf) {
|
||||||
|
|
||||||
// inherit lifeform knowledge in case we raise it
|
// inherit lifeform knowledge in case we raise it
|
||||||
copyflag(corpse->flags, lf->flags, F_KNOWSABOUT);
|
copyflag(corpse->flags, lf->flags, F_KNOWSABOUT);
|
||||||
|
copyflag(corpse->flags, lf->flags, F_HOMEMAP);
|
||||||
|
|
||||||
// corpse of a player pet?
|
// corpse of a player pet?
|
||||||
if (ispetof(lf, player)) {
|
if (ispetof(lf, player)) {
|
||||||
|
@ -3337,7 +3343,7 @@ int eat(lifeform_t *lf, object_t *o) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case for bananas
|
// special cases for object types
|
||||||
if (o->type->id == OT_BANANA) {
|
if (o->type->id == OT_BANANA) {
|
||||||
object_t *skin;
|
object_t *skin;
|
||||||
skin = addobfast(lf->pack, OT_BANANASKIN);
|
skin = addobfast(lf->pack, OT_BANANASKIN);
|
||||||
|
@ -3359,6 +3365,9 @@ int eat(lifeform_t *lf, object_t *o) {
|
||||||
} else if (o->type->id == OT_CARROT) {
|
} else if (o->type->id == OT_CARROT) {
|
||||||
killtransitoryflags(lf->flags, F_BLIND);
|
killtransitoryflags(lf->flags, F_BLIND);
|
||||||
addtempflag(lf->flags, F_SEEINDARK, 3, NA, NA, NULL, rnd(20,40));
|
addtempflag(lf->flags, F_SEEINDARK, 3, NA, NA, NULL, rnd(20,40));
|
||||||
|
} else if (o->type->id == OT_POISONSAC) {
|
||||||
|
// very bad!
|
||||||
|
poison(lf, rnd(10,20), P_VENOM, 4, "eating a venom sac");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isplayer(lf)) makeknown(o->type->id);
|
if (isplayer(lf)) makeknown(o->type->id);
|
||||||
|
@ -4068,7 +4077,7 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn to face our attacker
|
// turn to face our attacker
|
||||||
if (!lfhasflag(lf, F_STUNNED)) {
|
if (!lfhasflag(lf, F_STUNNED) && !isdead(lf)) {
|
||||||
if (isadjacent(lf->cell, attacker->cell)) {
|
if (isadjacent(lf->cell, attacker->cell)) {
|
||||||
turntoface(lf, attacker->cell);
|
turntoface(lf, attacker->cell);
|
||||||
}
|
}
|
||||||
|
@ -5047,7 +5056,7 @@ int getarmournoise(lifeform_t *lf) {
|
||||||
|
|
||||||
|
|
||||||
// hitob, hitchnace and narms are optional
|
// hitob, hitchnace and narms are optional
|
||||||
int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms) {
|
int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, enum BODYPART *hitbp, int *narms) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
int ar = 0, i;
|
int ar = 0, i;
|
||||||
|
@ -5066,6 +5075,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms
|
||||||
if (hitob) {
|
if (hitob) {
|
||||||
hitob[*narms] = NULL;
|
hitob[*narms] = NULL;
|
||||||
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
||||||
|
if (hitbp) hitbp[*narms] = BP_BODY;
|
||||||
(*narms)++;
|
(*narms)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5074,6 +5084,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms
|
||||||
if (hitob) {
|
if (hitob) {
|
||||||
hitob[*narms] = NULL;
|
hitob[*narms] = NULL;
|
||||||
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
||||||
|
if (hitbp) hitbp[*narms] = BP_BODY;
|
||||||
(*narms)++;
|
(*narms)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5095,6 +5106,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms
|
||||||
if (hitob) {
|
if (hitob) {
|
||||||
hitob[*narms] = NULL;
|
hitob[*narms] = NULL;
|
||||||
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
hitchance[*narms] = getbodyparthitchance(BP_BODY);
|
||||||
|
if (hitbp) hitbp[*narms] = BP_BODY;
|
||||||
(*narms)++;
|
(*narms)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5151,6 +5163,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms
|
||||||
if (hitob) {
|
if (hitob) {
|
||||||
hitob[*narms] = o;
|
hitob[*narms] = o;
|
||||||
hitchance[*narms] = getbodyparthitchance(isshield ? BP_BODY : eqflag->val[0]);
|
hitchance[*narms] = getbodyparthitchance(isshield ? BP_BODY : eqflag->val[0]);
|
||||||
|
if (hitbp) hitbp[*narms] = isshield ? BP_BODY : eqflag->val[0];
|
||||||
(*narms)++;
|
(*narms)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5863,7 +5876,7 @@ int gethitstokill(lifeform_t *lf, lifeform_t *victim, int useevasion, int usearm
|
||||||
// modify by victim's armour?
|
// modify by victim's armour?
|
||||||
if (usearmour) {
|
if (usearmour) {
|
||||||
int ar,aravg,amin,amax;
|
int ar,aravg,amin,amax;
|
||||||
ar = getarmourrating(victim, NULL, NULL, NULL);
|
ar = getarmourrating(victim, NULL, NULL, NULL, NULL);
|
||||||
getarrange(ar, &amin, &amax);
|
getarrange(ar, &amin, &amax);
|
||||||
aravg = (int)(((float)amin + (float)amax) / 2.0);
|
aravg = (int)(((float)amin + (float)amax) / 2.0);
|
||||||
maxdam -= aravg;
|
maxdam -= aravg;
|
||||||
|
@ -7359,33 +7372,43 @@ int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr) {
|
||||||
return rarity;
|
return rarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_t *getrandomarmour(lifeform_t *lf) {
|
// if optional 'attacker' is provided, only select form armours which they
|
||||||
|
// can reach.
|
||||||
|
object_t *getrandomarmour(lifeform_t *lf, lifeform_t *attacker) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
object_t *poss[MAXBODYPARTS];
|
object_t *poss[MAXBODYPARTS];
|
||||||
object_t **hitposition;
|
object_t **hitposition;
|
||||||
int hitchance[MAXBODYPARTS];
|
int hitchance[MAXBODYPARTS];
|
||||||
|
enum BODYPART hitbp[MAXBODYPARTS];
|
||||||
int nposs = 0;
|
int nposs = 0;
|
||||||
int maxroll = 0;
|
int maxroll = 0;
|
||||||
int i,n,idx;
|
int i,n,idx;
|
||||||
int sel;
|
int sel;
|
||||||
|
|
||||||
// make a list of all valid armour
|
// make a list of all valid armour
|
||||||
getarmourrating(lf, poss, hitchance, &nposs);
|
getarmourrating(lf, poss, hitchance, hitbp, &nposs);
|
||||||
if (!nposs) return NULL;
|
if (!nposs) return NULL;
|
||||||
|
|
||||||
maxroll = 0;
|
maxroll = 0;
|
||||||
for (i = 0; i < nposs; i++) {
|
for (i = 0; i < nposs; i++) {
|
||||||
|
if (!attacker || canreachbp(attacker, lf, hitbp[i])) {
|
||||||
maxroll += hitchance[i];
|
maxroll += hitchance[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (maxroll == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
// now figure out chances of each one getting hit
|
// now figure out chances of each one getting hit
|
||||||
hitposition = malloc(maxroll * sizeof(object_t *));
|
hitposition = malloc(maxroll * sizeof(object_t *));
|
||||||
idx = 0;
|
idx = 0;
|
||||||
for (i = 0; i < nposs; i++) {
|
for (i = 0; i < nposs; i++) {
|
||||||
|
if (!attacker || canreachbp(attacker, lf, hitbp[i])) {
|
||||||
for (n = 0; n < hitchance[i]; n++) {
|
for (n = 0; n < hitchance[i]; n++) {
|
||||||
hitposition[idx] = poss[i];
|
hitposition[idx] = poss[i];
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sel = rnd(0, maxroll-1);
|
sel = rnd(0, maxroll-1);
|
||||||
o = hitposition[sel];
|
o = hitposition[sel];
|
||||||
|
@ -9073,8 +9096,10 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, val[1], B_TRUE, OC_NONE, DT_NONE)) {
|
if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, maxobsize, val[1], B_TRUE, OC_NONE, DT_NONE)) {
|
||||||
|
char buf3[BUFLEN];
|
||||||
if (db) snprintf(buf2, BUFLEN, "finished startobwepsk successfuly.");
|
if (db) snprintf(buf2, BUFLEN, "finished startobwepsk successfuly.");
|
||||||
o = addob(op, buf);
|
sprintf(buf3, "%s%s%s",text,strlen(text) ? " " : "",buf);
|
||||||
|
o = addob(op, buf3);
|
||||||
} else {
|
} else {
|
||||||
if (db) snprintf(buf2, BUFLEN, "finished startobwepsk, failed.");
|
if (db) snprintf(buf2, BUFLEN, "finished startobwepsk, failed.");
|
||||||
}
|
}
|
||||||
|
@ -10249,8 +10274,10 @@ flag_t *isasleep(lifeform_t *lf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// is lf behind otherlf?
|
// is lf behind otherlf?
|
||||||
|
// you can never be "behind" something with f_awareness
|
||||||
int isbehind(lifeform_t *lf, lifeform_t *otherlf) {
|
int isbehind(lifeform_t *lf, lifeform_t *otherlf) {
|
||||||
int dir;
|
int dir;
|
||||||
|
if (lfhasflag(otherlf, F_AWARENESS)) return B_FALSE;
|
||||||
dir = getdirtowards(otherlf->cell, lf->cell, NULL, B_FALSE, DT_ORTH);
|
dir = getdirtowards(otherlf->cell, lf->cell, NULL, B_FALSE, DT_ORTH);
|
||||||
if (getrelativedir(otherlf, dir) == RD_BACKWARDS) {
|
if (getrelativedir(otherlf, dir) == RD_BACKWARDS) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
|
@ -10969,6 +10996,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
a->losdirty = B_TRUE;
|
a->losdirty = B_TRUE;
|
||||||
|
addflag(a->flags, F_HOMEMAP, cell->map->id, NA, NA, NULL);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11368,6 +11396,9 @@ lifeform_t *makezombie(object_t *o) {
|
||||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2) {
|
int areenemies(lifeform_t *lf1, lifeform_t *lf2) {
|
||||||
reason = E_OK;
|
reason = E_OK;
|
||||||
|
|
||||||
|
if (!isplayer(lf1) && lfhasflagval(lf1, F_TARGETLF, lf2->id, NA, NA, NULL)) return B_TRUE;
|
||||||
|
if (!isplayer(lf2) && lfhasflagval(lf2, F_TARGETLF, lf1->id, NA, NA, NULL)) return B_TRUE;
|
||||||
|
|
||||||
if (hasjob(lf1, J_DRUID) && (getraceclass(lf2) == RC_PLANT)) {
|
if (hasjob(lf1, J_DRUID) && (getraceclass(lf2) == RC_PLANT)) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
} else if (hasjob(lf2, J_DRUID) && (getraceclass(lf1) == RC_PLANT)) {
|
} else if (hasjob(lf2, J_DRUID) && (getraceclass(lf1) == RC_PLANT)) {
|
||||||
|
@ -11672,6 +11703,8 @@ void autoskill(lifeform_t *lf) {
|
||||||
object_t *o;
|
object_t *o;
|
||||||
enum SKILLLEVEL slev;
|
enum SKILLLEVEL slev;
|
||||||
int nweps = 0;
|
int nweps = 0;
|
||||||
|
flag_t *retflag[MAXCANDIDATES],*f;
|
||||||
|
int nretflags,i;
|
||||||
|
|
||||||
if (hasjob(lf, J_COMMANDO)) {
|
if (hasjob(lf, J_COMMANDO)) {
|
||||||
return;
|
return;
|
||||||
|
@ -11689,6 +11722,18 @@ void autoskill(lifeform_t *lf) {
|
||||||
if (sk && !getskill(lf, sk->id)) {
|
if (sk && !getskill(lf, sk->id)) {
|
||||||
giveskilllev(lf, sk->id, slev);
|
giveskilllev(lf, sk->id, slev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// monsters:increase stats to match attribn requirements for starting
|
||||||
|
// weapon.
|
||||||
|
if (!isplayer(lf)) {
|
||||||
|
getflags(o->flags, retflag, &nretflags, F_ATTREQ, F_NONE);
|
||||||
|
for (i = 0; i < nretflags; i++) {
|
||||||
|
f = retflag[i];
|
||||||
|
if (getattr(lf, f->val[0]) < f->val[1]) {
|
||||||
|
setattr(lf, f->val[0], f->val[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
nweps++;
|
nweps++;
|
||||||
}
|
}
|
||||||
if (isfirearm(o) && canweild(lf, o)) {
|
if (isfirearm(o) && canweild(lf, o)) {
|
||||||
|
@ -12361,7 +12406,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
||||||
|
|
||||||
setlastdam(lf, buf);
|
setlastdam(lf, buf);
|
||||||
|
|
||||||
if (fromlf && lfhasflag(fromlf, F_CARNIVORE)) {
|
if (fromlf && willeatlf(fromlf, lf)) {
|
||||||
setkillverb(lf, "Eaten");
|
setkillverb(lf, "Eaten");
|
||||||
} else {
|
} else {
|
||||||
switch (damtype) {
|
switch (damtype) {
|
||||||
|
@ -13231,7 +13276,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
||||||
|
|
||||||
if (willrespond) {
|
if (willrespond) {
|
||||||
// turn to face the sound
|
// turn to face the sound
|
||||||
if (isplayer(noisemaker) && cansee(l, player) && !lfhasflag(l, F_AWARENESS)) {
|
if (isplayer(noisemaker) && cansee(l, player) && !lfhasflag(l, F_AWARENESS) && !isdead(l)) {
|
||||||
// peaceful things only turn sometimes
|
// peaceful things only turn sometimes
|
||||||
if (!ispeaceful(l) || onein(6)) {
|
if (!ispeaceful(l) || onein(6)) {
|
||||||
char lfname[BUFLEN];
|
char lfname[BUFLEN];
|
||||||
|
@ -13271,6 +13316,7 @@ void outfitlf(lifeform_t *lf) {
|
||||||
//int db = B_FALSE;
|
//int db = B_FALSE;
|
||||||
givestartskills(lf, lf->flags);
|
givestartskills(lf, lf->flags);
|
||||||
givestartobs(lf, NULL, lf->flags);
|
givestartobs(lf, NULL, lf->flags);
|
||||||
|
autoskill(lf);
|
||||||
|
|
||||||
// weild/wear stuff
|
// weild/wear stuff
|
||||||
autoweild(lf);
|
autoweild(lf);
|
||||||
|
@ -14786,6 +14832,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
||||||
retainhp = B_TRUE;
|
retainhp = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loseconcentration(lf);
|
||||||
|
|
||||||
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
|
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
|
||||||
if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) {
|
if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) {
|
||||||
race_t *origrace = NULL;
|
race_t *origrace = NULL;
|
||||||
|
@ -17246,6 +17294,7 @@ int touch(lifeform_t *lf, object_t *o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void turntoface(lifeform_t *lf, cell_t *dstcell) {
|
void turntoface(lifeform_t *lf, cell_t *dstcell) {
|
||||||
|
if (isdead(lf)) return;
|
||||||
// not providing srclf, since this will make getdirtowards() not include
|
// not providing srclf, since this will make getdirtowards() not include
|
||||||
// directions in which the next cell is unwalkable. in this case we're
|
// directions in which the next cell is unwalkable. in this case we're
|
||||||
// not actually walking there, so we don't care.
|
// not actually walking there, so we don't care.
|
||||||
|
@ -18438,7 +18487,7 @@ int wear(lifeform_t *lf, object_t *o) {
|
||||||
case 1: strcpy(verb, "puts on"); break;
|
case 1: strcpy(verb, "puts on"); break;
|
||||||
case 2: strcpy(verb, "dons"); break;
|
case 2: strcpy(verb, "dons"); break;
|
||||||
}
|
}
|
||||||
msg("%s %s %s.", buf, obname);
|
msg("%s %s %s.", buf, verb, obname);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18835,4 +18884,18 @@ int willburden(lifeform_t *lf, object_t *o, int howmany) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int willeatlf(lifeform_t *eater, lifeform_t *eatee) {
|
||||||
|
if (isplayer(eater)) return B_FALSE;
|
||||||
|
// doesn't want to eat
|
||||||
|
if (!lfhasflagval(eater, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
// does eater eat eatee's material?
|
||||||
|
if ((eatee->material->id == MT_FLESH) && lfhasflag(eater, F_CARNIVORE)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
if ((eatee->material->id == MT_PLANT) && lfhasflag(eater, F_VEGETARIAN)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
5
lf.h
5
lf.h
|
@ -124,7 +124,7 @@ enum ALLEGIENCE getallegiance(lifeform_t *lf);
|
||||||
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
|
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
|
||||||
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||||
int getarmournoise(lifeform_t *lf);
|
int getarmournoise(lifeform_t *lf);
|
||||||
int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms);
|
int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, enum BODYPART *hitbp, int *narms);
|
||||||
int getattackspeed(lifeform_t *lf);
|
int getattackspeed(lifeform_t *lf);
|
||||||
float getattackstamloss(lifeform_t *lf);
|
float getattackstamloss(lifeform_t *lf);
|
||||||
float getattackstamloss(lifeform_t *lf);
|
float getattackstamloss(lifeform_t *lf);
|
||||||
|
@ -218,7 +218,7 @@ char *getpoisonname(enum POISONTYPE ptype);
|
||||||
enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
|
enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
|
||||||
int getraceclass(lifeform_t *lf);
|
int getraceclass(lifeform_t *lf);
|
||||||
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr);
|
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr);
|
||||||
object_t *getrandomarmour(lifeform_t *lf);
|
object_t *getrandomarmour(lifeform_t *lf, lifeform_t *attacker);
|
||||||
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker);
|
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker);
|
||||||
race_t *getrandomcorpserace(cell_t *c);
|
race_t *getrandomcorpserace(cell_t *c);
|
||||||
job_t *getrandomjob(int onlyplayerjobs);
|
job_t *getrandomjob(int onlyplayerjobs);
|
||||||
|
@ -427,4 +427,5 @@ int wear(lifeform_t *lf, object_t *o);
|
||||||
int weild(lifeform_t *lf, object_t *o);
|
int weild(lifeform_t *lf, object_t *o);
|
||||||
int willbleedfrom(lifeform_t *lf, enum BODYPART bp);
|
int willbleedfrom(lifeform_t *lf, enum BODYPART bp);
|
||||||
int willburden(lifeform_t *lf, object_t *o, int howmany);
|
int willburden(lifeform_t *lf, object_t *o, int howmany);
|
||||||
|
int willeatlf(lifeform_t *eater, lifeform_t *eatee);
|
||||||
//int youhear(cell_t *c, char *text);
|
//int youhear(cell_t *c, char *text);
|
||||||
|
|
55
map.c
55
map.c
|
@ -1695,7 +1695,7 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
||||||
int includethiscell = B_FALSE;
|
int includethiscell = B_FALSE;
|
||||||
cell = getcellat(map, rx,ry);
|
cell = getcellat(map, rx,ry);
|
||||||
|
|
||||||
// NEVER create a vault whcih will:
|
// NEVER create a room whcih will:
|
||||||
// - be on top of the player (normally this can't happen,
|
// - be on top of the player (normally this can't happen,
|
||||||
// but debugging via 'create vault' could do it)
|
// but debugging via 'create vault' could do it)
|
||||||
if (cell->lf && isplayer(cell->lf)) {
|
if (cell->lf && isplayer(cell->lf)) {
|
||||||
|
@ -1764,12 +1764,13 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int
|
||||||
if (db) dblog("cell %d,%d - a %dx%d room would not fit here",x,y,score,w,h);
|
if (db) dblog("cell %d,%d - a %dx%d room would not fit here",x,y,score,w,h);
|
||||||
}
|
}
|
||||||
coordscore[i] = score;
|
coordscore[i] = score;
|
||||||
if (db) dblog("cell %d,%d - score %d",x,y,score);
|
if (db) dblog("topleft at %d,%d => score %d",x,y,score);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundvalid) {
|
if (foundvalid) {
|
||||||
// now go through and make a list of all BEST positions
|
// now go through and make a list of all BEST positions
|
||||||
nposs = 0;
|
nposs = 0;
|
||||||
|
assert(bestscore != 9888);
|
||||||
for (i = 0; i < ncoords; i++) {
|
for (i = 0; i < ncoords; i++) {
|
||||||
if (coordscore[i] == bestscore) {
|
if (coordscore[i] == bestscore) {
|
||||||
poss[nposs++] = coord[i];
|
poss[nposs++] = coord[i];
|
||||||
|
@ -2434,10 +2435,10 @@ void createfakes(map_t *map, cell_t *cell) {
|
||||||
map->lastlf = NULL;
|
map->lastlf = NULL;
|
||||||
map->name = strdup("fake map");
|
map->name = strdup("fake map");
|
||||||
map->habitat = findhabitat(H_DUNGEON);
|
map->habitat = findhabitat(H_DUNGEON);
|
||||||
setcelltype(cell, CT_FAKE);
|
|
||||||
cell->lf = NULL;
|
|
||||||
cell->map = map;
|
cell->map = map;
|
||||||
|
cell->lf = NULL;
|
||||||
cell->obpile = addobpile(NULL, NULL, NULL);
|
cell->obpile = addobpile(NULL, NULL, NULL);
|
||||||
|
setcelltype(cell, CT_FAKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
|
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
|
||||||
|
@ -2814,6 +2815,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
||||||
switch (thing[nthings]->whatkind) {
|
switch (thing[nthings]->whatkind) {
|
||||||
case RT_VAULT:
|
case RT_VAULT:
|
||||||
case RT_RNDVAULTWITHFLAG:
|
case RT_RNDVAULTWITHFLAG:
|
||||||
|
case RT_RNDVAULTWITHTAG:
|
||||||
// this will reduce the amount of random rooms which can
|
// this will reduce the amount of random rooms which can
|
||||||
// be created on this map.
|
// be created on this map.
|
||||||
map->nfixedrooms++;
|
map->nfixedrooms++;
|
||||||
|
@ -2888,6 +2890,15 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
||||||
failed = B_TRUE;
|
failed = B_TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RT_RNDVAULTWITHTAG:
|
||||||
|
if (db) dblog(" adding rndvaultwithtag");
|
||||||
|
v = findvaultwithtag(thing[i]->what);
|
||||||
|
assert(v);
|
||||||
|
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
|
||||||
|
dblog("ERROR - couldn't create rndvaultwithtag %s on map %s", v->id, map->name);
|
||||||
|
failed = B_TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
|
||||||
|
@ -4632,7 +4643,7 @@ void finalisemap(map_t *map, object_t *entryob) {
|
||||||
} else {
|
} else {
|
||||||
// up stairs on all other levels
|
// up stairs on all other levels
|
||||||
int nneeded;
|
int nneeded;
|
||||||
nneeded = map->region->rtype->stairsperlev - countstairs(map, D_UP);
|
nneeded = map->region->rtype->stairsperlev - countmapobs(map, upstairtype);
|
||||||
for (i = 0; i < nneeded; i++) {
|
for (i = 0; i < nneeded; i++) {
|
||||||
c = NULL;
|
c = NULL;
|
||||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||||
|
@ -4659,7 +4670,7 @@ void finalisemap(map_t *map, object_t *entryob) {
|
||||||
// DOWN STAIRS
|
// DOWN STAIRS
|
||||||
if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) {
|
if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) {
|
||||||
int nneeded;
|
int nneeded;
|
||||||
nneeded = map->region->rtype->stairsperlev - countstairs(map, D_DOWN);
|
nneeded = map->region->rtype->stairsperlev - countmapobs(map, downstairtype);
|
||||||
for (i = 0; i < nneeded; i++) {
|
for (i = 0; i < nneeded; i++) {
|
||||||
c = NULL;
|
c = NULL;
|
||||||
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
while (!c || !isempty(c) || countobs(c->obpile, B_TRUE)) {
|
||||||
|
@ -5599,7 +5610,7 @@ void initmap(void) {
|
||||||
// region types
|
// region types
|
||||||
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
|
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
|
||||||
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
|
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
|
||||||
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 6, 1, D_DOWN, B_TRUE, 5);
|
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 5);
|
||||||
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
|
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
|
||||||
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
|
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
|
||||||
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2);
|
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2);
|
||||||
|
@ -5665,7 +5676,9 @@ void initmap(void) {
|
||||||
addregionthing(lastregionoutline, rnd(17,19), NA, NA, RT_OBJECT, NA, "random building");
|
addregionthing(lastregionoutline, rnd(17,19), NA, NA, RT_OBJECT, NA, "random building");
|
||||||
addregionthing(lastregionoutline, rnd(20,22), NA, NA, RT_OBJECT, NA, "random building");
|
addregionthing(lastregionoutline, rnd(20,22), NA, NA, RT_OBJECT, NA, "random building");
|
||||||
addregionthing(lastregionoutline, rnd(23,25), NA, NA, RT_OBJECT, NA, "random building");
|
addregionthing(lastregionoutline, rnd(23,25), NA, NA, RT_OBJECT, NA, "random building");
|
||||||
|
|
||||||
addregionoutline(RG_CAVE);
|
addregionoutline(RG_CAVE);
|
||||||
|
addregionthing(lastregionoutline, 5, NA, NA, RT_RNDVAULTWITHTAG, NA, "caveboss");
|
||||||
|
|
||||||
// add initial regions
|
// add initial regions
|
||||||
addregion(RG_WORLDMAP, NULL, -1, 0);
|
addregion(RG_WORLDMAP, NULL, -1, 0);
|
||||||
|
@ -6106,11 +6119,15 @@ int linkstairs(object_t *o, object_t *o2) {
|
||||||
}
|
}
|
||||||
if (othermap) {
|
if (othermap) {
|
||||||
int found = B_FALSE;
|
int found = B_FALSE;
|
||||||
// find an empty staircase in other map
|
object_t *poss[MAXCANDIDATES];
|
||||||
|
int nposs = 0;
|
||||||
|
// find an empty staircase of the correct type in the other map
|
||||||
for (n = 0; n < othermap->w*othermap->h; n++) {
|
for (n = 0; n < othermap->w*othermap->h; n++) {
|
||||||
c2 = othermap->cell[n];
|
c2 = othermap->cell[n];
|
||||||
oo = hasob(c2->obpile, otherstairtype->id);
|
oo = hasob(c2->obpile, otherstairtype->id);
|
||||||
if (oo) {
|
if (oo) {
|
||||||
|
// remember all stairs of correct type, for debugging.
|
||||||
|
poss[nposs++] = oo;
|
||||||
// does it go nowhere?
|
// does it go nowhere?
|
||||||
if (!hasflag(oo->flags, F_MAPLINK)) {
|
if (!hasflag(oo->flags, F_MAPLINK)) {
|
||||||
o2 = oo;
|
o2 = oo;
|
||||||
|
@ -6120,9 +6137,9 @@ int linkstairs(object_t *o, object_t *o2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
dblog("ERROR - stairs link to existing map %d('%s', depth %d), but it has no free stairs.",othermap->id,
|
dblog("ERROR - stairs should link to existing map ('%s', depth %d), but it has no free stairs.",
|
||||||
othermap->name, othermap->depth);
|
othermap->name, othermap->depth);
|
||||||
msg("ERROR - stairs link to existing map %d('%s', depth %d), but it has no free stairs.",othermap->id,
|
msg("ERROR - stairs should link to existing map ('%s', depth %d), but it has no free stairs.",
|
||||||
othermap->name, othermap->depth);
|
othermap->name, othermap->depth);
|
||||||
more();
|
more();
|
||||||
raise(SIGINT); // debug
|
raise(SIGINT); // debug
|
||||||
|
@ -6378,7 +6395,7 @@ int remove_deadends(map_t *m, int howmuch) {
|
||||||
for (n = 0; n < m->w * m->h; n++) {
|
for (n = 0; n < m->w * m->h; n++) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
c = m->cell[n];
|
c = m->cell[n];
|
||||||
if (countcellexits(c, DT_ORTH) == 1) {
|
if (!c->room && (countcellexits(c, DT_ORTH) == 1)) {
|
||||||
// erase this cell
|
// erase this cell
|
||||||
clearcell(c);
|
clearcell(c);
|
||||||
setcelltype(c, solidcell);
|
setcelltype(c, solidcell);
|
||||||
|
@ -6422,8 +6439,16 @@ void setcellknown(cell_t *cell, int forcelev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cell->known = B_TRUE;
|
cell->known = B_TRUE;
|
||||||
// default to remembering the cell's glyph
|
// default to remembering the cell's glyph, or a wall if there's a secret door there
|
||||||
|
o = hassecretdoor(cell->obpile);
|
||||||
|
if (o) {
|
||||||
|
celltype_t *ct;
|
||||||
|
ct = findcelltype(cell->habitat->solidcelltype);
|
||||||
|
cell->knownglyph = ct->glyph;
|
||||||
|
} else {
|
||||||
cell->knownglyph = cell->type->glyph;
|
cell->knownglyph = cell->type->glyph;
|
||||||
|
}
|
||||||
|
|
||||||
// high cartography skill lets us remember certain objects...
|
// high cartography skill lets us remember certain objects...
|
||||||
if (slev >= PR_EXPERT) {
|
if (slev >= PR_EXPERT) {
|
||||||
o = gettopobject(cell, B_TRUE);
|
o = gettopobject(cell, B_TRUE);
|
||||||
|
@ -6715,6 +6740,12 @@ int validateregionthing(regionthing_t *thing) {
|
||||||
goterrors = B_TRUE;
|
goterrors = B_TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case RT_RNDVAULTWITHTAG:
|
||||||
|
if (!findvaultwithtag(thing->what)) {
|
||||||
|
dblog("Invalid rt_rndvaultwithtag specified in regionthing.");
|
||||||
|
goterrors = B_TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
killfakes(&fakemap, &fakecell);
|
killfakes(&fakemap, &fakecell);
|
||||||
return goterrors;
|
return goterrors;
|
||||||
|
|
6
move.c
6
move.c
|
@ -171,6 +171,8 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wis = getattrbracket(getattr(lf, A_WIS), A_WIS, NULL);
|
||||||
|
|
||||||
// obvious things that you can see
|
// obvious things that you can see
|
||||||
if (!onlyifknown || (haslos(lf, cell) && !lfhasflag(lf, F_UNDEAD))) {
|
if (!onlyifknown || (haslos(lf, cell) && !lfhasflag(lf, F_UNDEAD))) {
|
||||||
// water needing creature out of water?
|
// water needing creature out of water?
|
||||||
|
@ -269,7 +271,6 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
if (!onlyifknown) {
|
if (!onlyifknown) {
|
||||||
include_nonobvious = B_TRUE;
|
include_nonobvious = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
wis = getattrbracket(getattr(lf, A_WIS), A_WIS, NULL);
|
|
||||||
if ((wis >= AT_AVERAGE) && haslos(lf, cell)) {
|
if ((wis >= AT_AVERAGE) && haslos(lf, cell)) {
|
||||||
if (!lfhasflag(lf, F_UNDEAD)) {
|
if (!lfhasflag(lf, F_UNDEAD)) {
|
||||||
include_nonobvious = B_TRUE;
|
include_nonobvious = B_TRUE;
|
||||||
|
@ -279,6 +280,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
if (include_nonobvious) {
|
if (include_nonobvious) {
|
||||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
// don't walk on sharp objects without boots
|
// don't walk on sharp objects without boots
|
||||||
|
if (!onlyifknown || (wis >= AT_AVERAGE)) {
|
||||||
if (hasflag(o->flags, F_SHARP)) {
|
if (hasflag(o->flags, F_SHARP)) {
|
||||||
if (!getequippedob(lf->pack, BP_FEET)) {
|
if (!getequippedob(lf->pack, BP_FEET)) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -290,6 +292,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3225,6 +3228,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||||
|
|
||||||
// don't attack other monsters
|
// don't attack other monsters
|
||||||
// or non-enemies
|
// or non-enemies
|
||||||
|
// (unless we have targetted them)
|
||||||
if (cell->lf) { // if someone is in the way
|
if (cell->lf) { // if someone is in the way
|
||||||
object_t *defenderwep = NULL;
|
object_t *defenderwep = NULL;
|
||||||
if (lf->race->raceclass->id == RC_INSECT) {
|
if (lf->race->raceclass->id == RC_INSECT) {
|
||||||
|
|
6
nexus.c
6
nexus.c
|
@ -934,13 +934,19 @@ void donextturn(map_t *map) {
|
||||||
//dbtimeend(buf);
|
//dbtimeend(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isplayer(who) && (who->timespent == 0) && !donormalmove) {
|
||||||
|
// our auto action failed!
|
||||||
|
taketime(who, getactspeed(who));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// us or the player moved into a new map? stop turn.
|
// us or the player moved into a new map? stop turn.
|
||||||
if ((who->cell->map != map) || (player->cell->map != map)) {
|
if ((who->cell->map != map) || (player->cell->map != map)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasflag(player->flags, F_ASLEEP)) {
|
if (hasflag(player->flags, F_ASLEEP)) {
|
||||||
|
|
47
objects.c
47
objects.c
|
@ -4,6 +4,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ai.h"
|
||||||
#include "attack.h"
|
#include "attack.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "flag.h"
|
#include "flag.h"
|
||||||
|
@ -2785,7 +2786,7 @@ int countobsoftype(obpile_t *op, enum OBTYPE oid) {
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (o = op->first ; o ; o = o->next) {
|
for (o = op->first ; o ; o = o->next) {
|
||||||
if (o->id == oid) {
|
if (o->type->id == oid) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6218,6 +6219,15 @@ object_t *hasobid(obpile_t *op, long id) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_t *hassecretdoor(obpile_t *op) {
|
||||||
|
object_t *o;
|
||||||
|
for (o = op->first ; o ; o = o->next) {
|
||||||
|
if (isdoor(o, NULL) && hasflag(o->flags, F_SECRET)) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// fully identify a single object.
|
// fully identify a single object.
|
||||||
void identify(object_t *o) {
|
void identify(object_t *o) {
|
||||||
|
@ -8541,7 +8551,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
||||||
if (!seen) {
|
if (!seen) {
|
||||||
noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL);
|
noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL);
|
||||||
}
|
}
|
||||||
} else if (o->type->id == OT_GODSTONEJ) {
|
} else if (o->type->obclass->id == OC_GODSTONE) {
|
||||||
f = hasflag(o->flags, F_CHARGES);
|
f = hasflag(o->flags, F_CHARGES);
|
||||||
if (f && (f->val[0] == f->val[1])) {
|
if (f && (f->val[0] == f->val[1])) {
|
||||||
int x,y;
|
int x,y;
|
||||||
|
@ -8554,6 +8564,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
||||||
msg("%s%s %s unleashes a blast of power!", lfname, getpossessive(lfname), noprefix(obname));
|
msg("%s%s %s unleashes a blast of power!", lfname, getpossessive(lfname), noprefix(obname));
|
||||||
}
|
}
|
||||||
noise(lf->cell, NULL, NC_OTHER, 10, "an ear-splitting crack", NULL);
|
noise(lf->cell, NULL, NC_OTHER, 10, "an ear-splitting crack", NULL);
|
||||||
|
switch (o->type->id) {
|
||||||
|
case OT_GODSTONEJ: // justice
|
||||||
// everyone in lof drops to same hp as user
|
// everyone in lof drops to same hp as user
|
||||||
for (y = 0; y < lf->cell->map->h; y++) {
|
for (y = 0; y < lf->cell->map->h; y++) {
|
||||||
for (x = 0; x < lf->cell->map->w; x++) {
|
for (x = 0; x < lf->cell->map->w; x++) {
|
||||||
|
@ -8571,6 +8583,28 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case OT_GODSTONER: // rage
|
||||||
|
// everyone in lof gets f_rage, and hates everything
|
||||||
|
for (y = 0; y < lf->cell->map->h; y++) {
|
||||||
|
for (x = 0; x < lf->cell->map->w; x++) {
|
||||||
|
cell_t *c;
|
||||||
|
c = getcellat(lf->cell->map, x, y);
|
||||||
|
if (c && c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_NEED, NULL)) {
|
||||||
|
int howlong = 50;
|
||||||
|
addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong);
|
||||||
|
if (!isplayer(c->lf)) {
|
||||||
|
addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong);
|
||||||
|
loseaitargets(c->lf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
f->val[0] = 0; // use up all charges
|
f->val[0] = 0; // use up all charges
|
||||||
} else {
|
} else {
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
|
@ -11918,7 +11952,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reduceamt && (speed >= 3)) {
|
if (reduceamt && (speed >= 3)) {
|
||||||
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE);
|
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam);
|
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam);
|
||||||
|
@ -12202,14 +12236,17 @@ void timeeffectsob(object_t *o) {
|
||||||
|
|
||||||
if (location) {
|
if (location) {
|
||||||
// object makes noise?
|
// object makes noise?
|
||||||
f = hasflag(o->flags, F_MAKESNOISE);
|
getflags(o->flags, retflag, &nretflags, F_MAKESNOISE, F_NONE);
|
||||||
if (f && pctchance(f->val[0])) {
|
if (nretflags) {
|
||||||
|
f = retflag[rnd(0,nretflags-1)];
|
||||||
|
if (pctchance(f->val[0])) {
|
||||||
// these are generally just to notify the player that something
|
// these are generally just to notify the player that something
|
||||||
// is nearby, so don't make noises the the player is already there.
|
// is nearby, so don't make noises the the player is already there.
|
||||||
if (location != player->cell) {
|
if (location != player->cell) {
|
||||||
noise(location, NULL, NC_OTHER, f->val[1], f->text, NULL);
|
noise(location, NULL, NC_OTHER, f->val[1], f->text, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// does object's material change cell type?
|
// does object's material change cell type?
|
||||||
if (o->material->id == MT_FIRE) {
|
if (o->material->id == MT_FIRE) {
|
||||||
if (hasflag(location->type->material->flags, F_FLAMMABLE)) {
|
if (hasflag(location->type->material->flags, F_FLAMMABLE)) {
|
||||||
|
|
|
@ -159,6 +159,7 @@ object_t *hasobmulti(obpile_t *op, enum OBTYPE *oid, int noids);
|
||||||
object_t *hasobwithflag(obpile_t *op, enum FLAG flagid);
|
object_t *hasobwithflag(obpile_t *op, enum FLAG flagid);
|
||||||
object_t *hasobwithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
object_t *hasobwithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
||||||
object_t *hasobid(obpile_t *op, long id);
|
object_t *hasobid(obpile_t *op, long id);
|
||||||
|
object_t *hassecretdoor(obpile_t *op);
|
||||||
void identify(object_t *o);
|
void identify(object_t *o);
|
||||||
void ignite(object_t *o);
|
void ignite(object_t *o);
|
||||||
flag_t *isarmour(object_t *o);
|
flag_t *isarmour(object_t *o);
|
||||||
|
|
10
spell.c
10
spell.c
|
@ -983,7 +983,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
||||||
msg("%s dies.", username);
|
msg("%s dies.", username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isprone(user)) {
|
||||||
addflag(user->flags, F_PRONE, B_TRUE, NA, NA, NULL);
|
addflag(user->flags, F_PRONE, B_TRUE, NA, NA, NULL);
|
||||||
|
}
|
||||||
addflag(user->flags, F_FEIGNINGDEATH, B_TRUE, NA, NA, NULL);
|
addflag(user->flags, F_FEIGNINGDEATH, B_TRUE, NA, NA, NULL);
|
||||||
// anyone attacking you stops
|
// anyone attacking you stops
|
||||||
for (lf = user->cell->map->lf ; lf ; lf = lf->next) {
|
for (lf = user->cell->map->lf ; lf ; lf = lf->next) {
|
||||||
|
@ -2966,7 +2968,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f = addflag(user->flags, F_ACCURACYMOD, 100, NA, NA, NULL);
|
f = addflag(user->flags, F_ACCURACYMOD, 200, NA, NA, NULL);
|
||||||
attackcell(user, targcell, B_FALSE);
|
attackcell(user, targcell, B_FALSE);
|
||||||
taketime(user, getattackspeed(user)*2);
|
taketime(user, getattackspeed(user)*2);
|
||||||
killflag(f);
|
killflag(f);
|
||||||
|
@ -3642,7 +3644,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
int i;
|
int i;
|
||||||
object_t *o,*nexto;
|
object_t *o,*nexto;
|
||||||
int donesomething = B_FALSE;
|
int donesomething = B_FALSE;
|
||||||
if (isplayer(caster)) {
|
if (!target) {
|
||||||
target = caster;
|
target = caster;
|
||||||
}
|
}
|
||||||
// animate corpses within lof of caster
|
// animate corpses within lof of caster
|
||||||
|
@ -6930,10 +6932,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
|
|
||||||
if (isplayer(target)) {
|
if (isplayer(target)) {
|
||||||
msg("^wYou are engulfed in an anti-magic field!");
|
msg("^wYou are engulfed in an anti-magic field!");
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
} else if (cansee(player, target)) {
|
} else if (cansee(player, target)) {
|
||||||
char lfname[BUFLEN];
|
char lfname[BUFLEN];
|
||||||
getlfname(target, lfname);
|
getlfname(target, lfname);
|
||||||
msg("^w%s is engulfed in an anti-magic field!", lfname);
|
msg("^w%s is engulfed in an anti-magic field!", lfname);
|
||||||
|
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||||
}
|
}
|
||||||
while (ndone < power) {
|
while (ndone < power) {
|
||||||
// get a list of flags which could be destroyed
|
// get a list of flags which could be destroyed
|
||||||
|
@ -7494,7 +7498,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
}
|
}
|
||||||
for (i = 0; i < howmany; i++) {
|
for (i = 0; i < howmany; i++) {
|
||||||
// pick armour
|
// pick armour
|
||||||
o = getrandomarmour(target);
|
o = getrandomarmour(target, NULL);
|
||||||
if (o) {
|
if (o) {
|
||||||
char obname[BUFLEN];
|
char obname[BUFLEN];
|
||||||
// move it
|
// move it
|
||||||
|
|
4
text.c
4
text.c
|
@ -431,11 +431,11 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
|
||||||
}
|
}
|
||||||
} else if (damtype == DT_CHOP) {
|
} else if (damtype == DT_CHOP) {
|
||||||
if (pct <= 5) {
|
if (pct <= 5) {
|
||||||
return "hit";
|
return "chop";
|
||||||
} else if (pct <= 15) {
|
} else if (pct <= 15) {
|
||||||
return "hack";
|
return "hack";
|
||||||
} else {
|
} else {
|
||||||
return "chop";
|
return "cleave";
|
||||||
}
|
}
|
||||||
} else if (damtype == DT_COLD) {
|
} else if (damtype == DT_COLD) {
|
||||||
if (pct <= 10) {
|
if (pct <= 10) {
|
||||||
|
|
23
vault.c
23
vault.c
|
@ -521,6 +521,24 @@ vault_t *findvaultwithflag(enum FLAG fid) {
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return a random vault with the given tag (ie. f_vaulttag "xxx").
|
||||||
|
// don't care about rarity.
|
||||||
|
vault_t *findvaultwithtag(char *tag) {
|
||||||
|
vault_t *v;
|
||||||
|
vault_t *poss[MAXCANDIDATES];
|
||||||
|
int nposs = 0;
|
||||||
|
for (v = firstvault ; v ; v = v->next) {
|
||||||
|
if (!v->valid) continue;
|
||||||
|
if (hasflagval(v->flags, F_VAULTTAG, NA, NA, NA, tag)) poss[nposs++] = v;
|
||||||
|
}
|
||||||
|
if (nposs) {
|
||||||
|
v = poss[rnd(0,nposs-1)];
|
||||||
|
} else {
|
||||||
|
v = NULL;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
// generate vault map 1 as x-flipped map0.
|
// generate vault map 1 as x-flipped map0.
|
||||||
// remember offsets into map[0]
|
// remember offsets into map[0]
|
||||||
void generatevaultflipsx(vault_t *v) {
|
void generatevaultflipsx(vault_t *v) {
|
||||||
|
@ -1405,6 +1423,11 @@ int handleline(vault_t *v, char *line) {
|
||||||
} else if (streq(line, "shop")) {
|
} else if (streq(line, "shop")) {
|
||||||
addflag(v->flags, F_VAULTISSHOP, B_TRUE, NA, NA, NULL);
|
addflag(v->flags, F_VAULTISSHOP, B_TRUE, NA, NA, NULL);
|
||||||
ok = B_TRUE;
|
ok = B_TRUE;
|
||||||
|
} else if (strstarts(line, "tag:")) {
|
||||||
|
char *p;
|
||||||
|
p = line + 4;
|
||||||
|
addflag(v->flags, F_VAULTTAG, B_TRUE, NA, NA, p);
|
||||||
|
ok = B_TRUE;
|
||||||
} else if (streq(line, "shrine")) { // a godstone shrine
|
} else if (streq(line, "shrine")) { // a godstone shrine
|
||||||
addflag(v->flags, F_VAULTISSHRINE, B_TRUE, NA, NA, NULL);
|
addflag(v->flags, F_VAULTISSHRINE, B_TRUE, NA, NA, NULL);
|
||||||
ok = B_TRUE;
|
ok = B_TRUE;
|
||||||
|
|
1
vault.h
1
vault.h
|
@ -9,6 +9,7 @@ void dumpvault(char *name, int rotation);
|
||||||
vault_t *findvault(char *id);
|
vault_t *findvault(char *id);
|
||||||
vault_t *findvaultbyid(int id);
|
vault_t *findvaultbyid(int id);
|
||||||
vault_t *findvaultwithflag(enum FLAG fid);
|
vault_t *findvaultwithflag(enum FLAG fid);
|
||||||
|
vault_t *findvaultwithtag(char *tag);
|
||||||
void generatevaultflipsx(vault_t *v);
|
void generatevaultflipsx(vault_t *v);
|
||||||
void generatevaultflipsy(vault_t *v);
|
void generatevaultflipsy(vault_t *v);
|
||||||
void generatevaultrotations(vault_t *v);
|
void generatevaultrotations(vault_t *v);
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
! Boss room for goblin caves
|
||||||
|
@id:caveboss_1
|
||||||
|
|
||||||
|
@map
|
||||||
|
##################
|
||||||
|
#c......a.c.+AA###
|
||||||
|
#.w#.#.#.#..#AA+C#
|
||||||
|
+..........f####_#
|
||||||
|
#.w#.#.#.#..#WW+C#
|
||||||
|
#c......a.c.+WW###
|
||||||
|
##################
|
||||||
|
@end
|
||||||
|
|
||||||
|
@legend
|
||||||
|
#:cell:rock wall
|
||||||
|
f:ob:wooden footstool
|
||||||
|
f:mon:goblin king
|
||||||
|
a:mon:goblin archer
|
||||||
|
w:mon:goblin warrior
|
||||||
|
c:ob:lit candelabrum
|
||||||
|
+:ob:iron gate
|
||||||
|
+:exit
|
||||||
|
A:ob:good armour
|
||||||
|
W:ob:good weapon
|
||||||
|
_:ob:pentagram
|
||||||
|
_:ob:Godstone of Rage
|
||||||
|
C:ob:chest
|
||||||
|
@end
|
||||||
|
|
||||||
|
@flags
|
||||||
|
goesin:cave
|
||||||
|
norandom
|
||||||
|
atoneof(10,1)(10,3)(10,5) ob:portal to lv1
|
||||||
|
scatter(1,1,-2,-2) ob:wooden footstool:0-3
|
||||||
|
scatter(1,1,-2,-2) ob:random food:0-2
|
||||||
|
mayflipx
|
||||||
|
tag:caveboss
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue