- [+] player start objects shouldn't get random brands like silver!

- [+] warn before moving/attacking with bleeding injury
    - [+] leg slash = hploss form move
    - [+] hand slash = hploss from attack

- [+] warn before walking onto pentagram with blessed gear
- [+] explosion should cause dt_explosion injuries?
    - [+] massive damage to whatever armour is there
    - [+] OR if no armour:
    - [+] limbs
        - [+] lose hand
    - [+] body
        - [+] collapsed lung (fitness = 0)k
        - [+] ribcrack (like bashing one)
    - [+] head
        - [+] ringing ears (can't hear anything for a long time)
        - [+] burnt eyes (blinded)
- [+] bug: not seeing fall msg during move (fell due to leg injury)
      need 'didmsg'
- [+] getrelativedir should always return FRONT when uou have
      f_awareness
- [+] bug: shouldn't try to leave trails when inside walls
- [+] announce when armour saves you from critical hits
- [+] F_DONELISTEN isn't working now - i'm getting multiple "you hear
      buzzing to the north".
    - [+] N_FLY needs to act the same as N_WALK (ie. be NC_MOVEMENT)
- [+] make validatespellcell() work on abilities
- [+] sonic bolt
- [+] mutated bat (sonar - damage)
- [+] merloch  (sonic scream - damage)
This commit is contained in:
Rob Pearce 2011-09-28 01:05:10 +00:00
parent 5cb8b05817
commit ad18cf2398
15 changed files with 248 additions and 57 deletions

View File

@ -60,6 +60,7 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
actualdam = dam;
/*
// adjust how much damage to do to armour
if ( ((armour->type->id == OT_FLAKJACKET) && (damtype == DT_PROJECTILE)) ||
(damtype == DT_ACID) ||
@ -77,6 +78,7 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
}
}
}
*/
// modify for rust
if (rust) {
@ -172,8 +174,16 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
int attackedfriend = B_FALSE;
int attackedpeaceful = B_FALSE;
// warn if attacking will cause injury
if (!force && isplayer(lf)) {
if (!confirm_injury_action(BP_HANDS, DT_SLASH, "attack")) {
return B_TRUE;
}
}
stoprunning(lf);
// anyone there? if so just attack.
if (c->lf) {
if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) {
@ -863,7 +873,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
adjustdamlf(victim, &dam[i], damtype[i]);
//dblog("adjusted for lf to dam[%d] = %d",i,dam[i]);
if (!backstab) {
// armour doesn't reduce damage for backstabs or critical hits.
// BUT in the case of a critical hit, the armour might get
// damaged during criticalhit()
if (!backstab && !critical) {
// modify for defender's armour
reduceamt = getarmourdamreduction(victim, wep, dam[i], damtype[i]);
@ -1119,7 +1132,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// critical hit effects
if (critical && damtypecausescriteffects(damtype[0])) {
criticalhit(lf, victim, critpos, damtype[0]);
criticalhit(lf, victim, critpos, dam[0], damtype[0]);
}
// confer flags from attacker?
@ -1414,7 +1427,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
}
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype) {
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) {
object_t *o,*armour;
char lfname[BUFLEN],victimname[BUFLEN],obname[BUFLEN];
// replace some dam types
@ -1457,6 +1470,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
takedamage(armour, dam, damtype);
} else {
injure(victim, BP_BODY, damtype);
}
@ -1487,6 +1501,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
takedamage(armour, dam, damtype);
}
} else {
injure(victim, BP_HEAD, damtype);
@ -1501,6 +1516,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
takedamage(armour, dam, damtype);
} else {
injure(victim, BP_HANDS, damtype);
}
@ -1521,6 +1537,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
takedamage(armour, dam, damtype);
} else {
injure(victim, BP_LEGS, damtype);
}
@ -1535,6 +1552,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum
getlfname(victim, victimname);
msg("%s%s %s protects it.", victimname, getpossessive(victimname), noprefix(obname));
}
takedamage(armour, dam, damtype);
} else {
injure(victim, hitpos, damtype);
}

View File

@ -6,7 +6,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force);
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
void confereffects(flagpile_t *fp, lifeform_t *victim);
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, enum DAMTYPE damtype);
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype);
int damtypecausesbleed(enum DAMTYPE dt);
int damtypecausescriteffects(enum DAMTYPE dt);
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);

82
data.c
View File

@ -512,7 +512,6 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "helmet");
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, "pair of metal boots");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "buckler");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10-20 gold coins");
// initial skills
@ -877,20 +876,13 @@ void initobjects(void) {
addmaterial(MT_STONE, "stone", 10);
addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BITE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_SILVER, "silver", 11);
addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL);
addmaterial(MT_METAL, "metal", 13);
addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_BITE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_GLASS, "glass", 13);
addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
@ -1155,7 +1147,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, "");
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "_");
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -2046,6 +2038,13 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_TAILWIND, "tailwind", "Propels the caster from behind, slightly speeding up movement when walking directly forwards.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, 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_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l3
addot(OT_S_AIRBLAST, "airblast", "Knocks enemies back with a powerful blast of air.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell's power determines how far objects or enemies will be knocked back.");
@ -2932,6 +2931,11 @@ void initobjects(void) {
addflag(lastot->flags, F_STAMCOST, 5, NA, NA, NULL);
addot(OT_A_REPAIR, "repair equipment", "Repair damage done to your equipment.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_SONICBOLT, "sonic bolt", "Emit a damaging burst of sound, targetted at a particular location.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
@ -6757,12 +6761,12 @@ void initrace(void) {
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
// fish
addrace(R_CRAB, "giant crab", 250, ';', C_ORANGE, MT_FLESH, RC_AQUATIC);
addrace(R_CRAB, "giant crab", 150, ';', C_ORANGE, MT_FLESH, RC_AQUATIC);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL); // very high armour
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+4");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4");
addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYSLOW, NA, NA, "");
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
@ -6780,6 +6784,35 @@ void initrace(void) {
addflag(lastrace->flags, F_NOARMOURON, BP_LEFTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL);
addrace(R_MERLOCH, "merloch", 250, 'm', C_ORANGE, MT_FLESH, RC_AQUATIC);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 15, NA, NA, NULL); // high armour
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4");
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, "");
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d3");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "2d3");
addflag(lastrace->flags, F_MAXATTACKS, 1, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_WAIST, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SONICBOLT, 5, 5, "pw:5;dam:2d6;");
addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "pincers");
addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw");
addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw");
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 2, NA, "^gurgling");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "gurgles loudly^a loud gurgle");
addflag(lastrace->flags, F_NOARMOURON, BP_RIGHTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_LEFTFINGER, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL);
addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC);
addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -6957,6 +6990,29 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addrace(R_BATMUTATED, "mutated bat", 3, 'B', C_MAGENTA, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, "");
addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2");
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3");
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SONICBOLT, 5, 5, "pw:5;dam:1d6;");
addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);

Binary file not shown.

14
defs.h
View File

@ -369,7 +369,7 @@ enum CASTTYPE {
enum NOISECLASS {
NC_NONE = 0,
NC_WALK = 1,
NC_MOVEMENT = 1,
NC_SPEECH = 2,
NC_OTHER = 3,
};
@ -678,9 +678,10 @@ enum DAMTYPE {
DT_PETRIFY = 23,
DT_POISON = 24,
DT_NECROTIC = 25,
DT_NONE = 26, // for direclty dealt damage, not really any type
DT_SONIC = 26,
DT_NONE = 27, // for direclty dealt damage, not really any type
};
#define MAXDAMTYPE 27
#define MAXDAMTYPE 28
// Object Classes
enum OBCLASS {
@ -822,6 +823,7 @@ enum RACE {
R_XAT,
// fish
R_CRAB,
R_MERLOCH,
R_PIRANHA,
R_PIRANHAKING,
R_EELELEC,
@ -835,6 +837,7 @@ enum RACE {
R_ANTS,
R_ANTLION,
R_BAT,
R_BATMUTATED,
R_BATVAMPIRE,
R_BEAR,
R_BEARCUB,
@ -1126,6 +1129,7 @@ enum OBTYPE {
OT_S_GUSTOFWIND,
OT_S_MIST,
OT_S_SHATTER,
OT_S_TAILWIND,
OT_S_WINDSHIELD,
// -- elemental - fire
OT_S_BLADEBURN,
@ -1277,6 +1281,7 @@ enum OBTYPE {
OT_A_PRAY,
OT_A_RAGE,
OT_A_REPAIR,
OT_A_SONICBOLT,
OT_A_SPRINT,
OT_A_STUDYSCROLL,
OT_A_STINGACID, // need to define dam in f_canwill
@ -1641,9 +1646,10 @@ enum NOISETYPE {
N_GETANGRY,
N_WALK,
N_FLY,
N_WARCRY,
N_LOWHP,
N_FRUSTRATED,
N_SONICBOLT,
N_WARCRY,
};
enum LFSIZE {

View File

@ -4,6 +4,10 @@ in defs.h:
in objcets.c:
update getdamname() - eg. you take 5 "electrical" damage
update getdamnamenoun() - eg. you are immune to "electricity"
update wepdullable() to say whether dealing this damtype to an object
will dull a weapon.
ie. hitting a door with DT_CHOP won't damage the weapon
ie. hitting a door with DT_SLASH _will_ damage the weapon
in attack.c
update isphysicaldam()
@ -11,9 +15,5 @@ in attack.c
update getattackverb if required
update getkillverb if required
update attackob() to say whether dealing this damtype to an object
will dull a weapon.
ie. hitting a door with DT_CHOP won't damage the weapon
ie. hitting a door with DT_SLASH _will_ damage the weapon

View File

@ -18,6 +18,7 @@ i = insect
j = jelly/ooze/leech
k = kobold
G = large goblin
m = mutant
n = small humanoid / nymph / sprite
o = orc
O = ogre

17
io.c
View File

@ -2343,6 +2343,23 @@ int confirm_badfeeling(object_t *o) {
return B_FALSE;
}
// returns true if the player wants to continue (or if there is no problem)
int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname) {
char ch;
char ques[BUFLEN];
if (lfhasflagval(player, F_INJURY, NA, bp, dt, NULL) &&
willbleedfrom(player, bp)) {
snprintf(ques, BUFLEN, "Your %s injury will cause damage if you %s - continue?",
getinjuredbpname(bp), actionname);
ch = askchar(ques, "yn","n", B_TRUE);
if (ch == 'n') {
return B_FALSE;
}
}
return B_TRUE;
}
lifeform_t *askgod(char *prompttext) {
lifeform_t *lf = NULL;
int i;

1
io.h
View File

@ -17,6 +17,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f);
int announceobflaggain(object_t *o, flag_t *f);
void announceobflagloss(object_t *o, flag_t *f);
int confirm_badfeeling(object_t *o);
int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname);
lifeform_t *askgod(char *prompt);
object_t *askobject(obpile_t *op, char *title, int *count, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag);

48
lf.c
View File

@ -700,10 +700,12 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
// can't hear if you have a hostile mosnter next to you
// and you're not blind.
// (you're too engrossed in the battle)
/*
celldist = getcelldist(lf->cell, dest);
if (isplayer(lf) && isinbattle(lf)) {
if (celldist != 1) return B_FALSE;
}
*/
map = dest->map;
@ -8737,7 +8739,7 @@ void killlf(lifeform_t *lf) {
int isdeaf(lifeform_t *lf) {
if (lfhasflag(lf, F_DEAF)) return B_TRUE;
if (lfhasflagval(lf, F_INJURY, IJ_EARSRINGING, NA, NA, NULL)) return B_TRUE;
return B_TRUE;
return B_FALSE;
}
// returns second weapon if you are dual weilding
@ -9375,6 +9377,11 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
return;
}
if ((damtype == DT_SONIC) && isdeaf(lf)) {
*amt = 0;
return;
}
if (lfhasflag(lf, F_INVULNERABLE)) {
switch (damtype) {
case DT_DIRECT:
@ -10480,7 +10487,7 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
if (nid == N_WALK) {
volume += getarmournoise(lf);
}
noise(lf->cell, lf, (nid == N_WALK) ? NC_WALK : NC_OTHER, volume, noisetext, verb);
noise(lf->cell, lf, noisetypetoclass(nid), volume, noisetext, verb);
} else {
// some defaults
if (nid == N_WALK) {
@ -10523,8 +10530,10 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
}
volume += getarmournoise(lf);
if (strlen(movetext)) {
noise(lf->cell, lf, (nid == N_WALK) ? NC_WALK : NC_OTHER, volume, movetext, NULL);
noise(lf->cell, lf, noisetypetoclass(nid), volume, movetext, NULL);
}
} else if (nid == N_SONICBOLT) {
noise(lf->cell, lf, NC_OTHER, 5, "a ear-splitting burst of sound!", "emits an ear-splitting burst of sound!");
} else if (nid == N_WARCRY) {
noise(lf->cell, lf, NC_OTHER, 4, "a blood-curdling war cry!", "shouts a blood-curdling war-cry!");
}
@ -10832,7 +10841,7 @@ int needstorest(lifeform_t *lf, char *validchars) {
}
// returns TRUE if the player heard it.
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext) {
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char *text, char *seetext) {
lifeform_t *l;
int sounddist;
int rv = B_FALSE;
@ -10861,7 +10870,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
dist = getcelldist(l->cell, c);
// listen check difficulty is based on sound distance vs max hearing distance
if ((nt == NC_SPEECH) && isplayer(l)) {
if ((nclass == NC_SPEECH) && isplayer(l)) {
// you always hear it, as long as you're in range
difficulty = 0;
} else {
@ -10902,7 +10911,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
msg("%s %s.", lfname, realseetext);
rv = B_TRUE;
}
} else if (text && !isdeaf(l) && ((nt != NC_WALK) || !lfhasflag(l, F_DONELISTEN))) {
} else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) {
// this means you can only hear one 'walk' sound per turn
char textnopunc[BUFLEN];
char punc;
@ -10991,7 +11000,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
rv = B_TRUE;
}
// can only hear one 'walk' sound per turn.
if (isplayer(l) && (nt == NC_WALK)) {
if (isplayer(l) && (nclass == NC_MOVEMENT)) {
addflag(l->flags, F_DONELISTEN, B_TRUE, NA, NA, NULL);
practice(l, SK_LISTEN, 1);
}
@ -11076,6 +11085,17 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, cha
}
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt) {
switch (nt) {
case N_WALK:
case N_FLY:
return NC_MOVEMENT;
default:
break;
}
return NC_OTHER;
}
// give initial equiment / skills to a lifeform
void outfitlf(lifeform_t *lf) {
//int db = B_FALSE;
@ -12578,11 +12598,15 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
}
}
} else if (ct == SC_SLIP) {
if (getequippedob(lf->pack, BP_FEET)) {
othermod += 5;
}
if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) {
othermod += 25;
if (lfhasflagval(lf, F_INJURY, IJ_LEGBROKEN, NA, NA, NULL)) {
othermod -= 25;
} else {
if (getequippedob(lf->pack, BP_FEET)) {
othermod += 5;
}
if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) {
othermod += 25;
}
}
} else if (ct == SC_FALL) {
if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) {

1
lf.h
View File

@ -305,6 +305,7 @@ float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
void modstamina(lifeform_t *lf, float howmuch);
int needstorest(lifeform_t *lf, char *validchars);
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
void outfitlf(lifeform_t *lf);
void petify(lifeform_t *lf, lifeform_t *owner);
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int antannounce);

2
map.c
View File

@ -3712,7 +3712,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
critchance = 100 - (mydist*40);
if (pctchance(critchance)) {
//criticalhit(NULL, cc->lf, getrandomcorebp(cc->lf), DT_EXPLOSION);
criticalhit(NULL, cc->lf, BP_HANDS, DT_EXPLOSIVE);
criticalhit(NULL, cc->lf, BP_HANDS, pctof(critchance, dam), DT_EXPLOSIVE);
}
// move away from centre of explosion

41
move.c
View File

@ -185,6 +185,22 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
}
return B_TRUE;
}
if (o->type->id == OT_PENTAGRAM) {
// this is only dangerous for the player
if (isplayer(lf)) {
object_t *oo;
// any blessed objects in your pack?
for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (oo->blessknown && isblessed(oo)) {
if (error) {
*error = E_AVOIDOB;
rdata = o;
}
return B_TRUE;
}
}
}
}
f = hasflag(o->flags, F_PIT);
if (f && (f->val[0] == D_DOWN)) {
if (!isairborne(lf)) {
@ -684,7 +700,7 @@ int getwalkoffdir(lifeform_t *lf, int dir) {
// use 'n/a' for zero chance of falling. 0 means 'calculate based on distance'
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff) {
int i;
int i,dam;
char lfname[BUFLEN];
char newlfname[BUFLEN];
int seen;
@ -757,12 +773,13 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
}
if (seen) msg("%s slam%s into %s!",lfname,isplayer(lf) ? "" : "s", thing);
snprintf(buf, BUFLEN, "slamming into %s", thing);
losehp(lf, rnd(1,6), DT_BASH, pusher, buf);
dam = roll("1d6");
losehp(lf, dam, DT_BASH, pusher, buf);
// stop moving
i = howfar;
// don't fall
mightfall = B_FALSE;
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf), DT_BASH);
if (onein(3)) criticalhit(NULL, lf, getrandomcorebp(lf), dam, DT_BASH);
break;
case E_SWIMMING:
case E_LFINWAY:
@ -2231,6 +2248,14 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
cell = getcellindir(lf->cell, dir);
// warn if moving will cause injury
if (onpurpose && isplayer(lf)) {
if (!confirm_injury_action(BP_LEGS, DT_SLASH, "move")) {
return B_TRUE;
}
}
// warn before moving onto dangerous cells
if (onpurpose && isplayer(lf) && !lfhasflag(lf, F_SNEAK)) {
if (cell && celldangerous(lf, cell, B_TRUE, &errcode)) {
char ques[BUFLEN];
@ -2298,6 +2323,8 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
// now move to new cell
moveto(lf, cell, rndmove ? B_FALSE : onpurpose, dontclearmsg);
// take some time
if (onpurpose) {
// strafing sideways/backwards takes longer
if (strafe && !lfhasflag(lf, F_AWARENESS)) {
@ -2305,10 +2332,16 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
case RD_SIDEWAYS: howlong = pctof(125, howlong); break;
case RD_BACKWARDS: howlong = pctof(150, howlong); break;
case RD_FORWARDS:
if (hasactivespell(lf, OT_S_TAILWIND)) {
// faster
howlong = pctof(75, howlong);
}
break;
default:
break;
}
}
limit(&howlong, SP_GODLIKE, NA);
taketime(lf, howlong);
if (!rndmove && !strafe) setfacing(lf, dir); // face the way we moved
}
@ -2818,5 +2851,3 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
return B_TRUE;
}

View File

@ -906,12 +906,16 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
wantdiffmat = MT_NOTHING;
}
// chance of being a different material baesd on ob flags
if (wantdiffmat == MT_NOTHING) {
getflags(ot->flags, retflag, &nretflags, F_CANBEDIFFMAT, F_NONE);
for (i = 0; i < nretflags; i++) {
if (pctchance(retflag[i]->val[1])) {
wantdiffmat = retflag[i]->val[0]; break;
// chance of being a different material based on ob flags
if ((gamemode != GM_GAMESTARTED) && isplayer(where->owner)) {
// ...but not in player's initial starting equipment
} else {
if (wantdiffmat == MT_NOTHING) {
getflags(ot->flags, retflag, &nretflags, F_CANBEDIFFMAT, F_NONE);
for (i = 0; i < nretflags; i++) {
if (pctchance(retflag[i]->val[1])) {
wantdiffmat = retflag[i]->val[0]; break;
}
}
}
}
@ -3524,6 +3528,7 @@ char *getdamname(enum DAMTYPE damtype) {
case DT_POISONGAS: return "poison gas";
case DT_PROJECTILE: return "projectile";
case DT_SLASH: return "slashing";
case DT_SONIC: return "sonic";
case DT_TOUCH: return "touch";
case DT_UNARMED: return "unarmed";
case DT_WATER: return "water";
@ -3560,6 +3565,7 @@ char *getdamnamenoun(enum DAMTYPE damtype) {
case DT_UNARMED: return "unarmed damage";
case DT_LIGHT: return "light damage";
case DT_CRUSH: return "crushing damage";
case DT_SONIC: return "sonic damage";
case DT_FALL: return "damage from falling";
default: return "unknown";
}

44
spell.c
View File

@ -920,6 +920,27 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// TODO: make this like eating/resting/etc ?
taketime(user, getactspeed(user));
} else if (abilid == OT_A_SONICBOLT) {
int volume;
if (!validatespellcell(user, &targcell,TT_MONSTER, abilid, power, B_FALSE)) return B_TRUE;
target = targcell->lf;
makenoise(user, N_SONICBOLT);
// if target can hear, they take damage
f = hasflagval(user->flags, F_NOISETEXT, N_SONICBOLT, NA, NA, NULL);
if (f) {
volume = f->val[1];
} else {
volume = power;
}
if (target && canhear(target, user->cell, volume)) {
if (isplayer(target)) {
msg("Pain shoots through your eardrums!");
}
losehp(target, roll(damstr), DT_SONIC, user, "a bolt of sound");
}
} else if (abilid == OT_A_SPRINT) {
flag_t *f;
if (lfhasflagval(user, F_INJURY, IJ_WINDPIPECRUSHED, NA, NA, NULL)) {
@ -7313,6 +7334,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
fizzle(caster);
}
} else if (spellid == OT_S_TAILWIND) {
if (!target) target = caster;
if (isplayer(target)) {
msg("A strong wind propels you forwards!");
} else if (cansee(player, target)) {
char targname[BUFLEN];
getlfname(target, targname);
msg("A strong wind propels %s forwards!", targname);
}
} else if (spellid == OT_S_TELEPORT) {
cell_t *c = NULL;
lifeform_t *ally[8];
@ -9372,25 +9402,25 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
if (isplayer(caster)) {
char buf[BUFLEN];
char buf2[BUFLEN];
objecttype_t *ot;
ot = findot(spellid);
if (maxrange == UNLIMITED) {
snprintf(buf, BUFLEN, "Where will you target your %s?", ot->name);
snprintf(buf, BUFLEN, "Where will you target your %s?", sp->name);
} else {
snprintf(buf, BUFLEN, "Where will you target your %s [max range %d]?",ot->name, maxrange);
snprintf(buf, BUFLEN, "Where will you target your %s [max range %d]?",sp->name, maxrange);
}
snprintf(buf2, BUFLEN, "%s->",ot->name);
snprintf(buf2, BUFLEN, "%s->",sp->name);
where = askcoords(buf, buf2, targtype, caster, maxrange, needlof, needlof ? B_TRUE : B_FALSE);
if (!where) {
char ques[BUFLEN];
int ch;
ch = askchar("Abandon your spell?","yn","n", B_TRUE);
snprintf(ques, BUFLEN, "Abandon your %s?", (sp->obclass->id == OC_SPELL) ? "spell" : "ability");
ch = askchar(ques,"yn","n", B_TRUE);
if (ch == 'y') {
return NULL;
}
}
} else {
// TODO: fill in monster code?
fizzle(caster);
if (sp->obclass->id == OC_SPELL) fizzle(caster);
return NULL;
}
}