- [+] 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:
parent
5cb8b05817
commit
ad18cf2398
24
attack.c
24
attack.c
|
@ -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);
|
||||
}
|
||||
|
|
2
attack.h
2
attack.h
|
@ -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
82
data.c
|
@ -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);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
14
defs.h
14
defs.h
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
17
io.c
|
@ -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
1
io.h
|
@ -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
48
lf.c
|
@ -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
1
lf.h
|
@ -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
2
map.c
|
@ -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
41
move.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
18
objects.c
18
objects.c
|
@ -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
44
spell.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue