- [+] tech is now uncommon, not rare.

- [+] bug: crash when linking to map entry objects
- [+] removed some material-based damage immunities
- [+] at night you shouldn't hear "a cash register chiming".
- [+] increase hp of chests
- [+] filling empty flask from potion of fshy lungs resulted in potion
      of water!
- [+] don't take migraine damage from light if your'e blind.
This commit is contained in:
Rob Pearce 2012-12-31 05:10:13 +00:00
parent a42ca5bb37
commit d89e93f64e
11 changed files with 123 additions and 24 deletions

49
ai.c
View File

@ -153,6 +153,29 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
return B_FALSE;
}
void ailoscheck(lifeform_t *lf) {
int i,ok = B_TRUE;
cell_t *c;
for (i = 0; i < lf->nlos; i++) {
c = lf->los[i];
if (c->known != B_TRUE) {
if ((c->known < PR_INEPT) || (c->known > PR_MASTER)) {
ok = B_FALSE; break;
}
}
if ((c->visited != B_FALSE) && (c->visited != B_TRUE)) {
ok = B_FALSE; break;
}
if (c->lf && (c->lf->id == 65432)) { // ie. will crash if c->lf is invalid
ok = B_FALSE; break;
}
}
if (!ok) {
msg("FATAL: corrupt los[] array for %s",lf->race->id);
assert("Corrupt los array" == 0);
}
}
// A* algorithm. Returns F_AIPATH flag.
flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
char *pathbuf;
@ -821,7 +844,8 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
// cell in sight and adjacent? aispellok() should have already confirmed
// that there will be at least one of these.
for (i = 1; i < lf->nlos; i++) {
if (!lf->los[i]->lf && lf->los[i]->type->solid && (getcelldist(lf->cell, lf->los[i]) == 1)) {
// using getcelldirorth to make sure direction is orthogonal
if (!lf->los[i]->lf && lf->los[i]->type->solid && (getcelldistorth(lf->cell, lf->los[i]) == 1)) {
poss[nposs++] = lf->los[i];
}
}
@ -2542,51 +2566,69 @@ void aiturn(lifeform_t *lf) {
master = findlf(lf->cell->map, f->val[0]);
}
ailoscheck(lf);
///////////////////////////////////////////////
// emergencies / fixing up
///////////////////////////////////////////////
if (ai_handle_emergencies(lf, iqb)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// housekeeping - weapon changes, drop/pickup,
// use items, talk,etc
///////////////////////////////////////////////
if (ai_housekeeping(lf, master)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// healing
///////////////////////////////////////////////
if (ai_healing(lf)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// inventory management
///////////////////////////////////////////////
if (ai_inventory_mgt(lf, &icanattack)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// attacking existing targets
///////////////////////////////////////////////
if (ai_attack_existing_target(lf)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// generic pre-movement actions.
///////////////////////////////////////////////
if (ai_premovement(lf)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// movement
///////////////////////////////////////////////
if (ai_movement(lf)) return;
ailoscheck(lf);
///////////////////////////////////////////////
// look for something to do (objects, things
// to attack, etc)
///////////////////////////////////////////////
if (ai_bored(lf, master, icanattack)) return;
ailoscheck(lf);
// DEFAULT - try to move in a random direction
if (db) dblog(".oO { default - moving randomly }");
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
ailoscheck(lf);
// somehow still here?
if (!lf->timespent) {
@ -3199,6 +3241,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE;
}
}
if (ot->id == OT_S_SUCK) {
if (getcelldist(lf->cell, victim->cell) <= 1) {
specificcheckok = B_FALSE;
}
}
if (ot->id == OT_S_SUMMONWEAPON) {
if (getweapon(lf)) {
specificcheckok = B_FALSE;

3
ai.h
View File

@ -2,8 +2,7 @@
void addignorecell(lifeform_t *lf, cell_t *c);
int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
int calcheuristic(cell_t *c, cell_t *end);
int calcg(lifeform_t *lf, cell_t *thiscell, node_t *parent, int dirfromparent);
void ailoscheck(lifeform_t *lf);
flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell);
cell_t *ai_getnextcellinpath(lifeform_t *lf);
int ai_popnextcellinpath(lifeform_t *lf);

9
data.c
View File

@ -1959,7 +1959,6 @@ void initobjects(void) {
addmaterial(MT_FIRE, "fire", 0);
addmaterial(MT_GAS, "gas", 0.5);
addmaterial(MT_WIRE, "wire", 1);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_PROJECTILE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_HOLY, NA, NA, NULL);
@ -2036,7 +2035,6 @@ void initobjects(void) {
addmaterial(MT_SLIME, "slime", 9);
addmaterial(MT_STONE, "stone", 10);
addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_SILVER, "silver", 11);
@ -2051,7 +2049,6 @@ void initobjects(void) {
addflag(lastmaterial->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
addmaterial(MT_BRICK, "brick", 14);
addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_GOLD, "gold", 16);
@ -2168,7 +2165,7 @@ void initobjects(void) {
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL); // will be overridden when making a corpse
addflag(lastobjectclass->flags, F_DECAY, 0, NA, 1, NULL); // decay increases by 1 each turn.
//addflag(lastobjectclass->flags, F_OBHPDRAIN, 1, DT_DECAY, NA, NULL); // ie. corpses last for 50 turns
addoc(OC_TECH, "Technology", "A strange piece of futuristic equipment. Perhaps someone with more skill in Technology could recognise it...", '[', C_GREY, RR_RARE);
addoc(OC_TECH, "Technology", "A strange piece of futuristic equipment. Perhaps someone with more skill in Technology could recognise it...", '[', C_GREY, RR_UNCOMMON);
addocnoun(lastobjectclass, "technology");
addocnoun(lastobjectclass, "tech");
addflag(lastobjectclass->flags, F_RARITY, H_SEWER, NA, RR_COMMON, NULL);
@ -7021,7 +7018,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_YELLOW, '(', NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL);
addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
@ -7038,7 +7035,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_LIGHTYELLOW, '(', NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
addflag(lastot->flags, F_OBHP, 100, 100, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKABLE, B_TRUE, NA, NA, NULL);

Binary file not shown.

1
defs.h
View File

@ -4548,6 +4548,7 @@ enum ERROR {
E_LFINWAY,
E_NOSPACE,
E_BADCLIMBDIR,
E_BADCLIMBDIR2,
E_STOPCLIMBING,
E_SELNOTHING,
E_ALREADYUSING,

15
lf.c
View File

@ -866,6 +866,10 @@ int cancook(lifeform_t *lf, recipe_t *rec, enum ERROR *reason) {
int canclimb(lifeform_t *lf, enum ERROR *reason) {
cell_t *cc;
if (!isorthogonal(lf->facing)) {
if (reason) *reason = E_BADCLIMBDIR2;
return B_FALSE;
}
cc = getcellindir(lf->cell, lf->facing);
if (isclimbing(lf)) {
if (reason) *reason = E_CLIMBING;
@ -1956,6 +1960,13 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
casttype = getcasttype(lf, sid);
}
// override 'fromob' based on conferred flags
if (willflag && (willflag->obfrom != NA)) {
fromob = findobbyid(lf->pack, willflag->obfrom);
} else if (castflag && (castflag->obfrom != NA)) {
fromob = findobbyid(lf->pack, castflag->obfrom);
}
sp = findot(sid);
if (!fromob) {
@ -23912,7 +23923,7 @@ void startlfturn(lifeform_t *lf) {
}
} else if (f->val[0] == P_MIGRAINE) {
// sleeping will avoid all migraine effects
if (!asleep && !ko) {
if (!asleep && !ko && !isblind(lf)) {
object_t *lamp = NULL;
int amt;
amt = lfproduceslight(lf, &lamp);
@ -24122,7 +24133,7 @@ void startlfturn(lifeform_t *lf) {
}
amt = obproduceslight(o);
if (amt) {
if (amt && !isblind(lf)) {
if (lighthurtseyes(lf)) {
int min=2,max;
if (isplayer(lf)) {

1
map.c
View File

@ -7510,7 +7510,6 @@ int finalisemap(map_t *map, object_t *entryob, int exitdir) {
c = getcell_cond(map, &okforstairs);
}
if (c) {
o = addobfast(c->obpile, entryoppositetype->id);
// DONT let addobject create maplinks, because we want to force it to
// link to entry object.
o = addobject(c->obpile, entryoppositetype->name, B_FALSE, B_FALSE, entryoppositetype->id);

View File

@ -1701,8 +1701,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// fountain flags
if (o && (o->type->id == OT_FOUNTAIN)) {
f = hasflag(o->flags, F_LINKOB);
if (wantfountaintype != OT_NONE) {
f = hasflag(o->flags, F_LINKOB); assert(f);
f->val[0] = wantfountaintype;
f = hasflag(o->flags, F_FILLPOT); assert(f);
f->val[0] = wantfountaintype;
} else if (where->where && (where->where->habitat->id != H_VILLAGE)) {
if (onein(3)) {
@ -1712,9 +1714,15 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE);
ot = getrandomobofclass(OC_POTION, min, max, NULL, NULL);
if (ot) {
f = hasflag(o->flags, F_LINKOB); assert(f);
f->val[0] = ot->id;
f = hasflag(o->flags, F_FILLPOT); assert(f);
f->val[0] = ot->id;
}
} else {
f = hasflag(o->flags, F_LINKOB); assert(f);
f->val[0] = OT_POT_WATER;
f = hasflag(o->flags, F_FILLPOT); assert(f);
f->val[0] = OT_POT_WATER;
}
}
@ -10220,7 +10228,11 @@ int obsfallthrough(cell_t *c, object_t *pit) {
if (belowcell) {
char oid[BUFLENSMALL];
sprintf(oid, "%ld",pit->id);
uphole = findmapobwithflagval(belowcell->map, F_MAPLINK, NA, NA, NA, oid);
//uphole = findmapobwithflagval(belowcell->map, F_MAPLINK, NA, NA, NA, oid);
uphole = hasobwithflagval(belowcell->obpile, F_MAPLINK, NA, NA, NA, oid);
if (!uphole) {
uphole = hasobwithflagval(belowcell->obpile, F_MAPLINK, NA, c->x, c->y, NULL);
}
assert(uphole);
getobname(uphole,upholename, 1);
}
@ -15831,8 +15843,16 @@ void timeeffectsob(object_t *o) {
// object makes noise?
getflags(o->flags, retflag, &nretflags, F_MAKESNOISE, F_NONE);
if (nretflags) {
int chance;
f = retflag[rnd(0,nretflags-1)];
if (pctchance(f->val[0])) {
chance = f->val[0];
// closed shops don't make cash register noises!
if (hasflag(o->flags, F_SHOP) && shopisclosed(o)) {
chance = 0;
}
if (pctchance(chance)) {
// these are generally just to notify the player that something
// is nearby, so don't make noises the the player is already there.
if (location != player->cell) {

23
shops.c
View File

@ -179,14 +179,9 @@ void shop(lifeform_t *lf, object_t *vm) {
}
// closed?
f = hasflag(vm->flags, F_OPENHOURS);
if (f) {
int h = -1,m = -1,s = -1;
splittime(&h, &m, &s);
if (!timeisbetween(h, f->val[0], f->val[1])) {
sayphrase(NULL, f->val[2], SV_TALK, hoursto12(f->val[0]), NULL, player);
return;
}
if (shopisclosed(vm)) {
sayphrase(NULL, f->val[2], SV_TALK, hoursto12(f->val[0]), NULL, player);
return;
}
if (lfhasflag(lf, F_STENCH)) {
@ -805,6 +800,18 @@ enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext,
return SR_CONTINUE;
}
int shopisclosed(object_t *shop) {
flag_t *f;
f = hasflag(shop->flags, F_OPENHOURS);
if (f) {
int h = -1,m = -1,s = -1;
splittime(&h, &m, &s);
if (!timeisbetween(h, f->val[0], f->val[1])) {
return B_TRUE;
}
}
return B_FALSE;
}
enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated) {
char ch;

View File

@ -12,6 +12,7 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex
enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *nid);
int shopisclosed(object_t *shop);
enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shoprepair(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);

19
spell.c
View File

@ -820,11 +820,24 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
taketime(user, getactspeed(user)*2);
} else if (abilid == OT_A_CLIMB) {
enum ERROR why;
int origdir = D_NONE;
// for ai only: turn to face target cell first.
if (!isplayer(user) && targcell) {
turntoface(user, targcell);
}
if (isplayer(user) && !isorthogonal(user->facing)) {
int dir;
dir = askdir("Climb in which direction (orthogonal only, - to cancel)", B_TRUE, B_FALSE);
if ((dir == D_NONE) || (dir == D_MYSELF) || !isorthogonal(dir)) {
msg("You can only climb in orthogonal directions.");
return B_TRUE;
} else {
origdir = user->facing;
setfacing(user, dir);
targcell = getcellindir(user->cell, user->facing);
}
}
if (!canclimb(user, &why)) {
if (isplayer(user)){
@ -832,6 +845,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
case E_CLIMBING: msg("You are already climbing!"); break;
case E_CANTMOVE: msg("You can't move!"); break;
case E_BADCLIMBDIR: msg("There is no wall to climb in front of you!"); break;
case E_BADCLIMBDIR2: msg("You can only climb in orthogonal directions."); break;
case E_LFINWAY: msg("Something is in the way!"); break;
case E_SWIMMING: msg("You can't climb while swimming!"); break;
case E_TOOHEAVY: msg("Your load is too heavy to climb with!"); break;
@ -839,6 +853,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
default: msg("For some reason, you can't climb."); break;
}
}
if (origdir != D_NONE) {
setfacing(user, origdir);
}
return B_TRUE;
}
@ -883,7 +900,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (corpse) {
getobname(corpse, obname, o->amt);
if (getobsize(corpse) > (getskill(user, SK_COOKING)+1)) {
msg("%s is too large for you to cook at the moment.", obname);
msg("%s is too large for you to cook (Cooking skill too low).", obname);
ncooked++;
break;
} else if (isimmuneto(corpse->flags, DT_FIRE, B_FALSE)) {