- [+] weapon skill of sk_skilled or high gives you a chance to block

some damtypes
    - [+] BUT each weapon can only block certain damtypes (whereas
          shields can block all melee damtypes)
    - [+] add f_canblock to some weapons
    - [+] add f_canblock to shields
    - [+] check_for_block() should be a function
    - [+] getallshields()
    - [+] move othermod in SC_SHIELDBLOCK out of skillcheck(). 
          calculate the bonus beforehand instead?? 
    - [+] update descriptions for weapon skills
    - [+] can only block if you have full attrib requirements for this
          weapon
    - [+] update io.c to show what weapons/shields can block. "it can
          block xx, xx and xx damage"
    - [+] weapons can't ever block projectiles
- [+] make pickup/drop actions heaps faster
- [+] better description of agi/str affecting weapon accuracy/dam
- [+] stinkbeetle should be hostile, and should have bite attack ,not
      zapper
- [+] don't recover stamina while training
- [+] add seetext for "a blaring siren"
- [+] draw up a matrix for weapon types
    - [+] draw it up for:
        - [+] accuracy
        - [+] damage
        - [+] attack speed
        - [+] crit chance
    - [+] then adjust weapon stats
- [+] in shops, "?" now lets you examine an object
- [+] add canwill option for abilities:  "stamcost:" (to override
      stamina cost)
    - [+] add it.
- [+] bug: pickaxe not working
    - [+] "you start digging".  but nothign more.
- [+] salt kills:
    - [+] frog
- [+] impaler frog
    - [+] canwill jump
    - [+] ranged tongue attack
    - [+] killed by salt
- [+] BUG; getting manuals with no contents
- [+] odd-sized armour should cost more.
- [+] need to set statdirty when we change armour.
- [+] when we say "you see x and y here", don't include obs we can't see
This commit is contained in:
Rob Pearce 2011-12-12 16:40:17 +00:00
parent 58e61e6a07
commit 58f23588e8
19 changed files with 682 additions and 349 deletions

76
ai.c
View File

@ -429,7 +429,53 @@ void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victi
} }
if (spelllf) *spelllf = NULL; if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
} else if (spelltype->id == OT_A_JUMP) {
cell_t *cell[MAXCANDIDATES],*c;
cell_t *poss[MAXCANDIDATES];
int ncells,i,bestdist,nposs;
if (purpose == F_AICASTTOATTACK) {
bestdist = 99;
} else {
bestdist = -99;
}
getradiuscells(lf->cell, 2, DT_COMPASS, B_TRUE, LOF_WALLSTOP, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (purpose == F_AICASTTOATTACK) {
// get closest cell to victim
if (disttovictim < bestdist) {
bestdist = disttovictim;
}
} else {
// get furthest cell from victim
if (disttovictim > bestdist) {
bestdist = disttovictim;
}
}
}
// now get all possible cells...
nposs = 0;
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (disttovictim == bestdist) {
poss[nposs++] = c;
}
}
// cast spell at one of the cells we found.
// we should ALWAYS have at least one cell, because aispellok()
// will check this.
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_TELEKINESIS) { } else if (spelltype->id == OT_S_TELEKINESIS) {
float maxweight; float maxweight;
object_t *poss[MAXPILEOBS]; object_t *poss[MAXPILEOBS];
@ -592,6 +638,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0; int nretflags = 0;
flag_t *f; flag_t *f;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
// not attacking anyone in particular // not attacking anyone in particular
if (db) dblog(".oO { i do not have a target or can't move towards it. }"); if (db) dblog(".oO { i do not have a target or can't move towards it. }");
@ -1281,7 +1328,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
else spellchance = 30; else spellchance = 30;
// some attacks can always happen // some attacks can always happen
if (cancast(lf, OT_A_THRUST, NULL) && (dist == 2)) { if (cancast(lf, OT_A_THRUST, NULL) && (dist == 2) && haslof(lf->cell, target->cell, LOF_NEED, NULL)) {
spellchance = 100; spellchance = 100;
} }
@ -1962,6 +2009,29 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
} }
} }
} }
} else if (ot->id == OT_A_JUMP) {
cell_t *cell[MAXCANDIDATES],*c;
int ncells,i;
getradiuscells(lf->cell, 2, DT_COMPASS, B_TRUE, LOF_WALLSTOP, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
if (purpose == F_AICASTTOATTACK) {
// is this cell closer to the victim?
if (getcelldist(victim->cell, c) < getcelldist(victim->cell, lf->cell)) {
ok = B_TRUE;
break;
}
} else {
// is this cell further away from the victim?
if (getcelldist(victim->cell, c) > getcelldist(victim->cell, lf->cell)) {
ok = B_TRUE;
break;
}
}
}
} else if (ot->id == OT_S_PYROMANIA) { } else if (ot->id == OT_S_PYROMANIA) {
int i; int i;
for (i = 0; i < lf->nlos; i++) { for (i = 0; i < lf->nlos; i++) {
@ -2084,7 +2154,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
if (ot->id == OT_A_SHIELDBASH) { if (ot->id == OT_A_SHIELDBASH) {
if (!getshield(lf)) { if (!getshield(lf, DT_ALL)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }

View File

@ -817,7 +817,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
if (ndam > 0) { if (ndam > 0) {
object_t *shield = NULL;
flag_t *f; flag_t *f;
for (i = 0; i < ndam; i++) { for (i = 0; i < ndam; i++) {
int reduceamt = 0; int reduceamt = 0;
@ -853,31 +852,17 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
if (i == 0) { if (i == 0) {
int difficulty;
char attackname[BUFLEN];
if (lfhasflag(lf, F_HOLYAURA) && isvulnto(victim->flags, DT_HOLY, B_FALSE)) { if (lfhasflag(lf, F_HOLYAURA) && isvulnto(victim->flags, DT_HOLY, B_FALSE)) {
damtype[i] = DT_HOLY; damtype[i] = DT_HOLY;
} }
// blocked by defender's shield? // blocked by defender's shield?
shield = getshield(victim); sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
if (shield && cansee(victim, lf)) { difficulty = 25 + ((gethitdice(lf) - gethitdice(victim))*3 );
int difficulty; if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname)) {
difficulty = 25 + ((gethitdice(lf) - gethitdice(victim))*3 ); blocked = B_TRUE;
if (skillcheck(victim, SC_SHIELDBLOCK, difficulty, 0)) { break; // stop processing damage now.
char shname[BUFLEN];
// announce
real_getobname(shield, shname, 1, B_TRUE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
if (isplayer(lf)) { // player is atatcking
msg("%s blocks your attack with %s.", victimname, shname);
} else if (cansee(player, lf) || cansee(player, victim)) { // monster is attacking
msg("%s block%s %s%s attack with %s.", victimname, isplayer(victim) ? "" : "s",
attackername, getpossessive(attackername),
shname);
}
// apply all damage to shield
takedamage(shield, dam[i], damtype[i]);
practice(victim, SK_SHIELDS, 1);
blocked = B_TRUE;
break; // stop processing damage now.
}
} }
} }
@ -1416,6 +1401,43 @@ enum DAMTYPE basedamagetype(enum DAMTYPE dt) {
return dt; return dt;
} }
// returns B_TRUE if victim blocked lf's attack
int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname) {
object_t *shield[MAXPILEOBS];
int checkmod[MAXPILEOBS];
int nshields,i;
if (lf && !cansee(victim, lf)) return B_FALSE;
// get all usable shields for this damtype
getallshields(victim, damtype, shield, checkmod, &nshields);
for (i = 0; i < nshields; i++) {
// did we block with this object?
if (skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i])) {
char shname[BUFLEN];
char victimname[BUFLEN];
getlfname(victim, victimname);
// announce
real_getobname(shield[i], shname, 1, B_TRUE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
if (isplayer(lf)) { // player is atatcking
msg("%s blocks %s with %s.", victimname, attackname, shname);
} else if (cansee(player, lf) || cansee(player, victim)) { // monster is attacking
msg("%s block%s %s with %s.", victimname, isplayer(victim) ? "" : "s",
attackname, shname);
}
if (isshield(shield[i])) {
// apply all damage to shield.
// (blocking with weapons won't damage them)
takedamage(shield[i], dam, damtype);
practice(victim, SK_SHIELDS, 1);
}
// stop checking.
return B_TRUE;
}
}
return B_FALSE;
}
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) { void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype) {
object_t *o,*armour; object_t *o,*armour;
int protected = B_FALSE; int protected = B_FALSE;

View File

@ -6,7 +6,8 @@ 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 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); int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
enum DAMTYPE basedamagetype(enum DAMTYPE dt); enum DAMTYPE basedamagetype(enum DAMTYPE dt);
void confereffects(flagpile_t *fp, lifeform_t *victim); int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname);
//void confereffects(flagpile_t *fp, lifeform_t *victim);
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype); void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int dam, enum DAMTYPE damtype);
int damtypecausesbleed(enum DAMTYPE dt); int damtypecausesbleed(enum DAMTYPE dt);
int damtypecausescriteffects(enum DAMTYPE dt); int damtypecausescriteffects(enum DAMTYPE dt);

148
data.c
View File

@ -86,7 +86,6 @@ void initcommands(void) {
addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities."); addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities.");
addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods."); addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods.");
addcommand(CMD_OPERATE, 'o', "Operate a tool/wand/device, or fill a flask."); addcommand(CMD_OPERATE, 'o', "Operate a tool/wand/device, or fill a flask.");
addcommand(CMD_PICKLOCK, 'p', "Pick a lock.");
addcommand(CMD_POUR, 'P', "Pour a potion onto something."); addcommand(CMD_POUR, 'P', "Pour a potion onto something.");
addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion."); addcommand(CMD_QUAFF, 'q', "Quaff (drink) a potion.");
addcommand(CMD_READ, 'r', "Read a scroll/book."); addcommand(CMD_READ, 'r', "Read a scroll/book.");
@ -3644,6 +3643,8 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL);
addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
@ -5415,6 +5416,7 @@ void initobjects(void) {
addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL); addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL);
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
@ -5422,12 +5424,14 @@ void initobjects(void) {
addot(OT_SHIELDHIDE, "hide shield", "A small shield constructed out of animal skin.", MT_LEATHER, 2.00, OC_ARMOUR, SZ_SMALL); addot(OT_SHIELDHIDE, "hide shield", "A small shield constructed out of animal skin.", MT_LEATHER, 2.00, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL);
addflag(lastot->flags, F_OBHP, 18, 18, NA, NULL); addflag(lastot->flags, F_OBHP, 18, 18, NA, NULL);
addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR, SZ_MEDIUM); addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
@ -5440,6 +5444,7 @@ void initobjects(void) {
addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR, SZ_HUMAN); addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 30, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 30, NA, NULL);
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
@ -5670,6 +5675,13 @@ void initobjects(void) {
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_TONGUE, "tongue", "tongue object", MT_FLESH, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_PIERCE, 10, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 110, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY); addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_ELECTRIC, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_ELECTRIC, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
@ -5827,14 +5839,14 @@ void initobjects(void) {
addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, 6, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, 6, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 9, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 9, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM); addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, 11, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, 11, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, 10, NULL);
addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM); addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON, SZ_MEDIUM);
@ -5849,7 +5861,7 @@ void initobjects(void) {
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2.5, OC_WEAPON, SZ_SMALL); addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, 7, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, 7, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, 5, NA, NA, NULL); addflag(lastot->flags, F_MISSILEDAM, 5, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
@ -5858,7 +5870,7 @@ void initobjects(void) {
addot(OT_HATCHET, "hatchet", "Similar to a handaxe but weighted at the head. A fast one-handed axe, ideal for throwing.", MT_METAL, 4, OC_WEAPON, SZ_SMALL); addot(OT_HATCHET, "hatchet", "Similar to a handaxe but weighted at the head. A fast one-handed axe, ideal for throwing.", MT_METAL, 4, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, 8, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, 8, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 8, 5, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 8, 5, NULL);
@ -5866,13 +5878,14 @@ void initobjects(void) {
addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM); addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_CHOP, 12, NA, NULL); addflag(lastot->flags, F_DAM, DT_CHOP, 12, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 11, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 11, 10, NULL);
// short blades // short blades
addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 5, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 5, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
@ -5883,13 +5896,16 @@ void initobjects(void) {
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 8, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 8, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 8, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 8, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
@ -5902,12 +5918,14 @@ void initobjects(void) {
addflag(lastot->flags, F_CANBEDIFFMAT, MT_BONE, 10, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_BONE, 10, NA, NULL);
addot(OT_FORK, "fork", "A common kitchen fork.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL); addot(OT_FORK, "fork", "A common kitchen fork.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON, SZ_SMALL); addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 3, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 3, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
@ -5923,33 +5941,30 @@ void initobjects(void) {
addflag(lastot->flags, F_CRITCHANCE, 15, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 15, NA, NA, NULL);
addot(OT_ORNDAGGER, "ornamental dagger", "This dagger is pretty, but not particularly effective.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_ORNDAGGER, "ornamental dagger", "This dagger is pretty, but not particularly effective.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 3, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 3, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality, which somehow allows its bearer to attack faster.", MT_METAL, 3.0, OC_WEAPON, SZ_MEDIUM); addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality and balance, it allows its bearar to attack faster than would seem possible.", MT_METAL, 3.0, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM); addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 7, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 7, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 6, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 6, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_CANBLOCK, DT_PIERCE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 15, NULL);
addot(OT_SHORTSWORD, "gladius", "A short gladiator blade. Designed for stabbing rather than slashing.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM); addot(OT_SHORTSWORD, "gladius", "A short gladiator blade. Designed for stabbing rather than slashing.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 6, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 6, NA, NULL);
@ -5958,14 +5973,17 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 6, 5, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 6, 5, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 6, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 6, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 2, NA, NA, NULL);
addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL); addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 50, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
@ -6002,14 +6020,6 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 15, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 15, 15, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addot(OT_KATANA, "katana", "A long, finely balanced blade. Less raw power then a standard longsword, but its weight gives it a higher critical chance.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 6, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 15, NULL);
addflag(lastot->flags, F_CRITCHANCE, 10, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL);
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 9, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 9, NA, NULL);
@ -6018,13 +6028,16 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 10, 3, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, 3, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON, SZ_MEDIUM); addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 5, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 5, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 90, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 90, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 8, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 8, NA, NULL);
@ -6032,6 +6045,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 8, 3, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 8, 3, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
// polearms // polearms
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN); addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON, SZ_HUMAN);
@ -6116,12 +6130,12 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 11, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 11, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
// staves // staves
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 8, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 8, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_NEEDSSPACE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NEEDSSPACE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
@ -6129,6 +6143,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 15, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON, SZ_HUMAN); addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
@ -6140,10 +6155,10 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 15, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON, SZ_HUMAN); addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 12, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 12, NA, NULL);
addflag(lastot->flags, F_NEEDSSPACE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NEEDSSPACE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
@ -6152,6 +6167,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_AGI, 15, 15, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 15, 15, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON, SZ_HUMAN); addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
@ -6165,6 +6181,8 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 10, NULL);
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_BASH, NA, NA, NULL);
addot(OT_WIZARDSTAFF, "neophyte staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); addot(OT_WIZARDSTAFF, "neophyte staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
@ -6250,6 +6268,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 10, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM); addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 8, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 8, NA, NULL);
@ -6258,6 +6277,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 10, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 10, 10, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 5, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 5, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL);
addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 115, NA, NA, NULL);
@ -6267,9 +6287,10 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTREQ, A_STR, 14, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 14, 10, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 5, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 5, NULL);
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL);
addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM); addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 220, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 200, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 15, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 15, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
@ -6282,6 +6303,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 12, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 12, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 7, NA, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 125, NA, NA, NULL);
addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM); addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
@ -6291,14 +6313,7 @@ void initobjects(void) {
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_STR, 13, 10, NULL); addflag(lastot->flags, F_ATTREQ, A_STR, 13, 10, NULL);
addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL);
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 7, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 13, 15, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON, SZ_MEDIUM); addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "It makes metalwork easier."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "It makes metalwork easier.");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
@ -6313,6 +6328,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_BASH, 5, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 5, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_STICK, "stick", "A sturdy wooden stick. It's brown and sticky.", MT_WOOD, 0.5, OC_WEAPON, SZ_SMALL); addot(OT_STICK, "stick", "A sturdy wooden stick. It's brown and sticky.", MT_WOOD, 0.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL);
@ -6323,6 +6339,35 @@ void initobjects(void) {
addflag(lastot->flags, F_NOQUALITY, 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_RODSHAPED, B_TRUE, NA, NA, NULL);
// exotic weapons
addot(OT_KATANA, "katana", "A long, finely balanced blade. Less raw power then a standard longsword, but its weight gives it a higher critical chance.", MT_METAL, 4, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
addflag(lastot->flags, F_DAM, DT_SLASH, 6, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 12, 15, NULL);
addflag(lastot->flags, F_CRITCHANCE, 10, NA, NA, NULL);
addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 5, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_PIERCE, NA, NA, NULL);
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short chain. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 7, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 13, 15, NULL);
addflag(lastot->flags, F_CRITCHANCE, 3, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL);
addflag(lastot->flags, F_DAM, DT_PIERCE, 4, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_DISARMLF, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL);
addflag(lastot->flags, F_ATTREQ, A_AGI, 10, 15, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_SLASH, NA, NA, NULL);
// projectile weapons // projectile weapons
addot(OT_BOW, "short bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 5, OC_WEAPON, SZ_MEDIUM); addot(OT_BOW, "short bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 5, OC_WEAPON, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
@ -6426,6 +6471,7 @@ void initobjects(void) {
addot(OT_ICESHIELD, "ice crystal shield", "A summoned shield made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL); addot(OT_ICESHIELD, "ice crystal shield", "A summoned shield made of ice crystals.", MT_ICE, 0, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL); // will be replaced when summoned
@ -8217,7 +8263,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of grey ooze. Grey, acidic ooze."); addrace(R_OOZEGREY, "green ooze", 10, 'j', C_GREEN, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of green ooze. Green, acidic ooze.");
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "puddle of slime"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "puddle of slime");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
@ -8915,6 +8961,32 @@ void initrace(void) {
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_FROG, "impaler frog", 10, ';', C_BOLDGREEN, MT_FLESH, RC_ANIMAL, "As their name implies, impaler frogs are dangerous frogs whose tongues end in a very sharp point. They use this to spear their enemies from afar, often while hiding underwater.");
setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_VULNTOSALT, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4");
addflag(lastrace->flags, F_HASATTACK, OT_TONGUE, 6, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_THRUST, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, "stamcost:0;");
addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "hop");
addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A young baby hawk."); // 'A' for Avian addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A young baby hawk."); // 'A' for Avian
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
lastrace->baseid = R_HAWK; lastrace->baseid = R_HAWK;
@ -10025,6 +10097,7 @@ void initrace(void) {
addrace(R_STINKBUG, "stinkbeetle", 1, 'x', C_MAGENTA, MT_FLESH, RC_INSECT, "A dog-sized beetle with tough scales. Emits a foul odour upon death."); addrace(R_STINKBUG, "stinkbeetle", 1, 'x', C_MAGENTA, MT_FLESH, RC_INSECT, "A dog-sized beetle with tough scales. Emits a foul odour upon death.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
@ -10034,7 +10107,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+0");
addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 1, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:1d1;"); addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:1d1;");
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
@ -10792,6 +10865,7 @@ void initskills(void) {
addskilldesc(sk->id, PR_BEGINNER, "^g-1 accuracy penalty^n", B_FALSE); addskilldesc(sk->id, PR_BEGINNER, "^g-1 accuracy penalty^n", B_FALSE);
addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE);
addskilldesc(sk->id, PR_SKILLED, "^g+2 accuracy, +20% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_SKILLED, "^g+2 accuracy, +20% damage bonus.^n", B_FALSE);
addskilldesc(sk->id, PR_SKILLED, "^gYou can now block certain attacks with this kind of weapon.^n", B_FALSE);
addskilldesc(sk->id, PR_EXPERT, "^g+4 accuracy, +30% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_EXPERT, "^g+4 accuracy, +30% damage bonus.^n", B_FALSE);
addskilldesc(sk->id, PR_MASTER, "^g+6 accuracy, +40%% damage bonus, combination strike ability.^n", B_FALSE); addskilldesc(sk->id, PR_MASTER, "^g+6 accuracy, +40%% damage bonus, combination strike ability.^n", B_FALSE);
} }

Binary file not shown.

8
defs.h
View File

@ -221,8 +221,8 @@
#define SPEED_DEAD 50 #define SPEED_DEAD 50
#define SPEED_ACTION SP_NORMAL #define SPEED_ACTION SP_NORMAL
#define SPEED_MOVE SP_NORMAL #define SPEED_MOVE SP_NORMAL
#define SPEED_DROP SP_FAST #define SPEED_DROP SP_ULTRAFAST
#define SPEED_PICKUP SP_FAST #define SPEED_PICKUP SP_ULTRAFAST
#define SPEED_THROW SP_FAST #define SPEED_THROW SP_FAST
#define SPEED_WAIT SP_NORMAL #define SPEED_WAIT SP_NORMAL
#define SPEED_READ SP_NORMAL #define SPEED_READ SP_NORMAL
@ -928,6 +928,7 @@ enum RACE {
R_HAWKYOUNG, R_HAWKYOUNG,
R_HAWKBLOOD, R_HAWKBLOOD,
R_HAWKFROST, R_HAWKFROST,
R_FROG,
R_LEECH, R_LEECH,
R_NEWT, R_NEWT,
R_PORCUPINE, R_PORCUPINE,
@ -1699,6 +1700,7 @@ enum OBTYPE {
OT_TEETH, OT_TEETH,
OT_TEETHSM, OT_TEETHSM,
OT_TENTACLE, OT_TENTACLE,
OT_TONGUE,
OT_ZAPPER, OT_ZAPPER,
// monster weapons // monster weapons
OT_ACIDATTACK, OT_ACIDATTACK,
@ -2257,6 +2259,7 @@ enum FLAG {
F_ARMOURSIZE, // v0 = sz_xxx, can be "medium", "human" or "large". F_ARMOURSIZE, // v0 = sz_xxx, can be "medium", "human" or "large".
F_ARMOURRATING, // val0 * 2 = pct of damage reduced F_ARMOURRATING, // val0 * 2 = pct of damage reduced
F_SHIELD, // this is a shield - use special bodyhitchance code F_SHIELD, // this is a shield - use special bodyhitchance code
F_CANBLOCK, // this objcet can block damtype xxx
F_OBHP, // val0 = object health, val1 = object maxhealth F_OBHP, // val0 = object health, val1 = object maxhealth
F_OBHPDRAIN, // val0 = amt hp to lose each second. val1 = NA or damtype F_OBHPDRAIN, // val0 = amt hp to lose each second. val1 = NA or damtype
// if no damtype specified, it will be DT_DIRECT // if no damtype specified, it will be DT_DIRECT
@ -3084,7 +3087,6 @@ enum COMMAND {
CMD_MSGHIST, CMD_MSGHIST,
CMD_OFFER, CMD_OFFER,
CMD_OPERATE, CMD_OPERATE,
CMD_PICKLOCK,
CMD_PICKUP, CMD_PICKUP,
CMD_POUR, CMD_POUR,
CMD_QUAFF, CMD_QUAFF,

View File

@ -41,6 +41,7 @@ X = unknown thing!
y/Y = air related creatures like clouds of gas, air elemental y/Y = air related creatures like clouds of gas, air elemental
z = lizard-like creature z = lizard-like creature
Z = undead Z = undead
; = fish
& = demon & = demon

6
flag.c
View File

@ -913,6 +913,9 @@ void killflag(flag_t *f) {
} }
} }
/////////////////////////////////////////////
// now we are actually removing the flag.
/////////////////////////////////////////////
// remember the pile so that we can re-index // remember the pile so that we can re-index
pile = f->pile; pile = f->pile;
@ -997,6 +1000,9 @@ void killflag(flag_t *f) {
} }
void killflagpile(flagpile_t *fp) { void killflagpile(flagpile_t *fp) {
if (fp->ob && !fp->ob->dying) {
assert(0 == "calling killflagpile on non-dying object");
}
while (fp->first) { while (fp->first) {
killflag(fp->first); killflag(fp->first);
} }

105
io.c
View File

@ -2055,9 +2055,6 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break; break;
case F_FLEEFROM: case F_FLEEFROM:
msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s"); msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
if (!isplayer(lf)) {
dblog("xx");
}
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_FRIENDLY: case F_FRIENDLY:
@ -4312,7 +4309,7 @@ void dolook(cell_t *where, int onpurpose) {
char buf[BUFLEN]; char buf[BUFLEN];
char seeverb[BUFLEN]; char seeverb[BUFLEN];
int seensomething = B_FALSE; int seensomething = B_FALSE;
object_t *o,*firstob = NULL; object_t *o,*firstob = NULL,*secondob = NULL;
flag_t *f; flag_t *f;
int includetrails = B_TRUE; int includetrails = B_TRUE;
@ -4345,7 +4342,11 @@ void dolook(cell_t *where, int onpurpose) {
interrupt(player); interrupt(player);
seensomething = B_TRUE; seensomething = B_TRUE;
} else { } else {
if (!firstob) { if (firstob) {
if (!secondob) {
secondob = o;
}
} else {
firstob = o; firstob = o;
} }
numobs++; numobs++;
@ -4376,45 +4377,24 @@ void dolook(cell_t *where, int onpurpose) {
} }
} else if (numobs == 2) { } else if (numobs == 2) {
char buf2[BUFLEN]; char buf2[BUFLEN];
object_t *secondob; if (streq(seeverb, "feel")) {
secondob = firstob->next; f = hasflag(firstob->flags, F_FEELTEXT);
if (hasflag(firstob->flags, F_THEREISHERE)) { if (f) {
strcpy(buf, ""); // don't show it strcpy(buf, f->text);
} else {
if (streq(seeverb, "feel")) {
f = hasflag(firstob->flags, F_FEELTEXT);
if (f) {
strcpy(buf, f->text);
} else {
getobname(firstob, buf, firstob->amt);
}
} else { } else {
getobname(firstob, buf, firstob->amt); getobname(firstob, buf, firstob->amt);
} }
} f = hasflag(secondob->flags, F_FEELTEXT);
if (hasflag(secondob->flags, F_THEREISHERE)) { if (f) {
strcpy(buf2, ""); // don't show it strcpy(buf2, f->text);
} else {
if (streq(seeverb, "feel")) {
f = hasflag(secondob->flags, F_FEELTEXT);
if (f) {
strcpy(buf2, f->text);
} else {
getobname(secondob, buf2, secondob->amt);
}
} else { } else {
getobname(secondob, buf2, secondob->amt); getobname(secondob, buf2, secondob->amt);
} }
}
if (!strlen(buf) && !strlen(buf2)) {
// both obs shown later!
} else if (!strlen(buf)) {
msg("You %s %s here.", seeverb, buf2);
} else if (!strlen(buf2)) {
msg("You %s %s here.", seeverb, buf);
} else { } else {
msg("You %s %s and %s here.", seeverb, buf, buf2); getobname(firstob, buf, firstob->amt);
getobname(secondob, buf2, secondob->amt);
} }
msg("You %s %s and %s here.", seeverb, buf, buf2);
} else if ((numobs >= 3) && (numobs <= 4)) { } else if ((numobs >= 3) && (numobs <= 4)) {
msg("You %s a few things here.", seeverb); msg("You %s a few things here.", seeverb);
} else if ((numobs >= 5) && (numobs <= 6)) { } else if ((numobs >= 5) && (numobs <= 6)) {
@ -4655,6 +4635,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, "\n", HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, "\n", HUGEBUFLEN);
} }
if ((f = hasflag(o->flags, F_IMPASSABLE)) != NULL) { if ((f = hasflag(o->flags, F_IMPASSABLE)) != NULL) {
if ((f->val[0] == SZ_MIN) && (f->val[1] == SZ_MAX)) { if ((f->val[0] == SZ_MIN) && (f->val[1] == SZ_MAX)) {
snprintf(buf, BUFLEN, "It is %simpassable.\n", hasflag(o->flags, F_DOOR) ? "currently " : ""); snprintf(buf, BUFLEN, "It is %simpassable.\n", hasflag(o->flags, F_DOOR) ? "currently " : "");
@ -5287,6 +5268,32 @@ char *makedesc_ob(object_t *o, char *retbuf) {
} }
// other weapon properties... // other weapon properties...
getflags(o->flags, retflag, &nretflags, F_CANBLOCK, F_NONE);
for (i = 0; i < nretflags; i++) {
char thisdt[BUFLEN];
f = retflag[i];
if (f->val[0] == DT_ALL) {
strcpy(thisdt, "melee");
} else {
sprintf(thisdt, "%s", getdamname(f->val[0]));
}
if (i == 0) {
snprintf(buf, BUFLEN, "Skilled weilders can use it to block %s", thisdt);
} else if (i == (nretflags - 1)) {
snprintf(buf, BUFLEN, " and %s", thisdt);
} else {
snprintf(buf, BUFLEN, ", %s", thisdt);
}
strncat(retbuf, buf, HUGEBUFLEN);
}
if (nretflags) {
snprintf(buf, BUFLEN, " damage.\n");
strncat(retbuf, buf, HUGEBUFLEN);
}
f = hasflag(o->flags, F_NEEDSSPACE); f = hasflag(o->flags, F_NEEDSSPACE);
if (f && f->known) { if (f && f->known) {
sprintf(buf, "It is ineffective in confined spaces due to its length.\n"); sprintf(buf, "It is ineffective in confined spaces due to its length.\n");
@ -5698,12 +5705,21 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf, "^%dIt requires at least %d %s to use%s.^n\n", col, f->val[1], getattrname(f->val[0]), sprintf(buf, "^%dIt requires at least %d %s to use%s.^n\n", col, f->val[1], getattrname(f->val[0]),
(f->val[2] == 0) ? "" : " effectively"); (f->val[2] == 0) ? "" : " effectively");
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
msg("^wYou low %s will lower your %s with this weapon.",
getattrname(retflag[i]->val[0]),
(retflag[i]->val[0] == A_AGI) ? "accuracy" : "damage");
if (usable && isweapon(o)) { if (usable && isweapon(o)) {
if (pctmod > 0) { if (pctmod > 0) {
sprintf(buf, "^%dYour high %s will increase your effectiveness with this weapon.^n\n", C_GREEN, getattrname(f->val[0])); sprintf(buf, "^%dYour high %s will increase your %s with this weapon.^n\n", C_GREEN,
getattrname(f->val[0]),
(f->val[0] == A_AGI) ? "accuracy" : "damage");
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} else if (pctmod < 0) { } else if (pctmod < 0) {
sprintf(buf, "^%dYour low %s will decrease your effectiveness with this weapon.^n\n", C_BROWN, getattrname(f->val[0])); sprintf(buf, "^%dYour low %s will decrease your %s with this weapon.^n\n", C_BROWN,
getattrname(f->val[0]),
(f->val[0] == A_AGI) ? "accuracy" : "damage");
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
} }
@ -6142,7 +6158,7 @@ char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite) {
char *makedesc_spell(objecttype_t *ot, char *retbuf) { char *makedesc_spell(objecttype_t *ot, char *retbuf) {
char buf[BUFLEN]; char buf[BUFLEN];
flag_t *retflag[MAXCANDIDATES], *f; flag_t *retflag[MAXCANDIDATES], *f;
int nretflags,i,power,range; int nretflags,i,power,range,stamcost;
strcpy(retbuf, ""); strcpy(retbuf, "");
@ -6213,10 +6229,9 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) {
} }
} }
stamcost = getstamcost(player, ot->id);
f = hasflag(ot->flags, F_STAMCOST); if (stamcost) {
if (f) { sprintf(buf, "It costs %d stamina to use.\n",stamcost);
sprintf(buf, "It costs %d stamina to use.\n",f->val[0]);
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
@ -8636,10 +8651,6 @@ void handleinput(void) {
case 't': // throw case 't': // throw
dothrow(player->pack); dothrow(player->pack);
break; break;
case 'p': // pick lock
addflag(player->flags, F_LASTCMD, NA, NA, NA, temp);
lockpick(player, NULL, NULL, NULL);
break;
case 'P': // Pour case 'P': // Pour
dopour(player->pack); dopour(player->pack);
break; break;

227
lf.c
View File

@ -531,6 +531,7 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
int castable = B_FALSE; int castable = B_FALSE;
flag_t *f; flag_t *f;
objecttype_t *ot; objecttype_t *ot;
int stamcost = 0;
// TODO: check for mute? // TODO: check for mute?
if (lfhasflag(lf, F_STUNNED)) { if (lfhasflag(lf, F_STUNNED)) {
@ -588,7 +589,6 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
return B_FALSE; return B_FALSE;
} }
} }
} else if (lfhasflagval(lf, F_CANCAST, oid, NA, NA, NULL)) { } else if (lfhasflagval(lf, F_CANCAST, oid, NA, NA, NULL)) {
int cost,power; int cost,power;
@ -622,8 +622,9 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
} }
f = hasflag(ot->flags, F_STAMCOST); // do we have enough stamina to do this?
if (f && (getstamina(lf) < f->val[0])) { stamcost = getstamcost(lf, oid);
if (stamcost && (getstamina(lf) < stamcost)) {
reason = E_NOSTAM; reason = E_NOSTAM;
return B_FALSE; return B_FALSE;
} }
@ -1195,19 +1196,11 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
return B_FALSE; return B_FALSE;
} }
// other flags to check if (!meetsallattreqs(lf, o)) {
getflags(o->flags, retflag, &nretflags, F_ATTREQ, F_NONE); // meetsattreq will set 'reason' for us.
for (i = 0; i < nretflags; i++) { return B_FALSE;
f = retflag[i];
if (f->id == F_ATTREQ) {
// meetsattreq will set 'reason' for us.
if (!meetsattreq(lf, f, o, NULL)) {
return B_FALSE;
}
}
} }
// can we wear it ANYWHERE? // can we wear it ANYWHERE?
getflags(o->flags, retflag, &nretflags, F_GOESON, F_NONE); getflags(o->flags, retflag, &nretflags, F_GOESON, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
@ -1992,7 +1985,7 @@ int continuedigging(lifeform_t *lf) {
int digpower; int digpower;
int stopnow = B_FALSE; int stopnow = B_FALSE;
if (!hasfreeaction(lf)) { if (!real_hasfreeaction(lf, F_DIGGING)) {
stopnow = B_TRUE; stopnow = B_TRUE;
} }
@ -6988,18 +6981,91 @@ object_t *getsecmeleeweapon(lifeform_t *lf) {
return NULL; return NULL;
} }
object_t *getshield(lifeform_t *lf) { // returns the best shield for the given damtype
object_t *getshield(lifeform_t *lf, enum DAMTYPE dt) {
object_t *shield[MAXPILEOBS];
int checkmod[MAXPILEOBS];
int nshields,i;
object_t *bestshield = NULL;
int bestcheckmod = -99;
getallshields(lf, dt, shield, checkmod, &nshields);
for (i = 0; i < nshields; i++) {
if (checkmod[i] > bestcheckmod) {
bestcheckmod = checkmod[i];
bestshield = shield[i];
}
}
return bestshield;
}
int getallshields(lifeform_t *lf, enum DAMTYPE damtype, object_t **retob, int *checkmod, int *nretobs) {
object_t *o; object_t *o;
o = getequippedob(lf->pack, BP_SECWEAPON);
if (o) { *nretobs = 0;
if (isshield(o)) return o;
// master two-weaponers can use their second weapon as a shield. if (!hasfreeaction(lf)) {
if ((getskill(lf, SK_TWOWEAPON) >= PR_MASTER) && isweapon(o) && getweaponskill(lf, o)) { return 0;
return o; }
for (o = lf->pack->first ; o ; o = o->next) {
flag_t *f;
f = isequipped(o);
if (f && meetsallattreqs(lf, o)) {
int isblockob = B_FALSE;
if (isshield(o) && (f->val[0] == BP_SECWEAPON)) {
// shield?
isblockob = B_TRUE;
} else if (isweapon(o) && (getweaponskill(lf, o) >= PR_SKILLED) && (damtype != DT_PROJECTILE)) {
if (f->val[0] == BP_WEAPON) {
// primary weapon which we are skilled in?
isblockob = B_TRUE;
} else if ((f->val[0] == BP_SECWEAPON) && (getskill(lf, SK_TWOWEAPON) >= PR_MASTER)) {
// secondary weapon which we are skilled in,
// and we are a master two-weaponer ?
isblockob = B_TRUE;
}
}
if (isblockob) {
// can it block this damage type?
if ((damtype == DT_ALL) ||
hasflagval(o->flags, F_CANBLOCK, damtype, NA, NA, NULL) ||
hasflagval(o->flags, F_CANBLOCK, DT_ALL, NA, NA, NULL)) {
retob[*nretobs] = o;
checkmod[*nretobs] = getshieldblockmod(lf, o);
(*nretobs)++;
}
}
} }
} }
return NULL; return *nretobs;
}
int getshieldblockmod(lifeform_t *lf, object_t *o) {
enum SKILLLEVEL slev = PR_INEPT;
int othermod = 0;
if (isshield(o)) {
slev = getskill(lf, SK_SHIELDS);
} else {
// using a weapon
// skilled weapon == beginner block
// expert weapon == adept block
// master weapon == skilled block
slev = getweaponskill(lf, o) - 2;
}
switch (slev) {
case PR_NOVICE: othermod = 0; break;
case PR_BEGINNER: othermod = 4; break;
case PR_ADEPT: othermod = 7; break;
case PR_SKILLED: othermod = 10; break;
case PR_EXPERT: othermod = 13; break;
case PR_MASTER: othermod = 16; break;
default:
// should never happen
othermod = -4;
break;
}
return othermod;
} }
@ -7033,7 +7099,10 @@ float getstamregen(lifeform_t *lf) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags,i; int nretflags,i;
if (lfhasflagval(lf, F_INJURY, IJ_WINDPIPECRUSHED, NA, NA, NULL)) { if (lfhasflag(lf, F_TRAINING)) {
// don't regain stamina while training!
return 0;
} else if (lfhasflagval(lf, F_INJURY, IJ_WINDPIPECRUSHED, NA, NA, NULL)) {
regenrate = 0.2; // override everything else regenrate = 0.2; // override everything else
} else { } else {
if (lfhasflag(lf, F_ASLEEP)) { if (lfhasflag(lf, F_ASLEEP)) {
@ -7433,14 +7502,27 @@ race_t *getreallyrandomrace(enum RACECLASS wantrc) {
} }
enum SKILL getrandomskill(void) { enum SKILL getrandomskill(void) {
int sel,count = 0; int sel,count;
int nskills;
skill_t *sk; skill_t *sk;
sel = rnd(1,MAXSKILLS-1); // 0 is SK_NONE enum SKILL retskill = SK_NONE;
// count skills
nskills = 0;
for (sk = firstskill ; sk ; sk = sk->next) { for (sk = firstskill ; sk ; sk = sk->next) {
if (count == sel) return sk->id; nskills++;
}
sel = rnd(0,nskills-1);
count = 0;
for (sk = firstskill ; sk ; sk = sk->next) {
if (count == sel) {
retskill = sk->id;
break;
}
count++; count++;
} }
return SK_NONE; assert(findskill(retskill));
return retskill;
} }
object_t *getrestob(lifeform_t *lf) { object_t *getrestob(lifeform_t *lf) {
@ -8915,11 +8997,18 @@ flag_t *hasbleedinginjury(lifeform_t *lf, enum BODYPART bp) {
int hasfreeaction(lifeform_t *lf) { int hasfreeaction(lifeform_t *lf) {
return real_hasfreeaction(lf, F_NONE);
}
int real_hasfreeaction(lifeform_t *lf, enum FLAG exception) {
flag_t *retflag[MAXCANDIDATES];
int nretflags,i;
if (isimmobile(lf)) return B_FALSE; if (isimmobile(lf)) return B_FALSE;
if (lfhasflag(lf, F_CASTINGSPELL)) return B_FALSE; getflags(lf->flags, retflag, &nretflags, F_ASLEEP, F_CASTINGSPELL, F_DIGGING, F_EATING, F_NONE);
if (lfhasflag(lf, F_DIGGING)) return B_FALSE; for (i = 0; i < nretflags; i++) {
if (lfhasflag(lf, F_EATING)) return B_FALSE; if (retflag[i]->id != exception) {
if (lfhasflag(lf, F_ASLEEP)) return B_FALSE; return B_FALSE;
}
}
return B_TRUE; return B_TRUE;
} }
@ -10085,9 +10174,11 @@ void killlf(lifeform_t *lf) {
} }
// kill object pile // kill object pile
free(lf->pack); free(lf->pack);
lf->pack = NULL;
// kill flags // kill flags
killflagpile(lf->flags); killflagpile(lf->flags);
lf->flags = NULL;
// remove from list // remove from list
nextone = lf->next; nextone = lf->next;
@ -12176,6 +12267,19 @@ void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how) {
} }
} }
int meetsallattreqs(lifeform_t *lf, object_t *o) {
flag_t *retflag[MAXCANDIDATES];
int nretflags,i;
// other flags to check
getflags(o->flags, retflag, &nretflags, F_ATTREQ, F_NONE);
for (i = 0; i < nretflags; i++) {
if (!meetsattreq(lf, retflag[i], o, NULL)) {
return B_FALSE;
}
}
return B_TRUE;
}
// if you don't meet it, return why not in 'reason' // if you don't meet it, return why not in 'reason'
int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *pctmod) { int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *pctmod) {
@ -12494,10 +12598,10 @@ void modmorale(lifeform_t *lf, int howmuch) {
void modstamina(lifeform_t *lf, float howmuch) { void modstamina(lifeform_t *lf, float howmuch) {
float orig; float orig;
if (howmuch == 0) return;
// you don't lose stamina while enraged // you don't lose stamina while enraged
if (lfhasflag(lf, F_RAGE) && (howmuch < 0)) { if (lfhasflag(lf, F_RAGE) && (howmuch < 0)) return;
return;
}
if (isplayer(lf)) { if (isplayer(lf)) {
if (howmuch < 0) { if (howmuch < 0) {
@ -12656,9 +12760,6 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
} else { } else {
msg("%s %s.", lfname, realseetext); msg("%s %s.", lfname, realseetext);
} }
if ((realseetext[0] == '\0') || !strlen(realseetext)) {
dblog("xxx");
}
rv = B_TRUE; rv = B_TRUE;
} }
} else if (!noisemaker && haslos(player, c)) { } else if (!noisemaker && haslos(player, c)) {
@ -14734,32 +14835,6 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) { if (lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET)) {
othermod += 10; othermod += 10;
} }
} else if (ct == SC_SHIELDBLOCK) {
object_t *shield;
enum SKILLLEVEL slev;
shield = getshield(lf);
if (shield) {
if (isshield(shield)) {
slev = getskill(lf, SK_SHIELDS);
} else {
// twoweaponer using their weapon
slev = PR_NOVICE;
}
} else {
// should never happen!!!
slev = PR_INEPT;
}
switch (slev) {
case PR_NOVICE: othermod = 0; break;
case PR_BEGINNER: othermod = 4; break;
case PR_ADEPT: othermod = 7; break;
case PR_SKILLED: othermod = 10; break;
case PR_EXPERT: othermod = 13; break;
case PR_MASTER: othermod = 16; break;
default:
othermod = -4;
break;
}
} else if (ct == SC_MORALE) { } else if (ct == SC_MORALE) {
othermod += (getstatmod(lf, A_WIS) / 30); // ie. -1 to 1 othermod += (getstatmod(lf, A_WIS) / 30); // ie. -1 to 1
} else if (ct == SC_OPENLOCKS) { } else if (ct == SC_OPENLOCKS) {
@ -16784,12 +16859,10 @@ int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where)
if (!rv) { if (!rv) {
objecttype_t *ot; objecttype_t *ot;
flag_t *f;
int stamcost = 0; int stamcost = 0;
// success - charge stamina // success - charge stamina
ot = findot(aid); ot = findot(aid);
f = hasflag(ot->flags, F_STAMCOST); stamcost = getstamcost(lf, aid);
if (f) stamcost = f->val[0];
if (stamcost) { if (stamcost) {
modstamina(lf, -stamcost); modstamina(lf, -stamcost);
} }
@ -17548,11 +17621,6 @@ int wear(lifeform_t *lf, object_t *o) {
int nretflags; int nretflags;
int showpos = B_FALSE; int showpos = B_FALSE;
// this might impact your AR
if (isplayer(lf)) {
statdirty = B_TRUE;
}
if (lfhasflag(lf, F_RAGE)) { if (lfhasflag(lf, F_RAGE)) {
if (isplayer(lf)) msg("You are too enraged!"); if (isplayer(lf)) msg("You are too enraged!");
return B_TRUE; return B_TRUE;
@ -17785,10 +17853,7 @@ int wear(lifeform_t *lf, object_t *o) {
return B_TRUE; return B_TRUE;
} }
// wear it // actually wear it
//f = hasflag(o->flags, F_GOESON);
//bp = f->val[0];
for (i = 0; i < ncheckparts; i++) { for (i = 0; i < ncheckparts; i++) {
addflag(o->flags, F_EQUIPPED, possbp[i], -1, -1, NULL); addflag(o->flags, F_EQUIPPED, possbp[i], -1, -1, NULL);
} }
@ -17807,7 +17872,9 @@ int wear(lifeform_t *lf, object_t *o) {
} }
if ((gamemode == GM_GAMESTARTED) && lf->created) { if ((gamemode == GM_GAMESTARTED) && lf->created) {
if (isplayer(lf)) { if (isplayer(lf)) {
// announce
if (showpos) { if (showpos) {
char posbuf[BUFLEN]; char posbuf[BUFLEN];
makewearstring(lf, o, B_TRUE, posbuf ); makewearstring(lf, o, B_TRUE, posbuf );
@ -17862,6 +17929,10 @@ int wear(lifeform_t *lf, object_t *o) {
// give flags // give flags
giveobflags(lf, o, F_EQUIPCONFER); giveobflags(lf, o, F_EQUIPCONFER);
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
// set statdirty since this might have impacted your AR / EV
statdirty = B_TRUE;
}
return rv; return rv;
} }
@ -18144,7 +18215,9 @@ int weild(lifeform_t *lf, object_t *o) {
int pctmod; int pctmod;
meetsattreq(lf, retflag[i], o, &pctmod); meetsattreq(lf, retflag[i], o, &pctmod);
if (pctmod < 0) { if (pctmod < 0) {
msg("^wYou lack of %s will hinder your usage of this weapon.", getattrname(retflag[i]->val[0])); msg("^wYou low %s will lower your %s with this weapon.",
getattrname(retflag[i]->val[0]),
(retflag[i]->val[0] == A_AGI) ? "accuracy" : "damage");
} }
} }
} }

6
lf.h
View File

@ -200,7 +200,9 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis);
enum LFSIZE getlfsize(lifeform_t *lf); enum LFSIZE getlfsize(lifeform_t *lf);
float getlfweight(lifeform_t *lf, int withobs); float getlfweight(lifeform_t *lf, int withobs);
object_t *getsecmeleeweapon(lifeform_t *lf); object_t *getsecmeleeweapon(lifeform_t *lf);
object_t *getshield(lifeform_t *lf); object_t *getshield(lifeform_t *lf, enum DAMTYPE dt);
int getallshields(lifeform_t *lf, enum DAMTYPE damtype, object_t **retob, int *checkmod, int *nretobs);
int getshieldblockmod(lifeform_t *lf, object_t *o);
int getspellspeed(lifeform_t *lf); int getspellspeed(lifeform_t *lf);
int getstamina(lifeform_t *lf); int getstamina(lifeform_t *lf);
float getstamregen(lifeform_t *lf); float getstamregen(lifeform_t *lf);
@ -250,6 +252,7 @@ map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
int gotosleep(lifeform_t *lf, int onpurpose); int gotosleep(lifeform_t *lf, int onpurpose);
flag_t *hasbleedinginjury(lifeform_t *lf, enum BODYPART bp); flag_t *hasbleedinginjury(lifeform_t *lf, enum BODYPART bp);
int hasfreeaction(lifeform_t *lf); int hasfreeaction(lifeform_t *lf);
int real_hasfreeaction(lifeform_t *lf, enum FLAG exception);
int hashealableinjuries(lifeform_t *lf); int hashealableinjuries(lifeform_t *lf);
job_t *hasjob(lifeform_t *lf, enum JOB job); job_t *hasjob(lifeform_t *lf, enum JOB job);
void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch); void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch);
@ -332,6 +335,7 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid);
void makepeaceful(lifeform_t *lf); void makepeaceful(lifeform_t *lf);
lifeform_t *makezombie(object_t *o); lifeform_t *makezombie(object_t *o);
void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how); void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how);
int meetsallattreqs(lifeform_t *lf, object_t *o);
int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *modpct); int meetsattreq(lifeform_t *lf, flag_t *f, object_t *o, int *modpct);
int mightflee(lifeform_t *lf); int mightflee(lifeform_t *lf);
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt); int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);

1
map.c
View File

@ -3375,6 +3375,7 @@ void killmap(map_t *m) {
while (m->lf) killlf(m->lf); while (m->lf) killlf(m->lf);
killflagpile(m->flags); killflagpile(m->flags);
m->flags = NULL;
for (i = 0; i < (m->w*m->h); i++){ for (i = 0; i < (m->w*m->h); i++){
killcell(m->cell[i]); killcell(m->cell[i]);

View File

@ -1290,6 +1290,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
// } // }
} else { // ie. manual } else { // ie. manual
bookcontents = getrandomskill(); bookcontents = getrandomskill();
assert(findskill(bookcontents));
} }
} }
@ -1323,6 +1324,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
} }
} }
} else { } else {
assert(findskill(bookcontents));
addflag(o->flags, F_MANUALOF, bookcontents, NA, NA, NULL); addflag(o->flags, F_MANUALOF, bookcontents, NA, NA, NULL);
} }
@ -3542,7 +3544,7 @@ int getobvalue(object_t *o) {
price += f->val[0]; price += f->val[0];
} }
getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE); getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_ARMOURSIZE, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
// damage // damage
@ -3557,6 +3559,12 @@ int getobvalue(object_t *o) {
rating = (float)f->val[0]; rating = (float)f->val[0];
price += (rating * 20.0); price += (rating * 20.0);
} }
// armour size (nonstandard costs more)
if (f->id == F_ARMOURSIZE) {
if (f->val[0] != SZ_HUMAN) {
price += 75;
}
}
// bonus/penalties // bonus/penalties
if (f->id == F_BONUS) { if (f->id == F_BONUS) {
price += (f->val[0] * 100); price += (f->val[0] * 100);
@ -6368,9 +6376,8 @@ int isedible(object_t *o) {
return B_FALSE; return B_FALSE;
} }
int isequipped(object_t *o) { flag_t *isequipped(object_t *o) {
if (hasflag(o->flags, F_EQUIPPED)) return B_TRUE; return hasflag(o->flags, F_EQUIPPED);
return B_FALSE;
} }
int isequippedon(object_t *o, enum BODYPART bp) { int isequippedon(object_t *o, enum BODYPART bp) {
@ -6889,9 +6896,18 @@ void killob(object_t *o) {
} }
// free mem // free mem
if (o->inscription) free(o->inscription); if (o->inscription) {
if (o->contents) killobpile(o->contents); free(o->inscription);
if (o->flags) killflagpile(o->flags); o->inscription = NULL;
}
if (o->contents) {
killobpile(o->contents);
o->contents = NULL;
}
if (o->flags) {
killflagpile(o->flags);
o->flags = NULL;
}
// remove from list // remove from list
nextone = o->next; nextone = o->next;
@ -11517,7 +11533,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
if (youhit && target) { if (youhit && target) {
flag_t *f; flag_t *f;
object_t *shield; char attackname[BUFLEN];
int difficulty;
// cyclone shield? // cyclone shield?
f = lfhasflag(target, F_WINDSHIELD); f = lfhasflag(target, F_WINDSHIELD);
if (f) { if (f) {
@ -11529,31 +11546,14 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
youhit = B_FALSE; youhit = B_FALSE;
} }
} }
// an actual physical shield?
shield = getshield(target);
if (shield && hasfreeaction(target)) {
// block chance based on shield skill
if (skillcheck(target, SC_SHIELDBLOCK, 14 + (speed*2), 0)) {
int throwdam,dam;
if (seen) {
char shname[BUFLEN];
real_getobname(shield, shname, 1, B_TRUE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
if (isplayer(target)) {
msg("You block %s with your %s.", obname, noprefix(shname));
} else {
msg("%s blocks %s with %s.", targetname, obname, shname);
}
announcedmiss = B_TRUE;
}
// damage shield
throwdam = getthrowdam(o);
dam = throwdam + speed;
takedamage(shield, dam, DT_PROJECTILE);
youhit = B_FALSE;
practice(target, SK_SHIELDS, 1);
missiledam += ((speed*2)+1); // an actual physical shield?
} sprintf(attackname, "%s", obname);
difficulty = 14 + (speed*2);
if (check_for_block(thrower, target, getthrowdam(o) + speed, DT_PROJECTILE, difficulty, attackname)) {
announcedmiss = B_TRUE;
youhit = B_FALSE;
missiledam += ((speed*2)+1);
} }
} }
@ -12403,7 +12403,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) {
} }
} }
} else if (oid == OT_TRAPALARM) { } else if (oid == OT_TRAPALARM) {
noise(c, NULL, NC_OTHER, 10, "a blaring siren!", NULL); noise(c, NULL, NC_OTHER, 10, "a blaring siren!", "A blaring siren goes off!");
} else if ((oid == OT_TRAPARROW) || (oid == OT_TRAPARROWP)) { } else if ((oid == OT_TRAPARROW) || (oid == OT_TRAPARROWP)) {
int dir,bestdir = D_NONE; int dir,bestdir = D_NONE;
cell_t *src = NULL; cell_t *src = NULL;

View File

@ -175,7 +175,7 @@ int isdangerousob(object_t *o, lifeform_t *lf, int onlyifknown);
int isdeadob(object_t *o); int isdeadob(object_t *o);
int isdrinkable(object_t *o); int isdrinkable(object_t *o);
int isedible(object_t *o); int isedible(object_t *o);
int isequipped(object_t *o); flag_t *isequipped(object_t *o);
int isequippedon(object_t *o, enum BODYPART bp); int isequippedon(object_t *o, enum BODYPART bp);
int isfirearm(object_t *o); int isfirearm(object_t *o);
int isflammable(object_t *o); int isflammable(object_t *o);

248
shops.c
View File

@ -553,19 +553,31 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
int y; int y;
char buf[BUFLEN], buf2[BUFLEN], choices[BUFLENSMALL]; char buf[BUFLEN], buf2[BUFLEN], choices[BUFLENSMALL];
char ch; char ch;
static enum {
BUY,
EXAMINE
} shopmode = BUY;
y = starty; y = starty;
// list objects for sale // list objects for sale
for (o = vm->contents->first ; o ; o = o->next) { for (o = vm->contents->first ; o ; o = o->next) {
char obname[BUFLEN]; char obname[BUFLEN];
int thisprice; int thisprice;
enum COLOUR col;
getshopobname(o, obname, o->amt); getshopobname(o, obname, o->amt);
thisprice = (int)getshopprice(o, player); thisprice = (int)getshopprice(o, player);
snprintf(buf, BUFLEN, "%c - %s", o->letter, obname); snprintf(buf, BUFLEN, "%c - %s", o->letter, obname);
snprintf(buf2, BUFLEN, "^%d%-60s$%d", if (shopmode == BUY) {
(countmoney(player->pack) >= thisprice) ? C_GREY : C_RED, if (countmoney(player->pack) >= thisprice) {
buf, thisprice); col = C_GREY;
} else {
col = C_RED;
}
} else {
col = C_GREY;
}
snprintf(buf2, BUFLEN, "^%d%-60s$%d", col, buf, thisprice);
wmove(mainwin, y, 0); wmove(mainwin, y, 0);
textwithcol(mainwin, buf2); textwithcol(mainwin, buf2);
y++; y++;
@ -581,140 +593,150 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
y++; y++;
// ask what to do // ask what to do
mvwprintw(mainwin, y, 0, "What will you buy (ESC when done)? "); mvwprintw(mainwin, y, 0, "What will you %s (ESC when done)? ", (shopmode == BUY) ? "buy" : "examine");
ch = getch(); ch = getch();
if (ch == 27) { if (ch == 27) {
strcpy(toptext, ""); strcpy(toptext, "");
return SR_BACK; return SR_BACK;
} else if (ch == '?') {
if (shopmode == BUY) {
shopmode = EXAMINE;
} else {
shopmode = BUY;
}
} else { } else {
// try to find that object... // try to find that object...
o = hasobletter(vm->contents, ch); o = hasobletter(vm->contents, ch);
if (o) { if (o) {
enum SKILLLEVEL slev; if (shopmode == EXAMINE) {
char obname[BUFLEN],validchars[BUFLENSMALL]; describeob(o);
char answer; } else {
int value; enum SKILLLEVEL slev;
char obname[BUFLEN],validchars[BUFLENSMALL];
char answer;
int value;
value = (int)getshopprice(o, player); value = (int)getshopprice(o, player);
slev = getskill(player, SK_THIEVERY); slev = getskill(player, SK_THIEVERY);
// confirm // confirm
getshopobname(o, obname, o->amt); getshopobname(o, obname, o->amt);
snprintf(buf, BUFLEN, "Buy%s %s for $%d?", slev ? "/steal" : "", obname, value); snprintf(buf, BUFLEN, "Buy%s %s for $%d?", slev ? "/steal" : "", obname, value);
strcpy(validchars, "yn"); strcpy(validchars, "yn");
if (slev) { if (slev) {
strcat(validchars, "s"); strcat(validchars, "s");
} }
answer = askchar(buf, validchars,"n", B_TRUE, B_FALSE); answer = askchar(buf, validchars,"n", B_TRUE, B_FALSE);
if (answer == 'y') { if (answer == 'y') {
// prompt to use a card // prompt to use a card
if (hasob(player->pack, OT_CREDITCARD)) { if (hasob(player->pack, OT_CREDITCARD)) {
char ch2; char ch2;
ch2 = askchar("Charge this purchase to your credit card?","yn","n", B_TRUE, B_FALSE); ch2 = askchar("Charge this purchase to your credit card?","yn","n", B_TRUE, B_FALSE);
if (ch2 == 'y') { if (ch2 == 'y') {
object_t *cc; object_t *cc;
// ask which one // ask which one
initprompt(&prompt, "Which credit card will you use?"); initprompt(&prompt, "Which credit card will you use?");
for (cc = player->pack->first ; cc ; cc = cc->next) { for (cc = player->pack->first ; cc ; cc = cc->next) {
if (cc->type->id == OT_CREDITCARD) { if (cc->type->id == OT_CREDITCARD) {
char cardname[BUFLEN]; char cardname[BUFLEN];
getobname(cc, cardname, 1); getobname(cc, cardname, 1);
addchoice(&prompt, cc->letter, cardname, cardname, cc, NULL); addchoice(&prompt, cc->letter, cardname, cardname, cc, NULL);
}
} }
} if (prompt.nchoices == 1) {
if (prompt.nchoices == 1) { // only one card?
// only one card? cc = (object_t *)prompt.choice[0].data;
cc = (object_t *)prompt.choice[0].data;
} else {
addchoice(&prompt, '-', "(cancel)", "(cancel)", NULL, NULL);
prompt.maycancel = B_TRUE;
getchoice(&prompt);
cc = (object_t *)prompt.result;
}
if (cc) {
if (getcharges(cc) >= getobvalue(o)) {
int shopamt;
// you got it!
usecharges(cc, getobvalue(o));
o->letter = '\0';
shopamt = o->amt; // avoid "purchased: 2 apples" when you only bought 1 but were holding 1
o = moveob(o, player->pack, ALL);
identify(o);
getobname(o, obname, shopamt);
snprintf(toptext, BUFLEN, "Charged to card: %c - %s", o->letter, obname);
if (npurchased) (*npurchased)++;
// god of thieves likes credit cards...
pleasegodmaybe(R_GODTHIEVES, (value/75));
return SR_CONTINUE;
} else { } else {
// maxed! addchoice(&prompt, '-', "(cancel)", "(cancel)", NULL, NULL);
usecharges(cc, getcharges(o)); // use up all remaining charges prompt.maycancel = B_TRUE;
// get kicked out getchoice(&prompt);
msg("^B\"Trying to use a maxed out card, eh? Get out of here, thief!\""); more(); cc = (object_t *)prompt.result;
// shop closes }
addflag(vm->flags, F_BANNEDLF, player->id, NA, NA, NULL); if (cc) {
return SR_QUIT; if (getcharges(cc) >= getobvalue(o)) {
int shopamt;
// you got it!
usecharges(cc, getobvalue(o));
o->letter = '\0';
shopamt = o->amt; // avoid "purchased: 2 apples" when you only bought 1 but were holding 1
o = moveob(o, player->pack, ALL);
identify(o);
getobname(o, obname, shopamt);
snprintf(toptext, BUFLEN, "Charged to card: %c - %s", o->letter, obname);
if (npurchased) (*npurchased)++;
// god of thieves likes credit cards...
pleasegodmaybe(R_GODTHIEVES, (value/75));
return SR_CONTINUE;
} else {
// maxed!
usecharges(cc, getcharges(o)); // use up all remaining charges
// get kicked out
msg("^B\"Trying to use a maxed out card, eh? Get out of here, thief!\""); more();
// shop closes
addflag(vm->flags, F_BANNEDLF, player->id, NA, NA, NULL);
return SR_QUIT;
}
} }
} }
} }
} // do you have enough money?
// do you have enough money? if (countmoney(player->pack) >= getobvalue(o) ) {
if (countmoney(player->pack) >= getobvalue(o) ) { int shopamt;
int shopamt; object_t *gold;
object_t *gold; gold = hasob(player->pack, OT_GOLD);
gold = hasob(player->pack, OT_GOLD); if (gold) {
if (gold) { // if so, buy it
// if so, buy it // lose money (do this first to avoid potential weight issues)
// lose money (do this first to avoid potential weight issues) givemoney(player, NULL, value);
givemoney(player, NULL, value); // clear o->letter
// clear o->letter o->letter = '\0';
// give object
shopamt = o->amt; // avoid "purchased: 2 apples" when you only bought 1 but were holding 1
o = moveob(o, player->pack, ALL);
identify(o);
getobname(o, obname, shopamt);
snprintf(toptext, BUFLEN, "Purchased: %c - %s", o->letter, obname);
if (npurchased) (*npurchased)++;
} else {
msg("You don't seem to have any money..."); more();
o = NULL;
}
} else {
msg("You can't afford that!"); more();
o = NULL;
}
} else if (answer == 's') { // steal
// skillcheck - difficulty based on total value of objects here
// 15 + value/50 means:
// $50 is diff 16
// $100 is diff 17
// $200 is diff 19
// $500 is diff 25
// $1000 is diff 35
if (skillcheck(player, SC_STEAL, 15+(value/50), 0)) {
int shopamt;
// success
o->letter = '\0'; o->letter = '\0';
// give object shopamt = o->amt; // avoid "stolen: 2 apples" when you only bought 1 but were holding 1
shopamt = o->amt; // avoid "purchased: 2 apples" when you only bought 1 but were holding 1
o = moveob(o, player->pack, ALL); o = moveob(o, player->pack, ALL);
identify(o); identify(o);
getobname(o, obname, shopamt); getobname(o, obname, shopamt);
snprintf(toptext, BUFLEN, "Purchased: %c - %s", o->letter, obname); snprintf(toptext, BUFLEN, "Stolen: %c - %s", o->letter, obname);
if (npurchased) (*npurchased)++;
} else { pleasegodmaybe(R_GODTHIEVES, (value/50));
msg("You don't seem to have any money..."); more();
o = NULL; o = NULL;
} else {
msg("^B\"HEY! Get out of my shop, thief!\""); more();
// shop closes
addflag(vm->flags, F_BANNEDLF, player->id, NA, NA, NULL);
return SR_QUIT;
} }
} else { } else {
msg("You can't afford that!"); more(); // cancelled
o = NULL; strcpy(toptext, "");
} }
} else if (answer == 's') { // steal } // end if shopmode == ...
// skillcheck - difficulty based on total value of objects here
// 15 + value/50 means:
// $50 is diff 16
// $100 is diff 17
// $200 is diff 19
// $500 is diff 25
// $1000 is diff 35
if (skillcheck(player, SC_STEAL, 15+(value/50), 0)) {
int shopamt;
// success
o->letter = '\0';
shopamt = o->amt; // avoid "stolen: 2 apples" when you only bought 1 but were holding 1
o = moveob(o, player->pack, ALL);
identify(o);
getobname(o, obname, shopamt);
snprintf(toptext, BUFLEN, "Stolen: %c - %s", o->letter, obname);
pleasegodmaybe(R_GODTHIEVES, (value/50));
o = NULL;
} else {
msg("^B\"HEY! Get out of my shop, thief!\""); more();
// shop closes
addflag(vm->flags, F_BANNEDLF, player->id, NA, NA, NULL);
return SR_QUIT;
}
} else {
// cancelled
strcpy(toptext, "");
}
} else { } else {
snprintf(toptext, BUFLEN, "No such item."); snprintf(toptext, BUFLEN, "No such item.");
} // end if o } // end if o

64
spell.c
View File

@ -102,8 +102,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
f = hasflag(ot->flags, F_STAMCOST); stamcost = getstamcost(user, abilid);
if (f) stamcost = f->val[0];
if (stamcost) { if (stamcost) {
if (getstamina(user) < stamcost) { if (getstamina(user) < stamcost) {
@ -1618,11 +1617,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// TODO: make this like eating/resting/etc ? // TODO: make this like eating/resting/etc ?
taketime(user, getactspeed(user)); taketime(user, getactspeed(user));
} else if (abilid == OT_A_SHIELDBASH) { } else if (abilid == OT_A_SHIELDBASH) {
object_t *shield; object_t *shield = NULL;
char dirch; char dirch;
flag_t *f; flag_t *f;
int badshield = B_FALSE; int badshield = B_FALSE;
int shpenalty,mod; int shpenalty,mod;
object_t *shieldlist[MAXPILEOBS];
int nshields,i;
char shname[BUFLEN], tname[BUFLEN]; char shname[BUFLEN], tname[BUFLEN];
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
@ -1630,8 +1631,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
return B_TRUE; return B_TRUE;
} }
shield = getshield(user); getallshields(user, DT_ALL, shieldlist, NULL, &nshields);
if (!shield || !isshield(shield)) { for (i = 0; i < nshields; i++) {
if (isshield(shieldlist[i])) {
shield = shieldlist[i];
break;
}
}
if (!shield) {
badshield = B_TRUE; badshield = B_TRUE;
} }
@ -2036,6 +2043,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
char targetname[BUFLEN]; char targetname[BUFLEN];
int badweapon = B_FALSE; int badweapon = B_FALSE;
flag_t *damflag; flag_t *damflag;
obpile_t *op = NULL;
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You lack the stability for a thrust while swimming."); if (isplayer(user)) msg("You lack the stability for a thrust while swimming.");
@ -2044,17 +2052,29 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
wep = getweapon(user); wep = getweapon(user);
if (!wep) { if (!wep) {
badweapon = B_TRUE; object_t *weplist[MAXPILEOBS];
} else if (getdamtype(wep) != DT_PIERCE) { int nweps;
badweapon = B_TRUE; // look for innate attack
getweapons(user, weplist, NULL, NULL, &op, &nweps);
if (nweps) {
wep = weplist[0];
} else {
badweapon = B_TRUE;
}
} }
damflag = hasflag(wep->flags, F_DAM); if (wep) {
if (!damflag) { if (getdamtype(wep) != DT_PIERCE) {
badweapon = B_TRUE; badweapon = B_TRUE;
}
damflag = hasflag(wep->flags, F_DAM);
if (!damflag) {
badweapon = B_TRUE;
}
} }
if (badweapon) { if (badweapon) {
if (isplayer(user)) msg("You need a long piercing weapon to perform a thrust!" ); if (isplayer(user)) msg("You need a long piercing weapon to perform a thrust!" );
if (op) killobpile(op);
return B_TRUE; return B_TRUE;
} }
@ -2064,6 +2084,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
targcell = askcoords(buf, "Thrust->", TT_MONSTER, user, 2, LOF_NEED, B_TRUE); targcell = askcoords(buf, "Thrust->", TT_MONSTER, user, 2, LOF_NEED, B_TRUE);
if (!targcell) { if (!targcell) {
msg("Cancelled."); msg("Cancelled.");
if (op) killobpile(op);
return TRUE; return TRUE;
} }
} }
@ -2071,6 +2092,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
target = targcell->lf; target = targcell->lf;
if (!target) { if (!target) {
if (isplayer(user)) msg("There is nobody there to attack!"); if (isplayer(user)) msg("There is nobody there to attack!");
if (op) killobpile(op);
return B_TRUE; return B_TRUE;
} }
getlfname(target, targetname); getlfname(target, targetname);
@ -2079,6 +2101,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
attacklf(user, target, wep, damflag); attacklf(user, target, wep, damflag);
killflag(f); killflag(f);
taketime(user, getattackspeed(user)); taketime(user, getattackspeed(user));
if (op) killobpile(op);
} else if (abilid == OT_A_TRAIN) { } else if (abilid == OT_A_TRAIN) {
// can we train? // can we train?
if (!user->skillpoints && !lfhasflag(user, F_HASNEWLEVEL)) { if (!user->skillpoints && !lfhasflag(user, F_HASNEWLEVEL)) {
@ -10448,6 +10471,25 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
return range; return range;
} }
int getstamcost(lifeform_t *lf, enum OBTYPE oid) {
int stamcost = -1;
flag_t *f;
f = lfhasflagval(lf, F_CANWILL, oid, NA, NA, NULL);
if (f) {
// override stamina cost?
texttospellopts(f->text, "stamcost:", &stamcost, NULL);
}
if (stamcost == -1) {
objecttype_t *ot;
ot = findot(oid);
if (ot) {
f = hasflag(ot->flags, F_STAMCOST);
if (f) stamcost = f->val[0];
}
}
return stamcost;
}
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf) { char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf) {
// default // default
strcpy(buf, ""); strcpy(buf, "");

View File

@ -27,6 +27,7 @@ enum SPELLSCHOOL getspellschool(enum OBTYPE spellid);
enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid); enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid);
enum SKILLLEVEL getspellskill(lifeform_t *lf, enum OBTYPE spellid); enum SKILLLEVEL getspellskill(lifeform_t *lf, enum OBTYPE spellid);
int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power); int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power);
int getstamcost(lifeform_t *lf, enum OBTYPE oid);
char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf); char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf);
int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repairablemats, int *cutoffpct, int *nmats); int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repairablemats, int *cutoffpct, int *nmats);
object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat); object_t *getworkhelpob(obpile_t *op, enum MATERIAL mat);

2
text.c
View File

@ -1674,6 +1674,7 @@ void texttospellopts(char *text, ... ) {
"needgrab:", "needgrab:",
"range:", "range:",
"race:", "race:",
"stamcost:",
NULL, NULL,
}; };
char argtype[] = { char argtype[] = {
@ -1682,6 +1683,7 @@ void texttospellopts(char *text, ... ) {
'b', 'b',
'i', 'i',
's', 's',
'i',
'\0', '\0',
}; };
char *wantname = NULL; char *wantname = NULL;

View File

@ -1403,6 +1403,7 @@ void killvault(vault_t *v) {
killlegend(v->legend); killlegend(v->legend);
} }
killflagpile(v->flags); killflagpile(v->flags);
v->flags = NULL;
// deallocate // deallocate
nextone = v->next; nextone = v->next;