From f4cdcae146a1b55606ddb09026543505d22fdfd5 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Fri, 27 May 2011 00:41:34 +0000 Subject: [PATCH] * [+] 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 --- ai.c | 18 +- attack.c | 2 +- defs.h | 27 +- flag.c | 35 +- io.c | 121 ++--- lf.c | 398 ++++++++++---- lf.h | 4 +- log.txt | 1498 +++++++++++++++++++++++++++++++++++++++++++++++------ map.c | 71 ++- map.h | 4 +- move.c | 120 ++++- nexus.c | 3 + objects.c | 109 ++-- spell.c | 279 +++++++--- 14 files changed, 2210 insertions(+), 479 deletions(-) diff --git a/ai.c b/ai.c index f2d9109..e18b3aa 100644 --- a/ai.c +++ b/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. }"); diff --git a/attack.c b/attack.c index 1a9f5b3..fac34e5 100644 --- a/attack.c +++ b/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; diff --git a/defs.h b/defs.h index 60d4e22..af94f42 100644 --- a/defs.h +++ b/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, }; diff --git a/flag.c b/flag.c index ecb1ba1..050e4f0 100644 --- a/flag.c +++ b/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; + } } } diff --git a/io.c b/io.c index 456202a..bcc1f45 100644 --- a/io.c +++ b/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)) { diff --git a/lf.c b/lf.c index c862f2d..1163251 100644 --- a/lf.c +++ b/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); diff --git a/lf.h b/lf.h index ff23b1a..38452f6 100644 --- a/lf.h +++ b/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); diff --git a/log.txt b/log.txt index ffd85ac..4bee9f2 100644 --- a/log.txt +++ b/log.txt @@ -2,22 +2,90 @@ ====== NEW LOGFILE ==== +rollhitdice() for giant newt - rolling 1d4 + 0 +rollhitdice() - mod is +32% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 5 +rollhitdice() for xat - rolling 1d4 + 0 +rollhitdice() - mod is +-5% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 +rollhitdice() for giant rat - rolling 0d4 + 1 +rollhitdice() - mod is +-22% +TOTAL: 1 + -> modified to: 1 +rollhitdice() for xat - rolling 1d4 + 0 +rollhitdice() - mod is +10% +rollhitdice() ---- die 1/1 == 2 +TOTAL: 2 + -> modified to: 2 +rollhitdice() for giant rat - rolling 0d4 + 1 +rollhitdice() - mod is +-27% +TOTAL: 1 + -> modified to: 1 +rollhitdice() for giant newt - rolling 1d4 + 0 +rollhitdice() - mod is +32% +rollhitdice() ---- die 1/1 == 3 +TOTAL: 3 + -> modified to: 3 rollhitdice() for xat - rolling 1d4 + 0 rollhitdice() - mod is +32% rollhitdice() ---- die 1/1 == 3 TOTAL: 3 -> modified to: 3 +rollhitdice() for xat - rolling 1d4 + 0 +rollhitdice() - mod is +22% +rollhitdice() ---- die 1/1 == 2 +TOTAL: 2 + -> modified to: 2 +rollhitdice() for giant newt - rolling 1d4 + 0 +rollhitdice() - mod is +22% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +0% +rollhitdice() - mod is +22% +TOTAL: 1 + -> modified to: 1 +rollhitdice() for giant newt - rolling 1d4 + 0 +rollhitdice() - mod is +66% +rollhitdice() ---- die 1/1 == 1 TOTAL: 1 -> modified to: 1 rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +54% -rollhitdice() ---- die 1/1 == 2 -TOTAL: 2 +rollhitdice() - mod is +22% +rollhitdice() ---- die 1/1 == 3 +TOTAL: 3 -> modified to: 3 rollhitdice() for giant rat - rolling 0d4 + 1 +rollhitdice() - mod is +10% +TOTAL: 1 + -> modified to: 1 +rollhitdice() for xat - rolling 1d4 + 0 +rollhitdice() - mod is +-16% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 +rollhitdice() for kobold - rolling 1d4 + 0 +rollhitdice() - mod is +66% +rollhitdice() ---- die 1/1 == 3 +TOTAL: 3 + -> modified to: 4 +rollhitdice() for giant newt - rolling 1d4 + 0 +rollhitdice() - mod is +-5% +rollhitdice() ---- die 1/1 == 3 +TOTAL: 3 + -> modified to: 3 +rollhitdice() for giant newt - rolling 1d4 + 0 rollhitdice() - mod is +0% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 +rollhitdice() for kobold - rolling 1d4 + 0 +rollhitdice() - mod is +-5% +rollhitdice() ---- die 1/1 == 1 TOTAL: 1 -> modified to: 1 rollhitdice() for kobold - rolling 1d4 + 0 @@ -26,159 +94,1297 @@ rollhitdice() ---- die 1/1 == 3 TOTAL: 3 -> modified to: 4 rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +-16% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 4 -rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +76% -rollhitdice() ---- die 1/1 == 1 -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +10% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 4 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +76% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 7 -rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +-27% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 3 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +22% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +10% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +0% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +-5% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 4 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +88% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 7 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +-5% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 4 -rollhitdice() for troglodyte - rolling 1d4 + 0 -rollhitdice() - mod is +0% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 4 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +10% -rollhitdice() ---- die 1/1 == 1 -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +0% -rollhitdice() ---- die 1/1 == 1 -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +-11% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +76% -rollhitdice() ---- die 1/1 == 3 -TOTAL: 3 - -> modified to: 5 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +32% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +-11% +rollhitdice() - mod is +44% rollhitdice() ---- die 1/1 == 2 TOTAL: 2 -> modified to: 2 -rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +66% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 6 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +76% -rollhitdice() ---- die 1/1 == 1 -TOTAL: 1 - -> modified to: 1 -rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +32% -rollhitdice() ---- die 1/1 == 2 -TOTAL: 2 - -> modified to: 2 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +54% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +54% -rollhitdice() ---- die 1/1 == 1 -TOTAL: 1 - -> modified to: 1 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +10% -rollhitdice() ---- die 1/1 == 3 -TOTAL: 3 - -> modified to: 3 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +0% -rollhitdice() ---- die 1/1 == 3 -TOTAL: 3 - -> modified to: 3 -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +32% -rollhitdice() ---- die 1/1 == 3 -TOTAL: 3 - -> modified to: 3 -rollhitdice() for giant rat - rolling 0d4 + 1 -rollhitdice() - mod is +-16% -TOTAL: 1 - -> modified to: 1 -rollhitdice() for xat - rolling 1d4 + 0 -rollhitdice() - mod is +22% -rollhitdice() ---- die 1/1 == 2 -TOTAL: 2 - -> modified to: 2 -rollhitdice() for giant newt - rolling 1d4 + 0 -rollhitdice() - mod is +66% -rollhitdice() ---- die 1/1 == 4 -TOTAL: 4 - -> modified to: 6 rollhitdice() for human - rolling 2d4 + 2 -rollhitdice() - mod is +0% +rollhitdice() - mod is +-22% rollhitdice() ---- die 1/2 == 6 -rollhitdice() ---- die 2/2 == 4 -TOTAL: 10 +rollhitdice() ---- die 2/2 == 6 +TOTAL: 12 -> modified to: 10 +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +88% +rollhitdice() ---- die 1/2 == 6 +rollhitdice() ---- die 2/2 == 5 +TOTAL: 11 + -> modified to: 20 +START drawscreen +FINISHED end. ndrawn was 1600 (total time 9955.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 7947.000000) +START drawscreen +FINISHED end. ndrawn was 18 (total time 8343.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8024.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 8081.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8102.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 9010.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 9811.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 9297.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8226.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 10913.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8166.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8294.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 8089.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 2 (total time 9388.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 9389.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8399.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8808.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 8476.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8391.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8387.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 8958.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 2 (total time 8573.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8193.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8398.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8236.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8141.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 8127.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 2 (total time 10036.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8303.000000) +START drawscreen +FINISHED end. ndrawn was 9 (total time 8574.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8158.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8626.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 8418.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8148.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8388.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 8186.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 8255.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 9462.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 9206.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 8475.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 8325.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 10 (total time 8117.000000) +START drawscreen +FINISHED end. ndrawn was 20 (total time 8160.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 8123.000000) +START drawscreen +FINISHED end. ndrawn was 104 (total time 9366.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 9229.000000) +START drawscreen +FINISHED end. ndrawn was 107 (total time 9895.000000) +START drawscreen +FINISHED end. ndrawn was 117 (total time 10788.000000) +START drawscreen +FINISHED end. ndrawn was 125 (total time 11827.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 11952.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 11588.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 11574.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11990.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 12302.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 11631.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 12119.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 1 (total time 12376.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 11569.000000) +START drawscreen +FINISHED end. ndrawn was 154 (total time 13140.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 12858.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 12815.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 12729.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 12761.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 12544.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15929.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 2 (total time 13165.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 12680.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 14267.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 13058.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14629.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 1 (total time 12647.000000) +START drawscreen +FINISHED end. ndrawn was 185 (total time 14045.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 13914.000000) +START drawscreen +FINISHED end. ndrawn was 181 (total time 14598.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14600.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 15136.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 14970.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16320.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 10 (total time 14547.000000) +START drawscreen +FINISHED end. ndrawn was 9 (total time 14405.000000) +START drawscreen +FINISHED end. ndrawn was 9 (total time 14560.000000) +START drawscreen +FINISHED end. ndrawn was 9 (total time 14377.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 14343.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 14308.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 14533.000000) +DRAWINGSCREEN from flag + +xxx +START drawscreen +FINISHED end. ndrawn was 8 (total time 14336.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 14622.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 14418.000000) +START drawscreen +FINISHED end. ndrawn was 9 (total time 14429.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 14337.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 14476.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 14391.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14746.000000) +START drawscreen +FINISHED end. ndrawn was 78 (total time 14253.000000) +START drawscreen +FINISHED end. ndrawn was 216 (total time 15191.000000) +START drawscreen +FINISHED end. ndrawn was 216 (total time 16170.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15736.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15861.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16168.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15972.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15835.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16379.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16165.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16142.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16983.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15921.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15892.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16051.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16073.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 16351.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15981.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16073.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15986.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 19051.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15783.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15912.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16701.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15933.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 17296.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16252.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16347.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16010.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16180.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 6 (total time 16295.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17387.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 15714.000000) +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +88% +rollhitdice() ---- die 1/2 == 4 +rollhitdice() ---- die 2/2 == 5 +TOTAL: 9 + -> modified to: 16 +START drawscreen +FINISHED end. ndrawn was 2 (total time 16479.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15731.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15878.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15821.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15933.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 16234.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15906.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15893.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15888.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15886.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15916.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16000.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15936.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15906.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16053.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 15928.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15918.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15911.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15941.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15903.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15925.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15953.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15942.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15973.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15934.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15958.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15977.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15988.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15901.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16008.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15973.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16020.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15909.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15970.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16070.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16060.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16726.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16033.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16050.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16129.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 16822.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16083.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 17241.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15870.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 15875.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16331.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15871.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15940.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16201.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 15945.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 23607.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 16257.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15785.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15925.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 16811.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16456.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17950.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 16471.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16401.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16128.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 15744.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15803.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16271.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 15819.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15862.000000) +START drawscreen +FINISHED end. ndrawn was 15 (total time 15767.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15757.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 15821.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 1600 (total time 18866.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 16030.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 15984.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 15912.000000) +START drawscreen +FINISHED end. ndrawn was 248 (total time 17261.000000) +START drawscreen +FINISHED end. ndrawn was 242 (total time 17638.000000) +START drawscreen +FINISHED end. ndrawn was 20 (total time 17307.000000) +START drawscreen +FINISHED end. ndrawn was 24 (total time 17362.000000) +START drawscreen +FINISHED end. ndrawn was 19 (total time 17337.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 17313.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 17379.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 17298.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 17365.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 17377.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17368.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 17405.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17487.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 17466.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17459.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 17579.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 18816.000000) +START drawscreen +FINISHED end. ndrawn was 15 (total time 17551.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17498.000000) +START drawscreen +FINISHED end. ndrawn was 40 (total time 17442.000000) +START drawscreen +FINISHED end. ndrawn was 38 (total time 17721.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 17279.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 17392.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 17331.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 17738.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 17276.000000) +START drawscreen +FINISHED end. ndrawn was 35 (total time 17355.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 17217.000000) +START drawscreen +FINISHED end. ndrawn was 258 (total time 17151.000000) +START drawscreen +FINISHED end. ndrawn was 239 (total time 15873.000000) +START drawscreen +FINISHED end. ndrawn was 234 (total time 14903.000000) +START drawscreen +FINISHED end. ndrawn was 220 (total time 14031.000000) +START drawscreen +FINISHED end. ndrawn was 209 (total time 13226.000000) +START drawscreen +FINISHED end. ndrawn was 193 (total time 12320.000000) +START drawscreen +FINISHED end. ndrawn was 179 (total time 11498.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11814.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 14397.000000) +START drawscreen +FINISHED end. ndrawn was 525 (total time 12191.000000) +START drawscreen +FINISHED end. ndrawn was 254 (total time 10961.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 10904.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 10414.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 10412.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 10459.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 12576.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 10600.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11834.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 10488.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 10508.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 10541.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 10439.000000) +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +10% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +54% +TOTAL: 3 + -> modified to: 4 +DRAWINGSCREEN from flag + +rollhitdice() for glowbug - rolling 1d4 + 0 +rollhitdice() - mod is +22% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 +DRAWINGSCREEN from flag + +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +44% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +-11% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +-5% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16103.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 16407.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14120.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 13673.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 13318.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 13461.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 13269.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 13364.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 2 (total time 13258.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 13389.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 13951.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 15313.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16028.000000) +CALCINGLIGHT from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 13926.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 13560.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 13844.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 15446.000000) +CALCINGLIGHT from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 18 (total time 13589.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 13498.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 13410.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 14558.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 15536.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 14948.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 17922.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 14746.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 15587.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 17136.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 18552.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 13534.000000) +START drawscreen +FINISHED end. ndrawn was 92 (total time 14686.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 14255.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14237.000000) +START drawscreen +FINISHED end. ndrawn was 87 (total time 15279.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 18416.000000) +START drawscreen +FINISHED end. ndrawn was 85 (total time 16346.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16198.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16188.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16511.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 16852.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16226.000000) +START drawscreen +FINISHED end. ndrawn was 15 (total time 17123.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 16262.000000) +START drawscreen +FINISHED end. ndrawn was 69 (total time 15999.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 15959.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15908.000000) +START drawscreen +FINISHED end. ndrawn was 68 (total time 15822.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15636.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15628.000000) +START drawscreen +FINISHED end. ndrawn was 14 (total time 16845.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15860.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15905.000000) +START drawscreen +FINISHED end. ndrawn was 17 (total time 15818.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 15890.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 15927.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 15650.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15627.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 15697.000000) +START drawscreen +FINISHED end. ndrawn was 63 (total time 15438.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 15387.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15487.000000) +START drawscreen +FINISHED end. ndrawn was 108 (total time 14459.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 14214.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14308.000000) +START drawscreen +FINISHED end. ndrawn was 86 (total time 13476.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 13653.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 13452.000000) +START drawscreen +FINISHED end. ndrawn was 86 (total time 12604.000000) +START drawscreen +FINISHED end. ndrawn was 90 (total time 11657.000000) +START drawscreen +FINISHED end. ndrawn was 14 (total time 11539.000000) +START drawscreen +FINISHED end. ndrawn was 91 (total time 11719.000000) +START drawscreen +FINISHED end. ndrawn was 11 (total time 10687.000000) +START drawscreen +FINISHED end. ndrawn was 89 (total time 9929.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 9860.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 9965.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 9777.000000) +START drawscreen +FINISHED end. ndrawn was 7 (total time 9816.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 9788.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 9760.000000) +START drawscreen +FINISHED end. ndrawn was 10 (total time 9886.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 9942.000000) +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +88% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +88% +rollhitdice() ---- die 1/2 == 6 +rollhitdice() ---- die 2/2 == 5 +TOTAL: 11 + -> modified to: 20 +DRAWINGSCREEN from flag + +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +-5% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +-16% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +66% +TOTAL: 3 + -> modified to: 4 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +10% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +88% +rollhitdice() ---- die 1/2 == 4 +rollhitdice() ---- die 2/2 == 5 +TOTAL: 9 + -> modified to: 16 +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16055.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14448.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14104.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 14570.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14024.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14327.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 14216.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 14078.000000) +START drawscreen +FINISHED end. ndrawn was 13 (total time 14108.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 14079.000000) +START drawscreen +FINISHED end. ndrawn was 4 (total time 14458.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 14290.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 15328.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 14298.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16710.000000) +START drawscreen +FINISHED end. ndrawn was 27 (total time 14327.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14234.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14167.000000) +START drawscreen +FINISHED end. ndrawn was 14 (total time 14095.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14234.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14054.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 14070.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15097.000000) +START drawscreen +FINISHED end. ndrawn was 6 (total time 14042.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 14290.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 15642.000000) +START drawscreen +FINISHED end. ndrawn was 97 (total time 16291.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 18290.000000) +START drawscreen +FINISHED end. ndrawn was 21 (total time 15121.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 14929.000000) +START drawscreen +FINISHED end. ndrawn was 12 (total time 15669.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15028.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 15199.000000) +START drawscreen +FINISHED end. ndrawn was 104 (total time 16240.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15809.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15835.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15864.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16798.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16200.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 15852.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 97 (total time 16964.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 16696.000000) +START drawscreen +FINISHED end. ndrawn was 95 (total time 18037.000000) +START drawscreen +FINISHED end. ndrawn was 96 (total time 16905.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 16764.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 16782.000000) +START drawscreen +FINISHED end. ndrawn was 95 (total time 16133.000000) +START drawscreen +FINISHED end. ndrawn was 5 (total time 16646.000000) +START drawscreen +FINISHED end. ndrawn was 3 (total time 16230.000000) +START drawscreen +FINISHED end. ndrawn was 94 (total time 16475.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 23601.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 14979.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 15008.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 118 (total time 14220.000000) +START drawscreen +FINISHED end. ndrawn was 114 (total time 13343.000000) +START drawscreen +FINISHED end. ndrawn was 104 (total time 12595.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 12429.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16029.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 16 (total time 12498.000000) +START drawscreen +FINISHED end. ndrawn was 16 (total time 12404.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 12656.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 14510.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 12550.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 13905.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 13910.000000) +START drawscreen +FINISHED end. ndrawn was 124 (total time 14412.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 12552.000000) +START drawscreen +FINISHED end. ndrawn was 8 (total time 12568.000000) +START drawscreen +FINISHED end. ndrawn was 14 (total time 12444.000000) +START drawscreen +FINISHED end. ndrawn was 13 (total time 12461.000000) +START drawscreen +FINISHED end. ndrawn was 24 (total time 12564.000000) +START drawscreen +FINISHED end. ndrawn was 67 (total time 12578.000000) +START drawscreen +FINISHED end. ndrawn was 23 (total time 12413.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 12712.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 13913.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 13795.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 15436.000000) +START drawscreen +FINISHED end. ndrawn was 177 (total time 12050.000000) +DRAWINGSCREEN from flag + +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 11602.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 50 (total time 13418.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11660.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 12141.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 11712.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 11878.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 1600 (total time 15037.000000) +START drawscreen +FINISHED end. ndrawn was 50 (total time 11882.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 76 (total time 11816.000000) +START drawscreen +FINISHED end. ndrawn was 65 (total time 11734.000000) +START drawscreen +FINISHED end. ndrawn was 90 (total time 11689.000000) +START drawscreen +FINISHED end. ndrawn was 90 (total time 11766.000000) +START drawscreen +FINISHED end. ndrawn was 231 (total time 11092.000000) +START drawscreen +FINISHED end. ndrawn was 212 (total time 10252.000000) +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +-16% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for glowbug - rolling 1d4 + 0 +rollhitdice() - mod is +-16% +rollhitdice() ---- die 1/1 == 2 +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +-22% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +32% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + rollhitdice() for young wolf - rolling 2d4 + 2 rollhitdice() - mod is +100% +rollhitdice() ---- die 1/2 == 6 +rollhitdice() ---- die 2/2 == 3 +TOTAL: 9 + -> modified to: 18 +DRAWINGSCREEN from flag + +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +88% rollhitdice() ---- die 1/2 == 4 rollhitdice() ---- die 2/2 == 4 TOTAL: 8 - -> modified to: 16 -xxx -rollhitdice() for kobold - rolling 1d4 + 0 -rollhitdice() - mod is +44% -rollhitdice() ---- die 1/1 == 3 + -> modified to: 15 +DRAWINGSCREEN from flag + +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +32% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +0% +TOTAL: 2 + -> modified to: 2 +DRAWINGSCREEN from flag + +rollhitdice() for glowbug - rolling 1d4 + 0 +rollhitdice() - mod is +10% +rollhitdice() ---- die 1/1 == 4 +TOTAL: 4 + -> modified to: 4 +DRAWINGSCREEN from flag + +rollhitdice() for giant bat - rolling 0d4 + 2 +rollhitdice() - mod is +66% TOTAL: 3 -> modified to: 4 +DRAWINGSCREEN from flag + +rollhitdice() for young wolf - rolling 2d4 + 2 +rollhitdice() - mod is +100% +rollhitdice() ---- die 1/2 == 4 +rollhitdice() ---- die 2/2 == 5 +TOTAL: 9 + -> modified to: 18 +DRAWINGSCREEN from flag + +rollhitdice() for butterfly - rolling 0d4 + 1 +rollhitdice() - mod is +32% +TOTAL: 1 + -> modified to: 1 +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 1600 (total time 16853.000000) +START drawscreen +FINISHED end. ndrawn was 33 (total time 14562.000000) +START drawscreen +FINISHED end. ndrawn was 45 (total time 14228.000000) +START drawscreen +FINISHED end. ndrawn was 42 (total time 14443.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17577.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15087.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14481.000000) +START drawscreen +FINISHED end. ndrawn was 62 (total time 19825.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 14360.000000) +START drawscreen +FINISHED end. ndrawn was 66 (total time 14497.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14521.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14298.000000) +START drawscreen +FINISHED end. ndrawn was 61 (total time 15101.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14304.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 14331.000000) +START drawscreen +FINISHED end. ndrawn was 81 (total time 14452.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 245 (total time 15804.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16168.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 15827.000000) +START drawscreen +FINISHED end. ndrawn was 226 (total time 16376.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 2 (total time 16086.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16959.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16158.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 16116.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16049.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 1 (total time 16119.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16137.000000) +START drawscreen +FINISHED end. ndrawn was 233 (total time 19126.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17822.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17842.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17389.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 17300.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 17577.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 17165.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16995.000000) +xxx +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 2 (total time 17288.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17135.000000) +START drawscreen +FINISHED end. ndrawn was 246 (total time 18595.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 18796.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 18085.000000) +START drawscreen +FINISHED end. ndrawn was 263 (total time 17557.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17185.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 17094.000000) +START drawscreen +FINISHED end. ndrawn was 275 (total time 16567.000000) +START drawscreen +FINISHED end. ndrawn was 2 (total time 16552.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 17172.000000) +DRAWINGSCREEN from flag + +START drawscreen +FINISHED end. ndrawn was 0 (total time 17600.000000) +START drawscreen +FINISHED end. ndrawn was 1 (total time 16220.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 53 (total time 17222.000000) +xxx +START drawscreen +FINISHED end. ndrawn was 263 (total time 15858.000000) +START drawscreen +FINISHED end. ndrawn was 259 (total time 14731.000000) +START drawscreen +FINISHED end. ndrawn was 246 (total time 13874.000000) +START drawscreen +FINISHED end. ndrawn was 226 (total time 12990.000000) +START drawscreen +FINISHED end. ndrawn was 209 (total time 11960.000000) +START drawscreen +FINISHED end. ndrawn was 200 (total time 11025.000000) +START drawscreen +FINISHED end. ndrawn was 31 (total time 11073.000000) +START drawscreen +FINISHED end. ndrawn was 20 (total time 10832.000000) +START drawscreen +FINISHED end. ndrawn was 22 (total time 10900.000000) +START drawscreen +FINISHED end. ndrawn was 28 (total time 10862.000000) +START drawscreen +FINISHED end. ndrawn was 21 (total time 10872.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11021.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 11203.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 10922.000000) +START drawscreen +FINISHED end. ndrawn was 0 (total time 12245.000000) +START drawscreen +FINISHED end. ndrawn was 1600 (total time 13619.000000) +START drawscreen +FINISHED end. ndrawn was 23 (total time 10881.000000) +START drawscreen +FINISHED end. ndrawn was 25 (total time 10898.000000) +START drawscreen +FINISHED end. ndrawn was 180 (total time 10191.000000) +START drawscreen +FINISHED end. ndrawn was 62 (total time 10067.000000) xxx diff --git a/map.c b/map.c index 60a576f..4a73c43 100644 --- a/map.c +++ b/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)); } diff --git a/map.h b/map.h index bc7e9b6..8c8f5f6 100644 --- a/map.h +++ b/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); diff --git a/move.c b/move.c index 4bfb4f7..8d154ab 100644 --- a/move.c +++ b/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); + } } - } } } diff --git a/nexus.c b/nexus.c index 18e4024..6ac9221 100644 --- a/nexus.c +++ b/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; } diff --git a/objects.c b/objects.c index 425b712..d2d6f85 100644 --- a/objects.c +++ b/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); diff --git a/spell.c b/spell.c index b5fb352..0539ebe 100644 --- a/spell.c +++ b/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) {