- [+] adjust damage for size
* [+] repair armour * [+] armour "hardness" to reduce damage? - [+] fix resting while poisoned. - [+] shouldn't be able to attack while ethereal - [+] cursed scroll of mending should damage stuff - [+] spark should light unactivated candles/torches instead of igniting. * [+] askcoords: add a subprompt param: * [+] xp levels: - [+] stealing skill * [+] alarm spell - level 1 wild magic - [+] reduce damage when drunk (-1d3) * [+] better armour material damage immunities * [+] bug - lots of mosnters on same square - bug with f_numappear - [+] chat-> "go to x,y" (they must have los to there) - [+] reduce # objects in rooms again!!!! * [+] put gatekeeper on DLEV 6 - [+] bug: when doing a heavy blow, don't use weapon effects liek trip. - [+] don't show "[magic]" or [inspected] at end of game - [+] knockback bug: You flatten the kobold! The kobold slams into a rock floor! - [+] warn before dulling blade.... (if pretty high iq) - [+] monstesr should not start eating when enemies are nearby! - [+] increase weight of weapons - [+] fix up what counts as a heavy wep - [+] check throwing - i can throw a 6.5 javelin 6 squares with a str of 7!! - [+] eat blinkdog corpse for instant blink ability - [+] true strike (???, next xx attacks alway hits). xx is power/3 - [+] floating disc (summon) - [+] obscuring mist spell fixes
This commit is contained in:
parent
27d22df11d
commit
9db5f3aeec
34
ai.c
34
ai.c
|
@ -33,6 +33,11 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
db = B_TRUE;
|
||||
}
|
||||
|
||||
// mindless?
|
||||
if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// already targetting this lf?
|
||||
f = lfhasflagval(lf, F_TARGETLF, victim->id, NA, NA, NULL);
|
||||
if (f) {
|
||||
|
@ -723,7 +728,7 @@ void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
|||
if (db) dblog(".oO { walking from %d,%d towards f_targetcell (%d,%d) ... }", lf->cell->x, lf->cell->y, x, y);
|
||||
c = getcellat(lf->cell->map, x, y);
|
||||
if (c) {
|
||||
// target cell adjacent and something in the way?
|
||||
// try to move towards the cll
|
||||
if (movetowards(lf, c, DT_ORTH)) {
|
||||
// couldn't move towards it for some reason.
|
||||
// so stop trying.
|
||||
|
@ -765,7 +770,7 @@ int aipickup(lifeform_t *lf, object_t *o) {
|
|||
int aipickupok(lifeform_t *lf, object_t *o) {
|
||||
int ok = B_FALSE;
|
||||
if (isedible(o)) {
|
||||
if (caneat(lf, o)) {
|
||||
if (caneat(lf, o) && !isinbattle(lf)) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
} else if (canpickup(lf, o, 1)) {
|
||||
|
@ -992,8 +997,6 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
// attacks
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
target = gettargetlf(lf);
|
||||
// do we already have a target we are attacking?
|
||||
if (target) {
|
||||
|
@ -1036,7 +1039,6 @@ void aiturn(lifeform_t *lf) {
|
|||
///////////////////////////////////////////////
|
||||
// movement
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// do we have a target cell?
|
||||
f = hasflag(lf->flags, F_TARGETCELL);
|
||||
if (f) {
|
||||
|
@ -1064,6 +1066,9 @@ void aiturn(lifeform_t *lf) {
|
|||
} else if (haslos(lf, c) && (what->pile->where != c)) {
|
||||
// if you can see the cell and object isn't there anymore
|
||||
valid = B_FALSE;
|
||||
} else if (c->lf && !areenemies(lf, c->lf) && haslos(lf, c) && (getcelldist(lf->cell, c) == 1)) {
|
||||
// can see a non-enemy on top of the object, and we are adjacent
|
||||
valid = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1091,8 +1096,6 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// not attacking anyone in particular
|
||||
if (db) dblog(".oO { i do not have a target or can't move towards it. looking for one. }");
|
||||
|
||||
|
@ -1211,6 +1214,20 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// do we have armour which needs repairing?
|
||||
if (getskill(lf, SK_ARMOUR) >= PR_SKILLED) {
|
||||
if (db) dblog(".oO { do i have any armour to repair? }");
|
||||
// just try to use the ability - it'll fail if we have nothing
|
||||
// which we can repair.
|
||||
if (!useability(lf, OT_A_REPAIR, NULL, NULL)) {
|
||||
if (db) dblog(".oO { yes - done. }");
|
||||
// success
|
||||
return;
|
||||
} else {
|
||||
if (db) dblog(".oO { no armour to repair. }");
|
||||
}
|
||||
}
|
||||
|
||||
// pet movement - note that pets will only rest if their
|
||||
// master is resting. the normal rest code underneath this section
|
||||
// will never be called.
|
||||
|
@ -1823,6 +1840,9 @@ int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) {
|
|||
if (!operate(lf, o, lf->cell)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
// here on are special cases
|
||||
} else if (o->type->id == OT_ASHCONCEAL) {
|
||||
throwat(lf, o, lf->cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
235
attack.c
235
attack.c
|
@ -39,45 +39,46 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
|||
|
||||
if (armour) {
|
||||
int actualdam;
|
||||
flag_t *rust;
|
||||
int ar = 0;
|
||||
flag_t *rust, *f;
|
||||
|
||||
f = hasflag(armour->flags, F_ARMOURRATING);
|
||||
if (f) {
|
||||
ar = f->val[0];
|
||||
}
|
||||
|
||||
rust = hasflag(armour->flags, F_RUSTED);
|
||||
|
||||
actualdam = dam;
|
||||
|
||||
// adjust how much damage to do to armour
|
||||
if ( ((armour->type->id == OT_FLAKJACKET) && (damtype == DT_PROJECTILE)) ||
|
||||
(damtype == DT_ACID) ||
|
||||
hasflag(wep->flags, F_ARMOURPIERCE)) {
|
||||
hasflag(wep->flags, F_ARMOURPIERCE) ||
|
||||
rust ) {
|
||||
// ALL of damage reduction goes towards armour
|
||||
actualdam = dam;
|
||||
} else {
|
||||
switch (getskill(lf, SK_ARMOUR)) {
|
||||
default:
|
||||
case PR_INEPT:
|
||||
actualdam = dam;
|
||||
break;
|
||||
case PR_NOVICE: actualdam = pctof(90, dam); break;
|
||||
case PR_BEGINNER: actualdam = pctof(80, dam); break;
|
||||
case PR_ADEPT: actualdam = pctof(70, dam); break;
|
||||
case PR_SKILLED: actualdam = pctof(60, dam); break;
|
||||
case PR_EXPERT: actualdam = pctof(50, dam); break;
|
||||
case PR_MASTER: actualdam = pctof(40, dam); break;
|
||||
// SOME of the damage reduction goes towards the armour
|
||||
if (ar) {
|
||||
actualdam -= rnd(0,ar);
|
||||
limit(&actualdam, 0, NA);
|
||||
}
|
||||
limit(&actualdam, 1, NA);
|
||||
}
|
||||
|
||||
// modify for rust
|
||||
rust = hasflag(armour->flags, F_RUSTED);
|
||||
if (rust) {
|
||||
int multiplier = 1;
|
||||
switch (rust->val[0]) {
|
||||
case R_RUSTY:
|
||||
multiplier = 2;
|
||||
case R_VRUSTY:
|
||||
multiplier = 6;
|
||||
multiplier = 3;
|
||||
case R_TRUSTY:
|
||||
multiplier = 10;
|
||||
multiplier = 4;
|
||||
}
|
||||
actualdam *= multiplier;
|
||||
}
|
||||
|
||||
|
||||
// actually apply the damage to the armour
|
||||
damtaken = takedamage(armour,actualdam, damtype);
|
||||
}
|
||||
|
@ -106,7 +107,7 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
|
|||
}
|
||||
|
||||
|
||||
int attackcell(lifeform_t *lf, cell_t *c) {
|
||||
int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
||||
int validwep[MAXCANDIDATES];
|
||||
object_t *wep[MAXCANDIDATES];
|
||||
flag_t *damflag[MAXCANDIDATES], *f;
|
||||
|
@ -128,7 +129,7 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
|
||||
// anyone there? if so just attack.
|
||||
if (c->lf) {
|
||||
if (isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) {
|
||||
if (!force && isplayer(lf) && !areenemies(lf,c->lf) && (getraceclass(c->lf) != RC_PLANT)) {
|
||||
char ch;
|
||||
char victimname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
|
@ -158,10 +159,30 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
// has an impassable object?
|
||||
o = hasobwithflag(c->obpile, F_IMPASSABLE);
|
||||
if (o) {
|
||||
object_t *priwep;
|
||||
attacktype = AT_OB;
|
||||
attacktarget = o;
|
||||
|
||||
priwep = getweapon(lf);
|
||||
|
||||
// confirm ?
|
||||
if (!force && isplayer(lf) && wepdullable(priwep) && (getiqname(getattr(player, A_IQ), NULL) >= IQ_SMART) ) {
|
||||
char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN];
|
||||
char ch;
|
||||
real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE);
|
||||
getobname(priwep, wepname, priwep->amt);
|
||||
sprintf(buf, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname));
|
||||
ch = askchar(buf, "yn","n", B_TRUE);
|
||||
if (ch == 'n') {
|
||||
// cancel.
|
||||
return B_TRUE;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// TODO: attack wall?
|
||||
if (isplayer(lf)) {
|
||||
msg("There is nothing there to attack!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +356,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
char victimname[BUFLEN];
|
||||
int fatal = B_FALSE;
|
||||
int deflected = B_FALSE;
|
||||
int weppassthrough = B_FALSE;
|
||||
int firstisbackstab = B_FALSE;
|
||||
int hit = B_FALSE;
|
||||
int critical = 0;
|
||||
|
@ -346,6 +368,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
int isunarmed = B_FALSE;
|
||||
|
||||
int aidb = B_FALSE;
|
||||
flag_t *f;
|
||||
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
|
@ -394,10 +417,41 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
// ie. you have been made noncorporeal
|
||||
if ((f->id == F_NONCORPOREAL) && (f->lifetime != FROMRACE)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Your attack passes straight through %s.", victimname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
}
|
||||
taketime(lf, getattackspeed(lf));
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// did you hit?
|
||||
ndam = 0;
|
||||
|
||||
|
||||
|
||||
hit = rolltohit(lf, victim, wep, &critical);
|
||||
|
||||
// weapon passing through ghosts etc?
|
||||
if (hit) {
|
||||
if (lfhasflag(victim, F_NONCORPOREAL) &&
|
||||
!lfhasflag(lf, F_NONCORPOREAL) ) {
|
||||
// using a magical or blessed weapon? if so you're ok.
|
||||
if (wep && (ismagical(wep) || isblessed(wep)) ) {
|
||||
} else {
|
||||
weppassthrough = B_TRUE;
|
||||
hit = B_FALSE;
|
||||
ndam = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// deflection?
|
||||
if (hit) {
|
||||
object_t *dwep;
|
||||
|
@ -469,6 +523,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
dam[0] = (int)((float)dam[0] * getstrdammod(lf));
|
||||
}
|
||||
|
||||
// modify for size
|
||||
modifyforsize(&dam[0], lf, victim, 5, M_PCT);
|
||||
|
||||
// backstab?
|
||||
if ((damtype[0] == DT_PIERCE) && // using a stabbing weapon
|
||||
getskill(lf, SK_BACKSTAB) && // able to backstab
|
||||
|
@ -519,7 +577,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (ndam > 0) {
|
||||
flag_t *f;
|
||||
for (i = 0; i < ndam; i++) {
|
||||
int reduceamt;
|
||||
int reduceamt = 0;
|
||||
int backstab = B_FALSE;
|
||||
flag_t *rust;
|
||||
|
||||
|
@ -686,8 +744,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
}
|
||||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW)) {
|
||||
wepeffects(wep->flags, victim->cell, damflag, dam[0]);
|
||||
}
|
||||
|
||||
// other effects
|
||||
if (!isdead(victim)) {
|
||||
|
@ -796,7 +856,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
} else { // miss!
|
||||
if (aidb) dblog(".oO { i missed! }");
|
||||
// announce it
|
||||
if (deflected) {
|
||||
if (weppassthrough) {
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s%s attack passes straight through %s!", attackername, getpossessive(attackername), victimname);
|
||||
}
|
||||
} else if (deflected) {
|
||||
if (cansee(player, lf)) {
|
||||
msg("%s deflect%s %s%s attack.", victimname, isplayer(victim) ? "" : "s",attackername, getpossessive(attackername));
|
||||
}
|
||||
|
@ -982,8 +1046,10 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
|
||||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW)) {
|
||||
wepeffects(wep->flags, obloc, damflag, dam[0]);
|
||||
}
|
||||
|
||||
if (isunarmed) {
|
||||
// touch effects
|
||||
|
@ -991,14 +1057,9 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
} else {
|
||||
// weapon gets damaged ?
|
||||
if (wep && (ndam > 0)) {
|
||||
switch (damtype[0]) {
|
||||
case DT_PIERCE:
|
||||
case DT_SLASH:
|
||||
if (wepdullable(wep)) {
|
||||
// weapon gets duller
|
||||
if (rnd(1,2)) makeduller(wep, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1630,19 +1691,83 @@ int isphysicaldam(enum DAMTYPE damtype) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// 'howmuch' is the numerical amount to adjust 'val' by for every size bracket
|
||||
// difference.
|
||||
//
|
||||
// if lf is bigger than victim, ADD howmuch.
|
||||
// if lf is smaller than victim, SUBTRACT howmuch.
|
||||
void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, enum MODTYPE how) {
|
||||
enum LFSIZE szlf,szvictim;
|
||||
|
||||
assert(val);
|
||||
|
||||
szlf = getlfsize(lf);
|
||||
szvictim = getlfsize(victim);
|
||||
if (szvictim < szlf) {
|
||||
// if defender is smaller...
|
||||
if (how == M_VAL) {
|
||||
// +howmuch per size difference
|
||||
*val += (howmuch * (szlf - szvictim));
|
||||
} else {
|
||||
// +(howmuch*sizediff)% of original value
|
||||
*val += (pctof(howmuch * (szlf - szvictim), *val));
|
||||
}
|
||||
} else if (szvictim > szlf) {
|
||||
// if defender is bigger...
|
||||
if (how == M_VAL) {
|
||||
// -howmuch per size difference
|
||||
*val -= (howmuch * (szvictim - szlf));
|
||||
} else {
|
||||
// +(howmuch*sizediff)% of original value
|
||||
*val -= (pctof(howmuch * (szlf - szvictim), *val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if we hit
|
||||
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) {
|
||||
int acc,ev;
|
||||
int gothit;
|
||||
enum LFSIZE szlf,szvictim;
|
||||
enum SKILLLEVEL slev;
|
||||
int myroll;
|
||||
flag_t *f;
|
||||
|
||||
|
||||
// base 5% critical chance - check this first.
|
||||
if (critical) {
|
||||
int critroll;
|
||||
critroll = rnd(1,100);
|
||||
|
||||
// default
|
||||
*critical = 0;
|
||||
|
||||
// modify for lore
|
||||
if (slev != PR_INEPT) {
|
||||
myroll += (slev*5); // ie. up to 30% bonus
|
||||
|
||||
}
|
||||
|
||||
if (critroll >= 95) *critical = 1;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_TRUESTRIKE);
|
||||
if (f) {
|
||||
if (f->val[0] > 1) {
|
||||
f->val[0]--;
|
||||
} else {
|
||||
killflag(f);
|
||||
}
|
||||
gothit = B_TRUE;
|
||||
} else if (critical) {
|
||||
gothit = B_TRUE;
|
||||
} else {
|
||||
// actually roll...
|
||||
acc = getlfaccuracy(lf, wep);
|
||||
|
||||
// size difference (penalty for attacking smaller ones)
|
||||
modifyforsize(&acc, lf, victim, -5, M_VAL);
|
||||
|
||||
// easier to hit victims who are prone.
|
||||
if (isprone(victim)) {
|
||||
acc += 30;
|
||||
}
|
||||
|
@ -1651,7 +1776,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
slev = getlorelevel(lf, victim->race->raceclass->id);
|
||||
|
||||
// modify for defender's evasion
|
||||
if (isprone(victim)) {
|
||||
if (isprone(victim) || !cansee(victim, lf)) {
|
||||
ev = 0;
|
||||
} else {
|
||||
ev = getevasion(victim);
|
||||
|
@ -1659,29 +1784,6 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
|
||||
acc -= ev;
|
||||
|
||||
// special case
|
||||
if (lfhasflag(victim, F_NONCORPOREAL) &&
|
||||
!lfhasflag(lf, F_NONCORPOREAL) ) {
|
||||
|
||||
// using a magical or blessed weapon?
|
||||
if (wep && (ismagical(wep) || isblessed(wep)) ) {
|
||||
} else {
|
||||
return B_FALSE; // automatic miss
|
||||
}
|
||||
}
|
||||
|
||||
// size difference
|
||||
szlf = getlfsize(lf);
|
||||
szvictim = getlfsize(victim);
|
||||
if (szvictim < szlf) {
|
||||
// if defender is smaller...
|
||||
// -7% per size difference
|
||||
acc -= (7 * (szlf - szvictim));
|
||||
} else if (szvictim > szlf) {
|
||||
// if defender is bigger...
|
||||
// +7% per size difference
|
||||
acc += (7 * (szvictim - szlf));
|
||||
}
|
||||
|
||||
// modify if we can't see the victim
|
||||
if (!cansee(lf, victim)) {
|
||||
|
@ -1698,23 +1800,11 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
acc += 50;
|
||||
}
|
||||
|
||||
// base 5% critical chance
|
||||
if (critical) {
|
||||
int critroll;
|
||||
critroll = rnd(1,100);
|
||||
|
||||
// modify for lore
|
||||
if (slev != PR_INEPT) {
|
||||
myroll += (slev*5); // ie. up to 30% bonus
|
||||
|
||||
}
|
||||
|
||||
if (critroll >= 95) *critical = 1;
|
||||
}
|
||||
|
||||
limit(&acc, 0, 100);
|
||||
|
||||
//if (aidb) dblog(".oO { my modified chance to hit is %d %% }", acc);
|
||||
|
||||
myroll = rnd(1,100);
|
||||
if (slev != PR_INEPT) {
|
||||
myroll += (slev*10);
|
||||
|
@ -1723,14 +1813,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
// modify for lore
|
||||
if (myroll <= acc) {
|
||||
gothit = B_TRUE;
|
||||
} else {
|
||||
if (critical && *critical) {
|
||||
// turn a miss into a hit
|
||||
gothit = B_TRUE;
|
||||
} else {
|
||||
gothit = B_FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return gothit;
|
||||
|
|
3
attack.h
3
attack.h
|
@ -2,7 +2,7 @@
|
|||
|
||||
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
|
||||
void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *dam, enum DAMTYPE damtype);
|
||||
int attackcell(lifeform_t *lf, cell_t *c);
|
||||
int attackcell(lifeform_t *lf, cell_t *c, int force);
|
||||
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
|
||||
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
|
||||
void confereffects(flagpile_t *fp, lifeform_t *victim);
|
||||
|
@ -22,5 +22,6 @@ float getstrdammod(lifeform_t *lf);
|
|||
//obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
|
||||
int ismeleedam(enum DAMTYPE damtype);
|
||||
int isphysicaldam(enum DAMTYPE damtype);
|
||||
void modifyforsize(int *val, lifeform_t *lf, lifeform_t *victim, int howmuch, enum MODTYPE how);
|
||||
int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical);
|
||||
void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam);
|
||||
|
|
27
defs.h
27
defs.h
|
@ -54,6 +54,7 @@ enum SKILL {
|
|||
SK_STEALTH,
|
||||
SK_SWIMMING,
|
||||
SK_TECHUSAGE,
|
||||
SK_THIEVERY,
|
||||
SK_TRACKING,
|
||||
SK_TRAPS,
|
||||
SK_TWOWEAPON,
|
||||
|
@ -87,7 +88,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 46
|
||||
#define MAXSKILLS 47
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -240,6 +241,11 @@ enum SENSE {
|
|||
// it will take to go from 'normal' to 'hungry' etc
|
||||
#define HUNGERCONST 200
|
||||
|
||||
enum MODTYPE {
|
||||
M_PCT,
|
||||
M_VAL,
|
||||
};
|
||||
|
||||
|
||||
// LIMITS
|
||||
|
||||
|
@ -610,8 +616,10 @@ enum RACECLASS {
|
|||
|
||||
enum RACE {
|
||||
R_NONE, R_RANDOM,
|
||||
R_HUMAN,
|
||||
// unique monstesr
|
||||
R_JAILER,
|
||||
// human monsters
|
||||
R_HUMAN,
|
||||
R_BANDIT,
|
||||
// monsters
|
||||
R_BEHOLDER,
|
||||
|
@ -705,8 +713,9 @@ enum RACE {
|
|||
R_SKELETON,
|
||||
R_ZOMBIE,
|
||||
// special
|
||||
R_GASCLOUD,
|
||||
R_DANCINGWEAPON,
|
||||
R_FLOATINGDISC,
|
||||
R_GASCLOUD,
|
||||
};
|
||||
|
||||
enum JOB {
|
||||
|
@ -935,6 +944,7 @@ enum OBTYPE {
|
|||
OT_S_ICICLE,
|
||||
OT_S_WALLOFICE,
|
||||
// -- gravity
|
||||
OT_S_TRUESTRIKE,
|
||||
OT_S_GRAVLOWER,
|
||||
OT_S_GRAVBOOST,
|
||||
OT_S_HASTE,
|
||||
|
@ -1000,6 +1010,7 @@ enum OBTYPE {
|
|||
OT_S_WARPWOOD,
|
||||
OT_S_WATERJET,
|
||||
// -- summoning
|
||||
OT_S_FLOATINGDISC,
|
||||
OT_S_CREATEMONSTER,
|
||||
OT_S_SUMMONWEAPON,
|
||||
// -- translocation
|
||||
|
@ -1010,6 +1021,7 @@ enum OBTYPE {
|
|||
OT_S_TELEPORT,
|
||||
OT_S_TWIDDLE,
|
||||
// -- wild
|
||||
OT_S_ALARM,
|
||||
OT_S_MANASPIKE,
|
||||
OT_S_DETONATE,
|
||||
OT_S_ENERGYBOLT,
|
||||
|
@ -1033,6 +1045,7 @@ enum OBTYPE {
|
|||
OT_A_CRUSH,
|
||||
OT_A_JUMP,
|
||||
OT_A_RAGE,
|
||||
OT_A_REPAIR,
|
||||
OT_A_SPRINT,
|
||||
OT_A_STINGACID, // need to define dam in f_canwill
|
||||
OT_A_SUCKBLOOD,
|
||||
|
@ -1043,6 +1056,7 @@ enum OBTYPE {
|
|||
OT_A_INSPECT,
|
||||
OT_A_HURRICANESTRIKE,
|
||||
OT_A_POLYREVERT,
|
||||
OT_A_STEAL,
|
||||
OT_A_WARCRY, // uses F_NOISETEXT -> N_WARCRY if it is there.
|
||||
// otherwise 'shouts a blood-curdling war cry'
|
||||
// wands
|
||||
|
@ -1061,6 +1075,8 @@ enum OBTYPE {
|
|||
OT_WAND_SLOW,
|
||||
OT_WAND_WEAKNESS,
|
||||
OT_WAND_WONDER,
|
||||
// tools - unique
|
||||
OT_ORBDUNGEONEXIT,
|
||||
// tools
|
||||
OT_BLANKET,
|
||||
OT_BLINDFOLD,
|
||||
|
@ -1467,6 +1483,8 @@ enum FLAG {
|
|||
F_HASBRAND, // has the object mod v0 (ie. OM_FLAMESTRIKE)
|
||||
F_HOLDCONFER, // gives flag v0+v1 when carried. v2 specifies if it must be id'd.
|
||||
F_EQUIPCONFER, // gives flag v0+v1 when weilded/worn. v2 specifies if it must be id'd.
|
||||
F_ACTIVATEPREFIX, // when activated, prefix this objects name with
|
||||
// text
|
||||
F_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
|
||||
|
||||
F_CRITKNOCKDOWN, // lf knocks down victims on a critical hit
|
||||
|
@ -1771,6 +1789,8 @@ enum FLAG {
|
|||
F_NOFLEE, // lf will not run away
|
||||
F_ATTACKRANGE, // v0/v1 = min/max celldist to stay away
|
||||
// from f_targetlf (ie. lf we are attacking)
|
||||
F_FOLLOWRANGE, // v0/v1 = min/max celldist to stay away
|
||||
// from pet's master
|
||||
F_TARGETLF, // lf will attack lfid v0. lastknown x/y is v1/v2
|
||||
// optional text is last known movement dir.
|
||||
F_IGNORECELL, // won't accept targetcells of v0=x v1=y
|
||||
|
@ -1931,6 +1951,7 @@ enum FLAG {
|
|||
F_RISEASGHOST, // become a ghost when you die.
|
||||
F_SEEINDARK, // nightvis range is val0
|
||||
F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0
|
||||
F_TRUESTRIKE, // your attacks ALWAYS hit. turnsleft=v0
|
||||
F_SEEINVIS, // can see invisible things
|
||||
F_STABILITY, // doesn't slip over
|
||||
F_STENCH, // creatures within v0 gain f_nauseated = v1
|
||||
|
|
8
flag.c
8
flag.c
|
@ -36,6 +36,12 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
known = B_KNOWN;
|
||||
}
|
||||
|
||||
if (id == F_INTERRUPTED) {
|
||||
if (fp->owner == player) {
|
||||
dblog("player got interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
if ((id == F_POISONED) && isimmuneto(fp, DT_POISON)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -186,7 +192,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
float pct;
|
||||
switch (f->id) {
|
||||
case F_ASLEEP:
|
||||
stopallspells(f->pile->owner);
|
||||
stopallspellsexcept(f->pile->owner, OT_S_ALARM, OT_NONE);
|
||||
break;
|
||||
case F_NONCORPOREAL:
|
||||
killflagsofid(f->pile->owner->flags, F_BEINGSTONED);
|
||||
|
|
249
io.c
249
io.c
|
@ -507,7 +507,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) {
|
|||
return ch;
|
||||
}
|
||||
|
||||
cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail) {
|
||||
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail) {
|
||||
static int startlf = -1;
|
||||
int finished = B_FALSE;
|
||||
int moved = B_FALSE;
|
||||
|
@ -849,7 +849,11 @@ cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange,
|
|||
|
||||
|
||||
wclear(msgwin);
|
||||
if (subprompt) {
|
||||
mvwprintw(msgwin, 0, 0, "%s%s", subprompt, buf);
|
||||
} else {
|
||||
mvwprintw(msgwin, 0, 0, "%s",buf);
|
||||
}
|
||||
wrefresh(msgwin);
|
||||
|
||||
// show our line of fire
|
||||
|
@ -1443,6 +1447,16 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_TRUESTRIKE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
if (f->val[0] > 1) {
|
||||
msg("Your next %d attacks will automatically hit.", f->val[0]);
|
||||
} else {
|
||||
msg("Your next attack will automatically hit.");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
if (isplayer(lf)) {
|
||||
msg("You are surrounded by a whirling cyclone!");
|
||||
|
@ -1928,6 +1942,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_TRUESTRIKE:
|
||||
// no message when you lose this.
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
msg("%s%s cyclonic shield vanishes.", lfname, getpossessive(lfname));
|
||||
|
@ -2804,48 +2821,105 @@ void describeob(object_t *o) {
|
|||
flag_t *f;
|
||||
int obknown;
|
||||
int i;
|
||||
int throwrange;
|
||||
|
||||
cls();
|
||||
|
||||
obknown = isknown(o);
|
||||
// title
|
||||
getobname(o, buf,o->amt);
|
||||
wattron(mainwin, A_BOLD);
|
||||
mvwprintw(mainwin, 0, 0, buf);
|
||||
wattroff(mainwin, A_BOLD);
|
||||
|
||||
// description
|
||||
getobdesc(o, buf);
|
||||
mvwprintw(mainwin, 2, 0, buf);
|
||||
|
||||
// append masterwork etc onto description
|
||||
f = hasflag(o->flags, F_MASTERWORK);
|
||||
if (f && f->known) {
|
||||
wprintw(mainwin, " It is extremely well crafted.");
|
||||
}
|
||||
f = hasflag(o->flags, F_SHODDY);
|
||||
if (f && f->known) {
|
||||
wprintw(mainwin, " It is very poorly crafted.");
|
||||
}
|
||||
|
||||
// properties
|
||||
|
||||
// weight
|
||||
y = 4;
|
||||
if (o->material->id != MT_FOOD) {
|
||||
mvwprintw(mainwin, y, 0, "%s made from %s.",(o->amt == 1) ? "It is" : "They are", o->material->name); y++;
|
||||
if (o->material->id == MT_FOOD) {
|
||||
sprintf(buf, "%s food product%s, ",(o->amt == 1) ? "It is a" : "They are",
|
||||
(o->amt == 1) ? "" : "s");
|
||||
} else {
|
||||
sprintf(buf, "%s made from %s, ",(o->amt == 1) ? "It is" : "They are", o->material->name);
|
||||
}
|
||||
|
||||
if (o->amt == 1) {
|
||||
char wbuf[BUFLEN];
|
||||
getweighttext(getobweight(o), wbuf);
|
||||
sprintf(buf2, "and weighs %s.",wbuf);
|
||||
strcat(buf, buf2);
|
||||
} else {
|
||||
char wbuf[BUFLEN];
|
||||
char wbuf2[BUFLEN];
|
||||
getweighttext(getobweight(o), wbuf);
|
||||
getweighttext(getobunitweight(o), wbuf2);
|
||||
sprintf(buf2, "and weigh %s (%s each).",wbuf, wbuf2);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "%s",buf);
|
||||
y++;
|
||||
|
||||
throwrange = getmaxthrowrange(player, o);
|
||||
if (throwrange >= 1) {
|
||||
mvwprintw(mainwin, y, 0, " You could throw %s %d metres.",(o->amt == 1) ? "it" : "one", throwrange);
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, " It is too heavy for you to throw.");
|
||||
}
|
||||
y++;
|
||||
|
||||
f = hasflag(o->flags, F_THROWMISSILE);
|
||||
if (f) {
|
||||
if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT)) {
|
||||
int dam;
|
||||
dam = getthrowdam(o);
|
||||
mvwprintw(mainwin, y, 0, " %s good for throwing [base damage %d].",(o->amt == 1) ? "It is" : "They are", dam);
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, " %s good for throwing.", (o->amt == 1) ? "It is" : "They are");
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
if (isedible(o)) {
|
||||
int basenutr;
|
||||
basenutr = getnutritionbase(o);
|
||||
mvwprintw(mainwin, y, 0, "%s edible.",(o->amt == 1) ? "It is" : "They are"); y++;
|
||||
mvwprintw(mainwin, y, 0, "%s %s.",(o->amt == 1) ? "It is" : "They are each", getfillingname(basenutr)); y++;
|
||||
}
|
||||
|
||||
|
||||
if (o->amt == 1) {
|
||||
getweighttext(getobweight(o), buf);
|
||||
mvwprintw(mainwin, y, 0, "It weighs %s.",buf);
|
||||
} else {
|
||||
getweighttext(getobweight(o), buf);
|
||||
getweighttext(getobunitweight(o), buf2);
|
||||
mvwprintw(mainwin, y, 0, "They weigh %s (%s each).",buf, buf2);
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "%s edible, and %s %s.",
|
||||
(o->amt == 1) ? "It is" : "They are",
|
||||
(o->amt == 1) ? "is" : "are each",
|
||||
getfillingname(basenutr));
|
||||
y++;
|
||||
if (hasflagval(o->flags, F_OBHPDRAIN, NA, DT_DECAY, NA, NULL)) {
|
||||
// don't show "it will rot" if it's already rotten (and you know this)
|
||||
if (isrotting(o) && ( (getiqname(getattr(player, A_IQ), NULL) >= IQ_SMART) || getskill(player, SK_COOKING)) ) {
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, "%s will decay and go bad over time.", (o->amt == 1) ? "It" : "They" );
|
||||
y++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// weapons?
|
||||
if (o->type->obclass->id == OC_WEAPON) {
|
||||
int delay;
|
||||
mvwprintw(mainwin, y, 0, "It is a weapon.");
|
||||
y++;
|
||||
if (hasflag(o->flags, F_DAM)) {
|
||||
int bonus = 0;
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_BONUS);
|
||||
if (f && f->known) {
|
||||
// only tell player about bonuses if they are known.!
|
||||
|
@ -2865,9 +2939,9 @@ void describeob(object_t *o) {
|
|||
if (maxdam < 0) maxdam = 0;
|
||||
|
||||
if (mindam == maxdam) {
|
||||
sprintf(buf, "It inflicts %d %s damage",maxdam, getdamname(damtype));
|
||||
sprintf(buf, " It inflicts %d %s damage",maxdam, getdamname(damtype));
|
||||
} else {
|
||||
sprintf(buf, "It inflicts %d-%d %s damage",mindam,maxdam, getdamname(damtype));
|
||||
sprintf(buf, " It inflicts %d-%d %s damage",mindam,maxdam, getdamname(damtype));
|
||||
}
|
||||
|
||||
//dicetotext(f->val[0], f->val[1], f->val[2], NULL, NULL, dicebuf, NULL);
|
||||
|
@ -2879,7 +2953,6 @@ void describeob(object_t *o) {
|
|||
mvwprintw(mainwin, y, 0, "%s",buf);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
// other extra damage or effects?
|
||||
f = hasflag(o->flags, F_ONFIRE);
|
||||
|
@ -2891,44 +2964,68 @@ void describeob(object_t *o) {
|
|||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
delay = 100;
|
||||
f = hasflag(o->flags, F_OBATTACKDELAY);
|
||||
if (f) {
|
||||
delay = f->val[0];
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "Its attack delay is %d%%.",delay - 100);
|
||||
mvwprintw(mainwin, y, 0, " Its attack delay is %d%%.",delay - 100);
|
||||
y++;
|
||||
|
||||
f = hasflag(o->flags, F_ACCURACY);
|
||||
if (f) {
|
||||
int acc;
|
||||
acc = getobaccuracy(o, NULL);
|
||||
mvwprintw(mainwin, y, 0, "It has %s accuracy.",getaccuracyname(acc));
|
||||
mvwprintw(mainwin, y, 0, " It has %s accuracy.",getaccuracyname(acc));
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_DISARMATTACK);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "A skilled weilder can disarm opponents with it.");
|
||||
mvwprintw(mainwin, y, 0, " A skilled weilder can disarm opponents with it.");
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_TRIPATTACK);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "A skilled weilder can trip opponents with it.");
|
||||
mvwprintw(mainwin, y, 0, " A skilled weilder can trip opponents with it.");
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_ARMOURPIERCE);
|
||||
if (f && f->known) {
|
||||
mvwprintw(mainwin, y, 0, " Armour will not reduce %s damage.",(o->amt == 1) ? "its" : "their");
|
||||
y++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// damage
|
||||
if (isarmour(o)) {
|
||||
f = hasflag(o->flags, F_GOESON);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It is worn %s your %s.",getbodypartequipname(f->val[0]), getbodypartname(f->val[0]));
|
||||
y++;
|
||||
sprintf(buf, "It is worn %s your %s, ",getbodypartequipname(f->val[0]), getbodypartname(f->val[0]));
|
||||
} else {
|
||||
strcpy(buf, "");
|
||||
}
|
||||
f = hasflag(o->flags, F_ARMOURRATING);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It has an Armour Rating of %d.",f->val[0] + getobbonus(o));
|
||||
if (strlen(buf)) {
|
||||
sprintf(buf2, "and has an Armour Rating of %d.",f->val[0] + getobbonus(o));
|
||||
strcat(buf, buf2);
|
||||
} else {
|
||||
sprintf(buf, "It has an Armour Rating of %d.",f->val[0] + getobbonus(o));
|
||||
}
|
||||
} else {
|
||||
if (strlen(buf)) {
|
||||
sprintf(buf2, "and provides no protection.");
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "%s",buf);
|
||||
y++;
|
||||
f = hasflag(o->flags, F_SCARY);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, " It may unnerve others when worn.");
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
@ -2946,36 +3043,12 @@ void describeob(object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_THROWMISSILE);
|
||||
if (f) {
|
||||
if (lfhasflag(player, F_EXTRAINFO) || lfhasflag(player, F_OMNIPOTENT)) {
|
||||
int dam;
|
||||
dam = getthrowdam(o);
|
||||
mvwprintw(mainwin, y, 0, "%s good for throwing [base damage %d].",(o->amt == 1) ? "It is" : "They are", dam);
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, "%s good for throwing.", (o->amt == 1) ? "It is" : "They are");
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_ARMOURPIERCE);
|
||||
if (f && f->known) {
|
||||
mvwprintw(mainwin, y, 0, "Armour will not reduce %s damage.",(o->amt == 1) ? "its" : "their");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_PICKLOCKS);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "You can use it to pick locks.");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_SCARY);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It may unnerve others when worn.");
|
||||
y++;
|
||||
}
|
||||
|
||||
// skip line
|
||||
y++;
|
||||
|
@ -3061,9 +3134,8 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
|
||||
// been made invulnerable ?
|
||||
if (hasflag(o->type->flags, F_DAMAGABLE) && !hasflag(o->flags, F_DAMAGABLE)) {
|
||||
if (hasflag(o->type->flags, F_INVULNERABLE) && !hasflag(o->flags, F_DAMAGABLE)) {
|
||||
mvwprintw(mainwin, y, 0, "It has been rendered invulnerable to most damage.");
|
||||
y++;
|
||||
}
|
||||
|
@ -3081,16 +3153,6 @@ void describeob(object_t *o) {
|
|||
|
||||
|
||||
// physical properties
|
||||
f = hasflag(o->flags, F_MASTERWORK);
|
||||
if (f && f->known) {
|
||||
mvwprintw(mainwin, y, 0, "It is extremely well crafted.");
|
||||
y++;
|
||||
}
|
||||
f = hasflag(o->flags, F_SHODDY);
|
||||
if (f && f->known) {
|
||||
mvwprintw(mainwin, y, 0, "It is very poorly crafted.");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_ONFIRE);
|
||||
if (f) {
|
||||
|
@ -3311,6 +3373,9 @@ void describeob(object_t *o) {
|
|||
case F_TREMORSENSE:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to 'see' by sensing vibrations around you.", buf); y++;
|
||||
break;
|
||||
case F_TRUESTRIKE:
|
||||
mvwprintw(mainwin, y, 0, "%s makes your attacks automatically hit.", buf); y++;
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
mvwprintw(mainwin, y, 0, "%s will surround you with a cyclonic shield.", buf); y++;
|
||||
break;
|
||||
|
@ -3350,7 +3415,6 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
|
||||
// requirements
|
||||
i = B_FALSE;
|
||||
for (f = o->flags->first ; f ; f = f->next) {
|
||||
|
@ -3499,10 +3563,7 @@ void doattackcell(char dirch) {
|
|||
f->val[2] = dirch;
|
||||
}
|
||||
|
||||
if (attackcell(player, c)) {
|
||||
// failed
|
||||
msg("There is nothing there to attack!");
|
||||
}
|
||||
attackcell(player, c, B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3561,9 +3622,11 @@ void docomms(void) {
|
|||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
char ch;
|
||||
enum IQBRACKET iqb;
|
||||
flag_t *f;
|
||||
|
||||
where = askcoords("Talk to who?", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
|
||||
where = askcoords("Talk to who?", "Talk->", TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf && cansee(player, where->lf)) {
|
||||
lf = where->lf;
|
||||
}
|
||||
|
@ -3576,22 +3639,33 @@ void docomms(void) {
|
|||
sprintf(buf, "What will you say to %s?",lfname);
|
||||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
|
||||
iqb = getiqname(getattr(lf, A_IQ), NULL);
|
||||
|
||||
// are they friendly?
|
||||
if (ispetof(lf, player)) {
|
||||
if (iqb >= IQ_ANIMAL) {
|
||||
addchoice(&prompt, 'a', "Attack something", NULL, NULL);
|
||||
}
|
||||
|
||||
if (!isadjacent(lf->cell, player->cell)) {
|
||||
addchoice(&prompt, 'c', "Come here", NULL, NULL);
|
||||
}
|
||||
|
||||
addchoice(&prompt, 'g', "Go somewhere", NULL, NULL);
|
||||
|
||||
if (isadjacent(lf->cell, player->cell) && !lfhasflag(lf, F_NOPACK)) {
|
||||
addchoice(&prompt, 't', "Trade items with me", NULL, NULL);
|
||||
}
|
||||
|
||||
if (iqb >= IQ_ANIMAL) {
|
||||
f = isresting(lf);
|
||||
if (f) {
|
||||
addchoice(&prompt, 'r', "Stop resting.", NULL, NULL);
|
||||
} else {
|
||||
addchoice(&prompt, 'r', "Rest until you are healed.", NULL, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL);
|
||||
}
|
||||
|
@ -3602,10 +3676,12 @@ void docomms(void) {
|
|||
cell_t *c;
|
||||
lifeform_t *lf2 = NULL;
|
||||
char lfname2[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
case 'a':
|
||||
sprintf(buf, "Tell %s to attack who?",lfname);
|
||||
c = askcoords(buf, TT_MONSTER, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && c->lf && cansee(player, c->lf)) {
|
||||
sprintf(buf2, "%s->Attack->",lfname);
|
||||
c = askcoords(buf, buf2, TT_MONSTER, lf, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && c->lf && cansee(lf, c->lf)) {
|
||||
lf2 = c->lf;
|
||||
|
||||
}
|
||||
|
@ -3629,6 +3705,18 @@ void docomms(void) {
|
|||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
sprintf(buf, "Tell %s to go where?",lfname);
|
||||
sprintf(buf2, "%s->Goto->",lfname);
|
||||
c = askcoords(buf, buf2, TT_NONE, lf, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (c && cellwalkable(lf, c, NULL) && cansee(lf, c->lf)) {
|
||||
} else {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
msg("You say \"Go over there!\" to %s.", lfname);
|
||||
aigoto(lf, c, MR_OTHER, NULL, AI_FOLLOWTIME);
|
||||
break;
|
||||
case 'n':
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
|
@ -4549,7 +4637,7 @@ void doenter(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
void doexplain(char *question) {
|
||||
askcoords(question, TT_NONE, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
askcoords(question, "", TT_NONE, player, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
restoregamewindows();
|
||||
msg("Done.");
|
||||
}
|
||||
|
@ -4901,7 +4989,7 @@ void dorest(void) {
|
|||
void doselguntarget(void) {
|
||||
object_t *gun;
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
char gunname[BUFLEN];
|
||||
gun = getfirearm(player);
|
||||
if (!gun) {
|
||||
|
@ -4911,7 +4999,8 @@ void doselguntarget(void) {
|
|||
getobname(gun, gunname, 1);
|
||||
|
||||
sprintf(buf, "Aim %s where?",gunname);
|
||||
where = askcoords(buf, TT_MONSTER, player, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
sprintf(buf2, "%s->Target->",gunname);
|
||||
where = askcoords(buf, buf2, TT_MONSTER, player, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
if (where) {
|
||||
if (where->lf && haslof(player->cell, where, LOF_NEED, NULL)) {
|
||||
setguntarget(player, where->lf);
|
||||
|
@ -4968,6 +5057,7 @@ void dothrow(obpile_t *op) {
|
|||
o = askobject(op, "Throw what", NULL, AO_NONE);
|
||||
if (o) {
|
||||
int maxdist;
|
||||
char subprompt[BUFLEN];
|
||||
cell_t *where;
|
||||
flag_t *f;
|
||||
getobname(o, buf, 1);
|
||||
|
@ -4983,7 +5073,8 @@ void dothrow(obpile_t *op) {
|
|||
|
||||
// ask where to throw it
|
||||
sprintf(buf2, "Throw %s where?",buf);
|
||||
where = askcoords(buf2, TT_MONSTER, player, maxdist, LOF_NEED, B_TRUE);
|
||||
sprintf(subprompt, "%s->Throw->",buf);
|
||||
where = askcoords(buf2, subprompt, TT_MONSTER, player, maxdist, LOF_NEED, B_TRUE);
|
||||
|
||||
if (where) {
|
||||
cell_t *newwhere = NULL;
|
||||
|
@ -8196,6 +8287,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around %s.", you(lf), you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_TREMORSENSE);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s%s attacks will automatically hit.", you(lf), getpossessive(you(lf)));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_WINDSHIELD);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s protected from missiles by a cyclonic shield", you(lf), is(lf));
|
||||
|
@ -8326,9 +8422,6 @@ void tombstone(lifeform_t *lf) {
|
|||
int y;
|
||||
char *p, *dummy;
|
||||
|
||||
|
||||
gamemode = GM_GAMEOVER;
|
||||
|
||||
getplayernamefull(pname);
|
||||
|
||||
// clear screen
|
||||
|
|
2
io.h
2
io.h
|
@ -21,7 +21,7 @@ object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, en
|
|||
object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...);
|
||||
int askobjectmulti(obpile_t *op, char *prompt, long opts);
|
||||
char askchar(char *prompt, char *validchars, char *def, int showchars);
|
||||
cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
|
||||
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
|
||||
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
|
||||
vault_t *askvault(char *prompttext);
|
||||
void centre(WINDOW *win, int y, char *format, ... );
|
||||
|
|
309
lf.c
309
lf.c
|
@ -1912,6 +1912,7 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
int fullyeaten = B_FALSE;
|
||||
flag_t *alreadyeating;
|
||||
enum HUNGER hlev,posthlev;
|
||||
int stopeating = B_FALSE;
|
||||
|
||||
if (hasflag(o->flags, F_DRINKABLE)) {
|
||||
drinking = B_TRUE;
|
||||
|
@ -2139,20 +2140,16 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
taketime(lf, amt);
|
||||
|
||||
if (fullyeaten) {
|
||||
// remove object
|
||||
removeob(o, 1);
|
||||
} else {
|
||||
// mark how much we ate
|
||||
f = hasflag(o->flags, F_EDIBLE);
|
||||
if (f) {
|
||||
f->val[2] = (int)(startpcteaten + pcteaten);
|
||||
}
|
||||
// special cases even if not fully eaten
|
||||
if (hasflagval(o->flags, F_CORPSEOF, R_DOGBLINK, NA, NA, NULL)) {
|
||||
// blink!
|
||||
dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE);
|
||||
|
||||
stopeating = B_TRUE;
|
||||
}
|
||||
|
||||
// stop eating if we are full
|
||||
if (!fullyeaten && (posthlev != hlev) && (posthlev <= H_FULL)) {
|
||||
int stopeating = B_FALSE;
|
||||
if (!stopeating && !fullyeaten && (posthlev != hlev) && (posthlev <= H_FULL)) {
|
||||
if (isplayer(lf)) {
|
||||
int ch;
|
||||
more();
|
||||
|
@ -2163,9 +2160,20 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
} else {
|
||||
stopeating = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (stopeating) {
|
||||
killflagsofid(lf->flags, F_EATING);
|
||||
}
|
||||
|
||||
if (fullyeaten) {
|
||||
// remove object
|
||||
removeob(o, 1);
|
||||
} else {
|
||||
// mark how much we ate
|
||||
f = hasflag(o->flags, F_EDIBLE);
|
||||
if (f) {
|
||||
f->val[2] = (int)(startpcteaten + pcteaten);
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
|
@ -2187,9 +2195,10 @@ void enhancerandomskill(lifeform_t *lf) {
|
|||
nposs++;
|
||||
}
|
||||
}
|
||||
if (nposs > 0) {
|
||||
sel = rnd(0,nposs-1);
|
||||
|
||||
giveskill(lf, poss[sel]);
|
||||
}
|
||||
}
|
||||
|
||||
void enhanceskills(lifeform_t *lf) {
|
||||
|
@ -2657,6 +2666,11 @@ int flee(lifeform_t *lf) {
|
|||
flag_t *f, *nextf;
|
||||
lifeform_t *fleefrom = NULL;
|
||||
|
||||
// mindless?
|
||||
if (getiqname(getattr(lf, A_IQ), NULL) == IQ_MINDLESS) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// are we fleeing?
|
||||
for (f = lf->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
|
@ -3414,6 +3428,8 @@ int getevasion(lifeform_t *lf) {
|
|||
if (ev < 0) ev = 0;
|
||||
|
||||
// modify for blindness
|
||||
// PLUS if you're blind, your evasion is 0 anyway for anyone
|
||||
// attacking you.
|
||||
if (isblind(lf)) {
|
||||
ev -= 15;
|
||||
}
|
||||
|
@ -4336,15 +4352,19 @@ char *getlfname(lifeform_t *lf, char *buf) {
|
|||
char *real_getlfname(lifeform_t *lf, char *buf, int usevis) {
|
||||
char descstring[BUFLEN];
|
||||
char jobstring[BUFLEN];
|
||||
char the[5];
|
||||
char the[6];
|
||||
job_t *j;
|
||||
flag_t *f;
|
||||
|
||||
// 'the' or 'your' ?
|
||||
if (ispetof(lf, player)) {
|
||||
strcpy(the, "your");
|
||||
if (lfhasflag(lf, F_UNIQUE)) {
|
||||
strcpy(the, "");
|
||||
} else {
|
||||
strcpy(the, "the");
|
||||
if (ispetof(lf, player)) {
|
||||
strcpy(the, "your ");
|
||||
} else {
|
||||
strcpy(the, "the ");
|
||||
}
|
||||
}
|
||||
|
||||
// construct description string
|
||||
|
@ -4379,9 +4399,9 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) {
|
|||
if (wep) {
|
||||
char obname[BUFLEN];
|
||||
real_getobname(wep, obname, 1, B_TRUE, B_FALSE, B_FALSE, B_FALSE, B_FALSE);
|
||||
sprintf(buf, "%s %s%s",the,descstring,noprefix(obname));
|
||||
sprintf(buf, "%s%s%s",the,descstring,noprefix(obname));
|
||||
} else {
|
||||
sprintf(buf, "%s %s%s%s",the,descstring,lf->race->name,jobstring);
|
||||
sprintf(buf, "%s%s%s%s",the,descstring,lf->race->name,jobstring);
|
||||
}
|
||||
} else {
|
||||
char zombiestring[BUFLEN];
|
||||
|
@ -4392,7 +4412,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis) {
|
|||
sprintf(zombiestring, " %s", f->text);
|
||||
}
|
||||
|
||||
sprintf(buf, "%s %s%s%s%s",the,descstring,lf->race->name,jobstring,zombiestring);
|
||||
sprintf(buf, "%s%s%s%s%s",the,descstring,lf->race->name,jobstring,zombiestring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4408,22 +4428,28 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, int usevis) {
|
|||
sprintf(buf, "you");
|
||||
} else {
|
||||
char buf2[BUFLEN];
|
||||
char the[5];
|
||||
char the[6];
|
||||
|
||||
real_getlfname(lf, buf2, usevis);
|
||||
|
||||
|
||||
if (lfhasflag(lf, F_UNIQUE)) {
|
||||
strcpy(the, "");
|
||||
} else {
|
||||
if (ispetof(lf, player)) {
|
||||
strcpy(the, "your");
|
||||
strcpy(the, "your ");
|
||||
} else {
|
||||
if (isvowel(lf->race->name[0])) {
|
||||
strcpy(the, "an");
|
||||
strcpy(the, "an ");
|
||||
} else {
|
||||
strcpy(the, "a");
|
||||
strcpy(the, "a ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buf, "%s %s", the, noprefix(buf2));
|
||||
|
||||
|
||||
|
||||
sprintf(buf, "%s%s", the, noprefix(buf2));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
@ -5127,8 +5153,14 @@ void getwantdistance(lifeform_t *lf, int *min, int *max, int attacking) {
|
|||
*max = f->val[1];
|
||||
}
|
||||
} else {
|
||||
// default - stay with 1-3 cells
|
||||
*min = 1;
|
||||
*max = 3;
|
||||
f = lfhasflag(lf, F_FOLLOWRANGE);
|
||||
if (f) {
|
||||
*min = f->val[0];
|
||||
*max = f->val[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5150,8 +5182,8 @@ object_t *getweapon(lifeform_t *lf) {
|
|||
long getxpforlev(int level) {
|
||||
long needxp = 0;
|
||||
// 2.8
|
||||
float multiplier = 10;
|
||||
float constant = 3.1;
|
||||
float multiplier = 13;
|
||||
float constant = 2.8;
|
||||
|
||||
// no xp needed for level 1
|
||||
/*
|
||||
|
@ -5427,11 +5459,14 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
if (id == SK_ATHLETICS) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
} else if (id == SK_ATHLETICS) {
|
||||
} else if (id == SK_COOKING) {
|
||||
makeknown(OT_POT_WATER);
|
||||
} else if (id == SK_LORE_ARCANA) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
} else if (id == SK_THIEVERY) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_STEAL, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
} else if (id == SK_TRAPS) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_DISARM, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
|
@ -5447,6 +5482,11 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
newf = addflag(lf->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_ARMOUR) {
|
||||
if (f->val[1] == PR_SKILLED) {
|
||||
newf = addflag(lf->flags, F_CANWILL, OT_A_REPAIR, NA, NA, NULL);
|
||||
newf->lifetime = FROMJOB;
|
||||
}
|
||||
} else if (id == SK_CARTOGRAPHY) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_NOVICE) {
|
||||
|
@ -5548,6 +5588,20 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (id == SK_THIEVERY) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_BEGINNER) {
|
||||
msg("Your accuracy penalty when stealing is reduced.");
|
||||
} else if (f->val[1] == PR_ADEPT) {
|
||||
msg("You can now steal specific items.");
|
||||
} else if (f->val[1] == PR_SKILLED) {
|
||||
msg("You can now steal heavy items.");
|
||||
} else if (f->val[1] == PR_EXPERT) {
|
||||
msg("You can now steal multiple items.");
|
||||
} else if (f->val[1] == PR_MASTER) {
|
||||
msg("You can now steal equipped items.");
|
||||
}
|
||||
}
|
||||
} else if (id == SK_TRACKING) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_NOVICE) {
|
||||
|
@ -6612,6 +6666,7 @@ void initjobs(void) {
|
|||
|
||||
addjob(J_PIRATE, "Pirate");
|
||||
// stats
|
||||
addflag(lastjob->flags, F_STARTATT, A_STR, NA, NA, "8-15");
|
||||
addflag(lastjob->flags, F_STARTATT, A_DEX, DX_DEXTROUS, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_CON, CN_HEALTHY, NA, NULL);
|
||||
// abilities
|
||||
|
@ -6643,6 +6698,8 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LORE_ARCANA, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_THIEVERY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TRACKING, NA, NA, NULL);
|
||||
|
||||
addjob(J_ROGUE, "Rogue");
|
||||
|
@ -6653,6 +6710,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "dagger");
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins");
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 lockpicks");
|
||||
addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL);
|
||||
|
@ -6661,6 +6719,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SPOTHIDDEN, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SHORTBLADES, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_THIEVERY, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL);
|
||||
|
@ -6764,6 +6823,37 @@ void initrace(void) {
|
|||
addraceclass(RC_SLIME, "slime", "slimes", SK_NONE);
|
||||
addraceclass(RC_UNDEAD, "undead", "the undead", SK_LORE_UNDEAD);
|
||||
|
||||
// unique monsters
|
||||
addrace(R_JAILER, "Jimbo", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID);
|
||||
addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 5, 2, NA, NULL);
|
||||
//addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
//addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d4");
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, ST_MIGHTY, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_DEX, NA, NA, "11-13");
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_STUPID, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_CON, CN_AVERAGE, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "gas mask");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "dungeon exit orb");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "concealing powder");
|
||||
addflag(lastrace->flags, F_FLEEONHPPCT, 40, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_POLEARMS, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTSKILL, SK_ARMOUR, PR_ADEPT, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_HEAVYBLOW, 2, 2, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_HURRICANESTRIKE, 2, 2, NULL);
|
||||
addflag(lastrace->flags, F_CANWILL, OT_A_RAGE, 20, 20, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// races / monsters
|
||||
addrace(R_HUMAN, "human", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
|
@ -6784,7 +6874,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
|
||||
// TODO: humans start with a random job sometimes?
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
|
||||
// addflag(lastrace->flags, F_RESTHEALMPAMT, 1, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// human monsters...
|
||||
|
@ -7833,7 +7922,7 @@ void initrace(void) {
|
|||
|
||||
addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL);
|
||||
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_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 1, 0, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
|
@ -8104,6 +8193,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "0d1+4");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
|
||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addrace(R_ANTS, "giant soldier ant", 25, 'a', C_BROWN, MT_FLESH, RC_ANIMAL);
|
||||
|
@ -8127,6 +8217,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:1d6+3;needgrab:1;");
|
||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
|
||||
addflag(lastrace->flags, F_MINIONS, 50, 1, 3, "giant worker ant");
|
||||
addrace(R_ANTLION, "giant antlion", 30, 'a', C_YELLOW, MT_FLESH, RC_ANIMAL);
|
||||
lastrace->baseid = R_ANT;
|
||||
|
@ -8149,6 +8240,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:2d4;");
|
||||
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
|
||||
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars");
|
||||
addrace(R_DOGBLINK, "blink dog", 35, 'd', C_YELLOW, MT_FLESH, RC_ANIMAL);
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 2, 8, NA, "");
|
||||
|
@ -8961,6 +9053,31 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
|
||||
addrace(R_FLOATINGDISC, "floating disc", 0, '_', C_BOLDGREEN, MT_METAL, RC_OTHER);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
|
||||
addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, "");
|
||||
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, "");
|
||||
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_FOLLOWRANGE, 1, 1, NA, NULL); // stay right next to master
|
||||
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEFTHAND, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_HEAD, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOBODYPART, BP_FEET, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
}
|
||||
|
||||
int isairborne(lifeform_t *lf) {
|
||||
|
@ -9041,6 +9158,10 @@ int ischarmable(lifeform_t *lf) {
|
|||
reason = E_DRUNK;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (hasflag(lf->flags, F_UNIQUE)) {
|
||||
reason = E_NOEFFECT; // generic error
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -9759,7 +9880,11 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
|
|||
// adjust for lifeform material
|
||||
//adjustdammaterial(amt, damtype, getlfmaterial(lf));
|
||||
|
||||
if (*amt < 0) *amt = 0;
|
||||
if (isdrunk(lf)) {
|
||||
*amt -= rnd(0,3);
|
||||
}
|
||||
|
||||
limit(amt, 0, NA);
|
||||
}
|
||||
|
||||
void makepeaceful(lifeform_t *who) {
|
||||
|
@ -10790,15 +10915,23 @@ int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seete
|
|||
|
||||
if ((l != noisemaker) && (l->cell)) {
|
||||
int difficulty;
|
||||
int lbonus;
|
||||
//if (canhear(l, c) && haslos(l, c)) {
|
||||
|
||||
// listen check difficulty is based on sound distance vs max hearing distance
|
||||
difficulty = (int) ( ((float)getcelldist(l->cell, c) / (float)gethearingrange(l)) * 20);
|
||||
// listen bonus is the sound volume
|
||||
|
||||
// listen bonus is the sound volume
|
||||
if (lfhasflag(l, F_ASLEEP)) {
|
||||
lbonus = 0;
|
||||
} else {
|
||||
lbonus = volume;
|
||||
}
|
||||
|
||||
// skillcheck to hear this
|
||||
if (canhear(l, c) &&
|
||||
(haslos(l, c) ||
|
||||
((dist <= sounddist) && skillcheck(l, SC_LISTEN, difficulty, volume)))) {
|
||||
((dist <= sounddist) && skillcheck(l, SC_LISTEN, difficulty, lbonus)))) {
|
||||
flag_t *f;
|
||||
// announce?
|
||||
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
|
||||
|
@ -10894,12 +11027,17 @@ int noise(cell_t *c, lifeform_t *noisemaker, int volume, char *text, char *seete
|
|||
}
|
||||
killflag(f);
|
||||
} else {
|
||||
// ie resting on purpose via 'r'
|
||||
// ie resting on purpose via 'R'
|
||||
// only wake up if the sound if very close
|
||||
if (getcelldist(c, l->cell) == 1) {
|
||||
//if (getcelldist(c, l->cell) == 1) {
|
||||
if (volume >= getcelldist(c, l->cell)) {
|
||||
// wake up!
|
||||
if (isplayer(l)) {
|
||||
msg("A nearby noise awakens you!");
|
||||
char wakenoise[BUFLEN];
|
||||
strcpy(wakenoise, text);
|
||||
wakenoise[strlen(wakenoise)-1] = '\0'; // omit punctuation
|
||||
//msg("A nearby noise awakens you!");
|
||||
msg("The sound of %s awakens you!", wakenoise);
|
||||
rv = B_TRUE;
|
||||
}
|
||||
killflag(f);
|
||||
|
@ -11959,7 +12097,7 @@ void setlastdam(lifeform_t *lf, char *buf) {
|
|||
}
|
||||
|
||||
void initskills(void) {
|
||||
addskill(SK_ARMOUR, "Armour", "Helps maintain armour, reducing evasion penalties and armour damage.");
|
||||
addskill(SK_ARMOUR, "Armour", "Lets you repair armour, and reduces evasion penalties from armour.");
|
||||
addskill(SK_ATHLETICS, "Athletics", "Assists with sprinting and exhaustion recovery.");
|
||||
addskill(SK_BACKSTAB, "Backstab", "Lets you inflict massive damage with stabs when unseen.");
|
||||
addskill(SK_CARTOGRAPHY, "Cartography", "Your ability to create and interpret maps.");
|
||||
|
@ -11975,6 +12113,7 @@ void initskills(void) {
|
|||
addskill(SK_STEALTH, "Stealth", "Affects your ability to move silently.");
|
||||
addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.");
|
||||
addskill(SK_TECHUSAGE, "Technology", "Determines your comprehension of modern technological items.");
|
||||
addskill(SK_THIEVERY, "Thievery", "Your ability to pick pockets and steal items.");
|
||||
addskill(SK_TRACKING, "Tracking", "Allows you to track enemies by their footprints.");
|
||||
addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.");
|
||||
addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.");
|
||||
|
@ -12504,6 +12643,38 @@ void stopsprinting(lifeform_t *lf) {
|
|||
|
||||
}
|
||||
|
||||
// very much like addmonster(), but announce that it appears
|
||||
// and make it worth zero xp.
|
||||
lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, int randomjobsok, job_t *forcejob, int lifetime, int wantfriendly) {
|
||||
lifeform_t *newlf = NULL;
|
||||
char buf[BUFLEN];
|
||||
newlf = addmonster(c, rid, randomjobsok, 1, B_FALSE, NULL);
|
||||
if (newlf) {
|
||||
// assign job if required
|
||||
if (forcejob) {
|
||||
givejob(newlf, forcejob->id);
|
||||
}
|
||||
if (haslos(player, c)) {
|
||||
//char *newbuf;
|
||||
getlfnamea(newlf, buf);
|
||||
capitalise(buf);
|
||||
msg("%s appears!", buf);
|
||||
}
|
||||
// summoned
|
||||
addflag(newlf->flags, F_SUMMONEDBY, caster->id, lifetime, NA, NULL);
|
||||
if (wantfriendly) {
|
||||
addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL);
|
||||
if (areallies(player, caster)) {
|
||||
makefriendly(newlf, PERMENANT);
|
||||
}
|
||||
}
|
||||
// not worth any xp
|
||||
killflagsofid(newlf->flags, F_XPVAL);
|
||||
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
}
|
||||
return newlf;
|
||||
}
|
||||
|
||||
// if this object is ammo, and we are using a gun
|
||||
// with no ammo, then equip it.
|
||||
int testammo(lifeform_t *lf, object_t *o) {
|
||||
|
@ -13014,28 +13185,8 @@ void turneffectslf(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
if (willvanish) {
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s vanishes.",
|
||||
(creator == player) ? "Your " : "",
|
||||
(creator == player) ? noprefix(lfname) : lfname
|
||||
);
|
||||
}
|
||||
|
||||
// all objects vanish
|
||||
while (lf->pack->first) {
|
||||
killob(lf->pack->first);
|
||||
}
|
||||
|
||||
// lf dies.
|
||||
lf->hp = 0;
|
||||
addflag(lf->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// puff
|
||||
addob(lf->cell->obpile, "puff of smoke");
|
||||
unsummon(lf, B_TRUE);
|
||||
}
|
||||
}
|
||||
if (isdead(lf)) return;
|
||||
|
@ -13056,7 +13207,11 @@ void turneffectslf(lifeform_t *lf) {
|
|||
// chance of losing hp
|
||||
if (rnd(1,100) <= getpoisondamchance(f->val[0])) {
|
||||
char buf[BUFLEN];
|
||||
if (!hasflag(lf->flags, F_ASLEEP)) {
|
||||
flag_t *asleep;
|
||||
// being asleep helps.
|
||||
|
||||
asleep = hasflag(lf->flags, F_ASLEEP);
|
||||
if (!asleep) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You %s violently.", getpoisondamverb(f->val[0]));
|
||||
} else if (cansee(player, lf)) {
|
||||
|
@ -13070,14 +13225,13 @@ void turneffectslf(lifeform_t *lf) {
|
|||
sprintf(buf, "poisoning^from %s",f->text);
|
||||
losehp(lf, f->val[1], DT_DIRECT, NULL, buf);
|
||||
|
||||
if (!hasflag(lf->flags, F_ASLEEP)) {
|
||||
if (!asleep) {
|
||||
if (poisoncausesvomit(f->val[0])) {
|
||||
addob(lf->cell->obpile, "pool of vomit");
|
||||
}
|
||||
}
|
||||
|
||||
loseconcentration(lf);
|
||||
}
|
||||
}
|
||||
|
||||
// extra effects
|
||||
if (f->val[0] == P_COLD) {
|
||||
|
@ -13425,6 +13579,37 @@ int touch(lifeform_t *lf, object_t *o) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void unsummon(lifeform_t *lf, int vanishobs) {
|
||||
lifeform_t *creator = NULL;
|
||||
flag_t *f;
|
||||
f = hasflag(lf->flags, F_SUMMONEDBY);
|
||||
if (f) {
|
||||
creator = findlf(NULL, f->val[0]);
|
||||
}
|
||||
|
||||
if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s vanishes.",
|
||||
(creator && (creator == player)) ? "Your " : "",
|
||||
(creator && (creator == player)) ? noprefix(lfname) : lfname
|
||||
);
|
||||
}
|
||||
|
||||
if (vanishobs) {
|
||||
// all objects vanish
|
||||
while (lf->pack->first) {
|
||||
killob(lf->pack->first);
|
||||
}
|
||||
}
|
||||
|
||||
lf->hp = 0;
|
||||
addflag(lf->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lf->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
|
||||
addob(lf->cell->obpile, "puff of smoke");
|
||||
}
|
||||
|
||||
int unweild(lifeform_t *lf, object_t *o) {
|
||||
flag_t *f;
|
||||
char obname[BUFLEN];
|
||||
|
|
2
lf.h
2
lf.h
|
@ -284,6 +284,7 @@ void stopeating(lifeform_t *lf);
|
|||
void stopresting(lifeform_t *lf);
|
||||
void stoprunning(lifeform_t *lf);
|
||||
void stopsprinting(lifeform_t *lf);
|
||||
lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, int randomjobsok, job_t *forcejob, int lifetime, int wantfriendly);
|
||||
int testammo(lifeform_t *lf, object_t *o);
|
||||
int takeoff(lifeform_t *lf, object_t *o);
|
||||
void taketime(lifeform_t *lf, long howlong);
|
||||
|
@ -292,6 +293,7 @@ void timeeffectslf(lifeform_t *lf);
|
|||
void turneffectslf(lifeform_t *lf);
|
||||
int touch(lifeform_t *lf, object_t *o);
|
||||
void unpoison(lifeform_t *lf);
|
||||
void unsummon(lifeform_t *lf, int vanishobs);
|
||||
int unweild(lifeform_t *lf, object_t *o);
|
||||
int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where);
|
||||
int useringofmiracles(lifeform_t *lf, int charges);
|
||||
|
|
9
map.c
9
map.c
|
@ -208,7 +208,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int auto
|
|||
// did we find one?
|
||||
if (!adjcell) break;
|
||||
|
||||
newlf = addlf(c, r->id, getrandommonlevel(r, adjcell->map));
|
||||
newlf = addlf(adjcell, r->id, getrandommonlevel(r, adjcell->map));
|
||||
if (!newlf) {
|
||||
break;
|
||||
}
|
||||
|
@ -523,8 +523,8 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
int sel;
|
||||
d = dodoor[i];
|
||||
getroomedge(map, roomid, minx, miny, maxx, maxy, d, cell, &ncells, B_TRUE);
|
||||
if (ncells) {
|
||||
sel = rnd(0,ncells-1);
|
||||
|
||||
if (rnd(1,100) <= doorpct) {
|
||||
makedoor(cell[sel]);
|
||||
doorsadded++;
|
||||
|
@ -534,6 +534,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (db) dblog("autodoors() added %d doors to roomid %d", doorsadded, roomid);
|
||||
return doorsadded;
|
||||
}
|
||||
|
@ -1465,8 +1466,8 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
}
|
||||
|
||||
numobsmin = 0;
|
||||
//numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||
numobsmax = MAXOF(roomw[i],roomh[i]);
|
||||
numobsmax = MAXOF(roomw[i],roomh[i]) / 2;
|
||||
//numobsmax = MAXOF(roomw[i],roomh[i]);
|
||||
|
||||
// then objects/monsters
|
||||
if (numobsmax <= numobsmin) {
|
||||
|
|
30
move.c
30
move.c
|
@ -250,7 +250,8 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
// ok
|
||||
} else if (cell->lf && (cell->lf != lf)) { // someone (else) in the wall?
|
||||
if (error) *error = E_LFINWAY; // ok but still set reason
|
||||
return B_FALSE;
|
||||
//return B_FALSE;
|
||||
// ok
|
||||
} else {
|
||||
if (error) *error = E_WALLINWAY;
|
||||
return B_FALSE;
|
||||
|
@ -623,6 +624,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
}
|
||||
if (reason != E_OK) {
|
||||
char buf[BUFLEN];
|
||||
char thing[BUFLEN];
|
||||
cell_t *newcell;
|
||||
newcell = getcellindir(lf->cell, dir);
|
||||
// failed to move
|
||||
|
@ -636,9 +638,16 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
}
|
||||
// fall through
|
||||
case E_WALLINWAY:
|
||||
if (seen) msg("%s slam%s into a %s!",lfname,isplayer(lf) ? "" : "s",
|
||||
newcell ? newcell->type->name : "wall");
|
||||
sprintf(buf, "slamming into a %s", newcell ? newcell->type->name : "wall");
|
||||
case E_OBINWAY:
|
||||
case E_DOORINWAY:
|
||||
if (reason == E_WALLINWAY) {
|
||||
if (newcell) strcpy(thing, newcell->type->name);
|
||||
else strcpy(thing, "wall");
|
||||
} else { // ie door or object
|
||||
getobname(rdata, thing, 1);
|
||||
}
|
||||
if (seen) msg("%s slam%s into %s!",lfname,isplayer(lf) ? "" : "s", thing);
|
||||
sprintf(buf, "slamming into %s", thing);
|
||||
losehp(lf, rnd(1,6), DT_BASH, pusher, buf);
|
||||
// stop moving
|
||||
i = howfar;
|
||||
|
@ -1054,6 +1063,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
for (l = newcell->map->lf ; l ; l = l->next) {
|
||||
if (l != lf) {
|
||||
flag_t *alarm;
|
||||
if (haslos(l, newcell)) {
|
||||
int dointerrupt = B_FALSE;
|
||||
|
||||
|
@ -1083,6 +1093,16 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
interrupt(l);
|
||||
}
|
||||
}
|
||||
|
||||
alarm = hasactivespell(l, OT_S_ALARM);
|
||||
if (alarm && areenemies(lf, l) && haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL) ) {
|
||||
// in range of alarm? range is 3 * spell power cells.
|
||||
if (getcelldist(lf->cell, l->cell) <= (alarm->val[2]*3)) {
|
||||
// alarm goes off
|
||||
noise(l->cell, NULL, 50, "a blaring siren!", NULL);
|
||||
killflag(alarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2125,7 +2145,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
} else {
|
||||
// attack!
|
||||
return attackcell(lf, cell);
|
||||
return attackcell(lf, cell, B_FALSE);
|
||||
}
|
||||
break;
|
||||
case E_CANTMOVE:
|
||||
|
|
1
nexus.c
1
nexus.c
|
@ -465,6 +465,7 @@ void checkdeath(void) {
|
|||
|
||||
void checkendgame(void) {
|
||||
if (!player->alive) {
|
||||
gamemode = GM_GAMEOVER;
|
||||
gameover = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
|
358
objects.c
358
objects.c
|
@ -2763,67 +2763,19 @@ void genhiddennames(void) {
|
|||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
f = hasflag(ot->flags, F_HASHIDDENNAME);
|
||||
if (f) {
|
||||
int n;
|
||||
int gotcolour = B_FALSE;
|
||||
char *thisname;
|
||||
if (strlen(f->text)) {
|
||||
thisname = strdup(f->text);
|
||||
} else {
|
||||
thisname = genhiddenname(ot->obclass->id);
|
||||
}
|
||||
addknowledge(ot->id, thisname, B_UNKNOWN);
|
||||
// some descriptions confer other effecst too...
|
||||
if (strstr(thisname, "glowing")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
||||
} else if (strstr(thisname, "flourescent")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
} else if (strstr(thisname, "luminous")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// set colour based on hiddenname
|
||||
for (n = 0; strlen(colour[n].name); n++) {
|
||||
if (strstr(thisname, colour[n].name)) {
|
||||
flag_t *gf;
|
||||
gf = hasflag(ot->flags, F_GLYPH);
|
||||
if (gf) {
|
||||
gf->val[0] = colour[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, colour[n].col, NA, NA, buf);
|
||||
gotcolour = B_TRUE;
|
||||
//dblog("assigning colour %s to %s (%s)",colour[n].name, thisname, ot->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotcolour) {
|
||||
for (n = 0; strlen(gemtype[n].name); n++) {
|
||||
if (strstr(thisname, gemtype[n].name)) {
|
||||
flag_t *gf;
|
||||
gf = hasflag(ot->flags, F_GLYPH);
|
||||
if (gf) {
|
||||
gf->val[0] = gemtype[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, gemtype[n].col, NA, NA, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sethiddenname(ot, thisname);
|
||||
free(thisname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the first hidden name for this objectclass
|
||||
char *genhiddenname(enum OBCLASS id) {
|
||||
hiddenname_t *hn;
|
||||
|
||||
|
@ -3419,23 +3371,23 @@ int getmaterialvalue(enum MATERIAL mat) {
|
|||
|
||||
int getmaxthrowrange(lifeform_t *lf, object_t *o) {
|
||||
int maxdist;
|
||||
float strmod;
|
||||
float modobweight;
|
||||
float str;
|
||||
float obweight;
|
||||
// adjust for lifeform strength
|
||||
// mighty = div by 10
|
||||
|
||||
// this will give us a number in range -44 - 50
|
||||
strmod = getstatmod(lf, A_STR);
|
||||
// this will give us a number in range 1 - 10
|
||||
strmod /= 5;
|
||||
if (strmod < 1) strmod = 1;
|
||||
// mighty = can throw 1kilo 10 metres
|
||||
// mighty = can throw 10kilos 1 metre
|
||||
// 11 - kilos = distance
|
||||
|
||||
modobweight = getobunitweight(o) / 2;
|
||||
modobweight /= strmod;
|
||||
str = getattr(lf, A_STR); // ie. 1 - 18
|
||||
str -= 2;
|
||||
limitf(&str, 1, NA); // ie. 1 to 16
|
||||
|
||||
maxdist = 10 - modobweight;
|
||||
obweight = getobunitweight(o);
|
||||
|
||||
if (maxdist < 0) maxdist = 0;
|
||||
maxdist = ceil(str - obweight);
|
||||
|
||||
if (maxdist < 1) maxdist = 0;
|
||||
return maxdist;
|
||||
}
|
||||
|
||||
|
@ -3669,10 +3621,12 @@ char *getobextrainfo(object_t *o, char *buf) {
|
|||
}
|
||||
|
||||
// activated
|
||||
if (!hasflag(o->flags, F_ACTIVATEPREFIX)) {
|
||||
f = hasflag(o->flags, F_ACTIVATED);
|
||||
if (f) {
|
||||
strcat(buf, " [activated]");
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -3795,10 +3749,15 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
sprintf(basename, "%s water", getwaterdepthname(getobdepth(o, player)));
|
||||
} else {
|
||||
strcpy(basename, "");
|
||||
if (isactivated(o) && hasflag(o->flags, F_ACTIVATEPREFIX)) {
|
||||
f = hasflag(o->flags, F_ACTIVATEPREFIX);
|
||||
sprintf(basename, "%s ", f->text);
|
||||
}
|
||||
if (showall) {
|
||||
strcpy(basename,o->type->name);
|
||||
strcat(basename,o->type->name);
|
||||
} else {
|
||||
strcpy(basename,gethiddenname(o));
|
||||
strcat(basename,gethiddenname(o));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4927,8 +4886,6 @@ void initobjects(void) {
|
|||
addhiddenname(OC_SCROLL, "scroll titled YES");
|
||||
addhiddenname(OC_SCROLL, "scroll titled ZAREL NOR");
|
||||
|
||||
addhiddenname(OC_POTION, "clear potion");
|
||||
|
||||
for (n = 0; strlen(colour[n].name); n++) {
|
||||
char buf[BUFLEN];
|
||||
// add it without an adjective
|
||||
|
@ -5092,6 +5049,7 @@ void initobjects(void) {
|
|||
addmaterial(MT_CLOTH, "cloth", 3);
|
||||
addflag(lastmaterial->flags, F_FLAMMABLE, 3, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_FOOD, "food", 3);
|
||||
addmaterial(MT_PLASTIC, "plastic", 3);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5102,6 +5060,7 @@ void initobjects(void) {
|
|||
addmaterial(MT_RUBBER, "rubber", 4);
|
||||
addmaterial(MT_LEATHER, "leather", 4);
|
||||
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_BONE, "bone", 5);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addmaterial(MT_OIL, "oil", 5);
|
||||
|
@ -5133,6 +5092,7 @@ void initobjects(void) {
|
|||
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
|
||||
addmaterial(MT_GLASS, "glass", 13);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_GOLD, "gold", 16);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
//addmaterial(MT_GOLD, "gold", 16);
|
||||
|
@ -5477,6 +5437,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
|
||||
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
|
||||
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_ASHSLEEP, "pile of sleeping powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -5625,6 +5586,8 @@ void initobjects(void) {
|
|||
addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water");
|
||||
sethiddenname(lastot, "clear potion");
|
||||
|
||||
addot(OT_POT_HEALING, "potion of healing", "Restores 10-20 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6262,6 +6225,12 @@ void initobjects(void) {
|
|||
///////////////////
|
||||
// gravity
|
||||
///////////////////
|
||||
// l1
|
||||
addot(OT_S_TRUESTRIKE, "true strike", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
||||
|
@ -6425,6 +6394,12 @@ void initobjects(void) {
|
|||
// summoning
|
||||
///////////////////
|
||||
// l1
|
||||
addot(OT_S_FLOATINGDISC, "floating disc", "Creates a disc of energy to carry your equipment.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_SUMMONWEAPON, "summon weapon", "Summons a blade of pure magic into your hands. Deals 1-power damage.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
|
@ -6493,6 +6468,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
addot(OT_S_ALARM, "alarm", "Creates a passive alarm which goes off when an enemy is nearby.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster (radius based on power), causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
||||
|
@ -6573,9 +6553,14 @@ void initobjects(void) {
|
|||
addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
||||
addot(OT_A_REPAIR, "repair armour", "Repair damage done to your armour.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
addot(OT_A_STEAL, "steal", "Try to steal an item from an enemy.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
addot(OT_A_STINGACID, "sting (acid)", "You can sting your enemies.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
|
@ -6670,6 +6655,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
|
||||
// tools - unique
|
||||
addot(OT_ORBDUNGEONEXIT, "dungeon exit orb", "When operated, this magical key will disable the barriers around the dungeon exit stairs.", MT_STONE, 2, OC_TOOLS);
|
||||
addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, "[");
|
||||
addflag(lastot->flags, F_UNIQUE, NA, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
// tools
|
||||
addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_TOOLS);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
||||
|
@ -6691,6 +6682,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit");
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL);
|
||||
|
@ -6751,6 +6743,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATEPREFIX, NA, NA, NA, "lit");
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
||||
addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL);
|
||||
|
@ -7762,7 +7755,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// this one if for the pirate
|
||||
// this one is for the pirate
|
||||
addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
|
@ -7879,7 +7872,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6.5, OC_MISSILE);
|
||||
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, "");
|
||||
|
@ -7888,7 +7881,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 3, 3, NA, "");
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.5, OC_MISSILE);
|
||||
addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.25, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
|
@ -7898,7 +7891,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 1, OC_MISSILE);
|
||||
addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 0.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
|
@ -7915,7 +7908,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_STONE, 0.1, OC_MISSILE);
|
||||
addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_STONE, 0.05, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
|
@ -7926,20 +7919,20 @@ void initobjects(void) {
|
|||
|
||||
|
||||
// axes
|
||||
addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 5, OC_WEAPON);
|
||||
addot(OT_BATTLEAXE, "battleaxe", "An large axe specifically designed for combat.", MT_METAL, 8, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+1");
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 8, OC_WEAPON);
|
||||
addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 10, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+1");
|
||||
|
@ -7947,14 +7940,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL);
|
||||
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2, OC_WEAPON);
|
||||
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe, ideal for throwing.", MT_METAL, 2.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7");
|
||||
addflag(lastot->flags, F_ACCURACY, 85, 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_ATTREQ, A_STR, 7, NA, NULL);
|
||||
addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_WARAXE, "war axe", "An axe made for combat.", MT_METAL, 7, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d7+1");
|
||||
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL);
|
||||
|
@ -7980,7 +7973,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 1, OC_WEAPON);
|
||||
addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 0.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d3");
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
|
@ -7997,32 +7990,32 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, 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, 1, OC_WEAPON);
|
||||
addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality, which somehow allows its bearer to attack faster.", MT_METAL, 3.0, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 75, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 2.5, OC_WEAPON);
|
||||
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 3.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8");
|
||||
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
||||
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1, OC_WEAPON);
|
||||
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
||||
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, 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_ATTREQ, A_DEX, 10, NA, NULL);
|
||||
addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 2.5, OC_WEAPON);
|
||||
addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
||||
addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 0.5, OC_WEAPON);
|
||||
addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 1, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL);
|
||||
|
@ -8037,7 +8030,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
||||
|
||||
// long blades
|
||||
addot(OT_FALCHION, "falchion", "A single-edged heavy sword made for chopping.", MT_METAL, 4.5, OC_WEAPON);
|
||||
addot(OT_FALCHION, "falchion", "A single-edged heavy sword made for chopping.", MT_METAL, 6.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 61, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+3");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
|
@ -8051,26 +8044,26 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 3, OC_WEAPON);
|
||||
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8+4");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL);
|
||||
addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 2, OC_WEAPON);
|
||||
addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 6, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
||||
addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 2, OC_WEAPON);
|
||||
addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 90, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
|
||||
addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 1, OC_WEAPON);
|
||||
addot(OT_CUTLASS, "cutlass", "An accurate, light-weight pirate blade.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7");
|
||||
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
||||
|
@ -8078,7 +8071,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
|
||||
|
||||
// polearms
|
||||
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 10, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7+3");
|
||||
|
@ -8086,7 +8079,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 10, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
||||
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8096,7 +8089,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_DEX, 7, NA, NULL);
|
||||
addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 12, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8106,7 +8099,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
||||
addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 12, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
||||
|
@ -8114,7 +8107,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 1, OC_WEAPON);
|
||||
addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 12, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
||||
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8124,14 +8117,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
||||
addot(OT_SCYTHE, "scythe", "An agricultural hand tool for mowing grass, or reaping crops.", MT_METAL, 3, OC_WEAPON);
|
||||
addot(OT_SCYTHE, "scythe", "An agricultural hand tool for mowing grass, or reaping crops.", MT_METAL, 6, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
||||
addot(OT_SPEAR, "spear", "A long pole with a sharpened head.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_SPEAR, "spear", "A long pole with a sharpened head.", MT_METAL, 9, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
||||
|
@ -8142,7 +8135,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
||||
addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 3, OC_WEAPON);
|
||||
addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d10");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
|
@ -8150,7 +8143,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
||||
|
||||
// staves
|
||||
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 2, OC_WEAPON);
|
||||
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d8");
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
|
||||
|
@ -8160,7 +8153,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 1.5, OC_WEAPON);
|
||||
addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 3, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
|
@ -8169,7 +8162,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 2, OC_WEAPON);
|
||||
addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 5, OC_WEAPON);
|
||||
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, NA, NA, "2d4+3");
|
||||
|
@ -8180,7 +8173,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 8, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "3d4+1");
|
||||
|
@ -8192,13 +8185,13 @@ void initobjects(void) {
|
|||
|
||||
|
||||
// clubs (bashing)
|
||||
addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 3, OC_WEAPON);
|
||||
addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 8, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
||||
addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 6, OC_WEAPON);
|
||||
addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 9, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
|
@ -8211,7 +8204,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 5, OC_WEAPON);
|
||||
addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 15, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d10+5");
|
||||
|
@ -8219,13 +8212,13 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL);
|
||||
addot(OT_MACE, "mace", "A weapon with a heavy head on a solid shaft used to bludgeon opponents.", MT_METAL, 3, OC_WEAPON);
|
||||
addot(OT_MACE, "mace", "A weapon with a heavy head on a solid shaft used to bludgeon opponents.", MT_METAL, 10, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d7+1");
|
||||
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
||||
addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 3.5, OC_WEAPON);
|
||||
addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 12, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d9+3");
|
||||
|
@ -8233,7 +8226,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
||||
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 1.5, OC_WEAPON);
|
||||
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 4.5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6+1");
|
||||
|
@ -8258,7 +8251,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// projectile weapons
|
||||
addot(OT_BOW, "bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 3, OC_WEAPON);
|
||||
addot(OT_BOW, "bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 5, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8269,7 +8262,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
||||
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but needs high strength to use.", MT_WOOD, 5, OC_WEAPON);
|
||||
addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but needs high strength to use.", MT_WOOD, 8, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8288,7 +8281,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL);
|
||||
|
||||
addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 6, OC_WEAPON);
|
||||
addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 7, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -8321,7 +8314,6 @@ void initobjects(void) {
|
|||
|
||||
|
||||
// special weapons
|
||||
|
||||
addot(OT_ENERGYBLADE, "energy blade", "A summoned weapon made of pure magical energy.", MT_MAGIC, 0, OC_WEAPON);
|
||||
addflag(lastot->flags, F_DAM, DT_MAGIC, NA, NA, "1d4"); // will be replaced when summoned
|
||||
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
||||
|
@ -9765,11 +9757,13 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
char subprompt[BUFLEN];
|
||||
sprintf(subprompt, "%s->Aim->", obname);
|
||||
if (strlen(f->text) > 0) {
|
||||
where = askcoords(f->text, ttype, lf, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
where = askcoords(f->text, subprompt, ttype, lf, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
} else {
|
||||
sprintf(buf, "Where will you aim %s?",obname);
|
||||
where = askcoords(buf, ttype, lf, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
where = askcoords(buf, subprompt, ttype, lf, UNLIMITED, LOF_NEED, B_TRUE);
|
||||
if (!haslos(lf, where)) {
|
||||
// exception - wand of digging doesn't need los
|
||||
if (isknown(o) && (o->type->id == OT_WAND_DIGGING)) {
|
||||
|
@ -9851,9 +9845,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
*/
|
||||
|
||||
if (hasflag(o->flags, F_OPERONOFF)) { // operating toggles on/off
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_ACTIVATED);
|
||||
if (f) {
|
||||
if (isactivated(o)) {
|
||||
turnoff(lf, o);
|
||||
} else {
|
||||
turnon(lf, o);
|
||||
|
@ -10129,6 +10121,27 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
msg("There is nothing here to fill your %s from.",noprefix(obname));
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_ORBDUNGEONEXIT) {
|
||||
map_t *m;
|
||||
m = lf->cell->map;
|
||||
if ((m->region == RG_FIRSTDUNGEON) && (m->depth == 1)) {
|
||||
cell_t *cell[MAXCANDIDATES];
|
||||
int ncells,i;
|
||||
getradiuscells(lf->cell, 1, DT_COMPASS, B_FALSE, B_TRUE, cell, &ncells);
|
||||
for (i = 0; i < ncells; i++) {
|
||||
if (hasob(cell[i]->obpile, OT_STAIRSUP)) {
|
||||
object_t *o;
|
||||
o = hasob(cell[i]->obpile, OT_MAGICBARRIER);
|
||||
if (o) {
|
||||
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
nothinghappens();
|
||||
}
|
||||
}
|
||||
} else if (o->type->id == OT_POCKETWATCH) {
|
||||
if (isplayer(lf)) {
|
||||
if (haslos(lf, lf->cell)) {
|
||||
|
@ -10848,20 +10861,12 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
if (!modattr(lf, A_STR, amt)) failed = B_FALSE;
|
||||
if (!modattr(lf, A_DEX, amt)) failed = B_FALSE;
|
||||
if (!modattr(lf, A_IQ, amt)) failed = B_FALSE;
|
||||
if (!modattr(lf, A_CON, amt)) failed = B_FALSE;
|
||||
} else {
|
||||
enum ATTRIB a;
|
||||
// modify just one attribute
|
||||
i = rnd(1,3);
|
||||
switch (i) {
|
||||
case 1:
|
||||
if (!modattr(lf, A_STR, amt)) failed = B_FALSE;
|
||||
break;
|
||||
case 2:
|
||||
if (!modattr(lf, A_DEX, amt)) failed = B_FALSE;
|
||||
break;
|
||||
case 3:
|
||||
if (!modattr(lf, A_IQ, amt)) failed = B_FALSE;
|
||||
break;
|
||||
}
|
||||
a = rnd(0,MAXATTS);
|
||||
if (!modattr(lf, a, amt)) failed = B_FALSE;
|
||||
}
|
||||
if (failed) {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -11591,6 +11596,64 @@ void setblessed(object_t *o, enum BLESSTYPE wantbless) {
|
|||
}
|
||||
}
|
||||
|
||||
int sethiddenname(objecttype_t *ot, char *text) {
|
||||
int n;
|
||||
int gotcolour = B_FALSE;
|
||||
|
||||
// add knowledge for it
|
||||
addknowledge(ot->id, text, B_UNKNOWN);
|
||||
|
||||
// some descriptions confer other effecst too...
|
||||
if (strstr(text, "glowing")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
||||
} else if (strstr(text, "flourescent")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
} else if (strstr(text, "luminous")) {
|
||||
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// set colour based on hiddenname
|
||||
for (n = 0; strlen(colour[n].name); n++) {
|
||||
if (strstr(text, colour[n].name)) {
|
||||
flag_t *gf;
|
||||
gf = hasflag(ot->flags, F_GLYPH);
|
||||
if (gf) {
|
||||
gf->val[0] = colour[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, colour[n].col, NA, NA, buf);
|
||||
gotcolour = B_TRUE;
|
||||
//dblog("assigning colour %s to %s (%s)",colour[n].name, text, ot->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotcolour) {
|
||||
for (n = 0; strlen(gemtype[n].name); n++) {
|
||||
if (strstr(text, gemtype[n].name)) {
|
||||
flag_t *gf;
|
||||
gf = hasflag(ot->flags, F_GLYPH);
|
||||
if (gf) {
|
||||
gf->val[0] = gemtype[n].col;
|
||||
} else {
|
||||
char buf[2];
|
||||
|
||||
buf[0] = ot->obclass->glyph.ch;
|
||||
buf[1] = '\0';
|
||||
addflag(ot->flags, F_GLYPH, gemtype[n].col, NA, NA, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
void setinscription(object_t *o, char *text) {
|
||||
if (o->inscription) {
|
||||
free(o->inscription);
|
||||
|
@ -11905,6 +11968,20 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno
|
|||
|
||||
// catches on fire?
|
||||
if (damtype == DT_FIRE) {
|
||||
if ( ((o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH)) &&
|
||||
!isactivated(o)) {
|
||||
cell_t *c;
|
||||
c = getoblocation(o);
|
||||
if (haslos(player, c)) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
msg("%s %s lit.", buf, (o->amt == 1) ? "is" : "are");
|
||||
}
|
||||
turnon(NULL, o);
|
||||
|
||||
// reduce damage a tiny bit
|
||||
howmuch--;
|
||||
}
|
||||
if (isflammable(o)) {
|
||||
ignite(o);
|
||||
if (isdeadob(o)) {
|
||||
|
@ -12245,7 +12322,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
// announce it ("xx throws xx" "at yy")
|
||||
if (thrower && isplayer(thrower)) {
|
||||
// player is throwing something
|
||||
if (target) {
|
||||
if (target && !hasflag(o->flags, F_POWDER)) {
|
||||
msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname);
|
||||
} else {
|
||||
msg("You %s %s.",throwverbpres, obname);
|
||||
|
@ -12257,7 +12334,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
sprintf(throwstring, "%s %ss %s", throwername, throwverbpres,
|
||||
obname);
|
||||
|
||||
if (target && haslos(player, where)) {
|
||||
if (target && haslos(player, where) && !hasflag(o->flags, F_POWDER)) {
|
||||
strcat(throwstring, willcatch ? " to " : " at ");
|
||||
strcat(throwstring, targetname);
|
||||
}
|
||||
|
@ -13208,7 +13285,7 @@ void turnon(lifeform_t *lf, object_t *o) {
|
|||
f = hasflag(o->flags, F_ACTIVATED);
|
||||
if (f) {
|
||||
// already on
|
||||
if (isplayer(lf)) {
|
||||
if (lf && isplayer(lf)) {
|
||||
msg("Your %s is already activated!\n", noprefix(obname));
|
||||
}
|
||||
return;
|
||||
|
@ -13218,13 +13295,14 @@ void turnon(lifeform_t *lf, object_t *o) {
|
|||
f = hasflag(o->flags, F_CHARGES);
|
||||
if (f && (f->val[0] <= 0)) {
|
||||
// out of power
|
||||
if (isplayer(lf)) {
|
||||
if (lf && isplayer(lf)) {
|
||||
nothinghappens();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
getobname(o, obname, 1);
|
||||
if (lf) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You activate your %s.",noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
|
@ -13232,6 +13310,7 @@ void turnon(lifeform_t *lf, object_t *o) {
|
|||
getlfname(lf, lfname);
|
||||
msg("%s activates %s.",lfname, obname);
|
||||
}
|
||||
}
|
||||
|
||||
// for grenades, give a new object which is activated
|
||||
if (hasflag(o->flags, F_GRENADE)) {
|
||||
|
@ -13254,7 +13333,9 @@ void turnon(lifeform_t *lf, object_t *o) {
|
|||
addflag(o->flags, F_ACTIVATED, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
if (lf) {
|
||||
giveobflags(lf, o, F_ACTIVATECONFER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -13427,6 +13508,23 @@ int validateobs(void) {
|
|||
return goterror;
|
||||
}
|
||||
|
||||
int wepdullable(object_t *o) {
|
||||
enum DAMTYPE dt;
|
||||
|
||||
if (!o) return B_FALSE;
|
||||
|
||||
dt = getdamtype(o);
|
||||
switch (dt) {
|
||||
case DT_PIERCE:
|
||||
case DT_SLASH:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
int willshatter(enum MATERIAL mat) {
|
||||
switch (mat) {
|
||||
case MT_GLASS:
|
||||
|
|
|
@ -201,6 +201,7 @@ int removeob(object_t *o, int howmany);
|
|||
object_t *relinkob(object_t *src, obpile_t *dst);
|
||||
void rrtorarity(enum RARITY r, int *minr, int *maxr);
|
||||
void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
||||
int sethiddenname(objecttype_t *o, char *text);
|
||||
void setinscription(object_t *o, char *text);
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||
void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
|
@ -216,6 +217,7 @@ void turnon(lifeform_t *lf, object_t *o);
|
|||
int uncurseob(object_t *o, int *seen);
|
||||
int usecharge(object_t *o);
|
||||
int validateobs(void);
|
||||
int wepdullable(object_t *o);
|
||||
int willshatter(enum MATERIAL mat);
|
||||
#endif
|
||||
|
||||
|
|
357
spell.c
357
spell.c
|
@ -115,7 +115,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) {
|
||||
sprintf(buf, "Charge who (max range %d)?",range);
|
||||
// TODO: ask for direction
|
||||
targcell = askcoords(buf, TT_MONSTER, user, range, LOF_NEED, B_TRUE);
|
||||
targcell = askcoords(buf, "Charge->", TT_MONSTER, user, range, LOF_NEED, B_TRUE);
|
||||
if (!targcell) {
|
||||
msg("Cancelled.");
|
||||
return TRUE;
|
||||
|
@ -196,7 +196,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
addflag(target->flags, F_GRABBEDBY, user->id, NA, NA, NULL);
|
||||
} else {
|
||||
// attack
|
||||
attackcell(user, targcell);
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
}
|
||||
} else if (abilid == OT_A_COOK) {
|
||||
object_t *water,*o;
|
||||
|
@ -267,7 +267,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else {
|
||||
sprintf(buf, "Darkwalk to where?");
|
||||
}
|
||||
targcell = askcoords(buf, TT_NONE, user, range, LOF_DONTNEED, B_FALSE);
|
||||
targcell = askcoords(buf, "Darkwalk->", TT_NONE, user, range, LOF_DONTNEED, B_FALSE);
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
// now attack them
|
||||
attackcell(user, target->cell);
|
||||
attackcell(user, target->cell, B_TRUE);
|
||||
} else if (abilid == OT_A_GRAB) {
|
||||
char dirch;
|
||||
flag_t *f;
|
||||
|
@ -569,7 +569,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
sprintf(buf, "Jump where (max distance 2)?");
|
||||
while (!targcell) {
|
||||
// ask where
|
||||
targcell = askcoords(buf, TT_NONE, user, 2, LOF_DONTNEED, B_TRUE);
|
||||
targcell = askcoords(buf, "Jump->", TT_NONE, user, 2, LOF_DONTNEED, B_TRUE);
|
||||
if (!targcell) {
|
||||
return B_TRUE;
|
||||
} else if (getcelldist(user->cell, targcell) > 2) {
|
||||
|
@ -690,6 +690,78 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
howlong = 10;
|
||||
addtempflag(user->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong);
|
||||
} else if (abilid == OT_A_REPAIR) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
int cutoffpct = 0;
|
||||
slev = getskill(user, SK_ARMOUR);
|
||||
switch (slev) {
|
||||
default:
|
||||
if (isplayer(user)) {
|
||||
msg("You are too unskilled to repair your armour.");
|
||||
}
|
||||
return B_TRUE;
|
||||
case PR_SKILLED: cutoffpct = 50; break;
|
||||
case PR_EXPERT: cutoffpct = 75; break;
|
||||
case PR_MASTER: cutoffpct = 100; break;
|
||||
}
|
||||
|
||||
// 1.compile a list of repairable objects
|
||||
// sk_armour lets you repair armour up to xx% (depends on skill)
|
||||
initprompt(&prompt, "Repair which object?");
|
||||
addchoice(&prompt, '-', "Cancel", buf, o);
|
||||
for (o = user->pack->first ; o ; o = o->next) {
|
||||
if (isarmour(o) && isdamaged(o)) {
|
||||
float pct;
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
pct = ((float)f->val[0] /(float) f->val[1]) * 100;
|
||||
if (pct < cutoffpct) {
|
||||
char buf[BUFLEN];
|
||||
getobname(o, buf, o->amt);
|
||||
// we can repair this object
|
||||
addchoice(&prompt, o->letter, buf, buf, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prompt.nchoices <= 1) {
|
||||
if (isplayer(user)) {
|
||||
msg("You don't have anything which you are able to repair.");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// 2. ask which ones to repair (or ALL)
|
||||
if (isplayer(user)) {
|
||||
getchoice(&prompt);
|
||||
o = (object_t *) prompt.result;
|
||||
} else {
|
||||
// pick a random one
|
||||
o = (object_t *) prompt.choice[rnd(0,prompt.nchoices-1)].data;
|
||||
}
|
||||
|
||||
|
||||
// in case it's on fire, etc
|
||||
if (touch(user, o)) {
|
||||
taketime(user, getactspeed(user));
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// repair it!
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
f->val[0] = pctof(cutoffpct, f->val[1]);
|
||||
if (isplayer(user)) {
|
||||
char buf[BUFLEN];
|
||||
real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
||||
msg("You %srepair your %s.", (f->val[0] == f->val[1]) ? "" : "partially ", noprefix(buf));
|
||||
} else {
|
||||
char buf[BUFLEN];
|
||||
real_getobname(o, buf, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
||||
msg("%s %s repairs %s.", username, (f->val[0] == f->val[1]) ? "completely" : "partially", buf);
|
||||
}
|
||||
|
||||
// TODO: make this like eating/resting/etc ?
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_SPRINT) {
|
||||
int howlong;
|
||||
int slev;
|
||||
|
@ -837,7 +909,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (isplayer(user)) {
|
||||
sprintf(buf, "Swoop who (max range %d)?",srange);
|
||||
// TODO: ask for direction
|
||||
targcell = askcoords(buf, TT_MONSTER, user, srange, LOF_NEED, B_TRUE);
|
||||
targcell = askcoords(buf, "Swoop->", TT_MONSTER, user, srange, LOF_NEED, B_TRUE);
|
||||
if (!targcell) {
|
||||
msg("Cancelled.");
|
||||
return TRUE;
|
||||
|
@ -899,7 +971,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
// attack
|
||||
attackcell(user, targcell);
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
|
||||
// teleport back to initial pos
|
||||
movelf(user, origcell);
|
||||
|
@ -971,13 +1043,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_FALSE;
|
||||
} else if (abilid == OT_A_DEBUG) {
|
||||
cell_t *where;
|
||||
where = askcoords("Debug who?", TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
where = askcoords("Debug who?", "Debug->",TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf) {
|
||||
debug(where->lf);
|
||||
}
|
||||
} else if (abilid == OT_A_EMPLOY) {
|
||||
cell_t *where;
|
||||
where = askcoords("Assign job to who?", TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
where = askcoords("Assign job to who?", "Assignjob->",TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf) {
|
||||
char question[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
|
@ -1001,7 +1073,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
} else if (abilid == OT_A_ENHANCE) {
|
||||
cell_t *where;
|
||||
where = askcoords("Enhance stats of who?", TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
where = askcoords("Enhance stats of who?", "Enhancestats->",TT_MONSTER, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && where->lf) {
|
||||
char ch;
|
||||
enum ATTRIB att;
|
||||
|
@ -1041,7 +1113,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
wep = getweapon(user);
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < 3)) {
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < 8)) { // ie. 8 is weight of a mace
|
||||
if (isplayer(user)) msg("You need a heavy weapon to perform a heavy blow!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1072,8 +1144,122 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
getlfname(target, targetname);
|
||||
|
||||
f = addflag(wep->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL);
|
||||
attackcell(user, targcell);
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
killflag(f);
|
||||
} else if (abilid == OT_A_STEAL) {
|
||||
enum SKILLLEVEL slev;
|
||||
char dirch;
|
||||
object_t *wep;
|
||||
char targetname[BUFLEN];
|
||||
flag_t *penalty = NULL;
|
||||
int failed = B_TRUE;
|
||||
|
||||
// ask for direction
|
||||
if (!targcell) {
|
||||
dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
||||
int dir;
|
||||
dir = chartodir(dirch);
|
||||
if (dir == D_NONE) {
|
||||
if (isplayer(user)) msg("Cancelled.");
|
||||
return B_TRUE ;
|
||||
} else {
|
||||
targcell = getcellindir(user->cell, dir);
|
||||
}
|
||||
}
|
||||
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
if (isplayer(user)) msg("There is nobody there to steal from!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
slev = getskill(user, SK_THIEVERY);
|
||||
if (slev == PR_INEPT) {
|
||||
if (isplayer(user)) msg("You are too unskilled to steal anything!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
getlfname(target, targetname);
|
||||
|
||||
if (slev == PR_NOVICE) {
|
||||
penalty = addflag(user->flags, F_ACCURACYMOD, -14, NA, NA, NULL);
|
||||
} else if (slev == PR_BEGINNER) {
|
||||
penalty = addflag(user->flags, F_ACCURACYMOD, -7, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// use empty handed attack accuracy
|
||||
wep = getweapon(user);
|
||||
if (rolltohit(user, target, wep, NULL)) {
|
||||
object_t *o;
|
||||
int i,nsteals;
|
||||
//
|
||||
if (slev >= PR_EXPERT) {
|
||||
nsteals = 2;
|
||||
} else {
|
||||
nsteals = 1;
|
||||
}
|
||||
// what do we steal?
|
||||
for (i = 0; i < nsteals; i++) {
|
||||
sprintf(buf, "Steal what (%d of %d)?", i+1, nsteals);
|
||||
initprompt(&prompt, buf);
|
||||
addchoice(&prompt, '-', "Nothing", NULL, NULL);
|
||||
for (o = target->pack->first ; o ; o = o->next) {
|
||||
int ok = B_TRUE;
|
||||
if ((slev < PR_SKILLED) && (getobunitweight(o) >= 3)) {
|
||||
// too heavy to steal
|
||||
ok = B_FALSE;
|
||||
} else if ((slev < PR_MASTER) && isequipped(o)) {
|
||||
// equipped
|
||||
ok = B_FALSE;
|
||||
} else if (!canpickup(user, o, 1)) {
|
||||
// can't pick it up
|
||||
ok = B_FALSE;
|
||||
}
|
||||
if (ok) {
|
||||
getobname(o, buf, 1);
|
||||
addchoice(&prompt, o->letter, buf, NULL, o);
|
||||
}
|
||||
}
|
||||
if (prompt.nchoices > 1) {
|
||||
if (slev >= PR_ADEPT) {
|
||||
// pick what you want
|
||||
getchoice(&prompt);
|
||||
o = (object_t *)prompt.result;
|
||||
} else {
|
||||
// random
|
||||
o = (object_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data;
|
||||
}
|
||||
if (o) {
|
||||
o = moveob(o, user->pack, 1);
|
||||
if (o) {
|
||||
getobname(o, buf, 1);
|
||||
if (isplayer(user)) {
|
||||
msg("You steal %s from %s!", buf, targetname);
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s steals %s from %s!", username, buf, targetname);
|
||||
}
|
||||
failed = B_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (penalty) {
|
||||
killflag(penalty);
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
if (isplayer(user)) {
|
||||
msg("You try to steal from %s, but fail.", targetname);
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s tries to steal from %s, but fails.", username, targetname);
|
||||
}
|
||||
}
|
||||
} else if (abilid == OT_A_WARCRY) {
|
||||
// announce
|
||||
if (isplayer(user)) {
|
||||
|
@ -1115,7 +1301,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||
c = getcellindir(user->cell, dir);
|
||||
if (c) {
|
||||
attackcell(user, c);
|
||||
attackcell(user, c, B_TRUE);
|
||||
}
|
||||
}
|
||||
// remove temporary flags
|
||||
|
@ -1430,6 +1616,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_ALARM) {
|
||||
if (isplayer(caster)) {
|
||||
msg("You create a alarm field around yourself.");
|
||||
}
|
||||
} else if (spellid == OT_S_ANIMATEDEAD) {
|
||||
int i;
|
||||
object_t *o,*nexto;
|
||||
|
@ -2154,7 +2344,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (!targcell) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
|
@ -2203,30 +2392,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
// add the monster
|
||||
newlf = addmonster(targcell, r->id, randomjobsok, 1, B_FALSE, NULL);
|
||||
newlf = summonmonster(caster, targcell, r->id, randomjobsok, forcejob, PERMENANT, B_FALSE);
|
||||
if (newlf) {
|
||||
// assign job if required
|
||||
if (forcejob) {
|
||||
givejob(newlf, forcejob->id);
|
||||
}
|
||||
if (haslos(player, targcell)) {
|
||||
char *newbuf;
|
||||
getlfname(newlf, buf);
|
||||
newbuf = strdup(buf);
|
||||
// newbuf will be "the xxx"
|
||||
if (isvowel(newbuf[4])) {
|
||||
newbuf = strrep(newbuf, "the ", "an ", NULL);
|
||||
} else {
|
||||
newbuf = strrep(newbuf, "the ", "a ", NULL);
|
||||
}
|
||||
capitalise(newbuf);
|
||||
msg("%s appears!", newbuf);
|
||||
free(newbuf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// not worth any xp
|
||||
killflagsofid(newlf->flags, F_XPVAL);
|
||||
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
|
||||
rv = B_FALSE;
|
||||
} else {
|
||||
// didn't work for some reason
|
||||
|
@ -2766,6 +2936,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
brightflash(caster->cell, 2 + (power/4), player);
|
||||
} else if (spellid == OT_S_FLOATINGDISC) {
|
||||
lifeform_t *newlf;
|
||||
// get random adjacent cell
|
||||
targcell = getrandomadjcell(caster->cell, WE_EMPTY, B_ALLOWEXPAND);
|
||||
if (!targcell) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
// add it
|
||||
newlf = summonmonster(caster, targcell, R_FLOATINGDISC, B_FALSE, NULL, PERMENANT, B_TRUE);
|
||||
if (newlf) {
|
||||
if (haslos(player, targcell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
// set carrying capacity
|
||||
setattr(newlf, A_STR, 8 + power);
|
||||
} else {
|
||||
// didn't work for some reason
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_FLOOD) {
|
||||
int failed = B_FALSE;
|
||||
// ask for a target cell
|
||||
|
@ -4359,7 +4550,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (caster->race->id == R_GHOST) {
|
||||
targcell = caster->cell;
|
||||
} else {
|
||||
if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
if (!validatespellcell(caster, &targcell,TT_PLAYER, spellid, power, frompot)) return B_TRUE;
|
||||
}
|
||||
target = targcell->lf;
|
||||
|
||||
|
@ -4873,6 +5064,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
|
||||
if (blessed) {
|
||||
f->val[0] += (rnd(1,6) + power);
|
||||
|
||||
if (f->val[0] >= f->val[1]) {
|
||||
|
@ -4881,6 +5073,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
msg("Your %s is repaired a little!", noprefix(obname));
|
||||
}
|
||||
} else {
|
||||
msg("Your %s deteriorates!", noprefix(obname));
|
||||
takedamage(o, rnd(1,6) + power, DT_DIRECT);
|
||||
}
|
||||
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
@ -5401,12 +5597,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
for (o = targcell->obpile->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (isflammable(o)) {
|
||||
takedamage(o, rnd(1,3), DT_FIRE);
|
||||
}
|
||||
// special cases
|
||||
if (isflammable(o) || (o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH)) {
|
||||
takedamage(o, 1, DT_FIRE);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_STENCH) {
|
||||
int howlong;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE;
|
||||
|
@ -5597,7 +5794,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
sprintf(buf, "Where will you teleport to?");
|
||||
while (!c) {
|
||||
int ch;
|
||||
c = askcoords(buf, TT_NONE, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
c = askcoords(buf, "Teleport->",TT_NONE, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (!c) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
|
@ -5762,7 +5959,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!targob) {
|
||||
// ask for a target cell (to take objects from)
|
||||
sprintf(buf, "Where will you focus your telekinetic power?");
|
||||
where = askcoords(buf, TT_OBJECT | TT_DOOR, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
where = askcoords(buf, "Telekinesis->", TT_OBJECT | TT_DOOR, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
if (where && haslos(caster, where)) {
|
||||
if (where->obpile->first) {
|
||||
// select object from cell...
|
||||
|
@ -5792,11 +5989,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
// if no target cell, ask where to throw object
|
||||
if (!targcell) {
|
||||
char obname[BUFLEN];
|
||||
char obname[BUFLEN],buf2[BUFLEN];
|
||||
getobname(targob, obname, 1);
|
||||
sprintf(buf, "Where will you move %s to?", obname);
|
||||
sprintf(buf, "Where will you throw %s to?", obname);
|
||||
// TODO: start trail from the object
|
||||
targcell = askcoords(buf, TT_MONSTER | TT_PLAYER, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
sprintf(buf2, "Telekinesis->%s->",obname);
|
||||
targcell = askcoords(buf, buf2,TT_MONSTER | TT_PLAYER, caster, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
}
|
||||
|
||||
// not liftable?
|
||||
|
@ -5855,6 +6053,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp thorns", FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_TRUESTRIKE) {
|
||||
if (!validatespellcell(caster, &targcell, TT_PLAYER, spellid, power, frompot)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
addflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL);
|
||||
} else if (spellid == OT_S_TURNUNDEAD) {
|
||||
int i;
|
||||
// works on all undead in sight
|
||||
|
@ -6778,6 +6984,13 @@ char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf) {
|
|||
case OT_S_SUMMONWEAPON:
|
||||
sprintf(buf, "Create a 2d%d damage magical weapon",power);
|
||||
break;
|
||||
case OT_S_TRUESTRIKE:
|
||||
if (power == 1) {
|
||||
sprintf(buf, "Next attack automatically hits");
|
||||
} else {
|
||||
sprintf(buf, "Next %d attacks automatically hit",power);
|
||||
}
|
||||
break;
|
||||
case OT_S_WINDSHIELD:
|
||||
sprintf(buf, "Protection from missiles <= %d km/h",speedtokph(power));
|
||||
break;
|
||||
|
@ -6852,6 +7065,38 @@ void stopallspells(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
void stopallspellsexcept(lifeform_t *lf, ...) {
|
||||
flag_t *f,*nextf;
|
||||
va_list args;
|
||||
enum OBTYPE exception[MAXCANDIDATES];
|
||||
int nexceptions = 0;
|
||||
|
||||
va_start(args, lf);
|
||||
exception[nexceptions] = va_arg(args, enum OBTYPE);
|
||||
while (exception[nexceptions] != OT_NONE) {
|
||||
nexceptions++;
|
||||
exception[nexceptions] = va_arg(args, enum OBTYPE);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
for (f = lf->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if (f->id == F_BOOSTSPELL) {
|
||||
int stopthis = B_TRUE;
|
||||
int n;
|
||||
for (n = 0; n < nexceptions; n++) {
|
||||
if (exception[n] == f->val[0]) {
|
||||
stopthis = B_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stopthis) {
|
||||
stopspell(lf, f->val[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int schoolappearsinbooks(enum SPELLSCHOOL ss) {
|
||||
switch (ss) {
|
||||
case SS_DIVINE:
|
||||
|
@ -6915,6 +7160,19 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
|||
killob(o);
|
||||
}
|
||||
}
|
||||
if (spellid == OT_S_FLOATINGDISC) {
|
||||
map_t *m;
|
||||
lifeform_t *lf;
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
for (lf = m->lf ; lf ; lf = lf->next) {
|
||||
if (lf->race->id == R_FLOATINGDISC) {
|
||||
if (lfhasflagval(lf, F_SUMMONEDBY, caster->id, NA, NA, NULL)) {
|
||||
unsummon(lf, B_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -6997,9 +7255,10 @@ lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **targe
|
|||
// ask for a target lifeform
|
||||
if (isplayer(user)) {
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
char buf[BUFLEN],buf2[BUFLEN];
|
||||
sprintf(buf, "Where will you target your %s?",ot->name);
|
||||
where = askcoords(buf, TT_MONSTER, user, maxrange, LOF_DONTNEED, B_FALSE);
|
||||
sprintf(buf2, "%s->",ot->name);
|
||||
where = askcoords(buf, buf2, TT_MONSTER, user, maxrange, LOF_DONTNEED, B_FALSE);
|
||||
if (where) {
|
||||
if (!haslf(where)) {
|
||||
msg("There is nobody there!");
|
||||
|
@ -7123,14 +7382,16 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
|
|||
// ask for a target cell
|
||||
if (isplayer(caster)) {
|
||||
char buf[BUFLEN];
|
||||
if (maxrange == UNLIMITED) {
|
||||
char buf2[BUFLEN];
|
||||
objecttype_t *ot;
|
||||
ot = findot(spellid);
|
||||
if (maxrange == UNLIMITED) {
|
||||
sprintf(buf, "Where will you target your %s?", ot->name);
|
||||
} else {
|
||||
sprintf(buf, "Where will you target your spell [max range %d]?",maxrange);
|
||||
sprintf(buf, "Where will you target your %s [max range %d]?",ot->name, maxrange);
|
||||
}
|
||||
where = askcoords(buf, targtype, caster, maxrange, needlof, needlof ? B_TRUE : B_FALSE);
|
||||
sprintf(buf2, "%s->",ot->name);
|
||||
where = askcoords(buf, buf2, targtype, caster, maxrange, needlof, needlof ? B_TRUE : B_FALSE);
|
||||
if (!where) {
|
||||
int ch;
|
||||
ch = askchar("Abandon your spell?","yn","n", B_TRUE);
|
||||
|
|
1
spell.h
1
spell.h
|
@ -25,6 +25,7 @@ int schoolappearsinbooks(enum SPELLSCHOOL ss);
|
|||
void spellcloud(cell_t *srcloc, int radius, char ch, enum COLOUR col, enum OBTYPE sid, int power, int frompot);
|
||||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
void stopallspellsexcept(lifeform_t *lf, ...);
|
||||
int summonlfs(lifeform_t *caster, enum RACECLASS wantrc, enum LFSIZE wantsize, int howmany, int lifetime);
|
||||
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target);
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, enum OBTYPE spellid, int power, int frompot);
|
||||
|
|
Loading…
Reference in New Issue