Updates
This commit is contained in:
parent
014d591109
commit
86ee482ce3
2
Makefile
2
Makefile
|
@ -1,2 +1,2 @@
|
||||||
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h flag.c flag.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h
|
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h flag.c flag.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h
|
||||||
gcc -g -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c -lncurses
|
gcc -Wall -g -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c -lncurses
|
||||||
|
|
627
ai.c
627
ai.c
|
@ -1,22 +1,36 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
|
#include "attack.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "flag.h"
|
#include "flag.h"
|
||||||
|
#include "io.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "move.h"
|
||||||
|
#include "nexus.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
#include "spell.h"
|
||||||
|
#include "text.h"
|
||||||
|
|
||||||
extern lifeform_t *player;
|
extern lifeform_t *player;
|
||||||
|
extern enum ERROR reason;
|
||||||
|
|
||||||
void aimove(lifeform_t *lf) {
|
void aimove(lifeform_t *lf) {
|
||||||
int dir;
|
|
||||||
int wantdb = B_TRUE;
|
int wantdb = B_TRUE;
|
||||||
int db = B_FALSE;
|
int db = B_FALSE;
|
||||||
object_t *curwep,*bestwep;
|
object_t *curwep,*bestwep, *o;
|
||||||
|
object_t *curgun,*bestgun;
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
//flag_t *nextf;
|
||||||
|
// lifeform_t *fleefrom = NULL;
|
||||||
lifeform_t *target;
|
lifeform_t *target;
|
||||||
char buf[BUFLEN];
|
enum BODYPART bp;
|
||||||
|
int x,y;
|
||||||
|
cell_t *c;
|
||||||
|
obpile_t *unarmedpile = NULL;
|
||||||
|
flag_t *unarmedflag = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (wantdb && haslos(player, lf->cell)) {
|
if (wantdb && haslos(player, lf->cell)) {
|
||||||
|
@ -25,16 +39,21 @@ void aimove(lifeform_t *lf) {
|
||||||
db = B_FALSE;
|
db = B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db) dblog("AIMOVE: %s", lf->race->name);
|
if (db) {
|
||||||
|
char lfname[BUFLEN];
|
||||||
|
getlfname(lf, lfname);
|
||||||
|
dblog("AIMOVE: %s", lfname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// if lifeform isn't alive, skip turn
|
// if lifeform isn't alive, skip turn
|
||||||
if (isdead(lf)) {
|
if (isdead(lf)) {
|
||||||
if (db) dblog(".oO { i am not alive, skipping turn. }");
|
if (db) dblog(".oO { i am not alive, skipping turn. }");
|
||||||
taketime(lf, SPEED_DEAD);
|
taketime(lf, SPEED_DEAD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// do we have a better weapon we could use?
|
// do we have a better weapon we could use?
|
||||||
|
@ -44,117 +63,557 @@ void aimove(lifeform_t *lf) {
|
||||||
if (curwep != bestwep) {
|
if (curwep != bestwep) {
|
||||||
if (db) dblog(".oO { i have a better weapon than my current one (%s > %s) }",bestwep->type->name, curwep ? curwep->type->name : "nothing");
|
if (db) dblog(".oO { i have a better weapon than my current one (%s > %s) }",bestwep->type->name, curwep ? curwep->type->name : "nothing");
|
||||||
// weild better one
|
// weild better one
|
||||||
weild(lf, bestwep);
|
if (!weild(lf, bestwep)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have a better firearm ?
|
||||||
|
curgun = getfirearm(lf);
|
||||||
|
bestgun = getbestfirearm(lf);
|
||||||
|
|
||||||
|
if (curgun != bestgun) {
|
||||||
|
if (db) dblog(".oO { i have a better gun than my current one (%s > %s) }",bestgun->type->name, curgun ? curgun->type->name : "nothing");
|
||||||
|
// weild better one
|
||||||
|
if (!weild(lf, bestgun)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have better armour?
|
||||||
|
for (bp = BP_RIGHTHAND ; bp < MAXBODYPARTS; bp++) {
|
||||||
|
object_t *curarm;
|
||||||
|
curarm = getarmour(lf, bp);
|
||||||
|
// do we have a better one?
|
||||||
|
for (o = lf->pack->first ; o ; o = o->next) {
|
||||||
|
if (isbetterarmourthan(o, curarm)) {
|
||||||
|
// wear this armour instead
|
||||||
|
if (!wear(lf, o)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// now check whetehr we have ANY weapon
|
||||||
|
curwep = getattackwep(lf, &unarmedpile, &unarmedflag);
|
||||||
|
if (unarmedpile) killobpile(unarmedpile);
|
||||||
|
|
||||||
|
// before attacking targets,
|
||||||
|
// look for any object which we _covet_.
|
||||||
|
// ie. if we covet something, we will pick it up
|
||||||
|
// instead of attacking our target.
|
||||||
|
if (db) dblog(".oO { looking for covetted objects... }");
|
||||||
|
if (lookforobs(lf, B_COVETS)) {
|
||||||
|
if (db) dblog(".oO { found covetted object. returning. }");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// do we already have a target we are attacking?
|
// do we already have a target we are attacking?
|
||||||
f = hasflag(lf->flags, F_TARGET);
|
f = hasflag(lf->flags, F_TARGET);
|
||||||
if (f) {
|
if (f) {
|
||||||
int targid;
|
int targid;
|
||||||
|
int lastx,lasty;
|
||||||
if (db) dblog(".oO { i have a target... }");
|
if (db) dblog(".oO { i have a target... }");
|
||||||
targid = f->val[0];
|
targid = f->val[0];
|
||||||
|
lastx = f->val[1];
|
||||||
|
lasty = f->val[2];
|
||||||
target = findlf(lf->cell->map, targid);
|
target = findlf(lf->cell->map, targid);
|
||||||
if (target) {
|
if (target) {
|
||||||
if (db) dblog(".oO { my target is lfid %d (%s). }", targid, target->race->name);
|
if (db) dblog(".oO { my target is lfid %d (%s). }", targid, target->race->name);
|
||||||
if (haslos(lf, target->cell)) {
|
if (haslos(lf, target->cell)) {
|
||||||
if (db) dblog(".oO { i can see my target. will move towards it. }");
|
int goingtomove = B_TRUE;
|
||||||
movetowards(lf, target->cell);
|
enum OBTYPE spell;
|
||||||
return;
|
object_t *gun;
|
||||||
} else {
|
|
||||||
if (db) dblog(".oO { i cannot see my target }");
|
|
||||||
// TODO: move towards last known location
|
|
||||||
|
|
||||||
|
// reset F_TARGET lifetime to full.
|
||||||
|
f->lifetime = AI_FOLLOWTIME;
|
||||||
|
if (db) dblog(".oO { i can see my target (at %d,%d). will move towards it. }",target->cell->x,target->cell->y);
|
||||||
|
// remember last known loc
|
||||||
|
f->val[1] = target->cell->x;
|
||||||
|
f->val[2] = target->cell->y;
|
||||||
|
|
||||||
|
goingtomove = B_TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
// can we attack with spells (ie. ones which target the victim)?
|
||||||
|
spell = getattackspell(lf);
|
||||||
|
if (spell != OT_NONE) {
|
||||||
|
int spellfailed = B_FALSE;
|
||||||
|
lifeform_t *spelllf = NULL;
|
||||||
|
cell_t *spellcell = NULL;
|
||||||
|
object_t *spellob = NULL;
|
||||||
|
if (db) {
|
||||||
|
objecttype_t *st;
|
||||||
|
st = findot(spell);
|
||||||
|
dblog(".oO { will cast attack spell: %s }", st->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// special cases: eg. spells like telekenesis
|
||||||
|
if (spell == OT_S_TELEKINESIS) {
|
||||||
|
float maxweight;
|
||||||
|
object_t *poss[MAXPILEOBS];
|
||||||
|
int nposs;
|
||||||
|
int i;
|
||||||
|
// find nearest object which can be picked up
|
||||||
|
|
||||||
|
// this is copied out of the telekenesis spell code!
|
||||||
|
maxweight = getlfweight(lf, B_NOOBS) +
|
||||||
|
(getlfweight(lf, B_NOOBS) * (getstatmod(lf, A_IQ) / 100));
|
||||||
|
|
||||||
|
nposs = 0;
|
||||||
|
for (i = 0; i < lf->nlos; i++) {
|
||||||
|
object_t *o;
|
||||||
|
for (o = lf->los[i]->obpile->first ; o ; o = o->next) {
|
||||||
|
if (!hasflag(o->flags, F_NOPICKUP) &&
|
||||||
|
getobweight(o) <= maxweight) {
|
||||||
|
poss[nposs] = o;
|
||||||
|
nposs++;
|
||||||
|
if (nposs >= MAXPILEOBS) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nposs >= MAXPILEOBS) break;
|
||||||
|
}
|
||||||
|
if (nposs > 0) {
|
||||||
|
spellob = poss[rnd(0,nposs-1)];
|
||||||
|
} else {
|
||||||
|
spellfailed = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cast spell at the player
|
||||||
|
spelllf = target;
|
||||||
|
spellcell = target->cell;
|
||||||
|
} else {
|
||||||
|
spelllf = target;
|
||||||
|
spellcell = target->cell;
|
||||||
|
spellob = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!spellfailed && !castspell(lf, spell, spelllf, spellob, spellcell)) {
|
||||||
|
// spell succesful
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { cast spell failed! }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// can we attack by firing something?
|
||||||
|
gun = getfirearm(lf);
|
||||||
|
if (goingtomove && gun && getammo(lf)) {
|
||||||
|
setguntarget(lf, target);
|
||||||
|
if (!shoot(lf)) {
|
||||||
|
// succesful
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { shoot gun failed! }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// can we attack by throwing something?
|
||||||
|
if (goingtomove && getcelldist(lf->cell, target->cell) > 1) {
|
||||||
|
// TODO: or firing! check if we have a firearm first.
|
||||||
|
o = getbestmissile(lf);
|
||||||
|
if (o) {
|
||||||
|
if (db) dblog(".oO { will throw %s at my target instead of moving }", o->type->name);
|
||||||
|
// try to throw it!
|
||||||
|
if (!throwat(lf, o, target->cell)) {
|
||||||
|
// succesful
|
||||||
|
goingtomove = B_FALSE;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { throw failed! }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have a valid melee attack?
|
||||||
|
if (!curwep) {
|
||||||
|
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||||
|
goingtomove = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (goingtomove) {
|
||||||
|
if (!movetowards(lf, target->cell)) {
|
||||||
|
// success
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { move towards failed! - reason = %d }",reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { i cannot see my target. moving to last known loc %d/%d }",lastx,lasty);
|
||||||
|
|
||||||
|
// can't see target.
|
||||||
|
// move towards their last known location instead
|
||||||
|
addflag(lf->flags, F_TARGETCELL, lastx, lasty, NA, NULL);
|
||||||
|
// remove f_target
|
||||||
|
killflag(f);
|
||||||
|
|
||||||
|
/*
|
||||||
// just try to move in a random direction
|
// just try to move in a random direction
|
||||||
if (db) dblog(".oO { will move randomly }");
|
if (db) dblog(".oO { will move randomly }");
|
||||||
|
// dorandommove will call taketime() if it fails,
|
||||||
|
// so it's safe to just return
|
||||||
dorandommove(lf, B_NOBADMOVES);
|
dorandommove(lf, B_NOBADMOVES);
|
||||||
return;
|
return;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// not attacking anyone in particular
|
|
||||||
|
|
||||||
if (db) dblog(".oO { i do not have a target. }");
|
|
||||||
// TODO: are we hostile? if so, look for a target
|
/*
|
||||||
f = hasflag(lf->flags, F_HOSTILE);
|
if (lookforobs(lf, B_COVETS)) {
|
||||||
if (f) {
|
if (db) dblog(".oO { found covetted object. returning. }");
|
||||||
int x,y;
|
return;
|
||||||
cell_t *c;
|
}
|
||||||
if (db) dblog(".oO { i am hostile. looking for a target. }");
|
*/
|
||||||
// look around for a target
|
|
||||||
// TODO: use our vis rang einstead of 10!
|
// do we have a target cell?
|
||||||
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
|
f = hasflag(lf->flags, F_TARGETCELL);
|
||||||
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
|
if (f) {
|
||||||
c = getcellat(lf->cell->map, x, y);
|
// if so, move towards it
|
||||||
// cell exists and we can see it?
|
x = f->val[0];
|
||||||
if (c && haslos(lf, c)) {
|
y = f->val[1];
|
||||||
// player there?
|
if (db) dblog(".oO { walking from %d,%d towards f_targetcell (%d,%d) ... }", lf->cell->x, lf->cell->y, x, y);
|
||||||
if (c->lf && c->lf->controller == C_PLAYER) {
|
c = getcellat(lf->cell->map, x, y);
|
||||||
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
if (c) {
|
||||||
// target them!
|
if (movetowards(lf, c)) {
|
||||||
addflag(lf->flags, F_TARGET, c->lf->id, -1, -1, "");
|
// couldn't move towards it for some reason.
|
||||||
// tell the player
|
// so stop trying.
|
||||||
if (haslos(player, lf->cell)) {
|
if (db) dblog(".oO { couldn't walk towards f_targetcell. abandoning it. }");
|
||||||
getlfname(lf, buf);
|
killflag(f);
|
||||||
capitalise(buf);
|
// remember NOT to target this one.
|
||||||
msg("%s sees you!", buf);
|
lf->ignorecell = c;
|
||||||
}
|
} else {
|
||||||
// then move towards them...
|
if (db) dblog(".oO { successfully walked towards f_targetcell. }");
|
||||||
if (db) dblog(".oO { moving towards my new target }");
|
// moved towards it.
|
||||||
movetowards(lf, c);
|
// reset lifetime
|
||||||
return;
|
f->lifetime = AI_FOLLOWTIME;
|
||||||
|
|
||||||
|
// are we there yet?
|
||||||
|
if (lf->cell == c) {
|
||||||
|
if (db) dblog(".oO { arrived at f_targetcell. removing. }");
|
||||||
|
killflag(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { f_targetcell doesn't exist. abandoning. }");
|
||||||
|
// destination doesn't exist!
|
||||||
|
killflag(f);
|
||||||
|
// remember NOT to target this one.
|
||||||
|
lf->ignorecell = c;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// look for any object which we want
|
||||||
|
if (db) dblog(".oO { looking for any ob which i want. }");
|
||||||
|
if (lookforobs(lf, B_ANY)) {
|
||||||
|
if (db) dblog(".oO { found ob that i want. returning. }");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// not attacking anyone in particular
|
||||||
|
if (db) dblog(".oO { i do not have a target or can't move towards it. }");
|
||||||
|
// are we hostile? if so, look for a target
|
||||||
|
f = hasflag(lf->flags, F_HOSTILE);
|
||||||
|
if (f) {
|
||||||
|
int x,y;
|
||||||
|
if (db) dblog(".oO { i am hostile. looking for a target. }");
|
||||||
|
// look around for a target
|
||||||
|
// TODO: use our vis rang einstead of 10!
|
||||||
|
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
|
||||||
|
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
|
||||||
|
c = getcellat(lf->cell->map, x, y);
|
||||||
|
// cell exists and we can see it?
|
||||||
|
if (c && haslos(lf, c)) {
|
||||||
|
// player there?
|
||||||
|
if (c->lf && (c->lf != lf) && isplayer(c->lf)) {
|
||||||
|
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||||
|
// target them!
|
||||||
|
addtempflag(lf->flags, F_TARGET, c->lf->id, NA, NA, NULL, AI_FOLLOWTIME);
|
||||||
|
// tell the player
|
||||||
|
if (haslos(player, lf->cell)) {
|
||||||
|
makenoise(lf, N_GETANGRY);
|
||||||
}
|
}
|
||||||
|
// then move towards them...
|
||||||
|
if (db) dblog(".oO { moving towards my new target }");
|
||||||
|
|
||||||
|
if (curwep) {
|
||||||
|
if (!movetowards(lf, c)) return;
|
||||||
|
} else {
|
||||||
|
if (db) dblog(".oO { won't move towards target - i have no weapon. }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// just try to move in a random direction
|
// are we friendly? if so, look for a target
|
||||||
if (db) dblog(".oO { default - moving randomly }");
|
f = hasflag(lf->flags, F_FRIENDLY);
|
||||||
dorandommove(lf, B_NOBADMOVES);
|
if (f) {
|
||||||
return;
|
int x,y;
|
||||||
}
|
if (db) dblog(".oO { i am friendly to the player. looking for a target. }");
|
||||||
|
// look around for a target
|
||||||
// if we get this far, just wait
|
// TODO: use our vis rang einstead of 10!
|
||||||
dowait(lf);
|
for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) {
|
||||||
}
|
for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) {
|
||||||
|
c = getcellat(lf->cell->map, x, y);
|
||||||
int getdirtowards(lifeform_t *lf, cell_t *dst) {
|
// cell exists and we can see it?
|
||||||
int d;
|
if (c && haslos(lf, c)) {
|
||||||
cell_t *c;
|
// player there?
|
||||||
int mindist=9999,bestdir=D_NONE;
|
if (c->lf && (c->lf != lf) && !isplayer(c->lf)) {
|
||||||
|
if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name);
|
||||||
for (d = DC_N; d <= DC_NW; d++) {
|
// target them!
|
||||||
c = getcellindir(lf->cell, d);
|
addtempflag(lf->flags, F_TARGET, c->lf->id, NA, NA, NULL, AI_FOLLOWTIME);
|
||||||
if (!c) continue;
|
// then move towards them...
|
||||||
if (c == dst) {
|
if (db) dblog(".oO { moving towards my new target }");
|
||||||
// destination is adjacent!
|
if (!movetowards(lf, c)) return;
|
||||||
bestdir = d;
|
}
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (canmove(lf, d)) {
|
|
||||||
int thisdist;
|
|
||||||
thisdist = getcelldist(c, dst);
|
|
||||||
if (thisdist < mindist) {
|
|
||||||
mindist = thisdist;
|
|
||||||
bestdir = d;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle ties
|
|
||||||
|
|
||||||
return bestdir;
|
// just try to move in a random direction
|
||||||
|
if (db) dblog(".oO { default - moving randomly }");
|
||||||
|
dorandommove(lf, B_NOBADMOVES);
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if we get this far, just wait
|
||||||
|
rest(lf, B_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void movetowards(lifeform_t *lf, cell_t *dst) {
|
int aipickup(lifeform_t *lf, object_t *o) {
|
||||||
int dir;
|
if (isedible(o)) {
|
||||||
// move towards them
|
return eat(lf, o);
|
||||||
dir = getdirtowards(lf, dst);
|
} else {
|
||||||
if (dir != D_NONE) {
|
return pickup(lf, o, o->amt);
|
||||||
trymove(lf, dir);
|
|
||||||
}
|
}
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum OBTYPE getattackspell(lifeform_t *lf) {
|
||||||
|
flag_t *f;
|
||||||
|
enum OBTYPE poss[MAXPILEOBS];
|
||||||
|
int nposs = 0;
|
||||||
|
int db = B_TRUE;
|
||||||
|
for (f = lf->flags->first ; f ; f = f->next) {
|
||||||
|
if (f->id == F_CANWILL) {
|
||||||
|
poss[nposs] = f->val[0];
|
||||||
|
nposs++;
|
||||||
|
} else if (f->id == F_CANCAST) {
|
||||||
|
objecttype_t *ot;
|
||||||
|
ot = findot(f->val[0]);
|
||||||
|
if (cancast(lf, f->val[0], NULL)) {
|
||||||
|
if (db) {
|
||||||
|
dblog(".oO { spell possibility: %s }", ot ? ot->name : "?unkownspell?");
|
||||||
|
|
||||||
|
}
|
||||||
|
poss[nposs] = f->val[0];
|
||||||
|
nposs++;
|
||||||
|
} else {
|
||||||
|
if (db) {
|
||||||
|
if (ot) {
|
||||||
|
dblog(".oO { can't cast %s right now (mpcost=%d, i have %d) }",
|
||||||
|
ot ? ot->name : "?unkownspell?",
|
||||||
|
getmpcost(ot->id), lf->mp);
|
||||||
|
} else {
|
||||||
|
dblog(".oO { can't cast ?unknownspell? right now }");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// select a random one
|
||||||
|
if (nposs > 0) {
|
||||||
|
int sel;
|
||||||
|
sel = rnd(0,nposs-1);
|
||||||
|
return poss[sel];
|
||||||
|
}
|
||||||
|
|
||||||
|
return OT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op) {
|
||||||
|
object_t *o;
|
||||||
|
|
||||||
|
for (o = op->first ; o ; o = o->next) {
|
||||||
|
if (isarmour(o)) {
|
||||||
|
object_t *curarm;
|
||||||
|
enum BODYPART bp;
|
||||||
|
flag_t *f;
|
||||||
|
// where does it go?
|
||||||
|
f = hasflag(o->flags, F_GOESON);
|
||||||
|
bp = f->val[0];
|
||||||
|
// is it better than what we have in that position?
|
||||||
|
curarm = getarmour(lf, bp);
|
||||||
|
if (isbetterwepthan(o, curarm)) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op) {
|
||||||
|
object_t *bestwep, *o;
|
||||||
|
|
||||||
|
bestwep = getbestweapon(lf);
|
||||||
|
for (o = op->first ; o ; o = o->next) {
|
||||||
|
if (isweapon(o) && isbetterwepthan(o, bestwep) && canweild(lf, o)) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns B_TRUE if we did something
|
||||||
|
int lookforobs(lifeform_t *lf, int covetsonly) {
|
||||||
|
object_t *o;
|
||||||
|
enum OBTYPE oid[MAXPILEOBS];
|
||||||
|
int noids = 0;
|
||||||
|
enum FLAG wantflag[MAXPILEOBS];
|
||||||
|
int nwantflags = 0;
|
||||||
|
int db = B_TRUE;
|
||||||
|
flag_t *f;
|
||||||
|
cell_t *c;
|
||||||
|
int n;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// construct a list of objects which we want
|
||||||
|
noids = 0;
|
||||||
|
for (f = lf->flags->first ; f ; f = f->next) {
|
||||||
|
if (f->id == F_WANTS) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
oid[noids] = f->val[0];
|
||||||
|
noids++;
|
||||||
|
}
|
||||||
|
} else if (f->id == F_WANTSOBFLAG) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
wantflag[nwantflags] = f->val[0];
|
||||||
|
nwantflags++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// current cell has an object we want?
|
||||||
|
o = hasobmulti(lf->cell->obpile, oid, noids);
|
||||||
|
if (o && (canpickup(lf, o) || caneat(lf,o)) ) {
|
||||||
|
if (db) dblog(".oO { current cell has ob i want (%s) }",o->type->name);
|
||||||
|
// try to pick it up
|
||||||
|
if (!aipickup(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { pickup of %s failed, trying to eat! }",o->type->name);
|
||||||
|
if (!eat(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { eating %s failed }",o->type->name);
|
||||||
|
}
|
||||||
|
// has an object with a flag we want?
|
||||||
|
for (n = 0; n < nwantflags; n++) {
|
||||||
|
o = hasobwithflag(lf->cell->obpile, wantflag[n]);
|
||||||
|
if (o && (canpickup(lf, o) || caneat(lf,o)) ) {
|
||||||
|
if (db) dblog(".oO { current cell has ob with flag i want (%s) }",o->type->name);
|
||||||
|
// try to pick it up
|
||||||
|
if (!aipickup(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { pickup of %s with wantflag failed, trying to eat! }",o->type->name);
|
||||||
|
if (!eat(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { eating %s with wantflag failed }",o->type->name);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// current cell has better weapon?
|
||||||
|
f = hasflag(lf->flags, F_WANTSBETTERWEP);
|
||||||
|
if (f ) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
o = hasbetterweapon(lf, lf->cell->obpile);
|
||||||
|
if (o && canpickup(lf, o)) {
|
||||||
|
if (db) dblog(".oO { current cell has better weapon (%s) }",o->type->name);
|
||||||
|
// try to pick it up
|
||||||
|
if (!aipickup(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { pickup of better wep %s failed! }",o->type->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// current cell has better armour?
|
||||||
|
f = hasflag(lf->flags, F_WANTSBETTERARM);
|
||||||
|
if (f ) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
o = hasbetterarmour(lf, lf->cell->obpile);
|
||||||
|
if (o && canpickup(lf, o)) {
|
||||||
|
if (db) dblog(".oO { current cell has better armour (%s) }",o->type->name);
|
||||||
|
// try to pick it up
|
||||||
|
if (!aipickup(lf, o)) return B_TRUE;
|
||||||
|
if (db) dblog(".oO { pickup of better armour %s failed! }",o->type->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// look around for objects which we want, if we don't already have a targetcell.
|
||||||
|
if (!hasflag(lf->flags, F_TARGETCELL)) {
|
||||||
|
if (db) dblog(".oO { no targetcell, so looking for remote objects }");
|
||||||
|
for (i = 0 ; i < lf->nlos; i++) {
|
||||||
|
int gothere = B_FALSE;
|
||||||
|
|
||||||
|
c = lf->los[i];
|
||||||
|
if (c != lf->ignorecell) {
|
||||||
|
o = hasobmulti(c->obpile, oid, noids);
|
||||||
|
if (o && (canpickup(lf, o) || caneat(lf,o)) ) {
|
||||||
|
if (db) dblog(".oO { remote cell has ob i want (%s). setting f_targetcell. }",o->type->name);
|
||||||
|
gothere = B_TRUE;
|
||||||
|
}
|
||||||
|
if (!gothere) {
|
||||||
|
// has an object with a flag we want?
|
||||||
|
for (n = 0; n < nwantflags; n++) {
|
||||||
|
o = hasobwithflag(c->obpile, wantflag[n]);
|
||||||
|
if (o && (canpickup(lf, o) || caneat(lf, o)) ) {
|
||||||
|
if (db) dblog(".oO { remote cell has ob with flag i want (%s) }", o->type->name);
|
||||||
|
gothere = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gothere) {
|
||||||
|
// remote cell has better weapon?
|
||||||
|
f = hasflag(lf->flags, F_WANTSBETTERWEP);
|
||||||
|
if (f) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
|
||||||
|
o = hasbetterweapon(lf, c->obpile);
|
||||||
|
if (o && canpickup(lf, o)) {
|
||||||
|
if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name);
|
||||||
|
gothere = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gothere) {
|
||||||
|
// remote cell has better armour?
|
||||||
|
f = hasflag(lf->flags, F_WANTSBETTERARM);
|
||||||
|
if (f) {
|
||||||
|
if (!covetsonly || (f->val[1] == B_COVETS)) {
|
||||||
|
|
||||||
|
o = hasbetterarmour(lf, c->obpile);
|
||||||
|
if (o && canpickup(lf, o)) {
|
||||||
|
if (db) dblog(".oO { remote cell has better armour (%s). setting f_targetcell }",o->type->name);
|
||||||
|
gothere = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (gothere) {
|
||||||
|
// start walking towards target cell
|
||||||
|
addtempflag(lf->flags, F_TARGETCELL, c->x, c->y, NA, NULL, AI_FOLLOWTIME);
|
||||||
|
// forget about people we are attacking
|
||||||
|
killflagsofid(lf->flags, F_TARGET);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
7
ai.h
7
ai.h
|
@ -1,5 +1,8 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
void aimove(lifeform_t *lf);
|
void aimove(lifeform_t *lf);
|
||||||
int getdirtowards(lifeform_t *lf, cell_t *dst);
|
int aipickup(lifeform_t *lf, object_t *o);
|
||||||
void movetowards(lifeform_t *lf, cell_t *dst);
|
enum OBTYPE getattackspell(lifeform_t *lf);
|
||||||
|
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op);
|
||||||
|
object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op);
|
||||||
|
int lookforobs(lifeform_t *lf, int covetsonly);
|
||||||
|
|
19
attack.h
19
attack.h
|
@ -1,8 +1,17 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
int doattack(lifeform_t *lf, lifeform_t *victim);
|
int attackcell(lifeform_t *lf, cell_t *c);
|
||||||
char *getattackverb(enum DAMTYPE damtype, int dam);
|
int attacklf(lifeform_t *lf, lifeform_t *victim);
|
||||||
char *getkillverb(enum DAMTYPE damtype, int dam);
|
int attackob(lifeform_t *lf, object_t *o);
|
||||||
int getdamrange(object_t *o, int *min, int *max);
|
const char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp);
|
||||||
|
object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
|
||||||
|
enum DAMTYPE getdamtype(object_t *wep);
|
||||||
|
int getextradam(object_t *wep, unsigned int *dam, enum DAMTYPE *damtype);
|
||||||
|
char *getkillverb(enum DAMTYPE damtype, int dam, int maxhp);
|
||||||
|
void getdamrange(flagpile_t *fp, int *min, int *max);
|
||||||
|
float getdamreducepct(float armourrating);
|
||||||
int getdamroll(object_t *o);
|
int getdamroll(object_t *o);
|
||||||
objecttype_t *getunarmedweapon(lifeform_t *lf, obpile_t *op);
|
int getdamrollfromflag(flag_t *f);
|
||||||
|
float getstrdammod(lifeform_t *lf);
|
||||||
|
obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
|
||||||
|
void wepeffects(object_t *wep, cell_t *where);
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
in defs.h:
|
||||||
|
add a new BODYPART enum entry
|
||||||
|
increment MAXBODYPARTS
|
||||||
|
|
||||||
|
in lf.c:
|
||||||
|
update getbodypartname
|
||||||
|
update getbodypartequipname
|
||||||
|
update getbodyparthitchance
|
|
@ -0,0 +1,10 @@
|
||||||
|
in defs.h:
|
||||||
|
add enum
|
||||||
|
increment MAXDAMTYPE
|
||||||
|
in objcets.c:
|
||||||
|
update getdamname() - eg. you take 5 "electrical" damage
|
||||||
|
update getdamnamenoun() - eg. you are immune to "electricity"
|
||||||
|
|
||||||
|
in attack.c
|
||||||
|
update getattackverb if required
|
||||||
|
update getkillverb if required
|
|
@ -0,0 +1,5 @@
|
||||||
|
defs.h:
|
||||||
|
add H_xx enum
|
||||||
|
|
||||||
|
map.c:
|
||||||
|
update getemptycelltype()
|
|
@ -0,0 +1,13 @@
|
||||||
|
defs.h:
|
||||||
|
add F_WHATEVER
|
||||||
|
|
||||||
|
io.c:
|
||||||
|
update describeob() for when an object confers this property
|
||||||
|
|
||||||
|
update showlfstats() to describe the property
|
||||||
|
|
||||||
|
update announceflaggain() to describe adding it
|
||||||
|
update announceflagloss() to describe losing it
|
||||||
|
|
||||||
|
|
||||||
|
then make it do something!
|
|
@ -0,0 +1,8 @@
|
||||||
|
defs.h:
|
||||||
|
define the MT_* enum
|
||||||
|
|
||||||
|
objects.c:
|
||||||
|
add an addmaterial() line
|
||||||
|
update adjustdammaterial() as required
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,11 @@ In defs.h:
|
||||||
In objects.c:
|
In objects.c:
|
||||||
define the class with addoc()
|
define the class with addoc()
|
||||||
add the class to sortorder[] at the top
|
add the class to sortorder[] at the top
|
||||||
findotn() must know how to un-pluralise the name
|
findotn() must know how to un-pluralise the name (eg. potions)
|
||||||
|
|
||||||
|
update genhiddenname() if this class isn't known
|
||||||
|
also add hidden names up the top
|
||||||
|
also update numXXXnames count in initobjects()
|
||||||
|
|
||||||
In text.c:
|
In text.c:
|
||||||
makeplural() must know about the name
|
makeplural() must know about the name (eg. potion -> potions)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
defs.h:
|
||||||
|
update enum SPELLSCHOOL
|
||||||
|
|
||||||
|
objects.c:
|
||||||
|
update getschoolname
|
|
@ -0,0 +1,19 @@
|
||||||
|
defs.h:
|
||||||
|
add the OT_xxx enum
|
||||||
|
(optional) add a scroll to do the same effect
|
||||||
|
(optional) add a potion to do the same effect
|
||||||
|
|
||||||
|
objects.c:
|
||||||
|
define the spell
|
||||||
|
remember to have spelllevle
|
||||||
|
(optional) add a scroll to do the same effect, use F_LINKSPELL
|
||||||
|
(optional) add a potion to do the same effect
|
||||||
|
|
||||||
|
spell.c:
|
||||||
|
implement the effects
|
||||||
|
remember to fill in *seenbyplayer if there is a scroll version
|
||||||
|
cope with:
|
||||||
|
blessed/cursed
|
||||||
|
target having antimagic - use hasmr(victim)
|
||||||
|
blindness if the effect is vision-based
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
baesball (0.14 kg) can be thrown 100 metres
|
||||||
|
|
||||||
|
so let's say:
|
||||||
|
|
||||||
|
1 kg = 10 metres (cells)
|
||||||
|
10 kg = 5m
|
||||||
|
20 kg = 1m
|
||||||
|
|
||||||
|
distance = 10m - (weight/2)
|
||||||
|
|
||||||
|
|
||||||
|
|
281
flag.c
281
flag.c
|
@ -3,12 +3,42 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
#include "flag.h"
|
#include "flag.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "lf.h"
|
||||||
|
#include "objects.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
|
||||||
|
extern int gamestarted;
|
||||||
|
|
||||||
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text) {
|
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text) {
|
||||||
|
return addflag_real(fp, id, val1, val2, val3, text, PERMENANT, B_KNOWN);
|
||||||
|
}
|
||||||
|
flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft) {
|
||||||
|
return addflag_real(fp, id, val1, val2, val3, text, timeleft, B_KNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// identified things mean all new flags are autmaticlaly known.
|
||||||
|
if (hasflag(fp, F_IDENTIFIED)) {
|
||||||
|
known = B_KNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// certain flags stack...
|
||||||
|
if (flagstacks(id)) {
|
||||||
|
f = hasflag(fp, id);
|
||||||
|
if (f) {
|
||||||
|
// add values!
|
||||||
|
f->val[0] += val1;
|
||||||
|
f->val[1] += val2;
|
||||||
|
f->val[2] += val3;
|
||||||
|
// TODO: how to handle text??
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fp->first == NULL) {
|
if (fp->first == NULL) {
|
||||||
fp->first = malloc(sizeof(flag_t));
|
fp->first = malloc(sizeof(flag_t));
|
||||||
f = fp->first;
|
f = fp->first;
|
||||||
|
@ -25,7 +55,10 @@ flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char
|
||||||
f->next = NULL;
|
f->next = NULL;
|
||||||
|
|
||||||
// fill in props
|
// fill in props
|
||||||
f->id = id; // increment next ob id
|
f->id = id;
|
||||||
|
f->lifetime = lifetime;
|
||||||
|
f->known = known;
|
||||||
|
f->obfrom = -1;
|
||||||
|
|
||||||
// first blank values
|
// first blank values
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
@ -50,34 +83,88 @@ flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char
|
||||||
|
|
||||||
f->pile = fp;
|
f->pile = fp;
|
||||||
|
|
||||||
|
|
||||||
|
// notify
|
||||||
|
if (gamestarted) {
|
||||||
|
if (f->pile->owner) {
|
||||||
|
if (announceflaggain(f->pile->owner, f)) {
|
||||||
|
f->known = B_TRUE;
|
||||||
|
}
|
||||||
|
if (isplayer(f->pile->owner)) {
|
||||||
|
switch (f->id) {
|
||||||
|
case F_BLIND:
|
||||||
|
case F_SEEINDARK:
|
||||||
|
drawscreen();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (f->pile->ob) {
|
||||||
|
if (announceobflaggain(f->pile->ob, f)) {
|
||||||
|
f->known = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
flagpile_t *addflagpile(void) {
|
flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
|
||||||
flagpile_t *fp;
|
flagpile_t *fp;
|
||||||
fp = malloc(sizeof(flagpile_t));
|
fp = malloc(sizeof(flagpile_t));
|
||||||
fp->first = NULL;
|
fp->first = NULL;
|
||||||
fp->last = NULL;
|
fp->last = NULL;
|
||||||
|
fp->owner = owner;
|
||||||
|
fp->ob = ob;
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
flag_t *hasflag(flagpile_t *fp, int id) {
|
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
for (f = fp->first ; f ; f = f->next) {
|
for (f = src->first ; f ; f = f->next) {
|
||||||
if (f->id == id) return f;
|
addflag_real(dst, f->id, f->val[0], f->val[1], f->val[2], f->text,
|
||||||
|
(lifetime == NA) ? f->lifetime : lifetime, f->known);
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) {
|
int flagstacks(enum FLAG fid) {
|
||||||
|
int res = B_FALSE;
|
||||||
|
switch (fid) {
|
||||||
|
case F_EVASION:
|
||||||
|
case F_BONUS:
|
||||||
|
res = B_TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = B_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *hasflag(flagpile_t *fp, int id) {
|
||||||
|
return hasflag_real(fp, id, NA);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *hasflagknown(flagpile_t *fp, int id) {
|
||||||
|
return hasflag_real(fp, id, B_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
|
lifeform_t *owner;
|
||||||
|
owner = fp->owner;
|
||||||
|
|
||||||
for (f = fp->first ; f ; f = f->next) {
|
for (f = fp->first ; f ; f = f->next) {
|
||||||
if (f->id == id) {
|
if (f->id == id) {
|
||||||
if ( ((val1 == NA) || (f->val[0] == val1)) &&
|
int valid = B_TRUE;
|
||||||
((val2 == NA) || (f->val[1] == val2)) &&
|
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
|
||||||
((val3 == NA) || (f->val[2] == val3)) &&
|
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
|
||||||
((text == NULL) || strstr(f->text, text))) {
|
valid = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,9 +172,79 @@ flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *t
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) {
|
||||||
|
return hasflagval_real(fp, id, val1, val2, val3, text, B_FALSE); // doesn't have to be known
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text) {
|
||||||
|
return hasflagval_real(fp, id, val1, val2, val3, text, B_TRUE); // must be known
|
||||||
|
}
|
||||||
|
|
||||||
|
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown) {
|
||||||
|
flag_t *f;
|
||||||
|
lifeform_t *owner;
|
||||||
|
owner = fp->owner;
|
||||||
|
for (f = fp->first ; f ; f = f->next) {
|
||||||
|
if (f->id == id) {
|
||||||
|
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
|
||||||
|
// invalid
|
||||||
|
} else {
|
||||||
|
if ( ((val1 == NA) || (f->val[0] == val1)) &&
|
||||||
|
((val2 == NA) || (f->val[1] == val2)) &&
|
||||||
|
((val3 == NA) || (f->val[2] == val3)) &&
|
||||||
|
((text == NULL) || strstr(f->text, text))) {
|
||||||
|
if (!wantknown || f->known) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void killflagsofid(flagpile_t *fp, enum FLAG fid) {
|
||||||
|
flag_t *f,*nextf;
|
||||||
|
for (f = fp->first ; f ; f = nextf) {
|
||||||
|
nextf = f->next;
|
||||||
|
if (f->id == fid) {
|
||||||
|
killflag(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void killflag(flag_t *f) {
|
void killflag(flag_t *f) {
|
||||||
int i;
|
|
||||||
flag_t *nextone, *lastone;
|
flag_t *nextone, *lastone;
|
||||||
|
lifeform_t *lf;
|
||||||
|
int needredraw = B_FALSE;
|
||||||
|
|
||||||
|
lf = f->pile->owner;
|
||||||
|
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
switch (f->id) {
|
||||||
|
case F_BLIND:
|
||||||
|
case F_SEEINDARK:
|
||||||
|
needredraw = B_TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify
|
||||||
|
if (gamestarted) {
|
||||||
|
if (f->pile->owner) {
|
||||||
|
announceflagloss(f->pile->owner, f);
|
||||||
|
} else if (f->pile->ob) {
|
||||||
|
announceobflagloss(f->pile->ob, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we will revert to our original form at the end of timeeffectslf().
|
||||||
|
if (lf && (f->id == F_POLYMORPHED)) {
|
||||||
|
lf->polyrevert = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// free mem
|
// free mem
|
||||||
|
|
||||||
|
@ -109,6 +266,10 @@ void killflag(flag_t *f) {
|
||||||
free (lastone->next );
|
free (lastone->next );
|
||||||
lastone->next = nextone;
|
lastone->next = nextone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gamestarted && needredraw) {
|
||||||
|
drawscreen();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void killflagpile(flagpile_t *fp) {
|
void killflagpile(flagpile_t *fp) {
|
||||||
|
@ -118,3 +279,99 @@ void killflagpile(flagpile_t *fp) {
|
||||||
free(fp);
|
free(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timeeffectsflag(flag_t *f) {
|
||||||
|
if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) {
|
||||||
|
f->lifetime--;
|
||||||
|
if (f->lifetime <= 0) {
|
||||||
|
killflag(f);
|
||||||
|
return;
|
||||||
|
} else if (f->lifetime == 5) {
|
||||||
|
// warn about certain flags......
|
||||||
|
if (isplayer(f->pile->owner)) {
|
||||||
|
switch (f->id) {
|
||||||
|
case F_CANWILL:
|
||||||
|
switch (f->val[0]) {
|
||||||
|
case OT_A_JUMP:
|
||||||
|
warn("Your ability to jump is starting to run out...");;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case F_DTIMMUNE:
|
||||||
|
warn("Your %s immunity is starting to run out...", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_DTRESIST:
|
||||||
|
warn("Your %s resistance is starting to run out...", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_DTVULN:
|
||||||
|
warn("You feel a little less vulnerable to %s...", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_MAGSHIELD:
|
||||||
|
warn("Your magnetic shield is weakening...");
|
||||||
|
break;
|
||||||
|
case F_POLYMORPHED:
|
||||||
|
warn("You are starting to revert to your original form...");
|
||||||
|
break;
|
||||||
|
default: // no message
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (f->lifetime == 1) {
|
||||||
|
// warn about certain flags......
|
||||||
|
if (isplayer(f->pile->owner)) {
|
||||||
|
switch (f->id) {
|
||||||
|
case F_CANWILL:
|
||||||
|
switch (f->val[0]) {
|
||||||
|
case OT_A_JUMP:
|
||||||
|
warn("Your ability to jump is about to expire!");;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case F_DTIMMUNE:
|
||||||
|
warn("Your %s immunity is about to expire!", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_DTRESIST:
|
||||||
|
warn("Your %s resistance is about to expire!", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_DTVULN:
|
||||||
|
warn("You feel a little less vulnerable to %s...", getdamname(f->val[0]));
|
||||||
|
break;
|
||||||
|
case F_MAGSHIELD:
|
||||||
|
warn("Your magnetic shield is about to expire!");
|
||||||
|
break;
|
||||||
|
case F_POLYMORPHED:
|
||||||
|
warn("You are about to revert to your original form!");
|
||||||
|
break;
|
||||||
|
default: // no message
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) {
|
||||||
|
flag_t *f;
|
||||||
|
if (val0) *val0 = 0;
|
||||||
|
if (val1) *val1 = 0;
|
||||||
|
if (val2) *val2 = 0;
|
||||||
|
for (f = fp->first ; f ; f = f->next) {
|
||||||
|
if (f->id == id) {
|
||||||
|
if (val0) *val0 = *val0 + f->val[0];
|
||||||
|
if (val1) *val1 = *val1 + f->val[1];
|
||||||
|
if (val2) *val2 = *val2 + f->val[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void timeeffectsflags(flagpile_t *fp) {
|
||||||
|
flag_t *f,*nextf;
|
||||||
|
for (f = fp->first ; f ; f = nextf) {
|
||||||
|
nextf = f->next;
|
||||||
|
timeeffectsflag(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
15
flag.h
15
flag.h
|
@ -3,8 +3,21 @@
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text);
|
flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text);
|
||||||
flagpile_t *addflagpile(void);
|
flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft);
|
||||||
|
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known);
|
||||||
|
flagpile_t *addflagpile(lifeform_t *owner, object_t *o);
|
||||||
|
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
||||||
|
int flagstacks(enum FLAG fid);
|
||||||
flag_t *hasflag(flagpile_t *fp, int id);
|
flag_t *hasflag(flagpile_t *fp, int id);
|
||||||
|
flag_t *hasflagknown(flagpile_t *fp, int id);
|
||||||
|
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown);
|
||||||
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||||
|
flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||||
|
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown);
|
||||||
|
void killflagsofid(flagpile_t *fp, enum FLAG fid);
|
||||||
void killflag(flag_t *f);
|
void killflag(flag_t *f);
|
||||||
void killflagpile(flagpile_t *fp);
|
void killflagpile(flagpile_t *fp);
|
||||||
|
void makeflagknown(flagpile_t *fp);
|
||||||
|
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2);
|
||||||
|
void timeeffectsflag(flag_t *f);
|
||||||
|
void timeeffectsflags(flagpile_t *fp);
|
||||||
|
|
59
io.h
59
io.h
|
@ -1,23 +1,58 @@
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
void addchoice(prompt_t *p, char ch, char *text, char *desc, void *data);
|
||||||
|
void addheading(prompt_t *p, char *text);
|
||||||
|
void addmsghist(char *text);
|
||||||
void anim(cell_t *src, cell_t *dst, char ch);
|
void anim(cell_t *src, cell_t *dst, char ch);
|
||||||
|
void animradial(cell_t *src, int radius, char ch);
|
||||||
|
//void announceob(enum OBTYPE oid);
|
||||||
|
int announceflaggain(lifeform_t *lf, flag_t *f);
|
||||||
|
void announceflagloss(lifeform_t *lf, flag_t *f);
|
||||||
|
int announceobflaggain(object_t *o, flag_t *f);
|
||||||
|
void announceobflagloss(object_t *o, flag_t *f);
|
||||||
object_t *askobject(obpile_t *op, char *title, int *count, int opts);
|
object_t *askobject(obpile_t *op, char *title, int *count, int opts);
|
||||||
|
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, int opts, enum FLAG withflag);
|
||||||
object_t *askobjectofclass(obpile_t *op, char *title, int *count, int opts, enum OBCLASS obclass);
|
object_t *askobjectofclass(obpile_t *op, char *title, int *count, int opts, enum OBCLASS obclass);
|
||||||
object_t *doaskobject(obpile_t *op, char *title, int *count, int opts, enum OBCLASS obclass);
|
object_t *doaskobject(obpile_t *op, char *title, int *count, int opts, enum OBCLASS obclass, enum FLAG withflag);
|
||||||
cell_t *askcoords(char *prompt);
|
int askobjectmulti(obpile_t *op, char *prompt, int opts);
|
||||||
|
char askchar(char *prompt, char *validchars, char *def, int showchars);
|
||||||
|
cell_t *askcoords(char *prompt, int targettype);
|
||||||
|
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||||
void centre(WINDOW *win, int y, char *format, ... );
|
void centre(WINDOW *win, int y, char *format, ... );
|
||||||
int chartodir(char ch);
|
int chartodir(char ch);
|
||||||
|
int cleanupgfx(void);
|
||||||
void clearmsg(void);
|
void clearmsg(void);
|
||||||
|
void real_clearmsg(int force);
|
||||||
|
void clearretobs(void);
|
||||||
|
void cls(void);
|
||||||
void describeob(object_t *o);
|
void describeob(object_t *o);
|
||||||
void dodrop(obpile_t *op);
|
void doattackcell(char dirch);
|
||||||
|
void doclose(void);
|
||||||
|
void dodrop(obpile_t *op, int wantmulti);
|
||||||
|
void doeat(obpile_t *op);
|
||||||
|
void doenter(lifeform_t *lf);
|
||||||
|
void doexplain(void);
|
||||||
|
void dofinaloblist(obpile_t *op);
|
||||||
|
void dofire(void);
|
||||||
void doinventory(obpile_t *op);
|
void doinventory(obpile_t *op);
|
||||||
void doknowledgelist(void);
|
void doknowledgelist(void);
|
||||||
|
void dolook(cell_t *where);
|
||||||
|
void domagic(enum OBTYPE spellid, int cellx, int celly);
|
||||||
|
void domsghist(void);
|
||||||
|
void dooperate(obpile_t *op);
|
||||||
int dopickup(obpile_t *op);
|
int dopickup(obpile_t *op);
|
||||||
|
void dolockpick(obpile_t *op);
|
||||||
|
void donextguntarget(void);
|
||||||
|
void dopour(obpile_t *op);
|
||||||
|
void doquit(void);
|
||||||
void doquaff(obpile_t *op);
|
void doquaff(obpile_t *op);
|
||||||
void doread(obpile_t *op);
|
void doread(obpile_t *op);
|
||||||
|
void dorest(void);
|
||||||
|
void doselguntarget(void);
|
||||||
|
void dostairs(int dir);
|
||||||
int dotakeoff(obpile_t *op);
|
int dotakeoff(obpile_t *op);
|
||||||
void dothrow(obpile_t *op);
|
void dothrow(obpile_t *op);
|
||||||
|
void dovendingmachine(lifeform_t *lf, object_t *vm);
|
||||||
int dowear(obpile_t *op);
|
int dowear(obpile_t *op);
|
||||||
int doweild(obpile_t *op);
|
int doweild(obpile_t *op);
|
||||||
void drawunviscell(cell_t *cell, int x, int y);
|
void drawunviscell(cell_t *cell, int x, int y);
|
||||||
|
@ -27,17 +62,25 @@ void drawlevelfor(lifeform_t *lf);
|
||||||
void drawmsg(void);
|
void drawmsg(void);
|
||||||
void drawscreen(void);
|
void drawscreen(void);
|
||||||
void drawstatus(void);
|
void drawstatus(void);
|
||||||
|
int drop(object_t *o, int count);
|
||||||
|
char getchoice(prompt_t *prompt);
|
||||||
|
char getchoicestr(prompt_t *prompt);
|
||||||
int getkey(void);
|
int getkey(void);
|
||||||
void handleinput(void);
|
void handleinput(void);
|
||||||
|
void initgfx(void);
|
||||||
|
void initprompt(prompt_t *p, char *q1);
|
||||||
int keycodetokey(int keycode);
|
int keycodetokey(int keycode);
|
||||||
void more(void);
|
void more(void);
|
||||||
|
void warn(char *format, ... );
|
||||||
void msg(char *format, ... );
|
void msg(char *format, ... );
|
||||||
int pickup(lifeform_t *lf, object_t *what, int howmany);
|
void msglower(char *format, ... );
|
||||||
|
void msg_real(char *format, ... );
|
||||||
|
void nothinghappens(void);
|
||||||
void dblog(char *format, ... );
|
void dblog(char *format, ... );
|
||||||
void redraw(void);
|
void redraw(void);
|
||||||
int savequit(void);
|
int savequit(void);
|
||||||
int takeoff(lifeform_t *lf, object_t *o);
|
void showlfarmour(lifeform_t *lf);
|
||||||
|
void showlfstats(lifeform_t *lf, int showall);
|
||||||
void tombstone(lifeform_t *lf);
|
void tombstone(lifeform_t *lf);
|
||||||
|
void updatestatus(void);
|
||||||
void updateviewfor(cell_t *cell);
|
void updateviewfor(cell_t *cell);
|
||||||
int wear(lifeform_t *lf, object_t *o);
|
|
||||||
int weild(lifeform_t *lf, object_t *o);
|
|
||||||
|
|
144
lf.h
144
lf.h
|
@ -1,34 +1,162 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
|
||||||
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
|
lifeform_t *addlf(cell_t *cell, enum RACE rid, int level);
|
||||||
race_t *addrace(enum RACE id, char *name, char glyph);
|
lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller);
|
||||||
|
job_t *addjob(enum JOB id, char *name);
|
||||||
|
race_t *addrace(enum RACE id, char *name, float weight, char glyph, enum MATERIAL mat);
|
||||||
|
void adjustdamlf(lifeform_t *lf, unsigned int *amt, enum DAMTYPE damtype);
|
||||||
|
void autotarget(lifeform_t *lf);
|
||||||
|
void autoweild(lifeform_t *lf);
|
||||||
|
int appearsrandomly(enum RACE rid);
|
||||||
|
void bleed(lifeform_t *lf);
|
||||||
|
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost);
|
||||||
|
int caneat(lifeform_t *lf, object_t *o);
|
||||||
|
int canhear(lifeform_t *lf, cell_t *c);
|
||||||
int canpickup(lifeform_t *lf, object_t *o);
|
int canpickup(lifeform_t *lf, object_t *o);
|
||||||
int canwear(lifeform_t *lf, object_t *o);
|
int canpush(lifeform_t *lf, object_t *o, int dir);
|
||||||
|
int canquaff(lifeform_t *lf, object_t *o);
|
||||||
|
int canrest(lifeform_t *lf);
|
||||||
|
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
|
||||||
int canweild(lifeform_t *lf, object_t *o);
|
int canweild(lifeform_t *lf, object_t *o);
|
||||||
int cantakeoff(lifeform_t *lf, object_t *o);
|
int cantakeoff(lifeform_t *lf, object_t *o);
|
||||||
|
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell);
|
||||||
void die(lifeform_t *lf);
|
void die(lifeform_t *lf);
|
||||||
|
void dumplf(void);
|
||||||
|
int eat(lifeform_t *lf, object_t *o);
|
||||||
|
object_t *eyesshaded(lifeform_t *lf);
|
||||||
void fightback(lifeform_t *lf, lifeform_t *attacker);
|
void fightback(lifeform_t *lf, lifeform_t *attacker);
|
||||||
|
job_t *findjob(enum JOB jobid);
|
||||||
lifeform_t *findlf(map_t *m, int lfid);
|
lifeform_t *findlf(map_t *m, int lfid);
|
||||||
race_t *findrace(enum RACE id);
|
race_t *findrace(enum RACE id);
|
||||||
|
race_t *findracebyname(char *name);
|
||||||
|
int flee(lifeform_t *lf);
|
||||||
void gainhp(lifeform_t *lf, int amt);
|
void gainhp(lifeform_t *lf, int amt);
|
||||||
int getarmour(lifeform_t *lf);
|
void gainlevel(lifeform_t *lf);
|
||||||
|
void gainmp(lifeform_t *lf, int amt);
|
||||||
|
void gainxp(lifeform_t *lf, long amt);
|
||||||
|
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||||
|
int getarmourrating(lifeform_t *lf);
|
||||||
|
int getattackspeed(lifeform_t *lf);
|
||||||
|
int getattr(lifeform_t *lf, enum ATTRIB attr);
|
||||||
|
int getdexmod(lifeform_t *lf);
|
||||||
|
int getevasion(lifeform_t *lf);
|
||||||
|
object_t *getbestmissile(lifeform_t *lf);
|
||||||
object_t *getbestweapon(lifeform_t *lf);
|
object_t *getbestweapon(lifeform_t *lf);
|
||||||
|
object_t *getbestfirearm(lifeform_t *lf);
|
||||||
|
int getbodyparthitchance(enum BODYPART bp);
|
||||||
char *getbodypartname(enum BODYPART bp);
|
char *getbodypartname(enum BODYPART bp);
|
||||||
char *getbodypartequipname(enum BODYPART bp);
|
char *getbodypartequipname(enum BODYPART bp);
|
||||||
object_t *getequippedob(obpile_t *op, enum BODYPART bp);
|
object_t *getequippedob(obpile_t *op, enum BODYPART bp);
|
||||||
int getlfattackspeed(lifeform_t *lf);
|
object_t *getfirearm(lifeform_t *lf);
|
||||||
|
lifeform_t *getguntarget(lifeform_t *lf);
|
||||||
|
int getguntargetid(lifeform_t *lf);
|
||||||
|
//int gethealtime(lifeform_t *lf);
|
||||||
|
int gethearingrange(lifeform_t *lf);
|
||||||
|
enum HUNGER gethungerlevel(int hunger);
|
||||||
|
char * gethungername(enum HUNGER hunger, char *buf);
|
||||||
|
int gethungerval(lifeform_t *lf);
|
||||||
|
job_t *getjob(lifeform_t *lf);
|
||||||
|
int getlfaccuracy(lifeform_t *lf);
|
||||||
|
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||||
|
int getnightvisrange(lifeform_t *lf);
|
||||||
|
char *getlfconditionname(enum LFCONDITION cond);
|
||||||
|
char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer);
|
||||||
|
enum MATERIAL getlfmaterial(lifeform_t *lf);
|
||||||
|
float getmaxcarryweight(lifeform_t *lf);
|
||||||
|
float getmaxliftweight(lifeform_t *lf);
|
||||||
|
float getmaxpushweight(lifeform_t *lf);
|
||||||
|
int getvisrange(lifeform_t *lf);
|
||||||
int getmovespeed(lifeform_t *lf);
|
int getmovespeed(lifeform_t *lf);
|
||||||
|
char *getmoveverb(lifeform_t *lf);
|
||||||
char *getlfname(lifeform_t *lf, char *buf);
|
char *getlfname(lifeform_t *lf, char *buf);
|
||||||
race_t *getrandomlf(map_t *map, int *level);
|
char *getlfnamea(lifeform_t *lf, char *buf);
|
||||||
|
enum LFSIZE getlfsize(lifeform_t *lf);
|
||||||
|
float getlfweight(lifeform_t *lf, int withobs);
|
||||||
|
int getspellspeed(lifeform_t *lf);
|
||||||
|
char *getplayername(char *buf);
|
||||||
|
char *getplayernamefull(char *buf);
|
||||||
|
object_t *getrandomarmour(lifeform_t *lf);
|
||||||
|
//int getrandommonlevel(int depth);
|
||||||
|
race_t *getrandomrace(map_t *map);
|
||||||
|
race_t *getreallyrandomrace(void);
|
||||||
char *getspeedname(int speed, char *buf);
|
char *getspeedname(int speed, char *buf);
|
||||||
|
float getstatmod(lifeform_t *lf, enum ATTRIB att);
|
||||||
|
enum STRBRACKET getstrname(int str, char *buf);
|
||||||
|
enum DEXBRACKET getdexname(int dex, char *buf);
|
||||||
|
enum IQBRACKET getiqname(int iq, char *buf);
|
||||||
|
int getthrowspeed(int str);
|
||||||
|
int getunarmedattackspeed(lifeform_t *lf);
|
||||||
object_t *getweapon(lifeform_t *lf);
|
object_t *getweapon(lifeform_t *lf);
|
||||||
|
long getxpforlev(int level);
|
||||||
|
void givejob(lifeform_t *lf, enum JOB jobid);
|
||||||
|
void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype);
|
||||||
|
void givestartobs(lifeform_t *lf, flagpile_t *fp);
|
||||||
|
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
|
||||||
|
job_t *hasjob(lifeform_t *lf, enum JOB job);
|
||||||
|
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
|
||||||
|
flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
|
||||||
|
flag_t *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
|
||||||
|
flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
|
||||||
|
int lockpick(lifeform_t *lf, object_t *target, object_t *device);
|
||||||
|
void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
||||||
int haslof(lifeform_t *viewer, cell_t *dest);
|
int haslof(lifeform_t *viewer, cell_t *dest);
|
||||||
int haslos(lifeform_t *viewer, cell_t *dest);
|
int haslos(lifeform_t *viewer, cell_t *dest);
|
||||||
|
int hasmr(lifeform_t *lf);
|
||||||
|
void initjobs(void);
|
||||||
void initrace(void);
|
void initrace(void);
|
||||||
|
void interrupt(lifeform_t *lf);
|
||||||
|
int isbleeding(lifeform_t *lf);
|
||||||
|
int isblind(lifeform_t *lf);
|
||||||
|
enum BURDENED isburdened(lifeform_t *lf);
|
||||||
int isdead(lifeform_t *lf);
|
int isdead(lifeform_t *lf);
|
||||||
|
int isfleeing(lifeform_t *lf);
|
||||||
|
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||||
|
int isgenius(lifeform_t *lf);
|
||||||
|
int isingunrange(lifeform_t *lf, cell_t *where);
|
||||||
|
int isimmobile(lifeform_t *lf);
|
||||||
|
int ispeaceful(lifeform_t *lf);
|
||||||
|
int isplayer(lifeform_t *lf);
|
||||||
|
int ispolymorphed(lifeform_t *lf);
|
||||||
|
void killjob(job_t *job);
|
||||||
void killlf(lifeform_t *lf);
|
void killlf(lifeform_t *lf);
|
||||||
void killrace(race_t *race);
|
void killrace(race_t *race);
|
||||||
void losehp(lifeform_t *lf, int amt, int damtype, lifeform_t *fromlf, char *damsrc);
|
int losehp(lifeform_t *lf, unsigned int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc);
|
||||||
|
int losehp_real(lifeform_t *lf, unsigned int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam);
|
||||||
|
void makenoise(lifeform_t *lf, enum NOISETYPE nid);
|
||||||
|
void maycastspellschool(flagpile_t *fp, enum SPELLSCHOOL ss);
|
||||||
|
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
||||||
|
void modhunger(lifeform_t *lf, int amt);
|
||||||
void outfitlf(lifeform_t *lf);
|
void outfitlf(lifeform_t *lf);
|
||||||
void taketime(lifeform_t *lf, int howlong);
|
int pickup(lifeform_t *lf, object_t *what, int howmany);
|
||||||
|
void precalclos(lifeform_t *lf);
|
||||||
|
int push(lifeform_t *lf, object_t *o, int dir);
|
||||||
|
void relinklf(lifeform_t *src, map_t *dst);
|
||||||
|
int rest(lifeform_t *lf, int onpurpose);
|
||||||
|
void startresting(lifeform_t *lf);
|
||||||
|
int rolldex(enum DEXBRACKET bracket);
|
||||||
|
int rolliq(enum IQBRACKET bracket);
|
||||||
|
int rollstr(enum STRBRACKET bracket);
|
||||||
|
int savingthrow(lifeform_t *lf, enum ATTRIB attr);
|
||||||
|
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong);
|
||||||
|
int setammo(lifeform_t *lf, object_t *o);
|
||||||
|
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
||||||
|
void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
||||||
|
void setrace(lifeform_t *lf, enum RACE rid);
|
||||||
|
void setlastdam(lifeform_t *lf, char *buf);
|
||||||
|
int shoot(lifeform_t *lf);
|
||||||
|
void sortlf(map_t *map, lifeform_t *lf);
|
||||||
|
void stopresting(lifeform_t *lf);
|
||||||
|
void stoprunning(lifeform_t *lf);
|
||||||
|
int takeoff(lifeform_t *lf, object_t *o);
|
||||||
|
void taketime(lifeform_t *lf, long howlong);
|
||||||
|
int throwat(lifeform_t *thrower, object_t *o, cell_t *where);
|
||||||
|
void timeeffectslf(lifeform_t *lf);
|
||||||
|
void turneffectslf(lifeform_t *lf);
|
||||||
|
int touch(lifeform_t *lf, object_t *o);
|
||||||
|
int unweild(lifeform_t *lf, object_t *o);
|
||||||
|
int useability(lifeform_t *lf, enum OBTYPE aid);
|
||||||
|
int usestairs(lifeform_t *lf, object_t *o);
|
||||||
|
int validateraces(void);
|
||||||
|
int wear(lifeform_t *lf, object_t *o);
|
||||||
|
int weild(lifeform_t *lf, object_t *o);
|
||||||
|
int youhear(cell_t *c, char *text);
|
||||||
|
|
713
map.c
713
map.c
|
@ -4,15 +4,21 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "flag.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "move.h"
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
#include "text.h"
|
||||||
|
|
||||||
extern map_t *firstmap,*lastmap;
|
extern map_t *firstmap,*lastmap;
|
||||||
extern int viewx,viewy,vieww,viewh;
|
extern int viewx,viewy,vieww,viewh;
|
||||||
extern lifeform_t *player;
|
extern lifeform_t *player;
|
||||||
|
|
||||||
|
extern enum OBCLASS sortorder[];
|
||||||
|
|
||||||
cell_t *addcell(map_t *m, int x, int y) {
|
cell_t *addcell(map_t *m, int x, int y) {
|
||||||
cell_t *cell;
|
cell_t *cell;
|
||||||
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
|
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
|
||||||
|
@ -25,6 +31,9 @@ cell_t *addcell(map_t *m, int x, int y) {
|
||||||
cell->obpile = addobpile(NOOWNER, cell);
|
cell->obpile = addobpile(NOOWNER, cell);
|
||||||
cell->lf = NULL;
|
cell->lf = NULL;
|
||||||
cell->roomid = -1;
|
cell->roomid = -1;
|
||||||
|
cell->lit = B_FALSE;
|
||||||
|
cell->writing = NULL;
|
||||||
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_t *addmap(void) {
|
map_t *addmap(void) {
|
||||||
|
@ -56,35 +65,216 @@ map_t *addmap(void) {
|
||||||
// props
|
// props
|
||||||
a->id = id;
|
a->id = id;
|
||||||
a->lf = NULL;
|
a->lf = NULL;
|
||||||
a->nextlfid = 0;
|
|
||||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||||
a->nextmap[i] = -1;
|
a->nextmap[i] = -1;
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addrandomthing(cell_t *c) {
|
|
||||||
char buf[BUFLEN];
|
lifeform_t *addmonster(cell_t *c, enum RACE raceid) {
|
||||||
int level;
|
lifeform_t *lf = NULL;
|
||||||
race_t *r;
|
race_t *r;
|
||||||
|
|
||||||
|
// ie. don't create mosnters on closed doors!
|
||||||
|
if (!cellwalkable(NULL, c, NULL)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((raceid == R_NONE) || (raceid == R_RANDOM)) {
|
||||||
|
r = getrandomrace(c->map);
|
||||||
|
} else {
|
||||||
|
r = findrace(raceid);
|
||||||
|
}
|
||||||
|
assert(r);
|
||||||
|
|
||||||
|
dblog("adding rand lf %s to cell %d,%d",r->name,c->x,c->y);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
//lf = addlf(c, r->id, getrandommonlevel(c->map->depth));
|
||||||
|
lf = addlf(c, r->id, 1);
|
||||||
|
if (lf) {
|
||||||
|
int amt;
|
||||||
|
flag_t *f;
|
||||||
|
// appears in groups?
|
||||||
|
f = hasflag(lf->flags, F_NUMAPPEAR);
|
||||||
|
if (f) {
|
||||||
|
amt = rnd(f->val[0], f->val[1]);
|
||||||
|
} else {
|
||||||
|
amt = 1;
|
||||||
|
}
|
||||||
|
if (amt > 1) {
|
||||||
|
cell_t *adjcell;
|
||||||
|
amt--; // we've already added one
|
||||||
|
adjcell = c;
|
||||||
|
for ( ; amt > 0; amt--) {
|
||||||
|
// add more in adjacent cells
|
||||||
|
adjcell = getrandomadjcell(adjcell, WE_NOTSOLID);
|
||||||
|
if (!adjcell) break;
|
||||||
|
|
||||||
|
//lf = addlf(adjcell, r->id, getrandommonlevel(adjcell->map->depth));
|
||||||
|
lf = addlf(adjcell, r->id, 1);
|
||||||
|
if (!lf) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addrandomob(cell_t *c) {
|
||||||
|
char buf[BUFLEN];
|
||||||
|
|
||||||
|
if (c->type->solid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getrandomob(c->map, buf)) {
|
||||||
|
dblog("adding rand obj %s to cell %d,%d",buf,c->x,c->y);
|
||||||
|
addob(c->obpile, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addrandomthing(cell_t *c) {
|
||||||
// if there's already someone there,
|
// if there's already someone there,
|
||||||
// then add an object.
|
// then add an object.
|
||||||
if (c->lf || (rnd(1,2) == 1)) {
|
if (c->lf || (rnd(1,2) == 1)) {
|
||||||
// object
|
// object
|
||||||
if (getrandomob(c->map, buf)) {
|
addrandomob(c);
|
||||||
dblog("adding %s to cell %d,%d",buf,c->x,c->y);
|
|
||||||
addob(c->obpile, buf);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
r = getrandomlf(c->map, &level);
|
// monster
|
||||||
if (r) {
|
addmonster(c, R_RANDOM);
|
||||||
dblog("adding %s to cell %d,%d",buf,c->x,c->y);
|
|
||||||
addlf(c, r->id, level);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cellhaslos(cell_t *c1, cell_t *dest) {
|
||||||
|
int deltax, deltay;
|
||||||
|
int numpixels;
|
||||||
|
int d;
|
||||||
|
int dinc1,dinc2,xinc1,xinc2,yinc1,yinc2;
|
||||||
|
int xinc,yinc,dinc;
|
||||||
|
int i;
|
||||||
|
int x1,y1;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
//int wentuphill = B_FALSE;
|
||||||
|
//int origheight;
|
||||||
|
//int shopwall;
|
||||||
|
int x2,y2;
|
||||||
|
map_t *map;
|
||||||
|
|
||||||
|
if (!dest) return B_FALSE;
|
||||||
|
|
||||||
|
// let the player see when dead, otherwise the screen wil
|
||||||
|
// go black when "You die" appears.
|
||||||
|
map = c1->map;
|
||||||
|
|
||||||
|
|
||||||
|
x1 = c1->x;
|
||||||
|
y1 = c1->y;
|
||||||
|
x2 = dest->x;
|
||||||
|
y2 = dest->y;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
deltax = (x2 - x1);
|
||||||
|
if (deltax < 0) deltax = -deltax;
|
||||||
|
deltay = (y2 - y1);
|
||||||
|
if (deltay < 0) deltay = -deltay;
|
||||||
|
|
||||||
|
// can always see your own cell
|
||||||
|
if ((deltax == 0) && (deltay == 0)) {
|
||||||
|
//if (viewer->controller == C_HUMAN) wreck->mazelev[z].maze[y2*MAZEW+x2].known = B_PERM;
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deltax >= deltay) {
|
||||||
|
numpixels = deltax + 1;
|
||||||
|
d = (deltay*2) - deltax;
|
||||||
|
dinc1 = deltay << 1;
|
||||||
|
dinc2 = (deltay-deltax) << 1;
|
||||||
|
xinc1 = 1;
|
||||||
|
xinc2 = 1;
|
||||||
|
yinc1 = 0;
|
||||||
|
yinc2 = 1;
|
||||||
|
} else {
|
||||||
|
numpixels = deltay + 1;
|
||||||
|
d = (deltax*2) - deltay;
|
||||||
|
dinc1 = deltax << 1;
|
||||||
|
dinc2 = (deltax - deltay) << 1;
|
||||||
|
xinc1 = 0;
|
||||||
|
xinc2 = 1;
|
||||||
|
yinc1 = 1;
|
||||||
|
yinc2 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x1 > x2) {
|
||||||
|
xinc1 = - xinc1;
|
||||||
|
xinc2 = - xinc2;
|
||||||
|
}
|
||||||
|
if (y1 > y2) {
|
||||||
|
yinc1 = - yinc1;
|
||||||
|
yinc2 = - yinc2;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = x1; y = y1;
|
||||||
|
|
||||||
|
for (i = 0; i < numpixels ; i++) {
|
||||||
|
cell_t *cell;
|
||||||
|
|
||||||
|
// don't need to move out of the last one
|
||||||
|
if ((x == x2) && (y == y2)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d < 0) {
|
||||||
|
xinc = xinc1;
|
||||||
|
yinc = yinc1;
|
||||||
|
dinc = dinc1;
|
||||||
|
} else {
|
||||||
|
xinc = xinc2;
|
||||||
|
yinc = yinc2;
|
||||||
|
dinc = dinc2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// you can always see your own cell
|
||||||
|
if (i != 0) {
|
||||||
|
// solid cells stop los - but if you are standing on a solid
|
||||||
|
// cell you can still see out.
|
||||||
|
cell = getcellat(map, x, y);
|
||||||
|
if (!cell->type->transparent) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// check for smoke
|
||||||
|
if ((x != x1) || (y != y1)) { // if not in first cell
|
||||||
|
if (hasopaqueobject(viewer, x,y,z) && (getheight(x,y,z) >= origheight)) {
|
||||||
|
if (!hasproplf(viewer, P_SEEINSMOKE)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// check for objects which block view
|
||||||
|
if (hasobwithflag(cell->obpile, F_BLOCKSVIEW)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next cell
|
||||||
|
d += dinc;
|
||||||
|
x += xinc;
|
||||||
|
y += yinc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// made it to the target cell!
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
cell_t *getcellat(map_t *map, int x, int y) {
|
cell_t *getcellat(map_t *map, int x, int y) {
|
||||||
if (!isonmap(map, x, y)) return NULL;
|
if (!isonmap(map, x, y)) return NULL;
|
||||||
return map->cell[y*map->w + x];
|
return map->cell[y*map->w + x];
|
||||||
|
@ -98,6 +288,87 @@ int getcelldist(cell_t *src, cell_t *dst) {
|
||||||
return (int)sqrt(xd*xd + yd*yd);
|
return (int)sqrt(xd*xd + yd*yd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getcelldistorth(cell_t *src, cell_t *dst) { // add x/y
|
||||||
|
return abs(dst->x - src->x) + abs(dst->y - src->y);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CELLTYPE getemptycelltype(enum HABITAT hab) {
|
||||||
|
switch (hab) {
|
||||||
|
case H_DUNGEON:
|
||||||
|
return CT_CORRIDOR;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CT_CORRIDOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_t *gettopobject(cell_t *where) {
|
||||||
|
object_t *o;
|
||||||
|
int c;
|
||||||
|
// draw highest object in sort order
|
||||||
|
c = 0;
|
||||||
|
while (sortorder[c] != OC_NULL) {
|
||||||
|
// check each object against this ob class
|
||||||
|
// count backwards so more recently dropped objects
|
||||||
|
// appear first.
|
||||||
|
for (o = where->obpile->last ; o ; o = o->prev) {
|
||||||
|
if (o->type->obclass->id == sortorder[c]) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calclight(map_t *map) {
|
||||||
|
int x,y;
|
||||||
|
cell_t *c;
|
||||||
|
for (y = 0; y < map->h; y++) {
|
||||||
|
for (x = 0; x < map->w; x++) {
|
||||||
|
c = getcellat(map, x,y);
|
||||||
|
if (c && (c->lit != B_PERM)) c->lit = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (y = 0; y < map->h; y++) {
|
||||||
|
for (x = 0; x < map->w; x++) {
|
||||||
|
c = getcellat(map, x,y);
|
||||||
|
if (c) {
|
||||||
|
int radius;
|
||||||
|
object_t *o;
|
||||||
|
// lit based on depth
|
||||||
|
if (map->depth <= 5) {
|
||||||
|
c->lit = B_PERM;
|
||||||
|
}
|
||||||
|
// has lightproducing lf? (ie.hasflag f_produceslight)
|
||||||
|
if (c->lf) {
|
||||||
|
if (lfhasflag(c->lf, F_PRODUCESLIGHT)) {
|
||||||
|
sumflags(c->lf->flags, F_PRODUCESLIGHT, &radius, NULL, NULL);
|
||||||
|
|
||||||
|
makelitradius(c, radius, B_TEMP);
|
||||||
|
}
|
||||||
|
// objects in hands or on body...
|
||||||
|
for (o = c->lf->pack->first ; o ; o = o->next) {
|
||||||
|
if (obproduceslight(o) && isequipped(o)) {
|
||||||
|
sumflags(o->flags, F_PRODUCESLIGHT, &radius, NULL, NULL);
|
||||||
|
|
||||||
|
makelitradius(c, radius, B_TEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// has light-producing object on ground?
|
||||||
|
for (o = c->obpile->first ; o ; o = o->next) {
|
||||||
|
if (obproduceslight(o)) {
|
||||||
|
sumflags(o->flags, F_PRODUCESLIGHT, &radius, NULL, NULL);
|
||||||
|
makelitradius(c, radius, B_TEMP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by) {
|
int calcroompos(map_t *map, int w, int h, int *bx, int *by) {
|
||||||
int x,y;
|
int x,y;
|
||||||
int bestx = -1, besty = -1;
|
int bestx = -1, besty = -1;
|
||||||
|
@ -159,6 +430,19 @@ int calcroompos(map_t *map, int w, int h, int *bx, int *by) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int countadjcellswithflag(cell_t *cell, enum FLAG fid) {
|
||||||
|
int d;
|
||||||
|
int count = 0;
|
||||||
|
cell_t *newcell;
|
||||||
|
for (d = D_N; d < MAXDIR_ORTH; d++) {
|
||||||
|
newcell = getcellindir(cell, d);
|
||||||
|
if (newcell && hasobwithflag(cell->obpile, fid)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
int countadjcellsoftype(cell_t *cell, int id) {
|
int countadjcellsoftype(cell_t *cell, int id) {
|
||||||
int d;
|
int d;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -193,11 +477,10 @@ int countcellexits(cell_t *cell) {
|
||||||
looppct = percentage change of turning dead-end into loop
|
looppct = percentage change of turning dead-end into loop
|
||||||
maxrooms = max # of rooms
|
maxrooms = max # of rooms
|
||||||
*/
|
*/
|
||||||
void createmap(map_t *map, int habitat) {
|
void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_t *returnstairtype) {
|
||||||
lifeform_t *lf;
|
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
int wantrooms = B_TRUE;
|
int wantrooms = B_TRUE;
|
||||||
int x,y,newx,newy;
|
int x,y;
|
||||||
int d;
|
int d;
|
||||||
int i;
|
int i;
|
||||||
int done,unused;
|
int done,unused;
|
||||||
|
@ -212,9 +495,10 @@ void createmap(map_t *map, int habitat) {
|
||||||
int maxroomh = MAX_ROOMH;
|
int maxroomh = MAX_ROOMH;
|
||||||
int bestx,besty;
|
int bestx,besty;
|
||||||
int w,h;
|
int w,h;
|
||||||
int startdir,forcex,forcey,ntries;
|
objecttype_t *ot;
|
||||||
cell_t *cell;
|
//int startdir,forcex,forcey,ntries;
|
||||||
//object_t *o;
|
cell_t *cell, *c;
|
||||||
|
object_t *o;
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
int turnpct = DEF_TURNPCT;
|
int turnpct = DEF_TURNPCT;
|
||||||
|
@ -225,7 +509,9 @@ void createmap(map_t *map, int habitat) {
|
||||||
|
|
||||||
int moved = 0;
|
int moved = 0;
|
||||||
|
|
||||||
int db = B_TRUE;
|
enum CELLTYPE emptycell;
|
||||||
|
|
||||||
|
//int db = B_TRUE;
|
||||||
|
|
||||||
sprintf(buf, "Map %d",map->id);
|
sprintf(buf, "Map %d",map->id);
|
||||||
map->name = strdup(buf);
|
map->name = strdup(buf);
|
||||||
|
@ -238,8 +524,13 @@ void createmap(map_t *map, int habitat) {
|
||||||
map->w = MAX_MAPW;
|
map->w = MAX_MAPW;
|
||||||
map->h = MAX_MAPH;
|
map->h = MAX_MAPH;
|
||||||
|
|
||||||
|
// map depth?
|
||||||
|
map->depth = depth;
|
||||||
|
|
||||||
// rememebr seed
|
// rememebr seed
|
||||||
|
//map->seed = 11734;
|
||||||
map->seed = rand() % 65535;
|
map->seed = rand() % 65535;
|
||||||
|
srand(map->seed);
|
||||||
|
|
||||||
// fill entire maze with walls
|
// fill entire maze with walls
|
||||||
for (y = 0; y < map->h; y++) {
|
for (y = 0; y < map->h; y++) {
|
||||||
|
@ -248,9 +539,14 @@ void createmap(map_t *map, int habitat) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// what kind of cells will 'empty' ones be?
|
||||||
|
emptycell = getemptycelltype(map->habitat);
|
||||||
|
|
||||||
// pick initial random spot
|
// pick initial random spot
|
||||||
cell = getrandomcell(map);
|
cell = getrandomcell(map);
|
||||||
setcelltype(cell, CT_CORRIDOR);
|
|
||||||
|
setcelltype(cell, emptycell);
|
||||||
cell->visited = B_TRUE;
|
cell->visited = B_TRUE;
|
||||||
//if (db) printf("- Starting (%d,%d)\n",cell->x, cell->y);
|
//if (db) printf("- Starting (%d,%d)\n",cell->x, cell->y);
|
||||||
|
|
||||||
|
@ -279,7 +575,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
|
|
||||||
// pick new EMPTY random spot
|
// pick new EMPTY random spot
|
||||||
cell = getrandomcell(map);
|
cell = getrandomcell(map);
|
||||||
while (cell->type->solid) {
|
while (!isempty(cell)) {
|
||||||
cell = getrandomcell(map);
|
cell = getrandomcell(map);
|
||||||
}
|
}
|
||||||
//if (db) printf("--- Couldn't find a valid direction. Jumped to (%d,%d).\n",cell->x, cell->y);
|
//if (db) printf("--- Couldn't find a valid direction. Jumped to (%d,%d).\n",cell->x, cell->y);
|
||||||
|
@ -298,7 +594,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
moved++;
|
moved++;
|
||||||
|
|
||||||
// blank it
|
// blank it
|
||||||
setcelltype(cell,CT_CORRIDOR);
|
setcelltype(cell,emptycell);
|
||||||
cell->visited = B_TRUE;
|
cell->visited = B_TRUE;
|
||||||
// mark surrounding cells as visited
|
// mark surrounding cells as visited
|
||||||
for (d = DC_N; d < MAXDIR_COMPASS; d++) {
|
for (d = DC_N; d < MAXDIR_COMPASS; d++) {
|
||||||
|
@ -399,7 +695,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
connected = B_TRUE;
|
connected = B_TRUE;
|
||||||
} else {
|
} else {
|
||||||
// blank adjacent cell
|
// blank adjacent cell
|
||||||
setcelltype(newcell, CT_CORRIDOR);
|
setcelltype(newcell, emptycell);
|
||||||
newcell->visited = B_TRUE;
|
newcell->visited = B_TRUE;
|
||||||
}
|
}
|
||||||
cell = newcell;
|
cell = newcell;
|
||||||
|
@ -454,6 +750,29 @@ void createmap(map_t *map, int habitat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// add return staircase to previous map
|
||||||
|
c = NULL;
|
||||||
|
while (!c || !isempty(c) || countobs(c->obpile)) {
|
||||||
|
c = getrandomroomcell(map, ANYROOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
o = addob(c->obpile, returnstairtype->name);
|
||||||
|
if (parentmap) {
|
||||||
|
addflag(o->flags, F_MAPLINK, parentmap->id, NA, NA, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add staircase continuing on (normally this will be down)
|
||||||
|
if ((map->depth >= MAXDEPTH) && (returnstairtype->id == OT_STAIRSUP)) {
|
||||||
|
// no need for a down staircase on the last level!
|
||||||
|
} else {
|
||||||
|
c = NULL;
|
||||||
|
while (!c || !isempty(c) || countobs(c->obpile)) {
|
||||||
|
c = getrandomroomcell(map, ANYROOM);
|
||||||
|
}
|
||||||
|
ot = getoppositestairs(returnstairtype);
|
||||||
|
addob(c->obpile, ot->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* void around map
|
/* void around map
|
||||||
// N
|
// N
|
||||||
|
@ -627,9 +946,8 @@ void createmap(map_t *map, int habitat) {
|
||||||
for (y = 0; y < map->h; y++) {
|
for (y = 0; y < map->h; y++) {
|
||||||
for (x = 0; x < map->w; x++) {
|
for (x = 0; x < map->w; x++) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
int obchance;
|
|
||||||
c = getcellat(map, x, y);
|
c = getcellat(map, x, y);
|
||||||
if (c && !c->type->solid) {
|
if (c && isempty(c)) {
|
||||||
if (rnd(1,100) <= getobchance(map->habitat)) {
|
if (rnd(1,100) <= getobchance(map->habitat)) {
|
||||||
addrandomthing(c);
|
addrandomthing(c);
|
||||||
}
|
}
|
||||||
|
@ -641,7 +959,6 @@ void createmap(map_t *map, int habitat) {
|
||||||
// add pillars & objects & monsters to rooms
|
// add pillars & objects & monsters to rooms
|
||||||
for (i = 0; i < numrooms; i++) {
|
for (i = 0; i < numrooms; i++) {
|
||||||
int numobsmin,numobsmax,numobs,n;
|
int numobsmin,numobsmax,numobs,n;
|
||||||
int x,y;
|
|
||||||
int maxpillars;
|
int maxpillars;
|
||||||
|
|
||||||
//dblog("Adding obs to room %d/%d",i+1,numrooms);
|
//dblog("Adding obs to room %d/%d",i+1,numrooms);
|
||||||
|
@ -657,7 +974,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
c = getrandomroomcell(map, i);
|
c = getrandomroomcell(map, i);
|
||||||
|
|
||||||
if (c && !c->type->solid && !countobs(c->obpile)) {
|
if (c && isempty(c) && !countobs(c->obpile)) {
|
||||||
setcelltype(cell, CT_WALL);
|
setcelltype(cell, CT_WALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,7 +988,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
} else {
|
} else {
|
||||||
*/
|
*/
|
||||||
numobsmin = 0;
|
numobsmin = 0;
|
||||||
numobsmax = MAXOF(roomw[i],roomh[i]);
|
numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -689,7 +1006,7 @@ void createmap(map_t *map, int habitat) {
|
||||||
while (!done) {
|
while (!done) {
|
||||||
c = getrandomroomcell(map, i);
|
c = getrandomroomcell(map, i);
|
||||||
// if nothing there
|
// if nothing there
|
||||||
if (c && !countobs(c->obpile)) {
|
if (c && isempty(c) && !countobs(c->obpile)) {
|
||||||
/*
|
/*
|
||||||
if (roomspecial[i]) {
|
if (roomspecial[i]) {
|
||||||
if (getrand(1,4) == 1) { // less chance of monster
|
if (getrand(1,4) == 1) { // less chance of monster
|
||||||
|
@ -901,8 +1218,7 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
if (newcell && !newcell->type->solid) {
|
if (newcell && !newcell->type->solid) {
|
||||||
int doorcount;
|
int doorcount;
|
||||||
|
|
||||||
doorcount = countadjcellsoftype(cell, CT_DOOROPEN) +
|
doorcount = countadjcellswithflag(cell, F_DOOR);
|
||||||
countadjcellsoftype(cell, CT_DOORCLOSED);
|
|
||||||
|
|
||||||
if (doorcount == 0) {
|
if (doorcount == 0) {
|
||||||
if ((countcellexits(newcell) == 1) &&
|
if ((countcellexits(newcell) == 1) &&
|
||||||
|
@ -934,9 +1250,8 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
if (newcell && !newcell->type->solid) {
|
if (newcell && !newcell->type->solid) {
|
||||||
int doorcount;
|
int doorcount;
|
||||||
|
|
||||||
doorcount = countadjcellsoftype(cell, CT_DOOROPEN) +
|
doorcount = countadjcellswithflag(cell, F_DOOR);
|
||||||
countadjcellsoftype(cell, CT_DOORCLOSED);
|
|
||||||
|
|
||||||
if (doorcount == 0) {
|
if (doorcount == 0) {
|
||||||
if ((countcellexits(newcell) == 1) &&
|
if ((countcellexits(newcell) == 1) &&
|
||||||
(iswallindir(newcell,D_E)) &&
|
(iswallindir(newcell,D_E)) &&
|
||||||
|
@ -966,8 +1281,7 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
newcell = getcellindir(cell, D_W);
|
newcell = getcellindir(cell, D_W);
|
||||||
if (newcell && !newcell->type->solid) {
|
if (newcell && !newcell->type->solid) {
|
||||||
int doorcount;
|
int doorcount;
|
||||||
doorcount = countadjcellsoftype(cell, CT_DOOROPEN) +
|
doorcount = countadjcellswithflag(cell, F_DOOR);
|
||||||
countadjcellsoftype(cell, CT_DOORCLOSED);
|
|
||||||
if (doorcount == 0) {
|
if (doorcount == 0) {
|
||||||
if ((countcellexits(newcell) == 1) &&
|
if ((countcellexits(newcell) == 1) &&
|
||||||
(iswallindir(newcell,D_N)) &&
|
(iswallindir(newcell,D_N)) &&
|
||||||
|
@ -997,8 +1311,7 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
||||||
newcell = getcellindir(cell, D_E);
|
newcell = getcellindir(cell, D_E);
|
||||||
if (newcell && !newcell->type->solid) {
|
if (newcell && !newcell->type->solid) {
|
||||||
int doorcount;
|
int doorcount;
|
||||||
doorcount = countadjcellsoftype(cell, CT_DOOROPEN) +
|
doorcount = countadjcellswithflag(cell, F_DOOR);
|
||||||
countadjcellsoftype(cell, CT_DOORCLOSED);
|
|
||||||
if (doorcount == 0) {
|
if (doorcount == 0) {
|
||||||
if ((countcellexits(newcell) == 1) &&
|
if ((countcellexits(newcell) == 1) &&
|
||||||
(iswallindir(newcell,D_N)) &&
|
(iswallindir(newcell,D_N)) &&
|
||||||
|
@ -1072,6 +1385,7 @@ int dirtoy(int dt, int dir) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1088,6 +1402,54 @@ printf("dump of map '%s' (%d x %d):\n",map->name, map->w, map->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int wantannounce) {
|
||||||
|
int x,y;
|
||||||
|
animradial(c, range, '}');
|
||||||
|
|
||||||
|
if (haslos(player, c)) {
|
||||||
|
if (wantannounce) {
|
||||||
|
msg("You see %s explosion!", (range > 0) ? "a huge" : "an");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
youhear(c, "an explosion!");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = c->y - range ; y <= c->y + range ; y++) {
|
||||||
|
for (x = c->x - range ; x <= c->x + range ; x++) {
|
||||||
|
cell_t *cc;
|
||||||
|
cc = getcellat(c->map, x,y);
|
||||||
|
if (cc && (getcelldist(c, cc) <= range)) {
|
||||||
|
explodesinglecell(cc, dam, killwalls, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
|
||||||
|
if (c->lf) {
|
||||||
|
char buf[BUFLEN];
|
||||||
|
if (o) {
|
||||||
|
getobname(o, obname, 1);
|
||||||
|
sprintf(buf, "an exploding %s",strchr(obname, ' ')+1);
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "an explosion");
|
||||||
|
}
|
||||||
|
losehp(c->lf, dam, DT_EXPLOSIVE, NULL, buf);
|
||||||
|
}
|
||||||
|
damageallobs(o, c->obpile, dam, DT_EXPLOSIVE);
|
||||||
|
|
||||||
|
if (killwalls) {
|
||||||
|
if (c->type->solid) {
|
||||||
|
// make it empty!
|
||||||
|
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||||
|
// add some rubble
|
||||||
|
addob(c->obpile, "10-50 stones");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
map_t *findmap(int mid) {
|
map_t *findmap(int mid) {
|
||||||
map_t *m;
|
map_t *m;
|
||||||
for (m = firstmap ; m ; m = m->next) {
|
for (m = firstmap ; m ; m = m->next) {
|
||||||
|
@ -1096,6 +1458,29 @@ map_t *findmap(int mid) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
map_t *findmapofdepth(int depth) {
|
||||||
|
map_t *m;
|
||||||
|
for (m = firstmap ; m ; m = m->next) {
|
||||||
|
if (m->depth == depth) return m;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the cell in 'map' which contains object oid
|
||||||
|
cell_t *findobinmap(map_t *m, enum OBCLASS oid) {
|
||||||
|
cell_t *c;
|
||||||
|
int x,y;
|
||||||
|
for (y = 0; y < m->h; y++) {
|
||||||
|
for (x = 0; x < m->w; x++) {
|
||||||
|
c = getcellat(m, x, y);
|
||||||
|
if (hasob(c->obpile, oid)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void forgetcells(map_t *map, int amt) {
|
void forgetcells(map_t *map, int amt) {
|
||||||
int amtleft;
|
int amtleft;
|
||||||
//int totcells;
|
//int totcells;
|
||||||
|
@ -1155,6 +1540,8 @@ cell_t *getcellindir(cell_t *cell, int dir) {
|
||||||
case DC_NW:
|
case DC_NW:
|
||||||
dt = DT_COMPASS;
|
dt = DT_COMPASS;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
newx = cell->x + dirtox(dt, dir);
|
newx = cell->x + dirtox(dt, dir);
|
||||||
newy = cell->y + dirtoy(dt, dir);
|
newy = cell->y + dirtoy(dt, dir);
|
||||||
|
@ -1181,8 +1568,6 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!foundvaliddir) { // keep going until we get a valid direction
|
while (!foundvaliddir) { // keep going until we get a valid direction
|
||||||
int newx,newy;
|
|
||||||
|
|
||||||
if (numtries >= MAXDIR_ORTH) { // no valid dirs
|
if (numtries >= MAXDIR_ORTH) { // no valid dirs
|
||||||
return D_NONE; // (pick a new random spot and refresh tried dirs and current dir)
|
return D_NONE; // (pick a new random spot and refresh tried dirs and current dir)
|
||||||
}
|
}
|
||||||
|
@ -1225,6 +1610,10 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
|
||||||
newcell1 = getcellindir(newcell,D_N);
|
newcell1 = getcellindir(newcell,D_N);
|
||||||
newcell2 = getcellindir(newcell,D_S);
|
newcell2 = getcellindir(newcell,D_S);
|
||||||
break;
|
break;
|
||||||
|
default: // should never happen
|
||||||
|
newcell1 = NULL;
|
||||||
|
newcell2 = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newcell1 = NULL;
|
newcell1 = NULL;
|
||||||
|
@ -1275,6 +1664,37 @@ int getobchance(int habitat) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell_t *getrandomadjcell(cell_t *c, int wantempty) {
|
||||||
|
int dir;
|
||||||
|
int ntries = 0;
|
||||||
|
cell_t *new;
|
||||||
|
dir = getrandomdir(DT_COMPASS);
|
||||||
|
while (ntries < 8) {
|
||||||
|
new = getcellindir(c, dir);
|
||||||
|
if (new) {
|
||||||
|
if (wantempty == WE_EMPTY) {
|
||||||
|
// make sure it's empty
|
||||||
|
if (isempty(new)) {
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
} else if (wantempty == WE_NOTSOLID) {
|
||||||
|
if (cellwalkable(NULL, new, NULL)) {
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// always ok
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// not found yet...
|
||||||
|
dir++;
|
||||||
|
if (dir > DC_NW) dir = DC_N;
|
||||||
|
ntries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
cell_t *getrandomcell(map_t *map) {
|
cell_t *getrandomcell(map_t *map) {
|
||||||
int x,y;
|
int x,y;
|
||||||
cell_t *cell;
|
cell_t *cell;
|
||||||
|
@ -1317,9 +1737,20 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
|
||||||
for (x = 0; x < map->w; x++) {
|
for (x = 0; x < map->w; x++) {
|
||||||
c = getcellat(map, x, y);
|
c = getcellat(map, x, y);
|
||||||
// is this cell in the correct room and not a wall?
|
// is this cell in the correct room and not a wall?
|
||||||
if (c && !c->type->solid && (c->roomid == roomid)) {
|
if (c && isempty(c)) {
|
||||||
poss[npossible] = c;
|
int ok = B_FALSE;
|
||||||
npossible++;
|
if (c->roomid == roomid) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else if (roomid == ANYROOM) {
|
||||||
|
if (c->roomid != -1) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
poss[npossible] = c;
|
||||||
|
npossible++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1333,6 +1764,143 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lifeform_t *haslf(cell_t *c) {
|
||||||
|
if (c->lf && !isdead(c->lf)) {
|
||||||
|
return c->lf;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hasobject(cell_t *c) {
|
||||||
|
if (c->obpile->first) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isadjacent(cell_t *src, cell_t *dst) {
|
||||||
|
if (getcelldist(src, dst) == 1) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isdiggable(cell_t *c) {
|
||||||
|
switch (c->type->id) {
|
||||||
|
case CT_WALL: return B_TRUE;
|
||||||
|
case CT_ROOMWALL: return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if isopen provided, returns whether or not the door is opened
|
||||||
|
int isdoor(object_t *o, int *isopen) {
|
||||||
|
int isdoor = B_FALSE;
|
||||||
|
if (hasflag(o->flags, F_DOOR)) {
|
||||||
|
isdoor = B_TRUE;
|
||||||
|
} else {
|
||||||
|
isdoor = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdoor) {
|
||||||
|
if (isopen) {
|
||||||
|
if (hasflag(o->flags, F_OPEN)) {
|
||||||
|
*isopen = B_TRUE;
|
||||||
|
} else {
|
||||||
|
*isopen = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isdoor;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isempty(cell_t *c) {
|
||||||
|
if (!c) return B_FALSE;
|
||||||
|
if (c->type->solid) return B_FALSE;
|
||||||
|
if (c->lf) return B_FALSE;
|
||||||
|
if (!cellwalkable(NULL, c, NULL)) return B_FALSE;
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns TT_ based on what you can scan there
|
||||||
|
int isinscanrange(cell_t *c, void **thing, char *desc, char *glyph) {
|
||||||
|
flag_t *f;
|
||||||
|
// handle scanner
|
||||||
|
f = lfhasflag(player, F_DETECTLIFE);
|
||||||
|
if (f) {
|
||||||
|
if (c->lf) {
|
||||||
|
if (getcelldistorth(player->cell, c) <= f->val[0]) {
|
||||||
|
*thing = c->lf;
|
||||||
|
if (desc) {
|
||||||
|
char *p;
|
||||||
|
p = getsizetext(getlfsize(c->lf));
|
||||||
|
sprintf(desc, "%s %s monster", isvowel(*p) ? "an" : "a", p);
|
||||||
|
}
|
||||||
|
if (glyph) {
|
||||||
|
// select glyph based on size
|
||||||
|
switch(getlfsize(c->lf)) {
|
||||||
|
case SZ_ENORMOUS:
|
||||||
|
*glyph = '6';
|
||||||
|
break;
|
||||||
|
case SZ_HUGE:
|
||||||
|
*glyph = '5';
|
||||||
|
break;
|
||||||
|
case SZ_LARGE:
|
||||||
|
*glyph = '4';
|
||||||
|
break;
|
||||||
|
case SZ_HUMAN:
|
||||||
|
*glyph = '3';
|
||||||
|
break;
|
||||||
|
case SZ_MEDIUM:
|
||||||
|
*glyph = '2';
|
||||||
|
break;
|
||||||
|
case SZ_SMALL:
|
||||||
|
*glyph = '1';
|
||||||
|
break;
|
||||||
|
case SZ_MINI:
|
||||||
|
case SZ_TINY:
|
||||||
|
default:
|
||||||
|
*glyph = '0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TT_MONSTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f = lfhasflag(player, F_DETECTMETAL);
|
||||||
|
if (f) {
|
||||||
|
if (getcelldistorth(player->cell, c) <= f->val[0]) {
|
||||||
|
if (c->lf && ismetal(c->lf->race->material->id) ) {
|
||||||
|
*thing = c->lf;
|
||||||
|
if (glyph) *glyph = '*';
|
||||||
|
if (desc) sprintf(desc, "something metallic");
|
||||||
|
return TT_MONSTER;
|
||||||
|
} else {
|
||||||
|
object_t *o;
|
||||||
|
for (o = c->obpile->first ; o ; o = o->next) {
|
||||||
|
if (ismetal(o->material->id)) {
|
||||||
|
*thing = o;
|
||||||
|
if (glyph) *glyph = '*';
|
||||||
|
if (desc) sprintf(desc, "something metallic");
|
||||||
|
return TT_OBJECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int islit(cell_t *c) {
|
||||||
|
if (c->lit) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int isloopdirok(cell_t *cell, int dir) {
|
int isloopdirok(cell_t *cell, int dir) {
|
||||||
int dirok = B_FALSE;
|
int dirok = B_FALSE;
|
||||||
cell_t *newcell;
|
cell_t *newcell;
|
||||||
|
@ -1393,12 +1961,47 @@ int iswallindir(cell_t *cell, int dir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void makedoor(cell_t *cell) {
|
void makedoor(cell_t *cell) {
|
||||||
setcelltype(cell, CT_DOORCLOSED);
|
object_t *o;
|
||||||
|
setcelltype(cell, getemptycelltype(cell->map->habitat));
|
||||||
|
o = addob(cell->obpile, "wooden door");
|
||||||
|
if (o && (rnd(1,2) == 1)) {
|
||||||
|
opendoor(NULL, o);
|
||||||
|
} else {
|
||||||
|
// door is closed - lock it?
|
||||||
|
if (rnd(1,3) == 1) {
|
||||||
|
addflag(o->flags, F_LOCKED, B_TRUE, NA, NA, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void makelit(cell_t *c, int how) {
|
||||||
|
if (how == B_FALSE) {
|
||||||
|
c->lit = how;
|
||||||
|
} else if (c->lit != B_PERM) { // don't override permenant light with temp light!
|
||||||
|
c->lit = how;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void makelitradius(cell_t *c, int radius, int how) {
|
||||||
|
int x,y;
|
||||||
|
cell_t *c2;
|
||||||
|
|
||||||
|
if (radius <= 0) return;
|
||||||
|
|
||||||
|
for (y = c->y - radius ; y <= c->y + radius; y++) {
|
||||||
|
for (x = c->x - radius ; x <= c->x + radius; x++) {
|
||||||
|
c2 = getcellat(c->map, x, y);
|
||||||
|
if (c2 && (getcelldistorth(c, c2) <= radius)) {
|
||||||
|
if (cellhaslos(c,c2)) {
|
||||||
|
makelit(c2, how);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setcelltype(cell_t *cell, int id) {
|
void setcelltype(cell_t *cell, int id) {
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(cell);
|
assert(cell);
|
||||||
cell->type = findcelltype(id);
|
cell->type = findcelltype(id);
|
||||||
assert(cell->type);
|
assert(cell->type);
|
||||||
|
@ -1409,15 +2012,27 @@ void setcelltype(cell_t *cell, int id) {
|
||||||
void updateknowncells(void) {
|
void updateknowncells(void) {
|
||||||
int x,y;
|
int x,y;
|
||||||
map_t *map;
|
map_t *map;
|
||||||
|
object_t *wep;
|
||||||
|
int seenundead = B_FALSE;
|
||||||
|
|
||||||
|
|
||||||
map = player->cell->map;
|
map = player->cell->map;
|
||||||
|
wep = getweapon(player);
|
||||||
|
|
||||||
for (y = viewy; y < viewy + viewh; y++) {
|
for (y = viewy; y < viewy + viewh; y++) {
|
||||||
for (x = viewx; x < viewx + vieww; x++) {
|
for (x = viewx; x < viewx + vieww; x++) {
|
||||||
cell_t *cell;
|
cell_t *cell;
|
||||||
cell = getcellat(map, x, y);
|
cell = getcellat(map, x, y);
|
||||||
if (cell && !cell->known && haslos(player, cell)) {
|
if (cell) {
|
||||||
cell->known = B_TRUE;
|
//if ((player->cell == cell) || haslos(player, cell)) {
|
||||||
|
if (haslos(player, cell)) {
|
||||||
|
if (!cell->known) {
|
||||||
|
cell->known = B_TRUE;
|
||||||
|
}
|
||||||
|
if (cell->lf && lfhasflag(cell->lf, F_UNDEAD)) {
|
||||||
|
seenundead = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
map.h
25
map.h
|
@ -2,30 +2,53 @@
|
||||||
|
|
||||||
cell_t *addcell(map_t *map, int x, int y);
|
cell_t *addcell(map_t *map, int x, int y);
|
||||||
map_t *addmap(void);
|
map_t *addmap(void);
|
||||||
|
lifeform_t *addmonster(cell_t *c, enum RACE raceid);
|
||||||
|
void addrandomob(cell_t *c);
|
||||||
void addrandomthing(cell_t *c);
|
void addrandomthing(cell_t *c);
|
||||||
|
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||||
cell_t *getcellat(map_t *map, int x, int y);
|
cell_t *getcellat(map_t *map, int x, int y);
|
||||||
int getcelldist(cell_t *src, cell_t *dst);
|
int getcelldist(cell_t *src, cell_t *dst);
|
||||||
|
int getcelldistorth(cell_t *src, cell_t *dst);
|
||||||
|
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
||||||
|
object_t *gettopobject(cell_t *where);
|
||||||
|
void calclight(map_t *map);
|
||||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
||||||
int countadjcellsoftype(cell_t *cell, int id);
|
int countadjcellsoftype(cell_t *cell, int id);
|
||||||
|
int countadjcellswithflag(cell_t *cell, enum FLAG fid);
|
||||||
int countcellexits(cell_t *cell);
|
int countcellexits(cell_t *cell);
|
||||||
void createmap(map_t *map, int habitat);
|
void createmap(map_t *map, int depth, int habitat, map_t *parentmap, objecttype_t *returnstairtype);
|
||||||
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid);
|
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid);
|
||||||
int dirtox(int dt, int dir);
|
int dirtox(int dt, int dir);
|
||||||
int dirtoy(int dt, int dir);
|
int dirtoy(int dt, int dir);
|
||||||
void dumpmap(map_t *map);
|
void dumpmap(map_t *map);
|
||||||
|
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o);
|
||||||
|
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int wantannounce);
|
||||||
map_t *findmap(int mid);
|
map_t *findmap(int mid);
|
||||||
|
map_t *findmapofdepth(int depth);
|
||||||
|
cell_t *findobinmap(map_t *m, enum OBCLASS oid);
|
||||||
void forgetcells(map_t *map, int amt);
|
void forgetcells(map_t *map, int amt);
|
||||||
cell_t *getcellindir(cell_t *cell, int dir);
|
cell_t *getcellindir(cell_t *cell, int dir);
|
||||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||||
int getobchance(int habitat);
|
int getobchance(int habitat);
|
||||||
|
cell_t *getrandomadjcell(cell_t *c, int wantempty);
|
||||||
cell_t *getrandomcell(map_t *map);
|
cell_t *getrandomcell(map_t *map);
|
||||||
cell_t *getrandomcelloftype(map_t *map, int id);
|
cell_t *getrandomcelloftype(map_t *map, int id);
|
||||||
int getrandomdir(int dirtype);
|
int getrandomdir(int dirtype);
|
||||||
cell_t *getrandomroomcell(map_t *map, int roomid);
|
cell_t *getrandomroomcell(map_t *map, int roomid);
|
||||||
|
lifeform_t *haslf(cell_t *c);
|
||||||
|
int hasobject(cell_t *c);
|
||||||
|
int isadjacent(cell_t *src, cell_t *dst);
|
||||||
|
int isdiggable(cell_t *c);
|
||||||
|
int isdoor(object_t *o, int *isopen);
|
||||||
|
int isempty(cell_t *c);
|
||||||
|
int isinscanrange(cell_t *c, void **thing, char *desc, char *glyph);
|
||||||
|
int islit(cell_t *c);
|
||||||
int isloopdirok(cell_t *cell, int dir);
|
int isloopdirok(cell_t *cell, int dir);
|
||||||
int isnewcellok(cell_t *cell, char *err);
|
int isnewcellok(cell_t *cell, char *err);
|
||||||
int isonmap(map_t *map, int x, int y);
|
int isonmap(map_t *map, int x, int y);
|
||||||
int iswallindir(cell_t *cell, int dir);
|
int iswallindir(cell_t *cell, int dir);
|
||||||
void makedoor(cell_t *cell);
|
void makedoor(cell_t *cell);
|
||||||
|
void makelit(cell_t *c, int how);
|
||||||
|
void makelitradius(cell_t *c, int radius, int how);
|
||||||
void setcelltype(cell_t *cell, int id);
|
void setcelltype(cell_t *cell, int id);
|
||||||
void updateknowncells(void);
|
void updateknowncells(void);
|
||||||
|
|
731
move.c
731
move.c
|
@ -1,32 +1,97 @@
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "attack.h"
|
#include "attack.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "flag.h"
|
||||||
|
#include "io.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "move.h"
|
||||||
|
#include "nexus.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
|
||||||
extern lifeform_t *player;
|
extern lifeform_t *player;
|
||||||
|
|
||||||
|
extern int statdirty;
|
||||||
|
|
||||||
|
extern enum ERROR reason;
|
||||||
|
extern void *rdata;
|
||||||
|
|
||||||
|
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
if (canmove(lf, dir, error)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (canmove(lf, dir, error) && willmove(lf, dir, error)) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int canmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
int canmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||||
cell_t *cell;
|
cell_t *cell;
|
||||||
|
|
||||||
|
// default
|
||||||
|
if (error) {
|
||||||
|
*error = E_OK;
|
||||||
|
rdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lfhasflag(lf, F_GRAVBOOSTED)) {
|
||||||
|
if (error) *error = E_GRAVBOOSTED;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check if we are burdened, paralyzed, etc
|
||||||
cell = getcellindir(lf->cell, dir);
|
cell = getcellindir(lf->cell, dir);
|
||||||
|
|
||||||
|
return cellwalkable(lf, cell, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
||||||
|
object_t *o;
|
||||||
|
// default
|
||||||
|
if (error) {
|
||||||
|
*error = E_OK;
|
||||||
|
rdata = NULL;
|
||||||
|
}
|
||||||
if (!cell || cell->type->solid) {
|
if (!cell || cell->type->solid) {
|
||||||
if (error) *error = E_WALLINWAY;
|
if (error) *error = E_WALLINWAY;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
if (cell->lf) {
|
|
||||||
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
|
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||||
|
if (lf) {
|
||||||
|
if ((lf->race->material->id != MT_GAS) &&
|
||||||
|
(lf->race->material->id != MT_SLIME)) {
|
||||||
|
rdata = o;
|
||||||
|
if (error) *error = E_OBINWAY;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rdata = o;
|
||||||
|
if (error) *error = E_OBINWAY;
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->lf && (cell->lf != lf)) {
|
||||||
if (error) *error = E_LFINWAY;
|
if (error) *error = E_LFINWAY;
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dorandommove(lifeform_t *lf, int badmovesok) {
|
void dorandommove(lifeform_t *lf, int badmovesok) {
|
||||||
int dir;
|
int dir;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
|
@ -36,64 +101,190 @@ void dorandommove(lifeform_t *lf, int badmovesok) {
|
||||||
// find a valid direction
|
// find a valid direction
|
||||||
dir = getrandomdir(DT_COMPASS);
|
dir = getrandomdir(DT_COMPASS);
|
||||||
|
|
||||||
moveok = canmove(lf, dir, &why);
|
moveok = canandwillmove(lf, dir, &why);
|
||||||
|
|
||||||
if (!moveok && badmovesok) {
|
if (!moveok && badmovesok) {
|
||||||
switch (why) {
|
switch (why) {
|
||||||
|
// actually okay to move into someone
|
||||||
case E_WALLINWAY:
|
case E_WALLINWAY:
|
||||||
case E_LFINWAY:
|
case E_LFINWAY:
|
||||||
moveok = B_TRUE;
|
moveok = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (!moveok) {
|
while (!moveok) {
|
||||||
// try next direction...
|
// try next direction...
|
||||||
if (++dir > DC_NW) dir = DC_N;
|
if (++dir > DC_NW) dir = DC_N;
|
||||||
if (++tries >= MAXDIR_COMPASS) {
|
if (++tries >= MAXDIR_COMPASS) {
|
||||||
dowait(lf);
|
rest(lf, B_TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check this direction...
|
// check this direction...
|
||||||
moveok = canmove(lf, dir, &why);
|
moveok = canandwillmove(lf, dir, &why);
|
||||||
if (!moveok && badmovesok) {
|
if (!moveok && badmovesok) {
|
||||||
switch (why) {
|
switch (why) {
|
||||||
case E_WALLINWAY:
|
case E_WALLINWAY:
|
||||||
case E_LFINWAY:
|
case E_LFINWAY:
|
||||||
moveok = B_TRUE;
|
moveok = B_TRUE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trymove(lf, dir);
|
trymove(lf, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dowait(lifeform_t *lf) {
|
|
||||||
taketime(lf, SPEED_WAIT);
|
int getdiraway(cell_t *src, cell_t *dst, int wantcheck) {
|
||||||
if (lf->controller == C_PLAYER) {
|
int d;
|
||||||
// clear msg bar
|
cell_t *c;
|
||||||
clearmsg();
|
int maxdist=-1,bestdir=D_NONE;
|
||||||
|
|
||||||
|
for (d = DC_N; d <= DC_NW; d++) {
|
||||||
|
int thisdist = -1;
|
||||||
|
int ok = B_FALSE;
|
||||||
|
c = getcellindir(src, d);
|
||||||
|
if (!c) continue;
|
||||||
|
|
||||||
|
if (c == dst) {
|
||||||
|
// destination is the thing we're fleeing from!
|
||||||
|
thisdist = -1;
|
||||||
|
} else {
|
||||||
|
if (wantcheck) {
|
||||||
|
if (src->lf && canandwillmove(src->lf, d, NULL)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else if (!src->lf) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src->lf && cellwalkable(src->lf, c, NULL)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else if (!src->lf) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
thisdist = getcelldist(c, dst);
|
||||||
|
} else {
|
||||||
|
thisdist = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisdist > maxdist) {
|
||||||
|
maxdist = thisdist;
|
||||||
|
bestdir = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return B_FALSE;
|
|
||||||
|
// TODO: handle ties
|
||||||
|
|
||||||
|
return bestdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void movelf(lifeform_t *lf, cell_t *newcell) {
|
|
||||||
|
int getdirtowards(cell_t *src, cell_t *dst, int wantcheck) {
|
||||||
|
int d;
|
||||||
|
cell_t *c;
|
||||||
|
int mindist=9999,bestdir=D_NONE;
|
||||||
|
|
||||||
|
for (d = DC_N; d <= DC_NW; d++) {
|
||||||
|
int ok = B_FALSE;
|
||||||
|
c = getcellindir(src, d);
|
||||||
|
if (!c) continue;
|
||||||
|
if (c == dst) {
|
||||||
|
// destination is adjacent!
|
||||||
|
bestdir = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantcheck) {
|
||||||
|
if (src->lf && canandwillmove(src->lf, d, NULL)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else if (!src->lf) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (src->lf && cellwalkable(src->lf, c, NULL)) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
} else if (!src->lf) {
|
||||||
|
ok = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
int thisdist;
|
||||||
|
thisdist = getcelldist(c, dst);
|
||||||
|
if (thisdist < mindist) {
|
||||||
|
mindist = thisdist;
|
||||||
|
bestdir = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle ties
|
||||||
|
|
||||||
|
return bestdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int moveawayfrom(lifeform_t *lf, cell_t *dst) {
|
||||||
|
int dir;
|
||||||
|
int rv = B_TRUE;
|
||||||
|
// move towards them
|
||||||
|
dir = getdiraway(lf->cell, dst, B_TRUE);
|
||||||
|
if (dir != D_NONE) {
|
||||||
|
rv = trymove(lf, dir);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// returns TRUE if something happened
|
||||||
|
int movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
object_t *o,*nexto;
|
object_t *o,*nexto;
|
||||||
char obname[BUFLEN],lfname[BUFLEN],buf[BUFLEN];
|
char obname[BUFLEN],lfname[BUFLEN],buf[BUFLEN];
|
||||||
|
lifeform_t *l;
|
||||||
|
int didmsg = B_FALSE;
|
||||||
|
flag_t *f;
|
||||||
|
|
||||||
// update current cell
|
// update current cell
|
||||||
lf->cell->lf = NULL;
|
lf->cell->lf = NULL;
|
||||||
|
|
||||||
|
// if required, relink lifeform to new map
|
||||||
|
if (newcell->map != lf->cell->map) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
statdirty = B_TRUE;
|
||||||
|
}
|
||||||
|
relinklf(lf, newcell->map);
|
||||||
|
}
|
||||||
|
|
||||||
// update lifeform
|
// update lifeform
|
||||||
lf->cell = newcell;
|
lf->cell = newcell;
|
||||||
|
|
||||||
|
// nothing should be in new cell..
|
||||||
|
assert(!newcell->lf);
|
||||||
|
|
||||||
// update new cell
|
// update new cell
|
||||||
newcell->lf = lf;
|
newcell->lf = lf;
|
||||||
|
|
||||||
|
if (isbleeding(lf)) {
|
||||||
|
if (rnd(1,2) == 1) {
|
||||||
|
bleed(lf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// check ground objects
|
// check ground objects
|
||||||
if (!hasflag(lf->flags, F_FLYING)) {
|
if (!lfhasflag(lf, F_FLYING)) {
|
||||||
for (o = newcell->obpile->first ; o ; o = nexto ) {
|
for (o = newcell->obpile->first ; o ; o = nexto ) {
|
||||||
nexto = o->next;
|
nexto = o->next;
|
||||||
if (hasflag(o->flags, F_SHARP)) {
|
f = hasflag(o->flags, F_SHARP);
|
||||||
|
if (f) {
|
||||||
object_t *boots;
|
object_t *boots;
|
||||||
// has boots on?
|
// has boots on?
|
||||||
boots = getequippedob(lf->pack, BP_FEET);
|
boots = getequippedob(lf->pack, BP_FEET);
|
||||||
|
@ -106,16 +297,18 @@ void movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
// we want 'xx steps on some pieces of broken glass'
|
// we want 'xx steps on some pieces of broken glass'
|
||||||
// not 'xx steps on 5 pieces of broken glass'
|
// not 'xx steps on 5 pieces of broken glass'
|
||||||
newname = makeplural(obname);
|
newname = makeplural(obname);
|
||||||
strrep(newname, "a ", "some ");
|
newname = strrep(newname, "a ", "some ", NULL);
|
||||||
strcpy(obname, newname);
|
strcpy(obname, newname);
|
||||||
free(newname);
|
free(newname);
|
||||||
}
|
}
|
||||||
if (lf->controller == C_PLAYER) {
|
if (lf->controller == C_PLAYER) {
|
||||||
msg("You crush %s underfoot.",obname);
|
msg("You crush %s underfoot.",obname);
|
||||||
|
didmsg = B_TRUE;
|
||||||
} else if (haslos(player, newcell)) {
|
} else if (haslos(player, newcell)) {
|
||||||
getlfname(lf, lfname);
|
getlfname(lf, lfname);
|
||||||
capitalise(lfname);
|
capitalise(lfname);
|
||||||
msg("%s crushes %s.",lfname, obname);
|
msg("%s crushes %s.",lfname, obname);
|
||||||
|
didmsg = B_TRUE;
|
||||||
}
|
}
|
||||||
// kill object
|
// kill object
|
||||||
removeob(o, o->amt);
|
removeob(o, o->amt);
|
||||||
|
@ -124,13 +317,15 @@ void movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
getobname(o, obname, 1);
|
getobname(o, obname, 1);
|
||||||
if (lf->controller == C_PLAYER) {
|
if (lf->controller == C_PLAYER) {
|
||||||
msg("Ow - you step on %s!",obname);
|
msg("Ow - you step on %s!",obname);
|
||||||
|
didmsg = B_TRUE;
|
||||||
} else if (haslos(player, newcell)) {
|
} else if (haslos(player, newcell)) {
|
||||||
getlfname(lf, lfname);
|
getlfname(lf, lfname);
|
||||||
capitalise(lfname);
|
capitalise(lfname);
|
||||||
msg("%s steps on %s!",lfname, obname);
|
msg("%s steps on %s!",lfname, obname);
|
||||||
|
didmsg = B_TRUE;
|
||||||
}
|
}
|
||||||
sprintf(buf, "stepping on %s", obname);
|
sprintf(buf, "stepping on %s", obname);
|
||||||
losehp(lf, rnd(1,2), DT_SLASH, NULL, buf);
|
losehp(lf, rnd(f->val[0],f->val[1]), DT_SLASH, NULL, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // end foreach object in cell
|
} // end foreach object in cell
|
||||||
|
@ -138,100 +333,474 @@ void movelf(lifeform_t *lf, cell_t *newcell) {
|
||||||
|
|
||||||
// update where player knows
|
// update where player knows
|
||||||
// (but without a map you will then slowly forget it)
|
// (but without a map you will then slowly forget it)
|
||||||
if (lf->controller == C_PLAYER) {
|
if (isplayer(lf)) {
|
||||||
updateknowncells();
|
updateknowncells();
|
||||||
|
}
|
||||||
|
|
||||||
|
// does anyone else see you?
|
||||||
|
for (l = newcell->map->lf ; l ; l = l->next) {
|
||||||
|
if (l != lf) {
|
||||||
|
if (haslos(l, newcell)) {
|
||||||
|
interrupt(lf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return didmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// basically this is a warpper for 'movelf' which
|
// basically this is a warpper for 'movelf' which
|
||||||
// does other game things like telling the player
|
// does other game things like telling the player
|
||||||
// what is here.
|
// what is here.
|
||||||
int moveto(lifeform_t *lf, cell_t *newcell) {
|
int moveto(lifeform_t *lf, cell_t *newcell) {
|
||||||
|
char lfname[BUFLEN];
|
||||||
|
int didmsg;
|
||||||
|
|
||||||
|
getlfname(lf, lfname);
|
||||||
|
|
||||||
// actually do the move
|
// actually do the move
|
||||||
movelf(lf, newcell);
|
didmsg = movelf(lf, newcell);
|
||||||
|
|
||||||
// tell player about things
|
// tell player about things
|
||||||
if (!isdead(lf) && (lf->controller == C_PLAYER)) {
|
if (!isdead(lf)) {
|
||||||
int numobs;
|
// some lifeforms can go through things
|
||||||
char buf[BUFLEN];
|
if (lf->race->material->id == MT_GAS) {
|
||||||
numobs = countobs(newcell->obpile);
|
object_t *o;
|
||||||
if (numobs == 1) {
|
char obname[BUFLEN];
|
||||||
getobname(newcell->obpile->first, buf, newcell->obpile->first->amt);
|
for (o = newcell->obpile->first ; o ; o = o->next) {
|
||||||
msg("You see %s here.", buf);
|
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||||
} else if ((numobs > 1) && (numobs <= 3)) {
|
getobname(o, obname, o->amt);
|
||||||
msg("You see a few objects here.");
|
if (isplayer(lf)) {
|
||||||
} else if ((numobs > 3) && (numobs <= 6)) {
|
msg("You seep around %s.", obname);
|
||||||
msg("You see some objects here.");
|
} else if (haslos(player, newcell)) {
|
||||||
} else if (numobs > 6) {
|
msg("%s seeps around %s.", lfname, obname);
|
||||||
msg("You see many objects here.");
|
}
|
||||||
} else {
|
}
|
||||||
// just clear the message buffer
|
}
|
||||||
clearmsg();
|
} else if (lf->race->material->id == MT_SLIME) {
|
||||||
}
|
object_t *o;
|
||||||
}
|
char obname[BUFLEN];
|
||||||
}
|
for (o = newcell->obpile->first ; o ; o = o->next) {
|
||||||
|
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||||
int opendoor(lifeform_t *lf, cell_t *cell) {
|
getobname(o, obname, o->amt);
|
||||||
char buf[BUFLEN];
|
if (isplayer(lf)) {
|
||||||
if (cell->type->id == CT_DOORCLOSED) {
|
msg("You seep under %s.", obname);
|
||||||
// open it
|
} else if (haslos(player, newcell)) {
|
||||||
setcelltype(cell, CT_DOOROPEN);
|
msg("%s seeps under %s.", lfname, obname);
|
||||||
if (lf->controller == C_PLAYER) {
|
}
|
||||||
msg("You open a door.");
|
}
|
||||||
} else {
|
|
||||||
// TODO: only announce if player can see it
|
|
||||||
if (haslos(player, cell)) {
|
|
||||||
getlfname(lf, buf);
|
|
||||||
capitalise(buf);
|
|
||||||
msg("%s opens a door.",buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taketime(lf, getmovespeed(lf));
|
|
||||||
|
// see objects on ground
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
int numobs;
|
||||||
|
numobs = countobs(newcell->obpile);
|
||||||
|
if ((numobs == 0) && !newcell->writing) {
|
||||||
|
// just clear the message buffer
|
||||||
|
if (!didmsg) clearmsg();
|
||||||
|
} else { // tell player what is here
|
||||||
|
dolook(newcell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int movetowards(lifeform_t *lf, cell_t *dst) {
|
||||||
|
int dir;
|
||||||
|
int rv = B_TRUE;
|
||||||
|
// move towards them
|
||||||
|
dir = getdirtowards(lf->cell, dst, B_TRUE);
|
||||||
|
if (dir != D_NONE) {
|
||||||
|
rv = trymove(lf, dir);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opendoorat(lifeform_t *lf, cell_t *c) {
|
||||||
|
object_t *o;
|
||||||
|
int rv;
|
||||||
|
o = hasobwithflag(c->obpile, F_DOOR);
|
||||||
|
if (o) {
|
||||||
|
rv = opendoor(lf, o);
|
||||||
} else {
|
} else {
|
||||||
|
rv = B_TRUE;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opendoor(lifeform_t *lf, object_t *o) {
|
||||||
|
cell_t *doorcell;
|
||||||
|
char buf[BUFLEN];
|
||||||
|
char obname[BUFLEN];
|
||||||
|
flag_t *f;
|
||||||
|
|
||||||
|
doorcell = o->pile->where;
|
||||||
|
assert(doorcell);
|
||||||
|
|
||||||
|
|
||||||
|
getobname(o, obname, 1);
|
||||||
|
|
||||||
|
if (!isdoor(o, NULL)) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lf && lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("You have no hands with which to open the door!");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = hasflag(o->flags, F_OPEN);
|
||||||
|
if (f) {
|
||||||
|
if (lf && isplayer(lf)) {
|
||||||
|
msg("It is already open!");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
} else {
|
||||||
|
// locked?
|
||||||
|
if (hasflag(o->flags, F_LOCKED)) {
|
||||||
|
if (lf && isplayer(lf)) {
|
||||||
|
msg("The door is locked.");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
} else {
|
||||||
|
// open it
|
||||||
|
addflag(o->flags, F_OPEN, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
|
f = hasflag(o->flags, F_IMPASSABLE);
|
||||||
|
if (f) killflag(f);
|
||||||
|
f = hasflag(o->flags, F_BLOCKSVIEW);
|
||||||
|
if (f) killflag(f);
|
||||||
|
|
||||||
|
if (lf) {
|
||||||
|
if (lf->controller == C_PLAYER) {
|
||||||
|
msg("You open %s.",obname);
|
||||||
|
} else {
|
||||||
|
if (haslos(player, lf->cell) && isadjacent(lf->cell, doorcell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
capitalise(buf);
|
||||||
|
msg("%s opens %s.",buf, obname);
|
||||||
|
} else if (haslos(player, doorcell)) {
|
||||||
|
capitalise(obname);
|
||||||
|
msg("%s opens.",obname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
|
||||||
|
touch(lf, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closedoorat(lifeform_t *lf, cell_t *c) {
|
||||||
|
object_t *o;
|
||||||
|
int rv;
|
||||||
|
o = hasobwithflag(c->obpile, F_DOOR);
|
||||||
|
if (o) {
|
||||||
|
rv = closedoor(lf, o);
|
||||||
|
} else {
|
||||||
|
rv = B_TRUE;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int closedoor(lifeform_t *lf, object_t *o) {
|
||||||
|
cell_t *cell;
|
||||||
|
char buf[BUFLEN];
|
||||||
|
char obname[BUFLEN];
|
||||||
|
flag_t *f;
|
||||||
|
|
||||||
|
getobname(o, obname, 1);
|
||||||
|
|
||||||
|
if (!isdoor(o, NULL)) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("There is nothing to close there!");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lf && lfhasflagval(lf, F_NOBODYPART, BP_HANDS, NA, NA, NULL)) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("You have no hands with which to close the door!");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = hasflag(o->flags, F_OPEN);
|
||||||
|
if (!f) {
|
||||||
|
if (lf && (lf->controller == C_PLAYER)) {
|
||||||
|
msg("It is already closed!");
|
||||||
|
}
|
||||||
|
return B_TRUE;
|
||||||
|
} else {
|
||||||
|
// close it
|
||||||
|
killflag(f);
|
||||||
|
addflag(o->flags, F_IMPASSABLE, B_TRUE, NA, NA, NULL);
|
||||||
|
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||||
|
|
||||||
|
if (lf) {
|
||||||
|
if (lf->controller == C_PLAYER) {
|
||||||
|
msg("You close %s.", obname);
|
||||||
|
} else {
|
||||||
|
if (haslos(player, lf->cell) && isadjacent(lf->cell, cell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
capitalise(buf);
|
||||||
|
msg("%s closes %s.",buf, obname);
|
||||||
|
} else if (haslos(player, cell)) {
|
||||||
|
capitalise(obname);
|
||||||
|
msg("%s closes.",obname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
touch(lf, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tryrun(lifeform_t *lf, int dir) {
|
int tryrun(lifeform_t *lf, int dir) {
|
||||||
// continue moving until we fail
|
if (!trymove(lf, dir)) {
|
||||||
while (canmove(lf, dir, NULL)) {
|
addflag(lf->flags, F_RUNNING, dir, NA, NA, NULL);
|
||||||
trymove(lf,dir);
|
|
||||||
}
|
}
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trymove(lifeform_t *lf, int dir) {
|
// try to pull lifeform towards cell c (or next to it)
|
||||||
cell_t *cell;
|
int pullnextto(lifeform_t *lf, cell_t *c) {
|
||||||
enum ERROR errcode;
|
int dir;
|
||||||
char buf[BUFLEN], buf2[BUFLEN];
|
cell_t *dst = NULL;
|
||||||
|
|
||||||
cell = getcellindir(lf->cell, dir);
|
dst = c;
|
||||||
if (canmove(lf, dir, &errcode)) {
|
|
||||||
moveto(lf, cell);
|
while (dst->lf) {
|
||||||
taketime(lf, getmovespeed(lf));
|
dir = getdirtowards(dst, lf->cell, B_FALSE);
|
||||||
} else {
|
if (dir == D_NONE) {
|
||||||
switch (errcode) {
|
return B_TRUE;
|
||||||
case E_WALLINWAY:
|
} else {
|
||||||
// is it a door in the way?
|
dst = getcellindir(dst, dir);
|
||||||
if (cell->type->id == CT_DOORCLOSED) {
|
if (dst == lf->cell) {
|
||||||
// try to open it
|
return B_TRUE;
|
||||||
opendoor(lf, cell);
|
}
|
||||||
} else {
|
|
||||||
if (lf->controller == C_PLAYER) {
|
|
||||||
msg("Ouch! You walk into a wall.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case E_LFINWAY:
|
|
||||||
// attack!
|
|
||||||
doattack(lf, cell->lf);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the path clear?
|
||||||
|
if (!dst || !haslof(lf, dst)) {
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
|
if (isplayer(lf) || haslos(player, lf->cell)) {
|
||||||
|
char buf[BUFLEN];
|
||||||
|
getlfname(lf, buf);
|
||||||
|
msg("%s %s pulled %s!", buf, isplayer(lf) ? "are" : "is",
|
||||||
|
lfhasflag(lf, F_FLYING) ? "through the air" :
|
||||||
|
"along the ground");
|
||||||
|
}
|
||||||
|
movelf(lf, dst);
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// teleport somewhere, along with puffs of smoke etc
|
||||||
|
int teleportto(lifeform_t *lf, cell_t *c) {
|
||||||
|
char buf[BUFLEN];
|
||||||
|
if (!isplayer(lf) && haslos(player, lf->cell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
msg("%s disappears in a puff of smoke!", buf);
|
||||||
|
}
|
||||||
|
addob(lf->cell->obpile, "puff of smoke");
|
||||||
|
movelf(lf, c);
|
||||||
|
addob(lf->cell->obpile, "cloud of smoke");
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("Suddenly, your surroundings appear different!");
|
||||||
|
} else if (haslos(player, lf->cell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
msg("%s appears in a cloud of smoke!", buf);
|
||||||
|
}
|
||||||
|
// show any objects here, just like if we moved.
|
||||||
|
// BUT don't let dolook() clear the msg bar if there are
|
||||||
|
// no objects here.
|
||||||
|
if (isplayer(lf) && countobs(lf->cell->obpile)) {
|
||||||
|
dolook(lf->cell);
|
||||||
|
}
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int trymove(lifeform_t *lf, int dir) {
|
||||||
|
cell_t *cell;
|
||||||
|
enum ERROR errcode;
|
||||||
|
char buf[BUFLEN];
|
||||||
|
|
||||||
|
cell = getcellindir(lf->cell, dir);
|
||||||
|
if (canandwillmove(lf, dir, &errcode)) {
|
||||||
|
reason = E_OK;
|
||||||
|
moveto(lf, cell);
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
} else {
|
||||||
|
object_t *inway;
|
||||||
|
int door, dooropen;
|
||||||
|
reason = errcode;
|
||||||
|
switch (errcode) {
|
||||||
|
case E_WALLINWAY:
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("Ouch! You %s into a wall.", getmoveverb(lf));
|
||||||
|
} else if (haslos(player, lf->cell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
msg("%s %ss into a wall.", buf, getmoveverb(lf));
|
||||||
|
}
|
||||||
|
if (isblind(lf)) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
// only take damage if we didn't know about this
|
||||||
|
if (!cell->known) {
|
||||||
|
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
||||||
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
|
cell->known = B_TRUE;
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
||||||
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case E_OBINWAY:
|
||||||
|
inway = (object_t *)rdata;
|
||||||
|
door = isdoor(inway, &dooropen);
|
||||||
|
if (door && !dooropen) {
|
||||||
|
if (isblind(lf)) {
|
||||||
|
// run into it
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
if (cell->known) {
|
||||||
|
// try to open it
|
||||||
|
opendoor(lf, inway);
|
||||||
|
} else {
|
||||||
|
msg("Ouch! You %s into a door.", getmoveverb(lf));
|
||||||
|
cell->known = B_TRUE;
|
||||||
|
sprintf(buf, "%sing into a door", getmoveverb(lf));
|
||||||
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (haslos(player, lf->cell)) {
|
||||||
|
getlfname(lf, buf);
|
||||||
|
msg("%s %ss into a wall.", buf, getmoveverb(lf));
|
||||||
|
}
|
||||||
|
sprintf(buf, "%sing into a door", getmoveverb(lf));
|
||||||
|
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try to open it
|
||||||
|
opendoor(lf, inway);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// can we push this?
|
||||||
|
if (ispushable(inway)) {
|
||||||
|
if (canpush(lf, inway, dir)) {
|
||||||
|
// push it!
|
||||||
|
push(lf, inway, dir);
|
||||||
|
} else {
|
||||||
|
if (lf->controller == C_PLAYER) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
getobname(inway, obname, 1);
|
||||||
|
switch (reason) {
|
||||||
|
case E_TOOHEAVY:
|
||||||
|
msg("The %s is too heavy to move.",strchr(obname, ' ')+1);
|
||||||
|
break;
|
||||||
|
case E_INSUBSTANTIAL:
|
||||||
|
msg("You cannot push %s without a physical body!",strchr(obname, ' ')+1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg("The %s won't move for some reason.",strchr(obname, ' ')+1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // object is in the way
|
||||||
|
if (lf->controller == C_PLAYER) {
|
||||||
|
char obname[BUFLEN];
|
||||||
|
getobname(inway, obname, 1);
|
||||||
|
msg("There is %s in your way.",obname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case E_LFINWAY:
|
||||||
|
// attack!
|
||||||
|
return attacklf(lf, cell->lf);
|
||||||
|
break;
|
||||||
|
case E_GRAVBOOSTED:
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
msg("You try to move but are unable to lift your feet!");
|
||||||
|
taketime(lf, getmovespeed(lf));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (reason == E_OK) {
|
||||||
|
return B_FALSE;
|
||||||
|
} else {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||||
|
cell_t *cell;
|
||||||
|
object_t *o;
|
||||||
|
enum IQBRACKET iq;
|
||||||
|
|
||||||
|
// default
|
||||||
|
if (error) {
|
||||||
|
*error = E_OK;
|
||||||
|
rdata = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell = getcellindir(lf->cell, dir);
|
||||||
|
// check for cursed objects + animals
|
||||||
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
|
if (!isplayer(lf)) {
|
||||||
|
if (o->blessed == B_CURSED) {
|
||||||
|
if (lfhasflag(lf, F_ANIMAL)) {
|
||||||
|
if (!lfhasflag(lf, F_FLYING)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for dangerous objects
|
||||||
|
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||||
|
if (iq >= IQ_AVERAGE) {
|
||||||
|
flag_t *f;
|
||||||
|
object_t *o;
|
||||||
|
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||||
|
// don't walk on sharp objects without boots
|
||||||
|
if (hasflag(o->flags, F_SHARP)) {
|
||||||
|
if (!getequippedob(lf->pack, BP_FEET)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f = hasflag(o->flags, F_WALKDAM);
|
||||||
|
if (f) {
|
||||||
|
// are we immune to this?
|
||||||
|
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[1], NA, NA, NULL)) {
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
17
move.h
17
move.h
|
@ -1,8 +1,21 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||||
int canmove(lifeform_t *lf, int dir, enum ERROR *error);
|
int canmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||||
|
int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error);
|
||||||
|
int closedoorat(lifeform_t *lf, cell_t *c);
|
||||||
|
int closedoor(lifeform_t *lf, object_t *o);
|
||||||
void dorandommove(lifeform_t *lf, int badmovesok);
|
void dorandommove(lifeform_t *lf, int badmovesok);
|
||||||
int dowait(lifeform_t *lf);
|
int getdiraway(cell_t *src, cell_t *dst, int wantcheck);
|
||||||
void movelf(lifeform_t *lf, cell_t *newcell);
|
int getdirtowards(cell_t *src, cell_t *dst, int wantcheck);
|
||||||
|
int moveawayfrom(lifeform_t *lf, cell_t *dst);
|
||||||
|
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||||
int moveto(lifeform_t *lf, cell_t *newcell);
|
int moveto(lifeform_t *lf, cell_t *newcell);
|
||||||
|
int movetowards(lifeform_t *lf, cell_t *dst);
|
||||||
|
int opendoorat(lifeform_t *lf, cell_t *c);
|
||||||
|
int opendoor(lifeform_t *lf, object_t *o);
|
||||||
|
int pullnextto(lifeform_t *lf, cell_t *c);
|
||||||
|
int teleportto(lifeform_t *lf, cell_t *c);
|
||||||
int trymove(lifeform_t *lf, int dir);
|
int trymove(lifeform_t *lf, int dir);
|
||||||
|
int tryrun(lifeform_t *lf, int dir);
|
||||||
|
int willmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||||
|
|
539
nexus.c
539
nexus.c
|
@ -1,38 +1,77 @@
|
||||||
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "ai.h"
|
||||||
|
#include "attack.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "flag.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "move.h"
|
||||||
#include "nexus.h"
|
#include "nexus.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
#include "text.h"
|
||||||
|
|
||||||
material_t *material = NULL,*lastmaterial = NULL;
|
material_t *material = NULL,*lastmaterial = NULL;
|
||||||
objectclass_t *objectclass = NULL,*lastobjectclass = NULL;
|
objectclass_t *objectclass = NULL,*lastobjectclass = NULL;
|
||||||
objecttype_t *objecttype = NULL,*lastobjecttype = NULL;
|
objecttype_t *objecttype = NULL,*lastobjecttype = NULL;
|
||||||
celltype_t *firstcelltype = NULL,*lastcelltype = NULL;
|
celltype_t *firstcelltype = NULL,*lastcelltype = NULL;
|
||||||
race_t *firstrace = NULL,*lastrace = NULL;
|
race_t *firstrace = NULL,*lastrace = NULL;
|
||||||
|
job_t *firstjob = NULL,*lastjob = NULL;
|
||||||
map_t *firstmap = NULL,*lastmap = NULL;
|
map_t *firstmap = NULL,*lastmap = NULL;
|
||||||
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
knowledge_t *knowledge = NULL, *lastknowledge = NULL;
|
||||||
|
|
||||||
|
// maintains unique lifeform ID numbers
|
||||||
|
long nextlfid = 0;
|
||||||
|
|
||||||
|
int SCREENW = DEF_SCREENW;
|
||||||
|
int SCREENH = DEF_SCREENH;
|
||||||
|
|
||||||
|
// object return list
|
||||||
|
object_t *retobs[MAXPILEOBS+1];
|
||||||
|
int retobscount[MAXPILEOBS+1];
|
||||||
|
int nretobs = 0;
|
||||||
|
|
||||||
FILE *logfile;
|
FILE *logfile;
|
||||||
|
|
||||||
|
prompt_t prompt;
|
||||||
|
|
||||||
|
char msghist[MAXHISTORY][BUFLEN];
|
||||||
|
int nmsghist = 0;
|
||||||
|
|
||||||
enum ERROR reason; // global for returning errors
|
enum ERROR reason; // global for returning errors
|
||||||
|
void *rdata; // globel for returning data
|
||||||
|
|
||||||
lifeform_t *player = NULL;
|
lifeform_t *player = NULL;
|
||||||
int gameover;
|
int gameover;
|
||||||
|
|
||||||
int gamestarted = B_FALSE;
|
int gamestarted = B_FALSE;
|
||||||
|
|
||||||
int main(char **argv, int argc) {
|
long curtime = 0;
|
||||||
|
long timeleft = 0;
|
||||||
|
|
||||||
|
extern int statdirty;
|
||||||
|
|
||||||
|
int needredraw = B_TRUE;
|
||||||
|
int numdraws = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
int newworld = B_FALSE;
|
int newworld = B_FALSE;
|
||||||
|
object_t *o;
|
||||||
|
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
|
|
||||||
// init params
|
// init params
|
||||||
init();
|
if (init()) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// load whatever maps are available
|
// load whatever maps are available
|
||||||
loadall();
|
loadall();
|
||||||
|
@ -44,25 +83,60 @@ int main(char **argv, int argc) {
|
||||||
if (!firstmap) {
|
if (!firstmap) {
|
||||||
newworld = B_TRUE;
|
newworld = B_TRUE;
|
||||||
addmap();
|
addmap();
|
||||||
createmap(firstmap, H_DUNGEON);
|
createmap(firstmap, 1, H_DUNGEON, NULL, findot(OT_STAIRSUP));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!knowledge) {
|
if (!knowledge) {
|
||||||
// populate scroll names
|
// populate scroll, potion, etc names
|
||||||
genhiddennames();
|
genhiddennames();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no player (ie. didn't load a game), add them
|
// if no player (ie. didn't load a game), add them
|
||||||
if (!player) {
|
if (!player) {
|
||||||
|
char *user;
|
||||||
|
char pname[BUFLEN];
|
||||||
|
job_t *j;
|
||||||
|
char ch;
|
||||||
|
cell_t *where;
|
||||||
|
|
||||||
|
// ask for race
|
||||||
|
initprompt(&prompt, "Select your race:");
|
||||||
|
ch = 'a';
|
||||||
|
for (j = firstjob ; j ; j = j->next) {
|
||||||
|
addchoice(&prompt, ch++, j->name, NULL, j);
|
||||||
|
}
|
||||||
|
j = NULL;
|
||||||
|
while (!j) {
|
||||||
|
getchoice(&prompt);
|
||||||
|
j = prompt.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find staircase
|
||||||
|
where = findobinmap(firstmap, OT_STAIRSUP);
|
||||||
|
assert(where);
|
||||||
// add player
|
// add player
|
||||||
player = addlf(getrandomcelloftype(firstmap, CT_ROOM), R_HUMAN, 1);
|
real_addlf(where, R_HUMAN, 1, C_PLAYER); // this will assign 'player'
|
||||||
player->controller = C_PLAYER;
|
|
||||||
|
user = getenv("USER");
|
||||||
|
if (user) {
|
||||||
|
addflag(player->flags, F_NAME, NA, NA, NA, getenv("USER"));
|
||||||
|
} else {
|
||||||
|
addflag(player->flags, F_NAME, NA, NA, NA, "Anonymous");
|
||||||
|
}
|
||||||
|
givejob(player, j->id);
|
||||||
|
|
||||||
|
// player needs hunger
|
||||||
|
addflag(player->flags, F_HUNGER, 0, NA, NA, NULL);
|
||||||
|
|
||||||
drawscreen();
|
drawscreen();
|
||||||
msg("Welcome to %snexus!", newworld ? "the new " : "");
|
getplayernamefull(pname);
|
||||||
|
msg("Greetings %s, welcome to %snexus!", pname, newworld ? "the new " : "");
|
||||||
more();
|
more();
|
||||||
// XXX testing
|
// XXX testing
|
||||||
//addlf(getcellindir(player->cell, D_N), R_GOBLIN, 1);
|
//addlf(getcellindir(player->cell, D_N), R_GOBLIN, 1);
|
||||||
|
|
||||||
|
// 00:00 - 23:59
|
||||||
|
curtime = rnd(0,86399);
|
||||||
} else {
|
} else {
|
||||||
drawscreen();
|
drawscreen();
|
||||||
msg("Welcome back!");
|
msg("Welcome back!");
|
||||||
|
@ -73,38 +147,71 @@ int main(char **argv, int argc) {
|
||||||
// start game - this will cause debug messages to now
|
// start game - this will cause debug messages to now
|
||||||
// go to the log file instead of stdout.
|
// go to the log file instead of stdout.
|
||||||
gamestarted = B_TRUE;
|
gamestarted = B_TRUE;
|
||||||
|
timeleft = 0; // reset game timer
|
||||||
|
|
||||||
|
// calculate initial light
|
||||||
|
calclight(player->cell->map);
|
||||||
|
// pre-calc line-of-sight for player
|
||||||
|
precalclos(player);
|
||||||
|
|
||||||
// show level
|
// show level
|
||||||
drawscreen();
|
drawscreen();
|
||||||
|
|
||||||
// MAIN LOOP
|
// MAIN LOOP
|
||||||
|
|
||||||
|
// basic flow is:
|
||||||
|
//
|
||||||
|
// donextturn() - process a turn for a lifeform
|
||||||
|
// turneffectslf() Rest effects, Damage from floor objects, etc
|
||||||
|
// lifeform takes action
|
||||||
|
// checkdeath() - check for object/player death. remove dead things.
|
||||||
|
// timeeffectsworld() Fires burn out, ice melts, etc
|
||||||
|
// Also keeps lf->timespent values under control.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// redraw screen
|
||||||
|
//
|
||||||
|
// checkendgame() - has the game ended yet?
|
||||||
|
|
||||||
|
|
||||||
gameover = B_FALSE;
|
gameover = B_FALSE;
|
||||||
while (!gameover) {
|
while (!gameover) {
|
||||||
|
map_t *curmap;
|
||||||
|
curmap = player->cell->map;
|
||||||
|
|
||||||
|
// default to no redraw - donextturn() will change this if needed.
|
||||||
|
needredraw = B_FALSE;
|
||||||
|
numdraws = 0;
|
||||||
|
|
||||||
|
// someone has a turn - this will then call taketime -> timehappens();
|
||||||
|
donextturn(curmap);
|
||||||
|
|
||||||
// someone has a turn
|
|
||||||
donextturn(player->cell->map);
|
|
||||||
// update lifeform structue to figure out who goes next
|
// update lifeform structue to figure out who goes next
|
||||||
sortlf(player->cell->map);
|
//timehappens(curmap);
|
||||||
|
|
||||||
// TODO: monsters move etc
|
// show level (if required)
|
||||||
|
//if (haslos(player, curmap->lf->cell)) {
|
||||||
// check for death etc
|
|
||||||
doeffects();
|
|
||||||
|
|
||||||
// show level
|
|
||||||
drawscreen();
|
drawscreen();
|
||||||
|
//dblog("**** END of turn, numdraws = %d", numdraws);
|
||||||
|
|
||||||
|
|
||||||
// check end of game
|
// check end of game
|
||||||
checkendgame();
|
checkendgame();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// identify all objects
|
||||||
|
for (o = player->pack->first ; o ; o = o->next) {
|
||||||
|
identify(o);
|
||||||
|
}
|
||||||
|
// show possessions
|
||||||
|
dofinaloblist(player->pack);
|
||||||
// print tombstone
|
// print tombstone
|
||||||
tombstone(player);
|
tombstone(player);
|
||||||
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
celltype_t *addcelltype(int id, char glyph, int solid, int transparent) {
|
celltype_t *addcelltype(int id, char *name, char glyph, int solid, int transparent, enum MATERIAL mat) {
|
||||||
celltype_t *a;
|
celltype_t *a;
|
||||||
|
|
||||||
// add to the end of the list
|
// add to the end of the list
|
||||||
|
@ -124,11 +231,47 @@ celltype_t *addcelltype(int id, char glyph, int solid, int transparent) {
|
||||||
|
|
||||||
// set props
|
// set props
|
||||||
a->id = id;
|
a->id = id;
|
||||||
|
a->name = strdup(name);
|
||||||
a->glyph = glyph;
|
a->glyph = glyph;
|
||||||
a->solid = solid;
|
a->solid = solid;
|
||||||
a->transparent = transparent;
|
a->transparent = transparent;
|
||||||
|
a->material = findmaterial(mat);
|
||||||
|
|
||||||
|
a->flags = addflagpile(NULL, NULL);
|
||||||
|
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkdeath(void) {
|
||||||
|
lifeform_t *lf, *nextlf;
|
||||||
|
int x,y;
|
||||||
|
for (lf = player->cell->map->lf; lf ; lf = nextlf) {
|
||||||
|
nextlf = lf->next;
|
||||||
|
|
||||||
|
// check for death
|
||||||
|
if (lf->hp <= 0) {
|
||||||
|
// die!
|
||||||
|
die(lf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// check for object death
|
||||||
|
removedeadobs(lf->pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for object death on map
|
||||||
|
for (y = 0; y < player->cell->map->h; y++) {
|
||||||
|
for (x = 0; x < player->cell->map->w; x++) {
|
||||||
|
cell_t *c;
|
||||||
|
c = getcellat(player->cell->map, x, y);
|
||||||
|
if (c) {
|
||||||
|
removedeadobs(c->obpile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void checkendgame(void) {
|
void checkendgame(void) {
|
||||||
if (!player->alive) {
|
if (!player->alive) {
|
||||||
gameover = B_TRUE;
|
gameover = B_TRUE;
|
||||||
|
@ -141,38 +284,94 @@ void cleanup(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void doeffects(void) {
|
|
||||||
lifeform_t *lf;
|
|
||||||
// check for death
|
|
||||||
for (lf = player->cell->map->lf; lf ; lf = lf->next) {
|
|
||||||
if (lf->hp <= 0) {
|
|
||||||
// die!
|
|
||||||
die(lf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void donextturn(map_t *map) {
|
void donextturn(map_t *map) {
|
||||||
lifeform_t *who;
|
lifeform_t *who;
|
||||||
|
|
||||||
// show messages to plaeyr
|
|
||||||
drawmsg();
|
|
||||||
|
|
||||||
who = map->lf;
|
who = map->lf;
|
||||||
if (who->controller == C_PLAYER) {
|
dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||||
drawcursor();
|
|
||||||
// find out what player wants to do
|
|
||||||
handleinput();
|
turneffectslf(who);
|
||||||
} else {
|
|
||||||
// TODO: do ai move
|
// calculate light
|
||||||
aimove(who);
|
calclight(map);
|
||||||
|
// pre-calculate line of sight for this lifeform
|
||||||
|
precalclos(who);
|
||||||
|
|
||||||
|
if (isplayer(who) || haslos(player, who->cell)) {
|
||||||
|
needredraw = B_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update gun targets
|
||||||
|
autotarget(who);
|
||||||
|
|
||||||
|
|
||||||
|
assert(who->timespent == 0);
|
||||||
|
// keep looping until they actually do something or are dead!
|
||||||
|
while (who->timespent == 0) {
|
||||||
|
if (isdead(who)) {
|
||||||
|
// skip turn
|
||||||
|
taketime(who, SPEED_DEAD);
|
||||||
|
} else {
|
||||||
|
// do we need to run away from something?
|
||||||
|
if (!flee(who)) {
|
||||||
|
int donormalmove = B_TRUE;
|
||||||
|
flag_t *f;
|
||||||
|
|
||||||
|
if (donormalmove) {
|
||||||
|
// paralyzed?
|
||||||
|
f = hasflag(who->flags, F_PARALYZED);
|
||||||
|
if (f) {
|
||||||
|
rest(who, B_FALSE);
|
||||||
|
donormalmove = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resting?
|
||||||
|
if (donormalmove) {
|
||||||
|
f = hasflag(who->flags, F_RESTING);
|
||||||
|
if (f) {
|
||||||
|
if (who->hp < who->maxhp) {
|
||||||
|
rest(who, B_TRUE);
|
||||||
|
donormalmove = B_FALSE;
|
||||||
|
} else {
|
||||||
|
killflag(f);
|
||||||
|
if (isplayer(who)) msg("You finish resting.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (donormalmove) {
|
||||||
|
if (isplayer(who)) {
|
||||||
|
drawcursor();
|
||||||
|
// find out what player wants to do
|
||||||
|
handleinput();
|
||||||
|
} else {
|
||||||
|
// do ai move
|
||||||
|
aimove(who);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isdead(who) || haslos(player, who->cell)) {
|
||||||
|
needredraw = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for death etc
|
||||||
|
checkdeath();
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// effects which happen every GAME TICK
|
||||||
|
// ie. object hp drain etc
|
||||||
|
//////////////////////////////////
|
||||||
|
timeeffectsworld(map);
|
||||||
|
|
||||||
// everyone else's time goes down by 1
|
// everyone else's time goes down by 1
|
||||||
for (who = map->lf->next ; who ; who = who->next ){
|
//for (who = map->lf->next ; who ; who = who->next ){
|
||||||
if (who->timespent > 0) who->timespent--;
|
// if (who->timespent > 0) who->timespent--;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
celltype_t *findcelltype(int id) {
|
celltype_t *findcelltype(int id) {
|
||||||
|
@ -196,6 +395,10 @@ char *getdirname(int dir) {
|
||||||
return "South";
|
return "South";
|
||||||
case D_W:
|
case D_W:
|
||||||
return "West";
|
return "West";
|
||||||
|
case D_UP:
|
||||||
|
return "up";
|
||||||
|
case D_DOWN:
|
||||||
|
return "down";
|
||||||
case D_UNKNOWN:
|
case D_UNKNOWN:
|
||||||
return "D_UNKNOWN";
|
return "D_UNKNOWN";
|
||||||
case D_NONE:
|
case D_NONE:
|
||||||
|
@ -204,27 +407,45 @@ char *getdirname(int dir) {
|
||||||
return "?errordir?";
|
return "?errordir?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getrarity(int depth, int *min, int *max, int range) {
|
||||||
|
int mid;
|
||||||
|
mid = 100 - (depth * 3);
|
||||||
|
*min = mid - range; if (*min < 0) *min = 0;
|
||||||
|
*max = mid + range; if (*max > 100) *max = 100;
|
||||||
|
|
||||||
|
if (*min > 75) *min = 75;
|
||||||
|
if (*max < 25) *max = 25;
|
||||||
|
}
|
||||||
|
|
||||||
int init(void) {
|
int init(void) {
|
||||||
// random numbers
|
// random numbers
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
|
|
||||||
|
initobjects();
|
||||||
|
initjobs();
|
||||||
|
initrace();
|
||||||
|
|
||||||
|
// cell types
|
||||||
|
addcelltype(CT_WALL, "rock wall", '#', B_SOLID, B_OPAQUE, MT_STONE);
|
||||||
|
addcelltype(CT_ROOMWALL, "rock wall", '#', B_SOLID, B_OPAQUE, MT_STONE);
|
||||||
|
addcelltype(CT_CORRIDOR, "rock floor", '.', B_EMPTY, B_TRANS, MT_STONE);
|
||||||
|
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', B_EMPTY, B_TRANS, MT_STONE);
|
||||||
|
addcelltype(CT_ROOM, "rock floor", '.', B_EMPTY, B_TRANS, MT_STONE);
|
||||||
|
//addcelltype(CT_DOOROPEN, "wooden door", '-', B_EMPTY, B_TRANS, MT_WOOD);
|
||||||
|
//addcelltype(CT_DOORCLOSED, "wooden door", '+', B_SOLID, B_OPAQUE, MT_WOOD);
|
||||||
|
|
||||||
|
if (validateobs()) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
if (validateraces()) {
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// open log file
|
// open log file
|
||||||
logfile = fopen("log.txt","wt");
|
logfile = fopen("log.txt","wt");
|
||||||
fprintf(logfile, "\n\n\n====== NEW LOGFILE ====\n");
|
fprintf(logfile, "\n\n\n====== NEW LOGFILE ====\n");
|
||||||
|
|
||||||
// cell types
|
|
||||||
addcelltype(CT_WALL, '#', B_SOLID, B_OPAQUE);
|
|
||||||
addcelltype(CT_ROOMWALL, '#', B_SOLID, B_OPAQUE);
|
|
||||||
addcelltype(CT_CORRIDOR, '.', B_EMPTY, B_TRANS);
|
|
||||||
addcelltype(CT_LOOPCORRIDOR, 'L', B_EMPTY, B_TRANS);
|
|
||||||
addcelltype(CT_ROOM, '.', B_EMPTY, B_TRANS);
|
|
||||||
addcelltype(CT_DOOROPEN, '-', B_EMPTY, B_TRANS);
|
|
||||||
addcelltype(CT_DOORCLOSED, '+', B_SOLID, B_OPAQUE);
|
|
||||||
|
|
||||||
initobjects();
|
|
||||||
|
|
||||||
initrace();
|
|
||||||
|
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +458,10 @@ int isplayerturn(void) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float pctof(float pct, float num) {
|
||||||
|
return ((pct / 100.0) * num);
|
||||||
|
}
|
||||||
|
|
||||||
// get a random number between min and max
|
// get a random number between min and max
|
||||||
int rnd(int min, int max) {
|
int rnd(int min, int max) {
|
||||||
int res;
|
int res;
|
||||||
|
@ -254,70 +479,220 @@ int rolldie(int ndice, int sides) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort map's lifeform list by time spent
|
int rollhitdice(lifeform_t *lf) {
|
||||||
|
flag_t *f;
|
||||||
|
int ndice, plus;
|
||||||
|
int roll;
|
||||||
|
|
||||||
|
f = hasflag(lf->flags, F_HITDICE);
|
||||||
|
if (f) {
|
||||||
|
ndice = f->val[0];
|
||||||
|
if (f->val[1] == NA) plus = 0;
|
||||||
|
else plus = f->val[1];
|
||||||
|
} else {
|
||||||
|
ndice = 1;
|
||||||
|
plus = 0;
|
||||||
|
}
|
||||||
|
roll = rolldie(ndice, 4) + plus;
|
||||||
|
return roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rollmpdice(lifeform_t *lf) {
|
||||||
|
flag_t *f;
|
||||||
|
int ndice, plus;
|
||||||
|
int roll;
|
||||||
|
|
||||||
|
f = hasflag(lf->flags, F_MPDICE);
|
||||||
|
if (f) {
|
||||||
|
ndice = f->val[0];
|
||||||
|
if (f->val[1] == NA) plus = 0;
|
||||||
|
else plus = f->val[1];
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
roll = rolldie(ndice, 4) + plus;
|
||||||
|
return roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void sortlf(map_t *map) {
|
void sortlf(map_t *map) {
|
||||||
int donesomething;
|
int donesomething;
|
||||||
lifeform_t *l;
|
int db = B_FALSE;
|
||||||
int adjustby;
|
lifeform_t *l,*nextl;
|
||||||
int db = B_TRUE;
|
int iter = 0;
|
||||||
|
|
||||||
// bubblesort
|
// bubblesort
|
||||||
/*
|
|
||||||
if (db) {
|
|
||||||
dblog("BEFORE sortlf():");
|
|
||||||
for (l = map->lf ; l ; l = l->next) {
|
|
||||||
dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
donesomething = B_TRUE;
|
donesomething = B_TRUE;
|
||||||
|
dblog("doing sort...");
|
||||||
while (donesomething) {
|
while (donesomething) {
|
||||||
donesomething = B_FALSE;
|
donesomething = B_FALSE;
|
||||||
for (l = map->lf ; l ; l = l->next) {
|
|
||||||
if (!l->sorted && l->next && (l->timespent > l->next->timespent) ) {
|
//dblog("ITER %d",iter++);
|
||||||
|
if (db) {
|
||||||
|
dblog("ITER %d",iter++);
|
||||||
|
for (l = map->lf ; l ; l = l->next) {
|
||||||
|
dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (l = map->lf ; l->next ; l = nextl) {
|
||||||
|
nextl = l->next;
|
||||||
|
//if (!l->sorted && (l->timespent >= l->next->timespent) ) {
|
||||||
|
if (l->sorted) {
|
||||||
|
//dblog("skipping id %d %s, already sorted ",l->id, l->race->name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->timespent >= l->next->timespent) {
|
||||||
lifeform_t *temp;
|
lifeform_t *temp;
|
||||||
|
//dblog("moving id %d %s upwards",l->id, l->race->name);
|
||||||
// remember next element
|
// remember next element
|
||||||
temp = l->next;
|
temp = l->next;
|
||||||
|
|
||||||
// remove this element from list
|
// remove this element from list
|
||||||
|
// don't bother checking if (l->next == NULL) as we know
|
||||||
|
// this won't be true due to the for loop condition
|
||||||
if (l->prev == NULL) {
|
if (l->prev == NULL) {
|
||||||
// first
|
// first
|
||||||
map->lf = l->next;
|
map->lf = l->next;
|
||||||
|
l->next->prev = NULL;
|
||||||
} else {
|
} else {
|
||||||
// not first
|
// not first
|
||||||
l->prev->next = l->next;
|
l->prev->next = l->next;
|
||||||
|
l->next->prev = l->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TESTING: re-add at correct position.
|
||||||
|
while (temp->next && (temp->next->timespent <= l->timespent)) {
|
||||||
|
//dblog("moving past %d %s (timespend=%d)...",temp->next->id, temp->next->race->name, temp->next->timespent);
|
||||||
|
temp = temp->next;
|
||||||
}
|
}
|
||||||
// don't bother checking for next - we know ther eis one.
|
|
||||||
l->next->prev = l->prev;
|
|
||||||
|
|
||||||
// re-add element afterwards
|
// re-add element afterwards
|
||||||
l->next = temp->next;
|
l->next = temp->next;
|
||||||
l->prev = temp;
|
l->prev = temp;
|
||||||
temp->next = l;
|
temp->next = l;
|
||||||
if (l->next == NULL) map->lastlf = l;
|
if (l->next == NULL) {
|
||||||
|
map->lastlf = l;
|
||||||
|
} else {
|
||||||
|
l->next->prev = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
l->sorted = B_TRUE;
|
||||||
|
|
||||||
donesomething = B_TRUE;
|
donesomething = B_TRUE;
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
l->sorted = B_TRUE;
|
l->sorted = B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//dblog("finished sort.");
|
||||||
|
|
||||||
|
// reset sorted var for next time
|
||||||
|
for (l = map->lf ; l->next ; l = l->next) {
|
||||||
|
l->sorted = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
if (player->next) {
|
||||||
|
assert(player->next->prev == player);
|
||||||
|
}
|
||||||
|
if (player->prev) {
|
||||||
|
assert(player->prev->next == player);
|
||||||
|
}
|
||||||
|
|
||||||
if (db) {
|
if (db) {
|
||||||
dblog("AFTER SORT:");
|
dblog("AFTER SORT:");
|
||||||
for (l = map->lf ; l ; l = l->next) {
|
for (l = map->lf ; l ; l = l->next) {
|
||||||
if (haslos(player, l->cell)) {
|
// if (haslos(player, l->cell)) {
|
||||||
dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted);
|
dblog("- %s (timespent= %d) (sorted=%d)", (l == player) ? "player" : l->race->name, l->timespent,l->sorted);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now go through the list and make the first element be 0
|
}
|
||||||
adjustby = map->lf->timespent;
|
*/
|
||||||
for (l = map->lf ; l ; l = l->next) {
|
|
||||||
l->timespent -= adjustby;
|
void timeeffectsworld(map_t *map) {
|
||||||
l->sorted = B_FALSE;
|
lifeform_t *l;
|
||||||
}
|
int db = B_TRUE;
|
||||||
|
object_t *o,*nexto;
|
||||||
|
int x,y;
|
||||||
|
long firstlftime;
|
||||||
|
|
||||||
|
// now go through the list and make the first element be 0
|
||||||
|
l = map->lf;
|
||||||
|
|
||||||
|
if (l) {
|
||||||
|
// if (db) dblog("first lf is: %s (id %ld)\n",l->race->name, l->id);
|
||||||
|
firstlftime = l->timespent;
|
||||||
|
assert(firstlftime >= 0);
|
||||||
|
} else {
|
||||||
|
dblog("no lifeforms on map!\n");
|
||||||
|
// no first lf!
|
||||||
|
firstlftime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (db) dblog("timespent = %d\n", timespent);
|
||||||
|
dblog("firstlftime = %d\n", firstlftime);
|
||||||
|
|
||||||
|
if (firstlftime > 0) {
|
||||||
|
dblog("making firstlf timespent = 0 (currently %d):", firstlftime);
|
||||||
|
//dumplf();
|
||||||
|
for (l = map->lf ; l ; l = l->next) {
|
||||||
|
//dblog("shuffling id %d %s timespent=%d -> %d",l->id,l->race->name, l->timespent, l->timespent - firstlftime);
|
||||||
|
l->timespent -= firstlftime;
|
||||||
|
assert(l->timespent >= 0);
|
||||||
|
if (isplayer(l)) {
|
||||||
|
statdirty = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//dblog("after shuffle:");
|
||||||
|
//dumplf();
|
||||||
|
} else {
|
||||||
|
dblog("firstlf timespent is not greater than 0. no shuffle.");
|
||||||
|
}
|
||||||
|
|
||||||
|
timeleft += firstlftime;
|
||||||
|
// now do effects based on time...
|
||||||
|
while (timeleft >= TICK_INTERVAL) {
|
||||||
|
|
||||||
|
timeleft -= TICK_INTERVAL;
|
||||||
|
|
||||||
|
// global time-based effects on map or map objects
|
||||||
|
for (y = 0; y < map->h; y++) {
|
||||||
|
for (x = 0; x < map->w; x++) {
|
||||||
|
cell_t *c;
|
||||||
|
c = getcellat(map, x, y);
|
||||||
|
if (c) {
|
||||||
|
// go through each object in the cell...
|
||||||
|
for (o = c->obpile->first ; o ; o = nexto) {
|
||||||
|
nexto = o->next;
|
||||||
|
|
||||||
|
timeeffectsob(o);
|
||||||
|
} // end foreach object here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end for (y...
|
||||||
|
|
||||||
|
// now handle effects on lifeforms and/or their objects
|
||||||
|
for (l = map->lf ; l ; l = l->next) {
|
||||||
|
timeeffectslf(l);
|
||||||
|
for (o = l->pack->first ; o ; o = nexto) {
|
||||||
|
nexto = o->next;
|
||||||
|
timeeffectsob(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//dblog("AFTER SORT AND ADJUST.....");
|
||||||
|
//dumplf();
|
||||||
|
} // end if timespent
|
||||||
|
|
||||||
|
// inc game time
|
||||||
|
curtime += firstlftime;
|
||||||
|
|
||||||
|
if (db) dblog("cur time is %ld\n",curtime);
|
||||||
}
|
}
|
||||||
|
|
11
nexus.h
11
nexus.h
|
@ -1,14 +1,19 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
celltype_t *addcelltype(int id, char glyph, int solid, int transparent);
|
celltype_t *addcelltype(int id, char *name, char glyph, int solid, int transparent, enum MATERIAL mat);
|
||||||
|
void checkdeath(void);
|
||||||
void checkendgame(void);
|
void checkendgame(void);
|
||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
void doeffects(void);
|
|
||||||
void donextturn(map_t *map);
|
void donextturn(map_t *map);
|
||||||
celltype_t *findcelltype(int id);
|
celltype_t *findcelltype(int id);
|
||||||
char *getdirname(int dir);
|
char *getdirname(int dir);
|
||||||
|
void getrarity(int depth, int *min, int *max, int range);
|
||||||
int init(void);
|
int init(void);
|
||||||
int isplayerturn(void);
|
int isplayerturn(void);
|
||||||
|
float pctof(float pct, float num);
|
||||||
int rnd(int min, int max);
|
int rnd(int min, int max);
|
||||||
int rolldie(int ndice, int sides);
|
int rolldie(int ndice, int sides);
|
||||||
void sortlf(map_t *map);
|
int rollhitdice(lifeform_t *lf);
|
||||||
|
int rollmpdice(lifeform_t *lf);
|
||||||
|
//void sortlf(map_t *map);
|
||||||
|
void timeeffectsworld(map_t *map);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
hay
|
||||||
|
pebbles
|
||||||
|
torch
|
||||||
|
boulder / monolith / statue
|
||||||
|
shackles
|
||||||
|
chain
|
||||||
|
bone
|
||||||
|
skeleton
|
||||||
|
scrap of material
|
100
objects.h
100
objects.h
|
@ -2,57 +2,151 @@
|
||||||
#define __OBJECTS_H
|
#define __OBJECTS_H
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
|
object_t *addemptyob(obpile_t *where, object_t *o);
|
||||||
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
|
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
|
||||||
material_t *addmaterial(enum MATERIAL id, char *name);
|
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
||||||
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph);
|
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph);
|
||||||
object_t *addob(obpile_t *where, char *name);
|
object_t *addob(obpile_t *where, char *name);
|
||||||
object_t *addobject(obpile_t *where, char *name, int canstack);
|
object_t *addobject(obpile_t *where, char *name, int canstack);
|
||||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||||
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid);
|
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid);
|
||||||
|
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||||
|
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype);
|
||||||
|
//void adjustprice(objecttype_t *ot, float *price );
|
||||||
|
void appendinscription(object_t *o, char *text);
|
||||||
|
int blessob(object_t *o);
|
||||||
|
void brightflash(cell_t *centre, int range, lifeform_t *immunelf);
|
||||||
object_t *canstackob(obpile_t *op, object_t *match);
|
object_t *canstackob(obpile_t *op, object_t *match);
|
||||||
object_t *canstacknewot(obpile_t *op, objecttype_t *match);
|
object_t *canstacknewot(obpile_t *op, objecttype_t *match);
|
||||||
|
int changemat(object_t *o, enum MATERIAL mat);
|
||||||
void copyobprops(object_t *dst, object_t *src);
|
void copyobprops(object_t *dst, object_t *src);
|
||||||
int countnames(char **list);
|
int countnames(char **list);
|
||||||
int countobs(obpile_t *op);
|
int countobs(obpile_t *op);
|
||||||
|
int curseob(object_t *o);
|
||||||
|
void damageallobs(object_t *exception, obpile_t *op, int howmuch, int damtype);
|
||||||
|
void explodeob(object_t *o, flag_t *f, int bigness);
|
||||||
|
void extinguish(object_t *o);
|
||||||
material_t *findmaterial(int id);
|
material_t *findmaterial(int id);
|
||||||
objectclass_t *findoc(int id);
|
objectclass_t *findoc(int id);
|
||||||
object_t *findobl(obpile_t *op, char let); // find object by letter
|
object_t *findobl(obpile_t *op, char let); // find object by letter
|
||||||
objecttype_t *findot(enum OBTYPE id);
|
objecttype_t *findot(enum OBTYPE id);
|
||||||
objecttype_t *findotn(char *name); // find objecttype by name
|
objecttype_t *findotn(char *name); // find objecttype by name
|
||||||
void genhiddennames(void);
|
void genhiddennames(void);
|
||||||
|
int getcharges(object_t *o);
|
||||||
|
int geteffecttime(int min, int max, enum BLESSTYPE isblessed);
|
||||||
|
int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, enum ATTRIB whichatt);
|
||||||
|
int getobaccuracy(object_t *wep);
|
||||||
|
int getobvalue(object_t *o);
|
||||||
|
//int getobtypevalue(objecttype_t *ot);
|
||||||
|
char *getaccuracyname(int accpct);
|
||||||
|
object_t *getammo(lifeform_t *lf);
|
||||||
|
object_t *getrandomammo(lifeform_t *lf);
|
||||||
char *getdamname(enum DAMTYPE damtype);
|
char *getdamname(enum DAMTYPE damtype);
|
||||||
|
char *getdamnamenoun(enum DAMTYPE damtype);
|
||||||
|
char *getfillingname(int nutrition);
|
||||||
|
int getfirearmrange(object_t *o);
|
||||||
|
int getfirearmspeed(object_t *o);
|
||||||
char getglyph(object_t *o);
|
char getglyph(object_t *o);
|
||||||
char *genhiddenname(enum OBCLASS id);
|
char *genhiddenname(enum OBCLASS id);
|
||||||
char *gethiddenname(object_t *o);
|
char *gethiddenname(object_t *o);
|
||||||
int getobattackspeed(object_t *o);
|
int getobattackspeed(object_t *o);
|
||||||
int getletindex(char let);
|
int getletindex(char let);
|
||||||
|
int getmaterialvalue(enum MATERIAL mat );
|
||||||
|
int getmaxthrowrange(lifeform_t *lf, object_t *o);
|
||||||
char getnextletter(obpile_t *op, char *wantletter);
|
char getnextletter(obpile_t *op, char *wantletter);
|
||||||
|
int getnumshards(object_t *o);
|
||||||
|
int getnutritionbase(object_t *o);
|
||||||
|
int getnutrition(object_t *o);
|
||||||
|
char *getobdesc(object_t *o, char *buf);
|
||||||
|
cell_t *getoblocation(object_t *o);
|
||||||
char *getobname(object_t *o, char *buf, int count);
|
char *getobname(object_t *o, char *buf, int count);
|
||||||
|
char *real_getobname(object_t *o, char *buf, int count, int wantcondition, int adjustforblind, int wantblesscurse);
|
||||||
|
float getobpileweight(obpile_t *op);
|
||||||
|
char *getobconditionname(object_t *o, char *buf);
|
||||||
|
char *getobhurtname(object_t *o, enum DAMTYPE damtype);
|
||||||
|
float getobweight(object_t *o);
|
||||||
|
float getobunitweight(object_t *o);
|
||||||
|
objecttype_t *getoppositestairs(objecttype_t *ot);
|
||||||
|
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth);
|
||||||
char *getrandomob(map_t *map, char *buf);
|
char *getrandomob(map_t *map, char *buf);
|
||||||
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf);
|
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf);
|
||||||
|
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf);
|
||||||
|
char *getschoolname(enum SPELLSCHOOL sch);
|
||||||
|
int getshatterdam(object_t *o);
|
||||||
|
int getthrowdam(object_t *o);
|
||||||
|
int hasedibleob(obpile_t *op);
|
||||||
object_t *hasknownob(obpile_t *op, enum OBTYPE oid);
|
object_t *hasknownob(obpile_t *op, enum OBTYPE oid);
|
||||||
object_t *hasob(obpile_t *op, enum OBTYPE oid);
|
object_t *hasob(obpile_t *op, enum OBTYPE oid);
|
||||||
|
object_t *hasobofclass(obpile_t *op, enum OBCLASS cid);
|
||||||
|
object_t *hasobmulti(obpile_t *op, enum OBTYPE *oid, int noids);
|
||||||
|
object_t *hasobwithflag(obpile_t *op, enum FLAG flagid);
|
||||||
|
object_t *hasobwithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text);
|
||||||
object_t *hasobid(obpile_t *op, int id);
|
object_t *hasobid(obpile_t *op, int id);
|
||||||
|
void identify(object_t *o);
|
||||||
void initobjects(void);
|
void initobjects(void);
|
||||||
|
flag_t *isarmour(object_t *o);
|
||||||
|
int isactivated(object_t *o);
|
||||||
|
int isammofor(object_t *ammo, object_t *gun);
|
||||||
|
int isbetterarmourthan(object_t *a, object_t *b);
|
||||||
|
int isbetterwepthan(object_t *a, object_t *b);
|
||||||
|
int isblessed(object_t *o);
|
||||||
|
int isblessknown(object_t *o);
|
||||||
|
int iscorpse(object_t *o);
|
||||||
|
int iscursed(object_t *o);
|
||||||
int isdrinkable(object_t *o);
|
int isdrinkable(object_t *o);
|
||||||
|
int isedible(object_t *o);
|
||||||
|
flag_t *isequipped(object_t *o);
|
||||||
|
int isequippedon(object_t *o, enum BODYPART bp);
|
||||||
|
int isfirearm(object_t *o);
|
||||||
|
int isflammable(object_t *o);
|
||||||
int isknown(object_t *o);
|
int isknown(object_t *o);
|
||||||
|
int isidentified(object_t *o);
|
||||||
|
int ismetal(enum MATERIAL mat);
|
||||||
|
int ismissile(object_t *o);
|
||||||
|
int isoperable(object_t *o);
|
||||||
int isplainob(object_t *o);
|
int isplainob(object_t *o);
|
||||||
|
int ispourable(object_t *o);
|
||||||
|
int ispushable(object_t *o);
|
||||||
int isreadable(object_t *o);
|
int isreadable(object_t *o);
|
||||||
|
int isrotting(object_t *o);
|
||||||
|
int isweapon(object_t *o);
|
||||||
|
int iswearable(object_t *o);
|
||||||
void killmaterial(material_t *m);
|
void killmaterial(material_t *m);
|
||||||
void killob(object_t *o);
|
void killob(object_t *o);
|
||||||
|
void killobpile(obpile_t *o);
|
||||||
void killoc(objectclass_t *oc);
|
void killoc(objectclass_t *oc);
|
||||||
void killot(objecttype_t *ot);
|
void killot(objecttype_t *ot);
|
||||||
|
lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level);
|
||||||
void makeknown(enum OBTYPE otid);
|
void makeknown(enum OBTYPE otid);
|
||||||
object_t *moveob(object_t *src, obpile_t *dst, int howmany);
|
object_t *moveob(object_t *src, obpile_t *dst, int howmany);
|
||||||
|
object_t *newobeffects(object_t *o);
|
||||||
|
void obaction(object_t *o, char *text);
|
||||||
object_t *obexists(enum OBTYPE obid);
|
object_t *obexists(enum OBTYPE obid);
|
||||||
|
void obdie(object_t *o);
|
||||||
int obfits(object_t *o, obpile_t *op);
|
int obfits(object_t *o, obpile_t *op);
|
||||||
|
enum DAMTYPE oblastdamtype(object_t *o);
|
||||||
|
flag_t *obproduceslight(object_t *o);
|
||||||
int obpropsmatch(object_t *a, object_t *b);
|
int obpropsmatch(object_t *a, object_t *b);
|
||||||
|
int obotpropsmatch(object_t *a, objecttype_t *b);
|
||||||
|
int operate(lifeform_t *lf, object_t *o);
|
||||||
int pilehasletter(obpile_t *op, char let);
|
int pilehasletter(obpile_t *op, char let);
|
||||||
|
void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE isblessed, int *seen);
|
||||||
|
int pour(lifeform_t *lf, object_t *o);
|
||||||
void quaff(lifeform_t *lf, object_t *o);
|
void quaff(lifeform_t *lf, object_t *o);
|
||||||
void read(lifeform_t *lf, object_t *o);
|
void readsomething(lifeform_t *lf, object_t *o);
|
||||||
|
void removedeadobs(obpile_t *op);
|
||||||
int removeob(object_t *o, int howmany);
|
int removeob(object_t *o, int howmany);
|
||||||
object_t *relinkob(object_t *src, obpile_t *dst);
|
object_t *relinkob(object_t *src, obpile_t *dst);
|
||||||
void throwat(lifeform_t *thrower, object_t *o, cell_t *where);
|
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
||||||
|
void setinscription(object_t *o, char *text);
|
||||||
|
object_t *splitob(object_t *o);
|
||||||
|
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||||
|
int fireat(lifeform_t *thrower, object_t *o, cell_t *where, int speed, object_t *firearm);
|
||||||
|
void timeeffectsob(object_t *o);
|
||||||
|
void turnoff(lifeform_t *lf, object_t *o);
|
||||||
|
void turnon(lifeform_t *lf, object_t *o);
|
||||||
|
int usecharge(object_t *o);
|
||||||
|
int validateobs(void);
|
||||||
int willshatter(enum MATERIAL mat);
|
int willshatter(enum MATERIAL mat);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
208
save.c
208
save.c
|
@ -3,7 +3,10 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "flag.h"
|
||||||
|
#include "io.h"
|
||||||
#include "lf.h"
|
#include "lf.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "move.h"
|
#include "move.h"
|
||||||
|
@ -11,6 +14,8 @@
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
|
||||||
|
extern long curtime;
|
||||||
|
|
||||||
extern lifeform_t *player;
|
extern lifeform_t *player;
|
||||||
extern map_t *firstmap;
|
extern map_t *firstmap;
|
||||||
extern knowledge_t *knowledge;
|
extern knowledge_t *knowledge;
|
||||||
|
@ -20,8 +25,6 @@ int loading = B_FALSE;
|
||||||
int loadall(void) {
|
int loadall(void) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
char *filename;
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
loading = B_TRUE;
|
loading = B_TRUE;
|
||||||
|
|
||||||
|
@ -52,6 +55,42 @@ int loadall(void) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int loadflagpile(FILE *f, flagpile_t *fp) {
|
||||||
|
flag_t tempflag;
|
||||||
|
flag_t *fl;
|
||||||
|
char buf[BUFLEN];
|
||||||
|
int rv;
|
||||||
|
int db = B_TRUE;
|
||||||
|
|
||||||
|
rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n",
|
||||||
|
&tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom);
|
||||||
|
|
||||||
|
while (tempflag.id != -1) {
|
||||||
|
dblog("got flag id=%d\n",tempflag.id);
|
||||||
|
// get flag text
|
||||||
|
fgets(buf, BUFLEN, f);
|
||||||
|
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||||
|
|
||||||
|
fl = addflag_real(fp, tempflag.id,
|
||||||
|
tempflag.val[0],
|
||||||
|
tempflag.val[1],
|
||||||
|
tempflag.val[2], strcmp(buf, "^^^") ? buf : NULL, tempflag.lifetime, tempflag.known);
|
||||||
|
|
||||||
|
fl->obfrom = tempflag.obfrom;
|
||||||
|
|
||||||
|
if (db) {
|
||||||
|
dblog("--> added flag id=%d. v0=%d, v1=%d, v2=%d, text=%s, lifetime=%d, known=%d, obfrom=%ld\n",fl->id,
|
||||||
|
fl->val[0], fl->val[1], fl->val[2], fl->text ? fl->text : "(null)", fl->lifetime, fl->known,fl->obfrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load next one
|
||||||
|
rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n",
|
||||||
|
&tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom);
|
||||||
|
//dblog("fscanf returned %d\n",rv);
|
||||||
|
}
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int loadknowledge(FILE *f) {
|
int loadknowledge(FILE *f) {
|
||||||
int db = B_FALSE;
|
int db = B_FALSE;
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
|
@ -74,6 +113,16 @@ int loadknowledge(FILE *f) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int loadvars(FILE *f) {
|
||||||
|
int db = B_FALSE;
|
||||||
|
if (db) dblog("--> Loading knowledge...\n");
|
||||||
|
fscanf(f, "startvars\n");
|
||||||
|
fscanf(f, "curtime:%ld\n",&curtime);
|
||||||
|
fscanf(f, "endvars\n");
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
// load and allocate one lifeform from given file
|
// load and allocate one lifeform from given file
|
||||||
lifeform_t *loadlf(FILE *f, cell_t *where) {
|
lifeform_t *loadlf(FILE *f, cell_t *where) {
|
||||||
lifeform_t *l;
|
lifeform_t *l;
|
||||||
|
@ -117,9 +166,15 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
||||||
l->y = y;
|
l->y = y;
|
||||||
|
|
||||||
// load rest of this lf
|
// load rest of this lf
|
||||||
|
fscanf(f, "str: %d/%d\n",&l->att[A_STR],&l->baseatt[A_STR]);
|
||||||
|
fscanf(f, "dex: %d/%d\n",&l->att[A_DEX],&l->baseatt[A_DEX]);
|
||||||
|
fscanf(f, "int: %d/%d\n",&l->att[A_IQ],&l->baseatt[A_IQ]);
|
||||||
|
fscanf(f, "xp: %ld\n",&l->xp);
|
||||||
fscanf(f, "contr: %d\n",&l->controller);
|
fscanf(f, "contr: %d\n",&l->controller);
|
||||||
fscanf(f, "hp: %d/%d\n",&l->hp, &l->maxhp);
|
fscanf(f, "hp: %d/%d\n",&l->hp, &l->maxhp);
|
||||||
|
fscanf(f, "mp: %d/%d\n",&l->mp, &l->maxmp);
|
||||||
fscanf(f, "alive: %d\n",&l->alive);
|
fscanf(f, "alive: %d\n",&l->alive);
|
||||||
|
fscanf(f, "lastdamtype: %d\n",(int *)&l->lastdamtype);
|
||||||
|
|
||||||
fgets(buf, BUFLEN, f); // lastdam
|
fgets(buf, BUFLEN, f); // lastdam
|
||||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||||
|
@ -128,9 +183,15 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
||||||
fscanf(f, "timespent: %d\n",&l->timespent);
|
fscanf(f, "timespent: %d\n",&l->timespent);
|
||||||
|
|
||||||
fscanf(f, "sorted: %d\n",&l->sorted);
|
fscanf(f, "sorted: %d\n",&l->sorted);
|
||||||
|
fscanf(f, "polyrevert: %d\n",&l->polyrevert);
|
||||||
fscanf(f, "forgettimer: %f\n",&l->forgettimer);
|
fscanf(f, "forgettimer: %f\n",&l->forgettimer);
|
||||||
|
|
||||||
if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading ob list.",l->hp,l->maxhp,l->timespent,l->sorted);
|
if (db) dblog("--> Got hp=%d/%d. timespend=%d. sorted=%d. Now loading flags.",l->hp,l->maxhp,l->timespent,l->sorted);
|
||||||
|
|
||||||
|
// lf flags
|
||||||
|
loadflagpile(f, l->flags);
|
||||||
|
|
||||||
|
if (db) dblog("--> now loading objects");
|
||||||
|
|
||||||
// load object list
|
// load object list
|
||||||
obcount = 0;
|
obcount = 0;
|
||||||
|
@ -165,6 +226,9 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
||||||
if (l->controller == C_PLAYER) {
|
if (l->controller == C_PLAYER) {
|
||||||
player = l;
|
player = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortlf(l->cell->map, l);
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,13 +237,12 @@ map_t *loadmap(char *basefile) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char filename[BUFLEN];
|
char filename[BUFLEN];
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
char buf2[BUFLEN];
|
|
||||||
int obcount;
|
int obcount;
|
||||||
int i;
|
int i;
|
||||||
int x,y;
|
int x,y;
|
||||||
int db = B_TRUE;
|
int db = B_TRUE;
|
||||||
lifeform_t *l;
|
lifeform_t *l;
|
||||||
object_t *o,*nexto;
|
object_t *o;
|
||||||
map_t *m;
|
map_t *m;
|
||||||
cell_t *dummycell;
|
cell_t *dummycell;
|
||||||
|
|
||||||
|
@ -202,13 +265,13 @@ map_t *loadmap(char *basefile) {
|
||||||
// load map info
|
// load map info
|
||||||
if (db) dblog("--> Loading map info...\n");
|
if (db) dblog("--> Loading map info...\n");
|
||||||
fscanf(f, "id:%d\n",&m->id); // map id
|
fscanf(f, "id:%d\n",&m->id); // map id
|
||||||
|
fscanf(f, "depth:%d\n",&m->depth); // map depth
|
||||||
fgets(buf, BUFLEN, f); // map name
|
fgets(buf, BUFLEN, f); // map name
|
||||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||||
m->name = strdup(buf + 5); // after 'name:'
|
m->name = strdup(buf + 5); // after 'name:'
|
||||||
fscanf(f, "habitat:%d\n",(int *)&m->habitat); // habitat
|
fscanf(f, "habitat:%d\n",(int *)&m->habitat); // habitat
|
||||||
fscanf(f, "seed:%d\n",&m->seed); // seed
|
fscanf(f, "seed:%d\n",&m->seed); // seed
|
||||||
fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons
|
fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons
|
||||||
fscanf(f, "nextlfid:%ld\n",&m->nextlfid);
|
|
||||||
fscanf(f, "nextmaps:\n");
|
fscanf(f, "nextmaps:\n");
|
||||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||||
fscanf(f, "%d\n",&m->nextmap[i]); // map dimensons
|
fscanf(f, "%d\n",&m->nextmap[i]); // map dimensons
|
||||||
|
@ -253,8 +316,8 @@ map_t *loadmap(char *basefile) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// cell info
|
// cell info
|
||||||
fscanf(f, "%d,%d,%d,%d\n",
|
fscanf(f, "%d,%d,%d,%d,%d\n",
|
||||||
&c->roomid, &celltypeid, &c->known, &c->visited);
|
&c->roomid, &celltypeid, &c->known, &c->visited, &c->lit);
|
||||||
|
|
||||||
|
|
||||||
ct = findcelltype(celltypeid);
|
ct = findcelltype(celltypeid);
|
||||||
|
@ -286,7 +349,6 @@ map_t *loadmap(char *basefile) {
|
||||||
|
|
||||||
// create all objects in a dummy cell
|
// create all objects in a dummy cell
|
||||||
for (i = 0; i < obcount; i++) {
|
for (i = 0; i < obcount; i++) {
|
||||||
int n;
|
|
||||||
long thisid;
|
long thisid;
|
||||||
if (db) dblog("-----> loading into dummycell: mapob %d/%d...\n",i+1,obcount);
|
if (db) dblog("-----> loading into dummycell: mapob %d/%d...\n",i+1,obcount);
|
||||||
if (loadob(f, dummycell->obpile, &thisid)) {
|
if (loadob(f, dummycell->obpile, &thisid)) {
|
||||||
|
@ -398,9 +460,6 @@ int loadob(FILE *f, obpile_t *op, long *id) {
|
||||||
long obid;
|
long obid;
|
||||||
int otid,matid;
|
int otid,matid;
|
||||||
char buf[BUFLEN];
|
char buf[BUFLEN];
|
||||||
int flagid;
|
|
||||||
flag_t tempflag;
|
|
||||||
int rv;
|
|
||||||
int db = B_TRUE;
|
int db = B_TRUE;
|
||||||
|
|
||||||
fscanf(f, "id:%ld\n",&obid);
|
fscanf(f, "id:%ld\n",&obid);
|
||||||
|
@ -413,7 +472,7 @@ int loadob(FILE *f, obpile_t *op, long *id) {
|
||||||
|
|
||||||
ot = findot(otid);
|
ot = findot(otid);
|
||||||
if (!ot) {
|
if (!ot) {
|
||||||
dblog("ERROR loading objects - can't find obtype id %ld\n",obid);
|
dblog("ERROR loading objects - can't find obtype id %d (obj id %ld)\n",otid,obid);
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
// create the object
|
// create the object
|
||||||
|
@ -442,29 +501,20 @@ int loadob(FILE *f, obpile_t *op, long *id) {
|
||||||
fscanf(f, "bless:%d\n",&o->blessed);
|
fscanf(f, "bless:%d\n",&o->blessed);
|
||||||
fscanf(f, "blessknown:%d\n",&o->blessknown);
|
fscanf(f, "blessknown:%d\n",&o->blessknown);
|
||||||
fscanf(f, "amt:%d\n",&o->amt);
|
fscanf(f, "amt:%d\n",&o->amt);
|
||||||
|
fscanf(f, "birthtime:%ld\n",&o->birthtime);
|
||||||
|
|
||||||
|
// now remove ALL obejct flags (which were inherited
|
||||||
|
// from the obtype during addobject() ). these will be
|
||||||
|
// loaded in instead.
|
||||||
|
|
||||||
|
while (o->flags->first) {
|
||||||
|
killflag(o->flags->first);
|
||||||
|
}
|
||||||
|
|
||||||
fscanf(f, "flags:\n");
|
fscanf(f, "flags:\n");
|
||||||
|
|
||||||
dblog("About to start loading object flags...");
|
dblog("About to start loading object flags...");
|
||||||
rv = fscanf(f, "%d,%d,%d,%d,%d\n",
|
loadflagpile(f, o->flags);
|
||||||
&tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2]);
|
|
||||||
|
|
||||||
while (tempflag.id != -1) {
|
|
||||||
dblog("got flag id=%d\n",tempflag.id);
|
|
||||||
// get flag text
|
|
||||||
fgets(buf, BUFLEN, f);
|
|
||||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
|
||||||
|
|
||||||
|
|
||||||
addflag(o->flags, tempflag.id,
|
|
||||||
tempflag.val[0],
|
|
||||||
tempflag.val[1],
|
|
||||||
tempflag.val[2], strcmp(buf, "^^^") ? buf : NULL);
|
|
||||||
// load next one
|
|
||||||
rv = fscanf(f, "%d,%d,%d,%d,%d\n",
|
|
||||||
&tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2]);
|
|
||||||
//dblog("fscanf returned %d\n",rv);
|
|
||||||
}
|
|
||||||
fscanf(f, "endob\n");
|
fscanf(f, "endob\n");
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -504,6 +554,10 @@ int loadsavegame(void) {
|
||||||
printf("Error loading knowledge from file '%s'",ent->d_name);
|
printf("Error loading knowledge from file '%s'",ent->d_name);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (loadvars(f)) {
|
||||||
|
printf("Error loading game variables from file '%s'",ent->d_name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
// successful load - kill the savegame now
|
// successful load - kill the savegame now
|
||||||
|
@ -512,14 +566,38 @@ int loadsavegame(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int savevars(FILE *f) {
|
||||||
|
int db = B_FALSE;
|
||||||
|
if (db) dblog("--> Saving knowledge...\n");
|
||||||
|
fprintf(f, "startvars\n");
|
||||||
|
fprintf(f, "curtime:%ld\n",curtime);
|
||||||
|
fprintf(f, "endvars\n");
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int saveflagpile(FILE *f, flagpile_t *fp) {
|
||||||
|
flag_t *fl;
|
||||||
|
fprintf(f, "flags:\n");
|
||||||
|
for (fl = fp->first ; fl ; fl = fl->next) {
|
||||||
|
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n",
|
||||||
|
fl->id, fl->nvals, fl->val[0], fl->val[1], fl->val[2],fl->lifetime,fl->known,fl->obfrom);
|
||||||
|
if (!fl->text || !strcmp(fl->text, "")) {
|
||||||
|
fprintf(f, "%s\n","^^^");
|
||||||
|
} else {
|
||||||
|
fprintf(f, "%s\n",fl->text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(f, "-1,-1,-1,-1,-1,-1,-1,-1\n");
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int saveknowledge(FILE *f) {
|
int saveknowledge(FILE *f) {
|
||||||
int db = B_FALSE;
|
int db = B_FALSE;
|
||||||
char buf[BUFLEN];
|
|
||||||
int otid,known;
|
|
||||||
char hiddenname[BUFLEN];
|
|
||||||
knowledge_t *k;
|
knowledge_t *k;
|
||||||
if (db) dblog("--> Saving knowledge...\n");
|
if (db) dblog("--> Saving knowledge...\n");
|
||||||
fprintf(f, "startknowledge\n");
|
fprintf(f, "startknowledge\n");
|
||||||
|
@ -542,14 +620,25 @@ int savelf(FILE *f, lifeform_t *l) {
|
||||||
fprintf(f, "map: %d\n",l->cell->map->id);
|
fprintf(f, "map: %d\n",l->cell->map->id);
|
||||||
fprintf(f, "pos: %d,%d\n",l->cell->x, l->cell->y);
|
fprintf(f, "pos: %d,%d\n",l->cell->x, l->cell->y);
|
||||||
fprintf(f, "level: %d\n",l->level);
|
fprintf(f, "level: %d\n",l->level);
|
||||||
// liefform will be cfeated after loading the above.
|
// liefform will be created after loading the above.
|
||||||
|
fprintf(f, "str: %d/%d\n",l->att[A_STR],l->baseatt[A_STR]);
|
||||||
|
fprintf(f, "dex: %d/%d\n",l->att[A_DEX],l->baseatt[A_DEX]);
|
||||||
|
fprintf(f, "int: %d/%d\n",l->att[A_IQ],l->baseatt[A_IQ]);
|
||||||
|
fprintf(f, "xp: %ld\n",l->xp);
|
||||||
fprintf(f, "contr: %d\n",l->controller);
|
fprintf(f, "contr: %d\n",l->controller);
|
||||||
fprintf(f, "hp: %d/%d\n",l->hp, l->maxhp);
|
fprintf(f, "hp: %d/%d\n",l->hp, l->maxhp);
|
||||||
|
fprintf(f, "mp: %d/%d\n",l->mp, l->maxmp);
|
||||||
fprintf(f, "alive: %d\n",l->alive);
|
fprintf(f, "alive: %d\n",l->alive);
|
||||||
|
fprintf(f, "lastdamtype: %d\n",l->lastdamtype);
|
||||||
fprintf(f, "lastdam: %s\n",l->lastdam);
|
fprintf(f, "lastdam: %s\n",l->lastdam);
|
||||||
fprintf(f, "timespent: %d\n",l->timespent);
|
fprintf(f, "timespent: %d\n",l->timespent);
|
||||||
fprintf(f, "sorted: %d\n",l->sorted);
|
fprintf(f, "sorted: %d\n",l->sorted);
|
||||||
|
fprintf(f, "polyrevert: %d\n",l->polyrevert);
|
||||||
fprintf(f, "forgettimer: %f\n",l->forgettimer);
|
fprintf(f, "forgettimer: %f\n",l->forgettimer);
|
||||||
|
|
||||||
|
// lf flags
|
||||||
|
saveflagpile(f, l->flags);
|
||||||
|
|
||||||
// lifeform objects
|
// lifeform objects
|
||||||
obcount = 0;
|
obcount = 0;
|
||||||
for (o = l->pack->first ; o ; o = o->next) {
|
for (o = l->pack->first ; o ; o = o->next) {
|
||||||
|
@ -568,6 +657,33 @@ int savelf(FILE *f, lifeform_t *l) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int savegame(void) {
|
||||||
|
map_t *m;
|
||||||
|
FILE *f;
|
||||||
|
char buf[BUFLEN];
|
||||||
|
int rv;
|
||||||
|
for (m = firstmap; m ; m = m->next) {
|
||||||
|
// save world
|
||||||
|
rv = savemap(m);
|
||||||
|
if (rv) {
|
||||||
|
msg("Could not save map '%s'",m->name);
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
// save player + their objects
|
||||||
|
sprintf(buf, "%s/game.sav",SAVEDIR);
|
||||||
|
f = fopen(buf, "wt");
|
||||||
|
if (!f) {
|
||||||
|
msg("Could not open save file!");
|
||||||
|
return B_TRUE;
|
||||||
|
}
|
||||||
|
savelf(f, player);
|
||||||
|
saveknowledge(f);
|
||||||
|
savevars(f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
int savemap(map_t *m) {
|
int savemap(map_t *m) {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
@ -584,11 +700,11 @@ int savemap(map_t *m) {
|
||||||
|
|
||||||
// save map info
|
// save map info
|
||||||
fprintf(f, "id:%d\n",m->id); // map id
|
fprintf(f, "id:%d\n",m->id); // map id
|
||||||
|
fprintf(f, "depth:%d\n",m->depth); // map depth
|
||||||
fprintf(f, "name:%s\n",m->name); // map name
|
fprintf(f, "name:%s\n",m->name); // map name
|
||||||
fprintf(f, "habitat:%d\n",m->habitat); // habitat
|
fprintf(f, "habitat:%d\n",m->habitat); // habitat
|
||||||
fprintf(f, "seed:%d\n",m->seed); // seed
|
fprintf(f, "seed:%d\n",m->seed); // seed
|
||||||
fprintf(f, "dims:%d,%d\n",m->w, m->h); // map dimensons
|
fprintf(f, "dims:%d,%d\n",m->w, m->h); // map dimensons
|
||||||
fprintf(f, "nextlfid:%ld\n",m->nextlfid);
|
|
||||||
fprintf(f, "nextmaps:\n");
|
fprintf(f, "nextmaps:\n");
|
||||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||||
fprintf(f, "%d\n",m->nextmap[i] ); // map dimensons
|
fprintf(f, "%d\n",m->nextmap[i] ); // map dimensons
|
||||||
|
@ -610,8 +726,8 @@ int savemap(map_t *m) {
|
||||||
cell_t *c;
|
cell_t *c;
|
||||||
c = getcellat(m, x, y);
|
c = getcellat(m, x, y);
|
||||||
// cell info
|
// cell info
|
||||||
fprintf(f, "%d,%d,%d,%d\n",
|
fprintf(f, "%d,%d,%d,%d,%d\n",
|
||||||
c->roomid, c->type->id, c->known, c->visited);
|
c->roomid, c->type->id, c->known, c->visited,c->lit);
|
||||||
// cell objects
|
// cell objects
|
||||||
for (o = c->obpile->first ; o ; o = o->next) {
|
for (o = c->obpile->first ; o ; o = o->next) {
|
||||||
fprintf(f, "ob:%ld\n",o->id);
|
fprintf(f, "ob:%ld\n",o->id);
|
||||||
|
@ -641,7 +757,6 @@ int savemap(map_t *m) {
|
||||||
|
|
||||||
|
|
||||||
int saveob(FILE *f, object_t *o) {
|
int saveob(FILE *f, object_t *o) {
|
||||||
flag_t *fl;
|
|
||||||
fprintf(f, "id:%ld\n",o->id);
|
fprintf(f, "id:%ld\n",o->id);
|
||||||
fprintf(f, "type:%d\n",o->type->id);
|
fprintf(f, "type:%d\n",o->type->id);
|
||||||
fprintf(f, "material:%d\n",o->material->id);
|
fprintf(f, "material:%d\n",o->material->id);
|
||||||
|
@ -651,17 +766,8 @@ int saveob(FILE *f, object_t *o) {
|
||||||
fprintf(f, "bless:%d\n",o->blessed);
|
fprintf(f, "bless:%d\n",o->blessed);
|
||||||
fprintf(f, "blessknown:%d\n",o->blessknown);
|
fprintf(f, "blessknown:%d\n",o->blessknown);
|
||||||
fprintf(f, "amt:%d\n",o->amt);
|
fprintf(f, "amt:%d\n",o->amt);
|
||||||
fprintf(f, "flags:\n");
|
fprintf(f, "birthtime:%ld\n",o->birthtime);
|
||||||
for (fl = o->flags->first ; fl ; fl = fl->next) {
|
saveflagpile(f, o->flags);
|
||||||
fprintf(f, "%d,%d,%d,%d,%d\n",
|
|
||||||
fl->id, fl->nvals, fl->val[0], fl->val[1], fl->val[2]);
|
|
||||||
if (!fl->text || !strcmp(fl->text, "")) {
|
|
||||||
fprintf(f, "%s\n","^^^");
|
|
||||||
} else {
|
|
||||||
fprintf(f, "%s\n",fl->text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(f, "-1,-1,-1,-1,-1\n");
|
|
||||||
fprintf(f, "endob\n");
|
fprintf(f, "endob\n");
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
3
save.h
3
save.h
|
@ -1,12 +1,15 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
int loadall(void);
|
int loadall(void);
|
||||||
|
int loadflagpile(FILE *f, flagpile_t *fp);
|
||||||
int loadknowledge(FILE *f);
|
int loadknowledge(FILE *f);
|
||||||
lifeform_t *loadlf(FILE *f, cell_t *where);
|
lifeform_t *loadlf(FILE *f, cell_t *where);
|
||||||
map_t *loadmap(char *basefile);
|
map_t *loadmap(char *basefile);
|
||||||
int loadob(FILE *f, obpile_t *op, long *id);
|
int loadob(FILE *f, obpile_t *op, long *id);
|
||||||
int loadsavegame(void);
|
int loadsavegame(void);
|
||||||
|
int saveflagpile(FILE *f, flagpile_t *fp);
|
||||||
int saveknowledge(FILE *f);
|
int saveknowledge(FILE *f);
|
||||||
int savelf(FILE *f, lifeform_t *l);
|
int savelf(FILE *f, lifeform_t *l);
|
||||||
|
int savegame(void);
|
||||||
int savemap(map_t *m);
|
int savemap(map_t *m);
|
||||||
int saveob(FILE *f, object_t *o);
|
int saveob(FILE *f, object_t *o);
|
||||||
|
|
10
spell.h
10
spell.h
|
@ -2,7 +2,13 @@
|
||||||
#define __SPELLS_H
|
#define __SPELLS_H
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
void dospelleffects(lifeform_t *caster, enum OBTYPE spellid, lifeform_t *target);
|
int abilityeffects(lifeform_t *user, enum OBTYPE abilid);
|
||||||
|
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer);
|
||||||
|
void fizzle(lifeform_t *caster);
|
||||||
|
int getmpcost(enum OBTYPE oid);
|
||||||
|
void pullobto(object_t *o, lifeform_t *lf);
|
||||||
|
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlof);
|
||||||
|
lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
283
text.c
283
text.c
|
@ -1,14 +1,131 @@
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "lf.h"
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
#include "text.h"
|
||||||
|
|
||||||
|
extern long curtime;
|
||||||
|
|
||||||
char *capitalise(char *text) {
|
char *capitalise(char *text) {
|
||||||
text[0] = toupper(text[0]);
|
if (strlen(text) > 0) {
|
||||||
|
text[0] = toupper(text[0]);
|
||||||
|
}
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *getattrname(enum ATTRIB att) {
|
||||||
|
switch (att) {
|
||||||
|
case A_STR:
|
||||||
|
return "strength";
|
||||||
|
case A_IQ:
|
||||||
|
return "intelligence";
|
||||||
|
case A_DEX:
|
||||||
|
return "dexterity";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "?unknown?";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getpossessive(char *text) {
|
||||||
|
char lastchar;
|
||||||
|
// you -> your
|
||||||
|
if (!strcmp(text, "you")) {
|
||||||
|
return "r";
|
||||||
|
}
|
||||||
|
|
||||||
|
// xxxs -> xxxs'
|
||||||
|
lastchar = text[strlen(text)-1];
|
||||||
|
if (tolower(lastchar) == 's') {
|
||||||
|
return "'";
|
||||||
|
}
|
||||||
|
// default: 's
|
||||||
|
return "'s";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getsizetext(enum LFSIZE sz) {
|
||||||
|
switch (sz) {
|
||||||
|
case SZ_ENORMOUS:
|
||||||
|
return "enormous";
|
||||||
|
case SZ_HUGE:
|
||||||
|
return "huge";
|
||||||
|
case SZ_LARGE:
|
||||||
|
return "large";
|
||||||
|
case SZ_HUMAN:
|
||||||
|
return "human-sized";
|
||||||
|
case SZ_MEDIUM:
|
||||||
|
return "medium";
|
||||||
|
case SZ_SMALL:
|
||||||
|
return "small";
|
||||||
|
case SZ_MINI:
|
||||||
|
case SZ_TINY:
|
||||||
|
return "extremely small";
|
||||||
|
default:
|
||||||
|
return "unknown-sized";
|
||||||
|
}
|
||||||
|
return "unknown-sized";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *gettimetext(char *retbuf) {
|
||||||
|
int hours,mins,secs;
|
||||||
|
splittime(&hours, &mins, &secs);
|
||||||
|
|
||||||
|
sprintf(retbuf, "%02d:%02d:%02d",hours,mins,secs);
|
||||||
|
return retbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *gettimetextfuzzy(char *retbuf, int wantpm) {
|
||||||
|
int hours,mins,secs;
|
||||||
|
int pm = B_FALSE;
|
||||||
|
splittime(&hours, &mins, &secs);
|
||||||
|
|
||||||
|
if (hours > 12) {
|
||||||
|
hours -= 12;
|
||||||
|
pm = B_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mins == 0) {
|
||||||
|
sprintf(retbuf, "exactly %d o'clock", hours);
|
||||||
|
} else if (mins <= 15) {
|
||||||
|
sprintf(retbuf, "a little after %d o'clock", hours);
|
||||||
|
} else if (mins <= 25) {
|
||||||
|
sprintf(retbuf, "nearly half past %d", hours);
|
||||||
|
} else if (mins <= 35) {
|
||||||
|
sprintf(retbuf, "around half past %d", hours);
|
||||||
|
} else if (mins <= 45) {
|
||||||
|
sprintf(retbuf, "comung up to %d o'clock", (hours == 12) ? 1 : (hours+1));
|
||||||
|
} else {
|
||||||
|
sprintf(retbuf, "nearly %d o'clock", (hours == 12) ? 1 : (hours+1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantpm) {
|
||||||
|
strcat(retbuf, " in the ");
|
||||||
|
if (pm) {
|
||||||
|
strcat(retbuf, "afternoon");
|
||||||
|
} else {
|
||||||
|
strcat(retbuf, "morning");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getweighttext(float weight, char *buf) {
|
||||||
|
if (weight >= 1) {
|
||||||
|
if ((int)weight == weight) { // ie. is weight an integer?
|
||||||
|
sprintf(buf, "%0.0f kg",weight);
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "%0.1f kg",weight);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "%0.0f grams", weight * 1000);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
int isvowel (char c) {
|
int isvowel (char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -23,23 +140,47 @@ int isvowel (char c) {
|
||||||
|
|
||||||
// allocates and returns new string
|
// allocates and returns new string
|
||||||
char *makeplural(char *text) {
|
char *makeplural(char *text) {
|
||||||
int newlen;
|
|
||||||
char lastlet;
|
char lastlet;
|
||||||
char *newtext;
|
char *newtext;
|
||||||
char *p;
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
newtext = strdup(text);
|
newtext = strdup(text);
|
||||||
|
|
||||||
// scrolls
|
// scrolls
|
||||||
rv = strrep(newtext, "scroll ", "scrolls ");
|
newtext = strrep(newtext, "berry ", "berries ", &rv);
|
||||||
if (rv) return newtext;
|
if (rv) return newtext;
|
||||||
rv = strrep(newtext, "potion ", "potions ");
|
newtext = strrep(newtext, "block ", "blocks ", &rv);
|
||||||
if (rv) return newtext;
|
if (rv) return newtext;
|
||||||
rv = strrep(newtext, "piece ", "pieces ");
|
newtext = strrep(newtext, "can ", "cans ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "chunk ", "chunks ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "gem ", "gems ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "loaf ", "loaves ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "lump ", "lumps ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "piece ", "pieces ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "pile ", "piles ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "pool ", "pools ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "potion ", "potions ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "puddle ", "puddles ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "ring ", "rings ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "scroll ", "scrolls ", &rv);
|
||||||
|
if (rv) return newtext;
|
||||||
|
newtext = strrep(newtext, "vial ", "vials ", &rv);
|
||||||
if (rv) return newtext;
|
if (rv) return newtext;
|
||||||
|
|
||||||
rv = strrep(newtext, "pair ", "pairs ");
|
|
||||||
|
//
|
||||||
|
newtext = strrep(newtext, "pair ", "pairs ", &rv);
|
||||||
// don't return
|
// don't return
|
||||||
|
|
||||||
// default
|
// default
|
||||||
|
@ -56,27 +197,50 @@ char *makeplural(char *text) {
|
||||||
return newtext;
|
return newtext;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strrep(char *text, char *oldtok, char *newtok) {
|
char *noprefix(char *obname) {
|
||||||
|
char *p;
|
||||||
|
p = strchr(obname, ' ');
|
||||||
|
if (p) {
|
||||||
|
p++;
|
||||||
|
return p;
|
||||||
|
} else {
|
||||||
|
return obname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void splittime(int *hours, int *mins, int *secs) {
|
||||||
|
long left;
|
||||||
|
left = curtime;
|
||||||
|
|
||||||
|
*hours = left / 3600;
|
||||||
|
left -= (*hours * 3600);
|
||||||
|
*mins = left / 60;
|
||||||
|
left -= (*mins * 60);
|
||||||
|
*secs = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strrep(char *text, char *oldtok, char *newtok, int *rv) {
|
||||||
char *temp;
|
char *temp;
|
||||||
int rv;
|
temp = strdup(" "); // ooooooo is this bad??
|
||||||
temp = strdup(" ");
|
dostrrep(text, &temp, oldtok, newtok, rv);
|
||||||
rv = dostrrep(text, &temp, oldtok, newtok);
|
|
||||||
// swap
|
// swap
|
||||||
text = realloc(text, strlen(temp));
|
text = realloc(text, strlen(temp)+1); // extra space for NUL
|
||||||
strcpy(text, temp);
|
strcpy(text, temp);
|
||||||
free(temp);
|
free(temp);
|
||||||
return rv;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns TRUE if any replacements made
|
// returns TRUE if any replacements made
|
||||||
int dostrrep(char* in, char** out, char* oldtok, char* newtok) {
|
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv) {
|
||||||
char *temp;
|
char *temp;
|
||||||
char *found = strstr(in, oldtok);
|
char *found = strstr(in, oldtok);
|
||||||
int idx;
|
int idx;
|
||||||
if(!found) {
|
if(!found) {
|
||||||
*out = realloc(*out, strlen(in) + 1);
|
*out = realloc(*out, strlen(in) + 1); // oooooooo crashing in realloc
|
||||||
strcpy(*out, in);
|
strcpy(*out, in);
|
||||||
return B_FALSE;
|
|
||||||
|
if (rv) *rv = B_FALSE;
|
||||||
|
return *out;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = found - in;
|
idx = found - in;
|
||||||
|
@ -90,13 +254,96 @@ int dostrrep(char* in, char** out, char* oldtok, char* newtok) {
|
||||||
strncpy(temp,*out,idx+strlen(newtok));
|
strncpy(temp,*out,idx+strlen(newtok));
|
||||||
temp[idx + strlen(newtok)] = '\0';
|
temp[idx + strlen(newtok)] = '\0';
|
||||||
|
|
||||||
dostrrep(found + strlen(oldtok), out, oldtok, newtok);
|
dostrrep(found + strlen(oldtok), out, oldtok, newtok, rv);
|
||||||
temp = realloc(temp, strlen(temp) + strlen(*out) + 1);
|
temp = realloc(temp, strlen(temp) + strlen(*out) + 1);
|
||||||
strcat(temp,*out);
|
strcat(temp,*out);
|
||||||
free(*out);
|
free(*out);
|
||||||
*out = temp;
|
*out = temp;
|
||||||
|
|
||||||
return B_TRUE;
|
if (rv) *rv = B_TRUE;
|
||||||
|
return *out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strpixmatch(char *haystack, char *needle) {
|
||||||
|
int matched = B_FALSE;
|
||||||
|
char *hword, *nword, *hcont,*ncont;
|
||||||
|
|
||||||
|
if (strchr(needle, ' ') || strchr(haystack, ' ')) {
|
||||||
|
char lochaystack[BUFLEN], locneedle[BUFLEN];
|
||||||
|
strcpy(lochaystack, haystack);
|
||||||
|
strcpy(locneedle, needle);
|
||||||
|
|
||||||
|
// match word for word
|
||||||
|
nword = strtok_r(locneedle, " ", &ncont);
|
||||||
|
hword = strtok_r(lochaystack, " ", &hcont);
|
||||||
|
while (nword && hword) {
|
||||||
|
// all typed words must match
|
||||||
|
if (strcasestr(hword, nword)) {
|
||||||
|
matched = B_TRUE;
|
||||||
|
} else {
|
||||||
|
matched = B_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nword = strtok_r(NULL, " ", &ncont);
|
||||||
|
hword = strtok_r(NULL, " ", &hcont);
|
||||||
|
if (nword && !hword) {
|
||||||
|
matched = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!matched && !strchr(needle, ' ')) {
|
||||||
|
// now try matching typed word against second word in spellname
|
||||||
|
strcpy(lochaystack, haystack);
|
||||||
|
hword = strtok_r(lochaystack, " ", &hcont);
|
||||||
|
while (hword) {
|
||||||
|
if (strcasestr(hword, needle)) {
|
||||||
|
matched = B_TRUE;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
matched = B_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hword = strtok_r(NULL, " ", &hcont);
|
||||||
|
if (!hword) {
|
||||||
|
matched = B_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
if (strcasestr(haystack, needle)) {
|
||||||
|
matched = B_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *you(lifeform_t *lf) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
return "You";
|
||||||
|
}
|
||||||
|
return "It";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *you_l(lifeform_t *lf) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
return "you";
|
||||||
|
}
|
||||||
|
return "it";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *your(lifeform_t *lf) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
return "Your";
|
||||||
|
}
|
||||||
|
return "Its";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *your_l(lifeform_t *lf) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
|
return "your";
|
||||||
|
}
|
||||||
|
return "its";
|
||||||
|
}
|
||||||
|
|
18
text.h
18
text.h
|
@ -1,8 +1,20 @@
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
char *capitalise(char *text);
|
char *capitalise(char *text);
|
||||||
|
char *getattrname(enum ATTRIB att);
|
||||||
|
char *getpossessive(char *text);
|
||||||
|
char *getsizetext(enum LFSIZE sz);
|
||||||
|
char *gettimetext(char *retbuf);
|
||||||
|
char *gettimetextfuzzy(char *retbuf, int wantpm);
|
||||||
|
char *getweighttext(float weight, char *buf);
|
||||||
int isvowel(char c);
|
int isvowel(char c);
|
||||||
char *makeplural(char *text);
|
char *makeplural(char *text);
|
||||||
|
char *noprefix(char *obname);
|
||||||
int strrep(char *text, char *oldtok, char *newtok);
|
void splittime(int *hours, int *mins, int *secs);
|
||||||
int dostrrep(char* in, char** out, char* oldtok, char* newtok);
|
char *strrep(char *text, char *oldtok, char *newtok, int *rv);
|
||||||
|
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
|
||||||
|
int strpixmatch(char *haystack, char *needle);
|
||||||
|
char *you(lifeform_t *lf);
|
||||||
|
char *you_l(lifeform_t *lf);
|
||||||
|
char *your(lifeform_t *lf);
|
||||||
|
char *your_l(lifeform_t *lf);
|
||||||
|
|
Loading…
Reference in New Issue