- [+] 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:
parent
a42ca5bb37
commit
d89e93f64e
49
ai.c
49
ai.c
|
@ -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
3
ai.h
|
@ -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
9
data.c
|
@ -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);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
1
defs.h
1
defs.h
|
@ -4548,6 +4548,7 @@ enum ERROR {
|
|||
E_LFINWAY,
|
||||
E_NOSPACE,
|
||||
E_BADCLIMBDIR,
|
||||
E_BADCLIMBDIR2,
|
||||
E_STOPCLIMBING,
|
||||
E_SELNOTHING,
|
||||
E_ALREADYUSING,
|
||||
|
|
15
lf.c
15
lf.c
|
@ -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
1
map.c
|
@ -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);
|
||||
|
|
26
objects.c
26
objects.c
|
@ -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) {
|
||||
|
|
19
shops.c
19
shops.c
|
@ -179,15 +179,10 @@ 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])) {
|
||||
if (shopisclosed(vm)) {
|
||||
sayphrase(NULL, f->val[2], SV_TALK, hoursto12(f->val[0]), NULL, player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_STENCH)) {
|
||||
msg("\"Pheeew! You're not coming in smelling like that.\"");
|
||||
|
@ -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;
|
||||
|
|
1
shops.h
1
shops.h
|
@ -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
19
spell.c
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue