- [+] glorana doesn't like you attacking during Glorana's Peace

- [+] make more shops let you donate
    - [+] bookstore
    - [+] jewellery store
- [+] rename blood hawk to hunting hawk
- [+] offering a bribe to creatures should make them move likely to
      helkp you, AND reset the "auto don't help' flag
- [+] change "get lost " message to "get lost, <racename>" if your race
      is different.
    - [+] sayphrase() needs a new arg:  lifeform_t *talkingto
- [+] colours for spell effect.
    - [+] eg. "the flame dart hits xxx" should use CC_BAD
- [+] muddy room - mud should be immutable.
- [+] maybe change rage - you lose control totally and just attack
      anything in sight?
    - [+] do it.
    - [+] don't train when enraged
    - [+] don't hear sounds when enraged
    - [+] RAGE effects: strength bonus, accuracy bonus, infinite
          stamina, never flee, 
- [+] fix bug in skill point calculation
- [+] CRASH - someone got their turn BEFORE the player!
- [+] new poisontype field - contracttext
- [+] hecta's pray effect not working.
- [+] adjust food poisioning check difficulty based on food age
    - [+] check OBHP percentage of max.
    - [+] >= 80% obhp means -30% difficulty check
- [+] ring of unholiness should confer dtvuln holy.
- [+] fix colour on spellclouds
- [+] fix bug with spellclouds not affecting centre cell.
- [+] if you are frozen, heat does extra damage and cold does none.
- [+] when frozen, lessen chance of melting.
- [+] reduce bite damage of snakes
- [+] balaclava should protect from gas
- [+] make some floor types (like carpet) be multicoloured
    - [+] celltype->altcolour
    - [+] if altcolour is not C_NONE then use it where (x + y) % 2 is
          true.
- [+] don't regain stamina while training
- [+] random text in shops - sayphrase needs to cope with lf == null
    - [+] done
- [+] fixed - hecta gifted me with a bamboo staff, but i'm inept with
      staves!
- [+] BUG: in vault.vlt.
    - [+] "30% chance of door" really means "otherwise empty cell"
    - [+] need to be able to say "else put a wall here"
    - [+] so change:
        - [+] c:type:what[:pct]
    - [+] to this:
        - [+] c:type:what[:pct][:alttype:altwhat]
    - [+] vlegend_t needs
        - [+] enum VAULTTHING tt2
        - [+] char *what2
        - [+] they default to VT_NONE, NULL
- [+] secret doors should take their fake wall type from the vault spec
    - [+] vaults need f_celltypeempty/solid flags
    - [+] add via:  solid:xxx in vault def
- [+]  recycler
    - [+] donate anything
This commit is contained in:
Rob Pearce 2012-07-15 05:01:58 +00:00
parent af3116f6d4
commit c421529221
25 changed files with 839 additions and 483 deletions

153
ai.c
View File

@ -18,6 +18,7 @@
extern lifeform_t *player; extern lifeform_t *player;
extern enum ERROR reason; extern enum ERROR reason;
extern int playerhasmoved;
int wantdb = B_TRUE; int wantdb = B_TRUE;
@ -113,9 +114,9 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
strcpy(text, "something"); strcpy(text, "something");
} }
if (cansee(player, victim)) { if (cansee(player, victim)) {
sayphrase(lf, SP_ALLY_ATTACK, SV_SHOUT, NA, text); sayphrase(lf, SP_ALLY_ATTACK, SV_SHOUT, NA, text, victim);
} else { } else {
sayphrase(lf, SP_ALLY_ATTACKUNSEEN, SV_SHOUT, NA, text); sayphrase(lf, SP_ALLY_ATTACKUNSEEN, SV_SHOUT, NA, text, victim);
} }
} else { } else {
makenoise(lf, N_GETANGRY); makenoise(lf, N_GETANGRY);
@ -804,7 +805,7 @@ int ai_attack_existing_target(lifeform_t *lf) {
if (areallies(lf, player) && cantalk(lf)) { if (areallies(lf, player) && cantalk(lf)) {
char text[BUFLEN]; char text[BUFLEN];
real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE); real_getlfname(target, text, NULL, B_NOSHOWALL, B_CURRACE);
sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text); sayphrase(lf, SP_ALLY_TARGETKILL, SV_SHOUT, NA, text, target);
} }
} else { } else {
// aquatic grabbers will try to drag their prey into the water // aquatic grabbers will try to drag their prey into the water
@ -832,7 +833,10 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
lifeform_t *newtarget = NULL; lifeform_t *newtarget = NULL;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0; int nretflags = 0;
flag_t *f; flag_t *f,*enraged;
enraged = lfhasflag(lf, F_RAGE);
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
// not attacking anyone in particular // not attacking anyone in particular
@ -914,7 +918,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
who->id, who->race->name); who->id, who->race->name);
hateposs[nhateposs++] = who; hateposs[nhateposs++] = who;
} }
} else if (lfhasflag(lf, F_HATESALL) || lfhasflag(lf, F_RAGE)) { } else if (lfhasflag(lf, F_HATESALL) || enraged) {
if (nhateposs < MAXCANDIDATES) { if (nhateposs < MAXCANDIDATES) {
if (db) dblog(".oO { hate everything - found lfid %d (%s) ! }",who->id, who->race->name); if (db) dblog(".oO { hate everything - found lfid %d (%s) ! }",who->id, who->race->name);
hateposs[nhateposs++] = who; hateposs[nhateposs++] = who;
@ -1004,50 +1008,52 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
/////////////////////////////////////////////// ///////////////////////////////////////////////
// need to train skills? // need to train skills?
if (readytotrain(lf)) { if (!enraged) {
if (safetorest(lf)) { if (readytotrain(lf) && safetorest(lf)) {
// special case - monsters don't need to actually rest to gain // special case - monsters don't need to actually rest to gain
// skills, although they DO still need to wait until the player // skills, although they DO still need to wait until the player
// is out of sight. // is out of sight.
enhanceskills(lf); enhanceskills(lf);
} }
}
// do we have armour which needs repairing? // do we have armour which needs repairing?
if (getskill(lf, SK_ARMOUR) >= PR_SKILLED) { if (getskill(lf, SK_ARMOUR) >= PR_SKILLED) {
if (db) dblog(".oO { do i have any armour to repair? }"); if (db) dblog(".oO { do i have any armour to repair? }");
// just try to use the ability - it'll fail if we have nothing // just try to use the ability - it'll fail if we have nothing
// which we can repair. // which we can repair.
if (!useability(lf, OT_A_REPAIR, NULL, NULL)) { if (!useability(lf, OT_A_REPAIR, NULL, NULL)) {
if (db) dblog(".oO { yes - done. }"); if (db) dblog(".oO { yes - done. }");
// success // success
return B_TRUE; return B_TRUE;
} else { } else {
if (db) dblog(".oO { no armour to repair. }"); if (db) dblog(".oO { no armour to repair. }");
}
} }
}
// pet movement - note that pets will only rest if their // pet movement - note that pets will only rest if their
// master is resting. the normal rest code underneath this section // master is resting. the normal rest code underneath this section
// will never be called. // will never be called.
if (master) { if (master) {
//lifeform_t *master; //lifeform_t *master;
//master = findlf(lf->cell->map, mf->val[0]); //master = findlf(lf->cell->map, mf->val[0]);
if (!aimovetolf(lf, master, B_FALSE)) { if (!aimovetolf(lf, master, B_FALSE)) {
// success // success
return B_TRUE; return B_TRUE;
} }
} }
}
/////////////////////////////////////////////// ///////////////////////////////////////////////
// resting / healing // resting / healing
/////////////////////////////////////////////// ///////////////////////////////////////////////
// need to heal? if (!enraged) {
if (needstorest(lf, NULL) && safetorest(lf) && !hasflag(lf->flags, F_RAGE)) { // need to heal?
if (db) dblog(".oO { resting to heal }"); if (needstorest(lf, NULL) && safetorest(lf) && !hasflag(lf->flags, F_RAGE)) {
rest(lf, B_TRUE); if (db) dblog(".oO { resting to heal }");
return B_TRUE; rest(lf, B_TRUE);
return B_TRUE;
}
} }
return B_FALSE; return B_FALSE;
@ -1141,6 +1147,7 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
int ai_healing(lifeform_t *lf) { int ai_healing(lifeform_t *lf) {
int db = B_FALSE; int db = B_FALSE;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
// special cases // special cases
if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) { if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) {
@ -1160,43 +1167,41 @@ int ai_healing(lifeform_t *lf) {
} }
} }
if (!lfhasflag(lf, F_RAGE)) { // feigning death with enemies in sight, and hurt?
// feigning death with enemies in sight, and hurt? if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) {
if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) { if (islowhp(lf)) {
if (islowhp(lf)) { if (db) dblog(".oO { i am feigning death and bleeding (hp=%d/%d), skipping turn. }",lf->hp,lf->maxhp);
if (db) dblog(".oO { i am feigning death and bleeding (hp=%d/%d), skipping turn. }",lf->hp,lf->maxhp); // just wait...
// just wait... rest(lf, B_TRUE);
rest(lf, B_TRUE); return B_TRUE;
}
}
// hurt gods planeshift away
if (lf->race->raceclass->id == RC_GOD) {
if (gethppct(lf) <= 10) {
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) {
return B_TRUE; return B_TRUE;
} }
} }
}
// hurt gods planeshift away // need to heal?
if (lf->race->raceclass->id == RC_GOD) { if (lf->hp < (lf->maxhp/2)) {
if (gethppct(lf) <= 10) { if (!useitemwithflag(lf, F_AIHEALITEM)) {
if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) { return B_TRUE;
return B_TRUE; } else if (cansleep(lf)) {
} // don't have or can't use our healing items
} // no enemies in sight?
} if (safetorest(lf)) {
// gods will only sleep/meditate if they are in the realm of gods
// need to heal? if (isgod(lf) && (lf->cell->habitat->id != H_HEAVEN)) {
if (lf->hp < (lf->maxhp/2)) { } else {
if (!useitemwithflag(lf, F_AIHEALITEM)) { // if it's "night time" for us, sleep forever.
return B_TRUE; // otehrwise just sleep until we're healed
} else if (cansleep(lf)) { if (!gotosleep(lf, issleepingtimefor(lf) ? B_TRUE : B_FALSE)) {
// don't have or can't use our healing items taketime(lf, getactspeed(lf)); // to make sure our turn ends
// no enemies in sight? return B_TRUE; // success
if (safetorest(lf)) {
// gods will only sleep/meditate if they are in the realm of gods
if (isgod(lf) && (lf->cell->habitat->id != H_HEAVEN)) {
} else {
// if it's "night time" for us, sleep forever.
// otehrwise just sleep until we're healed
if (!gotosleep(lf, issleepingtimefor(lf) ? B_TRUE : B_FALSE)) {
taketime(lf, getactspeed(lf)); // to make sure our turn ends
return B_TRUE; // success
}
} }
} }
} }
@ -1283,7 +1288,7 @@ int ai_housekeeping(lifeform_t *lf, lifeform_t *master) {
if (strlen(f->text)) { if (strlen(f->text)) {
say(lf, f->text, vol); say(lf, f->text, vol);
} else { } else {
sayphrase(lf, f->val[0], vol, NA, NULL); sayphrase(lf, f->val[0], vol, NA, NULL, NULL);
} }
} }
} }
@ -1473,6 +1478,7 @@ int ai_premovement(lifeform_t *lf) {
int db = B_FALSE; int db = B_FALSE;
int i; int i;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
// need light? // need light?
if (!haslos(lf, lf->cell)) { if (!haslos(lf, lf->cell)) {
@ -2085,6 +2091,13 @@ void aiturn(lifeform_t *lf) {
taketime(lf, SPEED_DEAD); taketime(lf, SPEED_DEAD);
return; return;
} }
// if game has just started and player hasn't had their turn yet,
// skip turn
if (!playerhasmoved) {
if (db) dblog(".oO { player hasn't had their initial turn yet, skipping turn. }");
taketime(lf, SPEED_DEAD);
return;
}
/////////////////////////////////////////// ///////////////////////////////////////////
// info gathering // info gathering

View File

@ -640,7 +640,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
killflagsofid(lf->flags, F_HIDING); killflagsofid(lf->flags, F_HIDING);
if (saysorry && attacktarget) { if (saysorry && attacktarget) {
sayphrase(lf, SP_SORRY, -1, NA, NULL); sayphrase(lf, SP_SORRY, -1, NA, NULL, attacktarget);
} }
if (hasbleedinginjury(lf, BP_HANDS)) { if (hasbleedinginjury(lf, BP_HANDS)) {

88
data.c
View File

@ -640,7 +640,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 exotic weapons, and gain special martial arts abilities at higher levels."); addjob(J_NINJA, "Ninja", "A dark warrior-assassin 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, 5, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 5, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 5, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 5, NA, NULL);
@ -655,7 +655,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "balaclava"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "balaclava");
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, "cloth trousers"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 shurikens"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 shurikens");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "manriki"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "manriki");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 smoke grenades"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 smoke grenades");
// shuriken // shuriken
@ -1024,16 +1024,16 @@ void initobjects(void) {
// init poison types // init poison types
addpoisontype(P_MIGRAINE, "a migraine", "Sick", "", OT_NONE, 0, 0, PS_DISEASE,20); addpoisontype(P_MIGRAINE, "a migraine", "Sick", "have developed", "", OT_NONE, 0, 0, PS_DISEASE,20);
addpoisontype(P_COLD, "hypothermia", "Sick", "^bYOU cough#S violently.", OT_NONE, 1, 25, PS_DISEASE, 30); addpoisontype(P_COLD, "hypothermia", "Sick", "are sick with", "^bYOU cough#S violently.", OT_NONE, 1, 25, PS_DISEASE, 30);
addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON,20); addpoisontype(P_FOOD, "gastroenteritis", "Poisoned", "have contracted", "^bYOU vomit#S violently.", OT_VOMITPOOL, 1, 25, PS_POISON,30);
addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30); addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "have contracted", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 40);
addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0); addpoisontype(P_GAS, "gas inhalation", "Poisoned", "are sick with", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0);
addpoisontype(P_LYCANTHROPY, "lycanthropy", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, -1); addpoisontype(P_LYCANTHROPY, "lycanthropy", "Cursed", "have been afflicted with", "", OT_NONE, 0, 0, PS_CURSE, -1);
addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0); addpoisontype(P_ROT, "the mummy's curse", "Cursed", "have been afflicated with", "", OT_NONE, 0, 0, PS_CURSE, 0);
addpoisontype(P_TETANUS, "tetanus", "Sick", "^bYOUR muscles spasm violently!", OT_NONE, 0, 3, PS_DISEASE, 15); addpoisontype(P_TETANUS, "tetanus", "Sick", "have contracted", "^bYOUR muscles spasm violently!", OT_NONE, 0, 3, PS_DISEASE, 15);
addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0); addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "have been infected with", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 5);
addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "cough", B_FALSE, 0, 0, PS_POISON, 0); addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "have been infected with", "cough", B_FALSE, 0, 0, PS_POISON, 0);
// generate hidden name text // generate hidden name text
for (n = 0; strlen(colour[n].name); n++) { for (n = 0; strlen(colour[n].name); n++) {
@ -1823,7 +1823,7 @@ void initobjects(void) {
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_SCROLL, NULL); addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_SCROLL, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_BOOK, NULL); addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_BOOK, NULL);
make_basic_shop(lastot->flags, B_ALLOWID); make_basic_shop(lastot->flags, B_ALLOWID, B_ALLOWDONATE);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_BOOK, RANDOM, NULL); f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_BOOK, RANDOM, NULL);
addcondition(f, FC_NOCONDITION, 33); addcondition(f, FC_NOCONDITION, 33);
@ -1833,7 +1833,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags, B_NOID); make_basic_shop(lastot->flags, B_NOID, B_NODONATE);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBCLASS, 100, OC_FOOD, RANDOM, NULL); addflag(lastot->flags, F_STARTOBCLASS, 100, OC_FOOD, RANDOM, NULL);
} }
@ -1841,15 +1841,17 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags, B_NOID); make_basic_shop(lastot->flags, B_NOID, B_NODONATE);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL);
} }
addot(OT_SHOPHARDWARE, "hardware store", "A small kiosk which sells tools and technology.", MT_METAL, 500, OC_BUILDING, SZ_LARGE); addot(OT_SHOPHARDWARE, "hardware store", "A small kiosk which sells tools and technology.", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_TOOLS, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_TECH, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags, B_NOID); make_basic_shop(lastot->flags, B_NOID, B_ALLOWDONATE);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_TOOLS, RANDOM, NULL); f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_TOOLS, RANDOM, NULL);
addcondition(f, FC_NOCONDITION, 50); addcondition(f, FC_NOCONDITION, 50);
@ -1860,10 +1862,19 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_DRINKABLE, NA, OC_POTION, NULL); addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_DRINKABLE, NA, OC_POTION, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags, B_ALLOWID); make_basic_shop(lastot->flags, B_ALLOWID, B_ALLOWDONATE);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBCLASS, 100, OC_POTION, RANDOM, NULL); addflag(lastot->flags, F_STARTOBCLASS, 100, OC_POTION, RANDOM, NULL);
} }
addot(OT_SHOPRECYCLE, "recycling bay", "A small kiosk which accepts used goods.", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_RARITY, NA, NA, NULL); // ie. basically anything
addflag(lastot->flags, F_SHOPMENU, 0, MA_GOTOMENU, SM_DONATE, "d:donate something");
addflag(lastot->flags, F_SHOPMENU, 1, MA_QUIT, NA, "q:leave");
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "the clanking of metal.");
addot(OT_SHOPRING, "jewellery store", "A small kiosk dealing in rings and amulets.", MT_METAL, 500, OC_BUILDING, SZ_LARGE); addot(OT_SHOPRING, "jewellery store", "A small kiosk dealing in rings and amulets.", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL);
@ -4804,7 +4815,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_REFLEXDODGE, "reflexive dodging", "Automatically use all remaining stamina to dodge fatal attacks.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_REFLEXDODGE, "reflexive dodging", "Automatically use all remaining stamina to dodge fatal attacks.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, losing conscious control but gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
addflag(lastot->flags, F_STAMCOST, 5, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 5, NA, NA, NULL);
@ -5448,7 +5459,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "cloud of smoke"); addflag(lastot->flags, F_DIECONVERT, 1, DT_COMPASS, NA, "cloud of smoke");
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "explodes"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "explodes");
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "explode"); addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "explode");
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
@ -5466,8 +5477,9 @@ void initobjects(void) {
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLCLOUDONDEATH, OT_S_SNAPFREEZE, 2, B_IFACTIVATED, "OB explodes in a cloud of freezing air!^Something explodes in a cloud of freezing air!^8"); addflag(lastot->flags, F_SPELLCLOUDONDEATH, OT_S_SNAPFREEZE, 1, B_IFACTIVATED, "OB explodes in a cloud of freezing air!^Something explodes in a cloud of freezing air!^8");
addflag(lastot->flags, F_SPELLCLOUDONDAM, OT_S_SNAPFREEZE, 2, B_IFACTIVATED, "8"); addflag(lastot->flags, F_SPELLCLOUDONDAM, OT_S_SNAPFREEZE, 1, B_IFACTIVATED, "8");
addflag(lastot->flags, F_SPELLCLOUDGLYPH, C_CYAN, UNI_SHADELIGHT, NA, NULL);
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
@ -6323,7 +6335,7 @@ void initobjects(void) {
addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN); addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL);
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of steam"); addflag(lastot->flags, F_DIECONVERT, 1, DT_ORTH, NA, "puff of steam");
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -6376,7 +6388,7 @@ void initobjects(void) {
addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, UNI_SHADEMED, NA, NULL);
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of smoke"); addflag(lastot->flags, F_DIECONVERT, 1, DT_COMPASS, NA, "puff of smoke");
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -6399,7 +6411,7 @@ void initobjects(void) {
addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, UNI_SHADEMED, NA, NULL);
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "thins out a little"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "thins out a little");
addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of gas"); addflag(lastot->flags, F_DIECONVERT, 1, DT_COMPASS, NA, "puff of gas");
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -6874,7 +6886,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addot(OT_BALACLAVA, "balaclava", "A form of cloth headgear that covers the whole head, exposing only the eyes.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addot(OT_BALACLAVA, "balaclava", "A form of cloth headgear that covers the whole head, exposing only the eyes. While it does not give much protection, its cloth will filter out poisonous particles.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
@ -6882,6 +6894,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_ANONYMOUS, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ANONYMOUS, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL);
addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL);
addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
@ -6900,10 +6913,10 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL);
addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_RUBBER, 3.5, OC_ARMOUR, SZ_SMALL); addot(OT_GASMASK, "gas mask", "A full face and neck mask which protects the wearer from both head damage and toxic gasses.", MT_RUBBER, 3.5, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL);
@ -7277,6 +7290,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_DECAY, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_DECAY, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_NECROTIC, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_NECROTIC, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTVULN, DT_HOLY, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_BREATHWATER, B_TRUE, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_BREATHWATER, B_TRUE, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_NIGHTBOOST, 15, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_NIGHTBOOST, 15, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DAYBOOST, -15, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DAYBOOST, -15, NA, NULL);
@ -12039,7 +12053,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTJOB, 20, J_DEMONOLOGIST, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_DEMONOLOGIST, NA, NULL);
addflag(lastrace->flags, F_STARTJOB, 20, J_SHAMAN, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 20, J_SHAMAN, NA, NULL);
addrace(R_ORCN, "norc", 90, 'o', C_BLUE, MT_FLESH, RC_HUMANOID, "While all orcs prefer the darkness, night orcs (or 'norcs') can actually _create_ it, spewing darkness from their bodies and blotting out all that is good and holy."); addrace(R_ORCN, "night orc", 90, 'o', C_BLUE, MT_FLESH, RC_HUMANOID, "While all orcs prefer the darkness, night orcs (or 'norcs') can actually _create_ it, spewing darkness from their bodies and blotting out all that is good and holy.");
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);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -12107,7 +12121,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addrace(R_ORCB, "borc", 90, 'o', C_RED, MT_FLESH, RC_HUMANOID, "Blood orcs (or 'borcs') are larger and more muscled than standard orcs. When they enter a state of blood rage, they are feared even by their own kind."); addrace(R_ORCB, "blood orc", 90, 'o', C_RED, MT_FLESH, RC_HUMANOID, "Blood orcs (or 'borcs') are larger and more muscled than standard orcs. When they enter a state of blood rage, they are feared even by their own kind.");
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);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -12136,7 +12150,7 @@ 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, 9, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 9, NA, NA, NULL);
addrace(R_ORCGRAND, "grorc", 120, 'o', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Even more powerful than blood orcs, grand orcs (or 'grorcs') are both extremely rare and extremely powerful."); addrace(R_ORCGRAND, "grand orc", 120, 'o', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Even more powerful than blood orcs, grand orcs (or 'grorcs') are both extremely rare and extremely powerful.");
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);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -14453,7 +14467,7 @@ void initrace(void) {
addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_HAWKBLOOD, "blood hawk", 1, 'A', C_RED, MT_FLESH, RC_ANIMAL, "A stronger version of a hawk."); // 'A' for Avian addrace(R_HAWKBLOOD, "trained hawk", 1, 'A', C_RED, MT_FLESH, RC_ANIMAL, "Once ordinary hawk, these creatures have been battle-hardened through regular combat."); // 'A' for Avian
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
lastrace->baseid = R_HAWK; lastrace->baseid = R_HAWK;
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
@ -14960,7 +14974,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 20, "5-10"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 20, "5-10");
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
@ -14992,7 +15006,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
@ -15020,7 +15034,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 5, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
@ -16252,6 +16266,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_LOTSOFLEGS, B_TRUE, 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_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -18061,9 +18076,12 @@ void killcommand(command_t *cmd) {
} }
} }
void make_basic_shop(flagpile_t *fp, int includeid) { void make_basic_shop(flagpile_t *fp, int includeid, int includedonate) {
int idx = 0; int idx = 0;
addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something"); addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something");
if (includedonate) {
addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_DONATE, "d:donate equipment");
}
if (includeid) { if (includeid) {
addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_ID, "i:inspect items"); addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_ID, "i:inspect items");
} }

2
data.h
View File

@ -14,5 +14,5 @@ void initskills(void);
void killbehaviour(behaviour_t *b); void killbehaviour(behaviour_t *b);
void killcommand(command_t *cmd); void killcommand(command_t *cmd);
void killoption(option_t *o); void killoption(option_t *o);
void make_basic_shop(flagpile_t *fp, int includeid); void make_basic_shop(flagpile_t *fp, int includeid, int includedonate);
void sortcommands(void); void sortcommands(void);

Binary file not shown.

View File

@ -13,7 +13,7 @@ autopop
entertext:It seems very muddy here! entertext:It seems very muddy here!
goesin:dungeon goesin:dungeon
! add mud to 50% of room cells ! add mud to 50% of room cells
scatter(1,1,-2,-2) ob:pool of mud:50% scatter(1,1,-2,-2) ob:immutable pool of mud:50%
rarity:uncommon rarity:uncommon
@end @end

View File

@ -11,15 +11,16 @@
#:cell:duranite wall #:cell:duranite wall
$:ob:25-200 gold $:ob:25-200 gold
! 30% chance of a door on each side ! 30% chance of a door on each side
+:ob:secret locked iron door:30 +:ob:secret locked iron door:30:cell:duranite wall
@end @end
@flags @flags
cellsolid:duranite wall
goesin:dungeon goesin:dungeon
mayrotate mayrotate
rarity:vrare rarity:vrare
! don't link to rest of map. ie this can be in the middle of nowhere. ! don't link to rest of map. ie this can be in the middle of nowhere.
nolink ! nolink
maintainedge maintainedge
@end @end

22
defs.h
View File

@ -84,10 +84,16 @@
#define B_ALLOWID (-1) #define B_ALLOWID (-1)
#define B_NOID (0) #define B_NOID (0)
#define B_ALLOWDONATE (-1)
#define B_NODONATE (0)
#define B_ONLYIFARMED (-1) #define B_ONLYIFARMED (-1)
#define B_INCLUDEDISTANT (-1) #define B_INCLUDEDISTANT (-1)
#define B_NODISTANT (0) #define B_NODISTANT (0)
#define B_INCLUDECENTRE (-1)
#define B_NOCENTRE (0)
#define B_MAYCHASE (-1) #define B_MAYCHASE (-1)
#define B_NOCHASE (0) #define B_NOCHASE (0)
#define B_ONLYEXTERNAL (-1) #define B_ONLYEXTERNAL (-1)
@ -1413,6 +1419,7 @@ enum OBTYPE {
OT_SHOPGENERAL, OT_SHOPGENERAL,
OT_SHOPHARDWARE, OT_SHOPHARDWARE,
OT_SHOPPOTION, OT_SHOPPOTION,
OT_SHOPRECYCLE,
OT_SHOPRING, OT_SHOPRING,
OT_SHOPWEAPON, OT_SHOPWEAPON,
OT_TEMPLE, OT_TEMPLE,
@ -2464,6 +2471,7 @@ enum FLAG {
F_NEWWATERDEPTH, // temp flag for the spread of f_deepwater obs. F_NEWWATERDEPTH, // temp flag for the spread of f_deepwater obs.
// v0+1 are x/y, v2 is new depth. // v0+1 are x/y, v2 is new depth.
F_STOMACHOF, // this map is the stomach of lf id V0, name = f->text F_STOMACHOF, // this map is the stomach of lf id V0, name = f->text
// map or vault flags
F_CELLTYPESOLID, // use celltype v0 for solid cells (walls) F_CELLTYPESOLID, // use celltype v0 for solid cells (walls)
F_CELLTYPEEMPTY, // use celltype v0 for empty cells (corridors/rooms) F_CELLTYPEEMPTY, // use celltype v0 for empty cells (corridors/rooms)
// object flags // object flags
@ -2590,8 +2598,9 @@ enum FLAG {
F_DIECONVERTTEXT, // text when the object converts. eg. "melts" F_DIECONVERTTEXT, // text when the object converts. eg. "melts"
F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt" F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt"
F_DIECONVERT, // text = what this turns into when dying F_DIECONVERT, // text = what this turns into when dying
// v0 = radius to scatter new object in (0 or NA means // v0 = radius to scatter new object in
// just convert the object) // (0 or NA means just convert the object)
// v1 = dirtype for radius
F_NOBLESS, // can't be blessed or cursed F_NOBLESS, // can't be blessed or cursed
F_NOQUALITY, // can't be masterwork / shoddy F_NOQUALITY, // can't be masterwork / shoddy
F_NOSTEAL, // this object can't be stolen, blown away, etc. F_NOSTEAL, // this object can't be stolen, blown away, etc.
@ -2661,6 +2670,8 @@ enum FLAG {
F_SPELLCLOUDONDAM, // cast spell v0 in radius v1 upon damage. F_SPELLCLOUDONDAM, // cast spell v0 in radius v1 upon damage.
// v2 = ifactivated // v2 = ifactivated
// text = "seebuf^noseebuf^spell_power" // text = "seebuf^noseebuf^spell_power"
F_SPELLCLOUDGLYPH, // v0 = enum COLOUR of the cloud
// v1 = glyph char
F_LASTDAMTYPE, // object equivilant of lf->lastdamtype F_LASTDAMTYPE, // object equivilant of lf->lastdamtype
F_SCROLLNEEDSOB, // this scroll targets an object F_SCROLLNEEDSOB, // this scroll targets an object
// v0 = B_ALWAYS (always targets an ob) // v0 = B_ALWAYS (always targets an ob)
@ -3473,6 +3484,7 @@ enum FLAG {
// -1 means always change on full moon. // -1 means always change on full moon.
F_UNDEAD, // this race is classed as undead F_UNDEAD, // this race is classed as undead
F_COLDBLOOD, // this race is coldblooded F_COLDBLOOD, // this race is coldblooded
F_LOTSOFLEGS, // this race is centipede-like - heaps of legs
F_NOBODYPART, // this race doesn't have bodypart val0 F_NOBODYPART, // this race doesn't have bodypart val0
// if v0 is true or b_frominjury, you can regrow it // if v0 is true or b_frominjury, you can regrow it
// via a healing potion. // via a healing potion.
@ -4235,6 +4247,7 @@ typedef struct poisontype_s {
enum POISONTYPE id; enum POISONTYPE id;
char *name; char *name;
char *desc; char *desc;
char *contracttext;
char *damverb; // can use macros: YOU YOUR and #S char *damverb; // can use macros: YOU YOUR and #S
enum OBTYPE vomitob; enum OBTYPE vomitob;
int dam; int dam;
@ -4320,7 +4333,9 @@ enum VAULTTHING {
typedef struct vlegend_s { typedef struct vlegend_s {
char ch; char ch;
enum VAULTTHING tt; enum VAULTTHING tt;
enum VAULTTHING tt2;
char *what; char *what;
char *what2;
int pct; int pct;
struct vault_s *vault; struct vault_s *vault;
struct vlegend_s *next, *prev; struct vlegend_s *next, *prev;
@ -4389,6 +4404,8 @@ typedef struct cell_s {
int littimer; int littimer;
int hp; int hp;
char *reason;
char *writing; char *writing;
int writinglifetime; int writinglifetime;
@ -4414,6 +4431,7 @@ typedef struct celltype_s {
char glyph; // how to display it char glyph; // how to display it
int colour; // which colour? int colour; // which colour?
*/ */
int altcol;
char *name; // name of cell type char *name; // name of cell type
int solid; // can you walk through it? int solid; // can you walk through it?
int transparent; // can you see through it? int transparent; // can you see through it?

View File

@ -18,15 +18,19 @@ General format:
@end @end
Legend is: Legend is:
c:type:what[:pct] c:type:what[:pct][:alttype:altwhat]
OR OR
c:exit (denotes an exit, for use by linkexits) c:exit (denotes an exit, for use by linkexits)
if pct chance fails, use alttype & altwhat to determine
what to place.
c = any letter c = any letter
type = ob, mon or cell type = ob, mon or cell
pct = optional pct chance of appearing pct = optional pct chance of appearing
what = text of what this letter represents what = text of what this letter represents
alttype = optional ob/mon/cell if pct chance fails
altwhat = optional text of what it represents if pct chance fails
Flags can be: Flags can be:
at(x,y) type:what[:pct] // put what at position x,y at(x,y) type:what[:pct] // put what at position x,y
@ -42,6 +46,9 @@ Flags can be:
fill(x,y,x2,y2) type:what[:pct] // filled box with what fill(x,y,x2,y2) type:what[:pct] // filled box with what
coords can be negative ("count back from right/bottom") coords can be negative ("count back from right/bottom")
cellempty:xxx // set empty cell type. eg. "dirt"
cellsolid:xxx // set solid cell type. eg. "brick wall"
scatter(x,y,x2,y2) type:what:howmany[:pct] // scatter what within region scatter(x,y,x2,y2) type:what:howmany[:pct] // scatter what within region
howmany can be: howmany can be:
- a number (x) - a number (x)

49
god.c
View File

@ -953,7 +953,7 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
break; break;
*/ */
case 2: case 2:
snprintf(obtogive, BUFLEN, "cursed branded weapon"); snprintf(obtogive, BUFLEN, "cursed appropriate branded weapon");
break; break;
case 3: // poison your weapon case 3: // poison your weapon
wep = getweapon(player); wep = getweapon(player);
@ -1991,41 +1991,34 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
break; break;
case R_GODDEATH: case R_GODDEATH:
msg("\"Behold, the power of death!\""); msg("\"Behold, the power of death!\"");
c = NULL;
n = OT_NONE; n = OT_NONE;
switch (rnd(0,1)) { switch (rnd(0,1)) {
case 0: n = OT_S_FLAYFLESH; break; case 0: n = OT_S_FLAYFLESH; break;
case 1: n = OT_S_HECTASSERVANT; case 1: n = OT_S_HECTASSERVANT; break;
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
break;
} }
if (n == OT_S_HECTASSERVANT) {
if (c) {
castspell(god, n, player, NULL, c, NULL, NULL);
n = OT_NONE;
} else {
n = OT_S_DRAINLIFE;
}
}
if (n != OT_NONE) { for (i = 1; i < lf->nlos; i++) {
// kill first lifeform in sight. lifeform_t *who;
for (i = 1; i < lf->nlos; i++) { who = lf->los[i]->lf;
lifeform_t *who; if (who && !areallies(lf, who)) {
who = lf->los[i]->lf; if (isundead(who)) {
if (who && !areallies(lf, who)) { makepeaceful(who, god);
if (isundead(who)) { } else if (gettr(who) <= 5) {
makepeaceful(who, god); // instakill
} else if (gettr(who) <= 5) { who->lastdamtype = DT_NECROTIC;
// instakill setlastdam(who, "Hecta's finger of death.");
who->lastdamtype = DT_NECROTIC; who->hp = 0;
setlastdam(who, "Hecta's finger of death."); } else if (n != OT_NONE) {
who->hp = 0; if (n == OT_S_HECTASSERVANT) {
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
if (c) {
castspell(god, n, player, NULL, c, NULL, NULL);
}
n = OT_S_DRAINLIFE;
} else { } else {
//castspell(god, n, who, NULL, who->cell, NULL, NULL);
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL); dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE, NULL);
break;
} }
break;
} }
} }
} }

84
io.c
View File

@ -1318,7 +1318,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
switch (f->id) { switch (f->id) {
case F_AICONTROLLED: case F_AICONTROLLED:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^%cYou lose control of your body!", getlfcol(lf, CC_VBAD)); msg("^%cYou lose control of your body!", getlfcol(lf, CC_VBAD)); more();
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
@ -1698,11 +1698,14 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
case F_POISONED: case F_POISONED:
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
if (isplayer(lf)) { if (isplayer(lf)) {
if (streq(pt->desc, "Sick") || (pt->id == P_FOOD) || (pt->id == P_FOODBAD)) { /*
if ((pt->id == P_FOOD) || (pt->id == P_FOODBAD)) {
msg("^%cYou are sick with %s.", getlfcol(lf, CC_VBAD), pt->name); msg("^%cYou are sick with %s.", getlfcol(lf, CC_VBAD), pt->name);
} else { } else {
msg("^%cYou have contracted %s.", getlfcol(lf, CC_VBAD), pt->name); msg("^%cYou %s %s.", getlfcol(lf, CC_VBAD), pt->contracttext, pt->name);
} }
*/
msg("^%cYou %s %s.", getlfcol(lf, CC_VBAD), pt->contracttext, pt->name);
more(); more();
} else { } else {
msg("^%c%s looks very sick.", getlfcol(lf, CC_VBAD), lfname); msg("^%c%s looks very sick.", getlfcol(lf, CC_VBAD), lfname);
@ -4451,7 +4454,7 @@ void docomms(lifeform_t *lf) {
if (!countmoney(lf->pack)) { if (!countmoney(lf->pack)) {
i = rnd(1,100); i = rnd(1,100);
if (i <= 5) { // attack you if (i <= 5) { // attack you
sayphrase(lf, SP_BEGATTACK, SV_SHOUT, NA, NULL); sayphrase(lf, SP_BEGATTACK, SV_SHOUT, NA, NULL, player);
fightback(lf, player); fightback(lf, player);
} else if (i <= 10) { // limited wish } else if (i <= 10) { // limited wish
// change to a god. // change to a god.
@ -4466,7 +4469,7 @@ void docomms(lifeform_t *lf) {
} else if (i <= 20) { // identify } else if (i <= 20) { // identify
object_t *poss[MAXPILEOBS],*o; object_t *poss[MAXPILEOBS],*o;
int nposs = 0; int nposs = 0;
sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL); sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL, player);
// get random unknown item from player's pack // get random unknown item from player's pack
for (o = player->pack->first ; o ; o = o->next){ for (o = player->pack->first ; o ; o = o->next){
if (!isknown(o)) { if (!isknown(o)) {
@ -4486,11 +4489,11 @@ void docomms(lifeform_t *lf) {
msg("%s %s.", OB1(o, "It's", "They're"), newobname); msg("%s %s.", OB1(o, "It's", "They're"), newobname);
} }
} else { // nothing } else { // nothing
sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL); sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL, player);
} }
} else { } else {
// they already had some money // they already had some money
sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL); sayphrase(lf, SP_BEGTHANKS, SV_TALK, NA, NULL, player);
} }
pleasegodmaybe(R_GODPURITY, 10); pleasegodmaybe(R_GODPURITY, 10);
pleasegodmaybe(R_GODMERCY, 20); pleasegodmaybe(R_GODMERCY, 20);
@ -4508,21 +4511,22 @@ void docomms(lifeform_t *lf) {
} else { } else {
// not giving money to a begger // not giving money to a begger
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
int mod = 0;
int wanted = B_FALSE, covetted = B_FALSE;
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
// chance of calming hostile intelligen, monsters mod = getoboffermod(givenob,lf, NULL);
wanted = aiwants(lf, givenob, &covetted);
// only get speech bonus if humanoid (ie they can understand you)
if (!cantalk(lf)) {
// this will counteract the bonus given in skillcheck()
mod -= (getskill(player, SK_SPEECH)*2);
}
// chance of calming hostile intelligent, monsters
if ((getallegiance(lf) == AL_HOSTILE) && (iqb >= IQ_ANIMAL) && cansee(lf, player)) { if ((getallegiance(lf) == AL_HOSTILE) && (iqb >= IQ_ANIMAL) && cansee(lf, player)) {
int mod = 0;
mod = getoboffermod(givenob,lf, NULL);
// only get speech bonus if humanoid (ie they can understand you)
if (!cantalk(lf)) {
// this will counteract the bonus given in skillcheck()
mod -= (getskill(player, SK_SPEECH)*2);
}
if (skillcheckvs(player, SC_SPEECH, mod, lf, SC_SPEECH, 0)) { if (skillcheckvs(player, SC_SPEECH, mod, lf, SC_SPEECH, 0)) {
// if humanoid+intelligent, say thanks. // if humanoid+intelligent, say thanks.
if (cantalk(lf)) sayphrase(lf, SP_THANKS, SV_TALK, NA, NULL); if (cantalk(lf)) sayphrase(lf, SP_THANKS, SV_TALK, NA, NULL, player);
// calm down // calm down
makepeaceful(lf, player); makepeaceful(lf, player);
// chance of becoming a pet if you gave something other than // chance of becoming a pet if you gave something other than
@ -4536,20 +4540,48 @@ void docomms(lifeform_t *lf) {
if (lf->race->raceclass->id == RC_HUMANOID) { if (lf->race->raceclass->id == RC_HUMANOID) {
p = assignnpcname(lf->flags); p = assignnpcname(lf->flags);
} }
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p, player);
} }
} }
pleasegodmaybe(R_GODTHIEVES, 10); pleasegodmaybe(R_GODTHIEVES, 10);
} }
} else { }
// yumi always likes giving things away, as long as } else if (wanted) { // if they WEREN'T hostile and liked the offer
// don't keep any for yourself. int min = 70,max = 90;
if (count == givenob->amt) { if (covetted) {
pleasegodmaybe(R_GODMERCY, 2); min = 50;
} max = 70;
} }
// reset rejected information offers
killflagsofid(lf->flags, F_NOINFO);
killflagsofid(lf->flags, F_NOHIRE);
f = lfhasflag(lf, F_INFOPRICE);
if (f) {
int newval;
// reduce asking price
newval = pctof(rnd(min,max),f->val[0]);
limit(&newval, 1, NA);
f->val[0] = newval;
}
f = lfhasflag(lf, F_HIREPRICE);
if (f) {
int newval;
// reduce asking price
newval = pctof(rnd(min,max),f->val[0]);
limit(&newval, 1, NA);
f->val[0] = newval;
}
// if humanoid+intelligent, say thanks.
if (cantalk(lf)) sayphrase(lf, SP_THANKS, SV_TALK, NA, NULL, player);
} }
} }
// yumi always likes giving things away, as long as
// don't keep any for yourself.
if (count == givenob->amt) {
pleasegodmaybe(R_GODMERCY, 2);
}
} // end if givenob } // end if givenob
break; break;
@ -4620,7 +4652,7 @@ void docomms(lifeform_t *lf) {
!isundead(lf)) { !isundead(lf)) {
if (skillcheck(player, SC_SPEECH, 30, alignmod)) { if (skillcheck(player, SC_SPEECH, 30, alignmod)) {
// passed! // passed!
sayphrase(lf, SP_MERCYACCEPT, SV_TALK, NA, player->race->name); sayphrase(lf, SP_MERCYACCEPT, SV_TALK, NA, player->race->name, player);
// they knock you out // they knock you out
msg("^%d*WHACK*^n", C_YELLOW); msg("^%d*WHACK*^n", C_YELLOW);
fallasleep(player, ST_KO, rnd(50,100)); fallasleep(player, ST_KO, rnd(50,100));

185
lf.c
View File

@ -28,6 +28,7 @@ extern FILE *logfile;
extern int noredraw; extern int noredraw;
extern int enteringmap; extern int enteringmap;
extern int playerorigalignment;
extern map_t *firstmap; extern map_t *firstmap;
extern race_t *firstrace, *lastrace; extern race_t *firstrace, *lastrace;
@ -902,7 +903,8 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume, int *numwalls) {
if (!hasbp(lf, BP_EARS)) return B_FALSE; if (!hasbp(lf, BP_EARS)) return B_FALSE;
if (isdeaf(lf)) return B_FALSE; if (isdeaf(lf)) return B_FALSE;
// can't hear when training // can't hear when training or enraged
if (lfhasflag(lf, F_RAGE)) return B_FALSE;
if (lfhasflag(lf, F_TRAINING)) return B_FALSE; if (lfhasflag(lf, F_TRAINING)) return B_FALSE;
// can't hear noises from other maps // can't hear noises from other maps
@ -2718,6 +2720,7 @@ int countlegs(lifeform_t *lf) {
} }
} }
} }
if (lfhasflag(lf, F_LOTSOFLEGS)) legs += 20;
return legs; return legs;
} }
@ -3212,7 +3215,7 @@ void die(lifeform_t *lf) {
if (!hasflag(lf->flags, F_NODEATHSPEECH) && !lfhasflag(lf, F_SUMMONEDBY)) { if (!hasflag(lf->flags, F_NODEATHSPEECH) && !lfhasflag(lf, F_SUMMONEDBY)) {
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
if (cantalk(lf) && canhear(player, lf->cell, 4, NULL)) { if (cantalk(lf) && canhear(player, lf->cell, 4, NULL)) {
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL); sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL, player);
} else if (!cansee(player, lf)) { } else if (!cansee(player, lf)) {
warn("You feel a profound sense of loss."); warn("You feel a profound sense of loss.");
// redraw since you can "see" the pet even if it's out of sight // redraw since you can "see" the pet even if it's out of sight
@ -3223,7 +3226,7 @@ void die(lifeform_t *lf) {
} }
} else if (cantalk(lf)) { } else if (cantalk(lf)) {
if (pctchance(33)) { if (pctchance(33)) {
sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL); sayphrase(lf, SP_DIE, SV_SHOUT, NA, NULL, killer);
} }
} }
} }
@ -4610,6 +4613,11 @@ int eat(lifeform_t *lf, object_t *o) {
timemax = 40; timemax = 40;
} }
// fresh food makes the check easier
if (getobhppct(o) >= 80) {
checkdiff = pctof(70, checkdiff);
}
// cannibulism ? // cannibulism ?
if (corpserace->id == lf->race->baseid) { if (corpserace->id == lf->race->baseid) {
ppower = 3; ppower = 3;
@ -4909,7 +4917,7 @@ void endlfturn(lifeform_t *lf) {
real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE); real_getlfname(lf, realname, NULL, B_NOSHOWALL, B_REALRACE);
warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname)); warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname));
} else if (cantalk(lf)) { } else if (cantalk(lf)) {
sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL); sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL, player);
} else { } else {
makenoise(lf, N_LOWHP); makenoise(lf, N_LOWHP);
} }
@ -5477,6 +5485,20 @@ void enhanceskills(lifeform_t *lf) {
} // end if gainedxplev } // end if gainedxplev
} }
int enrage(lifeform_t *lf, int howlong) {
if (lfhasflag(lf, F_RAGE)) return B_TRUE;
addtempflag(lf->flags, F_RAGE, NA, NA, NA, NULL, howlong);
if (isplayer(lf)) {
addtempflag(lf->flags, F_AICONTROLLED, B_TRUE, NA, NA, NULL, howlong);
} else {
loseaitargets(lf);
}
return B_FALSE;
}
int exchangeweapon(lifeform_t *lf) { int exchangeweapon(lifeform_t *lf) {
object_t *wep,*sec = NULL,*newsec = NULL; object_t *wep,*sec = NULL,*newsec = NULL;
// get secondary (if available) // get secondary (if available)
@ -6400,11 +6422,16 @@ void gainxp(lifeform_t *lf, long amt) {
assert(lf->skillxp >= 0); assert(lf->skillxp >= 0);
while (lf->skillxp >= amtneeded) { while (lf->skillxp >= amtneeded) {
newskillpoints++; newskillpoints++;
lf->skillpoints++;
lf->totskillpoints++;
lf->skillxp -= amtneeded; lf->skillxp -= amtneeded;
// recalculate
amtneeded = getspforpoint(lf);
if (isplayer(lf)) statdirty = B_TRUE; if (isplayer(lf)) statdirty = B_TRUE;
} }
// debug! // debug!
if (newskillpoints >= 3) { if (newskillpoints >= 5) {
raise(SIGINT); raise(SIGINT);
} }
} }
@ -6414,9 +6441,7 @@ void gainxp(lifeform_t *lf, long amt) {
gainlevel(lf, B_FALSE); // this will increment 'newlevel' gainlevel(lf, B_FALSE); // this will increment 'newlevel'
} }
if (newskillpoints) { if (newskillpoints) {
lf->skillpoints += newskillpoints;
msg("^GYou feel ready to learn a new skill!"); msg("^GYou feel ready to learn a new skill!");
lf->totskillpoints += newskillpoints;
} }
} }
} }
@ -7046,7 +7071,7 @@ int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset) {
} }
} }
if ((f->id == F_RAGE) && (attr == A_STR)) { if ((f->id == F_RAGE) && (attr == A_STR)) {
val += 25; val += 50;
} }
} }
@ -13743,7 +13768,7 @@ object_t *isstuck(lifeform_t *lf) {
} }
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime) { poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *contracttext, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime) {
poisontype_t *a; poisontype_t *a;
// add to the end of the list // add to the end of the list
@ -13765,6 +13790,7 @@ poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *da
a->id = id; a->id = id;
a->name = strdup(name); a->name = strdup(name);
a->desc = strdup(desc); a->desc = strdup(desc);
a->contracttext = strdup(contracttext);
a->damverb = strdup(damverb); a->damverb = strdup(damverb);
a->vomitob = vomitob; a->vomitob = vomitob;
a->dam = dam; a->dam = dam;
@ -14261,6 +14287,16 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
*amt = 0; *amt = 0;
} }
if (lfhasflag(lf, F_FROZEN)) {
if (basedamagetype(damtype) == DT_FIRE) {
// extra damage
(*amt) = pctof(150,*amt);
} else if (basedamagetype(damtype) == DT_COLD) {
*amt = 0;
}
}
if (isresistantto(lf->flags, damtype, B_FALSE)) { if (isresistantto(lf->flags, damtype, B_FALSE)) {
(*amt) /= 2; (*amt) /= 2;
} }
@ -14275,7 +14311,6 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
} }
} }
// don't adjust for lifeform material - we inherit all the material's flags. // don't adjust for lifeform material - we inherit all the material's flags.
//adjustdammaterial((unsigned int *)amt, damtype, getlfmaterial(lf)); //adjustdammaterial((unsigned int *)amt, damtype, getlfmaterial(lf));
adjustdamhardness(amt, damtype, getlfmaterial(lf)); adjustdamhardness(amt, damtype, getlfmaterial(lf));
@ -14610,7 +14645,7 @@ int askforinfo(lifeform_t *lf, int diffmod) {
if (lfhasflag(lf, F_NOINFO)) { if (lfhasflag(lf, F_NOINFO)) {
// refusing to give info // refusing to give info
sayphrase(lf, SP_INFO_REFUSE_AGAIN, SV_TALK, NA, NULL); sayphrase(lf, SP_INFO_REFUSE_AGAIN, SV_TALK, NA, NULL, player);
return B_FALSE; return B_FALSE;
} else { } else {
int doinfo = B_FALSE; int doinfo = B_FALSE;
@ -14657,7 +14692,7 @@ int askforinfo(lifeform_t *lf, int diffmod) {
if (askingprice == -1) { if (askingprice == -1) {
addflag(lf->flags, F_NOINFO, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_NOINFO, B_TRUE, NA, NA, NULL);
sayphrase(lf, SP_INFO_REFUSE, SV_TALK, NA, NULL); sayphrase(lf, SP_INFO_REFUSE, SV_TALK, NA, NULL, player);
return B_FALSE; return B_FALSE;
} else { } else {
addflag(lf->flags, F_INFOPRICE, askingprice, NA, NA, NULL); addflag(lf->flags, F_INFOPRICE, askingprice, NA, NA, NULL);
@ -14679,7 +14714,7 @@ int askforinfo(lifeform_t *lf, int diffmod) {
if (askingprice > 0) { if (askingprice > 0) {
char ch; char ch;
sayphrase(lf, SP_INFO_ASKPRICE, SV_TALK, askingprice, NULL); sayphrase(lf, SP_INFO_ASKPRICE, SV_TALK, askingprice, NULL, player);
more(); more();
if (askingprice > countmoney(player->pack)) { if (askingprice > countmoney(player->pack)) {
@ -14697,10 +14732,10 @@ int askforinfo(lifeform_t *lf, int diffmod) {
} }
if (doinfo) { if (doinfo) {
sayphrase(lf, SP_INFO_ACCEPT, SV_TALK, NA, NULL); sayphrase(lf, SP_INFO_ACCEPT, SV_TALK, NA, NULL, player);
return B_TRUE; return B_TRUE;
} else { } else {
sayphrase(lf, SP_INFO_DECLINE_WONTPAY, SV_TALK, askingprice, NULL); sayphrase(lf, SP_INFO_DECLINE_WONTPAY, SV_TALK, askingprice, NULL, player);
} }
} // end if !nohire } // end if !nohire
return B_FALSE; return B_FALSE;
@ -15150,6 +15185,7 @@ void killpoisontype(poisontype_t *pt) {
// free mem // free mem
free(pt->name); free(pt->name);
free(pt->desc); free(pt->desc);
free(pt->contracttext);
free(pt->damverb); free(pt->damverb);
// remove from list // remove from list
@ -15778,17 +15814,17 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
char buf2[BUFLEN]; char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of purple spores!", lfname); sprintf(buf, "^w%s releases a cloud of purple spores!", lfname);
sprintf(buf2, "^wSomething releases a cloud of purple spores!"); sprintf(buf2, "^wSomething releases a cloud of purple spores!");
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE, NULL); spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, 8, B_TRUE, buf, buf2, B_FALSE, NULL, B_NOCENTRE);
} else if (lf->race->id == R_FUNGUSRAGE) { } else if (lf->race->id == R_FUNGUSRAGE) {
char buf2[BUFLEN]; char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of red spores!", lfname); sprintf(buf, "^w%s releases a cloud of red spores!", lfname);
sprintf(buf2, "^wSomething releases a cloud of red spores!"); sprintf(buf2, "^wSomething releases a cloud of red spores!");
spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE, NULL); spellcloud(lf->cell, 3, UNI_SHADELIGHT, C_RED, OT_A_RAGE, 8, B_TRUE, buf, buf2, B_FALSE, NULL, B_NOCENTRE);
} else if ((lf->race->id == R_UNYON) && ((damtype == DT_SLASH) || (damtype == DT_PIERCE))) { } else if ((lf->race->id == R_UNYON) && ((damtype == DT_SLASH) || (damtype == DT_PIERCE))) {
char buf2[BUFLEN]; char buf2[BUFLEN];
sprintf(buf, "^w%s releases a cloud of fumes!", lfname); sprintf(buf, "^w%s releases a cloud of fumes!", lfname);
sprintf(buf2, "^wSomething releases a cloud of fumes!"); sprintf(buf2, "^wSomething releases a cloud of fumes!");
spellcloud(lf->cell, 1, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL); spellcloud(lf->cell, 1, UNI_SHADELIGHT, C_GREY, OT_S_BLINDNESS, 8, B_TRUE, buf, buf2, B_TRUE, NULL, B_NOCENTRE);
} }
@ -17630,11 +17666,11 @@ int recruit(lifeform_t *lf) {
if (lfhasflag(lf, F_NOHIRE)) { if (lfhasflag(lf, F_NOHIRE)) {
// refusing to join at all. // refusing to join at all.
sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL); sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL, player);
rv = B_TRUE; rv = B_TRUE;
} else if ( ((pa == AL_GOOD) && (lfa == AL_EVIL)) || } else if ( ((pa == AL_GOOD) && (lfa == AL_EVIL)) ||
((pa == AL_EVIL) && (lfa == AL_GOOD)) ) { ((pa == AL_EVIL) && (lfa == AL_GOOD)) ) {
sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL); sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL, player);
rv = B_TRUE; rv = B_TRUE;
} else { } else {
int dohire = B_FALSE; int dohire = B_FALSE;
@ -17688,7 +17724,7 @@ int recruit(lifeform_t *lf) {
} }
if (askingprice > 0) { if (askingprice > 0) {
sayphrase(lf, SP_RECRUIT_ASKPRICE, SV_TALK, askingprice, NULL); sayphrase(lf, SP_RECRUIT_ASKPRICE, SV_TALK, askingprice, NULL, player);
more(); more();
if (askingprice > countmoney(player->pack)) { if (askingprice > countmoney(player->pack)) {
@ -17713,12 +17749,12 @@ int recruit(lifeform_t *lf) {
if (lf->race->raceclass->id == RC_HUMANOID) { if (lf->race->raceclass->id == RC_HUMANOID) {
p = assignnpcname(lf->flags); p = assignnpcname(lf->flags);
} }
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p, player);
} else { } else {
if (askingprice > countmoney(player->pack)) { if (askingprice > countmoney(player->pack)) {
sayphrase(lf, SP_RECRUIT_DECLINE_CANTPAY, SV_TALK, askingprice, NULL); sayphrase(lf, SP_RECRUIT_DECLINE_CANTPAY, SV_TALK, askingprice, NULL, player);
} else { } else {
sayphrase(lf, SP_RECRUIT_DECLINE_WONTPAY, SV_TALK, askingprice, NULL); sayphrase(lf, SP_RECRUIT_DECLINE_WONTPAY, SV_TALK, askingprice, NULL, player);
} }
} }
} // end if !nohire } // end if !nohire
@ -18076,6 +18112,9 @@ int safetorest(lifeform_t *lf) {
return B_TRUE; return B_TRUE;
} }
// if lf is null, the player will just get a message \"blah blah blah\"
// this is used (for example) when shopkeepers are talking from the
// in-shop menu.
int say(lifeform_t *lf, char *text, int volume) { int say(lifeform_t *lf, char *text, int volume) {
char seebuf[BUFLEN]; char seebuf[BUFLEN];
char hearbuf[BUFLEN]; char hearbuf[BUFLEN];
@ -18139,13 +18178,17 @@ int say(lifeform_t *lf, char *text, int volume) {
snprintf(seebuf, BUFLEN, "%s \"%s\"", verb, localtext); snprintf(seebuf, BUFLEN, "%s \"%s\"", verb, localtext);
snprintf(hearbuf, BUFLEN, "%s \"%s\"", noun, localtext); snprintf(hearbuf, BUFLEN, "%s \"%s\"", noun, localtext);
rv = noise(lf->cell, lf, NC_SPEECH, volume, hearbuf, seebuf); if (lf) {
rv = noise(lf->cell, lf, NC_SPEECH, volume, hearbuf, seebuf);
} else {
msg("\"%s\"", localtext);
}
free(localtext); free(localtext);
return rv; return rv;
} }
// volume = -1 means "auto" // volume = -1 means "auto"
int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text) { int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text, lifeform_t *talkingto) {
int i,rv = B_FALSE; int i,rv = B_FALSE;
char buf[BUFLEN]; char buf[BUFLEN];
char buf2[BUFLEN]; char buf2[BUFLEN];
@ -18185,7 +18228,7 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
case SP_ALLY_TARGETKILL: case SP_ALLY_TARGETKILL:
switch (rnd(1,4)) { switch (rnd(1,4)) {
case 1: snprintf(buf, BUFLEN, "Got it!"); break; case 1: snprintf(buf, BUFLEN, "Got it!"); break;
case 2: snprintf(buf, BUFLEN, "%s one, %s zero!", lf->race->name, noprefix(text)); case 2: snprintf(buf, BUFLEN, "%s one, %s zero!", lf ? lf->race->name : "Me", noprefix(text));
buf[0] = toupper(buf[0]); buf[0] = toupper(buf[0]);
break; break;
case 3: snprintf(buf, BUFLEN, "Pow!"); break; case 3: snprintf(buf, BUFLEN, "Pow!"); break;
@ -18220,7 +18263,7 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
case SP_DIE: case SP_DIE:
switch (rnd(1,4)) { switch (rnd(1,4)) {
case 1: case 1:
if (ispetof(lf, player)) { if (lf && ispetof(lf, player)) {
getplayername(buf2); getplayername(buf2);
snprintf(buf, BUFLEN, "Avenge me, %s!", buf2); snprintf(buf, BUFLEN, "Avenge me, %s!", buf2);
} else { } else {
@ -18276,7 +18319,12 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
case SP_INFO_ACCEPT: case SP_INFO_ACCEPT:
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: snprintf(buf, BUFLEN, "Okay, here's what I know..."); break; case 1: snprintf(buf, BUFLEN, "Okay, here's what I know..."); break;
case 2: snprintf(buf, BUFLEN, "Listen carefully..."); break; case 2:
if (lf && talkingto && (talkingto->race->id != lf->race->id)) {
snprintf(buf, BUFLEN, "Listen carefully, %s...", talkingto->race->name); break;
} else {
snprintf(buf, BUFLEN, "Listen carefully..."); break;
}
} }
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
@ -18303,16 +18351,24 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
snprintf(buf, BUFLEN, "Can't help, sorry."); snprintf(buf, BUFLEN, "Can't help, sorry.");
break; break;
case 3: case 3:
snprintf(buf, BUFLEN, "Get lost!"); if (lf && talkingto && (talkingto->race->id != lf->race->id)) {
snprintf(buf, BUFLEN, "Get lost, %s!", talkingto->race->name);
} else {
snprintf(buf, BUFLEN, "Get lost!");
}
break; break;
case 4: case 4:
snprintf(buf, BUFLEN, "No time to talk!"); if (lf && talkingto && (talkingto->race->id != lf->race->id)) {
snprintf(buf, BUFLEN, "No time to talk, %s!", talkingto->race->name);
} else {
snprintf(buf, BUFLEN, "No time to talk!");
}
break; break;
} }
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
case SP_INFO_REFUSE_AGAIN: case SP_INFO_REFUSE_AGAIN:
switch (rnd(1,3)) { switch (rnd(1,4)) {
case 1: case 1:
snprintf(buf, BUFLEN, "Asking twice isn't going to change the answer!"); snprintf(buf, BUFLEN, "Asking twice isn't going to change the answer!");
break; break;
@ -18406,7 +18462,7 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
} }
break; break;
case SP_SORRY: case SP_SORRY:
if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= AT_HIGH) { if (lf && getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= AT_HIGH) {
switch (rnd(0,1)) { switch (rnd(0,1)) {
case 0: rv = say(lf, "My sincerest condolences!", volume); break; case 0: rv = say(lf, "My sincerest condolences!", volume); break;
case 1: rv = say(lf, "My mistake, I apologise.", volume); break; case 1: rv = say(lf, "My mistake, I apologise.", volume); break;
@ -18426,10 +18482,12 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
case SP_THANKS: case SP_THANKS:
switch (rnd(1,3)) { switch (rnd(1,5)) {
case 1: snprintf(buf, BUFLEN, "Why, thank you!"); break; case 1: snprintf(buf, BUFLEN, "Why, thank you!"); break;
case 2: snprintf(buf, BUFLEN, "You have my gratitude!"); break; case 2: snprintf(buf, BUFLEN, "You have my gratitude!"); break;
case 3: snprintf(buf, BUFLEN, "Thanks!"); break; case 3: snprintf(buf, BUFLEN, "Thanks!"); break;
case 4: snprintf(buf, BUFLEN, "Thank you, that is very generous of you!"); break;
case 5: snprintf(buf, BUFLEN, "How kind of you!"); break;
} }
rv = say(lf, buf, volume); rv = say(lf, buf, volume);
break; break;
@ -18585,6 +18643,11 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
void setalignment(lifeform_t *lf, enum ALIGNMENT al) { void setalignment(lifeform_t *lf, enum ALIGNMENT al) {
flag_t *f; flag_t *f;
if (isplayer(lf)) {
dblog("warning - changing player alignment");
msg("warning - changing player alignment");
more();
}
f = lfhasflag(lf, F_ALIGNMENT); f = lfhasflag(lf, F_ALIGNMENT);
if (f) { if (f) {
f->val[0] = al; f->val[0] = al;
@ -19821,9 +19884,19 @@ void startlfturn(lifeform_t *lf) {
if (db) dblog("startlfturn for lf id %d %s", lf->id, lf->race->name); if (db) dblog("startlfturn for lf id %d %s", lf->id, lf->race->name);
// debugging // debugging
lf->redraws = 0; lf->redraws = 0;
// more debug
if (isplayer(lf)) {
if ((gamemode == GM_GAMESTARTED) && (getalignment(lf) != playerorigalignment)) {
dblog("WARNING: player alignment has changed!!!");
msg("WARNING: player alignment has changed!!!");
more();
}
}
// MOVE OUT OF STOMACHS WHICH DONT EXIST ANYMORE // MOVE OUT OF STOMACHS WHICH DONT EXIST ANYMORE
sf = hasflag(map->flags, F_STOMACHOF); sf = hasflag(map->flags, F_STOMACHOF);
if (sf) { if (sf) {
@ -19876,7 +19949,7 @@ void startlfturn(lifeform_t *lf) {
msg("^wAll of your items are missing!^n"); more(); msg("^wAll of your items are missing!^n"); more();
} }
} else { } else {
sayphrase(lf, SP_ROBBED, SV_SHOUT, NA, NULL); sayphrase(lf, SP_ROBBED, SV_SHOUT, NA, NULL, NULL);
} }
killflagsofid(lf->flags, F_WASROBBED); killflagsofid(lf->flags, F_WASROBBED);
} }
@ -20077,7 +20150,7 @@ void startlfturn(lifeform_t *lf) {
if (lossamt) modstamina(lf, -lossamt); if (lossamt) modstamina(lf, -lossamt);
} else { } else {
// if we didn't take action last turn, regenerate stamina. // if we didn't take action last turn, regenerate stamina.
if (!killflagsofid(lf->flags, F_TOOKACTION)) { if (!killflagsofid(lf->flags, F_TOOKACTION) && !lfhasflag(lf, F_TRAINING)) {
if (getstamina(lf) < getmaxstamina(lf)) { if (getstamina(lf) < getmaxstamina(lf)) {
modstamina(lf, getstamregen(lf)); modstamina(lf, getstamregen(lf));
} }
@ -20313,7 +20386,7 @@ void startlfturn(lifeform_t *lf) {
getlfname(otherlf, lfname); getlfname(otherlf, lfname);
msg("The sight of %s makes your blood boil!", lfname); msg("The sight of %s makes your blood boil!", lfname);
} }
addtempflag(lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, DEF_RAGETIME/2); enrage(lf, DEF_RAGETIME/2);
if (getstamina(lf) < 1) setstamina(lf, 1); if (getstamina(lf) < 1) setstamina(lf, 1);
forceredraw(); forceredraw();
if (isplayer(lf)) more(); if (isplayer(lf)) more();
@ -20454,7 +20527,7 @@ void startlfturn(lifeform_t *lf) {
int bonus = 0; int bonus = 0;
int dist; int dist;
if (!lfhasflag(l, F_SILENTMOVE) && !isdeaf(lf)) { if (!lfhasflag(l, F_SILENTMOVE) && !isdeaf(lf)) {
bonus += getskill(lf, SK_LISTEN); bonus += (getskill(lf, SK_LISTEN)/2);
} }
dist = getcelldist(lf->cell, l->cell); dist = getcelldist(lf->cell, l->cell);
@ -20842,8 +20915,14 @@ void startlfturn(lifeform_t *lf) {
} }
if (lfhasflag(lf, F_FROZEN)) { if (lfhasflag(lf, F_FROZEN)) {
int willmelt = B_FALSE;
if (hasobofmaterial(lf->cell->obpile, MT_FIRE)) {
willmelt = B_TRUE;
} else if (onein(4) && !hasobofmaterial(lf->cell->obpile, MT_ICE)) {
willmelt = B_TRUE;
}
// melt... // melt...
if (rnd(1,2)) { if (willmelt) {
losehp(lf, 1, DT_MELT, NULL, "melting"); losehp(lf, 1, DT_MELT, NULL, "melting");
addob(lf->cell->obpile, "small puddle of water"); addob(lf->cell->obpile, "small puddle of water");
if (isplayer(lf)) { if (isplayer(lf)) {
@ -21828,7 +21907,7 @@ int tradeknowledge(lifeform_t *lf) {
// already traded? // already traded?
if (lfhasflag(lf, F_DONEKNOWLEDGETRADE)) { if (lfhasflag(lf, F_DONEKNOWLEDGETRADE)) {
sayphrase(lf, SP_TRADEINFO_DECLINE_ALREADYDONE, SV_TALK, NA, NULL); sayphrase(lf, SP_TRADEINFO_DECLINE_ALREADYDONE, SV_TALK, NA, NULL, player);
return B_TRUE; return B_TRUE;
} }
@ -21839,7 +21918,7 @@ int tradeknowledge(lifeform_t *lf) {
fromplayer = poss[sel]; fromplayer = poss[sel];
fromplayertype = tradetype[sel]; fromplayertype = tradetype[sel];
} else { } else {
sayphrase(lf, SP_TRADEINFO_DECLINE_PLAYERBAD, SV_TALK, NA, NULL); sayphrase(lf, SP_TRADEINFO_DECLINE_PLAYERBAD, SV_TALK, NA, NULL, player);
return B_TRUE; return B_TRUE;
} }
// does lf have a skill which the player needs? // does lf have a skill which the player needs?
@ -21858,7 +21937,7 @@ int tradeknowledge(lifeform_t *lf) {
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL); addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
ch = getchoice(&prompt); ch = getchoice(&prompt);
if (ch == '-') { if (ch == '-') {
sayphrase(lf, SP_TRADEINFO_CANCEL, SV_TALK, NA, NULL); sayphrase(lf, SP_TRADEINFO_CANCEL, SV_TALK, NA, NULL, player);
return B_TRUE; return B_TRUE;
} else { } else {
sel = ch - 'a'; sel = ch - 'a';
@ -21869,7 +21948,7 @@ int tradeknowledge(lifeform_t *lf) {
toplayer = poss[sel]; toplayer = poss[sel];
toplayertype = tradetype[sel]; toplayertype = tradetype[sel];
} else { } else {
sayphrase(lf, SP_TRADEINFO_DECLINE_OTHERBAD, SV_TALK, NA, NULL); sayphrase(lf, SP_TRADEINFO_DECLINE_OTHERBAD, SV_TALK, NA, NULL, player);
return B_TRUE; return B_TRUE;
} }
@ -21880,7 +21959,7 @@ int tradeknowledge(lifeform_t *lf) {
gettradeinfoname(toplayer, toplayertype, toplayertext); gettradeinfoname(toplayer, toplayertype, toplayertext);
sprintf(tradetext, "%s^%s",fromplayertext,toplayertext); sprintf(tradetext, "%s^%s",fromplayertext,toplayertext);
sayphrase(lf, SP_TRADEINFO_ACCEPT, SV_TALK, NA, tradetext); sayphrase(lf, SP_TRADEINFO_ACCEPT, SV_TALK, NA, tradetext, player);
more(); more();
// confirm. // confirm.
sprintf(buf, "Learn %s from %s", toplayertext, lfname); sprintf(buf, "Learn %s from %s", toplayertext, lfname);
@ -23828,12 +23907,18 @@ int wear(lifeform_t *lf, object_t *o) {
// special cases: // special cases:
if (isplayer(lf)) { if (isplayer(lf)) {
if (o->type->id == OT_RING_INVIS) { switch (o->type->id) {
// make ring of invis fully known - the HPDRAIN flag case OT_RING_INVIS:
// won't be announced, so since we don't know all the flags we would // make ring of invis fully known - the HPDRAIN flag
// otherwise get "you turn invisible!" but still have the ring known // won't be announced, so since we don't know all the flags we would
// as "a blue ring" (or whatever) // otherwise get "you turn invisible!" but still have the ring known
makeknown(o->type->id); // as "a blue ring" (or whatever)
case OT_RING_UNHOLINESS:
makeknown(o->type->id);
break;
default:
break;
} }
} }

5
lf.h
View File

@ -3,7 +3,7 @@
void addbodypart(race_t *r, enum BODYPART bp, char *name); void addbodypart(race_t *r, enum BODYPART bp, char *name);
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level); lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller); lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime); poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *contracttext, char *damverb, enum OBTYPE vomitob, int dam, int dampct, enum POISONSEVERITY severity, int incubationtime);
job_t *addjob(enum JOB id, char *name, char *desc); job_t *addjob(enum JOB id, char *name, char *desc);
race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc);
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
@ -100,6 +100,7 @@ int eat(lifeform_t *lf, object_t *o);
void endlfturn(lifeform_t *lf); void endlfturn(lifeform_t *lf);
void enhancerandomskill(lifeform_t *lf); void enhancerandomskill(lifeform_t *lf);
void enhanceskills(lifeform_t *lf); void enhanceskills(lifeform_t *lf);
int enrage(lifeform_t *lf, int howlong);
int exchangeweapon(lifeform_t *lf); int exchangeweapon(lifeform_t *lf);
void extinguishlf(lifeform_t *lf); void extinguishlf(lifeform_t *lf);
object_t *eyesshaded(lifeform_t *lf); object_t *eyesshaded(lifeform_t *lf);
@ -439,7 +440,7 @@ int rollattr(enum ATTRBRACKET bracket);
int rollstat(lifeform_t *lf, enum ATTRIB attr); int rollstat(lifeform_t *lf, enum ATTRIB attr);
int safetorest(lifeform_t *lf); int safetorest(lifeform_t *lf);
int say(lifeform_t *lf, char *text, int volume); int say(lifeform_t *lf, char *text, int volume);
int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text); 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); int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
//int setammo(lifeform_t *lf, object_t *o); //int setammo(lifeform_t *lf, object_t *o);
void setalignment(lifeform_t *lf, enum ALIGNMENT al); void setalignment(lifeform_t *lf, enum ALIGNMENT al);

235
map.c
View File

@ -88,6 +88,7 @@ cell_t *addcell(map_t *m, int x, int y) {
cell->visited = B_FALSE; cell->visited = B_FALSE;
cell->filled = B_FALSE; cell->filled = B_FALSE;
cell->isroomwall = D_NONE; cell->isroomwall = D_NONE;
cell->reason = NULL;
return cell; return cell;
} }
@ -947,20 +948,28 @@ branch_t *addbranch(enum BRANCH id, char *name, int pluralname, enum HABITAT def
return a; return a;
} }
void adjustcellglyphforlight(cell_t *c, glyph_t *g) { void adjustcellglyph(cell_t *c, glyph_t *g) {
if (g->ch == ' ') return; if (g->ch == ' ') return;
if (c->type->altcol != C_NONE) {
if ((c->x + c->y) % 2) g->colour = c->type->altcol;
}
switch (c->lit) { switch (c->lit) {
case L_PERMDARK: case L_PERMDARK:
case L_NOTLIT: case L_NOTLIT:
g->colour = C_BLUE; g->colour = C_BLUE;
break; break;
/*
case L_TEMP: // lit by a light source case L_TEMP: // lit by a light source
if (g->colour < 8) { if (g->colour < 8) {
g->colour = g->colour + 8; // ie. make bold g->colour = g->colour + 8; // ie. make bold
if (g->colour >= C_GREY) g->colour = C_WHITE; if (g->colour >= C_GREY) g->colour = C_WHITE;
} }
break; break;
*/
case L_PERMLIGHT: case L_PERMLIGHT:
default:
break; break;
} }
} }
@ -1085,12 +1094,24 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
// change a wall into an empty cell, and add some rubble // change a wall into an empty cell, and add some rubble
void breakwall(cell_t *c) { void breakwall(cell_t *c, char *why, ...) {
celltype_t *origtype; celltype_t *origtype;
int roomwall; int roomwall;
char buf[BUFLEN];
va_list args;
if (why) {
va_start(args, why);
vsnprintf( buf, BUFLEN, why, args );
va_end(args);
}
origtype = c->type; origtype = c->type;
roomwall = isroom(c); roomwall = isroom(c);
setcelltype(c, getcellempty(c)); setcelltype(c, getcellempty(c));
if (why) {
setcellreason(c, "%s", buf);
}
if (origtype->solid && roomwall && onein(2)) { if (origtype->solid && roomwall && onein(2)) {
switch (origtype->material->id) { switch (origtype->material->id) {
case MT_STONE: addob(c->obpile, "1-30 stones"); break; case MT_STONE: addob(c->obpile, "1-30 stones"); break;
@ -2009,7 +2030,7 @@ int fix_reachability(map_t *m) {
floodfill(c); floodfill(c);
// any remaining non-filled empty cells? // any remaining non-filled empty cells?
for (i = 0; i < m->w * m->h; i++) { for (i = 0; i < m->w * m->h; i++) {
if (!m->cell[i]->type->solid && !m->cell[i]->filled) { if (!m->cell[i]->type->solid && !m->cell[i]->filled && !m->cell[i]->locked) {
vault_t *v; vault_t *v;
v = getcellvault(m->cell[i]); v = getcellvault(m->cell[i]);
if (v && hasflag(v->flags, F_VAULTNOLINK)) { if (v && hasflag(v->flags, F_VAULTNOLINK)) {
@ -2203,6 +2224,7 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
// scanned lf here? // scanned lf here?
if (isinscanrange(c, &thing, NULL, &tempgl) == TT_MONSTER) { if (isinscanrange(c, &thing, NULL, &tempgl) == TT_MONSTER) {
*g = tempgl; *g = tempgl;
adjustcellglyph(c, g);
//mvwprintw(gamewin, y-viewy, x-viewx, "%c", glyph); //mvwprintw(gamewin, y-viewy, x-viewx, "%c", glyph);
//drawglyph(&glyph, x, y); //drawglyph(&glyph, x, y);
return; return;
@ -2222,13 +2244,13 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
} else { } else {
// objects here, but we can't see them. draw the cell. // objects here, but we can't see them. draw the cell.
*g = c->type->glyph; *g = c->type->glyph;
adjustcellglyphforlight(c, g); adjustcellglyph(c, g);
} }
} else { } else {
// draw cell normally // draw cell normally
//drawcell(cell, x, y); //drawcell(cell, x, y);
*g = c->type->glyph; *g = c->type->glyph;
adjustcellglyphforlight(c, g); adjustcellglyph(c, g);
} }
} else { // can't see the cell } else { // can't see the cell
void *thing; void *thing;
@ -2259,6 +2281,12 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
enum CELLTYPE getcellempty(cell_t *c) { enum CELLTYPE getcellempty(cell_t *c) {
flag_t *f; flag_t *f;
vault_t *v;
v = getcellvault(c);
if (v) {
f = hasflag(v->flags, F_CELLTYPEEMPTY);
if (f) return f->val[0];
}
if (c->habitat == c->map->habitat) { if (c->habitat == c->map->habitat) {
f = hasflag(c->map->flags, F_CELLTYPEEMPTY); f = hasflag(c->map->flags, F_CELLTYPEEMPTY);
if (f) return f->val[0]; if (f) return f->val[0];
@ -2268,6 +2296,14 @@ enum CELLTYPE getcellempty(cell_t *c) {
enum CELLTYPE getcellsolid(cell_t *c) { enum CELLTYPE getcellsolid(cell_t *c) {
flag_t *f; flag_t *f;
vault_t *v;
v = getcellvault(c);
if (v) {
f = hasflag(v->flags, F_CELLTYPESOLID);
if (f) return f->val[0];
}
if (c->habitat == c->map->habitat) { if (c->habitat == c->map->habitat) {
f = hasflag(c->map->flags, F_CELLTYPESOLID); f = hasflag(c->map->flags, F_CELLTYPESOLID);
if (f) return f->val[0]; if (f) return f->val[0];
@ -5132,57 +5168,60 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
int n; int n;
cell_t *c2; cell_t *c2;
startdist++; startdist++;
// check left/right from this cell for rooms // don't bother checking left/right if this cell isn't okay to be cleared.
for (n = 0; n <= 1; n++) { if (cellokforreachability(startcell, c, roomid, d, wantfilled, NULL)) {
int turndist = 0; // check left/right from this cell for rooms
c2 = getcellindir(c, perpdir[n]); for (n = 0; n <= 1; n++) {
int turndist = 0;
c2 = getcellindir(c, perpdir[n]);
while (c2) { while (c2) {
int gotsolution = B_FALSE; int gotsolution = B_FALSE;
int rv; int rv;
turndist++; turndist++;
perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns
perpturncell1[nperpcells] = c; perpturncell1[nperpcells] = c;
perpturndir1[nperpcells] = perpdir[n]; perpturndir1[nperpcells] = perpdir[n];
nperpcells++; nperpcells++;
rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL); rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL);
if (rv == B_FALSE) { if (rv == B_FALSE) {
break; break;
} else if (rv == B_TRUE) { } else if (rv == B_TRUE) {
gotsolution = B_TRUE; gotsolution = B_TRUE;
} else if (turndist > 1) { } else if (turndist > 1) {
// check l/r too // check l/r too
int perpdir2[2],nn; int perpdir2[2],nn;
cell_t *pcell = NULL; cell_t *pcell = NULL;
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W; perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N; perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
for (nn = 0; nn <= 1; nn++) { for (nn = 0; nn <= 1; nn++) {
pcell = getcellindir(c2, perpdir2[nn]); pcell = getcellindir(c2, perpdir2[nn]);
if (pcell && adjcellokforreachability(pcell, roomid, perpdir2[nn], wantfilled)) { if (pcell && adjcellokforreachability(pcell, roomid, perpdir2[nn], wantfilled)) {
// finished. // finished.
if (db) dblog(" Got to an empty cell next to us."); if (db) dblog(" Got to an empty cell next to us.");
gotsolution = B_TRUE; gotsolution = B_TRUE;
break; break;
}
} }
} }
if (gotsolution) {
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
startdist, getdirname(startdir),
turndist, getdirname(perpdir[n]));
// walkable and not in this roomid. ok!
turncell = c;
endcell = c2;
turndir = perpdir[n];
break;
}
// check next cell
c2 = getcellindir(c2, perpdir[n]);
} }
if (gotsolution) { if (turncell) break;
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
startdist, getdirname(startdir),
turndist, getdirname(perpdir[n]));
// walkable and not in this roomid. ok!
turncell = c;
endcell = c2;
turndir = perpdir[n];
break;
}
// check next cell
c2 = getcellindir(c2, perpdir[n]);
} }
if (turncell) break;
} }
// now keep going in main direction. // now keep going in main direction.
c = getcellindir(c, startdir); c = getcellindir(c, startdir);
@ -5193,17 +5232,17 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir)); if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir));
c = getcellindir(startcell, startdir); c = getcellindir(startcell, startdir);
while (c != turncell) { while (c != turncell) {
breakwall(c); breakwall(c, "turnset=1, making path from vault %d to corner", getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, startdir); c = getcellindir(c, startdir);
} }
// clear the corner cell // clear the corner cell
breakwall(c); breakwall(c, "turncell=1, this is the corner (from vault %d)",getroomid(startcell));
if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir)); if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir));
// now turn and clear up to the next room/empty cell // now turn and clear up to the next room/empty cell
c = getcellindir(c, turndir); c = getcellindir(c, turndir);
while (c != endcell) { while (c != endcell) {
breakwall(c); breakwall(c, "turncell=1, clearing from corner to end (from vault %d)", getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, turndir); c = getcellindir(c, turndir);
} }
@ -5282,17 +5321,17 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
if (db) dblog(" Making path from vault to first corner, initdir=%s", getdirname(startdir)); if (db) dblog(" Making path from vault to first corner, initdir=%s", getdirname(startdir));
c = getcellindir(startcell, startdir); c = getcellindir(startcell, startdir);
while (c != turncell) { while (c != turncell) {
breakwall(c); breakwall(c, "twoturn: path from vault %d to first corner 1", getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, startdir); c = getcellindir(c, startdir);
} }
// clear the corner cell // clear the corner cell
breakwall(c); breakwall(c, "twoturn: corner 1 (from vault %d)", getroomid(startcell));
// now turn and clear up to the next turn // now turn and clear up to the next turn
if (db) dblog(" Making path from 1st corner to 2nd corner, turndir=%s", getdirname(turndir)); if (db) dblog(" Making path from 1st corner to 2nd corner, turndir=%s", getdirname(turndir));
c = getcellindir(c, turndir); c = getcellindir(c, turndir);
while (c != turncell2) { while (c != turncell2) {
breakwall(c); breakwall(c, "twoturn: path from 1st corner to 2nd corner (from vault %d)", getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, turndir); c = getcellindir(c, turndir);
} }
@ -5301,7 +5340,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
if (db) dblog(" Making path from 2nd corner to rest of map, turndir=%s", getdirname(turndir2)); if (db) dblog(" Making path from 2nd corner to rest of map, turndir=%s", getdirname(turndir2));
c = getcellindir(c, turndir2); c = getcellindir(c, turndir2);
while (c != endcell) { while (c != endcell) {
breakwall(c); breakwall(c, "twoturn: path from 2nd corner to end (from vault %d)", getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, turndir2); c = getcellindir(c, turndir2);
} }
@ -5341,15 +5380,15 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
c = getcellindir(startcell, whichway); c = getcellindir(startcell, whichway);
//while (c && !cellwalkable(NULL, c, NULL)) { //while (c && !cellwalkable(NULL, c, NULL)) {
while (c && c != directendcell[whichway]) { while (c && c != directendcell[whichway]) {
breakwall(c); breakwall(c, "direct link (from vault %d)",getroomid(startcell));
if (ncellsadded) (*ncellsadded)++; if (ncellsadded) (*ncellsadded)++;
c = getcellindir(c, whichway); c = getcellindir(c, whichway);
} }
} }
// now make sure the START cell is empty too! // now make sure the START cell is empty too!
if (startcell->type->solid) { if (startcell->type->solid && !startcell->locked && !cellisfixedvaultwall(startcell)) {
breakwall(startcell); breakwall(startcell, "making sure start cell is empty (from vault %d)",getroomid(startcell));
} }
return B_FALSE; return B_FALSE;
@ -5364,6 +5403,7 @@ int linkexits(map_t *m, int roomid) {
int nadded = 0; int nadded = 0;
int minx = -1, miny = -1, maxx = -1, maxy = -1; int minx = -1, miny = -1, maxx = -1, maxy = -1;
int roomidx = -1; int roomidx = -1;
vault_t *v;
// figure out room coords // figure out room coords
for (i = 0; i < m->nrooms; i++) { for (i = 0; i < m->nrooms; i++) {
@ -5382,11 +5422,16 @@ int linkexits(map_t *m, int roomid) {
c = getrandomroomcell(m, roomid, WE_NONE); c = getrandomroomcell(m, roomid, WE_NONE);
if (!c) return B_FALSE; if (!c) return B_FALSE;
v = getcellvault(c);
if (v) {
if (hasflag(v->flags, F_VAULTNOLINK)) {
return B_FALSE;
}
}
if (db) { if (db) {
char buf[BUFLEN]; char buf[BUFLEN];
vault_t *v; //c = getrandomroomcell(m, roomid, WE_NONE);
c = getrandomroomcell(m, roomid, WE_NONE);
v = getcellvault(c);
snprintf(buf, BUFLEN, "*** linkexits for roomid %d (%s) [%d,%d-%d,%d]", roomid, snprintf(buf, BUFLEN, "*** linkexits for roomid %d (%s) [%d,%d-%d,%d]", roomid,
v ? v->id : "novault", v ? v->id : "novault",
minx,miny,maxx,maxy); minx,miny,maxx,maxy);
@ -7265,31 +7310,31 @@ void initmap(void) {
// cell types - solid // cell types - solid
// floorheight, hp // floorheight, hp
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0, 50); addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50);
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, B_SOLID, B_OPAQUE, MT_STONE, 0, 40); addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 20); addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20);
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000); addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30);
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100); addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25); addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20); addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20);
//addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100); //addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100); addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 75); addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75);
// cell types - non-solid // cell types - non-solid
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1); addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, C_ORANGE, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1);
addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1); addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, NA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1);
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1); addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, B_EMPTY, B_TRANS, MT_FLESH, 0, -1); addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, NA, B_EMPTY, B_TRANS, MT_FLESH, 0, -1);
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1); addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, B_EMPTY, B_TRANS, MT_METAL, 0, -1); addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1);
addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT, 0, -1); addcelltype(CT_GRASS, "grass", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_PLANT, 0, -1);
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_DIRT, "dirt", '.', C_BROWN, C_YELLOW, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -1, -1); addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -1, -1);
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1); addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -2, -1);
// region types // region types
// name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth? // name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth?
@ -8444,7 +8489,7 @@ void selectcelltypes(map_t *map) {
} }
// random chance of different floor type // random chance of different floor type
if (onein(6)) { if (onein(6)) {
switch (rnd(1,3)) { switch (rnd(1,4)) {
case 1: case 1:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORCARPET, NA, NA, NULL); addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORCARPET, NA, NA, NULL);
break; break;
@ -8454,6 +8499,9 @@ void selectcelltypes(map_t *map) {
case 3: case 3:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORWOOD, NA, NA, NULL); addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORWOOD, NA, NA, NULL);
break; break;
case 4:
addflag(map->flags, F_CELLTYPEEMPTY, CT_DIRT, NA, NA, NULL);
break;
} }
} }
} }
@ -8496,8 +8544,8 @@ void setcellknown(cell_t *cell, int forcelev) {
o = hassecretdoor(cell->obpile); o = hassecretdoor(cell->obpile);
if (o) { if (o) {
celltype_t *ct; celltype_t *ct;
//ct = findcelltype(getcellsolid(cell)); ct = findcelltype(getcellsolid(cell));
ct = findcelltype(getmapsolid(cell->map)); //ct = findcelltype(getmapsolid(cell->map));
cell->knownglyph = ct->glyph; cell->knownglyph = ct->glyph;
} else { } else {
cell->knownglyph = cell->type->glyph; cell->knownglyph = cell->type->glyph;
@ -8547,6 +8595,19 @@ void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype) {
} }
} }
void setcellreason(cell_t *c, char *why, ...) {
char buf[BUFLEN];
va_list args;
if (c->reason) free(c->reason);
va_start(args, why);
vsnprintf( buf, BUFLEN, why, args );
va_end(args);
c->reason = strdup(buf);
}
void setcelltype(cell_t *cell, enum CELLTYPE id) { void setcelltype(cell_t *cell, enum CELLTYPE id) {
assert(cell); assert(cell);
cell->type = findcelltype(id); cell->type = findcelltype(id);

5
map.h
View File

@ -11,9 +11,9 @@ region_t *addregion(enum BRANCH rtype, region_t *parent, int outlineid, int dept
regionoutline_t *addregionoutline(enum BRANCH rtype); regionoutline_t *addregionoutline(enum BRANCH rtype);
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what); regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
branch_t *addbranch(enum BRANCH id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod, int addparentdepth); branch_t *addbranch(enum BRANCH id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod, int addparentdepth);
void adjustcellglyphforlight(cell_t *c, glyph_t *col); void adjustcellglyph(cell_t *c, glyph_t *col);
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance); int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
void breakwall(cell_t *c); void breakwall(cell_t *c, char *why, ...);
int cellhaslos(cell_t *c1, cell_t *dest); int cellhaslos(cell_t *c1, cell_t *dest);
int cellisfixedvaultwall(cell_t *c); int cellisfixedvaultwall(cell_t *c);
int cellmatchescondition(cell_t *c, int wecond); int cellmatchescondition(cell_t *c, int wecond);
@ -188,6 +188,7 @@ void selectcelltypes(map_t *map);
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph); void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph);
void setcellknown(cell_t *cell, int forcelev); void setcellknown(cell_t *cell, int forcelev);
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype); void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
void setcellreason(cell_t *c, char *why, ...);
void setcelltype(cell_t *cell, enum CELLTYPE id); void setcelltype(cell_t *cell, enum CELLTYPE id);
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring); int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
int unlinkstairsto(map_t *unlinkmap); int unlinkstairsto(map_t *unlinkmap);

24
nexus.c
View File

@ -53,6 +53,8 @@ extern int ngodlfs;
int nextregionthingid = 0; int nextregionthingid = 0;
int playerorigalignment = AL_NONE;
buildingusage_t buildingusage[MAXBUILDINGTYPES]; buildingusage_t buildingusage[MAXBUILDINGTYPES];
int nbuildingusage = 0; int nbuildingusage = 0;
@ -61,6 +63,8 @@ option_t *firstoption = NULL,*lastoption = NULL;
int maxmonhitdice = 0; // highest number of hitdice for any monster int maxmonhitdice = 0; // highest number of hitdice for any monster
int playerhasmoved = B_FALSE;
double presin[360]; double presin[360];
double precos[360]; double precos[360];
@ -501,6 +505,7 @@ int main(int argc, char **argv) {
clearmsg(); clearmsg();
msg("%s",welcomemsg); msg("%s",welcomemsg);
more(); more();
playerorigalignment = getalignment(player);
// MAIN LOOP // MAIN LOOP
@ -553,7 +558,7 @@ int main(int argc, char **argv) {
return B_FALSE; return B_FALSE;
} }
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp) { celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp) {
celltype_t *a; celltype_t *a;
// add to the end of the list // add to the end of the list
@ -576,6 +581,11 @@ celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, in
a->name = strdup(name); a->name = strdup(name);
a->glyph.ch = glyph; a->glyph.ch = glyph;
a->glyph.colour = colour; a->glyph.colour = colour;
if (altcol == NA) {
a->altcol = C_NONE;
} else {
a->altcol = altcol;
}
a->solid = solid; a->solid = solid;
a->transparent = transparent; a->transparent = transparent;
a->material = findmaterial(mat); a->material = findmaterial(mat);
@ -804,10 +814,6 @@ void donextturn(map_t *map) {
completeincubation(who, incflag); completeincubation(who, incflag);
willchange = B_TRUE; willchange = B_TRUE;
free(localtext); free(localtext);
addflag(who->flags, F_AICONTROLLED, B_TRUE, NA, NA, NULL);
if (isplayer(who)) {
addflag(who->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
}
willrage = B_TRUE; willrage = B_TRUE;
} }
} }
@ -822,7 +828,7 @@ void donextturn(map_t *map) {
polymorphto(who, r->id, PERMENANT); polymorphto(who, r->id, PERMENANT);
donormalmove = B_FALSE; donormalmove = B_FALSE;
if (willrage) { if (willrage) {
addflag(who->flags, F_RAGE, B_TRUE, NA, NA, NULL); enrage(who, PERMENANT);
} }
} }
} else if (ispolymorphed(who)) { } else if (ispolymorphed(who)) {
@ -1088,6 +1094,12 @@ void donextturn(map_t *map) {
if (!isdead(who)) endlfturn(who); if (!isdead(who)) endlfturn(who);
} // end 'if (who)' } // end 'if (who)'
if (isplayer(who)) {
// in order to force the player's turn to be first,
// monsters will not take any actions until
// playerhasmoved is set
playerhasmoved = B_TRUE;
}
// check for death etc // check for death etc
checkdeath(); checkdeath();

View File

@ -1,6 +1,6 @@
#include "defs.h" #include "defs.h"
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp); celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp);
warning_t *addwarning(char *text, int lifetime); warning_t *addwarning(char *text, int lifetime);
void checkdeath(void); void checkdeath(void);
void checkendgame(void); void checkendgame(void);

110
objects.c
View File

@ -811,6 +811,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
p += strlen(mat->name); p += strlen(mat->name);
p++; // go past the space p++; // go past the space
donesomething = B_TRUE; donesomething = B_TRUE;
// special flags
} else if (strstarts(p, "immutable ")) {
f = addflag(wantflags, F_IMMUTABLE, B_TRUE, NA, NA, NULL);
f->known = B_FALSE;
p += strlen("immutable ");
donesomething = B_TRUE;
// rarity // rarity
} else if (strstarts(p, "frequent ")) { } else if (strstarts(p, "frequent ")) {
wantrarity = RR_FREQUENT; wantrarity = RR_FREQUENT;
@ -3425,7 +3431,7 @@ int doobdieconvert(object_t *o, int wantannounce) {
if (centre) { if (centre) {
cell_t *cell[MAXCANDIDATES]; cell_t *cell[MAXCANDIDATES];
int ncells,i; int ncells,i;
getradiuscells(centre, f->val[0], DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, cell, &ncells, B_FALSE); getradiuscells(centre, f->val[0], f->val[1], B_FALSE, LOF_WALLSTOP, B_FALSE, cell, &ncells, B_FALSE);
for (i = 0; i < ncells; i++) { for (i = 0; i < ncells; i++) {
newob = addob(cell[i]->obpile, f->text); newob = addob(cell[i]->obpile, f->text);
if (newob && !strchr(f->text, '-')) { if (newob && !strchr(f->text, '-')) {
@ -3766,7 +3772,8 @@ glyph_t *getglyph(object_t *o) {
if (isdoor(o, &isopen)) { if (isdoor(o, &isopen)) {
if (issecretdoor(o)) { if (issecretdoor(o)) {
return &(findcelltype(getmapsolid(obloc->map))->glyph); //return &(findcelltype(getmapsolid(obloc->map))->glyph);
return &(findcelltype(getcellsolid(obloc))->glyph);
} else { } else {
if (isopen) { if (isopen) {
g = '-'; g = '-';
@ -7593,21 +7600,12 @@ int isreadable(object_t *o) {
} }
int isrotting(object_t *o) { int isrotting(object_t *o) {
flag_t *f;
float pct;
if (hasflag(o->flags, F_TAINTED)) { if (hasflag(o->flags, F_TAINTED)) {
return B_TRUE; return B_TRUE;
} }
if (!iscorpse(o)) return B_FALSE; if (!iscorpse(o)) return B_FALSE;
f = hasflag(o->flags, F_OBHP); if (getobhppct(o) < 25) {
if (f) {
pct = ((float) f->val[0] / (float) f->val[1]) * 100.0;
} else {
pct = 100;
}
if (pct < 25) {
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -8742,6 +8740,8 @@ void obdie(object_t *o) {
int power; int power;
char obname[BUFLEN],seebuf[BUFLEN],noseebuf[BUFLEN]; char obname[BUFLEN],seebuf[BUFLEN],noseebuf[BUFLEN];
char buf[BUFLEN],*p; char buf[BUFLEN],*p;
flag_t *glyphflag;
glyph_t cloudglyph;
where = getoblocation(o); where = getoblocation(o);
getobname(o, obname, 1); getobname(o, obname, 1);
p = readuntil(seebuf, f->text, '^'); p = readuntil(seebuf, f->text, '^');
@ -8749,14 +8749,25 @@ void obdie(object_t *o) {
p = readuntil(buf, p, '^'); p = readuntil(buf, p, '^');
power = atoi(buf); power = atoi(buf);
glyphflag = hasflag(o->flags, F_SPELLCLOUDGLYPH);
if (glyphflag) {
cloudglyph.colour = glyphflag->val[0];
cloudglyph.ch = glyphflag->val[1];
} else {
cloudglyph.colour = C_RANDOM;
cloudglyph.ch = UNI_SHADELIGHT;
}
if (f->val[2] == B_IFACTIVATED) { if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) { if (isactivated(o)) {
spellcloud(where, f->val[1], UNI_SHADELIGHT, C_RANDOM, f->val[0], power, B_TRUE, seebuf, noseebuf, B_FALSE, o); spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
removeob(o, o->amt); removeob(o, o->amt);
return; return;
} }
} else { } else {
spellcloud(where, f->val[1], UNI_SHADELIGHT, C_RANDOM, f->val[0], power, B_TRUE, seebuf, noseebuf, B_FALSE, o); spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
removeob(o, o->amt); removeob(o, o->amt);
return; return;
} }
@ -8808,7 +8819,7 @@ void obdie(object_t *o) {
lifeform_t *l; lifeform_t *l;
l = findlf(loc->map, retflag[i]->val[0]); l = findlf(loc->map, retflag[i]->val[0]);
if (l) { if (l) {
sayphrase(l, SP_LIFEOB_DESTROYED, SV_CAR, NA, NULL); sayphrase(l, SP_LIFEOB_DESTROYED, SV_CAR, NA, NULL, NULL);
} }
} }
} }
@ -9903,11 +9914,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
// create fire // create fire
addobfast(c->obpile, OT_FIRELARGE); addobfast(c->obpile, OT_FIRELARGE);
// enrage // enrage
addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); enrage(c->lf, howlong);
if (!isplayer(c->lf)) {
addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong);
loseaitargets(c->lf);
}
} }
} }
break; break;
@ -12876,7 +12883,9 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
int power; int power;
char obname[BUFLEN],seebuf[BUFLEN],noseebuf[BUFLEN]; char obname[BUFLEN],seebuf[BUFLEN],noseebuf[BUFLEN];
char buf[BUFLEN],*p; char buf[BUFLEN],*p;
flag_t *glyphflag;
cell_t *where; cell_t *where;
glyph_t cloudglyph;
where = getoblocation(o); where = getoblocation(o);
getobname(o, obname, 1); getobname(o, obname, 1);
p = readuntil(seebuf, f->text, '^'); p = readuntil(seebuf, f->text, '^');
@ -12884,16 +12893,27 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
p = readuntil(buf, p, '^'); p = readuntil(buf, p, '^');
power = atoi(buf); power = atoi(buf);
glyphflag = hasflag(o->flags, F_SPELLCLOUDGLYPH);
if (glyphflag) {
cloudglyph.colour = glyphflag->val[0];
cloudglyph.ch = glyphflag->val[1];
} else {
cloudglyph.colour = C_RANDOM;
cloudglyph.ch = UNI_SHADELIGHT;
}
if (f->val[2] == B_IFACTIVATED) { if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) { if (isactivated(o)) {
if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) { if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) {
spellcloud(where, f->val[1], UNI_SHADELIGHT, C_RANDOM, f->val[0], power, B_TRUE, seebuf, noseebuf, B_FALSE, o); spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
} }
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL); addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
} }
} else { } else {
if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) { if (!hasflag(o->flags, F_SPELLCLOUDONDEATH)) {
spellcloud(where, f->val[1], UNI_SHADELIGHT, C_RANDOM, f->val[0], power, B_TRUE, seebuf, noseebuf, B_FALSE, o); spellcloud(where, f->val[1], cloudglyph.ch, cloudglyph.colour, f->val[0], power, B_TRUE,
seebuf, noseebuf, B_FALSE, o, B_INCLUDECENTRE);
} }
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL); addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
} }
@ -13344,7 +13364,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
radius = o->amt * 2; radius = o->amt * 2;
if (radius > 10) radius = 10; if (radius > 10) radius = 10;
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL); spellcloud(srcloc, radius, UNI_SHADELIGHT, C_RANDOM, OT_S_INVISIBILITY, radius, B_TRUE, buf, "A cloud of twinkling lights appear!", B_FALSE, NULL, B_INCLUDECENTRE);
} else if (o->type->id == OT_ASHSLEEP) { } else if (o->type->id == OT_ASHSLEEP) {
int radius; int radius;
char buf[BUFLEN]; char buf[BUFLEN];
@ -13357,7 +13377,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
radius = o->amt * 2; radius = o->amt * 2;
if (radius > 10) radius = 10; if (radius > 10) radius = 10;
spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL); spellcloud(srcloc, radius, UNI_SHADELIGHT, C_MAGENTA, OT_S_SLEEP, radius, B_TRUE, buf, "A wispy mist appears!", B_FALSE, NULL, B_INCLUDECENTRE);
} else if (o->type->id == OT_SALT) { } else if (o->type->id == OT_SALT) {
int dist; int dist;
dist = getcelldist(srcloc, where); dist = getcelldist(srcloc, where);
@ -13629,28 +13649,32 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
catchmod = -6; catchmod = -6;
dodgemod = 2; dodgemod = 2;
} }
// first check to see if you can catch it. this should be very hard! if (hasfreeaction(target) && skillcheck(target, SC_DODGE, 27+(speed*2), dodgemod)) {
if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) && // if we passed the dodge check, now see if we caught it...
lfhasflag(target, F_HUMANOID) && // first check to see if you can catch it. this should be very hard!
canpickup(target, o, o->amt) && if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) &&
!willburden(target, o, o->amt) && lfhasflag(target, F_HUMANOID) &&
!isimmobile(target) && canpickup(target, o, o->amt) &&
skillcheck(target, SC_DEX, 27 + (speed*5), catchmod)) { !willburden(target, o, o->amt) &&
willcatch = B_TRUE; !isimmobile(target) &&
} else if (hasfreeaction(target) && skillcheck(target, SC_DODGE, 27+(speed*2), dodgemod)) { skillcheck(target, SC_DEX, 27 + (speed*5), catchmod)) {
// then check if we dodge it... if (db) dblog("target passed catch check.");
if (db) dblog("target passed dodge check."); willcatch = B_TRUE;
} else {
// then check if we dodge it...
if (db) dblog("target passed dodge check.");
youhit = B_FALSE; youhit = B_FALSE;
if (seen) { if (seen) {
if (isplayer(target)) { if (isplayer(target)) {
msg("You dodge %s.", obname); msg("You dodge %s.", obname);
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("%s dodges %s.", targetname, obname); msg("%s dodges %s.", targetname, obname);
}
announcedmiss = B_TRUE;
} }
announcedmiss = B_TRUE; practice(target, SK_EVASION, 1);
} }
practice(target, SK_EVASION, 1);
} }
} }
} }

View File

@ -503,7 +503,8 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
msg("\"We appreciate your kind donation.\""); msg("\"We appreciate your kind donation.\"");
} }
} else { } else {
msg("\"Thanks!\""); more(); sayphrase(NULL, SP_THANKS, SV_TALK, NA, NULL, player);
more();
} }
f = hasflag(vm->flags, F_SHOPDONATED); f = hasflag(vm->flags, F_SHOPDONATED);

211
spell.c
View File

@ -1443,7 +1443,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
return B_TRUE; return B_TRUE;
} }
howlong = DEF_RAGETIME; howlong = DEF_RAGETIME;
addtempflag(user->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); enrage(user, howlong);
} else if (abilid == OT_A_REPAIR) { } else if (abilid == OT_A_REPAIR) {
object_t *o; object_t *o;
enum MATERIAL repairablemats[MAXCANDIDATES]; enum MATERIAL repairablemats[MAXCANDIDATES];
@ -2395,7 +2395,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
wep = getweapon(user); wep = getweapon(user);
// try to disarm them... // try to trip them...
taketime(user, getactspeed(user)); taketime(user, getactspeed(user));
if (wep) { if (wep) {
@ -4251,7 +4251,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (target && cansee(player, target)) { if (target && cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
msg("A green miasma surrounds %s%s %s.", lfname, msg("^%cA green miasma surrounds %s%s %s.", getlfcol(target, CC_BAD), lfname,
getpossessive(lfname), obname); getpossessive(lfname), obname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (targcell && haslos(player, targcell)) { } else if (targcell && haslos(player, targcell)) {
@ -4274,7 +4274,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (cansee(player, targcell->lf)) { if (cansee(player, targcell->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
msg("A green miasma surrounds %s.", lfname); msg("^%cA green miasma surrounds %s.", getlfcol(targcell->lf, CC_BAD), lfname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
if (isliving(targcell->lf)) { if (isliving(targcell->lf)) {
@ -4290,7 +4290,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
losehp(targcell->lf, dam, DT_DECAY, caster, damstr); losehp(targcell->lf, dam, DT_DECAY, caster, damstr);
if (isplayer(targcell->lf)) { if (isplayer(targcell->lf)) {
msg("A blight courses through your veins!"); msg("^%cA blight courses through your veins!", getlfcol(targcell->lf, CC_BAD));
} else if (cansee(player, targcell->lf)) { } else if (cansee(player, targcell->lf)) {
char tname[BUFLEN]; char tname[BUFLEN];
getlfname(targcell->lf, tname); getlfname(targcell->lf, tname);
@ -4516,7 +4516,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char realcname[BUFLEN]; char realcname[BUFLEN];
getlfname(c->lf,buf); getlfname(c->lf,buf);
if (!isimmuneto(c->lf->flags, DT_FIRE, B_FALSE)) { if (!isimmuneto(c->lf->flags, DT_FIRE, B_FALSE)) {
msg("%s burn%s!",buf,isplayer(c->lf) ? "" : "s"); msg("^%c%s burn%s!",getlfcol(c->lf, CC_BAD), buf,isplayer(c->lf) ? "" : "s");
} }
real_getlfname(caster, realcname, NULL, B_SHOWALL, B_REALRACE); real_getlfname(caster, realcname, NULL, B_SHOWALL, B_REALRACE);
snprintf(damstring, BUFLEN, "%s%s wave of fire", realcname, getpossessive(realcname)); snprintf(damstring, BUFLEN, "%s%s wave of fire", realcname, getpossessive(realcname));
@ -4615,7 +4615,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
animsky(targcell, '}', C_WHITE); animsky(targcell, '}', C_WHITE);
msg("%s %s struck by a bolt of lightning!",targname,is(target)); msg("^%c%s %s struck by a bolt of lightning!",getlfcol(target, CC_BAD), targname,is(target));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -4878,11 +4878,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
limit(&pct, 0, 100); limit(&pct, 0, 100);
if (pct) { if (pct) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Your wounds are healed!"); msg("^%cYour wounds are healed!", getlfcol(target, CC_GOOD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
msg("%s%s wounds are healed!", lfname, getpossessive(lfname)); msg("^%c%s%s wounds are healed!", getlfcol(target, CC_GOOD), lfname, getpossessive(lfname));
} }
gainhp(target, pctof(pct, target->maxhp)); gainhp(target, pctof(pct, target->maxhp));
} else { } else {
@ -5104,21 +5104,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
dam = rnd(1,exposedlimbs); dam = rnd(1,exposedlimbs);
if (isplayer(target)) { if (isplayer(target)) {
msg("The air around you feels icy cold!"); msg("^%cThe air around you feels icy cold!", getlfcol(target, CC_BAD));
} }
if (isplayer(target)) { if (isplayer(target)) {
if (isimmuneto(target->flags, DT_COLD, B_FALSE)) { if (isimmuneto(target->flags, DT_COLD, B_FALSE)) {
msg("You feel mildly chilly."); msg("You feel mildly chilly.");
} else { } else {
msg("You feel cold!"); msg("^%cYou feel very cold!", getlfcol(target, CC_BAD));
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
if (isimmuneto(target->flags, DT_COLD, B_FALSE)) { if (isimmuneto(target->flags, DT_COLD, B_FALSE)) {
msg("%s doesn't seem to mind the cold.", lfname); msg("%s doesn't seem to mind the cold.", lfname);
} else { } else {
msg("%s looks cold!", lfname); msg("^%c%s looks very cold!", getlfcol(target, CC_BAD), lfname);
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -5154,7 +5154,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// automatic hit // automatic hit
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
msg("%s %s chilled!",lfname,is(targcell->lf)); msg("^%c%s %s chilled!",getlfcol(targcell->lf, CC_BAD),
lfname,is(targcell->lf));
} }
losehp(targcell->lf, rolldie(1,8)+3, DT_COLD, caster, "a burst of coldness"); losehp(targcell->lf, rolldie(1,8)+3, DT_COLD, caster, "a burst of coldness");
} }
@ -5193,7 +5194,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int dam; int dam;
// hit // hit
if (cansee(player, target)) { if (cansee(player, target)) {
msg("A blast of icy air hits %s.",lfname); msg("^%cA blast of icy air assails %s.",getlfcol(target, CC_BAD), lfname);
} }
dam = roll("3d6"); dam = roll("3d6");
if (power > 1) { // overcast for dragons if (power > 1) { // overcast for dragons
@ -5398,9 +5399,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// announce // announce
getobname(o, obname, 1); getobname(o, obname, 1);
if (isplayer(target)) { if (isplayer(target)) {
msg("%s forms %s your %s!", obname, getbodypartequipname(bp[i]), getbodypartname(target, bp[i])); msg("^%c%s forms %s your %s!", getlfcol(target, CC_VGOOD), obname, getbodypartequipname(bp[i]), getbodypartname(target, bp[i]));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]), msg("^%c%s forms %s %s%s %s!", getlfcol(target, CC_VGOOD),obname, getbodypartequipname(bp[i]),
castername, getpossessive(castername), getbodypartname(target, bp[i])); castername, getpossessive(castername), getbodypartname(target, bp[i]));
} }
// don't use "wear" because we don't want it being announced. // don't use "wear" because we don't want it being announced.
@ -5449,9 +5450,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
// announce // announce
if (isplayer(target)) { if (isplayer(target)) {
msg("A %s shield of shimmering ice forms in your hand!", getsizetext(sz)); msg("^%cA %s shield of shimmering ice forms in your hand!", getlfcol(target, CC_GOOD),
getsizetext(sz));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("A %s shield of shimmering ice forms in %s%s hand!", getsizetext(sz), castername, msg("^%cA %s shield of shimmering ice forms in %s%s hand!",getlfcol(target, CC_GOOD),
getsizetext(sz), castername,
getpossessive(castername)); getpossessive(castername));
} }
// don't use "wear" because we don't want it being announced. // don't use "wear" because we don't want it being announced.
@ -5807,7 +5810,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
if (isplayer(target)) { if (isplayer(target)) {
msg("You feel your body's essence unraveling!"); msg("^%cYou feel your body's essence unraveling!", getlfcol(target, CC_BAD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
@ -5981,7 +5984,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_DETONATEDELAY) { } else if (spellid == OT_S_DETONATEDELAY) {
addobfast(targcell->obpile, OT_VIBCLOUD); addobfast(targcell->obpile, OT_VIBCLOUD);
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
msg("The air nearby begins to vibrate violently..."); more(); msg("^%cThe air nearby begins to vibrate violently...", getlfcol(player, CC_VBAD)); more();
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else if (spellid == OT_S_EQANDOP) { } else if (spellid == OT_S_EQANDOP) {
@ -5994,10 +5997,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
howlong = power*5; howlong = power*5;
addtempflag(caster->flags, F_AUTOCREATEOB, 0, NA, NA, "whirlwind", howlong); addtempflag(caster->flags, F_AUTOCREATEOB, 0, NA, NA, "whirlwind", howlong);
if (isplayer(caster)) { if (isplayer(caster)) {
msg("A spinning whirlwind lifts you off the ground!"); msg("^%cA spinning whirlwind lifts you off the ground!", getlfcol(caster, CC_GOOD));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
msg("A spinning whirlwind lifts %s off the ground!", castername); msg("^%cA spinning whirlwind lifts %s off the ground!", getlfcol(caster, CC_GOOD), castername);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
addtempflag(caster->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, howlong); addtempflag(caster->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, howlong);
@ -6193,13 +6196,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (isplayer(caster) || cansee(player, caster)) { if (isplayer(caster) || cansee(player, caster)) {
if (isimmuneto(target->flags, DT_NECROTIC, B_FALSE)) { if (isimmuneto(target->flags, DT_NECROTIC, B_FALSE)) {
msg("%s suck%s death from %s!",castername,isplayer(caster) ? "" : "s", lfname); msg("^%c%s suck%s death from %s!",getlfcol(target, CC_BAD),
castername,isplayer(caster) ? "" : "s", lfname);
} else { } else {
msg("%s suck%s life from %s!",castername,isplayer(caster) ? "" : "s", lfname); msg("^%c%s suck%s life from %s!",getlfcol(target, CC_BAD),
castername,isplayer(caster) ? "" : "s", lfname);
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (isplayer(target)) { } else if (isplayer(target)) {
msg("You feel your life force draining away!"); msg("^%cYou feel your life force draining away!", getlfcol(target, CC_BAD));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -6240,11 +6245,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (c->lf && (c->lf != caster) && haslof(targcell, c, B_FALSE, NULL)) { if (c->lf && (c->lf != caster) && haslof(targcell, c, B_FALSE, NULL)) {
// automatic hit // automatic hit
if (isplayer(c->lf)) { if (isplayer(c->lf)) {
msg("A blast of energy hits you!"); msg("^%cA blast of energy hits you!", getlfcol(c->lf, CC_BAD));
} else if (cansee(player, c->lf)) { } else if (cansee(player, c->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("A blast of energy hits %s.",lfname); msg("^%cA blast of energy hits %s.", getlfcol(c->lf, CC_BAD), lfname);
} }
losehp(c->lf, roll("2d6"), DT_MAGIC, caster, "an energy blast"); losehp(c->lf, roll("2d6"), DT_MAGIC, caster, "an energy blast");
} }
@ -6271,10 +6276,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (lfhasflag(target, F_ASLEEP)) { if (lfhasflag(target, F_ASLEEP)) {
if (isplayer(target)) { if (isplayer(target)) {
msg("You suffer terrifying nightmares!"); msg("^%cYou suffer terrifying nightmares!", getlfcol(target, CC_BAD));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
msg("%s thrashes about in its sleep!",targname); msg("^%c%s thrashes about in its sleep!",getlfcol(target, CC_BAD), targname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
losehp(target, roll("2d6"), DT_DIRECT, caster, "terrifying nightmares"); losehp(target, roll("2d6"), DT_DIRECT, caster, "terrifying nightmares");
@ -6364,11 +6369,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (isplayer(target)) { if (isplayer(target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("Unseen forces rip into your flesh!"); msg("^%cUnseen forces rip into your flesh!", getlfcol(target, CC_VBAD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
getlfname(target, targetname); getlfname(target, targetname);
msg("Unseen forces rip into %s%s flesh!", targetname, getpossessive(targetname)); msg("^%cUnseen forces rip into %s%s flesh!", getlfcol(target, CC_VBAD), targetname, getpossessive(targetname));
} }
criticalhit(caster, target, getrandomcorebp(target, NULL), NULL, rnd(1,6), DT_SLASH); criticalhit(caster, target, getrandomcorebp(target, NULL), NULL, rnd(1,6), DT_SLASH);
} else if (spellid == OT_S_GLYPHWARDING) { } else if (spellid == OT_S_GLYPHWARDING) {
@ -6504,9 +6509,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// ALWAYS hits. // ALWAYS hits.
if (cansee(player, target)) { if (cansee(player, target)) {
if (power == 1) { if (power == 1) {
msg("A bolt of energy hits %s.",lfname); msg("^%cA bolt of energy hits %s.",getlfcol(target, CC_BAD), lfname);
} else { } else {
msg("%s bolts of energy hit %s.",numbuf, lfname); msg("^%c%s bolts of energy hit %s.",getlfcol(target, CC_BAD), numbuf, lfname);
} }
} }
losehp(target, rolldie(power*2,4), DT_MAGIC, caster, "an energy bolt"); losehp(target, rolldie(power*2,4), DT_MAGIC, caster, "an energy bolt");
@ -6656,7 +6661,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
// hit // hit
if (isplayer(target) || cansee(player, target)) { if (isplayer(target) || cansee(player, target)) {
msg("A dart of flame hits %s.",lfname); msg("^%cA dart of flame hits %s.",getlfcol(target, CC_BAD), lfname);
} }
losehp(target, rnd(1,6) + power, DT_FIRE, caster, "a dart of flame"); losehp(target, rnd(1,6) + power, DT_FIRE, caster, "a dart of flame");
} }
@ -6690,7 +6695,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// automatic hit // automatic hit
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
if (haslos(caster, targcell)) { if (haslos(caster, targcell)) {
msg("%s burn%s!",lfname,isplayer(targcell->lf) ? "" : "s"); msg("^%c%s burn%s!",getlfcol(targcell->lf, CC_BAD),
lfname,isplayer(targcell->lf) ? "" : "s");
} }
losehp(targcell->lf, rolldie(2,6), DT_FIRE, caster, "a burst of fire"); losehp(targcell->lf, rolldie(2,6), DT_FIRE, caster, "a burst of fire");
} }
@ -6860,7 +6866,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
getlfname(target, targname); getlfname(target, targname);
if (cansee(player, target)) { if (cansee(player, target)) {
msg("Entangling vines rise up and grasp %s!",targname); msg("^%cEntangling vines rise up and grasp %s!",getlfcol(target, CC_BAD), targname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7057,14 +7063,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (isimmuneto(target->flags, DT_COLD, B_FALSE)) { if (isimmuneto(target->flags, DT_COLD, B_FALSE)) {
msg("You feel mildly chilly."); msg("You feel mildly chilly.");
} else { } else {
msg("You feel extremely cold!"); msg("^%cYou feel extremely cold!", getlfcol(target, CC_BAD) );
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
if (isimmuneto(target->flags, DT_COLD, B_FALSE)) { if (isimmuneto(target->flags, DT_COLD, B_FALSE)) {
msg("%s looks mildly chilly.", lfname); msg("%s looks mildly chilly.", lfname);
} else { } else {
msg("%s looks extremely cold!", lfname); msg("^%c%s looks extremely cold!", getlfcol(target, CC_BAD), lfname);
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7109,11 +7115,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
sprintf(buf, "being sucked into %s", castername); sprintf(buf, "being sucked into %s", castername);
losehp(c->lf, c->lf->maxhp, DT_DIRECT, target, buf); losehp(c->lf, c->lf->maxhp, DT_DIRECT, target, buf);
if (isplayer(c->lf)) { if (isplayer(c->lf)) {
msg("Your essence is sucked into %s!", castername); msg("^%cYour essence is sucked into %s!", getlfcol(c->lf, CC_VBAD), castername);
} else if (cansee(player, c->lf)) { } else if (cansee(player, c->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("%s%s essence is sucked into %s!", lfname, getpossessive(lfname), castername); msg("^%c%s%s essence is sucked into %s!",getlfcol(c->lf, CC_VBAD), lfname, getpossessive(lfname), castername);
} }
amt++; amt++;
} }
@ -7310,12 +7316,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (bpgone != BP_NONE) { if (bpgone != BP_NONE) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Your %s grows back!", getbodypartname(target, bpgone)); msg("^%cYour %s grows back!", getlfcol(target, CC_GOOD), getbodypartname(target, bpgone));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char targname[BUFLEN]; char targname[BUFLEN];
getlfname(target, targname); getlfname(target, targname);
msg("%s%s %s grows back!", targname, getpossessive(targname), msg("^%c%s%s %s grows back!", getlfcol(target, CC_GOOD), targname, getpossessive(targname),
getbodypartname(target, bpgone)); getbodypartname(target, bpgone));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7351,7 +7357,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
losehp(target, amt, DT_HOLY, caster, "the power of healing"); losehp(target, amt, DT_HOLY, caster, "the power of healing");
if (isplayer(target) || cansee(player, target)) { if (isplayer(target) || cansee(player, target)) {
getlfname(target, buf); getlfname(target, buf);
msg("%s writhe%s in agony!", buf, isplayer(target) ? "" : "s"); msg("^%c%s writhe%s in agony!", getlfcol(target, CC_BAD), buf, isplayer(target) ? "" : "s");
} }
} else if (target->hp < target->maxhp) { } else if (target->hp < target->maxhp) {
if (!undead && lfhasflagval(target, F_POISONED, P_ROT, NA, NA, NULL)) { if (!undead && lfhasflagval(target, F_POISONED, P_ROT, NA, NA, NULL)) {
@ -7363,34 +7369,34 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (target->hp >= target->maxhp) { if (target->hp >= target->maxhp) {
switch (spellid) { switch (spellid) {
case OT_S_HEALINGMIN: case OT_S_HEALINGMIN:
msg("All of your scrapes and bruises are healed!"); msg("^%cAll of your scrapes and bruises are healed!", getlfcol(target, CC_GOOD));
break; break;
case OT_S_HEALING: case OT_S_HEALING:
default: default:
msg("Your wounds close themselves!"); msg("^%cYour wounds close themselves!", getlfcol(target, CC_GOOD));
break; break;
case OT_S_HEALINGMAJ: case OT_S_HEALINGMAJ:
msg("Your injuries are healed!"); msg("^%cYour injuries are healed!", getlfcol(target, CC_GOOD));
break; break;
} }
} else { } else {
switch (spellid) { switch (spellid) {
case OT_S_HEALINGMIN: case OT_S_HEALINGMIN:
msg("Some of your scrapes and bruises are healed!"); msg("^%cSome of your scrapes and bruises are healed!", getlfcol(target, CC_GOOD));
break; break;
case OT_S_HEALING: case OT_S_HEALING:
default: default:
msg("Some of your wounds close themselves!"); msg("^%cSome of your wounds close themselves!", getlfcol(target, CC_GOOD));
break; break;
case OT_S_HEALINGMAJ: case OT_S_HEALINGMAJ:
msg("Your injuries are partially healed!"); msg("^%cYour injuries are partially healed!", getlfcol(target, CC_GOOD));
break; break;
} }
} }
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (haslos(player, target->cell)) { } else if (haslos(player, target->cell)) {
getlfname(target, buf); getlfname(target, buf);
msg("%s looks healthier!", buf); msg("^%c%s looks healthier!", getlfcol(target, CC_GOOD), buf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
donesomething = B_TRUE; donesomething = B_TRUE;
@ -7425,11 +7431,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (ismetal(target->race->material->id)) { if (ismetal(target->race->material->id)) {
if (!isimmuneto(target->flags, DT_HEAT, B_FALSE)) { if (!isimmuneto(target->flags, DT_HEAT, B_FALSE)) {
if (isplayer(target)) { if (isplayer(target)) {
msg("Your suffer massive burns!"); msg("^%cYou suffer massive burns!", getlfcol(target, CC_BAD) );
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
msg("%s glows red hot!", lfname); msg("^%c%s glows red hot!", getlfcol(target, CC_BAD), lfname);
} }
losehp(target, roll("6d4"), DT_HEAT, caster, "massive burns"); losehp(target, roll("6d4"), DT_HEAT, caster, "massive burns");
donesomething = B_TRUE; donesomething = B_TRUE;
@ -7552,12 +7558,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (isplayer(target)) { if (isplayer(target)) {
msg("A sudden hunger comes over you!"); msg("^%cA sudden hunger comes over you!", getlfcol(target, CC_BAD));
if (seenbyplayer) *seenbyplayer = B_TRUE; 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("%s looks more hungry.", lfname); msg("^%c%s looks ravenous!", getlfcol(target, CC_BAD), lfname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7594,12 +7600,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getobname(wep, obname, wep->amt); getobname(wep, obname, wep->amt);
if (isplayer(target)) { if (isplayer(target)) {
msg("Your %s is covered with ice!", noprefix(obname)); msg("^%cYour %s is covered with ice!", getlfcol(target, CC_GOOD), noprefix(obname));
if (seenbyplayer) *seenbyplayer = B_TRUE; 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("%s%s %s is covered with ice!", lfname, getpossessive(lfname), noprefix(obname)); msg("^%c%s%s %s is covered with ice!", getlfcol(target, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
@ -7625,11 +7631,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
knockback(targcell->lf, getdirtowards(targcell, c, NULL, B_FALSE, DT_COMPASS), 1, NULL, 25+power, B_TRUE); knockback(targcell->lf, getdirtowards(targcell, c, NULL, B_FALSE, DT_COMPASS), 1, NULL, 25+power, B_TRUE);
} else { } else {
if (isplayer(targcell->lf)) { if (isplayer(targcell->lf)) {
msg("You are impaled by an icicle!"); msg("^%cYou are impaled by an icicle!", getlfcol(targcell->lf, CC_BAD) );
} else if (cansee(player, targcell->lf)) { } else if (cansee(player, targcell->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
msg("%s is impaled by an icicle!", lfname); msg("^%c%s is impaled by an icicle!", getlfcol(targcell->lf, CC_BAD), lfname);
} }
losehp(targcell->lf, rolldie(3,power), DT_PIERCE, caster, "impalement on an icicle"); losehp(targcell->lf, rolldie(3,power), DT_PIERCE, caster, "impalement on an icicle");
} }
@ -7714,7 +7720,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
0, B_FALSE, B_FALSE, B_FALSE, B_TRUE, buf); 0, B_FALSE, B_FALSE, B_FALSE, B_TRUE, buf);
msg("%s", buf); msg("%s", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("%s is engulfed in roaring flames!", targname); msg("^%c%s is engulfed in roaring flames!", getlfcol(target, CC_BAD), targname);
addobfast(target->cell->obpile, OT_FIREMED); addobfast(target->cell->obpile, OT_FIREMED);
} }
} else { } else {
@ -7734,7 +7740,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A wave of incalculable evil blasts outwards from %s!", buf); msg("A wave of incalculable evil blasts outwards from %s!", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (player->cell->map == caster->cell->map) { // should always be true } else if (player->cell->map == caster->cell->map) { // should always be true
msg("Oh no! A wave of incalculable evil washes over you!"); msg("^%cOh no! A wave of incalculable evil washes over you!", getlfcol(player, CC_VBAD));
} }
for (l = caster->cell->map->lf ; l ; l = l->next) { for (l = caster->cell->map->lf ; l ; l = l->next) {
if (l != caster) { if (l != caster) {
@ -7793,9 +7799,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// always hit // always hit
if (cansee(player, target)) { if (cansee(player, target)) {
if (power == 1) { if (power == 1) {
msg("A spike of mana hits %s.",lfname); msg("^%cA spike of mana hits %s.",getlfcol(target, CC_BAD), lfname);
} else { } else {
msg("%s spikes of mana hit %s.",numbuf, lfname); msg("^%c%s spikes of mana hit %s.",getlfcol(target, CC_BAD), numbuf, lfname);
} }
} }
losehp(target, rolldie(power,4), DT_MAGIC, caster, "a mana spike"); losehp(target, rolldie(power,4), DT_MAGIC, caster, "a mana spike");
@ -7874,10 +7880,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// works on all metal in sight // works on all metal in sight
if (isplayer(caster)) { if (isplayer(caster)) {
if (seenbyplayer) *seenbyplayer = B_FALSE; if (seenbyplayer) *seenbyplayer = B_FALSE;
msg("You draw health from nearby metal!"); msg("^%cYou draw health from nearby metal!", getlfcol(caster, CC_GOOD));
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
if (seenbyplayer) *seenbyplayer = B_FALSE; if (seenbyplayer) *seenbyplayer = B_FALSE;
msg("%s draws health from nearby metal!",castername); msg("^%c%s draws health from nearby metal!", getlfcol(caster, CC_GOOD),castername);
} }
totalmass = 0; totalmass = 0;
@ -8767,7 +8773,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
// hit // hit
if (cansee(player, target)) { if (cansee(player, target)) {
msg("A glob of venom hits %s.",lfname); msg("^%cA glob of venom hits %s.",getlfcol(target, CC_BAD), lfname);
} }
if (!isimmuneto(target->flags, DT_POISON, B_FALSE)) { if (!isimmuneto(target->flags, DT_POISON, B_FALSE)) {
poison(target, power*3, P_VENOM, (power/4)+1, "a glob of venom", caster ? caster->race->id : R_NONE); poison(target, power*3, P_VENOM, (power/4)+1, "a glob of venom", caster ? caster->race->id : R_NONE);
@ -8909,9 +8915,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
losehp(target, dam, DT_DIRECT, caster, "a psionic blast"); losehp(target, dam, DT_DIRECT, caster, "a psionic blast");
getlfname(target, targetname); getlfname(target, targetname);
if (isplayer(target)) { if (isplayer(target)) {
msg("Your brain is blasted!"); msg("^%cYour brain is blasted!",getlfcol(target, CC_BAD) );
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("%s%s brain is blasted!",targetname, getpossessive(targetname)); msg("^%c%s%s brain is blasted!",getlfcol(target, CC_BAD), targetname, getpossessive(targetname));
} }
} else if (spellid == OT_S_PSYARMOUR) { } else if (spellid == OT_S_PSYARMOUR) {
flag_t *f; flag_t *f;
@ -9127,9 +9133,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (isplayer(target)) { if (isplayer(target)) {
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
if (haslos(player, newcell)) { if (haslos(player, newcell)) {
msg("Your %s suddenly appears next to you!", noprefix(obname)); msg("^%cYour %s suddenly appears next to you!", getlfcol(target, CC_BAD), noprefix(obname));
} else { } else {
msg("Your %s suddenly vanishes!", noprefix(obname)); msg("^%cYour %s suddenly vanishes!", getlfcol(target, CC_BAD), noprefix(obname));
announcethump = B_TRUE; announcethump = B_TRUE;
} }
@ -9138,10 +9144,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(target, lfname); getlfname(target, lfname);
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
if (haslos(player, newcell)) { if (haslos(player, newcell)) {
msg("%s%s %s suddenly appears next to it!", lfname, getpossessive(lfname), msg("^%c%s%s %s suddenly appears next to it!", getlfcol(target, CC_BAD), lfname, getpossessive(lfname),
noprefix(obname)); noprefix(obname));
} else { } else {
msg("%s%s %s suddenly vanishes!", lfname, getpossessive(lfname), msg("^%c%s%s %s suddenly vanishes!", getlfcol(target, CC_BAD), lfname, getpossessive(lfname),
noprefix(obname)); noprefix(obname));
} }
} }
@ -9197,11 +9203,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int dam; int dam;
// hit // hit
if (isplayer(target)) { if (isplayer(target)) {
msg("A pulse of electricity shocks you!"); msg("^%cA pulse of electricity shocks you!",getlfcol(target, CC_BAD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
msg("A pulse of electricity shocks %s!",lfname); msg("^%cA pulse of electricity shocks %s!",getlfcol(target, CC_BAD),lfname);
} }
dam = power*2; dam = power*2;
losehp(target, dam, DT_ELECTRIC, caster, "a jolt of electricity"); losehp(target, dam, DT_ELECTRIC, caster, "a jolt of electricity");
@ -9364,7 +9370,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// the bolt firing, announce it hitting people (since we've already said // the bolt firing, announce it hitting people (since we've already said
// "the javelin turns into lightning"). // "the javelin turns into lightning").
if (!fromob) { if (!fromob) {
msg("%s shoot%s a bolt of electricity!",castername, isplayer(caster) ? "" : "s"); msg("%s shoot%s a bolt of lightning!",castername, isplayer(caster) ? "" : "s");
} }
} }
@ -9379,14 +9385,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (power > 1) { if (power > 1) {
dam += power; // maxpower is 1, but blue dragons can exceed this dam += power; // maxpower is 1, but blue dragons can exceed this
} }
losehp(c->lf, dam, DT_ELECTRIC, caster, "an electricity bolt"); losehp(c->lf, dam, DT_ELECTRIC, caster, "a lightning bolt");
nhits--; nhits--;
} }
if (haslos(player, c)) { if (haslos(player, c)) {
if (fromob) { if (fromob) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("The bolt of lightning strikes %s!", lfname); msg("^%cThe bolt of lightning strikes %s!", getlfcol(c->lf, CC_BAD), lfname);
} }
needredraw = B_TRUE; needredraw = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
@ -9438,7 +9444,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (i = 0; i < ntarg; i++) { for (i = 0; i < ntarg; i++) {
if (cansee(player, targ[i])) { if (cansee(player, targ[i])) {
getlfname(targ[i],targname); getlfname(targ[i],targname);
msg("%s %s struck by a bolt of lightning!",targname, is(targ[i])); msg("^%c%s %s struck by a bolt of lightning!",getlfcol(targ[i], CC_BAD),
targname, is(targ[i]));
} }
if (caster && (targ[i]->cell->map->habitat->id == H_FOREST)) { if (caster && (targ[i]->cell->map->habitat->id == H_FOREST)) {
losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning");
@ -9737,9 +9744,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell->lf) { if (targcell->lf) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
msg("A thick veil of mist surrounds %s!", lfname); msg("^%cA thick veil of mist surrounds %s!", getlfcol(targcell->lf, CC_GOOD), lfname);
} else { } else {
msg("A thick veil of mist appears!"); msg("^%cA thick veil of mist appears!", getlfcol(targcell->lf, CC_GOOD));
} }
} }
o = addob(targcell->obpile, "thick mist"); o = addob(targcell->obpile, "thick mist");
@ -10391,7 +10398,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// cut power in half // cut power in half
f->val[1] /= 2; if (f->val[1] < 1) f->val[1] = 1; f->val[1] /= 2; if (f->val[1] < 1) f->val[1] = 1;
if (isplayer(target)) { if (isplayer(target)) {
msg("Your %s seems less intense.",pt->name); msg("^%cYour %s seems less intense.",getlfcol(target, CC_GOOD),pt->name);
} }
ndone++; ndone++;
} }
@ -10417,11 +10424,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
amttolose = power*2; amttolose = power*2;
if (isplayer(target)) { if (isplayer(target)) {
msg("You suddenly feel very lethargic!"); msg("^%cYou suddenly feel very lethargic!", getlfcol(target, CC_BAD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char targname[BUFLEN]; char targname[BUFLEN];
getlfname(target, targname); getlfname(target, targname);
msg("%s looks very lethargic!", targname); msg("%s looks very lethargic!", getlfcol(target, CC_BAD), targname);
} }
modstamina(target, -amttolose); modstamina(target, -amttolose);
} else if (spellid == OT_S_REFRACTION) { } else if (spellid == OT_S_REFRACTION) {
@ -10429,9 +10436,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(caster->flags, F_EVASION, 15+(power*5), NA, NA, NULL, FROMSPELL); f = addtempflag(caster->flags, F_EVASION, 15+(power*5), NA, NA, NULL, FROMSPELL);
f->obfrom = spellid; f->obfrom = spellid;
if (isplayer(caster)) { if (isplayer(caster)) {
msg("Your body seems to shimmer and bend!"); msg("^%cYour body seems to shimmer and bend!", getlfcol(caster, CC_GOOD));
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
msg("%s%s body seems to shimmer and bend!", castername, getpossessive(castername)); msg("^%c%s%s body seems to shimmer and bend!", getlfcol(caster, CC_GOOD),
castername, getpossessive(castername));
} }
} else if (spellid == OT_S_REPELINSECTS) { } else if (spellid == OT_S_REPELINSECTS) {
// just announce // just announce
@ -10545,7 +10553,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (isundead(target)) { if (isundead(target)) {
if (seen) { if (seen) {
msg("%s writhe%s in agony!", lfname, isplayer(target) ? "" : "s"); msg("^%c%s writhe%s in agony!",getlfcol(target, CC_BAD), lfname, isplayer(target) ? "" : "s");
} }
losehp(target, power*10, DT_HOLY, caster, "the power of restoration"); losehp(target, power*10, DT_HOLY, caster, "the power of restoration");
return B_FALSE; return B_FALSE;
@ -10589,7 +10597,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
gainhp(target, hpheal - target->hp); gainhp(target, hpheal - target->hp);
failed = B_FALSE; failed = B_FALSE;
if (!isplayer(target) && cansee(player, target)) { if (!isplayer(target) && cansee(player, target)) {
msg("%s%s health has been restored!", lfname, getpossessive(lfname)); msg("^%c%s%s health has been restored!", getlfcol(target, CC_GOOD),lfname, getpossessive(lfname));
} }
} }
if (target->mp < mpheal) { if (target->mp < mpheal) {
@ -10831,10 +10839,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// 2nd one failed - lose all stamina instead // 2nd one failed - lose all stamina instead
modstamina(target, -(getstamina(target))); modstamina(target, -(getstamina(target)));
if (isplayer(target)) { if (isplayer(target)) {
msg("You suddenly feel very lethargic!"); msg("^%cYou suddenly feel very lethargic!",getlfcol(target, CC_BAD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
getlfname(target, buf); getlfname(target, buf);
msg("%s looks very lethargic!", buf); msg("^%c%s looks very lethargic!", getlfcol(target, CC_BAD),buf);
} }
} }
return B_FALSE; return B_FALSE;
@ -10922,11 +10930,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
if (isplayer(target)) { if (isplayer(target)) {
msg("The power of %s smites you!", (spellid == OT_S_SMITEEVIL) ? "good" : "evil"); msg("^%cThe power of %s smites you!",getlfcol(target, CC_BAD),
(spellid == OT_S_SMITEEVIL) ? "good" : "evil");
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
msg("The power of %s smites %s!", (spellid == OT_S_SMITEEVIL) ? "good" : "evil", lfname); msg("^%cThe power of %s smites %s!", getlfcol(target, CC_BAD),
(spellid == OT_S_SMITEEVIL) ? "good" : "evil", lfname);
} }
// use direct damage rather than holy, because otherwise it might be increased // use direct damage rather than holy, because otherwise it might be increased
// due to vulnerabilities // due to vulnerabilities
@ -11057,7 +11067,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell->lf && cansee(player, targcell->lf)) { if (targcell->lf && cansee(player, targcell->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
msg("A small burst of flame singes %s.", lfname); msg("^%cA small burst of flame singes %s.", getlfcol(targcell->lf, CC_BAD),lfname);
} else { } else {
msg("A small burst of flame appears."); msg("A small burst of flame appears.");
} }
@ -12038,16 +12048,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
// announce // announce
if (isplayer(target)) { if (isplayer(target)) {
msg("A blade of pure energy forms in your hands!"); msg("^%cA blade of pure energy forms in your hands!", getlfcol(target, CC_GOOD));
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("A blade of pure energy forms in %s%s hands!",castername, msg("^%cA blade of pure energy forms in %s%s hands!", getlfcol(target, CC_GOOD),castername,
getpossessive(castername)); getpossessive(castername));
} }
weild(target, o); weild(target, o);
// set its damage value // set its damage value
f = hasflag(o->flags, F_DAM); f = hasflag(o->flags, F_DAM);
if (f) { if (f) {
f->val[1] = 2+power; f->val[1] = 3+power;
} }
addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL); addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL);
} else { } else {
@ -12475,11 +12485,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
addob(c->obpile, "web"); addob(c->obpile, "web");
if (isplayer(c->lf)) { if (isplayer(c->lf)) {
msg("You are stuck in a web!"); msg("^%cYou are stuck in a web!", getlfcol(c->lf, CC_BAD));
} else if (cansee(player, c->lf)) { } else if (cansee(player, c->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("%s is stuck in a web!", lfname); msg("^%c%s is stuck in a web!", getlfcol(c->lf, CC_BAD), lfname);
} }
} }
} }
@ -12732,7 +12742,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (isplayer(target)) { if (isplayer(target)) {
p = assignnpcname(lf->flags); p = assignnpcname(lf->flags);
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p, lf);
} }
strcpy(buf, ""); strcpy(buf, "");
@ -13941,7 +13951,7 @@ int schoolappearsinbooks(enum SPELLSCHOOL ss) {
return B_TRUE; return B_TRUE;
} }
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob) { void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob, int includecentre) {
int x,y; int x,y;
char *see = NULL, *nosee = NULL; char *see = NULL, *nosee = NULL;
objecttype_t *ot; objecttype_t *ot;
@ -13980,9 +13990,12 @@ void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE
for (x = srcloc->x - radius ; x <= srcloc->x + radius; x++) { for (x = srcloc->x - radius ; x <= srcloc->x + radius; x++) {
cell_t *c; cell_t *c;
c = getcellat(srcloc->map, x, y); c = getcellat(srcloc->map, x, y);
if (c && c->lf && (c != srcloc) && !c->type->solid && if (c && c->lf && !c->type->solid &&
haslof(srcloc, c, LOF_WALLSTOP, NULL)) { haslof(srcloc, c, LOF_WALLSTOP, NULL)) {
int safe = B_FALSE; int safe = B_FALSE;
if (!includecentre && (c == srcloc)) {
safe = B_TRUE;
}
if (aimedateyes && (!hasbp(c->lf, BP_EYES) || getarmour(c->lf, BP_EYES))) { if (aimedateyes && (!hasbp(c->lf, BP_EYES) || getarmour(c->lf, BP_EYES))) {
safe = B_TRUE; safe = B_TRUE;
} }

View File

@ -36,7 +36,7 @@ int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repair
object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat); object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat);
void pullobto(object_t *o, lifeform_t *lf); void pullobto(object_t *o, lifeform_t *lf);
int schoolappearsinbooks(enum SPELLSCHOOL ss); int schoolappearsinbooks(enum SPELLSCHOOL ss);
void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob); void spellcloud(cell_t *srcloc, int radius, int ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot, char *seetext, char *noseetext, int aimedateyes, object_t *fromob, int includecentre);
int spellisfromschool(int spellid, enum SPELLSCHOOL school); int spellisfromschool(int spellid, enum SPELLSCHOOL school);
int spellokformonsters(int spellid); int spellokformonsters(int spellid);
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce); int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce);

14
text.c
View File

@ -2428,6 +2428,20 @@ int strpixmatch(char *haystack, char *needle) {
return matched; return matched;
} }
enum VAULTTHING strtovt(char *text) {
enum VAULTTHING tt;
if (streq(text, "ob")) {
tt = VT_OB;
} else if (streq(text, "mon")) {
tt = VT_LF;
} else if (streq(text, "cell")) {
tt = VT_CELL;
} else {
tt = VT_NONE;
}
return tt;
}
int texttodice(char *text, int *ndice, int *nsides, int *bonus) { int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
char *dummy; char *dummy;
char *localtext; char *localtext;

1
text.h
View File

@ -73,6 +73,7 @@ char *strstarts(char *a, char *prefix);
char *strstartswitha(char *text, char *retprefix); char *strstartswitha(char *text, char *retprefix);
int strlen_without_colours(char *buf); int strlen_without_colours(char *buf);
int strpixmatch(char *haystack, char *needle); int strpixmatch(char *haystack, char *needle);
enum VAULTTHING strtovt(char *text);
int texttodice(char *text, int *ndice, int *nsides, int *bonus); int texttodice(char *text, int *ndice, int *nsides, int *bonus);
int texttospellopts(char *text, ... ); int texttospellopts(char *text, ... );
//void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range, char *racestr); //void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range, char *racestr);

105
vault.c
View File

@ -22,7 +22,7 @@ extern lifeform_t *player;
extern enum GAMEMODE gamemode; extern enum GAMEMODE gamemode;
vlegend_t *addlegend(vault_t *v, int ch, enum VAULTTHING tt, int pct, char *what) { vlegend_t *addlegend(vault_t *v, int ch, enum VAULTTHING tt, int pct, char *what, enum VAULTTHING tt2, char *what2) {
vlegend_t *l; vlegend_t *l;
// add to the end of the list // add to the end of the list
@ -46,6 +46,13 @@ vlegend_t *addlegend(vault_t *v, int ch, enum VAULTTHING tt, int pct, char *what
l->tt = tt; l->tt = tt;
l->pct = pct; l->pct = pct;
l->what = strdup(what); l->what = strdup(what);
// alternatives...
l->tt2 = tt2;
if (what2) {
l->what2 = strdup(what2);
} else {
l->what2 = strdup("");
}
return l; return l;
} }
@ -102,12 +109,15 @@ void addvaultcellcontents(cell_t *c, vault_t *v, int x, int y, int rotation) {
if (l->ch == ch) { if (l->ch == ch) {
if (rnd(1,100) <= l->pct) { if (rnd(1,100) <= l->pct) {
addvaultthing(c, v, l->tt, l->what); addvaultthing(c, v, l->tt, l->what);
} else if (l->tt2 != VT_NONE) {
addvaultthing(c, v, l->tt2, l->what2);
} }
} }
} }
} }
// add vault contents based on flags
void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int maxy, int rotation) { void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int maxy, int rotation) {
flag_t *f; flag_t *f;
char buf[BUFLEN]; char buf[BUFLEN];
@ -917,39 +927,51 @@ int handleline(vault_t *v, char *line) {
// legend definition // legend definition
if (nargs >= 2) { if (nargs >= 2) {
int pct; int pct;
enum VAULTTHING tt; enum VAULTTHING tt,tt2;
char what[BUFLEN]; char what[BUFLEN],what2[BUFLEN];
if (streq(arg[0], "ob")) {
tt = VT_OB; // default is no alternative
} else if (streq(arg[0], "mon")) { tt2 = VT_NONE;
tt = VT_LF; strcpy(what2, "");
} else if (streq(arg[0], "cell")) {
tt = VT_CELL; // get ob specification
} else { tt = strtovt(arg[0]);
tt = VT_NONE;
}
strcpy(what, arg[1]); strcpy(what, arg[1]);
if (nargs >= 3) { // ie have a percentage
if (nargs == 3) { // ie have a percentage
pct = atoi(arg[2]); pct = atoi(arg[2]);
} else { } else {
pct = 100; pct = 100;
} }
if (tt == VT_NONE) { if (nargs == 5) { // have alternative value if percentage fails
tt2 = strtovt(arg[3]);
strcpy(what2, arg[4]);
}
if (nargs == 4) {
dblog("alternative obtype given but no alternative ob text");
} else if (tt == VT_NONE) {
dblog("invalid type in legend definition"); dblog("invalid type in legend definition");
} else if (vaultthingok(tt, what)) {
// validated ok.
addlegend(v, command[0], tt, pct, what);
ok = B_TRUE;
} else { } else {
dblog("invalid legend definition: '%s'", line); int error = B_FALSE;
if (!vaultthingok(tt, what)) {
dblog("invalid legend definition: '%s'", line);
error = B_TRUE;
}
if ((tt2 != VT_NONE) && !vaultthingok(tt2,what2)) {
dblog("invalid legend alternative definition: '%s'", line);
error = B_TRUE;
}
if (!error) {
// validated ok.
addlegend(v, command[0], tt, pct, what, tt2, what2);
ok = B_TRUE;
}
} }
} else { // special legend... } else { // special legend...
if (streq(arg[0], "exit")) { if (streq(arg[0], "exit")) {
addlegend(v, command[0], VT_EXIT, 100, ""); addlegend(v, command[0], VT_EXIT, 100, "", VT_NONE, NULL);
ok = B_TRUE; ok = B_TRUE;
} else { } else {
dblog("invalid syntax for legend value"); dblog("invalid syntax for legend value");
@ -1283,6 +1305,44 @@ int handleline(vault_t *v, char *line) {
} else if (streq(line, "autopop")) { } else if (streq(line, "autopop")) {
addflag(v->flags, F_AUTOPOPULATE, B_TRUE, NA, NA, NULL); addflag(v->flags, F_AUTOPOPULATE, B_TRUE, NA, NA, NULL);
ok = B_TRUE; ok = B_TRUE;
} else if (strstarts(line, "cellempty")) {
char *p;
p = line + strlen("cellempty");
if (*p == ':') {
char buf[BUFLEN];
celltype_t *ct;
p++;
p = readuntil(buf, p, ','); // eol
// validate celltype name
ct = findcelltypebyname(buf);
if (ct) {
addflag(v->flags, F_CELLTYPEEMPTY, ct->id, NA, NA, NULL);
ok = B_TRUE;
} else {
dblog("invalid celltype specified in cellempty definition: '%s'", line);
}
} else {
dblog("syntax error in cellempty definition: '%s'", line);
}
} else if (strstarts(line, "cellsolid")) {
char *p;
p = line + strlen("cellsolid");
if (*p == ':') {
char buf[BUFLEN];
celltype_t *ct;
p++;
p = readuntil(buf, p, ','); // eol
// validate celltype name
ct = findcelltypebyname(buf);
if (ct) {
addflag(v->flags, F_CELLTYPESOLID, ct->id, NA, NA, NULL);
ok = B_TRUE;
} else {
dblog("invalid celltype specified in cellsolid definition: '%s'", line);
}
} else {
dblog("syntax error in cellsolid definition: '%s'", line);
}
} else if (strstarts(line, "dlevmax")) { } else if (strstarts(line, "dlevmax")) {
// dlevmax:max // dlevmax:max
char *p; char *p;
@ -1483,6 +1543,7 @@ int handleline(vault_t *v, char *line) {
void killlegend(vlegend_t *l) { void killlegend(vlegend_t *l) {
vlegend_t *nextone,*lastone; vlegend_t *nextone,*lastone;
if (l->what) free(l->what); if (l->what) free(l->what);
if (l->what2) free(l->what2);
// deallocate // deallocate
nextone = l->next; nextone = l->next;

View File

@ -1,6 +1,6 @@
#include "defs.h" #include "defs.h"
vlegend_t *addlegend(vault_t *v, int ch, enum VAULTTHING tt, int pct, char *what); vlegend_t *addlegend(vault_t *v, int ch, enum VAULTTHING tt, int pct, char *what, enum VAULTTHING tt2, char *what2);
vault_t *addvault(void); vault_t *addvault(void);
void addvaultcellcontents(cell_t *c, vault_t *v, int x, int y, int rotation); void addvaultcellcontents(cell_t *c, vault_t *v, int x, int y, int rotation);
void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int maxy, int rotationmapnum); void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int maxy, int rotationmapnum);