From 7c86e87f4a3a83e93a9691d9d829e6096ac8fbc9 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Wed, 13 Jul 2011 21:40:28 +0000 Subject: [PATCH] * [+] make vending machines use this container code instead. - [+] don't say "you see a few things" if one of them is footsteps * [+] IFMONSTER code failing....because flags are now SORTED!!! - [+] tumble - askcoords is letting us pick a cell we don't have lof to. * [+] assign a name to lfs once you hire them * [+] coloured msgtext - [+] make min dam reduction from AR be AR/5. - [+] safebox - [+] if intelligent, prompt before walking into RESTRICTMOVEMENT with no getsweaker (val1) * [+] make fire / ice damage mor elike netheck - [+] towns should have gates on EVERY side - [+] forest cells outside town gates need to be CLEARED. (maybe turn to dirt) - [+] fix up knock targetting to include magical barriers - [+] say "open a bag?" not "operate a bag?" * [+] implement immunetodisease - [+] sort known skills in @s. - [+] better damage bonus when attacking someone who is asleep - [+] practive firearms/throwing * [+] need objecttype->size * [+] containers * [+] change guns so you have to reload them. ("operate") - [+] crash when loading map with water - [+] SAVE OBJECT CONTENTSk - [+] monsters with jobs aren't getting start items - [+] shopkeeper has shotgun - [+] bug: monster keeps swapping between shotgun and flail - [+] when hiring, remember failure. * [+] Inn - [+] bug: pets fighting!!! then they all turn on you. never make allies get angry unless the attacker is the player * [+] hiring npcs - [+] chat to pet: "stay close" or "keep your distance" - [+] new 'furniture' obclass - [+] allow for 'randomshop' regiontype * [+] add enchantment school - [+] cast a scroll of mending on itself. CRASH. * [+] lessengravity should make you jump better and get knocked back further - [+] boostgrav/lessengrav cancel out each other. * [+] CRASH when you fall down a hole and die. - [+] problem: master gravitation doesn't let us cast levitat. getspellschoolknown() should return the HIGHEST known skill, not the first. * [+] bug: dregion is null?!??! * [+] dig a pit, if you cleared out land below, you just stay down there. - [+] potion of leveitation - [+] warning msg when levitate is about to expire * [+] if you fall upwards to the surface... * [+] if you are ever on the surface while levitating.... - [+] BUG: cna't go up stairs to surface anymore!!!!! - [+] get hungry LOTS more quickly when you start sprinting * [+] monk slow metabolism psionic pell. - [+] fix buf with lore giving LESS accuracy instead of more. - [+] food shop - [+] wand of digging not identified if you dig upwards * [+] when you make ah ole in the roof, objects above should fall through right away * [+] all towns should have: - [+] give monks more psionics spells. - [+] sk_throwing skill - [+] make calm animals use spellpower * [+] add wisdom * [+] need to save region data along with maps * [+] COMBINE armour evasion and accuracy penalty!!! * [+] make armour reduce accuracy as well (unless you have 'armour' skill) - [+] landmine trap * [+] make friendly monsters of same raceclass swap ammo - [+] rename 'pull' to 'suck' to avoid confusion with pull metal * [+] food to fix blindness - [+] potion of coffee * [+] genericise statbrackets * [+] tumble ability * [+] simplify spell power * [+] shopkeeprs should be allowed to pursue targets outside of the shop. - [+] give shopkeepers a shotgun * [+] make F_RNDHOSTILE be able to ahve a random chance. * [+] if you randomly generate food in a shop, still give it a price. - [+] if peaceful humanoid walks into you, "sorry!" - [+] sayphrase(lf, SP_SORRY, vol) - [+] only let you recruit jobs with j_recruitable - [+] CRASH - summon "monk" - [+] dogs, - [+] chickens, - [+] drunks, * [+] village objects - [+] change armourrating AGAIN. instead of a percentage, make it a number. - [+] rename inn to "pub", since you can't sleep there. * [+] random speech code * [+] genericise sayphrase text based on lf's job * [+] monks - add rest of abliities - [+] add fiengdeath ability to some monsters --- ai.c | 234 ++-- ai.h | 3 +- attack.c | 354 +++-- data/npcnames.txt | 301 ++++ defs.h | 277 ++-- doc/add_attrib.txt | 12 +- doc/glyphs.txt | 5 +- flag.c | 90 ++ flag.h | 5 + io.c | 919 +++++++----- io.h | 6 +- lf.c | 3307 +++++++++++++++++++++++++------------------- lf.h | 33 +- map.c | 339 +++-- map.h | 7 +- move.c | 104 +- nexus.c | 87 +- nexus.h | 2 + objects.c | 1929 ++++++++++++++++---------- objects.h | 14 +- save.c | 203 ++- save.h | 2 + spell.c | 567 ++++++-- text.c | 50 +- text.h | 1 + vaults/jimbo.vlt | 2 +- 26 files changed, 5750 insertions(+), 3103 deletions(-) create mode 100644 data/npcnames.txt diff --git a/ai.c b/ai.c index 67d075f..fb77623 100644 --- a/ai.c +++ b/ai.c @@ -25,7 +25,8 @@ void addignorecell(lifeform_t *lf, cell_t *c) { } } -void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { +// returns true on failure +int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { int db = B_FALSE; flag_t *f; @@ -34,9 +35,9 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { } // mindless? - if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) { + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) { if (!isundead(lf)) { - return; + return B_TRUE; } } @@ -46,7 +47,19 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { if ((f->lifetime > 0) && (f->lifetime < timelimit)) { f->lifetime = timelimit; } - return; + return B_TRUE; + } + + // feigning death? + if (lfhasflag(victim, F_FEIGNINGDEATH)) { + int penalty; + penalty = (getcelldist(lf->cell, victim->cell)-1); + if (penalty < 0) penalty = 0; + penalty *= 3; + if (!skillcheckvs(lf, SC_WILL, -penalty, victim, SC_WILL, 0)) { + dblog(".oO { attempted target fooled me with feign death. ignoring. }"); + return B_TRUE; + } } if (db) { @@ -84,6 +97,7 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) { // no longer a pet f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL); if (f) killflag(f); + return B_FALSE; } enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) { @@ -225,7 +239,7 @@ object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra) { if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; o = getfirearm(lf); - if (o && getammo(lf)) { + if (o && getammo(o)) { if (db) { char gunname[BUFLEN]; getobname(o, gunname, o->amt); @@ -423,6 +437,14 @@ flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int t return f; } +flag_t *aihastarget(lifeform_t *lf) { + flag_t *f; + f = lfhasflag(lf, F_TARGETLF); + if (f) return f; + f = lfhasflag(lf, F_TARGETCELL); + if (f) return f; + return NULL; +} // returns B_FALSE if we did something. // returns B_TRUE if we failed (ie. did nothing) @@ -486,6 +508,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) { attackok = B_TRUE; } else if (!lfhasflag(lf, F_HIDING)) { attackok = B_TRUE; + } else if (!lfhasflag(lf, F_FEIGNINGDEATH)) { + attackok = B_TRUE; } } @@ -609,8 +633,8 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) { // if we got here, we're either at the correct distance or couldn't // move. if (attackok) { - enum IQBRACKET iqb; - iqb = getiqname(getattr(lf, A_IQ), NULL); + enum ATTRBRACKET iqb; + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); // if not adjacent, check for guns, wands, throwing if ( (rangedattack != RA_NONE) && @@ -774,7 +798,6 @@ int aipickupok(lifeform_t *lf, object_t *o) { int ok = B_FALSE; if (hasflag(o->flags, F_SHOPITEM)) { - // && (getiqname(getattr(lf, A_IQ), NULL) > IQ_ANIMAL)) { return B_FALSE; } @@ -819,8 +842,8 @@ void aiturn(lifeform_t *lf) { enum BODYPART bp; //cell_t *c; lifeform_t *master = NULL; - enum IQBRACKET iqb; - int n; + enum ATTRBRACKET iqb; + int n,i; /* @@ -857,8 +880,7 @@ void aiturn(lifeform_t *lf) { // info gathering /////////////////////////////////////////// // remember our intelligence - iqb = getiqname(getattr(lf, A_IQ), NULL); - + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); // are we a pet? f = lfhasflagval(lf, F_PETOF, NA, NA, NA, NULL); @@ -869,7 +891,7 @@ void aiturn(lifeform_t *lf) { /////////////////////////////////////////////// // emergencies /////////////////////////////////////////////// - if (iqb >= IQ_AVERAGE) { + if (iqb >= AT_AVERAGE) { if (celldangerous(lf, lf->cell, B_TRUE, NULL)) { // if our cell is dangerous, move away! if (!dorandommove(lf, B_NOBADMOVES, B_FALSE)) { @@ -881,9 +903,29 @@ void aiturn(lifeform_t *lf) { /////////////////////////////////////////////// // housekeeping - weapon changes, drop/pickup, - // use items, etc + // use items, talk,etc /////////////////////////////////////////////// + // talking + f = lfhasflag(lf, F_RANDOMTALKPCT); + if (f) { + if (pctchance(f->val[0])) { + flag_t *poss[MAXCANDIDATES]; + int nposs = 0; + for (f = lf->flags->first ;f ; f = f->next) { + if (f->id == F_RANDOMTALK) { + poss[nposs++] = f; + } + } + if (nposs) { + int vol; + f = poss[rnd(0,nposs-1)]; + vol = rnd(f->val[1], f->val[2]); + sayphrase(lf, f->val[0], vol, NA, NULL); + } + } + } + /////////////////////////////////////////////// // healing /////////////////////////////////////////////// @@ -894,13 +936,26 @@ void aiturn(lifeform_t *lf) { int sleepval = 18; if (modcounter(lf->flags, 1) >= sleepval) { - taketime(lf, getactspeed(lf)); - addflag(lf->flags, F_ASLEEP, B_TRUE, NA, NA, NULL); - return; + // we say that this ISNT on purpose, because otherwise + // we'll wake up as soon as we're healed. in this case + // we actually want to sleep forever (or until woken). + if (!gotosleep(lf, B_FALSE)) { + // force this since when not on purpose, gotosleep wont + // take time. + taketime(lf, getactspeed(lf)); + return; // success + } } } } + // feigning death with enemies in sight? + if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) { + // just wait... + taketime(lf, getactspeed(lf)); + return; + } + // need to heal? if (lf->hp < (lf->maxhp/2)) { if (!useitemwithflag(lf, F_AIHEALITEM)) { @@ -944,16 +999,18 @@ void aiturn(lifeform_t *lf) { curwep = getweapon(lf); bestwep = getbestweapon(lf); - if (curwep != bestwep) { + if ((curwep != bestwep) && !isfirearm(curwep)) { if (db) dblog(".oO { i have a better weapon than my current one (%s > %s) }",bestwep->type->name, curwep ? curwep->type->name : "nothing"); // weild better one if (!weild(lf, bestwep)) return; } // do we have a better firearm ? + curgun = getfirearm(lf); if (curwep && hasflag(curwep->flags, F_TWOHANDED)) { + // we are using a two handed weapon. don't + // check for guns. } else { - curgun = getfirearm(lf); bestgun = getbestfirearm(lf); if (curgun != bestgun) { @@ -963,14 +1020,15 @@ void aiturn(lifeform_t *lf) { } } - // do we have better ammo? + // do we have ammo for an empty gun? if (curgun) { object_t *curammo; - curammo = getammo(lf); + curammo = getammo(curgun); if (!curammo) { - for (o = lf->pack->first ; o ; o = o->next) { - testammo(lf, o); // doesn't take any time. - if (getammo(lf)) break; + o = getrandomammo(lf); + if (o && !loadfirearm(lf, curgun, o)) { + // success + return; } } } @@ -998,7 +1056,7 @@ void aiturn(lifeform_t *lf) { // look for any object which we _covet_. // ie. if we covet something, we will pick it up // instead of attacking our target. - if (!lfhasflag(lf, F_HIDING)) { + if (!lfhasflag(lf, F_HIDING) && !lfhasflag(lf, F_FEIGNINGDEATH)) { if (db) dblog(".oO { looking for covetted objects... }"); if (lookforobs(lf)) { if (db) dblog(".oO { found covetted object. returning. }"); @@ -1034,6 +1092,7 @@ void aiturn(lifeform_t *lf) { /////////////////////////////////////////////// // generic pre-movement actions. /////////////////////////////////////////////// + // need light? if (!haslos(lf, lf->cell)) { object_t *lamp; lamp = hasobwithflagval(lf->pack, F_ACTIVATECONFER, F_PRODUCESLIGHT, NA, NA, NULL); @@ -1047,6 +1106,29 @@ void aiturn(lifeform_t *lf) { } } } + // ally needs ammo? + for (i = 0; i < lf->nlos; i++) { + cell_t *c; + c = lf->los[i]; + if (c->lf && (c->lf != lf) && areallies(lf, c->lf)) { + object_t *gun; + gun = getfirearm(c->lf); + if (gun && !getammo(gun)) { + object_t *o; + for (o = lf->pack->first ; o ; o = o->next) { + if (isammofor(o->type, gun) ) { + if (getcelldist(lf->cell, c) <= getmaxthrowrange(lf, o)) { + // throw it to them! + if (!throwat(lf, o, c)) { + // success + return; + } + } + } + } + } + } + } /////////////////////////////////////////////// // movement @@ -1111,6 +1193,26 @@ 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. }"); + // shopkeepers will return to their shops + if (hasjob(lf, J_SHOPKEEPER)) { + f = lfhasflag(lf, F_OWNSSHOP); + if (f) { + int myshop; + cell_t *where; + myshop = f->val[0]; + // find the closest cell of my shop + where = getclosestroomcell(lf, myshop); + // move towards my shop. note that if the player leaves then + // re-enters this map, they will find that we have instantly + // teleported there (see mapentereffects). + if (aigoto(lf, where, MR_OTHER, NULL, PERMENANT)) { + // success + return; + } + } + } + + // look for any race which we hate newtarget = NULL; for (n = 0; n < lf->nlos; n++) { @@ -1141,77 +1243,21 @@ void aiturn(lifeform_t *lf) { } if (newtarget) { - aiattack(lf, newtarget, AI_FOLLOWTIME); - // then move towards them... - if (db) dblog(".oO { moving towards my new target }"); - - if (icanattack) { - if (!movetowards(lf, newtarget->cell, DT_ORTH)) return; + if (aiattack(lf, newtarget, AI_FOLLOWTIME)) { + // failed for some reason. maybe target was feigning + // death? } else { - if (db) dblog(".oO { won't move towards target - i have no weapon. }"); - } + // then move towards them... + if (db) dblog(".oO { moving towards my new target }"); + + if (icanattack) { + if (!movetowards(lf, newtarget->cell, DT_ORTH)) return; + } else { + if (db) dblog(".oO { won't move towards target - i have no weapon. }"); + } + } } - /* - // look for a target to attack based on our allegiance - switch (getallegiance(lf)) { - int i; - int x,y; - case AL_HOSTILE: - if (db) dblog(".oO { i am hostile. looking for a target. }"); - - // look around for a target - for (i = 0; i < lf->nlos; i++) { - cell_t *c; - c = lf->los[i]; - - if (c->lf && cansee(lf, c->lf)) { - if (isplayer(c->lf)) { // TODO: change to if isenemy ? - if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name); - - aiattack(lf, c->lf, AI_FOLLOWTIME); - // then move towards them... - if (db) dblog(".oO { moving towards my new target }"); - - if (icanattack) { - if (!movetowards(lf, c, DT_ORTH)) return; - } else { - if (db) dblog(".oO { won't move towards target - i have no weapon. }"); - } - break; - } - } - } - break; - case AL_FRIENDLY: // are we friendly? if so, look for a target - if (db) dblog(".oO { i am friendly to the player. looking for a target. }"); - // look around for a target - // TODO: use our vis rang einstead of 10! - for (y = lf->cell->y - 10; y <= lf->cell->y + 10; y++) { - for (x = lf->cell->x - 10; x <= lf->cell->x + 10; x++) { - c = getcellat(lf->cell->map, x, y); - // cell exists and we can see it? - if (c && c->lf && (c->lf != lf) && cansee(lf, c->lf)) { - // player there? - //if (!isplayer(c->lf) && !ispeaceful(c->lf)) { - if (areenemies(lf, c->lf)) { - if (db) dblog(".oO { found a target - lfid %d (%s) ! }",c->lf->id, c->lf->race->name); - // target them! - addtempflag(lf->flags, F_TARGET, c->lf->id, c->x, c->y, NULL, AI_FOLLOWTIME); - // then move towards them... - if (db) dblog(".oO { moving towards my new target }"); - if (!movetowards(lf, c, DT_ORTH)) return; - } - } - } - } - break; - default: - break; - } - */ - - /////////////////////////////////////////////// // training /////////////////////////////////////////////// @@ -1484,6 +1530,8 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if (ot->id == OT_A_HIDE) { if (lfhasflag(victim, F_HIDING)) { specificcheckok = B_FALSE; + } else if (lfhasflag(victim, F_FEIGNINGDEATH)) { + specificcheckok = B_FALSE; } else if (!safetorest(victim)) { specificcheckok = B_FALSE; } diff --git a/ai.h b/ai.h index 920a679..adb9a83 100644 --- a/ai.h +++ b/ai.h @@ -1,7 +1,7 @@ #include "defs.h" void addignorecell(lifeform_t *lf, cell_t *c); -void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit); +int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit); enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim); enum OBTYPE aigetfleespell(lifeform_t *lf); cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir); @@ -9,6 +9,7 @@ object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra); void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose); object_t *aigetwand(lifeform_t *lf, enum FLAG purpose); flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit); +flag_t *aihastarget(lifeform_t *lf); int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack); void aimovetotargetcell(lifeform_t *lf, flag_t *f); int aipickup(lifeform_t *lf, object_t *o); diff --git a/attack.c b/attack.c index 267f4c9..5562270 100644 --- a/attack.c +++ b/attack.c @@ -61,10 +61,10 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty // SOME of the damage reduction goes towards the armour // damage taken by armour is reduced by half its armour rating if (ar) { - int max; - max = ar/2; - if (max >= 1) { - actualdam -= rnd(0,max); + int maxreduction; + maxreduction = ar/2; + if (maxreduction >= 1) { + actualdam -= rnd(0,maxreduction); limit(&actualdam, 0, NA); } } @@ -132,6 +132,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { int attacksdone = 0; int lastweaponidx = -1; flag_t *sf; + int saysorry = B_FALSE; // anyone there? if so just attack. if (c->lf) { @@ -172,7 +173,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { priwep = getweapon(lf); // confirm ? - if (!force && isplayer(lf) && wepdullable(priwep) && (getiqname(getattr(player, A_IQ), NULL) >= IQ_SMART) ) { + if (!force && isplayer(lf) && wepdullable(priwep) && (getattrbracket(getattr(player, A_IQ), A_IQ, NULL) >= AT_GTAVERAGE) ) { char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN]; char ch; real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE); @@ -244,7 +245,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { objecttype_t *ot; if (!op) { - op = addobpile(NULL, NULL); + op = addobpile(NULL, NULL, NULL); } ot = findot(f->val[0]); @@ -330,7 +331,14 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { if (validwep[i]) { if (attacktype == AT_LF) { if (!isdead((lifeform_t *)attacktarget)) { - if (attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i])) break; + lifeform_t *victim; + victim = (lifeform_t *)attacktarget; + // did we just attack someone by accident? + if (!isplayer(lf) && !areenemies(lf, victim) && (lf->race->raceclass->id == RC_HUMANOID) && + (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= A_LOW) ) { + saysorry = B_TRUE; + } + if (attacklf(lf, victim, wep[i], damflag[i])) break; } } else if (attacktype == AT_OB) { if (attackob(lf, (object_t *)attacktarget, wep[i], damflag[i])) break; @@ -356,6 +364,11 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { // now stop hiding killflagsofid(lf->flags, F_HIDING); + + if (saysorry) { + sayphrase(lf, SP_SORRY, -1, NA, NULL); + } + return B_FALSE; } @@ -367,6 +380,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) char attackername[BUFLEN]; char victimname[BUFLEN]; int fatal = B_FALSE; + int feigneddeath = B_FALSE; int deflected = B_FALSE; int weppassthrough = B_FALSE; int firstisbackstab = B_FALSE; @@ -424,9 +438,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (lf->race->raceclass->id == RC_INSECT) { if (hasactivespell(victim, OT_S_REPELINSECTS)) { if (isplayer(lf)) { - msg("Something prevents you from attacking %s!", victimname); + msg("^wSomething prevents you from attacking %s!", victimname); } else if (cansee(player, lf)) { - msg("Something prevents %s from attacking %s!", attackername, victimname); + msg("^wSomething prevents %s from attacking %s!", attackername, victimname); } taketime(lf, getattackspeed(lf)); return B_FALSE; @@ -438,9 +452,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // ie. you have been made noncorporeal if ((f->id == F_NONCORPOREAL) && (f->lifetime != FROMRACE)) { if (isplayer(lf)) { - msg("Your attack passes straight through %s.", victimname); + msg("^wYour attack passes straight through %s.", victimname); } else if (cansee(player, lf)) { - msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname); + msg("^w%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname); } taketime(lf, getattackspeed(lf)); return B_FALSE; @@ -450,8 +464,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // did you hit? ndam = 0; - - hit = rolltohit(lf, victim, wep, &critical); // weapon passing through ghosts etc? @@ -563,6 +575,12 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } + // target asleep? + if (lfhasflag(victim, F_ASLEEP)) { + dam[0] *= 2; + } + + // bonus for knowledge about the other lf's race? applied LAST. slev = getlorelevel(lf, victim->race->raceclass->id); if (slev == PR_INEPT) { @@ -598,6 +616,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (firstisbackstab && (i == 0)) backstab = B_TRUE; //dblog("initial dam[%d] = %d",i,dam[i]); + // slightly more damage for heavy blows if (lfhasflag(lf, F_HEAVYBLOW) || hasflag(wep->flags, F_HEAVYBLOW)) { dam[i] = (int)pctof(110,dam[i]); //dblog("heavy blow makes dam[%d] = %d",i,dam[i]); @@ -635,105 +654,134 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) //dblog("reduced by armour to dam[%d] = %d",i,dam[i]); } + if (lfhasflag(lf, F_QUIVERINGPALM)) { + // make sure damage isn't fatal + if (dam[i] >= victim->hp) { + dam[i] = victim->hp - 1; + } + } + // will this hit be fatal? if (dam[i] >= victim->hp) { fatal = B_TRUE; } + // monsters feigning death? + if (lfhasflag(victim, F_FEIGNINGDEATH)) { + killflagsofid(victim->flags, F_FEIGNINGDEATH); + } else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) { + if (onein(6) || isbleeding(victim)) { + // do it! + useability(victim, OT_A_FEIGNDEATH, lf, lf->cell); + feigneddeath = B_TRUE; + } + } + // announce it - if (isplayer(lf)) { - char extradambuf[BUFLEN]; - char withwep[BUFLEN]; - char *verb; - int needfree = B_FALSE; - - strcpy(extradambuf, ""); - - if (wep && !ismeleeweapon(wep)) { - sprintf(withwep, " with %s", wepname); - } else { - strcpy(withwep, ""); - } - - strcpy(extradambuf, ""); - if (dam[i] == 0) { - if (getlorelevel(lf, victim->race->raceclass->id) >= PR_ADEPT) { - strcpy(extradambuf, " but do no damage"); - } - } else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) { - sprintf(extradambuf, " [%d dmg]",dam[i]); - } - - if (backstab && (i == 0)) { - verb = strdup("backstab"); - needfree = B_TRUE; - } else if (fatal) { - verb = getkillverb(victim, wep, damtype[i], dam[i], victim->maxhp); - } else { - if ((getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) || - !ismeleedam(damtype[i])) { - verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp); - } else { - // always use verb for 10% - verb = getattackverb(lf, wep, damtype[i], pctof(10, victim->maxhp), victim->maxhp); - } - } - warn("You %s %s%s%s%s", - verb, - victimname, withwep,extradambuf, - (fatal || backstab) ? "!" : "."); - - if (fatal && strstr(verb, "behead")) { - addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL); - } - - if (fatal && !hasflag(victim->flags, F_NODEATHANNOUNCE)) { - // don't also say "the xx dies" - addflag(victim->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); - } - if (needfree) { - free(verb); - } - } else { - if (cansee(player, lf) || isplayer(victim)) { + if (!feigneddeath) { + if (isplayer(lf)) { + char extradambuf[BUFLEN]; char withwep[BUFLEN]; - char attackverb[BUFLEN]; - char nodamstr[BUFLEN]; + char *verb; + int needfree = B_FALSE; - // capitalise first letter - strcpy(buf, attackername); - capitalise(buf); - - if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) { + strcpy(extradambuf, ""); + + if (wep && !ismeleeweapon(wep)) { sprintf(withwep, " with %s", wepname); } else { strcpy(withwep, ""); - } - - strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp)); - if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) { - strcpy(nodamstr, " but does no damage"); - } else { - strcpy(nodamstr, ""); } - warn("%s %s%s %s%s%s.", buf, attackverb, - needses(attackverb) ? "es" : "s", - victimname,withwep, nodamstr); - } - noise(lf->cell, lf, NC_OTHER, 3, "sounds of fighting.", NULL); + + strcpy(extradambuf, ""); + if (dam[i] == 0) { + if (getlorelevel(lf, victim->race->raceclass->id) >= PR_ADEPT) { + strcpy(extradambuf, " but do no damage"); + } + } else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) { + sprintf(extradambuf, " [%d dmg]",dam[i]); + } + + if (backstab && (i == 0)) { + verb = strdup("backstab"); + needfree = B_TRUE; + } else if (fatal) { + verb = getkillverb(victim, wep, damtype[i], dam[i], victim->maxhp); + } else { + if ((getlorelevel(lf, victim->race->raceclass->id) >= PR_BEGINNER) || + !ismeleedam(damtype[i])) { + verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp); + } else { + // always use verb for 10% + verb = getattackverb(lf, wep, damtype[i], pctof(10, victim->maxhp), victim->maxhp); + } + } + warn("^%cYou %s %s%s%s%s", fatal ? 'g' : 'n', + verb, + victimname, withwep,extradambuf, + (fatal || backstab) ? "!" : "."); + + if (fatal && strstr(verb, "behead")) { + addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL); + } + + if (fatal && !hasflag(victim->flags, F_NODEATHANNOUNCE)) { + // don't also say "the xx dies" + addflag(victim->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); + } + if (needfree) { + free(verb); + } + } else { + if (cansee(player, lf) || isplayer(victim)) { + char withwep[BUFLEN]; + char attackverb[BUFLEN]; + char nodamstr[BUFLEN]; + int nodam = B_FALSE; + + // capitalise first letter + strcpy(buf, attackername); + capitalise(buf); + + if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) { + sprintf(withwep, " with %s", wepname); + } else { + strcpy(withwep, ""); + } + + strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp)); + if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) { + nodam = B_TRUE; + strcpy(nodamstr, " but does no damage"); + } else { + strcpy(nodamstr, ""); + } + warn("^%c%s %s%s %s%s%s.", (isplayer(victim) && !nodam) ? 'b' : 'n', buf, attackverb, + needses(attackverb) ? "es" : "s", + victimname,withwep, nodamstr); + } + noise(lf->cell, lf, NC_OTHER, 3, "sounds of fighting.", NULL); + } } if (willheal) { if (cansee(player, victim)) { flag_t *f; - msg("%s %s healed!",victimname, isplayer(victim) ? "are" : "is"); + if (areallies(player, victim)) { + msg("^g%s %s healed!",victimname, isplayer(victim) ? "are" : "is"); + } else { + msg("^w%s %s healed!",victimname, isplayer(victim) ? "are" : "is"); + } f = hasflag(wep->flags, F_BALANCE); if (f) { f->known = B_TRUE; } gainhp(victim, dam[i]); } + } else if (lfhasflag(lf, F_QUIVERINGPALM)) { + // victim explodes! + losehp_real(victim, victim->hp, DT_EXPLOSIVE, lf, "a quivering palm strike", B_FALSE); } else { char attackername2[BUFLEN]; real_getlfname(lf, attackername2, B_FALSE); @@ -796,7 +844,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) real_getlfname(lf, lfname, B_FALSE); losehp_real(victim, dam, DT_BITE, lf, lfname, B_FALSE); if (isplayer(victim) || cansee(player, victim)) { - msg("%s bites %s!", lfname, victimname); + msg("^%c%s bites %s!", isplayer(victim) ? 'b' : 'n', lfname, victimname); } } } @@ -822,7 +870,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) sprintf(damstring, "%s pack", lfname); losehp(victim, f->val[0], f->val[1], lf, damstring); if (isplayer(victim) || cansee(player, victim)) { - msg("%s pack attacks %s!", lfname, victimname); + msg("%c%s pack attacks %s!", isplayer(victim) ? 'b' : 'c', lfname, victimname); } } } @@ -870,7 +918,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) char damstring[BUFLEN]; rdam = rolldie(f->val[0], f->val[1]); if (cansee(player, victim)) { - msg("%s%s %s %s %s!", victimname, getpossessive(victimname), + msg("^%c%s%s %s %s %s!", isplayer(victim) ? 'b' : 'n', victimname, getpossessive(victimname), noprefix(f->text), getattackverb(victim, NULL, f->val[2], rdam, lf->maxhp), attackername); @@ -885,17 +933,17 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // announce it if (weppassthrough) { if (cansee(player, lf)) { - msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname); + msg("^w%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname); } } else if (deflected) { if (cansee(player, lf)) { - msg("%s deflect%s %s%s attack.", victimname, isplayer(victim) ? "" : "s",attackername, getpossessive(attackername)); + msg("^w%s deflect%s %s%s attack.", victimname, isplayer(victim) ? "" : "s",attackername, getpossessive(attackername)); } } else if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) { if (isplayer(lf) || cansee(player, lf)) { sprintf(buf, "%s",attackername); - msg("%s%s magnetic shield repels %s%s attack.", victimname, getpossessive(victimname), + msg("^w%s%s magnetic shield repels %s%s attack.", victimname, getpossessive(victimname), buf, getpossessive(buf)); } } else { @@ -921,7 +969,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) flag_t *f; f = addflag(victim->flags, F_NOTIME, B_TRUE, NA, NA, NULL); moveto(victim, adj, B_FALSE, B_FALSE); - msg("%s dodge%s!",victimname,isplayer(victim) ? "" : "s"); + msg("^w%s dodge%s!",victimname,isplayer(victim) ? "" : "s"); killflag(f); } @@ -1054,7 +1102,6 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { } else { strcpy(withwep, ""); } - msg("%s %ss %s%s.", attackername, getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep); } else { @@ -1066,7 +1113,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { sprintf(buf, "punching %s", obname); if ( losehp(lf, 1, DT_BASH, lf, buf)) { if (isplayer(lf)) { - msg("Ow!"); + msg("^bOw!"); } } } @@ -1118,21 +1165,21 @@ int damtypecausesbleed(enum DAMTYPE dt) { // returns the amount of damage the armour blocked... int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) { int reduceamt = 0; - int ar; - int pctrange; + int ar,min; + //int pctrange; object_t *o; ar = getarmourrating(lf, NULL, NULL, NULL); - //reducepct = getdamreducepct(ar); - //reduceamt = (int) ceil((reducepct / 100.0) * (float)dam); - - //reduceamt = ar/2; - // between 25% and 75% of AR. // ie. with AR of 20, all damage is reduced by 5-15. - pctrange = rnd(25,75); - reduceamt = pctof(pctrange, ar); + //pctrange = rnd(25,75); + //reduceamt = pctof(pctrange, ar); + + // between ar/5 and AR + min = ar/5; + reduceamt = rnd(min, ar); + // special case if (damtype == DT_PROJECTILE) { @@ -1486,46 +1533,6 @@ void getdamrange(flag_t *f, int *min, int *max) { if (max) *max = maxdam; } -/* -void getdamrangeunarmed(flag_t *f, int *min, int *max) { - obpile_t *op = NULL; - object_t *o = NULL; - flag_t *damflag = NULL; - - if (strlen(f->text)) { - damflag = f; - } else { - objecttype_t *ot; - ot = findot(f->val[0]); - op = addobpile(NULL, NULL); - // create the fake weapon - o = addob(op, ot->name); - if (o) { - damflag = hasflag(o->flags, F_DAM); - } - } - - - if (damflag) { - int ndice,nsides,mod; - texttodice(damflag->text, &ndice, &nsides, &mod); - - if (min) *min = (ndice * 1) + mod; - if (max) *max = (ndice * nsides) + mod; - } else { - if (min) *min = 0; - if (max) *max = 0; - } - - if (o) { - killob(o); - } - if (op) { - free(op); - } -} -*/ - // roll for damage int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) { @@ -1660,44 +1667,6 @@ float getstrdammod(lifeform_t *lf) { } -// determine attack type for lifeform. -// allocate a pile and add weapon to it. -// return the pile. remember to free it! -/* -obpile_t *getunarmedweapon(lifeform_t *lf,flag_t **uflag) { - int nposs; - flag_t *f; - int sel; - char poss[MAXPILEOBS][BUFLEN]; - obpile_t *op; - flag_t *possflag[MAXPILEOBS]; - - op = addobpile(NULL, NULL); - - // pick a random attack type. - nposs = 0; - for (f = lf->flags->first ; f ; f = f->next) { - if (f->id == F_HASATTACK) { - strcpy(poss[nposs],f->text); - possflag[nposs] = f; - nposs++; - } - } - if (nposs > 0) { - object_t *uob; - sel = rnd(0,nposs-1); - uob = addob(op, poss[sel]); - assert(uob); - if (uflag) *uflag = possflag[sel]; - } - - if (!op->first) { - if (uflag) *uflag = NULL; - } - return op; -} -*/ - // ie. caused by hitting something with a melee weapon int ismeleedam(enum DAMTYPE damtype) { switch (damtype) { @@ -1848,15 +1817,16 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) acc += 50; } + // modify for lore level + if (slev != PR_INEPT) { + acc += (slev*10); + } limit(&acc, 0, 100); //if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc); myroll = rnd(1,100); - if (slev != PR_INEPT) { - myroll += (slev*10); - } // modify for lore if (myroll <= acc) { @@ -1894,7 +1864,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { addob(where->obpile, "small fire"); // announce if (haslos(player, where)) { - msg("A column of fire erupts from the ground!"); + msg("^wA column of fire erupts from the ground!"); f->known = B_KNOWN; } } @@ -1927,10 +1897,10 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { // announce if (isplayer(owner)) { - msg("Your %s blasts %s!",noprefix(obname),victimname); + msg("^wYour %s blasts %s!",noprefix(obname),victimname); f->known = B_TRUE; } else if (cansee(player, owner)) { - msg("%s%s %s blasts %s!",buf, getpossessive(buf),noprefix(obname),victimname); + msg("^w%s%s %s blasts %s!",buf, getpossessive(buf),noprefix(obname),victimname); f->known = B_TRUE; } @@ -1961,7 +1931,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { getlfname(owner,lfname); getlfname(victim, victimname); if (cansee(player, owner)) { - msg("%s disarm%s %s!",lfname, isplayer(owner) ? "" : "s", victimname); + msg("^w%s disarm%s %s!",lfname, isplayer(owner) ? "" : "s", victimname); } drop(victimwep, ALL); } @@ -1983,7 +1953,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { getlfname(owner,lfname); getlfname(victim, victimname); if (cansee(player, owner)) { - msg("%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname); + msg("^w%s trip%s %s.",lfname, isplayer(owner) ? "" : "s", victimname); } fall(victim, NULL, B_TRUE); } diff --git a/data/npcnames.txt b/data/npcnames.txt new file mode 100644 index 0000000..f9b227b --- /dev/null +++ b/data/npcnames.txt @@ -0,0 +1,301 @@ +james +john +robert +michael +william +david +richard +charles +joseph +thomas +christopher +daniel +paul +mark +donald +george +kenneth +steven +edward +brian +ronald +anthony +kevin +jason +matthew +gary +timothy +jose +larry +jeffrey +frank +scott +eric +stephen +andrew +raymond +gregory +joshua +jerry +dennis +walter +patrick +peter +harold +douglas +henry +carl +arthur +ryan +roger +joe +juan +jack +albert +jonathan +justin +terry +gerald +keith +samuel +willie +ralph +lawrence +nicholas +roy +benjamin +bruce +brandon +adam +harry +fred +wayne +billy +steve +louis +jeremy +aaron +randy +howard +eugene +carlos +russell +bobby +victor +martin +ernest +phillip +todd +jesse +craig +alan +shawn +clarence +sean +philip +chris +johnny +earl +jimmy +antonio +danny +bryan +tony +luis +mike +stanley +leonard +nathan +dale +manuel +rodney +curtis +norman +allen +marvin +vincent +glenn +jeffery +travis +jeff +chad +jacob +lee +melvin +alfred +kyle +francis +bradley +jesus +herbert +frederick +ray +joel +edwin +don +eddie +ricky +troy +randall +barry +alexander +bernard +mario +leroy +francisco +marcus +micheal +theodore +clifford +miguel +oscar +jay +jim +tom +calvin +alex +jon +ronnie +bill +lloyd +tommy +leon +derek +warren +darrell +jerome +floyd +leo +alvin +tim +wesley +gordon +dean +greg +jorge +dustin +pedro +derrick +dan +lewis +zachary +corey +herman +maurice +vernon +roberto +clyde +glen +hector +shane +ricardo +sam +rick +lester +brent +ramon +charlie +tyler +gilbert +gene +marc +reginald +ruben +brett +angel +nathaniel +rafael +leslie +edgar +milton +raul +ben +chester +cecil +duane +franklin +andre +elmer +brad +gabriel +ron +mitchell +roland +arnold +harvey +jared +adrian +karl +cory +claude +erik +darryl +jamie +neil +jessie +christian +javier +fernando +clinton +ted +mathew +tyrone +darren +lonnie +lance +cody +julio +kelly +kurt +allan +nelson +guy +clayton +hugh +max +dwayne +dwight +armando +felix +jimmie +everett +jordan +ian +wallace +ken +bob +jaime +casey +alfredo +alberto +dave +ivan +johnnie +sidney +byron +julian +isaac +morris +clifton +willard +daryl +ross +virgil +andy +marshall +salvador +perry +kirk +sergio +marion +tracy +seth +kent +terrance +rene +eduardo +terrence +enrique +freddie +wade + diff --git a/defs.h b/defs.h index 65d9f96..d57fd15 100644 --- a/defs.h +++ b/defs.h @@ -17,7 +17,7 @@ */ // ncurses colours -#define C_NONE -1 +#define C_NONE (-1) enum COLOUR { C_BLACK = 0, C_RED = 1, @@ -45,6 +45,18 @@ enum NOISECLASS { NC_OTHER = 2, }; +enum SAYPHRASE { + SP_DRUNK, + SP_PAYWARN, + SP_PAYTHREAT, + SP_RECRUIT_ACCEPT, + SP_RECRUIT_ASKPRICE, + SP_RECRUIT_DECLINE, + SP_RECRUIT_DECLINE_CANTPAY, + SP_RECRUIT_DECLINE_WONTPAY, + SP_SORRY +}; + enum SPEECHVOL { SV_SILENT = 0, SV_WHISPER = 1, @@ -78,6 +90,7 @@ enum SKILL { SK_SWIMMING, SK_TECHUSAGE, SK_THIEVERY, + SK_THROWING, SK_TRACKING, SK_TRAPS, SK_TWOWEAPON, @@ -100,6 +113,7 @@ enum SKILL { SK_SS_AIR, SK_SS_DEATH, SK_SS_DIVINATION, + SK_SS_ENCHANTMENT, SK_SS_FIRE, SK_SS_COLD, SK_SS_GRAVITY, @@ -111,7 +125,7 @@ enum SKILL { SK_SS_TRANSLOCATION, SK_SS_WILD, }; -#define MAXSKILLS 52 +#define MAXSKILLS 54 // proficiency levels enum SKILLLEVEL { @@ -138,6 +152,7 @@ enum SKILLLEVEL { #define NOBODY (-1) #define ALLCONFERRED (-9873) #define PCT (65432) // must be POSITIVE +#define RANDOM (-2610) #define AUTO (-7654) @@ -155,11 +170,12 @@ enum ATTRIB { A_NONE = -1, A_STR = 0, A_DEX = 1, - A_IQ = 2, - A_CON = 3, - A_CHA = 4, + A_WIS = 2, + A_IQ = 3, + A_CON = 4, + A_CHA = 5, }; -#define MAXATTS 5 +#define MAXATTS 6 enum CHECKTYPE { SC_STR, @@ -167,6 +183,7 @@ enum CHECKTYPE { SC_IQ, SC_CON, SC_CHA, + SC_WIS, ////////// SC_CLIMB, SC_DISARM, @@ -182,6 +199,7 @@ enum CHECKTYPE { SC_SEARCH, SC_STEAL, SC_STEALTH, + SC_TUMBLE, SC_WILL, }; @@ -213,7 +231,7 @@ enum SENSE { // AI defs // if target lf is out of view for this many turns, abandon chase -#define AI_FOLLOWTIME (10) +#define AI_FOLLOWTIME (30) #define DEFAULTRESTHEALTIME (3) @@ -222,29 +240,40 @@ enum SENSE { #define RO_NONE 0 #define RO_DAMTYPE 1 #define RO_OBCLASS 2 +#define RO_HOLDABLE 3 -// for flags +// flag lifetimes #define PERMENANT (-9873) -#define FROMRACE (-9872) -#define FROMJOB (-9871) -#define FROMOBEQUIP (-9870) -#define FROMOBHOLD (-9869) -#define FROMOBACTIVATE (-9868) -#define FROMMAT (-9867) -#define FROMBLESSING (-9866) -#define FROMBRAND (-9865) -#define FROMOBMOD (-9864) #define FROMSPELL (-9863) #define FROMPOISON (-9862) +// external sources (ie. don't kill them) +#define FROMEXTERNAL_HIGH (-7000) +#define FROMRACE (-7872) +#define FROMJOB (-7871) +#define FROMOBEQUIP (-7870) +#define FROMOBHOLD (-7869) +#define FROMOBACTIVATE (-7868) +#define FROMMAT (-7867) +#define FROMBLESSING (-9866) +#define FROMBRAND (-7865) +#define FROMOBMOD (-7864) +#define FROMEXTERNAL_LOW (-7999) + + #define LEVABILITYDONE (-8000) #define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known. #define IFACTIVE (-9771) // used by f_prodeuceslight. only does so if object is activated -#define NOCONDITION (0) -#define IFMONSTER (-9769) // used in v2 of f_ifpct job flags -#define IFPLAYER (-9768) // used in v2 of f_ifpct job flags +enum FLAGCONDITION { + FC_NOCONDITION = 0, + FC_IFPLAYER, + FC_IFMONSTER, +}; +//#define NOCONDITION (0) +//#define IFMONSTER (-9769) // used in v2 of f_ifpct job flags +//#define IFPLAYER (-9768) // used in v2 of f_ifpct job flags #define ANYROOM (-9770) @@ -262,8 +291,17 @@ enum SENSE { #define MORESTRING "--More--" +#define MSGMORESTRING "^n--More--" #define SOLDOUTSTRING "--SOLD OUT--" +enum MSGCHARCOL { + CC_VBAD, + CC_BAD, + CC_NORMAL, + CC_GOOD, + CC_VGOOD, +}; + // hunger constant - this is how many turns // it will take to go from 'normal' to 'hungry' etc #define HUNGERCONST 200 @@ -361,6 +399,7 @@ enum MODTYPE { #define TT_DOOR 4 #define TT_PLAYER 8 #define TT_ALLY 16 +#define TT_IMPASSABLE 32 // target requirements #define TR_NONE 0 @@ -473,6 +512,7 @@ enum SPELLSCHOOL { SS_AIR, SS_DEATH, SS_DIVINATION, + SS_ENCHANTMENT, SS_FIRE, SS_COLD, SS_GRAVITY, @@ -486,70 +526,21 @@ enum SPELLSCHOOL { SS_LAST, }; -enum CHABRACKET { - CH_RANDOM = -1, - CH_HIDEOUS = 0, - CH_REPULSIVE, - CH_UGLY, - CH_UNATTRACTIVE, - CH_AVERAGE, - CH_ATTRACTIVE, - CH_ALLURING, - CH_BEAUTIFUL, +enum ATTRBRACKET { + AT_RANDOM = -99, + AT_EXLOW = -4, + AT_VLOW = -3, + AT_LOW = -2, + AT_LTAVERAGE = -1, + AT_AVERAGE = 0, + AT_GTAVERAGE = 1, + AT_HIGH = 2, + AT_VHIGH = 3, + AT_EXHIGH = 4, }; -enum STRBRACKET { - ST_RANDOM = -1, - ST_HELPLESS = 0, - ST_FEEBLE = 1, - ST_VWEAK = 2, - ST_WEAK = 3, - ST_AVERAGE = 4, - ST_STRONG = 5, - ST_MIGHTY = 6, - ST_TITANIC = 7, -}; - -enum DEXBRACKET { - DX_RANDOM = -1, - DX_INCOMPETENT = 0, - DX_OAFISH = 1, - DX_INEPT = 2, - DX_CLUMSY = 3, - DX_AWKWARD = 4, - DX_AVERAGE = 5, - DX_DEXTROUS = 6, - DX_NIMBLE = 7, - DX_AGILE = 8, - DX_SWIFT = 9, - DX_SUPERSONIC = 10, -}; - -enum IQBRACKET { - IQ_RANDOM = -1, - IQ_MINDLESS = 0, - IQ_VEGETABLE = 1, - IQ_ANIMAL = 2, - IQ_STUPID = 3, - IQ_DIMWITTED = 4, - IQ_DOPEY = 5, - IQ_AVERAGE = 6, - IQ_SMART = 7, - IQ_ENLIGHTENED = 8, - IQ_GENIUS = 9, -}; - -enum CONBRACKET { - CN_RANDOM = -1, - CN_FRAIL = 0, - CN_SICKLY = 1, - CN_UNHEALTHY = 2, - CN_UNFIT = 3, - CN_AVERAGE = 4, - CN_HEALTHY = 5, - CN_FIT = 6, - CN_HARDY = 7, -}; +#define IQ_MINDLESS AT_EXLOW +#define IQ_ANIMAL AT_VLOW // damage type enum DAMTYPE { @@ -594,6 +585,7 @@ enum OBCLASS { OC_EFFECT, OC_FLORA, OC_FOOD, + OC_FURNITURE, OC_MISC, OC_MISSILE, OC_MONEY, @@ -660,6 +652,7 @@ enum RACE { // human monsters R_HUMAN, R_BANDIT, + R_DRUNK, R_TOWNGUARD, // monsters R_BEHOLDER, @@ -717,6 +710,8 @@ enum RACE { R_BAT, R_BEAR, R_BEARGRIZZLY, + R_CHICKEN, + R_DOG, R_DOGBLINK, R_DOGDEATH, R_DOGWAR, @@ -774,6 +769,7 @@ enum JOB { J_SHOPKEEPER, J_WIZARD, }; +#define J_RANDOM J_NONE enum MATSTATE { MS_SOLID, @@ -822,13 +818,11 @@ enum OBTYPE { OT_STATUE, OT_DOORWOOD, OT_DOORIRON, + OT_FENCEWOOD, + OT_FOUNTAIN, OT_GATEIRON, OT_GATEWOOD, - OT_FENCEWOOD, OT_SIGN, - OT_WOODENTABLE, - OT_WOODENBARREL, - OT_WOODENSTOOL, OT_HOLYCIRCLE, OT_PENTAGRAM, OT_HOLEINGROUND, @@ -876,6 +870,7 @@ enum OBTYPE { OT_JERKY, OT_ROASTMEAT, OT_BREADFRESH, + OT_CARROT, OT_CHOCOLATE, OT_CLOVER, // corpses @@ -887,6 +882,7 @@ enum OBTYPE { OT_POT_AMBROSIA, OT_POT_BLOOD, OT_POT_BLOODC, + OT_POT_COFFEE, OT_POT_COMPETENCE, OT_POT_ELEMENTIMMUNE, OT_POT_ETHEREALNESS, @@ -897,6 +893,7 @@ enum OBTYPE { OT_POT_HEALINGMAJ, OT_POT_INVIS, OT_POT_INVULN, + OT_POT_LEVITATION, OT_POT_MAGIC, OT_POT_OIL, OT_POT_POISON, @@ -1009,6 +1006,7 @@ enum OBTYPE { OT_S_HEALINGMAJ, OT_S_TURNUNDEAD, // -- mental / psionic + OT_S_BODYCONTROL, OT_S_MINDSCAN, OT_S_SLEEP, OT_S_TELEKINESIS, @@ -1068,9 +1066,9 @@ enum OBTYPE { OT_S_SUMMONWEAPON, // -- translocation OT_S_BLINK, - OT_S_PULL, OT_S_DISPERSAL, OT_S_GATE, + OT_S_SUCK, OT_S_TELEPORT, OT_S_TWIDDLE, // -- wild @@ -1093,6 +1091,7 @@ enum OBTYPE { OT_A_COOK, OT_A_DARKWALK, OT_A_DISARM, + OT_A_FEIGNDEATH, OT_A_FLURRY, OT_A_GRAB, OT_A_CHARGE, @@ -1110,7 +1109,9 @@ enum OBTYPE { OT_A_INSPECT, OT_A_HURRICANESTRIKE, OT_A_POLYREVERT, + OT_A_QUIVERINGPALM, OT_A_STEAL, + OT_A_TUMBLE, OT_A_WARCRY, // uses F_NOISETEXT -> N_WARCRY if it is there. // otherwise 'shouts a blood-curdling war cry' // wands @@ -1135,7 +1136,6 @@ enum OBTYPE { OT_BLANKET, OT_BLINDFOLD, OT_BUGLAMP, - OT_CANDELABRUM, OT_CANDLE, OT_GUNPOWDER, OT_LAMPOIL, @@ -1144,6 +1144,8 @@ enum OBTYPE { OT_PANPIPES, OT_PICKAXE, OT_ROPE, + OT_SACK, + OT_SAFEBOX, OT_TORCH, OT_TOWEL, // tech @@ -1166,8 +1168,16 @@ enum OBTYPE { OT_TELEPAD, OT_TENT, OT_XRAYGOGGLES, + // furniture + OT_CANDELABRUM, + OT_FIREPLACE, + OT_WEAPONRACK, + OT_WOODENTABLE, + OT_WOODENBARREL, + OT_WOODENSTOOL, // misc objects OT_BONE, + OT_CHEST, OT_EMPTYFLASK, OT_EMPTYVIAL, OT_CALTROP, @@ -1356,6 +1366,7 @@ enum OBTYPE { OT_CROSSBOWHAND, OT_LONGBOW, OT_REVOLVER, + OT_SHOTGUN, OT_SLING, // special weapons OT_ENERGYBLADE, @@ -1447,6 +1458,11 @@ enum ALLEGIENCE { AL_FRIENDLY, // will help you fight }; +enum POISONSEVERITY { + PS_DISEASE, + PS_POISON, +}; + enum POISONTYPE { P_COLD, P_FOOD, @@ -1455,6 +1471,7 @@ enum POISONTYPE { P_WEAKNESS, }; + enum RANGEATTACK { RA_NONE = 0, RA_GUN, @@ -1505,7 +1522,6 @@ enum FLAG { F_VALUE, // how much an item is worth (over its base weight+material) // weapon/armour flags F_EQUIPPED, // val0 = where it is equipped. CLEAR WHEN OB MOVED! - F_CURAMMO, // currently equipped ammo F_GOESON, // val0 = where it can be equipped. F_BONUS, // val0=bonus/penalty to damage/armour. ie. +1 sword F_THROWMISSILE, // weapon would make a good thrown missle - used by AI @@ -1684,10 +1700,15 @@ enum FLAG { F_TWOHANDED, // weapon uses two hands to weild F_TRIPATTACK, // weapon can trip the victim F_DISARMATTACK, // weapon can disarm the victim + // gun flags F_FIREARM, // this weapon is equipped in bp_secweapon, not _weapon. F_FIRESPEED, // how fast this weapon shoots projectiles - F_AMMOOB, // what object this weapon fires + F_AMMOOB, // v0 = what object this weapon fires. can have multiple types. + F_AMMOCAPACITY, // v0 = max ammo that can be loaded F_RANGE, // range of projectile firing weapon + F_FIRETURNS, // # actions it takes to fire this gun + F_RELOADTURNS, // # actions it takes to reload this gun + // end gun flags F_FLAMESTRIKE, // causes fires where you hit F_BALANCE, // heals target if their maxhp < your maxhp F_REVENGE, // causes damage based on your hp @@ -1718,6 +1739,7 @@ enum FLAG { F_NODIECONVERTTEXT, // don't anounce when this object changes // misc flags F_LINKOB, // val0 = linked object id + // for fountains: v2 = ifknown F_LINKRACE, // val0 = linked race id // scroll flags F_LINKSPELL, // val0 = spell this scroll will cast when read @@ -1770,13 +1792,22 @@ enum FLAG { F_VEGETARIAN, // this lf will not eat meat. F_PARTVEGETARIAN,// this lf will only eat if hunger >= 'hungry' F_CARNIVORE, // this lf will only eat meat. - F_SHIELDPENALTY, // lower your accuracy by val0 due to a cumbersome - // shield + F_SHIELDPENALTY, // lower your acc/ev by val0 due to a cumbersome + // shield. lowered by sk_shield skill. + // v0 is accuracy penalty, v1 is evasion penalty. + F_ARMOURPENALTY, // lower your acc/ev by val0 due to cumbersome + // armour. lowered by sk_armour skill. + // v0 is accuracy penalty, v1 is evasion penalty. F_LEVRACE, // at level v0, this race is promoted to race v1 // must apply this to the BASE race. F_ATTRMOD, // modify attribute val0 by val1. ie. 0=A_STR,1=-3 F_ATTRSET, // forces attribute val0 to be val1. ie. 0=A_STR,1=18 F_SIZE, // val0 = lf size (enum LFSIZE) + F_RANDOMTALKPCT, // v0 = chance of randomly saying something each turn + F_RANDOMTALK, // v0 = sp_xxx for what to say when we randomly talk. + // v1/v2 are min/max volume + // can have multiple of these flags, if so then + // randomly eslect one each time. F_RESTCOUNT, // val0 = how long you've been resting for F_RESTHEALTIME, // val0 = how long to rest before healing hp F_RESTHEALAMT, // val0 = how many hp to gain after resting x turns @@ -1793,12 +1824,16 @@ enum FLAG { F_CANLEARN, // lf is able to learn skill val0 F_STARTOB, // val0 = %chance of starting with it, text = ob name // val1,2 = min/max amounts. if NA, min=max=1. - F_STARTSKILL, // val0 = skill id F_STARTOBDT, // val0 = %chance of starting with damtype val1 F_STARTOBCLASS, // val0 = %chance of starting with obclass val1 // option val2 = addition to map depth for rarity // calculation + F_STARTOBRND, // val0 = %chance of starting with a random ob + // v1 = depth modifier. can use 'RANDOM' + F_CONTAINER, // this object is a container - you can use 'o' + // to take stuff out or put it in. F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid + F_STARTSKILL, // val0 = skill id F_STARTATT, // val0 = A_xxx, val0 = start bracket (ie. IQ_GENIUS) // if text is set, it overrides val0. // text can be: @@ -1830,6 +1865,7 @@ enum FLAG { // (text is a long) F_STAYINHABITAT, // lf will not walk onto a cell of a different // habitat + F_STAYINROOM, // lf will not walk out of roomid v0 F_FALLDISTANCE, // how many floors this lf has fallen through. // ABILITY/SPELL FLAGS / ability flags / spell flags F_FAILEDINSPECT, // lf has failed an inspect check for item id v0 @@ -1850,6 +1886,9 @@ enum FLAG { // monsters with this abil/spell are worth // v0 more xp. F_XPMULTIPLY, // multiply xp val for killing this lf by v0 + F_HIRABLE, // this job/lf can be recruited + F_HIREPRICE, // how much it costs to hire this lf. + F_NOHIRE, // this lf will not be hired. F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc F_LASTDIR, // this is the last direction we moved. //F_OWNERLASTDIR, // for pets, this it the last dir our owner moved @@ -1866,6 +1905,7 @@ enum FLAG { F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on // sight F_HARMLESS, // it is safe to rest around this lf + F_RNDHOSTILE, // v0% chance of being hostile. F_HOSTILE, // lf will attack the player if in sight F_FRIENDLY, // lf will attack all non-players if in sight F_WANTS, // lf will try to pick up object type val0. if @@ -1916,7 +1956,7 @@ enum FLAG { F_HITDICE, // val0: # d4 to roll for maxhp per level. val1: +xx F_MPDICE, // val0: # d4 to roll for maxmp per level. val1: +xx F_JOB, // val0 = player's class/job - F_NAME, // text = player's name + F_NAME, // text = lf's name F_XPMOD, // add/subtract this much from calculated xpval F_BLOODOB, // text = type of object to drop for blood F_DIESPLATTER, // this lf will splatter objcets of type 'text' @@ -1952,6 +1992,8 @@ enum FLAG { F_MORALE, // gain +v0 in morale checks. F_SPOTTED, // you have spotted hiding lf id v0. you lsoe this if they // go out of sight. + F_HEAVYBLOW, // next attack is a heavy blow + F_QUIVERINGPALM, // your next strike will be a quivpalm attack // INTRINSICS F_MAGICARMOUR,// armour is magically boosted. f->text is the description // ie 'magic armour', 'force field' @@ -1963,6 +2005,7 @@ enum FLAG { F_BLIND, // cannot see anything F_DEAF, // cannot hear F_NEEDOBFORSPELLS, // lf can only cast spells if it has object v0 + F_CAFFEINATED, // can't sleep. F_CANCAST, // can cast the spell val0 (need MP) F_CANHEARLF, // you can hear lifeform id v0 (show their glyph) // this flag does not get announced. @@ -1987,6 +2030,7 @@ enum FLAG { F_DETECTMAGIC, // autodetect magic/special objects F_DETECTMETAL, // autodetect nearby metal F_DETECTOBS, // autodetect nearby obs in orthog dist v0 + F_DISEASEIMMUNE, // lf can't be diseased F_DRUNK, // v1 is drunknness - 1-5. F_ENHANCESEARCH, // gives v0 bonus on search checks. F_ENHANCESMELL, // can 'see' scents. @@ -1996,6 +2040,7 @@ enum FLAG { F_EXTRAINFO, // knows extra info F_EXTRALUCK, // lf gets +v0 to all skill checks! F_EXTRAMP, // lf has +v0 % extra maxmp + F_FEIGNINGDEATH, // lf is pretending to be dead F_FLYING, // lf is flying F_FASTACT, // modifier for action speed F_FASTMETAB, // hunger counter increases faster, poison cures faster. @@ -2009,7 +2054,6 @@ enum FLAG { // v2 is save difficulty F_GRABBEDBY,// you've been grabbed by lf id v0 F_GRABBING, // you are grabbing lf id v0 - F_HEAVYBLOW, // next attack is a heavy blow F_HURRICANESTRIKE, // lf is performing a hurricane strike F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks. F_INVISIBLE, // lifeform is invisible @@ -2018,6 +2062,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_GRAVLESSENED,// knockback maeks you go further, can jump further 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 @@ -2052,6 +2097,7 @@ enum FLAG { // if val2 is true, will only make light if ob // is activated! F_SLOWACT, // modifier for action speed + F_SLOWMETAB, // hunger counter increases slower, poison cures slower. F_SLOWMOVE, // modifier for move speed F_SLOWACTMOVE, // modifier for move and action speed F_XRAYVIS, //val0=num of walls we can see through @@ -2096,12 +2142,12 @@ enum FLAG { F_SELECTWEAPON, // this job gets to pick their starting weapon F_NOPLAYER, // players can't pick this job F_HASPET, // this job starts with a pet of race f->text - F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0. - F_ELSE, - F_IFPLAYER, - F_IFMONSTER, - F_ENDIFPLAYER, - F_ENDIFMONSTER, + //F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0. + //F_ELSE, + //F_IFPLAYER, + //F_IFMONSTER, + //F_ENDIFPLAYER, + //F_ENDIFMONSTER, F_LEVSKILL, // at level v0, this job gains 1 point in skill v1 F_LEVABIL, // at level v0, this job gains f_canwill v1. // v2 = how often you can do it (or NA for unlimited) @@ -2230,6 +2276,7 @@ enum SPELLTARGET { #define NOOWNER (NULL) #define NOLOC (NULL) +#define NOOB (NULL) #define B_NOTSOLID (0) #define B_EMPTY (0) @@ -2293,6 +2340,7 @@ enum ERROR { E_LOWIQ, E_LOWSTR, E_LOWCHA, + E_LOWWIS, E_WONT, E_OFFMAP, // charm failure reasons @@ -2352,6 +2400,11 @@ enum COMMAND { }; +typedef struct npcname_s { + char *name; + int valid; +} npcname_t; + typedef struct coord_s { int x,y; } coord_t; @@ -2393,6 +2446,7 @@ enum REGIONTHING { RT_REGIONLINK, // val is enum regiontype to link to. // what is stair object type RT_VAULT, // what is vaultname + RT_RNDVAULTWITHFLAG, // val is wantedflag }; typedef struct regionthing_s { @@ -2405,6 +2459,7 @@ typedef struct regionthing_s { #define MAXOUTLINETHINGS 20 typedef struct regionoutline_s { + int id; regiontype_t *rtype; regionthing_t thing[MAXOUTLINETHINGS]; int nthings; @@ -2416,7 +2471,7 @@ typedef struct region_s { regiontype_t *rtype; regionoutline_t *outline; struct region_s *parentregion; - int nthings; + int nthings; // is this used??? struct region_s *next, *prev; } region_t; @@ -2623,8 +2678,9 @@ typedef struct lifeform_s { typedef struct obpile_s { - lifeform_t *owner;// } Only one of these - cell_t *where; // } should be filled in + lifeform_t *owner;// } Only one of + cell_t *where; // } these should be + struct object_s *parentob; // } filled in struct object_s *first,*last; // for loading @@ -2641,11 +2697,20 @@ typedef struct flagpile_s { int nitems; } flagpile_t; +typedef struct altflagval_s { + enum FLAG id; + int val[3]; + char *text; +} altflagval_t; + typedef struct flag_s { enum FLAG id; int nvals; int val[3]; char *text; + struct altflagval_s *altval; // don't need to save this. + enum FLAGCONDITION condition; + int chance; long obfrom; // for conferred flags, link to object->id. -1 if not conferred. @@ -2657,6 +2722,7 @@ typedef struct flag_s { struct flag_s *next, *prev; } flag_t; + typedef struct material_s { enum MATERIAL id; char *name; @@ -2714,6 +2780,7 @@ typedef struct objecttype_s { char *desc; struct objectclass_s *obclass; material_t *material; + enum LFSIZE size; float weight; // in kilograms struct flagpile_s *flags; struct objecttype_s *next, *prev; @@ -2737,6 +2804,8 @@ typedef struct object_s { long birthtime; flagpile_t *flags; + struct obpile_s *contents; + struct object_s *next, *prev; } object_t; diff --git a/doc/add_attrib.txt b/doc/add_attrib.txt index 8d6a6a2..665b968 100644 --- a/doc/add_attrib.txt +++ b/doc/add_attrib.txt @@ -2,20 +2,24 @@ defs.h: add A_xxx inc MAXATTS + add E_LOWxxx + add CHECKTYPE (SC_xxx) - add xxxBRACKET lf.c: - add getxxxname() - update rollstat() - add rollxxx() + update getattrbracket() update skillcheck() update enhanceskills() question if you can up this at levelup update modattr() + update meetsattreq() + + update weild() E_xxx error message + update jobs io.c: update announceflaggain() and loss() for this stat text.c: + add getattrabbrev() add getattrname() diff --git a/doc/glyphs.txt b/doc/glyphs.txt index 4c3059f..3fda87b 100644 --- a/doc/glyphs.txt +++ b/doc/glyphs.txt @@ -3,7 +3,8 @@ { = water } = gas ^ = trap / dangerous thing -) = dancing weapon +) = weapon +ooo A = avian / bird a = ant B = bat @@ -46,5 +47,5 @@ hybrid human animal? } = gas , = small puddle { = large puddle/pool -( = barrel +( = barrel/container \ = furniture diff --git a/flag.c b/flag.c index 87d288a..d121618 100644 --- a/flag.c +++ b/flag.c @@ -16,6 +16,25 @@ extern int statdirty; extern lifeform_t *player; +altflagval_t *addaltval(flag_t *f, enum FLAG id, int val1, int val2, int val3, char *text) { + f->altval = malloc(sizeof(altflagval_t)); + f->altval->id = id; + f->altval->val[0] = val1; + f->altval->val[1] = val2; + f->altval->val[2] = val3; + if (text) { + f->altval->text = strdup(text); + } else { + f->altval->text = strdup(""); + } + return f->altval; +} + +void addcondition(flag_t *f, enum FLAGCONDITION fc, int chance) { + f->condition = fc; + f->chance = chance; +} + flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text) { return addflag_real(fp, id, val1, val2, val3, text, PERMENANT, B_KNOWN, -1); } @@ -148,6 +167,10 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, f->known = known; f->obfrom = obfromid; + f->altval = NULL; + f->condition = FC_NOCONDITION; + f->chance = 100; + // first blank values for (i = 0; i < 3; i++) { f->val[i] = NA; @@ -357,9 +380,11 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) { case F_BLIND: case F_EATING: case F_FASTMOVE: + case F_FLYING: case F_HASNEWLEVEL: case F_HIDING: case F_INVISIBLE: + case F_LEVITATING: case F_PARALYZED: case F_POISONED: case F_PRODUCESLIGHT: @@ -601,6 +626,15 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch */ } +int istransitoryflag(flag_t *f) { + if ((f->lifetime >= FROMEXTERNAL_LOW) && (f->lifetime <= FROMEXTERNAL_HIGH)) { + return B_FALSE; + } + + return B_TRUE; +} + + // returns true if we did something int killflagsofid(flagpile_t *fp, enum FLAG fid) { flag_t *f,*nextf; @@ -705,6 +739,11 @@ void killflag(flag_t *f) { } // free mem + if (f->text) free(f->text); + if (f->altval) { + if (f->altval->text) free(f->altval->text); + free(f->altval); + } // remove from list nextone = f->next; @@ -751,6 +790,45 @@ void killflagpile(flagpile_t *fp) { free(fp); } +int killtransitoryflags(flagpile_t *fp, enum FLAG fid) { + flag_t *f,*nextf; + int nkilled = 0; + for (f = fp->first ; f ; f = nextf) { + nextf = f->next; + + // gone past the requrested id's number - ie. it's not there. + if (f->id > fid) break; + + if (istransitoryflag(f) && (f->id == fid)) { + killflag(f); + nkilled++; + } + } + return nkilled; +} + +int killtransitoryflagvals(flagpile_t *fp, enum FLAG fid, int val1, int val2, int val3, char *text) { + flag_t *f, *nextf; + int nkilled = 0; + for (f = fp->first ; f ; f = nextf) { + nextf = f->next; + + // gone past the requrested id's number - ie. it's not there. + if (f->id > fid) break; + + if (istransitoryflag(f) && (f->id == fid)) { + if ( ((val1 == NA) || (f->val[0] == val1)) && + ((val2 == NA) || (f->val[1] == val2)) && + ((val3 == NA) || (f->val[2] == val3)) && + ((text == NULL) || strstr(f->text, text))) { + killflag(f); + nkilled++; + } + } + } + return nkilled; +} + void timeeffectsflag(flag_t *f, int howlong) { // special case: if (f->id == F_TRAIL) { @@ -800,6 +878,12 @@ void timeeffectsflag(flag_t *f, int howlong) { case F_POLYMORPHED: warn("You are starting to revert to your original form..."); break; + case F_LEVITATING: + warn("Your levitation is starting to expire..."); + break; + case F_FLYING: + warn("Your ability to fly is starting to expire..."); + break; default: // no message break; } @@ -851,9 +935,15 @@ void timeeffectsflag(flag_t *f, int howlong) { case F_MAGSHIELD: warn("Your magnetic shield is about to expire!"); break; + case F_LEVITATING: + warn("Your levitation is about to expire!"); + break; case F_POLYMORPHED: warn("You are about to revert to your original form!"); break; + case F_FLYING: + warn("Your ability to fly is about to expire!"); + break; default: // no message break; } diff --git a/flag.h b/flag.h index d307440..2ee6296 100644 --- a/flag.h +++ b/flag.h @@ -2,6 +2,8 @@ // functions +altflagval_t *addaltval(flag_t *f, enum FLAG id, int val1, int val2, int val3, char *text); +void addcondition(flag_t *f, enum FLAGCONDITION fc, int chance); flag_t *addflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text); flag_t *addtempflag(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int timeleft); flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, char *text, int lifetime, int known, long obfromid); @@ -19,9 +21,12 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception); flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text); flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text); flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown); +int istransitoryflag(flag_t *f); int killflagsofid(flagpile_t *fp, enum FLAG fid); void killflag(flag_t *f); void killflagpile(flagpile_t *fp); +int killtransitoryflags(flagpile_t *fp, enum FLAG fid); +int killtransitoryflagvals(flagpile_t *fp, enum FLAG fid, int val1, int val2, int val3, char *text); void makeflagknown(flagpile_t *fp); int modcounter(flagpile_t *fp, int amt); void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2); diff --git a/io.c b/io.c index cdbf248..671e68b 100644 --- a/io.c +++ b/io.c @@ -517,6 +517,8 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src cell_t *target[MAX_MAPW*MAX_MAPH]; int ntargets = 0,curtarget = -1; int x,y; + enum ATTRBRACKET iqb; + iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL); // remember previously targetted lifeforms if (startlf > 0) { @@ -534,14 +536,25 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src int valid = B_FALSE; if ((targettype & TT_MONSTER) && haslf(c) && cansee(player, c->lf) && (c->lf->controller != C_PLAYER)) { valid = B_TRUE; - } else if ((targettype & TT_ALLY) && haslf(c) && cansee(player, c->lf) && areallies(c->lf, player)) { - valid = B_TRUE; - } else if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) { - valid = B_TRUE; - } else if ((targettype & TT_OBJECT) && hasknownobject(c)) { + } + if ((targettype & TT_ALLY) && haslf(c) && cansee(player, c->lf) && areallies(c->lf, player)) { valid = B_TRUE; } - + if ((targettype & TT_PLAYER) && haslf(c) && cansee(player, c->lf) && isplayer(c->lf)) { + valid = B_TRUE; + } + if ((targettype & TT_OBJECT) && hasknownobject(c)) { + valid = B_TRUE; + } + if (targettype & TT_IMPASSABLE) { + object_t *o; + for (o = c->obpile->first ; o ; o = o->next) { + if (isimpassableob(o, player)) { + valid = B_TRUE; + break; + } + } + } if (targettype & TT_DOOR) { object_t *o; o = hasobwithflag(c->obpile, F_DOOR); @@ -604,6 +617,15 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src char extrainfo[BUFLEN]; strcpy(extrainfo, ""); getlfnamea(c->lf, buf); + if (lfhasflag(c->lf, F_NAME)) { + job_t *j; + // add on their job + j = getjob(c->lf); + if (j) { + strcat(buf, " the "); + strcat(buf, j->name); + } + } // level /* if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT)) { @@ -633,6 +655,13 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src break; } + // need a certain amount of iq to recognise drunkenness + f = isdrunk(c->lf); + if (f && (iqb >= AT_LTAVERAGE)) { + if (strlen(extrainfo)) strcat(extrainfo, ", "); + strcat(extrainfo, getdrunktext(f)); + } + if (isfleeing(c->lf)) { if (strlen(extrainfo)) strcat(extrainfo, ", "); strcat(extrainfo, "fleeing"); @@ -803,7 +832,8 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src } } - if (strlen(extrainfo)) { + // show iextra info if lf isn't feigning death + if (strlen(extrainfo) && !lfhasflag(c->lf, F_FEIGNINGDEATH)) { char buf2[BUFLEN]; sprintf(buf2, " [%s]",extrainfo); strcat(buf, buf2); @@ -1038,19 +1068,22 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { case F_ATTRMOD: switch (f->val[0]) { case A_STR: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "weaker" : "stronger"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "weaker" : "stronger"); break; case A_CHA: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "less attractive" : "more attractive"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "less attractive" : "more attractive"); break; case A_IQ: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "foolish" : "smarter"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "more stupid" : "smarter"); break; case A_DEX: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "sluggish" : "agile"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "sluggish" : "more agile"); break; case A_CON: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "frail" : "healthier"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "more frail" : "healthier"); + break; + case A_WIS: + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < 0) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "more foolish" : "wiser"); break; } donesomething = B_TRUE; @@ -1061,19 +1094,22 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { myatt = real_getattr(lf, f->val[0], B_TRUE); switch (f->val[0]) { case A_STR: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "weak" : "strong"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "weak" : "strong"); break; case A_CHA: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "ugly" : "attractive"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "ugly" : "attractive"); break; case A_IQ: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "foolish" : "smart"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "stupid" : "smart"); break; case A_DEX: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "sluggish" : "agile"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "sluggish" : "agile"); break; case A_CON: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "frail" : "healthier"); + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "frail" : "healthy"); + break; + case A_WIS: + msg("^%c%s %s %s!",getlfcol(lf, (f->val[1] < myatt) ? CC_BAD : CC_GOOD), lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < 0) ? "foolish" : "wise"); break; } } @@ -1103,17 +1139,17 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { lf2 = findlf(NULL, f->val[0]); if (lf2) { getlfname(lf2, buf); - msg("%s %s on to %s!",lfname, isplayer(lf) ? "latch" : "latches", buf); + msg("^%c%s %s on to %s!",isplayer(lf2) ? 'B' : 'n', lfname, isplayer(lf) ? "latch" : "latches", buf); donesomething = B_TRUE; } break; case F_BEINGSTONED: - msg("%s begin%s to turn to stone!",lfname, isplayer(lf) ? "" : "s"); + msg("^%c%s begin%s to turn to stone!",isplayer(lf) ? 'B' : 'n', lfname, isplayer(lf) ? "" : "s"); donesomething = B_TRUE; break; case F_BLIND: if (isplayer(lf)) { - msg("%s cannot see!",lfname); + msg("^WYou cannot see!"); } else { msg("%s is blinded!",lfname); } @@ -1121,7 +1157,13 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { break; case F_BREATHWATER: if (isplayer(lf)) { - msg("%s can now breath normally underwater.",lfname); + msg("You can now breath normally underwater."); + donesomething = B_TRUE; + } + break; + case F_CAFFEINATED: + if (isplayer(lf)) { + msg("You feel wide awake!"); donesomething = B_TRUE; } break; @@ -1130,7 +1172,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { objecttype_t *ot; ot = findot(f->val[0]); if (ot) { - msg("You have learned the spell '%s'.", ot->name); + msg("^gYou have learned the spell '%s'.", ot->name); donesomething = B_TRUE; } } @@ -1141,7 +1183,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { ot = findot(f->val[0]); if (ot && (!hasflag(ot->flags, F_NOANNOUNCE))) { char buf[BUFLEN]; - sprintf(buf, "You have learned the ability '%s'.", ot->name); + sprintf(buf, "^gYou have learned the ability '%s'.", ot->name); /* if (f->val[2] != NA) { char turnbuf[BUFLEN]; @@ -1171,19 +1213,19 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { break; case F_DTIMMUNE: if (isplayer(lf)) { // don't know if monsters get it - msg("You feel immune to %s!", getdamnamenoun(f->val[0])); + msg("^gYou feel immune to %s!", getdamnamenoun(f->val[0])); donesomething = B_TRUE; } break; case F_DTRESIST: if (isplayer(lf)) { // don't know if monsters get it - msg("You feel resistant to %s!", getdamnamenoun(f->val[0])); + msg("^gYou feel resistant to %s!", getdamnamenoun(f->val[0])); donesomething = B_TRUE; } break; case F_DTVULN: if (isplayer(lf)) { // don't know if monsters get it - msg("You feel vulnerable to %s!", getdamnamenoun(f->val[0])); + msg("^bYou feel vulnerable to %s!", getdamnamenoun(f->val[0])); donesomething = B_TRUE; } break; @@ -1271,7 +1313,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { } break; case F_POISONED: - msg("%s %s very sick.", lfname, isplayer(lf) ? "feel" : "looks"); + msg("^%c%s %s very sick.", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; break; case F_ENHANCESEARCH: @@ -1286,6 +1328,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { } donesomething = B_TRUE; break; + case F_DISEASEIMMUNE: + if (isplayer(lf)) { + msg("Your immune system feels boosted!"); + } + donesomething = B_TRUE; + break; case F_DRUNK: msg("%s %s tipsy.", lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; @@ -1314,7 +1362,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { break; case F_FASTMETAB: if (isplayer(lf)) { // don't know if monsters get it - msg("You feel ravenous!"); + msg("^BYou feel ravenous!"); donesomething = B_TRUE; } break; @@ -1342,26 +1390,32 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { lf2 = findlf(NULL, f->val[0]); if (lf2) { getlfname(lf2, buf); - msg("%s %s %s!",buf, isplayer(lf2) ? "grab" : "grabs", lfname); + msg("^w%s %s %s!",buf, isplayer(lf2) ? "grab" : "grabs", lfname); donesomething = B_TRUE; } break; // don't announce grabbing. case F_GRAVBOOSTED: - msg("%s %s incredibly heavy all of a sudden!",lfname, isplayer(lf) ? "feel" : "looks"); + msg("^%c%s %s incredibly heavy all of a sudden!",getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; break; + case F_GRAVLESSENED: + if (isplayer(lf)) { + msg("You feel very light all of a sudden!",lfname, isplayer(lf) ? "feel" : "looks"); + donesomething = B_TRUE; + } + break; case F_LEVITATING: msg("%s begin%s to levitate in the air!",lfname, isplayer(lf) ? "" : "s"); donesomething = B_TRUE; break; case F_MAGSHIELD: - msg("%s %s surrounded by a magnetic shield!",lfname, is(lf)); + msg("^%c%s %s surrounded by a magnetic shield!",getlfcol(lf, CC_GOOD), lfname, is(lf)); donesomething = B_TRUE; break; case F_NAUSEATED: if (isplayer(lf)) { - msg("You are nauseated by a disgusting stench!"); + msg("^WYou are nauseated by a disgusting stench!"); donesomething = B_TRUE; } else { msg("%s looks very unwell.",lfname); @@ -1373,12 +1427,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; break; case F_PAIN: - msg("%s%s skin erupts in stings and burns!",lfname, getpossessive(lfname)); + msg("^%c%s%s skin erupts in stings and burns!",isplayer(lf) ? 'W' : 'n', lfname, getpossessive(lfname)); donesomething = B_TRUE; break; case F_PARALYZED: if (isplayer(lf)) { - msg("You cannot move!"); + msg("^WYou cannot move!"); } else { msg("%s stops moving!",lfname); } @@ -1444,12 +1498,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { msg("%s %s",lfname, isplayer(lf) ? "feel sluggish." : "looks sluggish."); donesomething = B_TRUE; break; + case F_SLOWMETAB: + if (isplayer(lf)) { // don't know if monsters get it + msg("Your metabolism slows."); + donesomething = B_TRUE; + } + break; case F_SLOWMOVE: msg("%s %s slower.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving"); donesomething = B_TRUE; break; case F_SLOWACTMOVE: - msg("%s %s",lfname, isplayer(lf) ? "feel slow and sluggish." : "looks slow and sluggish."); + msg("%s %s",getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "feel slow and sluggish." : "looks slow and sluggish."); donesomething = B_TRUE; break; case F_SPRINTING: @@ -1482,7 +1542,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { break; case F_WINDSHIELD: if (isplayer(lf)) { - msg("You are surrounded by a whirling cyclone!"); + msg("^gYou are surrounded by a whirling cyclone!"); } else if (cansee(player, lf)) { msg("%s is surrounded by a whirling cyclone!",lfname); } @@ -1567,7 +1627,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less attractive" : "less ugly"); break; case A_IQ: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less smart" : "less foolish"); + msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less smart" : "less stupid"); break; case A_DEX: msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > 0) ? "less agile" : "less sluggish"); @@ -1590,7 +1650,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less attractive" : "less ugly"); break; case A_IQ: - msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less smart" : "less foolish"); + msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less smart" : "less stupid"); break; case A_DEX: msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less agile" : "less sluggish"); @@ -1633,6 +1693,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; } break; + case F_CAFFEINATED: + if (isplayer(lf)) { + msg("%s caffeine high has worn off.",lfname); + donesomething = B_TRUE; + } + break; case F_CANCAST: if (isplayer(lf)) { // don't know if monsters lose it objecttype_t *ot; @@ -1701,8 +1767,14 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { } donesomething = B_TRUE; break; + case F_DISEASEIMMUNE: + if (isplayer(lf)) { + msg("Your immune system no longer feels boosted."); + } + donesomething = B_TRUE; + break; case F_DRUNK: - msg("%s %s more steady now.", lfname, isplayer(lf) ? "feel" : "looks"); + msg("%s %s more sober now.", lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; break; case F_EXTRADAM: @@ -1728,6 +1800,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; break; case F_FASTMETAB: + case F_SLOWMETAB: if (isplayer(lf)) { // don't know if monsters lose it msg("Your metabolic rate has returned to normal."); donesomething = B_TRUE; @@ -1838,6 +1911,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { msg("%s %s no longer stuck to the floor.",lfname, is(lf)); donesomething = B_TRUE; break; + case F_GRAVLESSENED: + if (isplayer(lf)) { + msg("Your weight returns to normal."); + donesomething = B_TRUE; + } + break; case F_LEVITATING: msg("%s %s down to the ground.", lfname, isplayer(lf) ? "float" : "floats"); donesomething = B_TRUE; @@ -2251,7 +2330,6 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int char nextlet = 'a'; int useobletters; //flag_t *f; - object_t *ammo; enum FLAG wantflag[MAXCANDIDATES]; va_list flags; int nwantflags; @@ -2267,11 +2345,6 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int va_end(flags); //dblog("nwantflags is %d",nwantflags); - // remember player's current ammo - if (op->owner) { - ammo = getammo(op->owner); - } - if (countobs(op, B_TRUE) <= 0) { // no objects here cls(); @@ -2463,12 +2536,6 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { char nextlet = 'a'; int useobletters; objectclass_t *wantoc = NULL; - object_t *ammo; - - // remember player's current ammo - if (op->owner) { - ammo = getammo(op->owner); - } clearretobs(); @@ -2888,10 +2955,13 @@ void describeob(object_t *o) { y = 4; if (o->material->id != MT_NOTHING) { if (o->material->id == MT_FOOD) { - sprintf(buf, "%s food product%s, ",(o->amt == 1) ? "It is a" : "They are", + sprintf(buf, "%s %s food product%s, ",(o->amt == 1) ? "It is a" : "They are", + getsizetext(getobsize(o)), (o->amt == 1) ? "" : "s"); } else { - sprintf(buf, "%s made from %s, ",(o->amt == 1) ? "It is" : "They are", o->material->name); + sprintf(buf, "%s %s sized, made from %s, ",(o->amt == 1) ? "It is" : "They are", + getsizetext(getobsize(o)), + o->material->name); } if (o->amt == 1) { @@ -2941,7 +3011,7 @@ void describeob(object_t *o) { y++; if (hasflagval(o->flags, F_OBHPDRAIN, NA, DT_DECAY, NA, NULL)) { // don't show "it will rot" if it's already rotten (and you know this) - if (isrotting(o) && ( (getiqname(getattr(player, A_IQ), NULL) >= IQ_SMART) || getskill(player, SK_COOKING)) ) { + if (isrotting(o) && ( (getattrbracket(getattr(player, A_IQ), A_IQ, NULL) >= AT_GTAVERAGE) || getskill(player, SK_COOKING)) ) { } else { mvwprintw(mainwin, y, 0, "%s will decay and go bad over time.", (o->amt == 1) ? "It" : "They" ); y++; @@ -2951,7 +3021,62 @@ void describeob(object_t *o) { // weapons? - if (o->type->obclass->id == OC_WEAPON) { + if (isfirearm(o)) { + flag_t *ff, *ff2; + mvwprintw(mainwin, y, 0, "It is a %s firearm.", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed"); + y++; + f = hasflag(o->flags, F_ACCURACY); + if (f) { + int acc; + acc = getobaccuracy(o, NULL); + mvwprintw(mainwin, y, 0, " It has %s accuracy.",getaccuracyname(acc)); + y++; + } + f = hasflag(o->flags, F_RANGE); + if (f) { + mvwprintw(mainwin, y, 0, " Its maximum range is %d.",f->val[0]); + y++; + } + f = hasflag(o->flags, F_AMMOCAPACITY); + if (f) { + mvwprintw(mainwin, y, 0, " It can hold up to %d of the following kind(s) of ammo:",f->val[0]); + y++; + strcpy(buf, ""); + for (ff = o->flags->first; ff ; ff = ff->next) { + if (ff->id == F_AMMOOB) { + objecttype_t *ot; + ot = findot(ff->val[0]); + if (ot) { + if (streq(buf, "")) { + sprintf(buf, " %s",ot->name); + } else { + if (strlen(buf) >= 60) { + mvwprintw(mainwin, y, 0, "%s",buf); y++; + sprintf(buf, " %s",ot->name); + } else { + strcat(buf, ", "); + strcat(buf, ot->name); + } + } + } + } + } + if (strlen(buf)) { + mvwprintw(mainwin, y, 0, "%s",buf); y++; + } + } + ff = hasflag(o->flags, F_FIRESPEED); + if (ff) { + mvwprintw(mainwin, y, 0, " It fires at a speed of %d km/h.",speedtokph(ff->val[0])); + y++; + } + ff = hasflag(o->flags, F_FIRETURNS); + ff2 = hasflag(o->flags, F_RELOADTURNS); + mvwprintw(mainwin, y, 0, " It takes %d turn%s to fire, and %d turn%s to reload.", + ff->val[0], (ff->val[0] == 1) ? "" : "s", + ff2->val[0], (ff2->val[0] == 1) ? "" : "s"); + y++; + } else if (o->type->obclass->id == OC_WEAPON) { int delay; mvwprintw(mainwin, y, 0, "It is a %s weapon.", hasflag(o->flags, F_TWOHANDED) ? "two-handed" : "single handed"); y++; @@ -3074,7 +3199,12 @@ void describeob(object_t *o) { } } - + f = hasflag(o->flags, F_ACCURACYMOD); + if (f) { + mvwprintw(mainwin, y, 0, " It will %s your evasion chance by %d%%.", buf, + (f->val[0] < 0) ? "lower" : "raise", abs(f->val[0])); y++; + y++; + } f = hasflag(o->flags, F_SCARY); if (f) { @@ -3301,10 +3431,34 @@ void describeob(object_t *o) { // conferred intrinsics switch (f->val[0]) { - int amt; + int amt,amt2; + case F_ARMOURPENALTY: + amt = adjustarmourpenalty(player, f->val[1]); + amt2 = adjustarmourpenalty(player, f->val[2]); + if (amt > 0) { + setcol(mainwin, C_RED); + mvwprintw(mainwin, y, 0, "%s lowers your accuracy by %d%%. (Armour skill penalty)", buf, amt); y++; + unsetcol(mainwin, C_RED); + } + if (amt2 > 0) { + setcol(mainwin, C_RED); + mvwprintw(mainwin, y, 0, "%s lowers your evasion by %d%%. (Armour skill penalty)", buf, amt2); y++; + unsetcol(mainwin, C_RED); + } + break; case F_SHIELDPENALTY: amt = adjustshieldpenalty(player, f->val[1]); - mvwprintw(mainwin, y, 0, "%s lowers your attack accuracy by %d%%.", buf, amt); y++; + amt2 = adjustshieldpenalty(player, f->val[2]); + if (amt > 0) { + setcol(mainwin, C_RED); + mvwprintw(mainwin, y, 0, "%s lowers your attack accuracy by %d%%. (Shields skill too low)", buf, amt); y++; + unsetcol(mainwin, C_RED); + } + if (amt2 > 0) { + setcol(mainwin, C_RED); + mvwprintw(mainwin, y, 0, "%s lowers your evasion by %d%%. (Shields skill penalty)", buf, amt2); y++; + unsetcol(mainwin, C_RED); + } break; case F_ATTRMOD: mvwprintw(mainwin, y, 0, "%s %s your %s.", buf, (f->val[2] > 0) ? "increases" : "decreases", getattrname(f->val[1])); y++; @@ -3339,6 +3493,9 @@ void describeob(object_t *o) { case F_ENHANCESMELL: mvwprintw(mainwin, y, 0, "%s enhances your sense of smell.", buf); y++; break; + case F_DISEASEIMMUNE: + mvwprintw(mainwin, y, 0, "%s makes you immune to disease.", buf); y++; + break; case F_DRUNK: mvwprintw(mainwin, y, 0, "%s makes you tipsy.", buf); y++; break; @@ -3375,6 +3532,9 @@ void describeob(object_t *o) { case F_GRAVBOOSTED: mvwprintw(mainwin, y, 0, "%s increases gravity around you.", buf); y++; break; + case F_GRAVLESSENED: + mvwprintw(mainwin, y, 0, "%s decreases gravity around you.", buf); y++; + break; case F_DODGES: mvwprintw(mainwin, y, 0, "%s allows you to dodge attacks.", buf); y++; break; @@ -3392,6 +3552,9 @@ void describeob(object_t *o) { mvwprintw(mainwin, y, 0, "%s allows you to cast '%s' at will.", buf, buf2); y++; } break; + case F_CAFFEINATED: + mvwprintw(mainwin, y, 0, "%s acts as a stimulant.", buf); y++; + break; case F_CANCAST: ot = findot(f->val[1]); if (ot) { @@ -3470,6 +3633,9 @@ void describeob(object_t *o) { case F_SLOWACT: mvwprintw(mainwin, y, 0, "%s will slow down your actions.", buf); y++; break; + case F_SLOWMETAB: + mvwprintw(mainwin, y, 0, "%s will decrease your metabolic rate.", buf); y++; + break; case F_SLOWMOVE: mvwprintw(mainwin, y, 0, "%s will slow down your movement.", buf); y++; break; @@ -3575,6 +3741,19 @@ void describeob(object_t *o) { } } + if (o->contents->first) { + object_t *oo; + y++; // skip line + mvwprintw(mainwin, y, 0, "%s currently contain%s:", + (o->amt == 1) ? "It" : "They", + (o->amt == 1) ? "s" : ""); + y++; + for (oo = o->contents->first ;oo ; oo = oo->next) { + getobname(oo, buf, oo->amt); + mvwprintw(mainwin, y, 0, " - %s", buf); y++; + } + } + wrefresh(mainwin); @@ -3732,10 +3911,9 @@ void docomms(lifeform_t *lf) { char lfname[BUFLEN]; char ch; int moneyowing = 0; - enum IQBRACKET iqb; + enum ATTRBRACKET iqb; flag_t *f; - if (!lf) { where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE); if (where && where->lf && cansee(player, where->lf)) { @@ -3752,7 +3930,7 @@ void docomms(lifeform_t *lf) { initprompt(&prompt, buf); prompt.maycancel = B_TRUE; - iqb = getiqname(getattr(lf, A_IQ), NULL); + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); // are they friendly? if (ispetof(lf, player)) { @@ -3777,7 +3955,11 @@ void docomms(lifeform_t *lf) { } else { addchoice(&prompt, 'r', "Rest until you are healed.", NULL, NULL); } + addchoice(&prompt, '<', "Stay close.", NULL, NULL); + addchoice(&prompt, '>', "Keep your distance.", NULL, NULL); } + } else if (ishirable(lf) ) { + addchoice(&prompt, 'j', "Join me on my quest!", NULL, NULL); } f = lfhasflag(lf, F_OWNSSHOP); @@ -3843,6 +4025,11 @@ void docomms(lifeform_t *lf) { msg("You say \"Go over there!\" to %s.", lfname); aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME); break; + case 'j': + // charisma check to see if they'll join you. + msg("You say \"Join me on my quest!\" to %s.", lfname); + recruit(lf); + break; case 'n': msg("Cancelled."); return; @@ -3899,11 +4086,11 @@ void docomms(lifeform_t *lf) { dodrop(player->pack, B_MULTIPLE, lf->pack); break; case 'o': - dopickup(lf->pack); + dopickup(lf->pack, B_TRUE); break; case 'b': dodrop(player->pack, B_MULTIPLE, lf->pack); - dopickup(lf->pack); + dopickup(lf->pack, B_TRUE); break; case 'n': msg("Cancelled."); @@ -3914,6 +4101,14 @@ void docomms(lifeform_t *lf) { msg("You shout at %s!", lfname); noise(where, player, NC_OTHER, 3, "someone shouting!", NULL); break; + case '<': + msg("You say \"Stay close!\" to %s.", lfname); + setfollowdistance(lf, 1, 3); + break; + case '>': + msg("You say \"Keep your distance!\" to %s.", lfname); + setfollowdistance(lf, 3, 5); + break; } taketime(player, getactspeed(player)); } @@ -3924,19 +4119,25 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { int count = ALL; int i; lifeform_t *tolf = NULL; - char lfname[BUFLEN]; + object_t *toob = NULL; + char toname[BUFLEN]; // where is destination? if (dst->owner) { tolf = dst->owner; - getlfname(tolf, lfname); + getlfname(tolf, toname); + } else if (dst->parentob) { + toob = dst->parentob; + getobname(toob, toname, toob->amt); } else { // on ground } if (tolf) { - sprintf(buf, "Give what to %s",lfname); + sprintf(buf, "Give what to %s",toname); + } else if (toob) { + sprintf(buf, "Put what in %s",toname); } else { strcpy(buf, "Drop what"); } @@ -3974,7 +4175,9 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { if (unweild(player, o)) { if (nretobs > 1) { if (tolf) { - msg("Not giving %s to %s.",buf, lfname); more(); + msg("Not giving %s to %s.",buf, toname); more(); + } else if (toob) { + msg("Not putting %s into %s.",buf, toname); more(); } else { msg("Not dropping %s.",buf); more(); } @@ -3992,7 +4195,9 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { // failed to take it off - can't drop it. if (nretobs > 1) { if (tolf) { - msg("Not giving %s to %s.",buf, lfname); more(); + msg("Not giving %s to %s.",buf, toname); more(); + } else if (toob) { + msg("Not putting %s into %s.",buf, toname); more(); } else { msg("Not dropping %s.",buf); more(); } @@ -4003,7 +4208,9 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { } else { if (nretobs > 1) { if (tolf) { - msg("Not giving %s to %s.",buf, lfname); more(); + msg("Not giving %s to %s.",buf, toname); more(); + } else if (toob) { + msg("Not putting %s into %s.",buf, toname); more(); } else { msg("Not dropping %s.",buf); more(); } @@ -4019,9 +4226,17 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { o = moveob(o, dst, count); if (o) { getobname(o, buf, o->amt); - msg("%s takes %s from you.",lfname, buf); + msg("%s takes %s from you.",toname, buf); } else { - msg("%s can't carry that.",lfname); + msg("%s can't carry that.",toname); + } + } else if (toob) { + o = moveob(o, dst, count); + if (o) { + getobname(o, buf, o->amt); + msg("You put %s into %s.",buf, toname); + } else { + msg("You can't put %s into %s.",buf, toname); } } else { drop(o, count); @@ -4070,39 +4285,24 @@ void doeat(obpile_t *op) { void dovendingmachine(lifeform_t *lf, object_t *vm) { int y; - flag_t *f; - //int i; int done; char ch; char choices[BUFLEN]; char buf[BUFLEN]; char buf2[BUFLEN]; char toptext[BUFLEN]; - obpile_t *op; - + object_t *o; strcpy(toptext, ""); - op = addobpile(NULL, NULL); + - // populate machine with items - strcpy(choices, ""); - for (f = vm->flags->first ; f ; f = f->next) { - if (f->id == F_CONTAINSOB) { - object_t *o; - - ch = f->val[0]; - if (strlen(f->text)) { - o = addobject(op, f->text, B_FALSE, B_FALSE); // no stacking! - // remember letter - o->letter = ch; - // make object fully known - addflag(o->flags, F_VENDITEM, B_TRUE, NA, NA, NULL); - } - - } + // assign letters to objects + ch = 'a'; + for (o = vm->contents->first ; o ; o = o->next) { + o->letter = ch; + if (++ch > 'z') ch = 'A'; } - // list objects for sale and ask for input done = B_FALSE; while (!done) { @@ -4112,39 +4312,20 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { centre(mainwin,C_WHITE, y, "VENDING MACINE"); y += 2; + // list objects for sale - strcpy(choices, ""); - for (f = vm->flags->first ; f ; f = f->next) { - if (f->id == F_CONTAINSOB) { - char temp[2]; - char obname[BUFLEN]; - object_t *o; - - ch = f->val[0]; - sprintf(temp, "%c",ch); - - if (strlen(f->text)) { - // add this as a valid choice - strcat(choices, temp); - // construct string - o = hasobletter(op, ch); - // get the name of the object - getobname(o, obname, o->amt); - sprintf(buf, "%c - %s", ch, obname); - sprintf(buf2, "%-60s$%d",buf,getobvalue(o)); - mvwprintw(mainwin, y, 0, "%s", buf2); - y++; - } else { - // construct string - sprintf(buf, " %s", SOLDOUTSTRING); - sprintf(buf2, "%-60s",buf); - mvwprintw(mainwin, y, 0, "%s", buf2); - y++; - } - - } + for (o = vm->contents->first ; o ; o = o->next) { + char obname[BUFLEN]; + // get the name of the object + getobname(o, obname, o->amt); + sprintf(buf, "%c - %s", o->letter, obname); + sprintf(buf2, "%-60s$%d",buf,getobvalue(o)); + mvwprintw(mainwin, y, 0, "%s", buf2); + y++; } + + strcpy(choices, ""); y++; @@ -4159,9 +4340,8 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { if (ch == 27) { done = B_TRUE; } else { - object_t *o; // try to find that object... - o = hasobletter(op, ch); + o = hasobletter(vm->contents, ch); if (o) { // do you have enough money? if (countmoney(player) >= getobvalue(o)) { @@ -4177,20 +4357,15 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { sprintf(buf, "Buy %s for $%d?",obname, getobvalue(o)); answer = askchar(buf, "yn","n", B_TRUE); if (answer == 'y') { + int shopamt; givemoney(player, NULL, getobvalue(o)); - //gold->amt -= getobvalue(o); - // clear o->letter + // clear o->letter o->letter = '\0'; // give object + shopamt = o->amt; // avoid "purchased: 2 apples" when you only bought 1 but were holding 1 o = moveob(o, player->pack, ALL); - getobname(o, obname, o->amt); + getobname(o, obname, shopamt); sprintf(toptext, "Purchased: %c - %s", o->letter, obname); - // set F_CONTAINSOB text to "" - ie. sold out - for (f = vm->flags->first ; f ; f = f->next) { - if (f->val[0] == ch) { - strcpy(f->text, ""); - } - } } else { // cancelled strcpy(toptext, ""); @@ -4203,17 +4378,11 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { sprintf(toptext, "You cannot afford that!"); } } else { - sprintf(toptext, "That item is sold out!"); + sprintf(toptext, "No such item."); } // end if o } // end if ch } // end while not done - // free mem - while (op->first) { - killob(op->first); - } - killobpile(op); - restoregamewindows(); } @@ -4305,20 +4474,34 @@ void doknowledgelist(void) { } void dolook(cell_t *where, int onpurpose) { - int numobs; + int numobs,numtrails; char buf[BUFLEN]; char seeverb[BUFLEN]; int seensomething = B_FALSE; object_t *o,*firstob = NULL; flag_t *f; + int includetrails = B_TRUE; // first announce "there is xxx" objects // (also count objects without this flag) numobs = 0; + numtrails = 0; + + + for (o = where->obpile->first ; o ; o = o->next) { + if (!canseeob(player, o)) continue; + if (hasflag(o->flags, F_COSMETIC)) continue; + // footprints/scents only count if there are no other obs here + if (!hasflag(o->flags, F_TRAIL)) { + // found a non-trail object + includetrails = B_FALSE; + } + } for (o = where->obpile->first ; o ; o = o->next) { if (!canseeob(player, o)) continue; //if (hasflag(o->flags, F_SECRET)) continue; if (hasflag(o->flags, F_COSMETIC)) continue; + if (!includetrails && hasflag(o->flags, F_TRAIL)) continue; f = hasflag(o->flags, F_THEREISHERE); if (f) { @@ -4328,10 +4511,10 @@ void dolook(cell_t *where, int onpurpose) { interrupt(player); seensomething = B_TRUE; } else { - //if (onpurpose) { - if (!numobs) firstob = o; + if (!firstob) { + firstob = o; + } numobs++; - // } } } @@ -4660,7 +4843,8 @@ void domsghist(void) { mvwprintw(mainwin, 0, 0, "MESSAGE HISTORY:"); y = 1; for (i = 0; i < nmsghist; i++) { - mvwprintw(mainwin, y, 0, msghist[i]); + wmove(mainwin, y, 0); + textwithcol(mainwin, msghist[i]); y++; } wrefresh(mainwin); @@ -4676,11 +4860,14 @@ void dooperate(obpile_t *op) { for (o = player->cell->obpile->first; o ; o = o->next) { if (isoperable(o)) { char obname[BUFLEN],buf[BUFLEN]; + char verb[BUFLEN]; int ch; getobname(o, obname, o->amt); - sprintf(buf, "There %s %s here. Operate %s", + strcpy(verb, getoperateverb(o)); + capitalise(verb); + sprintf(buf, "There %s %s here. %s %s", (o->amt == 1) ? "is" : "are", - obname, + obname, verb, (o->amt == 1) ? "it" : "one"); ch = askchar(buf, "yn","n", B_TRUE); if (ch == 'y') { @@ -4697,13 +4884,14 @@ void dooperate(obpile_t *op) { } } -int dopickup(obpile_t *op) { +int dopickup(obpile_t *op, int forceask) { int obcount; //object_t *o = NULL; int howmany = ALL; int i; lifeform_t *fromlf = NULL; - char lfname[BUFLEN]; + object_t *fromob = NULL; + char lfname[BUFLEN],fromobname[BUFLEN]; char buf[BUFLEN]; int needtoask = B_TRUE; int failed = B_FALSE; @@ -4711,6 +4899,9 @@ int dopickup(obpile_t *op) { if (op->owner) { fromlf = op->owner; getlfname(fromlf, lfname); + } else if (op->parentob) { + fromob = op->parentob; + getobname(fromob, fromobname, fromob->amt); } obcount = countobs(op, B_TRUE); @@ -4725,7 +4916,7 @@ int dopickup(obpile_t *op) { o = o->next; } if (o) { - if (o->amt == 1) { + if ((o->amt == 1) && (!forceask)) { // just get it howmany = ALL; retobs[0] = o; @@ -4741,6 +4932,8 @@ int dopickup(obpile_t *op) { if (failed) { if (fromlf) { msg("%s is not carrying anything!", lfname); + } else if (fromob) { + msg("%s is empty!", fromobname); } else { msg("There is nothing here to pick up!"); } @@ -4750,6 +4943,8 @@ int dopickup(obpile_t *op) { if (needtoask) { if (fromlf) { sprintf(buf, "Take what from %s",lfname); + } else if (fromob) { + sprintf(buf, "Take what out of %s",fromobname); } else { strcpy(buf, "Pick up what"); } @@ -4783,12 +4978,6 @@ int dopickup(obpile_t *op) { void doenter(lifeform_t *lf) { object_t *enterob; if (isplayer(lf)) { - enterob = hasob(lf->cell->obpile, OT_VENDINGMACHINE); - if (enterob) { - dovendingmachine(lf, enterob); - restoregamewindows(); - return; - } enterob = hasob(lf->cell->obpile, OT_PORTAL); if (enterob) { usestairs(lf, enterob, B_TRUE); @@ -4894,10 +5083,16 @@ void doquaff(obpile_t *op) { char obname[BUFLEN]; char buf[BUFLEN]; char ch; + char drink[BUFLEN]; getobname(o, obname, o->amt); - sprintf(buf, "There %s %s here. Drink %s", + if (o->type->obclass->id == OC_POTION) { + strcpy(drink, "Drink"); + } else { + strcpy(drink, "Drink from"); + } + sprintf(buf, "There %s %s here. %s %s", (o->amt == 1) ? "is" : "are", - obname, + obname, drink, (o->amt == 1) ? "it" : "one"); ch = askchar(buf, "yn","n", B_TRUE); if (ch == 'y') { @@ -5132,9 +5327,10 @@ void dorest(void) { return; } } - startresting(player, willtrain); - // do the first one right away - rest(player, B_TRUE); + if (!startresting(player, willtrain)) { + // do the first one right away + rest(player, B_TRUE); + } } else { switch (reason) { case E_LEVITATING: @@ -5150,7 +5346,7 @@ void dorest(void) { } } -void doselguntarget(void) { +int doselguntarget(void) { object_t *gun; cell_t *where; char buf[BUFLEN],buf2[BUFLEN]; @@ -5158,7 +5354,7 @@ void doselguntarget(void) { gun = getfirearm(player); if (!gun) { msg("You have no firearm equipped!"); - return; + return B_TRUE; } getobname(gun, gunname, 1); @@ -5170,8 +5366,10 @@ void doselguntarget(void) { setguntarget(player, where->lf); } else { setguntarget(player, NULL); + return B_TRUE; } } + return B_FALSE; } void dostairs(int dir) { @@ -5639,6 +5837,23 @@ void dumpspells(void) { } +enum COLOUR getattrcolour(enum ATTRBRACKET brack) { + switch (brack) { + case AT_EXLOW: return C_BOLDMAGENTA; + case AT_VLOW: return C_MAGENTA; + case AT_LOW: return C_RED; + case AT_LTAVERAGE: return C_BROWN; + case AT_AVERAGE: return C_GREY; + case AT_GTAVERAGE: return C_GREEN; + case AT_HIGH: return C_BLUE; + case AT_VHIGH: return C_CYAN; + case AT_EXHIGH: return C_BOLDCYAN; + default: + break; + } + return C_GREY; +} + char getchoice(prompt_t *prompt) { int i; int y; @@ -6341,8 +6556,12 @@ void handleinput(void) { doselguntarget(); break; case 'F': // aim then fire - doselguntarget(); - dofire(); + if (!doselguntarget()) { + dofire(); + } + break; + case 'G': // reload Gun with current ammo + loadfirearmfast(player); break; case '\'': donextguntarget(); @@ -6374,7 +6593,7 @@ void handleinput(void) { dotakeoff(player->pack); break; case ',': // pickup - dopickup(player->cell->obpile); + dopickup(player->cell->obpile, B_FALSE); break; case 'r': // read doread(player->pack); @@ -6500,7 +6719,7 @@ void dblog(char *format, ... ) { // force a '--more--' prompt void more(void) { //msg("^"); - strcat(msgbuf, MORESTRING); + strcat(msgbuf, MSGMORESTRING); //mvwprintw(msgwin, 0, 0, msgbuf); drawmsg(); curs_set(1); @@ -6540,7 +6759,6 @@ void msg(char *format, ... ) { char buf[BUFLEN]; va_list args; - va_start(args, format); vsprintf( buf, format, args ); va_end(args); @@ -6580,6 +6798,7 @@ void msg_real(char *format, ... ) { } } strcat(msgbuf, buf); + strcat(msgbuf, "^n"); // back to normal colour if (db) dblog(" msgbuf is now: [%s]",msgbuf); @@ -6622,31 +6841,59 @@ void drawstatus(void) { flag_t *f; enum ATTRIB a; int myatt[MAXATTS]; - long xpleft; + int xpleft; getplayernamefull(pname); curs_set(0); wclear(statwin); - xpleft = getxpforlev(player->level + 1) - player->xp; + //xpleft = getxpforlev(player->level + 1) - player->xp; + xpleft = (int) (((float)player->xp / (float)getxpforlev(player->level + 1)) * 100.0); wmove(statwin, 0, 0); wattron(statwin, A_BOLD); wprintw(statwin, "["); wattroff(statwin, A_BOLD); - wprintw(statwin, "%-26s ", pname); + wprintw(statwin, "%s", pname); wattron(statwin, A_BOLD); wprintw(statwin, "] "); wattroff(statwin, A_BOLD); - wattron(statwin, A_BOLD); wprintw(statwin, "Lv:"); wattroff(statwin, A_BOLD); + // HP + wattron(statwin, A_BOLD); wprintw(statwin, "HP:"); wattroff(statwin, A_BOLD); + setcol(statwin, getpctcol(player->hp, player->maxhp)); + wprintw(statwin, "%d",player->hp); + unsetcol(statwin, getpctcol(player->hp, player->maxhp)); + wprintw(statwin, "/%d ",player->maxhp); + + // MP + if (getmaxmp(player) == player->maxmp) { + strcpy(maxmpstr, ""); + } else { + sprintf(maxmpstr, "(%d)",player->maxmp); + } + + if (getmaxmp(player) > 0) { + wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD); + setcol(statwin, getpctcol(player->mp, getmaxmp(player))); + wprintw(statwin, "%d",player->mp); + unsetcol(statwin, getpctcol(player->mp, getmaxmp(player))); + wprintw(statwin, "/%d%s ",getmaxmp(player),maxmpstr); + } else { + wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD); + wprintw(statwin, "- "); + } + + + wattron(statwin, A_BOLD); wprintw(statwin, "Xp:"); wattroff(statwin, A_BOLD); sprintf(buf, "%d", player->level); wprintw(statwin, buf); if (lfhasflag(player, F_HASNEWLEVEL)) { + wattron(statwin, A_BOLD); wprintw(statwin, "/"); wattroff(statwin, A_BOLD); setcol(statwin, C_BOLDGREEN); - wprintw(statwin, " LevUp",xpleft); + wprintw(statwin, "LevUp",xpleft); unsetcol(statwin, C_BOLDGREEN); } else { - wattron(statwin, A_BOLD); wprintw(statwin, " Next:"); wattroff(statwin, A_BOLD); - wprintw(statwin, "%ld",xpleft); + wattron(statwin, A_BOLD); wprintw(statwin, "/"); wattroff(statwin, A_BOLD); + wprintw(statwin, "%d%%",xpleft); } // blinded? if (isblind(player) && !lfhasflag(player, F_ASLEEP)) { @@ -6875,36 +7122,7 @@ void drawstatus(void) { } //redraw(); - if (getmaxmp(player) == player->maxmp) { - strcpy(maxmpstr, ""); - } else { - sprintf(maxmpstr, "(%d)",player->maxmp); - } - - - // HP wmove(statwin, 1, 0); - wattron(statwin, A_BOLD); wprintw(statwin, "HP:"); wattroff(statwin, A_BOLD); - setcol(statwin, getpctcol(player->hp, player->maxhp)); - wprintw(statwin, "%d",player->hp); - unsetcol(statwin, getpctcol(player->hp, player->maxhp)); - wprintw(statwin, "/%d ",player->maxhp); - - // MP - if (getmaxmp(player) > 0) { - wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD); - setcol(statwin, getpctcol(player->mp, getmaxmp(player))); - wprintw(statwin, "%d",player->mp); - unsetcol(statwin, getpctcol(player->mp, getmaxmp(player))); - wprintw(statwin, "/%d%s ",getmaxmp(player),maxmpstr); - } else { - wattron(statwin, A_BOLD); wprintw(statwin, "MP:"); wattroff(statwin, A_BOLD); - wprintw(statwin, "- "); - } - - wattron(statwin, A_BOLD); wprintw(statwin, "$:"); wattroff(statwin, A_BOLD); - sprintf(buf, "%d ", countmoney(player)); - wprintw(statwin, buf); wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD); sprintf(buf, "%d ", getarmourrating(player, NULL, NULL, NULL)); wprintw(statwin, buf); @@ -6912,6 +7130,10 @@ void drawstatus(void) { wattron(statwin, A_BOLD); wprintw(statwin, "EV:"); wattroff(statwin, A_BOLD); wprintw(statwin, "%d ", getevasion(player)); + wattron(statwin, A_BOLD); wprintw(statwin, "$:"); wattroff(statwin, A_BOLD); + sprintf(buf, "%d ", countmoney(player)); + wprintw(statwin, buf); + for (a = 0; a < MAXATTS; a++) { wattron(statwin, A_BOLD); wprintw(statwin, "%s:",getattrabbrev(a)); wattroff(statwin, A_BOLD); if (myatt[a] == player->baseatt[a]) { @@ -6947,8 +7169,15 @@ void drawmsg(void) { if (strcmp(msgbuf, lastmsgbuf) || msgmod) { wclear(msgwin); wmove(msgwin, 0, 0); - wprintw(msgwin, "%s", msgbuf); + + // default + setcol(msgwin, C_GREY); + + textwithcol(msgwin, msgbuf); + //wprintw(msgwin, "%s", msgbuf); //mvwprintw(msgwin, 0, 0, msgbuf); + + wrefresh(msgwin); strcpy(lastmsgbuf, msgbuf); } @@ -7167,7 +7396,6 @@ void showlfstats(lifeform_t *lf, int showall) { h = getmaxy(mainwin); - // determine knowledge about this monster lorelev = getlorelevel(player, lf->race->raceclass->id); if (isplayer(lf)) { @@ -7178,18 +7406,15 @@ void showlfstats(lifeform_t *lf, int showall) { lorecol = C_BROWN; } - - // override showall sometimes... // need 'player == lf' to cope with mind scans // where we update the player pointer, but don't // change the target's '->controller' setting (meaning // that isplayer(target) still returns false). - if (isplayer(lf) || isgenius(player) || (player == lf) || (lorelev >= PR_MASTER)) { + if (isplayer(lf) || (player == lf) || (lorelev >= PR_MASTER) || ispetof(lf, player)) { showall = B_TRUE; } - if (showall) { sprintf(prompt, "[@=stats S=skills/abilities M=magic E=effects %sESC=quit]", isplayer(lf) ? "" : "I=items " ); sprintf(cmdchars, "@asme%s",isplayer(lf) ? "" : "i"); @@ -7233,7 +7458,11 @@ void showlfstats(lifeform_t *lf, int showall) { j = getjob(lf); if (j) { doheadingsmall(mainwin, y, 0, ftext, "Job"); - sprintf(buf, "Level %d %s", lf->level, j->name); + if (showall) { + sprintf(buf, "Level %d %s", lf->level, j->name); + } else { + sprintf(buf, "%s", j->name); + } wprintw(mainwin, "%-20s", buf); y++; } @@ -7305,124 +7534,73 @@ void showlfstats(lifeform_t *lf, int showall) { } y++; // skip line - if (showall) { - char buf2[BUFLEN]; - int str; - str = getattr(lf, A_STR); - getstrname(str, buf2); - if (dammod == 1) { - sprintf(buf, "%d (%s)",str, buf2); - } else if (dammod > 1) { - sprintf(buf, "%d (%s, +%d%% dmg)",str, buf2, (int)((dammod * 100) - 100) ); - } else { // ie. dammod < 1 - sprintf(buf, "%d (%s, -%d%% dmg)",str, buf2, (int)(100 - (dammod * 100)) ); - } - if (str != lf->baseatt[A_STR]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Strength"); - wprintw(mainwin, "%s", buf); y++; - } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { - int str; - // just show name - str = getattr(lf, A_STR); - getstrname(str, buf); - doheadingsmall(mainwin, y, 0, ftext, "Strength"); - if (str != lf->baseatt[A_STR]) strcat(buf, "*"); - setcol(mainwin, lorecol); - wprintw(mainwin, "%s", buf); y++; - unsetcol(mainwin, lorecol); - } + for (i = 0; i < MAXATTS; i++) { + int val; + char bracketname[BUFLEN]; + char attrname[BUFLEN]; + enum ATTRBRACKET brack; + int mod; + val = getattr(lf, i); + brack = getattrbracket(val, i, bracketname); + strcpy(attrname, getattrname(i)); + capitalise(attrname); + sprintf(buf, "%d (%s",val, bracketname); + if (showall) { + char buf2[BUFLEN]; + switch (i) { + case A_STR: + if (dammod > 1) { + sprintf(buf2, ", +%d%% dmg", (int)((dammod * 100) - 100) ); + strcat(buf, buf2); + } else if (dammod < 1) { + sprintf(buf2, ", -%d%% dmg", (int)(100 - (dammod * 100)) ); + strcat(buf, buf2); + } + break; + case A_CON: + mod = getstatmod(lf, A_CON); + if (mod > 0) { + mod *= 2; // note: same code as in rollhitdice + sprintf(buf2, ", +%d%% hp",mod ); + strcat(buf, buf2); + } + break; + case A_DEX: + if (accmod > 0) { + sprintf(buf2, ", +%d%% acc",accmod ); + strcat(buf, buf2); + } else if (accmod < 0) { + sprintf(buf2, ", %d%% acc",accmod ); + strcat(buf, buf2); + } + break; + default: + break; + } + strcat(buf, ")"); - if (showall) { - char buf2[BUFLEN]; - int dex; - dex = getattr(lf, A_DEX); - getdexname(dex, buf2); + if (val != lf->baseatt[i]) strcat(buf, "*"); - if (accmod == 0) { - sprintf(buf, "%d (%s)",dex, buf2); - } else if (accmod > 0) { - sprintf(buf, "%d (%s, +%d%% bonus)",dex, buf2, accmod ); - } else { // ie. accmod < 0 - sprintf(buf, "%d (%s, %d%% penalty)",dex, buf2, accmod ); + doheadingsmall(mainwin, y, 0, ftext, attrname); + } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { + // just show name + strcat(buf, ")"); + if (val != lf->baseatt[i]) strcat(buf, "*"); + doheadingsmall(mainwin, y, 0, ftext, attrname); } - if (dex != lf->baseatt[A_DEX]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Dexterity"); - wprintw(mainwin, "%s", buf); y++; - } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { - int dex; - // just show name - dex = getattr(lf, A_DEX); - getdexname(dex, buf); - if (dex != lf->baseatt[A_DEX]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Dexterity"); - setcol(mainwin, lorecol); - wprintw(mainwin, "%s", buf); y++; - unsetcol(mainwin, lorecol); - } - - if (showall) { - char buf2[BUFLEN]; - int iq; - iq = getattr(lf, A_IQ); - getiqname(iq, buf2); - sprintf(buf, "%d (%s)",iq, buf2); - if (iq != lf->baseatt[A_IQ]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Intelligence"); - wprintw(mainwin, "%s", buf); y++; - } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { - int iq; - // just show name - iq = getattr(lf, A_IQ); - getiqname(iq, buf); - if (iq != lf->baseatt[A_IQ]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Intelligence"); - setcol(mainwin, lorecol); - wprintw(mainwin, "%s", buf); y++; - unsetcol(mainwin, lorecol); - } - - if (showall) { - char buf2[BUFLEN]; - int con; - con = getattr(lf, A_CON); - getconname(con, buf2); - sprintf(buf, "%d (%s)",con, buf2); - if (con != lf->baseatt[A_CON]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Fitness"); - wprintw(mainwin, "%s", buf); y++; - } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { - int con; - // just show name - con = getattr(lf, A_CON); - getconname(con, buf); - if (con != lf->baseatt[A_CON]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Fitness"); - setcol(mainwin, lorecol); - wprintw(mainwin, "%s", buf); y++; - unsetcol(mainwin, lorecol); - } - - if (showall) { - char buf2[BUFLEN]; - int cha; - cha = getattr(lf, A_CHA); - getchaname(cha, buf2); - sprintf(buf, "%d (%s)",cha, buf2); - if (cha != lf->baseatt[A_CHA]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Charisma"); - wprintw(mainwin, "%s", buf); y++; - } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { - int cha; - // just show name - cha = getattr(lf, A_CHA); - getconname(cha, buf); - if (cha != lf->baseatt[A_CHA]) strcat(buf, "*"); - doheadingsmall(mainwin, y, 0, ftext, "Charisma"); - setcol(mainwin, lorecol); - wprintw(mainwin, "%s", buf); y++; - unsetcol(mainwin, lorecol); - } + if (showall) { + // colour based on level + setcol(mainwin, getattrcolour(brack)); + wprintw(mainwin, "%s", buf); y++; + unsetcol(mainwin, getattrcolour(brack)); + } else if (!isplayer(lf) && (lorelev >= PR_NOVICE)) { + // colour based on lore level + setcol(mainwin, lorecol); + wprintw(mainwin, "%s", buf); y++; + unsetcol(mainwin, lorecol); + } + } // end foreach att //mvwprintw(mainwin, y, 0, ftext, "XP"); //wprintw(mainwin, "%ld (%ld more for next level)", lf->xp, xpneeded); y++; @@ -7535,7 +7713,7 @@ void showlfstats(lifeform_t *lf, int showall) { // unarmed attacks - op = addobpile(NULL, NULL); + op = addobpile(NULL, NULL, NULL); for (f = lf->flags->first ; f ; f = f->next) { if (f->id == F_HASATTACK) { @@ -7592,8 +7770,10 @@ void showlfstats(lifeform_t *lf, int showall) { // ARMOUR STUFF if (showall || (lorelev >= PR_NOVICE)) { + //int min,max; arating = getarmourrating(lf, NULL, NULL, NULL); - + //min = pctof(25, arating); + //max = pctof(75, arating); doheadingsmall(mainwin, y2, x2, ftext, "Armour Rating"); /* @@ -7604,7 +7784,11 @@ void showlfstats(lifeform_t *lf, int showall) { } */ if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol); - wprintw(mainwin, "%d", arating); y2++; + if (arating == 0) { + wprintw(mainwin, "%d (no dmgreduce)", arating); y2++; + } else { + wprintw(mainwin, "%d (dmgreduce %d-%d)", arating, arating/5, arating); y2++; + } if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol); } @@ -7689,7 +7873,7 @@ void showlfstats(lifeform_t *lf, int showall) { if (strlen(knowstring)) { char dambonusstr[BUFLEN]; // append dam bonus - sprintf(dambonusstr, " (+%d%% bonus)",(lorelev*10)); + sprintf(dambonusstr, " (+%d%% acc/dmg)",(lorelev*10)); strcat(knowstring, dambonusstr); // print it setcol(mainwin, lorecol); @@ -7749,6 +7933,16 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, buf); y++; } + f = lfhasknownflag(lf, F_FASTMETAB); + if (f && (f->known)) { + mvwprintw(mainwin, y, 0, "%s metabolic rate has been increased.", your(lf), getpossessive(you(lf))); + y++; + } + f = lfhasknownflag(lf, F_FEIGNINGDEATH); + if (f && (f->known)) { + mvwprintw(mainwin, y, 0, "%s %s pretending to be dead.", you(lf), is(lf)); + y++; + } f = lfhasknownflag(lf, F_FLYING); if (f && (f->known)) { mvwprintw(mainwin, y, 0, "%s %s flying.", you(lf), is(lf)); @@ -7818,6 +8012,11 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "%s produce%s light.", you(lf), isplayer(lf) ? "" : "s"); y++; } + f = lfhasknownflag(lf, F_SLOWMETAB); + if (f && (f->known)) { + mvwprintw(mainwin, y, 0, "%s metabolic rate has been decreased.", your(lf), getpossessive(you(lf))); + y++; + } f = lfhasknownflag(lf, F_SPRINTING); if (f) { if (f->val[0]) { @@ -8096,16 +8295,24 @@ void showlfstats(lifeform_t *lf, int showall) { flag_t *known[MAXSKILLS], *available[MAXSKILLS]; int numknown = 0, numavailable = 0; int n; + enum SKILLLEVEL slev; + // get available skills for (f = lf->flags->first ; f ; f = f->next) { - if (f->id == F_HASSKILL) { - known[numknown++] = f; - } else if (f->id == F_CANLEARN) { + if (f->id == F_CANLEARN) { if (!getskill(lf, f->val[0])) { available[numavailable++] = f; } } } + // get known skills, in order + for (slev = PR_MASTER ; slev >= PR_NOVICE; slev--) { + for (f = lf->flags->first ; f ; f = f->next) { + if ((f->id == F_HASSKILL) && (f->val[1] == slev)) { + known[numknown++] = f; + } + } + } //centre(mainwin, y, "SKILLS"); y ++; @@ -8400,10 +8607,15 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } + f = lfhasknownflag(lf, F_DISEASEIMMUNE); + if (f) { + mvwprintw(mainwin, y, 0, "%s %s immune to disease.", you(lf), is(lf)); + y++; + } + f = lfhasknownflag(lf, F_DRUNK); if (f) { - mvwprintw(mainwin, y, 0, "%s %s %s.", you(lf), - is(lf), getdrunktext(f)); + mvwprintw(mainwin, y, 0, "%s %s %s.", you(lf), is(lf), getdrunktext(f)); y++; } @@ -8535,6 +8747,11 @@ void showlfstats(lifeform_t *lf, int showall) { mvwprintw(mainwin, y, 0, "Gravity is increased around %s.", you_l(lf)); y++; } + f = lfhasflag(lf, F_GRAVLESSENED); + if (f && (f->known)) { + mvwprintw(mainwin, y, 0, "Gravity is lessened around %s.", you_l(lf)); + y++; + } f = lfhasknownflag(lf, F_DODGES); if (f && (f->known)) { mvwprintw(mainwin, y, 0, "%s can dodge attacks.", you(lf)); @@ -8756,6 +8973,38 @@ void showlfstats(lifeform_t *lf, int showall) { //redraw(); } +void textwithcol(WINDOW *win, char *buf) { + char *p; + enum COLOUR col; + int done = B_FALSE; + col = C_NONE; + // print char by char, looking for colour codes + for (p = buf ; *p ; p++) { + while (*p == '^') { + // colour change + if (col != C_NONE) unsetcol(win, col); + p++; + if (!(*p)) { + done = B_TRUE; + break; + } + col = chartocol(*p); + setcol(win, col); + p++; + if (!(*p)) { + done = B_TRUE; + break; + } + } + if (done) break; + waddch(win, *p); + } + // back to default colour + if (col != C_NONE) { + unsetcol(win, col); + } +} + void tombstone(lifeform_t *lf) { char pname[BUFLEN]; char buf[BUFLEN]; diff --git a/io.h b/io.h index 4a95bcb..418e8f1 100644 --- a/io.h +++ b/io.h @@ -52,7 +52,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly); void domemmagic(void); void domsghist(void); void dooperate(obpile_t *op); -int dopickup(obpile_t *op); +int dopickup(obpile_t *op, int forceask); void dolockpick(obpile_t *op); void donextguntarget(void); void dopour(obpile_t *op); @@ -60,7 +60,7 @@ void doquit(void); void doquaff(obpile_t *op); void doread(obpile_t *op); void dorest(void); -void doselguntarget(void); +int doselguntarget(void); void dostairs(int dir); int dotakeoff(obpile_t *op); void dothrow(obpile_t *op); @@ -78,6 +78,7 @@ void drawscreen(void); void drawstatus(void); int drop(object_t *o, int count); void dumpspells(void); +enum COLOUR getattrcolour(enum ATTRBRACKET brack); char getchoice(prompt_t *prompt); char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart); int getkey(void); @@ -108,6 +109,7 @@ void unsetcol(WINDOW *win, enum COLOUR col); void setobcolour(WINDOW *win, object_t *o, int set); void showlfarmour(lifeform_t *lf); void showlfstats(lifeform_t *lf, int showall); +void textwithcol(WINDOW *win, char *buf); void tombstone(lifeform_t *lf); void updatestatus(void); int updateviewfor(cell_t *cell); diff --git a/lf.c b/lf.c index f55c7d6..4b0e0e2 100644 --- a/lf.c +++ b/lf.c @@ -30,6 +30,9 @@ extern lifeform_t *player; extern glyph_t playerglyph; extern glyph_t tempglyph; +extern npcname_t *npcname; +extern int numnpcnames; + extern int needredraw; extern prompt_t prompt; @@ -94,15 +97,15 @@ void autoweild(lifeform_t *lf) { //if (isplayer(lf)) { firearm = getfirearm(lf); if (firearm) { - for (o = lf->pack->first ; o ; o = o->next) { - testammo(lf, o); - if (getammo(lf)) break; + o = getrandomammo(lf); + if (o) { + loadfirearm(NULL, firearm, o); } } //} // make sure monsters have ammo for their weapons - if (!isplayer(lf) && firearm && !getammo(lf)) { + if (!isplayer(lf) && firearm && !getammo(firearm)) { objecttype_t *ot; // make some ammo ot = getrandomammofor(firearm); @@ -110,7 +113,7 @@ void autoweild(lifeform_t *lf) { char buf[BUFLEN]; sprintf(buf, "1-5 %s",ot->name); o = addob(lf->pack, buf); - testammo(lf, o); + loadfirearm(NULL, firearm, o); } } @@ -495,7 +498,7 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) { // need >animal intelligence to cast spells if (ot->obclass->id == OC_SPELL) { - if (getiqname(getattr(lf, A_IQ), NULL) <= IQ_ANIMAL) { + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) <= IQ_ANIMAL) { reason = E_LOWIQ; return B_FALSE; } @@ -722,6 +725,10 @@ int canpickup(lifeform_t *lf, object_t *o, int amt) { return B_FALSE; } if (lf) { + if (getobsize(o) > getlfsize(lf)) { + reason = E_TOOBIG; + return B_FALSE; + } if (lfhasflag(lf, F_NOPACK)) { reason = E_NOPACK; return B_FALSE; @@ -743,11 +750,7 @@ int canpickup(lifeform_t *lf, object_t *o, int amt) { } // space in pack? - if (countobs(lf->pack, B_FALSE) >= MAXPILEOBS) { - reason = E_NOSPACE; - return B_FALSE; - } - if (getnextletter(lf->pack, NULL) == '\0') { + if (!obfits(o, lf->pack)) { reason = E_NOSPACE; return B_FALSE; } @@ -1147,7 +1150,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar if (power <= 1) power = 1; if (isplayer(lf)) { - msg("Your magic resistance interferes with your spell!"); + msg("^wYour magic resistance interferes with your spell!"); } } } @@ -1293,12 +1296,12 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { if (damamt >= lf->hp) { if (isplayer(lf)) { - msg("You drown."); + msg("^BYou drown."); didsomething = B_TRUE; } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s drowns.",lfname); + msg("^%c%s drowns.",getlfcol(lf, CC_BAD) , lfname); didsomething = B_TRUE; } addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); @@ -1306,12 +1309,12 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { setlastdam(lf, "drowning"); } else { if (isplayer(lf)) { - msg("You are drowning!"); + msg("^BYou are drowning!"); didsomething = B_TRUE; } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s is drowning!",lfname); + msg("^%c%s is drowning!", getlfcol(lf, CC_VBAD), lfname); didsomething = B_TRUE; } losehp(lf, damamt, DT_DIRECT, NULL, "drowning"); @@ -1599,7 +1602,7 @@ void die(lifeform_t *lf) { if (!willbecomeghost) { if (isplayer(lf) && hasjob(lf, J_GOD)) { char ch; - msg("You die..."); more(); + msg("^BYou die..."); more(); ch = askchar("Die", "yn", "n", B_TRUE); if (ch == 'n') { lf->hp = lf->maxhp; @@ -1628,10 +1631,10 @@ void die(lifeform_t *lf) { drawscreen(); if (lf->lastdamtype == DT_EXPLOSIVE) { - msg("You are vaporised!"); + msg("^BYou are vaporised!"); vaporised = B_TRUE; } else { - msg("You die."); + msg("^BYou die."); } more(); // force msg redraw! @@ -1641,14 +1644,14 @@ void die(lifeform_t *lf) { if (cansee(player, lf)) { getlfname(lf, buf); if (lf->lastdamtype == DT_EXPLOSIVE) { - msg("%s is vaporised!",buf); + msg("^%c%s is vaporised!",getlfcol(lf, CC_BAD), buf); vaporised = B_TRUE; } else if (lf->lastdamtype == DT_MELT) { - msg("%s completely melts.",buf); + msg("^%c%s completely melts.",getlfcol(lf, CC_BAD), buf); } else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) { - msg("%s shatters!",buf); + msg("^%c%s shatters!",getlfcol(lf, CC_BAD), buf); } else { - msg("%s dies.",buf); + msg("^%c%s dies.",getlfcol(lf, CC_BAD), buf); } } } @@ -2341,7 +2344,7 @@ int eat(lifeform_t *lf, object_t *o) { char dambuf[BUFLEN]; // lose hp if (isplayer(lf)) { - msg("That %s was bad!", drinking ? "liquid" : "food"); + msg("^BThat %s was bad!", drinking ? "liquid" : "food"); } // food poisoning for 20 turns if (drinking) { @@ -2386,6 +2389,8 @@ int eat(lifeform_t *lf, object_t *o) { skinname); } } + } else if (o->type->id == OT_CARROT) { + killtransitoryflags(lf->flags, F_BLIND); } } // end if fullyeaten @@ -2492,7 +2497,7 @@ void enhanceskills(lifeform_t *lf) { statdirty = B_TRUE; drawstatus(); wrefresh(statwin); - msg("Welcome to level %d!",lf->level); + msg("^GWelcome to level %d!",lf->level); more(); } @@ -2503,12 +2508,13 @@ void enhanceskills(lifeform_t *lf) { enum ATTRIB att; if (isplayer(lf)) { char ch; - ch = askchar("Increase your Strength, Dexterity, Fitness or Intelligence?", "sdfi",NULL, B_TRUE); + ch = askchar("Increase your Strength, Dexterity, Fitness, IQ or Wisdom?", "sdfiw",NULL, B_TRUE); switch (ch) { case 's': att = A_STR; break; case 'd': att = A_DEX; break; case 'f': att = A_CON; break; case 'i': att = A_IQ; break; + case 'w': att = A_WIS; break; } } else { // pick randomly @@ -2764,7 +2770,7 @@ void enhanceskills(lifeform_t *lf) { if (!streq(newtext, f->text)) { free(f->text); f->text = strdup(newtext); - if (isplayer(lf)) msg("Your unarmed attack damage has increased!"); + if (isplayer(lf)) msg("^gYour unarmed attack damage has increased!"); } } // enhance # attacks @@ -2789,7 +2795,7 @@ void enhanceskills(lifeform_t *lf) { if ((min != f->val[0]) || (max != f->val[1])) { f->val[0] = min; f->val[1] = max; - if (isplayer(lf)) msg("Your number of unarmed attacks has increased!"); + if (isplayer(lf)) msg("^gYour number of unarmed attacks has increased!"); } } } @@ -2828,9 +2834,9 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { if (fromlf) { char fromlfname[BUFLEN]; getlfname(fromlf, fromlfname); - msg("%s knock%s %s to the ground!",fromlfname, isplayer(fromlf) ? "" : "s", lfname); + msg("^w%s knock%s %s to the ground!",fromlfname, isplayer(fromlf) ? "" : "s", lfname); } else { - msg("%s fall%s to the ground.",lfname, isplayer(lf) ? "" : "s"); + msg("^w%s fall%s to the ground.",lfname, isplayer(lf) ? "" : "s"); } } } @@ -2841,10 +2847,22 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { return B_FALSE; } +// if you are going to sleep on purpose, use 'gotosleep'. +// this function is for when it is forced upon you by a spell, etc. int fallasleep(lifeform_t *lf, int howlong) { if (lfhasflag(lf, F_ASLEEP)) { return B_TRUE; } + if (lfhasflag(lf, F_CAFFEINATED)) { + if (isplayer(lf)) { + msg("You feel momentarily tired."); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s looks momentarily tired.", lfname); + } + return B_TRUE; + } loseconcentration(lf); interrupt(lf); @@ -2859,6 +2877,11 @@ int fallasleep(lifeform_t *lf, int howlong) { void fightback(lifeform_t *lf, lifeform_t *attacker) { interrupt(lf); + if (lfhasflag(lf, F_FEIGNINGDEATH)) { + // don't responsd. + return; + } + // special cases if ((lf->race->id == R_STIRGE) || (lf->race->id == R_LEECH)) { if (ispeaceful(lf)) { @@ -2872,11 +2895,23 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) { killflagsofid(lf->flags, F_ASLEEP); // monsters might flee, fight back, etc if (!isplayer(lf)) { + + if (isplayer(attacker) && ishirable(lf)) { + // can never recruit this person now! + addflag(lf->flags, F_NOHIRE, B_TRUE, NA, NA, NULL); + } + if (willflee(lf)) { scare(lf, attacker, PERMENANT, 0); } else { lifeform_t *l; + // special case for player's pets/allies... + if (areallies(lf, attacker) && (getallegiance(lf) == AL_FRIENDLY)) { + // only fight back if it was the PLAYER who attacked us + if (!isplayer(attacker)) return; + } + aiattack(lf, attacker, AI_FOLLOWTIME); // any nearby monsters which will help out? @@ -3045,7 +3080,7 @@ int flee(lifeform_t *lf) { lifeform_t *fleefrom = NULL; // mindless? - if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) { + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) == IQ_MINDLESS) { return B_FALSE; } @@ -3100,7 +3135,7 @@ int flee(lifeform_t *lf) { char buf[BUFLEN]; drawscreen(); getlfname(fleefrom, buf); - msg("You flee from %s!",buf); + msg("^wYou flee from %s!",buf); } // can we flee via stairs? @@ -3169,7 +3204,7 @@ int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong) { // note: damage value here will be halved due to resistance // so this really means rnd( 5,10) if (isplayer(freezee)) { - msg("You feel freezing cold!"); + msg("^bYou feel freezing cold!"); } if (freezer) { char lfname[BUFLEN]; @@ -3207,7 +3242,7 @@ void gainhp(lifeform_t *lf, int amt) { if (isplayer(lf)) { if (maxed) { - msg("You are now fully healed."); + msg("^gYou are now fully healed."); } // update screen drawstatus(); @@ -3262,9 +3297,9 @@ void gainlevel(lifeform_t *lf) { if (isplayer(lf)) { if (skillready) { - msg("You feel ready to learn a new skill!"); + msg("^GYou feel ready to learn a new skill!"); } else { - msg("You feel ready for a training session!"); + msg("^GYou feel ready for a training session!"); } more(); } else if (cansee(player, lf)) { @@ -3320,7 +3355,7 @@ void gainmp(lifeform_t *lf, int amt) { if (isplayer(lf)) { if (maxed) { - msg("Your mana is now fully restored."); + msg("^GYour mana is now fully restored."); } if (gained) { statdirty = B_TRUE; @@ -3663,7 +3698,7 @@ int getavgdam(lifeform_t *lf, int forxp) { db = B_TRUE; } - op = addobpile(NULL, NULL); + op = addobpile(NULL, NULL, NULL); for (f = lf->race->flags->first ; f ; f = f->next) { if (f->id == F_HASATTACK) { int min,max; @@ -3719,7 +3754,7 @@ int getavgdam(lifeform_t *lf, int forxp) { flag_t *of; obpile_t *op2; - op2 = addobpile(NULL,NULL); + op2 = addobpile(NULL,NULL, NULL); o = addob(op2, f->text); @@ -3815,7 +3850,6 @@ float getequippedweight(lifeform_t *lf) { } int getevasion(lifeform_t *lf) { - object_t *o; flag_t *f; int ev = 0; @@ -3839,6 +3873,7 @@ int getevasion(lifeform_t *lf) { ev += (getskill(lf, SK_EVASION)*5); // now get object penalties/bonuses + /* for (o = lf->pack->first ; o ; o = o->next) { // armour/weapons must be worn to do anything if (hasflag(o->flags, F_EQUIPPED)) { @@ -3853,6 +3888,16 @@ int getevasion(lifeform_t *lf) { } } } + */ + + // adjust for bulky armour/shield + for (f = lf->flags->first ;f ; f = f->next) { + if (f->id == F_ARMOURPENALTY) { + ev -= adjustarmourpenalty(lf, f->val[1]); + } else if (f->id == F_SHIELDPENALTY) { + ev -= adjustshieldpenalty(lf, f->val[1]); + } + } // dexterity mod ev += (getstatmod(lf, A_DEX) / 2); @@ -4032,6 +4077,17 @@ object_t *getequippedob(obpile_t *op, enum BODYPART bp) { return NULL; } +int getexposedlimbs(lifeform_t *lf) { + int exposedlimbs = 0; + if (!getouterequippedob(lf, BP_HEAD)) exposedlimbs += 1; + if (!getouterequippedob(lf, BP_SHOULDERS)) exposedlimbs += 1; + if (!getouterequippedob(lf, BP_BODY)) exposedlimbs += 2; + if (!getouterequippedob(lf, BP_HANDS)) exposedlimbs += 1; + if (!getouterequippedob(lf, BP_LEGS)) exposedlimbs += 2; + if (!getouterequippedob(lf, BP_FEET)) exposedlimbs += 1; + return exposedlimbs; +} + object_t *getfirearm(lifeform_t *lf) { object_t *o; o = getequippedob(lf->pack, BP_SECWEAPON); @@ -4231,6 +4287,7 @@ int getlastdir(lifeform_t *lf) { int getlfaccuracy(lifeform_t *lf, object_t *wep) { flag_t *f; + object_t *o; int acc = 0; // get weapon @@ -4248,12 +4305,19 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { } } + for (o = lf->pack->first ;o ; o = o->next) { + if (isequipped(o)) { + f = hasflag(o->flags, F_ACCURACYMOD); + if (f) acc += f->val[0]; + } + } + // adjust for bulky armour/shield for (f = lf->flags->first ;f ; f = f->next) { - if (f->id == F_ACCURACYMOD) { - acc += f->val[0]; - } else if (f->id == F_SHIELDPENALTY) { + if (f->id == F_SHIELDPENALTY) { acc -= adjustshieldpenalty(lf, f->val[0]); + } else if (f->id == F_ARMOURPENALTY) { + acc -= adjustarmourpenalty(lf, f->val[0]); } } @@ -4321,6 +4385,45 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { return acc; } +char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc) { + switch (cc) { + case CC_VBAD: + if (areallies(player, lf)) { + return 'B'; + } else if (areenemies(player, lf)) { + return 'G'; + } else { + return 'n'; + } + break; + case CC_BAD: + if (areallies(player, lf)) { + return 'b'; + } else if (areenemies(player, lf)) { + return 'g'; + } else { + return 'n'; + } + break; + case CC_NORMAL: + return 'n'; + case CC_GOOD: + if (areallies(player, lf)) { + return 'g'; + } else { + return 'n'; + } + break; + case CC_VGOOD: + if (areallies(player, lf)) { + return 'G'; + } else { + return 'n'; + } + break; + } + return 'n'; +} enum LFCONDITION getlfcondition(lifeform_t *lf) { float hp,maxhp; @@ -4442,26 +4545,26 @@ int getowing(lifeform_t *buyer, int shopid, int *retnitems) { // // this is based on intelligence and firstaid skill enum LFCONDITION getseenlfconditioncutoff(lifeform_t *lf) { - enum IQBRACKET iqb; + enum ATTRBRACKET iqb; enum SKILLLEVEL slev; enum LFCONDITION cutoff; // intelligence higher than 'average' doesn't count. - iqb = getiqname(getattr(lf, A_IQ), NULL); - if (iqb > IQ_AVERAGE) iqb = IQ_AVERAGE; + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); + if (iqb > AT_AVERAGE) iqb = AT_AVERAGE; // adjust for firstaid skill slev = getskill(lf, SK_FIRSTAID); iqb += slev; // figure out health cutoff - condition > cutoff gets no description - if (iqb >= IQ_GENIUS) { + if (iqb >= AT_VHIGH) { cutoff = C_HEALTHY; // - } else if (iqb >= IQ_AVERAGE) { + } else if (iqb >= AT_AVERAGE) { cutoff = C_HURT; // ie. no real cutoff - } else if (iqb >= IQ_DOPEY) { + } else if (iqb >= AT_LTAVERAGE) { cutoff = C_WOUNDED; - } else if (iqb >= IQ_ANIMAL) { + } else if (iqb >= AT_VLOW) { cutoff = C_SERIOUS; } else { cutoff = C_DEAD; @@ -4489,6 +4592,14 @@ glyph_t *getlfglyph(lifeform_t *lf) { } */ + if (lfhasflag(lf, F_FEIGNINGDEATH)) { + // look like a corpse + tempglyph.ch = '%'; + tempglyph.colour = lf->race->glyph.colour; + + return &tempglyph; + } + f = lfhasflag(lf, F_GLYPH); if (f) { tempglyph.ch = f->text[0]; @@ -4544,6 +4655,7 @@ int getattacks(lifeform_t *lf, int *min, int *max) { } if (getskill(lf, SK_TWOWEAPON) && isdualweilding(lf)) { + minattacks++; maxattacks++; } @@ -4557,26 +4669,28 @@ int getattacks(lifeform_t *lf, int *min, int *max) { float getmaxcarryweight(lifeform_t *lf) { float max; float mod; - enum STRBRACKET sbrack; + enum ATTRBRACKET sbrack; - sbrack = getstrname(getattr(lf, A_STR), NULL); + sbrack = getattrbracket(getattr(lf, A_STR), A_STR, NULL); switch (sbrack) { - case ST_HELPLESS: + case AT_EXLOW: mod = 0.1; break; - case ST_FEEBLE: + case AT_VLOW: mod = 0.25; break; - case ST_VWEAK: + case AT_LOW: mod = 0.5; break; - case ST_WEAK: + case AT_LTAVERAGE: mod = 0.75; break; - case ST_AVERAGE: + case AT_AVERAGE: mod = 1; break; // your body weight - case ST_STRONG: + case AT_GTAVERAGE: mod = 1.25; break; - case ST_MIGHTY: + case AT_HIGH: mod = 1.5; break; - case ST_TITANIC: + case AT_VHIGH: mod = 2; break; // twice your own body weight + case AT_EXHIGH: + mod = 2.25; break; // over twice default: mod = 1; break; // your body weight } @@ -4586,38 +4700,6 @@ float getmaxcarryweight(lifeform_t *lf) { return max; } -/* -float getmaxliftweight(lifeform_t *lf) { - float max; - float mod; - enum STRBRACKET sbrack; - - sbrack = getstrname(getattr(lf, A_STR), NULL); - switch (sbrack) { - case ST_HELPLESS: - mod = 0.05; break; - case ST_FEEBLE: - mod = 0.1; break; - case ST_VWEAK: - mod = 0.25; break; - case ST_WEAK: - mod = 0.4; break; - case ST_AVERAGE: - mod = 0.5; break; // half your body weight - case ST_STRONG: - mod = 0.75; break; - case ST_MIGHTY: - mod = 1; break; // your own body weight - case ST_TITANIC: - mod = 1.5; break; // more than your own body weight - } - - max = getlfweight(lf, B_NOOBS) * mod; - - return max; -} -*/ - int getmaxmp(lifeform_t *lf) { flag_t *f; int activemp = 0; @@ -4844,18 +4926,26 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) { char descstring[BUFLEN]; char jobstring[BUFLEN]; char the[6]; + char lname[BUFLEN]; job_t *j; flag_t *f; + // 'the' or 'your' ? - if (lfhasflag(lf, F_UNIQUE)) { + f = lfhasflag(lf, F_NAME); + if (f) { strcpy(the, ""); + strcpy(lname, f->text); + } else if (lfhasflag(lf, F_UNIQUE)) { + strcpy(the, ""); + strcpy(lname, lf->race->name); } else { if (ispetof(lf, player)) { strcpy(the, "your "); } else { strcpy(the, "the "); } + strcpy(lname, lf->race->name); } // construct description string @@ -4869,7 +4959,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) { // construct job string strcpy(jobstring, ""); - if (!lfhasflag(lf, F_NOJOBTEXT)) { + if (!lfhasflag(lf, F_NOJOBTEXT) && !lfhasflag(lf, F_NAME) && !lfhasflag(lf, F_UNIQUE)) { j = getjob(lf); if (j) { sprintf(jobstring, " %s", j->name); @@ -4892,8 +4982,18 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) { real_getobname(wep, obname, 1, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_FALSE); sprintf(buf, "%s%s%s",the,descstring,noprefix(obname)); } else { - sprintf(buf, "%s%s%s%s",the,descstring,lf->race->name,jobstring); + sprintf(buf, "%s%s%s%s",the,descstring,lname,jobstring); } + } else if (lfhasflag(lf, F_FEIGNINGDEATH)) { + if (lfhasflag(lf, F_NAME)) { + // ie. "jimbo's corpse" + sprintf(buf, "%s%s corpse", lname, getpossessive(lname)); + } else { + // ie. "a wolf corpse" + sprintf(buf, "%s %s corpse", needan(lname) ? "an" : "a", lname); + } + } else if (lfhasflag(lf, F_NAME)) { + sprintf(buf, "%s%s", descstring, lname); } else { char zombiestring[BUFLEN]; f = hasflag(lf->flags, F_LFSUFFIX); @@ -4903,7 +5003,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) { sprintf(zombiestring, " %s", f->text); } - sprintf(buf, "%s%s%s%s%s",the,descstring,lf->race->name,jobstring,zombiestring); + sprintf(buf, "%s%s%s%s%s",the,descstring,lname,jobstring,zombiestring); } } } @@ -4923,7 +5023,7 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis) { real_getlfname(lf, buf2, usevis); - if (lfhasflag(lf, F_UNIQUE)) { + if (lfhasflag(lf, F_NAME) || lfhasflag(lf, F_UNIQUE)) { strcpy(the, ""); } else { if (ispetof(lf, player)) { @@ -4937,9 +5037,6 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis) { } } - - - sprintf(buf, "%s%s", the, noprefix(buf2)); } return buf; @@ -5099,6 +5196,17 @@ char *getpoisonname(enum POISONTYPE ptype) { return ""; } +enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype) { + switch (ptype) { + case P_COLD: + return PS_DISEASE; + default: + break; + } + // default is not too bad. + return PS_POISON; +} + int getraceclass(lifeform_t *lf) { return lf->race->raceclass->id; } @@ -5184,6 +5292,33 @@ object_t *getrandomarmour(lifeform_t *lf) { return o; } +job_t *getrandomjob(int onlyplayerjobs) { + job_t *j; + int njobs = 0; + int sel,n; + // count them + for (j = firstjob ; j ; j = j->next) { + if (onlyplayerjobs && hasflag(j->flags, F_NOPLAYER)) { + } else if (j->id == J_GOD) { + } else { + njobs++; + } + } + if (njobs) { + sel = rnd(0,njobs-1); + n = 0; + for (j = firstjob ; j ; j = j->next) { + if (onlyplayerjobs && hasflag(j->flags, F_NOPLAYER)) { + } else if (j->id == J_GOD) { + } else { + if (n == sel) return j; + n++; + } + } + } + return NULL; +} + int getrandommonlevel(race_t *r, map_t *m) { flag_t *f; int wantlev = 1; @@ -5421,75 +5556,6 @@ char *getspeednameshort(int speed, char *buf) { return buf; } -// ie. intelligence level: xxx -enum IQBRACKET getiqname(int iq, char *buf) { - if (iq <= 0) { - if (buf) strcpy(buf, "mindless"); - return IQ_MINDLESS; - } else if (iq == 1) { - if (buf) strcpy(buf, "vegetable"); - return IQ_VEGETABLE; - } else if (iq <= 3) { - if (buf) strcpy(buf, "animal"); - return IQ_ANIMAL; - } else if (iq <= 6) { - if (buf) strcpy(buf, "dim-witted"); - return IQ_DIMWITTED; - } else if (iq <= 9) { - if (buf) strcpy(buf, "dopey"); - return IQ_DOPEY; - } else if (iq <= 12) { - if (buf) strcpy(buf, "average"); - return IQ_AVERAGE; - } else if (iq <= 15) { - if (buf) strcpy(buf, "smart"); - return IQ_SMART; - } else if (iq <= 17) { - if (buf) strcpy(buf, "enlightened"); - return IQ_ENLIGHTENED; - } - - if (buf) strcpy(buf, "genius"); - return IQ_GENIUS; -} - -enum DEXBRACKET getdexname(int dex, char *buf) { - if (dex <= 0) { - if (buf) strcpy(buf, "incompetent"); - return DX_INCOMPETENT; - } else if (dex <= 2) { - if (buf) strcpy(buf, "oafish"); - return DX_OAFISH; - } else if (dex <= 4) { - if (buf) strcpy(buf, "inept"); - return DX_INEPT; - } else if (dex <= 6) { - if (buf) strcpy(buf, "clumsy"); - return DX_CLUMSY; - } else if (dex <= 8) { - if (buf) strcpy(buf, "awkward"); - return DX_AWKWARD; - } else if (dex == 9) { - if (buf) strcpy(buf, "average"); - return DX_AVERAGE; - } else if (dex <= 11) { - if (buf) strcpy(buf, "dextrous"); - return DX_DEXTROUS; - } else if (dex <= 13) { - if (buf) strcpy(buf, "nimble"); - return DX_NIMBLE; - } else if (dex <= 15) { - if (buf) strcpy(buf, "agile"); - return DX_AGILE; - } else if (dex <= 17) { - if (buf) strcpy(buf, "swift"); - return DX_SWIFT; - } - - if (buf) strcpy(buf, "supersonic"); - return DX_SUPERSONIC; -} - // returns a pct addition for things like: // accuracy, evasion, lockpicking // result will be between -50 and 50 @@ -5504,94 +5570,184 @@ float getstatmod(lifeform_t *lf, enum ATTRIB att) { return mod; } -enum CHABRACKET getchaname(int cha, char *buf) { - if (cha <= 2) { - if (buf) strcpy(buf, "hideous"); - return CH_HIDEOUS; - } else if (cha <= 6) { - if (buf) strcpy(buf, "repulsive"); - return CH_REPULSIVE; - } else if (cha <= 8) { - if (buf) strcpy(buf, "ugly"); - return CH_UGLY; - } else if (cha <= 10) { - if (buf) strcpy(buf, "unattractive"); - return CH_UNATTRACTIVE; - } else if (cha <= 12) { - if (buf) strcpy(buf, "average"); - return CH_AVERAGE; - } else if (cha <= 14) { - if (buf) strcpy(buf, "attractive"); - return CH_ATTRACTIVE; - } else if (cha <= 16) { - if (buf) strcpy(buf, "alluring"); - return CH_ALLURING; - } else if (cha <= 18) { - if (buf) strcpy(buf, "beautiful"); - return CH_BEAUTIFUL; - } +enum ATTRBRACKET getattrbracket(int attrval, enum ATTRIB whichatt, char *buf) { + if (attrval <= 2) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "hideous"); break; + case A_CON: + strcpy(buf, "frail"); break; + case A_IQ: + strcpy(buf, "vegetable"); break; + case A_STR: + strcpy(buf, "helpless"); break; + case A_WIS: + strcpy(buf, "witless"); break; + default: + strcpy(buf, "?extralow?"); break; + } + } + return AT_EXLOW; + } else if (attrval <= 6) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "repulsive"); break; + case A_CON: + strcpy(buf, "sickly"); break; + case A_DEX: + strcpy(buf, "oafish"); break; + case A_IQ: + strcpy(buf, "animal"); break; + case A_STR: + strcpy(buf, "feeble"); break; + case A_WIS: + strcpy(buf, "reckless"); break; + default: + strcpy(buf, "?verylow?"); break; + } + } + return AT_VLOW; + } else if (attrval <= 8) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "ugly"); break; + case A_CON: + strcpy(buf, "unhealthy"); break; + case A_DEX: + strcpy(buf, "clumsy"); break; + case A_IQ: + strcpy(buf, "dim-witted"); break; + case A_STR: + strcpy(buf, "very weak"); break; + case A_WIS: + strcpy(buf, "foolish"); break; + default: + strcpy(buf, "?low?"); break; + } + } + return AT_LOW; + } else if (attrval <= 10) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "unattractive"); break; + case A_CON: + strcpy(buf, "unfit"); break; + case A_DEX: + strcpy(buf, "awkward"); break; + case A_IQ: + strcpy(buf, "dopey"); break; + case A_STR: + strcpy(buf, "weak"); break; + case A_WIS: + strcpy(buf, "naive"); break; + default: + strcpy(buf, "?lt_average?"); break; + } + } + return AT_LTAVERAGE; + } else if (attrval <= 12) { + if (buf) { + switch (whichatt) { + case A_CHA: + case A_CON: + case A_DEX: + case A_STR: + case A_IQ: + case A_WIS: + strcpy(buf, "average"); break; + default: + strcpy(buf, "?average?"); break; + } + } + return AT_AVERAGE; + } else if (attrval <= 14) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "attractive"); break; + case A_CON: + strcpy(buf, "healthy"); break; + case A_DEX: + strcpy(buf, "dextrous"); break; + case A_IQ: + strcpy(buf, "smart"); break; + case A_STR: + strcpy(buf, "strong"); break; + case A_WIS: + strcpy(buf, "prudent"); break; + default: + strcpy(buf, "?gt_average?"); break; + } + } + return AT_GTAVERAGE; + } else if (attrval <= 16) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "alluring"); break; + case A_CON: + strcpy(buf, "very fit"); break; + case A_DEX: + strcpy(buf, "nimble"); break; + case A_IQ: + strcpy(buf, "enlightened"); break; + case A_STR: + strcpy(buf, "mighty"); break; + case A_WIS: + strcpy(buf, "astute"); break; + default: + strcpy(buf, "?high?"); break; + } + } + return AT_HIGH; + } else if (attrval <= 18) { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "beautiful"); break; + case A_CON: + strcpy(buf, "hardy"); break; + case A_DEX: + strcpy(buf, "agile"); break; + case A_IQ: + strcpy(buf, "genius"); break; + case A_STR: + strcpy(buf, "powerful"); break; + case A_WIS: + strcpy(buf, "wise"); break; + default: + strcpy(buf, "?veryhigh?"); break; + } + } + return AT_VHIGH; + } else { + if (buf) { + switch (whichatt) { + case A_CHA: + strcpy(buf, "stunning"); break; + case A_CON: + strcpy(buf, "very hardy"); break; + case A_DEX: + strcpy(buf, "very agile"); break; + case A_IQ: + strcpy(buf, "supergenius"); break; + case A_STR: + strcpy(buf, "titanic"); break; + case A_WIS: + strcpy(buf, "sagely"); break; + default: + strcpy(buf, "?exhigh?"); break; + } + } + return AT_EXHIGH; + } - if (buf) strcpy(buf, "average"); - return CH_AVERAGE; -} - -enum CONBRACKET getconname(int str, char *buf) { - if (str <= 2) { - if (buf) strcpy(buf, "frail"); - return CN_FRAIL; - } else if (str <= 4) { - if (buf) strcpy(buf, "sickly"); - return CN_SICKLY; - } else if (str <= 6) { - if (buf) strcpy(buf, "unhealthy"); - return CN_UNHEALTHY; - } else if (str <= 8) { - if (buf) strcpy(buf, "unfit"); - return CN_UNFIT; - } else if (str <= 11) { - if (buf) strcpy(buf, "average"); - return CN_AVERAGE; - } else if (str <= 14) { - if (buf) strcpy(buf, "healthy"); - return CN_HEALTHY; - } else if (str <= 16) { - if (buf) strcpy(buf, "very fit"); - return CN_FIT; - } else if (str <= 18) { - if (buf) strcpy(buf, "hardy"); - return CN_HARDY; - } - - if (buf) strcpy(buf, "hardy"); - return CN_HARDY; -} - -enum STRBRACKET getstrname(int str, char *buf) { - if (str <= 0) { - if (buf) strcpy(buf, "helpless"); - return ST_HELPLESS; - } else if (str <= 3) { - if (buf) strcpy(buf, "feeble"); - return ST_FEEBLE; - } else if (str <= 6) { - if (buf) strcpy(buf, "very weak"); - return ST_VWEAK; - } else if (str <= 8) { - if (buf) strcpy(buf, "weak"); - return ST_WEAK; - } else if (str <= 12) { - if (buf) strcpy(buf, "average"); - return ST_AVERAGE; - } else if (str <= 15) { - if (buf) strcpy(buf, "strong"); - return ST_STRONG; - } else if (str <= 17) { - if (buf) strcpy(buf, "mighty"); - return ST_MIGHTY; - } - - if (buf) strcpy(buf, "titanic"); - return ST_TITANIC; + if (buf) strcpy(buf, "??noattrbracketname??"); + return AT_AVERAGE; } char *getskilldesc(enum SKILL id) { @@ -5644,29 +5800,30 @@ char *getskilllevelname(enum SKILLLEVEL sl) { // ie. 5 = 125km/h // ie. 10 = 1000km/h int getthrowspeed(int str) { - enum STRBRACKET sb; + enum ATTRBRACKET sb; int speed = 0; - sb = getstrname(str, NULL); + sb = getattrbracket(str, A_STR, NULL); switch (sb) { - case ST_HELPLESS: - case ST_FEEBLE: + case AT_EXLOW: + case AT_VLOW: speed = 1; break; - case ST_VWEAK: - case ST_WEAK: + case AT_LOW: + case AT_LTAVERAGE: speed = 2; break; - case ST_AVERAGE: + case AT_AVERAGE: speed = 3; break; - case ST_STRONG: + case AT_GTAVERAGE: + case AT_HIGH: speed = 4; break; - case ST_MIGHTY: + case AT_VHIGH: speed = 5; break; default: - case ST_TITANIC: + case AT_EXHIGH: speed = 6; break; // gun is 10 @@ -5674,6 +5831,7 @@ int getthrowspeed(int str) { return speed; } + void getwantdistance(lifeform_t *lf, int *min, int *max, int attacking) { flag_t *f; // default - run into them @@ -5733,13 +5891,12 @@ void givejob(lifeform_t *lf, enum JOB jobid) { job_t *j; flag_t *f; int i; - int condition = NOCONDITION; int rollhp = B_FALSE, rollmp = B_FALSE; int rollatt[MAXATTS]; - int ignorenext; - int ignoredprev; int db = B_FALSE; + if (jobid == J_WIZARD) db = B_TRUE; + if (db) dblog("givejob() starting.\n"); for (i = 0; i < MAXATTS; i++) { @@ -5768,75 +5925,54 @@ void givejob(lifeform_t *lf, enum JOB jobid) { } // inherit all flags except startob ones - ignorenext = B_FALSE; - ignoredprev = B_FALSE; for (f = j->flags->first ; f ; f = f->next) { - if (condition == IFPLAYER) { - if (f->id == F_ENDIFPLAYER) { - if (db) dblog("ending ifplayer condition"); - condition = NOCONDITION; - } else if (!isplayer(lf)) { - if (db) dblog("setting ignorenext cause of ifplayer"); - ignorenext = B_TRUE; // ie. ignore this one. - } - } else if (condition == IFMONSTER) { - if (f->id == F_ENDIFMONSTER) { - if (db) dblog("ending ifmonster condition"); - condition = NOCONDITION; - } else if (isplayer(lf)) { - if (db) dblog("setting ignorenext cause of ifmonster"); - ignorenext = B_TRUE; // ie. ignore this one. - } - } + int ignorethis = B_FALSE; + int val[3]; + int id; + char *text; - if (ignorenext) { - if (db) dblog("ignoring this flag: %d",f->id); - ignorenext = B_FALSE; - ignoredprev = B_TRUE; - } else { - if (f->id == F_IFPCT) { - if (db) dblog("ifpct flag..."); - if (rnd(0,100) > f->val[0]) { - if (db) dblog(" failed."); - ignorenext = B_TRUE; + id = f->id; + val[0] = f->val[0]; + val[1] = f->val[1]; + val[2] = f->val[2]; + text = f->text; + + if (f->chance != 100) { + if (rnd(0,100) > f->chance) { + // failed! got an altval? + if (f->altval) { + // use it instead + id = f->altval->id; + val[0] = f->altval->val[0]; + val[1] = f->altval->val[1]; + val[2] = f->altval->val[2]; + text = f->altval->text; } else { - if (db) dblog(" passed."); - } - /* - if ((f->val[2] == IFMONSTER) && isplayer(lf)) { - ignorenext = B_TRUE; - } else if ((f->val[2] == IFPLAYER) && !isplayer(lf)) { - ignorenext = B_TRUE; - } - */ - } else if (f->id == F_IFPLAYER) { - if (db) dblog("starting ifplayer condition"); - condition = IFPLAYER; - } else if (f->id == F_IFMONSTER) { - if (db) dblog("starting ifmonster condition"); - condition = IFMONSTER; - } else if (f->id == F_ELSE) { - if (db) dblog("else flag..."); - if (ignoredprev) { - if (db) dblog("... MATCHED."); - } else { - if (db) dblog("... ignoring next."); - ignorenext = B_TRUE; - } - } else { - addflag_real(lf->flags, f->id, f->val[0], f->val[1], f->val[2], f->text, FROMJOB,B_TRUE, -1); - if (f->id == F_STARTATT) { - rollatt[f->val[0]] = B_TRUE; + // ignore this one. + ignorethis = B_TRUE; } } - ignoredprev = B_FALSE; + } + + if ((f->condition == FC_IFMONSTER) && isplayer(lf)) { + ignorethis = B_TRUE; + } else if ((f->condition == FC_IFPLAYER) && !isplayer(lf)) { + ignorethis = B_TRUE; + } + + if (!ignorethis) { + if (db) dblog("inheriting flagid %d.", f->id); + addflag_real(lf->flags, id, val[0], val[1], val[2], text, FROMJOB,B_TRUE, -1); + if (id == F_STARTATT) { + rollatt[val[0]] = B_TRUE; + } } } // now give start obs/skills from it - givestartobs(lf, lf->flags); givestartskills(lf, lf->flags); + givestartobs(lf, NULL, lf->flags); autoskill(lf); @@ -5896,8 +6032,10 @@ void givejob(lifeform_t *lf, enum JOB jobid) { killflagsofid(lf->flags, F_HOSTILE); killflagsofid(lf->flags, F_HATESRACE); // mark its home shop - assert(isroom(lf->cell)); - addflag(lf->flags, F_OWNSSHOP, lf->cell->roomid, NA, NA, NULL); + if (isroom(lf->cell)) { + addflag(lf->flags, F_OWNSSHOP, lf->cell->roomid, NA, NA, NULL); + addflag(lf->flags, F_STAYINROOM, lf->cell->roomid, NA, NA, NULL); + } } } @@ -6023,7 +6161,7 @@ int giveskill(lifeform_t *lf, enum SKILL id) { f->val[1]++; } if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) { - msg("You have learned the %s %s skill!", getskilllevelname(f->val[1]), getskillname(sk->id)); + msg("^gYou have learned the %s %s skill!", getskilllevelname(f->val[1]), getskillname(sk->id)); more(); } statdirty = B_TRUE; // in case skill changes your stats @@ -6031,7 +6169,7 @@ int giveskill(lifeform_t *lf, enum SKILL id) { // gaining a new skill f = addflag(lf->flags, F_HASSKILL, id, PR_NOVICE, NA, NULL); if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) { - msg("You have learned the %s %s skill!", getskilllevelname(PR_NOVICE), getskillname(sk->id)); + msg("^gYou have learned the %s %s skill!", getskilllevelname(PR_NOVICE), getskillname(sk->id)); more(); } @@ -6076,22 +6214,25 @@ int giveskill(lifeform_t *lf, enum SKILL id) { // special effects based on skill level if (id == SK_ATHLETICS) { if (f->val[1] == PR_ADEPT) { + newf = addflag(lf->flags, F_CANWILL, OT_A_TUMBLE, 2, 2, NULL); + newf->lifetime = FROMJOB; + } else if (f->val[1] == PR_EXPERT) { newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL); newf->lifetime = FROMJOB; } } else if (id == SK_CARTOGRAPHY) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_NOVICE) { - msg("You now make basic maps of your surroundings."); + msg("^gYou now make basic maps of your surroundings."); } else if (f->val[1] == PR_BEGINNER) { - msg("Your map now shows the location of staircases."); + msg("^gYour map now shows the location of staircases."); } else if (f->val[1] == PR_ADEPT) { - msg("Your map now shows the location of doors."); + msg("^gYour map now shows the location of doors."); } else if (f->val[1] == PR_SKILLED) { //msg("You will no longer forget your surroundings."); addflag(lf->flags, F_PHOTOMEM, B_TRUE, NA, NA, NULL); } else if (f->val[1] == PR_EXPERT) { - msg("Your map will now show the location of objects."); + msg("^gYour map will now show the location of objects."); } } if (f->val[1] == PR_MASTER) { @@ -6101,9 +6242,9 @@ int giveskill(lifeform_t *lf, enum SKILL id) { } else if (id == SK_COOKING) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_NOVICE) { - msg("You can now recognise rotting food."); + msg("^gYou can now recognise rotting food."); } else if (f->val[1] == PR_BEGINNER) { - msg("You can now recognise all kinds of bad food."); + msg("^gYou can now recognise all kinds of bad food."); } else if (f->val[1] == PR_ADEPT) { newf = addflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL); newf->lifetime = FROMJOB; @@ -6112,26 +6253,26 @@ int giveskill(lifeform_t *lf, enum SKILL id) { } else if (id == SK_FIRSTAID) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_ADEPT) { - msg("You can now recgonise when poison is potentially fatal."); + msg("^gYou can now recgonise when poison is potentially fatal."); statdirty = B_TRUE; } } } else if (id == SK_LISTEN) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_BEGINNER) { - msg("You can now gauge the distance of sounds."); + msg("^gYou can now gauge the distance of sounds."); } else if (f->val[1] == PR_ADEPT) { - msg("You can now determine the direction sounds are coming from."); + msg("^gYou can now determine the direction sounds are coming from."); } else if (f->val[1] == PR_EXPERT) { - msg("You can now identify monsters based on sound."); + msg("^gYou can now identify monsters based on sound."); } else if (f->val[1] == PR_MASTER) { - msg("You can now locate monsters based on sound."); + msg("^gYou can now locate monsters based on sound."); } } } else if (id == SK_RANGED) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_MASTER) { - msg("Your no longer suffer ranged-based accuracy penalties when firing."); + msg("^gYour no longer suffer ranged-based accuracy penalties when firing."); } } } else if (id == SK_STEALTH) { @@ -6140,19 +6281,19 @@ int giveskill(lifeform_t *lf, enum SKILL id) { newf->lifetime = FROMJOB; } else if (f->val[1] == PR_EXPERT) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { - msg("You can now hide even when monsters are nearby."); + msg("^gYou 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."); + msg("^gYou can now swim."); } else if ((f->val[1] >= PR_BEGINNER) && (f->val[1] <= PR_SKILLED)) { - msg("You can now swim a bit faster."); + msg("^gYou can now swim a bit faster."); } else if (f->val[1] == PR_EXPERT) { - msg("You can now attack awkwardly and cast spells while swimming."); + msg("^gYou 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."); + msg("^gYou can now attack while swimming with no penalty."); } } } else if (id == SK_TECHUSAGE) { @@ -6183,52 +6324,52 @@ int giveskill(lifeform_t *lf, enum SKILL id) { } else if (id == SK_THIEVERY) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_BEGINNER) { - msg("Your accuracy penalty when stealing is reduced."); + msg("^gYour accuracy penalty when stealing is reduced."); } else if (f->val[1] == PR_ADEPT) { - msg("You can now steal specific items."); + msg("^gYou can now steal specific items."); } else if (f->val[1] == PR_SKILLED) { - msg("You can now steal heavy items."); + msg("^gYou can now steal heavy items."); } else if (f->val[1] == PR_EXPERT) { - msg("You can now steal multiple items."); + msg("^gYou can now steal multiple items."); } else if (f->val[1] == PR_MASTER) { - msg("You can now steal equipped items."); + msg("^gYou can now steal equipped items."); } } } else if (id == SK_TRACKING) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_NOVICE) { - msg("You can now see footprints."); + msg("^gYou can now see footprints."); } else if (f->val[1] == PR_BEGINNER) { - msg("You can now determine how recently footprints were made."); + msg("^gYou can now determine how recently footprints were made."); } else if (f->val[1] == PR_ADEPT) { - msg("You can now identify creatures from their footprints."); + msg("^gYou can now identify creatures from their footprints."); } else if (f->val[1] == PR_SKILLED) { - msg("You can now recognise the direction of footprints."); + msg("^gYou can now recognise the direction of footprints."); } else if (f->val[1] == PR_EXPERT) { - msg("You can now partially obscure your own footprints."); + msg("^gYou can now partially obscure your own footprints."); } else if (f->val[1] == PR_MASTER) { - msg("You can now move without leaving footprints."); + msg("^gYou can now move without leaving footprints."); } } } else if (id == SK_TWOWEAPON) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_NOVICE) { - msg("You can now weild two weapons at once."); + msg("^gYou can now weild two weapons at once."); } else if (f->val[1] == PR_ADEPT) { - msg("You no longer suffer an accuracy penalty when weilding two weapons."); + msg("^gYou no longer suffer an accuracy penalty when weilding two weapons."); } else if (f->val[1] == PR_SKILLED) { - msg("Follow-up attacks with your second weapon are now more accurate."); + msg("^gFollow-up attacks with your second weapon are now more accurate."); } else if (f->val[1] == PR_EXPERT) { addflag(lf->flags, F_CANWILL, OT_A_FLURRY, 3, 3, "pw:1;"); } else if (f->val[1] == PR_MASTER) { - msg("You can now deflect attacks with your second weapon."); + msg("^gYou can now deflect attacks with your second weapon."); } } } else if (id == SK_UNARMED) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (f->val[1] == PR_SKILLED) { if (hasbp(lf, BP_SECWEAPON)) { - msg("You can now make melee attacks with your off-hand."); + msg("^gYou can now make melee attacks with your off-hand."); } } } @@ -6254,15 +6395,15 @@ int giveskill(lifeform_t *lf, enum SKILL id) { if (rc) { // announce. if (f->val[1] >= PR_MASTER) { - msg("You now know everything there is to know about %s.", rc->pluralname); + msg("^gYou now know everything there is to know about %s.", rc->pluralname); } else if (f->val[1] >= PR_SKILLED) { - msg("You can now anticipate how %s will react.", rc->pluralname); + msg("^gYou can now anticipate how %s will react.", rc->pluralname); } else if (f->val[1] >= PR_ADEPT) { - msg("You can now determine how dangerous %s are.", rc->pluralname); + msg("^gYou can now determine how dangerous %s are.", rc->pluralname); } else if (f->val[1] >= PR_BEGINNER) { - msg("You can now determine how much damage %s will deal.", rc->pluralname); + msg("^gYou can now determine how much damage %s will deal.", rc->pluralname); } else if (f->val[1] >= PR_NOVICE) { - msg("You now know basic information about %s.", rc->pluralname); + msg("^gYou now know basic information about %s.", rc->pluralname); } } @@ -6294,20 +6435,33 @@ int giveskilllev(lifeform_t *lf, enum SKILL id, enum SKILLLEVEL slev) { } // give start objects from a particular flagpile -void givestartobs(lifeform_t *lf, flagpile_t *fp) { +// only give EITHER lf OR targob +void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { object_t *o; flag_t *f; char buf[BUFLEN],buf2[BUFLEN]; - int ignorenext = B_FALSE; - int ignoredprev = B_FALSE; int db = B_FALSE; + obpile_t *op; + map_t *targmap; + enum LFSIZE maxobsize = SZ_MAX; + + if (targob) { + cell_t *c; + op = targob->contents; + c = getoblocation(targob); + targmap = c->map; + maxobsize = getobsize(targob); + } else { + op = lf->pack; + targmap = lf->cell->map; + } if (db) { sprintf(buf2, "calling givestartobs for %s",lf->race->name); } // handle autoweapon - if (hasflag(fp, F_SELECTWEAPON)) { + if (lf && hasflag(fp, F_SELECTWEAPON)) { skill_t *sk; objecttype_t *poss[MAXSKILLS]; int nposs = 0, i; @@ -6325,126 +6479,162 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) { } } if (nposs) { - char ch = 'a'; objecttype_t *ot = NULL; + if (isplayer(lf)) { + char ch = 'a'; - // note: we use getplayername here even if this isn't a player, - // since in that case the prompt will never be displayed. - getplayernamefull(buf2); - sprintf(buf, "%s, select your starting weapon:", buf2); - initprompt(&prompt, buf); + // note: we use getplayername here even if this isn't a player, + // since in that case the prompt will never be displayed. + getplayernamefull(buf2); + sprintf(buf, "%s, select your starting weapon:", buf2); + initprompt(&prompt, buf); - for (i = 0; i < nposs; i++) { - addchoice(&prompt, ch++, poss[i]->name, NULL, poss[i]); - } - - if (prompt.nchoices == 1) { - ot = (objecttype_t *)prompt.choice[0].data; - } else if (prompt.nchoices) { - if (isplayer(lf)) { - getchoice(&prompt); - ot = (objecttype_t *)prompt.result; - } else { - ot = (objecttype_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data; + for (i = 0; i < nposs; i++) { + addchoice(&prompt, ch++, poss[i]->name, NULL, poss[i]); } - } + + if (prompt.nchoices == 1) { + ot = (objecttype_t *)prompt.choice[0].data; + } else if (prompt.nchoices) { + if (isplayer(lf)) { + getchoice(&prompt); + ot = (objecttype_t *)prompt.result; + } else { + ot = (objecttype_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data; + } + } + } else { + // not player - pick randomly. + i = rnd(0,nposs-1); + ot = poss[i]; + } if (ot) { + skill_t *sk; + object_t *o; // give that weapon - addob(lf->pack, ot->name); - // skill in this weapon will be added later during autoskill() + o = addob(lf->pack, ot->name); + + // give one extra rank of skill in this weapon + sk = getobskill(o); + giveskill(lf, sk->id); } - } - - } + } // end if lf && selectweapon // give start objects and id them - ignorenext = B_FALSE; for (f = fp->first ; f ; f = f->next) { + int val[3]; + int id; + char *text; o = NULL; - if (ignorenext) { - ignorenext = B_FALSE; - ignoredprev = B_TRUE; - continue; - } - if (f->id == F_IFPCT) { - if (rnd(0,100) > f->val[0]) { - ignorenext = B_TRUE; - } - if ((f->val[2] == IFMONSTER) && isplayer(lf)) { - ignorenext = B_TRUE; - } else if ((f->val[2] == IFPLAYER) && !isplayer(lf)) { - ignorenext = B_TRUE; - } - } else if (f->id == F_ELSE) { - if (ignoredprev) { - } else { - ignorenext = B_TRUE; - } - } else { + + id = f->id; + val[0] = f->val[0]; + val[1] = f->val[1]; + val[2] = f->val[2]; + text = f->text; + + if (lf) { if (isplayer(lf)) { // if this is the player, DONT inherit any STARTOB* flags from race if (f->lifetime == FROMRACE) { continue; } } else { - // if this is a monster, DONT inherit specific STARTOB flags from race + // if this is a jobless monster, DONT inherit specific STARTOB flags from race if ((f->lifetime == FROMJOB) && (f->id == F_STARTOB)) { + if (!lfhasflag(lf, F_JOB)) { + continue; + } + } + } + } + + // now handle other flag conditions... + if (f->chance != 100) { + if (rnd(0,100) > f->chance) { + // failed! got an altval? + if (f->altval) { + // use it instead + id = f->altval->id; + val[0] = f->altval->val[0]; + val[1] = f->altval->val[1]; + val[2] = f->altval->val[2]; + text = f->altval->text; + } else { + // ignore this one. continue; } } + } - if (f->id == F_STARTOB) { - assert(strlen(f->text) > 0); - if (rnd(1,100) <= f->val[0]) { - o = addob(lf->pack, f->text); + if (id == F_STARTOB) { + assert(strlen(text) > 0); + if (rnd(1,100) <= val[0]) { + o = addob(op, text); + } + } else if (id == F_STARTOBRND) { + if (rnd(1,100) <= val[0]) { + int depthmod; + depthmod = val[1]; + switch (depthmod) { + case NA: depthmod = 0; break; + case RANDOM: depthmod = rnd(0,MAXDEPTH); break; + default: break; } - } else if (f->id == F_STARTOBDT) { - if (rnd(1,100) <= f->val[0]) { - if (db) { - sprintf(buf2, "calling startobdt"); - } - if (getrandomobwithdt(lf->cell->map, f->val[1], buf)) { - if (db) sprintf(buf2, "finished startobdt successfuly."); - o = addob(lf->pack, buf); - } else { - if (db) sprintf(buf2, "finished startobdt, failed."); - } - //assert(strlen(buf) > 0); - } - } else if (f->id == F_STARTOBCLASS) { - if (rnd(1,100) <= f->val[0]) { - if (db) { - sprintf(buf2, "calling startobclass"); - } - //obdb = B_TRUE; - if (getrandomobwithclass(lf->cell->map, f->val[1], buf, f->val[2])) { - if (db) sprintf(buf2, "finished startobclass, success."); - o = addob(lf->pack, buf); - } else { - //obdb = B_FALSE; - if (db) sprintf(buf2, "finished startobclass. couldnt find an object."); - } - //if (strlen(buf) <= 0); + +// if (getrandomobofsize(targmap, buf, maxobsize)) { + if (real_getrandomob(targmap, buf, RO_HOLDABLE, NA, targmap->depth + depthmod, NA, maxobsize)) { + o = addob(op, buf); } } + } else if (id == F_STARTOBDT) { + if (rnd(1,100) <= val[0]) { + if (db) { + sprintf(buf2, "calling startobdt"); + } + if ( real_getrandomob(targmap, buf, RO_DAMTYPE, val[1], NA, NA, maxobsize)) { + if (db) sprintf(buf2, "finished startobdt successfuly."); + o = addob(op, buf); + } else { + if (db) sprintf(buf2, "finished startobdt, failed."); + } + //assert(strlen(buf) > 0); + } + } else if (id == F_STARTOBCLASS) { + if (rnd(1,100) <= val[0]) { + if (db) { + sprintf(buf2, "calling startobclass"); + } + //obdb = B_TRUE; + //if (getrandomobwithclass(targmap, val[1], buf, val[2])) { + if (real_getrandomob(targmap, buf, RO_OBCLASS, val[1], getmapdifficulty(targmap) + val[2], NA, maxobsize)) { + if (db) sprintf(buf2, "finished startobclass, success."); + o = addob(op, buf); + } else { + //obdb = B_FALSE; + if (db) sprintf(buf2, "finished startobclass. couldnt find an object."); + } + //if (strlen(buf) <= 0); + } + } - // added an object? - if (o) { + // added an object? + if (o) { + if (lf) { // undead can't have cursed objecst if (isundead(lf)) { if (o->blessed == B_BLESSED) setblessed(o, B_CURSED); } // player knows the objects they start with - if (isplayer(lf)) { + if (isplayer(lf) || (o->pile->parentob && isplayer(o->pile->parentob->pile->owner))) { identify(o); } } } - ignoredprev = B_FALSE; } @@ -6454,33 +6644,33 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp) { killflagsofid(fp, F_STARTOBCLASS); // SPECIAL CASES - if (lf->race->id == R_JAILER) { - regionoutline_t *ro; - region_t *r; - regionthing_t *rt = NULL; - int i; - o = addob(lf->pack, "map"); - assert(o); - // find first worldmap village - r = findregion(RG_WORLDMAP); - ro = r->outline; - for (i = 0; i < ro->nthings; i++) { - regionthing_t *thisthing; - thisthing = &ro->thing[i]; - if ((thisthing->whatkind == RT_HABITAT) && (thisthing->value == H_VILLAGE)) { - rt = thisthing; - break; + if (lf) { + if (lf->race->id == R_JAILER) { + regionoutline_t *ro; + region_t *r; + regionthing_t *rt = NULL; + int i; + o = addob(lf->pack, "map"); + assert(o); + // find first worldmap village + r = findregion(RG_WORLDMAP); + ro = r->outline; + for (i = 0; i < ro->nthings; i++) { + regionthing_t *thisthing; + thisthing = &ro->thing[i]; + if ((thisthing->whatkind == RT_HABITAT) && (thisthing->value == H_VILLAGE)) { + rt = thisthing; + break; + } } + addflag(o->flags, F_MAPTO, rt->x, rt->y, OT_GATEWOOD, "a village"); } - addflag(o->flags, F_MAPTO, rt->x, rt->y, OT_GATEWOOD, "a village"); - - } - // make sure lf doesn't start off burdened! - while (isburdened(lf)) { - modattr(lf, A_STR, 1); // get stronger + // make sure lf doesn't start off burdened! + while (isburdened(lf)) { + modattr(lf, A_STR, 1); // get stronger + } } - } void givestartskills(lifeform_t *lf, flagpile_t *fp) { @@ -6498,6 +6688,18 @@ void givestartskills(lifeform_t *lf, flagpile_t *fp) { killflagsofid(fp, F_STARTSKILL); } +int gotosleep(lifeform_t *lf, int onpurpose) { + if (lfhasflag(lf, F_CAFFEINATED)) { + if (isplayer(lf)) { + msg("Your caffeine high prevents you from sleeping."); + } + return B_TRUE; + } + if (onpurpose) taketime(lf, getactspeed(lf)); + addflag(lf->flags, F_ASLEEP, B_TRUE, NA, onpurpose ? B_TRUE : NA, NULL); + return B_FALSE; +} + int hasfreeaction(lifeform_t *lf) { if (isimmobile(lf)) return B_FALSE; if (lfhasflag(lf, F_ASLEEP)) return B_FALSE; @@ -6794,7 +6996,7 @@ int lockpick(lifeform_t *lf, object_t *target, object_t *device) { getobname(device,devname, 1); // kill object if (isplayer(lf)) { - msg("Your %s breaks!",noprefix(devname)); + msg("^wYour %s breaks!",noprefix(devname)); } else if (cansee(player, lf)) { msg("%s%s %s breaks!",lfname, getpossessive(lfname), noprefix(devname)); } @@ -7119,12 +7321,15 @@ int haslos(lifeform_t *viewer, cell_t *dest) { void initjobs(void) { int i; + flag_t *f; // job definitions // NOTE: try to always make the job's weapon be the first object defined. // this will make sure that they have the letter 'a'. addjob(J_GOD, "Diety"); //addflag(lastjob->flags, F_OMNIPOTENT, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_VHIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_EXHIGH, NA, NULL); addflag(lastjob->flags, F_MPDICE, 100, NA, NA, NULL); //addflag(lastjob->flags, F_MPREGEN, 100, NA, NA, NULL); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "short sword of pyromania"); @@ -7161,439 +7366,483 @@ void initjobs(void) { } addjob(J_ADVENTURER, "Adventurer"); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing"); - addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); - for (i = 1; i < MAXSKILLS; i++) { - addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); - } + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); + // learnable skills + for (i = 1; i < MAXSKILLS; i++) { + addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); + } + // abilities + addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); + addjob(J_ALLOMANCER, "Allomancer"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "club"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloak"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "potion of magic"); - addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); - //addflag(lastjob->flags, F_MPDICE, 5, 6, NA, NULL); - addflag(lastjob->flags, F_CANCAST, OT_S_ABSORBMETAL, NA, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_DETECTMETAL, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SS_ALLOMANCY, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL); - mayusespellschool(lastjob->flags, SS_ALLOMANCY, F_CANCAST); - addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); - // TODO skill: court knowledge ?? - // TODO skill: bartering 2 + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "club"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloak"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "potion of magic"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_SS_ALLOMANCY, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_THROWING, PR_NOVICE, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); + addflag(lastjob->flags, F_CANCAST, OT_S_ABSORBMETAL, NA, NA, NULL); + addflag(lastjob->flags, F_DETECTMETAL, B_TRUE, NA, NA, NULL); + mayusespellschool(lastjob->flags, SS_ALLOMANCY, F_CANCAST); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_BARBARIAN, "Barbarian"); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_FIT, NA, NULL); - addflag(lastjob->flags, F_HITDICE, 1, 6, NA, NULL); - addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "buckler"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); - addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CLUBS, PR_BEGINNER, NA, NULL); - 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_ATHLETICS, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); - 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_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); - addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); - addflag(lastjob->flags, F_LEVABIL, 3, OT_A_HEAVYBLOW, 3, NULL); - addflag(lastjob->flags, F_LEVABIL, 4, OT_A_WARCRY, 4, NULL); - addflag(lastjob->flags, F_LEVABIL, 5, OT_A_CHARGE, 5, NULL); - addflag(lastjob->flags, F_LEVABIL, 6, OT_A_RAGE, 50, NULL); - addflag(lastjob->flags, F_LEVABIL, 10, OT_A_HURRICANESTRIKE, 5, NULL); + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_LTAVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "buckler"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CLUBS, PR_NOVICE, NA, NULL); + 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_ATHLETICS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + 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_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); + addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STAVES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_HITDICE, 1, 6, NA, NULL); + addflag(lastjob->flags, F_SELECTWEAPON, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_LEVABIL, 3, OT_A_HEAVYBLOW, 3, NULL); + addflag(lastjob->flags, F_LEVABIL, 4, OT_A_WARCRY, 4, NULL); + addflag(lastjob->flags, F_LEVABIL, 5, OT_A_CHARGE, 5, NULL); + addflag(lastjob->flags, F_LEVABIL, 6, OT_A_RAGE, 50, NULL); + addflag(lastjob->flags, F_LEVABIL, 10, OT_A_HURRICANESTRIKE, 5, NULL); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); + addjob(J_COMMANDO, "Commando"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat knife"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "revolver"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "flak jacket"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat pants"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "nightvis goggles"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-2 blocks of c4"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-3 grenades"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-3 flashbangs"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "digital watch"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 bullets"); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); - 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_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_STARTSKILL, SK_LORE_HUMANOID, PR_SKILLED, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); - /////////////////////////////////////// + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_HIGH, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat knife"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "revolver"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "flak jacket"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "combat pants"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "nightvis goggles"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-2 blocks of c4"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-3 grenades"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1-3 flashbangs"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "digital watch"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 bullets"); + // initial skills + 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_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_STARTSKILL, SK_LORE_HUMANOID, PR_SKILLED, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, NA, NA, NULL); + // abilities addjob(J_DRUID, "Druid"); - // stats - addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_ATTRACTIVE, NA, NULL); - // objects - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "quarterstaff"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "sickle"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of sandals"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 sprigs of mistletoe"); - // skills - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_SKILLED, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL); - // learnable skills - 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 - addflag(lastjob->flags, F_LEVSKILL, 5, SK_LORE_NATURE, NA, NULL); - addflag(lastjob->flags, F_LEVSKILL, 10, SK_LORE_NATURE, NA, NULL); - addflag(lastjob->flags, F_LEVSKILL, 15, SK_LORE_NATURE, NA, NULL); - // abilities - mayusespellschool(lastjob->flags, SS_NATURE, F_CANCAST); - addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf"); - addflag(lastjob->flags, F_PARTVEGETARIAN, B_TRUE, NA, NA, NULL); + // stats + addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "quarterstaff"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "sickle"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of sandals"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 sprigs of mistletoe"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_SKILLED, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_ADEPT, NA, NULL); + // learnable skills + 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); + // abilities + mayusespellschool(lastjob->flags, SS_NATURE, F_CANCAST); + addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf"); + addflag(lastjob->flags, F_PARTVEGETARIAN, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_LEVSKILL, 5, SK_LORE_NATURE, NA, NULL); + addflag(lastjob->flags, F_LEVSKILL, 10, SK_LORE_NATURE, NA, NULL); + addflag(lastjob->flags, F_LEVSKILL, 15, SK_LORE_NATURE, NA, NULL); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); /////////////////////////////////////// addjob(J_MONK, "Monk"); - // stats - addflag(lastjob->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_NIMBLE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL); - // TODO: high wisdom - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_AVERAGE, NA, NULL); - // objects - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of sandals"); - // skills - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPOTHIDDEN, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL); - // learnable skills - addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TRAPS, NA, NA, NULL); - // starting abilities - // 1: feign death (mp) - addflag(lastjob->flags, F_MAXATTACKS, 1, 1, NA, NULL); // this will go up later - // gained abilities - // somewhere: slow falling when next to walls - // somehwere: heavy blow - // somehwere: flurry - // somehwere: alertness when sleeping - // somehwere: tremorsense - // 2: resist ESP (innate) - addflag(lastjob->flags, F_LEVSPELL, 3, OT_S_CALMANIMALS, NA, NULL); - // 4: self-healing (mp), immune to disease (innate), immune to haste/slow (innate) - // 5: waterawlk via 'body equilibrium' (innate) - // 6: empathy (ie. sense hostility.... useful???) - addflag(lastjob->flags, F_LEVSPELL, 7, OT_S_INVISIBILITY, NA, NULL); - // 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate) - // 9: resistance to charm, hypnosis, sleep (innate) - addflag(lastjob->flags, F_LEVFLAG, 10, F_DTIMMUNE, DT_POISON, NULL); - // 11: body control (ie. have one turn as another lf) (mp) - // 12: quivering palm (v.high mp cost OR once every 200 turns or so) - addflag(lastjob->flags, F_LEVFLAG, F_CANWILL, OT_S_BLINK, 10, "pw:6;"); // l6 = controlled - // 14: speak with plants (mp?innate?) - // 15: mind bar??? what is this - // 16: identify (not very often) (mp) - addflag(lastjob->flags, F_LEVFLAG, F_CANWILL, OT_S_IDENTIFY, 100, NULL); - // 17: dimension walk (controlled teleport??) (mp) - // 18: astral projection.. .??useful? - // 19: premonition of death 1-4 turns before - // 20: tower of iron will - // 21: planeshift - - + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 loaf of stale bread"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 cheese"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of sandals"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPOTHIDDEN, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TRAPS, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_CANWILL, OT_A_FEIGNDEATH, NA, NA, NULL); + addflag(lastjob->flags, F_MAXATTACKS, 1, 1, NA, NULL); // this will go up later + // gained abilities + // somewhere: slow falling when next to walls + // somehwere: alertness when sleeping + addflag(lastjob->flags, F_LEVFLAG, 2, F_MPDICE, 1, NULL); + addflag(lastjob->flags, F_LEVSPELL, 2, OT_S_CALMANIMALS, NA, NULL); + // 2: body control - low metabolism + addflag(lastjob->flags, F_LEVSPELL, 3, OT_S_BODYCONTROL, NA, NULL); + // 4: self-healing (mp), immune to haste/slow (innate) + addflag(lastjob->flags, F_LEVFLAG, 4, F_DISEASEIMMUNE, B_TRUE, NULL); + addflag(lastjob->flags, F_LEVABIL, 5, OT_A_HEAVYBLOW, 3, NULL); + // 6: waterawlk via 'body equilibrium' (innate) + addflag(lastjob->flags, F_LEVFLAG, 7, F_TREMORSENSE, 3, NULL); + // 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate) + addflag(lastjob->flags, F_LEVABIL, 8, OT_A_FLURRY, 3, "pw:1;"); + // 9: resistance to charm, hypnosis, sleep (innate) + addflag(lastjob->flags, F_LEVFLAG, 10, F_DTIMMUNE, DT_POISON, NULL); + addflag(lastjob->flags, F_LEVSPELL, 11, OT_S_PSYARMOUR, NA, NULL); + // 12: quivering palm (v.high mp cost OR once every 200 turns or so) + addflag(lastjob->flags, F_LEVABIL, 13, OT_S_BLINK, 10, "pw:6;"); // l6 = controlled + // 14: speak with plants (mp?innate?) + // 15: mind bar??? what is this + addflag(lastjob->flags, F_LEVABIL, 16, OT_S_IDENTIFY, 100, NULL); + // 17: dimension walk (controlled teleport??) (mp) + // 18: astral projection.. .??useful? + // 19: premonition of death 1-4 turns before + // 20: tower of iron will + // 21: planeshift + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_PLUMBER, "Plumber"); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_UGLY, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spanner"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "overalls"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cap"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3-5 mushrooms"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rubber boots"); - 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_CLIMBING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, 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); + // stats + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spanner"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "overalls"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cap"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3-5 mushrooms"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rubber boots"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL); + // learnable akills + addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, 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); + // abilities + 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_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_PRINCE, "Prince"); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_ALLURING, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "blessed ornamental sword"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "golden crown"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ornamental dagger"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "velvet robe"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "silk shirt"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "riding trousers"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); - addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); - 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_LORE_NATURE, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_SKILLED, 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); - addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL); + // stats + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_GTAVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "blessed ornamental sword"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "golden crown"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ornamental dagger"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "velvet robe"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "silk shirt"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "riding trousers"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); + 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_LORE_NATURE, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_SKILLED, NA, NULL); + // learnable skills + 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); + addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_POLEARMS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_PIRATE, "Pirate"); - // stats - addflag(lastjob->flags, F_STARTATT, A_STR, NA, NA, "8-15"); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_HEALTHY, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_UNATTRACTIVE, NA, NULL); - // abilities - addflag(lastjob->flags, F_STABILITY, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); - addflag(lastjob->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastjob->flags, F_EXTRALUCK, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young hawk"); - addflag(lastjob->flags, F_MAXATTACKS, 2, 2, NA, NULL);// this is so that our hookhand works - addflag(lastjob->flags, F_VISRANGEMOD, -4, NA, NA, NULL); - // also: has a hook instead of fists. - // startobjects - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cutlass"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "silk shirt"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "eyepatch"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "tricorne"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "300-350 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 potions of rum"); - // skills - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, 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_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, 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); - addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_THIEVERY, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL); + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, NA, NA, "8-15"); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cutlass"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "silk shirt"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "eyepatch"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "tricorne"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "300-350 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 potions of rum"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, 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_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); + // learnable skills + 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); + addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_THIEVERY, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_STABILITY, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL); + addflag(lastjob->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); + addflag(lastjob->flags, F_EXTRALUCK, B_TRUE, NA, NA, NULL); + addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young hawk"); + addflag(lastjob->flags, F_MAXATTACKS, 2, 2, NA, NULL);// this is so that our hookhand works + addflag(lastjob->flags, F_VISRANGEMOD, -4, NA, NA, NULL); + // also: has a hook instead of fists. + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_ROGUE, "Rogue"); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_WEAK, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_NIMBLE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_UNFIT, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_RANDOM, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "dagger"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 lockpicks"); - addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LISTEN, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_BACKSTAB, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPOTHIDDEN, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_THIEVERY, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL); - 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_SPEECH, 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); - addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_GRAVITY, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_MENTAL, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_TRANSLOCATION, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); - + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "dagger"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 lockpicks"); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LISTEN, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_BACKSTAB, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPOTHIDDEN, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_THIEVERY, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_BEGINNER, NA, NULL); + // learnable skills + 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_SPEECH, 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_THROWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_GRAVITY, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_MENTAL, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_TRANSLOCATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_WIZARD, "Wizard"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "knife"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of magic"); - /* - addflag(lastjob->flags, F_IFPLAYER, NA, NA, NA, NULL); - addflag(lastjob->flags, F_IFPCT, 50, NA, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spellbook of flame dart"); - addflag(lastjob->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spellbook of cone of cold"); - addflag(lastjob->flags, F_ENDIFPLAYER, NA, NA, NA, NULL); - */ - - addflag(lastjob->flags, F_IFMONSTER, NA, NA, NA, NULL); - addflag(lastjob->flags, F_IFPCT, 50, NA, NA, NULL); // monsters sometimes start with a random book - addflag(lastjob->flags, F_STARTOBCLASS, 100, OC_BOOK, NA, NULL); - addflag(lastjob->flags, F_ENDIFMONSTER, NA, NA, NA, NULL); - addflag(lastjob->flags, F_HITDICE, 1, 1, NA, NULL); // low hp - addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_STR, ST_WEAK, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CON, CN_UNFIT, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_CHA, CH_RANDOM, NA, NULL); - // wizard heals slowly, but regenerates mp - addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); - //addflag(lastjob->flags, F_MPREGEN, 1, SK_SPELLCASTING, 35, NULL); - // can detect magic objects - addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_BEGINNER, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_LORE_DEMONS, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_CHANNELING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SS_WILD, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); - // wizards can learn all spell schools except psionics and allomancy - addflag(lastjob->flags, F_CANLEARN, SK_SS_AIR, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_DEATH, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, 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); - addflag(lastjob->flags, F_CANLEARN, SK_SS_GRAVITY, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_SUMMONING, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_TRANSLOCATION, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LORE_DEMONS, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL); - // gained skills - addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); - addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); - addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); - addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level - - // for monster wizards only: - addflag(lastjob->flags, F_IFMONSTER, NA, NA, NA, NULL); - 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_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); - addflag(lastjob->flags, F_CANCAST, OT_S_BLINK, NA, NA, NULL); - addflag(lastjob->flags, F_IFPCT, 33, NA, NA, NULL); - addflag(lastjob->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL); - addflag(lastjob->flags, F_IFPCT, 20, NA, NA, NULL); - addflag(lastjob->flags, F_CANCAST, OT_S_HASTE, NA, NA, NULL); - addflag(lastjob->flags, F_IFPCT, 20, NA, NA, NULL); - addflag(lastjob->flags, F_CANCAST, OT_S_HEALING, NA, NA, NULL); - addflag(lastjob->flags, F_ENDIFMONSTER, NA, NA, NA, NULL); + // stats + addflag(lastjob->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CON, AT_LTAVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); + // initial objects + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "knife"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of magic"); + // monster wizards sometimes start with a random book + f = addflag(lastjob->flags, F_STARTOBCLASS, 100, OC_BOOK, NA, NULL); addcondition(f, FC_IFMONSTER, 50); + // initial skills + addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_LORE_DEMONS, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_CHANNELING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SS_WILD, PR_NOVICE, NA, NULL); + // learnable skills + addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_AIR, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_DEATH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_ENCHANTMENT, 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); + addflag(lastjob->flags, F_CANLEARN, SK_SS_GRAVITY, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_SUMMONING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_TRANSLOCATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LORE_DEMONS, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL); + // abilities + addflag(lastjob->flags, F_HITDICE, 1, 1, NA, NULL); // low hp + addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); + addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); // wizard heals slowly, but regenerates mp + addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); + addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); + addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); + addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level + addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); + // monster job flags + f = addflag(lastjob->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 50); + f = addflag(lastjob->flags, F_CANCAST, OT_S_COLDRAY, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 50); + f = addflag(lastjob->flags, F_CANCAST, OT_S_HEALINGMIN, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 33); + f = addflag(lastjob->flags, F_CANCAST, OT_S_BLINK, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 33); + f = addflag(lastjob->flags, F_CANCAST, OT_S_TELEKINESIS, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 33); + f = addflag(lastjob->flags, F_CANCAST, OT_S_HASTE, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20); + f = addflag(lastjob->flags, F_CANCAST, OT_S_HEALING, NA, NA, NULL); addcondition(f, FC_IFMONSTER, 20); // non-player jobs addjob(J_SHOPKEEPER, "Shopkeeper"); - addflag(lastjob->flags, F_NOPLAYER, B_TRUE, IQ_AVERAGE, NA, NULL); - addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_NOPLAYER, B_TRUE, AT_AVERAGE, NA, NULL); + addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100-1000 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "shotgun"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5-10 bullets"); addflag(lastjob->flags, F_WANTS, OT_GOLD, NA, NA, NULL); } void initrace(void) { + flag_t *f; // race classes addraceclass(RC_OTHER, "misc. creature", "miscellaneous creatures", SK_NONE); addraceclass(RC_ANIMAL, "animal", "animals and insects", SK_LORE_NATURE); @@ -7607,7 +7856,8 @@ void initrace(void) { addraceclass(RC_UNDEAD, "undead", "the undead", SK_LORE_UNDEAD); // unique monsters - addrace(R_JAILER, "Jimbo", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID); + addrace(R_JAILER, "jailer", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID); + addflag(lastrace->flags, F_NAME, NA, NA, NA, "Jimbo"); addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -7615,10 +7865,10 @@ void initrace(void) { //addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); //addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d4"); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_DEX, NA, NA, "11-13"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_STUPID, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "gas mask"); @@ -7641,6 +7891,7 @@ void initrace(void) { addrace(R_HUMAN, "human", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); + addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, 2, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -7655,7 +7906,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL); - // TODO: humans start with a random job sometimes? + addflag(lastrace->flags, F_STARTJOB, 75, J_RANDOM, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -7687,8 +7938,27 @@ void initrace(void) { addflag(lastrace->flags, F_NOJOBTEXT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 15, J_WIZARD, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 50, J_ROGUE, NA, NULL); + addrace(R_DRUNK, "drunkard", 90, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addflag(lastrace->flags, F_RARITY, H_VILLAGE, 90, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); + addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 1, 2, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); + addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins"); + addflag(lastrace->flags, F_STARTOB, 100, OC_POTION, NA, "1-5 potions of rum"); + addflag(lastrace->flags, F_STARTOB, 70, OC_POTION, NA, "1-5 empty flasks"); + addflag(lastrace->flags, F_STARTOB, 60, OC_POTION, NA, "1-2 gold coins"); + addflag(lastrace->flags, F_STARTJOB, 50, J_RANDOM, NA, NULL); // often unemployed + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts drunkenly^a drunken shout"); + addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RANDOMTALKPCT, 30, NA, NA, NULL); + addflag(lastrace->flags, F_RANDOMTALK, SP_DRUNK, SV_WHISPER, SV_SHOUT, NULL); + f = addflag(lastrace->flags, F_DRUNK, 5, NA, NA, NULL); + addcondition(f, FC_NOCONDITION, 30); + addaltval(f, F_DRUNK, 3, NA, NA, NULL); addrace(R_TOWNGUARD, "town guard", 100, '@', C_GREY, MT_FLESH, RC_HUMANOID); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "12-18"); addflag(lastrace->flags, F_DONTSTARTASLEEP, NA, NA, NA, NULL); addflag(lastrace->flags, F_STAYINHABITAT, NA, NA, NA, NULL); @@ -7715,7 +7985,7 @@ void initrace(void) { // monsters addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_GENIUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -7728,7 +7998,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_S_FIREDART, NA, NA, "pw:5;"); addflag(lastrace->flags, F_CANWILL, OT_S_WEAKEN, NA, NA, "pw:2;"); addflag(lastrace->flags, F_CANWILL, OT_S_SLEEP, NA, NA, "pw:2;"); - addflag(lastrace->flags, F_CANWILL, OT_S_PULL, NA, NA, "pw:2;"); + addflag(lastrace->flags, F_CANWILL, OT_S_SUCK, NA, NA, "pw:2;"); addflag(lastrace->flags, F_CANWILL, OT_S_PARALYZE, NA, NA, "pw:2;"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "2d4"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "gazes at you"); @@ -7752,7 +8022,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d4+1"); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "heavy flail"); addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL); @@ -7765,7 +8035,7 @@ void initrace(void) { addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior"); addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_SWIFT, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "splash of cockatrice blood"); @@ -7794,7 +8064,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); 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); @@ -7812,9 +8082,9 @@ void initrace(void) { addrace(R_DARKMANTLE, "darkmantle", 70, 'U', C_BLUE, MT_FLESH, RC_MAGIC); addflag(lastrace->flags, F_STARTHIDDENPCT, 80, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_SUPERSONIC, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_HARDY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); 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); @@ -7842,8 +8112,8 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addrace(R_EYEBAT, "eyebat", 5, 'e', C_BLUE, MT_FLESH, RC_MAGIC); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_SMART, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_VWEAK, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); @@ -7881,16 +8151,17 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d5"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins"); addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "1-2 boulders"); - addflag(lastrace->flags, F_IFPCT, 70, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "club"); + + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); + addcondition(f, FC_NOCONDITION, 70); + addaltval(f, F_STARTOB, 70, NA, NA, "club"); + addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_WANTS, OT_BOULDER, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_HEAVYBLOW, NA, NA, NULL); @@ -7909,10 +8180,9 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d5+3"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins"); - addflag(lastrace->flags, F_IFPCT, 70, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming longsword"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword"); + addcondition(f, FC_NOCONDITION, 70); + addaltval(f, F_STARTOB, 100, NA, NA, "flaming longsword"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "javelin"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "javelin"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "javelin"); @@ -7921,9 +8191,9 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOBCLASS, 70, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -7942,17 +8212,16 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d5+3"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins"); - addflag(lastrace->flags, F_IFPCT, 70, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming morningstar"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming mace"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming morningstar"); + addcondition(f, FC_NOCONDITION, 70); + addaltval(f, F_STARTOB, 100, NA, NA, "flaming mace"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "plate mail"); addflag(lastrace->flags, F_STARTOBCLASS, 70, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_MPDICE, 0, 9, NA, NULL); @@ -7977,15 +8246,14 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d5+8"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "100-300 gold coins"); - addflag(lastrace->flags, F_IFPCT, 65, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword of pyromania"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword of pyromania"); + addcondition(f, FC_NOCONDITION, 65); + addaltval(f, F_STARTOB, 100, NA, NA, "flaming greatsword"); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_TITANIC, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_SWIFT, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 3, NA, "^crackling flames."); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); @@ -8010,9 +8278,9 @@ void initrace(void) { addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-40 gold coins"); @@ -8035,9 +8303,9 @@ void initrace(void) { addflag(lastrace->flags, F_EVASION, 0, NA, 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_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "longbow"); @@ -8064,9 +8332,9 @@ void initrace(void) { addflag(lastrace->flags, F_EVASION, 0, NA, 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_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4+2"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "spear"); @@ -8079,6 +8347,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addrace(R_GOBLIN, "goblin", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); + addflag(lastrace->flags, F_CANWILL, OT_A_FEIGNDEATH, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, NULL); @@ -8088,9 +8357,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold coins"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "short sword"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "sling"); @@ -8117,9 +8386,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4+2"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "spear"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-5 javelins"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); @@ -8144,9 +8413,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "short sword"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "hand crossbow"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-15 bolts"); @@ -8174,9 +8443,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "club"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "leather armour"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); @@ -8203,9 +8472,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+2"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_SMART, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "longsword"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler"); addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL); @@ -8233,9 +8502,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_SMART, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flail"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-75 gold coins"); addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "large shield"); @@ -8265,9 +8534,9 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_WEAK, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_NIMBLE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTOBDT, 20, DT_PIERCE, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 25, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-3 darts"); @@ -8289,9 +8558,9 @@ void initrace(void) { addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DIMWITTED, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_HASATTACK, OT_TAIL, NA, NA, "1d3"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "club"); @@ -8311,9 +8580,9 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 72, NA, NULL); addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d5+1"); addflag(lastrace->flags, F_HASATTACK, OT_TAIL, NA, NA, "1d4"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins"); @@ -8364,8 +8633,8 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, NA, NA, "5-7"); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_TITANIC, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "+2 heavy flail"); @@ -8392,16 +8661,15 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d4"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "2d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_STUPID, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); - addflag(lastrace->flags, F_IFPCT, 80, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "morningstar"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); + addcondition(f, FC_NOCONDITION, 80); + addaltval(f, F_STARTOB, 100, NA, NA, "morningstar"); addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -8421,16 +8689,15 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "3d4"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "3d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_STUPID, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); - addflag(lastrace->flags, F_IFPCT, 80, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed great club"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed great club"); + addcondition(f, FC_NOCONDITION, 80); + addaltval(f, F_STARTOB, 100, NA, NA, "great club"); addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -8451,16 +8718,15 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "4d4"); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "4d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_STUPID, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); - addflag(lastrace->flags, F_IFPCT, 80, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "heavy flail"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "heavy flail"); + addcondition(f, FC_NOCONDITION, 80); + addaltval(f, F_STARTOB, 100, NA, NA, "great club"); addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-100 gold coins"); addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); @@ -8479,12 +8745,11 @@ void initrace(void) { addflag(lastrace->flags, F_ARMOURRATING, 5, NA, 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_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_IFPCT, 70, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "club"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOBDT, 50, DT_SLASH, NA, NULL); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "club"); + addcondition(f, FC_NOCONDITION, 70); + addaltval(f, F_STARTOBDT, 50, DT_SLASH, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "bone helmet"); @@ -8509,12 +8774,11 @@ void initrace(void) { addflag(lastrace->flags, F_ARMOURRATING, 10, NA, 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_STARTATT, A_IQ, IQ_DOPEY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_IFPCT, 70, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "battleaxe"); - addflag(lastrace->flags, F_ELSE, NA, NA, NA, NULL); - addflag(lastrace->flags, F_STARTOBDT, 50, DT_CHOP, NA, NULL); + f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "battleaxe"); + addcondition(f, FC_NOCONDITION, 70); + addaltval(f, F_STARTOBDT, 50, DT_CHOP, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 75, NA, NA, "buckler"); @@ -8539,7 +8803,7 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTOBDT, 100, DT_SLASH, NA, NULL); addflag(lastrace->flags, F_STARTOBDT, 30, DT_BASH, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); @@ -8559,9 +8823,9 @@ void initrace(void) { addrace(R_PEGASUS, "pegasus", 130, 'Q', C_GREY, MT_FLESH, RC_MAGIC); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 57, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 57, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_HARDY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -8585,7 +8849,7 @@ void initrace(void) { addrace(R_POLTERGEIST, "poltergeist", 50, 'p', C_GREEN, MT_FLESH, RC_UNDEAD); // sPirit addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); @@ -8617,7 +8881,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BUTT, NA, NA, "2d4"); addflag(lastrace->flags, F_STARTOBDT, 50, DT_SLASH, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "panpipes"); @@ -8687,8 +8951,8 @@ void initrace(void) { addrace(R_SPRITEFIRE, "fire sprite", 5, 'n', C_RED, MT_FIRE, RC_MAGIC); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "small fire"); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_VWEAK, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); @@ -8719,8 +8983,8 @@ void initrace(void) { addflag(lastrace->flags, F_HITDICE, 3, 0, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DIMWITTED, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6"); addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL); @@ -8737,8 +9001,8 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DIMWITTED, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_WEAK, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, 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); @@ -8873,7 +9137,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 70, NA, ""); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_VEGETABLE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); @@ -8896,7 +9160,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_VEGETABLE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); @@ -8955,7 +9219,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars"); @@ -8975,7 +9239,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d8"); addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars"); @@ -9035,7 +9299,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 60, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_HITDICE, 6, 0, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); @@ -9051,10 +9315,46 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars"); - addrace(R_DOGBLINK, "blink dog", 35, 'd', C_YELLOW, MT_FLESH, RC_ANIMAL); + addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_RARITY, H_VILLAGE, 100, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 80, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 0, 1, 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_SHOULDERS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); + addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SEEINDARK, 1, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 1, NA, "clucks^clucking"); + addrace(R_DOG, "dog", 35, 'd', C_BROWN, MT_FLESH, RC_ANIMAL); + addflag(lastrace->flags, F_RNDHOSTILE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); + addflag(lastrace->flags, F_RARITY, H_VILLAGE, 100, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, 82, NA, NULL); + addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 1, NA, NA, ""); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); + addflag(lastrace->flags, F_MAXATTACKS, 1, 2, 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_SHOULDERS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); + addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); + addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 2, 8, NA, ""); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ENLIGHTENED, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 77, NA, ""); @@ -9072,12 +9372,12 @@ void initrace(void) { addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_BLINK, 2, 2, "pw:1;"); - addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 1, NA, "whines in pain^whining"); - addrace(R_DOGDEATH, "death hound", 40, 'd', C_BLUE, MT_FLESH, RC_ANIMAL); + addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); + addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_NUMAPPEAR, 2, 6, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, ""); @@ -9102,7 +9402,7 @@ void initrace(void) { addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 4, NA, ""); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); @@ -9128,7 +9428,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 85, NA, ""); 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_STARTATT, A_STR, IQ_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9156,7 +9456,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 77, NA, ""); 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_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9185,7 +9485,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_FOREST, 65, NA, ""); 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_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9210,7 +9510,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, ""); 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_STARTATT, A_STR, ST_STRONG, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -9293,7 +9593,7 @@ void initrace(void) { addflag(lastrace->flags, F_CORPSEFLAG, F_SHARP, 1, 4, NULL); addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, ST_VWEAK, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, 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); @@ -9411,7 +9711,7 @@ void initrace(void) { 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_STARTATT, A_STR, ST_MIGHTY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, 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, ""); @@ -9459,7 +9759,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 87, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); @@ -9483,7 +9783,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 63, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 63, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); @@ -9509,7 +9809,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, 78, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 78, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_DEX, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); @@ -9533,7 +9833,7 @@ void initrace(void) { addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL); 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_STARTATT, A_CON, CN_HARDY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ENHANCESMELL, B_TRUE, NA, NA, NULL); @@ -9554,7 +9854,7 @@ void initrace(void) { addflag(lastrace->flags, F_LEVRACE, 5, R_WOLF, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL); - addflag(lastrace->flags, F_STARTATT, A_CON, CN_HARDY, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); @@ -9756,7 +10056,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD); - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_SMART, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -9775,7 +10075,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD); // p for sPirit - addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_SMART, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -9956,7 +10256,7 @@ enum BURDENED isburdened(lifeform_t *lf) { } int ischarmable(lifeform_t *lf) { - if (getiqname(getattr(lf, A_IQ), NULL) <= IQ_VEGETABLE) { + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) <= AT_EXLOW) { reason = E_LOWIQ; return B_FALSE; } @@ -10108,12 +10408,12 @@ int isfriendly(lifeform_t *lf) { } int isgenius(lifeform_t *lf) { - enum IQBRACKET iqb; - iqb = getiqname(getattr(lf, A_IQ), NULL); + enum ATTRBRACKET iqb; + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); if (lfhasflag(lf, F_OMNIPOTENT) || lfhasflag(lf, F_EXTRAINFO) || - iqb >= IQ_GENIUS) { + iqb >= AT_VHIGH) { return B_TRUE; } return B_FALSE; @@ -10158,6 +10458,15 @@ int isingunrange(lifeform_t *lf, cell_t *where) { return B_FALSE; } +// can you try to recruit this lf? +int ishirable(lifeform_t *lf) { + if (!isplayer(lf) && ispeaceful(lf) && lfhasflag(lf, F_JOB)) { + if (lfhasflag(lf, F_HIRABLE)) { + return B_TRUE; + } + } + return B_FALSE; +} // cannot voluntarily move _at all_. int isimmobile(lifeform_t *lf) { @@ -10411,7 +10720,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { // avoid messages when equipping initial obs a->created = B_FALSE; - a->pack = addobpile(a, NOLOC); + a->pack = addobpile(a, NOLOC, NOOB); a->turnsskipped = 0; @@ -10433,8 +10742,6 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { // init flags a->flags = addflagpile(a, NULL); - //addflag(a->flags, F_DEBUG, B_TRUE, NA, NA, NULL); // ooooooooooo - // set race - this will inherit race flags and material a->race = NULL; @@ -10778,7 +11085,7 @@ lifeform_t *makezombie(object_t *o) { addflag(lf->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); killflagsofid(lf->flags, F_ACTIONSPEED); addflag(lf->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL); - lf->baseatt[A_IQ] = rolliq(IQ_MINDLESS); + lf->baseatt[A_IQ] = rollattr(IQ_MINDLESS); lf->att[A_IQ] = lf->baseatt[A_IQ]; // no magic @@ -10863,24 +11170,22 @@ void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o) { if (isplayer(lf) || cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s choke%s on %s!", lfname, isplayer(lf) ? "" : "s", buf); + msg("^%c%s choke%s on %s!", getlfcol(lf, CC_BAD), lfname, isplayer(lf) ? "" : "s", buf); } } else { if (isplayer(lf)) { - msg("%s %ss you!", buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp)); + msg("^b%s %ss you!", buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp)); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s %ss %s!", buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname); + msg("^c%s %ss %s!", getlfcol(lf, CC_BAD), buf, getattackverb(NULL, NULL, damtype, dam,lf->maxhp), lfname); } } } } int areallies(lifeform_t *lf1, lifeform_t *lf2) { -// UNCOMMENT THIS TO GO BACK TO ONLY HAVING MONSTERS -// OF THE SAME BASE RACE COUNTING AS ALLIES. - if (getallegiance(lf1) == getallegiance(lf2)) { + if (getallegiance(lf1) == getallegiance(lf2)) { // same allegience? if (isplayer(lf1) || isplayer(lf2)) { // if one of them is the player return B_TRUE; @@ -10889,6 +11194,10 @@ int areallies(lifeform_t *lf1, lifeform_t *lf2) { return B_TRUE; } } + } else { + if (lf1->race->baseid == lf2->race->baseid) { + return B_TRUE; + } } /* if (getallegiance(lf1) == getallegiance(lf2)) { @@ -10921,6 +11230,31 @@ int askforpayment(lifeform_t *shk, lifeform_t *lf) { return B_FALSE; } +char *assignnpcname(lifeform_t *lf) { + npcname_t *poss,*sel; + int nposs = 0,i; + poss = malloc(numnpcnames * sizeof(npcname_t *)); + + // already got one? + if (lfhasflag(lf, F_NAME)) { + return NULL; + } + // count possibilities + for (i = 0;i < numnpcnames; i++) { + if (npcname[i].valid) { + poss[nposs++] = npcname[i]; + } + } + // get random name + i = rnd(0,nposs); + sel = &npcname[i]; + + // none else can use this name now + sel->valid = B_FALSE; + addflag(lf->flags, F_NAME, NA, NA, NA, sel->name); + return sel->name; +} + // make sure player has at least novice skill in all their start weapons/armour void autoskill(lifeform_t *lf) { skill_t *sk; @@ -10978,7 +11312,7 @@ void autotarget(lifeform_t *lf) { gun = getfirearm(lf); if (!gun) return; - if (!getammo(lf)) return; + if (!getammo(gun)) return; gunrange = getfirearmrange(gun); @@ -11171,6 +11505,110 @@ flag_t *levelabilityready(lifeform_t *lf) { return NULL; } +int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo) { + int amttoload; + int guncapacityleft,guncapacityused; + char gunname[BUFLEN]; + object_t *curammo; + flag_t *f,*ammoflag; + + curammo = gun->contents->first; + getobname(gun, gunname, 1); + + if (curammo) { + guncapacityused = curammo->amt; + } else { + guncapacityused = 0; + } + + ammoflag = hasflag(gun->flags, F_AMMOCAPACITY); + guncapacityleft = ammoflag->val[0] - guncapacityused; + + // is ammo ok? + if (curammo && (ammo->type->id != curammo->type->id)) { + if (lf) { + // unload current ammo first + moveob(curammo, lf->pack, curammo->amt); + if (lf && isplayer(lf)) { + char buf[BUFLEN]; + getobname(curammo, buf, curammo->amt); + msg("You unload %s from your %s.", curammo, noprefix(gunname)); + } + } else { + return B_TRUE; + } + } else { + if (guncapacityleft <= 0) { + if (isplayer(lf)) { + msg("Your %s is already fully loaded.", noprefix(gunname)); + } + return B_TRUE; + } + } + + if (ammo->amt >= guncapacityleft) { + amttoload = guncapacityleft; + } else { + amttoload = ammo->amt; + } + + // load ammo into gun + moveob(ammo, gun->contents, amttoload); + + // take time + if (lf) { + f = hasflag(gun->flags, F_RELOADTURNS); + taketime(lf, getactspeed(lf)*f->val[0]); + + if (isplayer(lf)) { + char buf[BUFLEN]; + getobname(gun->contents->first, buf, gun->contents->first->amt); + msg("You load %s into your %s.", buf, noprefix(gunname)); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s reloads %s.", lfname, gunname); + } + + // update target + autotarget(lf); + } + return B_FALSE; +} + +int loadfirearmfast(lifeform_t *lf) { + object_t *gun,*newammo,*curammo; + gun = getfirearm(lf); + if (!gun) { + if (isplayer(lf)) { + msg("You have no firearm equipped."); + } + return B_TRUE; + } + curammo = getammo(gun); + if (curammo) { + if (isplayer(lf)) { + char buf[BUFLEN]; + getobname(gun, buf, 1); + msg("Your %s is already loaded!", noprefix(buf)); + } + return B_TRUE; + } + + newammo = getrandomammo(lf); + if (newammo) { + loadfirearm(lf, gun, newammo); + } else { + if (isplayer(lf)) { + char buf[BUFLEN]; + getobname(gun, buf, 1); + msg("You have no ammo for your %s.", noprefix(buf)); + } + return B_TRUE; + } + return B_FALSE; +} + void loseconcentration(lifeform_t *lf) { // stop sprinting stopsprinting(lf); @@ -11286,13 +11724,21 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml addflag(lf->flags, F_KILLEDBYPLAYER, B_TRUE, NA, NA, NULL); } } else { - // effects based on damage - if ((damtype == DT_COLD) && lfhasflag(lf, F_COLDBLOOD)) { - // slow them - addtempflag(lf->flags, F_SLOWMOVE, 5, NA, NA, NULL, 10); - } else if ((damtype == DT_POISONGAS) && (amt > 0)) { - if (!skillcheck(lf, SC_POISON, 25, 0)) { - poison(lf, rnd(5,10), P_GAS, 2, "poison gas"); + // effects based on damage type + if (damtype == DT_COLD) { + if (lfhasflag(lf, F_COLDBLOOD)) { + // slow them + addtempflag(lf->flags, F_SLOWMOVE, 5, NA, NA, NULL, 10); + } + // catch a cold? + if (!skillcheck(lf, SC_CON, (amt/2) + getexposedlimbs(lf), 0)) { + poison(lf, 20+(amt*3), P_COLD, 0, "the cold"); + } + } else if (damtype == DT_POISONGAS) { + if (amt > 0) { + if (!skillcheck(lf, SC_POISON, 25, 0)) { + poison(lf, rnd(5,10), P_GAS, 2, "poison gas"); + } } } } @@ -11320,7 +11766,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml if (lf->race->id == R_DREAMFUNGUS) { if (cansee(player, lf)) { animradialorth(lf->cell, 4, '}', C_MAGENTA); - msg("%s releases a cloud of purple spores!", lfname); + msg("^w%s releases a cloud of purple spores!", lfname); drawscreen(); } spellcloud(lf->cell, 3, '\0', C_MAGENTA, OT_S_SLEEP, 8, B_TRUE); @@ -11358,10 +11804,10 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml } } } + // you wake up if you were hit! killflagsofid(lf->flags, F_ASLEEP); - // automatic onbleed abilities? if (postbleed && !prebleed) { f = lfhasflag(lf, F_BLEEDABIL); @@ -11372,6 +11818,37 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml killflag(notime); } } + + // elemental effects on held objects + if (damtype == DT_FIRE) { + object_t *o, *nexto; + // fire: dam*10 chance of burning each object which is vulnerable to fire + for (o = lf->pack->first ; o ; o = nexto) { + nexto = o->next; + if (isvulnto(o->flags, DT_FIRE) && pctchance(amt*10)) { + int newdam; + // object takes 1/4 of damage + newdam = pctof(25, amt); + limit(&newdam, 1, NA); + takedamage(o, newdam, DT_FIRE); + } + } + } else if (damtype == DT_COLD) { + object_t *o, *nexto; + // cold: dam*10 chance of shattering potions, or damaging other things. + for (o = lf->pack->first ; o ; o = nexto) { + nexto = o->next; + //if (isvulnto(o->flags, DT_COLD) && pctchance(amt*10)) { + if (isvulnto(o->flags, DT_COLD)) { + int newdam; + // object takes 1/4 of damage + newdam = pctof(25, amt); + limit(&newdam, 1, NA); + takedamage(o, newdam, DT_COLD); + } + } + } + } // update screen @@ -11572,6 +12049,9 @@ int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o) { case A_STR: reason = E_LOWSTR; break; + case A_WIS: + reason = E_LOWWIS; + break; case A_NONE: break; } @@ -11626,6 +12106,9 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { case A_IQ: strcpy(adverb, "smarter"); break; + case A_WIS: + strcpy(adverb, "wiser"); + break; default: break; } @@ -11644,13 +12127,16 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { strcpy(adverb, "sluggish"); break; case A_IQ: + strcpy(adverb, "stupid"); + break; + case A_WIS: strcpy(adverb, "foolish"); break; default: break; } } - msg("%s %s %s!", lfname, verb, adverb); + msg("^%c%s %s %s!", getlfcol(lf, (amt > 0) ? CC_GOOD : CC_BAD), lfname, verb, adverb); more(); } return B_FALSE; @@ -11659,7 +12145,6 @@ int modattr(lifeform_t *lf, enum ATTRIB attr, int amt) { void modhunger(lifeform_t *lf, int amt) { flag_t *f; int prehlev, posthlev; - int multiplier; f = hasflag(lf->flags, F_HUNGER); if (!f) { return; @@ -11667,9 +12152,17 @@ void modhunger(lifeform_t *lf, int amt) { // modify for effects if (amt > 0) { - sumflags(lf->flags, F_FASTMETAB, &multiplier, NULL, NULL); + int multiplier = 0; + int tempmult; + sumflags(lf->flags, F_FASTMETAB, &tempmult, NULL, NULL); + multiplier += tempmult; + sumflags(lf->flags, F_SLOWMETAB, &tempmult, NULL, NULL); + multiplier -= tempmult; + if (multiplier > 0) { amt *= multiplier; + } else if (multiplier < 0) { + amt /= abs(multiplier); } } @@ -11679,7 +12172,7 @@ void modhunger(lifeform_t *lf, int amt) { if (posthlev == H_STARVED) { if (isplayer(lf)) { - msg("You collapse from starvation."); + msg("^BYou collapse from starvation."); } setlastdam(lf, "starvation"); lf->hp = 0; @@ -11711,7 +12204,7 @@ void modhunger(lifeform_t *lf, int amt) { if (isplayer(lf)) { gethungername(posthlev, buf); - msg("You are %s%s%s%c", + msg("^wYou are %s%s%s%c", ((amt < 0) && (posthlev > H_NONE)) ? "still " : "", needfeeling ? "feeling " : "", buf, @@ -11786,9 +12279,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha // listen check difficulty is based on sound distance vs max hearing distance if (nt == NC_SPEECH) { - if (isplayer(l)) { - dblog("xxx"); - } // you always hear it, as long as you're in range difficulty = 0; } else { @@ -11823,6 +12313,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha punc = text[strlen(text)-1]; strncpy(textnopunc, text, strlen(text)-1); + textnopunc[strlen(text)] = '\0'; dist = getcelldist(l->cell, c); @@ -11896,7 +12387,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha if (f->val[2] == NA) { // ie asleep rather than 'resting' // wake up! if (isplayer(l)) { - msg("A nearby noise awakens you!"); + msg("^wA nearby noise awakens you!"); rv = B_TRUE; } killflag(f); @@ -11911,7 +12402,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha strcpy(wakenoise, text); wakenoise[strlen(wakenoise)-1] = '\0'; // omit punctuation //msg("A nearby noise awakens you!"); - msg("The sound of %s awakens you!", wakenoise); + msg("^wThe sound of %s awakens you!", wakenoise); rv = B_TRUE; } killflag(f); @@ -11942,8 +12433,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha // give initial equiment / skills to a lifeform void outfitlf(lifeform_t *lf) { //int db = B_FALSE; - givestartobs(lf, lf->flags); givestartskills(lf, lf->flags); + givestartobs(lf, NULL, lf->flags); autoskill(lf); // weild/wear stuff @@ -11951,6 +12442,14 @@ void outfitlf(lifeform_t *lf) { } +// make 'lf' into a pet/ally of 'owner' +void petify(lifeform_t *lf, lifeform_t *owner) { + makefriendly(lf, PERMENANT); + addflag(lf->flags, F_PETOF, owner->id, owner->cell->x, owner->cell->y, NULL); + killflagsofid(lf->flags, F_STAYINROOM); +} + + int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground) { char obname[BUFLEN]; object_t *o; @@ -12045,9 +12544,6 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground) { taketime(lf, SPEED_PICKUP); // TODO: update burdened status - - // use ammo rightaway if required. - testammo(lf, o); } else { // tell the player why! if (isplayer(lf)) { @@ -12080,6 +12576,13 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground) { void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat) { flag_t *f; int found = B_FALSE; + enum POISONSEVERITY psev; + + // are you immune to disease? + psev = getpoisonseverity(ptype); + if ((psev == PS_DISEASE) && hasflag(lf->flags, F_DISEASEIMMUNE)) { + return; + } // adjust time based on first aid skill howlong -= getskill(lf, SK_FIRSTAID); @@ -12095,11 +12598,11 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char // announce - announceflaggain won't be called // since this isn't a new flag. if (isplayer(lf)) { - msg("You feel more sick."); + msg("^bYou feel more sick."); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s looks even more sick.", lfname); + msg("^%c%s looks even more sick.", getlfcol(lf, CC_BAD), lfname); } found = B_TRUE; @@ -12279,6 +12782,67 @@ int readytotrain(lifeform_t *lf) { return B_FALSE; } +int recruit(lifeform_t *lf) { + int rv = B_FALSE; + if (!lfhasflag(lf, F_NOHIRE) && + (lfhasflag(lf, F_HIREPRICE) || skillcheck(player, A_CHA, 20 + ((gethitdice(player) - gethitdice(lf))*2), 0)) ) { + int dohire = B_FALSE; + int askingprice = 0; + char lfname[BUFLEN]; + char buf[BUFLEN]; + flag_t *f; + getlfname(lf, lfname); + // they will consider it - now negotiate a price + f = lfhasflag(lf, F_HIREPRICE); + if (f) { + askingprice = f->val[0]; + } else { + askingprice = rnd(gethitdice(lf)*50, gethitdice(lf)*100 ); + addflag(lf->flags, F_HIREPRICE, askingprice, NA, NA, NULL); + } + + // modify by charisma + askingprice = pctof(100 + getstatmod(player, A_CHA), askingprice); + + sayphrase(lf, SP_RECRUIT_ASKPRICE, SV_TALK, askingprice, NULL); + more(); + + if (askingprice > countmoney(player)) { + } else { + char ch; + sprintf(buf, "Pay $%d to hire %s", askingprice, lfname); + ch = askchar(buf, "yn","n", B_TRUE); + if (ch == 'y') { + dohire = B_TRUE; + } + } + + if (dohire) { + char *p = NULL; + petify(lf, player); + + // give them a name + if (getjob(lf)) { + p = assignnpcname(lf); + } + sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); + } else { + if (askingprice > countmoney(player)) { + sayphrase(lf, SP_RECRUIT_DECLINE_CANTPAY, SV_TALK, askingprice, NULL); + } else { + sayphrase(lf, SP_RECRUIT_DECLINE_WONTPAY, SV_TALK, askingprice, NULL); + } + } + } else { + sayphrase(lf, SP_RECRUIT_DECLINE, SV_TALK, NA, NULL); + rv = B_TRUE; + if (!lfhasflag(lf, F_NOHIRE)) { + addflag(lf->flags, F_NOHIRE, B_TRUE, NA, NA, NULL); + } + } + return rv; +} + void refreshlevelabilities(lifeform_t *lf) { flag_t *f; for (f = lf->flags->first ; f ; f = f->next) { @@ -12346,14 +12910,9 @@ void relinklf(lifeform_t *src, map_t *dst) { } // strat resting... -void startresting(lifeform_t *lf, int willtrain) { +int startresting(lifeform_t *lf, int willtrain) { int traincounter; - if (isplayer(lf)) { - statdirty = B_TRUE; - needredraw = B_TRUE; - } - if (willtrain) { traincounter = 50; traincounter = modifybystat(traincounter, player, A_IQ); @@ -12361,17 +12920,22 @@ void startresting(lifeform_t *lf, int willtrain) { traincounter = NA; } - if (isplayer(lf)) { - lf->turnsskipped = 0; - } - // stop hiding killflagsofid(lf->flags, F_HIDING); if (willtrain) { addflag(lf->flags, F_TRAINING, B_TRUE, NA, traincounter, NULL); } else { - addflag(lf->flags, F_ASLEEP, B_TRUE, NA, B_TRUE, NULL); + if (gotosleep(lf, B_TRUE)) { + // failed + return B_TRUE; + } + } + + if (isplayer(lf)) { + statdirty = B_TRUE; + needredraw = B_TRUE; + lf->turnsskipped = 0; } // stop movement for all allies @@ -12391,181 +12955,38 @@ void startresting(lifeform_t *lf, int willtrain) { drawmsg(); drawcursor(); } + return B_FALSE; } -int rolliq(enum IQBRACKET bracket) { +int rollattr(enum ATTRBRACKET bracket) { int roll = 0; switch (bracket) { - case IQ_MINDLESS: - roll = 0; - break; - case IQ_VEGETABLE: - roll = rnd(1,3); - break; - case IQ_ANIMAL: - roll = rnd(4,6); - break; - case IQ_DIMWITTED: - roll = rnd(4,6); - break; - case IQ_DOPEY: - roll = rnd(7,9); - break; - case IQ_AVERAGE: - roll = rnd(10,12); - break; - case IQ_SMART: - roll = rnd(13,15); - break; - case IQ_ENLIGHTENED: - roll = rnd(16,17); - break; - case IQ_GENIUS: - roll = 18; - break; - default: - roll = rolldie(3,6); - break; - } - return roll; -} - -int rollcha(enum CHABRACKET bracket) { - int roll = 0; - switch (bracket) { - case CH_HIDEOUS: + case AT_EXLOW: roll = rnd(0,2); break; - case CH_REPULSIVE: + case AT_VLOW: roll = rnd(3, 6); break; - case CH_UGLY: + case AT_LOW: roll = rnd(7, 8); break; - case CH_UNATTRACTIVE: + case AT_LTAVERAGE: roll = rnd(9, 10); break; - case CH_AVERAGE: + case AT_AVERAGE: roll = rnd(11, 12); break; - case CH_ATTRACTIVE: + case AT_GTAVERAGE: roll = rnd(13, 14); break; - case CH_ALLURING: + case AT_HIGH: roll = rnd(15, 16); break; - case CH_BEAUTIFUL: + case AT_VHIGH: roll = rnd(17, 18); break; - default: - roll = rolldie(3,6); - break; - } - return roll; -} -int rollcon(enum CONBRACKET bracket) { - int roll = 0; - switch (bracket) { - case CN_FRAIL: - roll = rnd(1,2); - break; - case CN_SICKLY: - roll = rnd(3,4); - break; - case CN_UNHEALTHY: - roll = rnd(5,6); - break; - case CN_UNFIT: - roll = rnd(7,8); - break; - case CN_AVERAGE: - roll = rnd(9,11); - break; - case CN_HEALTHY: - roll = rnd(12,14); - break; - case CN_FIT: - roll = rnd(15,16); - break; - case CN_HARDY: - roll = rnd(17,18); - break; - default: - roll = rolldie(3,6); - break; - } - return roll; -} - -int rolldex(enum DEXBRACKET bracket) { - int roll = 0; - switch (bracket) { - case DX_INCOMPETENT: - roll = 0; - break; - case DX_OAFISH: - roll = rnd(1,2); - break; - case DX_INEPT: - roll = rnd(3,4); - break; - case DX_CLUMSY: - roll = rnd(5,6); - break; - case DX_AWKWARD: - roll = rnd(7,8); - break; - case DX_AVERAGE: - roll = 9; - break; - case DX_DEXTROUS: - roll = rnd(10,11); - break; - case DX_NIMBLE: - roll = rnd(12,13); - break; - case DX_AGILE: - roll = rnd(14,15); - break; - case DX_SWIFT: - roll = rnd(16,17); - break; - case DX_SUPERSONIC: - roll = 18; - break; - default: - roll = rolldie(3,6); - break; - } - return roll; -} - -int rollstr(enum STRBRACKET bracket) { - int roll = 0; - switch (bracket) { - case ST_HELPLESS: - roll = 0; - break; - case ST_FEEBLE: - roll = rnd(1,3); - break; - case ST_VWEAK: - roll = rnd(4,6); - break; - case ST_WEAK: - roll = rnd(7,9); - break; - case ST_AVERAGE: - roll = rnd(10,12); - break; - case ST_STRONG: - roll = rnd(13,15); - break; - case ST_MIGHTY: - roll = rnd(16,17); - break; - case ST_TITANIC: - roll = 18; + case AT_EXHIGH: + roll = rnd(19, 20); break; default: roll = rolldie(3,6); @@ -12576,7 +12997,7 @@ int rollstr(enum STRBRACKET bracket) { int rollstat(lifeform_t *lf, enum ATTRIB attr) { flag_t *f; - int bracket; + enum ATTRBRACKET bracket; f = hasflagval(lf->flags, F_STARTATT, attr, NA, NA, NULL); if (f) { @@ -12602,41 +13023,10 @@ int rollstat(lifeform_t *lf, enum ATTRIB attr) { } } else { - switch (attr) { - case A_STR: - bracket = ST_RANDOM; break; - case A_CHA: - bracket = CH_RANDOM; break; - case A_CON: - bracket = CN_RANDOM; break; - case A_DEX: - bracket = DX_RANDOM; break; - case A_IQ: - bracket = IQ_RANDOM; break; - default: - return B_TRUE; - } + bracket = AT_RANDOM; } - switch (attr) { - case A_CHA: - lf->att[attr] = rollcha(bracket); - break; - case A_CON: - lf->att[attr] = rollcon(bracket); - break; - case A_DEX: - lf->att[attr] = rolldex(bracket); - break; - case A_IQ: - lf->att[attr] = rolliq(bracket); - break; - case A_STR: - lf->att[attr] = rollstr(bracket); - break; - default: - return B_TRUE; - } + lf->att[attr] = rollattr(bracket); return B_FALSE; } @@ -12685,6 +13075,86 @@ int say(lifeform_t *lf, char *text, int volume) { return noise(lf->cell, lf, NC_SPEECH, volume, hearbuf, seebuf); } +// volume = -1 means "auto" +int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text) { + int i,rv = B_FALSE; + char buf[BUFLEN]; + switch (what) { + case SP_DRUNK: + // random blurred speech + strcpy(buf, ""); + for (i = 0; i < rnd(15,30); i++) { + if ((i != 0) && onein(4)) { + strcat(buf, " "); + } else { + char let[2]; + let[0] = rnd('a', 'z'); + let[1] = '\0'; + strcat(buf, let); + } + } + if (volume >= SV_SHOUT) { + strcat(buf, "!"); + } else { + strcat(buf, "."); + } + say(lf, buf, volume); + break; + case SP_PAYWARN: + switch (rnd(1,3)) { + case 1: sprintf(buf, "Hey! Where do you think you're going?"); break; + case 2: sprintf(buf, "AHEM!"); break; + case 3: sprintf(buf, "I hope you are going to pay for %s!", text); break; + } + rv = say(lf, buf, volume); + break; + case SP_PAYTHREAT: + switch (rnd(1,3)) { + case 1: rv = say(lf, "Stop thief!", volume); break; + case 2: rv = say(lf, "GUARDS!", volume); break; + case 3: rv = say(lf, "I've been robbed!", volume); break; + } + break; + case SP_RECRUIT_ACCEPT: + if (text) { + sprintf(buf, "I will join you - my name is %s.", text); + } else { + sprintf(buf, "I will join you."); + } + rv = say(lf, buf, volume); + break; + case SP_RECRUIT_ASKPRICE: + sprintf(buf, "My services will cost you $%d.",val0); + rv = say(lf, buf, volume); + break; + case SP_RECRUIT_DECLINE: + rv = say(lf, "No, I regretfully decline your offer.", volume); + break; + case SP_RECRUIT_DECLINE_CANTPAY: + rv = say(lf, "...which I see you cannot afford.", volume); + break; + case SP_RECRUIT_DECLINE_WONTPAY: + rv = say(lf, "Perhaps another time, then.", volume); + break; + case SP_SORRY: + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= AT_HIGH) { + switch (rnd(0,1)) { + case 0: rv = say(lf, "My sincerest condolences!", volume); break; + case 1: rv = say(lf, "My mistake, I apologise.", volume); break; + } + } else { + switch (rnd(0,1)) { + case 0: rv = say(lf, "Whoops, sorry!", volume); break; + case 1: rv = say(lf, "Sorry 'bout that!", volume); break; + } + } + break; + default: + break; + } + return rv; +} + // returns TRUE if something happened int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) { int nfailures = 0; @@ -12699,7 +13169,7 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) { return B_FALSE; } // not intelligent enough to be scared? - if (getiqname(getattr(lf, A_IQ), NULL) <= IQ_VEGETABLE) { + if (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) <= IQ_MINDLESS) { return B_FALSE; } @@ -12722,6 +13192,9 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) { } } + + // modify by charisma: -3 to 3 + scarerbonus += (getstatmod(lf, A_CHA) / 15); // three checks nfailures = 0; @@ -12751,57 +13224,6 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) { } return B_FALSE; } - - -int setammo(lifeform_t *lf, object_t *ammo) { - object_t *gun; - object_t *o; - char gunname[BUFLEN],ammoname[BUFLEN]; - - if (ammo) { - getobname(ammo, ammoname, ammo->amt); - } - - gun = getfirearm(lf); - if (!gun) { - if (isplayer(lf)) { - msg("You have no firearm weilded!"); - } - return B_TRUE; - } - getobname(gun, gunname, gun->amt); - - - if (ammo && !isammofor(ammo->type, gun)) { - if (isplayer(lf)) { - msg("You can't load %s with %s!", gunname, ammoname); - } - return B_TRUE; - } - - - // remove current ammo - for (o = lf->pack->first ; o ; o = o->next) { - flag_t *f; - f = hasflag(o->flags, F_CURAMMO); - if (f) { - killflag(f); - } - } - - - if (ammo) { - addflag(ammo->flags, F_CURAMMO, B_TRUE, NA, NA, NULL); - if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { - msg("Using %s as ammo for %s.", ammoname, gunname); - } - } else { - if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { - msg("No ammo equipped for %s.", gunname); - } - } - return B_FALSE; -} void setattr(lifeform_t *lf, enum ATTRIB attr, int val) { lf->att[attr] = val; @@ -12810,6 +13232,17 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val) { } } +void setfollowdistance(lifeform_t *lf, int min, int max) { + flag_t *f; + f = lfhasflag(lf, F_FOLLOWRANGE); + if (f) { + f->val[0] = min; + f->val[1] = max; + } else { + addflag(lf->flags, F_FOLLOWRANGE, min, max, NA, NULL); + } +} + void setguntarget(lifeform_t *lf, lifeform_t *targ) { flag_t *f; f = hasflag(lf->flags, F_GUNTARGET); @@ -12875,10 +13308,10 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { // reverting to original form.... if (!isdead(lf)) { if (isplayer(lf)) { - msg("You revert to your original form!"); + msg("^wYou revert to your original form!"); } else if (cansee(player, lf)) { getlfname(lf, buf); - msg("The %s transforms back to its original form!", newrace->name); + msg("^wThe %s transforms back to its original form!", newrace->name); } } @@ -12890,10 +13323,10 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { killflagsofid(lf->flags, F_POLYMORPHED); } else { if (isplayer(lf)) { - msg("You transform into %s %s!", isvowel(newrace->name[0]) ? "an" : "a", newrace->name); + msg("^wYou transform into %s %s!", isvowel(newrace->name[0]) ? "an" : "a", newrace->name); } else if (cansee(player, lf)) { getlfname(lf, buf); - msg("%s transforms into %s %s!", buf, isvowel(newrace->name[0]) ? "an" : "a", newrace->name); + msg("^w%s transforms into %s %s!", buf, isvowel(newrace->name[0]) ? "an" : "a", newrace->name); } } } @@ -12922,6 +13355,17 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { copyflags(lf->flags, lf->race->flags, FROMRACE); // don't want certain race only flags... killflagsofid(lf->flags, F_RARITY); + + // certain other flags are rnadom + for (f = lf->flags->first ; f ; f = nextf) { + nextf = f->next; + if (f->id == F_RNDHOSTILE) { + if (pctchance(f->val[0])) { + addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + } + killflag(f); + } + } // generate stats for (i = 0; i < MAXATTS; i++) { @@ -13052,6 +13496,7 @@ void initskills(void) { addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.", 50); addskill(SK_TECHUSAGE, "Technology", "Determines your comprehension of modern technological items.", 0); // untrain addskill(SK_THIEVERY, "Thievery", "Your ability to pick pockets and steal items.", 50); + addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50); addskill(SK_TRACKING, "Tracking", "Allows you to track enemies by their footprints.", 0); // untrain addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.", 25); addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50); @@ -13074,6 +13519,7 @@ void initskills(void) { addskill(SK_SS_AIR, "Air Magic", "Boosts casting of spells from this school.", 50); addskill(SK_SS_DEATH, "Necromancy", "Boosts casting of spells from this school.", 50); addskill(SK_SS_DIVINATION, "Divination", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_ENCHANTMENT, "Enchantment", "Boosts casting of spells from this school.", 50); addskill(SK_SS_FIRE, "Fire Magic", "Boosts casting of spells from this school.", 50); addskill(SK_SS_COLD, "Cold Magic", "Boosts casting of spells from this school.", 50); addskill(SK_SS_GRAVITY, "Gravitation Magic", "Boosts casting of spells from this school.", 50); @@ -13125,7 +13571,7 @@ int setlfmaterial(lifeform_t *lf, enum MATERIAL id) { // announce if (gamemode == GM_GAMESTARTED) { if (isplayer(lf)) { - msg("Your body %s to %s%c", (id == lf->race->material->id) ? "reverts" : "turns", lf->material->name, + msg("^wYour body %s to %s%c", (id == lf->race->material->id) ? "reverts" : "turns", lf->material->name, (id == lf->race->material->id) ? '.' : '!' ); } else if (cansee(player, lf)) { char lfname[BUFLEN]; @@ -13142,6 +13588,7 @@ int setlfmaterial(lifeform_t *lf, enum MATERIAL id) { int shoot(lifeform_t *lf) { object_t *gun,*ammo; lifeform_t *targ; + flag_t *f; int firespeed; reason = E_OK; @@ -13157,7 +13604,7 @@ int shoot(lifeform_t *lf) { return B_TRUE; } // get ammo - ammo = getammo(lf); + ammo = getammo(gun); if (!ammo) { reason = E_NOAMMO; return B_TRUE; @@ -13166,7 +13613,8 @@ int shoot(lifeform_t *lf) { // get fire speed firespeed = getfirearmspeed(gun); - taketime(lf, getattackspeed(lf)); + f = hasflag(gun->flags, F_FIRETURNS); + taketime(lf, getactspeed(lf) * f->val[0]); fireat(lf, ammo, 1, targ->cell, firespeed, gun); return B_FALSE; @@ -13204,15 +13652,24 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r case SC_DEX: attrib = getattr(lf, A_DEX); break; + case SC_IQ: + attrib = getattr(lf, A_IQ); + break; case SC_CHA: attrib = getattr(lf, A_CHA); break; + case SC_WIS: + attrib = getattr(lf, A_WIS); + break; + /////////////// case SC_OPENLOCKS: attrib = getattr(lf, A_DEX); break; - case SC_IQ: case SC_WILL: - attrib = getattr(lf, A_IQ); + attrib = getattr(lf, A_WIS); + break; + case SC_TUMBLE: + attrib = getskill(lf, SK_ATHLETICS); break; case SC_MORALE: // based on level/hitdice and size. attrib = (lf->hp / 4); @@ -13253,7 +13710,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r } break; case SC_RESISTMAG: - attrib = (getattr(lf, A_CON)/4) + (getattr(lf, A_IQ)/4) + getmr(lf); + attrib = (getattr(lf, A_CON)/4) + (getattr(lf, A_WIS)/4) + getmr(lf); break; case SC_SEARCH: attrib = (getskill(lf, SK_SPOTHIDDEN)*4); @@ -13267,7 +13724,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r } // level modifier - levmod = (lf->level / 3); + levmod = (gethitdice(lf) / 3); // other modifiers if (ct == SC_CLIMB) { @@ -13301,6 +13758,9 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r othermod = 0; break; } + } else if (ct == SC_MORALE) { + // ie. -5 to 5 + othermod += (getstatmod(lf, A_WIS) / 10); } else if (ct == SC_OPENLOCKS) { enum SKILLLEVEL slev; slev = getskill(lf, SK_LOCKPICKING); @@ -13339,6 +13799,9 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r } else if (ct == SC_WILL) { // level counts for more levmod *= 2; + } else if (ct == SC_TUMBLE) { + // ie. -3 to 3 + othermod += (getstatmod(lf, A_DEX) / 15); } @@ -13666,7 +14129,7 @@ int stone(lifeform_t *lf) { addflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); if (cansee(player, lf)) { - msg("%s %s to stone!", lfname, isplayer(lf) ? "turn" : "turns"); + msg("^%c%s %s to stone!", getlfcol(lf, CC_VBAD), lfname, isplayer(lf) ? "turn" : "turns"); } setlastdam(lf, "petrification"); die(lf); @@ -13767,23 +14230,6 @@ lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, int rand return newlf; } -// if this object is ammo, and we are using a gun -// with no ammo, then equip it. -int testammo(lifeform_t *lf, object_t *o) { - object_t *gun; - gun = getfirearm(lf); - if (gun) { - if (isammofor(o->type, gun)) { - object_t *curammo; - curammo = getammo(lf); - if (!curammo) { - setammo(lf, o); - return B_TRUE; - } - } - } - return B_FALSE; -} int takeoff(lifeform_t *lf, object_t *o) { flag_t *f; @@ -14109,12 +14555,12 @@ void turneffectslf(lifeform_t *lf) { // suffocate? if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { if (isplayer(lf)) { - msg("You are suffocating without water to breath!"); + msg("^BYou are suffocating without water to breath!"); } else if (cansee(player, lf)) { int dam; char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s is suffocating!", lfname); + msg("^%c%s is suffocating!", getlfcol(lf, CC_VBAD), lfname); dam = lf->maxhp / 3; limit(&dam, 1, NA); losehp(lf, dam, DT_DIRECT, NULL, "suffocation"); @@ -14122,6 +14568,28 @@ void turneffectslf(lifeform_t *lf) { } } + // float up into space? + if (lf->cell->map->region->rtype->id == RG_WORLDMAP) { + if (lfhasflag(lf, F_LEVITATING)) { + if (isplayer(lf)) { + msg("You float up into the sky!"); + msg("You float up through the atmosphere."); + } else if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s floats up into the sky!", lfname); + } + + if (isplayer(lf)) { + lf->hp = 0; + lf->lastdamtype = DT_DIRECT; + setlastdam(lf, "high altitude suffocation"); + } else { + killlf(lf); + } + } + } + // get more hungry modhunger(lf, 1); @@ -14161,7 +14629,7 @@ void turneffectslf(lifeform_t *lf) { moveob(o, c->obpile, o->amt); if (isplayer(lf)) { getobname(o, buf, o->amt); - msg("Your %s flies out of your hands!",noprefix(buf), (o->amt == 1) ? "flies" : "fly"); + msg("^wYour %s flies out of your hands!",noprefix(buf), (o->amt == 1) ? "flies" : "fly"); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getobname(o, buf, o->amt); @@ -14235,7 +14703,7 @@ void turneffectslf(lifeform_t *lf) { f = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL); if (f) killflag(f); // drain life - if (isplayer(lf)) msg("Without your corpse, you feel yourself fading into nothingness."); + if (isplayer(lf)) msg("^BWithout your corpse, you feel yourself fading into nothingness."); losehp(lf, 2, DT_DIRECT, NULL, "fading into nothingness"); } } @@ -14295,7 +14763,7 @@ void turneffectslf(lifeform_t *lf) { if (isplayer(lf)) { char lname[BUFLEN]; getlfname(l, lname); - msg("You spot %s!", lname); + msg("^wYou spot %s!", lname); } else if (isplayer(l) && cansee(l, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); @@ -14328,7 +14796,7 @@ void turneffectslf(lifeform_t *lf) { char obname[BUFLEN]; // reveal it getobname(o, obname, o->amt); - msg("You notice %s!",obname); + msg("^wYou notice %s!",obname); killflag(f); needredraw = B_TRUE; drawscreen(); @@ -14389,11 +14857,11 @@ void turneffectslf(lifeform_t *lf) { asleep = hasflag(lf->flags, F_ASLEEP); if (!asleep) { if (isplayer(lf)) { - msg("You %s violently.", getpoisondamverb(f->val[0])); + msg("^bYou %s violently.", getpoisondamverb(f->val[0])); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s %ss violently.", lfname, getpoisondamverb(f->val[0])); + msg("^%c%s %ss violently.",getlfcol(lf, CC_BAD), lfname, getpoisondamverb(f->val[0])); } taketime(lf, getactspeed(lf)); } @@ -14414,11 +14882,11 @@ void turneffectslf(lifeform_t *lf) { if (rnd(1,100) <= 10) { object_t *wep; if (isplayer(lf)) { - msg("You shiver uncontrollably."); + msg("^bYou shiver uncontrollably."); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s shivers.", lfname); + msg("^%c%s shivers.", getlfcol(lf, CC_BAD), lfname); } wep = getweapon(lf); if (wep) { @@ -14438,11 +14906,11 @@ void turneffectslf(lifeform_t *lf) { // chance of being delayed if (onein(4)) { if (isplayer(lf)) { - msg("You %s!", rnd(0,1) ? "retch" : "gag"); + msg("^bYou %s!", rnd(0,1) ? "retch" : "gag"); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s %s.", lfname, rnd(0,1) ? "retches" : "gags"); + msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags"); } taketime(lf,getactspeed(lf)); @@ -14456,11 +14924,11 @@ void turneffectslf(lifeform_t *lf) { losehp(lf, 1, DT_MELT, NULL, "melting"); addob(lf->cell->obpile, "small puddle of water"); if (isplayer(lf)) { - msg("You are melting!"); + msg("^BYou are melting!"); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); - msg("%s melts a little.",lfname); + msg("^b%s melts a little.",getlfcol(lf, CC_BAD), lfname); } } } @@ -14479,7 +14947,7 @@ void turneffectslf(lifeform_t *lf) { getobname(o, obname, o->amt); if (!skillcheck(lf, SC_CON, f->val[0] * o->amt, 0)) { if (isplayer(lf)) { - msg("You cough on %s.", obname); + msg("^wYou cough on %s.", obname); } else if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf, lfname); @@ -14548,6 +15016,11 @@ void turneffectslf(lifeform_t *lf) { } } + if ((f->id == F_FEIGNINGDEATH) && !isprone(lf)) { + killflag(f); + continue; + } + if (f->id == F_ATTACHEDTO) { lifeform_t *lf2; lf2 = findlf(NULL, f->val[0]); @@ -14690,7 +15163,7 @@ int touch(lifeform_t *lf, object_t *o) { gloves = getequippedob(lf->pack, BP_HANDS); if (!gloves) { if (isplayer(lf)) { - msg("The %s burn%s you as you touch %s!",noprefix(obname), + msg("^bThe %s burn%s you as you touch %s!",noprefix(obname), (o->amt == 1) ? "s" : "", (o->amt == 1) ? "it" : "them" ); o->blessknown = B_TRUE; @@ -14717,7 +15190,7 @@ int touch(lifeform_t *lf, object_t *o) { gloves = getequippedob(lf->pack, BP_HANDS); if (!gloves) { if (isplayer(lf)) { - msg("Ow! You cut your finger on %s.", obname); + msg("^bOw! You cut your finger on %s.", obname); } sprintf(buf, "touching %s", obname); @@ -14742,7 +15215,7 @@ int touch(lifeform_t *lf, object_t *o) { } else { // otherwise YOU get damaged. if (isplayer(lf)) { - msg("Ow! You burn your hands on %s.",obname); + msg("^bOw! You burn your hands on %s.",obname); } else if (cansee(player, lf)) { msg("%s burns itself on %s.",lfname, obname); } @@ -14893,6 +15366,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { lifeform_t *adjally[8]; int nadjallies = 0; int falling = B_FALSE; + int madenewmap = B_FALSE; region_t *newregion = NULL; // need up update 'dlev:' @@ -15027,6 +15501,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { */ // at this point, stairs should have a destination newcell = getstairdestination(o); + madenewmap = B_TRUE; } } } @@ -15107,6 +15582,12 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { return B_TRUE; } + if (falling && (dir == D_DOWN) && madenewmap && (newcell->map->region->rtype->id == RG_PIT)) { + // you just dug downwards and made a big hole, so you + // didn't actually fall. + falling = B_FALSE; + } + if (falling) { if (dir == D_DOWN) { if (hasobwithflagval(lf->cell->obpile, F_PIT, D_DOWN, NA, NA, NULL)) { @@ -15121,9 +15602,9 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { } else { int howfar; if (isplayer(lf)) { - msg("You slam into the ground!"); + msg("^bYou slam into the ground!"); } else if (cansee(player, lf)){ - msg("%s slams into the ground!", lfname); + msg("^%c%s slams into the ground!", getlfcol(lf, CC_BAD), lfname); } // how far did you fall? sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL); @@ -15134,8 +15615,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { // fall over fall(lf, NULL, B_FALSE); } - } else { - // TODO: if you are outside, DIE! + } else if (dir == D_UP) { if (hasobwithflagval(lf->cell->obpile, F_PIT, D_UP, NA, NA, NULL)) { flag_t *ff; // inc fall distance @@ -15145,12 +15625,12 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { } else { addflag(lf->flags, F_FALLDISTANCE, 1, NA, NA, NULL); } - } else { + } else if (newcell->map->region->rtype->id != RG_WORLDMAP) { int howfar; if (isplayer(lf)) { - msg("You slam into the roof!"); + msg("^bYou slam into the roof!"); } else if (cansee(player, lf)){ - msg("%s slams into the roof!", lfname); + msg("^%c%s slams into the roof!",getlfcol(lf, CC_BAD), lfname); } // how far did you fall? sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL); @@ -15179,6 +15659,11 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) { int useringofmiracles(lifeform_t *lf, int charges) { object_t *o; char lfname[BUFLEN]; + + if (lf->lastdamtype == DT_DIRECT) { + return B_FALSE; + } + getlfname(lf, lfname); for (o = lf->pack->first ; o ; o = o->next) { if ( (o->type->id == OT_RING_MIRACLES) && @@ -15221,7 +15706,21 @@ int validateraces(void) { 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_DEMON) { + addflag(lastrace->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); + } else if (r->raceclass->id == RC_MAGIC) { + addflag(lastrace->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); + } else if (r->raceclass->id == RC_PLANT) { + addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_DTRESIST, DT_BASH, NA, NA, NULL); + addflag(r->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(r->flags, F_DTVULN, DT_COLD, NA, NA, NULL); + addflag(r->flags, F_DTVULN, DT_DECAY, NA, NA, NULL); + addflag(r->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); + } else if (r->raceclass->id == RC_SLIME) { + addflag(lastrace->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_UNDEAD) { + addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); 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); @@ -15229,12 +15728,6 @@ int validateraces(void) { addflag(r->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL); addflag(r->flags, F_DTVULN, DT_HOLY, NA, NA, NULL); addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); - } else if (r->raceclass->id == RC_PLANT) { - addflag(r->flags, F_DTRESIST, DT_BASH, NA, NA, NULL); - addflag(r->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); - addflag(r->flags, F_DTVULN, DT_COLD, NA, NA, NULL); - addflag(r->flags, F_DTVULN, DT_DECAY, NA, NA, NULL); - addflag(r->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); } } @@ -15610,7 +16103,7 @@ int wear(lifeform_t *lf, object_t *o) { // metal objects and magshield? if (lfhasflag(lf, F_MAGSHIELD)) { if (isplayer(lf)) { - msg("Your %s evades your grasp!", noprefix(buf)); + msg("^wYour %s evades your grasp!", noprefix(buf)); } return B_TRUE; } @@ -15767,7 +16260,7 @@ int wear(lifeform_t *lf, object_t *o) { if (o->blessed == B_CURSED) { if (isplayer(lf)) { - msg("Oh no! The %s releases a pulse of evil!", noprefix(obname)); + msg("^bOh no! The %s releases a pulse of evil!", noprefix(obname)); o->blessknown = B_TRUE; } else if (cansee(player, lf)) { getlfname(lf, buf); @@ -15782,7 +16275,7 @@ int wear(lifeform_t *lf, object_t *o) { if (isplayer(lf)) { f = hasflag(o->flags, F_SHIELD); if (f && (getskill(lf, SK_SHIELDS) <= PR_INEPT) ) { - msg("You find this shield very cumbersome to use."); + msg("^wYou find this shield very cumbersome to use."); } } @@ -15841,6 +16334,9 @@ int weild(lifeform_t *lf, object_t *o) { case E_LOWSTR: msg("You are not strong enough to use this weapon."); break; + case E_LOWWIS: + msg("You are not wise enough to use this weapon."); + break; default: msg("For some reason, you weild this!"); break; @@ -15868,7 +16364,7 @@ int weild(lifeform_t *lf, object_t *o) { // metal objects and magshield? if (lfhasflag(lf, F_MAGSHIELD)) { if (isplayer(lf)) { - msg("Your %s evades your grasp!", noprefix(buf)); + msg("^wYour %s evades your grasp!", noprefix(buf)); } return B_TRUE; } @@ -16026,13 +16522,13 @@ int weild(lifeform_t *lf, object_t *o) { msg(buf2); // warn if it won't do any damage if (!ismeleeweapon(o) && !isfirearm(o)) { - msg("You have a feeling that this weapon will not be very effective..."); + msg("^wYou have a feeling that this weapon will not be very effective..."); } else { // warn if unskilled in this weapon skill_t *sk; sk = getobskill(o); if (sk && !getskill(lf, sk->id)) { - msg("You feel rather inept with this weapon."); + msg("^wYou feel rather inept with this weapon."); } } } else if (cansee(player, lf)) { @@ -16048,7 +16544,7 @@ int weild(lifeform_t *lf, object_t *o) { if (o->blessed == B_CURSED) { if (isplayer(lf)) { - msg("Oh no! The %s releases a pulse of evil!", strchr(buf, ' ')+1); + msg("^bOh no! The %s releases a pulse of evil!", strchr(buf, ' ')+1); o->blessknown = B_TRUE; } else if (cansee(player, lf)) { char buf2[BUFLEN]; @@ -16057,15 +16553,6 @@ int weild(lifeform_t *lf, object_t *o) { o->blessknown = B_TRUE; } } - - if (isfirearm(o)) { - // select ammo - setammo(lf, getrandomammo(lf)); - - if (getammo(lf)) { - autotarget(lf); - } - } } // give flags @@ -16075,7 +16562,7 @@ int weild(lifeform_t *lf, object_t *o) { if (isplayer(lf)) { f = hasflag(o->flags, F_ARMOURPIERCE); if (f) { - msg("Your %s seems unnaturally sharp!",noprefix(buf)); + msg("^gYour %s seems unnaturally sharp!",noprefix(buf)); f->known = B_TRUE; } } @@ -16085,7 +16572,7 @@ int weild(lifeform_t *lf, object_t *o) { // will the lf flee after taking damage? int willflee(lifeform_t *lf) { - enum IQBRACKET iqb; + enum ATTRBRACKET iqb; flag_t *f; @@ -16097,8 +16584,8 @@ int willflee(lifeform_t *lf) { return B_TRUE; } - iqb = getiqname(getattr(lf, A_IQ), NULL); - if ((iqb >= IQ_SMART) && isbleeding(lf)) { + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); + if ((iqb >= AT_GTAVERAGE) && isbleeding(lf)) { return B_TRUE; } diff --git a/lf.h b/lf.h index a4ab7df..62ff009 100644 --- a/lf.h +++ b/lf.h @@ -13,6 +13,7 @@ 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); int askforpayment(lifeform_t *shk, lifeform_t *lf); +char *assignnpcname(lifeform_t *lf); void autoskill(lifeform_t *lf); void autotarget(lifeform_t *lf); void autoweild(lifeform_t *lf); @@ -91,6 +92,7 @@ int getarmourrating(lifeform_t *lf, object_t **hitob, int *hitchance, int *narms int getattackspeed(lifeform_t *lf); int getattpoints(lifeform_t *lf); int getattr(lifeform_t *lf, enum ATTRIB attr); +enum ATTRBRACKET getattrbracket(int attrval, enum ATTRIB whichatt, char *buf); int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset); int getavgdam(lifeform_t *lf, int forxp); float getequippedweight(lifeform_t *lf); @@ -102,6 +104,7 @@ int getbodyparthitchance(enum BODYPART bp); char *getbodypartname(enum BODYPART bp); char *getbodypartequipname(enum BODYPART bp); object_t *getequippedob(obpile_t *op, enum BODYPART bp); +int getexposedlimbs(lifeform_t *lf); object_t *getfirearm(lifeform_t *lf); int getfootprinttime(lifeform_t *lf); lifeform_t *getguntarget(lifeform_t *lf); @@ -117,6 +120,7 @@ int gethungerval(lifeform_t *lf); job_t *getjob(lifeform_t *lf); int getlastdir(lifeform_t *lf); int getlfaccuracy(lifeform_t *lf, object_t *wep); +char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc); enum LFCONDITION getlfcondition(lifeform_t *lf); int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions); int getnightvisrange(lifeform_t *lf); @@ -155,9 +159,11 @@ int getpoisondamchance(enum POISONTYPE ptype); char *getpoisondamverb(enum POISONTYPE ptype); char *getpoisondesc(enum POISONTYPE ptype); char *getpoisonname(enum POISONTYPE ptype); +enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype); int getraceclass(lifeform_t *lf); int getracerarity(map_t *map, enum RACE rid); object_t *getrandomarmour(lifeform_t *lf); +job_t *getrandomjob(int onlyplayerjobs); int getrandommonlevel(race_t *r, map_t *m); race_t *getrandomrace(cell_t *c, int forcedepth); race_t *getreallyrandomrace(enum RACECLASS wantrc); @@ -168,11 +174,6 @@ int getsounddist(int volume); char *getspeedname(int speed, char *buf); char *getspeednameshort(int speed, char *buf); float getstatmod(lifeform_t *lf, enum ATTRIB att); -enum CHABRACKET getchaname(int cha, char *buf); -enum CONBRACKET getconname(int con, char *buf); -enum STRBRACKET getstrname(int str, char *buf); -enum DEXBRACKET getdexname(int dex, char *buf); -enum IQBRACKET getiqname(int iq, char *buf); char *getskilldesc(enum SKILL id ); char *getskillname(enum SKILL id ); char *getskilllevelname(enum SKILLLEVEL sl); @@ -185,9 +186,10 @@ int givemoney(lifeform_t *from, lifeform_t *to, int amt); void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype); int giveskill(lifeform_t *lf, enum SKILL id); int giveskilllev(lifeform_t *lf, enum SKILL id, enum SKILLLEVEL slev); -void givestartobs(lifeform_t *lf, flagpile_t *fp); +void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp); void givestartskills(lifeform_t *lf, flagpile_t *fp); map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs); +int gotosleep(lifeform_t *lf, int onpurpose); int hasfreeaction(lifeform_t *lf); job_t *hasjob(lifeform_t *lf, enum JOB job); int lfcanbestoned(lifeform_t *lf); @@ -219,6 +221,7 @@ int isfleeing(lifeform_t *lf); int isfreebp(lifeform_t *lf, enum BODYPART bp); int isfriendly(lifeform_t *lf); int isgenius(lifeform_t *lf); +int ishirable(lifeform_t *lf); int isimmobile(lifeform_t *lf); flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt); int isinbattle(lifeform_t *lf); @@ -244,6 +247,8 @@ void killjob(job_t *job); void killlf(lifeform_t *lf); void killrace(race_t *race); flag_t *levelabilityready(lifeform_t *lf); +int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo); +int loadfirearmfast(lifeform_t *lf); void loseconcentration(lifeform_t *lf); int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc); int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam); @@ -261,6 +266,7 @@ float modifybystat(float num, lifeform_t *lf, enum ATTRIB att); int needstorest(lifeform_t *lf, char *validchars); int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext); void outfitlf(lifeform_t *lf); +void petify(lifeform_t *lf, lifeform_t *owner); int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground); void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat); int poisoncausesvomit(enum POISONTYPE ptype); @@ -269,21 +275,20 @@ void practice(lifeform_t *lf, enum SKILL skid, int amt); void precalclos(lifeform_t *lf); int push(lifeform_t *lf, object_t *o, int dir); int readytotrain(lifeform_t *lf); +int recruit(lifeform_t *lf); void refreshlevelabilities(lifeform_t *lf); void relinklf(lifeform_t *src, map_t *dst); int rest(lifeform_t *lf, int onpurpose); -void startresting(lifeform_t *lf, int willtrain); -int rollcha(enum CHABRACKET bracket); -int rollcon(enum CONBRACKET bracket); -int rolldex(enum DEXBRACKET bracket); -int rolliq(enum IQBRACKET bracket); -int rollstr(enum STRBRACKET bracket); +int startresting(lifeform_t *lf, int willtrain); +int rollattr(enum ATTRBRACKET bracket); int rollstat(lifeform_t *lf, enum ATTRIB attr); int safetorest(lifeform_t *lf); int say(lifeform_t *lf, char *text, int volume); +int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *text); int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus); -int setammo(lifeform_t *lf, object_t *o); +//int setammo(lifeform_t *lf, object_t *o); void setattr(lifeform_t *lf, enum ATTRIB attr, int val); +void setfollowdistance(lifeform_t *lf, int min, int max); void setguntarget(lifeform_t *lf, lifeform_t *targ); void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph); void setlastdam(lifeform_t *lf, char *buf); @@ -302,7 +307,7 @@ void stopresting(lifeform_t *lf); void stoprunning(lifeform_t *lf); void stopsprinting(lifeform_t *lf); lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, int randomjobsok, job_t *forcejob, int lifetime, int wantfriendly); -int testammo(lifeform_t *lf, object_t *o); +//int testammo(lifeform_t *lf, object_t *o); int takeoff(lifeform_t *lf, object_t *o); void taketime(lifeform_t *lf, long howlong); int throwat(lifeform_t *thrower, object_t *o, cell_t *where); diff --git a/map.c b/map.c index 4b857ad..6b23c8a 100644 --- a/map.c +++ b/map.c @@ -44,7 +44,7 @@ cell_t *addcell(map_t *m, int x, int y) { cell->habitat = m->habitat; setcelltype(cell, cell->habitat->solidcelltype); cell->visited = B_FALSE; - cell->obpile = addobpile(NOOWNER, cell); + cell->obpile = addobpile(NOOWNER, cell, NOOB); cell->lf = NULL; cell->roomid = -1; cell->vault = NULL; @@ -196,7 +196,15 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto // has a job? if (f->id == F_STARTJOB) { if (rnd(1,100) <= f->val[0]) { - givejob(lf, f->val[1]); + enum JOB wantjob; + if (f->val[1] == J_RANDOM) { + job_t *j; + j = getrandomjob(B_TRUE); + wantjob = j->id; + } else { + wantjob = f->val[1]; + } + givejob(lf, wantjob); break; } } @@ -367,7 +375,7 @@ object_t *addrandomob(cell_t *c) { return NULL; } - if (real_getrandomob(c->map, buf, RO_NONE, NA, NA, c->habitat->id)) { + if (real_getrandomob(c->map, buf, RO_NONE, NA, NA, c->habitat->id, SZ_MAX)) { if (db) dblog("adding rand obj %s to cell %d,%d",buf,c->x,c->y); o = addob(c->obpile, buf); } @@ -483,7 +491,8 @@ void getroomedge(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, } } -region_t *addregion(enum REGIONTYPE rtype, region_t *parent) { +// if outlineid is -1, it's automatically assigned +region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid) { region_t *a; regionoutline_t *ro,*poss[MAXCANDIDATES]; int nposs = 0; @@ -515,17 +524,22 @@ region_t *addregion(enum REGIONTYPE rtype, region_t *parent) { a->rtype = findregiontype(rtype); a->parentregion = parent; - // randomly assign a regionoutline - for (ro = firstregionoutline; ro ; ro = ro->next) { - if (ro->rtype->id == rtype) { - poss[nposs++] = ro; + if (outlineid == -1) { + // randomly assign a regionoutline + for (ro = firstregionoutline; ro ; ro = ro->next) { + if (ro->rtype->id == rtype) { + poss[nposs++] = ro; + } + } + // make sure we got one... + if (nposs) { + a->outline = poss[rnd(0,nposs-1)]; + } else { + a->outline = NULL; } - } - // make sure we got one... - if (nposs) { - a->outline = poss[rnd(0,nposs-1)]; } else { - a->outline = NULL; + a->outline = findoutline(outlineid); + assert(a->outline); } return a; } @@ -549,6 +563,11 @@ regionoutline_t *addregionoutline(enum REGIONTYPE rtype) { a->next = NULL; // props + if (a == firstregionoutline) { + a->id = 0; + } else { + a->id = lastregionoutline->id + 1; + } a->rtype = findregiontype(rtype); a->nthings = 0; return a; @@ -838,7 +857,7 @@ int cellhaslos(cell_t *c1, cell_t *dest) { } void clearcell(cell_t *c) { - // kill everything there + // kill everything there - (lifeforms && objects) if (c->lf && !isplayer(c->lf)) { killlf(c->lf); } @@ -1898,11 +1917,12 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob) { lifeform_t *lf; map_t *m; - char buf[BUFLEN]; + char buf[BUFLEN],buf2[BUFLEN]; int i,x,y; enum HABITAT habitat; regionthing_t *thing[MAXOUTLINETHINGS]; int nthings = 0; + int db = B_TRUE; // determine habitat based on region // note: we might override this later based on our region outline @@ -1918,8 +1938,10 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex map->depth = depth; map->region = region; - sprintf(buf, "RegionID %d (#%d)",map->region->id, map->id); - map->name = strdup(buf); + if (db) { + getregionname(buf, map, B_FALSE); + dblog("Creating new map of region '%s'",buf); + } map->habitat = findhabitat(habitat); map->nrooms = 0; @@ -1934,6 +1956,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex } // look for adjacent maps above/below this one + if (db) dblog(" look for adjacent maps above/below this one"); for (i = depth-1; i <= depth+1; i += 2) { map_t *othermap; othermap = findregionmap(map->region->id, i); @@ -1941,8 +1964,10 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex if (othermap) { if (i == (depth-1)) { map->nextmap[D_UP] = othermap->id; + if (db) dblog(" found mapin dir d_up: %s", othermap->name); } else { map->nextmap[D_DOWN] = othermap->id; + if (db) dblog(" found mapin dir d_down: %s", othermap->name); } } } @@ -1952,6 +1977,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex if (parentmap) { if ((parentmap->region->id == map->region->id) || (map->region->rtype->majorbranch)) { + if (db) dblog(" linking to parentmap %s in dir %s", parentmap->name, getdirname(diropposite(exitdir))); parentmap->nextmap[exitdir] = map->id; map->nextmap[diropposite(exitdir)] = parentmap->id; } @@ -1985,12 +2011,16 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // set map coords // first world map?? if (map == firstmap) { + if (db) dblog(" map is the first world map. setting coords to 0,0."); addflag(map->flags, F_MAPCOORDS, 0, 0, NA, NULL); + x = 0; + y = 0; } else { // set mapcoords if not already done. if (!hasflag(map->flags, F_MAPCOORDS)) { x = -999; y = -999; + // set mapcoords based on parent map if (parentmap) { getmapcoords(parentmap, &x, &y); assert((x != -999) && (y != -999)); @@ -2011,16 +2041,18 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // no change break; } - addflag(map->flags, F_MAPCOORDS, x, y, NA, NULL); + if (db) dblog(" setting map coords to %d,%d (based on parent map)",x,y); } else { // set it based on something else... if (region->rtype->id == RG_WORLDMAP) { + // TODO: is this right??????????? // find another map of this region and set it. for (m = firstmap ; m ; m = m->next) { if ((m != map) && (m->region == region)) { flag_t *ff; ff = hasflag(m->flags, F_MAPCOORDS); if (ff) { + if (db) dblog(" setting map coords to %d,%d (based on other region map)",x,y); x = ff->val[0]; y = ff->val[1]; break; @@ -2038,10 +2070,15 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex } } + // we now have the map name! + getregionname(buf2, map, B_TRUE); + sprintf(buf, "%s (id #%d)",buf2, map->id); + map->name = strdup(buf); // get a list of what things are here based on the region's outline nthings = 0; if (region->outline) { + if (db) dblog(" checking region outline for things..."); for (i = 0; i < region->outline->nthings; i++) { int matched = B_FALSE; if ((region->rtype->id == RG_WORLDMAP) && @@ -2058,27 +2095,36 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex if (matched) { // override region if (region->outline->thing[i].whatkind == RT_HABITAT) { - map->habitat = findhabitat(region->outline->thing[i].value); + habitat_t *h; + h = findhabitat(region->outline->thing[i].value); + if (db) dblog(" setting map habitat to %s based on outlinething.",h->name); + map->habitat = h; } else { + if (db) dblog(" remembering region thing for later."); // remember this thing thing[nthings] = ®ion->outline->thing[i]; nthings++; } } } + } else { + if (db) dblog(" region has no outline."); } // build it... + if (db) dblog(" creating map habitat."); createhabitat(map, depth, parentmap, exitdir, entryob); // add home objects + if (db) dblog(" adding home objects."); for (lf = map->lf ; lf ; lf = lf->next) { addhomeobs(lf); } // add outline things + if (db) dblog(" adding remembered region outline things..."); for (i = 0; i < nthings ;i++) { vault_t *v; // add this thing @@ -2086,26 +2132,38 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex case RT_HABITAT: // already handled above break; case RT_REGIONLINK: + if (db) dblog(" adding regionlink"); createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region); // ... don't need to do this since we know there won't be anywhere to link to. //linkstairs(o); break; case RT_VAULT: + if (db) dblog(" adding vault"); v = findvault(thing[i]->what); assert(v); if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) { dblog("ERROR - couldn't create vault %s on map %s", v->id, map->name); } break; + case RT_RNDVAULTWITHFLAG: + if (db) dblog(" adding rndvaultwithflag"); + v = findvaultwithflag(thing[i]->value); + assert(v); + if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) { + dblog("ERROR - couldn't create rndvaultwithflag %s on map %s", v->id, map->name); + } + break; } } // special cases // village - add town walls and clear it out + if (db) dblog(" finalising village creation..."); if (map->habitat->id == H_VILLAGE) { int x1 = 999,y1 = 999,x2 = -1,y2 = -1,x,y; - int gx,gy; - int guardx[2], guardy[2]; + int gx[MAXDIR_ORTH],gy[MAXDIR_ORTH]; + int guardx[MAXDIR_ORTH][2], guardy[MAXDIR_ORTH][2]; + int dir; cell_t *c; // find outermost dimensions of shops for (y = 0; y < map->h; y++) { @@ -2131,39 +2189,41 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex limit(&y2, 0, map->h-1); // decide where the gate will be (not the corner) - switch (rnd(D_N, D_W)) { - case D_N: - gx = rnd(x1+2,x2-2); - gy = y1; - guardx[0] = gx-1; - guardy[0] = gy+1; - guardx[1] = gx+1; - guardy[1] = gy+1; - break; - case D_E: - gx = x2; - gy = rnd(y1+2,y2-2); - guardx[0] = gx-1; - guardy[0] = gy-1; - guardx[1] = gx-1; - guardy[1] = gy+1; - break; - case D_S: - gx = rnd(x1+2,x2-2); - gy = y2; - guardx[0] = gx-1; - guardy[0] = gy-1; - guardx[1] = gx+1; - guardy[1] = gy-1; - break; - case D_W: - gx = x1; - gy = rnd(y1+2,y2-2); - guardx[0] = gx+1; - guardy[0] = gy-1; - guardx[1] = gx+1; - guardy[1] = gy+1; - break; + for (dir = D_N; dir <= D_W; dir++) { + switch (dir) { + case D_N: + gx[dir] = rnd(x1+2,x2-2); + gy[dir] = y1; + guardx[dir][0] = gx[dir]-1; + guardy[dir][0] = gy[dir]+1; + guardx[dir][1] = gx[dir]+1; + guardy[dir][1] = gy[dir]+1; + break; + case D_E: + gx[dir] = x2; + gy[dir] = rnd(y1+2,y2-2); + guardx[dir][0] = gx[dir]-1; + guardy[dir][0] = gy[dir]-1; + guardx[dir][1] = gx[dir]-1; + guardy[dir][1] = gy[dir]+1; + break; + case D_S: + gx[dir] = rnd(x1+2,x2-2); + gy[dir] = y2; + guardx[dir][0] = gx[dir]-1; + guardy[dir][0] = gy[dir]-1; + guardx[dir][1] = gx[dir]+1; + guardy[dir][1] = gy[dir]-1; + break; + case D_W: + gx[dir] = x1; + gy[dir] = rnd(y1+2,y2-2); + guardx[dir][0] = gx[dir]+1; + guardy[dir][0] = gy[dir]-1; + guardx[dir][1] = gx[dir]+1; + guardy[dir][1] = gy[dir]+1; + break; + } } // fill in town walls and clearing @@ -2179,13 +2239,14 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // mark as different habitat to outside c->habitat = findhabitat(H_VILLAGE); - - if ((c->x == gx) && (c->y == gy)) { - // town gate location - clearcell(c); + if (!isroom(c)) { + // get rid of objects (ie. trees) here + killallobs(c->obpile); + // make the ground dirt setcelltype(c, CT_DIRT); - addob(c->obpile, "wooden gate"); - } else if ((c->x == x1) || (c->y == y1) || + } + + if ((c->x == x1) || (c->y == y1) || (c->x == x2) || (c->y == y2)) { // town perimeter (walls) if (!isroom(c)) { @@ -2193,18 +2254,30 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex setcelltype(c, CT_DIRT); addob(c->obpile, "wooden fence"); } - } else { // elsewhere within the town grounds - if (!isroom(c)) { - // get rid of objects (ie. trees) here - killallobs(c->obpile); - // make the ground dirt + } + + for (dir = D_N; dir <= D_W; dir++) { + // town gate location + if ((c->x == gx[dir]) && (c->y == gy[dir])) { + int d2; + cell_t *c2; + clearcell(c); setcelltype(c, CT_DIRT); + addob(c->obpile, "wooden gate"); + // also make surrounding forest cells be dirt and no trees, + for (d2 = DC_N; d2 <= DC_NW; d2++) { + c2 = getcellindir(c, d2); + if (c2 && (c2->habitat->id != H_VILLAGE)) { + clearcell(c2); + setcelltype(c2, CT_DIRT); + } + } } - } - // village guards - for (i = 0; i < 1; i++) { - if ((c->x == guardx[i]) && (c->y == guardy[i])) { - addmonster(c, R_TOWNGUARD, B_FALSE, 1, B_TRUE, NULL); + // village guards + for (i = 0; i < 1; i++) { + if ((c->x == guardx[dir][i]) && (c->y == guardy[dir][i])) { + addmonster(c, R_TOWNGUARD, B_FALSE, 1, B_TRUE, NULL); + } } } } @@ -2218,6 +2291,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex } // try to join up any unlinked staircases in this map. + if (db) dblog(" joining unlinked stairs..."); for (y = 0; y < map->h; y++) { for (x = 0; x < map->w; x++) { cell_t *c; @@ -2227,7 +2301,18 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex if (o && !getstairdestination(o)) { // this will join these stairs to existing ones on // existing adjacent maps - linkstairs(o, NULL); + if (!linkstairs(o, NULL)) { + if (db) { + cell_t *dst; + dst = getstairdestination(o); + dblog(" linked '%s' to map %s",o->type->name, dst->map->name); + } + } else { + if (db) { + dblog(" FAILED to link stiars: '%s'",o->type->name); + } + + } } } } @@ -2235,9 +2320,13 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex // link up holes - this will create NEW holes in THIS map connecting to // EXISTING unlinked holes in adjacent maps - linkholes(map); + i = linkholes(map); + if (db) { + if (db) dblog(" autolinked to %d holes in adjacent maps.",i); + } // add random objects and monsters + if (db) dblog(" adding random objects+monsters"); for (y = 0; y < map->h; y++) { for (x = 0; x < map->w; x++) { cell_t *c; @@ -2252,6 +2341,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex } // look for adjacent maps + if (db) dblog(" linking to adjacent maps"); getmapcoords(map, &x, &y); assert(x != -999); assert(y != -999); @@ -2260,21 +2350,34 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex int thisx,thisy; getmapcoords(m, &thisx, &thisy); if (map->nextmap[D_N] == -1) { - if (thisy == (y - 1)) map->nextmap[D_N] = m->id; + if (thisy == (y - 1)) { + map->nextmap[D_N] = m->id; + if (db) dblog(" linked to map %d (dir N)",m->id); + } } if (map->nextmap[D_E] == -1) { - if (thisx == (x + 1)) map->nextmap[D_E] = m->id; + if (thisx == (x + 1)) { + map->nextmap[D_E] = m->id; + if (db) dblog(" linked to map %d (dir E)",m->id); + } } if (map->nextmap[D_S] == -1) { - if (thisy == (y + 1)) map->nextmap[D_S] = m->id; + if (thisy == (y + 1)) { + map->nextmap[D_S] = m->id; + if (db) dblog(" linked to map %d (dir S)",m->id); + } } if (map->nextmap[D_W] == -1) { - if (thisx == (x - 1)) map->nextmap[D_W] = m->id; + if (thisx == (x - 1)) { + map->nextmap[D_W] = m->id; + if (db) dblog(" linked to map %d (dir W)",m->id); + } } } } map->beingcreated = B_FALSE; + if (db) dblog(" Map creation finished."); } int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety) { @@ -2496,7 +2599,7 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO flag_t *f; region_t *r; // create a new region - r = addregion(newregiontype, m->region); + r = addregion(newregiontype, m->region, -1); // add stairs to new region if (!c) { c = NULL; @@ -2887,6 +2990,14 @@ cell_t *findobinmap(map_t *m, enum OBTYPE oid) { return NULL; } +regionoutline_t *findoutline(int id) { + regionoutline_t *ro; + for (ro = firstregionoutline ;ro ; ro = ro->next) { + if (ro->id == id) return ro; + } + return NULL; +} + region_t *findregion(int regionid) { region_t *r; for (r = firstregion ; r ; r = r->next) { @@ -3015,6 +3126,21 @@ cell_t *getcellindir(cell_t *cell, int dir) { return newcell; } +cell_t *getclosestroomcell(lifeform_t *lf, int roomid) { + int i; + cell_t *c,*best = NULL; + int closest = 9999; + for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) { + c = lf->cell->map->cell[i]; + if ((c->roomid == roomid) & cellwalkable(lf, c, NULL)) { + if (getcelldist(lf->cell, c) < closest) { + best = c; + } + } + } + return best; +} + // select a new direction (random chance of turnung) int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) { int foundvaliddir = B_FALSE; @@ -3495,7 +3621,7 @@ void initmap(void) { addregiontype(RG_WORLDMAP, H_FOREST, 10, 0, D_NONE, B_TRUE); addregiontype(RG_FIRSTDUNGEON, H_DUNGEON, 30, 3, D_DOWN, B_TRUE); addregiontype(RG_PIT, H_PIT, 1, 1, D_DOWN, B_FALSE); - // region outlines + // region definitions (outlines) addregionoutline(RG_WORLDMAP); // link to first dungeon addregionthing(lastregionoutline, NA, 0, 0, RT_REGIONLINK, RG_FIRSTDUNGEON, "staircase going down"); @@ -3509,9 +3635,11 @@ void initmap(void) { */ vx = 0; vy = -1; addregionthing(lastregionoutline, NA, vx, vy, RT_HABITAT, H_VILLAGE, NULL); - addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "potion_shop"); - addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "weapon_shop"); - addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "armour_shop"); + addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "food_shop"); + addregionthing(lastregionoutline, NA, vx, vy, RT_VAULT, NA, "pub"); + addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL); + addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL); + addregionthing(lastregionoutline, NA, vx, vy, RT_RNDVAULTWITHFLAG, F_VAULTISSHOP, NULL); addregionoutline(RG_FIRSTDUNGEON); addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair"); } @@ -3754,12 +3882,14 @@ int iswallindir(cell_t *cell, int dir) { // search for unlinked pits/holes in roof in ADJACENT maps // if we find any, add a matching end as close as we can in THIS map. -void linkholes(map_t *map) { +// returns then umber of holes linked. +int linkholes(map_t *map) { map_t *adjmap; cell_t *c; object_t *o, *newob; int x,y; int dir; + int nlinked = 0; for (dir = D_UP ; dir <= D_DOWN; dir++) { adjmap = getmapindir(map, dir); @@ -3792,6 +3922,14 @@ void linkholes(map_t *map) { newob = addobject(c2->obpile, ot->name, B_FALSE, B_FALSE); // link holes manually now. linkstairs(newob, o); + + // objects above fall down + if (dir == D_UP) { + obsfallthrough(c, o); + } else { + obsfallthrough(c2, newob); + } + nlinked++; } } } @@ -3799,6 +3937,7 @@ void linkholes(map_t *map) { } } } + return nlinked; } // link the staircase 'o' to a free one in adjacent maps. @@ -3990,6 +4129,36 @@ void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong) { } } +void mapentereffects(map_t *m) { + int i; + cell_t *c; + flag_t *f; + for (i = 0; i < m->w * m->h; i++) { + // teleport shopkeepers back to their shops + c = m->cell[i]; + if (c->lf && hasjob(c->lf, J_SHOPKEEPER) && !isplayer(c->lf)) { + f = lfhasflag(c->lf, F_OWNSSHOP); + if (f) { + cell_t *where; + int myshop; + myshop = f->val[0]; + // find the closest cell of my shop + where = getclosestroomcell(c->lf, myshop); + if (where) { + movelf(c->lf, where); + } + } + } + // replace people in the Inn + if (c->vault && streq(c->vault->id, "inn") && c->lf && (c->lf->race->id == R_HUMAN)) { + lifeform_t *lf; + killlf(c->lf); + lf = addmonster(c, R_HUMAN, B_TRUE, 1, B_FALSE, NULL); + addflag(lf->flags, F_STAYINROOM, c->roomid, NA, NA, NULL); + } + } +} + void setcellknown(cell_t *cell, int forcelev) { enum SKILLLEVEL slev; object_t *o; @@ -4188,6 +4357,12 @@ int validateregionthing(regionthing_t *thing) { return B_TRUE; } break; + case RT_RNDVAULTWITHFLAG: + if (!findvaultwithflag(thing->value)) { + dblog("Invalid rt_rndvaultwithflag specified in regionthing."); + return B_TRUE; + } + break; } return B_FALSE; } diff --git a/map.h b/map.h index dbd3ff4..6500b87 100644 --- a/map.h +++ b/map.h @@ -7,7 +7,7 @@ map_t *addmap(void); lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded); object_t *addrandomob(cell_t *c); int addrandomthing(cell_t *c, int obchance, int *nadded); -region_t *addregion(enum REGIONTYPE rtype, region_t *parent); +region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid); regionoutline_t *addregionoutline(enum REGIONTYPE rtype); regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what); regiontype_t *addregiontype(enum REGIONTYPE id, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major); @@ -58,6 +58,7 @@ map_t *findmapofdepth(int depth); cell_t *findmapentrypoint(map_t *m, int side, lifeform_t *lf); object_t *findobidinmap(map_t *m, long id); cell_t *findobinmap(map_t *m, enum OBTYPE oid); +regionoutline_t *findoutline(int id); region_t *findregion(int regionid); region_t *findregionbytype(enum REGIONTYPE rtid); map_t *findregionmap(int regionid, int depth); @@ -65,6 +66,7 @@ regiontype_t *findregiontype(enum REGIONTYPE rtype); map_t *findsurfaceexitmap(map_t *m); void forgetcells(map_t *map, int amt); cell_t *getcellindir(cell_t *cell, int dir); +cell_t *getclosestroomcell(lifeform_t *lf, int roomid); int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved); int getobchance(int habitat); char *getregionname(char *buf, map_t *m, int withlevel); @@ -99,11 +101,12 @@ int isoutdoors(map_t *m); int isroom(cell_t *c); int iswallindir(cell_t *cell, int dir); int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy); -void linkholes(map_t *map); +int linkholes(map_t *map); int linkstairs(object_t *o, object_t *o2); void makedoor(cell_t *cell, int openchance); void makelit(cell_t *c, enum LIGHTLEV how, int howlong); void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong); +void mapentereffects(map_t *m); void setcellknown(cell_t *cell, int forcelev); void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype); void setcelltype(cell_t *cell, enum CELLTYPE id); diff --git a/move.c b/move.c index d89301d..e45a622 100644 --- a/move.c +++ b/move.c @@ -138,7 +138,7 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) { // onlyifknown = true means "check for _known_ dangerous objects" // onlyifknown = false means "check for _any dangerous objects, doesn't matter if we know about them" int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *error) { - enum IQBRACKET iq; + enum ATTRBRACKET iq; int include_nonobvious = B_FALSE; flag_t *f; object_t *o; @@ -200,6 +200,15 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err } } } + f = obrestrictsmovement(o, lf); + if (f) { + // always avoid if possible + if (error) { + *error = E_AVOIDOB; + rdata = o; + } + return B_TRUE; + } f = hasflag(o->flags, F_WALKDAM); if (f) { if ((f->val[0] != DT_WATER) || isvulnto(lf->flags, DT_WATER)) { @@ -220,8 +229,8 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err if (!onlyifknown) { include_nonobvious = B_TRUE; } else { - iq = getiqname(getattr(lf, A_IQ), NULL); - if ((iq >= IQ_AVERAGE) && haslos(lf, cell)) { + iq = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); + if ((iq >= AT_AVERAGE) && haslos(lf, cell)) { if (!lfhasflag(lf, F_UNDEAD)) { include_nonobvious = B_TRUE; } @@ -644,6 +653,13 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc int mightfall = B_TRUE; lifeform_t *newlf; + if (lfhasflag(lf, F_GRAVLESSENED)) { + howfar *= 2; + } else if (lfhasflag(lf, F_GRAVBOOSTED)) { + howfar /= 2; + if (howfar < 0) howfar = 0; + } + // calculate chance of falling if (fallcheckdiff == 0) { // chance based on distance @@ -962,6 +978,11 @@ int movelf(lifeform_t *lf, cell_t *newcell) { needredraw = B_TRUE; } + // special effects when the player moves to a new map + if (changedlev && isplayer(lf)) { + mapentereffects(newcell->map); + } + didmsg = moveeffects(lf); killflagsofid(lf->flags, F_HIDING); @@ -1193,18 +1214,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) { shk = findshopkeeper(lf->cell->map, preshop); // do you have any unpaid items from that shop? if (shk && getowing(lf, preshop, &nitems)) { - char saybuf[BUFLEN]; // warning... - switch (rnd(1,3)) { - case 1: sprintf(saybuf, "Hey! Where do you think you're going?"); - break; - case 2: sprintf(saybuf, "AHEM!"); - break; - case 3: sprintf(saybuf, "I hope you are going to pay for %s!", - (nitems == 1) ? "that" : "those" ); - break; - } - say(shk, saybuf, SV_SHOUT); + sayphrase(shk, SP_PAYWARN, SV_SHOUT, NA, (nitems == 1) ? "that" : "those" ); didmsg = B_TRUE; } } else if (lf->cell->roomid != preshop) { @@ -1212,17 +1223,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) { lifeform_t *shk; shk = findshopkeeper(lf->cell->map, preshop); if (shk && getowing(lf, preshop, NULL)) { - char saybuf[BUFLEN]; // call the guards - switch (rnd(1,3)) { - case 1: sprintf(saybuf, "Stop thief!"); - break; - case 2: sprintf(saybuf, "GUARDS!"); - break; - case 3: sprintf(saybuf, "I've been robbed!"); - break; - } - say(shk, saybuf, SV_ROAR); + sayphrase(shk, SP_PAYTHREAT, SV_ROAR, NA, NULL); didmsg = B_TRUE; fightback(shk, lf); // shopkeeper attacks callguards(shk, lf); // guards come running @@ -1369,19 +1371,13 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { msg("%s trigger%s %s!", lfname, isplayer(lf) ? "" : "s", trapname); if (isplayer(lf)) more(); } - trapeffects(o, o->type->id, lf); - interrupt(lf); if (haslos(player, newcell)) { // no longer hidden killflagsofid(o->flags, F_SECRET); } - switch (o->type->id) { - case OT_TRAPGAS: - removeob(o, o->amt); - break; - default: - break; - } + // NOTE: after trapeffects(), o might be killed. + trapeffects(o, o->type->id, lf); + interrupt(lf); } } } @@ -1775,30 +1771,17 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) { nexto = o->next; - if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) { - continue; - } - if ((o->type->id == OT_VINE) && hasjob(lf, J_DRUID)) { - continue; - } - - f = hasflag(o->flags, F_RESTRICTMOVEMENT); + f = obrestrictsmovement(o, lf); if (f) { char lfname[BUFLEN]; int diff; int checkmod = 0; int getsweaker; - if (isairborne(lf) && (f->val[2] != B_TRUE)) { - continue; - } - - if ((o->type->id == OT_WEB) && isairborne(lf)) { checkmod -= 5; } - getlfname(lf,lfname); getobname(o, buf, o->amt); @@ -1859,6 +1842,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) { msg("%s stands up.",lfname); } killflagsofid(lf->flags, F_PRONE); + killflagsofid(lf->flags, F_FEIGNINGDEATH); // time to get up depends on armour // 1*movespeed for every 1/4 of maxcarryweight being worn. quartermax = getmaxcarryweight(lf) / 4; @@ -2440,12 +2424,13 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) { int willmove(lifeform_t *lf, int dir, enum ERROR *error) { cell_t *cell; - enum IQBRACKET iq; + enum ATTRBRACKET iq; object_t *o; char buf[BUFLEN]; + flag_t *f; //object_t *o; - iq = getiqname(getattr(lf, A_IQ), NULL); + iq = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); // default if (error) { @@ -2468,9 +2453,18 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) { return B_FALSE; } - if (!isroom(cell) && hasjob(lf, J_SHOPKEEPER)) { - if (error) *error = E_WONT; - return B_FALSE; + // shopkeepers will only leave their shops if they have a target + f = lfhasflag(lf, F_STAYINROOM); + if (f) { + int roomid; + roomid = f->val[0]; + // if moving out of my room.. + if ((lf->cell->roomid == roomid) && (lf->cell->roomid != cell->roomid)) { + if (!aihastarget(lf)) { + if (error) *error = E_WONT; + return B_FALSE; + } + } } if (lfhasflag(lf, F_STAYINHABITAT) && (cell->habitat->id != lf->cell->habitat->id)) { @@ -2501,7 +2495,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) { } // for at least average iq things... - if (iq >= IQ_AVERAGE) { + if (iq >= AT_AVERAGE) { // don't move if in pain if (lfhasflag(lf, F_PAIN)) { if (error) *error = E_WONT; @@ -2528,13 +2522,13 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) { if (hasflag(o->flags, F_TRAP)) { if (hasflag(o->flags, F_SECRET)) { // hidden traps? - if (iq >= IQ_SMART) { + if (iq >= AT_GTAVERAGE) { if (error) *error = E_WONT; return B_FALSE; } } else { // non-hidden traps? - if (iq >= IQ_AVERAGE) { + if (iq >= AT_AVERAGE) { if (error) *error = E_WONT; return B_FALSE; } diff --git a/nexus.c b/nexus.c index 25ed709..6ec02ec 100644 --- a/nexus.c +++ b/nexus.c @@ -38,6 +38,8 @@ regionoutline_t *firstregionoutline = NULL,*lastregionoutline = NULL; regiontype_t *firstregiontype = NULL,*lastregiontype = NULL; knowledge_t *knowledge = NULL, *lastknowledge = NULL; hiddenname_t *firsthiddenname = NULL, *lasthiddenname = NULL; +npcname_t *npcname; +int numnpcnames; extern vault_t *firstvault; @@ -177,7 +179,7 @@ int main(int argc, char **argv) { } j = NULL; while (!j) { - getchoice(&prompt); + getchoicestr(&prompt, B_FALSE, B_TRUE); j = prompt.result; } } @@ -188,12 +190,14 @@ int main(int argc, char **argv) { region_t *wregion, *dregion; newworld = B_TRUE; // create world map. - wregion = addregion(RG_WORLDMAP, NULL); + wregion = addregion(RG_WORLDMAP, NULL, -1); + assert(wregion); addmap(); createmap(firstmap, 1, wregion, NULL, D_NONE, NULL); //createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE); // create first dungeon dregion = findregionbytype(RG_FIRSTDUNGEON); + assert(dregion); dmap = addmap(); createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL); } @@ -278,9 +282,8 @@ int main(int argc, char **argv) { c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND); assert(c); pet = addlf(c, r->id, 1); - makefriendly(pet, PERMENANT); // mark us as its master - addflag(pet->flags, F_PETOF, player->id, player->cell->x, player->cell->y, NULL); + petify(pet, player); } getplayernamefull(pname); @@ -533,6 +536,9 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in void donextturn(map_t *map) { lifeform_t *who; int db = B_FALSE; + map_t *oldpmap; + + oldpmap = player->cell->map; who = map->lf; if (db) dblog("**** donextturn for: id %d %s", who->id, who->race->name); @@ -738,8 +744,19 @@ void donextturn(map_t *map) { ////////////////////////////////// // note: can't use 'who->' below since 'who' might have died - // and been de-alloced during checkdeath() above. - timeeffectsworld(player->cell->map); // in case the player changed levels! + // and been de-alloced during checkdeath() above if they + // died. + timeeffectsworld(player->cell->map); + + // the previous call to timeeffectsworld might cause the player to + // change levels (ie. falling down through one or more pits). + // + // if this happens, we need to call it again to make sure that ->timespent + // values don't get out of whack. + while (player->cell->map != oldpmap) { + oldpmap = player->cell->map; + timeeffectsworld(player->cell->map); + } } char *getdirname(int dir) { @@ -833,6 +850,9 @@ int init(void) { playerglyph.colour = C_GREY; tempglyph.ch = '@'; tempglyph.colour = C_GREY; + + // load npc names + loadnpcnames(); initcommands(); initobjects(); @@ -1010,6 +1030,45 @@ int limitf(float *what, float min, float max) { return limited; } +int loadnpcnames(void) { + FILE *f; + char buf[BUFLEN]; + int i = 0; + f = fopen("data/npcnames.txt", "rt"); + if (!f) return B_TRUE; + + // count lines... + fgets(buf, BUFLEN, f); + numnpcnames = 0; + while (!feof(f)) { + buf[strlen(buf)-1] = '\0'; // strip newline + if (strlen(buf)) { + numnpcnames++; + } + fgets(buf, BUFLEN, f); + } + + // alloc mem + npcname = malloc(numnpcnames * sizeof(npcname_t)); + + // back to start + fseek(f, 0, SEEK_SET); + + // now read in names + fgets(buf, BUFLEN, f); + while (!feof(f)) { + buf[strlen(buf)-1] = '\0'; // strip newline + if (strlen(buf)) { + capitalise(buf); + npcname[i].name = strdup(buf); + npcname[i].valid = B_TRUE; + i++; + } + fgets(buf, BUFLEN, f); + } + return B_FALSE; +} + int onein(int howmany) { if (howmany <= 0) return B_FALSE; if (rnd(1,howmany) == 1) return B_TRUE; @@ -1067,6 +1126,13 @@ int parseplayerfile(FILE *f, lifeform_t *lf) { return goterror; } +int pctchance(int pct) { + if (rnd(1,100) <= pct) { + return B_TRUE; + } + return B_FALSE; +} + float pctof(float pct, float num) { return ((pct / 100.0) * num); } @@ -1371,7 +1437,14 @@ void timeeffectsworld(map_t *map) { for (x = 0; x < map->w; x++) { cell_t *c; c = getcellat(map, x, y); - if (c) { + if (c) { + object_t *pit; + pit = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL); + if (pit) { + obsfallthrough(c, pit); + } + + // go through each object in the cell... for (o = c->obpile->first ; o ; o = nexto) { nexto = o->next; diff --git a/nexus.h b/nexus.h index 5ed932e..d76fa64 100644 --- a/nexus.h +++ b/nexus.h @@ -20,8 +20,10 @@ void initcommands(void); int isplayerturn(void); int limit(int *what, int min, int max); int limitf(float *what, float min, float max); +int loadnpcnames(void); int onein(int howmany); int parseplayerfile(FILE *f, lifeform_t *lf); +int pctchance(int pct); float pctof(float pct, float num); int rnd(int min, int max); int roll(char *string); diff --git a/objects.c b/objects.c index 3433bee..0f83ab9 100644 --- a/objects.c +++ b/objects.c @@ -29,6 +29,8 @@ extern object_t *retobs[MAXPILEOBS+1]; extern int retobscount[MAXPILEOBS+1]; extern int nretobs; +extern prompt_t prompt; + extern glyph_t tempglyph; extern map_t *firstmap; @@ -70,6 +72,7 @@ enum OBCLASS sortorder[] = { OC_TECH, OC_TOOLS, OC_BOOK, + OC_FURNITURE, OC_ROCK, OC_FLORA, OC_DFEATURE, @@ -743,8 +746,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes //////////////////////////////////// // we now have the objecttype! //////////////////////////////////// - if (hasflag(ot->flags, F_ONEPERCELL)) { + + if ((gamemode != GM_LOADING) && hasflag(ot->flags, F_ONEPERCELL)) { if (hasob(where, ot->id)) { + if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name); nretobs = 0; return NULL; } @@ -846,6 +851,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes o->type = ot; o->pile = where; + o->contents = addobpile(NOOWNER, NOLOC, o); + o->birthtime = curtime; // inherit props from objecttype @@ -965,6 +972,23 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes } } + // foundtain flags + if (o && (o->type->id == OT_FOUNTAIN)) { + f = hasflag(o->flags, F_LINKOB); + if (where->where && (where->where->habitat->id != H_VILLAGE)) { + objecttype_t *ot; + int min,max; + + getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE); + // random potion type + ot = getrandomobofclass(OC_POTION, min, max); + if (ot) { + f->val[0] = ot->id; + } + } + } + + // tool flags if (o && hasflag(o->flags, F_LIGHTSOURCE) && wantlit) { turnon(NULL, o); @@ -1016,9 +1040,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes addflag(o->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, selhn->text); } - if (o && hasflag(o->flags,F_PIT)) { - dblog("added pit"); - } // create linked holes in adjacent maps if (wantlinkholes && o && hasflag(o->flags, F_PIT)) { @@ -1424,6 +1445,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes } // special cases + /* if (o->type->id == OT_VENDINGMACHINE) { char buf[BUFLEN]; cell_t *loc; @@ -1433,7 +1455,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes objecttype_t *ot2; strcpy(buf, ""); while (!strcmp(buf, "")) { - real_getrandomob(loc->map, buf, RO_NONE, NA, loc->map->depth + rnd(10,15), NA); + real_getrandomob(loc->map, buf, RO_NONE, NA, loc->map->depth + rnd(10,15), NA, getobsize(o)-1); // replace "1 potion" with "a potion" if (strstr(buf, "1 ") == buf) { char temp[BUFLEN]; @@ -1452,6 +1474,22 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes addflag(o->flags, F_CONTAINSOB, 'a' + i, NA, NA, buf); } } + */ + + // containers + if (hasflag(o->flags, F_CONTAINER)) { + if (getoblocation(o)) { + givestartobs(NULL, o, o->flags); + } + } + + // apply cost to shop items + if (o->pile->where && o->pile->where->vault && hasflag(o->pile->where->vault->flags, F_VAULTISSHOP)) { + if (canpickup(NULL, o, 1)) { + addflag(o->flags, F_SHOPITEM, getobvalue(o), o->pile->where->roomid, NA, NULL); + } + } + if (gamemode == GM_GAMESTARTED) { if (o && where->where && !hasflag(o->flags, F_NOGLYPH) && haslos(player, where->where) ) { @@ -1541,13 +1579,14 @@ obmod_t *addobmod(enum OBMOD id, char *prefix) { return a; } -obpile_t *addobpile(lifeform_t *owner, cell_t *where) { +obpile_t *addobpile(lifeform_t *owner, cell_t *where, object_t *parentob) { obpile_t *op; op = malloc(sizeof(obpile_t)); op->first = NULL; op->last = NULL; op->owner = owner; op->where = where; + op->parentob = parentob; return op; } @@ -1579,7 +1618,7 @@ void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int all } } -objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid) { +objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size) { objecttype_t *a, *ot; //flag_t *f; @@ -1612,6 +1651,7 @@ objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, a->desc = strdup(description); a->material = findmaterial(material); a->weight = weight; + a->size = size; a->obclass = findoc(obclassid); a->flags = addflagpile(NULL, NULL); // inherit flags from object class @@ -1679,9 +1719,6 @@ void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma // adjust based on damage type if (damtype == DT_FIRE) { switch (mat) { - case MT_PAPER: - *dam *= 3; - break; case MT_WOOD: case MT_ICE: case MT_SLIME: @@ -1849,7 +1886,7 @@ void adjustprice(objecttype_t *ot, float *price) { } */ -// adjusts armour's evasion penalty based on skill +// adjusts armour's ac//evasion penalty based on skill int adjustarmourpenalty(lifeform_t *lf, float amt) { enum SKILLLEVEL slev; @@ -1857,32 +1894,10 @@ int adjustarmourpenalty(lifeform_t *lf, float amt) { if (!isplayer(lf)) { return 0; } - // only adjust if it is a NEGATIVE penalty! - if (amt < 0) { - slev = getskill(lf, SK_ARMOUR); - switch (slev) { - case PR_INEPT: - amt *= 2; // double penalty! - break; - case PR_NOVICE: - break; - case PR_BEGINNER: - amt *= 0.8; - break; - case PR_ADEPT: - amt *= 0.6; - break; - case PR_SKILLED: - amt *= 0.4; - break; - case PR_EXPERT: - amt *= 0.2; - break; - case PR_MASTER: // no penalty! - amt = 0; - break; - } - } + slev = getskill(lf, SK_ARMOUR); + amt -= (slev*10); + limitf(&amt, 0, NA); + return amt; } @@ -1900,24 +1915,11 @@ int adjustshieldpenalty(lifeform_t *lf, float amt) { case PR_INEPT: amt *= 3; break; - case PR_NOVICE: - break; - case PR_BEGINNER: - amt *= 0.8; - break; - case PR_ADEPT: - amt *= 0.6; - break; - case PR_SKILLED: - amt *= 0.4; - break; - case PR_EXPERT: - amt *= 0.2; - break; - case PR_MASTER: - amt = 0; + default: + amt -= (5*slev); break; } + limitf(&amt, 0, NA); return amt; } @@ -2984,6 +2986,23 @@ skill_t *getobskill(object_t *o) { return NULL; } +enum LFSIZE getobsize(object_t *o) { + flag_t *f; + f = hasflag(o->flags, F_CORPSEOF); + if (f) { + race_t *r; + flag_t *ff; + r = findrace(f->val[0]); + ff = hasflag(r->flags, F_SIZE); + if (ff) { + return ff->val[0]; + } else { + return SZ_MEDIUM; + } + } + return o->type->size; +} + int getobspellpower(object_t *o, lifeform_t *lf) { flag_t *f; int power = 1; @@ -3175,6 +3194,24 @@ int getobtypevalue(objecttype_t *ot) { } */ +char *getoperateverb(object_t *o) { + if (hasflag(o->flags, F_CONTAINER) && (o->type->id != OT_VENDINGMACHINE)) { + return "open"; + } + return "operate"; +} + +// get outermost object in a pile +// ie if you call this on a gem inside a bag inside +// a barrel, will return the barrel. +object_t *getoutercontainer(object_t *o) { + while (o->pile->parentob) { + o = o->pile->parentob; + } + return o; +} + + // ie. "it has xxx accuracy" char *getaccuracyname(int accpct) { if (accpct >= 200) { @@ -3199,9 +3236,9 @@ char *getaccuracyname(int accpct) { } -object_t *getammo(lifeform_t *lf) { +object_t *getammo(object_t *gun) { object_t *o; - o = hasobwithflag(lf->pack, F_CURAMMO); + o = gun->contents->first; return o; } @@ -3694,7 +3731,11 @@ char *getobequipinfo(object_t *o, char *buf) { strcpy(buf, ""); if (o->pile->owner) { - ammo = getammo(o->pile->owner); + object_t *gun; + gun = getfirearm(o->pile->owner); + if (gun) { + ammo = getammo(gun); + } } f = hasflag(o->flags,F_EQUIPPED); @@ -3736,15 +3777,10 @@ char *getobequipinfo(object_t *o, char *buf) { } char *getobextrainfo(object_t *o, char *buf) { - object_t *ammo = NULL; flag_t *f; strcpy(buf, ""); - if (o->pile->owner) { - ammo = getammo(o->pile->owner); - } - // charges f = hasflag(o->flags, F_CHARGES); if (f && f->known) { @@ -3759,6 +3795,11 @@ char *getobextrainfo(object_t *o, char *buf) { } } + // loaded guns + if (isfirearm(o) && getammo(o)) { + strcat(buf, " [loaded]"); + } + // activated if (!hasflag(o->flags, F_ACTIVATEPREFIX)) { f = hasflag(o->flags, F_ACTIVATED); @@ -3771,8 +3812,18 @@ char *getobextrainfo(object_t *o, char *buf) { } cell_t *getoblocation(object_t *o) { - if (o->pile->owner) return o->pile->owner->cell; - else return o->pile->where; + if (o->pile->owner) { // held by someone + return o->pile->owner->cell; + } else if (o->pile->where) { // on the ground + return o->pile->where; + } else if (o->pile->parentob) { // inside another object + object_t *outerob; + // get outside object + outerob = getoutercontainer(o); + return getoblocation(outerob); + } + // in a dummy cell + return NULL; } char *getobname(object_t *o, char *buf, int count) { @@ -3979,20 +4030,33 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan f = hasflag(o->flags, F_CORPSEOF); if (f) { race_t *corpserace; + flag_t *ff; corpserace = findrace(f->val[0]); - if (hasflag(corpserace->flags, F_UNIQUE)) { - sprintf(basename, "%s%s corpse",corpserace->name, getpossessive(corpserace->name)); + ff = hasflag(corpserace->flags, F_NAME); + if (ff) { + sprintf(basename, "%s%s corpse",ff->text, getpossessive(ff->text)); no_a = B_TRUE; } else { sprintf(basename, "%s corpse",corpserace->name); } } - } else if (o->type->id == OT_HEAD) { - f = hasflag(o->flags, F_CORPSEOF); - if (f) { - race_t *corpserace; - corpserace = findrace(f->val[0]); - sprintf(basename, "%s head",corpserace->name); + } else if ((o->type->id == OT_FOUNTAIN) && hasflagval(o->flags, F_LINKOB, NA, NA, B_TRUE, NULL)) { + objecttype_t *ot; + // ie. if fountain type is known + f = hasflag(o->flags, F_LINKOB); + ot = findot(f->val[0]); + if (ot) { + char *srcp; + srcp = ot->name; + // skip first word from potion name. + // ie. we're left with " of xxx" + while (*srcp != ' ') { + srcp++; + } + srcp++; // go past the space + // now copy the rest into buf + strcpy(buf, srcp); + sprintf(basename, "fountain %s",buf); } } else if (o->type->id == OT_STATUE) { f = hasflag(o->flags, F_CORPSEOF); @@ -4299,24 +4363,23 @@ float getobpileweight(obpile_t *op) { char *getobconditionname(object_t *o, char *buf) { float pct; - enum IQBRACKET iqb; + enum ATTRBRACKET iqb; if (player) { - iqb = getiqname(getattr(player, A_IQ), NULL); + iqb = getattrbracket(getattr(player, A_IQ), A_IQ, NULL); } else { - iqb = IQ_AVERAGE; // this should be sufficient to show everything + iqb = AT_AVERAGE; // this should be sufficient to show everything } if (iscorpse(o)) { // you only know it's rotting if you are smart or a cook if (isrotting(o) && - ( (iqb >= IQ_SMART) || getskill(player, SK_COOKING)) ) { + ( (iqb >= AT_GTAVERAGE) || getskill(player, SK_COOKING)) ) { sprintf(buf, "rotting"); } else { strcpy(buf, ""); } } else { - if (iqb >= IQ_DIMWITTED) { - + if (iqb >= AT_LOW) { pct = getobhppct(o); if (pct >= 100) { @@ -4428,7 +4491,7 @@ objecttype_t *getoppositestairs(objecttype_t *ot) { return findot(f->val[0]); } -char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat) { +char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat, enum LFSIZE maxsize) { objecttype_t *ot; objecttype_t *poss[MAXRANDOMOBCANDIDATES]; int nposs = 0; @@ -4476,6 +4539,9 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth oc = findoc(cval); dblog(" (must have obclass = %s)",oc->name); break; + case RO_HOLDABLE: + dblog(" (must be holdable)",oc->name); + break; } } @@ -4518,10 +4584,14 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth if (ot->obclass->id == cval) { condok = B_TRUE; } + } else if (cond == RO_HOLDABLE) { + if (!hasflag(ot->flags, F_NOPICKUP)) { + condok = B_TRUE; + } } } - if (rarok && condok) { + if (rarok && condok && (ot->size <= maxsize)) { if (db) dblog("-> possibility: %s, rarity=%d",ot->name, rarflag->val[1]); poss[nposs] = ot; nposs++; @@ -4644,17 +4714,21 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth } char *getrandomob(map_t *map, char *buf) { - return real_getrandomob(map, buf, RO_NONE, NA, NA, NA); + return real_getrandomob(map, buf, RO_NONE, NA, NA, NA, SZ_MAX); +} + +char *getrandomobofsize(map_t *map, char *buf, enum LFSIZE maxsize) { + return real_getrandomob(map, buf, RO_NONE, NA, NA, NA, maxsize); } char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf) { - return real_getrandomob(map, buf, RO_DAMTYPE, damtype, NA, NA); + return real_getrandomob(map, buf, RO_DAMTYPE, damtype, NA, NA, SZ_MAX); } char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod) { //return real_getrandomob(map, buf, RO_OBCLASS, cid, map->depth + depthmod); if (depthmod == NA) depthmod = 0; - return real_getrandomob(map, buf, RO_OBCLASS, cid, getmapdifficulty(map) + depthmod, NA); + return real_getrandomob(map, buf, RO_OBCLASS, cid, getmapdifficulty(map) + depthmod, NA, SZ_MAX); } int getobrarity(object_t *o, enum RARITY *rr) { @@ -4708,6 +4782,7 @@ char *getschoolname(enum SPELLSCHOOL sch) { case SS_ABILITY: return "Abilities"; case SS_ALLOMANCY: return "Allomancy"; case SS_DIVINE: return "Divine Powers"; + case SS_ENCHANTMENT: return "Enchantments"; case SS_WILD: return "Wild Magic"; case SS_MENTAL: return "Psionic Powers"; case SS_AIR: return "Elemental/Air Magic"; @@ -4738,6 +4813,7 @@ char *getschoolnameshort(enum SPELLSCHOOL sch) { case SS_FIRE: return "Fire Magic"; case SS_COLD: return "Cold Magic"; case SS_DEATH: return "Necromancy"; + case SS_ENCHANTMENT: return "Enchantment"; case SS_LIFE: return "Life Magic"; case SS_MENTAL: return "Psionic Powers"; case SS_MODIFICATION: return "Modification"; @@ -5276,6 +5352,7 @@ void initobjects(void) { addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_WATER, NA, NA, "goes soggy"); addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy"); addflag(lastmaterial->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); + addflag(lastmaterial->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addmaterial(MT_SILK, "silk", 1); addflag(lastmaterial->flags, F_FLAMMABLE, 6, NA, NA, NULL); addflag(lastmaterial->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); // doesn't catch on fire, but IS vulnerable to it @@ -5287,6 +5364,7 @@ void initobjects(void) { addflag(lastmaterial->flags, F_FLAMMABLE, 3, NA, NA, NULL); addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL); addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL); + addflag(lastmaterial->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); // doesn't catch on fire, but IS vulnerable to it addmaterial(MT_FOOD, "food", 3); addmaterial(MT_PLASTIC, "plastic", 3); addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL); @@ -5330,12 +5408,15 @@ void initobjects(void) { addmaterial(MT_GLASS, "glass", 13); addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL); addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL); + addflag(lastmaterial->flags, F_DTVULN, DT_COLD, NA, NA, NULL); addmaterial(MT_GOLD, "gold", 16); addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL); //addmaterial(MT_GOLD, "gold", 16); // object classes addoc(OC_DFEATURE, "Dungeon Features", "Doors, etc.", '\\', C_GREY); + addoc(OC_FURNITURE, "Furniture", "Various kinds of mundane (or not so mundane) furnishings.", '\\', C_BROWN); + addocnoun(lastobjectclass, "furniture"); addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY); addoc(OC_TRAP, "Trap", "Fiendish traps.", '^', C_GREY); addocnoun(lastobjectclass, "trap"); @@ -5431,7 +5512,7 @@ void initobjects(void) { // object types // dungeon features - addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 150, OC_DFEATURE); + addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 150, OC_DFEATURE, SZ_LARGE); // GLYPH here is a special case in getglyph addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); @@ -5444,7 +5525,7 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE); + addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE, SZ_LARGE); // GLYPH here is a special case in getglyph addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); @@ -5458,8 +5539,22 @@ void initobjects(void) { addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL); addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL); + + addot(OT_FOUNTAIN, "fountain", "A running fountain of some kind of liquid.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); + addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "_"); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice"); + addflag(lastot->flags, F_DTCREATEOB, DT_FIRE, 0, DT_COMPASS, "cloud of steam"); + addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, B_DONTKILL, NULL); + addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL); + // blocks movement, but you can see and fire through them. - addot(OT_GATEIRON, "iron gate", "A gate comprised of a series of vertical iron bars, raised slightly above the floor.", MT_METAL, 500, OC_DFEATURE); + addot(OT_GATEIRON, "iron gate", "A gate comprised of a series of vertical iron bars, raised slightly above the floor.", MT_METAL, 500, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "+"); addflag(lastot->flags, F_DOOR, SZ_MEDIUM, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, SZ_MAX, NA, NULL); @@ -5471,7 +5566,7 @@ void initobjects(void) { addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL); addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL); - addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE); + addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "+"); addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); @@ -5482,7 +5577,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_FENCEWOOD, "wooden fence", "A tell fence created from a series of upright logs of wood.", MT_WOOD, 200, OC_DFEATURE); + addot(OT_FENCEWOOD, "wooden fence", "A tell fence created from a series of upright logs of wood.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL); @@ -5492,7 +5587,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK); + addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); @@ -5507,7 +5602,7 @@ void initobjects(void) { addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones"); - addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK); + addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "'"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL); @@ -5516,7 +5611,7 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); - addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK); + addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, ""); addflag(lastot->flags, F_RARITY, H_VILLAGE, 80, NA, ""); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'"); @@ -5529,7 +5624,7 @@ void initobjects(void) { addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "20-50 stones"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "a statue"); - addot(OT_HOLEINGROUND, "hole in the ground", "A gaping hole in the ground.", MT_NOTHING, 0, OC_DFEATURE); + addot(OT_HOLEINGROUND, "hole in the ground", "A gaping hole in the ground.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "^"); addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL); @@ -5539,7 +5634,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); - addot(OT_HOLEINROOF, "hole in the roof", "A gaping hole in the roof.", MT_NOTHING, 0, OC_DFEATURE); + addot(OT_HOLEINROOF, "hole in the roof", "A gaping hole in the roof.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "<"); addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL); addflag(lastot->flags, F_PIT, D_UP, NA, NA, NULL); @@ -5548,27 +5643,40 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); - addot(OT_STAIRSDOWN, "staircase going down", "A stone staircase winding downwards.", MT_STONE, 3000, OC_DFEATURE); + addot(OT_STAIRSDOWN, "staircase going down", "A stone staircase winding downwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ">"); addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL); addflag(lastot->flags, F_OPPOSITESTAIRS, OT_STAIRSUP, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); - addot(OT_STAIRSUP, "staircase going up", "A stone staircase climbing upwards.", MT_STONE, 3000, OC_DFEATURE); + addot(OT_STAIRSUP, "staircase going up", "A stone staircase climbing upwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "<"); addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL); addflag(lastot->flags, F_OPPOSITESTAIRS, OT_STAIRSDOWN, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); - addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_DFEATURE); + addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "_"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + // 10 random objects + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); - addot(OT_HOLYCIRCLE, "holy circle", "A consecrated area imbued with holy power.", MT_NOTHING, 0, OC_DFEATURE); + addot(OT_HOLYCIRCLE, "holy circle", "A consecrated area imbued with holy power.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, ""); addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "_"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); @@ -5577,7 +5685,7 @@ void initobjects(void) { addflag(lastot->flags, F_REPELBLESSED, B_CURSED, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_PENTAGRAM, "pentagram", "A area imbued with evil.", MT_NOTHING, 0, OC_DFEATURE); + addot(OT_PENTAGRAM, "pentagram", "A area imbued with evil.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, ""); addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "_"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); @@ -5587,7 +5695,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE); + addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "&"); addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); @@ -5595,7 +5703,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); // terrain - addot(OT_WATERDEEP, "water", "Deep water.", MT_WATER, 300, OC_TERRAIN); + addot(OT_WATERDEEP, "water", "Deep water.", MT_WATER, 300, OC_TERRAIN, SZ_HUGE); 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, "{"); @@ -5608,7 +5716,7 @@ void initobjects(void) { addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); // traps - addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 10, B_FALSE, 20, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5616,7 +5724,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "."); addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL); - addot(OT_TRAPROCK, "falling rock trap", "A pressure plate which causes heavy rocks to drop from the ceiling.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPROCK, "falling rock trap", "A pressure plate which causes heavy rocks to drop from the ceiling.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 20, B_TRUE, 22, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5626,7 +5734,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPTELEPORT, "teleportation trap", "A magical dispersal field.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPTELEPORT, "teleportation trap", "A magical dispersal field.", MT_NOTHING, 0, OC_TRAP, SZ_LARGE); addflag(lastot->flags, F_TRAP, NA, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, "^"); @@ -5636,7 +5744,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5646,7 +5754,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5656,7 +5764,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 27, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5666,7 +5774,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -5676,7 +5784,7 @@ void initobjects(void) { addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_TRAP); + addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 20, NA, NULL); @@ -5689,28 +5797,28 @@ void initobjects(void) { // money etc - addot(OT_GOLD, "gold coin", "Sparkling nuggets of gold, the standard currency of Nexus.", MT_GOLD, 0.01, OC_MONEY); + addot(OT_GOLD, "gold coin", "Sparkling nuggets of gold, the standard currency of Nexus.", MT_GOLD, 0.01, OC_MONEY, SZ_MINI); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 100, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some gold"); - addot(OT_STONE, "stone", "A medium-sized roundish stone.", MT_STONE, 0.5, OC_ROCK); + addot(OT_STONE, "stone", "A medium-sized roundish stone.", MT_STONE, 0.5, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK); + addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); - addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK); + addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "1d6"); @@ -5719,7 +5827,7 @@ void initobjects(void) { addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); - addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK); + addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, ""); @@ -5728,7 +5836,7 @@ void initobjects(void) { addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_ASHSLEEP, "pile of sleeping powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK); + addot(OT_ASHSLEEP, "pile of sleeping powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, ""); @@ -5736,7 +5844,7 @@ void initobjects(void) { addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); - addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK); + addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK, SZ_TINY); addflag(lastot->flags, F_HOLDCONFER, F_XRAYVIS, 2, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_SEEINVIS, B_TRUE, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_ENHANCESEARCH, 20, NA, NULL); @@ -5745,21 +5853,21 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); // flora - addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA); + addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, ","); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); - addot(OT_LEAF, "leaf", "A fallen leaf from a tree.", MT_PLANT, 0.01, OC_FLORA); + addot(OT_LEAF, "leaf", "A fallen leaf from a tree.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ","); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); - addot(OT_MISTLETOE, "sprig of mistletoe", "A small cutting of mistletoe.", MT_PLANT, 0.01, OC_FLORA); + addot(OT_MISTLETOE, "sprig of mistletoe", "A small cutting of mistletoe.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "leaf"); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); @@ -5767,7 +5875,7 @@ void initobjects(void) { addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 50, OC_FLORA); + addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 50, OC_FLORA, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MEDIUM, NA, NULL); @@ -5777,7 +5885,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_STUMP, "stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA); + addot(OT_STUMP, "stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "'"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL); @@ -5786,7 +5894,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA); + addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA, SZ_LARGE); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "#"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); @@ -5800,163 +5908,176 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); // food - addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD); + addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 8, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, ""); - addot(OT_NUT, "peanut", "A species in the legume family.", MT_FOOD, 0.1, OC_FOOD); + addot(OT_NUT, "peanut", "A species in the legume family.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 12, NA, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, ""); - addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD); + addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 80, NA, NULL); - addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD); + addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL); addflag(lastot->flags, F_SLIPMOVE, 15, NA, NA, NULL); - addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL); - addot(OT_MUSHROOM, "mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD); + addot(OT_MUSHROOM, "mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); - addot(OT_BREADSTALE, "loaf of stale bread", "A small loaf of old, stale bread.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_BREADSTALE, "loaf of stale bread", "A small loaf of old, stale bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 80, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread"); - addot(OT_CHEESE, "chunk of cheese", "A chunk of hard cheese.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_CHEESE, "chunk of cheese", "A chunk of hard cheese.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 85, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); - addot(OT_STEW, "stew", "Some kind of meat soaked in water.", MT_FOOD, 1.5, OC_FOOD); + addot(OT_STEW, "stew", "Some kind of meat soaked in water.", MT_FOOD, 1.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); - addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD); // weight normally comes from corpse type + addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); - addot(OT_BREADFRESH, "loaf of fresh bread", "A freshly-baked loaf of bread.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_BREADFRESH, "loaf of fresh bread", "A freshly-baked loaf of bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread"); - addot(OT_CLOVER, "four leafed clover", "A rare 4-leafed clover.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_CLOVER, "four leafed clover", "A rare 4-leafed clover.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 65, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_EXTRALUCK, 1, NA, NULL); - addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD); + addot(OT_CARROT, "carrot", "A stout orange carrot. Rumour has it that carrots are good for your eyesight.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); + addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "%"); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, ""); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL); + addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 110, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL); // corpses - addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE); + addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY); addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); - addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE); + addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_SMALL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); - addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD); + addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD, SZ_SMALL); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); // potions (sorted by rarity) - addot(OT_POT_JUICE, "potion of fruit juice", "Tasty (but not very fresh) fruit juice!", MT_GLASS, 1, OC_POTION); + addot(OT_POT_JUICE, "potion of fruit juice", "Tasty (but not very fresh) fruit juice!", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); - addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water"); sethiddenname(lastot, "clear potion"); - addot(OT_POT_HEALING, "potion of healing", "Restores 10-20 health to whoever drinks it.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_HEALING, "potion of healing", "Restores 10-20 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_HEALINGMAJ, "potion of major healing", "Restores 20-30 health to whoever drinks it.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_HEALINGMAJ, "potion of major healing", "Restores 20-30 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 72, NA, NULL); addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_OIL, "potion of oil", "A bottle of cooking oil.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_OIL, "potion of oil", "A bottle of cooking oil.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of oil"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_RUM, "potion of rum", "String liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(lastot->flags, F_EXPLODEONDAM, DT_FIRE, NA, NA, "2d4"); + addot(OT_POT_COFFEE, "potion of coffee", "A caffeinated beverage prepared from coffee beans.", MT_GLASS, 1, OC_POTION, SZ_TINY); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL); + addot(OT_POT_RUM, "potion of rum", "Strong liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL); addflag(lastot->flags, F_FLAMMABLE, 1, NA, NA, "medium fire"); + addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastot->flags, F_EXPLODEONDAM, DT_FIRE, NA, NA, "2d6"); - addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); - addot(OT_POT_SLEEP, "potion of sleep", "Puts the drinker into a deep sleep.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_SLEEP, "potion of sleep", "Puts the drinker into a deep sleep.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_SPEED, "potion of haste", "Temporarily increasees the drinker's speed.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_SPEED, "potion of haste", "Temporarily increasees the drinker's speed.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_MAGIC, "potion of magic", "Fully restores the drinker's magical energy.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_LEVITATION, "potion of levitation", "Causes the drinker to float up in the air.", MT_GLASS, 1, OC_POTION, SZ_TINY); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 78, NA, NULL); + addot(OT_POT_MAGIC, "potion of magic", "Fully restores the drinker's magical energy.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_ACROBATICS, "potion of acrobatics", "Allows the drinker to leap large distances.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_ACROBATICS, "potion of acrobatics", "Allows the drinker to leap large distances.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); - addot(OT_POT_INVIS, "potion of invisibility", "Temporarily renders the drinker invisible.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_INVIS, "potion of invisibility", "Temporarily renders the drinker invisible.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_POISON, "potion of poison", "Poisons the drinker.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_POISON, "potion of poison", "Poisons the drinker.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_ACID, "flask of battery acid", "Causes massive internal burning if ingested.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_ACID, "flask of battery acid", "Causes massive internal burning if ingested.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of acid"); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_ELEMENTIMMUNE, "potion of elemental immunity", "Grants the imbiber temporary immunity to both fire and cold.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_ELEMENTIMMUNE, "potion of elemental immunity", "Grants the imbiber temporary immunity to both fire and cold.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); - addot(OT_POT_BLOOD, "potion of blood", "A small quantity of blood.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_BLOOD, "potion of blood", "A small quantity of blood.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of blood"); - addot(OT_POT_SANCTUARY, "potion of sanctuary", "Creates a temporary magical barrier abour the drinker.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_SANCTUARY, "potion of sanctuary", "Creates a temporary magical barrier abour the drinker.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); - addot(OT_POT_ETHEREALNESS, "potion of etherealness", "Allows the walker to temporarily pass through walls.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_ETHEREALNESS, "potion of etherealness", "Allows the walker to temporarily pass through walls.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); - addot(OT_POT_EXPERIENCE, "potion of experience", "Instantly grants the imbiber the next experience level.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_EXPERIENCE, "potion of experience", "Instantly grants the imbiber the next experience level.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, 40, NA, NULL); - addot(OT_POT_BLOODC, "potion of cockatrice blood", "A small quantity of cockatrice blood.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_BLOODC, "potion of cockatrice blood", "A small quantity of cockatrice blood.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of cockatrice blood"); - addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's strength, intelligence or dexterity.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's strength, intelligence or dexterity.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); - addot(OT_POT_GASEOUSFORM, "potion of gaseous form", "Turns the drinker into a cloud of gas.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_GASEOUSFORM, "potion of gaseous form", "Turns the drinker into a cloud of gas.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_POLYMORPH, "potion of polymorph self", "Transmutes the drinker into another living race.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_POLYMORPH, "potion of polymorph self", "Transmutes the drinker into another living race.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); - addot(OT_POT_INVULN, "potion of invulnerability", "Grants the drinker temporary immunity to physical harm.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_INVULN, "potion of invulnerability", "Grants the drinker temporary immunity to physical harm.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); - addot(OT_POT_AMBROSIA, "vial of ambrosia", "The nectar of the gods, said to completely restore the drinker's health.", MT_GLASS, 1, OC_POTION); + addot(OT_POT_AMBROSIA, "vial of ambrosia", "The nectar of the gods, said to completely restore the drinker's health.", MT_GLASS, 1, OC_POTION, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 35, NA, NULL); addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL); @@ -5965,97 +6086,97 @@ void initobjects(void) { // scrolls - addot(OT_SCR_REMOVECURSE, "scroll of remove curse", "Removes curses from all weilded equipment.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_REMOVECURSE, "scroll of remove curse", "Removes curses from all weilded equipment.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); - addot(OT_SCR_IDENTIFY, "scroll of identify", "Completely identifies any one item.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_IDENTIFY, "scroll of identify", "Completely identifies any one item.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_IDENTIFY, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); - addot(OT_SCR_MENDING, "scroll of mending", "Repairs damage to objects.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_MENDING, "scroll of mending", "Repairs damage to objects.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_MENDING, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 98, RR_UNCOMMON, NULL); addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); - addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 84, RR_UNCOMMON, NULL); - addot(OT_GRAPHPAPER, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_GRAPHPAPER, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); - addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); - addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, 4, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_SCR_DETECTAURA, "scroll of detect aura", "Senses holiness or evil near the caster.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_DETECTAURA, "scroll of detect aura", "Senses holiness or evil near the caster.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTAURA, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, RR_UNCOMMON, NULL); - addot(OT_SCR_DETECTLIFE, "scroll of detect life", "Senses life near the caster.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_DETECTLIFE, "scroll of detect life", "Senses life near the caster.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTLIFE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, RR_UNCOMMON, NULL); - addot(OT_SCR_DETECTOBS, "scroll of detect objects", "Senses objects near the caster.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_DETECTOBS, "scroll of detect objects", "Senses objects near the caster.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTOBS, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, RR_UNCOMMON, NULL); - addot(OT_SCR_DETECTMAGIC, "scroll of detect magic", "Allows the reader to detect magical enchantments.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_DETECTMAGIC, "scroll of detect magic", "Allows the reader to detect magical enchantments.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTMAGIC, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); - addot(OT_SCR_FLAMEPILLAR, "scroll of flame pillar", "Creates a tall pillar of flame.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_FLAMEPILLAR, "scroll of flame pillar", "Creates a tall pillar of flame.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEPILLAR, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); - addot(OT_SCR_FLAMEBURST, "scroll of flame burst", "Creates a radial blast of fire out from the caster, dealing 2d6 damage. Range is based on spell power.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_FLAMEBURST, "scroll of flame burst", "Creates a radial blast of fire out from the caster, dealing 2d6 damage. Range is based on spell power.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEBURST, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_UNCOMMON, NULL); - addot(OT_SCR_ENCHANT, "scroll of enchantment", "Magically enhances a weapon or piece of armour.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_ENCHANT, "scroll of enchantment", "Magically enhances a weapon or piece of armour.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_ENCHANT, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_UNCOMMON, NULL); - addot(OT_SCR_FREEZEOB, "scroll of freezing touch", "Permenantly changes the next object touched into solid ice.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_FREEZEOB, "scroll of freezing touch", "Permenantly changes the next object touched into solid ice.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_FREEZEOB, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_UNCOMMON, NULL); - addot(OT_SCR_KNOCK, "scroll of knock", "Magically opens a barrier.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_KNOCK, "scroll of knock", "Magically opens a barrier.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_KNOCK, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); - addot(OT_SCR_LIGHT, "scroll of light", "Creates a permenant light source centred on the caster.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_LIGHT, "scroll of light", "Creates a permenant light source centred on the caster.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_COMMON, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_SCR_MAPPING, "scroll of sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_MAPPING, "scroll of sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, 4, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); - addot(OT_SCR_MINDSCAN, "scroll of mind scan", "Reveals detailed information about the target.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_MINDSCAN, "scroll of mind scan", "Reveals detailed information about the target.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_MINDSCAN, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_UNCOMMON, NULL); - addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_RARE, NULL); - addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, 4, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, RR_COMMON, NULL); - addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_UNCOMMON, NULL); - addot(OT_SCR_WISH, "scroll of wishing", "Grants the caster any item of their choice (with some limitations).", MT_PAPER, 0.5, OC_SCROLL); + addot(OT_SCR_WISH, "scroll of wishing", "Grants the caster any item of their choice (with some limitations).", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addflag(lastot->flags, F_LINKSPELL, OT_S_WISH, NA, NA, NULL); @@ -6066,34 +6187,34 @@ void initobjects(void) { // allomancy /////////////////// // l1 - addot(OT_S_ABSORBMETAL, "absorb metal", "Draws mana from nearby metallic objects.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ABSORBMETAL, "absorb metal", "Draws mana from nearby metallic objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MPCOST, 0, NA, NA, NULL); // l2 - addot(OT_S_PULLMETAL, "pull metal", "Pulls metal objects to the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PULLMETAL, "pull metal", "Pulls metal objects to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); - addot(OT_S_ACCELMETAL, "accelerate metal", "Greatly accelerates a metal object thrown by the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ACCELMETAL, "accelerate metal", "Greatly accelerates a metal object thrown by the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_WALLSTOP, NA, NULL); - addot(OT_S_METALHEAL, "metal healing", "Uses nearby metal for accelerated healing.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_METALHEAL, "metal healing", "Uses nearby metal for accelerated healing.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); // l3 - addot(OT_S_EXPLODEMETAL, "explode metal", "Causes all metal objects in a location explode.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_EXPLODEMETAL, "explode metal", "Causes all metal objects in a location explode.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_MAGSHIELD, "magnetic shield", "Surrounds the caster with magnetic force, repelling metal objects and attacks.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MAGSHIELD, "magnetic shield", "Surrounds the caster with magnetic force, repelling metal objects and attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); // l4 - addot(OT_S_ANIMATEMETAL, "animate metal", "Imbues a metallic weapon with temporary life, enabling it to fight on its own.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ANIMATEMETAL, "animate metal", "Imbues a metallic weapon with temporary life, enabling it to fight on its own.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); @@ -6102,74 +6223,81 @@ void initobjects(void) { // death /////////////////// // l1 - addot(OT_S_STENCH, "stench", "Nauseates the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_STENCH, "stench", "Nauseates the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, 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_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 - addot(OT_S_BLINDNESS, "blindness", "Temporarily blinds the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BLINDNESS, "blindness", "Temporarily blinds the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_COMMANDUNDEAD, "command undead", "Compels an undead creature to follow a single simple command.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_COMMANDUNDEAD, "command undead", "Compels an undead creature to follow a single simple command.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_FEAR, "cause fear", "Causes intense fear in the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FEAR, "cause fear", "Causes intense fear in the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 - addot(OT_S_POISONBOLT, "poison bolt", "Fires a glob of venom at the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_POISONBOLT, "poison bolt", "Fires a glob of venom at the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); - addot(OT_S_DRAINLIFE, "drain life", "Draws life force from the victim in order to heal the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DRAINLIFE, "drain life", "Draws life force from the victim in order to heal the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); - addot(OT_S_PAIN, "pain", "Causes extreme pain in the target whenever they move.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PAIN, "pain", "Causes extreme pain in the target whenever they move.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 - addot(OT_S_WEAKEN, "weaken", "Temporarily lowers the target's muscle strength.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WEAKEN, "weaken", "Temporarily lowers the target's muscle strength.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_PARALYZE, "paralyze", "Disables the target's muscles, leaving them unable to move.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PARALYZE, "paralyze", "Disables the target's muscles, leaving them unable to move.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); // TODO: should be "castnearob ot_corpse" addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); // l5 - addot(OT_S_FEEBLEMIND, "feeblemind", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FEEBLEMIND, "feeblemind", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l7 - addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l8 - addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL); addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL); @@ -6178,62 +6306,72 @@ void initobjects(void) { // divination /////////////////// // l1 - addot(OT_S_DETECTLIFE, "detect life", "Senses the size of creatures near the caster. At Power V, it will detect exact creature types.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETECTLIFE, "detect life", "Senses the size of creatures near the caster. At Power V, it will detect exact creature types.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); // l2 - addot(OT_S_LOCATEOBJECT, "locate object", "Locates any object within an area the caster has previously travelled.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LOCATEOBJECT, "locate object", "Locates any object within an area the caster has previously travelled.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); - addot(OT_S_SEEINVIS, "see invisible", "Allows the caster to see invisible creatures.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SEEINVIS, "see invisible", "Allows the caster to see invisible creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); - addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); // l3 - addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); - addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); - addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); // l4 - addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); // l8 - addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL); + + /////////////////// + // enchantment + /////////////////// + // l7 + addot(OT_S_ENCHANT, "enchantment", "Magically enhances a weapon or piece of armour.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); + // TODO: hardcode how ai casts this spell + /////////////////// // elemental - air /////////////////// // l1 - addot(OT_S_MIST, "obscuring mist", "Hides the caster from view with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MIST, "obscuring mist", "Hides the caster from view with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_ADJSELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_CALLWIND, "call wind", "Conjures a friendly wind, carrying a single object to the caster's hands.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CALLWIND, "call wind", "Conjures a friendly wind, carrying a single object to the caster's hands.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); - addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); 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); @@ -6242,27 +6380,27 @@ void initobjects(void) { 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); + addot(OT_S_GUSTOFWIND, "gust of wind", "Causes a gust of wind to blow the target's objects away.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); - addot(OT_S_SHATTER, "shatter", "Instantly shatters all glass in the target location.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SHATTER, "shatter", "Instantly shatters all glass in the target location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 - addot(OT_S_AIRBLAST, "airblast", "Knocks enemies back with a powerful blast of air.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_AIRBLAST, "airblast", "Knocks enemies back with a powerful blast of air.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); - addot(OT_S_WINDSHIELD, "cyclonic shield", "Surrounds the caster with a whirling cyclone to repel missiles.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WINDSHIELD, "cyclonic shield", "Surrounds the caster with a whirling cyclone to repel missiles.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); @@ -6270,12 +6408,12 @@ void initobjects(void) { addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); // l4 - addot(OT_S_CLOUDKILL, "cloudkill", "Creates a cloud of poisonous gas.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CLOUDKILL, "cloudkill", "Creates a cloud of poisonous gas.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l5 - addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs between all nearby enemies.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs between all nearby enemies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); @@ -6284,44 +6422,45 @@ void initobjects(void) { // elemental - fire /////////////////// // l1 - addot(OT_S_SPARK, "spark", "Creates a tiny spark of flame, dealing 1-3 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SPARK, "spark", "Creates a tiny spark of flame, dealing 1-3 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 - addot(OT_S_BLADEBURN, "bladeburn", "Ignites the target's bladed weapon, causing it to temporarily deal fire damage.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BLADEBURN, "bladeburn", "Ignites the target's bladed weapon, causing it to temporarily deal fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); 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_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+power fire damage.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+power fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l3 - addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); // l4 - addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); // l5 - addot(OT_S_BURNINGWAVE, "burning wave", "Fire bursts from the ground in a line towards the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BURNINGWAVE, "burning wave", "Fire bursts from the ground in a line towards the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); - addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim" @@ -6330,46 +6469,47 @@ void initobjects(void) { // elemental - ice /////////////////// // l1 - addot(OT_S_FROSTBITE, "frostbite", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FROSTBITE, "frostbite", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 - addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); - addot(OT_S_ICEEDGE, "ice edge", "Enhances the edge of a bladed weapon with a layer of ice.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ICEEDGE, "ice edge", "Enhances the edge of a bladed weapon with a layer of ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); 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_COLDRAY, "cold ray", "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, SZ_TINY); 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); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l3 - addot(OT_S_COLDBURST, "cold burst", "Creates a radial blast of coldness out from the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_COLDBURST, "cold burst", "Creates a radial blast of coldness out from the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); - addot(OT_S_ICICLE, "icicle", "A huge icicle rises form the ground, knocking enemies away and blocking passage.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ICICLE, "icicle", "A huge icicle rises form the ground, knocking enemies away and blocking passage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 - addot(OT_S_CHILL, "chill", "Deals 3-24 cold damage to target creature per exposed body part.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CHILL, "chill", "Deals 3-24 cold damage to target creature per exposed body part.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_WALLOFICE, "wall of ice", "Creates an impassable wall of solid ice.", MT_ICE, 0, OC_SPELL); + addot(OT_S_WALLOFICE, "wall of ice", "Creates an impassable wall of solid ice.", MT_ICE, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); @@ -6378,129 +6518,132 @@ void initobjects(void) { // nature /////////////////// // l1 - addot(OT_S_CALMANIMALS, "calm animals", "Makes animals within the casters line of sight become peaceful.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CALMANIMALS, "calm animals", "Makes animals within the casters line of sight become peaceful.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); - addot(OT_S_DETECTPOISON, "detect poison", "Detects any poisoned object in sight of the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETECTPOISON, "detect poison", "Detects any poisoned object in sight of the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_PURIFYFOOD, "purify food", "Removes rot or poison from food or drink.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PURIFYFOOD, "purify food", "Removes rot or poison from food or drink.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_STICKTOSNAKE, "sticks to snakes", "Transforms all seen wooden weapons into snakes.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_STICKTOSNAKE, "sticks to snakes", "Transforms all seen wooden weapons into snakes.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); // l2 - addot(OT_S_BARKSKIN, "barkskin", "Covers the caster with a skin of bark, reducing damage but making them vulnerable to fire.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BARKSKIN, "barkskin", "Covers the caster with a skin of bark, reducing damage but making them vulnerable to fire.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); - addot(OT_S_CHARMANIMAL, "befriend animal", "Temporarily makes a single animal friendly to you.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CHARMANIMAL, "befriend animal", "Temporarily makes a single animal friendly to you.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_LESSENPOISON, "lessen poison", "Reduces the effects of poison within the caster's bloodstream.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LESSENPOISON, "lessen poison", "Reduces the effects of poison within the caster's bloodstream.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_REPELINSECTS, "repel insects", "Surrounds the caster with an insect-repelling smell.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_REPELINSECTS, "repel insects", "Surrounds the caster with an insect-repelling smell.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_SOFTENEARTH, "soften earth", "Converts earth into mud, slowing down.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SOFTENEARTH, "soften earth", "Converts earth into mud, slowing down.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, 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_WARPWOOD, "warp wood", "Causes damage to all wooden object in the target area.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WARPWOOD, "warp wood", "Causes damage to all wooden object in the target area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 - addot(OT_S_CALLLIGHTNING, "call lightning", "Blasts a single enemy with a bolt of lightning from the sky.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CALLLIGHTNING, "call lightning", "Blasts a single enemy with a bolt of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_LIGHTNINGBOLT, "lightning bolt", "Fires electricity through multiple enemies.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LIGHTNINGBOLT, "lightning bolt", "Fires electricity through multiple enemies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); - addot(OT_S_ENDUREELEMENTS, "endure elements", "Provides resistance to fire and cold.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ENDUREELEMENTS, "endure elements", "Provides resistance to fire and cold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, 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_QUENCH, "quench", "Extinguishes all fires within the given area.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_QUENCH, "quench", "Extinguishes all fires within the given area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_EVAPORATE, "evaporate", "Instantly converts all water in the given area into steam.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_EVAPORATE, "evaporate", "Instantly converts all water in the given area into steam.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_THORNS, "thorns", "Sharp thorns grow from your skin, dealing 1d4 damage to attackers.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_THORNS, "thorns", "Sharp thorns grow from your skin, dealing 1d4 damage to attackers.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_WEB, "web", "Slows down pursuers with a burst of sticky spider web.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WEB, "web", "Slows down pursuers with a burst of sticky spider web.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); // l4 - addot(OT_S_DIG, "dig", "Blasts away earth to create passages.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DIG, "dig", "Blasts away earth to create passages.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_ENTANGLE, "entangle", "Causes magical vines to hold enemies.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ENTANGLE, "entangle", "Causes magical vines to hold enemies.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_CALMINGSCENT, "calming scent", "Automatically calms any nearby animals.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CALMINGSCENT, "calming scent", "Automatically calms any nearby animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); - addot(OT_S_CUREPOISON, "cure poison", "Cures the target of all poisons.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CUREPOISON, "cure poison", "Cures the target of all poisons.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_HAILSTORM, "hail storm", "Creates an intense storm of hail, causing damage to all within.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HAILSTORM, "hail storm", "Creates an intense storm of hail, causing damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); @@ -6508,28 +6651,28 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, 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_WATERJET, "water spray", "Fires a high pressure blast of water from the caster's hands.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WATERJET, "water spray", "Fires a high pressure blast of water from the caster's hands.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l6 - addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); - addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); 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); + addot(OT_S_FLOOD, "flood", "Converts the earth directly into water, creating a deep pool.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); 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); @@ -6537,38 +6680,42 @@ void initobjects(void) { // gravity /////////////////// // l1 - addot(OT_S_TRUESTRIKE, "true strike", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_TRUESTRIKE, "true strike", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); // l3 - addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); // l4 - addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); - addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); // l5 // l6 - addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); - addot(OT_S_HASTE, "haste", "Increases the speed of the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HASTE, "haste", "Increases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); @@ -6577,17 +6724,17 @@ void initobjects(void) { // life /////////////////// // l1 - addot(OT_S_HEALINGMIN, "minor healing", "Restores 1-8 health to the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HEALINGMIN, "minor healing", "Restores 1-8 health to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_TURNUNDEAD, "turn undead", "Instills fear in undead creatures. Power depends on caster's skill.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_TURNUNDEAD, "turn undead", "Instills fear in undead creatures. Power depends on caster's skill.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); // l3 - addot(OT_S_HEALING, "healing", "Restores 10-20 health to the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HEALING, "healing", "Restores 10-20 health to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); @@ -6597,40 +6744,48 @@ void initobjects(void) { // mental/psionic /////////////////// // l1 - addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 - addot(OT_S_SLEEP, "sleep", "Puts the target creature to sleep.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BODYCONTROL, "body control", "Slow your body's functions, decreasing your rate of hunger but also your speed. At power level V your speed is no longer affected.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); + addot(OT_S_SLEEP, "sleep", "Puts the target creature to sleep.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_TELEKINESIS, "telekinesis", "Mentally move or manipulate nearby objects.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_TELEKINESIS, "telekinesis", "Mentally move or manipulate nearby objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); // l3 - addot(OT_S_PSYARMOUR, "psychic armour", "Mentally block incoming attacks.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PSYARMOUR, "psychic armour", "Mentally block incoming attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); // TODO: hardcode how ai casts this - // l4 - addot(OT_S_PACIFY, "pacify", "Induces calmness in another, preventing them from attacking.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PACIFY, "pacify", "Induces calmness in another, preventing them from attacking.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); - addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL); + // l4 + addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_HEALINGMAJ, "major healing", "Restores 20-30 health to the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HEALINGMAJ, "major healing", "Restores 20-30 health to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); @@ -6640,82 +6795,81 @@ void initobjects(void) { // modification /////////////////// // l1 - addot(OT_S_HOLDPORTAL, "hold portal", "Prevents a door from opening.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_HOLDPORTAL, "hold portal", "Prevents a door from opening.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_INSCRIBE, "inscribe", "Creates a magical inscription viewable to anyone standing nearby.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_INSCRIBE, "inscribe", "Creates a magical inscription viewable to anyone standing nearby.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); - addot(OT_S_KNOCK, "knock", "Magically opens doors or other such barriers.\nAt Power VII, this spell will also knock back living creatures.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_KNOCK, "knock", "Magically opens doors or other such barriers.\nAt Power VII, this spell will also knock back living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_LIGHT, "light area", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_LIGHT, "light area", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); - addot(OT_S_MENDING, "mending", "Repairs minor damage to objects.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MENDING, "mending", "Repairs minor damage to objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); // l2 - addot(OT_S_GREASE, "grease", "Creates a large pool of greasy oil.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GREASE, "grease", "Creates a large pool of greasy oil.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); // l3 - addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); - addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); //addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL); - addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); + addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); // l6 - addot(OT_S_PETRIFY, "petrify", "Causes the target mosnter to turn into stone.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_PETRIFY, "petrify", "Causes the target mosnter to turn into stone.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.\nBecomes semi-controlled at Power V, and fully-controlled at power VIII.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.\nBecomes semi-controlled at Power V, and fully-controlled at power VIII.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); // l7 - addot(OT_S_GASEOUSFORM, "gaseous form", "Changes the caster into a cloud of gas.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GASEOUSFORM, "gaseous form", "Changes the caster into a cloud of gas.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); - addot(OT_S_ENCHANT, "enchantment", "Magically enhances a weapon or piece of armour.", MT_NOTHING, 0, OC_SPELL); - addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); - addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL); - // TODO: hardcode how ai casts this spell /////////////////// // summoning /////////////////// // l1 - addot(OT_S_FLOATINGDISC, "floating disc", "Creates a disc of energy to carry your equipment.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FLOATINGDISC, "floating disc", "Creates a disc of energy to carry your equipment.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_SUMMONWEAPON, "summon weapon", "Summons a blade of pure magic into your hands. Deals 1-power damage.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SUMMONWEAPON, "summon weapon", "Summons a blade of pure magic into your hands. Deals 1-power damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); @@ -6723,7 +6877,7 @@ void initobjects(void) { addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); // l2 - addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.\nAt Power V you can control where the monster appears.\nAt Power VII, you can control the type of monster created.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.\nAt Power V you can control where the monster appears.\nAt Power VII, you can control the type of monster created.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); @@ -6732,37 +6886,37 @@ void initobjects(void) { // translocation /////////////////// // l2 - addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view. Becomes controlled at power VI.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view. Becomes controlled at power VI.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_S_PULL, "pull", "Pulls lifeforms towards the caster.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_SUCK, "suck", "Sucks the target lifeform towards the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); // l3 - addot(OT_S_TWIDDLE, "twiddle", "Swaps places with the target creature.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_TWIDDLE, "twiddle", "Swaps places with the target creature.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 - addot(OT_S_TELEPORT, "teleportation", "Teleports the caster (and Power-1 adjacent allies) to a new location within the same level.\nBecomes semi-controlled at Power V, and fully controlled at Power VII.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_TELEPORT, "teleportation", "Teleports the caster (and Power-1 adjacent allies) to a new location within the same level.\nBecomes semi-controlled at Power V, and fully controlled at Power VII.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); // l5 - addot(OT_S_DISPERSAL, "dispersal", "Scatters everything in the target cell around the area.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DISPERSAL, "dispersal", "Scatters everything in the target cell around the area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l6 - addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); @@ -6771,251 +6925,250 @@ void initobjects(void) { // wild /////////////////// // l1 - addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d2 magical damage per power level.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d2 magical damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l2 - addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 1d4 damage per power level.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 1d4 damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); - addot(OT_S_ALARM, "alarm", "Creates a passive alarm which goes off when an enemy is nearby.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ALARM, "alarm", "Creates a passive alarm which goes off when an enemy is nearby.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); // l3 - addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster (radius based on power), causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster (radius based on power), causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); - addot(OT_S_FLASH, "flash", "Causes a very bright flash, stunning anyone who sees it.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_FLASH, "flash", "Causes a very bright flash, stunning anyone who sees it.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); // l6 - addot(OT_S_DETONATE, "detonate", "Causes a given area to explode with massive force.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_DETONATE, "detonate", "Causes a given area to explode with massive force.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // divine powers (spells/abilities) - addot(OT_A_BLINDALL, "nosight", "Make everyone on the level blind.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_BLINDALL, "nosight", "Make everyone on the level blind.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_DEBUG, "debug", "You can toggle debugging for a lifeform.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_DEBUG, "debug", "You can toggle debugging for a lifeform.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_ENHANCE, "enhance", "Enhance a lifeform's stats.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_ENHANCE, "enhance", "Enhance a lifeform's stats.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_LEARN, "learn", "Learn new skills.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_LEARN, "learn", "Learn new skills.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_LEVELUP, "levelup", "Bestow the given xp level.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_LEVELUP, "levelup", "Bestow the given xp level.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_S_WISH, "wish", "Grants the caster any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_WISH, "wish", "Grants the caster any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); - addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); - addot(OT_S_CLEARLEVEL, "blank level", "Blanks out the current map.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CLEARLEVEL, "blank level", "Blanks out the current map.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_CREATEVAULT, "create vault", "Create a vault of the given type.", MT_NOTHING, 0, OC_SPELL); + addot(OT_S_CREATEVAULT, "create vault", "Create a vault of the given type.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_A_EMPLOY, "employ", "Assigns a job to the target lifeform.", MT_NOTHING, 0, OC_ABILITY); - addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); // abilities - addot(OT_A_CHARGE, "charge", "You can quickly charge into close quarters for battle.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_EMPLOY, "employ", "Assigns a job to the target lifeform.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_CHARGE, "charge", "You can quickly charge into close quarters for battle.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_A_CRUSH, "crush", "You can crush enemies after grabbing them.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_CRUSH, "crush", "You can crush enemies after grabbing them.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_NEEDSGRAB, B_TRUE, NA, NA, NULL); - addot(OT_A_COOK, "cook", "Combine food and water into a healthy meals.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_COOK, "cook", "Combine food and water into a healthy meals.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_DARKWALK, "darkwalk", "Step between the shadows.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_DARKWALK, "darkwalk", "Step between the shadows.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); // ai will cast this spell in a special manner... - addot(OT_A_DISARM, "disarm", "Attempt to disable a known trap.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_DISARM, "disarm", "Attempt to disable a known trap.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_FLURRY, "flurry", "Perform a flurry of attacks, forcing your opponent backwards.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_FEIGNDEATH, "feign death", "Pretend to be dead.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_FLURRY, "flurry", "Perform a flurry of attacks, forcing your opponent backwards.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); - addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_XPVAL, 10, NA, NA, NULL); - addot(OT_A_HEAVYBLOW, "heavy blow", "Mighty blow which knocks enemies backwards.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_HEAVYBLOW, "heavy blow", "Mighty blow which knocks enemies backwards.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); - addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY); - addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_HIDE, "hide", "You can hide in the shadows.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_HIDE, "hide", "You can hide in the shadows.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); - addot(OT_A_INSPECT, "inspect", "Try to identify an unknown object from your pack.", MT_NOTHING, 0, OC_ABILITY); - addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_HURRICANESTRIKE, "hurricane strike", "A sweeping attack aginst everything nearby.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_HURRICANESTRIKE, "hurricane strike", "A sweeping attack aginst everything nearby.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); - addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_INSPECT, "inspect", "Try to identify an unknown object from your pack.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL); - addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_QUIVERINGPALM, "quivering palm", "A deadly palm strike which knocks the molecules in the target's body out of alignment.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); - addot(OT_A_REPAIR, "repair equipment", "Repair damage done to your equipment.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_REPAIR, "repair equipment", "Repair damage done to your equipment.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); - addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); - addot(OT_A_STEAL, "steal", "Try to steal an item from an enemy.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_STEAL, "steal", "Try to steal an item from an enemy.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); - addot(OT_A_STINGACID, "sting (acid)", "You can sting your enemies.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_STINGACID, "sting (acid)", "You can sting your enemies.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); - addot(OT_A_SUCKBLOOD, "suck blood", "You can suck the blood from enemies after attaching to them.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_SUCKBLOOD, "suck blood", "You can suck the blood from enemies after attaching to them.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); - addot(OT_A_SWOOP, "swoop", "You can attack an enemy while flying past them.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_SWOOP, "swoop", "You can attack an enemy while flying past them.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_A_WARCRY, "warcry", "Inspire fear in your enemies with a mighty war cry.", MT_NOTHING, 0, OC_ABILITY); + addot(OT_A_TUMBLE, "tumble", "You can tumble across the ground.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_WARCRY, "warcry", "Inspire fear in your enemies with a mighty war cry.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); // books - addot(OT_MANUAL, "manual", "Teaches you one level of its subject matter.", MT_PAPER, 1.5, OC_BOOK); + addot(OT_MANUAL, "manual", "Teaches you one level of its subject matter.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 48, RR_RARE, NULL); - addot(OT_SPELLBOOK, "spellbook", "Teaches you the spell contained within.", MT_PAPER, 1.5, OC_BOOK); + addot(OT_SPELLBOOK, "spellbook", "Teaches you the spell contained within.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_RARE, NULL); // wands - addot(OT_WAND_KNOCK, "wand of opening", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_KNOCK, "wand of opening", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_KNOCK, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_DOOR, NA, NA, NULL); - addot(OT_WAND_LIGHT, "wand of light", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_LIGHT, "wand of light", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, RR_UNCOMMON, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, 3, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL); - addot(OT_WAND_REVEALHIDDEN, "wand of reveal hidden", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_REVEALHIDDEN, "wand of reveal hidden", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL); - addot(OT_WAND_SLOW, "wand of slowness", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_SLOW, "wand of slowness", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_SLOW, 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_DIGGING, "wand of digging", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_DIGGING, "wand of digging", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_DIG, NA, NA, NULL); //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); + addot(OT_WAND_COLD, "wand of cold", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, RR_RARE, 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); + addot(OT_WAND_FIRE, "wand of fire", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_FIREDART, 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_HASTE, "wand of haste", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_HASTE, "wand of haste", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_HASTE, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); - addot(OT_WAND_WEAKNESS, "wand of enfeeblement", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_WEAKNESS, "wand of enfeeblement", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_WEAKEN, 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_WONDER, "wand of wonder", "Produces random effects.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_WONDER, "wand of wonder", "Produces random effects.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, RR_RARE, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); - addot(OT_WAND_INVIS, "wand of invisibility", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_INVIS, "wand of invisibility", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_INVISIBILITY, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); - addot(OT_WAND_DISPERSAL, "wand of dispersal", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_DISPERSAL, "wand of dispersal", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_DISPERSAL, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER|TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); - addot(OT_WAND_FIREBALL, "wand of fireball", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_FIREBALL, "wand of fireball", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_FIREBALL, 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_DETONATION, "wand of detonation", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_DETONATION, "wand of detonation", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_DETONATE, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER|TT_DOOR, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); - addot(OT_WAND_POLYMORPH, "wand of polymorph", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND); + addot(OT_WAND_POLYMORPH, "wand of polymorph", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, RR_RARE, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_POLYMORPH, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // tools - unique - addot(OT_ORBDUNGEONEXIT, "dungeon exit orb", "When operated, this magical key will disable the barriers around the dungeon exit stairs.", MT_STONE, 2, OC_TOOLS); + addot(OT_ORBDUNGEONEXIT, "dungeon exit orb", "When operated, this magical key will disable the barriers around the dungeon exit stairs.", MT_STONE, 2, OC_TOOLS, SZ_SMALL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, "["); addflag(lastot->flags, F_UNIQUE, NA, NA, NA, NULL); addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); // tools - addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_TOOLS); + addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_TOOLS, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_HELPSREST, 10, NA, NA, NULL); - addot(OT_BLINDFOLD, "blindfold", "Short length of wide cloth, used for blocking eyesight.", MT_CLOTH, 0.01, OC_TOOLS); + addot(OT_BLINDFOLD, "blindfold", "Short length of wide cloth, used for blocking eyesight.", MT_CLOTH, 0.01, OC_TOOLS, SZ_TINY); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_BLIND, B_TRUE, NA, NULL); addflag(lastot->flags, F_VALUE, 20, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); - addot(OT_BUGLAMP, "glowing flask", "A glass flask with a glowbug corpse inside.", MT_GLASS, 0.3, OC_TOOLS); + addot(OT_CALTROP, "caltrop", "Connected metal spikes arranged such that one will always point upwards.", MT_METAL, 0.2, OC_TOOLS, SZ_TINY); + addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); + addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); + addflag(lastot->flags, F_SHARP, 2, 5, NA, NULL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); + + addot(OT_BUGLAMP, "glowing flask", "A glass flask with a glowbug corpse inside.", MT_GLASS, 0.3, OC_TOOLS, SZ_SMALL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "!"); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_PRODUCESLIGHT, 2, IFKNOWN, NULL); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "a flask"); - /// TODO: should we make a new object class "furniture" for this? - addot(OT_CANDELABRUM, "candelabrum", "A large (and heavy) decorative candle, about human height.", MT_METAL, 60, OC_TOOLS); - addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "\\"); - 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); - addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit"); - addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 4, NA, NULL); - addflag(lastot->flags, F_PRODUCESLIGHT, 4, NA, IFACTIVE, NULL); - addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); - addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); - addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); - - addot(OT_CANDLE, "candle", "A short wax candle.", MT_WAX, 0.2, OC_TOOLS); + addot(OT_CANDLE, "candle", "A short wax candle.", MT_WAX, 0.2, OC_TOOLS, SZ_TINY); 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); @@ -7027,7 +7180,7 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); - addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder.", MT_METAL, 0.5, OC_TOOLS); + addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder.", MT_METAL, 0.5, OC_TOOLS, SZ_TINY); 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_STACKABLE, B_TRUE, NA, NA, NULL); @@ -7038,7 +7191,7 @@ void initobjects(void) { addflag(lastot->flags, F_FLAMMABLE, 3, NA, NA, NULL); 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); + addot(OT_LAMPOIL, "oil lamp", "An oil-powered lamp which produces light.", MT_METAL, 1, OC_TOOLS, SZ_SMALL); 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); @@ -7050,7 +7203,7 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); 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); + addot(OT_LANTERNOIL, "oil lantern", "An oil-powered lantern which produces a lot of light.", MT_METAL, 1, OC_TOOLS, SZ_SMALL); 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); @@ -7062,26 +7215,49 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); - addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks.", MT_METAL, 0.05, OC_TOOLS); + addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks.", MT_METAL, 0.05, OC_TOOLS, SZ_TINY); addflag(lastot->flags, F_STACKABLE, 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); - addot(OT_PANPIPES, "set of panpipes", "A set of musical pipes.", MT_METAL, 0.5, OC_TOOLS); + addot(OT_PANPIPES, "set of panpipes", "A set of musical pipes.", MT_METAL, 0.5, OC_TOOLS, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_PICKAXE, "pickaxe", "A heavy tool for breaking rock.", MT_METAL, 8, OC_TOOLS); + addot(OT_PICKAXE, "pickaxe", "A heavy tool for breaking rock.", MT_METAL, 8, OC_TOOLS, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_ROPE, "rope", "A long length of strong rope.", MT_CLOTH, 5, OC_TOOLS); + addot(OT_ROPE, "rope", "A long length of strong rope.", MT_CLOTH, 5, OC_TOOLS, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 75, NA, NULL); addflag(lastot->flags, F_HELPSCLIMB, 3, NA, NA, NULL); - addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS); + addot(OT_SACK, "sack", "A small cloth sack.", MT_CLOTH, 1, OC_TOOLS, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL); + addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "("); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 30, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 10, NA, NA, NULL); + + addot(OT_SAFEBOX, "safebox", "A small metal container for safely storing valuables.", MT_METAL, 2, OC_TOOLS, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 77, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "("); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); + + addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS, SZ_SMALL); 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); @@ -7098,18 +7274,18 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); - addot(OT_TOWEL, "towel", "An large absorbent cloth used for drawing off moisture.", MT_CLOTH, 1.5, OC_TOOLS); + addot(OT_TOWEL, "towel", "An large absorbent cloth used for drawing off moisture.", MT_CLOTH, 1.5, OC_TOOLS, SZ_MEDIUM); 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); + addot(OT_CREDITCARD, "credit card", "A rectangular plastic card.", MT_PLASTIC, 0.01, OC_TECH, SZ_TINY); 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, 70, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 2, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_PAPERCLIP, "paperclip", "A thin, looped wire for holding paper together.", MT_METAL, 0.01, OC_TECH); + addot(OT_PAPERCLIP, "paperclip", "A thin, looped wire for holding paper together.", MT_METAL, 0.01, OC_TECH, SZ_TINY); 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, 70, NA, NULL); @@ -7119,22 +7295,22 @@ void initobjects(void) { addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d1"); addflag(lastot->flags, F_ACCURACY, 50, NA, NA, NULL); - addot(OT_SLEEPINGBAG, "sleeping bag", "An insulated bag for sleeping in. Very comfortable.", MT_CLOTH, 4, OC_TECH); + addot(OT_SLEEPINGBAG, "sleeping bag", "An insulated bag for sleeping in. Very comfortable.", MT_CLOTH, 4, OC_TECH, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_HELPSREST, 15, NA, NA, NULL); // tech - l1 - addot(OT_POCKETWATCH, "pocket watch", "A portable timekeeping device made to be carried in a pocket.", MT_METAL, 0.1, OC_TECH); + addot(OT_POCKETWATCH, "pocket watch", "A portable timekeeping device made to be carried in a pocket.", MT_METAL, 0.1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_DIGITALWATCH, "digital watch", "An electronic timekeeping device which shows the time as a number.", MT_METAL, 0.1, OC_TECH); + addot(OT_DIGITALWATCH, "digital watch", "An electronic timekeeping device which shows the time as a number.", MT_METAL, 0.1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_INSECTICIDE, "can of insecticide", "A spraycan containing poisonous chemicals.", MT_METAL, 0.5, OC_TECH); + addot(OT_INSECTICIDE, "can of insecticide", "A spraycan containing poisonous chemicals.", MT_METAL, 0.5, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERUSECHARGE, B_TRUE, NA, NA, NULL); @@ -7142,7 +7318,7 @@ void initobjects(void) { addflag(lastot->flags, F_RNDCHARGES, 1, 5, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_LANTERNLED, "LED lantern", "A low-powered but efficient lantern which will last almost forever.", MT_METAL, 0.5, OC_TECH); + addot(OT_LANTERNLED, "LED lantern", "A low-powered but efficient lantern which will last almost forever.", MT_METAL, 0.5, OC_TECH, SZ_TINY); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -7151,14 +7327,14 @@ void initobjects(void) { addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_TENT, "tent", "A easy to use, portable shelter made of fabric.", MT_CLOTH, 10, OC_TECH); + addot(OT_TENT, "tent", "A easy to use, portable shelter made of fabric.", MT_CLOTH, 10, OC_TECH, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL); addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL); // tech - l2 - addot(OT_FLASHBANG, "flashbang", "A stun grenade which temporarily blinds all within sight.", MT_METAL, 1, OC_TECH); + addot(OT_FLASHBANG, "flashbang", "A stun grenade which temporarily blinds all within sight.", MT_METAL, 1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -7174,7 +7350,7 @@ void initobjects(void) { addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_GRENADE, "grenade", "An explosive weapon which explodes a short time after activation.", MT_METAL, 1, OC_TECH); + addot(OT_GRENADE, "grenade", "An explosive weapon which explodes a short time after activation.", MT_METAL, 1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -7190,7 +7366,7 @@ void initobjects(void) { addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_C4, "block of c4", "A highly explosive plastic which explodes a medium time after activation.", MT_PLASTIC, 1, OC_TECH); + addot(OT_C4, "block of c4", "A highly explosive plastic which explodes a medium time after activation.", MT_PLASTIC, 1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -7205,7 +7381,7 @@ void initobjects(void) { addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_MOTIONSCANNER, "motion scanner", "Small scanning device which detects nearby lifeforms.", MT_METAL, 1.5, OC_TECH); + addot(OT_MOTIONSCANNER, "motion scanner", "Small scanning device which detects nearby lifeforms.", MT_METAL, 1.5, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_DETECTLIFE, 10, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); @@ -7213,27 +7389,27 @@ void initobjects(void) { // tech - l3 - addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH); + addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH, SZ_SMALL); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAINFO, B_TRUE, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH); + addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH, SZ_TINY); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_PORTLADDER, "portable ladder", "A lightweight two metre ladder which automatically folds down to pocket size.", MT_METAL, 2, OC_TECH); + addot(OT_PORTLADDER, "portable ladder", "A lightweight two metre ladder which automatically folds down to pocket size.", MT_METAL, 2, OC_TECH, SZ_TINY); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); // tech - l4 - addot(OT_JETPACK, "jet pack", "A portable ion-thruster which allows the wearer to fly.", MT_METAL, 10, OC_TECH); + addot(OT_JETPACK, "jet pack", "A portable ion-thruster which allows the wearer to fly.", MT_METAL, 10, OC_TECH, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL); @@ -7245,12 +7421,12 @@ void initobjects(void) { addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); // tech - l5 - addot(OT_TELEPAD, "teleport beacon", "A metal cone which will teleport the user to the nearest similar cone.", MT_METAL, 3, OC_TECH); + addot(OT_TELEPAD, "teleport beacon", "A metal cone which will teleport the user to the nearest similar cone.", MT_METAL, 3, OC_TECH, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_EXPERT, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_XRAYGOGGLES, "pair of xray goggles", "Bulky looking goggles which allow you to see through walls.", MT_METAL, 0.3, OC_TECH); + addot(OT_XRAYGOGGLES, "pair of xray goggles", "Bulky looking goggles which allow you to see through walls.", MT_METAL, 0.3, OC_TECH, SZ_TINY); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_XRAYVIS, 2, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); @@ -7262,19 +7438,38 @@ void initobjects(void) { // misc - addot(OT_EMPTYFLASK, "empty flask", "An empty glass flask.", MT_GLASS, 0.2, OC_MISC); + addot(OT_BONE, "bone", "A bone from an unknown creature.", MT_BONE, 0.1, OC_MISC, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); + 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); + addot(OT_CHEST, "chest", "A small wooden treasure chest.", MT_METAL, 40, OC_FURNITURE, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_COMMON, NULL); + addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "("); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 90, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 80, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 70, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 60, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); + addot(OT_EMPTYFLASK, "empty flask", "An empty glass flask.", MT_GLASS, 0.2, OC_MISC, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "!"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_EMPTYVIAL, "empty vial", "An empty glass vial.", MT_GLASS, 0.1, OC_MISC); + addot(OT_EMPTYVIAL, "empty vial", "An empty glass vial.", MT_GLASS, 0.1, OC_MISC, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "!"); addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); - addot(OT_BROKENGLASS, "piece of broken glass", "Sharp shards of broken glass.", MT_GLASS, 0.1, OC_MISC); + addot(OT_BROKENGLASS, "piece of broken glass", "Sharp shards of broken glass.", MT_GLASS, 0.1, OC_MISC, SZ_MINI); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 8, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -7283,14 +7478,7 @@ void initobjects(void) { addflag(lastot->flags, F_CRUSHABLE, SZ_MEDIUM, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL); - addot(OT_CALTROP, "caltrop", "Connected metal spikes arranged such that one will always point upwards.", MT_METAL, 0.2, OC_MISC); - addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); - addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL); - addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_GLYPH, NA, NA, NA, "^"); - addflag(lastot->flags, F_SHARP, 2, 5, NA, NULL); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); - addot(OT_ICESHEET, "sheet of ice", "A large sheet of slippery ice.", MT_ICE, 0.5, OC_MISC); + addot(OT_ICESHEET, "sheet of ice", "A large sheet of slippery ice.", MT_ICE, 0.5, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "_"); @@ -7303,7 +7491,7 @@ void initobjects(void) { 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, 14, NA, NA, NULL); - addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC); + addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 3, NA, NULL); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -7317,19 +7505,20 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL); - addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC); + addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC, SZ_TINY); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_NOMATCONVERT, B_TRUE, NA, NA, NULL); - addot(OT_SOGGYPAPER, "lump of soggy paper", "A useless lump of soggy paper.", MT_WETPAPER, 0.1, OC_MISC); + addot(OT_SOGGYPAPER, "lump of soggy paper", "A useless lump of soggy paper.", MT_WETPAPER, 0.1, OC_MISC, SZ_TINY); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "?"); addflag(lastot->flags, F_NOMATCONVERT, NA, NA, NA, NULL); - addot(OT_VOMITPOOL, "pool of vomit", "A disgusting pool of regurgitated food.", MT_WATER, 1, OC_MISC); + addot(OT_VOMITPOOL, "pool of vomit", "A disgusting pool of regurgitated food.", MT_WATER, 1, OC_MISC, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 90, RR_UNCOMMON, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, ","); @@ -7338,7 +7527,7 @@ void initobjects(void) { addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL); addflag(lastot->flags, F_TAINTED, B_TRUE, NA, NA, NULL); - addot(OT_ACIDPOOL, "pool of acid", "A pool of corrosive acid.", MT_ACID, 0, OC_MISC); + addot(OT_ACIDPOOL, "pool of acid", "A pool of corrosive acid.", MT_ACID, 0, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "~"); @@ -7353,7 +7542,7 @@ void initobjects(void) { addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL); - addot(OT_ACIDPUDDLE, "puddle of acid", "A small puddle of corrosive acid.", MT_ACID, 0, OC_MISC); + addot(OT_ACIDPUDDLE, "puddle of acid", "A small puddle of corrosive acid.", MT_ACID, 0, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "~"); @@ -7367,7 +7556,7 @@ void initobjects(void) { addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL); - addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC); + addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); @@ -7381,14 +7570,14 @@ void initobjects(void) { addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL); - addot(OT_SLIMEPOOL, "pool of slime", "A disgusting mass of sticky slime.", MT_WATER, 20, OC_MISC); + addot(OT_SLIMEPOOL, "pool of slime", "A disgusting mass of sticky slime.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 2, NA, NULL); - addot(OT_PUDDLEOIL, "puddle of oil", "A slippery puddle of oil.", MT_OIL, 15, OC_MISC); + addot(OT_PUDDLEOIL, "puddle of oil", "A slippery puddle of oil.", MT_OIL, 15, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, ","); // should really be dark grey @@ -7405,7 +7594,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates"); // this isn't made out of water, so that it won't put out fire etc - addot(OT_SPLASHWATER, "splash of water", "A small splash of water.", MT_NOTHING, 0.5, OC_MISC); + addot(OT_SPLASHWATER, "splash of water", "A small splash of water.", MT_NOTHING, 0.5, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, ","); @@ -7418,7 +7607,7 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "0d1+100"); addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL); - addot(OT_MUDPOOL, "pool of mud", "A large puddle of wet mud.", MT_WATER, 60, OC_MISC); + addot(OT_MUDPOOL, "pool of mud", "A large puddle of wet mud.", MT_WATER, 60, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "~"); @@ -7431,10 +7620,11 @@ void initobjects(void) { //addflag(lastot->flags, F_WALKDAM, DT_WATER, NA, NA, "0d1+1"); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1"); - addot(OT_PUDDLEWATER, "small puddle of water", "A small puddle of water.", MT_WATER, 10, OC_MISC); + addot(OT_PUDDLEWATER, "small puddle of water", "A small puddle of water.", MT_WATER, 10, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, ","); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); @@ -7450,10 +7640,11 @@ void initobjects(void) { //addflag(lastot->flags, F_WALKDAM, DT_WATER, NA, NA, "0d1+1"); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1"); - addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 20, OC_MISC); + addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "~"); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); @@ -7468,7 +7659,7 @@ void initobjects(void) { addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+2"); - addot(OT_BLOODSTAIN, "blood stain", "A dried stain of blood.", MT_BLOOD, 0, OC_MISC); + addot(OT_BLOODSTAIN, "blood stain", "A dried stain of blood.", MT_BLOOD, 0, OC_MISC, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, ","); @@ -7477,7 +7668,7 @@ void initobjects(void) { addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_BLOODCSPLASH, "splash of cockatrice blood", "A small pool of cockatrice blood.", MT_BLOOD, 0, OC_MISC); + addot(OT_BLOODCSPLASH, "splash of cockatrice blood", "A small pool of cockatrice blood.", MT_BLOOD, 0, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); @@ -7492,10 +7683,11 @@ void initobjects(void) { addflag(lastot->flags, F_LINKOB, OT_POT_BLOODC, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_BLOODSPLASH, "splash of blood", "A small pool of blood.", MT_BLOOD, 0, OC_MISC); + addot(OT_BLOODSPLASH, "splash of blood", "A small pool of blood.", MT_BLOOD, 0, OC_MISC, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); + addflag(lastot->flags, F_RARITY, H_VILLAGE, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SLIPPERY, 1, NA, NA, NULL); @@ -7510,7 +7702,7 @@ void initobjects(void) { addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_BLOODPOOL, "pool of blood", "A large pool of blood.", MT_BLOOD, 0, OC_MISC); + addot(OT_BLOODPOOL, "pool of blood", "A large pool of blood.", MT_BLOOD, 0, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "~"); @@ -7527,14 +7719,50 @@ void initobjects(void) { addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); - addot(OT_SIGN, "sign", "A marker with something written on it.", MT_WOOD, 25, OC_MISC); + addot(OT_SIGN, "sign", "A marker with something written on it.", MT_WOOD, 25, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "|"); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL); - addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 40, OC_MISC); + + // furniture + addot(OT_CANDELABRUM, "candelabrum", "A large (and heavy) decorative candle, about human height.", MT_METAL, 60, OC_FURNITURE, SZ_HUMAN); + addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "\\"); + 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); + addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit"); + addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 4, NA, NULL); + addflag(lastot->flags, F_PRODUCESLIGHT, 4, NA, IFACTIVE, NULL); + addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); + addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers"); + addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); + + addot(OT_FIREPLACE, "fireplace", "A roaring fireplace.", MT_STONE, 200, OC_FURNITURE, SZ_LARGE); + addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "\\"); + addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL); + addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_ONFIRE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); + + addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN); + addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_RARE, NULL); + addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "\\"); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_STARTOB, 80, NA, NA, "random weapon"); + addflag(lastot->flags, F_STARTOB, 60, NA, NA, "random weapon"); + addflag(lastot->flags, F_STARTOB, 50, NA, NA, "good weapon"); + addflag(lastot->flags, F_STARTOB, 50, NA, NA, "great weapon"); + + addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 40, OC_FURNITURE, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_VILLAGE, 75, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "("); @@ -7544,9 +7772,19 @@ void initobjects(void) { addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL); + addflag(lastot->flags, F_OBHP, 12, 12, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); + addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); - addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_MISC); + addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "\\"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL); @@ -7559,7 +7797,7 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_MISC); + addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_FURNITURE, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "\\"); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -7567,15 +7805,8 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); - addot(OT_BONE, "bone", "A bone from an unknown creature.", MT_BONE, 0.1, OC_MISC); - addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); - addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); - 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); - // trail objects - addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC); + addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC, SZ_MINI); addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NO_PLURAL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); @@ -7585,7 +7816,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, 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); + addot(OT_SCENT, "scent", "The scent of a creature, only perceivable to those with an enhanced sense of smell.", MT_NOTHING, 0, OC_MISC, SZ_MINI); addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NO_PLURAL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -7596,7 +7827,7 @@ void initobjects(void) { // NOTE: must add F_TRAIL when creating this object. // effects - addot(OT_FIRELARGE, "large fire", "A large, roaring inferno.", MT_FIRE, 0, OC_EFFECT); + addot(OT_FIRELARGE, "large fire", "A large, roaring inferno.", MT_FIRE, 0, OC_EFFECT, SZ_HUMAN); addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "{"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dies down a little"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "medium fire"); @@ -7607,7 +7838,7 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_FIREMED, "medium fire", "A medium-sized roaring fire.", MT_FIRE, 0, OC_EFFECT); + addot(OT_FIREMED, "medium fire", "A medium-sized roaring fire.", MT_FIRE, 0, OC_EFFECT, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "{"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small fire"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dies down a little"); @@ -7618,7 +7849,7 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT); + addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT, SZ_SMALL); addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "{"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); @@ -7629,7 +7860,7 @@ void initobjects(void) { addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT); + addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of steam"); @@ -7641,7 +7872,7 @@ void initobjects(void) { addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d2"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_STEAMPUFF, "puff of steam", "A small puff of scalding steam.", MT_GAS, 0, OC_EFFECT); + addot(OT_STEAMPUFF, "puff of steam", "A small puff of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "}"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses"); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); @@ -7653,7 +7884,7 @@ void initobjects(void) { addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement", MT_GAS, 0, OC_EFFECT); + addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); @@ -7671,7 +7902,7 @@ void initobjects(void) { addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2"); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2"); - addot(OT_MIST, "thick mist", "A thick cloud of obscuring mist.", MT_GAS, 0, OC_EFFECT); + addot(OT_MIST, "thick mist", "A thick cloud of obscuring mist.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "clears"); addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); @@ -7681,7 +7912,7 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT); + addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of smoke"); @@ -7694,7 +7925,7 @@ void initobjects(void) { addflag(lastot->flags, F_CAUSESCOUGH, 26, NA, NA, NULL); - addot(OT_SMOKEPUFF, "puff of smoke", "A small puff of black smoke.", MT_GAS, 0, OC_EFFECT); + addot(OT_SMOKEPUFF, "puff of smoke", "A small puff of black smoke.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses"); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); @@ -7705,7 +7936,7 @@ void initobjects(void) { addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "."); addflag(lastot->flags, F_CAUSESCOUGH, 18, NA, NA, NULL); - addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT); + addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "}"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "thins out a little"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of gas"); @@ -7717,7 +7948,7 @@ void initobjects(void) { addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_BLOCKSVIEW, 2, NA, NA, NULL); - addot(OT_POISONPUFF, "puff of poison gas", "A small puff of poisonous gas.", MT_GAS, 0, OC_EFFECT); + addot(OT_POISONPUFF, "puff of poison gas", "A small puff of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "}"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses"); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); @@ -7727,7 +7958,7 @@ void initobjects(void) { addflag(lastot->flags, F_WALKDAM, DT_POISONGAS, NA, NA, "1d2"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_HAILSTORM, "hail storm", "An intense storm of damaging hail.", MT_GAS, 0, OC_EFFECT); + addot(OT_HAILSTORM, "hail storm", "An intense storm of damaging hail.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); @@ -7745,7 +7976,7 @@ void initobjects(void) { addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2"); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2"); - addot(OT_ICEWALL, "wall of ice", "A wall made of solid ice.", MT_ICE, 0, OC_EFFECT); + addot(OT_ICEWALL, "wall of ice", "A wall made of solid ice.", MT_ICE, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "#"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -7753,7 +7984,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); - addot(OT_MAGICBARRIER, "magical barrier", "A glowing, impassable barrier of magical energy.", MT_MAGIC, 0, OC_EFFECT); + addot(OT_MAGICBARRIER, "magical barrier", "A glowing, impassable barrier of magical energy.", MT_MAGIC, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "#"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL); @@ -7761,20 +7992,20 @@ void initobjects(void) { addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes"); addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL); - addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT); + addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT, SZ_HUMAN); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "^"); - addflag(lastot->flags, F_RESTRICTMOVEMENT, 30, B_FALSE, B_TRUE, NULL);// the value here will be filled in by the spell. + addflag(lastot->flags, F_RESTRICTMOVEMENT, 30, B_TRUE, B_TRUE, NULL);// the value here will be filled in by the spell. addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_ACID, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); - addot(OT_WEB, "web", "A huge, sticky spider web.", MT_SILK, 0.1, OC_EFFECT); + addot(OT_WEB, "web", "A huge, sticky spider web.", MT_SILK, 0.1, OC_EFFECT, SZ_HUMAN); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^"); @@ -7790,79 +8021,76 @@ void initobjects(void) { // armour - body - addot(OT_COTTONSHIRT, "cotton shirt", "A comfortable white cotton shirt.", MT_CLOTH, 0.7, OC_ARMOUR); + addot(OT_COTTONSHIRT, "cotton shirt", "A comfortable white cotton shirt.", MT_CLOTH, 0.7, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); - addot(OT_ARMOURLEATHER, "leather armour", "Body armour created from soft leather.", MT_LEATHER, 10, OC_ARMOUR); + addot(OT_ARMOURLEATHER, "leather armour", "Body armour created from soft leather.", MT_LEATHER, 10, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); - addot(OT_ARMOURRING, "suit of ring mail", "Body armour formed by a series of metallic rings sewn to a leather foundation.", MT_METAL, 15, OC_ARMOUR); + addot(OT_ARMOURRING, "suit of ring mail", "Body armour formed by a series of metallic rings sewn to a leather foundation.", MT_METAL, 15, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 6, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 20, 20, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); - addot(OT_ARMOURSCALE, "suit of scale armour", "Body armour consisting of many small scales attached to leather.", MT_METAL, 20, OC_ARMOUR); + addot(OT_ARMOURSCALE, "suit of scale armour", "Body armour consisting of many small scales attached to leather.", MT_METAL, 20, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 72, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 10, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -15, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 30, 30, NULL); addflag(lastot->flags, F_OBHP, 35, 35, NA, NULL); - addot(OT_ARMOURCHAIN, "suit of chainmail", "Heavy body armour consisting of tightly meshed metal rings.", MT_METAL, 25, OC_ARMOUR); + addot(OT_ARMOURCHAIN, "suit of chainmail", "Heavy body armour consisting of tightly meshed metal rings.", MT_METAL, 25, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 15, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -20, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 40, 40, NULL); addflag(lastot->flags, F_OBHP, 45, 45, NA, NULL); - addot(OT_ARMOURSPLINT, "suit of splint mail", "Heavy armour, consisting of strips of metal attached to a leather backing.", MT_METAL, 35, OC_ARMOUR); + addot(OT_ARMOURSPLINT, "suit of splint mail", "Heavy armour, consisting of strips of metal attached to a leather backing.", MT_METAL, 35, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 67, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 20, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -25, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 50, 50, NULL); addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); - addot(OT_ARMOURPLATE, "suit of plate mail", "Heavy armour with embedded metal plates.", MT_METAL, 40, OC_ARMOUR); + addot(OT_ARMOURPLATE, "suit of plate mail", "Heavy armour with embedded metal plates.", MT_METAL, 40, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 25, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -30, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 60, 60, NULL); addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL); - addot(OT_FLAKJACKET, "flak jacket", "Heavy metal body armour, designed to stop a bullet.", MT_METAL, 30, OC_ARMOUR); + addot(OT_FLAKJACKET, "flak jacket", "Heavy metal body armour, designed to stop a bullet.", MT_METAL, 30, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 10, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); - addot(OT_OVERALLS, "pair of overalls", "Well-made, brightly coloured workman overalls.", MT_CLOTH, 1, OC_ARMOUR); + addot(OT_OVERALLS, "pair of overalls", "Well-made, brightly coloured workman overalls.", MT_CLOTH, 1, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); - addot(OT_SILKSHIRT, "silk shirt", "A lightweight, comfortable white silk shirt.", MT_SILK, 0.5, OC_ARMOUR); + addot(OT_SILKSHIRT, "silk shirt", "A lightweight, comfortable white silk shirt.", MT_SILK, 0.5, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); - addot(OT_ROBE, "robe", "A plain robe.", MT_CLOTH, 4, OC_ARMOUR); + addot(OT_ROBE, "robe", "A plain robe.", MT_CLOTH, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); - addot(OT_VELVETROBE, "velvet robe", "A luxurious velvet robe.", MT_CLOTH, 4, OC_ARMOUR); + addot(OT_VELVETROBE, "velvet robe", "A luxurious velvet robe.", MT_CLOTH, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); // armour - shoulders - addot(OT_CLOAK, "cloak", "A standard leather cloak.", MT_LEATHER, 4, OC_ARMOUR); + addot(OT_CLOAK, "cloak", "A standard leather cloak.", MT_LEATHER, 4, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SHOULDERS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); @@ -7870,136 +8098,125 @@ void initobjects(void) { addflag(lastot->flags, F_WATERPROOF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HELPSREST, 5, NA, NA, NULL); // armour - waist - addot(OT_BELTLEATHER, "leather belt", "A plain leather belt.", MT_LEATHER, 0.2, OC_ARMOUR); + addot(OT_BELTLEATHER, "leather belt", "A plain leather belt.", MT_LEATHER, 0.2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); addflag(lastot->flags, F_GOESON, BP_WAIST, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); // armour - legs - addot(OT_CLOTHTROUSERS, "pair of cloth trousers", "A rough pair of cloth trousers.", MT_CLOTH, 2, OC_ARMOUR); + addot(OT_CLOTHTROUSERS, "pair of cloth trousers", "A rough pair of cloth trousers.", MT_CLOTH, 2, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); - addot(OT_RIDINGTROUSERS, "pair of riding trousers", "A fitted pair of leather trousers.", MT_LEATHER, 2, OC_ARMOUR); + addot(OT_RIDINGTROUSERS, "pair of riding trousers", "A fitted pair of leather trousers.", MT_LEATHER, 2, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); - addot(OT_COMBATPANTS, "pair of combat pants", "An armoured pair of camoflauged trousers.", MT_CLOTH, 2, OC_ARMOUR); + addot(OT_COMBATPANTS, "pair of combat pants", "An armoured pair of camoflauged trousers.", MT_CLOTH, 2, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 8, 8, NA, NULL); // armour - feet - addot(OT_SANDALS, "pair of sandals", "Comfortable pair of open leather sandals.", MT_LEATHER, 1, OC_ARMOUR); + addot(OT_SANDALS, "pair of sandals", "Comfortable pair of open leather sandals.", MT_LEATHER, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); - addot(OT_SHOESLEATHER, "pair of leather shoes", "Cheap and rather uncomfortable leather shoes.", MT_LEATHER, 2, OC_ARMOUR); + addot(OT_SHOESLEATHER, "pair of leather shoes", "Cheap and rather uncomfortable leather shoes.", MT_LEATHER, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); - addot(OT_BOOTSRUBBER, "pair of rubber boots", "A waterproof (but somewhat cumbersome) pair of rubber boots.", MT_RUBBER, 6, OC_ARMOUR); + addot(OT_BOOTSRUBBER, "pair of rubber boots", "A waterproof (but somewhat cumbersome) pair of rubber boots.", MT_RUBBER, 6, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); // bulky + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 0, 5, NULL); addflag(lastot->flags, F_OBHP, 8, 8, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_ELECTRIC, NA, NULL); - addot(OT_BOOTSSPIKED, "pair of spiked boots", "A plain pair of leather boots with spikes on the bottom.", MT_LEATHER, 3, OC_ARMOUR); + addot(OT_BOOTSSPIKED, "pair of spiked boots", "A plain pair of leather boots with spikes on the bottom.", MT_LEATHER, 3, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_STABILITY, NA, NA, NULL); - addot(OT_BOOTSLEATHER, "pair of leather boots", "A stout pair of leather boots.", MT_LEATHER, 4, OC_ARMOUR); + addot(OT_BOOTSLEATHER, "pair of leather boots", "A stout pair of leather boots.", MT_LEATHER, 4, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // armour - gloves - addot(OT_GLOVESCLOTH, "pair of cloth gloves", "A pair of soft cloth gloves.", MT_CLOTH, 0.15, OC_ARMOUR); + addot(OT_GLOVESCLOTH, "pair of cloth gloves", "A pair of soft cloth gloves.", MT_CLOTH, 0.15, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); - addot(OT_GLOVESLEATHER, "pair of leather gloves", "A pair of coarse leather gloves.", MT_LEATHER, 0.25, OC_ARMOUR); + addot(OT_GLOVESLEATHER, "pair of leather gloves", "A pair of coarse leather gloves.", MT_LEATHER, 0.25, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); - addot(OT_GAUNTLETS, "pair of gauntlets", "A durable pair of metal gauntlets.", MT_METAL, 2, OC_ARMOUR); + addot(OT_GAUNTLETS, "pair of gauntlets", "A durable pair of metal gauntlets.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -3, NA, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 5, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); // armour - head - addot(OT_SUNHAT, "sun hat", "Wide-brimmed hat made for working in the sun.", MT_CLOTH, 1, OC_ARMOUR); + addot(OT_SUNHAT, "sun hat", "Wide-brimmed hat made for working in the sun.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -5, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); - addot(OT_PIRATEHAT, "tricorne", "A three cornered hat with a skull and crossbones emblem.", MT_CLOTH, 1, OC_ARMOUR); + addot(OT_PIRATEHAT, "tricorne", "A three cornered hat with a skull and crossbones emblem.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); - addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR); + addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); - addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_METAL, 3.5, OC_ARMOUR); + addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_METAL, 3.5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -5, NA, NULL); - addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR); + addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); - addot(OT_HELMFOOTBALL, "football helmet", "A metal helmet with a grill in front of the face.", MT_METAL, 1, OC_ARMOUR); + addot(OT_HELMFOOTBALL, "football helmet", "A metal helmet with a grill in front of the face.", MT_METAL, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL); - addot(OT_GOLDCROWN, "golden crown", "A heavy gold crown, encrusted with jewels.", MT_GOLD, 5, OC_ARMOUR); + addot(OT_GOLDCROWN, "golden crown", "A heavy gold crown, encrusted with jewels.", MT_GOLD, 5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); - addot(OT_HELMBONE, "bone helmet", "Scary-looking helmet made from the bones of an animal (?).", MT_BONE, 1, OC_ARMOUR); + addot(OT_HELMBONE, "bone helmet", "Scary-looking helmet made from the bones of an animal (?).", MT_BONE, 1, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); - addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL); // armour - eyes - addot(OT_SUNGLASSES, "sunglasses", "Tinted eyewear to protect against sunlight.", MT_PLASTIC, 0.01, OC_ARMOUR); + addot(OT_SUNGLASSES, "sunglasses", "Tinted eyewear to protect against sunlight.", MT_PLASTIC, 0.01, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL); @@ -8007,12 +8224,12 @@ void initobjects(void) { addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -4, NA, NULL); addflag(lastot->flags, F_TINTED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); - addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR); + addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); - addot(OT_NVGOGGLES, "nightvis goggles", "Special goggles which allow the wear to see in the dark.", MT_METAL, 1.5, OC_ARMOUR); + addot(OT_NVGOGGLES, "nightvis goggles", "Special goggles which allow the wear to see in the dark.", MT_METAL, 1.5, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL); addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); @@ -8022,28 +8239,28 @@ void initobjects(void) { // armour - shields - addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR); + addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); - addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR); + addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 76, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 6, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); - addot(OT_SHIELDLARGE, "large shield", "A large (if somewhat cumbersome) shield.", MT_METAL, 6.00, OC_ARMOUR); + addot(OT_SHIELDLARGE, "large shield", "A large (if somewhat cumbersome) shield.", MT_METAL, 6.00, OC_ARMOUR, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 78, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 20, NA, NULL); addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL); - addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR); + addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); @@ -8052,68 +8269,68 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); // rings - addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 3, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL); - addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAMP, 10, NA, NULL); - addot(OT_RING_LUCK, "ring of luck", "Makes the wearer more lucky.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_LUCK, "ring of luck", "Makes the wearer more lucky.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRALUCK, 5, NA, NULL); - addot(OT_RING_PROTFIRE, "ring of fire immunity", "Grants the caster complete immunity to fire.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_PROTFIRE, "ring of fire immunity", "Grants the caster complete immunity to fire.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FIRE, NA, NULL); - addot(OT_RING_PROTCOLD, "ring of cold immunity", "Grants the caster complete immunity to cold.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_PROTCOLD, "ring of cold immunity", "Grants the caster complete immunity to cold.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_COLD, NA, NULL); - addot(OT_RING_STR, "ring of strength", "Increases the wearer's strength.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_STR, "ring of strength", "Increases the wearer's strength.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); - addot(OT_RING_IQ, "ring of intelligence", "Increases the wearer's intelligence.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_IQ, "ring of intelligence", "Increases the wearer's intelligence.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); - addot(OT_RING_CON, "ring of fitness", "Increases the wearer's fitness.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_CON, "ring of fitness", "Increases the wearer's fitness.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); - addot(OT_RING_DEX, "ring of dexterity", "Increases the wearer's dexterity.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_DEX, "ring of dexterity", "Increases the wearer's dexterity.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_DEX, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); - addot(OT_RING_HUNGER, "ring of hunger", "Greatly increases the metabolic rate of the wearer.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_HUNGER, "ring of hunger", "Greatly increases the metabolic rate of the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_FASTMETAB, 3, NA, NULL); addflag(lastot->flags, F_STARTBLESSED, B_CURSED, NA, NA, NULL); - addot(OT_RING_WOUNDING, "ring of wounding", "Increases the damage output of the wearer.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_WOUNDING, "ring of wounding", "Increases the damage output of the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_EXTRADAM, NA, NA, "0d0+4"); addflag(lastot->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); - addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_INVISIBLE, NA, NA, NULL); - addot(OT_RING_INVULN, "ring of invulnerability", "Grants the caster complete immunity to physical harm.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_INVULN, "ring of invulnerability", "Grants the caster complete immunity to physical harm.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_EQUIPCONFER, F_INVULNERABLE, NA, NA, NULL); - addot(OT_RING_MPREGEN, "ring of recharging", "Slowly regenerates the wearer's mana.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_MPREGEN, "ring of recharging", "Slowly regenerates the wearer's mana.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_MPREGEN, 1, NA, NULL); - addot(OT_RING_CONTROL, "ring of control", "Allows the wearer control over teleportation and polymorphic effects.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_CONTROL, "ring of control", "Allows the wearer control over teleportation and polymorphic effects.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_CONTROL, NA, NA, NULL); - addot(OT_RING_REGENERATION, "ring of regeneration", "Slowly regenerates the wearer's health, even when not resting.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_REGENERATION, "ring of regeneration", "Slowly regenerates the wearer's health, even when not resting.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_REGENERATES, 1, NA, NULL); - addot(OT_RING_RESISTMAG, "ring of magic resistance", "Renders the wearer immune to most magical effects.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_RESISTMAG, "ring of magic resistance", "Renders the wearer immune to most magical effects.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, ""); addflag(lastot->flags, F_EQUIPCONFER, F_RESISTMAG, 5, NA, NULL); - addot(OT_RING_MIRACLES, "ring of miracles", "Grants a limited number of miracles to the wearer.", MT_METAL, 0.1, OC_RING); + addot(OT_RING_MIRACLES, "ring of miracles", "Grants a limited number of miracles to the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI); addflag(lastot->flags, F_RARITY, H_ALL, 40, NA, ""); addflag(lastot->flags, F_CHARGES, 3, 3, NA, NULL); @@ -8121,14 +8338,14 @@ void initobjects(void) { // overridded with the lifeform flag F_HASATTACK // // DAMTYPE _cannot_ be overridden (yet)! - addot(OT_FISTS, "fists", "human fists", MT_FLESH, 0, OC_WEAPON); + addot(OT_FISTS, "fists", "human fists", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_UNARMED, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); // this one is for the pirate - addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON); + addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL); @@ -8138,7 +8355,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTACKVERB, 16, NA, NA, "rake"); - addot(OT_TEETH, "teeth", "teeth object", MT_BONE, 0, OC_WEAPON); + addot(OT_TEETH, "teeth", "teeth object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_BITE, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); @@ -8146,7 +8363,7 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON); + addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2"); addflag(lastot->flags, F_ATTACKVERB, NA, 5, NA, "scratch"); addflag(lastot->flags, F_ATTACKVERB, 6, 15, NA, "claw"); @@ -8159,21 +8376,21 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_HOOF, "hooves", "hoof object", MT_BONE, 0, OC_WEAPON); + addot(OT_HOOF, "hooves", "hoof object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "kick"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_BUTT, "headbutt", "headbutt object", MT_BONE, 0, OC_WEAPON); + addot(OT_BUTT, "headbutt", "headbutt object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "butt"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_STING, "sting", "sting object", MT_BONE, 0, OC_WEAPON); + addot(OT_STING, "sting", "sting object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting"); addflag(lastot->flags, F_DAM, DT_ACID, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -8181,20 +8398,20 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_TAIL, "tail", "tail object", MT_FLESH, 0, OC_WEAPON); + addot(OT_TAIL, "tail", "tail object", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "tailslap"); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON); + addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON); + addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_ELECTRIC, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); @@ -8202,13 +8419,13 @@ void initobjects(void) { addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); // monster weapons - addot(OT_ACIDATTACK, "acidattack", "acid attack object", MT_WATER, 0, OC_WEAPON); + addot(OT_ACIDATTACK, "acidattack", "acid attack object", MT_WATER, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_ACID, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_TOUCHPARALYZE, "paralyzing touch", "paralyzing touch object", MT_BONE, 0, OC_WEAPON); + addot(OT_TOUCHPARALYZE, "paralyzing touch", "paralyzing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_TOUCH, NA, NA, "0d1"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 22, "2-4"); @@ -8216,7 +8433,7 @@ void initobjects(void) { addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); - addot(OT_TOUCHPARALYZE2, "strong paralyzing touch", "strong paralyzing touch object", MT_BONE, 0, OC_WEAPON); + addot(OT_TOUCHPARALYZE2, "strong paralyzing touch", "strong paralyzing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addflag(lastot->flags, F_DAM, DT_TOUCH, NA, NA, "0d1"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "5-10"); @@ -8226,7 +8443,7 @@ void initobjects(void) { addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); // missiles - addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE); + addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, ""); @@ -8235,7 +8452,7 @@ void initobjects(void) { addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE); + addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE, SZ_TINY); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, ""); @@ -8244,7 +8461,7 @@ void initobjects(void) { addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); - addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6, OC_MISSILE); + addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6, OC_MISSILE, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, ""); @@ -8253,7 +8470,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 3, 3, NA, ""); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); - addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.25, OC_MISSILE); + addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.25, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); @@ -8263,7 +8480,7 @@ void initobjects(void) { addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 0.5, OC_MISSILE); + addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 0.5, OC_MISSILE, SZ_SMALL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); @@ -8271,7 +8488,7 @@ void initobjects(void) { addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); - addot(OT_BULLET, "bullet", "A regular gun bullet.", MT_STONE, 0.1, OC_MISSILE); + addot(OT_BULLET, "bullet", "A regular gun bullet.", MT_METAL, 0.1, OC_MISSILE, SZ_MINI); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); @@ -8280,7 +8497,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); - addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_STONE, 0.05, OC_MISSILE); + addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_STONE, 0.05, OC_MISSILE, SZ_MINI); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); @@ -8291,20 +8508,20 @@ void initobjects(void) { // axes - addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON); + addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d6"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); - addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON); + addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+1"); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON); + addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+1"); @@ -8312,14 +8529,14 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL); - addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2.5, OC_WEAPON); + addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7"); addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); - addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON); + addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1"); addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); @@ -8327,7 +8544,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 11, NA, NULL); // short blades - addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON); + addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4+1"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -8336,7 +8553,7 @@ void initobjects(void) { addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON); + addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -8345,7 +8562,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON); + addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d3"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -8354,7 +8571,7 @@ void initobjects(void) { addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_ORNDAGGER, "ornamental dagger", "This dagger is pretty, but not particularly effective.", MT_METAL, 1, OC_WEAPON); + addot(OT_ORNDAGGER, "ornamental dagger", "This dagger is pretty, but not particularly effective.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d3"); @@ -8362,37 +8579,37 @@ void initobjects(void) { addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality, which somehow allows its bearer to attack faster.", MT_METAL, 3.0, OC_WEAPON); + addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality, which somehow allows its bearer to attack faster.", MT_METAL, 3.0, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON); + addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8"); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); - addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON); + addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4"); addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL); - addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 4, OC_WEAPON); + addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d6"); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); - addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON); + addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6"); addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); - addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON); + addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2"); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); @@ -8402,13 +8619,13 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); // long blades - addot(OT_FALCHION, "falchion", "A single-edged heavy sword made for chopping.", MT_METAL, 6.5, OC_WEAPON); + addot(OT_FALCHION, "falchion", "A single-edged heavy sword made for chopping.", MT_METAL, 6.5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 61, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+3"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_GREATSWORD, "greatsword", "A massive two-handed sword.", MT_METAL, 10, OC_WEAPON); + addot(OT_GREATSWORD, "greatsword", "A massive two-handed sword.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d12+6"); @@ -8416,26 +8633,26 @@ void initobjects(void) { addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON); + addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL); - addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON); + addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6"); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); - addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 5, OC_WEAPON); + addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 90, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL); - addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON); + addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7"); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); @@ -8443,7 +8660,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL); // polearms - addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON); + addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7+3"); @@ -8451,7 +8668,7 @@ void initobjects(void) { addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON); + addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); @@ -8461,7 +8678,7 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 7, NA, NULL); - addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON); + addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL); addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL); @@ -8471,7 +8688,7 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL); - addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 12, OC_WEAPON); + addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL); @@ -8479,7 +8696,7 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON); + addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL); addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); @@ -8489,14 +8706,14 @@ void initobjects(void) { addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL); - addot(OT_SCYTHE, "scythe", "An agricultural hand tool for mowing grass, or reaping crops.", MT_METAL, 6, OC_WEAPON); + addot(OT_SCYTHE, "scythe", "An agricultural hand tool for mowing grass, or reaping crops.", MT_METAL, 6, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4"); addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); - addot(OT_SPEAR, "spear", "A long pole with a sharpened head.", MT_METAL, 9, OC_WEAPON); + addot(OT_SPEAR, "spear", "A long pole with a sharpened head.", MT_METAL, 9, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL); @@ -8507,7 +8724,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); - addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 5, OC_WEAPON); + addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 5, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d10"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); @@ -8515,7 +8732,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); // staves - addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON); + addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d8"); addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL); @@ -8525,7 +8742,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON); + addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); @@ -8534,7 +8751,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON); + addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4+3"); @@ -8545,7 +8762,7 @@ void initobjects(void) { addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON); + addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON, SZ_HUMAN); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "3d4+1"); @@ -8557,26 +8774,26 @@ void initobjects(void) { // clubs (bashing) - addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 8, OC_WEAPON); + addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 8, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL); - addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON); + addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); - addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON); + addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON); + addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d10+5"); @@ -8584,13 +8801,13 @@ void initobjects(void) { addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL); - addot(OT_MACE, "mace", "A weapon with a heavy head on a solid shaft used to bludgeon opponents.", MT_METAL, 10, OC_WEAPON); + addot(OT_MACE, "mace", "A weapon with a heavy head on a solid shaft used to bludgeon opponents.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d7+1"); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); - addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON); + addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d9+3"); @@ -8598,21 +8815,21 @@ void initobjects(void) { addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON); + addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6+1"); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL); - addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON); + addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4"); addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDDIR, B_TRUE, NA, NA, "Use your spanner in which direction"); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); - addot(OT_STICK, "stick", "A sturdy wooden stick.", MT_WOOD, 0.5, OC_WEAPON); + addot(OT_STICK, "stick", "A sturdy wooden stick.", MT_WOOD, 0.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2"); @@ -8623,7 +8840,7 @@ void initobjects(void) { addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); // projectile weapons - addot(OT_BOW, "bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 5, OC_WEAPON); + addot(OT_BOW, "short bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8631,10 +8848,13 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 1, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 1, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); - addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but needs high strength to use.", MT_WOOD, 8, OC_WEAPON); + addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but needs high strength to use.", MT_WOOD, 8, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8642,9 +8862,12 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 1, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 2, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 2, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_CROSSBOWHAND, "hand crossbow", "A small one-handed crossbow. Lightweight, but less powerful than a full-sized one.", MT_WOOD, 3, OC_WEAPON); + addot(OT_CROSSBOWHAND, "hand crossbow", "A small one-handed crossbow. Lightweight, but less powerful than a full-sized one.", MT_WOOD, 3, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8652,8 +8875,11 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 1, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 1, NA, NA, NULL); - addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 7, OC_WEAPON); + addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 7, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8661,9 +8887,12 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 1, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 1, NA, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); - addot(OT_REVOLVER, "revolver", "Basic one-handed firearm.", MT_METAL, 1, OC_WEAPON); + addot(OT_REVOLVER, "revolver", "Basic one-handed firearm.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8674,8 +8903,24 @@ void initobjects(void) { addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_BULLET, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_RUBBERBULLET, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 6, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 2, NA, NA, NULL); - addot(OT_SLING, "sling", "Stretchy piece of rubber for launching projectiles.", MT_RUBBER, 0.5, OC_WEAPON); + addot(OT_SHOTGUN, "shotgun", "Powerful but short-ranged gun.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); + addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_FIRESPEED, 30, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); + addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); + addflag(lastot->flags, F_AMMOOB, OT_BULLET, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 2, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 3, NA, NA, NULL); + + addot(OT_SLING, "sling", "Stretchy piece of rubber for launching projectiles.", MT_RUBBER, 0.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); @@ -8683,14 +8928,17 @@ void initobjects(void) { addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL); addflag(lastot->flags, F_AMMOOB, OT_STONE, NA, NA, NULL); + addflag(lastot->flags, F_AMMOCAPACITY, 1, NA, NA, NULL); + addflag(lastot->flags, F_FIRETURNS, 1, NA, NA, NULL); + addflag(lastot->flags, F_RELOADTURNS, 1, NA, NA, NULL); // special weapons - addot(OT_ENERGYBLADE, "energy blade", "A summoned weapon made of pure magical energy.", MT_MAGIC, 0, OC_WEAPON); + addot(OT_ENERGYBLADE, "energy blade", "A summoned weapon made of pure magical energy.", MT_MAGIC, 0, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_DAM, DT_MAGIC, NA, NA, "1d4"); // will be replaced when summoned addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); - addot(OT_HANDOFGOD, "hand of god", "The ultimate power.", MT_FLESH, 0.1, OC_WEAPON); + addot(OT_HANDOFGOD, "hand of god", "The ultimate power.", MT_FLESH, 0.1, OC_WEAPON, SZ_MEDIUM); //addflag(lastot->flags, F_RARITY, H_DUNGEON, RR_UNIQUE, NA, NULL); //addflag(lastot->flags, F_DAMTYPE, DT_HOLY, NA, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6+100"); @@ -8867,10 +9115,10 @@ int isdamaged(object_t *o) { } int isdangerousob(object_t *o, lifeform_t *lf, int onlyifknown) { - enum IQBRACKET iqb; - iqb = getiqname(getattr(lf, A_IQ), NULL); + enum ATTRBRACKET iqb; + iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL); - if (!onlyifknown || (iqb >= IQ_AVERAGE)) { + if (!onlyifknown || (iqb >= AT_AVERAGE)) { if (hasflag(o->flags, F_SHARP)) { if (!getequippedob(lf->pack, BP_HANDS) && !isimmuneto(lf->flags, DT_SLASH)) { return B_TRUE; @@ -8942,6 +9190,7 @@ int isequippedon(object_t *o, enum BODYPART bp) { } int isfirearm(object_t *o) { + if (!o) return B_FALSE; if (hasflag(o->flags, F_FIREARM)) { return B_TRUE; } @@ -9466,7 +9715,7 @@ lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) { } } if (newlf) { - addflag(newlf->flags, F_PETOF, lf->id, NA, NA, NULL); + petify(newlf, lf); } return newlf; } @@ -9651,6 +9900,11 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) { reason = E_OK; + if (!obfits(src, dst)) { + reason = E_NOSPACE; + return NULL; + } + // adjust destination for pits if (dst->where) { object_t *pit; @@ -9709,7 +9963,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) { // create temporary object pile - tempop = addobpile(NULL, NULL); + tempop = addobpile(NULL, NULL, NULL); // add new object to the temporary pile o = addob(tempop, src->type->name); // copy props from original object @@ -9965,6 +10219,14 @@ void obdie(object_t *o) { explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0); } return; + } + + + if (hasflag(o->flags, F_CONTAINER)) { + // dump object's contents into parent container + while (o->contents->first) { + moveob(o->contents->first, o->pile, ALL); + } } // flashes? @@ -10001,6 +10263,16 @@ int obfits(object_t *o, obpile_t *op) { if (countobs(op, B_FALSE) >= MAXPILEOBS) { return B_FALSE; } + + if (op->owner && (getnextletter(op, NULL) == '\0')) { + reason = E_NOSPACE; + return B_FALSE; + } + + if (op->parentob && (getobsize(o) > getobsize(op->parentob) )) { + reason = E_NOSPACE; + return B_FALSE; + } return B_TRUE; } @@ -10123,6 +10395,90 @@ int obpropsmatch(object_t *a, object_t *b) { return B_TRUE; } +flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf) { + flag_t *f; + f = hasflag(o->flags, F_RESTRICTMOVEMENT); + if (f) { + if (!lf) return NULL; + if (lf) { + if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) { + } else if ((o->type->id == OT_VINE) && hasjob(lf, J_DRUID)) { + } else if (isairborne(lf) && (f->val[2] != B_TRUE)) { + } else { + return f; + } + } + } + return NULL; +} + +// returns # objects which fell through +int obsfallthrough(cell_t *c, object_t *pit) { + object_t *oo,*uphole; + cell_t *belowcell; + char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN]; + int nfallen = 0; + + belowcell = getstairdestination(pit); + if (!belowcell) return 0; + + uphole = hasobwithflagval(belowcell->obpile, F_PIT, D_UP, NA, NA, NULL); + + getobname(pit,downholename, 1); + getobname(uphole,upholename, 1); + + for (oo = c->obpile->first ; oo ; oo = oo->next) { + if (oo == pit) continue; + if (!hasflag(oo->flags, F_NOPICKUP)) { + int canseebelowlf = B_FALSE; + // fall through! + if (haslos(player, c)) { + // player can see the top of the hole + getobname(oo,obname, oo->amt); + msg("%s fall%s through %s.", obname, + (oo->amt == 1) ? "s" : "", + downholename); + } + + // remember if we can see the bottom cell before the object drops + if (belowcell->lf && cansee(player, belowcell->lf)) { + canseebelowlf = B_TRUE; + } + + moveob(oo, belowcell->obpile, oo->amt); + + if (haslos(player, belowcell)) { + // player can see the bottom of the hole + getobname(oo,obname, oo->amt); + msg("%s fall%s through %s.", obname, + (oo->amt == 1) ? "s" : "", + upholename); + } + + // does the object hit anyone? + if (belowcell->lf) { + lifeform_t *lf; + char dambuf[BUFLEN]; + lf = belowcell->lf; + + if (canseebelowlf) { + char lfname[BUFLEN]; + getobname(oo,obname, oo->amt); + getlfname(lf, lfname); + msg("%s hit%s %s!", obname, + (oo->amt == 1) ? "s" : "", + lfname); + } + sprintf(dambuf, "a falling %s", oo->type->name); + losehp(lf, getthrowdam(oo) * 6, DT_PROJECTILE, NULL, dambuf); + } + + nfallen++; + } + } + return nfallen; +} + int operate(lifeform_t *lf, object_t *o, cell_t *where) { char buf[BUFLEN],obname[BUFLEN]; int playercansee; @@ -10276,7 +10632,41 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } */ - if (hasflag(o->flags, F_OPERONOFF)) { // operating toggles on/off + if (hasflag(o->flags, F_CONTAINER) && (o->type->id != OT_VENDINGMACHINE)) { // loot it + if (isplayer(lf)) { // only player can loot. + char ch; + sprintf(buf, "Looting a %s. Will you:",obname); + initprompt(&prompt, buf); + if (countobs(lf->pack, B_FALSE)) { + sprintf(buf, "Put items in %s",obname); + addchoice(&prompt, 'i', buf, NULL, NULL); + } + if (countobs(o->contents, B_FALSE)) { + sprintf(buf, "Take items out of %s",obname); + addchoice(&prompt, 'o', buf, NULL, NULL); + } + sprintf(buf, "Both"); + addchoice(&prompt, 'b', buf, NULL, NULL); + sprintf(buf, "Neither"); + addchoice(&prompt, 'n', buf, NULL, NULL); + ch = getchoice(&prompt); + switch (ch) { + case 'i': + dodrop(player->pack, B_MULTIPLE, o->contents); + break; + case 'o': + dopickup(o->contents, B_TRUE); + break; + case 'b': + dodrop(player->pack, B_MULTIPLE, o->contents); + dopickup(o->contents, B_TRUE); + break; + case 'n': + msg("Cancelled."); + return B_FALSE; + } + } + } else if (hasflag(o->flags, F_OPERONOFF)) { // operating toggles on/off if (isactivated(o)) { turnoff(lf, o); } else { @@ -10300,7 +10690,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { sprintf(buf, "Load %s with what ammo",obname); oo = askobject(lf->pack, buf, NULL, AO_SPECIFIED); if (oo) { - setammo(lf, oo); + loadfirearm(lf, o, oo); } } } else if (o->type->obclass->id == OC_WAND) { @@ -10389,7 +10779,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); break; case 12: // pull - dospelleffects(lf, OT_S_PULL, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid, B_FALSE); + dospelleffects(lf, OT_S_SUCK, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid, B_FALSE); break; case 13: // blast dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid, B_FALSE); @@ -10824,7 +11214,19 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } } taketime(lf, getactspeed(lf)); - } + } else if (o->type->id == OT_VENDINGMACHINE) { + if (isplayer(lf)) { + dovendingmachine(lf, o); + restoregamewindows(); + } else { + if (cansee(player, lf)) { + char lfname[BUFLEN]; + getlfname(lf, lfname); + msg("%s fiddles with %s.", lfname, obname); + } + } + taketime(lf, getactspeed(lf)); + } return B_FALSE; } @@ -11059,7 +11461,7 @@ void quaff(lifeform_t *lf, object_t *o) { getobname(o, obname, 1); - if ((isplayer(lf)) || cansee(player, lf)) { + if (isplayer(lf) || cansee(player, lf)) { playercansee = B_TRUE; } else { playercansee = B_FALSE; @@ -11092,45 +11494,95 @@ void quaff(lifeform_t *lf, object_t *o) { // figure out whether to id the object willid = B_FALSE; if (playercansee) { - switch (o->type->id) { + enum OBTYPE obid; + if (o->type->id == OT_FOUNTAIN) { + flag_t *f; + // ie if not already identified... + f = hasflag(o->flags, F_LINKOB); + if (f->val[2] == B_TRUE) { + // already identified + willid = B_FALSE; + obid = OT_NONE; + } else { + // then identify based on potion effects... + obid = f->val[0]; + } + } else { + obid = o->type->id; + } + + switch (obid) { + case OT_NONE: + willid = B_FALSE; + break; case OT_POT_HEALING: case OT_POT_HEALINGMIN: if (lf->hp < lf->maxhp) { willid = B_TRUE; } break; + case OT_FOUNTAIN: + break; default: willid = B_TRUE; break; } } - if (!isknown(o) && willid) { - // id the potion - makeknown(o->type->id); - real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness - if (isplayer(lf)) { - // tell the player - msg("This is %s!",obname); - more(); - drawmsg(); + if (willid) { + if (o->type->id == OT_FOUNTAIN) { + flag_t *f; + f = hasflag(o->flags, F_LINKOB); + f->val[2] = B_TRUE; + // refresh fountain name + getobname(o, obname, 1); + if (isplayer(lf)) { + // tell the player + msg("This is %s!",obname); + more(); + drawmsg(); + } + } else if (!isknown(o)) { + // id the potion + makeknown(o->type->id); + real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness + if (isplayer(lf)) { + // tell the player + msg("This is %s!",obname); + more(); + drawmsg(); + } } } + if (o->type->obclass->id == OC_POTION) { potioneffects(lf, o->type->id, o, o->blessed, &seen); } else { - drinkflag= hasflag(o->flags, F_DRINKABLE); + drinkflag = hasflag(o->flags, F_DRINKABLE); if (drinkflag) { - // drinkable thing which isn't a potion? + // this is a drinkable thing which isn't a potion flag_t *f; + + f = hasflag(o->flags, F_LINKOB); if (f) { potioneffects(lf, f->val[0], o, o->blessed, NULL); } else { eat(lf, o); } - // + + // fountains sometimes dry up + if ((o->type->id == OT_FOUNTAIN) && onein(4)) { + cell_t *loc; + // dry up (ie. remove DONTKILL property) + drinkflag->val[2] = NA; + loc = getoblocation(o); + if (haslos(lf, loc)) { + msg("%s dries up.", obname); + } + } + if (drinkflag->val[2] == B_DONTKILL) { killobwhendone = B_FALSE; } @@ -11151,7 +11603,7 @@ void quaff(lifeform_t *lf, object_t *o) { } if (killobwhendone) { - // lose the potion + // remove the potion (or whatever it is) removeob(o, 1); } @@ -11231,6 +11683,18 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE msg("This makes you feel incredible!"); } } + break; + case OT_POT_COFFEE: + if (isplayer(lf)) { + msg("This tastes like coffee."); + } + // sates hunger a tiny bit + modhunger(lf, -pctof(10, (float)HUNGERCONST)); + // sobers you up + killtransitoryflags(lf->flags, F_DRUNK); + // no more sleeping for a while! + addtempflag(lf->flags, F_CAFFEINATED, B_TRUE, NA, NA, NULL,rnd(30,60)); + break; case OT_POT_COMPETENCE: failed = B_TRUE; @@ -11248,10 +11712,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE // select a random attribute if (potblessed == B_BLESSED) { // modify all attributes - if (!modattr(lf, A_STR, amt)) failed = B_FALSE; - if (!modattr(lf, A_DEX, amt)) failed = B_FALSE; - if (!modattr(lf, A_IQ, amt)) failed = B_FALSE; - if (!modattr(lf, A_CON, amt)) failed = B_FALSE; + for (i = 0; i < MAXATTS; i++) { + if (!modattr(lf, i, amt)) failed = B_FALSE; + } } else { enum ATTRIB a; // modify just one attribute @@ -11268,26 +11731,28 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE } break; case OT_POT_RUM: - // how long for? - f = lfhasflag(lf, F_DRUNK); - if (f) { + + // kill coffee flags + killtransitoryflags(lf->flags, F_CAFFEINATED); + if (lfhasflag(lf, F_CAFFEINATED)) { + // ie. conferred by something equipped etc if (isplayer(lf)) { - msg("You feel more tipsy."); - } else if (cansee(player, lf)) { - msg("%s looks more tipsy.", lfname); + msg("For some reason, the alcohol has no effect on you."); } - f->lifetime += DRUNKTIME; } else { - addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, DRUNKTIME); + // get drunk(er) + f = lfhasflag(lf, F_DRUNK); + if (f) { + if (isplayer(lf)) { + msg("You feel more tipsy."); + } else if (cansee(player, lf)) { + msg("%s looks more tipsy.", lfname); + } + f->lifetime += DRUNKTIME; + } else { + addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, DRUNKTIME); + } } - /* - if (!lfhasflagval(lf, F_DTRESIST, DT_FIRE, NA, NA, NULL)) { - addtempflag(lf->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL, i); - } - if (!lfhasflagval(lf, F_DTRESIST, DT_COLD, NA, NA, NULL)) { - addtempflag(lf->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, i); - } - */ break; case OT_POT_ELEMENTIMMUNE: if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) { @@ -11350,6 +11815,10 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE addtempflag(lf->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL, i); } break; + case OT_POT_LEVITATION: + i = rnd(5,20); + addtempflag(lf->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, i); + break; case OT_POT_MAGIC: if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, -10)) { if (isplayer(lf)) { @@ -11999,8 +12468,6 @@ object_t *relinkob(object_t *src, obpile_t *dst) { nextf = f->next; if (f->id == F_EQUIPPED) { killflag(f); - } else if (f->id == F_CURAMMO) { - killflag(f); } } @@ -12341,6 +12808,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { case OT_POT_ELEMENTIMMUNE: case OT_POT_ETHEREALNESS: case OT_POT_GASEOUSFORM: + case OT_POT_LEVITATION: case OT_POT_POISON: case OT_POT_POLYMORPH: case OT_POT_INVIS: @@ -12550,6 +13018,16 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno return howmuch; } } + } else if (damtype == DT_COLD) { + // cold will shatter glass + if (o->material->id == MT_GLASS) { + char buf[BUFLEN]; + char buf2[BUFLEN]; + getobname(o, buf2, 1); + sprintf(buf, "a shattering %s", buf2); + shatter(o, B_TRUE, buf, B_FALSE); + return howmuch; + } } @@ -12717,7 +13195,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno if (o->pile->owner) { if (wantannounce) { if (isplayer(o->pile->owner)) { - msg("Your %s %s!",noprefix(obname), getobhurtname(o, damtype)); + msg("^wYour %s %s!",noprefix(obname), getobhurtname(o, damtype)); } else if (cansee(player, o->pile->owner)) { // don't announce decay damage for object you aren't holding if (damtype != DT_DECAY) { @@ -12767,6 +13245,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, int db = B_TRUE; int willcatch = B_FALSE; int announcedmiss = B_FALSE; + int outofammo = B_FALSE; float multiplier; reason = E_OK; @@ -12825,7 +13304,11 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, strcat(realthrowernamea, "something"); } - srcloc = getoblocation(o); + if (firearm) { + srcloc = getoblocation(firearm); + } else { + srcloc = getoblocation(o); + } // can't throw weilded cursed objects if ((o->blessed == B_CURSED) && (!firearm)) { @@ -12878,11 +13361,17 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, } // touch effects - if (thrower && !firearm) { - if (o->pile == thrower->pack) { - if (touch(thrower, o)) { + if (thrower) { + if (firearm) { + if (touch(thrower, firearm)) { return B_TRUE; } + } else { + if (o->pile == thrower->pack) { + if (touch(thrower, o)) { + return B_TRUE; + } + } } } @@ -13055,7 +13544,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, // roll for hit youhit = B_FALSE; - // metal weapon versus magnetic shield? + // metal projectile versus magnetic shield? if (target && lfhasflag(target, F_MAGSHIELD) && ismetal(o->material->id)) { // announce if (seen) { @@ -13067,6 +13556,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, youhit = B_TRUE; } + if (youhit && target) { flag_t *f; object_t *shield; @@ -13085,7 +13575,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, shield = getshield(target); if (shield && !lfhasflag(target, F_CASTINGSPELL)) { // block chance based on shield skill - // ie. ST_AVERAGE = speed3 = 18 + // ie. AT_AVERAGE = speed3 = 18 // ie. gun = speed20 = 120 = impossible if (skillcheck(target, SC_SHIELDBLOCK, speed*6, 0)) { int throwdam,dam; @@ -13216,6 +13706,12 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, } missiledam += ((speed*2)+1); + + if (firearm) { + practice(thrower, SK_THROWING, 1); + } else { + practice(thrower, SK_RANGED, 1); + } } } else { // ie. if !youhit if (!announcedmiss) { @@ -13243,6 +13739,11 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, // fake its birth time so that it can be damaged newob->birthtime = -1; + // gun out of ammo? + if (firearm && !countobs(firearm->contents, B_FALSE)) { + outofammo = B_TRUE; + } + if (willshatter(newob->material->id)) { char dambuf[BUFLEN]; sprintf(dambuf, "%s (%s by %s)",obname,throwverbpast, realthrowernamea); @@ -13255,6 +13756,12 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, } } + if (firearm && outofammo && isplayer(thrower)) { + char buf[BUFLEN]; + getobname(firearm, buf, 1); + msg("Your %s is now out of ammo.", noprefix(buf)); + } + return B_FALSE; } @@ -13782,12 +14289,11 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf) { } else if (oid == OT_TRAPGAS) { // can't be dodged dospelleffects(NULL, OT_S_CLOUDKILL, 3, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); + removeob(trapob, trapob->amt); } else if (oid == OT_TRAPMINE) { // can't be dodged explodecells(lf->cell, roll("2d6"), B_FALSE, trapob, 1, DT_ORTH, B_TRUE); - if (trapob) { - killob(trapob); - } + if (trapob) removeob(trapob, trapob->amt); } else if (oid == OT_TRAPTRIP) { if (avoided) { if (isplayer(lf)) { @@ -14015,9 +14521,24 @@ int validateobs(void) { printf("ERROR in object '%s' - cannot have F_BLUNTONFAIL on stackable objects.\n", ot->name); goterror = B_TRUE; } - if (hasflag(ot->flags, F_FIREARM) && !hasflag(ot->flags, F_RANGE)) { - printf("ERROR in object '%s' - firearms need to have F_RANGE.\n", ot->name); - goterror = B_TRUE; + if (hasflag(ot->flags, F_FIREARM)) { + if (!hasflag(ot->flags, F_RANGE)) { + printf("ERROR in object '%s' - firearms need to have F_RANGE.\n", ot->name); + goterror = B_TRUE; + } + if (!hasflag(ot->flags, F_AMMOCAPACITY)) { + printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name); + goterror = B_TRUE; + } + if (!hasflag(ot->flags, F_FIRETURNS)) { + printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name); + goterror = B_TRUE; + } + if (!hasflag(ot->flags, F_RELOADTURNS)) { + printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name); + goterror = B_TRUE; + } + } f = hasflag(ot->flags, F_TECHLEVEL); if (f && (f->val[0] != PR_INEPT)) { @@ -14226,7 +14747,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob // figure out if you miss or not, based on distance and // dexterity // base: - // if throwing, 50% + // if throwing, 40% + 10*sk_throwing // if firing, gun accuracy modified by sk_ranged // adjust for range: // pointblank = +30% @@ -14242,8 +14763,11 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob // ie. inept = -30%, adept = 0%, master = +30% acc += ((slev - PR_ADEPT) * 10); } else { - slev = PR_INEPT; - acc = 50; + slev = getskill(thrower, SK_THROWING); + acc = 40; + // ie. inept = -30%, adept = 0%, master = +30% + acc += ((slev - PR_ADEPT) * 10); + // acc will now be 10 - 70 } // adjust for range @@ -14258,6 +14782,15 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob } howfar = getcelldist(thrower->cell, where); + + // ie. -30 to 30 + if (firearm && (slev == PR_MASTER) ) { + } else { + int rangemod; + rangemod = 30 - ((int) (((float)howfar / (float)maxrange) * 60.0)); + acc += rangemod; + } + /* if (howfar == 1) { acc += 30; } else if (howfar == maxrange) { @@ -14265,6 +14798,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob acc -= 30; } } + */ // modify for dexterity if (whichatt != A_NONE) { @@ -14278,12 +14812,13 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob // modify for prone throwers if (isprone(thrower)) { acc -= 50; - } else { - // modify for prone defenders - if (where->lf && isprone(where->lf)) { - acc -= 30; - } + } + + // modify for prone defenders + if (where->lf && isprone(where->lf)) { + acc -= 30; } + limit(&acc, 0, NA); return acc; } diff --git a/objects.h b/objects.h index fa3fff8..1abf267 100644 --- a/objects.h +++ b/objects.h @@ -13,9 +13,9 @@ object_t *addob(obpile_t *where, char *name); object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes); int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof); obmod_t *addobmod(enum OBMOD id, char *prefix); -obpile_t *addobpile(lifeform_t *owner, cell_t *where); +obpile_t *addobpile(lifeform_t *owner, cell_t *where, object_t *parentob); void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes); -objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid); +objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size); void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat); void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat); void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype); @@ -63,11 +63,14 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob int getobaccuracy(object_t *wep, lifeform_t *weilder); int getobbonus(object_t *o); skill_t *getobskill(object_t *o); +enum LFSIZE getobsize(object_t *o); int getobspellpower(object_t *o, lifeform_t *lf); int getobvalue(object_t *o); +char *getoperateverb(object_t *o); +object_t *getoutercontainer(object_t *o); //int getobtypevalue(objecttype_t *ot); char *getaccuracyname(int accpct); -object_t *getammo(lifeform_t *lf); +object_t *getammo(object_t *gun); objecttype_t *getbasicweaponforskill(enum SKILL skid); object_t *getrandomammo(lifeform_t *lf); objecttype_t *getrandomammofor(object_t *o); @@ -104,8 +107,9 @@ char *getobhurtname(object_t *o, enum DAMTYPE damtype); float getobweight(object_t *o); float getobunitweight(object_t *o); objecttype_t *getoppositestairs(objecttype_t *ot); -char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat); +char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat, enum LFSIZE maxsize); char *getrandomob(map_t *map, char *buf); +char *getrandomobofsize(map_t *map, char *buf, enum LFSIZE maxsize); char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf); char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod); int getobrarity(object_t *o, enum RARITY *rr); @@ -196,6 +200,8 @@ int obmatchescondition(object_t *o, long opts); int obproduceslight(object_t *o); int obpropsmatch(object_t *a, object_t *b); int obotpropsmatch(object_t *a, objecttype_t *b); +flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf); +int obsfallthrough(cell_t *c, object_t *pit); int operate(lifeform_t *lf, object_t *o, cell_t *where); int pilehasletter(obpile_t *op, char let); void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE potlessed, int *seen); diff --git a/save.c b/save.c index caa5add..b0a0d12 100644 --- a/save.c +++ b/save.c @@ -13,6 +13,7 @@ #include "nexus.h" #include "objects.h" #include "save.h" +#include "text.h" #include "vault.h" extern long curtime; @@ -20,6 +21,8 @@ extern long curtime; extern lifeform_t *player; extern map_t *firstmap; extern knowledge_t *knowledge; +extern region_t *firstregion,*lastregion; +extern regionoutline_t *firstregionoutline,*lastregionoutline; extern enum GAMEMODE gamemode; @@ -34,6 +37,14 @@ int loadall(void) { dblog("Could not open map directory '%s'",MAPDIR); return B_TRUE; } + + // load region outlines first. + if (loadregions()) { + // this isn't an error - just means no savegames + dblog("No region data found."); + return B_FALSE; + } + // for each map file in directory while ((ent = readdir(dir)) != NULL) { char *p; @@ -61,7 +72,7 @@ int loadflagpile(FILE *f, flagpile_t *fp) { flag_t *fl; char buf[BUFLEN]; int rv; - int db = B_TRUE; + int db = B_FALSE; rv = fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%ld\n", &tempflag.id, &tempflag.nvals, &tempflag.val[0], &tempflag.val[1], &tempflag.val[2],&tempflag.lifetime, &tempflag.known,&tempflag.obfrom); @@ -265,6 +276,7 @@ map_t *loadmap(char *basefile) { object_t *o; map_t *m; cell_t *dummycell; + int regionid; if (db) dblog("Loading map from %s...",basefile); sprintf(filename, "%s/%s",MAPDIR,basefile); @@ -273,7 +285,7 @@ map_t *loadmap(char *basefile) { // create map m = addmap(); dummycell = malloc(sizeof(cell_t)); - dummycell->obpile = addobpile(NULL, dummycell); + dummycell->obpile = addobpile(NULL, dummycell, NULL); dummycell->map = m; dummycell->type = (celltype_t *)DUMMYCELLTYPE; // for debugging @@ -285,11 +297,13 @@ map_t *loadmap(char *basefile) { // load map info if (db) dblog("--> Loading map info...\n"); fscanf(f, "id:%d\n",&m->id); // map id + fscanf(f, "region:%d\n",®ionid); // region id + m->region = findregion(regionid); fscanf(f, "depth:%d\n",&m->depth); // map depth fgets(buf, BUFLEN, f); // map name buf[strlen(buf)-1] = '\0'; // strip newline m->name = strdup(buf + 5); // after 'name:' - fscanf(f, "habitat:%d\n",(int *)habitatid); // habitat + fscanf(f, "habitat:%d\n",(int *)&habitatid); // habitat m->habitat = findhabitat(habitatid); fscanf(f, "seed:%d\n",&m->seed); // seed fscanf(f, "dims:%d,%d\n",&m->w, &m->h); // map dimensons @@ -549,7 +563,105 @@ int loadob(FILE *f, obpile_t *op, long *id) { dblog("About to start loading object flags..."); loadflagpile(f, o->flags); - fscanf(f, "endob\n"); + + fgets(buf, BUFLEN, f);// either 'obcontents:xx' or 'endob' + if (strstarts(buf, "obcontents")) { + // load this object's contents... + char *p; + char buf2[BUFLEN]; + int ncontents; + int i; + //dblog("got obcontents"); + // strip newline + buf[strlen(buf)-1] = '\0'; + p = readuntil(buf2, buf, ':'); // ignore bit before : + p = readuntil(buf2, p, ')'); // ) will really be eol + ncontents = atoi(buf2); + for (i = 0 ; i < ncontents; i++) { + loadob(f, o->contents, NULL); + } + fgets(buf, BUFLEN, f);// 'endobcontents' + //dblog("want endobcontents, got: '%s'", buf); + fgets(buf, BUFLEN, f);// 'endob' + //dblog("want endob, got: '%s'", buf); + } + if (strstarts(buf, "endob")) { + // we got 'endob' + } else { + dblog("ERROR loading objects - expecting 'endob' but got '%s'\n",buf); + exit(1); + } + + //fscanf(f, "endob\n"); + return B_FALSE; +} + +int loadregions(void) { + FILE *f; + char filename[BUFLEN]; + int rtid,nthings,i,n; + int numoutlines,numregions; + int db = B_FALSE; + + // TODO: check that map dir exists + sprintf(filename, "%s/regions.dat",MAPDIR); + f = fopen(filename, "rt"); + if (!f) { + return B_TRUE; + } + + fscanf(f, "numoutlines:%d\n",&numoutlines); + if (db) dblog("Found %d region outlines.\n",numoutlines); + for (n = 0; n < numoutlines; n++) { + fscanf(f, "startro\n"); + fscanf(f, "rtypeid:%d\n",&rtid); // region type id + addregionoutline(rtid); + + fscanf(f, "nthings:%d\n",&nthings); + for (i = 0; i < nthings; i++) { + int depth,x,y,val; + enum REGIONTHING whatkind; + char buf[BUFLEN],*p; + fscanf(f, "startthing\n"); + fscanf(f, " thingdepth:%d,%d,%d\n",&depth, &x, &y); + fscanf(f, " thingkind:%d\n",(int *)&whatkind); + fscanf(f, " thingval:%d\n",&val); + fscanf(f, " thingwhat:%s\n",buf); + fscanf(f, "endthing\n"); + + // replace ^ with ' ' in thingwhat + for (p = buf ; *p; p++) { + if (*p == '^') *p = ' '; + } + addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf); + } + fscanf(f, "endro\n"); + if (db) dblog("Loaded regionoutline #%d / %d",n+1, numoutlines); + } + + // now save out the actual region->outline mappings + fscanf(f, "numregions:%d\n",&numregions); + if (db) dblog("Found %d regions.\n",numregions); + for (n = 0; n < numregions; n++) { + region_t *r; + enum REGIONTYPE rtid; + int outlineid,parentid,nthings; + fscanf(f, "startregion\n"); + fscanf(f, " rtypeid:%d\n",(int *)&rtid); + fscanf(f, " outline:%d\n",&outlineid); + fscanf(f, " parentregion:%d\n",&parentid); + fscanf(f, " nthings:%d\n",&nthings); + fscanf(f, "endregion\n"); + r = addregion(rtid, (parentid == -1) ? NULL : findregion(parentid), outlineid); + r->nthings = nthings; + if (db) dblog("Loaded region #%d / %d",n+1, numregions); + } + + fclose(f); + + // successful load - kill the file now + unlink(filename); + return B_FALSE; } @@ -581,7 +693,7 @@ int loadsavegame(void) { exit(1); } if (!loadlf(f, NULL)) { - printf("Error loading savegame from file '%s'",ent->d_name); + printf("Error loading player from file '%s'",ent->d_name); exit(1); } if (loadknowledge(f)) { @@ -699,6 +811,12 @@ int savegame(void) { FILE *f; char buf[BUFLEN]; int rv; + rv = saveregions(); + if (rv) { + msg("Could not save region data."); + return B_TRUE; + } + for (m = firstmap; m ; m = m->next) { // save world rv = savemap(m); @@ -737,6 +855,7 @@ int savemap(map_t *m) { // save map info fprintf(f, "id:%d\n",m->id); // map id + fprintf(f, "region:%d\n",m->region->id); // map region id fprintf(f, "depth:%d\n",m->depth); // map depth fprintf(f, "name:%s\n",m->name); // map name fprintf(f, "habitat:%d\n",m->habitat->id); // habitat @@ -797,6 +916,8 @@ int savemap(map_t *m) { int saveob(FILE *f, object_t *o) { + object_t *oo; + int ncontents; fprintf(f, "id:%ld\n",o->id); fprintf(f, "type:%d\n",o->type->id); fprintf(f, "material:%d\n",o->material->id); @@ -808,6 +929,78 @@ int saveob(FILE *f, object_t *o) { fprintf(f, "amt:%d\n",o->amt); fprintf(f, "birthtime:%ld\n",o->birthtime); saveflagpile(f, o->flags); + // object contents... + ncontents = countobs(o->contents, B_FALSE); + if (ncontents) { + fprintf(f, "obcontents:%d\n",ncontents); + for (oo = o->contents->first ; oo ; oo = oo->next) { + saveob(f, oo); + } + fprintf(f, "endobcontents\n"); + } fprintf(f, "endob\n"); return B_FALSE; } + +int saveregions(void) { + FILE *f; + char filename[BUFLEN]; + int i; + regionoutline_t *ro; + region_t *r; + int numoutlines = 0,numregions = 0; + + // TODO: check that map dir exists + sprintf(filename, "%s/regions.dat",MAPDIR); + f = fopen(filename, "wt"); + for (ro = firstregionoutline ; ro ; ro = ro->next) { + numoutlines++; + } + fprintf(f, "numoutlines:%d\n",numoutlines); + + for (ro = firstregionoutline ; ro ; ro = ro->next) { + // save this outline + fprintf(f, "startro\n"); + fprintf(f, "rtypeid:%d\n",ro->rtype->id); // region type id + fprintf(f, "nthings:%d\n",ro->nthings); + for (i = 0; i < ro->nthings; i++) { + fprintf(f, "startthing\n"); + fprintf(f, " thingdepth:%d,%d,%d\n",ro->thing[i].depth, ro->thing[i].x, ro->thing[i].y); + fprintf(f, " thingkind:%d\n",(int)ro->thing[i].whatkind); + fprintf(f, " thingval:%d\n",(int)ro->thing[i].value); + if (strlen(ro->thing[i].what)) { + char localwhat[BUFLEN],*p; + strcpy(localwhat,ro->thing[i].what); + for (p = localwhat ; *p; p++) { + if (*p == ' ') *p = '^'; + } + fprintf(f, " thingwhat:%s\n",localwhat); + } else { + fprintf(f, " thingwhat:NULL\n"); + } + fprintf(f, "endthing\n"); + } + fprintf(f, "endro\n"); + } + + + // now save out the actual region->outline mappings + + numregions = 0; + for (r = firstregion ; r; r = r->next) { + numregions++; + } + + fprintf(f, "numregions:%d\n",numregions); + for (r = firstregion ; r; r = r->next) { + fprintf(f, "startregion\n"); + fprintf(f, " rtypeid:%d\n",r->rtype->id); + fprintf(f, " outline:%d\n",r->outline ? r->outline->id : -1); + fprintf(f, " parentregion:%d\n",r->parentregion ? r->parentregion->id : -1); + fprintf(f, " nthings:%d\n",r->nthings); + fprintf(f, "endregion\n"); + } + fclose(f); + + return B_FALSE; +} diff --git a/save.h b/save.h index aeb6e9c..f46b2c4 100644 --- a/save.h +++ b/save.h @@ -6,6 +6,7 @@ int loadknowledge(FILE *f); lifeform_t *loadlf(FILE *f, cell_t *where); map_t *loadmap(char *basefile); int loadob(FILE *f, obpile_t *op, long *id); +int loadregions(void); int loadsavegame(void); int saveflagpile(FILE *f, flagpile_t *fp); int saveknowledge(FILE *f); @@ -13,3 +14,4 @@ int savelf(FILE *f, lifeform_t *l); int savegame(void); int savemap(map_t *m); int saveob(FILE *f, object_t *o); +int saveregions(void); diff --git a/spell.c b/spell.c index e1e9bd3..d8165c6 100644 --- a/spell.c +++ b/spell.c @@ -390,6 +390,41 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } } } + } else if (abilid == OT_A_FEIGNDEATH) { + lifeform_t *lf; + if (hasflag(user->flags, F_FEIGNINGDEATH)) { + if (isplayer(user)) msg("You are already feigning death!"); + return B_TRUE; + } + taketime(user, getactspeed(user)); + + if (isplayer(user)) { + msg("You drop to the ground."); + } else if (cansee(player, user)) { + if (target) { + char targname[BUFLEN]; + getlfname(target, targname); + msg("%s kill%s %s.", targname, isplayer(target) ? "" : "s", username); + } else { + msg("%s dies.", username); + } + } + addflag(user->flags, F_PRONE, B_TRUE, NA, NA, NULL); + addflag(user->flags, F_FEIGNINGDEATH, B_TRUE, NA, NA, NULL); + // anyone attacking you stops + for (lf = user->cell->map->lf ; lf ; lf = lf->next) { + flag_t *f; + char buf[BUFLENTINY]; + f = hasflagval(lf->flags, F_TARGETLF, user->id, NA, NA, NULL); + if (f) killflag(f); + f = hasflagval(lf->flags, F_TARGETCELL, user->cell->x, user->cell->y, NA, NULL); + if (f) killflag(f); + sprintf(buf, "%d\n",user->id); + f = hasflagval(lf->flags, F_TARGETCELL, NA, NA, MR_LF, buf); + if (f) killflag(f); + } + needredraw = B_TRUE; + statdirty = B_TRUE; } else if (abilid == OT_A_FLURRY) { int dir; int dirch; @@ -399,7 +434,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - if (!isdualweilding(user)) { + if (hasjob(user, J_MONK)) { + if (getweapon(user)) { + if (isplayer(user)) msg("You need be unarmed to perform an attack flurry!"); + } + return B_TRUE; + } else if (!isdualweilding(user)) { if (isplayer(user)) msg("You need two be dual-weilding to perform an attack flurry!"); return B_TRUE; } @@ -561,28 +601,40 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef char victimname[BUFLEN]; int dodged = B_FALSE; cell_t *origcell; + int maxrange = 2; if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isplayer(user)) msg("You can't jump while swimming!"); return B_TRUE; + } else if (isairborne(user)) { + if (isplayer(user)) msg("You can't jump while airbourne!"); + return B_TRUE; + } else if (hasflag(user->flags, F_GRAVBOOSTED)) { + if (isplayer(user)) msg("You can't jump with gravity boosted around you!"); + return B_TRUE; } + if (hasflag(user->flags, F_GRAVLESSENED)) { + maxrange++; + } + + if (!targcell) { - sprintf(buf, "Jump where (max distance 2)?"); + sprintf(buf, "Jump where (max distance %d)?", maxrange); while (!targcell) { // ask where - targcell = askcoords(buf, "Jump->", TT_NONE, user, 2, LOF_DONTNEED, B_TRUE); + targcell = askcoords(buf, "Jump->", TT_NONE, user, maxrange, LOF_DONTNEED, B_TRUE); if (!targcell) { return B_TRUE; - } else if (getcelldist(user->cell, targcell) > 2) { + } else if (getcelldist(user->cell, targcell) > maxrange) { targcell = NULL; if (isplayer(user)) { - sprintf(buf, "You can't jump that far! Jump where (max distance 2)?"); + sprintf(buf, "You can't jump that far! Jump where (max distance %d)?", maxrange); } } else if (!haslos(user, targcell)) { targcell = NULL; if (isplayer(user)) { - sprintf(buf, "You can't see where to land! Jump where (max distance 2)?"); + sprintf(buf, "You can't see where to land! Jump where (max distance %d)?", maxrange); } } } @@ -707,10 +759,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef int cutoff; switch (slev) { case PR_NOVICE: cutoff = 33; break; - case PR_BEGINNER: cutoff = 40; break; - case PR_ADEPT: cutoff = 50; break; - case PR_SKILLED: cutoff = 65; break; - case PR_EXPERT: cutoff = 80; break; + case PR_BEGINNER: cutoff = 50; break; + case PR_ADEPT: cutoff = 60; break; + case PR_SKILLED: cutoff = 70; break; + case PR_EXPERT: cutoff = 85; break; case PR_MASTER: cutoff = 100; break; default: cutoff = 0; break; } @@ -723,10 +775,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef int cutoff; switch (slev) { case PR_NOVICE: cutoff = 33; break; - case PR_BEGINNER: cutoff = 40; break; - case PR_ADEPT: cutoff = 50; break; - case PR_SKILLED: cutoff = 65; break; - case PR_EXPERT: cutoff = 80; break; + case PR_BEGINNER: cutoff = 50; break; + case PR_ADEPT: cutoff = 60; break; + case PR_SKILLED: cutoff = 70; break; + case PR_EXPERT: cutoff = 85; break; case PR_MASTER: cutoff = 100; break; default: cutoff = 0; break; } @@ -868,6 +920,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef addtempflag(user->flags, F_SPRINTING, B_TRUE, NA, NA, NULL, howlong); practice(user, SK_ATHLETICS, 1); + // get hungry heaps! + modhunger(user, 50); } else if (abilid == OT_A_STINGACID) { validateabillf(user, abilid, &target); if (!target) return B_TRUE; @@ -1031,6 +1085,109 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (haslos(player, origcell)) { redraw(); } + } else if (abilid == OT_A_TUMBLE) { + cell_t *origcell,*c; + cell_t *retcell[MAXRETCELLS]; + int i,nretcell = 0; + object_t *stopob = NULL; + + if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { + if (isplayer(user)) msg("You can't tumble while swimming!"); + return B_TRUE; + } else if (isairborne(user)) { + if (isplayer(user)) msg("You can't tumble while airbourne!"); + return B_TRUE; + } + + if (!targcell) { + sprintf(buf, "Tumble where (max distance 2)?"); + while (!targcell) { + // ask where + targcell = askcoords(buf, "Tumble->", TT_NONE, user, 2, LOF_NEED, B_TRUE); + if (!targcell) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE; + } else if (!haslos(user, targcell)) { + targcell = NULL; + if (isplayer(user)) { + sprintf(buf, "You can't see where to land! Tumble where (max distance 2)?"); + } + } else if (!haslof(user->cell, targcell, LOF_NEED, NULL)) { + targcell = NULL; + if (isplayer(user)) { + sprintf(buf, "You don't have a clear line of fire to there!"); + } + } + } + } + + if (isburdened(user)) { + if (isplayer(user)) { + msg("Your load is too heavy to tumble with!"); + } + return B_TRUE; + } else if (lfhasflag(user, F_GRAVBOOSTED)) { + if (isplayer(user)) { + msg("Gravity around you is too strong to tumble!"); + } + return B_TRUE; + } + + origcell = user->cell; + + taketime(user, getactspeed(user)); + + + // will you be interrupted on the way? + calcbresnham(origcell->map, origcell->x, origcell->y, targcell->x, targcell->y, retcell, &nretcell); + for (i = 0; i < nretcell; i++) { + c = retcell[i]; + if (getcellwaterdepth(c, user)) { + // stop here. + targcell = c; + stopob = hasobwithflag(c->obpile, F_DEEPWATER); + break; + } else if (hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL)) { + // stop here. + targcell = c; + stopob = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL); + break; + } + } + + // skillcheck... + if (!skillcheck(user, SC_TUMBLE, 10, 0)) { + // fail! + if (isplayer(user)) { + msg("You fumble and fall."); + } else if (cansee(player, user)) { + msg("%s fumbles and falls.", username); + } + fall(user, NULL, B_FALSE); + return B_FALSE; + } + + + // go there! + movelf(user, targcell); + + // announce + if (isplayer(user)) { + msg("You tumble across the ground!"); + } else if (cansee(player, user)) { + msg("%s tumbles across the ground!", username); + } + // pits/water? + if (stopob) { + char obname[BUFLEN]; + getobname(stopob, obname, 1); + if (isplayer(user)) { + msg("Your tumble is interrupted by %s!",obname); + } else if (cansee(player, user)) { + msg("%s%s tumble is interrupted by %s!",username,getpossessive(username), obname); + } + } + } else if (abilid == OT_A_POLYREVERT) { flag_t *f; if (!target) target = user; @@ -1170,6 +1327,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef char targetname[BUFLEN]; flag_t *f; int heavyamt = 8; + int badweapon = B_FALSE; if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isplayer(user)) msg("You lack the stability for a heavy blow while swimming."); @@ -1177,10 +1335,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } wep = getweapon(user); - if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < heavyamt)) { // ie. 8 is weight of a mace + if (!wep) { + if (!hasjob(user, J_MONK)) { + badweapon = B_TRUE; + } + } else if (!ismeleeweapon(wep) || (getobunitweight(wep) < heavyamt)) { // ie. 8 is weight of a mace + badweapon = B_TRUE; + } + + if (badweapon) { if (isplayer(user)) msg("You need a heavy weapon (%dkg or more) to perform a heavy blow!", heavyamt); return B_TRUE; - } + } // ask for direction if (!targcell) { @@ -1207,7 +1373,52 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } getlfname(target, targetname); - f = addflag(wep->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); + f = addflag(user->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); + attackcell(user, targcell, B_TRUE); + killflag(f); + } else if (abilid == OT_A_QUIVERINGPALM) { + object_t *wep; + char dirch; + char targetname[BUFLEN]; + flag_t *f; + + if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { + if (isplayer(user)) msg("You lack the stability to use this ability while swimming."); + return B_TRUE; + } + + wep = getweapon(user); + if (wep) { + if (isplayer(user)) msg("You must be unarmed to make a quivering palm strike."); + return B_TRUE; + } + + // ask for direction + if (!targcell) { + dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + if (dirch == '.') { + // yourself! + targcell = user->cell; + } else { + int dir; + dir = chartodir(dirch); + if (dir == D_NONE) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE ; + } else { + targcell = getcellindir(user->cell, dir); + } + } + } + + target = targcell->lf; + if (!target) { + if (isplayer(user)) msg("There is nobody there to attack!"); + return B_TRUE; + } + getlfname(target, targetname); + + f = addflag(user->flags, F_QUIVERINGPALM, B_TRUE, NA, NA, NULL); attackcell(user, targcell, B_TRUE); killflag(f); } else if (abilid == OT_A_STEAL) { @@ -1895,6 +2106,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } teleportto(caster, targcell, B_TRUE); } + } else if (spellid == OT_S_BODYCONTROL) { + flag_t *f; + // ie. 2 - 4 + f = addtempflag(caster->flags, F_SLOWMETAB, 2+(power/4), NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; + // you move more slowly too. + if (power < 3) { + f = addtempflag(caster->flags, F_SLOWMOVE, 10, NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; + } else if (power < 5) { + f = addtempflag(caster->flags, F_SLOWMOVE, 5, NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; + } } else if (spellid == OT_S_BURNINGWAVE) { cell_t *retcell[MAXRETCELLS]; int nretcell; @@ -2037,7 +2261,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int powerleft; int donesomething = B_FALSE; cell_t *c; - powerleft = rolldie(power+1, 4); + //powerleft = rolldie(power+1, 4); + powerleft = power; for (i = 0; i < caster->nlos; i++) { c = caster->los[i]; if (c->lf && (c->lf->race->raceclass->id == RC_ANIMAL) && (gethitdice(c->lf) <= powerleft)) { @@ -2328,13 +2553,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ getlfname(target, lfname); // how many body parts are impacted? - exposedlimbs = 0; - if (!getouterequippedob(target, BP_HEAD)) exposedlimbs += 1; - if (!getouterequippedob(target, BP_SHOULDERS)) exposedlimbs += 1; - if (!getouterequippedob(target, BP_BODY)) exposedlimbs += 2; - if (!getouterequippedob(target, BP_HANDS)) exposedlimbs += 1; - if (!getouterequippedob(target, BP_LEGS)) exposedlimbs += 2; - if (!getouterequippedob(target, BP_FEET)) exposedlimbs += 1; + exposedlimbs = getexposedlimbs(target); dam = rolldie(exposedlimbs, 3); @@ -2358,9 +2577,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // always hit if (!isimmuneto(target->flags, DT_COLD)) { losehp(target, dam, DT_COLD, caster, "a chill spell"); - if (!skillcheck(target, SC_CON, 20+(exposedlimbs*3), 0)) { - poison(target, 20+(power*3), P_COLD, 0, "a chill spell"); - } } } else if (spellid == OT_S_COLDBURST) { int range = 1; @@ -2515,12 +2731,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ jobname[0] = tolower(jobname[0]); p = strstr(buf, jobname); if (p) { - char newbuf[BUFLEN]; - strncpy(newbuf, buf, (p - buf) - 1); - r = findracebyname(newbuf); - if (r) { - forcejob = j; + if (p == buf) { + // just asked for the job name + // fail. break; + } else { + char newbuf[BUFLEN]; + strncpy(newbuf, buf, (p - buf) - 1); + r = findracebyname(newbuf); + if (r) { + forcejob = j; + break; + } } } } @@ -2691,8 +2913,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } else if (ch == '<') { + if (seenbyplayer && haslos(player, caster->cell)) *seenbyplayer = B_TRUE; return digup(caster, NULL); } else if (ch == '>') { + if (seenbyplayer && haslos(player, caster->cell)) *seenbyplayer = B_TRUE; return digdown(caster, NULL); } else { dir = chartodir(ch); @@ -3503,6 +3727,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = hasflag(o->flags, F_RESTRICTMOVEMENT); if (f) { f->val[0] = 30 + (power/2); + f->val[1] = B_FALSE; // struggling doesn't damage the vine } /// remmeber creator. if they don't have los to us, spell // is broken and vines will vanish. @@ -4261,7 +4486,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - // 4 is the same as ST_TITANIC strength + // 5 is the same as AT_VHIGH strength // 10 = gun speed fireat(caster, targob, 1, targcell, 8 + (power / 2) , NULL); } else if (spellid == OT_S_PARALYZE) { @@ -4512,37 +4737,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(caster->flags, F_MAGICARMOUR, power*4, NA, NA, "psychic barrier", FROMSPELL); f->obfrom = spellid; - } else if (spellid == OT_S_PULL) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - - target = targcell->lf; - - if (target) { - int failed = B_FALSE; - - if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { - failed = B_TRUE; - } else { - // they get pulled towards caster - failed = pullnextto(target, caster->cell); - } - - if (isplayer(target) || cansee(player, target)) { - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - - if (failed) { - if (isplayer(target) || cansee(player, target)) { - char buf[BUFLEN]; - getlfname(target, buf); - msg("%s %s pulled forward slightly.", buf, is(target)); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - return B_FALSE; - } - } else { - fizzle(caster); - } } else if (spellid == OT_S_PULLMETAL) { int donesomething = B_FALSE; if (!validatespellcell(caster, &targcell,TT_OBJECT, spellid, power, frompot)) return B_TRUE; @@ -4811,7 +5005,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_KNOCK) { object_t *o; - if (!validatespellcell(caster, &targcell,TT_DOOR, spellid, power, frompot)) return B_TRUE; + if (!validatespellcell(caster, &targcell,TT_DOOR|TT_IMPASSABLE, spellid, power, frompot)) return B_TRUE; target = targcell->lf; @@ -5136,18 +5330,36 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_GRAVBOOST) { // ask for target if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; + target = targcell->lf; if (target) { int howlong = 15; + flag_t *f; + int i; + + if (isplayer(target) || cansee(player, target)) { + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + + f = hasactivespell(target, OT_S_GRAVLOWER); + if (f) { + stopspell(target, OT_S_GRAVLOWER); + return B_FALSE; + } + + i = 0; + i += killtransitoryflags(target->flags, F_GRAVLESSENED); + i += killtransitoryflagvals(target->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL); + if (i) { + return B_FALSE; + } if (lfhasflag(target, F_GRAVBOOSTED) || skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { if (isplayer(target)) { msg("You feel momentarily heavier."); - if (seenbyplayer) *seenbyplayer = B_TRUE; } else if (cansee(player, target)) { char targname[BUFLEN]; getlfname(target, targname); msg("%s looks momentarily heavier.", targname); - if (seenbyplayer) *seenbyplayer = B_TRUE; } return B_FALSE; } @@ -5163,8 +5375,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ targcell = caster->cell; target = caster; + f = lfhasflag(target, F_GRAVBOOSTED); + if (f) { + killflag(f); + if (isplayer(target) || cansee(player, target)) { + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + return B_FALSE; + } + f = addtempflag(caster->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL, FROMSPELL); f->obfrom = spellid; + f = addtempflag(caster->flags, F_GRAVLESSENED, B_TRUE, NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; } else if (spellid == OT_S_GUSTOFWIND) { obpile_t *op; object_t *o, *nexto; @@ -5263,15 +5486,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ flag_t *f; char fullobname[BUFLEN]; char obname[BUFLEN]; - getobname(o, obname, o->amt); - - if (isplayer(caster)) { - sprintf(fullobname, "Your %s", noprefix(obname)); - } else if (cansee(player, caster)) { - sprintf(fullobname, "%s%s %s", castername, getpossessive(castername), noprefix(obname)); - } else { - strcpy(fullobname, ""); - } if (targob) { o = targob; @@ -5284,6 +5498,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_TRUE; } + getobname(o, obname, o->amt); + + if (isplayer(caster)) { + sprintf(fullobname, "Your %s", noprefix(obname)); + } else if (cansee(player, caster)) { + sprintf(fullobname, "%s%s %s", castername, getpossessive(castername), noprefix(obname)); + } else { + strcpy(fullobname, ""); + } + f = hasflag(o->flags, F_OBHP); if (f && isdamaged(o)) { if (blessed == B_CURSED) { @@ -6001,6 +6225,37 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { fizzle(caster); } + } else if (spellid == OT_S_SUCK) { + if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; + + target = targcell->lf; + + if (target) { + int failed = B_FALSE; + + if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) { + failed = B_TRUE; + } else { + // they get pulled towards caster + failed = pullnextto(target, caster->cell); + } + + if (isplayer(target) || cansee(player, target)) { + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + + if (failed) { + if (isplayer(target) || cansee(player, target)) { + char buf[BUFLEN]; + getlfname(target, buf); + msg("%s %s pulled forward slightly.", buf, is(target)); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + return B_FALSE; + } + } else { + fizzle(caster); + } } else if (spellid == OT_S_TELEPORT) { cell_t *c = NULL; lifeform_t *ally[8]; @@ -6860,6 +7115,8 @@ enum SKILL getschoolskill(enum SPELLSCHOOL ss) { return SK_SS_DEATH; case SS_DIVINATION: return SK_SS_DIVINATION; + case SS_ENCHANTMENT: + return SK_SS_ENCHANTMENT; case SS_NATURE: return SK_SS_NATURE; case SS_FIRE: @@ -7013,6 +7270,118 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) { return buf; } +int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { + int power = 0; + int spelllev; + enum SKILLLEVEL spellcastskill,schoolskill; + enum SPELLSCHOOL school; + int db = B_FALSE; + int usesorcery = B_FALSE; + flag_t *f; + + if (db) { + objecttype_t *ot; + ot = findot(spellid); + if (db) dblog("getspellpower for lf %s, spell %s", lf->race->name, ot->name); + } + + //////////////////////////////////// + // CAN WE CAST THIS AT ALL + //////////////////////////////////// + // If we can _will_ this to occur then we might have a set + // spellpower + f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL); + if (f && strlen(f->text)) { + texttospellopts(f->text, &power, NULL, NULL, NULL); + if (power > 0) { + if (db) { + dblog("-->power = %d (from canwill)", power); + } + return power; + } + } + + // get spell details + school = getspellschoolknown(lf, spellid); + schoolskill = getskill(lf, getschoolskill(school)); + spellcastskill = getskill(lf, SK_SPELLCASTING); + spelllev = getspelllevel(spellid); + + // for most spell schools, your skill in the school determines which + // spells you can cast. + // + // this check doesn't apply for monsters. + if (isplayer(lf)) { + if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) { + // always okay + } else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) { + // dont need spellcasting skill for mental/allomancy + } else { + int maxspelllevel; + usesorcery = B_TRUE; + switch (schoolskill) { + case PR_INEPT: maxspelllevel = 0; break; + case PR_NOVICE: maxspelllevel = 1; break; + case PR_BEGINNER: maxspelllevel = 2; break; + case PR_ADEPT: maxspelllevel = 4; break; + case PR_SKILLED: maxspelllevel = 6; break; + case PR_EXPERT: maxspelllevel = 8; break; + case PR_MASTER: maxspelllevel = 9; break; + } + + // player can only ever cast spells up to your level. + if (!hasjob(lf, J_GOD)) { + limit(&maxspelllevel, NA, lf->level); + } + + if (spelllev > maxspelllevel) { + if (db) dblog("-->power = 0 (no skilled enough in spell school)"); + return 0; + } + } + } + + + //////////////////////////////////// + // HOW POWERFUL IS THIS SPELL? + //////////////////////////////////// + if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) { + // always okay + usesorcery = B_FALSE; + } else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) { + // dont need spellcasting skill for mental/allomancy + usesorcery = B_FALSE; + } else { + usesorcery = B_TRUE; + } + + power = 1; // base power of 1. + // plus either your hitdice/3 OR your sorcery skill + if (usesorcery) { + power += spellcastskill; + } else { + power += (gethitdice(lf)/3); + } + + // plus intelligence modifier + if (school == SS_MENTAL) { + // +/- 2 for iq + power += (getstatmod(lf, A_IQ) / 25); + } else if (school == SS_NATURE) { + // +/- 1 for wisdom + power += (getstatmod(lf, A_WIS) / 50); + // TODO: clerical +/- 2 for wisdom + } else { + // +/- 1 for iq + power += (getstatmod(lf, A_IQ) / 50); + } + + limit(&power, 0, getspellmaxpower(spellid)); + return power; +} + +/* +ooooooo old oooooooo int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { int power = 0; int statmod; @@ -7134,6 +7503,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { if (db) dblog("==> final power: %d", power); return power; } +*/ enum SPELLSCHOOL getspellschool(enum OBTYPE spellid) { flag_t *f; @@ -7152,10 +7522,15 @@ enum SPELLSCHOOL getspellschool(enum OBTYPE spellid) { return SS_NONE; } +// return the school which the given spell belongs to, HOWEVER if it +// belongs to multiple ones, prefer ones which the given lifeform +// is skilled in. enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) { flag_t *f; enum SPELLSCHOOL thisschool; objecttype_t *ot; + enum SPELLSCHOOL poss[MAXCANDIDATES]; + int nposs = 0; ot = findot(spellid); if (!ot) { @@ -7166,24 +7541,46 @@ enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid) { return SS_ABILITY; } - - // find a school which we know about! + // make a list of all schools which this spell belongs to, and which we know. thisschool = SS_NONE; for (f = ot->flags->first ; f ; f = f->next) { if ((f->id == F_SPELLSCHOOL) && getskill(lf, getschoolskill(f->val[0]))) { - thisschool = f->val[0]; - break; + poss[nposs++] = f->val[0]; } } - // if we don't know any of the schools... - if (thisschool == SS_NONE) { + if (nposs) { + int i; + enum SPELLSCHOOL poss2[MAXCANDIDATES]; + int nposs2 = 0; + enum SKILLLEVEL highestskill = PR_INEPT; + // find the school which we are most skilled in + for (i = 0; i < nposs; i++) { + enum SKILLLEVEL thisslev; + thisslev = getskill(lf, getschoolskill(poss[i])); + if (thisslev > highestskill) { + highestskill = thisslev; + } + } + + // now only select from these ones... + for (i = 0; i < nposs; i++) { + enum SKILLLEVEL thisslev; + thisslev = getskill(lf, getschoolskill(poss[i])); + if (thisslev == highestskill) { + poss2[nposs2++] = poss[i]; + } + } + + // pick one randomly + thisschool = poss2[rnd(0,nposs2-1)]; + } else { + // if we don't know any of the schools... // just pick the first one. f = hasflag(ot->flags, F_SPELLSCHOOL); assert(f); thisschool = f->val[0]; } - return thisschool; } @@ -7599,7 +7996,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e if (!frompot && where && where->lf && haslos(caster, where) && isplayer(caster) && areallies(caster, where->lf)) { // warn before targetting yourself! - if (getiqname(getattr(caster, A_IQ), NULL) >= IQ_AVERAGE) { + if (getattrbracket(getattr(caster, A_IQ), A_IQ, NULL) >= AT_AVERAGE) { objecttype_t *sp; sp = findot(spellid); if (sp) { diff --git a/text.c b/text.c index 70a24ff..7741f06 100644 --- a/text.c +++ b/text.c @@ -19,8 +19,16 @@ int needan(char *text) { } char *capitalise(char *text) { - if (strlen(text) > 0) { - text[0] = toupper(text[0]); + if (strlen(text)) { + char *p; + p = text; + while (*p == '^') { + p++; // go past the ^ + if (!(*p)) return text; // do nothing + p++; // go past the colour char + if (!(*p)) return text; // do nothing + } + *p = toupper(*p); } return text; } @@ -40,6 +48,27 @@ char *capitaliseall(char *text) { return text; } +enum COLOUR chartocol(char ch) { + switch (ch) { + case 'w': // warning + return C_YELLOW; + case 'W': // extra warning + return C_BOLDMAGENTA; + case 'b': // bad + return C_BROWN; + case 'B': // v.bad + return C_RED; + case 'g': // good + return C_GREEN; + case 'G': // v.good + return C_CYAN; + case 'n': // normal + default: + break; + } + return C_GREY; +} + char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf) { int localmin, localmax; @@ -122,13 +151,15 @@ char *getattrabbrev(enum ATTRIB att) { case A_CHA: return "Ch"; case A_CON: - return "Fi"; + return "Ft"; case A_DEX: return "Dx"; case A_IQ: return "Iq"; case A_STR: return "St"; + case A_WIS: + return "Wi"; } return "??"; } @@ -147,6 +178,8 @@ char *getattrname(enum ATTRIB att) { return "intelligence"; case A_STR: return "strength"; + case A_WIS: + return "wisdom"; } return "?badattrib?"; } @@ -186,7 +219,7 @@ int gethitconferlifetime(char *text, int *min, int *max) { char *getpossessive(char *text) { char lastchar; // you -> your - if (!strcmp(text, "you")) { + if (!strcasecmp(text, "you")) { return "r"; } @@ -235,14 +268,15 @@ char *getsizetext(enum LFSIZE sz) { case SZ_LARGE: return "large"; case SZ_HUMAN: - return "human-sized"; + return "human"; case SZ_MEDIUM: return "medium"; case SZ_SMALL: return "small"; - case SZ_MINI: case SZ_TINY: - return "extremely small"; + return "tiny"; + case SZ_MINI: + return "miniscule"; default: return "unknown-sized"; } @@ -550,7 +584,7 @@ char *roman(int num) { } int speedtokph(int speed) { - return speed * speed * speed; + return speed * speed; } void splittime(int *hours, int *mins, int *secs) { diff --git a/text.h b/text.h index a25edfa..db71a2d 100644 --- a/text.h +++ b/text.h @@ -3,6 +3,7 @@ int needan(char *text); char *capitalise(char *text); char *capitaliseall(char *text); +enum COLOUR chartocol(char ch); char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf); int flip(int ch); char *getattrabbrev(enum ATTRIB att); diff --git a/vaults/jimbo.vlt b/vaults/jimbo.vlt index c239785..ecd9dd2 100644 --- a/vaults/jimbo.vlt +++ b/vaults/jimbo.vlt @@ -19,7 +19,7 @@ /:ob:wooden table -:ob:wooden footstool c:ob:lit candelabrum -@:mon:Jimbo +@:mon:jailer @end @flags