- [+] prevent 'A' (forceattack) behind you

- [+] replace:
    - [+] Something critically savages your body.  
          Your uncursed suit of ring mail protects you.
          Your suit of ring mail is damaged!
    - [+] with:
        - [+] Something critically savages your suit of ring mail.
        - [+] Your suit of ring mail is damaged!
- [+] tremorsense shouldn't see flying creatures
- [+] rename blink to "bamf"
- [+] add F_containsmeat for non-vegetarian foods
    - [+] use this in vegetarian checks instead of mt_Flesh
- [+] "what goes up" spell
- [+] "equal and opposite" spell
- [+] why didn't cyborg ninja start with weapon weilded?
    - [+] getbestwepon - accuracy was counting for too much. have
          changed calculation.
- [+] why is wizard's staff not enchanted???
- [+] elephant race - Pachyon or Mammoan
    - [+] bonus
        - [+] Leather skin
        - [+] str++
        - [+] photo mem
        - [+] high listen skill
        - [+] good smell
    - [+] penalty
        - [+] slow movement
        - [+] no armour on ears
        - [+] agi-
        - [+] low eyesight
        - [+] vuln to sonic
        - [+] vegetarian
    - [+] other
        - [+] large
- [+] throw salt to blind targets
- [+] if you learn a new spell school skill while game is in progress,
      gain a 1st level spell too.
- [+] for random roast meat, always use base race 
    - [+] ie. orc, not "elite orc"
    - [+]  (ie. human, not 'town guard')
- [+] remove "prepare food" skill.
    - [+] use "cook" instead
- [+] startskill should be a modifier, not absolute.
    - [+] ie. elf can have sk_ranged, so can hunter.  these will now
          stack.
- [+] chance for ai to use a firearm is lowered based on firearm
      accuracy
- [+] bug: massively high amount of skillxp needed for a point
- [+] firearms should do more damage at pointblank range.
- [+] icicle bugs - getrandomadjcell for knockback failing
- [+] still a bug with firearm accuracy updating
    - [+] 2 squares away, move towards enemy - it doesn't update!
- [+] display all valid hits in brown
- [+] wear melted wax in ears to reduce sonic damage
- [+] ranged skillls
    - [+] adp
        - [+] fast reloading
    - [+] exp
        - [+] fire through lifeforms!  lof_wallstop instead of lof_need
    - [+] mas
        - [+] extra dam.
- [+] object HP issue:
    - [+]          head: b - an uncursed helmet [AR:3] [110%]
    - [+]          body: c - an uncursed suit of ring mail [AR:6] [173%]
    - [+]        hands: d - an uncursed battered pair of gauntlets
          [AR:2] [86%]
    - [+] are objects taking negative damage??
    - [+] have put an assertion in to check
    - [+] wait for it to happen again...
- [+] add hitchance to askcoords when throwing/shooting
    - [+] code it
    - [+] test for throw
    - [+] add for telekeniis too
    - [+] add for guns:
        - [+] "targetted:  something [x%]"
        - [+] "bow->Target->xxx [x%]"
    - [+] show gun target on botl
- [+] redo throw accuracy:
    - [+] 100 to hit yourself
    - [+] apply per-cell penalty based on:
        - [+] throwing / ranged skill (more)
        - [+] AGI (lesser)
- [+] wetsuit description not showing dtresist cold!!
- [+] hunter job
- [+] wetsuit (covers multiple body parts), prot from cold
- [+] announce bleeding damage from injuries
- [+] only mark _weapons_ as 'tried' when weilding them
- [+] change random items:
    - [+] fix wantrr bug
    - [+] test...
    - [+] new function: enum RARITY  pickrarity()
    - [+] check for all wantrr = xxx and use pickrarity instead.
    - [+] give classes a RR_RARITY
        - [+] common
            - [+] weapon / armour / money / missile
            - [+] furniture
            - [+] misc
            - [+] rock
        - [+] uncommon
            - [+] potion / scroll / food
        - [+] rare
            - [+] trap
            - [+] tech/tool
            - [+] dfeature (pentagram, vending machine, etc)
        - [+] vrare
            - [+] wand
            - [+] ring
            - [+] book
    * [+] rewrite wrappers
    * [+] marge getrandomobofclass and getrandomob
- [+] bug: telling allies to attack something they can't see. need a
      msg for this.
    - [+] Norman->Attack->A young hawk [flying, facing NE]
    - [+] Cancelled.
- [+] bug: allies not regaining hp when asleep! fixed.
- [+]  you can now always 'see' your allies if you have LOH
    - [+] ie. scannedcell
    - [+] ie. cansee
- [+] player luck should cause better random item creation, and easier
      monsters
    - [+] pickrr() needs arg to say what it is for (vault , ob, lf)
- [+] meals have special effects. eg:
    - [+] easy:
        - [+] mushroom + water = mushroom soup = restore a little
              stamina
        - [+] tomato + water = tomato soup = restore a little stamina
        - [+] apple + stone = fruit juice (don't kill the stone) 
        - [+] cheese + bread = cheese sandwich = restore all food and
              stamina
        - [+] rum + chocolate  = rum ball = cure pain, restore some hp
    - [+] med:
        - [+] corpse + water + salt = jerky
        - [+] mushroom + water + beef = beef strogonoff = filling,
              temporary Fitness boost
        - [+] garlic + bread + clover = garlic bread = produce stench
              like a trogolodyte
        - [+] bread + meat + tomato = hot dog = temporary strength
        - [+] water + sugar + 2 berries = potion of red cordial = speed
              boost
    - [+] hard
        - [+] peanut + stone + salt + bread = peanut butter sandwich =
              super filling, restore all stamina, temp fitness boost
        - [+] rum + chocolate + sugar + berry = fruit cake = restores
              all stamina and hp and mp
- [+] implement recipe_t
    - [+] int ningerdients
    - [+] enum OBTYPE ingredient[MAXINGREDS]
    - [+] int count[MAXINGREDS]
    - [+] int cosumeingredient[MAXINGREDS] (boolean)
- [+] makedesc_ob should show the recipe for it, if cooking skill is
      high enough
- [+] cooking skill determines how many ingredients you can use
    - [+] ie. beginner = you can make recipes which need 2 ingredients
- [+] redo "cook" ability.
- [+] can combine ingredients using recipes to make meals
- [+] ingredients must be known!
- [+] chef job
    - [+] attr
        - [+] gtaverage agility
        - [+] low fitnesss
    - [+] objects:
        - [+] meat cleaver (slashing, low acc, high crit)
        - [+] apron (rubber, low protection)
        - [+] chef hat (cloth, low protection)
        - [+] butane torch (flambe on adjacent lifeform)
    - [+] abilities
        - [+] rage at lv3
    * [+] skills
- [+] chef job
    - [+] attr
        - [+] gtaverage agility
        - [+] low fitnesss
    - [+] objects:
        - [+] meat cleaver (slashing, low acc, high crit)
        - [+] apron (rubber, low protection)
        - [+] chef hat (cloth, low protection)
        - [+] butane torch (flambe on adjacent lifeform)
    - [+] abilities
        - [+] rage at lv3
    * [+] skills
This commit is contained in:
Rob Pearce 2011-11-14 18:21:40 +00:00
parent 497b4e0ead
commit dd03042c70
22 changed files with 994 additions and 333 deletions

View File

@ -3,3 +3,6 @@ nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h
check: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h vault.c vault.h check: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h data.c data.h flag.c flag.h god.c god.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h vault.c vault.h
splint -onlytrans -nullret -nullstate -branchstate -usedef -type -retvalint -retvalother +posixlib -unrecog -boolops -mustfreefresh -predboolint -unqualifiedtrans -compdef *.c splint -onlytrans -nullret -nullstate -branchstate -usedef -type -retvalint -retvalother +posixlib -unrecog -boolops -mustfreefresh -predboolint -unqualifiedtrans -compdef *.c
dist:
tar zcvf nexus_`date '+%Y%m%d'`.tar.gz --exclude='.svn' *.c *.h data doc vaults Makefile

57
ai.c
View File

@ -283,7 +283,7 @@ cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *l
return NULL; return NULL;
} }
object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra, int *range) { object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range) {
int db = B_FALSE; int db = B_FALSE;
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
object_t *o; object_t *o;
@ -329,11 +329,17 @@ object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra, int *range) {
// can we attack by throwing something? // can we attack by throwing something?
if (hasbp(lf, BP_HANDS)) { if (hasbp(lf, BP_HANDS)) {
o = getbestthrowmissile(lf); o = getbestthrowmissile(lf, target);
if (o) { if (o) {
if (db) dblog(".oO { will throw %s at my target }", o->type->name); if (db) dblog(".oO { will throw %s at my target }", o->type->name);
if (ra) *ra = RA_THROW; if (ra) *ra = RA_THROW;
if (range) *range = getmaxthrowrange(lf, o); if (range) {
if (hasflag(o->flags, F_POWDER)) {
*range = 1;
} else {
*range = getmaxthrowrange(lf, o);
}
}
return o; return o;
} }
} }
@ -544,6 +550,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
enum RANGEATTACK rangedattack = RA_NONE; enum RANGEATTACK rangedattack = RA_NONE;
int shootrange = 0; int shootrange = 0;
int movefailed = B_FALSE; int movefailed = B_FALSE;
int closethrowok = B_FALSE;
// pet movement // pet movement
if (ismaster) { if (ismaster) {
@ -699,13 +706,41 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
// see if we have a ranged attack. if so, adjust wantdist // see if we have a ranged attack. if so, adjust wantdist
// to maintain distance. // to maintain distance.
rangedob = aigetrangedattack(lf, &rangedattack, &shootrange); rangedob = aigetrangedattack(lf, target, &rangedattack, &shootrange);
// for firearms, chance to fire depends on accuracy.
if (rangedattack == RA_GUN) {
int acc,chance;
acc = getmissileaccuracy(lf, target->cell, getammo(rangedob), rangedob, NULL);
switch (getpctletter(acc,100)) {
case 'S':
case 'A':
chance = 100; break;
case 'B':
chance = 75; break;
case 'C':
chance = 50; break;
default:
chance = 25; break;
}
if (!pctchance(chance)) {
rangedattack = RA_NONE;
rangedob = NULL;
}
}
if (rangedattack != RA_NONE) { // ie if we found a ranged attack if (rangedattack != RA_NONE) { // ie if we found a ranged attack
// stay out of target's attack range if ((rangedattack == RA_THROW) && rangedob && hasflag(rangedob->flags, F_POWDER)) {
if (wantdistmin < 2) wantdistmin = 2; // don't have to maintain distance to throw powder
// and stay within range for our ranged attack closethrowok = B_TRUE;
if (wantdistmax < wantdistmin) wantdistmax = shootrange; if (wantdistmin < 1) wantdistmin = 1;
if (wantdistmax < wantdistmin) wantdistmax = shootrange;
} else {
// stay out of target's attack range
if (wantdistmin < 2) wantdistmin = 2;
// and stay within range for our ranged attack
if (wantdistmax < wantdistmin) wantdistmax = shootrange;
}
} }
} // end if attackok } // end if attackok
@ -745,9 +780,9 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
// move. // move.
if (attackok) { if (attackok) {
// if not adjacent, check for guns, wands, throwing // if not adjacent, check for guns, wands, throwing
if ( (rangedattack != RA_NONE) && if ( (rangedattack != RA_NONE) && // we have a ranged attack
haslof(lf->cell, target->cell, LOF_NEED, NULL) && // and we have line of fire to them haslof(lf->cell, target->cell, LOF_NEED, NULL) && // and we have line of fire to them
(onein(2) || (getcelldist(lf->cell, target->cell) > 1) )) { // and we're not adjacent to target OR random (closethrowok || onein(2) || (getcelldist(lf->cell, target->cell) > 1) )) { // and we're not adjacent to target OR random
if (rangedattack == RA_GUN) { if (rangedattack == RA_GUN) {
setguntarget(lf, target); setguntarget(lf, target);
if (!shoot(lf)) { if (!shoot(lf)) {
@ -1473,7 +1508,7 @@ void aiturn(lifeform_t *lf) {
} }
// will usually ignore targets who we can't reach // will usually ignore targets who we can't reach
if (!canreach(lf, who, &reachpenalty)) { if (!canreach(lf, who, &reachpenalty)) {
if (!aigetrangedattack(lf, NULL, NULL)) { // no ranged attack? if (!aigetrangedattack(lf, who, NULL, NULL)) { // no ranged attack?
// 1 size too small = 53% chance to attack // 1 size too small = 53% chance to attack
// 1 size too small = 6% chance to attack // 1 size too small = 6% chance to attack
chance = 100 - (reachpenalty*47); chance = 100 - (reachpenalty*47);

2
ai.h
View File

@ -5,7 +5,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit);
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim); enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim);
enum OBTYPE aigetfleespell(lifeform_t *lf); enum OBTYPE aigetfleespell(lifeform_t *lf);
cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir); cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir);
object_t *aigetrangedattack(lifeform_t *lf, enum RANGEATTACK *ra, int *range); object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range);
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose); 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); 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 *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);

View File

@ -633,13 +633,23 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
hit = rolltohit(lf, victim, wep, &critical); hit = rolltohit(lf, victim, wep, &critical);
if (critical) { if (critical) {
object_t *armour;
char noun[BUFLEN];
critpos = getrandomcorebp(victim); critpos = getrandomcorebp(victim);
armour = getequippedob(victim->pack, critpos);
if (armour) {
char armname[BUFLEN];
real_getobname(armour, armname, 1, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
sprintf(noun, "%s", noprefix(armname));
} else {
sprintf(noun, "%s", getbodypartname(victim, critpos));
}
// replace victicname to include body part // replace victicname to include body part
if ((lf == victim) && !isplayer(lf)) { if ((lf == victim) && !isplayer(lf)) {
snprintf(victimbpname, BUFLEN, "its %s", getbodypartname(victim, critpos)); snprintf(victimbpname, BUFLEN, "its %s", noun);
} else { } else {
getlfname(victim, buf); getlfname(victim, buf);
snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), getbodypartname(victim, critpos)); snprintf(victimbpname, BUFLEN, "%s%s %s", buf, getpossessive(buf), noun);
} }
} else { } else {
strcpy(victimbpname, ""); strcpy(victimbpname, "");
@ -1396,7 +1406,7 @@ enum DAMTYPE basedamagetype(enum DAMTYPE dt) {
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) { void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) {
object_t *o,*armour; object_t *o,*armour;
int protected = B_FALSE; int protected = B_FALSE;
char lfname[BUFLEN],victimname[BUFLEN],obname[BUFLEN]; char lfname[BUFLEN],victimname[BUFLEN];
// replace some dam types // replace some dam types
if (damtype == DT_UNARMED) damtype = DT_BASH; if (damtype == DT_UNARMED) damtype = DT_BASH;
if (damtype == DT_BITE) damtype = DT_SLASH; if (damtype == DT_BITE) damtype = DT_SLASH;
@ -1455,12 +1465,14 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
} }
moveob(o, victim->cell->obpile, o->amt); moveob(o, victim->cell->obpile, o->amt);
} else { } else {
/*
if (isplayer(victim)) { if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname)); msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, victim)) { } else if (cansee(player, victim)) {
getlfname(victim, victimname); getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname)); msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
} }
*/
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} }
} else { } else {
@ -1485,6 +1497,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
case BP_LEGS: case BP_LEGS:
if (pctchance(70)) fall(victim, lf, B_TRUE); if (pctchance(70)) fall(victim, lf, B_TRUE);
if ((armour = getarmour(victim, BP_LEGS)) != NULL) { if ((armour = getarmour(victim, BP_LEGS)) != NULL) {
/*
getobname(armour, obname, armour->amt); getobname(armour, obname, armour->amt);
if (isplayer(victim)) { if (isplayer(victim)) {
msg("Your %s protects you.", noprefix(obname)); msg("Your %s protects you.", noprefix(obname));
@ -1492,6 +1505,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
getlfname(victim, victimname); getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname)); msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
} }
*/
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} else { } else {
injure(victim, BP_LEGS, damtype); injure(victim, BP_LEGS, damtype);
@ -1688,6 +1702,7 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam) {
lifeform_t *owner; lifeform_t *owner;
owner = wep->pile->owner; owner = wep->pile->owner;
// enchanted weapons only deal magic damage if the user has remaining mp.
if (owner && owner->mp) { if (owner && owner->mp) {
f = hasflag(wep->flags, F_ENCHANTED); f = hasflag(wep->flags, F_ENCHANTED);
if (f) { if (f) {

211
data.c
View File

@ -64,15 +64,15 @@ void initcommands(void) {
addcommand(CMD_REST, '.', "Rest once."); addcommand(CMD_REST, '.', "Rest once.");
addcommand(CMD_PICKUP, ',', "Pick up something from the ground."); addcommand(CMD_PICKUP, ',', "Pick up something from the ground.");
addcommand(CMD_CLOSE, 'c', "Close a door."); addcommand(CMD_CLOSE, 'c', "Close a door.");
addcommand(CMD_COMMS, 'C', "Communicate with an ally."); addcommand(CMD_COMMS, 'C', "Chat/Communicate with someone.");
//addcommand(CMD_DROP, 'd', "Drop an item."); //addcommand(CMD_DROP, 'd', "Drop an item.");
addcommand(CMD_DROPMULTI, 'd', "Drop one or more items."); addcommand(CMD_DROPMULTI, 'd', "Drop one or more items.");
addcommand(CMD_EAT, 'e', "Eat something."); addcommand(CMD_EAT, 'e', "Eat something.");
addcommand(CMD_EAT, 'E', "Enhance your skills."); addcommand(CMD_EAT, 'E', "Enhance your skills.");
addcommand(CMD_MAGIC, 'm', "Use magic or abilities."); addcommand(CMD_MAGIC, 'm', "Use magic or abilities.");
addcommand(CMD_MEMMAGIC, 'M', "Memorise a magic shortcut"); addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities.");
addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods."); addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods.");
addcommand(CMD_OPERATE, 'o', "Operate a tool/wand/device."); addcommand(CMD_OPERATE, 'o', "Operate a tool/wand/device, or fill a flask.");
addcommand(CMD_PICKLOCK, 'p', "Pick a lock."); addcommand(CMD_PICKLOCK, 'p', "Pick a lock.");
addcommand(CMD_POUR, 'P', "Pour a potion onto something."); addcommand(CMD_POUR, 'P', "Pour a potion onto something.");
addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion."); addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion.");
@ -139,12 +139,14 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 blessed potions of experience"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 blessed potions of experience");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of miracles"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of miracles");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of control"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of control");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "infovisor");
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DEATH, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_DEATH, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_TRANSLOCATION, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_TRANSLOCATION, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_DIVINATION, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_SUMMONING, PR_MASTER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_ADEPT, NA, NULL);
//addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf"); //addflag(lastjob->flags, F_HASPET, NA, NA, NA, "young wolf");
for (i = 1; i < MAXSKILLS; i++) { for (i = 1; i < MAXSKILLS; i++) {
addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, i, NA, NA, NULL);
@ -407,6 +409,54 @@ void initjobs(void) {
// 20: tower of iron will // 20: tower of iron will
// 21: planeshift // 21: planeshift
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
addjob(J_HUNTER, "Hunter", "Hunters eke out a living hunting game in the woods. Their dependance on wild animals for sustenance has made them skilled archers.");
// stats
addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 1, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_CON, 1, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, 2, NA, NULL);
// initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "hatchet");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "bow");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "50 arrows");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "throwing net");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of leather boots");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of leather gloves");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "sleeping bag");
// initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LISTEN, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_SKILLED, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_RANGED, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL);
// learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_CLUBS, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_EVASION, 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_TECHUSAGE, PR_ADEPT, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_TRAPS, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LORE_HUMANOID, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_LORE_DRAGONS, NA, NA, NULL);
// abilities
addflag(lastjob->flags, F_CANWILL, OT_S_CALMANIMALS, 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_MECHANIC, "Mechanic", "Mechanics, while great at negotiating high hourly rates, are not generally very suited for adventuring. Their spanner and metal-working skills might come in handy though."); addjob(J_MECHANIC, "Mechanic", "Mechanics, while great at negotiating high hourly rates, are not generally very suited for adventuring. Their spanner and metal-working skills might come in handy though.");
// stats // stats
addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL);
@ -682,7 +732,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, 4, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, 4, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_CON, -3, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_CON, -3, NA, NULL);
// initial objects // initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "neophyte staff"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "enchanted neophyte staff");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "wizard hat"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "wizard hat");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); 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_STARTOB, 100, NA, NA, "2 potions of magic");
@ -704,6 +754,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_STAVES, PR_ADEPT, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_STAVES, PR_ADEPT, NA, NULL); // limit
addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_SS_AIR, 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_DEATH, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL);
@ -1755,9 +1806,11 @@ void initobjects(void) {
addot(OT_HOTDOG, "hot dog", "A chunk of meat sandwiched between two pieces of bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_HOTDOG, "hot dog", "A chunk of meat sandwiched between two pieces of bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 80, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 80, NA, "");
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_JERKY, "jerky", "Salted animal flesh. Lightweight and filling.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_JERKY, "jerky", "Salted animal flesh. Lightweight and filling.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 90, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 90, NA, "");
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_MUSHROOMSHI, "shiitake mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); addot(OT_MUSHROOMSHI, "shiitake mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 30, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 30, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
@ -1781,13 +1834,17 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_RUMBALL, "rum ball", "A rum-filled ball of chocolate. Cures pain and restores 2-6 hit points.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type addot(OT_RUMBALL, "rum ball", "A rum-filled ball of chocolate. Cures pain and restores 2-6 hit points.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addot(OT_SALT, "pinch of salt", "A small measure of salt. Used for cooking.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_SALT, "pinch of salt", "A small measure of salt. Used for cooking.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, NULL);
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, "");
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addot(OT_SANDWICHCHEESE, "cheese sandwich", "A tasty cheese sandwich. Filling, and restores all stamina.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_SANDWICHCHEESE, "cheese sandwich", "A tasty cheese sandwich. Filling, and restores all stamina.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "%"); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "%");
@ -1807,13 +1864,17 @@ void initobjects(void) {
// corpses // corpses
addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY); addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_SMALL); addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_SMALL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD, SZ_SMALL); 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_GLYPH, C_BROWN, NA, NA, "%");
addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL);
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY); addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
// potions (sorted by rarity) // potions (sorted by rarity)
@ -1902,7 +1963,7 @@ void initobjects(void) {
addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's strength, intelligence or dexterity.", MT_GLASS, 1, OC_POTION, SZ_TINY); 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); 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, SZ_TINY); addot(OT_POT_GASEOUSFORM, "potion of gaseous form", "Turns the drinker into a cloud of gas. Only intended for emergencies, since it will cause you to drop all your items.", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
@ -2471,7 +2532,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 2, 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_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_NORANDOM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NORANDOM, B_TRUE, NA, NA, NULL);
addot(OT_S_ICECRUST, "ice crust", "Enrusts your bladed weapon with a layer of ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_ICECRUST, "ice crust", "Encrusts your weapon with a layer of sharp ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the enchantment will remain."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the enchantment will remain.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
@ -2513,7 +2574,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the icicle will remain."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the icicle will remain.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, 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_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, 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); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
@ -2782,8 +2843,12 @@ void initobjects(void) {
// l2 // l2
addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); 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_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addot(OT_S_WHATGOESUP, "what goes up", "...must come down. Thrown or fired missiles will return to the caster's hands if not destroyed.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, 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); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
// l3 // l3
addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
@ -2813,6 +2878,11 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, 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_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addot(OT_S_EQANDOP, "equal and opposite", "Surrounds the caster with a negative gravity field, repelling all missiles in a direct path back to their source.", 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_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
// l5 // l5
// l6 // l6
addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
@ -3123,7 +3193,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l2 // l2
addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_BLINK, "bamf", "Teleports the caster to a random location within view.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VI you can choose where to blink to."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VI you can choose where to blink to.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -3288,7 +3358,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_ANYWHERE, NA, NA, NULL);
addot(OT_A_COOK, "cook", "Combine various foods into a healthy meal.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_COOK, "cook", "Cook a corpse, or combine various foods into a healthy meal.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_DARKWALK, "darkwalk", "Step between the shadows.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); 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); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
@ -3338,8 +3408,6 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL);
addot(OT_A_PREPARECORPSE, "prepare corpse", "Prepare and cook a corpse, making it more nutritious.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
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); 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_STAMCOST, 10, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 10, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
@ -3746,7 +3814,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_PIERCE, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 50, NA, NA, NULL); 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, SZ_MEDIUM); addot(OT_SLEEPINGBAG, "sleeping bag", "An insulated bag for sleeping in. Very comfortable.", MT_CLOTH, 2, OC_TECH, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
addflag(lastot->flags, F_HELPSREST, 15, NA, NA, NULL); addflag(lastot->flags, F_HELPSREST, 15, NA, NA, NULL);
@ -4010,6 +4078,10 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, 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_GLYPH, NA, NA, NA, ",");
addflag(lastot->flags, F_NOMATCONVERT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOMATCONVERT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_EARS, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_SONIC, NA, NULL);
addot(OT_SOGGYPAPER, "lump of soggy paper", "A useless lump of soggy paper.", MT_WETPAPER, 0.1, OC_MISC, SZ_TINY); 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_STACKABLE, NA, NA, NA, NULL);
@ -5228,7 +5300,7 @@ void initobjects(void) {
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 25, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 25, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addot(OT_NET, "throwing net", "A grid of strong cords, weighted at the edges. Made for throwing over a target.", MT_CLOTH, 3, OC_MISSILE, SZ_MEDIUM); addot(OT_NET, "throwing net", "A grid of strong cords, weighted at the edges. Made for throwing over a target.", MT_CLOTH, 2, OC_MISSILE, SZ_MEDIUM);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, NULL); addflag(lastot->flags, F_MISSILEDAM, 0, NA, NA, NULL);
@ -5248,7 +5320,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 3, 3, NA, ""); addflag(lastot->flags, F_OBHP, 3, 3, NA, "");
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.25, OC_MISSILE, SZ_SMALL); addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.1, OC_MISSILE, SZ_SMALL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
@ -5259,7 +5331,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 15, NA, NULL);
addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 0.5, OC_MISSILE, SZ_SMALL); addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 0.25, OC_MISSILE, SZ_SMALL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
@ -5639,6 +5711,7 @@ void initobjects(void) {
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addot(OT_WIZARDSTAFF, "neophyte staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF, "neophyte staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5649,6 +5722,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch");
addot(OT_WIZARDSTAFF2, "enchanter staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF2, "enchanter staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5660,6 +5734,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch");
addot(OT_WIZARDSTAFF3, "sorcerer staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF3, "sorcerer staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5671,6 +5746,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch");
addot(OT_WIZARDSTAFF4, "spellbinder staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF4, "spellbinder staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5682,6 +5758,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch");
addot(OT_WIZARDSTAFF5, "warlock staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF5, "warlock staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5693,6 +5770,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch");
addot(OT_WIZARDSTAFF6, "archmagi staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF6, "archmagi staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ")");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
@ -5791,34 +5869,31 @@ void initobjects(void) {
addflag(lastot->flags, F_RANGE, 5, 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_AMMOOB, OT_ARROW, NA, NA, NULL);
addflag(lastot->flags, F_AMMOCAPACITY, 1, 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_RELOADTURNS, 1, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, 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, SZ_MEDIUM); addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but slow to reload and 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_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, 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_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_FIRESPEED, 12, NA, NA, NULL); addflag(lastot->flags, F_FIRESPEED, 15, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
addflag(lastot->flags, F_AMMOOB, OT_BOLT, 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_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_RELOADTURNS, 2, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 15, 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, SZ_SMALL); addot(OT_CROSSBOWHAND, "hand crossbow", "A small wrist-mounted crossbow. Less powerful and accurate than its full-sized sibling, the hand crossbow's primary strength is its ability to fire multiple shots before reloading.", MT_WOOD, 3, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, 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_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_FIRESPEED, 6, NA, NA, NULL); addflag(lastot->flags, F_FIRESPEED, 8, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 7, NA, NA, NULL);
addflag(lastot->flags, F_AMMOOB, OT_BOLT, 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_AMMOCAPACITY, 3, 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_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, SZ_MEDIUM); addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 7, OC_WEAPON, SZ_MEDIUM);
@ -5830,7 +5905,6 @@ void initobjects(void) {
addflag(lastot->flags, F_RANGE, 10, 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_AMMOOB, OT_ARROW, NA, NA, NULL);
addflag(lastot->flags, F_AMMOCAPACITY, 1, 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_RELOADTURNS, 1, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
@ -5846,7 +5920,6 @@ void initobjects(void) {
addflag(lastot->flags, F_AMMOOB, OT_BULLET, 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_AMMOOB, OT_RUBBERBULLET, NA, NA, NULL);
addflag(lastot->flags, F_AMMOCAPACITY, 6, 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); addflag(lastot->flags, F_RELOADTURNS, 2, NA, NA, NULL);
addot(OT_SHOTGUN, "shotgun", "Powerful but short-ranged gun.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addot(OT_SHOTGUN, "shotgun", "Powerful but short-ranged gun.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM);
@ -5859,7 +5932,6 @@ void initobjects(void) {
addflag(lastot->flags, F_RANGE, 3, 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_AMMOOB, OT_BULLET, NA, NA, NULL);
addflag(lastot->flags, F_AMMOCAPACITY, 2, 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); 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); addot(OT_SLING, "sling", "Stretchy piece of rubber for launching projectiles.", MT_RUBBER, 0.5, OC_WEAPON, SZ_SMALL);
@ -5871,7 +5943,6 @@ void initobjects(void) {
addflag(lastot->flags, F_RANGE, 5, 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_AMMOOB, OT_STONE, NA, NA, NULL);
addflag(lastot->flags, F_AMMOCAPACITY, 1, 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_RELOADTURNS, 1, NA, NA, NULL);
@ -6074,6 +6145,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, "pw:1;");
addflag(lastrace->flags, F_VISRANGEMOD, 1, NA, NA, NULL); addflag(lastrace->flags, F_VISRANGEMOD, 1, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL);
// penalties // penalties
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
@ -6160,6 +6232,7 @@ void initrace(void) {
// bonuses // bonuses
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_METALWORK, PR_NOVICE, NA, NULL);
// penalties // penalties
addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL); addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL);
addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL);
@ -6197,6 +6270,47 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MPMOD, 3, NA, NA, NULL); addflag(lastrace->flags, F_MPMOD, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_RANGED, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL);
addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL);
addrace(R_MAMMOAN, "mammoan", 120, '@', C_GREY, MT_LEATHER, RC_HUMANOID, "Mammoans are huge, elephant-like humanoids. Their have great senses of hearing and smell, a photographic memory, and leather skin which greatly lessens damage. On the other hand they vision is poor, their movement slow, and their digestive system cannot cope with meat.");
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_VLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d3+4");
addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_WEAPON, 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_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
addflag(lastrace->flags, F_STARTJOB, 75, J_RANDOM, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roars");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL);
// bonuses
addflag(lastrace->flags, F_PHOTOMEM, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_NOVICE, NA, NULL);
// penalties
addflag(lastrace->flags, F_NOARMOURON, BP_EARS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL);
addflag(lastrace->flags, F_VISRANGEMOD, -2, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_SONIC, NA, NA, NULL);
addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL);
// human monsters... // human monsters...
@ -7502,6 +7616,7 @@ void initrace(void) {
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_SPELLSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_FIREDART, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_FIREDART, NA, NA, "pw:1;");
addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
@ -7526,6 +7641,7 @@ void initrace(void) {
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_SPELLSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_FROSTBITE, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_FROSTBITE, NA, NA, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_FREEZEOB, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_FREEZEOB, NA, NA, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_ICICLE, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_ICICLE, NA, NA, "pw:1;");
@ -9664,7 +9780,7 @@ void initskills(void) {
addskilldesc(SK_CLIMBING, PR_MASTER, "No accuracy penalty or stamina cost to remain climbing.", B_FALSE); addskilldesc(SK_CLIMBING, PR_MASTER, "No accuracy penalty or stamina cost to remain climbing.", B_FALSE);
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50); addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50);
addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE); addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE);
addskilldesc(SK_COOKING, PR_NOVICE, "^gYou can now prepare corpses for consumption.", B_FALSE); addskilldesc(SK_COOKING, PR_NOVICE, "^gYou can now cook corpses before consumption.", B_TRUE);
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou now recognise bad food.^n", B_TRUE); addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou now recognise bad food.^n", B_TRUE);
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook recipes using up to 2 ingredients.", B_TRUE); addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook recipes using up to 2 ingredients.", B_TRUE);
addskilldesc(SK_COOKING, PR_ADEPT, "^gYou can now cook recipes using up to 3 ingredients.", B_TRUE); addskilldesc(SK_COOKING, PR_ADEPT, "^gYou can now cook recipes using up to 3 ingredients.", B_TRUE);
@ -9699,12 +9815,16 @@ void initskills(void) {
addskilldesc(SK_METALWORK, PR_EXPERT, "^gYou can repair metal items up to 85% condition.^n", B_FALSE); addskilldesc(SK_METALWORK, PR_EXPERT, "^gYou can repair metal items up to 85% condition.^n", B_FALSE);
addskilldesc(SK_METALWORK, PR_MASTER, "^gYou can fully repair metal items.^n", B_FALSE); addskilldesc(SK_METALWORK, PR_MASTER, "^gYou can fully repair metal items.^n", B_FALSE);
addskill(SK_RANGED, "Ranged Weapons", "Your ability to aim a ranged weapon like a bow or gun.", 50); addskill(SK_RANGED, "Ranged Weapons", "Your ability to aim a ranged weapon like a bow or gun.", 50);
addskilldesc(SK_RANGED, PR_NOVICE, "^gYou suffer a -20% accuracy penalty when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_INEPT, "^gYour ranged accuracy decreases by 32%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_BEGINNER, "^gYou suffer a -10% accuracy penalty when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_NOVICE, "^gYour ranged accuracy decreases by 22%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_ADEPT, "^gYou no longer suffer a accuracy penalty when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_BEGINNER, "^gYour ranged accuracy decreases by 16%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_SKILLED, "^gYou gain a +10% accuracy bonus when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_ADEPT, "^gYou can now reload ranged weapons instantly.^n", B_TRUE);
addskilldesc(SK_RANGED, PR_EXPERT, "^gYou gain a +20% accuracy bonus when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_ADEPT, "^gYour ranged accuracy decreases by 12%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_MASTER, "^gYou gain a +30% accuracy bonus when using ranged weapons.^n", B_FALSE); addskilldesc(SK_RANGED, PR_SKILLED, "^gYour ranged accuracy decreases by 10%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_EXPERT, "^gMonsters no longer block your line of fire for ranged weapons.^n", B_TRUE);
addskilldesc(SK_RANGED, PR_EXPERT, "^gYour ranged accuracy decreases by 8%% per cell.^n", B_FALSE);
addskilldesc(SK_RANGED, PR_MASTER, "^gYour ranged attacks now deal 50% more damage.^n", B_TRUE);
addskilldesc(SK_RANGED, PR_MASTER, "^gYour ranged accuracy decreases by 6%% per cell.^n", B_FALSE);
addskill(SK_SEWING, "Sewing", "Lets you repair cloth or leather objects.", 100); addskill(SK_SEWING, "Sewing", "Lets you repair cloth or leather objects.", 100);
addskilldesc(SK_SEWING, PR_NOVICE, "^gYou can repair cloth items up to 33% condition.^n", B_FALSE); addskilldesc(SK_SEWING, PR_NOVICE, "^gYou can repair cloth items up to 33% condition.^n", B_FALSE);
addskilldesc(SK_SEWING, PR_BEGINNER, "^gYou can repair cloth items up to 50% condition^n", B_FALSE); addskilldesc(SK_SEWING, PR_BEGINNER, "^gYou can repair cloth items up to 50% condition^n", B_FALSE);
@ -9758,12 +9878,13 @@ void initskills(void) {
addskilldesc(SK_THIEVERY, PR_EXPERT, "gYou can now steal multiple items.", B_TRUE); addskilldesc(SK_THIEVERY, PR_EXPERT, "gYou can now steal multiple items.", B_TRUE);
addskilldesc(SK_THIEVERY, PR_MASTER, "gYou can now steal equipped items.", B_TRUE); addskilldesc(SK_THIEVERY, PR_MASTER, "gYou can now steal equipped items.", B_TRUE);
addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50); addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50);
addskilldesc(SK_THROWING, PR_NOVICE, "^gYou suffer a -20% accuracy penalty when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_INEPT, "^gYour throw accuracy decreases by 32%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_BEGINNER, "^gYou suffer a -10% accuracy penalty when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_NOVICE, "^gYour throw accuracy decreases by 22%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_ADEPT, "^gYou no longer suffer a accuracy penalty when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_BEGINNER, "^gYour throw accuracy decreases by 16%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_SKILLED, "^gYou gain a +10% accuracy bonus when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_ADEPT, "^gYour throw accuracy decreases by 12%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_EXPERT, "^gYou gain a +20% accuracy bonus when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_SKILLED, "^gYour throw accuracy decreases by 10%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_MASTER, "^gYou gain a +30% accuracy bonus when throwing items.^n", B_FALSE); addskilldesc(SK_THROWING, PR_EXPERT, "^gYour throw accuracy decreases by 8%% per cell.^n", B_FALSE);
addskilldesc(SK_THROWING, PR_MASTER, "^gYour throw accuracy decreases by 6%% per cell.^n", B_FALSE);
addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.", 25); addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.", 25);
addskilldesc(SK_TRAPS, PR_NOVICE, "^gYou gain the 'disarm traps' ability.^n", B_FALSE); addskilldesc(SK_TRAPS, PR_NOVICE, "^gYou gain the 'disarm traps' ability.^n", B_FALSE);
addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50); addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50);

Binary file not shown.

16
defs.h
View File

@ -806,6 +806,7 @@ enum RACE {
R_DWARF, R_DWARF,
R_ELF, R_ELF,
R_HUMAN, R_HUMAN,
R_MAMMOAN,
// human monsters // human monsters
R_BANDITLDR, R_BANDITLDR,
R_BANDIT, R_BANDIT,
@ -945,6 +946,7 @@ enum JOB {
J_CHEF, J_CHEF,
J_COMMANDO, J_COMMANDO,
J_DRUID, J_DRUID,
J_HUNTER,
J_MECHANIC, J_MECHANIC,
J_MONK, J_MONK,
J_NINJA, J_NINJA,
@ -1235,6 +1237,7 @@ enum OBTYPE {
OT_S_SNOWBALL, OT_S_SNOWBALL,
OT_S_WALLOFICE, OT_S_WALLOFICE,
// -- gravity // -- gravity
OT_S_EQANDOP,
OT_S_FLIGHT, OT_S_FLIGHT,
OT_S_FORCESPHERE, OT_S_FORCESPHERE,
OT_S_GRAVLOWER, OT_S_GRAVLOWER,
@ -1243,6 +1246,7 @@ enum OBTYPE {
OT_S_LEVITATION, OT_S_LEVITATION,
OT_S_SLOW, OT_S_SLOW,
OT_S_TRUESTRIKE, OT_S_TRUESTRIKE,
OT_S_WHATGOESUP,
// -- life / cleric // -- life / cleric
OT_S_HEALING, OT_S_HEALING,
OT_S_HEALINGMIN, OT_S_HEALINGMIN,
@ -1382,7 +1386,6 @@ enum OBTYPE {
OT_A_INSPECT, OT_A_INSPECT,
OT_A_HURRICANESTRIKE, OT_A_HURRICANESTRIKE,
OT_A_POLYREVERT, OT_A_POLYREVERT,
OT_A_PREPARECORPSE,
OT_A_QUIVERINGPALM, OT_A_QUIVERINGPALM,
OT_A_STEAL, OT_A_STEAL,
OT_A_THRUST, // attack up to 2 cells away with a piercing weapon. OT_A_THRUST, // attack up to 2 cells away with a piercing weapon.
@ -1980,6 +1983,8 @@ enum FLAG {
// what can you do with this object? // what can you do with this object?
F_TAINTED, // will give food poisoning if you eat/drink it F_TAINTED, // will give food poisoning if you eat/drink it
F_PREPARED, // raw meat has been prepared using cooking skill F_PREPARED, // raw meat has been prepared using cooking skill
F_ISMEAT, // this food contains meat parts - not suitable for
// vegetarians
F_EDIBLE, // you can eat this. val1 = nutrition. 100 = a meal F_EDIBLE, // you can eat this. val1 = nutrition. 100 = a meal
// -1 means "nutrition is weight x abs(val1)" // -1 means "nutrition is weight x abs(val1)"
// v2 = nutrition left when partially eaten // v2 = nutrition left when partially eaten
@ -2109,7 +2114,6 @@ enum FLAG {
F_AMMOOB, // v0 = what object this weapon fires. can have multiple types. F_AMMOOB, // v0 = what object this weapon fires. can have multiple types.
F_AMMOCAPACITY, // v0 = max ammo that can be loaded F_AMMOCAPACITY, // v0 = max ammo that can be loaded
F_RANGE, // range of projectile firing weapon 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 F_RELOADTURNS, // # actions it takes to reload this gun
// end gun flags // end gun flags
F_FLAMESTRIKE, // causes fires where you hit F_FLAMESTRIKE, // causes fires where you hit
@ -2292,6 +2296,11 @@ enum FLAG {
F_VISRANGEMOD, // modifications to visrange F_VISRANGEMOD, // modifications to visrange
F_NIGHTVISRANGEMOD, // modifications to nightvisrange F_NIGHTVISRANGEMOD, // modifications to nightvisrange
F_GUNTARGET, // current projectile weapon target F_GUNTARGET, // current projectile weapon target
// v0 is guntarget id.
// text is targetting string (ie. Orc [50%])
F_THROWING, // set while the player is throwing/firing something
// f->text = obid of what we're throwing
// if f->text is NULL, we're using a firearm.
F_CASTINGSPELL, // set while the player is casting a spell F_CASTINGSPELL, // set while the player is casting a spell
// for instant spells: // for instant spells:
// v0 is spell id // v0 is spell id
@ -2600,6 +2609,7 @@ enum FLAG {
F_RESISTMAG, // immunity to magic effects. v0=amt (1-20) F_RESISTMAG, // immunity to magic effects. v0=amt (1-20)
F_MPREGEN, // regenerate MP at val0 per turn F_MPREGEN, // regenerate MP at val0 per turn
F_RAGE, // you are enraged. v0/v1 will be set to player's old hp/maxhp F_RAGE, // you are enraged. v0/v1 will be set to player's old hp/maxhp
F_REFLECTION, // missiles are reflected back at thrower
F_RETALIATE, // deal damage to anyone who hits you F_RETALIATE, // deal damage to anyone who hits you
// v0=ndice, v1=dsides, v2=damtype, text=obname // v0=ndice, v1=dsides, v2=damtype, text=obname
// text must have at least TWO words // text must have at least TWO words
@ -3183,9 +3193,9 @@ typedef struct lifeform_s {
struct race_s *race; struct race_s *race;
int level; int level;
int newlevel; int newlevel;
long totskillxp;
long xp,skillxp; long xp,skillxp;
int skillpoints; int skillpoints;
long totskillpoints;
int hp,maxhp; int hp,maxhp;
int mp,maxmp; int mp,maxmp;
float stamina; float stamina;

1
flag.c
View File

@ -453,6 +453,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
case F_FASTMOVE: case F_FASTMOVE:
case F_FLYING: case F_FLYING:
case F_GRAVBOOSTED: case F_GRAVBOOSTED:
case F_GUNTARGET:
case F_HASNEWLEVEL: case F_HASNEWLEVEL:
case F_HIDING: case F_HIDING:
case F_ICESLIDE: case F_ICESLIDE:

142
io.c
View File

@ -531,6 +531,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars, int mayca
return ch; return ch;
} }
// "func" is a pointer to a function which returns an added description for a highlighted cell
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE LOFTYPE, int wanttrail) { cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE LOFTYPE, int wanttrail) {
static int startlf = -1; static int startlf = -1;
int finished = B_FALSE; int finished = B_FALSE;
@ -617,9 +618,15 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
} }
wclear(msgwin); // only show the question if we don't have a starting target
mvwprintw(msgwin, 0, 0, "%s", prompt); if (c == player->cell) {
wrefresh(msgwin); wclear(msgwin);
mvwprintw(msgwin, 0, 0, "%s", prompt);
wrefresh(msgwin);
} else {
// force cell description to show
moved = B_TRUE;
}
while (!finished) { while (!finished) {
int dir; int dir;
@ -631,6 +638,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
drawlevelfor(player); drawlevelfor(player);
if (moved) { if (moved) {
flag_t *f;
int inlof = B_TRUE, inrange = B_TRUE; int inlof = B_TRUE, inrange = B_TRUE;
cell_t *trailtarg = NULL; cell_t *trailtarg = NULL;
// show what we are over in msg bar // show what we are over in msg bar
@ -929,7 +937,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
if (srclf && (maxrange != UNLIMITED)) { if (srclf && (maxrange != UNLIMITED)) {
if (getcelldist(srclf->cell, c) > maxrange) { if (getcelldist(srclf->cell, c) > maxrange) {
inrange = B_FALSE; inrange = B_FALSE;
strcat(buf, " [too-far]"); strcat(buf, " ^R[too-far]^n");
valid = B_FALSE; valid = B_FALSE;
} }
} }
@ -939,7 +947,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
cell_t *newcell; cell_t *newcell;
if (!haslof(srclf->cell, c, LOFTYPE, &newcell)) { if (!haslof(srclf->cell, c, LOFTYPE, &newcell)) {
inlof = B_FALSE; inlof = B_FALSE;
strcat(buf, " [no-lof]"); strcat(buf, " ^B[no-lof]^n");
valid = B_FALSE; valid = B_FALSE;
} }
if (newcell) { if (newcell) {
@ -947,6 +955,17 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
} }
} }
// throwing hitchance?
f = lfhasflag(player, F_THROWING);
if (f && valid) {
char throwbuf[BUFLEN];
makethrowaccstring(player, c, f, throwbuf);
if (strlen(throwbuf)) {
strcat(buf, throwbuf);
}
}
wclear(msgwin); wclear(msgwin);
if (subprompt) { if (subprompt) {
@ -999,6 +1018,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
if (c->lf && cansee(player, c->lf)) { if (c->lf && cansee(player, c->lf)) {
startlf = c->lf->id; startlf = c->lf->id;
} }
restoregamewindows();
return c; return c;
} else if (ch == 'v') { // view } else if (ch == 'v') { // view
// todo: show obpile or view lf // todo: show obpile or view lf
@ -1035,6 +1055,7 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
} }
clearmsg(); clearmsg();
restoregamewindows();
return NULL; return NULL;
} }
@ -1575,6 +1596,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
msg("%s enter%s a berzerker rage!", lfname, isplayer(lf) ? "" : "s"); msg("%s enter%s a berzerker rage!", lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_REFLECTION:
msg("^%cA negative gravity field forms around %s!",getlfcol(lf, CC_GOOD), lfname);
donesomething = B_TRUE;
break;
case F_RETALIATE: case F_RETALIATE:
msg("%s appear%s from %s%s skin.", noprefix(f->text), msg("%s appear%s from %s%s skin.", noprefix(f->text),
(f->text[strlen(f->text)-1] == 's') ? "" : "s", (f->text[strlen(f->text)-1] == 's') ? "" : "s",
@ -2147,6 +2172,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
msg("%s %s less angry now.", lfname, isplayer(lf) ? "feel" : "seems"); msg("%s %s less angry now.", lfname, isplayer(lf) ? "feel" : "seems");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_REFLECTION:
msg("^%cThe negative gravity around %s vanishes!", lfname);
donesomething = B_TRUE;
break;
case F_RETALIATE: case F_RETALIATE:
msg("%s disappear%s from %s%s skin.", noprefix(f->text), msg("%s disappear%s from %s%s skin.", noprefix(f->text),
(f->text[strlen(f->text)-1] == 's') ? "" : "s", (f->text[strlen(f->text)-1] == 's') ? "" : "s",
@ -3393,6 +3422,14 @@ void doattackcell(char dirch) {
f->val[2] = dirch; f->val[2] = dirch;
} }
if (getrelativedir(player, dir) != RD_FORWARDS) {
if (!lfhasflag(player, F_AWARENESS)) {
msg("You can't attack behind you!");
return;
}
}
attackcell(player, c, B_FALSE); attackcell(player, c, B_FALSE);
} }
} }
@ -4596,11 +4633,8 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf, "@It fires at a speed of %d km/h.\n",speedtokph(ff->val[0])); sprintf(buf, "@It fires at a speed of %d km/h.\n",speedtokph(ff->val[0]));
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
ff = hasflag(o->flags, F_FIRETURNS);
ff2 = hasflag(o->flags, F_RELOADTURNS); ff2 = hasflag(o->flags, F_RELOADTURNS);
sprintf(buf, "@It takes %d turn%s to fire, and %d turn%s to reload.\n", sprintf(buf, "@It takes %d turn%s to reload.\n", ff2->val[0], (ff2->val[0] == 1) ? "" : "s");
ff->val[0], (ff->val[0] == 1) ? "" : "s",
ff2->val[0], (ff2->val[0] == 1) ? "" : "s");
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} else if (isweapon(o) && isknown(o)) { } else if (isweapon(o) && isknown(o)) {
flag_t *damflag; flag_t *damflag;
@ -5244,6 +5278,18 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf2, "%s makes you immune to disease.\n", buf); sprintf(buf2, "%s makes you immune to disease.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
break; break;
case F_DTIMMUNE:
sprintf(buf2, "%s makes you immune to %s.\n", buf, getdamnamenoun(f->val[1]));
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_DTRESIST:
sprintf(buf2, "%s makes you resistant to %s.\n", buf, getdamnamenoun(f->val[1]));
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_DTVULN:
sprintf(buf2, "%s renders you vulnerable to %s.\n", buf, getdamnamenoun(f->val[1]));
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_DRUNK: case F_DRUNK:
sprintf(buf2, "%s makes you tipsy.\n", buf); sprintf(buf2, "%s makes you tipsy.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
@ -5380,6 +5426,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf2, "%s produces light.\n", buf); sprintf(buf2, "%s produces light.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
break; break;
case F_REFLECTION:
sprintf(buf2, "%s reflects all missiles back to their source.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_RETALIATE: case F_RETALIATE:
sprintf(buf2, "%s protects you with %s.\n", buf, f->text); sprintf(buf2, "%s protects you with %s.\n", buf, f->text);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
@ -6595,9 +6645,12 @@ int doselguntarget(void) {
snprintf(buf, BUFLEN, "Aim %s where?",gunname); snprintf(buf, BUFLEN, "Aim %s where?",gunname);
snprintf(buf2, BUFLEN, "%s->Target->",gunname); snprintf(buf2, BUFLEN, "%s->Target->",gunname);
where = askcoords(buf, buf2, TT_MONSTER, player, UNLIMITED, LOF_NEED, B_TRUE); addflag(player->flags, F_THROWING, B_TRUE, NA, NA, NULL);
where = askcoords(buf, buf2, TT_MONSTER, player, UNLIMITED, getfirearmloftype(player), B_TRUE);
killflagsofid(player->flags, F_THROWING);
if (where) { if (where) {
if (where->lf && haslof(player->cell, where, LOF_NEED, NULL)) { //if (where->lf && haslof(player->cell, where, LOF_NEED, NULL)) {
if (where->lf) {
setguntarget(player, where->lf); setguntarget(player, where->lf);
} else { } else {
setguntarget(player, NULL); setguntarget(player, NULL);
@ -6644,6 +6697,7 @@ int dotakeoff(obpile_t *op) {
void dothrow(obpile_t *op) { void dothrow(obpile_t *op) {
object_t *o; object_t *o;
char buf[BUFLEN],buf2[BUFLEN]; char buf[BUFLEN],buf2[BUFLEN];
flag_t *f;
if (!hasbp(player, BP_HANDS)) { if (!hasbp(player, BP_HANDS)) {
msg("You have no hands to throw with!"); msg("You have no hands to throw with!");
@ -6654,9 +6708,8 @@ void dothrow(obpile_t *op) {
o = askobject(op, "Throw what", NULL, AO_NONE); o = askobject(op, "Throw what", NULL, AO_NONE);
if (o) { if (o) {
int maxdist; int maxdist;
char subprompt[BUFLEN]; char subprompt[BUFLEN],oidbuf[BUFLENSMALL];
cell_t *where; cell_t *where;
flag_t *f;
getobname(o, buf, 1); getobname(o, buf, 1);
f = hasflag(o->flags, F_EQUIPPED); f = hasflag(o->flags, F_EQUIPPED);
@ -6671,7 +6724,11 @@ void dothrow(obpile_t *op) {
// ask where to throw it // ask where to throw it
snprintf(buf2, BUFLEN, "Throw %s where?",buf); snprintf(buf2, BUFLEN, "Throw %s where?",buf);
snprintf(subprompt, BUFLEN, "%s->Throw->",buf); snprintf(subprompt, BUFLEN, "%s->Throw->",buf);
sprintf(oidbuf, "%ld", o->id);
addflag(player->flags, F_THROWING, B_TRUE, NA, NA, oidbuf);
where = askcoords(buf2, subprompt, TT_MONSTER, player, maxdist, LOF_NEED, B_TRUE); where = askcoords(buf2, subprompt, TT_MONSTER, player, maxdist, LOF_NEED, B_TRUE);
killflagsofid(player->flags, F_THROWING);
if (where) { if (where) {
cell_t *newwhere = NULL; cell_t *newwhere = NULL;
@ -6932,7 +6989,7 @@ void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading) {
void initgfx(void) { void initgfx(void) {
int msgwinh = 2; int msgwinh = 2;
int statwinh = 2; int statwinh = 3;
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
@ -7970,7 +8027,7 @@ void handleinput(void) {
} }
break; break;
case 'G': // reload Gun with current ammo case 'G': // reload Gun with current ammo
loadfirearmfast(player); loadfirearmfast(player, B_TRUE);
break; break;
case '\'': case '\'':
donextguntarget(); donextguntarget();
@ -8290,14 +8347,25 @@ void drawstatus(void) {
int myatt[MAXATTS]; int myatt[MAXATTS];
int xpleft; int xpleft;
curs_set(0); curs_set(0);
wclear(statwin); wclear(statwin);
// FIRST LINE
wmove(statwin, 0, 0);
// gun target ?
f = hasflag(player->flags, F_GUNTARGET);
if (f) {
wprintw(statwin, "Aim: ");
textwithcol(statwin, f->text);
}
// SECOND LINE
wmove(statwin, 1, 0);
//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); xpleft = (int) (((float)player->xp / (float)getxpforlev(player->level + 1)) * 100.0);
wmove(statwin, 0, 0);
/* /*
getplayername(pname); getplayername(pname);
wattron(statwin, A_BOLD); wprintw(statwin, "["); wattroff(statwin, A_BOLD); wattron(statwin, A_BOLD); wprintw(statwin, "["); wattroff(statwin, A_BOLD);
@ -8612,14 +8680,13 @@ void drawstatus(void) {
} }
// SECOND LINE // THIRD LINE
for (a = 0; a < MAXATTS; a++) { for (a = 0; a < MAXATTS; a++) {
myatt[a] = getattr(player, a); myatt[a] = getattr(player, a);
} }
//redraw(); //redraw();
wmove(statwin, 1, 0); wmove(statwin, 2, 0);
wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD); wattron(statwin, A_BOLD); wprintw(statwin, "AR:"); wattroff(statwin, A_BOLD);
snprintf(buf, BUFLEN, "%d ", getarmourrating(player, NULL, NULL, NULL)); snprintf(buf, BUFLEN, "%d ", getarmourrating(player, NULL, NULL, NULL));
wprintw(statwin, buf); wprintw(statwin, buf);
@ -8654,6 +8721,7 @@ void drawstatus(void) {
capitalise(buf); capitalise(buf);
wprintw(statwin, "%s", buf); wprintw(statwin, "%s", buf);
unsetcol(statwin, C_BROWN); unsetcol(statwin, C_BROWN);
} }
void drawmsg(void) { void drawmsg(void) {
@ -9754,6 +9822,10 @@ void showlfstats(lifeform_t *lf, int showall) {
strcat(buf, "."); strcat(buf, ".");
wrapprint(mainwin, &y, &x, "%s ", buf); wrapprint(mainwin, &y, &x, "%s ", buf);
} }
f = lfhasflag(lf, F_REFLECTION);
if (f && (f->known)) {
wrapprint(mainwin, &y, &x, "%s %s surrounded by a negative gravity field.", you(lf), is(lf));
}
f = lfhasflag(lf, F_RETALIATE); f = lfhasflag(lf, F_RETALIATE);
if (f && (f->known)) { if (f && (f->known)) {
@ -9881,16 +9953,20 @@ void showlfstats(lifeform_t *lf, int showall) {
if (!dounknown && (slev != PR_INEPT)) { if (!dounknown && (slev != PR_INEPT)) {
char endbit[BUFLEN]; char endbit[BUFLEN];
char basecolour = 'n'; char basecolour = 'n';
int max;
if (ismaxedskill(lf, sk->id)) { if (ismaxedskill(lf, sk->id)) {
basecolour = 'h'; basecolour = 'h';
} }
// known skill // known skill
sprintf(thisline, "^%c%-21s^%c[^%d", basecolour, sk->name, basecolour, sprintf(thisline, "^%c%-21s^%c[^%d", basecolour, sk->name, basecolour,
getskilllevelcolour(slev)); getskilllevelcolour(slev));
max = getmaxskilllevel(player, sk->id);
for (i = PR_NOVICE; i <= PR_MASTER; i++) { for (i = PR_NOVICE; i <= PR_MASTER; i++) {
char toadd[BUFLEN]; char toadd[BUFLEN];
if (i > getmaxskilllevel(player, sk->id)) { if (i == (max+1)) {
sprintf(toadd, "^n]########");
} else if (i > max) {
sprintf(toadd, "^n#########"); sprintf(toadd, "^n#########");
} else if (i == slev) { } else if (i == slev) {
if (i == getmaxskilllevel(player, sk->id)) { if (i == getmaxskilllevel(player, sk->id)) {
@ -9912,15 +9988,23 @@ void showlfstats(lifeform_t *lf, int showall) {
textwithcol(mainwin, thisline); textwithcol(mainwin, thisline);
printed = B_TRUE; printed = B_TRUE;
} else if (dounknown && !slev && lfhasflagval(lf, F_CANLEARN, sk->id, NA, NA, NULL)) { } else if (dounknown && !slev && lfhasflagval(lf, F_CANLEARN, sk->id, NA, NA, NULL)) {
char toadd[BUFLEN];
int max;
// learnable skill // learnable skill
setcol(mainwin, C_RED); sprintf(toadd, "^B%-21s[", sk->name );
mvwprintw(mainwin, y, 0, "%-21s", sk->name, " " ); wmove(mainwin, y, 0);
wprintw(mainwin, "["); textwithcol(mainwin, toadd);
for (i = PR_NOVICE; i < PR_MASTER+1; i++) { max = getmaxskilllevel(player, sk->id);
wprintw(mainwin, " "); for (i = PR_NOVICE; i <= PR_MASTER; i++) {
if (i == max+1) {
textwithcol(mainwin, "^B]########");
} else if (i > max) {
textwithcol(mainwin, "^B#########");
} else {
wprintw(mainwin, " ");
}
} }
wprintw(mainwin, "]"); textwithcol(mainwin, "^B]^n");
unsetcol(mainwin, C_RED);
printed = B_TRUE; printed = B_TRUE;
} }

280
lf.c
View File

@ -81,6 +81,10 @@ void autoweild(lifeform_t *lf) {
pretimespent = lf->timespent; pretimespent = lf->timespent;
if (isplayer(lf)) {
dblog("db: calling autoweild for player.");
}
// weild weapons if required // weild weapons if required
bestwep = getbestweapon(lf); bestwep = getbestweapon(lf);
if (bestwep) { if (bestwep) {
@ -688,16 +692,16 @@ int caneat(lifeform_t *lf, object_t *o) {
} }
} }
if (lfhasflag(lf, F_VEGETARIAN) && (o->material->id == MT_FLESH)) { if (lfhasflag(lf, F_VEGETARIAN) && hasflag(o->flags, F_ISMEAT)) {
reason = E_VEGETARIAN; reason = E_VEGETARIAN;
return B_FALSE; return B_FALSE;
} }
if (lfhasflag(lf, F_CARNIVORE) && (o->material->id != MT_FLESH)) { if (lfhasflag(lf, F_CARNIVORE) && !hasflag(o->flags, F_ISMEAT)) {
reason = E_CARNIVORE; reason = E_CARNIVORE;
return B_FALSE; return B_FALSE;
} }
if (lfhasflag(lf, F_PARTVEGETARIAN) && (o->material->id == MT_FLESH)) { if (lfhasflag(lf, F_PARTVEGETARIAN) && hasflag(o->flags, F_ISMEAT)) {
if (gethungerlevel(gethungerval(player)) < H_PECKISH) { if (gethungerlevel(gethungerval(player)) < H_PECKISH) {
reason = E_PARTVEGETARIAN; reason = E_PARTVEGETARIAN;
return B_FALSE; return B_FALSE;
@ -1011,7 +1015,7 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) {
} }
dist = getcelldist(viewer->cell, viewee->cell); dist = getcelldist(viewer->cell, viewee->cell);
f = lfhasflag(viewer, F_TREMORSENSE); f = lfhasflag(viewer, F_TREMORSENSE);
if (f) { if (f && !isairborne(viewee)) {
if (f->val[0] > 0) { if (f->val[0] > 0) {
tremordist = f->val[0]; tremordist = f->val[0];
} else { } else {
@ -4302,7 +4306,6 @@ void gainxp(lifeform_t *lf, long amt) {
amtneeded = getspforpoint(lf); amtneeded = getspforpoint(lf);
lf->skillxp += amt; lf->skillxp += amt;
lf->totskillxp += amt;
assert(lf->skillxp >= 0); assert(lf->skillxp >= 0);
while (lf->skillxp >= amtneeded) { while (lf->skillxp >= amtneeded) {
@ -4321,6 +4324,7 @@ void gainxp(lifeform_t *lf, long amt) {
if (newskillpoints) { if (newskillpoints) {
lf->skillpoints += newskillpoints; lf->skillpoints += newskillpoints;
msg("^GYou feel ready to learn a new skill!"); msg("^GYou feel ready to learn a new skill!");
lf->totskillpoints += newskillpoints;
} }
} }
@ -5155,21 +5159,29 @@ int getevasion(lifeform_t *lf) {
return ev; return ev;
} }
object_t *getbestthrowmissile(lifeform_t *lf) { object_t *getbestthrowmissile(lifeform_t *lf, lifeform_t *target) {
object_t *bestwep = NULL; object_t *bestwep = NULL;
int bestdam = -1; int bestdam = -1;
object_t *o; object_t *o;
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
if (!isequipped(o) && isthrowmissile(o) ) { if (!isequipped(o) && isthrowmissile(o) ) {
int thisdam; int valid = B_TRUE;
// better than last one?
thisdam = getthrowdam(o) + getshatterdam(o); // powder is only a valid missile if we're adjacent to our target
if ((bestwep == NULL) || (thisdam > bestdam)) { if (target && hasflag(o->flags, F_POWDER)) {
bestwep = o; if (getcelldist(lf->cell,target->cell) > 1) valid = B_FALSE;
bestdam = thisdam;
} }
if (valid) {
int thisdam;
// better than last one?
thisdam = getthrowdam(o) + getshatterdam(o);
if ((bestwep == NULL) || (thisdam > bestdam)) {
bestwep = o;
bestdam = thisdam;
}
}
} }
} }
return bestwep; return bestwep;
@ -5369,6 +5381,13 @@ object_t *getfirearm(lifeform_t *lf) {
return NULL; return NULL;
} }
enum LOFTYPE getfirearmloftype(lifeform_t *lf) {
if (getskill(lf, SK_RANGED) >= PR_EXPERT) {
return LOF_WALLSTOP;
}
return LOF_NEED;
}
int getfootprinttime(lifeform_t *lf) { int getfootprinttime(lifeform_t *lf) {
int time; int time;
@ -7076,7 +7095,7 @@ race_t *getreallyrandomrace(enum RACECLASS wantrc) {
enum SKILL getrandomskill(void) { enum SKILL getrandomskill(void) {
int sel,count = 0; int sel,count = 0;
skill_t *sk; skill_t *sk;
sel = rnd(0,MAXSKILLS-1); sel = rnd(1,MAXSKILLS-1); // 0 is SK_NONE
for (sk = firstskill ; sk ; sk = sk->next) { for (sk = firstskill ; sk ; sk = sk->next) {
if (count == sel) return sk->id; if (count == sel) return sk->id;
count++; count++;
@ -7177,7 +7196,7 @@ long getspforpoint(lifeform_t *lf) {
float mod; float mod;
long amtneeded; long amtneeded;
amtneeded = SKILLXPPERPOINT; amtneeded = SKILLXPPERPOINT;
amtneeded += (50 * lf->totskillxp); amtneeded += (50 * lf->totskillpoints);
mod = MAXOF(getstatmod(lf, A_IQ), getstatmod(lf, A_WIS)); mod = MAXOF(getstatmod(lf, A_IQ), getstatmod(lf, A_WIS));
amtneeded = pctof(100 - mod, amtneeded); amtneeded = pctof(100 - mod, amtneeded);
return amtneeded; return amtneeded;
@ -7958,9 +7977,9 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
makeknown(OT_POT_JUICE); makeknown(OT_POT_JUICE);
makeknown(OT_POT_RUM); makeknown(OT_POT_RUM);
} }
newf = hasflagval(lf->flags, F_CANWILL, OT_A_PREPARECORPSE, NA, NA, NULL); newf = hasflagval(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL);
if (!newf) { if (!newf) {
newf = addflag(lf->flags, F_CANWILL, OT_A_PREPARECORPSE, NA, NA, NULL); newf = addflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL);
newf->lifetime = FROMSKILL; newf->lifetime = FROMSKILL;
} }
} else if (id == SK_LORE_ARCANA) { } else if (id == SK_LORE_ARCANA) {
@ -7988,6 +8007,23 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
newf = addflag(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL); newf = addflag(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL);
newf->lifetime = FROMSKILL; newf->lifetime = FROMSKILL;
} }
// learning a new spell school skill will grant you a random first level spell from
// that school.
if (isspellskill(id)) {
enum OBTYPE oid;
int tries = 0;
oid = getrandomspellfromschool(getskillschool(id), 1);
while (cancast(lf, oid, NULL) && (tries < 3)) {
oid = getrandomspellfromschool(getskillschool(id), 1);
tries++;
}
if (oid != OT_NONE) {
addflag(lf->flags, F_CANCAST, oid, NA, NA, NULL);
}
}
statdirty = B_TRUE; // in case skill changes your stats statdirty = B_TRUE; // in case skill changes your stats
} }
@ -8011,10 +8047,6 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
newf->lifetime = FROMSKILL; newf->lifetime = FROMSKILL;
} }
} else if (id == SK_COOKING) { } else if (id == SK_COOKING) {
if (f->val[1] == PR_BEGINNER) {
newf = addflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL);
newf->lifetime = FROMSKILL;
}
if (f->val[1] == PR_ADEPT) { if (f->val[1] == PR_ADEPT) {
if (isplayer(lf)) { if (isplayer(lf)) {
makeknown(OT_MUSHROOMSHI); makeknown(OT_MUSHROOMSHI);
@ -8397,9 +8429,10 @@ void givestartskills(lifeform_t *lf, flagpile_t *fp) {
f = retflag[i]; f = retflag[i];
if (f->id == F_STARTSKILL) { if (f->id == F_STARTSKILL) {
int wantval; int wantval,n;
wantval = f->val[1]; wantval = f->val[1];
while (getskill(lf, f->val[0]) < wantval) { for (n = 0; n < wantval; n++) {
//while (getskill(lf, f->val[0]) < wantval) {
giveskill(lf, f->val[0]); giveskill(lf, f->val[0]);
} }
} }
@ -9630,6 +9663,30 @@ int isloreskill(enum SKILL skid) {
return B_FALSE; return B_FALSE;
} }
int isspellskill(enum SKILL skid) {
switch (skid) {
case SK_SS_ALLOMANCY:
case SK_SS_MENTAL:
case SK_SS_NATURE:
case SK_SS_AIR:
case SK_SS_DEATH:
case SK_SS_DIVINATION:
case SK_SS_ENCHANTMENT:
case SK_SS_FIRE:
case SK_SS_COLD:
case SK_SS_GRAVITY:
case SK_SS_LIFE:
case SK_SS_MODIFICATION:
case SK_SS_SUMMONING:
case SK_SS_TRANSLOCATION:
case SK_SS_WILD:
return B_TRUE;
default:
break;
}
return B_FALSE;
}
int ismadeofice(lifeform_t *lf) { int ismadeofice(lifeform_t *lf) {
if (lf->material->id == MT_ICE) return B_TRUE; if (lf->material->id == MT_ICE) return B_TRUE;
if (lfhasflag(lf, F_FROZEN)) return B_TRUE; if (lfhasflag(lf, F_FROZEN)) return B_TRUE;
@ -9850,7 +9907,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
a->level = level; a->level = level;
a->newlevel = level; a->newlevel = level;
a->xp = getxpforlev(a->level); a->xp = getxpforlev(a->level);
a->totskillxp = 0; a->totskillpoints = 0;
a->skillxp = 0; a->skillxp = 0;
a->skillpoints = 0; a->skillpoints = 0;
a->cell = cell; a->cell = cell;
@ -10195,7 +10252,7 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
// don't adjust for lifeform material - we inherit all the material's flags. // don't adjust for lifeform material - we inherit all the material's flags.
//adjustdammaterial((unsigned int *)amt, damtype, getlfmaterial(lf)); //adjustdammaterial((unsigned int *)amt, damtype, getlfmaterial(lf));
adjustdamhardness((unsigned int *)amt, damtype, getlfmaterial(lf)); adjustdamhardness(amt, damtype, getlfmaterial(lf));
if (lfhasflag(lf, F_DRUNK)) { if (lfhasflag(lf, F_DRUNK)) {
*amt -= rnd(0,3); *amt -= rnd(0,3);
@ -10544,23 +10601,24 @@ void autoskill(lifeform_t *lf) {
void autotarget(lifeform_t *lf) { void autotarget(lifeform_t *lf) {
object_t *gun; object_t *gun;
lifeform_t *targ,*newtarg; lifeform_t *targ = NULL,*newtarg = NULL;
int closest; int closest;
int i; int i;
int gunrange; int gunrange;
int targid; int targid;
gun = getfirearm(lf); gun = getfirearm(lf);
if (!gun) return; if (gun && getammo(gun)) {
gunrange = getfirearmrange(gun);
if (!getammo(gun)) return; // already got a target?
targid = getguntargetid(lf);
gunrange = getfirearmrange(gun); } else {
gunrange = -1;
// already got a target? targid = -1;
targid = getguntargetid(lf); }
if (targid == -1) { if (targid == -1) {
// no existing target
targ = NULL; targ = NULL;
} else { } else {
targ = findlf(NULL, targid); targ = findlf(NULL, targid);
@ -10569,45 +10627,63 @@ void autotarget(lifeform_t *lf) {
if (isdead(targ)) { if (isdead(targ)) {
// clear target ? // clear target ?
targ = NULL; targ = NULL;
} else if (!haslof(lf->cell, targ->cell, B_FALSE, NULL)) { } else if (!cansee(lf, targ) || !haslof(lf->cell, targ->cell, getfirearmloftype(lf), NULL)) {
// clear target ? // clear target ?
targ = NULL; targ = NULL;
} else { } else {
// already got a valid target. return. flag_t *f;
// already got a valid target. just update targetting text.
f = hasflag(lf->flags, F_GUNTARGET);
if (f) {
char targbuf[BUFLEN];
makegunaimstring(lf, f->val[0], targbuf);
if (!streq(targbuf, f->text)) {
free(f->text);
f->text = strdup(targbuf);
if (isplayer(lf)) {
statdirty = B_TRUE;
drawstatus();
updatestatus();
}
}
}
return; return;
} }
} else { } else {
// target no longer exists? // target no longer exists
// clear target ? // clear target
targ = NULL;
} }
} }
// find new target if (gun && (gunrange != -1)) {
newtarg = NULL; // find new target
closest = 9999; newtarg = NULL;
for (i = 0; i < lf->nlos; i++) { closest = 9999;
cell_t *c; for (i = 0; i < lf->nlos; i++) {
c = lf->los[i]; cell_t *c;
if (c->lf && (c->lf != lf) && cansee(lf, c->lf) && isingunrange(lf, c)) { c = lf->los[i];
int valid = B_TRUE; if (c->lf && (c->lf != lf) && cansee(lf, c->lf) && isingunrange(lf, c) && areenemies(lf, c->lf)) {
if (!areenemies(lf, c->lf)) { if (haslof(lf->cell, c, getfirearmloftype(lf), NULL)) {
valid = B_FALSE; int thisdist;
} thisdist = getcelldist(lf->cell, c);
if (valid) { if (thisdist < closest) {
int thisdist; newtarg = c->lf;
thisdist = getcelldist(lf->cell, c); closest = thisdist;
if (thisdist < closest) { }
newtarg = c->lf;
closest = thisdist;
} }
} }
} }
} }
if (newtarg != targ) {
if (newtarg && (newtarg != targ)) {
setguntarget(lf, newtarg); setguntarget(lf, newtarg);
} }
if (!newtarg) {
killflagsofid(lf->flags, F_GUNTARGET);
}
} }
int issmellablelf(lifeform_t *lf) { int issmellablelf(lifeform_t *lf) {
@ -10828,13 +10904,16 @@ int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo) {
// take time // take time
if (lf) { if (lf) {
f = hasflag(gun->flags, F_RELOADTURNS); if (getskill(lf, SK_RANGED) < PR_ADEPT) {
taketime(lf, getactspeed(lf)*f->val[0]); f = hasflag(gun->flags, F_RELOADTURNS);
taketime(lf, getactspeed(lf)*f->val[0]);
}
if (isplayer(lf)) { if (isplayer(lf)) {
char buf[BUFLEN]; //char buf[BUFLEN];
getobname(gun->contents->first, buf, gun->contents->first->amt); //getobname(gun->contents->first, buf, gun->contents->first->amt);
msg("You load %s into your %s.", buf, noprefix(gunname)); //msg("You load %s into your %s.", buf, noprefix(gunname));
msg("You reload your %s.", noprefix(gunname));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
@ -10847,18 +10926,18 @@ int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo) {
return B_FALSE; return B_FALSE;
} }
int loadfirearmfast(lifeform_t *lf) { int loadfirearmfast(lifeform_t *lf, int onpurpose) {
object_t *gun,*newammo,*curammo; object_t *gun,*newammo,*curammo;
gun = getfirearm(lf); gun = getfirearm(lf);
if (!gun) { if (!gun) {
if (isplayer(lf)) { if (isplayer(lf) && onpurpose) {
msg("You have no firearm equipped."); msg("You have no firearm equipped.");
} }
return B_TRUE; return B_TRUE;
} }
curammo = getammo(gun); curammo = getammo(gun);
if (curammo) { if (curammo) {
if (isplayer(lf)) { if (isplayer(lf) && onpurpose) {
char buf[BUFLEN]; char buf[BUFLEN];
getobname(gun, buf, 1); getobname(gun, buf, 1);
msg("Your %s is already loaded!", noprefix(buf)); msg("Your %s is already loaded!", noprefix(buf));
@ -10870,13 +10949,14 @@ int loadfirearmfast(lifeform_t *lf) {
if (newammo) { if (newammo) {
loadfirearm(lf, gun, newammo); loadfirearm(lf, gun, newammo);
} else { } else {
if (isplayer(lf)) { if (isplayer(lf) && onpurpose) {
char buf[BUFLEN]; char buf[BUFLEN];
getobname(gun, buf, 1); getobname(gun, buf, 1);
msg("You have no ammo for your %s.", noprefix(buf)); msg("You have no ammo for your %s.", noprefix(buf));
} }
return B_TRUE; return B_TRUE;
} }
if ((gamemode == GM_GAMESTARTED) && onpurpose) taketime(lf, getactspeed(lf));
return B_FALSE; return B_FALSE;
} }
@ -13115,38 +13195,39 @@ void setfollowdistance(lifeform_t *lf, int min, int max) {
} }
void setguntarget(lifeform_t *lf, lifeform_t *targ) { void setguntarget(lifeform_t *lf, lifeform_t *targ) {
flag_t *f; flag_t *f,*targflag = NULL;
char oldtargbuf[BUFLEN];
char targbuf[BUFLEN];
// have an existing target?
f = hasflag(lf->flags, F_GUNTARGET); f = hasflag(lf->flags, F_GUNTARGET);
if (f) { if (f) {
strcpy(oldtargbuf, f->text);
killflag(f); killflag(f);
} else {
strcpy(oldtargbuf, "");
} }
if (targ) { if (targ) {
addflag(lf->flags, F_GUNTARGET, targ->id, NA, NA, NULL); makegunaimstring(lf, targ->id, targbuf); // fill in the text
if (isplayer(lf)) { f = addflag(lf->flags, F_GUNTARGET, targ->id, NA, NA, targbuf);
// announce } else {
char targname[BUFLEN]; targflag = NULL;
getlfname(targ, targname); strcpy(targbuf, "nothing");
msg("Targetted: %s.",noprefix(targname)); // remove 'the ' }
} else {
if (lfhasflag(lf, F_DEBUG)) { // announce if required
char lfname[BUFLEN]; if (isplayer(lf)) {
char targname[BUFLEN]; if (!streq(targbuf, oldtargbuf)) {
getlfname(lf, lfname); warn("Targetted: %s", targbuf );
getlfname(targ, targname); statdirty = B_TRUE;
dblog("%s targetted %s.",lfname,targname);
}
} }
} else { } else {
if (isplayer(lf)) { if (lfhasflag(lf, F_DEBUG)) {
// announce char lfname[BUFLEN];
msg("Targetted: nothing."); char targname[BUFLEN];
} else { getlfname(lf, lfname);
if (lfhasflag(lf, F_DEBUG)) { getlfname(targ, targname);
char lfname[BUFLEN]; dblog("%s targetted %s.",lfname,targname);
getlfname(lf, lfname);
dblog("%s target set to nothing.",lfname);
}
} }
} }
} }
@ -13480,7 +13561,6 @@ void setstamina(lifeform_t *lf, float howmuch) {
int shoot(lifeform_t *lf) { int shoot(lifeform_t *lf) {
object_t *gun,*ammo; object_t *gun,*ammo;
lifeform_t *targ; lifeform_t *targ;
flag_t *f;
int firespeed; int firespeed;
reason = E_OK; reason = E_OK;
@ -13505,10 +13585,19 @@ int shoot(lifeform_t *lf) {
// get fire speed // get fire speed
firespeed = getfirearmspeed(gun); firespeed = getfirearmspeed(gun);
f = hasflag(gun->flags, F_FIRETURNS); taketime(lf, getactspeed(lf));
taketime(lf, getactspeed(lf) * f->val[0]);
fireat(lf, ammo, 1, targ->cell, firespeed, gun); fireat(lf, ammo, 1, targ->cell, firespeed, gun);
if (!getammo(gun)) {
if (loadfirearmfast(lf, B_FALSE)) {
if (isplayer(lf)) {
char obname[BUFLEN];
getobname(gun, obname, 1);
msg("^bYour %s is now out of ammo!", noprefix(obname));
}
}
}
return B_FALSE; return B_FALSE;
} }
@ -14662,7 +14751,7 @@ void startlfturn(lifeform_t *lf) {
getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FLEEFROM, getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FLEEFROM,
F_GRABBEDBY, F_GRABBING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_INJURY, F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_INJURY,
F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE); F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -16327,6 +16416,11 @@ int wear(lifeform_t *lf, object_t *o) {
statdirty = B_TRUE; statdirty = B_TRUE;
} }
if (o->amt > 1) {
// eg. for melted wax in your ears
o = splitob(o);
}
getobname(o, obname, 1); getobname(o, obname, 1);
// check if it is already equipped first! // check if it is already equipped first!

6
lf.h
View File

@ -126,7 +126,7 @@ int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
int getavgdam(lifeform_t *lf, int forxp); int getavgdam(lifeform_t *lf, int forxp);
float getequippedweight(lifeform_t *lf); float getequippedweight(lifeform_t *lf);
int getevasion(lifeform_t *lf); int getevasion(lifeform_t *lf);
object_t *getbestthrowmissile(lifeform_t *lf); object_t *getbestthrowmissile(lifeform_t *lf, lifeform_t *target);
object_t *getbestweapon(lifeform_t *lf); object_t *getbestweapon(lifeform_t *lf);
object_t *getbestfirearm(lifeform_t *lf); object_t *getbestfirearm(lifeform_t *lf);
int getbodyparthitchance(enum BODYPART bp); int getbodyparthitchance(enum BODYPART bp);
@ -135,6 +135,7 @@ char *getbodypartequipname(enum BODYPART bp);
object_t *getequippedob(obpile_t *op, enum BODYPART bp); object_t *getequippedob(obpile_t *op, enum BODYPART bp);
int getexposedlimbs(lifeform_t *lf); int getexposedlimbs(lifeform_t *lf);
object_t *getfirearm(lifeform_t *lf); object_t *getfirearm(lifeform_t *lf);
enum LOFTYPE getfirearmloftype(lifeform_t *lf);
int getfootprinttime(lifeform_t *lf); int getfootprinttime(lifeform_t *lf);
lifeform_t *getguntarget(lifeform_t *lf); lifeform_t *getguntarget(lifeform_t *lf);
int getguntargetid(lifeform_t *lf); int getguntargetid(lifeform_t *lf);
@ -283,6 +284,7 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
int isinbattle(lifeform_t *lf); int isinbattle(lifeform_t *lf);
int isingunrange(lifeform_t *lf, cell_t *where); int isingunrange(lifeform_t *lf, cell_t *where);
int isloreskill(enum SKILL skid); int isloreskill(enum SKILL skid);
int isspellskill(enum SKILL skid);
int ismadeofice(lifeform_t *lf); int ismadeofice(lifeform_t *lf);
int ismaxedskill(lifeform_t *lf, enum SKILL skid); int ismaxedskill(lifeform_t *lf, enum SKILL skid);
int ispeaceful(lifeform_t *lf); int ispeaceful(lifeform_t *lf);
@ -309,7 +311,7 @@ void killlf(lifeform_t *lf);
void killrace(race_t *race); void killrace(race_t *race);
flag_t *levelabilityready(lifeform_t *lf); flag_t *levelabilityready(lifeform_t *lf);
int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo); int loadfirearm(lifeform_t *lf, object_t *gun, object_t *ammo);
int loadfirearmfast(lifeform_t *lf); int loadfirearmfast(lifeform_t *lf, int onpurpose);
void loseconcentration(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(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, object_t *fromob, int retaliate); int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate);

17
map.c
View File

@ -5530,7 +5530,9 @@ void setcellknown(cell_t *cell, int forcelev) {
} }
} }
if (slev == PR_INEPT) { if (hasflag(player->flags, F_PHOTOMEM)) {
cell->knowntime = PERMENANT;
} else if (slev == PR_INEPT) {
cell->knowntime = getattr(player, A_IQ)*5; cell->knowntime = getattr(player, A_IQ)*5;
} else { } else {
cell->knowntime = PERMENANT; cell->knowntime = PERMENANT;
@ -5706,12 +5708,17 @@ int unlinkstairsto(map_t *unlinkmap) {
void updateknowncells(void) { void updateknowncells(void) {
int x,y; int x,y;
map_t *map; map_t *map;
object_t *wep; //object_t *wep;
int seenundead = B_FALSE; //int seenundead = B_FALSE;
// you don't remember cells when you're flying, unless you
// have a magic map or photographic memory.
if (isairborne(player) && !lfhasflag(player, F_PHOTOMEM)) {
return;
}
map = player->cell->map; map = player->cell->map;
wep = getweapon(player); //wep = getweapon(player);
for (y = viewy; y < viewy + viewh; y++) { for (y = viewy; y < viewy + viewh; y++) {
for (x = viewx; x < viewx + vieww; x++) { for (x = viewx; x < viewx + vieww; x++) {
@ -5721,9 +5728,11 @@ void updateknowncells(void) {
//if ((player->cell == cell) || haslos(player, cell)) { //if ((player->cell == cell) || haslos(player, cell)) {
if (haslos(player, cell)) { if (haslos(player, cell)) {
setcellknown(cell, B_FALSE); setcellknown(cell, B_FALSE);
/*
if (cell->lf && lfhasflag(cell->lf, F_UNDEAD)) { if (cell->lf && lfhasflag(cell->lf, F_UNDEAD)) {
seenundead = B_TRUE; seenundead = B_TRUE;
} }
*/
} }
} }
} }

4
move.c
View File

@ -809,7 +809,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
for (i = 0; i < howfar; i++) { for (i = 0; i < howfar; i++) {
if (moveclear(lf, dir, &reason)) { if (moveclear(lf, dir, &reason)) {
if ((i == 0) && seen && wantannounce) { if ((i == 0) && seen && wantannounce) {
msg("%s %s knocked backwards!",lfname,is(lf)); msg("%s %s knocked %s!",lfname,is(lf), getreldirname(getrelativedir(lf, dir)));
} }
trymove(lf, dir, B_FALSE, B_FALSE); trymove(lf, dir, B_FALSE, B_FALSE);
} }
@ -1833,7 +1833,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
msg("%s bursts open!",obname); msg("%s bursts open!",obname);
} else { } else {
char noisebuf[BUFLEN]; char noisebuf[BUFLEN];
sprintf(noisebuf, "%s bursting open.", obname); sprintf(noisebuf, "%s bursting open!", obname);
noise(doorcell, NULL, NC_OTHER, 4, noisebuf, NULL); noise(doorcell, NULL, NC_OTHER, 4, noisebuf, NULL);
} }
} }

19
nexus.c
View File

@ -896,6 +896,25 @@ enum COLOUR getpctcol(float num, float max) {
return C_ORANGE; return C_ORANGE;
} }
char getpctletter(float num, float max) {
float pct;
pct = (num / max) * 100;
if (pct >= 100) {
return 'S';
} else if (pct >= 85) {
return 'A';
} else if (pct >= 70) {
return 'B';
} else if (pct >= 55) {
return 'C';
} else if (pct >= 40) {
return 'D';
} else { // ie. < 40%
return 'E';
}
return '?';
}
void getrarityrange(int depth, int *min, int *max, int range, int oodok) { void getrarityrange(int depth, int *min, int *max, int range, int oodok) {
int mid; int mid;
int num; int num;

View File

@ -11,6 +11,7 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in
void donextturn(map_t *map); void donextturn(map_t *map);
void gethitdicerange(int depth, int *min, int *max, int range, int oodok); void gethitdicerange(int depth, int *min, int *max, int range, int oodok);
enum COLOUR getpctcol(float num, float max); enum COLOUR getpctcol(float num, float max);
char getpctletter(float num, float max);
void getrarityrange(int depth, int *min, int *max, int range, int oodok); void getrarityrange(int depth, int *min, int *max, int range, int oodok);
int init(void); int init(void);
void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels); void calcbresnham(map_t *m, int x1, int y1, int x2, int y2, cell_t **retcell, int *numpixels);

247
objects.c
View File

@ -1308,6 +1308,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
// ie. vending machine, or inside another object/fake cell? // ie. vending machine, or inside another object/fake cell?
corpserace = getrandomcorpserace(NULL); corpserace = getrandomcorpserace(NULL);
} }
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
} }
ratio = o->material->weightrating / corpserace->material->weightrating; ratio = o->material->weightrating / corpserace->material->weightrating;
@ -1363,6 +1364,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
} else if (o->type->id == OT_JERKY) { } else if (o->type->id == OT_JERKY) {
if (!corpserace) { if (!corpserace) {
corpserace = getrandomcorpserace(NULL); corpserace = getrandomcorpserace(NULL);
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
} }
addflag(o->flags, F_LINKRACE, corpserace->id, NA, NA, NULL); addflag(o->flags, F_LINKRACE, corpserace->id, NA, NA, NULL);
} else if (o->type->id == OT_ROASTMEAT) { } else if (o->type->id == OT_ROASTMEAT) {
@ -1371,6 +1373,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
if (!corpserace || hasflag(corpserace->flags, F_NOCORPSE)) { if (!corpserace || hasflag(corpserace->flags, F_NOCORPSE)) {
// random one. // random one.
corpserace = getrandomcorpserace(NULL); corpserace = getrandomcorpserace(NULL);
if (corpserace->id != corpserace->baseid) corpserace = findrace(corpserace->baseid);
} }
o->weight = corpserace->weight / 2; o->weight = corpserace->weight / 2;
@ -1806,7 +1809,7 @@ recipe_t *addrecipe(enum OBTYPE result, ...) {
} }
void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat) { void adjustdamhardness(int *dam, enum DAMTYPE damtype, enum MATERIAL mat) {
// now check for hardness // now check for hardness
if (isphysicaldam(damtype)) { if (isphysicaldam(damtype)) {
*dam -= gethardness(mat); *dam -= gethardness(mat);
@ -1820,7 +1823,7 @@ void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma
} }
// adjust damage based on material being damaged // adjust damage based on material being damaged
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat) { void adjustdammaterial(int *dam, enum DAMTYPE damtype, enum MATERIAL mat) {
// adjust based on material // adjust based on material
if (mat == MT_MAGIC) { if (mat == MT_MAGIC) {
switch (damtype) { switch (damtype) {
@ -1926,7 +1929,7 @@ void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma
} }
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype) { void adjustdamob(object_t *o, int *dam, enum DAMTYPE damtype) {
// objects can't get hurt the turn they // objects can't get hurt the turn they
// were created. // were created.
if (o->birthtime == curtime) { if (o->birthtime == curtime) {
@ -2410,6 +2413,7 @@ int checkcritprotection(lifeform_t *lf, object_t *o) {
if (pctchance(getcritprotection(o))) { if (pctchance(getcritprotection(o))) {
char obname[BUFLEN]; char obname[BUFLEN];
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
/*
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your %s protects you.", noprefix(obname)); msg("Your %s protects you.", noprefix(obname));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
@ -2417,6 +2421,7 @@ int checkcritprotection(lifeform_t *lf, object_t *o) {
getlfname(lf, lfname); getlfname(lf, lfname);
msg("%s%s %s protects it.", lfname, getpossessive(lfname), noprefix(obname)); msg("%s%s %s protects it.", lfname, getpossessive(lfname), noprefix(obname));
} }
*/
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -3260,6 +3265,8 @@ int getcharges(object_t *o) {
return amt; return amt;
} }
// return the base accuracy for the firearm 'wep', or for a throw if wep is null.
// (ie. the accuracy for a range of 0).
int getobaccuracy(object_t *wep, lifeform_t *weilder) { int getobaccuracy(object_t *wep, lifeform_t *weilder) {
int acc; int acc;
flag_t *f; flag_t *f;
@ -3282,25 +3289,6 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder) {
acc += (getobbonus(wep, B_FALSE)*10); acc += (getobbonus(wep, B_FALSE)*10);
if (weilder) {
enum SKILLLEVEL slev;
// modify for weilder's skill
slev = getweaponskill(weilder, wep);
if (hasflag(wep->flags, F_MASTERWORK)) {
if (slev < PR_ADEPT) slev++;
}
switch (slev) {
case PR_INEPT: acc -= 35; break;
case PR_NOVICE: acc -= 10; break;
case PR_BEGINNER: acc -= 5; break;
case PR_ADEPT: break;
case PR_SKILLED: acc += 10; break;
case PR_EXPERT: acc += 20; break;
case PR_MASTER: acc += 30; break;
}
}
} }
return acc; return acc;
} }
@ -5938,8 +5926,9 @@ int isbetterwepthan(object_t *a, object_t *b, lifeform_t *owner) {
msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb); msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
} }
dama = pctof(acca, dama); // add on the (acc/2)*damage to each one
damb = pctof(accb, damb); dama = dama + pctof(acca/2, dama);
damb = damb + pctof(accb/2, damb);
if (db) { if (db) {
msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb); msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
@ -7663,7 +7652,15 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
snprintf(buf, BUFLEN, "Load %s with what ammo",obname); snprintf(buf, BUFLEN, "Load %s with what ammo",obname);
oo = askobject(lf->pack, buf, NULL, AO_SPECIFIED); oo = askobject(lf->pack, buf, NULL, AO_SPECIFIED);
if (oo) { if (oo) {
loadfirearm(lf, o, oo); if (isammofor(oo->type, o)) {
loadfirearm(lf, o, oo);
} else {
if (isplayer(lf)) msg("That can't be used as ammo for %s.", obname);
return B_TRUE;
}
} else {
if (isplayer(lf)) msg("Cancelled.");
return B_TRUE;
} }
} }
} else if (o->type->obclass->id == OC_WAND) { } else if (o->type->obclass->id == OC_WAND) {
@ -8737,7 +8734,7 @@ void quaff(lifeform_t *lf, object_t *o) {
// o can be NULL if we're just doing potion EFFECTS, not actually drinking one. // o can be NULL if we're just doing potion EFFECTS, not actually drinking one.
void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE potblessed, int *seen) { void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE potblessed, int *seen) {
char lfname[BUFLEN]; char lfname[BUFLEN];
unsigned int dam; int dam;
int i; int i;
int first,dir; int first,dir;
int amt; int amt;
@ -10272,12 +10269,12 @@ object_t *splitob(object_t *o) {
return newob; return newob;
} }
// returns amount of damage taken // returns amount of damage taken
int takedamage(object_t *o, unsigned int howmuch, int damtype) { int takedamage(object_t *o, int howmuch, int damtype) {
return real_takedamage(o, howmuch, damtype, B_TRUE); return real_takedamage(o, howmuch, damtype, B_TRUE);
} }
// returns amount of damage taken // returns amount of damage taken
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce) { int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
char predamname[BUFLEN],postdamname[BUFLEN]; char predamname[BUFLEN],postdamname[BUFLEN];
char obname[BUFLEN]; char obname[BUFLEN];
flag_t *hpflag, *f; flag_t *hpflag, *f;
@ -10405,6 +10402,7 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
} }
adjustdamob(o, &howmuch, damtype); adjustdamob(o, &howmuch, damtype);
assert(howmuch < 1000);
// effects which have to happen before damage is applied... // effects which have to happen before damage is applied...
@ -10478,6 +10476,10 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
hpflag->val[0] -= howmuch; hpflag->val[0] -= howmuch;
} }
if (hpflag) {
assert(hpflag->val[0] <= hpflag->val[1]);
}
if (!hpflag || (hpflag->val[0] <= 0)) { if (!hpflag || (hpflag->val[0] <= 0)) {
// special cases.... // special cases....
if (damtype == DT_FIRE) { if (damtype == DT_FIRE) {
@ -10699,6 +10701,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
if (target && isdead(target)) { if (target && isdead(target)) {
target = NULL; target = NULL;
} }
if (thrower && target && !isprone(target) && !lfhasflag(target, F_CASTINGSPELL)) { if (thrower && target && !isprone(target) && !lfhasflag(target, F_CASTINGSPELL)) {
if (areallies(thrower, target) && !firearm) { if (areallies(thrower, target) && !firearm) {
willcatch = B_TRUE; willcatch = B_TRUE;
@ -10727,10 +10731,12 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
// announce it ("xx throws xx" "at yy") // announce it ("xx throws xx" "at yy")
if (thrower && isplayer(thrower)) { if (thrower && isplayer(thrower)) {
// player is throwing something // player is throwing something
if (target && !hasflag(o->flags, F_POWDER)) { if (!firearm) {
msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname); if (target && !hasflag(o->flags, F_POWDER)) {
} else { msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname);
msg("You %s %s.",throwverbpres, obname); } else {
msg("You %s %s.",throwverbpres, obname);
}
} }
} else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) { } else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) {
char throwstring[BUFLEN]; char throwstring[BUFLEN];
@ -10765,21 +10771,6 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
} }
// adjust destination location in case something is in the way.
haslof(srcloc, where, LOF_NEED, &newloc);
if (newloc) {
where = newloc;
target = where->lf;
if (target && isdead(target)) {
target = NULL;
}
if (target) {
getlfname(target, targetname);
}
}
//taketime(thrower, SPEED_THROW); //taketime(thrower, SPEED_THROW);
// some obejcts will die when thrown. // some obejcts will die when thrown.
@ -10825,7 +10816,21 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
if (radius > 10) radius = 10; if (radius > 10) radius = 10;
spellcloud(srcloc, radius, '}', C_MAGENTA, OT_S_SLEEP, radius, B_TRUE); spellcloud(srcloc, radius, '}', C_MAGENTA, OT_S_SLEEP, radius, B_TRUE);
} else if (o->type->id == OT_SALT) {
if (target && (getcelldist(srcloc, where) <= 1)) {
if (hasbp(target, BP_EYES) && !isblind(target) && !getequippedob(target->pack, BP_EYES)) {
if (cansee(player, target)) {
msg("%s irritates %s%s eyes!", obname, targetname, getpossessive(targetname));
}
// blind for 5-7 turns
addtempflag(target->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(5,10));
}
} else {
if (haslos(player, srcloc)) {
msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e");
if (!isknown(o)) makeknown(o->type->id);
}
}
} else { } else {
if (haslos(player, srcloc)) { if (haslos(player, srcloc)) {
msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e"); msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e");
@ -10848,6 +10853,20 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
} }
} }
// adjust destination location in case something is in the way.
haslof(srcloc, where, LOF_NEED, &newloc);
if (newloc) {
where = newloc;
target = where->lf;
if (target && isdead(target)) {
target = NULL;
}
if (target) {
getlfname(target, targetname);
}
}
// do throw animation // do throw animation
if (seen) { if (seen) {
glyph_t *gl; glyph_t *gl;
@ -10855,6 +10874,27 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
anim(srcloc, where, gl->ch, gl->colour); anim(srcloc, where, gl->ch, gl->colour);
} }
// reflection?
if ( target && lfhasflag(target, F_REFLECTION)) {
if (seen) {
glyph_t *gl;
gl = getglyph(o);
anim(where, srcloc, gl->ch, gl->colour);
msg("%s is reflected away from %s!", obname, targetname);
}
// adjust target
where = srcloc;
target = where->lf;
if (target && isdead(target)) {
target = NULL;
}
if (target) {
getlfname(target, targetname);
}
thrower = NULL;
}
// find out your chances of hitting // find out your chances of hitting
if (target) { if (target) {
if (thrower) { if (thrower) {
@ -10989,7 +11029,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
if (seen) { if (seen) {
if (isplayer(target)) { if (isplayer(target)) {
msg("You dodge %s.", obname); msg("You dodge %s.", obname);
} else { } else if (cansee(player, target)) {
msg("%s dodges %s.", targetname, obname); msg("%s dodges %s.", targetname, obname);
} }
announcedmiss = B_TRUE; announcedmiss = B_TRUE;
@ -11026,7 +11066,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
if (youhit) { if (youhit) {
if (willcatch) { if (willcatch) {
if (seen) { if (seen) {
msg("%s catch%s %s.", targetname, isplayer(target) ? "" : "es", obname); msg("^%c%s catch%s %s.", isplayer(target) ? 'g' : 'n',
targetname, isplayer(target) ? "" : "es", obname);
} }
moveob(o, target->pack, amt); moveob(o, target->pack, amt);
return B_FALSE; return B_FALSE;
@ -11048,8 +11089,21 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
throwdam = getthrowdam(o); throwdam = getthrowdam(o);
dam = (int)((float)throwdam * multiplier); dam = (int)((float)throwdam * multiplier);
// firearms at pointblank range? +50% damage
if (firearm) {
if ((getcelldist(srcloc, where) <= 1)) {
dam = pctof(150, dam);
}
// master marksman ?
if (thrower && (getskill(thrower, SK_RANGED) >= PR_MASTER)) {
dam = pctof(150, dam);
}
}
// special case // special case
if (o->type->id == OT_RUBBERBULLET) { if (o->type->id == OT_RUBBERBULLET) {
dam = 1; dam = 1;
@ -11086,7 +11140,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
snprintf(damstring, BUFLEN, " [%d dmg]",dam); snprintf(damstring, BUFLEN, " [%d dmg]",dam);
strcat(buf2, damstring); strcat(buf2, damstring);
} }
msg("%s", buf2); msg("^b%s", buf2);
} }
snprintf(damstring, BUFLEN, "%s (%s by %s)",obname,throwverbpast, realthrowernamea); snprintf(damstring, BUFLEN, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
@ -11192,11 +11246,30 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
} }
} }
if (thrower && hasactivespell(thrower, OT_S_WHATGOESUP)) {
if (newob && !isdeadob(newob)) {
// on the ground?
if ((newob->pile->where == where) && haslof(newob->pile->where, thrower->cell, LOF_NEED, NULL)) {
if (isplayer(thrower)) {
msg("%s returns to you!", obname);
} else if (cansee(player, thrower)) {
msg("%s returns to %s!", obname, throwername);
} else if (haslos(player, newob->pile->where)) {
msg("%s returns to someone!", obname);
}
moveob(newob, thrower->pack, newob->amt);
}
}
}
/*
if (firearm && outofammo && isplayer(thrower)) { if (firearm && outofammo && isplayer(thrower)) {
char buf[BUFLEN]; char buf[BUFLEN];
getobname(firearm, buf, 1); getobname(firearm, buf, 1);
msg("Your %s is now out of ammo.", noprefix(buf)); msg("Your %s is now out of ammo.", noprefix(buf));
} }
*/
return B_FALSE; return B_FALSE;
} }
@ -12076,12 +12149,8 @@ int validateobs(void) {
printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name); printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name);
goterror = B_TRUE; 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)) { if (!hasflag(ot->flags, F_RELOADTURNS)) {
printf("ERROR in object '%s' - firearms need to have F_AMMOCAPACITY.\n", ot->name); printf("ERROR in object '%s' - firearms need to have F_RELOADTURNS.\n", ot->name);
goterror = B_TRUE; goterror = B_TRUE;
} }
@ -12385,10 +12454,73 @@ enum MATSTATE getmaterialstate(enum MATERIAL mat) {
} }
int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, flag_t *tkthrow) { int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, flag_t *tkthrow) {
int acc,maxrange,howfar; int acc,howfar,cellpenalty;
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
enum SKILL whichskill; enum SKILL whichskill;
enum ATTRIB whichatt; enum ATTRIB whichatt;
// base accuracy of 100% for hitting yourself
// then accuracy goes down for each cell based on skill + agility
if (tkthrow) {
whichatt = tkthrow->val[0];
whichskill = tkthrow->val[1];
} else {
whichatt = A_AGI;
if (firearm) {
whichskill = SK_RANGED;
} else {
whichskill = SK_THROWING;
}
}
// base accuracy to hit your own cell
// (firearm == null) means we are throwing.
acc = getobaccuracy(firearm, thrower);
// for each cell travelled, lower accuracy, based on skill.
slev = getskill(thrower, whichskill);
// masterwork firearms?
if (firearm && hasflag(firearm->flags, F_MASTERWORK)) {
if (slev < PR_ADEPT) slev++;
}
switch (slev) {
case PR_INEPT: cellpenalty = 32; break;
case PR_NOVICE: cellpenalty = 22; break;
case PR_BEGINNER: cellpenalty = 16; break;
case PR_ADEPT: cellpenalty = 12; break;
case PR_SKILLED: cellpenalty = 10; break;
case PR_EXPERT: cellpenalty = 8; break;
case PR_MASTER: cellpenalty = 6; break;
}
howfar = getcelldist(thrower->cell, where);
acc -= (cellpenalty*howfar);
if (whichatt != A_NONE) {
int mod;
mod = getstatmod(thrower, whichatt); // -50 to 50
mod /= 2; // -25 to +25
acc += mod;
}
// penalty for throwing non-missiles
if (missile && !firearm && !isthrowmissile(missile) && !tkthrow) {
acc -= 20;
}
// modify for prone throwers
if (isprone(thrower)) {
acc -= 50;
}
// modify for prone defenders
if (where->lf && isprone(where->lf)) {
acc -= 30;
}
limit(&acc, 0, NA);
/*
// figure out if you miss or not, based on distance and // figure out if you miss or not, based on distance and
// dexterity // dexterity
// base: // base:
@ -12463,6 +12595,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
acc -= 30; acc -= 30;
} }
limit(&acc, 0, NA); limit(&acc, 0, NA);
*/
return acc; return acc;
} }

View File

@ -18,9 +18,9 @@ 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); 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, enum LFSIZE size); objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid, enum LFSIZE size);
recipe_t *addrecipe(enum OBTYPE result, ...); recipe_t *addrecipe(enum OBTYPE result, ...);
void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat); void adjustdamhardness(int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat); void adjustdammaterial(int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype); void adjustdamob(object_t *o, int *dam, enum DAMTYPE damtype);
int adjustarmourpenalty(lifeform_t *lf, float amt); int adjustarmourpenalty(lifeform_t *lf, float amt);
int adjustshieldpenalty(lifeform_t *lf, float amt); int adjustshieldpenalty(lifeform_t *lf, float amt);
//void adjustprice(objecttype_t *ot, float *price ); //void adjustprice(objecttype_t *ot, float *price );
@ -247,8 +247,8 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
void shufflehiddennames(void); void shufflehiddennames(void);
int sizetonutrition(enum LFSIZE size); int sizetonutrition(enum LFSIZE size);
object_t *splitob(object_t *o); object_t *splitob(object_t *o);
int takedamage(object_t *o, unsigned int howmuch, int damtype); int takedamage(object_t *o, int howmuch, int damtype);
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce); int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce);
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm); int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
void timeeffectsob(object_t *o); void timeeffectsob(object_t *o);
//void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf); //void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf);

4
save.c
View File

@ -200,7 +200,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
fscanf(f, "int: %d/%d\n",&l->att[A_IQ],&l->baseatt[A_IQ]); fscanf(f, "int: %d/%d\n",&l->att[A_IQ],&l->baseatt[A_IQ]);
fscanf(f, "xp: %ld\n",&l->xp); fscanf(f, "xp: %ld\n",&l->xp);
fscanf(f, "skillxp: %ld\n",&l->skillxp); fscanf(f, "skillxp: %ld\n",&l->skillxp);
fscanf(f, "totskillxp: %ld\n",&l->totskillxp); fscanf(f, "totskillpoints: %ld\n",&l->totskillpoints);
fscanf(f, "skp: %d\n",&l->skillpoints); fscanf(f, "skp: %d\n",&l->skillpoints);
fscanf(f, "contr: %d\n",&l->controller); fscanf(f, "contr: %d\n",&l->controller);
fscanf(f, "hp: %d/%d\n",&l->hp, &l->maxhp); fscanf(f, "hp: %d/%d\n",&l->hp, &l->maxhp);
@ -790,7 +790,7 @@ int savelf(FILE *f, lifeform_t *l) {
fprintf(f, "int: %d/%d\n",l->att[A_IQ],l->baseatt[A_IQ]); fprintf(f, "int: %d/%d\n",l->att[A_IQ],l->baseatt[A_IQ]);
fprintf(f, "xp: %ld\n",l->xp); fprintf(f, "xp: %ld\n",l->xp);
fprintf(f, "skillxp: %ld\n",l->skillxp); fprintf(f, "skillxp: %ld\n",l->skillxp);
fprintf(f, "totskillxp: %ld\n",l->totskillxp); fprintf(f, "totskillpoints: %ld\n",l->totskillpoints);
fprintf(f, "skp: %d\n",l->skillpoints); fprintf(f, "skp: %d\n",l->skillpoints);
fprintf(f, "contr: %d\n",l->controller); fprintf(f, "contr: %d\n",l->controller);
fprintf(f, "hp: %d/%d\n",l->hp, l->maxhp); fprintf(f, "hp: %d/%d\n",l->hp, l->maxhp);

203
spell.c
View File

@ -580,16 +580,54 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
int i; int i;
cell_t fakecell; cell_t fakecell;
map_t fakemap; map_t fakemap;
createfakes(&fakemap, &fakecell); char obname[BUFLEN];
int donesomething = B_TRUE;
int ncooked = 0;
if (!isplayer(user)) { if (!isplayer(user)) return B_TRUE;
return B_TRUE;
}
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You can't cook while swimming!"); if (isplayer(user)) msg("You can't cook while swimming!");
return B_TRUE; return B_TRUE;
} }
while (donesomething) {
object_t *corpse = NULL;
donesomething = B_FALSE;
// anything here to cook?
for (o = user->cell->obpile->first ; o ; o = o->next) {
if (iscorpse(o) && !hasflag(o->flags, F_PREPARED)) {
char yn;
char ques[BUFLEN];
getobname(o, obname, o->amt);
sprintf(ques, "There %s %s here. Cook it?", (o->amt == 1) ? "is" : "are",obname);
yn = askchar(ques, "yn","n", B_TRUE, B_FALSE);
if (yn == 'y') {
corpse = o;
break;
}
}
}
if (corpse) {
preparecorpse(user, corpse);
donesomething = B_TRUE;
ncooked++;
corpse = NULL;
}
} // end while donesomething
if (ncooked) {
if (ncooked > 1) {
// takes longer
taketime(user, getactspeed(user) * (ncooked-1));
}
return B_FALSE;
}
// didn't cook anything from the ground?
// make recipes.
createfakes(&fakemap, &fakecell);
longdesc = malloc(HUGEBUFLEN * sizeof(char)); longdesc = malloc(HUGEBUFLEN * sizeof(char));
initprompt(&prompt, "What will you cook (ESC to cancel)?"); initprompt(&prompt, "What will you cook (ESC to cancel)?");
for (rec = firstrecipe ; rec ; rec = rec->next ) { for (rec = firstrecipe ; rec ; rec = rec->next ) {
@ -2164,57 +2202,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// this call will also remove this ability... // this call will also remove this ability...
setrace(user, f->val[0], B_TRUE); setrace(user, f->val[0], B_TRUE);
} else if (abilid == OT_A_PREPARECORPSE) {
object_t *o,*corpse = NULL;
char obname[BUFLEN];
int donesomething = B_TRUE;
int ncooked = 0;
if (!isplayer(user)) return B_TRUE;
while (donesomething) {
donesomething = B_FALSE;
// anything here to cook?
for (o = user->cell->obpile->first ; o ; o = o->next) {
if (iscorpse(o) && !hasflag(o->flags, F_PREPARED)) {
char yn;
char ques[BUFLEN];
getobname(o, obname, o->amt);
sprintf(ques, "There %s %s here. Prepare it?", (o->amt == 1) ? "is" : "are",obname);
yn = askchar(ques, "yn","n", B_TRUE, B_FALSE);
if (yn == 'y') {
corpse = o;
break;
}
}
}
if (corpse) {
preparecorpse(user, corpse);
donesomething = B_TRUE;
ncooked++;
corpse = NULL;
}
} // end while donesomething
// didn't cook anything from the ground?
// check inventory.
if (!ncooked) {
initprompt(&prompt, "What will you prepare (ESC to cancel)?");
for (o = user->pack->first ; o ; o = o->next) {
if (iscorpse(o) && !hasflag(o->flags, F_PREPARED)) {
getobname(o, obname, o->amt);
addchoice(&prompt, o->letter, obname, NULL, o, NULL);
}
}
addchoice(&prompt, '-', "(cancel)", NULL, NULL, NULL);
getchoice(&prompt);
corpse = (object_t *)prompt.result;
if (corpse) preparecorpse(user, corpse);
}
if (ncooked > 1) {
// takes longer
taketime(user, getactspeed(user) * (ncooked-1));
}
} else if (abilid == OT_A_PRAY) { } else if (abilid == OT_A_PRAY) {
lifeform_t *lf; lifeform_t *lf;
if (!isplayer(user)) return B_FALSE; if (!isplayer(user)) return B_FALSE;
@ -4608,6 +4595,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else if (spellid == OT_S_EQANDOP) {
flag_t *f;
f = addtempflag(caster->flags, F_REFLECTION, B_TRUE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (spellid == OT_S_EVAPORATE) { } else if (spellid == OT_S_EVAPORATE) {
cell_t *cell[MAXCANDIDATES]; cell_t *cell[MAXCANDIDATES];
int i,ncells; int i,ncells;
@ -5924,24 +5916,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *o; object_t *o;
int donesomething = B_FALSE; int donesomething = B_FALSE;
// create icicle if (haslos(player, targcell)) {
o = addob(targcell->obpile, "huge icicle"); msg("A massive icicle rises from the ground!");
if (o) { if (seenbyplayer) *seenbyplayer = B_TRUE;
flag_t *f; }
if (haslos(player, targcell)) { // note: we don't actually create the icicle yet, because "getrandomadjcell" will fail
drawscreen(); // for cells which contain impassable objects (ie. the icicle).
msg("A massive icicle rises from the ground!");
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
f = hasflag(o->flags, F_OBHP);
if (f) {
f->val[0] = 3+power;
f->val[1] = 3+power;
}
addflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL);
donesomething = B_TRUE;
}
// knock lfs away // knock lfs away
if (targcell->lf) { if (targcell->lf) {
@ -5957,11 +5938,29 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
msg("%s is impaled by an icicle!", lfname); msg("%s is impaled by an icicle!", lfname);
} }
losehp(targcell->lf, roll("3d6"), DT_PIERCE, caster, "impalement on an icicle"); losehp(targcell->lf, rolldie(3,power), DT_PIERCE, caster, "impalement on an icicle");
} }
donesomething = B_TRUE; donesomething = B_TRUE;
} }
// NOW create the icicle
o = addob(targcell->obpile, "huge icicle");
if (o) {
flag_t *f;
f = hasflag(o->flags, F_OBHP);
if (f) {
f->val[0] = 3+power;
f->val[1] = 3+power;
}
addflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL);
donesomething = B_TRUE;
} else {
if (haslos(player, targcell)) {
msg("The icicle vanishes.");
}
}
if (!donesomething) { if (!donesomething) {
fizzle(caster); fizzle(caster);
return B_FALSE; return B_FALSE;
@ -6236,6 +6235,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
} }
} else if (spellid == OT_S_ACCELMETAL) { } else if (spellid == OT_S_ACCELMETAL) {
char oidbuf[BUFLEN];
flag_t *f;
if (!targob) { if (!targob) {
// ask for an object // ask for an object
targob = askobject(caster->pack, "Fire which object", NULL, AO_NONE); targob = askobject(caster->pack, "Fire which object", NULL, AO_NONE);
@ -6253,7 +6254,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
sprintf(oidbuf, "%ld", targob->id);
f = addflag(caster->flags, F_THROWING, B_TRUE, NA, NA, oidbuf);
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE;
killflagsofid(caster->flags, F_THROWING);
// 5 is the same as AT_VHIGH strength // 5 is the same as AT_VHIGH strength
// 10 = gun speed // 10 = gun speed
@ -8716,11 +8720,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// if no target cell, ask where to throw object // if no target cell, ask where to throw object
if (!targcell) { if (!targcell) {
char obname[BUFLEN],buf2[BUFLEN]; char obname[BUFLEN],buf2[BUFLEN];
char oidbuf[BUFLENSMALL];
getobname(targob, obname, 1); getobname(targob, obname, 1);
snprintf(buf, BUFLEN, "Where will you throw %s to?", obname); snprintf(buf, BUFLEN, "Where will you throw %s to?", obname);
// TODO: start trail from the object // TODO: start trail from the object
snprintf(buf2, BUFLEN, "Telekinesis->%s->",obname); snprintf(buf2, BUFLEN, "Telekinesis->%s->",obname);
sprintf(oidbuf, "%ld", targob->id);
addflag(caster->flags, F_THROWING, B_TRUE, NA, NA, oidbuf);
targcell = askcoords(buf, buf2,TT_MONSTER | TT_PLAYER, caster, UNLIMITED, LOF_DONTNEED, B_FALSE); targcell = askcoords(buf, buf2,TT_MONSTER | TT_PLAYER, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
killflagsofid(caster->flags, F_THROWING);
} }
// not liftable? // not liftable?
@ -9246,6 +9255,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} }
} else if (spellid == OT_S_WHATGOESUP) {
if (isplayer(caster)) {
msg("A positive gravity field forms around you!");
} else if (cansee(player, caster)) {
msg("A positive gravity field forms around %s!", castername);
}
if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (spellid == OT_S_WINDSHIELD) { } else if (spellid == OT_S_WINDSHIELD) {
flag_t *f; flag_t *f;
// always targetted at caster // always targetted at caster
@ -9737,6 +9753,45 @@ enum SKILL getschoolskill(enum SPELLSCHOOL ss) {
return SK_NONE; return SK_NONE;
} }
// returns the spellschool associated with the given skill
enum SPELLSCHOOL getskillschool(enum SKILL skid) {
switch (skid) {
case SK_SS_ALLOMANCY:
return SS_ALLOMANCY;
case SK_SS_AIR:
return SS_AIR;
case SK_SS_DEATH:
return SS_DEATH;
case SK_SS_DIVINATION:
return SS_DIVINATION;
case SK_SS_ENCHANTMENT:
return SS_ENCHANTMENT;
case SK_SS_NATURE:
return SS_NATURE;
case SK_SS_FIRE:
return SS_FIRE;
case SK_SS_COLD:
return SS_COLD;
case SK_SS_GRAVITY:
return SS_GRAVITY;
case SK_SS_LIFE:
return SS_LIFE;
case SK_SS_MODIFICATION:
return SS_MODIFICATION;
case SK_SS_MENTAL:
return SS_MENTAL;
case SK_SS_SUMMONING:
return SS_SUMMONING;
case SK_SS_TRANSLOCATION:
return SS_TRANSLOCATION;
case SK_SS_WILD:
return SS_WILD;
default:
break;
}
return SS_NONE;
}
// returns "x MP" or "x-y MP", or "x-y MP, ongoing" ect // returns "x MP" or "x-y MP", or "x-y MP, ongoing" ect
char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf) { char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf) {
objecttype_t *ot; objecttype_t *ot;

View File

@ -16,6 +16,7 @@ enum OBTYPE getrandomspell(int maxlev);
enum OBTYPE getrandomspellfromschool(enum SPELLSCHOOL school, int wantlev); enum OBTYPE getrandomspellfromschool(enum SPELLSCHOOL school, int wantlev);
enum SPELLSCHOOL getrandomspellschool(void); enum SPELLSCHOOL getrandomspellschool(void);
enum SKILL getschoolskill(enum SPELLSCHOOL ss); enum SKILL getschoolskill(enum SPELLSCHOOL ss);
enum SPELLSCHOOL getskillschool(enum SKILL skid);
char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf); char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf);
int getspellduration(int min,int max,int blessed); int getspellduration(int min,int max,int blessed);
int getspelllevel(enum OBTYPE spellid); int getspelllevel(enum OBTYPE spellid);

79
text.c
View File

@ -102,6 +102,8 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
char withwep[BUFLEN]; char withwep[BUFLEN];
char *verb; char *verb;
int needfree = B_FALSE; int needfree = B_FALSE;
int knownnodam = B_FALSE;
int col;
strcpy(extradambuf, ""); strcpy(extradambuf, "");
@ -116,6 +118,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
if (!victim || getlorelevel(lf, victim->race->raceclass->id)) { if (!victim || getlorelevel(lf, victim->race->raceclass->id)) {
//strcpy(extradambuf, " but do no damage"); //strcpy(extradambuf, " but do no damage");
strcpy(extradambuf, " ineffectually"); strcpy(extradambuf, " ineffectually");
knownnodam = B_TRUE;
} }
} else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) { } else if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT) ) {
snprintf(extradambuf, BUFLEN, " [%d dmg]",dam); snprintf(extradambuf, BUFLEN, " [%d dmg]",dam);
@ -136,7 +139,14 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
verb = getattackverb(lf, wep, damtype, pctof(10, maxhp), maxhp); verb = getattackverb(lf, wep, damtype, pctof(10, maxhp), maxhp);
} }
} }
snprintf(retbuf, BUFLEN, "^%cYou %s%s %s%s%s%s", fatal ? 'g' : 'n', if (knownnodam) {
col = C_GREY;
} else if (fatal) {
col = C_GREEN;
} else {
col = C_BROWN; // normal hit
}
snprintf(retbuf, BUFLEN, "^%dYou %s%s %s%s%s%s", col,
usecrittext ? "critically " : "", verb, usecrittext ? "critically " : "", verb,
usecrittext ? victimbpname : victimname, withwep,extradambuf, usecrittext ? victimbpname : victimname, withwep,extradambuf,
(fatal || backstab) ? "!" : "."); (fatal || backstab) ? "!" : ".");
@ -150,6 +160,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
char attackverb[BUFLEN]; char attackverb[BUFLEN];
char nodamstr[BUFLEN]; char nodamstr[BUFLEN];
int nodam = B_FALSE; int nodam = B_FALSE;
int col;
// capitalise first letter // capitalise first letter
strcpy(buf, attackername); strcpy(buf, attackername);
@ -168,7 +179,13 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
} else { } else {
strcpy(nodamstr, ""); strcpy(nodamstr, "");
} }
snprintf(retbuf, BUFLEN, "^%c%s %s%s%s %s%s%s.", (victim && isplayer(victim) && !nodam) ? 'b' : 'n', buf,
if (victim && isplayer(victim) && !nodam) {
col = C_YELLOW;
} else {
col = C_GREY;
}
snprintf(retbuf, BUFLEN, "^%d%s %s%s%s %s%s%s.", col, buf,
usecrittext ? "critically " : "", attackverb, usecrittext ? "critically " : "", attackverb,
needses(attackverb) ? "es" : "s", needses(attackverb) ? "es" : "s",
usecrittext ? victimbpname : victimname,withwep, nodamstr); usecrittext ? victimbpname : victimname,withwep, nodamstr);
@ -907,6 +924,19 @@ char *getrarityname(enum RARITY rr) {
return "?unknownrarity?"; return "?unknownrarity?";
} }
char *getreldirname(int reldir) {
switch (reldir) {
case RD_FORWARDS:
return "forwards";
case RD_BACKWARDS:
return "backwards";
case RD_SIDEWAYS:
return "sideways";
default: break;
}
return "away";
}
char *getsizetext(enum LFSIZE sz) { char *getsizetext(enum LFSIZE sz) {
switch (sz) { switch (sz) {
case SZ_MAX: case SZ_MAX:
@ -1042,6 +1072,27 @@ int isvowel (char c) {
return B_FALSE; return B_FALSE;
} }
// return text for player's F_GUNTARGET flag eg. "goblin [acc:50%]"
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf) {
char accbuf[BUFLEN];
char targname[BUFLEN];
flag_t *f;
lifeform_t *targ;
targ = findlf(lf->cell->map, lfid);
if (!targ) {
strcpy(retbuf, "");
return;
}
getlfname(targ, targname);
f = addflag(lf->flags, F_THROWING, B_TRUE, NA, NA, NULL);
makethrowaccstring(lf, targ->cell, f, accbuf);
killflagsofid(lf->flags, F_THROWING);
sprintf(retbuf, "%s %s", noprefix(targname), accbuf);
}
char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra) { char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra) {
char *p, *dummy; char *p, *dummy;
p = strtok_r(lastdam,"^", &dummy); p = strtok_r(lastdam,"^", &dummy);
@ -1156,6 +1207,30 @@ char *makeplural(char *text) {
return newtext; return newtext;
} }
// throwflag should be either a F_THROWING or a F_FIRING flag.
char *makethrowaccstring(lifeform_t *lf, cell_t *c, flag_t *throwflag, char *retbuf) {
object_t *o = NULL, *gun = NULL;
int acc = 0;
strcpy(retbuf, "");
if (strlen(throwflag->text)) {
// get the object being thrown
o = findobbyid(lf->pack, atol(throwflag->text));
} else { // ie. firing a gun
gun = getfirearm(lf);
if (!gun) return NULL;
o = getammo(gun);
}
if (!o) return NULL;
acc = getmissileaccuracy(lf, c, o, gun, lfhasflag(player, F_TKTHROW)) ;
if (lfhasflag(lf, F_EXTRAINFO)) {
sprintf(retbuf, "^%d [acc:%d%%]^n", getpctcol(acc,100), acc);
} else {
sprintf(retbuf, "^%d [acc:%c]^n", getpctcol(acc,100), getpctletter(acc,100));
}
return retbuf;
}
char *makeuppercase(char *text) { char *makeuppercase(char *text) {
if (strlen(text) > 0) { if (strlen(text) > 0) {
char *p; char *p;

3
text.h
View File

@ -27,6 +27,7 @@ char *getinjuredbpname(enum BODYPART bp);
char *getinjuryname(enum DAMTYPE dt); char *getinjuryname(enum DAMTYPE dt);
char *getinjurydesc(enum BODYPART bp, enum DAMTYPE dt); char *getinjurydesc(enum BODYPART bp, enum DAMTYPE dt);
char *getrarityname(enum RARITY rr); char *getrarityname(enum RARITY rr);
char *getreldirname(int reldir);
char *getsizetext(enum LFSIZE sz); char *getsizetext(enum LFSIZE sz);
char *gettimetext(char *retbuf); char *gettimetext(char *retbuf);
char *gettimetextfuzzy(char *retbuf, int wantpm); char *gettimetextfuzzy(char *retbuf, int wantpm);
@ -34,8 +35,10 @@ char *getwaterdepthname(enum DEPTH d);
char *getweighttext(float weight, char *buf, int shortfmt); char *getweighttext(float weight, char *buf, int shortfmt);
char *is(lifeform_t *lf); char *is(lifeform_t *lf);
int isvowel(char c); int isvowel(char c);
void makegunaimstring(lifeform_t *lf, int lfid, char *retbuf);
char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra); char *makekillertext(char *retbuf, char *killverb, char *lastdam, int wantextra);
char *makeplural(char *text); char *makeplural(char *text);
char *makethrowaccstring(lifeform_t *lf, cell_t *c, flag_t *throwflag, char *retbuf);
char *makeuppercase(char *text); char *makeuppercase(char *text);
char *makewearstring(lifeform_t *lf, object_t *o, int wantyour, char *posbuf); char *makewearstring(lifeform_t *lf, object_t *o, int wantyour, char *posbuf);
char *makewearstringsingle(lifeform_t *lf, flag_t *f, char *yourbuf, char *posbuf); char *makewearstringsingle(lifeform_t *lf, flag_t *f, char *yourbuf, char *posbuf);