* [+] check darkmantle code now that i can se ab it in dark
- [+] don't drip blood from melting damge * [+] climbing - [+] LOTS of bugs with holes - [+] cope with walking diagonally off world map - [+] can no longer walk off the world map!!! * [+] BUG: worldmap 0,-1 had a link to dungeon! - [+] Dig down into a pit - CRASH. fixing previous one might fix this? * [+] CRASH: * [+] walking onto water: - [+] boots of stealth / elven boots - make footstep volume = 1 * [+] f_freezingtouch
This commit is contained in:
parent
57d783ab71
commit
cf328f849f
26
attack.c
26
attack.c
|
@ -761,8 +761,16 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
if (isunarmed) {
|
||||
f = lfhasflag(lf, F_FREEZINGTOUCH);
|
||||
if (f) {
|
||||
int diff;
|
||||
diff = f->val[2];
|
||||
if (isimmuneto(victim->flags, DT_COLD) || skillcheck(victim, SC_RESISTMAG, diff, 0)) {
|
||||
if (isplayer(victim)) {
|
||||
msg("You feel mildly chilly.");
|
||||
}
|
||||
} else {
|
||||
// victim turns to ice for a while!
|
||||
freezelf(victim, lf, rnd(5,10));
|
||||
}
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
|
@ -1074,6 +1082,24 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int damtypecausesbleed(enum DAMTYPE dt) {
|
||||
switch (dt) {
|
||||
case DT_PIERCE:
|
||||
case DT_SLASH:
|
||||
case DT_BASH:
|
||||
case DT_BITE:
|
||||
case DT_CHOP:
|
||||
case DT_PROJECTILE:
|
||||
case DT_EXPLOSIVE:
|
||||
case DT_UNARMED:
|
||||
case DT_FALL:
|
||||
return B_TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns the amount of damage the armour blocked...
|
||||
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
|
||||
int reduceamt = 0;
|
||||
|
|
1
attack.h
1
attack.h
|
@ -6,6 +6,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force);
|
|||
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
|
||||
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
|
||||
void confereffects(flagpile_t *fp, lifeform_t *victim);
|
||||
int damtypecausesbleed(enum DAMTYPE dt);
|
||||
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
|
||||
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
|
||||
//object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
|
||||
|
|
16
defs.h
16
defs.h
|
@ -43,6 +43,7 @@ enum SKILL {
|
|||
SK_BACKSTAB,
|
||||
SK_CARTOGRAPHY,
|
||||
SK_CHANNELING,
|
||||
SK_CLIMBING,
|
||||
SK_COOKING,
|
||||
SK_FIRSTAID,
|
||||
SK_LISTEN,
|
||||
|
@ -90,7 +91,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 49
|
||||
#define MAXSKILLS 50
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -145,6 +146,7 @@ enum CHECKTYPE {
|
|||
SC_IQ,
|
||||
SC_CON,
|
||||
//////////
|
||||
SC_CLIMB,
|
||||
SC_DISARM,
|
||||
SC_DODGE,
|
||||
SC_SHIELDBLOCK,
|
||||
|
@ -1089,6 +1091,7 @@ enum OBTYPE {
|
|||
OT_LOCKPICK,
|
||||
OT_PANPIPES,
|
||||
OT_PICKAXE,
|
||||
OT_ROPE,
|
||||
OT_TORCH,
|
||||
OT_TOWEL,
|
||||
// tech
|
||||
|
@ -1106,6 +1109,7 @@ enum OBTYPE {
|
|||
OT_MOTIONSCANNER,
|
||||
OT_NVGOGGLES,
|
||||
OT_PAPERCLIP,
|
||||
OT_PORTLADDER,
|
||||
OT_SLEEPINGBAG,
|
||||
OT_TELEPAD,
|
||||
OT_TENT,
|
||||
|
@ -1518,6 +1522,7 @@ enum FLAG {
|
|||
F_LIGHTSOURCE, // a light source like a torch, lantern etc
|
||||
F_CHARGELOWMSG, // text = msg when charges are nearly out
|
||||
F_CHARGEOUTMSG, // text = msg when charges are gone
|
||||
F_HELPSCLIMB, // object gives v0 bonus to sc_climb checks.
|
||||
// technology flags
|
||||
F_TECHLEVEL, // v0 is a PR_xxx enum for tech usage skill
|
||||
// what can you do with this object?
|
||||
|
@ -1751,6 +1756,7 @@ enum FLAG {
|
|||
// v0 is spell id
|
||||
F_AVOIDCURSEDOB, // for AI animals - they will avoid walking on obid 'text'
|
||||
// (text is a long)
|
||||
F_FALLDISTANCE, // how many floors this lf has fallen through.
|
||||
// ABILITY/SPELL FLAGS / ability flags / spell flags
|
||||
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
|
||||
F_BOOSTSPELL, // v0 is active boost spell, v1 is ongoing mpcost, v2 is power
|
||||
|
@ -1822,7 +1828,6 @@ enum FLAG {
|
|||
// this lf's spell casting at all.
|
||||
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
|
||||
F_BEHEADED, // use special corpse drop code
|
||||
F_SILENTMOVE, // lf makes no noise when walking/flying
|
||||
F_MOVESPEED, // override default move speed
|
||||
F_ACTIONSPEED, // override default action speed
|
||||
F_SPELLSPEED, // override default spellcast speed (ie. movespeed)
|
||||
|
@ -1925,6 +1930,7 @@ enum FLAG {
|
|||
// v1 = power
|
||||
// text = what from.eg'a bad egg'
|
||||
F_FREEZINGTOUCH,// next thing touched turns to ice!
|
||||
// v2 is save difficulty
|
||||
F_GRABBEDBY,// you've been grabbed by lf id v0
|
||||
F_GRABBING, // you are grabbing lf id v0
|
||||
F_HEAVYBLOW, // next attack is a heavy blow
|
||||
|
@ -1958,11 +1964,12 @@ enum FLAG {
|
|||
// text must have at least TWO words
|
||||
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_SILENTMOVE, // lf makes no noise when walking/flying
|
||||
F_STABILITY, // doesn't slip over
|
||||
F_STENCH, // creatures within v0 gain f_nauseated = v1
|
||||
F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0
|
||||
F_TRUESTRIKE, // your attacks ALWAYS hit. turnsleft=v0
|
||||
F_PRODUCESLIGHT, // produces light of val0 radius.
|
||||
// (but not for obs in pack)
|
||||
// if val2 is true, will only make light if ob
|
||||
|
@ -2670,6 +2677,7 @@ enum BRAND {
|
|||
BR_SHADOWS,
|
||||
BR_SLOTH,
|
||||
BR_SPEED,
|
||||
BR_STEALTH,
|
||||
BR_POWER,
|
||||
BR_SWIFTNESS,
|
||||
BR_TELEKINESIS,
|
||||
|
|
31
io.c
31
io.c
|
@ -1417,6 +1417,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You now move silently.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SLOWACT:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "feel sluggish." : "looks sluggish.");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1902,6 +1908,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You no longer move silently.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_SLOWACT:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "no longer feel sluggish." : "no longer looks sluggish.");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -2849,6 +2861,7 @@ void describeob(object_t *o) {
|
|||
|
||||
// weight
|
||||
y = 4;
|
||||
if (o->material->id != MT_NOTHING) {
|
||||
if (o->material->id == MT_FOOD) {
|
||||
sprintf(buf, "%s food product%s, ",(o->amt == 1) ? "It is a" : "They are",
|
||||
(o->amt == 1) ? "" : "s");
|
||||
|
@ -2891,6 +2904,7 @@ void describeob(object_t *o) {
|
|||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
if (isedible(o)) {
|
||||
int basenutr;
|
||||
|
@ -3049,6 +3063,13 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_HELPSCLIMB);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It can be used to assist in climbing.");
|
||||
y++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// skip line
|
||||
y++;
|
||||
|
@ -3364,6 +3385,9 @@ void describeob(object_t *o) {
|
|||
case F_SEEINDARK:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to see in the dark.", buf); y++;
|
||||
break;
|
||||
case F_SILENTMOVE:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to move silently.", buf); y++;
|
||||
break;
|
||||
case F_SLOWACT:
|
||||
mvwprintw(mainwin, y, 0, "%s will slow down your actions.", buf); y++;
|
||||
break;
|
||||
|
@ -3952,7 +3976,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
|
|||
|
||||
ch = f->val[0];
|
||||
if (strlen(f->text)) {
|
||||
o = addobject(op, f->text, B_FALSE); // no stacking!
|
||||
o = addobject(op, f->text, B_FALSE, B_FALSE); // no stacking!
|
||||
// remember letter
|
||||
o->letter = ch;
|
||||
// make object fully known
|
||||
|
@ -8325,6 +8349,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_SILENTMOVE);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s move%s silently.", you(lf), isplayer(lf) ? "" : "s");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_STABILITY);
|
||||
if (f && (f->known)) {
|
||||
|
|
234
lf.c
234
lf.c
|
@ -49,11 +49,13 @@ extern int obdb;
|
|||
|
||||
extern enum ERROR reason;
|
||||
|
||||
|
||||
// for xplist
|
||||
race_t **raceposs;
|
||||
int *xpposs;
|
||||
int xplistlen;
|
||||
|
||||
int notime = B_FALSE; // prevent taketime from doing anything
|
||||
|
||||
void autoweild(lifeform_t *lf) {
|
||||
object_t *bestwep,*bestfirearm;
|
||||
|
@ -1923,6 +1925,15 @@ int digdown(lifeform_t *lf, object_t *o) {
|
|||
|
||||
// TODO: check if the floor is solid?
|
||||
|
||||
if (o) {
|
||||
if (lfhasflag(lf, F_LEVITATING)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the ground from up here!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig a hole in the floor.");
|
||||
} else if (cansee(player, lf)) {
|
||||
|
@ -1932,7 +1943,9 @@ int digdown(lifeform_t *lf, object_t *o) {
|
|||
addob(lf->cell->obpile, "hole in the ground");
|
||||
|
||||
// takes a lot of time
|
||||
if (o) {
|
||||
taketime(lf, getactspeed(lf) * 9);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1948,14 +1961,15 @@ int digup(lifeform_t *lf, object_t *o) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// TODO: check if the roof is solid?
|
||||
|
||||
// if digging with an object, you must be able to reach the roof
|
||||
if (o) {
|
||||
if (!isairborne(lf)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig a hole in the roof.");
|
||||
|
@ -1969,7 +1983,9 @@ int digup(lifeform_t *lf, object_t *o) {
|
|||
addob(lf->cell->obpile, "hole in the roof");
|
||||
|
||||
// takes a LOT of time since gravity is against us
|
||||
if (o) {
|
||||
taketime(lf, getactspeed(lf) * 18);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -3170,8 +3186,8 @@ int getactspeed(lifeform_t *lf) {
|
|||
return speed;
|
||||
}
|
||||
|
||||
// only include allies which will follow you up/down stairs etc
|
||||
void getadjallies(lifeform_t *lf, lifeform_t **adjally, int *nadjallies) {
|
||||
// include allies or enemies which will follow you up/down stairs etc
|
||||
void getadjallies(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *nadjallies) {
|
||||
int d;
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
cell_t *c;
|
||||
|
@ -3179,6 +3195,13 @@ void getadjallies(lifeform_t *lf, lifeform_t **adjally, int *nadjallies) {
|
|||
if (c && c->lf) {
|
||||
if (areallies(lf, c->lf) || areenemies(lf, c->lf)) {
|
||||
if (!isimmobile(c->lf) && cansee(c->lf, lf)) {
|
||||
int ok = B_TRUE;
|
||||
// if this was a pit, only flying things will follow
|
||||
if (stairob && hasflag(stairob->flags, F_PIT)) {
|
||||
if (!lfhasflag(c->lf, F_FLYING)) {
|
||||
ok = B_FALSE;
|
||||
}
|
||||
}
|
||||
adjally[*nadjallies] = c->lf;
|
||||
(*nadjallies)++;
|
||||
}
|
||||
|
@ -6565,6 +6588,11 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
|
|||
if (!islit(dest)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
// inside our nightvis range and magically dark
|
||||
if (dest->lit == L_PERMDARK) {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6723,6 +6751,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL);
|
||||
mayusespellschool(lastjob->flags, SS_ALLOMANCY, F_CANCAST);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL);
|
||||
|
@ -6752,6 +6781,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_TRACKING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LOCKPICKING, NA, NA, NULL);
|
||||
|
@ -6797,6 +6827,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_SKILLED, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_BACKSTAB, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
|
@ -6845,6 +6876,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_CANWILL, OT_A_JUMP, 3, 3, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL);
|
||||
|
@ -6901,6 +6933,7 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 potions of rum");
|
||||
// skills
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_ADEPT, NA, NULL);
|
||||
|
@ -6927,6 +6960,7 @@ void initjobs(void) {
|
|||
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_CLIMBING, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_LISTEN, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTSKILL, SK_BACKSTAB, PR_BEGINNER, NA, NULL);
|
||||
|
@ -10622,17 +10656,9 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
|
|||
}
|
||||
|
||||
// occasionally drop blood
|
||||
switch (damtype) {
|
||||
case DT_POISON:
|
||||
case DT_POISONGAS:
|
||||
case DT_WATER:
|
||||
break;
|
||||
default:
|
||||
if (onein(3)) {
|
||||
if (damtypecausesbleed(damtype) && onein(3)) {
|
||||
bleed(lf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasflag(lf->flags, F_DEBUG)) {
|
||||
msg("[%s takes %d dam]",lfname, amt);
|
||||
|
@ -12339,6 +12365,7 @@ void initskills(void) {
|
|||
addskill(SK_BACKSTAB, "Backstab", "Lets you inflict massive damage with stabs when unseen.", 50);
|
||||
addskill(SK_CARTOGRAPHY, "Cartography", "Your ability to create and interpret maps.", 0); // untrainable
|
||||
addskill(SK_CHANNELING, "Channeling", "Lets you make better use of magical items.", 0); // untrainable
|
||||
addskill(SK_CLIMBING, "Climbing", "Helps you to climb walls, mountains or other terrain.", 50);
|
||||
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50);
|
||||
addskill(SK_FIRSTAID, "First Aid", "Increases your healing rate and reduces duration of poison.", 0); // untrainable
|
||||
addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.", 100);
|
||||
|
@ -12507,6 +12534,9 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
attrib += (getattr(lf, A_DEX)/4);
|
||||
}
|
||||
break;
|
||||
case SC_CLIMB:
|
||||
attrib = (getskill(lf, SK_CLIMBING)*2);
|
||||
break;
|
||||
case SC_DODGE:
|
||||
// getevasion returns 0-100 (ie. pct chance)
|
||||
// convert this to 0-20
|
||||
|
@ -12535,7 +12565,15 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
levmod = (lf->level / 3);
|
||||
|
||||
// other modifiers
|
||||
if (ct == SC_SLIP) {
|
||||
if (ct == SC_CLIMB) {
|
||||
object_t *o;
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_HELPSCLIMB);
|
||||
if (f && isknown(o)) {
|
||||
othermod += f->val[0];
|
||||
}
|
||||
}
|
||||
} else if (ct == SC_SLIP) {
|
||||
if (getequippedob(lf->pack, BP_FEET)) {
|
||||
othermod += 5;
|
||||
}
|
||||
|
@ -13001,8 +13039,7 @@ void taketime(lifeform_t *lf, long howlong) {
|
|||
int db = B_FALSE;
|
||||
map_t *map;
|
||||
|
||||
|
||||
if (lfhasflag(lf, F_NOTIME)) {
|
||||
if (notime || lfhasflag(lf, F_NOTIME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -13061,6 +13098,10 @@ int throwat(lifeform_t *thrower, object_t *o, cell_t *where) {
|
|||
void timeeffectslf(lifeform_t *lf) {
|
||||
object_t *o, *nexto;
|
||||
flag_t *f,*nextf;
|
||||
int dir;
|
||||
|
||||
// make SURE we don't take any time!
|
||||
notime = B_TRUE;
|
||||
|
||||
// decrement flags
|
||||
timeeffectsflags(lf->flags);
|
||||
|
@ -13082,6 +13123,7 @@ void timeeffectslf(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
if (isdead(lf)) {
|
||||
killflagsofid(lf->flags, F_NOTIME);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -13121,19 +13163,78 @@ void timeeffectslf(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// holes in the floor/roof
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
if (o) {
|
||||
if (!isairborne(lf)) {
|
||||
usestairs(lf, o, B_FALSE);
|
||||
for (dir = D_UP; dir <= D_DOWN; dir++) {
|
||||
int donesomething = B_TRUE;
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, dir, NA, NA, NULL);
|
||||
while (o && donesomething) {
|
||||
int willfall = B_FALSE;
|
||||
donesomething = B_FALSE;
|
||||
if ((dir == D_DOWN) && !isairborne(lf)) {
|
||||
willfall = B_TRUE;
|
||||
} else if ((dir == D_UP) && lfhasflag(lf, F_LEVITATING)) {
|
||||
willfall = B_TRUE;
|
||||
}
|
||||
}
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, D_UP, NA, NA, NULL);
|
||||
if (o) {
|
||||
if (lfhasflag(lf, F_LEVITATING)) {
|
||||
|
||||
if (willfall) {
|
||||
usestairs(lf, o, B_FALSE);
|
||||
donesomething = B_TRUE;
|
||||
o = hasobwithflagval(lf->cell->obpile, F_PIT, dir, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notime = B_FALSE;
|
||||
}
|
||||
|
||||
// return B_TRUE on failure.
|
||||
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat) {
|
||||
// if you have a rope or there's an adjacent wall, you can try
|
||||
// to climb up
|
||||
int adjwalls;
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
adjwalls = countadjwalls(where);
|
||||
if (adjwalls || hasobwithflag(lf->pack, F_HELPSCLIMB)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You start climbing...");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s starts climbing...", lfname);
|
||||
}
|
||||
|
||||
taketime(lf, getactspeed(lf));
|
||||
|
||||
// base difficulty of 20
|
||||
if (skillcheck(lf, SC_CLIMB, 20, (countadjwalls(where)+1)/2)) {
|
||||
// you made it!
|
||||
if (isplayer(lf)) {
|
||||
msg("You reach %s.", towhat);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s reaches %s.", towhat);
|
||||
}
|
||||
// train climbing
|
||||
practice(lf, SK_CLIMBING, 1);
|
||||
// continue...
|
||||
|
||||
} else {
|
||||
// you fall.
|
||||
if (isplayer(lf)) {
|
||||
msg("You fall to the ground!");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s falls to the ground!", lfname);
|
||||
}
|
||||
fall(lf, NULL, B_FALSE); // this will take some time.
|
||||
losehp(lf, roll("1d6"), DT_FALL, NULL, "a fall while climbing");
|
||||
return B_TRUE;
|
||||
}
|
||||
} else { // no rope or adjacent walls
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// success
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
@ -13967,6 +14068,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
flag_t *f;
|
||||
map_t *curmap;
|
||||
map_t *newmap;
|
||||
cell_t *obcell;
|
||||
cell_t *newcell;
|
||||
int dir;
|
||||
int newdepth;
|
||||
|
@ -13985,20 +14087,21 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
|
||||
getlfname(lf, lfname);
|
||||
getobname(o, obname, 1);
|
||||
obcell = getoblocation(o);
|
||||
|
||||
if (initiatemove(lf, NULL, NULL)) {
|
||||
// failed?
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
curmap = lf->cell->map;
|
||||
curmap = obcell->map;
|
||||
|
||||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
assert(f);
|
||||
dir = f->val[0];
|
||||
if (f->val[1] == NA) {
|
||||
// use same region
|
||||
newregion = lf->cell->map->region;
|
||||
newregion = obcell->map->region;
|
||||
} else {
|
||||
newregion = findregion(f->val[1]);
|
||||
}
|
||||
|
@ -14032,14 +14135,16 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
// can only go up if you have a rope or are flying/levitating
|
||||
if (lfhasflag(lf, F_LEVITATING) || lfhasflag(lf, F_FLYING)) {
|
||||
// ok.
|
||||
} else { // TODO: if has rope???
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't reach the roof!");
|
||||
}
|
||||
} else {
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "the %s", noprefix(obname));
|
||||
if (tryclimb(lf, obcell, buf)) {
|
||||
// failed
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// announce
|
||||
curs_set(1);
|
||||
|
@ -14070,9 +14175,9 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
}
|
||||
|
||||
// find adjacent allies or enemies which will follow you
|
||||
// (but not into/out of pits)
|
||||
if (isplayer(lf) || !hasflag(o->flags, F_PIT)) {
|
||||
getadjallies(lf, adjally, &nadjallies);
|
||||
// (getadjallies will handle following through pits)
|
||||
if (isplayer(lf)) {
|
||||
getadjallies(lf, o, adjally, &nadjallies);
|
||||
}
|
||||
|
||||
// do stairs go somewhere?
|
||||
|
@ -14100,9 +14205,11 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
// previous/next levels in the same region.
|
||||
|
||||
// if not, we need to call linkstairs() on the staircase first.
|
||||
/*
|
||||
if (newmap->region->id != curmap->region->id) {
|
||||
linkstairs(o);
|
||||
}
|
||||
*/
|
||||
// at this point, stairs should have a destination
|
||||
newcell = getstairdestination(o);
|
||||
}
|
||||
|
@ -14112,10 +14219,29 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
curs_set(0);
|
||||
if (newcell) {
|
||||
int n;
|
||||
|
||||
// if we just climbed up through a hole, and are not flying, we want to
|
||||
// end up adjacent to the hole in the ground. otherwise we'll just fall
|
||||
// straight back down!
|
||||
if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf)) {
|
||||
cell_t *noholecell;
|
||||
noholecell = real_getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL);
|
||||
if (noholecell) {
|
||||
// go here instead
|
||||
newcell = noholecell;
|
||||
} else {
|
||||
// alert
|
||||
if (isplayer(lf)) {
|
||||
msg("You can't find anywhere safe to get out.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check noone is in the way
|
||||
if (newcell->lf) {
|
||||
cell_t *c;
|
||||
// if they are, move them
|
||||
// if they are, find somewhere to move them.
|
||||
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
// move them there
|
||||
|
@ -14168,24 +14294,56 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
|
||||
if (falling) {
|
||||
if (dir == D_DOWN) {
|
||||
if (hasobwithflagval(lf->cell->obpile, F_PIT, D_DOWN, NA, NA, NULL)) {
|
||||
flag_t *ff;
|
||||
// inc fall distance
|
||||
ff = lfhasflag(lf, F_FALLDISTANCE);
|
||||
if (ff) {
|
||||
ff->val[0]++;
|
||||
} else {
|
||||
addflag(lf->flags, F_FALLDISTANCE, 1, NA, NA, NULL);
|
||||
}
|
||||
} else {
|
||||
int howfar;
|
||||
if (isplayer(lf)) {
|
||||
msg("You slam into the ground!");
|
||||
} else if (cansee(player, lf)){
|
||||
msg("%s slams into the ground!", lfname);
|
||||
}
|
||||
// take fall damage
|
||||
losehp(lf, roll("2d6"), DT_FALL, NULL, "falling");
|
||||
// how far did you fall?
|
||||
sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL);
|
||||
howfar++;
|
||||
// take fall damage. 2d6 per level.
|
||||
losehp(lf, rolldie(howfar*2, 6), DT_FALL, NULL, "falling");
|
||||
killflagsofid(lf->flags, F_FALLDISTANCE);
|
||||
// fall over
|
||||
fall(lf, NULL, B_FALSE);
|
||||
}
|
||||
} else {
|
||||
// TODO: if you are outside, DIE!
|
||||
if (hasobwithflagval(lf->cell->obpile, F_PIT, D_UP, NA, NA, NULL)) {
|
||||
flag_t *ff;
|
||||
// inc fall distance
|
||||
ff = lfhasflag(lf, F_FALLDISTANCE);
|
||||
if (ff) {
|
||||
ff->val[0]++;
|
||||
} else {
|
||||
addflag(lf->flags, F_FALLDISTANCE, 1, NA, NA, NULL);
|
||||
}
|
||||
} else {
|
||||
int howfar;
|
||||
if (isplayer(lf)) {
|
||||
msg("You slam into the roof!");
|
||||
} else if (cansee(player, lf)){
|
||||
msg("%s slams into the roof!", lfname);
|
||||
}
|
||||
// take hitting roof damage
|
||||
losehp(lf, roll("1d4"), DT_FALL, NULL, "slamming into the roof");
|
||||
// how far did you fall?
|
||||
sumflags(lf->flags, F_FALLDISTANCE, &howfar, NULL, NULL);
|
||||
howfar++;
|
||||
// take hitting roof damage (less than floor). 1d4 per level.
|
||||
losehp(lf, rolldie(howfar, 4), DT_FALL, NULL, "slamming into the roof");
|
||||
killflagsofid(lf->flags, F_FALLDISTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3
lf.h
3
lf.h
|
@ -79,7 +79,7 @@ void gainmp(lifeform_t *lf, int amt);
|
|||
void gainxp(lifeform_t *lf, long amt);
|
||||
void genxplist(void);
|
||||
int getactspeed(lifeform_t *lf);
|
||||
void getadjallies(lifeform_t *lf, lifeform_t **adjally, int *nadjallies);
|
||||
void getadjallies(lifeform_t *lf, object_t *stairob, lifeform_t **adjally, int *nadjallies);
|
||||
enum ALLEGIENCE getallegiance(lifeform_t *lf);
|
||||
int getallouterarmour(lifeform_t *lf, object_t **ob, int *nobs);
|
||||
object_t *getarmour(lifeform_t *lf, enum BODYPART bp);
|
||||
|
@ -295,6 +295,7 @@ int takeoff(lifeform_t *lf, object_t *o);
|
|||
void taketime(lifeform_t *lf, long howlong);
|
||||
int throwat(lifeform_t *thrower, object_t *o, cell_t *where);
|
||||
void timeeffectslf(lifeform_t *lf);
|
||||
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat);
|
||||
void turneffectslf(lifeform_t *lf);
|
||||
int touch(lifeform_t *lf, object_t *o);
|
||||
void unpoison(lifeform_t *lf);
|
||||
|
|
121
map.c
121
map.c
|
@ -389,6 +389,20 @@ int addrandomthing(cell_t *c, int obchance, int *nadded) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
map_t *getmapindir(map_t *src, int dir) {
|
||||
map_t *other = NULL;
|
||||
if (src->nextmap[dir] != -1) {
|
||||
other = findmap(src->nextmap[dir]);
|
||||
} else {
|
||||
if (dir == D_DOWN) {
|
||||
other = findregionmap(src->region->id, src->depth+1);
|
||||
} else {
|
||||
other = findregionmap(src->region->id, src->depth-1);
|
||||
}
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
// populates retcell[] with all cells within given radius of centre
|
||||
void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells) {
|
||||
int (*distfunc)(cell_t *, cell_t *);
|
||||
|
@ -1276,6 +1290,20 @@ int countadjcellsoftype(cell_t *cell, int id) {
|
|||
return count;
|
||||
}
|
||||
|
||||
int countadjwalls(cell_t *cell) {
|
||||
int d;
|
||||
int walls = 0;
|
||||
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
cell_t *newcell;
|
||||
newcell = getcellindir(cell, d);
|
||||
if (!newcell || newcell->type->solid) {
|
||||
walls++;
|
||||
}
|
||||
}
|
||||
return walls;
|
||||
}
|
||||
|
||||
int countcellexits(cell_t *cell) {
|
||||
int d;
|
||||
int exits = 0;
|
||||
|
@ -1751,7 +1779,6 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
map_t *m;
|
||||
char buf[BUFLEN];
|
||||
int i,x,y;
|
||||
int firstworldmap = B_FALSE;
|
||||
enum HABITAT habitat;
|
||||
regionthing_t *thing[MAXOUTLINETHINGS];
|
||||
int nthings = 0;
|
||||
|
@ -1760,10 +1787,11 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
// note: we might override this later based on our region outline
|
||||
habitat = region->rtype->defaulthabitat;
|
||||
|
||||
/*
|
||||
if ((region->rtype->id == RG_WORLDMAP) && (depth == 1)) {
|
||||
firstworldmap = B_TRUE;
|
||||
}
|
||||
|
||||
*/
|
||||
map->beingcreated = B_TRUE;
|
||||
|
||||
map->depth = depth;
|
||||
|
@ -1777,6 +1805,9 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
|
||||
// link to other maps if required.
|
||||
// default to no links
|
||||
for (i = D_N; i <= D_W; i++) {
|
||||
map->nextmap[i] = -1;
|
||||
}
|
||||
for (i = D_UP; i <= D_DOWN; i++) {
|
||||
map->nextmap[i] = -1;
|
||||
}
|
||||
|
@ -1795,17 +1826,27 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// did we come from a previous map?
|
||||
if (parentmap) {
|
||||
parentmap->nextmap[exitdir] = map->id;
|
||||
for (i = 0; i < MAXDIR_ORTH; i++) {
|
||||
if (parentmap && (i == diropposite(exitdir)) ) {
|
||||
map->nextmap[diropposite(exitdir)] = parentmap->id;
|
||||
}
|
||||
|
||||
/*
|
||||
if (map->region->rtype->id == RG_WORLDMAP) {
|
||||
map_t *adjmap;
|
||||
for (i = D_N; i <= D_W; i++) {
|
||||
// is there a map this dir from us???
|
||||
adjmap = findmapcoords(, x, y);
|
||||
if (i == diropposite(exitdir) ) {
|
||||
map->nextmap[i] = parentmap->id;
|
||||
} else {
|
||||
map->nextmap[i] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
map->w = MAX_MAPW;
|
||||
map->h = MAX_MAPH;
|
||||
|
@ -1818,7 +1859,8 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
srand(map->seed);
|
||||
|
||||
// set map coords
|
||||
if (firstworldmap) {
|
||||
// first world map??
|
||||
if (map == firstmap) {
|
||||
addflag(map->flags, F_MAPCOORDS, 0, 0, NA, NULL);
|
||||
} else {
|
||||
// set mapcoords if not already done.
|
||||
|
@ -1947,7 +1989,8 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
}
|
||||
}
|
||||
|
||||
// link up holes - this will add matching holes on adjacent maps
|
||||
// link up holes - this will create NEW holes in THIS map connecting to
|
||||
// EXISTING unlinked holes in adjacent maps
|
||||
linkholes(map);
|
||||
|
||||
// add random objects and monsters
|
||||
|
@ -2175,8 +2218,8 @@ void createpit(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
c = getrandomcell(map);
|
||||
// clear it
|
||||
setcelltype(c, CT_CORRIDOR);
|
||||
// put an exit here
|
||||
o = addob(c->obpile, "hole in the roof");
|
||||
// put an exit here - don't link it yet - this will happen back in createmap().
|
||||
o = addobject(c->obpile, "hole in the roof", B_FALSE, B_FALSE);
|
||||
assert(o);
|
||||
}
|
||||
|
||||
|
@ -2622,10 +2665,10 @@ map_t *findsurfaceexitmap(map_t *m) {
|
|||
if (c) {
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, F_CLIMBABLE, D_UP, NA, NA, NULL)) {
|
||||
cell_t *c;
|
||||
c = getstairdestination(o);
|
||||
if (c) {
|
||||
return c->map;
|
||||
cell_t *newc;
|
||||
newc = getstairdestination(o);
|
||||
if (newc) {
|
||||
return newc->map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3449,22 +3492,25 @@ int iswallindir(cell_t *cell, int dir) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
// search for unlinked pits/holes in roof in adjacent maps
|
||||
// if we find any, add a matching end as close as we can in this map.
|
||||
// search for unlinked pits/holes in roof in ADJACENT maps
|
||||
// if we find any, add a matching end as close as we can in THIS map.
|
||||
void linkholes(map_t *map) {
|
||||
map_t *adjmap;
|
||||
cell_t *c;
|
||||
object_t *o, *newob;
|
||||
int x,y;
|
||||
// check previous map for pits.
|
||||
adjmap = findregionmap(map->region->id, map->depth-1);
|
||||
int dir;
|
||||
|
||||
for (dir = D_UP ; dir <= D_DOWN; dir++) {
|
||||
adjmap = getmapindir(map, dir);
|
||||
if (adjmap) {
|
||||
for (y = 0; y < adjmap->h; y++) {
|
||||
for (x = 0; x < adjmap->w; x++) {
|
||||
c = getcellat(adjmap, x, y);
|
||||
if (c) {
|
||||
// does the adjacent map have an unlinked pit going to us?
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, F_PIT, D_DOWN, NA, NA, NULL) &&
|
||||
if (hasflagval(o->flags, F_PIT, diropposite(dir), NA, NA, NULL) &&
|
||||
!hasflag(o->flags, F_MAPLINK)) {
|
||||
cell_t *c2;
|
||||
objecttype_t *ot;
|
||||
|
@ -3472,9 +3518,13 @@ void linkholes(map_t *map) {
|
|||
// make a link to it in this map, as close as possible to same pos
|
||||
c2 = getcellat(map, x, y);
|
||||
if (c2->type->solid) {
|
||||
c2 = real_getrandomadjcell(c2, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id);
|
||||
// this will automatically avoid lifeforms since we're using
|
||||
// we_walkable rather than we_notwall. this saves problems
|
||||
// with someine coming up underneath you!
|
||||
c2 = real_getrandomadjcell(c2, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id);
|
||||
}
|
||||
newob = addob(c2->obpile, ot->name);
|
||||
// note we specifically say DONT link the new hole!
|
||||
newob = addobject(c2->obpile, ot->name, B_FALSE, B_FALSE);
|
||||
// link them!
|
||||
linkstairs(newob);
|
||||
}
|
||||
|
@ -3484,12 +3534,12 @@ void linkholes(map_t *map) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// link the staircase 'o' to a free one in adjacent maps.
|
||||
// returns TRUE if it failed because othermap doesn't exist.
|
||||
int linkstairs(object_t *o) {
|
||||
map_t *othermap;
|
||||
int othermapid;
|
||||
object_t *o2;
|
||||
map_t *stairmap;
|
||||
cell_t *staircell;
|
||||
|
@ -3522,13 +3572,7 @@ int linkstairs(object_t *o) {
|
|||
// if so, find the first map in that region (ie depth 1)
|
||||
othermap = findregionmap(f->val[1], 1);
|
||||
} else {
|
||||
othermapid = stairmap->nextmap[f->val[0]];
|
||||
othermap = findmap(othermapid);
|
||||
|
||||
if (!othermap) {
|
||||
// find next map based on depth...
|
||||
othermap = findregionmap(stairmap->region->id, stairmap->depth+dir);
|
||||
}
|
||||
othermap = getmapindir(stairmap, f->val[0]);
|
||||
}
|
||||
if (othermap) {
|
||||
// find an empty staircase in other map
|
||||
|
@ -3536,23 +3580,8 @@ int linkstairs(object_t *o) {
|
|||
c2 = othermap->cell[n];
|
||||
o2 = hasob(c2->obpile, otherstairtype->id);
|
||||
if (o2) {
|
||||
int ok = B_FALSE;
|
||||
// does it go nowhere?
|
||||
if (!hasflag(o2->flags, F_MAPLINK)) {
|
||||
if (othermap->region->id == stairmap->region->id) {
|
||||
ok = B_TRUE;
|
||||
} else {
|
||||
/*
|
||||
// handle cross-region stairs!
|
||||
f = hasflag(o2->flags, F_CLIMBABLE);
|
||||
if (f->val[1] == stairmap->region->id) {
|
||||
ok = B_TRUE;
|
||||
}
|
||||
*/
|
||||
ok = B_TRUE;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
char obid[BUFLEN];
|
||||
// link it to here!
|
||||
sprintf(obid, "%ld", o->id);
|
||||
|
@ -3561,11 +3590,12 @@ int linkstairs(object_t *o) {
|
|||
sprintf(obid, "%ld", o2->id);
|
||||
addflag(o->flags, F_MAPLINK, othermap->id, NA, NA, obid);
|
||||
found = B_TRUE;
|
||||
// now mark that we are not a new staircase to a new region anymore
|
||||
f->val[1] = NA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
dblog("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id);
|
||||
msg("ERROR - stairs link to existing map %d, but it has no free stairs.",othermap->id);
|
||||
|
@ -3883,3 +3913,8 @@ int wallstoleftright(cell_t *c, int dir) {
|
|||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
2
map.h
2
map.h
|
@ -24,6 +24,7 @@ int getdoorlockdiff(int depth);
|
|||
int getdoorsecretdiff(int depth);
|
||||
flag_t *getmapcoords(map_t *m, int *x, int *y);
|
||||
int getmapdifficulty(map_t *m);
|
||||
map_t *getmapindir(map_t *src, int dir);
|
||||
void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlof, int wantcentre, cell_t **retcell, int *ncells);
|
||||
void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, int whichside, cell_t **retcell, int *ncells, int onlywantsolid);
|
||||
object_t *gettopobject(cell_t *where, int forglyph);
|
||||
|
@ -31,6 +32,7 @@ void calclight(map_t *map);
|
|||
int calcroompos(map_t *map, int w, int h, int *bx, int *by, int force);
|
||||
int countadjcellsoftype(cell_t *cell, int id);
|
||||
int countadjcellswithflag(cell_t *cell, enum FLAG fid);
|
||||
int countadjwalls(cell_t *cell);
|
||||
int countcellexits(cell_t *cell);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
|
|
63
move.c
63
move.c
|
@ -168,13 +168,24 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
|
||||
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_TRAP) && canseeob(lf, o)) {
|
||||
if (onlyifknown && !canseeob(lf, o)) continue;
|
||||
if (hasflag(o->flags, F_TRAP)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
if (f && (f->val[0] == D_DOWN)) {
|
||||
if (!isairborne(lf)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
if (f) {
|
||||
// non swimming creature in water?
|
||||
|
@ -340,6 +351,10 @@ int diropposite(int dir) {
|
|||
return DC_E;
|
||||
case DC_NW:
|
||||
return DC_SE;
|
||||
case D_UP:
|
||||
return D_DOWN;
|
||||
case D_DOWN:
|
||||
return D_UP;
|
||||
}
|
||||
// should never happen!
|
||||
return dir;
|
||||
|
@ -582,6 +597,39 @@ int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, in
|
|||
return bestdir;
|
||||
}
|
||||
|
||||
int getwalkoffdir(lifeform_t *lf, int dir) {
|
||||
switch (dir) {
|
||||
case DC_NE:
|
||||
if (lf->cell->y == 0) {
|
||||
return DC_N;
|
||||
} else if ( lf->cell->x == (lf->cell->map->w-1)) {
|
||||
return DC_E;
|
||||
}
|
||||
break;
|
||||
case DC_SE:
|
||||
if (lf->cell->y == (lf->cell->map->h-1)) {
|
||||
return DC_S;
|
||||
} else if ( lf->cell->x == (lf->cell->map->w-1)) {
|
||||
return DC_E;
|
||||
}
|
||||
break;
|
||||
case DC_SW:
|
||||
if (lf->cell->y == (lf->cell->map->h-1)) {
|
||||
return DC_S;
|
||||
} else if ( lf->cell->x == 0) {
|
||||
return DC_W;
|
||||
}
|
||||
break;
|
||||
case DC_NW:
|
||||
if (lf->cell->y == 0) {
|
||||
return DC_N;
|
||||
} else if ( lf->cell->x == 0) {
|
||||
return DC_W;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return D_NONE;
|
||||
}
|
||||
|
||||
// use 'n/a' for zero chance of falling. 0 means 'calculate based on distance'
|
||||
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff) {
|
||||
|
@ -2018,16 +2066,23 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (isswimming(lf)) {
|
||||
practice(lf, SK_SWIMMING, 1);
|
||||
}
|
||||
} else {
|
||||
} else { // ie !moveok
|
||||
object_t *inway = NULL;
|
||||
int door, dooropen;
|
||||
reason = errcode;
|
||||
switch (errcode) {
|
||||
case E_OFFMAP:
|
||||
if ((lf->cell->map->region == RG_WORLDMAP) && (isorthogonal(dir))) {
|
||||
if (lf->cell->map->region->rtype->id == RG_WORLDMAP) {
|
||||
// cope with nonorthogonal!
|
||||
// ie. ne counts as n if we are at the top.
|
||||
if (!isorthogonal(dir)) {
|
||||
dir = getwalkoffdir(lf, dir);
|
||||
}
|
||||
if (dir != D_NONE) {
|
||||
// we are allowed to walk off the edge
|
||||
return walkoffmap(lf, dir, B_TRUE);
|
||||
}
|
||||
}
|
||||
// otherwise fall through...
|
||||
case E_WALLINWAY:
|
||||
if (isplayer(lf)) {
|
||||
|
@ -2264,7 +2319,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (onpurpose) {
|
||||
// get list of adjacent allies
|
||||
if (isplayer(lf)) {
|
||||
getadjallies(lf, adjally, &nadjallies);
|
||||
getadjallies(lf, NULL, adjally, &nadjallies);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
move.h
1
move.h
|
@ -10,6 +10,7 @@ int diropposite(int dir);
|
|||
int dorandommove(lifeform_t *lf, int badmovesok, int restonfail);
|
||||
int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
|
||||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
|
||||
int getwalkoffdir(lifeform_t *lf, int dir);
|
||||
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff);
|
||||
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype);
|
||||
int moveclear(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
|
|
2
nexus.c
2
nexus.c
|
@ -192,7 +192,7 @@ int main(int argc, char **argv) {
|
|||
// create first dungeon
|
||||
dregion = findregionbytype(RG_FIRSTDUNGEON);
|
||||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, NULL, D_NONE);
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN);
|
||||
}
|
||||
|
||||
// find staircase
|
||||
|
|
105
objects.c
105
objects.c
|
@ -390,7 +390,7 @@ void addocnoun(objectclass_t *oc, char *text) {
|
|||
|
||||
// create a new object, stacking ok
|
||||
object_t *addob(obpile_t *where, char *name) {
|
||||
return addobject(where, name, B_TRUE);
|
||||
return addobject(where, name, B_TRUE, B_TRUE);
|
||||
}
|
||||
|
||||
// create a new object
|
||||
|
@ -399,7 +399,7 @@ object_t *addob(obpile_t *where, char *name) {
|
|||
// object with o->amt set, instead of
|
||||
// creating new obejct entries.
|
||||
// NOTE: This function MUST return number of obs created via global "nretobs"
|
||||
object_t *addobject(obpile_t *where, char *name, int canstack) {
|
||||
object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes) {
|
||||
objecttype_t *ot;
|
||||
object_t *o = NULL;
|
||||
char *p,*nsp,*p2;
|
||||
|
@ -981,52 +981,25 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
addflag(o->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, selhn->text);
|
||||
}
|
||||
|
||||
|
||||
// link holes to adjacent maps
|
||||
if (o && hasflag(o->flags,F_PIT)) {
|
||||
dblog("added pit");
|
||||
}
|
||||
|
||||
// create linked holes in adjacent maps
|
||||
if (wantlinkholes && o && hasflag(o->flags, F_PIT)) {
|
||||
cell_t *c;
|
||||
map_t *adjmap = NULL;
|
||||
|
||||
f = hasflag(o->flags, F_PIT);
|
||||
|
||||
c = getoblocation(o);
|
||||
if ((c->map->region->rtype->id == RG_WORLDMAP) && (f->val[0] == D_DOWN)) {
|
||||
// ie. going down from the surface. MUST be down because holes
|
||||
// going up make no sense!
|
||||
adjmap = getmapindir(c->map, f->val[0]);
|
||||
if ((c->map->region->rtype->id == RG_WORLDMAP) && !adjmap) {
|
||||
// ie. going down from the surface, and no dungeon below.
|
||||
// ( MUST be down because holes going up make no sense! )
|
||||
createregionlink(c->map, c, o, NULL, RG_PIT, c->map->region);
|
||||
} else {
|
||||
// create linked holes on any existing adjacent maps
|
||||
if (f->val[0] == D_DOWN) {
|
||||
adjmap = findregionmap(c->map->region->id, c->map->depth+1);
|
||||
} else if (f->val[0] == D_UP) {
|
||||
if ((c->map->region->rtype->id != RG_WORLDMAP) &&
|
||||
(c->map->depth == 1) &&
|
||||
(c->map->region->rtype->deeperdir == D_DOWN)) {
|
||||
cell_t *newcell;
|
||||
object_t *newob;
|
||||
char buf[BUFLEN];
|
||||
// ie. digging up to the surface
|
||||
adjmap = findsurfaceexitmap(c->map);
|
||||
// make a hole here. don't use linkholes since it can't
|
||||
// cross regions.
|
||||
newcell = getcellat(adjmap, c->x, c->y);
|
||||
if (newcell->type->solid) {
|
||||
newcell = real_getrandomadjcell(newcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, &(o->type->id));
|
||||
}
|
||||
|
||||
newob = addob(newcell->obpile, "hole in the ground");
|
||||
sprintf(buf, "%ld", o->id);
|
||||
addflag(newob->flags, F_MAPLINK, c->map->id, NA, NA, buf);
|
||||
|
||||
sprintf(buf, "%ld", newob->id);
|
||||
addflag(o->flags, F_MAPLINK, adjmap->id, NA, NA, buf);
|
||||
|
||||
// don't call linkholes
|
||||
adjmap = NULL;
|
||||
} else {
|
||||
adjmap = findregionmap(c->map->region->id, c->map->depth-1);
|
||||
}
|
||||
}
|
||||
// create linked holes on the map at the other end of this one.
|
||||
if (adjmap) {
|
||||
linkholes(adjmap);
|
||||
}
|
||||
|
@ -5043,6 +5016,8 @@ void initobjects(void) {
|
|||
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FASTMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
||||
addbrand(BR_SLOTH, "of sloth", BP_FEET);
|
||||
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SLOWMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
||||
addbrand(BR_STEALTH, "of stealth", BP_FEET);
|
||||
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SILENTMOVE, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
||||
|
||||
// hands
|
||||
addbrand(BR_POWER, "of power", BP_HANDS);
|
||||
|
@ -6131,7 +6106,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_FREEZEOB, "freezing touch", "Permenantly changes the next object touched into solid ice.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
|
@ -6709,7 +6684,7 @@ void initobjects(void) {
|
|||
addot(OT_WAND_DIGGING, "wand of digging", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DIG, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL);
|
||||
addot(OT_WAND_COLD, "wand of cold", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, RR_RARE, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_COLDRAY, NA, NA, NULL);
|
||||
|
@ -6846,6 +6821,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_ROPE, "rope", "A long length of strong rope.", MT_CLOTH, 5, OC_TOOLS);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_HELPSCLIMB, 3, NA, NA, NULL);
|
||||
|
||||
addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6973,7 +6953,28 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
||||
// tech - l3
|
||||
addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH);
|
||||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAINFO, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_PORTLADDER, "portable ladder", "A lightweight two metre ladder which automatically folds down to pocket size.", MT_METAL, 2, OC_TECH);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// tech - l4
|
||||
addot(OT_JETPACK, "jet pack", "A portable ion-thruster which allows the wearer to fly.", MT_METAL, 10, OC_TECH);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6982,21 +6983,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_FLYING, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// tech - l4
|
||||
addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH);
|
||||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAINFO, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
||||
|
@ -9888,14 +9874,10 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
sprintf(buf, "Where will you aim %s?",obname);
|
||||
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)) {
|
||||
} else {
|
||||
msg("You can't see there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
|
@ -10001,7 +9983,6 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
msg("%s zaps %s.",lfname,obname);
|
||||
}
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_LINKSPELL);
|
||||
if (f) {
|
||||
enum OBTYPE spelltocast;
|
||||
|
@ -11997,7 +11978,7 @@ object_t *splitob(object_t *o) {
|
|||
// doesn't matter if it goes down to zero, as we will put it back up soon.
|
||||
o->amt--;
|
||||
// give new object
|
||||
newob = addobject(o->pile, o->type->name, B_NOSTACK);
|
||||
newob = addobject(o->pile, o->type->name, B_NOSTACK, B_FALSE);
|
||||
// restore count
|
||||
o->amt++;
|
||||
if (newob) {
|
||||
|
|
|
@ -10,7 +10,7 @@ material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
|
|||
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour);
|
||||
void addocnoun(objectclass_t *oc, char *text);
|
||||
object_t *addob(obpile_t *where, char *name);
|
||||
object_t *addobject(obpile_t *where, char *name, int canstack);
|
||||
object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes);
|
||||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf, enum LOFTYPE needlof);
|
||||
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||
|
|
2
save.c
2
save.c
|
@ -498,7 +498,7 @@ int loadob(FILE *f, obpile_t *op, long *id) {
|
|||
return B_TRUE;
|
||||
}
|
||||
// create the object
|
||||
o = addobject(op, ot->name, B_NOSTACK); // no stacking!
|
||||
o = addobject(op, ot->name, B_NOSTACK, B_FALSE); // no stacking!
|
||||
|
||||
// overwrite ob parameters
|
||||
o->id = obid;
|
||||
|
|
49
spell.c
49
spell.c
|
@ -2584,29 +2584,49 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_DIG) {
|
||||
int numseen = 0;
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int nretcell,i;
|
||||
cell_t *c;
|
||||
int ndigs;
|
||||
char ch;
|
||||
int dir;
|
||||
|
||||
if (targcell) {
|
||||
dir = getdirtowards(caster->cell, targcell, NULL, B_FALSE, DT_COMPASS);
|
||||
} else {
|
||||
// don't need line of fire OR sight!
|
||||
if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE;
|
||||
//if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE;
|
||||
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn.-<>","-", B_FALSE);
|
||||
if ((ch == '.') || (ch == '-')) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
} else if (ch == '<') {
|
||||
return digup(caster, NULL);
|
||||
} else if (ch == '>') {
|
||||
return digdown(caster, NULL);
|
||||
} else {
|
||||
dir = chartodir(ch);
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a line from caster to the target cell
|
||||
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y,
|
||||
targcell->x, targcell->y, retcell, &nretcell);
|
||||
if (dir == DT_NONE) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
ndigs = 0;
|
||||
|
||||
// get rid of rock in the cells...
|
||||
for (i = 0; i < nretcell && (ndigs <= power) ; i++) {
|
||||
c = getcellindir(caster->cell, dir);
|
||||
while (c && (ndigs <= power)) {
|
||||
int seenthiscell = B_FALSE;
|
||||
if (haslos(player, retcell[i])) seenthiscell = B_TRUE;
|
||||
if (retcell[i]->type->solid) {
|
||||
|
||||
if (haslos(player, c)) seenthiscell = B_TRUE;
|
||||
|
||||
if (c->type->solid) {
|
||||
// can dig through stone, but nothing else.
|
||||
if (retcell[i]->type->material->id == MT_STONE) {
|
||||
setcelltype(retcell[i], retcell[i]->map->habitat->emptycelltype);
|
||||
if (seenthiscell) {
|
||||
if (c->type->material->id == MT_STONE) {
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
ndigs++;
|
||||
if (seenthiscell) {
|
||||
numseen++;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
@ -2616,7 +2636,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else {
|
||||
object_t *o;
|
||||
for (o = retcell[i]->obpile->first ; o ; o = o->next) {
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_IMPASSABLE)) {
|
||||
char obname[BUFLEN];
|
||||
// destroy this object then stop.
|
||||
|
@ -2632,6 +2652,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
}
|
||||
ndigs++;
|
||||
}
|
||||
|
||||
// announce destruction of any walls seen
|
||||
|
@ -3429,7 +3450,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else {
|
||||
// next thing touched
|
||||
addflag(caster->flags, F_FREEZINGTOUCH, 1, NA, NA, NULL);
|
||||
addflag(caster->flags, F_FREEZINGTOUCH, 1, NA, 10+power, NULL);
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands begin to glow blue!");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
|
Loading…
Reference in New Issue