* [+] shallow water / deep water
- [+] copy getmovespeed() water code into getactspeed too. - [+] CAN throw missiles or fire guns while swimming, but you have an accuracy penalty, and they go slower. * [+] can't cast spells while in the water * [+] sk_swimming - [+] new obclass - terrain - goes baove everythign - [+] remember tarrain like dfeatures - [+] replace cone of cold with cold ray which hits all objects in the path, but stops at the first lf. - [+] towel - dries things off. - [+] f_needswater - suffocate if you aren't in water. - [+] l6 nature - FLOOD. - [+] make water jet leave a water trail * [+] water monsters ( non-grey ;) - [+] add aquatic mosnters to flooded rooms. addmonsters needs to check for water. * [+] SPEED UP the game. running very slowly now. switched ncusrses draw func. - [+] fix crash when moving off forest map with DC_xx instead of D_xx
This commit is contained in:
parent
69982623ed
commit
f4cdcae146
18
ai.c
18
ai.c
|
@ -565,6 +565,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// see if we have a ranged attack. if so, adjust wantdist
|
||||
// to maintain distance.
|
||||
rangedob = aigetrangedattack(lf, &rangedattack);
|
||||
|
||||
if (rangedattack != RA_NONE) {
|
||||
if (wantdistmin < 2) wantdistmin = 2;
|
||||
if (wantdistmax < wantdistmin) wantdistmax = wantdistmin;
|
||||
|
@ -575,7 +576,9 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
|
|||
// try to get to our ideal range from them.
|
||||
if (db) dblog(".oO { i am at distance %d, want to be at %d-%d }", dist, wantdistmin, wantdistmax);
|
||||
if (dist > wantdistmax) {
|
||||
if (db) dblog(".oO { moving towards target. }");
|
||||
if (db) {
|
||||
dblog(".oO { moving towards target. }");
|
||||
}
|
||||
if (!movetowards(lf, target->cell, DT_ORTH)) {
|
||||
// success
|
||||
return B_FALSE;
|
||||
|
@ -813,6 +816,7 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
if (wantdb && lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
} else {
|
||||
|
@ -1000,6 +1004,17 @@ void aiturn(lifeform_t *lf) {
|
|||
target = findlf(lf->cell->map, targid);
|
||||
if (target) {
|
||||
if (db) dblog(".oO { my target is lfid %d (%s). }", targid, target->race->name);
|
||||
// aquatic grabbers will try to drag their prey into the water
|
||||
if (lfhasflagval(lf, F_GRABBING, target->id, NA, NA, NULL) && isaquatic(lf) ) {
|
||||
if ( hasobwithflag(lf->cell->obpile, F_DEEPWATER) &&
|
||||
!hasobwithflag(target->cell->obpile, F_DEEPWATER)) {
|
||||
// move away!
|
||||
if (!moveawayfrom(lf, target->cell, DT_ORTH)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to move towards them.
|
||||
if (!aimovetolf(lf, target, B_TRUE)) {
|
||||
// success
|
||||
return;
|
||||
|
@ -1082,6 +1097,7 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// not attacking anyone in particular
|
||||
if (db) dblog(".oO { i do not have a target or can't move towards it. looking for one. }");
|
||||
|
||||
|
|
2
attack.c
2
attack.c
|
@ -647,7 +647,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (willheal) {
|
||||
if (cansee(player, victim)) {
|
||||
flag_t *f;
|
||||
msg("%s is healed!",victimname);
|
||||
msg("%s %s healed!",victimname, isplayer(victim) ? "are" : "is");
|
||||
f = hasflag(wep->flags, F_BALANCE);
|
||||
if (f) {
|
||||
f->known = B_TRUE;
|
||||
|
|
27
defs.h
27
defs.h
|
@ -419,6 +419,11 @@ enum CELLTYPE {
|
|||
CT_ROOM,
|
||||
};
|
||||
|
||||
enum SPECIALROOMTYPE {
|
||||
RT_NONE = 0,
|
||||
RT_FLOODED,
|
||||
};
|
||||
|
||||
|
||||
enum SPELLSCHOOL {
|
||||
SS_NONE,
|
||||
|
@ -529,6 +534,7 @@ enum DAMTYPE {
|
|||
|
||||
// Object Classes
|
||||
enum OBCLASS {
|
||||
OC_TERRAIN,
|
||||
OC_MONEY,
|
||||
OC_WEAPON,
|
||||
OC_ARMOUR,
|
||||
|
@ -582,6 +588,7 @@ enum RARITY {
|
|||
enum RACECLASS {
|
||||
RC_ANY, // not actually ever defined
|
||||
RC_ANIMAL,
|
||||
RC_AQUATIC,
|
||||
RC_DEMON,
|
||||
RC_HUMANOID,
|
||||
RC_INSECT,
|
||||
|
@ -635,6 +642,12 @@ enum RACE {
|
|||
R_TROGLODYTE,
|
||||
R_TROLL,
|
||||
R_XAT,
|
||||
// fish
|
||||
R_CRAB,
|
||||
R_PIRANHA,
|
||||
R_PIRANHAKING,
|
||||
R_EELELEC,
|
||||
R_EELGIANT,
|
||||
// plants
|
||||
R_CACTUS,
|
||||
R_DREAMFUNGUS,
|
||||
|
@ -662,6 +675,7 @@ enum RACE {
|
|||
R_SNAKECOBRA,
|
||||
R_SNAKECONSTRICTOR,
|
||||
R_SNAKETREE,
|
||||
R_SNAKEWATER,
|
||||
R_SPIDER,
|
||||
R_SPIDERFUNNELWEB,
|
||||
R_SPIDERREDBACK,
|
||||
|
@ -756,6 +770,9 @@ enum OBTYPE {
|
|||
OT_STAIRSUP,
|
||||
OT_VENDINGMACHINE,
|
||||
OT_PORTAL,
|
||||
// terrain
|
||||
OT_WATERSHALLOW,
|
||||
OT_WATERDEEP,
|
||||
// traps
|
||||
OT_TRAPROCK,
|
||||
OT_TRAPARROW,
|
||||
|
@ -1024,6 +1041,7 @@ enum OBTYPE {
|
|||
OT_S_IDENTIFY,
|
||||
OT_S_MAPPING,
|
||||
// -- elemental - air
|
||||
OT_S_JOLT,
|
||||
OT_S_AIRBLAST,
|
||||
OT_S_CLOUDKILL,
|
||||
OT_S_GUSTOFWIND,
|
||||
|
@ -1040,7 +1058,7 @@ enum OBTYPE {
|
|||
// -- elemental - ice
|
||||
OT_S_CHILL,
|
||||
OT_S_COLDBURST,
|
||||
OT_S_CONECOLD,
|
||||
OT_S_COLDRAY,
|
||||
OT_S_FREEZEOB,
|
||||
OT_S_FROSTBITE,
|
||||
OT_S_ICEEDGE,
|
||||
|
@ -1093,6 +1111,7 @@ enum OBTYPE {
|
|||
OT_S_WEB,
|
||||
OT_S_ENDUREELEMENTS,
|
||||
OT_S_ENTANGLE,
|
||||
OT_S_FLOOD,
|
||||
OT_S_HAILSTORM,
|
||||
OT_S_LIGHTNINGBOLT,
|
||||
OT_S_LIGHTNINGSTORM,
|
||||
|
@ -1182,6 +1201,7 @@ enum OBTYPE {
|
|||
OT_PANPIPES,
|
||||
OT_PICKAXE,
|
||||
OT_TORCH,
|
||||
OT_TOWEL,
|
||||
// tech
|
||||
OT_POCKETWATCH,
|
||||
OT_C4,
|
||||
|
@ -1214,8 +1234,6 @@ enum OBTYPE {
|
|||
OT_SPLASHWATER,
|
||||
OT_PUDDLEWATER,
|
||||
OT_PUDDLEWATERL,
|
||||
OT_WATERSHALLOW,
|
||||
OT_WATERDEEP,
|
||||
OT_ACIDSPLASH,
|
||||
OT_ACIDPUDDLE,
|
||||
OT_ACIDPOOL,
|
||||
|
@ -1511,6 +1529,7 @@ enum FLAG {
|
|||
F_UNIQUE, // only one may appear
|
||||
F_GLYPH, // override the glyph with the first char of text.
|
||||
// v0 is either NA (white) or colourid (C_xxx).
|
||||
F_NOGLYPH, // this object doesn't appear normally
|
||||
F_COSMETIC, // this object is mostly cosmetic, don't say 'you see xx'
|
||||
F_NOPICKUP, // cannot pick this up
|
||||
F_IMPASSABLE, // cannot walk past this if your size if v0 or smaller
|
||||
|
@ -1979,6 +1998,7 @@ enum FLAG {
|
|||
F_QUICKBITE, // deals v0 d d1 + d2 damage when you hit a bleeding victim
|
||||
// (bypasses armour)
|
||||
F_GRAVBOOSTED,// cannot walk or throw stuff
|
||||
F_NEEDSWATER, // cannot survive out of deep water
|
||||
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
|
||||
// if text not set, default dam is 1d2
|
||||
F_PARALYZED,// cannot do anything
|
||||
|
@ -2232,6 +2252,7 @@ enum ERROR {
|
|||
E_PRONE = 54,
|
||||
E_PENTAGRAM = 55,
|
||||
E_SWIMMING = 56,
|
||||
E_DANGEROUS = 57,
|
||||
};
|
||||
|
||||
|
||||
|
|
35
flag.c
35
flag.c
|
@ -24,6 +24,7 @@ flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
}
|
||||
|
||||
flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid) {
|
||||
lifeform_t *lf;
|
||||
flag_t *f;
|
||||
map_t *redolight = NULL;
|
||||
int i;
|
||||
|
@ -37,19 +38,26 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lf = fp->owner;
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if ((id == F_PRODUCESLIGHT) || (id == F_ASLEEP) ) {
|
||||
if (fp->owner && fp->owner->cell) {
|
||||
if (fp->owner->cell->map == player->cell->map) {
|
||||
redolight = fp->owner->cell->map;
|
||||
}
|
||||
if (id == F_PRODUCESLIGHT) {
|
||||
if (lf && lf->cell && (lf->cell->map == player->cell->map)) {
|
||||
// someone started producing light
|
||||
redolight = lf->cell->map;
|
||||
} else if (fp->ob) {
|
||||
cell_t *obloc;
|
||||
obloc = getoblocation(fp->ob);
|
||||
if (obloc && (obloc->map == player->cell->map)) {
|
||||
// an object started producing light
|
||||
redolight = obloc->map;
|
||||
}
|
||||
}
|
||||
} else if (id == F_ASLEEP) {
|
||||
// someone fell asleep - ie their glyph will turn upsidedown
|
||||
if (lf && (isplayer(lf) || cansee(player, lf))) {
|
||||
redolight = lf->cell->map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,10 +203,12 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
|
||||
if ((gamemode == GM_GAMESTARTED) && (needredraw || statdirty || redolight)) {
|
||||
if (redolight) {
|
||||
dblog("CALCINGLIGHT from flag\n");
|
||||
needredraw = B_TRUE;
|
||||
calclight(redolight);
|
||||
precalclos(player);
|
||||
}
|
||||
dblog("DRAWINGSCREEN from flag\n");
|
||||
drawscreen();
|
||||
}
|
||||
return f;
|
||||
|
@ -423,18 +433,23 @@ void killflag(flag_t *f) {
|
|||
lf = f->pile->owner;
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if ((f->id == F_PRODUCESLIGHT) || (f->id == F_ASLEEP) ) {
|
||||
if (lf && lf->cell) {
|
||||
if (lf->cell->map == player->cell->map) {
|
||||
redolight = lf->cell->map;
|
||||
}
|
||||
if (f->id == F_PRODUCESLIGHT) {
|
||||
if (lf && lf->cell && (lf->cell->map == player->cell->map)) {
|
||||
// someone stopped producing light
|
||||
redolight = lf->cell->map;
|
||||
} else if (f->pile->ob) {
|
||||
cell_t *obloc;
|
||||
obloc = getoblocation(f->pile->ob);
|
||||
if (obloc && (obloc->map == player->cell->map)) {
|
||||
// an object stopped producing light
|
||||
redolight = obloc->map;
|
||||
}
|
||||
}
|
||||
} else if (f->id == F_ASLEEP) {
|
||||
// someone woke up - ie their glyph will turn upsidedown
|
||||
if (lf && (isplayer(lf) || cansee(player, lf))) {
|
||||
redolight = lf->cell->map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
121
io.c
121
io.c
|
@ -595,6 +595,10 @@ cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange,
|
|||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "prone");
|
||||
}
|
||||
if (isswimming(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "swimming");
|
||||
}
|
||||
|
||||
f = lfhasflag(c->lf, F_ATTACHEDTO);
|
||||
if (lfhasflag(c->lf, F_ATTACHEDTO)) {
|
||||
|
@ -821,6 +825,7 @@ cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange,
|
|||
|
||||
// move cursor selected position
|
||||
wmove(gamewin, c->y - viewy, c->x - viewx);
|
||||
curs_set(1);
|
||||
redraw();
|
||||
|
||||
// get input
|
||||
|
@ -936,6 +941,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
char buf[BUFLEN];
|
||||
char *buf2;
|
||||
|
||||
if (isdead(player)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (!lf->born) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -1037,7 +1046,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
break;
|
||||
case F_BREATHWATER:
|
||||
if (isplayer(lf)) {
|
||||
msg("%s can now breath underwater.",lfname);
|
||||
msg("%s can now breath normally underwater.",lfname);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -1439,6 +1448,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
lifeform_t *lf2;
|
||||
int donesomething = B_FALSE;
|
||||
|
||||
if (isdead(player)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (!lf->born) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -2009,7 +2022,7 @@ void announceobflagloss(object_t *o, flag_t *f) {
|
|||
msg("%s %s no longer glowing.",prefix,isare);
|
||||
break;
|
||||
case F_WET:
|
||||
msg("%s %s out.",prefix, (o->amt == 1) ? "dries" : "dry");
|
||||
msg("%s %s now dry.",prefix, (o->amt == 1) ? "is" : "are");
|
||||
break;
|
||||
default: // no message
|
||||
break;
|
||||
|
@ -2673,6 +2686,7 @@ int updateviewfor(cell_t *cell) {
|
|||
|
||||
void drawscreen(void) {
|
||||
int didstatus = B_FALSE;
|
||||
int didredraw = B_FALSE;
|
||||
if (gamemode < GM_GAMESTARTED) {
|
||||
return;
|
||||
}
|
||||
|
@ -2688,9 +2702,10 @@ void drawscreen(void) {
|
|||
updateviewfor(player->cell);
|
||||
drawlevelfor(player);
|
||||
//drawcursor(); // this will call redraw gamewin
|
||||
didredraw = B_TRUE;
|
||||
}
|
||||
|
||||
if (didstatus && !needredraw) {
|
||||
if (didstatus && !didredraw) {
|
||||
drawcursor();
|
||||
}
|
||||
}
|
||||
|
@ -5023,7 +5038,8 @@ void drawglyph(glyph_t *g, int x, int y) {
|
|||
col = g->colour;
|
||||
}
|
||||
setcol(gamewin, col);
|
||||
mvwprintw(gamewin, y, x, "%lc", g->ch);
|
||||
//mvwprintw(gamewin, y, x, "%lc", g->ch);
|
||||
mvwaddch(gamewin, y, x, g->ch);
|
||||
unsetcol(gamewin, col);
|
||||
}
|
||||
|
||||
|
@ -5042,11 +5058,13 @@ void drawlevelfor(lifeform_t *lf) {
|
|||
int ndrawn = 0;
|
||||
int db = B_FALSE;
|
||||
int w,h;
|
||||
char buf[BUFLEN];
|
||||
|
||||
if (noredraw) {
|
||||
return;
|
||||
}
|
||||
|
||||
dbtimestart("drawscreen");
|
||||
map = lf->cell->map;
|
||||
|
||||
needredraw = B_FALSE;
|
||||
|
@ -5094,8 +5112,13 @@ void drawlevelfor(lifeform_t *lf) {
|
|||
dblog("last x,y checked was %d,%d",x+viewx,y+viewy);
|
||||
}
|
||||
if (db) dblog("ending DRAWLEVEL");
|
||||
|
||||
sprintf(buf, "end. ndrawn was %d",ndrawn);
|
||||
dbtimeend(buf);
|
||||
// move cursor to the player's position and blit
|
||||
drawcursor();
|
||||
if (ndrawn) {
|
||||
drawcursor();
|
||||
}
|
||||
}
|
||||
|
||||
void doheading(WINDOW *win, int *y, int x, char *what) {
|
||||
|
@ -6135,8 +6158,7 @@ void msg_real(char *format, ... ) {
|
|||
|
||||
// update msg window
|
||||
drawmsg();
|
||||
drawcursor();
|
||||
|
||||
//drawcursor();
|
||||
}
|
||||
|
||||
int needsbold(enum COLOUR col) {
|
||||
|
@ -6454,19 +6476,6 @@ void drawmsg(void) {
|
|||
int db = B_FALSE;
|
||||
|
||||
if (db) dblog("drawmsg called");
|
||||
|
||||
/*
|
||||
if ( !strcmp(msgbuf, "") ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isplayerturn() && !msgmod) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
//dblog("calling drawmsg");
|
||||
|
||||
|
||||
// is msgbuf has changed...
|
||||
if (strcmp(msgbuf, lastmsgbuf) || msgmod) {
|
||||
|
@ -6479,69 +6488,6 @@ void drawmsg(void) {
|
|||
}
|
||||
|
||||
// drawcursor();
|
||||
/*
|
||||
// TODO: if it's a monster's turn, always do a more?
|
||||
nexttok = strstr(msgbuf, "^");
|
||||
if (!nexttok) {
|
||||
// just update msg with current text
|
||||
wclear(msgwin);
|
||||
mvwprintw(msgwin, 0, 0, "%s", msgbuf);
|
||||
wrefresh(msgwin);
|
||||
} else {
|
||||
while (nexttok) {
|
||||
char thistok[BUFLEN];
|
||||
int thistoklen;
|
||||
// print up to just before the "^" current token
|
||||
|
||||
// remember this token
|
||||
|
||||
thistoklen = nexttok - msgbuf;
|
||||
strncpy(thistok, msgbuf, thistoklen);
|
||||
thistok[thistoklen] = '\0';
|
||||
if (db) dblog("drawmsg: thistok is [%s]",thistok);
|
||||
|
||||
// is there another token?
|
||||
nexttok = strstr(msgbuf, "^");
|
||||
|
||||
if (nexttok) {
|
||||
nexttok++; // go forward past the ^
|
||||
if (db) dblog("drawmsg: nexttok is [%s]",nexttok);
|
||||
// print with '--more--' added to the end
|
||||
if (db) dblog("drawmsg: displaying thistok [%s]",thistok);
|
||||
wclear(msgwin);
|
||||
mvwprintw(msgwin, 0, 0, "%s%s", thistok,MORESTRING);
|
||||
wrefresh(msgwin);
|
||||
|
||||
// ...wait for spacebar before showing next bit...
|
||||
while (getch() != ' ');
|
||||
|
||||
// we now know the player has read this
|
||||
|
||||
if (db) dblog("prompting for --more--");
|
||||
|
||||
// now clear msgstring up to end of where
|
||||
// 'thistok' appears!
|
||||
strcpy(msgbuf, nexttok);
|
||||
if (db) dblog(" reduced msgbuf to: [%s]",msgbuf);
|
||||
} else {
|
||||
if (db) dblog("drawmsg: no nexttok");
|
||||
// just print this bit
|
||||
wclear(msgwin);
|
||||
mvwprintw(msgwin, 0, 0, "%s", thistok);
|
||||
wrefresh(msgwin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// clear message buffer
|
||||
if (isplayerturn()) {
|
||||
strcpy(msgbuf, "");
|
||||
if (db) dblog("clearing msg buf");
|
||||
}
|
||||
*/
|
||||
//msgmod = B_FALSE;
|
||||
|
||||
}
|
||||
|
||||
void redraw(void) {
|
||||
|
@ -7886,8 +7832,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, buf);
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_BREATHWATER);
|
||||
if (f) {
|
||||
if (lfhasknownflag(lf, F_BREATHWATER) || lfhasknownflag(lf, F_AQUATIC)) {
|
||||
mvwprintw(mainwin, y, 0, "%s can breath normally while underwater.", you(lf));
|
||||
y++;
|
||||
}
|
||||
|
@ -8084,6 +8029,12 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_NEEDSWATER);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s will suffocate without water.", you(lf), is(lf));
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_PAIN);
|
||||
if (f && (f->known)) {
|
||||
if (isdrunk(lf)) {
|
||||
|
|
398
lf.c
398
lf.c
|
@ -422,6 +422,10 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
|||
reason = E_PRONE;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (isswimming(lf) && (getskill(lf, SK_SWIMMING) < PR_EXPERT)) {
|
||||
reason = E_SWIMMING;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
reason = E_OK;
|
||||
|
||||
|
@ -1021,6 +1025,9 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
case E_PRONE:
|
||||
msg("You can't cast spells while prone.");
|
||||
break;
|
||||
case E_SWIMMING:
|
||||
msg("You can't cast spells while swimming.");
|
||||
break;
|
||||
default:
|
||||
msg("For some reason, you can't cast that.");
|
||||
break;
|
||||
|
@ -1149,11 +1156,33 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
int depth,i;
|
||||
int didsomething = B_FALSE;
|
||||
flag_t *f;
|
||||
enum SKILLLEVEL slev;
|
||||
|
||||
i = getskill(lf, SK_SWIMMING) - isburdened(lf);
|
||||
limit(&i, 0, NA);
|
||||
slev = i;
|
||||
|
||||
depth = getobdepth(o, lf);
|
||||
|
||||
// apply water damage (ie rust etc) to armour.
|
||||
for (i = 0; i <= depth; i++) {
|
||||
object_t *armour = NULL;
|
||||
if (i == DP_FEET) {
|
||||
armour = getouterequippedob(lf, BP_FEET); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_WAIST) {
|
||||
armour = getouterequippedob(lf, BP_LEGS); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
armour = getouterequippedob(lf, BP_WAIST); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_SHOULDERS) {
|
||||
armour = getouterequippedob(lf, BP_BODY); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
armour = getouterequippedob(lf, BP_SHOULDERS); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_HEAD) {
|
||||
armour = getouterequippedob(lf, BP_HEAD); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
}
|
||||
}
|
||||
|
||||
// will you drown?
|
||||
if (depth >= DP_HEAD) {
|
||||
if (!getskill(lf, SK_SWIMMING) && !lfhasflag(lf, F_BREATHWATER)) {
|
||||
if (!slev && !lfhasflag(lf, F_BREATHWATER)) {
|
||||
// you drown.
|
||||
if (isplayer(lf)) {
|
||||
msg("You drown.");
|
||||
|
@ -1170,32 +1199,18 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
// apply damage to armour now.
|
||||
for (i = 0; i <= depth; i++) {
|
||||
object_t *armour = NULL;
|
||||
if (i == DP_FEET) {
|
||||
armour = getouterequippedob(lf, BP_FEET); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_WAIST) {
|
||||
armour = getouterequippedob(lf, BP_LEGS); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
armour = getouterequippedob(lf, BP_WAIST); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_SHOULDERS) {
|
||||
armour = getouterequippedob(lf, BP_BODY); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
armour = getouterequippedob(lf, BP_SHOULDERS); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
} else if (i == DP_HEAD) {
|
||||
armour = getouterequippedob(lf, BP_HEAD); if (armour) takedamage(armour, 4, DT_WATER);
|
||||
if (!isdead(lf)) {
|
||||
f = isvulnto(lf->flags, DT_WATER);
|
||||
if (f) {
|
||||
int dam;
|
||||
if (strlen(f->text)) {
|
||||
dam = roll(f->text);
|
||||
} else {
|
||||
dam = roll("1d6");
|
||||
}
|
||||
applywalkdam(lf, dam, DT_WATER, o);
|
||||
}
|
||||
}
|
||||
|
||||
f = isvulnto(lf->flags, DT_WATER);
|
||||
if (f) {
|
||||
int dam;
|
||||
if (strlen(f->text)) {
|
||||
dam = roll(f->text);
|
||||
} else {
|
||||
dam = roll("1d6");
|
||||
}
|
||||
applywalkdam(lf, dam, DT_WATER, o);
|
||||
}
|
||||
|
||||
return didsomething;
|
||||
}
|
||||
|
@ -2927,6 +2942,8 @@ int getactspeed(lifeform_t *lf) {
|
|||
break;
|
||||
}
|
||||
|
||||
adjustspeedforwater(lf, &speed);
|
||||
|
||||
if (speed < 1) speed = 1;
|
||||
|
||||
return speed;
|
||||
|
@ -3723,6 +3740,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
for (f = lf->flags->first ;f ; f = f->next) {
|
||||
if (f->id == F_ACCURACYMOD) {
|
||||
acc += f->val[0];
|
||||
|
@ -3756,6 +3774,16 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
|
|||
if (isprone(lf)) {
|
||||
acc -= 30;
|
||||
}
|
||||
// modify for swimming
|
||||
if (isswimming(lf) && !isaquatic(lf)) {
|
||||
switch (getskill(lf, SK_SWIMMING)) {
|
||||
// you can't attack until you are at
|
||||
// expert or better.
|
||||
default: acc = 0; break;
|
||||
case PR_EXPERT: acc -= 20; break;
|
||||
case PR_MASTER: break; // no penalty
|
||||
}
|
||||
}
|
||||
|
||||
// modify for drunkenness
|
||||
f = isdrunk(lf);
|
||||
|
@ -4141,7 +4169,6 @@ int getvisrange(lifeform_t *lf) {
|
|||
|
||||
int getmovespeed(lifeform_t *lf) {
|
||||
int speed = 0;
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
|
||||
f = lfhasflag(lf, F_MOVESPEED);
|
||||
|
@ -4182,36 +4209,7 @@ int getmovespeed(lifeform_t *lf) {
|
|||
|
||||
if (speed < 1) speed = 1;
|
||||
|
||||
if (!isairborne(lf)) {
|
||||
for (o = lf->cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_REDUCEMOVEMENT);
|
||||
if (f) {
|
||||
if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
int modamt = 0;
|
||||
// water
|
||||
if (lfhasflag(lf, F_AQUATIC)) {
|
||||
modamt = 0;
|
||||
} else {
|
||||
switch (getskill(lf, SK_SWIMMING)) {
|
||||
default:
|
||||
case PR_NOVICE:
|
||||
case PR_INEPT: modamt = f->val[0]; break; // normal penalty
|
||||
case PR_BEGINNER: modamt = f->val[0] - 2; break;
|
||||
case PR_ADEPT: modamt = 0; break;
|
||||
case PR_SKILLED: modamt = -1; break;
|
||||
case PR_EXPERT: modamt = -2; break;
|
||||
case PR_MASTER: modamt = -2; break;
|
||||
}
|
||||
}
|
||||
limit(&modamt, 0, 5);
|
||||
speed += (modamt * SPEEDUNIT);
|
||||
} else {
|
||||
// something else
|
||||
speed += (f->val[0] * SPEEDUNIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
adjustspeedforwater(lf, &speed);
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
@ -4222,10 +4220,12 @@ char *getmoveverb(lifeform_t *lf) {
|
|||
} else if (lfhasflag(lf, F_LEVITATING)) {
|
||||
return "float";
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_FLEEFROM)) {
|
||||
return "flee";
|
||||
}
|
||||
if (isswimming(lf)) {
|
||||
return "swim";
|
||||
}
|
||||
return "walk";
|
||||
}
|
||||
|
||||
|
@ -4608,7 +4608,7 @@ int getrandommonlevel(race_t *r, map_t *m) {
|
|||
return wantlev;
|
||||
}
|
||||
|
||||
race_t *getrandomrace(map_t *map, int forcedepth) {
|
||||
race_t *getrandomrace(cell_t *c, int forcedepth) {
|
||||
//int rarity;
|
||||
race_t *r;
|
||||
race_t *poss[MAXRANDOMLFCANDIDATES];
|
||||
|
@ -4622,7 +4622,7 @@ race_t *getrandomrace(map_t *map, int forcedepth) {
|
|||
if (forcedepth != NA) {
|
||||
depth = forcedepth;
|
||||
} else {
|
||||
depth = getmapdifficulty(map);
|
||||
depth = getmapdifficulty(c ? c->map : NULL);
|
||||
}
|
||||
|
||||
getrarity(depth, &raritymin, &raritymax, RARITYVARIANCELF, B_TRUE);
|
||||
|
@ -4641,8 +4641,8 @@ race_t *getrandomrace(map_t *map, int forcedepth) {
|
|||
// correct rarity?
|
||||
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (map) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, map->habitat, NA, NA, NULL);
|
||||
if (c) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->map->habitat, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
|
@ -4654,6 +4654,21 @@ race_t *getrandomrace(map_t *map, int forcedepth) {
|
|||
}
|
||||
}
|
||||
|
||||
if (valid && c) {
|
||||
// can it go into the cell?
|
||||
if (hasobwithflag(c->obpile, F_DEEPWATER)) {
|
||||
// water
|
||||
if (!hasflag(r->flags, F_AQUATIC) && (r->raceclass->id != RC_AQUATIC)) {
|
||||
// not aquatic
|
||||
valid = B_FALSE;
|
||||
}
|
||||
} else {
|
||||
// no water
|
||||
if (hasflag(r->flags, F_NEEDSWATER)) {
|
||||
valid = B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
if (db) dblog("-> possibility: %s, rarity=%d",r->name, rarflag->val[1]);
|
||||
|
@ -5416,6 +5431,18 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
msg("You can now hide even when monsters are nearby.");
|
||||
}
|
||||
}
|
||||
} else if (id == SK_SWIMMING) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_NOVICE) {
|
||||
msg("You can now swim.");
|
||||
} else if ((f->val[1] >= PR_BEGINNER) && (f->val[1] <= PR_SKILLED)) {
|
||||
msg("You can now swim a bit faster.");
|
||||
} else if (f->val[1] == PR_EXPERT) {
|
||||
msg("You can now attack awkwardly and cast spells while swimming.");
|
||||
} else if (f->val[1] == PR_MASTER) {
|
||||
msg("You can now attack while swimming with no penalty.");
|
||||
}
|
||||
}
|
||||
} else if (id == SK_TECHUSAGE) {
|
||||
objecttype_t *ot;
|
||||
// automatically make known all tech <= our skill level
|
||||
|
@ -5541,7 +5568,6 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
|
||||
if (db) {
|
||||
sprintf(buf2, "calling givestartobs for %s",lf->race->name);
|
||||
dbtimestart(buf2);
|
||||
}
|
||||
|
||||
// give start objects and id them
|
||||
|
@ -5582,7 +5608,6 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
|
||||
if (f->id == F_STARTOB) {
|
||||
assert(strlen(f->text) > 0);
|
||||
if (db) dbtime(f->text);
|
||||
if (rnd(1,100) <= f->val[0]) {
|
||||
o = addob(lf->pack, f->text);
|
||||
}
|
||||
|
@ -5591,14 +5616,12 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
int counter = 0;
|
||||
if (db) {
|
||||
sprintf(buf2, "calling startobdt");
|
||||
dbtime(buf2);
|
||||
}
|
||||
while (!getrandomobwithdt(lf->cell->map, f->val[1], buf)) {
|
||||
counter++;
|
||||
}
|
||||
if (db) {
|
||||
sprintf(buf2, "finished startobdt (needed %d tries)", counter);
|
||||
dbtime(buf2);
|
||||
}
|
||||
//assert(strlen(buf) > 0);
|
||||
o = addob(lf->pack, buf);
|
||||
|
@ -5608,7 +5631,6 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
int counter = 0;
|
||||
if (db) {
|
||||
sprintf(buf2, "calling startobclass");
|
||||
dbtime(buf2);
|
||||
}
|
||||
//obdb = B_TRUE;
|
||||
while (!getrandomobwithclass(lf->cell->map, f->val[1], buf, f->val[2])) {
|
||||
|
@ -5617,7 +5639,6 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
//obdb = B_FALSE;
|
||||
if (db) {
|
||||
sprintf(buf2, "finished startobclass (needed %d tries)", counter);
|
||||
dbtime(buf2);
|
||||
}
|
||||
//if (strlen(buf) <= 0);
|
||||
o = addob(lf->pack, buf);
|
||||
|
@ -5641,17 +5662,14 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) {
|
|||
}
|
||||
|
||||
// now remove startob flags so we don't get them again!
|
||||
if (db) dbtime("killing startflags");
|
||||
killflagsofid(fp, F_STARTOB);
|
||||
killflagsofid(fp, F_STARTOBDT);
|
||||
killflagsofid(fp, F_STARTOBCLASS);
|
||||
if (db) dbtime("finished killing startflags");
|
||||
|
||||
// make sure lf doesn't start off burdened!
|
||||
while (isburdened(lf)) {
|
||||
modattr(lf, A_STR, 1); // get stronger
|
||||
}
|
||||
if (db) dbtimeend("done.");
|
||||
}
|
||||
|
||||
void givestartskills(lifeform_t *lf, flagpile_t *fp) {
|
||||
|
@ -6382,6 +6400,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LOCKPICKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LONGBLADES, NA, NA, NULL);
|
||||
|
@ -6412,9 +6431,10 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_CON, CN_HEALTHY, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_FIRSTAID, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL);
|
||||
|
@ -6442,6 +6462,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL);
|
||||
// gained skills
|
||||
|
@ -6463,8 +6484,10 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_EVASION, 30, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SPELLCASTING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SS_FIRE, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SS_COLD, NA, NA, NULL);
|
||||
|
@ -6482,6 +6505,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
|
@ -6515,6 +6539,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_ADEPT, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
|
@ -6542,6 +6567,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL);
|
||||
|
@ -6610,7 +6636,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_IFPCT, 50, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_IFPCT, 50, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANCAST, OT_S_CONECOLD, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANCAST, OT_S_COLDRAY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_IFPCT, 33, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANCAST, OT_S_HEALINGMIN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_IFPCT, 33, NA, NA, NULL);
|
||||
|
@ -6628,6 +6654,7 @@ void initrace(void) {
|
|||
// race classes
|
||||
addraceclass(RC_OTHER, "misc. creature", "miscellaneous creatures", SK_NONE);
|
||||
addraceclass(RC_ANIMAL, "animal", "animals and insects", SK_LORE_NATURE);
|
||||
addraceclass(RC_AQUATIC, "aquatic creature", "aquatic creatures", SK_LORE_NATURE);
|
||||
addraceclass(RC_DEMON, "demon", "demons", SK_LORE_DEMONS);
|
||||
addraceclass(RC_HUMANOID, "humanoid", "humanoid creatures", SK_LORE_HUMANOID);
|
||||
addraceclass(RC_INSECT, "insect", "insects and animals", SK_LORE_NATURE);
|
||||
|
@ -7679,7 +7706,104 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3");
|
||||
|
||||
// end monsters
|
||||
// fish
|
||||
addrace(R_CRAB, "giant crab", 250, ';', C_ORANGE, MT_FLESH, RC_AQUATIC);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL); // very high armour
|
||||
addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYSLOW, NA, NA, "");
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d4");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d4");
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||
addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC);
|
||||
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 1, -2, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2");
|
||||
addrace(R_PIRANHAKING, "king piranha", 1, ';', C_GREEN, MT_FLESH, RC_AQUATIC);
|
||||
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6");
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;");
|
||||
addrace(R_EELELEC, "electric eel", 120, ';', C_CYAN, MT_FLESH, RC_AQUATIC);
|
||||
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 2, 0, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, NA, NA, "1d6");
|
||||
addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL);
|
||||
addrace(R_EELGIANT, "giant eel", 150, ';', C_BLUE, MT_FLESH, RC_AQUATIC);
|
||||
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 68, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 5, 0, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;");
|
||||
|
||||
// plants
|
||||
addrace(R_CACTUS, "cactus", 30, 'F', C_YELLOW, MT_PLANT, RC_PLANT);
|
||||
|
@ -8069,6 +8193,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain");
|
||||
addrace(R_LEECH, "giant leech", 10, 'j', C_MAGENTA, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
|
||||
|
@ -8263,6 +8388,31 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;");
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addrace(R_SNAKEWATER, "water snake", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 85, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, "");
|
||||
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d4+1");
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^hissing");
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addrace(R_SPIDER, "giant spider", 5, 'S', C_GREY, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, "");
|
||||
addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, "");
|
||||
|
@ -8674,6 +8824,7 @@ void initrace(void) {
|
|||
}
|
||||
|
||||
int isairborne(lifeform_t *lf) {
|
||||
if (!lf) return B_FALSE;
|
||||
if (lfhasflag(lf, F_FLYING)) {
|
||||
return B_TRUE;
|
||||
} else if (lfhasflag(lf, F_LEVITATING)) {
|
||||
|
@ -8682,6 +8833,15 @@ int isairborne(lifeform_t *lf) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isaquatic(lifeform_t *lf) {
|
||||
if (lf->race->raceclass->id == RC_AQUATIC) {
|
||||
return B_TRUE;
|
||||
} else if (lfhasflag(lf, F_AQUATIC)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int isbleeding(lifeform_t *lf) {
|
||||
float hppct;
|
||||
hppct = ((float)lf->hp / (float) lf->maxhp) * 100;
|
||||
|
@ -9115,14 +9275,13 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
|||
map_t *m;
|
||||
lifeform_t *a;
|
||||
int i;
|
||||
int db = B_FALSE;
|
||||
//int db = B_FALSE;
|
||||
|
||||
assert(cell);
|
||||
if (cell->type != (celltype_t *) DUMMYCELLTYPE) {
|
||||
assert(!cell->type->solid);
|
||||
}
|
||||
|
||||
if (db) dbtimestart("startime addlf");
|
||||
|
||||
m = cell->map;
|
||||
|
||||
|
@ -9203,9 +9362,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
|||
// set race - this will inherit race flags
|
||||
a->race = NULL;
|
||||
|
||||
if (db) dbtime("before setrace done.");
|
||||
setrace(a, rid, B_FALSE);
|
||||
if (db) dbtime("setrace done.");
|
||||
|
||||
|
||||
// update other things
|
||||
|
@ -9213,16 +9370,13 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
|||
|
||||
// give start objetcs
|
||||
if ((gamemode != GM_LOADING) && (gamemode != GM_VALIDATION)) {
|
||||
if (db) dbtime("about to outfitlf.");
|
||||
outfitlf(a);
|
||||
if (db) dbtime("done outfitlf.");
|
||||
}
|
||||
a->created = B_TRUE;
|
||||
a->born = B_TRUE; // now finished creating it.
|
||||
if ((gamemode == GM_GAMESTARTED) && cansee(player, a)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
if (db) dbtimeend("addlf");
|
||||
return a;
|
||||
}
|
||||
|
||||
|
@ -9374,6 +9528,41 @@ void addtrail(lifeform_t *lf, int dir) {
|
|||
}
|
||||
}
|
||||
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed) {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
if (!isairborne(lf)) {
|
||||
for (o = lf->cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_REDUCEMOVEMENT);
|
||||
if (f) {
|
||||
if (hasflag(o->flags, F_DEEPWATER)) {
|
||||
int modamt = 0;
|
||||
// water
|
||||
if (isaquatic(lf)) {
|
||||
modamt = 0;
|
||||
} else {
|
||||
switch (getskill(lf, SK_SWIMMING)) {
|
||||
default:
|
||||
case PR_NOVICE:
|
||||
case PR_INEPT: modamt = f->val[0]; break; // normal penalty
|
||||
case PR_BEGINNER: modamt = f->val[0] - 2; break;
|
||||
case PR_ADEPT: modamt = 0; break;
|
||||
case PR_SKILLED: modamt = -1; break;
|
||||
case PR_EXPERT: modamt = -2; break;
|
||||
case PR_MASTER: modamt = -2; break;
|
||||
}
|
||||
}
|
||||
limit(&modamt, 0, 5);
|
||||
*speed += (modamt * SPEEDUNIT);
|
||||
} else {
|
||||
// something else
|
||||
*speed += (f->val[0] * SPEEDUNIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
|
||||
flag_t *f;
|
||||
if (isimmuneto(lf->flags, damtype)) {
|
||||
|
@ -9745,6 +9934,10 @@ void autotarget(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
int isswimming(lifeform_t *lf) {
|
||||
if (!lf) return B_FALSE;
|
||||
if (gamemode != GM_GAMESTARTED) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if (!isairborne(lf) &&
|
||||
hasobwithflag(lf->cell->obpile, F_DEEPWATER) &&
|
||||
getskill(lf, SK_SWIMMING)) {
|
||||
|
@ -10602,19 +10795,13 @@ int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seete
|
|||
|
||||
// give initial equiment / skills to a lifeform
|
||||
void outfitlf(lifeform_t *lf) {
|
||||
int db = B_FALSE;
|
||||
if (db) dbtimestart("outfitlf");
|
||||
//int db = B_FALSE;
|
||||
givestartobs(lf, lf->flags);
|
||||
if (db) dbtime("finished giveobs");
|
||||
givestartskills(lf, lf->flags);
|
||||
if (db) dbtime("finished givestartskills");
|
||||
autoskill(lf);
|
||||
if (db) dbtime("finished autoskill");
|
||||
|
||||
// weild/wear stuff
|
||||
autoweild(lf);
|
||||
if (db) dbtime("finished autoweild");
|
||||
if (db) dbtimeend("outfitlf done");
|
||||
}
|
||||
|
||||
|
||||
|
@ -12147,6 +12334,11 @@ void stoprunning(lifeform_t *lf) {
|
|||
if (f) {
|
||||
killflag(f);
|
||||
}
|
||||
f = lfhasflag(lf, F_SPRINTING);
|
||||
if (f && f->val[0]) {
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if this object is ammo, and we are using a gun
|
||||
|
@ -12236,6 +12428,7 @@ void taketime(lifeform_t *lf, long howlong) {
|
|||
int db = B_FALSE;
|
||||
map_t *map;
|
||||
|
||||
|
||||
if (lfhasflag(lf, F_NOTIME)) {
|
||||
return;
|
||||
}
|
||||
|
@ -12409,6 +12602,21 @@ void turneffectslf(lifeform_t *lf) {
|
|||
if (isdead(lf)) return;
|
||||
}
|
||||
}
|
||||
// suffocate?
|
||||
if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You are suffocating without water to breath!");
|
||||
} else if (cansee(player, lf)) {
|
||||
int dam;
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s is suffocating!", lfname);
|
||||
dam = lf->maxhp / 3;
|
||||
limit(&dam, 1, NA);
|
||||
losehp(lf, dam, DT_DIRECT, NULL, "suffocation");
|
||||
if (isdead(lf)) return;
|
||||
}
|
||||
}
|
||||
|
||||
// get more hungry
|
||||
modhunger(lf, 1);
|
||||
|
@ -13233,13 +13441,18 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
dblog("ERROR - unlinked stairs!\n");
|
||||
msg("ERROR - unlinked stairs!\n");
|
||||
} else {
|
||||
enum HABITAT newhabitat;
|
||||
int newregion;
|
||||
// generate a new map! this will fill in the destination of our stairs
|
||||
newmap = addmap();
|
||||
if (newdepth == 0) {
|
||||
createmap(newmap, newdepth, RG_WORLDMAP, AUTO, curmap, dir);
|
||||
newregion = RG_WORLDMAP;
|
||||
newhabitat = AUTO;
|
||||
} else {
|
||||
createmap(newmap, newdepth, lf->cell->map->region, AUTO, curmap, dir);
|
||||
newregion = lf->cell->map->region;
|
||||
newhabitat = AUTO;
|
||||
}
|
||||
createmap(newmap, newdepth, newregion, newhabitat, curmap, dir);
|
||||
// link our stairs to the new map.
|
||||
//linkstairs(o);
|
||||
|
||||
|
@ -13356,7 +13569,12 @@ int validateraces(void) {
|
|||
|
||||
// add flags based on raceclass
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
if (r->raceclass->id == RC_UNDEAD) {
|
||||
if (r->raceclass->id == RC_AQUATIC) {
|
||||
addflag(r->flags, F_HASSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
|
||||
addflag(r->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(r->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
|
||||
} else if (r->raceclass->id == RC_UNDEAD) {
|
||||
addflag(r->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
|
||||
addflag(r->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
|
||||
addflag(r->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
|
||||
|
|
4
lf.h
4
lf.h
|
@ -8,6 +8,7 @@ raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum
|
|||
skill_t *addskill(enum SKILL id, char *name, char *desc);
|
||||
void addtrail(lifeform_t *lf, int dir);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
||||
void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o);
|
||||
int areallies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
|
@ -147,7 +148,7 @@ int getraceclass(lifeform_t *lf);
|
|||
int getracerarity(map_t *map, enum RACE rid);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
race_t *getrandomrace(map_t *map, int forcedepth);
|
||||
race_t *getrandomrace(cell_t *c, int forcedepth);
|
||||
race_t *getreallyrandomrace(void);
|
||||
enum SKILL getrandomskill(void);
|
||||
object_t *getrestob(lifeform_t *lf);
|
||||
|
@ -191,6 +192,7 @@ void initrace(void);
|
|||
void initskills(void);
|
||||
void interrupt(lifeform_t *lf);
|
||||
int isairborne(lifeform_t *lf);
|
||||
int isaquatic(lifeform_t *lf);
|
||||
int isbleeding(lifeform_t *lf);
|
||||
int isblind(lifeform_t *lf);
|
||||
enum BURDENED isburdened(lifeform_t *lf);
|
||||
|
|
71
map.c
71
map.c
|
@ -125,7 +125,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
}
|
||||
|
||||
if ((raceid == R_NONE) || (raceid == R_RANDOM)) {
|
||||
r = getrandomrace(c->map, 0);
|
||||
r = getrandomrace(c, 0);
|
||||
} else {
|
||||
r = findrace(raceid);
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
|||
|
||||
// draw highest object in sort order
|
||||
o = gettopobject(c);
|
||||
if (o) {
|
||||
if (o && !hasflag(o->flags, F_NOGLYPH)) {
|
||||
// return the object's glyph
|
||||
*g = *(getglyph(o));
|
||||
} else {
|
||||
|
@ -1089,7 +1089,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
createroom(map, bestx,besty, w,h, i);
|
||||
|
||||
/*
|
||||
// maybe make it a special room
|
||||
if (getrand(1,100) <= CH_SPECIALROOM) {
|
||||
int curpos;
|
||||
int roomid;
|
||||
|
@ -1700,6 +1699,41 @@ void createroom(map_t *map, int minx, int miny, int w, int h, int roomid) {
|
|||
makedoor(cell);
|
||||
}
|
||||
|
||||
// maybe make it a special room
|
||||
if (rnd(1,100) <= getspecialroomchance(map)) {
|
||||
enum SPECIALROOMTYPE rt;
|
||||
rt = getspecialroomtype(map);
|
||||
if (rt == RT_FLOODED) {
|
||||
int sx,sy,ex,ey;
|
||||
char wtype[BUFLEN];
|
||||
switch (rnd(1,2)) {
|
||||
case 1: strcpy(wtype, "deep water"); break;
|
||||
case 2: strcpy(wtype, "shallow water"); break;
|
||||
}
|
||||
switch (rnd(1,2)) {
|
||||
case 1: // entire room flooded
|
||||
sx = minx+1;
|
||||
sy = miny+1;
|
||||
ex = maxx-1;
|
||||
ey = maxy-1;
|
||||
break;
|
||||
case 2: // small walkway around the edge
|
||||
sx = minx+2;
|
||||
sy = miny+2;
|
||||
ex = maxx-2;
|
||||
ey = maxy-2;
|
||||
if (sx > ex) sx = ex;
|
||||
if (sy > ey) sy = ey;
|
||||
break;
|
||||
}
|
||||
for (y = sy; y <= ey; y++) {
|
||||
for (x = sx; x <= ex; x++) {
|
||||
cell = getcellat(map, x, y);
|
||||
addob(cell->obpile, wtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dirtox(int dt, int dir) {
|
||||
|
@ -1888,6 +1922,7 @@ cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
|||
// oooooo TODO handle side being diagonal
|
||||
switch (side) {
|
||||
case D_N:
|
||||
case DC_N:
|
||||
x = 0;
|
||||
y = 0;
|
||||
xinc = 1;
|
||||
|
@ -1895,6 +1930,7 @@ cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
|||
bestcell = getcellat(m, lf->cell->x, 0);
|
||||
break;
|
||||
case D_E:
|
||||
case DC_E:
|
||||
x = m->w-1;
|
||||
y = 0;
|
||||
xinc = 0;
|
||||
|
@ -1902,6 +1938,7 @@ cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
|||
bestcell = getcellat(m, m->w - 1, lf->cell->y);
|
||||
break;
|
||||
case D_S:
|
||||
case DC_S:
|
||||
x = 0;
|
||||
y = m->h - 1;
|
||||
xinc = 1;
|
||||
|
@ -1909,6 +1946,7 @@ cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf) {
|
|||
bestcell = getcellat(m, lf->cell->x, m->h - 1);
|
||||
break;
|
||||
case D_W:
|
||||
case DC_W:
|
||||
x = 0;
|
||||
y = 0;
|
||||
xinc = 0;
|
||||
|
@ -2160,6 +2198,31 @@ int getobchance(int habitat) {
|
|||
// default of no objects
|
||||
return 0;
|
||||
}
|
||||
// chance that a room is a 'special' one
|
||||
int getspecialroomchance(map_t *m) {
|
||||
switch (m->habitat) {
|
||||
case H_DUNGEON:
|
||||
return 5;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
// default of no chance
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum SPECIALROOMTYPE getspecialroomtype(map_t *m) {
|
||||
if (m->habitat == H_DUNGEON) {
|
||||
/*
|
||||
switch (rnd(1,1)) {
|
||||
|
||||
}
|
||||
*/
|
||||
return RT_FLOODED;
|
||||
}
|
||||
return RT_NONE;
|
||||
}
|
||||
|
||||
|
||||
// chance of each empty cell in a map has of getting an object/monster
|
||||
int getthingchance(int habitat) {
|
||||
switch (habitat) {
|
||||
|
@ -2875,7 +2938,7 @@ void setcellknown(cell_t *cell, int forcelev) {
|
|||
}
|
||||
if (slev >= PR_ADEPT) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (o->type->obclass->id == OC_DFEATURE) {
|
||||
if ((o->type->obclass->id == OC_DFEATURE) || (o->type->obclass->id == OC_TERRAIN)) {
|
||||
if (!issecretdoor(o)) {
|
||||
cell->knownglyph = *(getglyph(o));
|
||||
}
|
||||
|
|
4
map.h
4
map.h
|
@ -23,7 +23,7 @@ int countadjcellswithflag(cell_t *cell, enum FLAG fid);
|
|||
int countcellexits(cell_t *cell);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createmap(map_t *map, int dungeonid, int depth, int habitat, map_t *parentmap, int exitdir);
|
||||
void createmap(map_t *map, int depth, int region, int habitat, map_t *parentmap, int exitdir);
|
||||
void createroom(map_t *map, int minx, int miny, int w, int h, int roomid);
|
||||
int dirtox(int dt, int dir);
|
||||
int dirtoy(int dt, int dir);
|
||||
|
@ -41,6 +41,8 @@ void forgetcells(map_t *map, int amt);
|
|||
cell_t *getcellindir(cell_t *cell, int dir);
|
||||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||
int getobchance(int habitat);
|
||||
int getspecialroomchance(map_t *m);
|
||||
enum SPECIALROOMTYPE getspecialroomtype(map_t *m);
|
||||
int getthingchance(int habitat);
|
||||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob);
|
||||
|
|
120
move.c
120
move.c
|
@ -135,15 +135,32 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
rdata = NULL;
|
||||
}
|
||||
|
||||
// never dangerous if there's someone there, since we'll
|
||||
// attack them instead of moving!
|
||||
if (cell->lf) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// obvious things that you can see
|
||||
if (!onlyifknown || (haslos(lf, cell) && !lfhasflag(lf, F_UNDEAD))) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f) {
|
||||
if (!isairborne(lf) && (getobdepth(o, lf) >= DP_HEAD) && !getskill(lf, SK_SWIMMING)) {
|
||||
// non swimming creature in water?
|
||||
if (!isairborne(lf) && (getobdepth(o, lf) >= DP_HEAD)) {
|
||||
if (getskill(lf, SK_SWIMMING) - isburdened(lf) <= 0) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// water needing creature out of water?
|
||||
if (lfhasflag(lf, F_NEEDSWATER)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
*error = E_DANGEROUS;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -221,7 +238,7 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
// so that we are able to attack monsters embedded in walls.
|
||||
if (cell->lf && (cell->lf != lf)) {
|
||||
// usually can't attack while swimming
|
||||
if (isswimming(lf) && (getskill(lf, SK_SWIMMING) <= PR_EXPERT)) {
|
||||
if (lf && isswimming(lf) && (getskill(lf, SK_SWIMMING) <= PR_EXPERT)) {
|
||||
if (!lfhasflag(lf, F_AQUATIC)) {
|
||||
if (error) *error = E_SWIMMING;
|
||||
return B_FALSE;
|
||||
|
@ -836,13 +853,17 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// remove grabs (but not attached things)
|
||||
f = lfhasflag(lf, F_GRABBING);
|
||||
// Note: only remove this from the person _being grabbed_.
|
||||
// if the grabb_er_ moves away, they'll drag the grabee with them.
|
||||
f = lfhasflag(lf, F_GRABBEDBY);
|
||||
if (f) {
|
||||
lifeform_t *grabee;
|
||||
grabee = findlf(NULL, f->val[0]);
|
||||
assert(grabee);
|
||||
killflagsofid(grabee->flags, F_GRABBEDBY);
|
||||
killflagsofid(lf->flags, F_GRABBING);
|
||||
lifeform_t *grabber;
|
||||
grabber = findlf(NULL, f->val[0]);
|
||||
assert(grabber);
|
||||
if (getcelldist(lf->cell, grabber->cell) > 1) {
|
||||
killflagsofid(grabber->flags, F_GRABBING);
|
||||
killflagsofid(lf->flags, F_GRABBEDBY);
|
||||
}
|
||||
}
|
||||
|
||||
// passwall ends when you walk onto a non-solid cell.
|
||||
|
@ -889,6 +910,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
msg("%s starts swimming.", lfname);
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
// stop sprinting
|
||||
stoprunning(lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1260,15 +1283,17 @@ 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
|
||||
stoprunning(lf);
|
||||
/*
|
||||
sf = lfhasflag(lf, F_SPRINTING);
|
||||
if (sf && sf->val[0]) {
|
||||
killflag(sf);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// locked?
|
||||
|
@ -1417,6 +1442,9 @@ int closedoor(lifeform_t *lf, object_t *o) {
|
|||
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
|
||||
if (lf) {
|
||||
// stop sprinting
|
||||
stoprunning(lf);
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You close %s.", obname);
|
||||
} else {
|
||||
|
@ -1767,15 +1795,19 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
|
||||
if (celldangerous(lf, cell, B_TRUE, &errcode)) {
|
||||
if ((errcode == E_AVOIDOB) && rdata) {
|
||||
char obname[BUFLEN];
|
||||
if (isplayer(lf)) {
|
||||
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
|
||||
char ques[BUFLEN];
|
||||
char ch;
|
||||
object_t *avoidob;
|
||||
avoidob = (object_t *)rdata;
|
||||
getobname(avoidob, obname, avoidob->amt);
|
||||
sprintf(ques, "Really %s into %s?", getmoveverb(lf), obname);
|
||||
if ((errcode == E_AVOIDOB) && rdata) {
|
||||
char obname[BUFLEN];
|
||||
object_t *avoidob;
|
||||
avoidob = (object_t *)rdata;
|
||||
getobname(avoidob, obname, avoidob->amt);
|
||||
sprintf(ques, "Really %s into %s?", getmoveverb(lf), obname);
|
||||
} else {
|
||||
sprintf(ques, "Really %s there?", getmoveverb(lf));
|
||||
}
|
||||
ch = askchar(ques, "yn","n", B_TRUE);
|
||||
if (ch != 'y') {
|
||||
return B_TRUE;
|
||||
|
@ -1814,13 +1846,15 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
|
||||
lifeform_t *l;
|
||||
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
||||
if (cansee(l, lf)) {
|
||||
flag_t *tf;
|
||||
flag_t *tf;
|
||||
if (isplayer(lf)) {
|
||||
tf = ispetortarget(l, lf);
|
||||
if (tf) {
|
||||
// update text field
|
||||
free(tf->text);
|
||||
asprintf(&(tf->text), "%d", dir);
|
||||
if (cansee(l, lf)) {
|
||||
// update text field
|
||||
free(tf->text);
|
||||
asprintf(&(tf->text), "%d", dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1832,9 +1866,21 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
taketime(lf, getmovespeed(lf));
|
||||
}
|
||||
|
||||
// attached things will move the same direction if they can
|
||||
// attached lfs or lfs you have grabbed will move the same direction if they can
|
||||
for (alf = cell->map->lf ; alf ; alf = alf->next) {
|
||||
int willdrag = B_FALSE;
|
||||
int attached = B_FALSE;
|
||||
int grabbed = B_FALSE;
|
||||
if (lfhasflagval(alf, F_ATTACHEDTO, lf->id, NA, NA, NULL)) {
|
||||
willdrag = B_TRUE;
|
||||
attached = B_TRUE;
|
||||
grabbed = B_FALSE;
|
||||
} else if (lfhasflagval(lf, F_GRABBING, alf->id, NA, NA, NULL)) {
|
||||
willdrag = B_TRUE;
|
||||
attached = B_FALSE;
|
||||
grabbed = B_TRUE;
|
||||
}
|
||||
if (willdrag) {
|
||||
// if the lifeform we were attached to just moved away from us,
|
||||
// try to stay with them.
|
||||
if (getcelldist(alf->cell,lf->cell) > 1) {
|
||||
|
@ -1842,10 +1888,30 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
newdir = getdirtowards(alf->cell, lf->cell, alf, B_FALSE, DT_ORTH);
|
||||
// do a manual canmove check here first, to avoid 'the stirge flies into a wall'
|
||||
// if the move fails.
|
||||
if ((newdir != D_NONE) && moveclear(alf, newdir, NULL)) {
|
||||
trymove(alf, newdir, B_FALSE);
|
||||
//
|
||||
// but DONT do the check if you're dragging someone you grabbed. otherwise
|
||||
// moveclear() will say "can't move because someone is holding you"
|
||||
if (newdir != D_NONE) {
|
||||
cell_t *nc;
|
||||
nc = getcellindir(alf->cell, newdir);
|
||||
if (nc && cellwalkable(alf, nc, NULL)) {
|
||||
if (isplayer(lf)) {
|
||||
char alfname[BUFLEN];
|
||||
getlfname(alf, alfname);
|
||||
msg("You drag %s along.", alfname);
|
||||
} else if (isplayer(alf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s drags you along.", lfname);
|
||||
} else if (cansee(player, lf) || cansee(player, alf)) {
|
||||
char lfname[BUFLEN],alfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
getlfname(alf, alfname);
|
||||
msg("%s drags %s along.", lfname, alfname);
|
||||
}
|
||||
movelf(alf, nc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
3
nexus.c
3
nexus.c
|
@ -513,6 +513,7 @@ void donextturn(map_t *map) {
|
|||
who = map->lf;
|
||||
if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name);
|
||||
|
||||
|
||||
assert(who->timespent == 0);
|
||||
|
||||
turneffectslf(who);
|
||||
|
@ -1019,6 +1020,8 @@ int rollhitdice(lifeform_t *lf) {
|
|||
}
|
||||
if (db) dblog("TOTAL: %d",roll);
|
||||
roll = roll + (int)((float)roll * (mod/100));
|
||||
// must be at least 1!!
|
||||
limit(&roll, 1, NA);
|
||||
if (db) dblog(" -> modified to: %d",roll);
|
||||
return roll;
|
||||
}
|
||||
|
|
109
objects.c
109
objects.c
|
@ -56,6 +56,7 @@ objecttype_t *lastot = NULL;
|
|||
|
||||
enum OBCLASS sortorder[] = {
|
||||
OC_EFFECT,
|
||||
OC_TERRAIN,
|
||||
OC_MONEY,
|
||||
OC_WEAPON,
|
||||
OC_MISSILE,
|
||||
|
@ -831,7 +832,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
where = getoblocation(o);
|
||||
// select random race
|
||||
if (where) {
|
||||
corpserace = getrandomrace(where->map, 0);
|
||||
corpserace = getrandomrace(where, 0);
|
||||
} else {
|
||||
// ie. vending machine
|
||||
corpserace = getrandomrace(NULL, 0);
|
||||
|
@ -1130,7 +1131,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
}
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (where->where && haslos(player, where->where)) {
|
||||
if (o && where->where && !hasflag(o->flags, F_NOGLYPH) && haslos(player, where->where) ) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -4694,6 +4695,7 @@ void initobjects(void) {
|
|||
|
||||
// object classes
|
||||
addoc(OC_DFEATURE, "Dungeon Features", "Doors, etc.", '\\', C_GREY);
|
||||
addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY);
|
||||
addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY);
|
||||
addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY);
|
||||
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4872,7 +4874,8 @@ 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_WATERSHALLOW, "shallow water", "Waist-deep water.", MT_WATER, 150, OC_DFEATURE);
|
||||
// terrain
|
||||
addot(OT_WATERSHALLOW, "shallow water", "Waist-deep water.", MT_WATER, 150, OC_TERRAIN);
|
||||
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{");
|
||||
|
@ -4884,7 +4887,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_REDUCEMOVEMENT, 3, NA, NA, NULL);
|
||||
|
||||
addot(OT_WATERDEEP, "deep water", "Very deep water.", MT_WATER, 300, OC_DFEATURE);
|
||||
addot(OT_WATERDEEP, "deep water", "Very deep water.", MT_WATER, 300, OC_TERRAIN);
|
||||
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDBLUE, NA, NA, "{");
|
||||
|
@ -5478,6 +5481,13 @@ void initobjects(void) {
|
|||
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);
|
||||
addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity.", 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, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, 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);
|
||||
|
@ -5570,7 +5580,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_CONECOLD, "cone of cold", "Shoots a blast of ice cold air, dealing 2-10 cold damage.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 2-10 cold damage.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
|
@ -5752,6 +5762,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
addot(OT_S_FLOOD, "flood", "Converts the earth directly into water, creating a deep pool.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
///////////////////
|
||||
// gravity
|
||||
///////////////////
|
||||
|
@ -6263,8 +6277,8 @@ void initobjects(void) {
|
|||
// elemental - ice
|
||||
addot(OT_SB_CHILL, "spellbook of chill", "Teaches the spell 'chill'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CHILL, NA, NA, NULL);
|
||||
addot(OT_SB_CONECOLD, "spellbook of cone of cold", "Teaches the spell 'cone of cold'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CONECOLD, NA, NA, NULL);
|
||||
addot(OT_SB_COLDRAY, "spellbook of cone of cold", "Teaches the spell 'cone of cold'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_COLDRAY, NA, NA, NULL);
|
||||
addot(OT_SB_FROSTBITE, "spellbook of frostbite", "Teaches the spell 'frostbite'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_FROSTBITE, NA, NA, NULL);
|
||||
addot(OT_SB_FREEZEOB, "spellbook of freezing touch", "Teaches the spell 'freezing touch'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
|
@ -6404,7 +6418,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL);
|
||||
addot(OT_WAND_COLD, "wand of cold", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CONECOLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_COLDRAY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_WAND_FIRE, "wand of fire", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
|
@ -6467,12 +6481,10 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_BUGLAMP, "glowing flask", "A glass flask with a glowbug corpse inside.", MT_GLASS, 0.3, OC_TOOLS);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "!");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_PRODUCESLIGHT, 2, IFKNOWN, NULL);
|
||||
|
||||
addot(OT_CANDLE, "candle", "A short wax candle.", MT_WAX, 0.2, OC_TOOLS);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6486,7 +6498,6 @@ void initobjects(void) {
|
|||
addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder.", MT_METAL, 0.5, OC_TOOLS);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of black powder");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6496,7 +6507,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_LAMPOIL, "oil lamp", "An oil-powered lamp which produces light.", MT_METAL, 1, OC_TOOLS);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6509,7 +6519,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
|
||||
|
||||
addot(OT_LANTERNOIL, "oil lantern", "An oil-powered lantern which produces a lot of light.", MT_METAL, 1, OC_TOOLS);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6523,7 +6532,6 @@ void initobjects(void) {
|
|||
|
||||
addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks.", MT_METAL, 0.05, OC_TOOLS);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 10, B_DIEONFAIL, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6537,7 +6545,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6548,9 +6555,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_FIRE, NA, NA, "1d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
|
||||
addot(OT_TOWEL, "towel", "An large absorbent cloth used for drawing off moisture.", MT_CLOTH, 1.5, OC_TOOLS);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// tech - l0
|
||||
addot(OT_CREDITCARD, "credit card", "A rectangular plastic card.", MT_PLASTIC, 0.01, OC_TECH);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6746,7 +6756,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SLIPPERY, 14, NA, NA, NULL);
|
||||
addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC);
|
||||
addflag(lastot->flags, F_EDIBLE, B_TRUE, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
||||
|
@ -7003,7 +7013,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NO_PLURAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "."); // ie not really visible
|
||||
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
// NOTE: must add F_TRAIL when creating this object.
|
||||
addot(OT_SCENT, "scent", "The scent of a creature, only perceivable to those with an enhanced sense of smell.", MT_NOTHING, 0, OC_MISC);
|
||||
|
@ -7011,7 +7021,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NO_PLURAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "."); // ie not really visible
|
||||
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
// NOTE: must add F_TRAIL when creating this object.
|
||||
|
||||
|
@ -8715,7 +8725,7 @@ void killob(object_t *o) {
|
|||
// remove flags conferred by this object
|
||||
if (o->pile->owner) {
|
||||
loseobflags(o->pile->owner, o, ALLCONFERRED);
|
||||
} else if (o->pile->where && !o->pile->where->lf && haslos(player, o->pile->where)) {
|
||||
} else if (o->pile->where && !o->pile->where->lf && !hasflag(o->flags, F_NOGLYPH) && haslos(player, o->pile->where)) {
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -9020,7 +9030,7 @@ void makewet(object_t *o, int amt) {
|
|||
}
|
||||
} else {
|
||||
// rust
|
||||
if (haslos(player, loc)) {
|
||||
if (haslos(player, loc) && !isdead(player)) {
|
||||
msg("%s rust%s.",obnamefull, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
f = addflag(o->flags, F_RUSTED, amt, NA, NA, NULL);
|
||||
|
@ -9047,7 +9057,7 @@ void makewet(object_t *o, int amt) {
|
|||
} else {
|
||||
|
||||
// get wet
|
||||
if (haslos(player, loc)) {
|
||||
if (haslos(player, loc) && !isdead(player)) {
|
||||
msg("%s get%s wet.",obnamefull, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
f = addflag(o->flags, F_WET, amt, WETTIME, NA, NULL);
|
||||
|
@ -9151,7 +9161,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
|
|||
}
|
||||
}
|
||||
|
||||
if (dst->where && !dst->where->lf && haslos(player, dst->where)) {
|
||||
if (o && dst->where && !dst->where->lf && !hasflag(o->flags, F_NOGLYPH) && haslos(player, dst->where)) {
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
}
|
||||
|
@ -10040,18 +10050,18 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
if (c->type->solid) {
|
||||
if (isdiggable(c)) {
|
||||
// replace wall
|
||||
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig through the wall.");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s digs through a wall.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
// replace wall
|
||||
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||
// redraw screen
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
//drawscreen();
|
||||
// takes extra time
|
||||
taketime(lf, getactspeed(lf)*9);
|
||||
} else {
|
||||
|
@ -10078,15 +10088,16 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
// TODO: metal doors are immune to CHOP damage
|
||||
if (!isimmuneto(door->flags, DT_CHOP)) {
|
||||
taketime(lf, getactspeed(lf));
|
||||
removeob(door, door->amt);
|
||||
if (isplayer(lf)) {
|
||||
msg("You smash open a door!");
|
||||
needredraw = B_TRUE;
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s smashes open a door.",lfname);
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
removeob(door, door->amt);
|
||||
needredraw = B_TRUE;
|
||||
drawscreen();
|
||||
failed = B_FALSE;
|
||||
}
|
||||
|
@ -10195,6 +10206,22 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
nothinghappens();
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_TOWEL) {
|
||||
object_t *oo;
|
||||
if (isplayer(lf)) {
|
||||
msg("You dry yourself off with %s.", obname);
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s dries itself off with %s.", lfname, obname);
|
||||
}
|
||||
// make objects dry
|
||||
for (oo = lf->pack->first ;oo ; oo = oo->next) {
|
||||
if (isequipped(oo)) {
|
||||
killflagsofid(oo->flags, F_WET);
|
||||
}
|
||||
}
|
||||
taketime(lf, getactspeed(lf));
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -11836,6 +11863,12 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
|
||||
reason = E_OK;
|
||||
|
||||
// you can't throw with as much force while swimming.
|
||||
if (isswimming(thrower) && !firearm) {
|
||||
speed /= 2;
|
||||
limit(&speed, 1, NA);
|
||||
}
|
||||
|
||||
multiplier = speed / 2;
|
||||
|
||||
if (firearm) {
|
||||
|
@ -12097,6 +12130,21 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
acc = 100;
|
||||
}
|
||||
|
||||
// adjust for swimming
|
||||
if (isswimming(thrower)) {
|
||||
switch (getskill(thrower, SK_SWIMMING)) {
|
||||
default:
|
||||
case PR_INEPT: acc -= 40; break;
|
||||
case PR_NOVICE: acc -= 30; break;
|
||||
case PR_BEGINNER: acc -= 20; break;
|
||||
case PR_ADEPT: acc -= 10; break;
|
||||
case PR_SKILLED:
|
||||
case PR_EXPERT:
|
||||
case PR_MASTER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// roll for hit
|
||||
youhit = B_FALSE;
|
||||
// metal weapon versus magnetic shield?
|
||||
|
@ -12437,7 +12485,6 @@ void timeeffectsob(object_t *o) {
|
|||
// player now knows that this is blessed
|
||||
o->blessknown = B_TRUE;
|
||||
}
|
||||
//if (needredraw) drawlevelfor(player);
|
||||
// update location
|
||||
|
||||
//if (inv) killflag(inv);
|
||||
|
|
279
spell.c
279
spell.c
|
@ -92,6 +92,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) msg("You can't move!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't charge while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!range) {
|
||||
// get max range - based on speed.
|
||||
|
@ -164,6 +168,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
case R_CREEPINGCLAW:
|
||||
case R_LEECH:
|
||||
case R_SNAKETREE:
|
||||
case R_PIRANHAKING:
|
||||
strcpy(verb, "leap");
|
||||
break;
|
||||
default:
|
||||
|
@ -196,6 +201,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (!isplayer(user)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't cook while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
water = hasob(user->pack, OT_POT_WATER);
|
||||
if (!water || !isknown(water)) {
|
||||
msg("You need some water before you can cook.");
|
||||
|
@ -290,6 +299,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
object_t *o,*trapob = NULL;
|
||||
flag_t *trapflag = NULL;
|
||||
char buf[BUFLEN];
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't disarm traps while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// ask for direction
|
||||
if (!targcell) {
|
||||
int dirch;
|
||||
|
@ -372,6 +387,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (abilid == OT_A_FLURRY) {
|
||||
int dir;
|
||||
int dirch;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't make an attack flurry traps while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!isdualweilding(user)) {
|
||||
if (isplayer(user)) msg("You need two be dual-weilding to perform an attack flurry!");
|
||||
return B_TRUE;
|
||||
|
@ -534,6 +555,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char victimname[BUFLEN];
|
||||
int dodged = B_FALSE;
|
||||
cell_t *origcell;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't jump while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!targcell) {
|
||||
sprintf(buf, "Jump where (max distance 2)?");
|
||||
while (!targcell) {
|
||||
|
@ -664,6 +691,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
int slev;
|
||||
flag_t *f;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't sprint while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
f = lfhasflag(user, F_SPRINTING);
|
||||
if (f) {
|
||||
if (f->val[0]) {
|
||||
|
@ -998,6 +1030,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char dirch;
|
||||
char targetname[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You lack the stability for a heavy blow while swimming.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
wep = getweapon(user);
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < 3)) {
|
||||
|
@ -1056,6 +1093,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
int dir;
|
||||
cell_t *c;
|
||||
flag_t *f,*f2;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You cannot do that while swimming.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// take time
|
||||
// - NOTE: purposely using action speed, not weapon speed.
|
||||
taketime(user, getactspeed(user));
|
||||
|
@ -1076,6 +1119,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
killflag(f2);
|
||||
} else if (abilid == OT_A_HIDE) {
|
||||
int penalty = 0;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You can't hide while swimming!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (lfhasflag(user, F_HIDING)) {
|
||||
if (isplayer(user)) msg("You are already hiding!");
|
||||
return B_TRUE;
|
||||
|
@ -1102,6 +1151,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (!isplayer(user)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("That wouldn't be a good idea while swimming.");
|
||||
return B_TRUE;
|
||||
}
|
||||
if (!haslos(user, user->cell)) {
|
||||
msg("You can't inspect anything, since you can't see!");
|
||||
return B_TRUE;
|
||||
|
@ -1933,52 +1986,62 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (y = caster->cell->y - range ; y <= caster->cell->y + range; y++) {
|
||||
for (x = caster->cell->x - range ; x <= caster->cell->x + range; x++) {
|
||||
targcell = getcellat(caster->cell->map, x,y);
|
||||
if (targcell && (getcelldistorth(caster->cell, targcell) <= range)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster->cell, targcell, B_FALSE, NULL)) {
|
||||
char lfname[BUFLEN];
|
||||
// automatic hit
|
||||
getlfname(targcell->lf, lfname);
|
||||
if (haslos(caster, targcell)) {
|
||||
msg("%s %s chilled!",lfname,is(targcell->lf));
|
||||
if (targcell && (getcelldistorth(caster->cell, targcell) <= range) &&
|
||||
haslof(caster->cell, targcell, B_FALSE, NULL)) {
|
||||
if (targcell->lf) {
|
||||
if (targcell->lf != caster) {
|
||||
char lfname[BUFLEN];
|
||||
// automatic hit
|
||||
getlfname(targcell->lf, lfname);
|
||||
if (haslos(caster, targcell)) {
|
||||
msg("%s %s chilled!",lfname,is(targcell->lf));
|
||||
}
|
||||
losehp(targcell->lf, rolldie(1,8)+3, DT_COLD, caster, "a burst of coldness");
|
||||
}
|
||||
losehp(targcell->lf, rolldie(1,8)+3, DT_COLD, caster, "a burst of coldness");
|
||||
} else {
|
||||
// noone there, hit objects.
|
||||
damageallobs(NULL, targcell->obpile, 0, DT_COLD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_CONECOLD) {
|
||||
} else if (spellid == OT_S_COLDRAY) {
|
||||
char lfname[BUFLEN];
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell,i;
|
||||
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}', C_GREY);
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
msg("%s shoot%s a blast of coldness.",castername,isplayer(caster) ? "" : "s");
|
||||
msg("%s shoot%s a ray of coldness.",castername,isplayer(caster) ? "" : "s");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
target = haslf(targcell);
|
||||
if (target) {
|
||||
getlfname(target, lfname);
|
||||
// target takes magical damage
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y,
|
||||
targcell->x, targcell->y, retcell, &nretcell);
|
||||
|
||||
if (skillcheck(target, SC_DODGE, 20 + (power*2), 0)) {
|
||||
// miss
|
||||
if (cansee(caster, target)) {
|
||||
msg("A blast of coldness misses %s.",lfname);
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
target = haslf(retcell[i]);
|
||||
if (target) {
|
||||
getlfname(target, lfname);
|
||||
// target takes magical damage
|
||||
if (skillcheck(target, SC_DODGE, 20 + (power*2), 0)) {
|
||||
// miss
|
||||
if (cansee(player, target)) {
|
||||
msg("A ray of coldness misses %s.",lfname);
|
||||
}
|
||||
} else {
|
||||
// hit
|
||||
if (cansee(player, target)) {
|
||||
msg("A ray of coldness ray hits %s.",lfname);
|
||||
}
|
||||
losehp(target, rnd(2,5), DT_COLD, caster, "a blast of coldness");
|
||||
// ray stops here.
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// hit
|
||||
if (cansee(caster, target)) {
|
||||
msg("A blast of coldness ray hits %s.",lfname);
|
||||
}
|
||||
losehp(target, rnd(2,5), DT_COLD, caster, "a blast of coldness");
|
||||
}
|
||||
|
||||
} else {
|
||||
object_t *o, *nexto;
|
||||
for (o = targcell->obpile->first; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
takedamage(o, 0, DT_COLD);
|
||||
damageallobs(NULL, retcell[i]->obpile, 0, DT_COLD);
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_CREATEMONSTER) {
|
||||
|
@ -2557,6 +2620,45 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
brightflash(caster->cell, 2 + (power/4), player);
|
||||
} else if (spellid == OT_S_FLOOD) {
|
||||
int failed = B_FALSE;
|
||||
// ask for a target cell
|
||||
if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power)) return B_TRUE;
|
||||
if (targcell) {
|
||||
if (!targcell->type->solid) {
|
||||
// create water there
|
||||
object_t *o;
|
||||
o = addob(targcell->obpile, "deep water");
|
||||
if (o) {
|
||||
enum OBTYPE badoid[2];
|
||||
int i,amt;
|
||||
amt = ((power+1) * (power+1)) - 1;
|
||||
badoid[0] = OT_WATERDEEP;
|
||||
badoid[1] = OT_NONE;
|
||||
for (i = 0; i < amt; i++) {
|
||||
cell_t *c;
|
||||
c = real_getrandomadjcell(targcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_WALLSTOP, badoid);
|
||||
if (c) {
|
||||
addob(c->obpile, "deep water");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haslos(player, targcell)) {
|
||||
msg("A huge pool of water appears!");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_ENERGYBOLT) {
|
||||
char lfname[BUFLEN];
|
||||
char numbuf[BUFLEN];
|
||||
|
@ -2579,7 +2681,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(target, lfname);
|
||||
// target takes magical damage
|
||||
// ALWAYS hits.
|
||||
if (cansee(caster, target)) {
|
||||
if (cansee(player, target)) {
|
||||
if (power == 1) {
|
||||
msg("A bolt of energy hits %s.",lfname);
|
||||
} else {
|
||||
|
@ -2701,17 +2803,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("A dart of flame misses %s.",lfname);
|
||||
} else {
|
||||
// hit
|
||||
if (cansee(caster, target)) {
|
||||
if (cansee(player, target)) {
|
||||
msg("A dart of flame hits %s.",lfname);
|
||||
}
|
||||
losehp(target, rnd(1,6) + power, DT_FIRE, caster, "a dart of flame");
|
||||
}
|
||||
} else {
|
||||
object_t *o, *nexto;
|
||||
for (o = targcell->obpile->first; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
takedamage(o, 0, DT_FIRE);
|
||||
}
|
||||
damageallobs(NULL, targcell->obpile, 0, DT_FIRE);
|
||||
}
|
||||
} else if (spellid == OT_S_FLAMEBURST) {
|
||||
int range = 1;
|
||||
|
@ -3402,7 +3500,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
getlfname(target, lfname);
|
||||
// target takes magical damage
|
||||
// always hit
|
||||
if (cansee(caster, target)) {
|
||||
if (cansee(player, target)) {
|
||||
if (power == 1) {
|
||||
msg("A spike of mana hits %s.",lfname);
|
||||
} else {
|
||||
|
@ -3719,12 +3817,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// target gets saving throw to avoid...
|
||||
if (skillcheck(target, SC_DODGE, 20 + (power*2), 0)) {
|
||||
// miss
|
||||
if (cansee(caster, target)) {
|
||||
if (cansee(player, target)) {
|
||||
msg("A glob of venom misses %s.",lfname);
|
||||
}
|
||||
} else {
|
||||
// hit
|
||||
if (cansee(caster, target)) {
|
||||
if (cansee(player, target)) {
|
||||
msg("A glob of venom hits %s.",lfname);
|
||||
}
|
||||
if (!isimmuneto(target->flags, DT_POISON)) {
|
||||
|
@ -3732,11 +3830,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
} else {
|
||||
object_t *o, *nexto;
|
||||
for (o = targcell->obpile->first; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
takedamage(o, 0, DT_FIRE);
|
||||
}
|
||||
damageallobs(NULL, targcell->obpile, 0, DT_FIRE);
|
||||
}
|
||||
} else if (spellid == OT_S_POSSESSION) {
|
||||
char targname[BUFLEN];
|
||||
|
@ -4132,6 +4226,25 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
msg("%s flicker%s then vanishes!",targname, isplayer(target) ? "" : "s");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_JOLT) {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
|
||||
target = haslf(targcell);
|
||||
if (target) {
|
||||
int dam;
|
||||
// hit
|
||||
if (isplayer(target)) {
|
||||
msg("A pulse of electricity shocks you!");
|
||||
} else if (cansee(player, target)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(target, lfname);
|
||||
msg("A pulse of electricity shocks %s!",lfname);
|
||||
}
|
||||
dam = rolldie(1, power);
|
||||
losehp(target, dam, DT_ELECTRIC, caster, "a jolt of electricity");
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_KNOCK) {
|
||||
object_t *o;
|
||||
if (!validatespellcell(caster, &targcell,TT_DOOR, spellid, power)) return B_TRUE;
|
||||
|
@ -4264,7 +4377,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
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");
|
||||
msg("%s shoot%s a bolt of electricity!",castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
// don't hit the caster cell on fire!
|
||||
|
@ -4273,7 +4386,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
c = retcell[i];
|
||||
if (c->lf) {
|
||||
// hit with lightning
|
||||
losehp(c->lf, roll("2d6"), DT_ELECTRIC, caster, "a lightning bolt");
|
||||
losehp(c->lf, roll("2d6"), DT_ELECTRIC, caster, "an electricity bolt");
|
||||
nhits--;
|
||||
}
|
||||
if (haslos(player, c)) {
|
||||
|
@ -5316,7 +5429,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
while (!c) {
|
||||
int ch;
|
||||
c = askcoords(buf, TT_NONE, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (!c->known) {
|
||||
if (!c) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
} else if (!c->known) {
|
||||
// confirm
|
||||
ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE);
|
||||
if (ch != 'y') c = NULL;
|
||||
|
@ -5798,44 +5914,49 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
} else if (spellid == OT_S_WATERJET) {
|
||||
char lfname[BUFLEN];
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell,i;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
// animation
|
||||
anim(caster->cell, targcell, '}', C_BLUE);
|
||||
//anim(caster->cell, targcell, '}', C_BLUE);
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
msg("%s fire%s a jet of high-pressure water.",castername,isplayer(caster) ? "" : "s");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
target = haslf(targcell);
|
||||
if (target) {
|
||||
getlfname(target, lfname);
|
||||
int dir,amt;
|
||||
object_t *arm[MAXBODYPARTS];
|
||||
int narm = 0;
|
||||
int i;
|
||||
|
||||
// hit
|
||||
if (cansee(caster, target)) {
|
||||
msg("%s %s hit by a jet of water!",lfname, is(target));
|
||||
}
|
||||
// water damage will generally be turn to zero unless people are specifically
|
||||
// vulnerable to water, so do bashing damage too.
|
||||
losehp(target, roll("3d4"), DT_WATER, caster, "a high-pressure jet of water");
|
||||
losehp(target, roll("3d4"), DT_BASH, caster, "a high-pressure jet of water");
|
||||
// knock backwards
|
||||
dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS);
|
||||
amt = (power/3); if (amt < 2) amt = 2;
|
||||
knockback(target, dir, amt, caster, 0);
|
||||
// rust
|
||||
getallouterarmour(target, arm, &narm);
|
||||
for (i = 0; i < narm; i++) {
|
||||
takedamage(arm[i], R_TRUSTY, DT_WATER);
|
||||
}
|
||||
} else {
|
||||
object_t *o, *nexto;
|
||||
for (o = targcell->obpile->first; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
takedamage(o, 0, DT_COLD);
|
||||
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcell);
|
||||
for (i = 1; i < nretcell; i++) {
|
||||
target = haslf(retcell[i]);
|
||||
if (target) {
|
||||
int dir,amt, i;
|
||||
object_t *arm[MAXBODYPARTS];
|
||||
int narm = 0;
|
||||
getlfname(target, lfname);
|
||||
// hit
|
||||
if (cansee(player, target)) {
|
||||
msg("%s %s hit by a jet of water!",lfname, is(target));
|
||||
}
|
||||
// water damage will generally be turn to zero unless people are specifically
|
||||
// vulnerable to water, so do bashing damage too.
|
||||
losehp(target, roll("3d4"), DT_WATER, caster, "a high-pressure jet of water");
|
||||
losehp(target, roll("3d4"), DT_BASH, caster, "a high-pressure jet of water");
|
||||
// knock backwards
|
||||
dir = getdirtowards(caster->cell, target->cell, target, B_FALSE, DT_COMPASS);
|
||||
amt = (power/3); if (amt < 2) amt = 2;
|
||||
knockback(target, dir, amt, caster, 0);
|
||||
// rust
|
||||
getallouterarmour(target, arm, &narm);
|
||||
for (i = 0; i < narm; i++) {
|
||||
takedamage(arm[i], R_TRUSTY, DT_WATER);
|
||||
}
|
||||
// add water object
|
||||
addob(retcell[i]->obpile, "large puddle of water");
|
||||
break;
|
||||
} else {
|
||||
damageallobs(NULL, retcell[i]->obpile, 0, DT_WATER);
|
||||
// add water object
|
||||
addob(retcell[i]->obpile, "large puddle of water");
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_WARPWOOD) {
|
||||
|
|
Loading…
Reference in New Issue