- [+] issues with drawing off edge of map.
- [+] should ALWAYS be blank (' ') - [+] The fire giant forgecaller incinerates you with a flaming morningstar.--More-- HP:-115193/139 - [+] barbarian should start with a heavy weapon (to do heavy blow with) - [+] chang epegasus symbol to Q - [+] stop sprinting when you open a door, attack, etc - [+] "the darkmantle vanishes" "the darkmantle appearS" "the darkmantle steps though the shadows" - [+] when generating humanoid monsters on dark levels without seeindark, high chance of them having a torch/candle - [+] all undead should seeindark - [+] major healing pot doesn't work - [+] crossbow should do more damage * [+] aiming skill - determines accuracy of firearms * [+] change spellbooks to be a single object ("spellbook") - [+] call wind spell - [+] make plants boost power of druid spells - [+] secret iron door showing up as '.' - [+] table shoudl be misc, not dfeature * [+] implement sound volume. 1 - xx * [+] some monsers have f_varlevel. v0 = max. - [+] implement 'say' * [+] bandits should demand a bribe (based on their hit dice) * [+] replace graph paper with cartography skill - [+] lightning bolt (air, goes THROUGH all lfs until the target one. less damage than fireball though.) - [+] no casting spells while prone Initial world map implemention. - [+] maps need flags. * [+] when in world map, calculate rarity differently based on distance from 0,0 * [+] allow walking off edge of forest to new map areas
This commit is contained in:
parent
300f1637b3
commit
a763c3c4b1
25
ai.c
25
ai.c
|
@ -828,6 +828,24 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// generic pre-movement actions.
|
||||
///////////////////////////////////////////////
|
||||
if (!haslos(lf, lf->cell)) {
|
||||
object_t *lamp;
|
||||
lamp = hasobwithflagval(lf->pack, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL);
|
||||
if (lamp && !isactivated(lamp)) {
|
||||
if (db) dblog(".oO { it's dark and i have an inactive light source (%s) }", lamp->type->name);
|
||||
if (!operate(lf, lamp, NULL)) {
|
||||
if (db) dblog(".oO { successfully turned it on. }");
|
||||
return;
|
||||
} else {
|
||||
if (db) dblog(".oO { failed to turn it on. }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// movement
|
||||
///////////////////////////////////////////////
|
||||
|
@ -1581,6 +1599,13 @@ int lookforobs(lifeform_t *lf, int covetsonly) {
|
|||
|
||||
|
||||
if (gothere) {
|
||||
// cast a spell?
|
||||
if (cancast(lf, OT_S_CALLWIND, NULL) && haslof(lf->cell, c, LOF_NEED, NULL)) {
|
||||
if (!castspell(lf, OT_S_CALLWIND, NULL, o, c)) {
|
||||
// successful
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
// start walking towards target cell
|
||||
if (aigoto(lf, c, MR_OB, o, AI_FOLLOWTIME)) {
|
||||
return B_FALSE;
|
||||
|
|
24
attack.c
24
attack.c
|
@ -125,6 +125,7 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
int gotweapon = B_FALSE;
|
||||
int maxattacks = ALL;
|
||||
int lastweaponidx = -1;
|
||||
flag_t *sf;
|
||||
|
||||
// anyone there? if so just attack.
|
||||
if (c->lf) {
|
||||
|
@ -166,6 +167,23 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
}
|
||||
}
|
||||
|
||||
// stop sprinting
|
||||
sf = lfhasflag(lf, F_SPRINTING);
|
||||
if (sf && sf->val[0]) {
|
||||
killflag(sf);
|
||||
}
|
||||
|
||||
// ai code...
|
||||
if (lfhasflag(lf, F_DEMANDSBRIBE)) {
|
||||
if (!isplayer(lf) && (attacktype == AT_LF) && isplayer((lifeform_t *)attacktarget)) {
|
||||
if (demandbribe(lf)) {
|
||||
// ie. player paid.
|
||||
taketime(lf, getactspeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// first use our weapon...
|
||||
nweps = 0;
|
||||
wep[nweps] = getweapon(lf);
|
||||
|
@ -622,7 +640,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
needses(attackverb) ? "es" : "s",
|
||||
victimname,withwep, nodamstr);
|
||||
}
|
||||
noise(lf->cell, lf, "sounds of fighting.", NULL);
|
||||
noise(lf->cell, lf, 3, "sounds of fighting.", NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -938,7 +956,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
msg("%s %ss %s%s.", attackername,
|
||||
getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep);
|
||||
} else {
|
||||
noise(lf->cell, NULL, "sounds of fighting.", NULL);
|
||||
noise(lf->cell, NULL, 3, "sounds of fighting.", NULL);
|
||||
}
|
||||
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARD)) {
|
||||
|
@ -1236,7 +1254,7 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
|
|||
flag_t *f;
|
||||
for (f = wep->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_ONFIRE) {
|
||||
if (f->text) {
|
||||
if (strlen(f->text)) {
|
||||
*(dam + *ndam) = roll(f->text);
|
||||
} else {
|
||||
*(dam + *ndam) = rolldie(2,6);
|
||||
|
|
43
defs.h
43
defs.h
|
@ -39,11 +39,13 @@ enum SKILL {
|
|||
SK_ARMOUR = 1,
|
||||
SK_ATHLETICS,
|
||||
SK_BACKSTAB,
|
||||
SK_CARTOGRAPHY,
|
||||
SK_CHANNELING,
|
||||
SK_COOKING,
|
||||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
SK_LOCKPICKING,
|
||||
SK_CHANNELING,
|
||||
SK_RANGED,
|
||||
SK_SHIELDS,
|
||||
SK_SPELLCASTING,
|
||||
SK_SPOTHIDDEN,
|
||||
|
@ -81,7 +83,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 42
|
||||
#define MAXSKILLS 44
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -248,6 +250,9 @@ enum LFCONDITION {
|
|||
#define MAX_MAPH 20
|
||||
|
||||
|
||||
#define MINCLEARINGRADIUS 2
|
||||
#define MAXCLEARINGRADIUS 5
|
||||
|
||||
//#define MAX_MAPROOMS 10
|
||||
|
||||
#define MIN_ROOMH 4
|
||||
|
@ -574,6 +579,8 @@ enum RACECLASS {
|
|||
enum RACE {
|
||||
R_NONE, R_RANDOM,
|
||||
R_HUMAN,
|
||||
// human monsters
|
||||
R_BANDIT,
|
||||
// monsters
|
||||
R_BEHOLDER,
|
||||
R_BUGBEAR,
|
||||
|
@ -794,6 +801,7 @@ enum OBTYPE {
|
|||
OT_POT_RESTORATION,
|
||||
OT_POT_RUM,
|
||||
OT_POT_SANCTUARY,
|
||||
OT_POT_SLEEP,
|
||||
OT_POT_SPEED,
|
||||
OT_POT_WATER,
|
||||
OT_POT_JUICE,
|
||||
|
@ -821,6 +829,9 @@ enum OBTYPE {
|
|||
OT_SCR_TURNUNDEAD,
|
||||
OT_SCR_WISH,
|
||||
// BOOKS
|
||||
OT_MANUAL,
|
||||
OT_SPELLBOOK,
|
||||
/*
|
||||
OT_MAN_ARMOUR,
|
||||
OT_MAN_ATHLETICS,
|
||||
OT_MAN_BACKSTAB,
|
||||
|
@ -829,6 +840,7 @@ enum OBTYPE {
|
|||
OT_MAN_LISTEN,
|
||||
OT_MAN_LOCKPICKING,
|
||||
OT_MAN_MAGITEMUSAGE,
|
||||
OT_MAN_RANGED,
|
||||
OT_MAN_SHIELDS,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_SPOTHIDDEN,
|
||||
|
@ -959,6 +971,7 @@ enum OBTYPE {
|
|||
OT_SB_TELEPORT,
|
||||
OT_SB_TWIDDLE,
|
||||
// -- wild can't be learned from books
|
||||
*/
|
||||
// spells
|
||||
// -- allomancy
|
||||
OT_S_ABSORBMETAL,
|
||||
|
@ -1052,6 +1065,7 @@ enum OBTYPE {
|
|||
// nature
|
||||
OT_S_BARKSKIN,
|
||||
OT_S_CALLLIGHTNING,
|
||||
OT_S_CALLWIND,
|
||||
OT_S_CALMANIMALS,
|
||||
OT_S_CALMINGSCENT,
|
||||
OT_S_CHARMANIMAL,
|
||||
|
@ -1062,6 +1076,7 @@ enum OBTYPE {
|
|||
OT_S_ENDUREELEMENTS,
|
||||
OT_S_ENTANGLE,
|
||||
OT_S_HAILSTORM,
|
||||
OT_S_LIGHTNINGBOLT,
|
||||
OT_S_LIGHTNINGSTORM,
|
||||
OT_S_PURIFYFOOD,
|
||||
OT_S_QUENCH,
|
||||
|
@ -1306,6 +1321,7 @@ enum OBTYPE {
|
|||
OT_HANDAXE,
|
||||
OT_BATTLEAXE,
|
||||
OT_GREATAXE,
|
||||
OT_WARAXE,
|
||||
// short blades
|
||||
OT_COMBATKNIFE,
|
||||
OT_DAGGER,
|
||||
|
@ -1423,6 +1439,8 @@ enum POISONTYPE {
|
|||
|
||||
enum FLAG {
|
||||
F_NONE, // dummy flag
|
||||
// map flags
|
||||
F_MAPCOORDS, // v0+v1 are x/y coords for this map area
|
||||
// object flags
|
||||
F_DEAD, // object will be removed
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
|
@ -1737,11 +1755,17 @@ enum FLAG {
|
|||
F_LOSLOF, // v0 = whether this spell needs line of sight
|
||||
// v1 = whether this spell needs line of fire
|
||||
// MONSTER AI FLAGS
|
||||
F_DEMANDSBRIBE, // lf will demand gold from the player.
|
||||
F_VARLEVEL, // lf is generated with random level between
|
||||
// 1 and its map dificulty/depth.
|
||||
// if v0 is set, this is the max level.
|
||||
F_MINION, // v0=lfid of minion
|
||||
F_XPVAL, // force xp val for killing this lf to v0
|
||||
// ...OR if applied to an ability...
|
||||
// monsters with this abil/spell are worth
|
||||
// v0 more xp.
|
||||
F_XPMULTIPLY, // multiply xp val for killing this lf by v0
|
||||
F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc
|
||||
F_LASTDIR, // this is the last direction we moved.
|
||||
F_OWNERLASTDIR, // for pets, this it the last dir our owner moved
|
||||
// when we could see them.
|
||||
|
@ -1779,6 +1803,7 @@ enum FLAG {
|
|||
F_KILLEDBYPLAYER, // did the player kill this lf?
|
||||
// monster noise flags
|
||||
F_NOISETEXT, // val0 is a enum NOISETYPE
|
||||
// val1 is the volume of the noise
|
||||
// text is "verb^noun"
|
||||
// eg. "shouts^a shout"
|
||||
F_SPELLCASTTEXT, // text is announcement for spellcast
|
||||
|
@ -2138,6 +2163,7 @@ enum ERROR {
|
|||
E_CARNIVORE = 51,
|
||||
E_NOOB = 52,
|
||||
E_LEVITATING = 53,
|
||||
E_PRONE = 54,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2204,9 +2230,16 @@ typedef struct map_s {
|
|||
|
||||
struct lifeform_s *lf,*lastlf;
|
||||
|
||||
struct flagpile_s *flags;
|
||||
|
||||
struct map_s *next, *prev;
|
||||
} map_t; //////////////// remember to modify save/load for new props!!
|
||||
|
||||
typedef struct glyph_s {
|
||||
int ch;
|
||||
int colour;
|
||||
} glyph_t;
|
||||
|
||||
typedef struct cell_s {
|
||||
map_t *map; // pointer back to map
|
||||
int x,y; // map coords
|
||||
|
@ -2225,16 +2258,12 @@ typedef struct cell_s {
|
|||
struct lifeform_s *lf;
|
||||
// known to player?
|
||||
int known;
|
||||
struct glyph_s knownglyph;
|
||||
|
||||
// FOR CONSTRUCTION
|
||||
int visited;
|
||||
} cell_t;
|
||||
|
||||
typedef struct glyph_s {
|
||||
int ch;
|
||||
int colour;
|
||||
} glyph_t;
|
||||
|
||||
typedef struct celltype_s {
|
||||
int id; // eg. dungeonfloor, wall, door
|
||||
struct glyph_s glyph;
|
||||
|
|
|
@ -8,7 +8,6 @@ objects.c:
|
|||
remember to have spelllevel
|
||||
(optional) add a scroll to do the same effect, use F_LINKSPELL
|
||||
(optional) add a potion to do the same effect
|
||||
(optional) add a spellbook to learn it
|
||||
assign AI hint flags so it knows how to cast it
|
||||
|
||||
spell.c:
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
0 = tiny/mini walking
|
||||
1 = light footsteps
|
||||
2 = footsteps, door opening
|
||||
3 = heavy footsteps, shout, instruments, fighting
|
||||
4 = extremely loud thumping, war cry
|
||||
5 = footsteps of SZ_ENORMOUS, explosion
|
||||
6 = footsteps of SZ_MAX, big explosion
|
132
io.c
132
io.c
|
@ -234,6 +234,55 @@ void anim(cell_t *src, cell_t *dst, char ch, int colour) {
|
|||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char ch2, int colour) {
|
||||
glyph_t gl;
|
||||
int i;
|
||||
|
||||
gl.ch = ch;
|
||||
gl.colour = colour;
|
||||
|
||||
// hide cursor
|
||||
curs_set(0);
|
||||
for (i = 0; i < ndst; i++) {
|
||||
int n;
|
||||
|
||||
if ((i % 2) == 0) {
|
||||
gl.ch = ch;
|
||||
} else {
|
||||
gl.ch = ch2;
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
// update screen each time
|
||||
updateviewfor(src);
|
||||
drawlevelfor(player);
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
// draw one at a time
|
||||
for (n = 0; n <= i; n++) {
|
||||
drawglyph(&gl, dst[n]->x - viewx, dst[n]->y - viewy);
|
||||
}
|
||||
} else {
|
||||
drawglyph(&gl, dst[i]->x - viewx, dst[i]->y - viewy);
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
}
|
||||
// show cursor
|
||||
curs_set(1);
|
||||
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
void animradial(cell_t *src, int radius, char ch, int colour) {
|
||||
glyph_t gl;
|
||||
int i;
|
||||
|
@ -399,7 +448,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
|
|||
return ch;
|
||||
}
|
||||
|
||||
cell_t *askcoords(char *prompt, int targettype) {
|
||||
cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange) {
|
||||
static int startlf = -1;
|
||||
int finished = B_FALSE;
|
||||
int moved = B_FALSE;
|
||||
|
@ -721,6 +770,11 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
}
|
||||
// dont use msg() to avoid 'more's
|
||||
capitalise(buf);
|
||||
if (srclf && (maxrange != UNLIMITED)) {
|
||||
if (getcelldist(srclf->cell, c) > maxrange) {
|
||||
strcat(buf, " [outofrange]");
|
||||
}
|
||||
}
|
||||
wclear(msgwin);
|
||||
mvwprintw(msgwin, 0, 0, "%s",buf);
|
||||
wrefresh(msgwin);
|
||||
|
@ -810,6 +864,20 @@ void announceob(enum OBTYPE oid) {
|
|||
}
|
||||
*/
|
||||
|
||||
void announcearrival(lifeform_t *lf, map_t *newmap) {
|
||||
if (isplayer(lf)) {
|
||||
if (newmap->region == RG_WORLDMAP) {
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
msg("You arrive in a new area.");
|
||||
} else {
|
||||
msg("You arrive at the surface.");
|
||||
}
|
||||
} else if (newmap->habitat == H_DUNGEON) {
|
||||
msg("You arrive at dungeon level %d.", newmap->depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int announceflaggain(lifeform_t *lf, flag_t *f) {
|
||||
int donesomething = B_FALSE;
|
||||
lifeform_t *lf2;
|
||||
|
@ -2018,9 +2086,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
centre(mainwin, getmaxy(mainwin)-1, "[Press any key]");
|
||||
getch();
|
||||
|
||||
needredraw = B_TRUE;
|
||||
clearmsg();
|
||||
drawscreen();
|
||||
restoregamewindows();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2056,22 +2122,6 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
if (opts & AO_SPECIFIED) {
|
||||
int n;
|
||||
int found = B_FALSE;
|
||||
// does retlist contain this?
|
||||
for (n = 0; n < nretobs; n++) {
|
||||
if (retobs[n] == o) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ok = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
ok = obmatchescondition(o, opts);
|
||||
|
@ -2162,18 +2212,14 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int
|
|||
*count = o->amt;
|
||||
}
|
||||
// display game windows again
|
||||
needredraw = B_TRUE;
|
||||
clearmsg();
|
||||
drawscreen();
|
||||
restoregamewindows();
|
||||
return o;
|
||||
}
|
||||
} else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing
|
||||
reason = E_SELNOTHING;
|
||||
// display game windows again
|
||||
needredraw = B_TRUE;
|
||||
clearmsg();
|
||||
drawscreen();
|
||||
restoregamewindows();
|
||||
return NULL;
|
||||
} else if (isdigit(ch) && count) {
|
||||
char temp[2];
|
||||
|
@ -3329,7 +3375,7 @@ void docomms(void) {
|
|||
char ch;
|
||||
flag_t *f;
|
||||
|
||||
where = askcoords("Talk to who?", TT_MONSTER);
|
||||
where = askcoords("Talk to who?", TT_MONSTER, player, UNLIMITED);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
|
@ -3370,7 +3416,7 @@ void docomms(void) {
|
|||
char lfname2[BUFLEN];
|
||||
case 'a':
|
||||
sprintf(buf, "Tell %s to attack who?",lfname);
|
||||
c = askcoords(buf, TT_MONSTER);
|
||||
c = askcoords(buf, TT_MONSTER, player, UNLIMITED);
|
||||
if (c && c->lf && cansee(player, c->lf)) {
|
||||
lf2 = c->lf;
|
||||
|
||||
|
@ -3445,7 +3491,7 @@ void docomms(void) {
|
|||
break;
|
||||
case 'y':
|
||||
msg("You shout at %s!", lfname);
|
||||
noise(where, player, "someone shouting!", NULL);
|
||||
noise(where, player, 3, "someone shouting!", NULL);
|
||||
break;
|
||||
}
|
||||
taketime(player, getactspeed(player));
|
||||
|
@ -3746,6 +3792,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
|
|||
}
|
||||
killobpile(op);
|
||||
|
||||
restoregamewindows();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4288,7 +4335,7 @@ void doexplain(char *question) {
|
|||
|
||||
while (!done) {
|
||||
//sprintf(buf, "Select glyph to explain (ESC to cancel):");
|
||||
where = askcoords(question, TT_NONE);
|
||||
where = askcoords(question, TT_NONE, player, UNLIMITED);
|
||||
if (!where) {
|
||||
clearmsg();
|
||||
break;
|
||||
|
@ -4668,7 +4715,7 @@ void doselguntarget(void) {
|
|||
getobname(gun, gunname, 1);
|
||||
|
||||
sprintf(buf, "Aim %s where?",gunname);
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
where = askcoords(buf, TT_MONSTER, player, UNLIMITED);
|
||||
if (where) {
|
||||
if (where->lf && haslof(player->cell, where, LOF_NEED, NULL)) {
|
||||
setguntarget(player, where->lf);
|
||||
|
@ -4740,7 +4787,7 @@ void dothrow(obpile_t *op) {
|
|||
|
||||
// ask where to throw it
|
||||
sprintf(buf2, "Throw %s where?",buf);
|
||||
where = askcoords(buf2, TT_MONSTER);
|
||||
where = askcoords(buf2, TT_MONSTER, player, UNLIMITED);
|
||||
|
||||
if (where) {
|
||||
cell_t *newwhere = NULL;
|
||||
|
@ -4913,20 +4960,18 @@ void drawlevelfor(lifeform_t *lf) {
|
|||
}
|
||||
for (y = 0; y < h; y++) {
|
||||
for (x = 0; x < w; x++) {
|
||||
cell = getcellat(map, x + viewx, y + viewy);
|
||||
if (cell) {
|
||||
glyph_t glyph,screenglyph;
|
||||
int needdraw = B_FALSE;
|
||||
cell = getcellat(map, x + viewx, y + viewy);
|
||||
|
||||
if (cell) {
|
||||
getcellglyph(&glyph, cell, player);
|
||||
//drawglyph(&glyph, x - viewx, y - viewy);
|
||||
} else {
|
||||
glyph.ch = ' ';
|
||||
glyph.colour = C_GREY;
|
||||
}
|
||||
|
||||
// only draw if screen char/colour is different
|
||||
/*
|
||||
if (cell == player->cell) {
|
||||
dblog("test");
|
||||
}
|
||||
*/
|
||||
screenglyph.ch = mvwinch(gamewin, y, x) & A_CHARTEXT;
|
||||
if (screenglyph.ch != glyph.ch) {
|
||||
needdraw = B_TRUE;
|
||||
|
@ -4948,7 +4993,6 @@ void drawlevelfor(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db) {
|
||||
dblog("last x,y checked was %d,%d",x+viewx,y+viewy);
|
||||
}
|
||||
|
@ -7637,6 +7681,10 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s %s missing one eye.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
if (hasjob(lf, J_DRUID)) {
|
||||
mvwprintw(mainwin, y, 0, "%s spells are boosted by nearby plants.", isplayer(lf) ? "Your" : "Its");
|
||||
y++;
|
||||
}
|
||||
|
||||
// flags which aren't really intrinsics
|
||||
if (lfhasflag(lf, F_VEGETARIAN)) {
|
||||
|
@ -8092,7 +8140,11 @@ void tombstone(lifeform_t *lf) {
|
|||
centre(mainwin, y, "R.I.P."); y++;
|
||||
//printf("%s\n",lf->name);
|
||||
centre(mainwin, y, "%s (%ld points)",pname, calcscore(lf)); y++;
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
centre(mainwin, y, "Died in the forest.");
|
||||
} else {
|
||||
centre(mainwin, y, "Died on level %d of the dungeon.", lf->cell->map->depth); y++;
|
||||
}
|
||||
|
||||
p = strtok_r(lf->lastdam,"^", &dummy);
|
||||
if (p) {
|
||||
|
|
4
io.h
4
io.h
|
@ -5,10 +5,12 @@ void addheading(prompt_t *p, char *text);
|
|||
void addmsghist(char *text);
|
||||
void addpromptq(prompt_t *p, char *q);
|
||||
void anim(cell_t *src, cell_t *dst, char ch, int colour);
|
||||
void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char ch2, int colour);
|
||||
void animradial(cell_t *src, int radius, char ch, int colour);
|
||||
void animradialorth(cell_t *src, int radius, char ch, int colour);
|
||||
void animsky(cell_t *src, char ch, int colour);
|
||||
//void announceob(enum OBTYPE oid);
|
||||
void announcearrival(lifeform_t *lf, map_t *newmap);
|
||||
int announceflaggain(lifeform_t *lf, flag_t *f);
|
||||
int announceflagloss(lifeform_t *lf, flag_t *f);
|
||||
int announceobflaggain(object_t *o, flag_t *f);
|
||||
|
@ -18,7 +20,7 @@ object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, en
|
|||
object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...);
|
||||
int askobjectmulti(obpile_t *op, char *prompt, long opts);
|
||||
char askchar(char *prompt, char *validchars, char *def, int showchars);
|
||||
cell_t *askcoords(char *prompt, int targettype);
|
||||
cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange);
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||
void centre(WINDOW *win, int y, char *format, ... );
|
||||
int chartodir(char ch);
|
||||
|
|
9
lf.h
9
lf.h
|
@ -42,6 +42,7 @@ int countmoney(lifeform_t *lf);
|
|||
int countnearbyallies(lifeform_t *lf);
|
||||
int countnearbyhurtallies(lifeform_t *lf);
|
||||
void debug(lifeform_t *lf);
|
||||
int demandbribe(lifeform_t *lf);
|
||||
void die(lifeform_t *lf);
|
||||
void dumplev(void);
|
||||
void dumplf(void);
|
||||
|
@ -70,6 +71,7 @@ void gainmp(lifeform_t *lf, int amt);
|
|||
void gainxp(lifeform_t *lf, long amt);
|
||||
void genxplist(void);
|
||||
int getactspeed(lifeform_t *lf);
|
||||
void getadjallies(lifeform_t *lf, lifeform_t **adjally, int *nadjallies);
|
||||
enum ALLEGIENCE getallegiance(lifeform_t *lf);
|
||||
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
|
||||
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||
|
@ -103,6 +105,7 @@ job_t *getjob(lifeform_t *lf);
|
|||
int getlastdir(lifeform_t *lf);
|
||||
int getlfaccuracy(lifeform_t *lf, object_t *wep);
|
||||
enum LFCONDITION getlfcondition(lifeform_t *lf);
|
||||
int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
char *getlfconditionname(enum LFCONDITION cond);
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||
|
@ -140,9 +143,10 @@ char *getpoisonname(enum POISONTYPE ptype);
|
|||
int getraceclass(lifeform_t *lf);
|
||||
int getracerarity(map_t *map, enum RACE rid);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
//int getrandommonlevel(int depth);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
race_t *getrandomrace(map_t *map, int forcedepth);
|
||||
race_t *getreallyrandomrace(void);
|
||||
enum SKILL getrandomskill(void);
|
||||
object_t *getrestob(lifeform_t *lf);
|
||||
enum SKILLLEVEL getskill(lifeform_t *lf, enum SKILL id);
|
||||
char *getspeedname(int speed, char *buf);
|
||||
|
@ -230,7 +234,7 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
|||
void modhunger(lifeform_t *lf, int amt);
|
||||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
int needstorest(lifeform_t *lf, char *validchars);
|
||||
void noise(cell_t *c, lifeform_t *noisemaker, char *text, char *seetext);
|
||||
int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seetext);
|
||||
void outfitlf(lifeform_t *lf);
|
||||
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
|
||||
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat);
|
||||
|
@ -250,6 +254,7 @@ int rolliq(enum IQBRACKET bracket);
|
|||
int rollstr(enum STRBRACKET bracket);
|
||||
int rollstat(lifeform_t *lf, enum ATTRIB attr);
|
||||
int safetorest(lifeform_t *lf);
|
||||
int say(lifeform_t *lf, char *text, int volume);
|
||||
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus);
|
||||
int setammo(lifeform_t *lf, object_t *o);
|
||||
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
||||
|
|
359
log.txt
359
log.txt
|
@ -4,3 +4,362 @@
|
|||
====== NEW LOGFILE ====
|
||||
givejob() starting.
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 175 (kobold) spending 20 time
|
||||
|
||||
lfid 180 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
lfid 181 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 175 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
lfid 180 (kobold) spending 20 time
|
||||
|
||||
fireat(): dam = throwdam(3) * speed(2)/2 = 3
|
||||
lfid 181 (kobold) spending 20 time
|
||||
|
||||
fireat(): dam = throwdam(2) * speed(3)/2 = 2
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 195 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 175 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
lfid 178 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
lfid 180 (kobold) spending 20 time
|
||||
|
||||
fireat(): dam = throwdam(3) * speed(2)/2 = 3
|
||||
xxx
|
||||
lfid 181 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 195 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 175 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
lfid 178 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 195 (kobold) spending 15 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
lfid 170 (giant rat) spending 15 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 178 (kobold) spending 15 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 167 (xat) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 40 time
|
||||
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 198 (human) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
lfid 175 (kobold) spending 20 time
|
||||
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
xxx
|
||||
|
|
427
map.c
427
map.c
|
@ -15,6 +15,7 @@
|
|||
|
||||
extern map_t *firstmap,*lastmap;
|
||||
extern celltype_t *firstcelltype, *lastcelltype;
|
||||
extern objecttype_t *objecttype,*lastobjecttype;
|
||||
extern int viewx,viewy,vieww,viewh;
|
||||
extern lifeform_t *player;
|
||||
|
||||
|
@ -46,6 +47,8 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell->origlittimer = 0;
|
||||
cell->writing = NULL;
|
||||
cell->known = B_FALSE;
|
||||
cell->knownglyph.ch = ' ';
|
||||
cell->knownglyph.colour = C_GREY;
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
@ -102,6 +105,7 @@ map_t *addmap(void) {
|
|||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
a->nextmap[i] = -1;
|
||||
}
|
||||
a->flags = addflagpile(NULL, NULL);
|
||||
a->beingcreated = B_TRUE;
|
||||
return a;
|
||||
}
|
||||
|
@ -132,23 +136,23 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
if (db) dblog("adding rand lf %s to cell %d,%d",r->name,c->x,c->y);
|
||||
|
||||
if (r) {
|
||||
//lf = addlf(c, r->id, getrandommonlevel(c->map->depth));
|
||||
lf = addlf(c, r->id, 1);
|
||||
lf = addlf(c, r->id, getrandommonlevel(r, c->map));
|
||||
if (lf) {
|
||||
flag_t *f;
|
||||
|
||||
lf->born = B_FALSE;
|
||||
if (jobok) {
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
// has a job?
|
||||
f = hasflag(lf->flags, F_STARTJOB);
|
||||
if (f) {
|
||||
if (f->id == F_STARTJOB) {
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
givejob(lf, f->val[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if (lf->cell->map->beingcreated) {
|
||||
if (autogen) {
|
||||
// sometimes start off asleep in new maps
|
||||
if (!lfhasflag(lf, F_DEAF) && cansleep(lf)) {
|
||||
|
@ -188,12 +192,23 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
// did we find one?
|
||||
if (!adjcell) break;
|
||||
|
||||
newlf = addlf(adjcell, r->id, 1);
|
||||
newlf = addlf(c, r->id, getrandommonlevel(r, adjcell->map));
|
||||
if (!newlf) {
|
||||
break;
|
||||
}
|
||||
newlf->born = B_FALSE;
|
||||
if (lfhasflag(lf, F_ASLEEP)) addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// initial monster shoudl remember its minions
|
||||
addflag(lf->flags, F_MINION, newlf->id, NA, NA, NULL);
|
||||
|
||||
// if master is asleep, minions will also be asleep
|
||||
if (lfhasflag(lf, F_ASLEEP)) {
|
||||
addflag(newlf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// minions never have certain flags.
|
||||
killflagsofid(newlf->flags, F_DEMANDSBRIBE);
|
||||
|
||||
newlf->born = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +235,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
newr = findracebyname(f->text);
|
||||
if (!newr) break;
|
||||
|
||||
newlf = addlf(adjcell, newr->id, 1);
|
||||
newlf = addlf(adjcell, newr->id, getrandommonlevel(newr, adjcell->map));
|
||||
if (!newlf) break;
|
||||
|
||||
newlf->born = B_FALSE;
|
||||
|
@ -250,6 +265,31 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// humanoids on dark levels which can't see will probably have some
|
||||
// kind of light producing device
|
||||
if (!islit(c) && !hasflag(lf->flags, F_SEEINDARK) && !hasflag(lf->flags, F_TREMORSENSE)) {
|
||||
if (lfhasflag(lf, F_HUMANOID)) {
|
||||
objecttype_t *ot, *poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
// get a random light-producing object
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if (hasflag(ot->flags, F_OPERABLE) &&
|
||||
hasflagval(ot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL)) {
|
||||
poss[nposs++] = ot;
|
||||
}
|
||||
}
|
||||
if (nposs > 0) {
|
||||
ot = poss[rnd(0,nposs-1)];
|
||||
} else {
|
||||
ot = NULL;
|
||||
}
|
||||
if (ot) {
|
||||
addob(lf->pack, ot->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lf->born = B_TRUE;
|
||||
} // end if lf
|
||||
}
|
||||
|
@ -257,30 +297,38 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
return lf;
|
||||
}
|
||||
|
||||
void addrandomob(cell_t *c) {
|
||||
object_t *addrandomob(cell_t *c) {
|
||||
char buf[BUFLEN];
|
||||
int db = B_FALSE;
|
||||
object_t *o = NULL;
|
||||
|
||||
if (c->type->solid) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (getrandomob(c->map, buf)) {
|
||||
if (db) dblog("adding rand obj %s to cell %d,%d",buf,c->x,c->y);
|
||||
addob(c->obpile, buf);
|
||||
o = addob(c->obpile, buf);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
void addrandomthing(cell_t *c, int obchance) {
|
||||
int addrandomthing(cell_t *c, int obchance) {
|
||||
int rv = TT_NONE;
|
||||
// if there's already someone there,
|
||||
// then add an object.
|
||||
if (c->lf || (rnd(1,100) <= obchance)) {
|
||||
// object
|
||||
addrandomob(c);
|
||||
if (addrandomob(c)) {
|
||||
rv = TT_OBJECT;
|
||||
}
|
||||
} else {
|
||||
// monster
|
||||
addmonster(c, R_RANDOM, B_TRUE, 1, B_TRUE);
|
||||
if (addmonster(c, R_RANDOM, B_TRUE, 1, B_TRUE)) {
|
||||
rv = TT_MONSTER;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int cellhaslos(cell_t *c1, cell_t *dest) {
|
||||
|
@ -493,28 +541,14 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
|||
break;
|
||||
default:
|
||||
if (c->known) {
|
||||
//drawunviscell(cell, x-viewx, y-viewy);
|
||||
object_t *o;
|
||||
|
||||
// copy from cell
|
||||
/*
|
||||
*g = c->type->glyph;
|
||||
*/
|
||||
*g = c->knownglyph;
|
||||
if (g->ch == '.') {
|
||||
g->ch = ' ';
|
||||
}
|
||||
|
||||
// show staircases...
|
||||
o = hasobwithflag(c->obpile, F_CLIMBABLE);
|
||||
if (o) {
|
||||
*g = *(getglyph(o));
|
||||
}
|
||||
// show dungeon features
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (o->type->obclass->id == OC_DFEATURE) {
|
||||
if (!issecretdoor(o)) {
|
||||
*g = *(getglyph(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -543,18 +577,58 @@ enum CELLTYPE getwallcelltype(enum HABITAT hab) {
|
|||
return CT_WALL;
|
||||
}
|
||||
|
||||
flag_t *getmapcoords(map_t *m, int *x, int *y) {
|
||||
flag_t *f;
|
||||
f = hasflag(m->flags, F_MAPCOORDS);
|
||||
if (f) {
|
||||
if (x) *x = f->val[0];
|
||||
if (y) *y = f->val[1];
|
||||
return f;
|
||||
}
|
||||
if (x) *x = -999;
|
||||
if (y) *y = -999;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int getmapdifficulty(map_t *m) {
|
||||
int diff = 1;
|
||||
if (m) {
|
||||
if (m->region == RG_WORLDMAP) {
|
||||
int x,y;
|
||||
// depth is distance from 0,0
|
||||
getmapcoords(m, &x, &y);
|
||||
diff = (abs(x) + abs(y))+1;
|
||||
} else {
|
||||
diff = m->depth;
|
||||
}
|
||||
} else {
|
||||
diff = rnd(1,MAXDEPTH);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
object_t *gettopobject(cell_t *where) {
|
||||
object_t *o;
|
||||
object_t *o,*oo = NULL;
|
||||
enum LFSIZE largest = SZ_MINI;
|
||||
int c;
|
||||
// draw impassable objects first...
|
||||
o = hasobwithflag(where->obpile, F_IMPASSABLE);
|
||||
if (o) {
|
||||
|
||||
// get largest known impassable object first
|
||||
for (o = where->obpile->first ; o ; o = o->next) {
|
||||
flag_t *f;
|
||||
// ignore hidden traps, but not secret doors
|
||||
if (hasflag(o->flags, F_SECRET) && !isdoor(o, NULL)) {
|
||||
} else {
|
||||
return o;
|
||||
f = hasflag(o->flags, F_IMPASSABLE);
|
||||
if (f && (f->val[0] > largest)) {
|
||||
largest = f->val[0];
|
||||
oo = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oo) {
|
||||
return oo;
|
||||
}
|
||||
|
||||
// otherwise draw highest object in sort order
|
||||
c = 0;
|
||||
|
@ -1074,14 +1148,26 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
if (db) dblog("--> Will add %d objects to room %d (of %d)",numobs,i,numrooms);
|
||||
for (n = 0 ; n < numobs; n++) {
|
||||
int ntries = 0;
|
||||
int nmonsters = 0;
|
||||
cell_t *c;
|
||||
done = B_FALSE;
|
||||
while (!done) {
|
||||
c = getrandomroomcell(map, i);
|
||||
// if nothing there
|
||||
if (c && isempty(c) && !countobs(c->obpile)) {
|
||||
int obchance;
|
||||
|
||||
// limit # monster per room to depth+1
|
||||
if (nmonsters >= (depth+1)) {
|
||||
obchance = 100;
|
||||
} else {
|
||||
// slightly more chance of objects in rooms
|
||||
addrandomthing(c,60);
|
||||
obchance = getobchance(map->habitat) + 10;
|
||||
}
|
||||
|
||||
if (addrandomthing(c,obchance) == TT_MONSTER) {
|
||||
nmonsters++;
|
||||
}
|
||||
done = B_TRUE;
|
||||
} else {
|
||||
ntries++;
|
||||
|
@ -1106,6 +1192,8 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
int ntrees;
|
||||
int density;
|
||||
cell_t *c;
|
||||
char buf[BUFLEN];
|
||||
int nclearings;
|
||||
//object_t *o;
|
||||
|
||||
// what kind of cells will 'empty' ones be?
|
||||
|
@ -1118,7 +1206,6 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// determine density
|
||||
density = rnd(40,70);
|
||||
// add a plant to density percent of cells
|
||||
|
@ -1128,7 +1215,44 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
while (c->lf) {
|
||||
c = getrandomcell(map);
|
||||
}
|
||||
addob(c->obpile, "tree");
|
||||
switch (rnd(0,1)) {
|
||||
default: case 0: strcpy(buf, "tree"); break;
|
||||
case 1: strcpy(buf, "shrub"); break;
|
||||
}
|
||||
addob(c->obpile, buf);
|
||||
}
|
||||
|
||||
// clearings
|
||||
nclearings = rnd(0,5);
|
||||
for (i = 0; i < nclearings; i++) {
|
||||
int w;
|
||||
c = getrandomcell(map);
|
||||
w = rnd(MINCLEARINGRADIUS,MAXCLEARINGRADIUS);
|
||||
for (y = c->y - w; y <= c->y + w; y++) {
|
||||
for (x = c->x - w; x <= c->x + w; x++) {
|
||||
cell_t *newc;
|
||||
int dist = 999;
|
||||
newc = getcellat(map, x, y);
|
||||
|
||||
|
||||
if (newc) {
|
||||
dist = getcelldistorth(newc, c);
|
||||
if (dist <= w) {
|
||||
int dirtchance;
|
||||
// kill all obs here
|
||||
while (newc->obpile->first) killob(newc->obpile->first);
|
||||
|
||||
// change it into dirt.
|
||||
// ie. at centre (dist=0) dirt chance is 100%
|
||||
// ie. at max distance, dirt chance is 30%
|
||||
dirtchance = 100 - (((float)dist / (float)w) * 70);
|
||||
if (rnd(1,100) <= dirtchance) {
|
||||
setcelltype(newc, CT_DIRT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add monsters
|
||||
|
@ -1143,8 +1267,10 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
*/
|
||||
void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir) {
|
||||
lifeform_t *lf;
|
||||
map_t *m;
|
||||
char buf[BUFLEN];
|
||||
int i,x,y;
|
||||
int firstworldmap = B_FALSE;
|
||||
// determine habitat?
|
||||
if (habitat == AUTO) {
|
||||
if (depth > 0) {
|
||||
|
@ -1154,6 +1280,21 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
}
|
||||
}
|
||||
|
||||
if (region == RG_WORLDMAP) {
|
||||
int found = B_FALSE;
|
||||
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
if ((m != map) && (m->region == RG_WORLDMAP)) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
firstworldmap = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
map->beingcreated = B_TRUE;
|
||||
|
||||
map->depth = depth;
|
||||
|
@ -1169,7 +1310,7 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
map->nextmap[i] = -1;
|
||||
}
|
||||
|
||||
// look for adjacent maps in this region
|
||||
// look for adjacent maps above/below this one
|
||||
for (i = depth-1; i <= depth+1; i += 2) {
|
||||
map_t *othermap;
|
||||
othermap = findregionmap(map->region, i);
|
||||
|
@ -1204,6 +1345,62 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
map->seed = rand() % 65535;
|
||||
srand(map->seed);
|
||||
|
||||
// set map coords
|
||||
if (firstworldmap) {
|
||||
addflag(map->flags, F_MAPCOORDS, 0, 0, NA, NULL);
|
||||
} else {
|
||||
// set mapcoords if not already done.
|
||||
if (!hasflag(map->flags, F_MAPCOORDS)) {
|
||||
x = -999;
|
||||
y = -999;
|
||||
if (parentmap) {
|
||||
getmapcoords(parentmap, &x, &y);
|
||||
assert((x != -999) && (y != -999));
|
||||
switch (exitdir) {
|
||||
case D_N:
|
||||
y--;
|
||||
break;
|
||||
case D_E:
|
||||
x++;
|
||||
break;
|
||||
case D_S:
|
||||
y++;
|
||||
break;
|
||||
case D_W:
|
||||
x--;
|
||||
break;
|
||||
default:
|
||||
// no change
|
||||
break;
|
||||
}
|
||||
addflag(map->flags, F_MAPCOORDS, x, y, NA, NULL);
|
||||
} else {
|
||||
// set it based on something else...
|
||||
if (region == RG_FIRSTDUNGEON) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
// find another map of this region and set it.
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
if ((m != map) && (m->region == region)) {
|
||||
flag_t *ff;
|
||||
ff = hasflag(m->flags, F_MAPCOORDS);
|
||||
if (ff) {
|
||||
x = ff->val[0];
|
||||
y = ff->val[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
assert(x != -999);
|
||||
assert(y != -999);
|
||||
addflag(map->flags, F_MAPCOORDS, x, y, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// build it...
|
||||
if (habitat == H_DUNGEON) {
|
||||
createdungeon(map, depth, parentmap, exitdir);
|
||||
|
@ -1216,18 +1413,11 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
addhomeobs(lf);
|
||||
}
|
||||
|
||||
// if this is the first world map, add stairs to the dungeon
|
||||
if (region == RG_WORLDMAP) {
|
||||
map_t *m;
|
||||
int found = B_FALSE;
|
||||
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
if ((m != map) && (m->region == 0)) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
|
||||
// if this is the first world map, add stairs to the dungeon
|
||||
if (firstworldmap) {
|
||||
// ie. this is the first forest map
|
||||
map_t *firstdungeon;
|
||||
|
||||
// link to first dungeon map
|
||||
|
@ -1247,7 +1437,6 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
linkstairs(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// join up any unlinked staircases
|
||||
for (y = 0; y < map->h; y++) {
|
||||
|
@ -1275,6 +1464,29 @@ void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap,
|
|||
}
|
||||
}
|
||||
|
||||
// look for adjacent maps
|
||||
getmapcoords(map, &x, &y);
|
||||
assert(x != -999);
|
||||
assert(y != -999);
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
if ((m != map) && (m->region == map->region)) {
|
||||
int thisx,thisy;
|
||||
getmapcoords(m, &thisx, &thisy);
|
||||
if (map->nextmap[D_N] == -1) {
|
||||
if (thisy == (y - 1)) map->nextmap[D_N] = m->id;
|
||||
}
|
||||
if (map->nextmap[D_E] == -1) {
|
||||
if (thisx == (x + 1)) map->nextmap[D_E] = m->id;
|
||||
}
|
||||
if (map->nextmap[D_S] == -1) {
|
||||
if (thisy == (y + 1)) map->nextmap[D_S] = m->id;
|
||||
}
|
||||
if (map->nextmap[D_W] == -1) {
|
||||
if (thisx == (x - 1)) map->nextmap[D_W] = m->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map->beingcreated = B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1522,7 +1734,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
msg("You see %s explosion!", (range > 0) ? "a huge" : "an");
|
||||
}
|
||||
} else {
|
||||
noise(c, NULL, "an explosion!", NULL);
|
||||
noise(c, NULL, (range > 0) ? 6 : 5, "an explosion!", NULL);
|
||||
}
|
||||
|
||||
for (y = c->y - range ; y <= c->y + range ; y++) {
|
||||
|
@ -1615,6 +1827,63 @@ map_t *findmapofdepth(int depth) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
||||
int x,y,xinc,yinc;
|
||||
|
||||
cell_t *selection = NULL;
|
||||
cell_t *bestcell = NULL;
|
||||
int closest = 999;
|
||||
switch (side) {
|
||||
case D_N:
|
||||
x = 0;
|
||||
y = 0;
|
||||
xinc = 1;
|
||||
yinc = 0;
|
||||
bestcell = getcellat(m, lf->cell->x, 0);
|
||||
break;
|
||||
case D_E:
|
||||
x = m->w-1;
|
||||
y = 0;
|
||||
xinc = 0;
|
||||
yinc = 1;
|
||||
bestcell = getcellat(m, m->w - 1, lf->cell->y);
|
||||
break;
|
||||
case D_S:
|
||||
x = 0;
|
||||
y = m->h - 1;
|
||||
xinc = 1;
|
||||
yinc = 0;
|
||||
bestcell = getcellat(m, lf->cell->x, m->h - 1);
|
||||
break;
|
||||
case D_W:
|
||||
x = 0;
|
||||
y = 0;
|
||||
xinc = 0;
|
||||
yinc = 1;
|
||||
bestcell = getcellat(m, 0, lf->cell->y);
|
||||
break;
|
||||
}
|
||||
|
||||
for (;(x < m->w) && (y < m->h);) {
|
||||
cell_t *c;
|
||||
// check cell
|
||||
c = getcellat(m, x, y);
|
||||
if (c && cellwalkable(lf, c, NULL)) {
|
||||
int dist;
|
||||
dist = getcelldist(c, bestcell);
|
||||
if (dist < closest) {
|
||||
selection = c;
|
||||
closest = dist;
|
||||
}
|
||||
}
|
||||
// go to next one
|
||||
x += xinc;
|
||||
y += yinc;
|
||||
}
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
// find the object with id 'id' in map 'm'
|
||||
object_t *findobidinmap(map_t *m, long id) {
|
||||
cell_t *c;
|
||||
|
@ -1844,7 +2113,7 @@ int getthingchance(int habitat) {
|
|||
case H_DUNGEON:
|
||||
return 3;
|
||||
case H_FOREST:
|
||||
return 5;
|
||||
return 3;
|
||||
}
|
||||
// default of no objects
|
||||
return 0;
|
||||
|
@ -2503,6 +2772,52 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) {
|
|||
}
|
||||
}
|
||||
|
||||
void setcellknown(cell_t *cell, int forcelev) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
|
||||
if (forcelev > 0) {
|
||||
slev = forcelev;
|
||||
} else {
|
||||
slev = getskill(player, SK_CARTOGRAPHY);
|
||||
}
|
||||
|
||||
// photographic memory counts as novice level
|
||||
if ((slev == PR_INEPT) && lfhasflag(player, F_PHOTOMEM)) {
|
||||
slev = PR_NOVICE;
|
||||
}
|
||||
|
||||
|
||||
if (slev >= PR_NOVICE) {
|
||||
cell->known = B_TRUE;
|
||||
// default to remembering the cell's glyph
|
||||
cell->knownglyph = cell->type->glyph;
|
||||
// high cartography skill lets us remember certain objects...
|
||||
if (slev >= PR_EXPERT) {
|
||||
o = gettopobject(cell);
|
||||
if (o) {
|
||||
cell->knownglyph = *(getglyph(o));
|
||||
}
|
||||
}
|
||||
if (slev >= PR_ADEPT) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (o->type->obclass->id == OC_DFEATURE) {
|
||||
if (!issecretdoor(o)) {
|
||||
cell->knownglyph = *(getglyph(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slev >= PR_BEGINNER) {
|
||||
o = hasobwithflag(cell->obpile, F_CLIMBABLE);
|
||||
if (o) {
|
||||
cell->knownglyph = *(getglyph(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
//getcellglyph(&(cell->knownglyph), cell, player);
|
||||
}
|
||||
|
||||
void setcelltype(cell_t *cell, int id) {
|
||||
assert(cell);
|
||||
cell->type = findcelltype(id);
|
||||
|
@ -2528,9 +2843,7 @@ void updateknowncells(void) {
|
|||
if (cell) {
|
||||
//if ((player->cell == cell) || haslos(player, cell)) {
|
||||
if (haslos(player, cell)) {
|
||||
if (!cell->known) {
|
||||
cell->known = B_TRUE;
|
||||
}
|
||||
setcellknown(cell, B_FALSE);
|
||||
if (cell->lf && lfhasflag(cell->lf, F_UNDEAD)) {
|
||||
seenundead = B_TRUE;
|
||||
}
|
||||
|
|
8
map.h
8
map.h
|
@ -4,8 +4,8 @@ cell_t *addcell(map_t *map, int x, int y);
|
|||
void addhomeobs(lifeform_t *lf);
|
||||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen);
|
||||
void addrandomob(cell_t *c);
|
||||
void addrandomthing(cell_t *c, int obchance);
|
||||
object_t *addrandomob(cell_t *c);
|
||||
int addrandomthing(cell_t *c, int obchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
cell_t *getcellat(map_t *map, int x, int y);
|
||||
int getcelldist(cell_t *src, cell_t *dst);
|
||||
|
@ -13,6 +13,8 @@ int getcelldistorth(cell_t *src, cell_t *dst);
|
|||
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
||||
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
||||
enum CELLTYPE getwallcelltype(enum HABITAT hab);
|
||||
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
||||
int getmapdifficulty(map_t *m);
|
||||
object_t *gettopobject(cell_t *where);
|
||||
void calclight(map_t *map);
|
||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
||||
|
@ -31,6 +33,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
celltype_t *findcelltype(enum CELLTYPE cid);
|
||||
map_t *findmap(int mid);
|
||||
map_t *findmapofdepth(int depth);
|
||||
cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf);
|
||||
object_t *findobidinmap(map_t *m, long id);
|
||||
cell_t *findobinmap(map_t *m, enum OBCLASS oid);
|
||||
map_t *findregionmap(int region, int depth);
|
||||
|
@ -68,5 +71,6 @@ int linkstairs(object_t *o);
|
|||
void makedoor(cell_t *cell);
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||
void setcellknown(cell_t *cell, int forcelev);
|
||||
void setcelltype(cell_t *cell, int id);
|
||||
void updateknowncells(void);
|
||||
|
|
128
move.c
128
move.c
|
@ -1,4 +1,5 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -24,7 +25,7 @@ extern enum GAMEMODE gamemode;
|
|||
extern enum ERROR reason;
|
||||
extern void *rdata;
|
||||
|
||||
extern WINDOW *gamewin;
|
||||
extern WINDOW *gamewin, *msgwin;
|
||||
|
||||
int canandwillmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -544,8 +545,15 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
if (reason != E_OK) {
|
||||
// failed to move
|
||||
switch (reason) {
|
||||
case E_WALLINWAY:
|
||||
case E_OFFMAP:
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
if (!walkoffmap(lf, dir, B_FALSE)) {
|
||||
// successful
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case E_WALLINWAY:
|
||||
if (seen) msg("%s slam%s into a wall!",lfname,isplayer(lf) ? "" : "s");
|
||||
losehp(lf, rnd(1,6), DT_BASH, pusher, "slamming into a wall");
|
||||
// stop moving
|
||||
|
@ -830,6 +838,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// haslos() code to handle looking along walls
|
||||
// instead.
|
||||
// if you walked into a new fully lit room, reveal it
|
||||
|
||||
if (getskill(lf, SK_CARTOGRAPHY) >= PR_NOVICE) {
|
||||
if ((postroom > 0) && (postroom != preroom)) {
|
||||
cell_t *c[MAX_MAPW*MAX_MAPH];
|
||||
int ncells;
|
||||
|
@ -849,12 +859,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
if (alllit && !allknown) {
|
||||
// make the all known
|
||||
for (i = 0; i < ncells; i++) {
|
||||
c[i]->known = B_TRUE;
|
||||
setcellknown(c[i], B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// does anyone else see you?
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
|
@ -1116,8 +1127,15 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
} else {
|
||||
if (lf) {
|
||||
flag_t *sf;
|
||||
taketime(lf, getactspeed(lf));
|
||||
touch(lf, o);
|
||||
|
||||
// stop sprinting
|
||||
sf = lfhasflag(lf, F_SPRINTING);
|
||||
if (sf && sf->val[0]) {
|
||||
killflag(sf);
|
||||
}
|
||||
}
|
||||
|
||||
// locked?
|
||||
|
@ -1180,7 +1198,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
// checking if we have LOS to the lifeform making
|
||||
// sound, but in this case it's the door making
|
||||
// the sound, not the lf.
|
||||
noise(where, NULL, "a door opening.", NULL);
|
||||
noise(where, NULL, 2, "a door opening.", NULL);
|
||||
}
|
||||
if (player && haslos(player, where)) {
|
||||
needredraw = B_TRUE;
|
||||
|
@ -1657,11 +1675,9 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
reason = errcode;
|
||||
switch (errcode) {
|
||||
case E_OFFMAP:
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't go any further in that direction.");
|
||||
} else if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
msg("%s %ss around randomly.", buf, getmoveverb(lf));
|
||||
if (lf->cell->map->region == RG_WORLDMAP) {
|
||||
// we are allowed to walk off the edge
|
||||
walkoffmap(lf, dir, B_TRUE);
|
||||
}
|
||||
break;
|
||||
case E_WALLINWAY:
|
||||
|
@ -1679,7 +1695,8 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||
// we now know there is a wall there.
|
||||
cell->known = B_TRUE;
|
||||
setcellknown(cell, B_FALSE);
|
||||
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
}
|
||||
} else {
|
||||
|
@ -1701,7 +1718,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
opendoor(lf, inway);
|
||||
} else {
|
||||
msg("Ouch! You %s into a door.", getmoveverb(lf));
|
||||
cell->known = B_TRUE;
|
||||
setcellknown(cell, B_FALSE);
|
||||
sprintf(buf, "%sing into a door", getmoveverb(lf));
|
||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||
if (onpurpose) taketime(lf, getmovespeed(lf));
|
||||
|
@ -1829,6 +1846,95 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
||||
map_t *adjmap = NULL, *thismap;
|
||||
cell_t *dst = NULL;
|
||||
lifeform_t *adjally[8];
|
||||
int nadjallies = 0;
|
||||
int n;
|
||||
|
||||
// announce
|
||||
if (isplayer(lf)) {
|
||||
char dirname[BUFLEN];
|
||||
curs_set(1);
|
||||
strcpy(dirname, getdirname(dir));
|
||||
dirname[0] = tolower(dirname[0]);
|
||||
msg("You %s to the %s...", getmoveverb(lf), getdirname(dir));
|
||||
// move cursor to msgwindow while we create the new level...
|
||||
wrefresh(msgwin);
|
||||
} else if (cansee(player, lf)) {
|
||||
char dirname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
curs_set(1);
|
||||
strcpy(dirname, getdirname(dir));
|
||||
dirname[0] = tolower(dirname[0]);
|
||||
msg("%s %s to the %s...", lfname, getmoveverbother(lf), getdirname(dir));
|
||||
wrefresh(msgwin);
|
||||
}
|
||||
|
||||
// is there a map in that direction ?
|
||||
thismap = lf->cell->map;
|
||||
adjmap = findmap(lf->cell->map->nextmap[dir]);
|
||||
if (!adjmap) {
|
||||
// make one
|
||||
adjmap = addmap();
|
||||
createmap(adjmap, thismap->depth, thismap->region, AUTO, thismap, dir);
|
||||
}
|
||||
|
||||
if (adjmap) {
|
||||
// find an empty cell in the next map
|
||||
dst = findmapentrypoint(adjmap, diropposite(dir), lf);
|
||||
}
|
||||
|
||||
if (!dst) {
|
||||
// failed
|
||||
if (isplayer(lf)) {
|
||||
msg("Your path seems to be blocked.");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (onpurpose) {
|
||||
// get list of adjacent allies
|
||||
if (isplayer(lf)) {
|
||||
getadjallies(lf, adjally, &nadjallies);
|
||||
}
|
||||
}
|
||||
|
||||
// announce
|
||||
announcearrival(lf, dst->map);
|
||||
|
||||
// move there
|
||||
moveto(lf, dst, onpurpose, B_TRUE);
|
||||
if (onpurpose) {
|
||||
taketime(lf, getmovespeed(lf));
|
||||
}
|
||||
|
||||
// move adjacent allies
|
||||
if (onpurpose) {
|
||||
for (n = 0; n < nadjallies; n++) {
|
||||
cell_t *c;
|
||||
c = getrandomadjcell(dst, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
if (!initiatemove(adjally[n], NULL, NULL)) {
|
||||
movelf(adjally[n], c);
|
||||
taketime(adjally[n], getmovespeed(adjally[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
statdirty = B_TRUE;
|
||||
needredraw = B_TRUE;
|
||||
calclight(player->cell->map);
|
||||
precalclos(lf);
|
||||
drawscreen();
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
||||
cell_t *cell;
|
||||
|
|
1
move.h
1
move.h
|
@ -25,4 +25,5 @@ void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int onpurpose);
|
|||
int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke);
|
||||
int trymove(lifeform_t *lf, int dir, int onpurpose);
|
||||
int tryrun(lifeform_t *lf, int dir);
|
||||
int walkoffmap(lifeform_t *lf, int dir, int onpurpose);
|
||||
int willmove(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
|
|
14
nexus.c
14
nexus.c
|
@ -264,7 +264,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
// start game - this will cause debug messages to now
|
||||
// go to the log file instead of stdout.
|
||||
gamemode = GM_GAMESTARTED;
|
||||
timeleft = 0; // reset game timer
|
||||
|
||||
// calculate initial light
|
||||
|
@ -287,6 +286,13 @@ int main(int argc, char **argv) {
|
|||
needredraw = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
|
||||
// start game
|
||||
gamemode = GM_GAMESTARTED;
|
||||
|
||||
// redo light and player los
|
||||
calclight(player->cell->map);
|
||||
precalclos(player);
|
||||
|
||||
// show level
|
||||
drawscreen();
|
||||
|
||||
|
@ -541,7 +547,8 @@ void donextturn(map_t *map) {
|
|||
} else {
|
||||
if (isplayer(who)) {
|
||||
if (++who->turnsskipped >= 10) {
|
||||
msg("Time passes...");
|
||||
//msg("Time passes...");
|
||||
msg(".");
|
||||
who->turnsskipped = 0;
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +564,8 @@ void donextturn(map_t *map) {
|
|||
if (isimmobile(who)) {
|
||||
if (isplayer(who)) {
|
||||
if (++who->turnsskipped >= 10) {
|
||||
msg("Time passes...");
|
||||
//msg("Time passes...");
|
||||
msg(".");
|
||||
who->turnsskipped = 0;
|
||||
}
|
||||
}
|
||||
|
|
277
objects.c
277
objects.c
|
@ -404,6 +404,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
obmod_t *wantom[MAXOBMODS];
|
||||
int nom = 0;
|
||||
int n;
|
||||
int bookcontents = -1;
|
||||
|
||||
|
||||
localname = strdup(name);
|
||||
|
@ -530,6 +531,28 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
|
||||
corpserace = findracebyname(racename);
|
||||
ot = findot(OT_HEAD);
|
||||
} else if (strstr(p, "spellbook of ")) {
|
||||
char *pp;
|
||||
pp = p + 13;
|
||||
if (*pp) {
|
||||
objecttype_t *spelltype = NULL;
|
||||
spelltype = findspelln(pp);
|
||||
if (spelltype) {
|
||||
bookcontents = spelltype->id;
|
||||
}
|
||||
}
|
||||
ot = findot(OT_SPELLBOOK);
|
||||
} else if (strstr(p, "manual of ")) {
|
||||
char *pp;
|
||||
pp = p + 10;
|
||||
if (*pp) {
|
||||
skill_t *sk;
|
||||
sk = findskillbyname(pp);
|
||||
if (sk) {
|
||||
bookcontents = sk->id;
|
||||
}
|
||||
}
|
||||
ot = findot(OT_MANUAL);
|
||||
} else {
|
||||
// make sure we can find the requested object type
|
||||
if (db) dblog("DB: Looking for object name '%s'", p );
|
||||
|
@ -564,7 +587,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
canstack = B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// special checks for unique objects
|
||||
if (hasflag(ot->flags, F_UNIQUE)) {
|
||||
// does this unique ob already exist?
|
||||
|
@ -579,6 +601,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
|
||||
if (db) dblog("DB: '%s' -> adding %d x %s",name, howmany, ot->name);
|
||||
|
||||
|
||||
for (i = 0; i < howmany; i++) {
|
||||
int added = B_FALSE;
|
||||
if (canstack) {
|
||||
|
@ -694,6 +717,52 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
}
|
||||
}
|
||||
|
||||
// fill in book types
|
||||
if (o && (o->type->obclass->id == OC_BOOK)) {
|
||||
hiddenname_t *hn,*selhn = NULL;
|
||||
int numhiddennames;
|
||||
int n,sel;
|
||||
if (bookcontents == -1) {
|
||||
if (o->type->id == OT_SPELLBOOK) {
|
||||
bookcontents = getrandomspell();
|
||||
while (!schoolappearsinbooks(getspellschool(bookcontents))) {
|
||||
bookcontents = getrandomspell();
|
||||
}
|
||||
} else { // ie. manual
|
||||
bookcontents = getrandomskill();
|
||||
}
|
||||
}
|
||||
|
||||
// link
|
||||
if (o->type->id == OT_SPELLBOOK) {
|
||||
addflag(o->flags, F_LINKSPELL, bookcontents, NA, NA, NULL);
|
||||
} else {
|
||||
addflag(o->flags, F_MANUALOF, bookcontents, NA, NA, NULL);
|
||||
}
|
||||
|
||||
|
||||
// count hidden names
|
||||
numhiddennames = 0;
|
||||
for (hn = firsthiddenname ; hn ; hn = hn->next) {
|
||||
if (hn->obclass == o->type->obclass->id) {
|
||||
numhiddennames++;
|
||||
}
|
||||
}
|
||||
// assign hidden name
|
||||
sel = rnd(0,numhiddennames-1);
|
||||
n = 0;
|
||||
for (hn = firsthiddenname ; hn ; hn = hn->next) {
|
||||
if (hn->obclass == o->type->obclass->id) {
|
||||
if (n == sel) {
|
||||
selhn = hn;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
addflag(o->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, selhn->text);
|
||||
}
|
||||
|
||||
|
||||
// other special changes we need to make based on what was
|
||||
// asked for
|
||||
|
@ -3134,6 +3203,28 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
strcpy(basename,gethiddenname(o));
|
||||
}
|
||||
|
||||
if (o->type->obclass->id == OC_BOOK) {
|
||||
if (!strcmp(basename, o->type->name)) {
|
||||
if (o->type->id == OT_SPELLBOOK) {
|
||||
f = hasflag(o->flags, F_LINKSPELL);
|
||||
if (f) {
|
||||
objecttype_t *st;
|
||||
st = findot(f->val[0]);
|
||||
strcat(basename, " of ");
|
||||
strcat(basename, st->name);
|
||||
}
|
||||
} else {
|
||||
f = hasflag(o->flags, F_MANUALOF);
|
||||
if (f) {
|
||||
skill_t *sk;
|
||||
sk = findskill(f->val[0]);
|
||||
strcat(basename, " of ");
|
||||
strcat(basename, sk->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!showall) {
|
||||
if ((gamemode == GM_GAMESTARTED) && adjustforblind && !haslos(player, where) ) {
|
||||
// override with obclass names
|
||||
|
@ -3600,10 +3691,8 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
|
||||
if (forcedepth != NA) {
|
||||
depth = forcedepth;
|
||||
} else if (map) {
|
||||
depth = map->depth;
|
||||
} else {
|
||||
depth = rnd(1,MAXDEPTH);
|
||||
depth = getmapdifficulty(map);
|
||||
}
|
||||
|
||||
getrarity(depth, &raritymin, &raritymax, RARITYVARIANCEOB, B_TRUE);
|
||||
|
@ -3811,7 +3900,8 @@ char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf) {
|
|||
}
|
||||
|
||||
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod) {
|
||||
return real_getrandomob(map, buf, RO_OBCLASS, cid, map->depth + depthmod);
|
||||
//return real_getrandomob(map, buf, RO_OBCLASS, cid, map->depth + depthmod);
|
||||
return real_getrandomob(map, buf, RO_OBCLASS, cid, getmapdifficulty(map) + depthmod);
|
||||
}
|
||||
|
||||
int getobrarity(object_t *o) {
|
||||
|
@ -4090,7 +4180,7 @@ object_t *hasobid(obpile_t *op, int id) {
|
|||
// fully identify a single object.
|
||||
void identify(object_t *o) {
|
||||
flag_t *f;
|
||||
if (!isknown(o)) {
|
||||
if (!isknown(o) && (o->type->obclass->id != OC_BOOK)) {
|
||||
makeknown(o->type->id);
|
||||
}
|
||||
addflag(o->flags, F_IDENTIFIED, B_TRUE, -1, -1, NULL);
|
||||
|
@ -4151,7 +4241,6 @@ void ignite(object_t *o) {
|
|||
void initobjects(void) {
|
||||
//int ch;
|
||||
int i,n;
|
||||
objecttype_t *ot;
|
||||
|
||||
// generate hidden names
|
||||
for (n = 0; strlen(colour[n].name); n++) {
|
||||
|
@ -4503,18 +4592,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "\\");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
|
@ -4564,13 +4641,13 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_MISC);
|
||||
addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "_");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_MISC);
|
||||
addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "&");
|
||||
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4579,7 +4656,7 @@ void initobjects(void) {
|
|||
// traps
|
||||
addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 10, B_FALSE, 20, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4587,7 +4664,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
||||
addot(OT_TRAPROCK, "falling rock trap", "A pressure plate which causes heavy rocks to drop from the ceiling.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 20, B_TRUE, 22, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4596,7 +4673,7 @@ void initobjects(void) {
|
|||
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 76, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4605,7 +4682,7 @@ void initobjects(void) {
|
|||
addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4614,7 +4691,7 @@ void initobjects(void) {
|
|||
addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 27, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4623,7 +4700,7 @@ void initobjects(void) {
|
|||
addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 59, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4632,7 +4709,8 @@ void initobjects(void) {
|
|||
addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 20, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4707,6 +4785,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_REDUCEMOVEMENT, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
||||
|
@ -4831,6 +4910,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
|
||||
addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addot(OT_POT_SLEEP, "potion of sleep", "Puts the drinker into a deep sleep.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_SPEED, "potion of haste", "Temporarily increasees the drinker's speed.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5144,6 +5226,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_ADJSELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_CALLWIND, "call wind", "Conjures a friendly wind, carrying a single object to the caster's hands.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||
|
||||
// l2
|
||||
addot(OT_S_GUSTOFWIND, "gust of wind", "Causes a gust of wind to blow the target's objects away.", MT_NOTHING, 0, OC_SPELL);
|
||||
|
@ -5332,6 +5419,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_LIGHTNINGBOLT, "lightning bolt", "Fires electricity through multiple enemies.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
||||
addot(OT_S_ENDUREELEMENTS, "endure elements", "Provides resistance to fire and cold.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5521,7 +5613,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_LIGHT, "light", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_LIGHT, "light area", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
|
@ -5738,7 +5830,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
||||
|
||||
// manuals
|
||||
// books
|
||||
addot(OT_MANUAL, "manual", "Teaches you one level of its subject matter.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 48, NA, NULL);
|
||||
addot(OT_SPELLBOOK, "spellbook", "Teaches you the spell contained within.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
/*
|
||||
addot(OT_MAN_ARMOUR, "manual of armour", "Teaches you the skill 'armour'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_ARMOUR, NA, NA, NULL);
|
||||
addot(OT_MAN_ATHLETICS, "manual of athletics", "Teaches you the skill 'athletics'.", MT_PAPER, 3, OC_BOOK);
|
||||
|
@ -5755,6 +5852,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_LOCKPICKING, NA, NA, NULL);
|
||||
addot(OT_MAN_MAGITEMUSAGE, "manual of channeling", "Teaches you the skill 'channeling'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_CHANNELING, NA, NA, NULL);
|
||||
addot(OT_MAN_RANGED, "manual of ranged weapons", "Teaches you the skill 'ranged weapons'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_RANGED, NA, NA, NULL);
|
||||
addot(OT_MAN_SHIELDS, "manual of shields", "Teaches you the skill 'shields'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SHIELDS, NA, NA, NULL);
|
||||
addot(OT_MAN_SPELLCASTING, "manual of sorcery", "Teaches you the skill 'sorcery'.", MT_PAPER, 3, OC_BOOK);
|
||||
|
@ -5824,8 +5923,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_SS_TRANSLOCATION, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_WILD, "manual of wild magic", "Teaches you the skill 'wild magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_WILD, NA, NA, NULL);
|
||||
*/
|
||||
|
||||
// spellbooks
|
||||
/*
|
||||
addot(OT_SB_ANIMATEDEAD, "spellbook of animate dead", "Teaches the spell 'animate dead'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_ANIMATEDEAD, NA, NA, NULL);
|
||||
addot(OT_SB_DRAINLIFE, "spellbook of drain life", "Teaches the spell 'drain life'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
|
@ -5993,9 +6094,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, NA, NA, NULL);
|
||||
addot(OT_SB_TWIDDLE, "spellbook of twiddle", "Teaches the spell 'twiddle'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_TWIDDLE, NA, NA, NULL);
|
||||
*/
|
||||
|
||||
|
||||
// assign rarity to books
|
||||
/*
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if ((ot->obclass->id == OC_BOOK) && !hasflag(ot->flags, F_RARITY)) {
|
||||
flag_t *f;
|
||||
|
@ -6025,6 +6128,7 @@ void initobjects(void) {
|
|||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// wands
|
||||
|
@ -6614,6 +6718,19 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL);
|
||||
|
||||
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "\\");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "\\");
|
||||
|
@ -7331,10 +7448,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An axe specifically designed for combat.", MT_METAL, 5, OC_WEAPON);
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9");
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+1");
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
|
@ -7342,19 +7459,26 @@ void initobjects(void) {
|
|||
addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 8, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d10");
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+1");
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL);
|
||||
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe made for combat.", MT_METAL, 2, OC_WEAPON);
|
||||
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d6+1");
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7");
|
||||
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
||||
addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1");
|
||||
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 11, NA, NULL);
|
||||
|
||||
// short blades
|
||||
addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON);
|
||||
|
@ -7551,7 +7675,7 @@ void initobjects(void) {
|
|||
// staves
|
||||
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 2, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d8");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7582,7 +7706,7 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 135, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "3d4+1");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7667,7 +7791,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 8, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL);
|
||||
|
@ -7678,7 +7802,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 9, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 12, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL);
|
||||
|
@ -7688,7 +7812,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL);
|
||||
|
@ -7697,7 +7821,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 7, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 12, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL);
|
||||
|
@ -7709,7 +7833,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_DAMTYPE, DT_BASH, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_DAM, 3, 4, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 20, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_BULLET, NA, NA, NULL);
|
||||
|
@ -7719,7 +7843,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_FIRESPEED, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_STONE, NA, NA, NULL);
|
||||
|
@ -8161,6 +8285,8 @@ int istried(object_t *o) {
|
|||
int istriedot(objecttype_t *ot) {
|
||||
knowledge_t *k;
|
||||
|
||||
if (ot->obclass->id == OC_BOOK) return B_FALSE;
|
||||
|
||||
for (k = knowledge; k ; k = k->next) {
|
||||
if (k->id == ot->id) {
|
||||
// it DOES have a hidden name.
|
||||
|
@ -9030,6 +9156,20 @@ int obmatchescondition(object_t *o, long opts) {
|
|||
if ((opts & AO_POURABLE) && ispourable(o)) ok = B_TRUE;
|
||||
if ((opts & AO_NOTIDENTIFIED) && !isidentified(o)) ok = B_TRUE;
|
||||
if ((opts & AO_NOTKNOWN) && !isknown(o)) ok = B_TRUE;
|
||||
if (opts & AO_SPECIFIED) {
|
||||
int n;
|
||||
int found = B_FALSE;
|
||||
// does retlist contain this?
|
||||
for (n = 0; n < nretobs; n++) {
|
||||
if (retobs[n] == o) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
@ -9139,10 +9279,10 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
|
||||
if (isplayer(lf)) {
|
||||
if (strlen(f->text) > 0) {
|
||||
where = askcoords(f->text, ttype);
|
||||
where = askcoords(f->text, ttype, lf, UNLIMITED);
|
||||
} else {
|
||||
sprintf(buf, "Where will you aim %s?",obname);
|
||||
where = askcoords(buf, ttype);
|
||||
where = askcoords(buf, ttype, lf, UNLIMITED);
|
||||
if (!haslos(lf, where)) {
|
||||
// exception - wand of digging doesn't need los
|
||||
if (isknown(o) && (o->type->id == OT_WAND_DIGGING)) {
|
||||
|
@ -9424,7 +9564,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
// announce
|
||||
if (!seen) {
|
||||
noise(where, NULL, "something spraying.", NULL);
|
||||
noise(where, NULL, 0, "something spraying.", NULL);
|
||||
}
|
||||
} else if ((o->type->id == OT_EMPTYFLASK) || (o->type->id == OT_EMPTYVIAL)) {
|
||||
object_t *oo,*nextoo;
|
||||
|
@ -9610,7 +9750,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
if (isplayer(lf)) {
|
||||
msg("You play a few notes on your panpipes.");
|
||||
} else {
|
||||
noise(lf->cell, lf, "the sound of panpipes.", "plays a tune on its panpipes.");
|
||||
noise(lf->cell, lf, 3, "the sound of panpipes.", "plays a tune on its panpipes.");
|
||||
}
|
||||
} else if (o->type->id == OT_PICKAXE) {
|
||||
int ch,dir;
|
||||
|
@ -10279,6 +10419,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
case OT_POT_HEALINGMIN:
|
||||
dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
||||
break;
|
||||
case OT_POT_HEALINGMAJ:
|
||||
dospelleffects(lf, OT_S_HEALINGMAJ,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
||||
break;
|
||||
case OT_POT_INVIS:
|
||||
dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen);
|
||||
break;
|
||||
|
@ -10409,17 +10552,20 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OT_POT_SLEEP:
|
||||
dospelleffects(lf, OT_S_SLEEP, 8, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
||||
if (seen) *seen = B_TRUE;
|
||||
break;
|
||||
case OT_POT_SPEED:
|
||||
if (potblessed == B_BLESSED) {
|
||||
dospelleffects(lf, OT_S_HASTE, 1, lf, NULL, lf->cell, B_BLESSED, NULL);
|
||||
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_BLESSED, NULL);
|
||||
} else if (potblessed == B_CURSED) {
|
||||
dospelleffects(lf, OT_S_SLOW, 1, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
||||
dospelleffects(lf, OT_S_SLOW, 5, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
||||
} else { // uncursed
|
||||
dospelleffects(lf, OT_S_HASTE, 1, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
||||
dospelleffects(lf, OT_S_HASTE, 5, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
||||
}
|
||||
if (seen) *seen = B_TRUE;
|
||||
break;
|
||||
|
||||
case OT_POT_WATER:
|
||||
switch (potblessed) {
|
||||
case B_BLESSED:
|
||||
|
@ -10585,8 +10731,12 @@ int readsomething(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
if (!isknown(o) && willid) {
|
||||
// id the scroll
|
||||
// id the object
|
||||
if (o->type->obclass->id == OC_BOOK) {
|
||||
identify(o);
|
||||
} else {
|
||||
makeknown(o->type->id);
|
||||
}
|
||||
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness
|
||||
if (isplayer(lf)) {
|
||||
// tell the player
|
||||
|
@ -10911,7 +11061,7 @@ void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
|
||||
seen = B_TRUE;
|
||||
} else {
|
||||
noise(where, NULL, "shattering glass.", NULL);
|
||||
noise(where, NULL, 3, "shattering glass.", NULL);
|
||||
}
|
||||
|
||||
if (target) {
|
||||
|
@ -11256,7 +11406,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
|
||||
|
||||
|
||||
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
||||
getobconditionname(o, predamname);
|
||||
hpflag = hasflag(o->flags, F_OBHP);
|
||||
if (hpflag) {
|
||||
|
@ -11342,7 +11492,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
return damtaken;
|
||||
}
|
||||
|
||||
// throw speed is the damage multiplier
|
||||
// throw speed/2 is the damage multiplier
|
||||
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) {
|
||||
char throwername[BUFLEN];
|
||||
char throwernamea[BUFLEN];
|
||||
|
@ -11661,7 +11811,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (shield) {
|
||||
// block chance based on shield skill
|
||||
// ie. ST_AVERAGE = speed3 = 18
|
||||
// ie. gun = speed10 = 60 = basically impossible
|
||||
// ie. gun = speed20 = 120 = impossible
|
||||
if (skillcheck(target, SC_SHIELDBLOCK, speed*6, 0)) {
|
||||
int throwdam,dam;
|
||||
if (seen) {
|
||||
|
@ -12453,7 +12603,6 @@ int usecharge(object_t *o) {
|
|||
|
||||
int validateobs(void) {
|
||||
objecttype_t *ot;
|
||||
skill_t *sk;
|
||||
int foundspells = B_FALSE;
|
||||
int goterror = B_FALSE;
|
||||
flag_t *f;
|
||||
|
@ -12553,6 +12702,7 @@ int validateobs(void) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
for (sk = firstskill ; sk ; sk = sk->next) {
|
||||
int found = B_FALSE;
|
||||
// make sure every skill have an object providing it
|
||||
|
@ -12567,6 +12717,7 @@ int validateobs(void) {
|
|||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return goterror;
|
||||
}
|
||||
|
@ -12670,21 +12821,27 @@ enum MATSTATE getmaterialstate(enum MATERIAL mat) {
|
|||
|
||||
int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, enum ATTRIB whichatt) {
|
||||
int acc,maxrange,howfar;
|
||||
enum SKILLLEVEL slev;
|
||||
// figure out if you miss or not, based on distance and
|
||||
// dexterity
|
||||
// base:
|
||||
// if throwing, 50%
|
||||
// if firing, gun accuracy
|
||||
// if firing, gun accuracy modified by sk_ranged
|
||||
// adjust for range:
|
||||
// pointblank = +30%
|
||||
// max = -30%
|
||||
// then modify using dexterity/int/whatever
|
||||
// then penalise for throwing non-missiles
|
||||
|
||||
|
||||
// base accuracy
|
||||
if (firearm) {
|
||||
slev = getskill(thrower, SK_RANGED);
|
||||
acc = getobaccuracy(firearm, thrower);
|
||||
// ie. inept = -30%, adept = 0%, master = +30%
|
||||
acc += ((slev - PR_ADEPT) * 10);
|
||||
} else {
|
||||
slev = PR_INEPT;
|
||||
acc = 50;
|
||||
}
|
||||
|
||||
|
@ -12700,13 +12857,13 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
|
|||
}
|
||||
|
||||
howfar = getcelldist(thrower->cell, where);
|
||||
|
||||
if (howfar == 1) {
|
||||
acc += 30;
|
||||
} else if (howfar == maxrange) {
|
||||
if (slev != PR_MASTER) {
|
||||
acc -= 30;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// modify for dexterity
|
||||
if (whichatt != A_NONE) {
|
||||
|
|
14
save.c
14
save.c
|
@ -332,8 +332,8 @@ map_t *loadmap(char *basefile) {
|
|||
*/
|
||||
|
||||
// cell info
|
||||
fscanf(f, "%d,%d,%d,%d,%d,%d,%d\n",
|
||||
&c->roomid, &celltypeid, &c->known, &c->visited, &c->lit, &c->origlit, &c->littimer);
|
||||
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
&c->roomid, &celltypeid, &c->known, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer);
|
||||
|
||||
|
||||
ct = findcelltype(celltypeid);
|
||||
|
@ -445,6 +445,10 @@ map_t *loadmap(char *basefile) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
// load flags
|
||||
loadflagpile(f, m->flags);
|
||||
|
||||
fclose(f);
|
||||
|
||||
// move lifeforms to their proper locations
|
||||
|
@ -745,8 +749,8 @@ int savemap(map_t *m) {
|
|||
cell_t *c;
|
||||
c = getcellat(m, x, y);
|
||||
// cell info
|
||||
fprintf(f, "%d,%d,%d,%d,%d,%d,%d\n",
|
||||
c->roomid, c->type->id, c->known, c->visited,c->lit,c->origlit,c->littimer);
|
||||
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
c->roomid, c->type->id, c->known, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer);
|
||||
// cell objects
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
fprintf(f, "ob:%ld\n",o->id);
|
||||
|
@ -769,6 +773,8 @@ int savemap(map_t *m) {
|
|||
}
|
||||
}
|
||||
|
||||
saveflagpile(f, m->flags);
|
||||
|
||||
fclose(f);
|
||||
|
||||
return B_FALSE;
|
||||
|
|
238
spell.c
238
spell.c
|
@ -27,6 +27,7 @@ extern prompt_t prompt;
|
|||
extern WINDOW *msgwin;
|
||||
|
||||
extern job_t *firstjob;
|
||||
extern objecttype_t *objecttype;
|
||||
|
||||
extern map_t *firstmap;
|
||||
|
||||
|
@ -106,7 +107,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) {
|
||||
sprintf(buf, "Charge who (max range %d)?",range);
|
||||
// TODO: ask for direction
|
||||
targcell = askcoords(buf, TT_MONSTER);
|
||||
targcell = askcoords(buf, TT_MONSTER, user, range);
|
||||
if (!targcell) {
|
||||
msg("Cancelled.");
|
||||
return TRUE;
|
||||
|
@ -253,7 +254,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else {
|
||||
sprintf(buf, "Darkwalk to where?");
|
||||
}
|
||||
targcell = askcoords(buf, TT_NONE);
|
||||
targcell = askcoords(buf, TT_NONE, user, range);
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -537,7 +538,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
sprintf(buf, "Jump where (max distance 2)?");
|
||||
while (!targcell) {
|
||||
// ask where
|
||||
targcell = askcoords(buf, TT_NONE);
|
||||
targcell = askcoords(buf, TT_NONE, user, 2);
|
||||
if (!targcell) {
|
||||
return B_TRUE;
|
||||
} else if (getcelldist(user->cell, targcell) > 2) {
|
||||
|
@ -800,7 +801,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) {
|
||||
sprintf(buf, "Swoop who (max range %d)?",srange);
|
||||
// TODO: ask for direction
|
||||
targcell = askcoords(buf, TT_MONSTER);
|
||||
targcell = askcoords(buf, TT_MONSTER, user, srange);
|
||||
if (!targcell) {
|
||||
msg("Cancelled.");
|
||||
return TRUE;
|
||||
|
@ -934,13 +935,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_FALSE;
|
||||
} else if (abilid == OT_A_DEBUG) {
|
||||
cell_t *where;
|
||||
where = askcoords("Debug who?", TT_MONSTER);
|
||||
where = askcoords("Debug who?", TT_MONSTER, user, UNLIMITED);
|
||||
if (where && where->lf) {
|
||||
debug(where->lf);
|
||||
}
|
||||
} else if (abilid == OT_A_EMPLOY) {
|
||||
cell_t *where;
|
||||
where = askcoords("Assign job to who?", TT_MONSTER);
|
||||
where = askcoords("Assign job to who?", TT_MONSTER, user, UNLIMITED);
|
||||
if (where && where->lf) {
|
||||
char question[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
|
@ -964,7 +965,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
} else if (abilid == OT_A_ENHANCE) {
|
||||
cell_t *where;
|
||||
where = askcoords("Enhance stats of who?", TT_MONSTER);
|
||||
where = askcoords("Enhance stats of who?", TT_MONSTER, user, UNLIMITED);
|
||||
if (where && where->lf) {
|
||||
char ch;
|
||||
enum ATTRIB att;
|
||||
|
@ -1039,8 +1040,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
makenoise(user, N_WARCRY);
|
||||
|
||||
// take a lot of time
|
||||
taketime(user, getactspeed(user)*4);
|
||||
// take a lot of time, so that there is a danger in just
|
||||
// using it all the time.
|
||||
taketime(user, getactspeed(user)*2);
|
||||
|
||||
// all in range must pass a morale check or flee
|
||||
for (target = user->cell->map->lf ; target ; target = target->next) {
|
||||
|
@ -1601,6 +1603,67 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
failed = B_TRUE;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_CALLWIND) {
|
||||
int failed = B_FALSE;
|
||||
float maxweight;
|
||||
|
||||
// if no target object...
|
||||
if (!targob) {
|
||||
// ask for a target cell (to take objects from)
|
||||
if (!validatespellcell(caster, &targcell, TT_OBJECT, spellid, power)) return B_TRUE;
|
||||
|
||||
if (targcell->obpile->first) {
|
||||
// select object from cell...
|
||||
if (countobs(targcell->obpile) == 1) {
|
||||
targob = targcell->obpile->first;
|
||||
} else {
|
||||
targob = askobject(targcell->obpile, "Target which object", NULL, AO_NONE);
|
||||
if (!targob) {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
targcell = caster->cell;
|
||||
|
||||
// not liftable?
|
||||
if (hasflag(targob->flags, F_NOPICKUP)) {
|
||||
if (isplayer(caster)) {
|
||||
nothinghappens();
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// too heavy? max weight is now based on our race's weight and intelligence
|
||||
maxweight = getlfweight(caster, B_NOOBS) +
|
||||
(getlfweight(caster, B_NOOBS) * (getstatmod(caster, A_IQ) / 100));
|
||||
|
||||
// modify by power
|
||||
maxweight += (10*power);
|
||||
|
||||
if (getobweight(targob) > maxweight) {
|
||||
cell_t *obloc;
|
||||
char obname[BUFLEN];
|
||||
obloc = getoblocation(targob);
|
||||
getobname(targob, obname, targob->amt);
|
||||
if (haslos(player, obloc)) {
|
||||
msg("%s lifts slightly, then drops again.",obname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
pullobto(targob, caster);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
fizzle(caster);
|
||||
}
|
||||
|
@ -2253,7 +2316,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!targcell) {
|
||||
if (isplayer(caster)) {
|
||||
sprintf(buf, "Where will you target your dispersal?");
|
||||
targcell = askcoords(buf, TT_MONSTER|TT_OBJECT);
|
||||
targcell = askcoords(buf, TT_MONSTER|TT_OBJECT, caster, UNLIMITED);
|
||||
if (!targcell) { // no cell
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
|
@ -2962,6 +3025,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_HAILSTORM) {
|
||||
int failed = B_FALSE;
|
||||
if (isoutdoors(caster->cell->map)) {
|
||||
power += 3;
|
||||
limit(&power, NA, 10);
|
||||
}
|
||||
// ask for a target cell
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
if (targcell) {
|
||||
|
@ -3371,9 +3438,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
if (range == UNLIMITED) {
|
||||
c->known = B_TRUE;
|
||||
setcellknown(c, PR_ADEPT);
|
||||
} else if (getcelldist(caster->cell, c) <= range) {
|
||||
c->known = B_TRUE;
|
||||
setcellknown(c, PR_ADEPT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3467,7 +3534,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (isplayer(caster)) {
|
||||
// ask for a target cell
|
||||
sprintf(buf, "Whose mind will you scan?");
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
where = askcoords(buf, TT_MONSTER, caster, UNLIMITED);
|
||||
if (where && haslos(caster, where) && haslf(where)) {
|
||||
char targname[BUFLEN];
|
||||
lifeform_t *oldplayer;
|
||||
|
@ -4150,6 +4217,34 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
calclight(targcell->map);
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
} else if (spellid == OT_S_LIGHTNINGBOLT) {
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcells;
|
||||
int i;
|
||||
int nhits = power;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
|
||||
// create a line of fire towards the target cell
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcells);
|
||||
animcells(caster->cell, &retcell[1], nretcells-1, B_FALSE, '/', '\\', C_WHITE);
|
||||
if (cansee(player, caster)) {
|
||||
msg("%s shoot%s a bolt of lightning!",castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
// don't hit the caster cell on fire!
|
||||
for (i = 1; (i < nretcells) && (nhits > 0); i++) {
|
||||
cell_t *c;
|
||||
c = retcell[i];
|
||||
if (c->lf) {
|
||||
// hit with lightning
|
||||
losehp(c->lf, roll("2d6"), DT_ELECTRIC, caster, "a lightning bolt");
|
||||
nhits--;
|
||||
}
|
||||
if (haslos(player, c)) {
|
||||
needredraw = B_TRUE;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_LIGHTNINGSTORM) {
|
||||
char targname[BUFLEN];
|
||||
lifeform_t *poss[MAXCANDIDATES], *targ[MAXCANDIDATES];
|
||||
|
@ -4196,7 +4291,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(targ[i],targname);
|
||||
msg("%s %s struck by a bolt of lightning!",targname, is(targ[i]));
|
||||
}
|
||||
if (isoutdoors(target->cell->map)) {
|
||||
if (isoutdoors(targ[i]->cell->map)) {
|
||||
losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning");
|
||||
} else {
|
||||
losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning");
|
||||
|
@ -4331,7 +4426,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (isplayer(caster)) {
|
||||
cell_t *where;
|
||||
sprintf(buf, "Where will you target your spell?");
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
where = askcoords(buf, TT_MONSTER, caster, UNLIMITED);
|
||||
if (where && haslos(caster, where) && haslf(where)) {
|
||||
target = haslf(where);
|
||||
} else {
|
||||
|
@ -4376,6 +4471,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int i;
|
||||
char targname[BUFLEN];
|
||||
|
||||
if (isoutdoors(caster->cell->map)) {
|
||||
power += 5;
|
||||
limit(&power, NA, 10);
|
||||
}
|
||||
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_OBJECT, spellid, power)) return B_TRUE;
|
||||
|
||||
target = targcell->lf;
|
||||
|
@ -4552,7 +4652,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// ask for target if required
|
||||
if (!target && isplayer(caster)) {
|
||||
cell_t *where;
|
||||
where = askcoords("Who will you polymorph?", TT_MONSTER);
|
||||
where = askcoords("Who will you polymorph?", TT_MONSTER, caster, UNLIMITED);
|
||||
if (haslos(caster, where)) {
|
||||
target = where->lf;
|
||||
} else {
|
||||
|
@ -4676,6 +4776,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (isplayer(caster)) {
|
||||
char obname[BUFLEN];
|
||||
flag_t *f;
|
||||
int donesomething = B_FALSE;
|
||||
|
||||
getobname(o, obname, o->amt);
|
||||
|
||||
|
@ -4684,27 +4785,37 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
makeknown(o->type->id); // you now know that it was poison.
|
||||
o->type = findot(OT_POT_WATER);
|
||||
makeknown(o->type->id); // you now know what water is too.
|
||||
donesomething = B_TRUE;
|
||||
} else {
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (!f) {
|
||||
nothinghappens();
|
||||
return B_TRUE;
|
||||
} else {
|
||||
|
||||
if (f) {
|
||||
f->val[0] = f->val[1];
|
||||
|
||||
if (isdrinkable(o)) {
|
||||
msg("Your %s looks more clean now.", noprefix(obname));
|
||||
} else {
|
||||
msg("Your %s looks more fresh now.", noprefix(obname));
|
||||
}
|
||||
f = hasflagval(o->flags, F_OBHPDRAIN, NA, DT_DECAY, NA, NULL);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_TAINTED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (donesomething) {
|
||||
if (isdrinkable(o)) {
|
||||
msg("Your %s looks more clean now.", noprefix(obname));
|
||||
} else {
|
||||
msg("Your %s looks more fresh now.", noprefix(obname));
|
||||
}
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else {
|
||||
nothinghappens();
|
||||
return B_TRUE;
|
||||
}
|
||||
} else {
|
||||
// monsters can't purify things!
|
||||
|
@ -4882,6 +4993,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_SLEETSTORM) {
|
||||
int failed = B_FALSE;
|
||||
if (isoutdoors(caster->cell->map)) {
|
||||
power += 3;
|
||||
limit(&power, NA, 10);
|
||||
}
|
||||
// ask for a target cell
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
if (targcell) {
|
||||
|
@ -5181,7 +5296,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
sprintf(buf, "Where will you teleport to?");
|
||||
while (!c) {
|
||||
int ch;
|
||||
c = askcoords(buf, TT_NONE);
|
||||
c = askcoords(buf, TT_NONE, caster, UNLIMITED);
|
||||
if (!c->known) {
|
||||
// confirm
|
||||
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE);
|
||||
|
@ -5337,7 +5452,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!targob) {
|
||||
// ask for a target cell (to take objects from)
|
||||
sprintf(buf, "Where will you focus your telekinetic power?");
|
||||
where = askcoords(buf, TT_OBJECT | TT_DOOR);
|
||||
where = askcoords(buf, TT_OBJECT | TT_DOOR, caster, UNLIMITED);
|
||||
if (where && haslos(caster, where)) {
|
||||
if (where->obpile->first) {
|
||||
// select object from cell...
|
||||
|
@ -5374,7 +5489,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char obname[BUFLEN];
|
||||
getobname(targob, obname, 1);
|
||||
sprintf(buf, "Where will you move %s to?", obname);
|
||||
targcell = askcoords(buf, TT_MONSTER | TT_PLAYER);
|
||||
targcell = askcoords(buf, TT_MONSTER | TT_PLAYER, caster, UNLIMITED);
|
||||
}
|
||||
|
||||
// not liftable?
|
||||
|
@ -5888,7 +6003,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
o = relinkob(o, newloc->obpile);
|
||||
}
|
||||
if (o) {
|
||||
noise(caster->cell, NULL, "something hitting the ground.", NULL);
|
||||
noise(caster->cell, NULL, 1, "something hitting the ground.", NULL);
|
||||
if (!isblind(caster)) {
|
||||
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
|
@ -5909,6 +6024,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return rv;
|
||||
}
|
||||
|
||||
objecttype_t *findspelln(char *buf) {
|
||||
objecttype_t *ot;
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if (ot->obclass->id == OC_SPELL) {
|
||||
if (!strcasecmp(ot->name, buf)) {
|
||||
return ot;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fizzle(lifeform_t *caster) {
|
||||
if (isplayer(caster)) {
|
||||
if (lfhasflag(caster, F_CASTINGSPELL)) {
|
||||
|
@ -5925,6 +6052,30 @@ void fizzle(lifeform_t *caster) {
|
|||
}
|
||||
}
|
||||
|
||||
enum OBTYPE getrandomspell(void) {
|
||||
int wantlev;
|
||||
objecttype_t *ot,*poss[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
||||
wantlev = 1;
|
||||
while (rnd(1,2) == 1) {
|
||||
wantlev++;
|
||||
}
|
||||
|
||||
// get list of all spells of this level
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if ((ot->obclass->id == OC_SPELL) && (getspelllevel(ot->id) == wantlev) ) {
|
||||
poss[nposs++] = ot;
|
||||
}
|
||||
}
|
||||
|
||||
if (nposs <= 0) {
|
||||
return OT_NONE;
|
||||
}
|
||||
ot = poss[rnd(0,nposs-1)];
|
||||
return ot->id;
|
||||
}
|
||||
|
||||
enum SKILL getschoolskill(enum SPELLSCHOOL ss) {
|
||||
switch (ss) {
|
||||
case SS_ALLOMANCY:
|
||||
|
@ -6252,6 +6403,12 @@ int getspellrange(enum OBTYPE spellid, int power) {
|
|||
// base range for this spell is 3
|
||||
range += (power/3);
|
||||
break;
|
||||
case OT_S_CALLWIND:
|
||||
range = (power*2);
|
||||
break;
|
||||
case OT_S_LIGHTNINGBOLT:
|
||||
range = (power*3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6345,6 +6502,19 @@ void stopallspells(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
int schoolappearsinbooks(enum SPELLSCHOOL ss) {
|
||||
switch (ss) {
|
||||
case SS_DIVINE:
|
||||
case SS_ABILITY:
|
||||
case SS_ALLOMANCY:
|
||||
case SS_MENTAL:
|
||||
return B_FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYPE sid, int power) {
|
||||
int x,y;
|
||||
if (ch != '\0') {
|
||||
|
@ -6480,7 +6650,7 @@ lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **targe
|
|||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "Where will you target your %s?",ot->name);
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
where = askcoords(buf, TT_MONSTER, user, maxrange);
|
||||
if (where) {
|
||||
if (!haslf(where)) {
|
||||
msg("There is nobody there!");
|
||||
|
@ -6611,7 +6781,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
|
|||
} else {
|
||||
sprintf(buf, "Where will you target your spell [max range %d]?",maxrange);
|
||||
}
|
||||
where = askcoords(buf, targtype);
|
||||
where = askcoords(buf, targtype, caster, maxrange);
|
||||
if (!where) {
|
||||
int ch;
|
||||
ch = askchar("Abandon your spell?","yn","n", B_TRUE);
|
||||
|
@ -6704,7 +6874,7 @@ lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **target) {
|
|||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "Where will you target your spell?");
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
where = askcoords(buf, TT_MONSTER, caster, UNLIMITED);
|
||||
if (where && haslos(caster, where) && haslf(where)) {
|
||||
*target = haslf(where);
|
||||
} else {
|
||||
|
|
3
spell.h
3
spell.h
|
@ -4,9 +4,11 @@
|
|||
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag);
|
||||
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer);
|
||||
objecttype_t *findspelln(char *buf);
|
||||
void fizzle(lifeform_t *caster);
|
||||
//int getiqreq(enum OBTYPE oid);
|
||||
int getmpcost(lifeform_t *lf, enum OBTYPE oid);
|
||||
enum OBTYPE getrandomspell(void);
|
||||
enum SKILL getschoolskill(enum SPELLSCHOOL ss);
|
||||
char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf);
|
||||
int getspellduration(int min,int max,int blessed);
|
||||
|
@ -19,6 +21,7 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid);
|
|||
int getspellrange(enum OBTYPE spellid, int power);
|
||||
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
|
||||
void pullobto(object_t *o, lifeform_t *lf);
|
||||
int schoolappearsinbooks(enum SPELLSCHOOL ss);
|
||||
void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYPE sid, int power);
|
||||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
|
|
2
text.c
2
text.c
|
@ -328,7 +328,7 @@ char *makeplural(char *text) {
|
|||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "gem ", "gems ", &rv);
|
||||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "leaf ", "leaves ", &rv);
|
||||
newtext = strrep(newtext, "leaf", "leaves", &rv);
|
||||
if (rv) return newtext;
|
||||
newtext = strrep(newtext, "loaf ", "loaves ", &rv);
|
||||
if (rv) return newtext;
|
||||
|
|
Loading…
Reference in New Issue