- [+] modifications to alchemy spell - affect stone, not metal

- [+] fire/cold spells:
    - [+] endure fire/cold
        - [+] L2
        - [+] ongoing
        - [+] like endure elements but only one element.
        - [+] fire - done
        - [+] cold - done
    - [+] negate fire/cold
        - [+] L3 ongoing
- [+] rename "gold coin" to "gold dollar"
- [+] announce mosnters losing interest.
- [+] if accuracy is too low, chance to fumble your atttack if you miss.
    - [+] ie. drop weapon 
- [+] show "please wait' message during initial build.
- [+] why can't i fill an empty flask from a potion of blood?
    - [+] because blood grew into a bigger one
- [+] CRASH - go to a shop, 'sell gems', pick a letter not in the list
- [+] The giant ant kills the kobold.  The kobold dies.
    - [+] never use "kills" when a monsters is killing another one.
- [+] implement CURSED scroll of wishing effects.
    - [+] stoning
    - [+] hostile summons
    - [+] insanity- drop iq prmenantly
    - [+] golden boulder
- [+] proximity mine (l3 tech)
    - [+] if activated, explodes when someone walks ONTO it (but not
          _off_ it)
    - [+] only gtaverage WIS _or_ adept tech knowledge won't walk onto
          it
- [+] rollerskates (wear on feet, move fast fowards)
- [+] jet skates (faster version of rollerskates)
    - [+] only work when ACTIVATED
    - [+] only work when they have CHARGES left
    - [+] drain charges when activated (like a jetpack)
- [+] cattle prod - piercing DR 1, +10 electical dam while it has
      charges
    - [+] f_extradamwithcharges
- [+] computers
    - [+] operable
    - [+] no pickup (or at least, VERY heavy)
    - [+] need tech usage to use.
    - [+] get choices equal to your tech level (novice = random)
    - [+] choices:
        - [+] 1 M = map whole level
        - [+] 2 O = show location of loot (detect objects)
        - [+] 3 L = show lifeforms
        - [+] 5 D = explode
        - [+] 6 I = identify one item.
        - [+] 7U - unlock all doors + chests
    - [+] at high techusage you can pick destruct time ?j:e sp
This commit is contained in:
Rob Pearce 2012-06-25 12:49:53 +00:00
parent 1de13a1904
commit ff6dba534e
13 changed files with 745 additions and 200 deletions

123
attack.c
View File

@ -46,6 +46,19 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
}
}
// if attacker is directly behind us, tortoiseshell is what was hit.
/*
if (attacker) {
if (getcellindir(lf->cell, diropposite(lf->facing)) == attacker->cell) {
object_t *o;
o = hasequippedob(lf->pack, OT_TORTOISESHELL);
if (o) {
armour = o;
}
}
}
*/
// figure out what bit of armour was hit
if (!armour) {
// pick a random piece of armour
@ -707,6 +720,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
flag_t *magicarm = NULL;
int hit = B_FALSE;
int critical = 0;
int fumble = B_FALSE;
char wepname[BUFLEN];
//int acc;
//int ev;
@ -850,7 +864,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// did you hit?
ndam = 0;
hit = rolltohit(lf, victim, wep, &critical);
hit = rolltohit(lf, victim, wep, &critical, &fumble);
if (critical && !lfhasflag(lf, F_PHANTASM)) {
object_t *armour;
@ -1313,7 +1327,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
}
//if ((isplayer(lf) || cansee(player, victim)) && !hasflag(victim->flags, F_NODEATHANNOUNCE)) {
if (isplayer(lf) && cansee(player, victim) && !hasflag(victim->flags, F_NODEATHANNOUNCE)) {
if (!hasflag(victim->flags, F_PHANTASM)) {
// don't also say "the xx dies"
@ -1518,14 +1531,31 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
// train evasion
// victim trains evasion
practice(victim, SK_EVASION, 1);
// chance to fumble attack.
if (fumble) {
if (wep && !isunarmed) {
if (isplayer(lf)) {
msg("^%cYou fumble your attack!", getlfcol(lf, CC_BAD));
} else if (cansee(player, lf)) {
msg("^%c%s fumbles its attack!", attackername, getlfcol(lf, CC_BAD));
}
drop(wep, ALL);
wep = NULL;
}
}
// chance that ai will give up if we can't reach the victim
if (!isplayer(lf) && !canreach(lf, victim, NULL)) {
if (pctchance(90)) {
// TODO: announce this.
// the xxx loses interest
loseaitargets(lf);
if (isplayer(victim) && cansee(player, lf)) {
msg("%s seems to have lost interest in you.", attackername);
}
}
}
}
@ -1576,8 +1606,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
}
if (fatal || waskod || dodged) {
if (fatal || waskod || dodged || fumble) {
// don't keep attacking if the victim is dead, or moved!
// also don't keep attacking if we fumbled.
return B_TRUE;
}
@ -1643,7 +1674,6 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
getextradamwep(wep, &dam[0], &damtype[0], &ndam, B_FALSE);
getextradamlf(lf, &dam[0], &damtype[0], &ndam, B_FALSE);
for (i = 0; i < ndam; i++) {
// announce the hit
construct_hit_string(lf, NULL, attackername, obname, NULL, wep, damtype[i], dam[i], maxhp, i, B_FALSE, B_FALSE, B_FALSE, isunarmed, buf);
@ -2357,7 +2387,7 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, in
return *dam;
}
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax) {
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int fordisplay) {
flag_t *f;
int i;
flag_t *retflag[MAXCANDIDATES];
@ -2365,19 +2395,43 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, in
lifeform_t *owner;
owner = wep->pile->owner;
if (owner && lfhasflag(owner, F_PHANTASM)) {
return *dam;
}
// weapons like cattle prod deal extra damage if they have charges left
f = hasflag(wep->flags, F_EXTRADAMWITHCHARGES);
if (f) {
int charges;
charges = getcharges(wep);
if (fordisplay && !chargesknown(wep)) {
// ie don't display the extra damage
charges = 0;
}
if (charges > 0) {
if (!fordisplay) {
// use up a charge
usecharge(wep);
}
// deal extra electric damage
*(dam + *ndam) = real_roll(f->text, fordisplay);
*(damtype + *ndam) = f->val[0];
(*ndam)++;
}
}
// enchanted weapons only deal magic damage if the user has remaining mp.
if (owner && owner->mp) {
f = hasflag(wep->flags, F_ENCHANTED);
if (f) {
if (strlen(f->text)) {
*(dam + *ndam) = real_roll(f->text, wantmax);
*(dam + *ndam) = real_roll(f->text, fordisplay);
} else {
*(dam + *ndam) = real_roll("1d2", wantmax); // default: 1d2 extra damage
*(dam + *ndam) = real_roll("1d2", fordisplay); // default: 1d2 extra damage
}
*(damtype + *ndam) = DT_MAGIC;
(*ndam)++;
@ -2397,13 +2451,13 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, in
// addition to the first one
damwhere = dam;
damtypewhere = damtype;
*(damwhere) += real_roll(f->text, wantmax); // addition
*(damwhere) += real_roll(f->text, fordisplay); // addition
} else {
// add a new damtype
damwhere = (dam + *ndam);
damtypewhere = (damtype + *ndam);
doinc = B_TRUE;
*(damwhere) = real_roll(f->text, wantmax); // set
*(damwhere) = real_roll(f->text, fordisplay); // set
*(damtypewhere) = f->val[0];
}
@ -2414,22 +2468,22 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, in
if (f->id == F_ONFIRE) {
if (strlen(f->text)) {
*(dam + *ndam) = real_roll(f->text, wantmax);
*(dam + *ndam) = real_roll(f->text, fordisplay);
} else {
*(dam + *ndam) = real_roll("1d4", wantmax);
*(dam + *ndam) = real_roll("1d4", fordisplay);
}
*(damtype + *ndam) = DT_FIRE;
(*ndam)++;
} else if (f->id == F_HOT) {
if (strlen(f->text)) {
*(dam + *ndam) = real_roll(f->text, wantmax);
*(dam + *ndam) = real_roll(f->text, fordisplay);
} else {
*(dam + *ndam) = real_roll("1d2", wantmax);
*(dam + *ndam) = real_roll("1d2", fordisplay);
}
*(damtype + *ndam) = DT_HEAT;
(*ndam)++;
} else if (f->id == F_FROZEN) {
*(dam + *ndam) = real_roll("1d4", wantmax);
*(dam + *ndam) = real_roll("1d4", fordisplay);
*(damtype + *ndam) = DT_COLD;
(*ndam)++;
}
@ -2646,14 +2700,15 @@ void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, en
}
// returns true if we hit. also sets 'critical' if passed
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) {
int acc,ev;
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, int *fumble) {
int acc,baseacc,ev;
int gothit = B_FALSE;
enum SKILLLEVEL lorelev = PR_INEPT;
flag_t *f;
// default
if (critical) *critical = 0;
if (fumble) *fumble = B_FALSE;
// anticipate action spell?
if (lfhasflagval(victim, F_ANTICIPATE, lf->id, NA, NA, NULL)) {
@ -2677,7 +2732,8 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
} else {
int reachpenalty = 0;
// actually roll...
acc = getlfaccuracy(lf, wep);
baseacc = getlfaccuracy(lf, wep);
acc = baseacc;
// size difference (penalty for attacking smaller ones)
modifyforsize(&acc, lf, victim, -5, M_VAL);
@ -2710,7 +2766,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
acc -= ev;
// modify if we can't see the victim
if (!cansee(lf, victim)) acc -= 50;
if (!cansee(lf, victim)) acc -= 30;
// metal weapon versus magnetic shield?
if (lfhasflag(victim, F_MAGSHIELD) && ismetal(wep->material->id)) acc -= 45;
// victim immobile or asleep?
@ -2721,12 +2777,12 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
// modify for attacking while climbing
if (isclimbing(lf) && !lfhasflag(lf, F_SPIDERCLIMB)) {
switch (getskill(lf, SK_CLIMBING)) {
case PR_INEPT: acc -= 100; break;
case PR_NOVICE: acc -= 100; break;
case PR_BEGINNER: acc -= 75; break;
case PR_ADEPT: acc -= 50; break;
case PR_SKILLED: acc -= 25; break;
case PR_EXPERT: acc -= 10; break;
case PR_INEPT: acc -= 50; break;
case PR_NOVICE: acc -= 50; break;
case PR_BEGINNER: acc -= 30; break;
case PR_ADEPT: acc -= 20; break;
case PR_SKILLED: acc -= 10; break;
case PR_EXPERT: acc -= 5; break;
default:
case PR_MASTER: break;
}
@ -2760,6 +2816,22 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
}
}
if (fumble && !gothit) {
if ((baseacc <= 60) || !getweaponskill(lf, wep)) {
int nfailed = 0, i;
int nrolls = 1;
// chance to fumble
// if you miss, make more attack rolls. if you fail
// all of them, you fumble..
for (i = 0; i < nrolls; i++) {
if (!pctchance(acc)) nfailed++;
}
if (nfailed >= nrolls) {
*fumble = B_TRUE;
}
}
}
return gothit;
}
@ -3008,5 +3080,6 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
}
}
}
}
}

View File

@ -17,7 +17,7 @@ void getarrange(int arating, int *min, int *max);
//object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
enum DAMTYPE getdamtype(object_t *wep);
int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax);
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int wantmax);
int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam, int fordisplay);
void getdamrange(object_t *o, flag_t *f, int *min, int *max);
//void getdamrange(object_t *o, int *min, int *max);
//void getdamrangeunarmed(flag_t *f, int *min, int *max);
@ -29,5 +29,5 @@ int getstrdammod(lifeform_t *lf);
int ismeleedam(enum DAMTYPE damtype);
int isphysicaldam(enum DAMTYPE damtype);
void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, enum MODTYPE how);
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical);
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, int *fumble);
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam);

215
data.c
View File

@ -296,7 +296,7 @@ void initjobs(void) {
// initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "short sword");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3 potions of healing");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "lockpick");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "nylon rope");
@ -306,7 +306,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL);
@ -323,7 +323,7 @@ void initjobs(void) {
// stat mods
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL);
// initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "1 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "club");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloak");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "potion of magic");
@ -616,7 +616,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of safety goggles");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "overalls");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cap");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "80 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "80 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "block of chocolate");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of oil");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rubber boots");
@ -702,7 +702,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
// initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "blessed ornamental sword");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "golden crown");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ornamental dagger");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "velvet robe");
@ -752,7 +752,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cloth trousers");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "eyepatch");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "tricorne");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "300-350 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "300-350 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 potions of rum");
// initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL);
@ -848,7 +848,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "suit of ring mail");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of gauntlets");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "buckler");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10-20 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10-20 gold dollars");
// initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_AXES, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_COOKING, PR_NOVICE, NA, NULL);
@ -1009,7 +1009,7 @@ void initjobs(void) {
addjob(J_SHOPKEEPER, "Shopkeeper", "Shopkeepers make a living by selling goods to others. Always wary of thieves, most of them keep a shotgun under the counter.");
addflag(lastjob->flags, F_NOPLAYER, B_TRUE, NA, NA, NULL);
addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100-1000 gold coins");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100-1000 gold dollars");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "shotgun");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5-10 bullets");
addflag(lastjob->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
@ -2131,7 +2131,7 @@ void initobjects(void) {
// money etc
addot(OT_GOLD, "gold coin", "Sparkling nuggets of gold, the standard currency of Nexus.", MT_GOLD, 0.01, OC_MONEY, SZ_MINI);
addot(OT_GOLD, "gold dollar", "Sparkling nuggets of gold, the standard currency of Nexus.", MT_GOLD, 0.01, OC_MONEY, SZ_MINI);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 100, NA, "");
@ -3023,10 +3023,11 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MPCOST, 0, NA, NA, NULL);
// l2
addot(OT_S_ALCHEMY, "alchemy", "Converts any metal item into (^bpower * 10^n)% of its value in gold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addot(OT_S_ALCHEMY, "alchemy", "Converts any stack of stone items into gold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how much stone is lost in the conversion.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL);
addot(OT_S_PULLMETAL, "pull metal", "Pulls metal objects to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -3591,34 +3592,50 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 2, NA, NULL);
addot(OT_S_ENDUREFIRE, "endure fire", "Provides resistance to fire.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, 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_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l3
addot(OT_S_NEGATEFIRE, "negate fire", "Renders the caster immune to the damaging effects of fire.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster, inflicting 2d6 fire damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The size of the radial blast is based on the spell's power.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 3, NA, NULL);
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level 5, the size of the fireball is slightly increased.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 3, NA, NULL);
// l4
addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the spell's range, and the fire's size.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 4, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 4, NA, NULL);
// l4
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level 5, the size of the fireball is slightly increased.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 3, NA, NULL);
addot(OT_S_QUICKENFIRE, "quicken fire", "Forms nearby fire into powerful fire primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level VI, stronger creatures will be created.");
@ -3682,6 +3699,14 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
// l2
addot(OT_S_ENDURECOLD, "endure cold", "Provides resistance to cold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, 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_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
@ -3714,6 +3739,14 @@ void initobjects(void) {
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
// l3
addot(OT_S_NEGATECOLD, "negate cold", "Renders the caster immune to the effects of cold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 3d6 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how difficult the ray is to dodge.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
@ -5247,6 +5280,13 @@ void initobjects(void) {
addflag(lastot->flags, F_HOLDCONFER, F_DTIMMUNE, DT_POISON, NA, NULL);
// tech - l0
addot(OT_COMPUTER, "computer", "A complex technological device. In theory it is usable by most but without the correct skill your mileage may vary...", MT_METAL, 500, OC_TECH, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_BLUE, '[', NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 2000, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_INEPT, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 1, 3, NA, NULL);
addot(OT_CREDITCARD, "credit card", "A rectangular plastic card.", MT_PLASTIC, 0.01, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 75, 500, NA, NULL);
@ -5264,6 +5304,16 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_PIERCE, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 50, NA, NA, NULL);
addot(OT_ROLLERSKATES, "pair of rollerskates", "Standard leather shoes mounted atop four small wheels. Increases your speed when moving forwards.", MT_LEATHER, 3, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 180, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 50, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 75, NA, NA, NULL);
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_VALUE, 75, NA, NA, NULL);
@ -5280,6 +5330,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addot(OT_POCKETWATCH, "pocket watch", "A portable timekeeping device made to be carried in a pocket.", MT_METAL, 0.1, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL);
addflag(lastot->flags, F_VALUE, 25, NA, NA, NULL);
@ -5397,6 +5448,19 @@ void initobjects(void) {
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addot(OT_CATTLEPROD, "cattle prod", "A stabbing device intended for animal control. When charged it deals powerful electric shocks upon contact.", MT_METAL, 4, OC_TECH, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, RR_UNCOMMON, NA, NULL);
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 1, NA, NULL);
addflag(lastot->flags, F_EXTRADAMWITHCHARGES, DT_ELECTRIC, NA, NA, "10");
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 5, 20, NA, NULL);
addot(OT_C4, "block of c4", "An extremely explosive plastic which explodes a medium time after activation.", MT_PLASTIC, 1, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 76, RR_UNCOMMON, NULL);
@ -5441,13 +5505,15 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, RR_UNCOMMON, NA, NULL);
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_HEAT, 6, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 1, NA, NULL);
addflag(lastot->flags, F_EXTRADAMWITHCHARGES, DT_HEAT, NA, NA, "6");
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 5, 20, NA, NULL);
addot(OT_STYPTIC, "styptic", "A medical compound designed to inhibit bleeding.", MT_METAL, 0.5, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_VALUE, 65, NA, NA, NULL);
@ -5478,6 +5544,20 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addot(OT_JETSKATES, "pair of jetskates", "Metal boots with built-in miniaturised jet boosters. Dramatically increases your speed when moving forwards.", MT_LEATHER, 3, OC_TECH, SZ_SMALL);
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 180, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 65, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 80, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RNDCHARGES, 10, 30, NA, NULL);
addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 78, RR_UNCOMMON, NULL);
@ -5491,6 +5571,21 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 150, NA, NA, NULL);
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
addot(OT_PROXMINE, "proximity mine", "An explosive charge which, once activated, is triggered by nearby motion.", MT_METAL, 2, OC_TECH, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 2, 2, NA, NULL);
addflag(lastot->flags, F_DONTSHOWCHARGES, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_EXPLODEONMOTION, NA, 1, B_IFACTIVATED, "16d2");
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
// tech - l4
addot(OT_JETPACK, "jet pack", "A portable ion-thruster which allows the wearer to fly.", MT_METAL, 10, OC_TECH, SZ_MEDIUM);
@ -6041,6 +6136,20 @@ void initobjects(void) {
addflag(lastot->flags, F_GROWSTO, OT_WOODENTABLE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL);
addot(OT_BOULDERGOLD, "gigantic golden boulder", "A massive boulder, seemingly made of solid gold.", MT_STONE, 800, OC_MISC, SZ_HUGE);
addflag(lastot->flags, F_GLYPH, C_YELLOW, '\'', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
// addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 800, 800, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "1000-2000 gold dollars");
addflag(lastot->flags, F_SHRINKSTO, OT_GOLD, VT_OB, NA, NULL);
// trail objects
addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC, SZ_MINI);
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
@ -8595,7 +8704,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STAYINROOM, NA, B_MAYCHASE, NA, NULL); // stay in our room, but we can chase targets out.
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold dollars");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great armour");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
@ -8997,7 +9106,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_WEAPON, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_ARMOUR, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_ARMOUR, NA, NULL);
@ -9313,7 +9422,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-100 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_WEAPON, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL);
@ -9348,7 +9457,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-100 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_WEAPON, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL);
@ -9378,7 +9487,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-2 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-2 gold dollars");
addflag(lastrace->flags, F_STARTOB, 25, OC_POTION, NA, "potion of rum");
addflag(lastrace->flags, F_STARTSKILL, SK_THIEVERY, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_RANDOMTALKPCT, 30, NA, NA, NULL);
@ -9400,10 +9509,10 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 0, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_STARTOB, 100, OC_POTION, NA, "1-5 potions of rum");
addflag(lastrace->flags, F_STARTOB, 70, OC_POTION, NA, "1-5 empty flasks");
addflag(lastrace->flags, F_STARTOB, 60, OC_POTION, NA, "1-2 gold coins");
addflag(lastrace->flags, F_STARTOB, 60, OC_POTION, NA, "1-2 gold dollars");
addflag(lastrace->flags, F_STARTJOB, 50, J_RANDOM, NA, NULL); // often unemployed
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts drunkenly^a drunken shout");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
@ -10109,7 +10218,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10-30 arrows");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "lance");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-20 gold coins");
addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-20 gold dollars");
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain");
addflag(lastrace->flags, F_MORALE, 9, NA, NA, NULL);
addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL);
@ -10547,7 +10656,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 10, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold dollars");
addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "1-2 boulders");
addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50");
@ -10588,7 +10697,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 13, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold dollars");
f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming greatsword");
addcondition(f, FC_NOCONDITION, 70);
addaltval(f, F_STARTOB, 100, NA, NA, "flaming longsword");
@ -10633,7 +10742,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 13, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold dollars");
f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "flaming morningstar");
addcondition(f, FC_NOCONDITION, 70);
addaltval(f, F_STARTOB, 100, NA, NA, "flaming mace");
@ -10696,7 +10805,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOBWEPSK, 50, SK_POLEARMS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-40 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-40 gold dollars");
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
@ -10733,7 +10842,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold dollars");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "sling");
f = addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_SHORTBLADES, NA, NULL);
addcondition(f, FC_NOCONDITION, 90);
@ -10868,7 +10977,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_POLEARMS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-5 javelins");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
@ -10905,7 +11014,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "hand crossbow");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "1-15 bolts");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold dollars");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
@ -10984,7 +11093,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great suit of ring mail");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great random armour");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great random armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "100-300 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "100-300 gold dollars");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
@ -11130,7 +11239,7 @@ void initrace(void) {
addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler");
addflag(lastrace->flags, F_STARTOBCLASS, 100, OC_ARMOUR, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
@ -11173,7 +11282,7 @@ void initrace(void) {
f = addflag(lastrace->flags, F_STARTOBWEPSK, 100, SK_CLUBS, NA, NULL);
addcondition(f, FC_NOCONDITION, 80);
addaltval(f, F_STARTOBWEPSK, 100, SK_WHIPS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-75 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-75 gold dollars");
addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "large shield");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "scale armour");
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_ARMOUR, NA, NULL);
@ -11261,7 +11370,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 33, NA, NA, "1-3 darts");
addflag(lastrace->flags, F_STARTOB, 10, NA, NA, "javelin");
addflag(lastrace->flags, F_STARTOB, 15, NA, NA, "buckler");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold dollars");
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL);
@ -11297,7 +11406,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_STARTOBWEPSK, 50, SK_CLUBS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold dollars");
addflag(lastrace->flags, F_DTVULN, DT_COLD, B_TRUE, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_FIRE, B_TRUE, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
@ -11326,7 +11435,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 1, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "shillelagh");
addflag(lastrace->flags, F_STARTOB, 10, NA, NA, "ring of luck");
addflag(lastrace->flags, F_STARTOB, 75, NA, NA, "50-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 75, NA, NA, "50-100 gold dollars");
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_BLINK, 5, 5, "pw:1;");
@ -11388,7 +11497,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TAIL, 4, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_STARTOBWEPSK, 50, SK_POLEARMS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-2 javelins");
addflag(lastrace->flags, F_DTVULN, DT_COLD, B_TRUE, NA, NULL);
@ -11550,7 +11659,7 @@ void initrace(void) {
addcondition(f, FC_NOCONDITION, 80);
addaltval(f, F_STARTOB, 100, NA, NA, "morningstar");
addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold dollars");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MINIONS, 50, 1, 5, "orc");
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
@ -11630,7 +11739,7 @@ void initrace(void) {
addcondition(f, FC_NOCONDITION, 80);
addaltval(f, F_STARTOB, 100, NA, NA, "club");
addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold dollars");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL);
@ -11668,7 +11777,7 @@ void initrace(void) {
addcondition(f, FC_NOCONDITION, 80);
addaltval(f, F_STARTOB, 100, NA, NA, "great club");
addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-100 gold dollars");
addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
@ -11705,7 +11814,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "leather armour");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "bone helmet");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
@ -11818,7 +11927,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "flak jacket");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "leather boots");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "football helmet");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-25 gold dollars");
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_TECH, 10, NULL);
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
@ -12316,7 +12425,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "panpipes");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "short bow");
addflag(lastrace->flags, F_STARTOB, 75, NA, NA, "1-10 arrows");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-30 gold coins");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-30 gold dollars");
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "plays its pipes");

Binary file not shown.

16
defs.h
View File

@ -1353,6 +1353,7 @@ enum OBTYPE {
OT_NONE,
// dungeon features
OT_BOULDER,
OT_BOULDERGOLD,
OT_GRATINGFLOOR,
OT_GRATINGROOF,
OT_ICICLE,
@ -1628,6 +1629,7 @@ enum OBTYPE {
OT_S_BURNINGWAVE,
OT_S_CLEANSINGFIRE,
OT_S_DANCINGFLAME,
OT_S_ENDUREFIRE,
OT_S_FIREDART,
OT_S_FIREBALL,
OT_S_FLAMEPILLAR,
@ -1635,6 +1637,7 @@ enum OBTYPE {
OT_S_GATHERFLAME,
OT_S_IMMOLATE,
OT_S_METEOR,
OT_S_NEGATEFIRE,
OT_S_PYROMANIA,
OT_S_QUICKENFIRE,
OT_S_SPARK,
@ -1647,11 +1650,13 @@ enum OBTYPE {
OT_S_COLDRAY,
OT_S_CRYSTALARM,
OT_S_CRYSTALSHIELD,
OT_S_ENDURECOLD,
OT_S_FREEZEOB,
OT_S_FROSTBITE,
OT_S_GLACIATE,
OT_S_ICECRUST,
OT_S_ICICLE,
OT_S_NEGATECOLD,
OT_S_SLIDE,
OT_S_SHARDSHOT,
OT_S_SNAPFREEZE,
@ -1903,8 +1908,10 @@ enum OBTYPE {
OT_TOWEL,
OT_UNICORNHORN,
// tech l0
OT_COMPUTER,
OT_CREDITCARD,
OT_PAPERCLIP,
OT_ROLLERSKATES,
OT_SLEEPINGBAG,
// tech l1
OT_BUTANETORCH,
@ -1915,6 +1922,7 @@ enum OBTYPE {
OT_SOLDERINGIRON,
// tech l2
OT_BATTERY,
OT_CATTLEPROD,
OT_C4,
OT_FLASHBANG,
OT_GRENADE,
@ -1928,8 +1936,10 @@ enum OBTYPE {
OT_TENT,
// tech l3
OT_INFOVISOR,
OT_JETSKATES,
OT_LOCKHACKER,
OT_PORTLADDER,
OT_PROXMINE,
// tech l4
OT_JETPACK,
// tech l5
@ -2603,6 +2613,10 @@ enum FLAG {
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
// val1 = explosion radius (dtorth)
// val2 = ifactivated, only explodes if activated.
F_EXPLODEONMOTION, // explodes when something walks onto it and
// deals TEXT damage.
// val1 = explosion radius (dtorth)
// val2 = ifactivated, only explodes if activated.
F_EXPLODEONDAM, // explodes when it is damaged, deals TEXT damage.
// v0 = damage type which makes it explode.
// NA means 'any damage type'
@ -3515,6 +3529,8 @@ enum FLAG {
// when they hit
// if v1 is TRUE, also deal extra damage based on
// the flagpile's F_BONUS flag.
F_EXTRADAMWITHCHARGES, // if this objects has charges remaining,
// deal an extra "text" damage of type v0.
F_EXTRAINFO, // knows extra info
F_EXTRALUCK, // lf gets +v0 to all skill checks!
// higher chance of rare objects

81
io.c
View File

@ -3294,8 +3294,16 @@ object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, in
if (useobletters) {
o = findobl(op, ch);
} else {
o = NULL;
for (i = firstob ; (mylist[i] != NULL) && (y < lastline); i++) {
}
o = NULL;
for (i = firstob ; (mylist[i] != NULL) && (y < lastline); i++) {
if (useobletters) {
if (mylist[i]->letter == ch) {
o = mylist[i];
break;
}
} else {
if (myletters[i] == ch) {
o = mylist[i];
break;
@ -5941,6 +5949,14 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf,"@It also inflicts %s extra magical damage if the user has spare mana.\n", strlen(f->text) ? f->text : "1-2");
strncat(retbuf, buf, HUGEBUFLEN);
}
if (chargesknown(o)) {
getflags(o->flags, retflag, &nretflags, F_EXTRADAMWITHCHARGES, F_NONE);
for (i = 0 ; i < nretflags; i++) {
f = retflag[i];
sprintf(buf,"@It also inflicts %s extra %s damage while charged.\n", f->text, getdamname(f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN);
}
}
getflags(o->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
for (i = 0 ; i < nretflags; i++) {
f = retflag[i];
@ -6340,38 +6356,41 @@ char *makedesc_ob(object_t *o, char *retbuf) {
} // end if isknown
// charges remaining
if ((o->type->obclass->id == OC_WAND) || (o->type->id == OT_BATTERY)) {
if (isidentified(o) || chargesknown(o)) {
int charges;
charges = getcharges(o);
if (charges) {
sprintf(buf, "It has %d charge%s left.\n",charges, (charges == 1) ? "" : "s");
} else {
sprintf(buf, "It has no charges left.\n");
//if ((o->type->obclass->id == OC_WAND) || (o->type->id == OT_BATTERY)) {
if (!hasflag(o->flags, F_DONTSHOWCHARGES)) {
if (o->type->obclass->id == OC_GODSTONE) {
if (isidentified(o)) {
int charges,max;
getchargeinfo(o, &charges, &max);
if (charges == max) {
sprintf(buf, "It is fully charged.\n");
} else {
sprintf(buf, "It is depleted.\n");
}
strncat(retbuf, buf, HUGEBUFLEN);
}
strncat(retbuf, buf, HUGEBUFLEN);
}
} else if (o->type->obclass->id == OC_GODSTONE) {
if (isidentified(o)) {
int charges,max;
getchargeinfo(o, &charges, &max);
if (charges == max) {
sprintf(buf, "It is fully charged.\n");
} else {
sprintf(buf, "It is depleted.\n");
} else if (o->type->id == OT_CREDITCARD) {
if (isidentified(o)) {
int charges;
charges = getcharges(o);
if (charges) {
sprintf(buf, "It has $%d remaining until its limit.\n",charges);
} else {
sprintf(buf, "It is maxed out.\n");
}
strncat(retbuf, buf, HUGEBUFLEN);
}
strncat(retbuf, buf, HUGEBUFLEN);
}
} else if (o->type->id == OT_CREDITCARD) {
if (isidentified(o)) {
int charges;
charges = getcharges(o);
if (charges) {
sprintf(buf, "It has $%d remaining until its limit.\n",charges);
} else {
sprintf(buf, "It is maxed out.\n");
} else if ((o->type->obclass->id == OC_WAND) || hasflag(o->flags, F_CHARGES)) {
if (isidentified(o) || chargesknown(o)) {
int charges;
charges = getcharges(o);
if (charges) {
sprintf(buf, "It has %d charge%s left.\n",charges, (charges == 1) ? "" : "s");
} else {
sprintf(buf, "It has no charges left.\n");
}
strncat(retbuf, buf, HUGEBUFLEN);
}
strncat(retbuf, buf, HUGEBUFLEN);
}
}

8
lf.c
View File

@ -4971,7 +4971,7 @@ void enhanceskills(lifeform_t *lf) {
if (i == 0) {
sprintf(ques, "Increase your %s", getattrname(poss[i]));
} else if (i == (nposs-1)) {
strcat(ques, "or ");
strcat(ques, " or ");
strcat(ques, getattrname(poss[i]));
strcat(ques, "?");
} else {
@ -7823,6 +7823,7 @@ int getleftrightwalls(lifeform_t *lf) {
return walls;
}
// returns lf's accuracy, as a percentage.
int getlfaccuracy(lifeform_t *lf, object_t *wep) {
flag_t *f;
object_t *o;
@ -10870,7 +10871,7 @@ int givemoney(lifeform_t *from, lifeform_t *to, int amt) {
object_t *togold;
togold = hasob(to->pack, OT_GOLD);
if (!togold) {
togold = addob(to->pack, "gold coin");
togold = addob(to->pack, "gold dollar");
amt--;
}
togold += amt;
@ -18410,6 +18411,9 @@ void setattr(lifeform_t *lf, enum ATTRIB attr, int val) {
if (lf->att[attr] > lf->baseatt[attr]) {
lf->baseatt[attr] = lf->att[attr];
}
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
statdirty = B_TRUE;
}
}
void setbodypartname(race_t *r, enum BODYPART bp, char *name) {

54
move.c
View File

@ -277,7 +277,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
if (!onlyifknown) {
include_nonobvious = B_TRUE;
} else {
if ((wis >= AT_AVERAGE) && haslos(lf, cell)) {
if (haslos(lf, cell)) {
if (!lfhasflag(lf, F_UNDEAD)) {
include_nonobvious = B_TRUE;
}
@ -294,7 +294,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
}
return B_TRUE;
}
} if (wis >= AT_AVERAGE) {
} else if (wis >= AT_AVERAGE) {
// don't walk on sharp objects without boots
if (hasflag(o->flags, F_SHARP)) {
if (!getequippedob(lf->pack, BP_FEET)) {
@ -306,6 +306,31 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
}
}
}
// other checks - ie ones where the condition for knowing
// about the danger is based on more than just wisdom.
// avoid active landmines
f = hasflag(o->flags, F_EXPLODEONMOTION);
if (f) {
if ((wis >= AT_GTAVERAGE) || (getskill(lf, SK_TECHUSAGE) >= gettechlevel(o->type->id))) {
int avoidit = B_FALSE;
if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) {
avoidit = B_TRUE;
}
} else {
avoidit = B_TRUE;
}
if (avoidit) {
if (error) {
*error = E_AVOIDOB;
rdata = o;
}
return B_TRUE;
}
}
}
}
}
return B_FALSE;
@ -1452,6 +1477,20 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
msg("%s grab%s %s!",obname, OBS1(o), lfname);
}
}
// objects which explode when you walk onto them
f = hasflag(o->flags, F_EXPLODEONMOTION);
if (f) {
if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) {
explodeob(o, f, f->val[1]);
break; // stop processing other objects, the explosion may have killed them.
}
} else {
explodeob(o, f, f->val[1]);
break; // stop processing other objects, the explosion may have killed them.
}
}
} // end foreach object in cell
} // end if !flying
@ -2961,6 +3000,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
if (onpurpose) {
// strafing sideways/backwards takes longer
if (strafe && !lfhasflag(lf, F_AWARENESS)) {
object_t *o;
switch (reldir) {
//case RD_SIDEWAYS: howlong = pctof(125, howlong); break;
case RD_SIDEWAYS: break;
@ -2974,10 +3014,16 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
}
break;
case RD_FORWARDS:
if (hasactivespell(lf, OT_S_TAILWIND)) {
// 50% faster
if (hasactivespell(lf, OT_S_TAILWIND) ||
hasequippedobid(lf->pack, OT_ROLLERSKATES)) {
// 50% faster if moving forwards
howlong = pctof(50, howlong);
}
o = hasequippedobid(lf->pack, OT_JETSKATES);
if (o && isactivated(o) && (getcharges(o) > 0)) {
// super fast if moving forwards
howlong = pctof(10, howlong);
}
break;
default:
break;

View File

@ -274,6 +274,8 @@ int main(int argc, char **argv) {
}
}
msg("Digging the dungeon...");
// add player in fake cell
createfakes(&fakemap, &fakecell);
real_addlf(&fakecell, startrace->id, 1, C_PLAYER); // this will assign 'player'
@ -290,6 +292,7 @@ int main(int argc, char **argv) {
assert(wregion);
surfmap = addmap();
createmap(firstmap, 1, wregion, NULL, D_NONE, NULL);
msg(".");
// create realm of gods - must do this first, so that
// gods get created because any temples.
@ -297,12 +300,14 @@ int main(int argc, char **argv) {
assert(hregion);
heaven = addmap();
createmap(heaven, 1, hregion, NULL, D_NONE, NULL);
msg("^n.");
// create main dungeon
dregion = findregionbytype(BH_MAINDUNGEON);
assert(dregion);
dmap = addmap();
createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL);
msg("^n.");
// add player in the starting position
@ -492,6 +497,7 @@ int main(int argc, char **argv) {
// show level
drawscreen();
clearmsg();
msg("%s",welcomemsg);
more();

190
objects.c
View File

@ -9596,6 +9596,152 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (!seen) {
noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL);
}
} else if (o->type->id == OT_COMPUTER) {
if (isplayer(lf)) {
enum SKILLLEVEL slev;
char allchoices[BUFLEN],ch;
int i;
strcpy(allchoices, "moldip");
slev = getskill(lf, SK_TECHUSAGE);
if (slev >= PR_ADEPT) {
msg("You input a login sequence to %s.", obname);
} else {
msg("You poke a few random buttons on %s.",obname);
}
if (getcharges(o) <= 0) {
nothinghappens();
} else {
more();
// populate choices...
initprompt(&prompt, "WELCOME TO NXS-OS v8.44. ENTER COMMAND CODE:");
for (i = 0;i < slev; i++) {
int idx;
char *p,cmdtext[BUFLEN];
// pick one
idx = rnd(0,strlen(allchoices)-1);
ch = allchoices[idx];
// remove it from the list
for (p = allchoices + idx; *(p) ; p++) {
*p = *(p+1);
}
// add it to the prompt
switch (ch) {
case 'm': strcpy(cmdtext, "MAP AREA"); break;
case 'o': strcpy(cmdtext, "OBJECT SCAN"); break;
case 'l': strcpy(cmdtext, "LIFEFORM SCAN"); break;
case 'd': strcpy(cmdtext, "DESTRUCTIVE SANITISATION FUNCTION"); break;
case 'i': strcpy(cmdtext, "IDENTIFICATION ROUTINE"); break;
case 'p': strcpy(cmdtext, "PHYSICAL SECURITY BYPASS"); break;
default: strcpy(cmdtext, "UNKNOWN COMMAND"); break;
}
addchoice(&prompt, ch, cmdtext, NULL, NULL, NULL);
}
ch = '\0';
if (prompt.nchoices == 0) {
msg("Nothing seems to happen.");
} else if (prompt.nchoices == 1) {
// it just happens.
ch = prompt.choice[0].ch;
} else {
// you can pick one
addchoice(&prompt, '-', "LOGOUT", NULL, NULL, NULL);
prompt.maycancel = B_TRUE;
ch = getchoice(&prompt);
}
if ((ch == '\0') || (ch == '-')) {
msg("You log off %s.", obname);
} else {
int n,x,y;
switch (ch) {
case 'm':
dospelleffects(NULL, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, o);
dospelleffects(NULL, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE, o);
msg("\"AREA MAPPING COMPLETE.\"");
break;
case 'o':
// locate all objects on the level
for (y = 0; y < lf->cell->map->h; y++) {
for (x = 0; x < lf->cell->map->w; x++) {
cell_t *c;
c = getcellat(lf->cell->map, x, y);
if (c && countnoncosmeticobs(c->obpile, B_FALSE, B_FALSE)) {
setcellknown(c, PR_MASTER);
}
}
}
setlosdirty(lf);
msg("\"OBJECT SCAN COMPLETE.\"");
break;
case 'l':
// locate all objects on the level
for (y = 0; y < lf->cell->map->h; y++) {
for (x = 0; x < lf->cell->map->w; x++) {
cell_t *c;
c = getcellat(lf->cell->map, x, y);
if (c && c->lf) {
c->known = B_TRUE;
c->knownglyph = *(getlfglyph(c->lf));
}
}
}
setlosdirty(lf);
msg("\"LIFEFORM SCAN COMPLETE.\"");
break;
case 'd':
if (slev >= PR_ADEPT) {
char ch2;
ch2 = askchar("SET DELAY TIMER (0-9):", "0123456789", "3", B_FALSE, B_FALSE);
// ie. typing '0' sets a value of 1.
// ie. typing '9' sets a value of 10.
n = (ch2 - '0')+1;
} else {
n = rnd(2,6);
}
msg("\"DESTRUCTIVE SANITISATION INITIATED. PLEASE VACATE AREA.\"");
addflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(o->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(o->flags, F_EXPLODEONDEATH, NA, 1, NA, "10d2");
addflag(o->flags, F_OBHP, n, n, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, SV_TALK, NA, "something sparking.");
break;
case 'i':
msg("\"SCAN & IDENTIFY ROUTINE INITIATED.\"");
more();
dospelleffects(NULL, OT_S_IDENTIFY, 10, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE, o);
break;
case 'p':
// unlock everything on the level
for (y = 0; y < lf->cell->map->h; y++) {
for (x = 0; x < lf->cell->map->w; x++) {
cell_t *c;
c = getcellat(lf->cell->map, x, y);
if (c) {
object_t *oo;
for (oo = c->obpile->first ;oo ; oo = oo->next) {
if (killflagsofid(oo->flags, F_LOCKED)) {
noise(c, NULL, NC_OTHER, SV_TALK, "a loud 'click'.", NULL);
}
}
}
}
}
msg("\"PHYSICAL SECURITY BYPASS COMPLETE.\"");
break;
default:
msg("\"not implemented yet.\"");
break;
}
// chance of computer turning off...
if (usecharge(o) == 0) {
msg("\"ALERT - UNAUTHORISED ACCESS. SHUTTING DOWN.\"");
}
}
} // end if has charges
} else {
return B_TRUE;
}
} else if (o->type->obclass->id == OC_GODSTONE) {
if (isfullycharged(o)) {
int i;
@ -11344,7 +11490,10 @@ int readsomething(lifeform_t *lf, object_t *o) {
} else {
makeknown(o->type->id);
}
o->blessknown = B_TRUE;
// don't show that scolls of wishing are cursed!
if (o->type->id != OT_SCR_WISH) {
o->blessknown = B_TRUE;
}
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
if (isplayer(lf)) {
// tell the player
@ -13751,6 +13900,7 @@ void timeeffectsob(object_t *o) {
int i;
flag_t *retflag[MAXCANDIDATES];
int nretflags = 0;
int onground = B_FALSE;
if (hasflag(o->flags, F_DEAD)) return;
@ -13764,6 +13914,10 @@ void timeeffectsob(object_t *o) {
owner = NULL;
}
if (o->pile->where) {
onground = B_TRUE;
}
checkflagpile(o->flags);
// special case for trail flags
@ -13797,6 +13951,7 @@ void timeeffectsob(object_t *o) {
newoid = f->val[1];
}
// some flags will be inherited by the new object
killflagsofid(o->flags, F_FILLPOT);
copyflag(fp, o->flags, F_FILLPOT);
removeob(o, o->amt);
for (i = 0; i < newamt; i++) {
@ -14090,6 +14245,31 @@ void timeeffectsob(object_t *o) {
// TODO: add smoke!
}
}
} else if (o->type->id == OT_JETSKATES) {
int chargeleft;
// use up power
chargeleft = usecharge(o);
// out of power?
if (chargeleft == -1) {
if (owner) {
// announce power loss
if (isplayer(owner)) {
msg("Your %s are out of power!",noprefix(obname));
// you know it's out
f = hasflag(o->flags, F_CHARGES);
f->known = B_TRUE;
}
}
turnoff(NULL, o);
} else if (chargeleft <= 10) { // about to run out of power?
if (isplayer(owner)) {
msg("Your %s splutter.", noprefix(obname));
}
// TODO: add smoke!
}
} else if (hasflag(o->flags, F_GRENADE)) {
flag_t *f2;
// countdown...
@ -14104,8 +14284,6 @@ void timeeffectsob(object_t *o) {
}
}
if (hasflag(o->flags, F_LIGHTSOURCE)) {
flag_t *f2,*mf;
// countdown...
@ -15249,9 +15427,9 @@ int chargesknown(object_t *o) {
case PR_MASTER: cutoff = 9999; break;
default: break;
}
}
if (f->val[0] <= cutoff) {
return B_TRUE;
if (f->val[0] <= cutoff) {
return B_TRUE;
}
}
return B_FALSE;
}

28
shops.c
View File

@ -35,7 +35,7 @@ extern WINDOW *mainwin;
// this function will adjust the object name to avoid objects which shouldn't appear in shops.
// returns TRUE if the name was modified.
int apply_shopob_restrictions(char *buf) {
if (strstr(buf, "gold coin")) {
if (strstr(buf, "gold dollar")) {
strcpy(buf, "potion of water");
return B_TRUE;
}
@ -621,7 +621,7 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex
if (skillcheck(player, SC_SPEECH, 20, 0)) {
char goldbuf[BUFLEN];
msg("\"...so I will return your payment.\""); more();
sprintf(goldbuf, "%d gold coins", cost);
sprintf(goldbuf, "%d gold dollars", cost);
addob(player->pack, goldbuf);
} else {
msg("\"Unfortunately, we do not offer refunds.\""); more();
@ -1242,13 +1242,6 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext
object_t *newob;
char let, paymentbuf[BUFLEN],obname[BUFLEN],buf[BUFLEN];
int sellprice;
// can we remove it?
if (isequipped(o)) {
if (takeoff(lf, o)) {
more();
return SR_CONTINUE;
}
}
// get matching sell flag
curflag = NULL;
@ -1258,7 +1251,20 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext
break;
}
}
assert(curflag);
if (!curflag) {
// you picked something impoassible
msg("We don't accept that kind of object.");
more();
return SR_CONTINUE;
}
// can we remove it?
if (isequipped(o)) {
if (takeoff(lf, o)) {
more();
return SR_CONTINUE;
}
}
// calculate sale price
sellprice = applyshoppricemod (
@ -1281,7 +1287,7 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext
newob->letter = let;
(*nsold)++;
// give money to player
sprintf(paymentbuf, "%d gold coins", sellprice);
sprintf(paymentbuf, "%d gold dollars", sellprice);
addob(player->pack, paymentbuf);
practice(player, SK_SPEECH, 1);

202
spell.c
View File

@ -3205,7 +3205,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// use empty handed attack accuracy
wep = getweapon(user);
if (rolltohit(user, target, wep, NULL)) {
if (rolltohit(user, target, wep, NULL, NULL)) {
// success!
failed = B_FALSE;
if (steal(user, target->pack, F_NONE)) {
@ -3796,11 +3796,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char obtocreate[BUFLEN];
obpile_t *op;
object_t *newob = NULL;
int obvalue,obamt;
int obamt;
float obweight;
float convrate, powerpct;
float obvalue;
// needs:
// object = which object to convert
if (!targob && isplayer(caster)) {
targob = doaskobject(caster->pack, "Convert which object to gold", NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_METAL, AO_NONE, F_NONE);
targob = doaskobject(caster->pack, "Convert which object to gold", NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_STONE, AO_NONE, F_NONE);
}
if (!targob) {
fizzle(caster);
@ -3809,9 +3812,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
op = targob->pile;
obamt = targob->amt;
getobname(targob, obname, targob->amt);
obvalue = getobvalue(targob);
obvalue = pctof(power*10, obvalue);
limit(&obvalue, 0, NA);
obweight = getobweight(targob);
// get conversion rate
powerpct = ((double)power / getspellmaxpower(spellid)) ;
convrate = (powerpct * (4.0 - 0.5)) + 0.5;
// determine value of gold
obvalue = convrate * obweight;
limitf(&obvalue, 0, NA);
// original object vanishes.
killob(targob);
// create new object
@ -3819,13 +3826,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (op->owner) {
newob = hasob(op, OT_GOLD);
if (newob) {
newob->amt += obvalue;
newob->amt += (int)obvalue;
} else {
sprintf(obtocreate, "%d gold coins", obvalue);
sprintf(obtocreate, "%d gold dollars", (int)obvalue);
newob = addob(op, obtocreate);
}
} else {
sprintf(obtocreate, "%d gold coins", obvalue);
sprintf(obtocreate, "%d gold dollars", (int)obvalue);
newob = addob(op, obtocreate);
}
}
@ -3835,7 +3842,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE;
if (newob) {
char newobname[BUFLEN];
msg("%s change%s into %d gold coin%s!", obname, (obamt == 1) ? "s" : "", obvalue, (obvalue == 1) ? "" : "s");
msg("%s change%s into %d gold dollar%s!", obname, (obamt == 1) ? "s" : "", (int)obvalue, ((int)obvalue == 1) ? "" : "s");
if (newob->pile->owner && isplayer(newob->pile->owner)) {
getobname(newob, newobname, newob->amt);
msgnocap("%c - %s", newob->letter, newobname);
@ -6720,6 +6727,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
// monsters can't id things!
}
} else if (spellid == OT_S_ENDURECOLD) {
flag_t *f;
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
f = addtempflag(caster->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_ENDUREELEMENTS) {
flag_t *f;
target = targcell->lf;
@ -6732,6 +6749,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->obfrom = spellid;
f = addtempflag(caster->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_ENDUREFIRE) {
flag_t *f;
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
f = addtempflag(caster->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_ENTANGLE) {
char targname[BUFLEN];
flag_t *f;
@ -7544,12 +7571,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_IDENTIFY) {
object_t *o;
if (!target) target = caster;
if (targob) {
o = targob;
} else {
// ask for an object
o = askobject(caster->pack, "Identify which object", "You have nothing which needs identifying.", NULL, '\0', AO_NOTIDENTIFIED);
o = askobject(target->pack, "Identify which object", "You have nothing which needs identifying.", NULL, '\0', AO_NOTIDENTIFIED);
}
if (!o) {
fizzle(caster);
@ -7590,7 +7618,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
getlfname(target, targname);
if (rolltohit(caster, target, NULL, NULL)) {
if (rolltohit(caster, target, NULL, NULL, NULL)) {
if (isplayer(caster) || cansee(player, caster)) {
construct_hit_string(caster, target, castername, targname, targname, NULL, DT_TOUCH, 0, target->maxhp,
0, B_FALSE, B_FALSE, B_FALSE, B_TRUE, buf);
@ -7735,7 +7763,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (c) {
if (range == UNLIMITED) {
setcellknown(c, MAXOF(PR_ADEPT, getskill(target, SK_CARTOGRAPHY)));
} else if (getcelldist(caster->cell, c) <= range) {
} else if (getcelldist(target->cell, c) <= range) {
setcellknown(c, MAXOF(PR_ADEPT, getskill(target, SK_CARTOGRAPHY)));
}
}
@ -7917,6 +7945,26 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s of %s appear%s!", copytext, castername, (ndone == 1) ? "s" : "");
}
} else if (spellid == OT_S_NEGATECOLD) {
flag_t *f;
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
f = addtempflag(caster->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_NEGATEFIRE) {
flag_t *f;
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
f = addtempflag(caster->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_NULLIFY) {
flag_t *retflag[MAXCANDIDATES],*poss[MAXCANDIDATES],*f;
int nretflags,i,ndone = 0,nposs;
@ -12434,6 +12482,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *o = NULL;
char obname[BUFLEN];
char ch;
int appearonground = B_FALSE;
if (!target) target = caster;
initprompt(&prompt, "For what do you wish?");
addchoice(&prompt, 'a', "Wealth", NULL, NULL, NULL);
@ -12458,8 +12507,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("^%cUh oh, you have a bad feeling about this...", getlfcol(target, CC_VBAD)); more();
}
if (ch == 'a') { // wealth (gold, bad: goldtouch)
snprintf(buf, BUFLEN, "1000-2000 gold coins");
if (ch == 'a') { // wealth (gold, bad: massive chunk of gold which you can't carry)
if (blessed == B_CURSED) {
snprintf(buf, BUFLEN, "gigantic golden boulder");
appearonground = B_TRUE;
} else {
snprintf(buf, BUFLEN, "1000-2000 gold dollars");
}
} else if (ch == 'b') { // power (weapons, bad: battery)
if (blessed == B_CURSED) {
snprintf(buf, BUFLEN, "battery");
@ -12503,41 +12557,45 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (ch == 'c') { // protection. bad: turn to stone
enum BODYPART bp,poss[MAXBODYPARTS];
int nposs = 0;
// get a list of all valid body parts
if (hasbp(target, BP_HEAD)) poss[nposs++] = BP_HEAD;
if (hasbp(target, BP_SHOULDERS)) poss[nposs++] = BP_SHOULDERS;
if (hasbp(target, BP_BODY)) poss[nposs++] = BP_BODY;
if (hasbp(target, BP_LEGS)) poss[nposs++] = BP_LEGS;
if (hasbp(target, BP_FEET)) poss[nposs++] = BP_FEET;
if (hasbp(target, BP_HANDS)) poss[nposs++] = BP_HANDS;
if (nposs) {
int narms = 0;
objecttype_t *ot;
// pick a random body part
bp = poss[rnd(0,nposs-1)];
// find all associated armour
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_ARMOUR) && hasflagval(ot->flags, F_GOESON, bp, NA, NA, NULL)) {
narms++;
}
}
if (narms) {
int sel,n = 0;
sel = rnd(0,narms-1);
if (blessed == B_CURSED) {
stone(caster);
} else {
// get a list of all valid body parts
if (hasbp(target, BP_HEAD)) poss[nposs++] = BP_HEAD;
if (hasbp(target, BP_SHOULDERS)) poss[nposs++] = BP_SHOULDERS;
if (hasbp(target, BP_BODY)) poss[nposs++] = BP_BODY;
if (hasbp(target, BP_LEGS)) poss[nposs++] = BP_LEGS;
if (hasbp(target, BP_FEET)) poss[nposs++] = BP_FEET;
if (hasbp(target, BP_HANDS)) poss[nposs++] = BP_HANDS;
if (nposs) {
int narms = 0;
objecttype_t *ot;
// pick a random body part
bp = poss[rnd(0,nposs-1)];
// find all associated armour
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_ARMOUR) && hasflagval(ot->flags, F_GOESON, bp, NA, NA, NULL)) {
if (n == sel) break;
n++;
narms++;
}
}
snprintf(buf, BUFLEN, "excellent branded %s", ot->name);
if (narms) {
int sel,n = 0;
sel = rnd(0,narms-1);
for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == OC_ARMOUR) && hasflagval(ot->flags, F_GOESON, bp, NA, NA, NULL)) {
if (n == sel) break;
n++;
}
}
snprintf(buf, BUFLEN, "excellent branded %s", ot->name);
} else {
snprintf(buf, BUFLEN, "sun hat");
}
} else {
snprintf(buf, BUFLEN, "sun hat");
}
} else {
stone(caster);
}
} else if (ch == 'd') { // fame (allies bad: useless allies or monsters)
} else if (ch == 'd') { // fame (allies bad: hostile lfs )
lifeform_t *lf;
cell_t *c;
job_t *j;
@ -12567,24 +12625,32 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// only possible for the player!
strcpy(buf, "");
if (isplayer(target)) {
knowledge_t *k;
msg("^GKnowledge floods into your mind!");
for (o = target->pack->first ; o ; o = o->next) {
if (!isidentified(o)) {
identify(o);
getobname(o, obname, o->amt);
msgnocap("%c - %s.", o->letter, obname);
if (blessed == B_CURSED) {
int newval;
msg("^%cYour sanity is blasted by a flood of alien knowledge!", getlfcol(caster, CC_VBAD));
newval = caster->att[A_IQ] - 25;
caster->baseatt[A_IQ] = newval;
setattr(caster, A_IQ, newval);
} else {
knowledge_t *k;
msg("^GKnowledge floods into your mind!");
for (o = target->pack->first ; o ; o = o->next) {
if (!isidentified(o)) {
identify(o);
getobname(o, obname, o->amt);
msgnocap("%c - %s.", o->letter, obname);
}
}
}
// now identify everything that you have tried,
// and 10% chance of identifying others
for (k = knowledge; k ; k = k->next) {
if ((k->known == B_TRIED) || pctchance(10)) {
makeknown(k->id);
// now identify everything that you have tried,
// and 10% chance of identifying others
for (k = knowledge; k ; k = k->next) {
if ((k->known == B_TRIED) || pctchance(10)) {
makeknown(k->id);
}
}
}
}
} else if (ch == 'f') { // magic (spellbooks)
} else if (ch == 'f') { // magic (spellbooks), bad: ???
objecttype_t *ot,*poss[MAXCANDIDATES];
int nposs = 0;
// find all castable spells (spellpower > 0)
@ -12632,10 +12698,26 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
if (strlen(buf)) {
// give the object
o = addob(target->pack, buf);
getobname(o, obname, o->amt);
msgnocap("%c - %s.", o->letter, obname);
if (appearonground) {
cell_t *where;
where = real_getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, target);
if (!where) {
where = target->cell;
}
o = addob(where->obpile, buf);
if (o) {
noise(caster->cell, NULL, NC_OTHER, SV_WHISPER, "something hitting the ground.", NULL);
if (haslos(player, where)) {
getobname(o, obname, o->amt);
msg("%s appear%s on the ground!", obname, (o->amt == 1) ? "s" : "");
}
}
} else {
// give the object
o = addob(target->pack, buf);
getobname(o, obname, o->amt);
msgnocap("%c - %s.", o->letter, obname);
}
}
// now age the caster

18
text.c
View File

@ -210,15 +210,18 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
}
verb = getattackverb(lf, wep, damtype,dam,maxhp);
// when the player is being attacked, we want:
// "the xxx hits you. you die."
// when a monster is attacking someone, we want:
// "the xxx hits yyy. yyy dies."
// rather than
// "the xxx kills you."
// "the xxx kills yyy."
/*
if (fatal && !isplayer(victim)) {
verb = getkillverb(victim, wep, damtype, dam, maxhp);
} else {
verb = getattackverb(lf, wep, damtype,dam,maxhp);
}
*/
verb = getattackverb(lf, wep, damtype,dam,maxhp);
strcpy(nodamstr, "");
if ((dam == 0) && (damtype != DT_TOUCH) && !lfhasflag(lf, F_PHANTASM)) {
@ -283,14 +286,17 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
} else { // normal
switch (damtype) {
case DT_COLD:
snprintf(retbuf, BUFLEN, "^n%s %s chilled!", locvictimname, is(victim));
snprintf(retbuf, BUFLEN, "^%c%s %s chilled!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
break;
case DT_ELECTRIC:
snprintf(retbuf, BUFLEN, "^%c%s %s zapped!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
break;
case DT_HEAT:
case DT_FIRE:
snprintf(retbuf, BUFLEN, "^n%s %s burned!", locvictimname, is(victim));
snprintf(retbuf, BUFLEN, "^%c%s %s burned!", getlfcol(victim, CC_BAD), locvictimname, is(victim));
break;
case DT_MAGIC:
snprintf(retbuf, BUFLEN, "^nMagical energy sears %s!", locvictimname);
snprintf(retbuf, BUFLEN, "^%cMagical energy sears %s!", getlfcol(victim, CC_BAD), locvictimname);
break;
default:
//snprintf(retbuf, BUFLEN, "^n%s %s hurt!", locvictimname, is(victim));