- Fixed heaps of memory leaks and bad memory usage. This should finally fix the flagpile corruption from 6 years ago!
- forgot to initialise brand->description - door displaying as "leaf" - definition of knowledge->id was OBCLASS instead of OBTYPE. - Repeated text: Minimum agility to use effectively: 50 to use.Minimum agility to use effectively: 50 to use. (bonus at 70). - change wish text to be more meaningful - fix failure when loading objects with a bonus from vaults/bones (eg. blessed '+5' sword) - when raging, don't prompt to really attack when you won't gain xp - disable flagpile checks - Use 'interact' to use shops, not 'operate' - Bad text: You are resistant to: projectiles[-7870t], explosives[-7870t]. - scorpions shouldn't follow you up stairs. (but giant scorpions can) - make failed relinkob() calls return the original object rather than null, otherwise we get situations where an object becomes NULL and causes a crash. - make cooking skill description show what size corpses you can cook. - bug: potion of growth caused instadeath when reverting. - bug: not showing monster abilites properly - show raceclass in descriptions (/ v) - make evasion only work if you're not exhausted - Felix should be pleased by attacking people while hidden - Not seeing felix angered messages when donating items - Holes in roof - you now need to climb to inspect them. - Fixed crash when hitting @ while producing light.
This commit is contained in:
parent
2f80d6ba05
commit
e9a2ccb2c8
78
Makefile
78
Makefile
|
@ -1,62 +1,62 @@
|
|||
#all: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.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 shops.c shops.h spell.c spell.h vault.c vault.h
|
||||
# gcc -Wall -g -pg -o nexus nexus.c ai.c attack.c data.c flag.c god.c io.c lf.c map.c move.c objects.c text.c save.c spell.c shops.c vault.c -lncurses -lsqlite3
|
||||
# gcc -Werror -Wall -g -pg -o nexus nexus.c ai.c attack.c data.c flag.c god.c io.c lf.c map.c move.c objects.c text.c save.c spell.c shops.c vault.c -lncurses -lsqlite3
|
||||
|
||||
nexus: ai.o astar.o attack.o data.o findleak.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o ai.h attack.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -g -pg -Wall -o nexus ai.o astar.o attack.o data.o findleak.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o -lncurses -lsqlite3
|
||||
nexus: ai.o astar.o attack.o data.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o ai.h attack.h data.h defs.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -g -pg -Wall -o nexus ai.o astar.o attack.o data.o flag.o god.o io.o lf.o map.o move.o nexus.o objects.o save.o shops.o spell.o text.o vault.o -lncurses -lsqlite3
|
||||
|
||||
ai.o: ai.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h ai.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o ai.o ai.c
|
||||
ai.o: ai.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h ai.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o ai.o ai.c
|
||||
|
||||
attack.o: attack.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h attack.h astar.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o attack.o attack.c
|
||||
attack.o: attack.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h attack.h astar.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o attack.o attack.c
|
||||
|
||||
astar.o: astar.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h attack.h astar.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o astar.o astar.c
|
||||
astar.o: astar.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h attack.h astar.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o astar.o astar.c
|
||||
|
||||
data.o: data.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h data.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o data.o data.c
|
||||
data.o: data.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h data.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o data.o data.c
|
||||
|
||||
findleak.o: findleak.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h findleak.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o findleak.o findleak.c
|
||||
: ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o
|
||||
|
||||
flag.o: flag.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h flag.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o flag.o flag.c
|
||||
flag.o: flag.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h flag.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o flag.o flag.c
|
||||
|
||||
god.o: god.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h god.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o god.o god.c
|
||||
god.o: god.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h god.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o god.o god.c
|
||||
|
||||
io.o: io.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h io.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o io.o io.c
|
||||
io.o: io.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h io.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o io.o io.c
|
||||
|
||||
lf.o: lf.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h lf.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o lf.o lf.c
|
||||
lf.o: lf.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h lf.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o lf.o lf.c
|
||||
|
||||
map.o: map.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h map.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o map.o map.c
|
||||
map.o: map.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h map.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o map.o map.c
|
||||
|
||||
move.o: move.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h move.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o move.o move.c
|
||||
move.o: move.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h move.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o move.o move.c
|
||||
|
||||
nexus.o: nexus.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o nexus.o nexus.c
|
||||
nexus.o: nexus.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h nexus.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o nexus.o nexus.c
|
||||
|
||||
objects.o: objects.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h objects.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o objects.o objects.c
|
||||
objects.o: objects.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h objects.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o objects.o objects.c
|
||||
|
||||
save.o: save.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h save.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o save.o save.c
|
||||
save.o: save.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h save.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o save.o save.c
|
||||
|
||||
shops.o: shops.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h shops.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o shops.o shops.c
|
||||
shops.o: shops.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h shops.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o shops.o shops.c
|
||||
|
||||
spell.o: spell.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h spell.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o spell.o spell.c
|
||||
spell.o: spell.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h spell.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o spell.o spell.c
|
||||
|
||||
text.o: text.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h text.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o text.o text.c
|
||||
text.o: text.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h text.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o text.o text.c
|
||||
|
||||
vault.o: vault.c ai.h attack.h astar.h data.h defs.h findleak.h flag.h god.h io.h lf.h map.h move.h vault.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Wall -c -g -pg -o vault.o vault.c
|
||||
vault.o: vault.c ai.h attack.h astar.h data.h defs.h flag.h god.h io.h lf.h map.h move.h vault.h objects.h save.h shops.h spell.h text.h vault.h
|
||||
gcc -Werror -Wall -c -g -pg -o vault.o vault.c
|
||||
|
||||
|
||||
######################
|
||||
|
|
69
ai.c
69
ai.c
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -190,6 +191,8 @@ flag_t *ai_createpathto(lifeform_t *lf, cell_t *targcell) {
|
|||
char lfname[BUFLEN];
|
||||
flag_t *newf;
|
||||
|
||||
checkflagpile(lf->flags); // debug
|
||||
|
||||
if (!db && lfhasflag(lf, F_DEBUG)) db = B_TRUE;
|
||||
|
||||
real_getlfname(lf, lfname, NULL, B_SHOWALL, B_CURRACE);
|
||||
|
@ -353,6 +356,7 @@ if (db) dblog("%s pathfind - finding path from %d,%d to %d,%d\n",lfname, lf->cel
|
|||
}
|
||||
}
|
||||
}
|
||||
checkflagpile(lf->flags); // debug
|
||||
|
||||
// work backwards from node[cur] (ie. targcell) following parents.
|
||||
// populate path and return
|
||||
|
@ -366,10 +370,13 @@ if (db) dblog("%s pathfind - finding path from %d,%d to %d,%d\n",lfname, lf->cel
|
|||
|
||||
cur = cur->parent;
|
||||
}
|
||||
checkflagpile(lf->flags); // debug
|
||||
|
||||
pathbuf = malloc(pathlen*6*sizeof(char));
|
||||
strcpy(pathbuf, "");
|
||||
|
||||
checkflagpile(lf->flags); // debug
|
||||
|
||||
for (i = pathlen-1; i >= 0 ; i--) {
|
||||
char smallbuf[BUFLENTINY];
|
||||
// don't include starting cell
|
||||
|
@ -381,8 +388,10 @@ if (db) dblog("%s pathfind - finding path from %d,%d to %d,%d\n",lfname, lf->cel
|
|||
}
|
||||
if (db) dblog("* %s - path takes %d steps. ", lfname, pathlen);
|
||||
if (db) dblog("* %s - pathbuf: [%s] ", lfname, pathbuf);
|
||||
checkflagpile(lf->flags); // debug
|
||||
newf = addflag(lf->flags, F_AIPATH, targcell->x, targcell->y, NA, pathbuf);
|
||||
free(pathbuf);
|
||||
checkflagpile(lf->flags); // debug
|
||||
return newf;
|
||||
}
|
||||
|
||||
|
@ -1701,8 +1710,8 @@ int ai_housekeeping(lifeform_t *lf, lifeform_t *master) {
|
|||
|
||||
int ai_inventory_mgt(lifeform_t *lf, int *canattack) {
|
||||
int db = B_FALSE,i;
|
||||
object_t *curwep,*bestwep, *o;
|
||||
object_t *curgun,*bestgun;
|
||||
object_t *curwep = NULL,*bestwep = NULL, *o = NULL;
|
||||
object_t *curgun = NULL,*bestgun = NULL;
|
||||
enum BODYPART bp;
|
||||
int icanattack = B_FALSE;
|
||||
enum ATTRBRACKET iqb;
|
||||
|
@ -1746,7 +1755,6 @@ int ai_inventory_mgt(lifeform_t *lf, int *canattack) {
|
|||
|
||||
|
||||
// do we have a better weapon we could use?
|
||||
|
||||
if (iqb >= AT_AVERAGE) {
|
||||
curwep = getweapon(lf);
|
||||
bestwep = getbestweapon(lf);
|
||||
|
@ -1978,6 +1986,9 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// to maintain distance.
|
||||
rangedob = aigetrangedattack(lf, target, &rangedattack, &shootrange);
|
||||
|
||||
// how far away is my target ?
|
||||
dist = getcelldist(lf->cell, target->cell);
|
||||
|
||||
// try spells first.
|
||||
// can we attack with spells (ie. ones which target the victim)?
|
||||
// if target is adjacent, we will normally just attack rather than try a spell.
|
||||
|
@ -1987,6 +1998,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
if (f) spellchance = f->val[0];
|
||||
else spellchance = 30;
|
||||
|
||||
|
||||
// some attacks can always happen
|
||||
if (cancast(lf, OT_A_THRUST, NULL) && (dist == 2) && haslofknown(lf->cell, target->cell, LOF_NEED, NULL)) {
|
||||
spellchance = 100;
|
||||
|
@ -2013,8 +2025,6 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// otherwise fall through to below movement code.
|
||||
}
|
||||
|
||||
// how far away is my target ?
|
||||
dist = getcelldist(lf->cell, target->cell);
|
||||
// how far away do i _want_ to be?
|
||||
getwantdistance(lf,target, &wantdistmin,&wantdistmax, wantattack);
|
||||
|
||||
|
@ -2345,10 +2355,14 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
enum ATTRBRACKET iqb;
|
||||
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
|
||||
checkflagpile(lf->flags); // debug
|
||||
|
||||
x = f->val[0];
|
||||
y = f->val[1];
|
||||
if (db) dblog(".oO { walking from %d,%d towards f_targetcell (%d,%d) ... }", lf->cell->x, lf->cell->y, x, y);
|
||||
|
@ -2401,16 +2415,22 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
if (pathf && (lf->cell == c)) {
|
||||
ai_popnextcellinpath(lf);
|
||||
}
|
||||
assert(f->id <= F_LAST);
|
||||
|
||||
// moved towards it.
|
||||
// reset lifetime
|
||||
f->lifetime = aigetchasetime(lf);
|
||||
assert(f->id <= F_LAST);
|
||||
|
||||
// are we there yet?
|
||||
if (lf->cell == targetc) {
|
||||
enum MOVEREASON mr;
|
||||
// yes. remove target cell
|
||||
if (db) dblog(".oO { arrived at f_targetcell. removing. }");
|
||||
if (f->val[2] == MR_LF) {
|
||||
assert(f->id <= F_LAST);
|
||||
mr = f->val[2];
|
||||
|
||||
if ((mr == MR_LF) && f->text) {
|
||||
lifeform_t *targlf;
|
||||
// if we were chasing someone, keep looking
|
||||
// for them.
|
||||
|
@ -2442,6 +2462,8 @@ int aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
// move randomly now.
|
||||
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
|
||||
}
|
||||
checkflagpile(lf->flags); // debug
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
// success
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -2516,8 +2538,7 @@ void aiturn(lifeform_t *lf) {
|
|||
lifeform_t *master = NULL;
|
||||
enum ATTRBRACKET iqb;
|
||||
|
||||
|
||||
checkflagpile(lf->flags);
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
/*
|
||||
if (wantdb && haslos(player, lf->cell)) {
|
||||
|
@ -2544,6 +2565,9 @@ void aiturn(lifeform_t *lf) {
|
|||
if (isdead(lf)) {
|
||||
if (db) dblog(".oO { i am not alive, skipping turn. }");
|
||||
taketime(lf, SPEED_DEAD);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
return;
|
||||
}
|
||||
// if game has just started and player hasn't had their turn yet,
|
||||
|
@ -2551,6 +2575,7 @@ void aiturn(lifeform_t *lf) {
|
|||
if (!playerhasmoved) {
|
||||
if (db) dblog(".oO { player hasn't had their initial turn yet, skipping turn. }");
|
||||
taketime(lf, SPEED_DEAD);
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2566,14 +2591,19 @@ void aiturn(lifeform_t *lf) {
|
|||
master = findlf(lf->cell->map, f->val[0]);
|
||||
}
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
ailoscheck(lf);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// emergencies / fixing up
|
||||
///////////////////////////////////////////////
|
||||
if (ai_handle_emergencies(lf, iqb)) return;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -2589,6 +2619,8 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
if (ai_healing(lf)) return;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -2596,6 +2628,7 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
if (ai_inventory_mgt(lf, &icanattack)) return;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -2603,6 +2636,7 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
if (ai_attack_existing_target(lf)) return;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -2610,12 +2644,14 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
if (ai_premovement(lf)) return;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// movement
|
||||
///////////////////////////////////////////////
|
||||
if (ai_movement(lf)) return;
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -2623,17 +2659,22 @@ void aiturn(lifeform_t *lf) {
|
|||
// to attack, etc)
|
||||
///////////////////////////////////////////////
|
||||
if (ai_bored(lf, master, icanattack)) return;
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
// DEFAULT - try to move in a random direction
|
||||
if (db) dblog(".oO { default - moving randomly }");
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
ailoscheck(lf);
|
||||
|
||||
// somehow still here?
|
||||
if (!lf->timespent) {
|
||||
taketime(lf, getmovespeed(lf));
|
||||
}
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
}
|
||||
|
||||
// is the spell 'spellid' okay for AI lifeform 'lf' to cast at 'victim', for given purpose.
|
||||
|
@ -3057,7 +3098,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
if (ot->id == OT_S_BLINKASS) {
|
||||
cell_t *targcell;
|
||||
targcell = getcellindir(targcell, diropposite(victim->facing));
|
||||
targcell = getcellindir(victim->cell, diropposite(victim->facing));
|
||||
if (!cellwalkable(lf, targcell, NULL)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
|
@ -3310,7 +3351,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
specificcheckok = B_FALSE;
|
||||
}
|
||||
|
||||
if ((ot->id == OT_S_WARPWOOD)) {
|
||||
if (ot->id == OT_S_WARPWOOD) {
|
||||
specificcheckok = B_FALSE;
|
||||
if (victim) {
|
||||
object_t *oo;
|
||||
|
@ -3322,7 +3363,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_S_WEAKEN)) {
|
||||
if (ot->id == OT_S_WEAKEN) {
|
||||
flag_t *lff;
|
||||
for (lff = lf->flags->first; lff ; lff = lff->next) {
|
||||
if ((lff->id == F_ATTRMOD) && (lff->val[0] == A_STR) && (lff->obfrom == OT_S_WEAKEN)) {
|
||||
|
@ -3719,6 +3760,9 @@ void makewantedoblist(lifeform_t *lf, int *noids, enum OBTYPE *oid, int *oidcove
|
|||
wantflagcovet[*nwantflags] = (f->val[1] == B_COVETS) ? B_TRUE : B_FALSE;
|
||||
(*nwantflags)++;
|
||||
}
|
||||
if (*nwantflags >= MAXCANDIDATES) {
|
||||
raise(SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasflag(lf->flags, F_HUNGER)) {
|
||||
|
@ -3727,6 +3771,9 @@ void makewantedoblist(lifeform_t *lf, int *noids, enum OBTYPE *oid, int *oidcove
|
|||
wantflag[*nwantflags] = F_EDIBLE;
|
||||
wantflagcovet[*nwantflags] = B_TRUE;
|
||||
(*nwantflags)++;
|
||||
if (*nwantflags >= MAXCANDIDATES) {
|
||||
raise(SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
ai.h
2
ai.h
|
@ -33,7 +33,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
void aiturn(lifeform_t *lf);
|
||||
int aiwants(lifeform_t *lf, object_t *o, int *covets);
|
||||
int aiwants_real(lifeform_t *lf, object_t *o, int *covets, int *noids, enum OBTYPE *oid, int *oidcovet,int *nwantflags, enum FLAG *wantflag, int *wantflagcovet);
|
||||
void clearnode(node_t *n;);
|
||||
void clearnode(node_t *n);
|
||||
lifeform_t *gettargetlf(lifeform_t *lf);
|
||||
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op);
|
||||
object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op);
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "astar.h"
|
||||
#include "defs.h"
|
||||
#include "flag.h"
|
||||
#include "move.h"
|
||||
#include "nexus.h"
|
||||
#include "lf.h"
|
||||
#include "map.h"
|
||||
#include "objects.h"
|
||||
#include "text.h"
|
||||
|
||||
int calcg(lifeform_t *lf, cell_t *thiscell, node_t *parent, int dirfromparent) {
|
||||
int fromstart;
|
||||
object_t *o;
|
||||
int dooropen;
|
||||
enum ATTRBRACKET wis = AT_EXHIGH;
|
||||
if (lf) {
|
||||
wis = getattrbracket(getattr(lf, A_WIS), A_WIS, NULL);
|
||||
}
|
||||
if (isorthogonal(dirfromparent)) {
|
||||
fromstart = parent->fromstart + 10;
|
||||
} else {
|
||||
fromstart = parent->fromstart + 14;
|
||||
}
|
||||
|
||||
// closed doors count for more.
|
||||
if (wis >= AT_AVERAGE) {
|
||||
o = hasdoor(thiscell);
|
||||
if (o && isdoor(o, &dooropen) && !dooropen) {
|
||||
fromstart += 10;
|
||||
}
|
||||
}
|
||||
|
||||
// lf's wisdom will affect what is the "best" path
|
||||
if (wis >= AT_GTAVERAGE) {
|
||||
// avoid mud, etc
|
||||
o = hasobwithflag(thiscell->obpile, F_REDUCEMOVEMENT);
|
||||
if (o) {
|
||||
int howmuch;
|
||||
sumflags(o->flags, F_REDUCEMOVEMENT, &howmuch, NULL, NULL);
|
||||
if (howmuch > 0) {
|
||||
fromstart += (10*howmuch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fromstart;
|
||||
}
|
||||
|
||||
int calcg_map(cell_t *thiscell, node_t *parent, int dirfromparent) {
|
||||
int fromstart;
|
||||
/*
|
||||
if (isorthogonal(dirfromparent)) {
|
||||
fromstart = parent->fromstart + 10;
|
||||
} else {
|
||||
fromstart = parent->fromstart + 14;
|
||||
}
|
||||
*/
|
||||
fromstart = parent->fromstart + 10;
|
||||
|
||||
return fromstart;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int calcheuristic(cell_t *c, cell_t *end) {
|
||||
int h,xd,yd;
|
||||
xd = abs(c->x - end->x);
|
||||
yd = abs(c->y - end->y);
|
||||
if (xd > yd) {
|
||||
h = (14*yd) + 10*(xd - yd);
|
||||
} else {
|
||||
h = (14*xd) + 10*(yd - xd);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
//
|
||||
int calch_map(cell_t *c, int destroomid) {
|
||||
int h,xd,yd;
|
||||
cell_t *end = NULL;
|
||||
end = getroommidcell(c->map, destroomid);
|
||||
|
||||
// returns distance to centre of given roomid
|
||||
xd = abs(c->x - end->x);
|
||||
yd = abs(c->y - end->y);
|
||||
if (xd > yd) {
|
||||
h = (14*yd) + 10*(xd - yd);
|
||||
} else {
|
||||
h = (14*xd) + 10*(yd - xd);
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
void clearnode(node_t *n) {
|
||||
n->c = NULL;
|
||||
n->parent = NULL;
|
||||
n->dirfromparent = D_NONE;
|
||||
n->fromstart = -1;
|
||||
n->heur = -1;
|
||||
n->cost = -1;
|
||||
}
|
||||
|
||||
|
||||
// inserts node 'n' into list 'list' (sorted by cost)
|
||||
// returns index of insert position.
|
||||
int insert(node_t *n, node_t *list, int *listcount) {
|
||||
int pos,i;
|
||||
// add it to open list, with parent = node[cur]
|
||||
pos = -1;
|
||||
for (pos = 0; pos < *listcount; pos++) {
|
||||
if (n->cost <= list[pos].cost) {
|
||||
// add here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle others up
|
||||
for (i = *listcount; i > pos; i--) {
|
||||
list[i] = list[i-1];
|
||||
}
|
||||
(*listcount)++;
|
||||
// fill in .
|
||||
list[pos] = *n;
|
||||
return pos;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#include "defs.h"
|
||||
|
||||
int calcg(lifeform_t *lf, cell_t *thiscell, node_t *parent, int dirfromparent);
|
||||
int calcg_map(cell_t *thiscell, node_t *parent, int dirfromparent);
|
||||
int calcheuristic(cell_t *c, cell_t *end);
|
||||
int calch_map(cell_t *c, int destroomid);
|
||||
void clearnode(node_t *n);
|
||||
int insert(node_t *n, node_t *list, int *listcount);
|
25
attack.c
25
attack.c
|
@ -1053,7 +1053,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
} else {
|
||||
critpos = getrandomcorebp(victim, lf);
|
||||
}
|
||||
if (critpos == BP_NONE) {
|
||||
if ((int)critpos == BP_NONE) {
|
||||
strcpy(victimbpname, victimname);
|
||||
} else {
|
||||
armour = getouterequippedob(victim, critpos);
|
||||
|
@ -1570,9 +1570,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
|
||||
if (backstab) {
|
||||
practice(lf, SK_BACKSTAB, 1);
|
||||
pleasegodmaybe(R_GODTHIEVES, 10);
|
||||
} else if (lfhasflagval(lf, F_UNSEENATTACKER, victim->id, NA, NA, NULL)) {
|
||||
pleasegodmaybe(R_GODTHIEVES, 8);
|
||||
}
|
||||
|
||||
|
||||
// now handle the extra hp loss effects which we postponed above.
|
||||
losehpeffects(victim, dam[i], damtype[i], lf, wep, B_NORETALIATE, waskod,
|
||||
&waskod, prebleed, BP_NONE, damreducedbyarmour, critical);
|
||||
|
@ -1737,8 +1740,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
}
|
||||
|
||||
if (canevade(victim, lf)) {
|
||||
// victim trains evasion
|
||||
practice(victim, SK_EVASION, 1);
|
||||
}
|
||||
|
||||
// chance to fumble attack.
|
||||
if (fumble) {
|
||||
|
@ -2293,7 +2298,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, objec
|
|||
int protected = B_FALSE;
|
||||
char lfname[BUFLEN],victimname[BUFLEN];
|
||||
|
||||
if (hitpos == BP_NONE) return;
|
||||
if ((int)hitpos == BP_NONE) return;
|
||||
|
||||
// replace some dam types
|
||||
if (damtype == DT_UNARMED) damtype = DT_BASH;
|
||||
|
@ -3126,14 +3131,14 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical,
|
|||
}
|
||||
|
||||
// modify for defender's evasion
|
||||
if (isprone(victim) || !cansee(victim, lf)) {
|
||||
ev = 0;
|
||||
} else {
|
||||
if (canevade(victim, lf)) {
|
||||
ev = getevasion(victim);
|
||||
} else {
|
||||
ev = 0;
|
||||
}
|
||||
|
||||
acc -= ev;
|
||||
if (db) dblog("%s: minus victim's evasion (%d) -> %d", lfname, ev, acc);
|
||||
if (db) dblog("%s: minus victim's modified evasion (%d) -> %d", lfname, ev, acc);
|
||||
|
||||
// modify if victim is flying and we're not
|
||||
if (isairborne(victim,&vicheight)) {
|
||||
|
@ -3451,19 +3456,17 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam, int isu
|
|||
valflag = hasflag(f->pile, F_HITCONFERVALS);
|
||||
|
||||
if (fid == F_POISONED) {
|
||||
// need to fill in the name of what poisoned us
|
||||
enum POISONTYPE ptype;
|
||||
int ppower;
|
||||
// defaults - need to fill in the name of what poisoned us
|
||||
enum POISONTYPE ptype = P_VENOM;
|
||||
int ppower = 1;
|
||||
|
||||
assert(valflag);
|
||||
if (valflag) {
|
||||
ptype = valflag->val[0];
|
||||
if (valflag->val[1] == NA) {
|
||||
ppower = 1;
|
||||
} else {
|
||||
ppower = valflag->val[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!wep && strlen(ftext)) {
|
||||
strcpy(frombuf, ftext);
|
||||
|
|
20
data.c
20
data.c
|
@ -2684,7 +2684,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_REPELBLESSED, B_CURSED, B_BLESSED, NA, NULL);
|
||||
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_PENTAGRAM, "pentagram", "A area imbued with evil.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE);
|
||||
addot(OT_PENTAGRAM, "pentagram", "A area imbued with evil. It will repel any blessed objects which enter.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_DARKRED, '_', NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4059,7 +4059,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
// TODO: should be "castnearob ot_corpse"
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PLEASESGOD, R_GODDEATH, 1, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_STENCH, "stench of death", "Nauseates the target with the smell of dying flesh.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
|
@ -6023,7 +6024,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||
addot(OT_A_TRAIN, "training", "Start training to gain a new experience level or enhance skill.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_TUMBLE, "tumble", "You can tumble across the ground.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addot(OT_A_TUMBLE, "tumble", "You can tumble two metres across the ground.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL);
|
||||
addot(OT_A_WARCRY, "warcry", "Inspire fear in your enemies with a mighty war cry.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
|
@ -8704,7 +8705,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, "");
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_MPREGEN, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL);
|
||||
addot(OT_RING_MEDITATION, "ring of meditation", "Allows the wearer to rest by entering a state of meditation.", MT_METAL, 0.1, OC_RING, SZ_MINI);
|
||||
addot(OT_RING_MEDITATION, "ring of meditation", "Allows the wearer to remain aware while resting, by entering a state of meditation.", MT_METAL, 0.1, OC_RING, SZ_MINI);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, "");
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_MEDITATES, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL);
|
||||
|
@ -11667,6 +11668,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANCAST, OT_S_BLINKASS, NA, NA, "pw:10;");
|
||||
//addflag(lastrace->flags, F_CANCAST, OT_S_HUNGER, NA, NA, "pw:1;");
|
||||
// likes/dislikes
|
||||
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "sneak attacks");
|
||||
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "backstabbing");
|
||||
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "stealing items");
|
||||
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "lockpicking");
|
||||
|
@ -15469,7 +15471,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addrace(R_FUNGUSDREAM, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_PLANT, RC_PLANT, "A huge, spotty, purple mold which releases speed-inducing spores on the slightest contact.");
|
||||
addrace(R_FUNGUSDREAM, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_PLANT, RC_PLANT, "A huge, spotty, purple mold which releases sleep-inducing spores on the slightest contact.");
|
||||
addbodypart(lastrace, BP_BODY, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
|
||||
|
@ -17203,6 +17205,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_EXLOW, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
|
@ -20699,10 +20702,15 @@ void initskills(void) {
|
|||
addskillabil(SK_COOKING, PR_NOVICE, OT_A_COOK, NA, NULL, B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou now recognise bad food.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook recipes using up to 2 ingredients.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook up to Small sized corpses.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_ADEPT, "^gYou can now cook recipes using up to 3 ingredients.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_ADEPT, "^gYou can now cook up to Medium sized corpses.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_SKILLED, "^gYou can now cook recipes using up to 4 ingredients.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_SKILLED, "^gYou can now cook up to Human sized corpses.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_EXPERT, "^gYou can now cook recipes using up to 5 ingredients.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_EXPERT, "^gYou can now cook up to Large sized corpses.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_MASTER, "^gYou can now cook all recipes.^n", B_TRUE);
|
||||
addskilldesc(SK_COOKING, PR_MASTER, "^gYou can now cook up to Huge sized corpses.^n", B_TRUE);
|
||||
addskill(SK_EVASION, "Evasion", "Your ability to dodge blows or traps.", 50);
|
||||
addskilldesc(SK_EVASION, PR_NOVICE, "^gIncreases your EV by 12%.^n", B_FALSE);
|
||||
addskilldesc(SK_EVASION, PR_BEGINNER, "^gIncreases your EV by 24%.^n", B_FALSE);
|
||||
|
@ -20813,7 +20821,7 @@ void initskills(void) {
|
|||
addskilldesc(SK_PERCEPTION, PR_MASTER, "^gYou field of vision now extends behind you.^n", B_TRUE);
|
||||
addskill(SK_STEALTH, "Stealth", "Affects your ability to move silently.", 0); // untrainable?
|
||||
addskillabil(SK_STEALTH, PR_NOVICE, OT_A_HIDE, NA, NULL, B_TRUE);
|
||||
addskilldesc(SK_STEALTH, PR_BEGINNER, "^gYou can now move while hiding.^n", B_TRUE);
|
||||
addskilldesc(SK_STEALTH, PR_BEGINNER, "^gYou can now move (slowly) while hiding.^n", B_TRUE);
|
||||
addskilldesc(SK_STEALTH, PR_SKILLED, "^gYou can now peek down staircases.^n", B_TRUE);
|
||||
addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.", 50);
|
||||
addskilldesc(SK_SWIMMING, PR_NOVICE, "^gYou can now swim.^n", B_TRUE);
|
||||
|
|
9
defs.h
9
defs.h
|
@ -160,8 +160,8 @@
|
|||
#define B_UNKNOWN (0)
|
||||
#define B_NOVIS (-1)
|
||||
#define B_KEEPLOF (-1)
|
||||
#define B_MALE (0)
|
||||
#define B_FEMALE (-1)
|
||||
//#define B_MALE (0)
|
||||
//#define B_FEMALE (-1)
|
||||
#define B_MAYCHASE (-1)
|
||||
#define B_NODOORS (0)
|
||||
#define B_DONTKILL (-1)
|
||||
|
@ -2693,8 +2693,9 @@ enum OBTYPE {
|
|||
#define MAXBUILDINGTYPES (11)
|
||||
|
||||
|
||||
#define BP_NONE (-1)
|
||||
//#define BP_NONE (-1)
|
||||
enum BODYPART {
|
||||
BP_NONE = -1,
|
||||
// humanoid parts
|
||||
BP_WEAPON = 0,
|
||||
BP_SECWEAPON = 1,
|
||||
|
@ -3649,6 +3650,7 @@ enum FLAG {
|
|||
F_SIZETIMER, // lf weill resize to LFSIZE val0 in val1 turns.
|
||||
// v2 = B_FALSE = don't resize armour.
|
||||
// B_TRUE = resize armour too
|
||||
// text = "origSTR,origMAXHP"
|
||||
F_UNSEENATTACKER, // this lf attacked lfid v0 while lfid v0 couldn't
|
||||
// see them. used to mark 'X' on the player's map
|
||||
// for unseen attackers.
|
||||
|
@ -4433,6 +4435,7 @@ enum FLAG {
|
|||
// just a normal random room
|
||||
F_KEEPMARGIN, // this vault must be at least v0 from e/w of map
|
||||
// and at least v1 from n/s of map
|
||||
F_LAST,
|
||||
F_NULL = -1
|
||||
};
|
||||
|
||||
|
|
52
flag.c
52
flag.c
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -22,6 +23,8 @@ extern int ngodlfs;
|
|||
|
||||
extern lifeform_t *player;
|
||||
|
||||
extern int flagcheck;
|
||||
|
||||
int flagdb = B_FALSE;
|
||||
|
||||
altflagval_t *addaltval(flag_t *f, enum FLAG id, int val1, int val2, int val3, char *text) {
|
||||
|
@ -66,7 +69,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
int rv;
|
||||
enum { NONE, FIRST, FIRST2, MIDDLE, LAST } fml = NONE;
|
||||
|
||||
//checkflagpile(fp);
|
||||
checkflagpile(fp);
|
||||
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
|
||||
|
||||
// identified things mean all new flags are autmaticlaly known.
|
||||
|
@ -74,6 +77,13 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
known = B_KNOWN;
|
||||
}
|
||||
|
||||
// debug
|
||||
if (id == F_DOOR) {
|
||||
if (fp->ob && fp->ob->type->id == OT_LEAF) {
|
||||
raise(SIGINT);
|
||||
}
|
||||
}
|
||||
|
||||
if (fp->owner && (id == F_VAULTISPLAYERSTART)) {
|
||||
dblog("added vaultisplayerstart");
|
||||
}
|
||||
|
@ -444,6 +454,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
}
|
||||
//checkflagpile(fp);
|
||||
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
|
||||
checkflagpile(fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
@ -497,7 +508,7 @@ void changeflagtext(flag_t *f, char *newtext) {
|
|||
}
|
||||
}
|
||||
|
||||
void checkmapflags(map_t *m) {
|
||||
void checkflagpile_mapobs(map_t *m) {
|
||||
cell_t *c;
|
||||
object_t *o;
|
||||
int nbad = 0,x,y;
|
||||
|
@ -522,7 +533,16 @@ void checkmapflags(map_t *m) {
|
|||
}
|
||||
}
|
||||
|
||||
void checkflagpile_maplfs(map_t *m) {
|
||||
lifeform_t *l;
|
||||
if (!flagcheck) return;
|
||||
for (l = m->lf ; l ; l = l->next) {
|
||||
checkflagpile(l->flags);
|
||||
}
|
||||
}
|
||||
|
||||
void checkflagpile(flagpile_t *fp) {
|
||||
if (!flagcheck) return;
|
||||
if (fpisbad(fp)) {
|
||||
assert("flagpile is corrupt!" == 0);
|
||||
}
|
||||
|
@ -530,8 +550,18 @@ void checkflagpile(flagpile_t *fp) {
|
|||
|
||||
int fpisbad(flagpile_t *fp) {
|
||||
flag_t *f;
|
||||
|
||||
if (!flagcheck) return B_FALSE;
|
||||
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
if (f->next) {
|
||||
if(f->next->prev != f) {
|
||||
dblog("flag after %d is bad! its prev = 0x%x, should be this flag (0x%x)",f->id, f->next->prev, f);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
if (fp->ob && fp->owner) {
|
||||
dblog("flag %d has both ob and owner",f->id);
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -1100,8 +1130,6 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
int i,dopleasegod[MAXGODS];
|
||||
flagpile_t *newflags = NULL;
|
||||
|
||||
//checkflagpile(f->pile);
|
||||
|
||||
|
||||
// remember the pile so that we can re-index
|
||||
pile = f->pile;
|
||||
|
@ -1141,7 +1169,7 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
fleefrom = findlf(lf->cell->map, f->val[0]);
|
||||
// ie. this lf was fleeing from the player, and
|
||||
// got away.
|
||||
if (isplayer(fleefrom) && !cansee(lf, fleefrom)) {
|
||||
if (fleefrom && isplayer(fleefrom) && !cansee(lf, fleefrom)) {
|
||||
for (i = 0; i < ngodlfs; i++) {
|
||||
if (godlf[i] && (godlf[i]->race->id == R_GODMERCY)) dopleasegod[i] += 5;
|
||||
}
|
||||
|
@ -1149,6 +1177,7 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
}
|
||||
}
|
||||
}
|
||||
checkflagpile(pile);
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
// flags which cause a redraw
|
||||
|
@ -1159,6 +1188,7 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
redolos = getflagpilelocation(f->pile);
|
||||
}
|
||||
}
|
||||
checkflagpile(pile);
|
||||
|
||||
// notify
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
|
@ -1225,6 +1255,7 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
}
|
||||
}
|
||||
}
|
||||
checkflagpile(pile);
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// now we are actually removing the flag.
|
||||
|
@ -1269,8 +1300,10 @@ void real_killflag(flag_t *f, int wantannounce) {
|
|||
//////////////////////////////////////////
|
||||
f = NULL;
|
||||
|
||||
checkflagpile(pile);
|
||||
// re-index the pile
|
||||
updatefpindex(pile);
|
||||
checkflagpile(pile);
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
for (i = 0; i < ngodlfs; i++) {
|
||||
|
@ -1529,9 +1562,8 @@ void timeeffectsflag(flag_t *f, int howlong) {
|
|||
if (stone(f->pile->owner)) {
|
||||
// stoning failed
|
||||
killflag(f);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// announce
|
||||
if (isplayer(f->pile->owner)) {
|
||||
|
@ -1721,12 +1753,16 @@ void sumflags(flagpile_t *fp, enum FLAG id, int *val0, int *val1, int *val2) {
|
|||
|
||||
void timeeffectsflags(flagpile_t *fp) {
|
||||
flag_t *f,*nextf;
|
||||
enum FLAG thisid;
|
||||
|
||||
//checkflagpile(fp);
|
||||
|
||||
for (f = fp->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
thisid = f->id;
|
||||
timeeffectsflag(f, 1);
|
||||
// if this checkflag() crashes, we know there we a bug during processing of
|
||||
// flag 'thisid'
|
||||
checkflagpile(fp);
|
||||
}
|
||||
//checkflagpile(fp);
|
||||
}
|
||||
|
|
4
flag.h
4
flag.h
|
@ -11,9 +11,11 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
flagpile_t *addflagpile(lifeform_t *owner, object_t *o);
|
||||
int canbemadepermenant(enum FLAG id);
|
||||
void changeflagtext(flag_t *f, char *newtext);
|
||||
void checkmapflags(map_t *m);
|
||||
int fpisbad(flagpile_t *fp);
|
||||
void checkflagpile(flagpile_t *fp);
|
||||
void checkflagpile_maplfs(map_t *m);
|
||||
void checkflagpile_mapobs(map_t *m);
|
||||
|
||||
int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
|
||||
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
||||
int countflags(flagpile_t *fp);
|
||||
|
|
2
god.c
2
god.c
|
@ -503,7 +503,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
|
|||
checkgodbonus(rid,plev, oldplev);
|
||||
}
|
||||
|
||||
// anger the god if you are worshippin them.
|
||||
// anger the god if you are worshipping them.
|
||||
// returns TRUE if someone got angry
|
||||
int angergodmaybe(enum RACE rid, int amt, enum GODANGERREASON why) {
|
||||
lifeform_t *god;
|
||||
|
|
159
io.c
159
io.c
|
@ -982,7 +982,9 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
|
|||
// two different weapons with the same name?
|
||||
if (secwep && (secwep != wep) && streq(obname, obname2)) {
|
||||
char *plur;
|
||||
plur = makeplural(noprefix(obname));
|
||||
//plur = makeplural(noprefix(obname));
|
||||
plur = strdup(obname);
|
||||
makeplural(&plur);
|
||||
snprintf(buf2, BUFLEN, "weilding two %s",plur);
|
||||
free(plur);
|
||||
donesec = B_TRUE;
|
||||
|
@ -3856,13 +3858,13 @@ int askobjectmulti(obpile_t *op, char *prompt, condset_t *cs, int includenothing
|
|||
mvwprintw(mainwin, y, 0, MORESTRING);
|
||||
}
|
||||
if (descmode) {
|
||||
snprintf(pbuf, BUFLEN,"%s (ESC to quit): ", altprompt);
|
||||
snprintf(pbuf, BUFLEN,"%s (?=sel/ESC=quit): ", altprompt);
|
||||
} else if (strlen(numstring) > 0) {
|
||||
snprintf(pbuf, BUFLEN,"%s (%s','=all, ESC to quit) [%s]: ", prompt,
|
||||
snprintf(pbuf, BUFLEN,"%s (%s','=all, ?=desc/ESC=quit) [%s]: ", prompt,
|
||||
includenothing ? "- for nothing, " : "",
|
||||
numstring);
|
||||
} else {
|
||||
snprintf(pbuf, BUFLEN,"%s (%sESC to quit): ", prompt,
|
||||
snprintf(pbuf, BUFLEN,"%s (%s?=desc/ESC=quit): ", prompt,
|
||||
includenothing ? "- for nothing, " : "");
|
||||
}
|
||||
|
||||
|
@ -4008,6 +4010,34 @@ int askobjectmulti(obpile_t *op, char *prompt, condset_t *cs, int includenothing
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int asktoclimb(object_t *o, char *promptformat) {
|
||||
char buf[BUFLEN];
|
||||
char ch,question[BUFLEN],obname[BUFLEN];
|
||||
cell_t *obcell;
|
||||
|
||||
obcell = getoblocation(o);
|
||||
|
||||
assert(strstr(promptformat, "%s"));
|
||||
|
||||
// confirm...
|
||||
getobname(o, obname, o->amt);
|
||||
sprintf(question, promptformat, obname);
|
||||
|
||||
ch = askchar(question, "yn","n", B_TRUE, B_FALSE);
|
||||
if (ch != 'y') {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
snprintf(buf, BUFLEN, "the %s", noprefix(obname));
|
||||
if (tryclimb(player, obcell, buf, B_ONPURPOSE)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
// success
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
vault_t *askvault(char *prompttext) {
|
||||
vault_t *v;
|
||||
|
||||
|
@ -4200,6 +4230,14 @@ void clearretobs(void) {
|
|||
nretobs = 0;
|
||||
}
|
||||
|
||||
char cmdtochar(enum COMMAND cmd) {
|
||||
command_t *c;
|
||||
for (c = firstcommand ; c ; c = c->next) {
|
||||
if (c->id == cmd) return c->ch;
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
|
||||
// clears the screen
|
||||
void cls(void) {
|
||||
wclear(mainwin);
|
||||
|
@ -4311,7 +4349,7 @@ void describerace(enum RACE rid) {
|
|||
if (gamemode == GM_GAMESTARTED) {
|
||||
enum SKILLLEVEL slev;
|
||||
slev = getlorelevel(player, r->raceclass->id);
|
||||
snprintf(buf, BUFLEN, "Race::%s (%s level lore)",r->name, getskilllevelname(slev));
|
||||
snprintf(buf, BUFLEN, "Race::%s (%s) - %s level lore",r->name, r->raceclass->name, getskilllevelname(slev));
|
||||
} else {
|
||||
snprintf(buf, BUFLEN, "Race::%s",r->name);
|
||||
}
|
||||
|
@ -5518,7 +5556,7 @@ void doeat(obpile_t *op) {
|
|||
eatob = askobject(op, "Eat what", "You have nothing to eat!", NULL, 'e', &cs, B_FALSE);
|
||||
}
|
||||
if (eatob) {
|
||||
if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
|
||||
if (isunknownbadobject(eatob) && skillcheck(player, SC_WIS, D_BADFEELING, 0)) {
|
||||
if (!confirm_badfeeling(eatob)) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
|
@ -5530,13 +5568,13 @@ void doeat(obpile_t *op) {
|
|||
|
||||
int dowear(obpile_t *op) {
|
||||
object_t *o;
|
||||
int rv;
|
||||
int rv = B_FALSE;
|
||||
condset_t cs;
|
||||
initcondv(&cs, CC_WEARABLE, B_TRUE, NA,
|
||||
CC_NONE);
|
||||
o = askobject(op, "Wear what", "You have nothing to wear!", NULL, '\0', &cs, B_FALSE);
|
||||
if (o) {
|
||||
if (isunknownbadobject(o) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
|
||||
if (isunknownbadobject(o) && skillcheck(player, SC_WIS, D_BADFEELING, 0)) {
|
||||
if (!confirm_badfeeling(o)) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
|
@ -5562,7 +5600,7 @@ int doweild(obpile_t *op) {
|
|||
CC_NONE);
|
||||
o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', &cs, B_TRUE);
|
||||
if (o) {
|
||||
if (isunknownbadobject(o) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
|
||||
if (isunknownbadobject(o) && skillcheck(player, SC_WIS, D_BADFEELING, 0)) {
|
||||
if (!confirm_badfeeling(o)) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
|
@ -5879,7 +5917,8 @@ char *makedesc_god(lifeform_t *god, char *retbuf) {
|
|||
objecttype_t *ot;
|
||||
char *text;
|
||||
ot = findot(retflag[i]->val[0]);
|
||||
text = makeplural(ot->name);
|
||||
text = strdup(ot->name);
|
||||
makeplural(&text);
|
||||
sprintf(thisline, "- %s", text);
|
||||
free(text);
|
||||
if ((god->race->id == R_GODPURITY) && (retflag[i]->val[0] == OT_CORPSE)){
|
||||
|
@ -7470,9 +7509,8 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
col = C_GREY;
|
||||
}
|
||||
if (f->val[1] != NA) {
|
||||
sprintf(buf, "^%dMinimum %s to use%s: %d to use.", col, getattrname(f->val[0]),
|
||||
sprintf(buf, "^%dMinimum %s to use%s: %d", col, getattrname(f->val[0]),
|
||||
strlen(f->text) ? " effectively" : "", f->val[1]);
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
if (f->val[2] != NA) {
|
||||
char addon[BUFLEN];
|
||||
|
@ -7646,6 +7684,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
lorelev = getlorelevel(player, r->raceclass->id);
|
||||
}
|
||||
|
||||
// TODO: add this to doco.
|
||||
// Your Lore skill for this race will determine how much information is shown.
|
||||
//
|
||||
// NOVICE:
|
||||
|
@ -7741,6 +7780,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
spellorabil[1] = OC_SPELL;
|
||||
getflags(r->flags, retflag, &nretflags, F_CANWILL, F_NONE);
|
||||
for (n = 0; n <= 1; n++) {
|
||||
int nfound = 0;
|
||||
strcpy(buf, "");
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
objecttype_t *ot;
|
||||
|
@ -7748,11 +7788,14 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
f = retflag[i];
|
||||
ot = findot(f->val[0]);
|
||||
if (ot && (ot->obclass->id == spellorabil[n])) {
|
||||
if (i == 0) {
|
||||
sprintf(buf, "Innate %s: %s", (spellorabil[n] == OC_ABILITY) ? "Ability" : "Spell",
|
||||
char templine[BUFLEN];
|
||||
if (nfound == 0) {
|
||||
sprintf(templine, "Innate %s: %s", (spellorabil[n] == OC_ABILITY) ? "Ability" : "Spell",
|
||||
ot->name);
|
||||
strcat(buf, templine);
|
||||
} else {
|
||||
sprintf(buf, ", %s", ot->name);
|
||||
sprintf(templine, ", %s", ot->name);
|
||||
strcat(buf, templine);
|
||||
}
|
||||
texttospellopts(f->text, "pw:", &power, NULL);
|
||||
if (power) {
|
||||
|
@ -7760,6 +7803,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
strcat(buf, roman(power));
|
||||
strcat(buf, ")");
|
||||
}
|
||||
nfound++;
|
||||
}
|
||||
}
|
||||
if (strlen(buf)) {
|
||||
|
@ -7800,7 +7844,8 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
switch (f->id) {
|
||||
case F_AUTOCREATEOB:
|
||||
if (lorelev >= PR_NOVICE) {
|
||||
p = makeplural(f->text);
|
||||
p = strdup(f->text);
|
||||
makeplural(&p);
|
||||
sprintf(buf, "Automatically creates %s around itself.", p);
|
||||
free(p);
|
||||
}
|
||||
|
@ -8109,7 +8154,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
|
|||
strncat(retbuf, "^n@None known.\n", HUGEBUFLEN);
|
||||
}
|
||||
}
|
||||
free(doneflags);
|
||||
killflagpile(doneflags);
|
||||
|
||||
return retbuf;
|
||||
}
|
||||
|
@ -8279,7 +8324,7 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) {
|
|||
god = findgod(retflag[i]->val[0]);
|
||||
f = lfhasflag(god, F_GODOF);
|
||||
sprintf(buf, "Successfully casting this spell will please %s (%s of %s).\n",god->race->name,
|
||||
(getgender(god) == B_FEMALE) ? "Goddess" : "God", f->text);
|
||||
(getgender(god) == G_FEMALE) ? "Goddess" : "God", f->text);
|
||||
strncat(retbuf, buf, BUFLEN);
|
||||
}
|
||||
|
||||
|
@ -8674,28 +8719,6 @@ void dooperate(obpile_t *op) {
|
|||
object_t *o;
|
||||
condset_t cs;
|
||||
|
||||
// operable objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
//if (isoperable(o) && canpickup(player, o, 1)) {
|
||||
if (isoperable(o)) {
|
||||
char obname[BUFLEN],buf[BUFLEN];
|
||||
char verb[BUFLEN];
|
||||
int ch;
|
||||
getobname(o, obname, o->amt);
|
||||
strcpy(verb, getoperateverb(o));
|
||||
capitalise(verb);
|
||||
snprintf(buf, BUFLEN, "There %s %s here. %s %s",
|
||||
OB1(o,"is","are"),
|
||||
obname, verb,
|
||||
OB1(o,"it","one"));
|
||||
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
|
||||
if (ch == 'y') {
|
||||
operate(player, o, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ask which object to read
|
||||
initcondv(&cs, CC_OPERABLE, B_TRUE, NA,
|
||||
CC_NONE);
|
||||
|
@ -9058,6 +9081,28 @@ void dointeract(void) {
|
|||
int opened = B_FALSE;
|
||||
int nobs,n;
|
||||
|
||||
// operable objects here?
|
||||
for (o = player->cell->obpile->first; o ; o = o->next) {
|
||||
if (isoperable(o)) {
|
||||
char obname[BUFLEN],buf[BUFLEN];
|
||||
char verb[BUFLEN];
|
||||
int ch;
|
||||
getobname(o, obname, o->amt);
|
||||
strcpy(verb, getoperateverb(o));
|
||||
capitalise(verb);
|
||||
snprintf(buf, BUFLEN, "There %s %s here. %s %s",
|
||||
OB1(o,"is","are"),
|
||||
obname, verb,
|
||||
OB1(o,"it","one"));
|
||||
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
|
||||
if (ch == 'y') {
|
||||
operate(player, o, NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nothing on our space - ask to interact elsewhere
|
||||
dir = askdir("Interact in which direction (- to cancel)", B_TRUE, B_TRUE);
|
||||
if ((dir == D_MYSELF) || (dir == D_NONE)) {
|
||||
msg("Cancelled.");
|
||||
|
@ -9180,7 +9225,7 @@ void doquaff(obpile_t *op) {
|
|||
}
|
||||
if (liquid) {
|
||||
if (candrink(player, liquid)) {
|
||||
if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
|
||||
if (isunknownbadobject(liquid) && skillcheck(player, SC_WIS, D_BADFEELING, 0)) {
|
||||
if (!confirm_badfeeling(liquid)) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
|
@ -10260,7 +10305,7 @@ char getchoice(prompt_t *prompt) {
|
|||
prompt->selection = i;
|
||||
}
|
||||
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
} else {
|
||||
|
@ -10595,7 +10640,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
prompt->selection = i;
|
||||
}
|
||||
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
} else {
|
||||
|
@ -10603,7 +10648,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
wrefresh(mainwin);
|
||||
}
|
||||
curs_set(0);
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
restoregamewindows();
|
||||
}
|
||||
|
||||
|
@ -11319,7 +11364,7 @@ void msg_real(char *format, ... ) {
|
|||
//drawcursor();
|
||||
}
|
||||
|
||||
int needsbold(enum COLOUR col) {
|
||||
int needsbold(int col) {
|
||||
if (col >= REDBG) col -= REDBG;
|
||||
if (col >= GREENBG) col -= GREENBG;
|
||||
if (col >= BLUEBG) col -= BLUEBG;
|
||||
|
@ -11372,7 +11417,10 @@ void drawstatus(void) {
|
|||
// gun target ?
|
||||
f = hasflag(player->flags, F_GUNTARGET);
|
||||
if (f) {
|
||||
wprintw(statwin, "Aim: ");
|
||||
char aimname[11];
|
||||
wprintw(statwin, "Aim:");
|
||||
// limit
|
||||
snprintf(aimname,11,"%s",f->text);
|
||||
textwithcol(statwin, f->text);
|
||||
}
|
||||
|
||||
|
@ -11885,11 +11933,10 @@ int screenglyphmatches(int x, int y, glyph_t *g) {
|
|||
// prompts the player to learn a new spell from school 'ss' (ss_none means any)
|
||||
void select_new_spell(enum SPELLSCHOOL ss, int lev) {
|
||||
int done = B_FALSE;
|
||||
flag_t *f;
|
||||
char qbuf[BUFLEN];
|
||||
sprintf(qbuf, "Learn which new spell (maxmp=%d):", getmaxmp(player));
|
||||
while (!done) {
|
||||
makespellchoicelist(&prompt, player, qbuf, "Describe which spell:", f->val[1], B_TRUE, B_FALSE, B_FALSE, player->maxmp);
|
||||
makespellchoicelist(&prompt, player, qbuf, "Describe which spell:", ss, B_TRUE, B_FALSE, B_FALSE, player->maxmp);
|
||||
if (prompt.nchoices > 0) {
|
||||
objecttype_t *ot;
|
||||
getchoicestr(&prompt, B_TRUE, B_TRUE);
|
||||
|
@ -12003,10 +12050,11 @@ int showhiscoreline(void *hilitescore, int ncols, char **argv, char **colname) {
|
|||
} else {
|
||||
wprintw(mainwin, "\n");
|
||||
}
|
||||
free(score);
|
||||
free(name);
|
||||
free(job);
|
||||
free(killer);
|
||||
if (rank) free(rank);
|
||||
if (job) free(job);
|
||||
if (name) free(name);
|
||||
if (score) free(score);
|
||||
if (killer) free(killer);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -13038,7 +13086,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
} else {
|
||||
sprintf(youstr, "%s",you(lf));
|
||||
}
|
||||
wrapprint(mainwin, &y, &x, 0, "%s produce%s light (minimum vision range: %d). %s", youstr,
|
||||
wrapprint(mainwin, &y, &x, 0, "%s produce%s light (minimum vision range: %d).", youstr,
|
||||
isplayer(lf) ? "" : "s", amt);
|
||||
}
|
||||
f = lfhasknownflag(lf, F_SLOWMETAB);
|
||||
|
@ -13935,7 +13983,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
|
||||
if (lfhasknownflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT)) {
|
||||
if (f->lifetime != PERMENANT) {
|
||||
if ((f->lifetime != PERMENANT) && (f->lifetime > 0)) {
|
||||
char buf3[BUFLEN];
|
||||
snprintf(buf3, BUFLEN, "[%dt]",f->lifetime);
|
||||
strcat(buf2, buf3);
|
||||
|
@ -14040,7 +14088,8 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char *pname;
|
||||
objecttype_t *ot;
|
||||
ot = findot(f->val[0]);
|
||||
pname = makeplural(ot->name);
|
||||
pname = strdup(ot->name);
|
||||
makeplural(&pname);
|
||||
mvwprintw(mainwin, y, 0, 0, "It %s %s.", (f->val[1] == B_COVETS) ? "covets" : "wants", pname);
|
||||
y++;
|
||||
free(pname);
|
||||
|
|
2
io.h
2
io.h
|
@ -32,6 +32,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int minrange, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs);
|
||||
char askdir(char *prompt, int maycancel, int usedrunk);
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||
int asktoclimb(object_t *o, char *promptformat);
|
||||
vault_t *askvault(char *prompttext);
|
||||
void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );
|
||||
enum COMMAND chartocmd(char ch);
|
||||
|
@ -42,6 +43,7 @@ void clearmsg(void);
|
|||
void real_clearmsg(int force);
|
||||
void clearretobs(void);
|
||||
void cls(void);
|
||||
char cmdtochar(enum COMMAND cmd);
|
||||
int contains(enum OBCLASS *array, int nargs, enum OBCLASS want);
|
||||
void describegod(lifeform_t *god);
|
||||
void describejob(enum JOB jid);
|
||||
|
|
118
lf.c
118
lf.c
|
@ -1019,6 +1019,16 @@ int caneat(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// can lf try to evade attacker (or anything, if attacker isn't given)
|
||||
int canevade(lifeform_t *lf, lifeform_t *attacker) {
|
||||
if (isprone(lf)) return B_FALSE;
|
||||
if (isexhausted(lf)) return B_FALSE;
|
||||
if (attacker && !cansee(lf, attacker)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
int canexorcise(lifeform_t *lf, lifeform_t *target, int modifier) {
|
||||
int maxlevel;
|
||||
if (lfhasflag(target, F_UNIQUE)) return B_FALSE;
|
||||
|
@ -1348,6 +1358,7 @@ int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) {
|
|||
case BP_LEFTFINGER:
|
||||
bpheight = vicfeet + pctof(75, getlfsize(victim));
|
||||
break;
|
||||
case BP_NONE: // this counts as body
|
||||
case BP_BODY:
|
||||
case BP_WAIST:
|
||||
case BP_WINGS:
|
||||
|
@ -1381,6 +1392,16 @@ int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
int canreachroof(lifeform_t *lf) {
|
||||
if (getlfsize(lf) >= SZ_HUGE) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (lfhasflag(lf, F_LEVITATING) || lfhasflag(lf, F_FLYING) || lfhasflag(lf, F_CLIMBING)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int cansee(lifeform_t *viewer, lifeform_t *viewee) {
|
||||
return cansee_real(viewer, viewee, B_TRUE);
|
||||
}
|
||||
|
@ -4451,7 +4472,7 @@ int genalignmentlist(flagpile_t *fp, char *buf) {
|
|||
void generatealignment(lifeform_t *lf) {
|
||||
int nposs,i;
|
||||
char possbuf[BUFLEN],buf[BUFLEN],buf2[BUFLEN],ch;
|
||||
enum FLAG wantalignment = AL_NONE;
|
||||
enum ALIGNMENT wantalignment = AL_NONE;
|
||||
|
||||
// get a list of all possible alignments
|
||||
nposs = genalignmentlist(lf->flags, possbuf);
|
||||
|
@ -5741,7 +5762,7 @@ void enhanceskills(lifeform_t *lf) {
|
|||
if (skillstolearn) {
|
||||
char buf[BUFLEN];
|
||||
if (skillstoenhance) {
|
||||
snprintf(buf, BUFLEN, "(E)nhance skills, (L)earn skills, or (N)either (%d points left)?",lf->skillpoints);
|
||||
snprintf(buf, BUFLEN, "(E)nhance skills, (L)earn skills, or (N)one (%d points left)?",lf->skillpoints);
|
||||
eorl = askchar(buf,"eln","e", B_TRUE, B_FALSE);
|
||||
} else {
|
||||
snprintf(buf, BUFLEN,"Learn a new skill (%d points left)?",lf->skillpoints);
|
||||
|
@ -6533,10 +6554,12 @@ race_t *findracebyname(char *name, condset_t *cs) {
|
|||
char searchfor[BUFLEN];
|
||||
// first check for exact matches
|
||||
for (r = firstrace; r ; r = r->next) {
|
||||
if (!strcmp(r->name, name) && racemeets(r->id, cs)) {
|
||||
if (!strcmp(r->name, name)) {
|
||||
if (racemeets(r->id, cs)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now check raceclasses
|
||||
for (rc = firstraceclass; rc ; rc = rc->next) {
|
||||
|
@ -8087,11 +8110,15 @@ int getevasion(lifeform_t *lf) {
|
|||
|
||||
slev = getskill(lf, SK_EVASION);
|
||||
|
||||
// no evasion if you can't move!
|
||||
// no evasion if you can't move or are exhausted!
|
||||
if (isimmobile(lf)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isexhausted(lf)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no evasion if you're holding someone, or someone is holding you
|
||||
if (lfhasflag(lf, F_GRABBEDBY) || lfhasflag(lf, F_GRABBING)) {
|
||||
return 0;
|
||||
|
@ -8111,7 +8138,6 @@ int getevasion(lifeform_t *lf) {
|
|||
ev += level_ev;
|
||||
|
||||
// dexterity mod
|
||||
|
||||
if (slev) {
|
||||
ev += (getattr(lf, A_AGI)/5);
|
||||
} else {
|
||||
|
@ -8303,6 +8329,7 @@ object_t *getbestweapon(lifeform_t *lf) {
|
|||
|
||||
int getbodyparthitchance(enum BODYPART bp) {
|
||||
switch (bp) {
|
||||
case BP_NONE: return 0;
|
||||
case BP_WEAPON: return 0;
|
||||
case BP_SECWEAPON: return 0;
|
||||
case BP_EYES: return 1;
|
||||
|
@ -8344,6 +8371,8 @@ char *getbodypartname(lifeform_t *lf, enum BODYPART bp) {
|
|||
}
|
||||
|
||||
switch (bp) {
|
||||
case BP_NONE:
|
||||
return "__bp_none__";
|
||||
case BP_WEAPON:
|
||||
return "right hand";
|
||||
case BP_SECWEAPON:
|
||||
|
@ -8407,6 +8436,7 @@ char *getbodypartequipname(enum BODYPART bp) {
|
|||
case BP_FEET:
|
||||
case BP_WINGS:
|
||||
case BP_TAIL:
|
||||
case BP_NONE:
|
||||
return "on";
|
||||
case BP_EYES:
|
||||
case BP_SHOULDERS:
|
||||
|
@ -11416,6 +11446,7 @@ int gettr(lifeform_t *lf) {
|
|||
return lf->level;
|
||||
}
|
||||
f = hasflag(lf->flags, F_TR);
|
||||
assert(f);
|
||||
return f->val[0];
|
||||
//return (lf->maxhp / 4);
|
||||
}
|
||||
|
@ -14591,7 +14622,7 @@ void killlf(lifeform_t *lf) {
|
|||
map_t *m;
|
||||
flag_t *f;
|
||||
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (cansee(player, lf)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
@ -14613,6 +14644,12 @@ void killlf(lifeform_t *lf) {
|
|||
// shouldn't need this...
|
||||
lf->cell = NULL;
|
||||
|
||||
// remove line of sight data
|
||||
if (lf->los) {
|
||||
free(lf->los);
|
||||
lf->los = NULL;
|
||||
}
|
||||
|
||||
// remove impossible stuff
|
||||
if (getstamina(lf) > getmaxstamina(lf)) {
|
||||
setstamina(lf, getmaxstamina(lf));
|
||||
|
@ -14623,7 +14660,7 @@ void killlf(lifeform_t *lf) {
|
|||
// we are dead.
|
||||
// also: does anyone have us as a master?
|
||||
// TODO: check on all maps?
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
for (l = m->lf ; l ; l = l->next) {
|
||||
f = lfhasflagval(l, F_TARGETLF, lf->id, NA, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
|
@ -14655,6 +14692,8 @@ void killlf(lifeform_t *lf) {
|
|||
free(lf->polypack);
|
||||
lf->polypack = NULL;
|
||||
|
||||
|
||||
|
||||
// kill flags
|
||||
killflagpile(lf->flags);
|
||||
lf->flags = NULL;
|
||||
|
@ -15709,6 +15748,8 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
object_t *footprint, *scent,*retob = NULL;
|
||||
flag_t *fpflag = NULL;
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
// no tracks at all?
|
||||
if (where->type->solid) {
|
||||
return NULL;
|
||||
|
@ -15734,6 +15775,8 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
fpdir = dir;
|
||||
}
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
|
||||
if (footprint) {
|
||||
assert(fpflag);
|
||||
|
@ -15742,8 +15785,16 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
} else {
|
||||
char buf[BUFLENTINY];
|
||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
footprint = addobfast(where->obpile, OT_FOOTPRINT);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
addtempflag(footprint->flags, F_TRAIL, lf->race->id, fpdir, S_SIGHT, buf, getfootprinttime(lf));
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
}
|
||||
retob = footprint;
|
||||
}
|
||||
|
@ -15758,11 +15809,20 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos
|
|||
} else {
|
||||
char buf[BUFLENTINY];
|
||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
scent = addobfast(where->obpile, OT_SCENT);
|
||||
assert(scent);
|
||||
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
|
||||
addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, TM_SCENT);
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
}
|
||||
retob = scent;
|
||||
}
|
||||
checkflagpile_maplfs(lf->cell->map);
|
||||
return retob;
|
||||
}
|
||||
|
||||
|
@ -16668,7 +16728,7 @@ void autospells(lifeform_t *lf, int howmany) {
|
|||
|
||||
// power = 0 means select it based on depth
|
||||
for (i = 0 ; i < nposs; i++) {
|
||||
if (powerposs[nposs] == 0) {
|
||||
if (powerposs[nposs] == 0) { // ooo TODO: use of unit value here ??
|
||||
powerposs[nposs] = mapdiff;
|
||||
limit(&(powerposs[nposs]), 1, getspellmaxpower(poss[nposs]));
|
||||
}
|
||||
|
@ -16956,10 +17016,15 @@ void killpoisontype(poisontype_t *pt) {
|
|||
|
||||
void killrace(race_t *r) {
|
||||
race_t *nextone, *lastone;
|
||||
int i;
|
||||
|
||||
// free mem
|
||||
free(r->name);
|
||||
free(r->desc);
|
||||
killflagpile(r->flags);
|
||||
for (i = 0; i < r->nbodyparts; i++) {
|
||||
free(r->bodypart[i].name);
|
||||
}
|
||||
|
||||
// remove from list
|
||||
nextone = r->next;
|
||||
|
@ -20561,7 +20626,7 @@ int say(lifeform_t *lf, char *text, int volume) {
|
|||
char verb[BUFLEN];
|
||||
char noun[BUFLEN];
|
||||
char *localtext;
|
||||
int rv;
|
||||
int rv = B_FALSE;
|
||||
|
||||
if (lf && lfhasflag(lf, F_SILENCED)) {
|
||||
return B_FALSE;
|
||||
|
@ -21437,7 +21502,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
f = lfhasflag(lf, F_GODOF);
|
||||
if (f) {
|
||||
msg("^w%s transforms into %s, the %s of %s!", buf, newrace->name,
|
||||
(getgender(lf) == B_FEMALE) ? "Goddess" : "God", f->text);
|
||||
(getgender(lf) == G_FEMALE) ? "Goddess" : "God", f->text);
|
||||
} else {
|
||||
msg("^w%s transforms into %s %s!", buf, isvowel(newrace->name[0]) ? "an" : "a", newrace->name);
|
||||
}
|
||||
|
@ -21621,7 +21686,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
// new race can hold objects (F_NOPACK xx)
|
||||
// TODO: new race can use magic (F_NOSPELLS)
|
||||
// new race can still hold all the items which you have
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
object_t *o,*nexto;
|
||||
int donemeldmsg = B_FALSE;
|
||||
|
||||
|
@ -23101,7 +23166,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
if (lfhasflag(lf, F_SPRINTING)) {
|
||||
modstamina(lf, -1.5);
|
||||
} else if (isswimming(lf) && isplayer(lf)) {
|
||||
int lossamt;
|
||||
double lossamt;
|
||||
// players lose stamina based on swimming skill
|
||||
// monsters don't.
|
||||
switch (getskill(lf, SK_SWIMMING)) {
|
||||
|
@ -23116,7 +23181,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
if (lossamt) modstamina(lf, -lossamt);
|
||||
} else if (isclimbing(lf) && !lfhasflag(lf, F_SPIDERCLIMB)) {
|
||||
int lossamt;
|
||||
double lossamt;
|
||||
// players lose stamina based on climbing skill
|
||||
// monsters don't lose stamina to climb.
|
||||
switch (getskill(lf, SK_CLIMBING)) {
|
||||
|
@ -24960,7 +25025,7 @@ int takeoff(lifeform_t *lf, object_t *o) {
|
|||
killflagsofid(o->flags, F_EQUIPPED);
|
||||
|
||||
taketime(lf, getactspeed(lf));
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You take off %s.", obname);
|
||||
statdirty = B_TRUE;
|
||||
|
@ -25521,7 +25586,7 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
enum DAMTYPE dt;
|
||||
enum DAMTYPE dt = DT_HEAT;
|
||||
int dam = 3;
|
||||
// otherwise YOU get damaged.
|
||||
f->known = B_TRUE;
|
||||
|
@ -25965,26 +26030,11 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
|
|||
return B_TRUE;
|
||||
}
|
||||
} else if (dir == D_UP) {
|
||||
if (hasflagval(o->flags, F_PIT, D_UP, NA, NA, NULL) || (o->type->id == OT_GRATINGROOF)) {
|
||||
// can only go up if you have a rope or are flying/levitating
|
||||
if (lfhasflag(lf, F_LEVITATING) || lfhasflag(lf, F_FLYING)) {
|
||||
if (isinroof(o)) {
|
||||
if (canreachroof(lf)) {
|
||||
// ok.
|
||||
} else {
|
||||
char buf[BUFLEN];
|
||||
if (isplayer(lf)) {
|
||||
char ch,buf2[BUFLEN],obname[BUFLEN];
|
||||
// confirm...
|
||||
getobname(o, obname, o->amt);
|
||||
sprintf(buf2, "Climb up %s", obname);
|
||||
ch = askchar(buf2, "yn","n", B_TRUE, B_FALSE);
|
||||
if (ch != 'y') {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, BUFLEN, "the %s", noprefix(obname));
|
||||
if (tryclimb(lf, obcell, buf, onpurpose)) {
|
||||
if (asktoclimb(o, "Climb up %s")) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
} else {
|
||||
|
@ -26634,7 +26684,7 @@ int resizelf(lifeform_t *lf, enum LFSIZE newsize, int doobs) {
|
|||
}
|
||||
|
||||
// resizing an lf might change its glyph...
|
||||
if (cansee(player, lf)) {
|
||||
if (cansee(player, lf) || isplayer(lf)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
|
|
2
lf.h
2
lf.h
|
@ -53,6 +53,7 @@ int cancook(lifeform_t *lf, recipe_t *rec, enum ERROR *reason);
|
|||
int canclimb(lifeform_t *lf, enum ERROR *reason);
|
||||
int candrink(lifeform_t *lf, object_t *o);
|
||||
int caneat(lifeform_t *lf, object_t *o);
|
||||
int canevade(lifeform_t *lf, lifeform_t *attacker);
|
||||
int canexorcise(lifeform_t *lf, lifeform_t *target, int modifier);
|
||||
int canhaverandombehaviour(lifeform_t *lf);
|
||||
int canhear(lifeform_t *lf, cell_t *c, int volume, int *numwalls);
|
||||
|
@ -65,6 +66,7 @@ int canpolymorphto(enum RACE rid);
|
|||
int canpush(lifeform_t *lf, object_t *o, int dir);
|
||||
int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty);
|
||||
int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp);
|
||||
int canreachroof(lifeform_t *lf);
|
||||
int cansee(lifeform_t *viewer, lifeform_t *viewee);
|
||||
int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos);
|
||||
int canshoot(lifeform_t *lf, enum ERROR *why);
|
||||
|
|
76
map.c
76
map.c
|
@ -67,7 +67,8 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell = m->cell[(y*m->w)+x];
|
||||
if (cell) {
|
||||
clearcell(cell);
|
||||
free(cell);
|
||||
killcell(&cell);
|
||||
//free(cell);
|
||||
}
|
||||
|
||||
m->cell[(y*m->w)+x] = malloc(sizeof(cell_t));
|
||||
|
@ -1669,6 +1670,28 @@ enum CELLTYPE celltypefromvault(cell_t *c) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// clear and deallocate cell strings
|
||||
void clearcellstrings(cell_t *c) {
|
||||
if (c->writing) {
|
||||
free(c->writing);
|
||||
c->writing = NULL;
|
||||
}
|
||||
if (c->reason) {
|
||||
free(c->reason);
|
||||
c->reason = NULL;
|
||||
}
|
||||
if (c->lockedreason) {
|
||||
free(c->lockedreason);
|
||||
c->lockedreason = NULL;
|
||||
}
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
c->known = B_FALSE;
|
||||
c->knownglyph.ch = ' ';
|
||||
c->knownglyph.colour = C_GREY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// kill everything in the given cell (lifeforms && objects)
|
||||
// but DONT remove the cell itself.
|
||||
void clearcell(cell_t *c) {
|
||||
|
@ -1678,12 +1701,9 @@ void clearcell(cell_t *c) {
|
|||
while (c->obpile->first) {
|
||||
killob(c->obpile->first);
|
||||
}
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
c->known = B_FALSE;
|
||||
c->knownglyph.ch = ' ';
|
||||
c->knownglyph.colour = C_GREY;
|
||||
}
|
||||
clearcellstrings(c);
|
||||
}
|
||||
|
||||
void clearcell_exceptflags(cell_t *c, ... ) {
|
||||
va_list args;
|
||||
enum FLAG exception[MAXCANDIDATES];
|
||||
|
@ -1729,7 +1749,6 @@ int delve(map_t *map, int neighbourmin, int neighbourmax, int connchance, int ch
|
|||
int cellsdone = 0;
|
||||
int wantcells;
|
||||
int x,y;
|
||||
int totcells;
|
||||
int ngroups,ncount;
|
||||
int changed = B_FALSE;
|
||||
|
||||
|
@ -1873,7 +1892,7 @@ int delve(map_t *map, int neighbourmin, int neighbourmax, int connchance, int ch
|
|||
|
||||
dblog("DELVE DEBUG:");
|
||||
dblog(" PATTERN: ngb_min=%d, ngb_max=%d, connchance=%d", neighbourmin, neighbourmax, connchance);
|
||||
dblog(" wanted cells: %d / %d (%d%%)", wantcells, totcells, (int) (((double)wantcells / (double)totcells)*(double)100) );
|
||||
dblog(" wanted cells: %d", wantcells);
|
||||
dblog(" dug cells: %d", cellsdone);
|
||||
dblog("generated map:");
|
||||
dumpmap(map, B_FALSE, NULL);
|
||||
|
@ -4618,6 +4637,8 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
int db = B_TRUE;
|
||||
char dbtag[BUFLEN],dbbuf[BUFLEN];
|
||||
|
||||
snprintf(dbtag, BUFLEN, "[createmap.c]");
|
||||
|
||||
|
||||
// don't redraw screen during level change calculations
|
||||
redrawpause();
|
||||
|
@ -4874,7 +4895,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
// place forced vaults.
|
||||
if (db) {
|
||||
dblog(" adding forced things first...");
|
||||
//dblog(" adding forced things first...");
|
||||
dblog(" adding forced things first...");
|
||||
}
|
||||
|
||||
|
@ -5028,6 +5049,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
c = map->cell[i];
|
||||
if (c->lockedreason && streq(c->lockedreason, TEMPVAULTLOCK)) {
|
||||
free(c->lockedreason);
|
||||
c->lockedreason = NULL;
|
||||
c->locked = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -5826,9 +5848,13 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void killcell(cell_t *c) {
|
||||
killobpile(c->obpile);
|
||||
if (c->writing) free(c->writing);
|
||||
void killcell(cell_t **c) {
|
||||
// if (c) {
|
||||
clearcell(*c);
|
||||
killobpile((*c)->obpile);
|
||||
free(*c);
|
||||
*c = NULL;
|
||||
// }
|
||||
}
|
||||
|
||||
void killcelltype(celltype_t *ct) {
|
||||
|
@ -5867,11 +5893,12 @@ void killmap(map_t *m) {
|
|||
// free mem
|
||||
while (m->lf) killlf(m->lf);
|
||||
|
||||
free(m->name);
|
||||
killflagpile(m->flags);
|
||||
m->flags = NULL;
|
||||
|
||||
for (i = 0; i < (m->w*m->h); i++){
|
||||
killcell(m->cell[i]);
|
||||
for (i = 0; i < (m->w*m->h); i++) {
|
||||
killcell(&(m->cell[i]));
|
||||
}
|
||||
|
||||
// remove from list
|
||||
|
@ -8729,7 +8756,7 @@ vault_t *maphasvault(map_t *m, char *id) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tflag, lifeform_t *viewer) {
|
||||
object_t *hastrailof(obpile_t *op, lifeform_t *lf, int oid, flag_t **tflag, lifeform_t *viewer) {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
// default
|
||||
|
@ -8880,6 +8907,7 @@ void initmaplayout(void) {
|
|||
//vx = 0; vy = -1;
|
||||
*/
|
||||
|
||||
// *************** MAP OUTLINE ***************
|
||||
addregionoutline(BH_MAINDUNGEON);
|
||||
addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL);
|
||||
// l2-4: sylvan woods
|
||||
|
@ -9694,6 +9722,10 @@ void makedoor(cell_t *cell, int openchance) {
|
|||
// don't open it!
|
||||
o = addob(cell->obpile, doorbuf);
|
||||
if (o) {
|
||||
if (o->type->id == OT_LEAF) {
|
||||
raise(SIGINT);
|
||||
}
|
||||
|
||||
if (!hasflag(o->flags, F_LOCKED) && (rnd(1,100) <= openchance)) {
|
||||
opendoor(NULL, o);
|
||||
} else {
|
||||
|
@ -10419,7 +10451,10 @@ void setcelllocked(cell_t *c, char *why, ...) {
|
|||
|
||||
c->locked = B_TRUE;
|
||||
|
||||
if (c->lockedreason) free(c->lockedreason);
|
||||
if (c->lockedreason) {
|
||||
free(c->lockedreason);
|
||||
c->lockedreason = NULL;
|
||||
}
|
||||
|
||||
va_start(args, why);
|
||||
vsnprintf( buf, BUFLEN, why, args );
|
||||
|
@ -10433,7 +10468,10 @@ void setcellreason(cell_t *c, char *why, ...) {
|
|||
char buf[BUFLEN];
|
||||
va_list args;
|
||||
|
||||
if (c->reason) free(c->reason);
|
||||
if (c->reason) {
|
||||
free(c->reason);
|
||||
c->reason = NULL;
|
||||
}
|
||||
|
||||
va_start(args, why);
|
||||
vsnprintf( buf, BUFLEN, why, args );
|
||||
|
@ -10671,9 +10709,7 @@ void unmakemap(map_t *map) {
|
|||
if (db) dblog(" %d linked regions removed.", nreg);
|
||||
// free cells on this map
|
||||
for (i = 0; i < (map->w*map->h); i++){
|
||||
killcell(map->cell[i]);
|
||||
free(map->cell[i]);
|
||||
map->cell[i] = NULL;
|
||||
killcell(&(map->cell[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
map.h
5
map.h
|
@ -21,6 +21,7 @@ int cellmeetscondition(cell_t *c, enum CELLCONDITION cond, int arg, int value);
|
|||
int cellmeets(cell_t *c, condset_t *cs);
|
||||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom, char *why);
|
||||
enum CELLTYPE celltypefromvault(cell_t *c);
|
||||
void clearcellstrings(cell_t *c);
|
||||
void clearcell(cell_t *c);
|
||||
void clearcell_exceptflags(cell_t *c, ...);
|
||||
int delve(map_t *map, int neighbourmin, int neighbourmax, int connchance, int chancepct, int newneighbourmin, int newneighbourmax, int newconnchance, enum CELLTYPE empty, enum CELLTYPE solid);
|
||||
|
@ -164,7 +165,7 @@ lifeform_t *haslf(cell_t *c);
|
|||
int hasknownobject(cell_t *c);
|
||||
int hasobject(cell_t *c);
|
||||
vault_t *maphasvault(map_t *m, char *id);
|
||||
object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tflag, lifeform_t *viewer);
|
||||
object_t *hastrailof(obpile_t *op, lifeform_t *lf, int oid, flag_t **tflag, lifeform_t *viewer);
|
||||
void initmap(void);
|
||||
void initmaplayout(void);
|
||||
int isadjacent(cell_t *src, cell_t *dst);
|
||||
|
@ -183,7 +184,7 @@ int isoutdoors(map_t *m);
|
|||
int isroom(cell_t *c);
|
||||
int issolid(cell_t *c);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
void killcell(cell_t *c);
|
||||
void killcell(cell_t **c);
|
||||
void killcelltype(celltype_t *ct);
|
||||
void killfakes(map_t *map, cell_t *cell);
|
||||
void killmap(map_t *m);
|
||||
|
|
25
move.c
25
move.c
|
@ -574,6 +574,7 @@ int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe) {
|
|||
|
||||
if (lfhasflag(lf, F_DOESNTMOVE)) {
|
||||
rest(lf, B_TRUE);
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -582,6 +583,7 @@ int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe) {
|
|||
|
||||
moveok = canandwillmove(lf, dir, &why);
|
||||
|
||||
|
||||
if (!moveok && badmovesok) {
|
||||
switch (why) {
|
||||
// actually okay to move into someone
|
||||
|
@ -619,6 +621,7 @@ int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe) {
|
|||
|
||||
origtimespent = lf->timespent;
|
||||
rv = trymove(lf, dir, B_TRUE, strafe);
|
||||
|
||||
if (restonfail && (rv || (lf->timespent == origtimespent))) {
|
||||
// ie move failed
|
||||
rest(lf, B_TRUE);
|
||||
|
@ -639,7 +642,7 @@ int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int d
|
|||
int dist[MAXDIR_COMPASS];
|
||||
int poss[MAXDIR_COMPASS];
|
||||
int nposs;
|
||||
enum ERROR error;
|
||||
enum ERROR error = E_OK;
|
||||
|
||||
if (dirtype == DT_ORTH) {
|
||||
maxdist = getcelldistorth(src, dst);
|
||||
|
@ -960,8 +963,11 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
case E_OBINWAY:
|
||||
case E_DOORINWAY:
|
||||
if (reason == E_WALLINWAY) {
|
||||
if (newcell) strcpy(thing, newcell->type->name);
|
||||
else strcpy(thing, "wall");
|
||||
if (newcell) {
|
||||
snprintf(thing, BUFLEN, "%s %s", needan(newcell->type->name) ? "an" : "a",newcell->type->name);
|
||||
} else {
|
||||
strcpy(thing, "a wall");
|
||||
}
|
||||
} else { // ie door or object
|
||||
getobname(rdata, thing, 1);
|
||||
}
|
||||
|
@ -1486,7 +1492,8 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
char *newname;
|
||||
// we want 'xx steps on some pieces of broken glass'
|
||||
// not 'xx steps on 5 pieces of broken glass'
|
||||
newname = makeplural(obname);
|
||||
newname = strdup(obname);
|
||||
makeplural(&newname);
|
||||
strrep(&newname, "a ", "some ", NULL);
|
||||
strcpy(obname, newname);
|
||||
free(newname);
|
||||
|
@ -1655,7 +1662,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
lf->race->known = B_TRUE;
|
||||
rc = findraceclass(lf->race->raceclass->id);
|
||||
if (rc) {
|
||||
practice(lf, getskill(lf, rc->skill), 2);
|
||||
practice(lf, rc->skill, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1910,7 +1917,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// maybe make some noise
|
||||
// (stealth check to avoid this)
|
||||
willmakenoise = B_TRUE;
|
||||
|
@ -3502,7 +3508,11 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
taketime(lf, getmovespeed(lf));
|
||||
} else {
|
||||
if (!onpurpose || canandwillmove(lf, dir, &errcode)) {
|
||||
return attackcell(lf, cell, B_FALSE);
|
||||
int forceattack = B_FALSE;
|
||||
if (lfhasflag(lf, F_RAGE)) {
|
||||
forceattack = B_TRUE;
|
||||
}
|
||||
return attackcell(lf, cell, forceattack);
|
||||
} else {
|
||||
// won't attack for some reason.
|
||||
return B_TRUE;
|
||||
|
@ -3561,7 +3571,6 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// purposely moving away from money?
|
||||
if (onpurpose && isplayer(lf) && srcmoney) {
|
||||
angergodmaybe(R_GODTHIEVES, srcmoney, GA_MONEY);
|
||||
|
|
45
nexus.c
45
nexus.c
|
@ -128,6 +128,8 @@ extern int statdirty;
|
|||
int needredraw = B_TRUE;
|
||||
int numdraws = 0;
|
||||
|
||||
int flagcheck = B_FALSE;
|
||||
|
||||
// for xp list debugging
|
||||
extern race_t **raceposs;
|
||||
extern int *xpposs;
|
||||
|
@ -844,7 +846,7 @@ void checkendgame(void) {
|
|||
}
|
||||
|
||||
void cleanup(void) {
|
||||
//int i;
|
||||
int i;
|
||||
gamemode = GM_CLEANUP;
|
||||
|
||||
free(xpposs);
|
||||
|
@ -875,13 +877,11 @@ void cleanup(void) {
|
|||
while (firstpoisontype) killpoisontype(firstpoisontype);
|
||||
// free celltypes
|
||||
while (firstcelltype) killcelltype(firstcelltype);
|
||||
/*
|
||||
// free npcname strings
|
||||
for (i = 0; i < numnpcnames; i++) {
|
||||
// free npcnames
|
||||
free(npcname[i].name);
|
||||
free(&npcname[i]);
|
||||
}
|
||||
*/
|
||||
// free npcname structures
|
||||
free(npcname);
|
||||
// free hidden names
|
||||
while (firsthiddenname) killhiddenname(firsthiddenname);
|
||||
|
@ -960,7 +960,7 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in
|
|||
|
||||
|
||||
void donextturn(map_t *map) {
|
||||
lifeform_t *who;
|
||||
lifeform_t *who,*l;
|
||||
int db = B_FALSE;
|
||||
map_t *oldpmap;
|
||||
|
||||
|
@ -968,8 +968,10 @@ void donextturn(map_t *map) {
|
|||
|
||||
who = map->lf;
|
||||
|
||||
|
||||
if (who) {
|
||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||
checkflagpile(who->flags);
|
||||
|
||||
if (who->timespent > 0) {
|
||||
// shuffling lf times...
|
||||
|
@ -1355,8 +1357,13 @@ void donextturn(map_t *map) {
|
|||
if (getoption(OPT_TIMEDEBUG)) {
|
||||
dbtimeendlf(who);
|
||||
}
|
||||
checkflagpile(who->flags);
|
||||
} // end 'if (who)'
|
||||
|
||||
for (l = map->lf ; l ; l = l->next) {
|
||||
checkflagpile(l->flags);
|
||||
}
|
||||
|
||||
if (isplayer(who)) {
|
||||
// in order to force the player's turn to be first,
|
||||
// monsters will not take any actions until
|
||||
|
@ -1367,6 +1374,7 @@ void donextturn(map_t *map) {
|
|||
// check for death etc
|
||||
checkdeath();
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// effects which happen every GAME TICK
|
||||
// ie. object hp drain etc
|
||||
|
@ -1378,6 +1386,7 @@ void donextturn(map_t *map) {
|
|||
//timeeffectsworld(player->cell->map);
|
||||
timeeffectsworld(map, B_TRUE);
|
||||
|
||||
|
||||
// the previous call to timeeffectsworld might cause the player to
|
||||
// change levels (ie. falling down through one or more pits).
|
||||
//
|
||||
|
@ -1836,10 +1845,12 @@ int loadnpcnames(void) {
|
|||
if (!f) return B_TRUE;
|
||||
|
||||
// count lines...
|
||||
fgets(buf, BUFLEN, f);
|
||||
fgets(buf, BUFLEN, f); // VALGRIND: memleak here
|
||||
numnpcnames = 0;
|
||||
while (!feof(f)) {
|
||||
if (strlen(buf)) {
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
}
|
||||
if (strlen(buf)) {
|
||||
numnpcnames++;
|
||||
}
|
||||
|
@ -1847,7 +1858,8 @@ int loadnpcnames(void) {
|
|||
}
|
||||
|
||||
// alloc mem
|
||||
npcname = malloc(numnpcnames * sizeof(npcname_t));
|
||||
//npcname = malloc(numnpcnames * sizeof(npcname_t));
|
||||
npcname = calloc(numnpcnames, sizeof(npcname_t));
|
||||
|
||||
// back to start
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
@ -1855,7 +1867,9 @@ int loadnpcnames(void) {
|
|||
// now read in names
|
||||
fgets(buf, BUFLEN, f);
|
||||
while (!feof(f)) {
|
||||
if (strlen(buf)) {
|
||||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
}
|
||||
if (strlen(buf)) {
|
||||
capitalise(buf);
|
||||
npcname[i].name = strdup(buf);
|
||||
|
@ -2165,7 +2179,7 @@ void setcurtime(int hours, int minutes) {
|
|||
void timeeffectsworld(map_t *map, int updategametime) {
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags;
|
||||
lifeform_t *l;
|
||||
lifeform_t *l,*nextl;
|
||||
int db = B_FALSE;
|
||||
object_t *o,*nexto;
|
||||
int x,y;
|
||||
|
@ -2193,6 +2207,13 @@ void timeeffectsworld(map_t *map, int updategametime) {
|
|||
//if (db) dblog("timespent = %d\n", timespent);
|
||||
if (db) dblog("firstlftime = %d\n", firstlftime);
|
||||
|
||||
/*
|
||||
for (l = map->lf ; l ; l = nextl) {
|
||||
nextl = l->next;
|
||||
checkflagpile(l->flags);
|
||||
}
|
||||
*/
|
||||
|
||||
if (firstlftime > 0) {
|
||||
if (db) dblog("making firstlf timespent = 0 (currently %d):", firstlftime);
|
||||
shuffledown(map);
|
||||
|
@ -2253,7 +2274,6 @@ void timeeffectsworld(map_t *map, int updategametime) {
|
|||
obsfallthrough(c, pit);
|
||||
}
|
||||
|
||||
|
||||
// go through each object in the cell...
|
||||
for (o = c->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
|
@ -2301,11 +2321,12 @@ void timeeffectsworld(map_t *map, int updategametime) {
|
|||
killflagsofid(map->flags, F_NEWWATERDEPTH);
|
||||
redrawresume();
|
||||
|
||||
|
||||
// now handle effects on lifeforms and/or their objects
|
||||
for (l = map->lf ; l ; l = l->next) {
|
||||
for (l = map->lf ; l ; l = nextl) {
|
||||
nextl = l->next;
|
||||
checkflagpile(l->flags);
|
||||
timeeffectslf(l);
|
||||
checkflagpile(l->flags);
|
||||
}
|
||||
|
||||
// time out warnings
|
||||
|
|
165
objects.c
165
objects.c
|
@ -282,6 +282,7 @@ brand_t *addbrand(enum BRAND id, char *suffix, enum BODYPART bp, enum BLESSTYPE
|
|||
// props
|
||||
a->id = id;
|
||||
a->bp = bp;
|
||||
a->description = NULL;
|
||||
snprintf(buf, BUFLEN, " %s",suffix);
|
||||
a->suffix = strdup(buf);
|
||||
a->blessed = blessed;
|
||||
|
@ -356,7 +357,7 @@ hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text) {
|
|||
return a;
|
||||
}
|
||||
|
||||
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known) {
|
||||
knowledge_t *addknowledge(enum OBTYPE id, char *hiddenname, int known) {
|
||||
knowledge_t *a;
|
||||
|
||||
// add to the end of the list
|
||||
|
@ -522,6 +523,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
int jamchance = 0;
|
||||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0;
|
||||
lifeform_t *firstlf;
|
||||
|
||||
if (player) firstlf = player->cell->map->lf;
|
||||
else firstlf = NULL;
|
||||
|
||||
// just in case we don't add any
|
||||
addedob[0] = NULL;
|
||||
|
@ -675,8 +680,14 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
// might not be the case if it was part of the object name
|
||||
// eg. "waist-deep water"
|
||||
if (bonus) {
|
||||
int charsremoved;
|
||||
while (*bonusend == ' ') bonusend++; // go past spaces
|
||||
strcpy(bonusstart, bonusend);
|
||||
// using memmove instead
|
||||
//strcpy(bonusstart, bonusend);
|
||||
memmove(bonusstart, bonusend, strlen(bonusend));
|
||||
charsremoved = strlen(bonusstart) - strlen(bonusend);
|
||||
// NUL out remainder of buffer
|
||||
p[strlen(p) - charsremoved] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -980,9 +991,19 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
char racename[BUFLEN];
|
||||
p2 = strstr(p, "corpse");
|
||||
len = p2 - p;
|
||||
snprintf(racename, len, "%s",p);
|
||||
assert (len >= 0);
|
||||
|
||||
if (len == 0) {
|
||||
// eg. "corpse"
|
||||
cell_t *c;
|
||||
c = getobpilelocation(where);
|
||||
corpserace = getrandomrace(c, NA, NULL);
|
||||
} else {
|
||||
// eg. "goblin corpse"
|
||||
snprintf(racename, len, "%s",p);
|
||||
assert(strlen(racename) > 0);
|
||||
corpserace = findracebyname(racename, NULL);
|
||||
}
|
||||
ot = findot(OT_CORPSE);
|
||||
} else if (strstr(p, "map to ")) {
|
||||
branch_t *rt;
|
||||
|
@ -1053,6 +1074,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
}
|
||||
} else {
|
||||
killflagpile(wantflags);
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1065,16 +1087,25 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
|
||||
pp = p + strlen("generator \"");
|
||||
pp = readuntil(tempbuf, pp, ',');
|
||||
if (pp) strcpy(whattomake, tempbuf);
|
||||
else return NULL;
|
||||
if (!pp) {
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(whattomake, tempbuf);
|
||||
|
||||
pp = readuntil(tempbuf, pp, ',');
|
||||
if (pp) radius = atoi(tempbuf);
|
||||
else return NULL;
|
||||
if (!pp) {
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
radius = atoi(tempbuf);
|
||||
|
||||
pp = readuntil(tempbuf, pp, '"');
|
||||
if (pp) pct = atoi(tempbuf);
|
||||
else return NULL;
|
||||
if (!pp) {
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
pct = atoi(tempbuf);
|
||||
|
||||
addflag(wantflags, F_GENERATES, pct, radius, NA, whattomake);
|
||||
|
||||
|
@ -1236,6 +1267,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (db) dblog("DB: No match for object name '%s'", p );
|
||||
nretobs = 0;
|
||||
killflagpile(wantflags);
|
||||
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1292,6 +1325,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name);
|
||||
nretobs = 0;
|
||||
killflagpile(wantflags);
|
||||
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1311,6 +1346,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (db) dblog("DB: Cannot give a spell object to a player, or a cell! object name '%s'", ot->name );
|
||||
nretobs = 0;
|
||||
killflagpile(wantflags);
|
||||
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1340,6 +1377,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (db) dblog("DB: trying to give NOPICKUP object '%s' to a lifeform ('%s').", ot->name, where->owner->race->name );
|
||||
nretobs = 0;
|
||||
killflagpile(wantflags);
|
||||
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1367,6 +1406,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
if (db) dblog("DB: Unique ob %s already exists!", ot->name );
|
||||
nretobs = 0;
|
||||
killflagpile(wantflags);
|
||||
|
||||
if (localname) free(localname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1401,11 +1442,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
|
|||
|
||||
for (i = 0; i < howmany; i++) {
|
||||
int added = B_FALSE;
|
||||
|
||||
|
||||
if (canstack) {
|
||||
object_t *existob;
|
||||
if (db) dblog("DB: Looking for stacks...");
|
||||
// TODO: if object is stackable
|
||||
// TODO: if (hasflag(ob,stackable) && hasobject(where, ot)) {
|
||||
// TODO: if (hasflag(ob,stackable) && hasobject(where, ot)) brace
|
||||
// does the pile already contain one?
|
||||
existob = canstacknewot(where, ot);
|
||||
if (existob) {
|
||||
|
@ -3796,15 +3839,6 @@ void explodeob(object_t *o, flag_t *f, int bigness, lifeform_t *causedby) {
|
|||
char obname[BUFLEN];
|
||||
object_t *outerob;
|
||||
|
||||
// override causedby
|
||||
if (!causedby) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_THROWNBY);
|
||||
if (f) {
|
||||
causedby = findlf(c->map, f->val[0]);
|
||||
}
|
||||
}
|
||||
|
||||
dam = roll(f->text);
|
||||
|
||||
// inside a container? if so, it's the container
|
||||
|
@ -3816,6 +3850,15 @@ void explodeob(object_t *o, flag_t *f, int bigness, lifeform_t *causedby) {
|
|||
}
|
||||
c = getoblocation(outerob);
|
||||
|
||||
// override causedby
|
||||
if (!causedby) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_THROWNBY);
|
||||
if (f) {
|
||||
causedby = findlf(c->map, f->val[0]);
|
||||
}
|
||||
}
|
||||
|
||||
getobname(outerob, obname, outerob->amt);
|
||||
|
||||
// announce
|
||||
|
@ -3925,6 +3968,7 @@ objecttype_t *findotn(char *name) {
|
|||
knowledge_t *k;
|
||||
char *modname;
|
||||
char *p;
|
||||
char *tempstr;
|
||||
int db = B_FALSE;
|
||||
brand_t *om;
|
||||
|
||||
|
@ -3966,17 +4010,21 @@ objecttype_t *findotn(char *name) {
|
|||
// skip past bonusses
|
||||
p = strchr(modname, '+');
|
||||
if (p) {
|
||||
while (!isalpha(*p)) {
|
||||
while (*p && !isalpha(*p)) {
|
||||
p++;
|
||||
}
|
||||
strcpy(modname, p);
|
||||
tempstr = strdup(p);
|
||||
strcpy(modname, tempstr);
|
||||
free(tempstr);
|
||||
}
|
||||
p = strchr(modname, '-');
|
||||
if (p) {
|
||||
while (!isalpha(*p)) {
|
||||
p++;
|
||||
}
|
||||
strcpy(modname, p);
|
||||
tempstr = strdup(p);
|
||||
strcpy(modname, tempstr);
|
||||
free(tempstr);
|
||||
}
|
||||
|
||||
if (db) dblog("findotn(): modname is '%s'",modname);
|
||||
|
@ -6264,10 +6312,9 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
pluralname = strdup(basename);
|
||||
} else {
|
||||
// multiple objects?
|
||||
if (hasflag(o->flags, F_NO_PLURAL)) {
|
||||
pluralname = strdup(basename);
|
||||
} else {
|
||||
pluralname = makeplural(basename);
|
||||
if (!hasflag(o->flags, F_NO_PLURAL)) {
|
||||
makeplural(&pluralname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6409,8 +6456,9 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
} else if (where) {
|
||||
celltype_t *ct;
|
||||
ct = findcelltype(getmapsolid(where->map));
|
||||
free(pluralname);
|
||||
// solid cell description
|
||||
strcpy(pluralname, ct->name);
|
||||
pluralname = strdup(ct->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6852,7 +6900,7 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
flag_t *f;
|
||||
int db = B_FALSE;
|
||||
int partdb = B_FALSE;
|
||||
char *pluralname;
|
||||
char *pluralname = NULL;
|
||||
char brandname[BUFLEN];
|
||||
char cursestr[BUFLEN];
|
||||
int raritymin,raritymax;
|
||||
|
@ -6866,7 +6914,7 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
char habname[BUFLEN];
|
||||
int rrmoddir = -1;
|
||||
int brandchance;
|
||||
enum OBTYPE wantcl = OC_NONE;
|
||||
enum OBCLASS wantcl = OC_NONE;
|
||||
int multiwantcl = B_FALSE;
|
||||
|
||||
if (!db) db = obdb;
|
||||
|
@ -6885,8 +6933,7 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
strcpy(habname, "(any)");
|
||||
}
|
||||
|
||||
//if (forcedepth != NA) {
|
||||
if (forcedepth >= 0) {
|
||||
if (forcedepth >= 0) { // WAS: if (forcedepth != NA)
|
||||
depth = forcedepth;
|
||||
} else if (cell) {
|
||||
depth = getmapdifficulty(cell->map);
|
||||
|
@ -6997,8 +7044,12 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
if ((rarnum >= raritymin) && (rarnum <= raritymax)) {
|
||||
// now check common, rare, etc
|
||||
enum RARITY thisrr;
|
||||
|
||||
if (rarflag->val[2] == NA) {
|
||||
thisrr = RR_FREQUENT;
|
||||
} else {
|
||||
thisrr = rarflag->val[2];
|
||||
if (thisrr == NA) thisrr = RR_FREQUENT;
|
||||
}
|
||||
|
||||
if (thisrr == wantrr) {
|
||||
rarok = B_TRUE;
|
||||
|
@ -7090,12 +7141,6 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
amt = 1;
|
||||
}
|
||||
|
||||
if (amt > 1) {
|
||||
pluralname = makeplural(ot->name);
|
||||
} else {
|
||||
pluralname = strdup(ot->name);
|
||||
}
|
||||
|
||||
// chance to be blessed or cursed? 15% chance each way
|
||||
strcpy(cursestr, "");
|
||||
if (!hasflag(ot->flags, F_NOBLESS) && !hasflag(ot->flags, F_STARTSPLAIN)) {
|
||||
|
@ -7178,6 +7223,12 @@ objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forc
|
|||
if (br) strcpy(brandname, br->suffix);
|
||||
}
|
||||
|
||||
|
||||
pluralname = strdup(ot->name);
|
||||
if (amt > 1) {
|
||||
makeplural(&pluralname);
|
||||
}
|
||||
|
||||
snprintf(buf, BUFLEN, "%d %s%s%s", amt, cursestr, pluralname,brandname);
|
||||
|
||||
if (db || partdb) dblog("random ob for %s: %d x %s ('%s')", habname, amt, ot->name,pluralname);
|
||||
|
@ -8054,7 +8105,7 @@ int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) {
|
|||
}
|
||||
|
||||
if (lf) {
|
||||
if ((lf->race->raceclass->id == RC_UNDEAD)) {
|
||||
if (lf->race->raceclass->id == RC_UNDEAD) {
|
||||
if (hasflagval(o->flags, F_REPELBLESSED, B_CURSED, NA, NA, NULL)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -8216,6 +8267,13 @@ int isvalidoverridemat(enum MATERIAL mat) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isinroof(object_t *o) {
|
||||
if (hasflagval(o->flags, F_PIT, D_UP, NA, NA, NULL) || (o->type->id == OT_GRATINGROOF)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isoperable(object_t *o) {
|
||||
if (hasflag(o->flags, F_OPERABLE)) return B_TRUE;
|
||||
//if (o->type->obclass->id == OC_TECH) return B_TRUE;
|
||||
|
@ -8558,9 +8616,13 @@ void killob(object_t *o) {
|
|||
|
||||
void killobmod(obmod_t *om) {
|
||||
obmod_t *nextone, *lastone;
|
||||
int i;
|
||||
|
||||
// free mem
|
||||
if (om->prefix) free(om->prefix);
|
||||
for (i = 0; i < om->naltprefix; i++) {
|
||||
free(om->altprefix[i]);
|
||||
}
|
||||
killflagpile(om->flags);
|
||||
|
||||
// remove from list
|
||||
|
@ -12221,7 +12283,7 @@ void quaff(lifeform_t *lf, object_t *o) {
|
|||
int willid = B_FALSE;
|
||||
int playercansee;
|
||||
int forcedrop = B_FALSE;
|
||||
int seen;
|
||||
int seen = B_FALSE;
|
||||
int killobwhendone = B_TRUE;
|
||||
flag_t *drinkflag;
|
||||
enum OBTYPE realobid = OT_NONE;
|
||||
|
@ -12385,6 +12447,7 @@ void quaff(lifeform_t *lf, object_t *o) {
|
|||
// o can be NULL if we're just doing potion EFFECTS, not actually drinking one.
|
||||
void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE potblessed, int *seen) {
|
||||
char lfname[BUFLEN];
|
||||
char origstats[BUFLEN];
|
||||
int dam;
|
||||
int i;
|
||||
int first,dir;
|
||||
|
@ -12620,13 +12683,15 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
break;
|
||||
case OT_POT_GROWTH:
|
||||
i = getlfsize(lf);
|
||||
sprintf(origstats, "%d,%d", lf->att[A_STR], lf->maxhp);
|
||||
if (iscursed(o)) {
|
||||
dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL);
|
||||
} else {
|
||||
dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE, NULL);
|
||||
}
|
||||
// revert in a little while...
|
||||
addflag(lf->flags, F_SIZETIMER, i, rnd(10,20), NA, NULL);
|
||||
|
||||
addflag(lf->flags, F_SIZETIMER, i, rnd(10,20), NA, origstats);
|
||||
break;
|
||||
case OT_POT_HEALING:
|
||||
dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
|
||||
|
@ -12744,7 +12809,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
cell_t *c;
|
||||
c = getcellindir(lf->cell, dir);
|
||||
if (c && !c->type->solid) {
|
||||
object_t *newob;
|
||||
object_t *newob = NULL;
|
||||
|
||||
// get lifeforms out of the way
|
||||
if (c->lf) {
|
||||
|
@ -12754,12 +12819,11 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
|
||||
if (!c->lf) {
|
||||
newob = addob(c->obpile, "magical barrier");
|
||||
if (newob) {
|
||||
if (first && haslos(player, c)) {
|
||||
msg("A magical barrier appears!");
|
||||
first = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// it will disappear eventually
|
||||
//addflag(newob->flags, F_OBHP, i, i, NA, NULL);
|
||||
//addflag(newob->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -12767,6 +12831,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
addflag(newob->flags, F_CREATEDBY, lf->id, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OT_POT_SLEEP:
|
||||
dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, NULL);
|
||||
|
@ -13581,8 +13648,12 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
object_t *relinkob(object_t *src, obpile_t *dst) {
|
||||
/*
|
||||
if (!obfits(src, dst)) return NULL;
|
||||
if (isdeadob(src)) return NULL;
|
||||
*/
|
||||
if (!obfits(src, dst)) return src;
|
||||
if (isdeadob(src)) return src;
|
||||
|
||||
if (src->pile->owner) {
|
||||
// previous owner loses all flags conferred by this object
|
||||
|
@ -13605,7 +13676,7 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
|
|||
// this might have killed the object - eg. unequipping
|
||||
// a summoned energy blade.
|
||||
if (isdeadob(src)) {
|
||||
return NULL;
|
||||
return src; // was null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13620,8 +13691,6 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
|
|||
src->letter = getnextletter(dst, &src->letter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// unlink this object from the current list
|
||||
if (src->prev == NULL) {
|
||||
// first
|
||||
|
@ -13652,7 +13721,6 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
|
|||
aa->next = src;
|
||||
}
|
||||
|
||||
|
||||
dst->last = src;
|
||||
src->pile = dst;
|
||||
src->next = NULL;
|
||||
|
@ -13831,6 +13899,7 @@ int setcolfromhiddenname(flagpile_t *fp, char *text, int defaultglyph) {
|
|||
int sethiddenname(objecttype_t *ot, char *text) {
|
||||
// add knowledge for it (unless it's a book)
|
||||
if (ot->obclass->id != OC_BOOK) {
|
||||
//addknowledge(ot->obclass->id, text, B_UNKNOWN);
|
||||
addknowledge(ot->id, text, B_UNKNOWN);
|
||||
}
|
||||
|
||||
|
@ -16302,7 +16371,7 @@ void timeeffectsob(object_t *o) {
|
|||
contagious = B_TRUE;
|
||||
}
|
||||
// turn into a zombified version of itself.
|
||||
lf = makezombie(o, 10, revivetext, lf); // this will do the announcement
|
||||
lf = makezombie(o, 10, revivetext, NULL); // this will do the announcement
|
||||
if (lf && contagious) {
|
||||
addflag(lf->flags, F_HITCONFER, F_REVIVETIMER, SC_POISON, 165, NULL);
|
||||
addflag(lf->flags, F_HITCONFERVALS, 0, 1, R_ZOMBIECON, "rises up as a zombie!");
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
brand_t *addbrand(enum BRAND id, char *suffix, enum BODYPART bp, enum BLESSTYPE blessed, int blesschance);
|
||||
object_t *addemptyob(obpile_t *where, object_t *o);
|
||||
hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text);
|
||||
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
|
||||
knowledge_t *addknowledge(enum OBTYPE id, char *hiddenname, int known);
|
||||
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
||||
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, int glyph, int glyphcolour, enum RARITY rarity);
|
||||
void addocnoun(objectclass_t *oc, char *text);
|
||||
|
@ -217,6 +217,7 @@ int ismeleeweapon(object_t *o);
|
|||
int ismetal(enum MATERIAL mat);
|
||||
int isthrowmissile(object_t *o);
|
||||
int isvalidoverridemat(enum MATERIAL mat);
|
||||
int isinroof(object_t *o);
|
||||
int isoperable(object_t *o);
|
||||
int isplainob(object_t *o);
|
||||
int ispourable(object_t *o);
|
||||
|
|
1
shops.c
1
shops.c
|
@ -578,6 +578,7 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
|
|||
return SR_BACK;
|
||||
}
|
||||
angergodmaybe(R_GODTHIEVES, 10, GA_MONEY);
|
||||
more();
|
||||
|
||||
return SR_CONTINUE;
|
||||
}
|
||||
|
|
99
spell.c
99
spell.c
|
@ -216,7 +216,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (npossible >= 2) {
|
||||
char ptext[BUFLEN],buf[BUFLEN];
|
||||
char *p;
|
||||
p = makeplural(tempot->name);
|
||||
p = strdup(tempot->name);
|
||||
makeplural(&p);
|
||||
sprintf(ptext, "How many %s will you build (max %d)", p, npossible);
|
||||
free(p);
|
||||
askstring(ptext, '?', buf, BUFLEN, "1");
|
||||
|
@ -392,7 +393,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
lifeform_t *inway = NULL, *movedlf = NULL;
|
||||
cell_t *c;
|
||||
object_t *stairs;
|
||||
int stairdir;
|
||||
int stairdir, needsclimb = B_FALSE;
|
||||
char climbprompt[BUFLEN];
|
||||
|
||||
if (!isplayer(user)) {
|
||||
return B_FALSE;
|
||||
|
@ -411,6 +413,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// are stairs on the roof?
|
||||
if (isinroof(stairs) && !canreachroof(user)) {
|
||||
needsclimb = B_TRUE;
|
||||
snprintf(climbprompt, BUFLEN, "Climb to check %%s");
|
||||
}
|
||||
|
||||
// how can we check the stairs?
|
||||
getobname(stairs, obname, 1);
|
||||
sprintf(buf, "How will you check %s", obname);
|
||||
|
@ -423,11 +432,22 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
addchoice(&prompt, 'l', "Listen for sounds", NULL, NULL, NULL);
|
||||
}
|
||||
if ((getskill(user, SK_PERCEPTION)) && !isblind(user)) {
|
||||
if (needsclimb) {
|
||||
addchoice(&prompt, 'f', "Check for footprints (requires climbing)", NULL, NULL, NULL);
|
||||
snprintf(climbprompt, BUFLEN, "Climb to check %%s for footprints");
|
||||
} else {
|
||||
addchoice(&prompt, 'f', "Check for footprints", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
if (getskill(user, SK_STEALTH) >= PR_SKILLED) {
|
||||
if (needsclimb) {
|
||||
addchoice(&prompt, 'p', "Peek at the other end (requires climbing)", NULL, NULL, NULL);
|
||||
snprintf(climbprompt, BUFLEN, "Climb to peek through %%s");
|
||||
} else {
|
||||
addchoice(&prompt, 'p', "Peek at the other end", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
if (lfhasflag(user, F_ENHANCESMELL)) {
|
||||
addchoice(&prompt, 's', "Sniff for scents", NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -444,6 +464,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (needsclimb) {
|
||||
// must try to climb first.
|
||||
if (asktoclimb(stairs, climbprompt)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// announce the check, so that the player has feedback
|
||||
// if map generation takes a while.
|
||||
if (ch == 'd') {
|
||||
|
@ -625,7 +653,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (slev >= PR_EXPERT) {
|
||||
char *newtext;
|
||||
if (movetextcount[n] > 1) {
|
||||
newtext = makeplural(movetext[n]);
|
||||
newtext = strdup(movetext[n]);
|
||||
makeplural(&newtext);
|
||||
msg("You can hear %s%s.", amttext, noprefix(newtext));
|
||||
free(newtext);
|
||||
} else {
|
||||
|
@ -637,6 +666,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// free this mem
|
||||
free(movetext[n]);
|
||||
}
|
||||
|
||||
} else {
|
||||
msg("You don't hear anything unusual.");
|
||||
}
|
||||
|
@ -699,7 +729,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
if (smellcount[n] > 1) {
|
||||
newtext = makeplural(smellrace[n]->name);
|
||||
newtext = strdup(smellrace[n]->name);
|
||||
makeplural(&newtext);
|
||||
msg("You can smell %s%s.", amttext, newtext);
|
||||
free(newtext);
|
||||
} else {
|
||||
|
@ -816,8 +847,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (ch == 'p') {
|
||||
// if we peeked, then we have to redraw now.
|
||||
setlosdirty(user);
|
||||
if (needsclimb) {
|
||||
msg("You drop to the ground.");
|
||||
} else {
|
||||
msg("You return to your original position.");
|
||||
}
|
||||
} else if (needsclimb) {
|
||||
msg("You drop to the ground.");
|
||||
}
|
||||
|
||||
taketime(user, getactspeed(user)*2);
|
||||
} else if (abilid == OT_A_CLIMB) {
|
||||
|
@ -3939,11 +3976,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// skillcheck...
|
||||
f = hasflag(o->flags, F_RARITY);
|
||||
if (f) {
|
||||
if (f->val[2] == NA) {
|
||||
rarity = RR_COMMON;
|
||||
} else {
|
||||
rarity = f->val[2];
|
||||
}
|
||||
} else {
|
||||
rarity = 0;
|
||||
}
|
||||
if (rarity == NA) rarity = RR_COMMON;
|
||||
difficulty = 120 + (rarity*10);
|
||||
/*
|
||||
switch (o->type->obclass->id) {
|
||||
|
@ -6514,7 +6554,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// use direct damage rather than holy, because otherwise it might be increased
|
||||
// due to vulnerabilities
|
||||
losehp(target, roll("3d6" + power), DT_DIRECT, caster, "disruption");
|
||||
losehp(target, roll("3d6") + power, DT_DIRECT, caster, "disruption");
|
||||
} else if (spellid == OT_S_DISORIENT) {
|
||||
target = targcell->lf;
|
||||
|
||||
|
@ -6949,7 +6989,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("^%cYou blast %s%s brain cells!", getlfcol(target, CC_VBAD),
|
||||
lfname, getpossessive(lfname));
|
||||
}
|
||||
if (!ischarmable(target) && (reason != F_CHARMEDBY) && (reason != E_LOWIQ)) {
|
||||
if (!ischarmable(target) && (reason != E_ALREADYUSING) && (reason != E_LOWIQ)) {
|
||||
if (isplayer(caster)) {
|
||||
char tname[BUFLEN];
|
||||
getlfname(target, tname);
|
||||
|
@ -8815,7 +8855,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
if (getattrbracket(getattr(target, A_IQ), A_IQ, NULL) <= AT_VLOW) {
|
||||
fail = B_TRUE;
|
||||
} else if (!ischarmable(target) && (reason != F_CHARMEDBY)) {
|
||||
} else if (!ischarmable(target) && (reason != E_ALREADYUSING)) {
|
||||
fail = B_TRUE;
|
||||
}
|
||||
if (fail) {
|
||||
|
@ -9072,7 +9112,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
enum OBTYPE newoid = OT_NONE;
|
||||
enum LFSIZE newsize = SZ_ANY;
|
||||
enum CELLTYPE newcelltype = CT_NONE;
|
||||
skill_t *obsk = SK_NONE;
|
||||
skill_t *obsk = NULL;
|
||||
char obname[BUFLEN],newobname[BUFLEN];
|
||||
int seen;
|
||||
|
||||
|
@ -9161,7 +9201,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char obtocreate[BUFLEN];
|
||||
enum LFSIZE newsize = SZ_ANY;
|
||||
enum CELLTYPE newcelltype = CT_NONE;
|
||||
skill_t *obsk = SK_NONE;
|
||||
skill_t *obsk = NULL;
|
||||
char obname[BUFLEN],newobname[BUFLEN];
|
||||
int seen;
|
||||
|
||||
|
@ -9790,7 +9830,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// not smart enough
|
||||
if (iqb <= AT_EXLOW) {
|
||||
fail = B_TRUE;
|
||||
} else if (!ischarmable(target) && (reason != F_CHARMEDBY)) {
|
||||
} else if (!ischarmable(target) && (reason != E_ALREADYUSING)) {
|
||||
fail = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -12514,7 +12554,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
*/
|
||||
// for each cell we can see... (including our own)
|
||||
// for each cell we can see... (including our own, but don't affect our own weapon)
|
||||
for (i = 0; i < caster->nlos; i++) {
|
||||
c = caster->los[i];
|
||||
if (c->lf && cansee(caster, c->lf) && (c->lf != caster)) {
|
||||
|
@ -13102,7 +13142,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
lifeform_t *lf;
|
||||
if (caster && !isplayer(caster) && cansee(player, caster)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
getlfname(caster, lfname);
|
||||
msg("%s glows brightly with the essense of life!", lfname);
|
||||
}
|
||||
if (!target) {
|
||||
|
@ -13308,7 +13348,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (ngot == 1) {
|
||||
msg("%s %s appears near %s!", needan(r->name) ? "An" : "A", r->name, castername);
|
||||
} else {
|
||||
msg("%s appear around %s!", makeplural(r->name), castername);
|
||||
char *plur;
|
||||
plur = strdup(r->name);
|
||||
makeplural(&plur);
|
||||
msg("%s appear around %s!", plur, castername);
|
||||
free(plur);
|
||||
}
|
||||
} else {
|
||||
raceclass_t *rc;
|
||||
|
@ -13316,7 +13360,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (ngot == 1) {
|
||||
msg("%s %s appears near %s!", needan(rc->name) ? "An" : "A", rc->name, castername);
|
||||
} else {
|
||||
msg("%s appear around %s!", makeplural(rc->name), castername);
|
||||
char *plur;
|
||||
plur = strdup(rc->name);
|
||||
makeplural(&plur);
|
||||
msg("%s appear around %s!", plur, castername);
|
||||
free(plur);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13938,12 +13986,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int appearonground = B_FALSE;
|
||||
if (!target) target = caster;
|
||||
initprompt(&prompt, "For what do you wish?");
|
||||
addchoice(&prompt, 'a', "Wealth", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'b', "Power", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'c', "Protection", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'd', "Fame", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'e', "Knowledge", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'f', "Magic", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'a', "Wealth (riches beyond your imagination)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'b', "Power (an item with which to smite your foes)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'c', "Protection (an item to defend against harm)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'd', "Fame (followers to obey your every whim)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'e', "Knowledge (identify everything and more)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, 'f', "Magic (books full of arcane writings)", NULL, NULL, NULL);
|
||||
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
|
||||
if (isplayer(target)) {
|
||||
ch = getchoice(&prompt);
|
||||
|
@ -14088,7 +14136,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
strcpy(buf, "");
|
||||
} else if (ch == 'e') { // knowledge (makeknown everything you have plus 5-10 others. bad: insanity)
|
||||
} else if (ch == 'e') { // knowledge (makeknown everything you have plus 10% chance for everything else. bad: insanity)
|
||||
// only possible for the player!
|
||||
strcpy(buf, "");
|
||||
if (isplayer(target)) {
|
||||
|
@ -14115,6 +14163,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
makeknown(k->id);
|
||||
}
|
||||
}
|
||||
msg("(check '%c' to see your knowledge)", cmdtochar(CMD_INFOKNOWLEDGE));
|
||||
}
|
||||
}
|
||||
} else if (ch == 'f') { // magic (spellbooks), bad: gain 'explode self' magic
|
||||
|
@ -14795,7 +14844,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
|||
// player can only ever cast spells up to your level.
|
||||
if (!hasjob(lf, J_GOD)) limit(&maxspelllevel, NA, lf->level);
|
||||
|
||||
if (spelllev > maxspelllevel) {
|
||||
if (!willflag && (spelllev > maxspelllevel)) {
|
||||
if (db) dblog("-->power = 0 (no skilled enough in spell school)");
|
||||
return 0;
|
||||
}
|
||||
|
@ -14816,8 +14865,10 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
|||
// plus god modifier
|
||||
power += getspellpowergodmod(lf, school, NULL);
|
||||
|
||||
if (!willflag) {
|
||||
// plus any extra school levels beyond what you need
|
||||
power += (schoolskill - spelllev);
|
||||
power += ((int)schoolskill - spelllev);
|
||||
}
|
||||
} else {
|
||||
// for monsters, just based on hitdice:
|
||||
power = gettr(lf)/2;
|
||||
|
|
48
text.c
48
text.c
|
@ -2355,39 +2355,64 @@ char *makelowercase(char *text) {
|
|||
return text;
|
||||
}
|
||||
|
||||
// allocates and returns new string
|
||||
char *makeplural(char *text) {
|
||||
// deallocates string, allocates a new one
|
||||
char *makeplural(char **text) {
|
||||
char lastlet;
|
||||
char *newtext;
|
||||
int rv;
|
||||
int rv,len,done = B_FALSE;
|
||||
plural_t *pl;
|
||||
|
||||
newtext = strdup(text);
|
||||
assert(*text != NULL);
|
||||
len = strlen(*text);
|
||||
assert(len > 0);
|
||||
|
||||
newtext = strdup(*text); // make copy
|
||||
|
||||
for (pl = firstplural ; pl ; pl = pl->next) {
|
||||
strrep(&newtext, pl->singular, pl->plural, &rv);
|
||||
if (rv && pl->stopafter) return newtext;
|
||||
if (rv && pl->stopafter) {
|
||||
done = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
// default
|
||||
lastlet = text[strlen(text)-1];
|
||||
//lastlet = (*text)[len-1];
|
||||
lastlet = newtext[len-1];
|
||||
switch (lastlet) {
|
||||
char *temptext;
|
||||
case 'y': // change to 'ies'
|
||||
temptext = strdup(text);
|
||||
temptext = strdup(newtext);
|
||||
temptext[strlen(temptext)-1] = '\0';
|
||||
free(newtext);
|
||||
asprintf(&newtext, "%sies",temptext);
|
||||
free(temptext);
|
||||
break;
|
||||
case 's':
|
||||
case 'o': // append "es"
|
||||
asprintf(&newtext, "%ses",text);
|
||||
asprintf(&temptext, "%ses",newtext);
|
||||
free(newtext);
|
||||
newtext = strdup(temptext);
|
||||
free(temptext);
|
||||
break;
|
||||
default: // append "s"
|
||||
asprintf(&newtext, "%ss",text);
|
||||
asprintf(&temptext, "%ss",newtext);
|
||||
free(newtext);
|
||||
newtext = strdup(temptext);
|
||||
free(temptext);
|
||||
break;
|
||||
}
|
||||
return newtext;
|
||||
}
|
||||
|
||||
// 'newtext' now holdes the pluralized version of '*text'
|
||||
|
||||
// make original pointer large enough to hold the new version + NUL.
|
||||
*text = realloc(*text, strlen(newtext)+1);
|
||||
snprintf(*text, strlen(newtext)+1, "%s", newtext);
|
||||
free(newtext);
|
||||
|
||||
return *text;
|
||||
}
|
||||
|
||||
// throwflag should be either a F_THROWING or a F_FIRING flag.
|
||||
|
@ -2775,9 +2800,10 @@ char *do_strrep(const char *s1, const char *s2, const char *s3) {
|
|||
return 0;
|
||||
|
||||
char *newstr = (char *)malloc(newstr_len + 1); /* w/ terminator */
|
||||
if (!newstr)
|
||||
if (!newstr) {
|
||||
/* ENOMEM, but no good way to signal it. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *dst = newstr;
|
||||
const char *start_substr = s1;
|
||||
|
|
2
text.h
2
text.h
|
@ -67,7 +67,7 @@ void killplural(plural_t *w);
|
|||
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf);
|
||||
char *makekillertext(char *retbuf, char *killverb, char *lastdam, map_t *where, int wantextra, int wantlocation);
|
||||
char *makelowercase(char *text);
|
||||
char *makeplural(char *text);
|
||||
char *makeplural(char **text);
|
||||
char *makethrowaccstring(lifeform_t *lf, cell_t *c, flag_t *throwflag, char *retbuf);
|
||||
char *makeuppercase(char *text);
|
||||
char *makewearstring(lifeform_t *lf, object_t *o, int wantyour, char *posbuf);
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
*Fix double free and use after free in aimovetotargetcell() - this MIGHT be what's causing all my flagpile corruption.
|
||||
*Fix a bunch of cases where I use a variable uninitialised.
|
||||
*forgot to initialised brand->description
|
||||
*free bodypart names
|
||||
*free om->altprefix[]
|
||||
*Invalid free / delete / realloc in clearcell()
|
||||
*fix makeplural memleaks
|
||||
*door displaying as "leaf" - definition of knowledge->id was OBCLASS instead of OBTYPE.
|
||||
*Bad text:
|
||||
* Minimum agility to use effectively: 50 to use.Minimum agility to use
|
||||
* effectively: 50 to use. (bonus at 70).
|
||||
*change wish text to be more meaningful
|
||||
*fix bug when creating objects with a bonus (eg. blessed '+5' sword)
|
||||
*when raging, don't prompt to really attack when you won't gain xp
|
||||
*disable flagpile checks now.
|
||||
*Use 'interact' to use shops, not 'operate'
|
||||
*You are resistant to: projectiles[-7870t], explosives[-7870t].
|
||||
*scorpions shouldn't follow up stairs. (but giant scorpions can)
|
||||
*make failed relinkob() calls return the original object rather than null, otherwise we get situations where an object becomes NULL and causes a crash.
|
||||
*make cooking skill description cover what size corpses you can cook.
|
||||
*bug: potion of growth caused instadeath when reverting.
|
||||
*bug in description of monster abilities
|
||||
*show raceclass in descriptions
|
||||
*bug: not showing monster abilites properly
|
||||
*make evasion only work if you're not exhausetd
|
||||
*Felix shoudl like attacking while hidden
|
||||
*Not seeing felix angered messages when donating items
|
||||
*holes in roof - shouldn't be able to inspect a hole in the roof if you can't reach it!
|
||||
*crash when hitting @ while producing light.
|
||||
|
||||
|
||||
Set up a GIT server on slime.
|
||||
clone svn first ?
|
||||
|
||||
stunned mosnters shuld stop flying.
|
||||
|
||||
glorana sohuld get VERY happy from offering healing potions - too hard to level up right now
|
||||
|
||||
|
||||
make it easier to slip if your'e sprinting.
|
||||
|
||||
no critical hits when exhausted
|
||||
|
||||
|
||||
spiders shouldn't slip (insects in general shoudln't)
|
||||
|
||||
|
||||
Trn:0/103% <- huh?
|
||||
|
||||
safety goggles should PROTECT from eye burning from light
|
||||
even if you're a delver etc
|
||||
|
||||
|
||||
|
||||
more things to build!
|
||||
door.
|
||||
|
||||
is tumble skill too hard to use ?? always seems to fail.
|
||||
|
||||
say in skill description whether it might fail or not.
|
||||
|
||||
HELP
|
||||
Stunned
|
||||
Prone
|
||||
|
||||
Poison
|
||||
help on types of poison?
|
||||
|
||||
god help
|
||||
don't worry about choosing - will approach you when the time is right.
|
||||
|
||||
Attack/Defense calc
|
||||
|
||||
Spell power calc
|
||||
level of spells castable is determined by your skill inthe spell's school.
|
||||
inept = 0
|
||||
master = 6
|
||||
|
||||
power = 1
|
||||
+ (level / 3)
|
||||
+ modifier based on INT/WIS/STR
|
||||
+ 1 per skill level beyond what you need
|
||||
|
||||
|
||||
|
||||
Help text for str, agi, fitness, etc
|
||||
|
||||
find proper font to use.
|
||||
|
||||
can wyrmspawn possible win ?
|
||||
|
||||
better 'inspect item' help - show which skills help
|
||||
|
||||
|
||||
|
||||
Skills screen
|
||||
with --More--, have a special key to go up/down, rather than the
|
||||
next keypress.
|
||||
|
||||
Don't show --More-- on skills screen if we're at the last one.
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#valgrind --track-origins=yes --leak-check=yes --dsymutil=yes --log-file=valout ./nexus
|
||||
valgrind --leak-check=yes --dsymutil=yes --log-file=valout ./nexus
|
||||
|
7
vault.c
7
vault.c
|
@ -1670,18 +1670,23 @@ vault_t *loadvault(char *dir, char *filename) {
|
|||
// read a line
|
||||
fgets(line, BUFLEN, f);
|
||||
while (!feof(f)) {
|
||||
if (strlen(line)) {
|
||||
// strip newline
|
||||
line[strlen(line)-1] = '\0';
|
||||
// strip trailing spaces
|
||||
while (line[strlen(line)-1] == ' ') {
|
||||
while (strlen(line) && line[strlen(line)-1] == ' ') {
|
||||
line[strlen(line)-1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// anything left?
|
||||
if (strlen(line)) {
|
||||
// handle it
|
||||
if (handleline(v, line)) {
|
||||
goterrors = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// read next line
|
||||
fgets(line, BUFLEN, f);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue