- [+] display cell wall types in askcoords()
- [+] sort OC_ in defs.h - [+] when a monster UNHIDES, need to redraw!!! * [+] chain lightning - [+] teleportation trap - [+] wish bug with invalid strings: The xxx's strong scent leading east appears on the ground! - [+] bug: animals ggetting extra attacks due to unarmed skill. - [+] change melee attack with 2nd hand to happen at SKILLED level, not adept. * [+] infinite loops during creation - [+] make javelins weigh more - [+] potions still cost too much.. should be at least 1/3 the cost - [+] "you feel footprints here". need F_nofeel
This commit is contained in:
parent
b6c2fb818c
commit
3442dc293d
11
attack.c
11
attack.c
|
@ -28,7 +28,6 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty
|
|||
object_t *o;
|
||||
o = getequippedob(lf->pack, BP_BODY);
|
||||
if (o && (o->type->id == OT_FLAKJACKET)) {
|
||||
// stop ALL missile damage
|
||||
armour = o;
|
||||
}
|
||||
}
|
||||
|
@ -1001,14 +1000,14 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
// returns the amount of damage the armour blocked...
|
||||
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype) {
|
||||
int reduceamt = 0;
|
||||
float reducepct;
|
||||
int ar;
|
||||
object_t *o;
|
||||
|
||||
ar = getarmourrating(lf);
|
||||
|
||||
reducepct = getdamreducepct(ar);
|
||||
reduceamt = (int) ceil((reducepct / 100.0) * (float)dam);
|
||||
//reducepct = getdamreducepct(ar);
|
||||
//reduceamt = (int) ceil((reducepct / 100.0) * (float)dam);
|
||||
reduceamt = ar/2;
|
||||
|
||||
// special case
|
||||
if (damtype == DT_PROJECTILE) {
|
||||
|
@ -1455,11 +1454,13 @@ int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
|
|||
return dam;
|
||||
}
|
||||
|
||||
/*
|
||||
float getdamreducepct(float armourrating) {
|
||||
float reducepct;
|
||||
reducepct = (armourrating * 1.5);
|
||||
return reducepct;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
int getunarmeddamroll(flag_t *f) {
|
||||
|
@ -1659,7 +1660,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical)
|
|||
}
|
||||
|
||||
// victim immobile or asleep?
|
||||
if (isimmobile(victim)) {
|
||||
if (isimmobile(victim) || lfhasflag(victim, F_EATING)) {
|
||||
acc += 50;
|
||||
}
|
||||
|
||||
|
|
2
attack.h
2
attack.h
|
@ -15,7 +15,7 @@ int getextradamwep(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam);
|
|||
char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
|
||||
void getdamrange(flag_t *f, int *min, int *max);
|
||||
//void getdamrangeunarmed(flag_t *f, int *min, int *max);
|
||||
float getdamreducepct(float armourrating);
|
||||
//float getdamreducepct(float armourrating);
|
||||
int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag);
|
||||
//int getunarmeddamroll(flag_t *f);
|
||||
float getstrdammod(lifeform_t *lf);
|
||||
|
|
193
defs.h
193
defs.h
|
@ -534,27 +534,28 @@ enum DAMTYPE {
|
|||
|
||||
// Object Classes
|
||||
enum OBCLASS {
|
||||
OC_TERRAIN,
|
||||
OC_MONEY,
|
||||
OC_WEAPON,
|
||||
OC_ARMOUR,
|
||||
OC_MISSILE,
|
||||
OC_RING,
|
||||
OC_SCROLL,
|
||||
OC_POTION,
|
||||
OC_WAND,
|
||||
OC_FOOD,
|
||||
OC_CORPSE,
|
||||
OC_ROCK,
|
||||
OC_TOOLS,
|
||||
OC_TECH,
|
||||
OC_MISC,
|
||||
OC_FLORA,
|
||||
OC_SPELL,
|
||||
OC_ABILITY,
|
||||
OC_EFFECT,
|
||||
OC_DFEATURE,
|
||||
OC_ARMOUR,
|
||||
OC_BOOK,
|
||||
OC_CORPSE,
|
||||
OC_DFEATURE,
|
||||
OC_EFFECT,
|
||||
OC_FLORA,
|
||||
OC_FOOD,
|
||||
OC_MISC,
|
||||
OC_MISSILE,
|
||||
OC_MONEY,
|
||||
OC_POTION,
|
||||
OC_RING,
|
||||
OC_ROCK,
|
||||
OC_SCROLL,
|
||||
OC_TECH,
|
||||
OC_TERRAIN,
|
||||
OC_TOOLS,
|
||||
OC_TRAP,
|
||||
OC_SPELL,
|
||||
OC_WAND,
|
||||
OC_WEAPON,
|
||||
OC_NULL = -999
|
||||
};
|
||||
|
||||
|
@ -782,12 +783,13 @@ enum OBTYPE {
|
|||
OT_WATERSHALLOW,
|
||||
OT_WATERDEEP,
|
||||
// traps
|
||||
OT_TRAPROCK,
|
||||
OT_TRAPARROW,
|
||||
OT_TRAPARROWP,
|
||||
OT_TRAPGAS,
|
||||
OT_TRAPFIRE,
|
||||
OT_TRAPGAS,
|
||||
OT_TRAPMINE,
|
||||
OT_TRAPROCK,
|
||||
OT_TRAPTELEPORT,
|
||||
OT_TRAPTRIP,
|
||||
// rocks / plants
|
||||
OT_GOLD,
|
||||
|
@ -874,147 +876,6 @@ enum OBTYPE {
|
|||
// BOOKS
|
||||
OT_MANUAL,
|
||||
OT_SPELLBOOK,
|
||||
/*
|
||||
OT_MAN_ARMOUR,
|
||||
OT_MAN_ATHLETICS,
|
||||
OT_MAN_BACKSTAB,
|
||||
OT_MAN_COOKING,
|
||||
OT_MAN_FIRSTAID,
|
||||
OT_MAN_LISTEN,
|
||||
OT_MAN_LOCKPICKING,
|
||||
OT_MAN_MAGITEMUSAGE,
|
||||
OT_MAN_RANGED,
|
||||
OT_MAN_SHIELDS,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_SPOTHIDDEN,
|
||||
OT_MAN_STEALTH,
|
||||
OT_MAN_TECHUSAGE,
|
||||
OT_MAN_TRAPS,
|
||||
OT_MAN_TWOWEAPON,
|
||||
// manuals of knowledge
|
||||
OT_MAN_LORE_ARCANA,
|
||||
OT_MAN_LORE_DEMONS,
|
||||
OT_MAN_LORE_HUMANOID,
|
||||
OT_MAN_LORE_NATURE,
|
||||
OT_MAN_LORE_UNDEAD,
|
||||
// manuals of weaponry
|
||||
OT_MAN_AXES,
|
||||
OT_MAN_CLUBS,
|
||||
OT_MAN_LONGBLADES,
|
||||
OT_MAN_POLEARMS,
|
||||
OT_MAN_SHORTBLADES,
|
||||
OT_MAN_STAVES,
|
||||
OT_MAN_UNARMED,
|
||||
// manuals of spells
|
||||
OT_MAN_SS_ALLOMANCY,
|
||||
OT_MAN_SS_AIR,
|
||||
OT_MAN_SS_DEATH,
|
||||
OT_MAN_SS_DIVINATION,
|
||||
OT_MAN_SS_NATURE,
|
||||
OT_MAN_SS_FIRE,
|
||||
OT_MAN_SS_COLD,
|
||||
OT_MAN_SS_GRAVITY,
|
||||
OT_MAN_SS_LIFE,
|
||||
OT_MAN_SS_MODIFICATION,
|
||||
OT_MAN_SS_MENTAL,
|
||||
OT_MAN_SS_SUMMONING,
|
||||
OT_MAN_SS_TRANSLOCATION,
|
||||
OT_MAN_SS_WILD,
|
||||
// SPELLBOOKS
|
||||
// allomancy can't be learned from books
|
||||
// -- death
|
||||
OT_SB_ANIMATEDEAD,
|
||||
OT_SB_DRAINLIFE,
|
||||
OT_SB_FEAR,
|
||||
OT_SB_PAIN,
|
||||
OT_SB_PARALYZE,
|
||||
OT_SB_POISONBOLT,
|
||||
OT_SB_INFINITEDEATH,
|
||||
OT_SB_WEAKEN,
|
||||
OT_SB_FEEBLEMIND,
|
||||
OT_SB_BLINDNESS,
|
||||
OT_SB_POSSESSION,
|
||||
OT_SB_STENCH,
|
||||
// -- divination
|
||||
OT_SB_DETECTAURA,
|
||||
OT_SB_DETECTLIFE,
|
||||
OT_SB_DETECTOBS,
|
||||
OT_SB_LOCATEOBJECT,
|
||||
OT_SB_LORE,
|
||||
OT_SB_REVEALHIDDEN,
|
||||
OT_SB_IDENTIFY,
|
||||
OT_SB_MAPPING,
|
||||
OT_SB_SEEINVIS,
|
||||
// -- elemental - air
|
||||
OT_SB_AIRBLAST,
|
||||
OT_SB_CALLLIGHTNING,
|
||||
OT_SB_CLOUDKILL,
|
||||
OT_SB_GUSTOFWIND,
|
||||
OT_SB_LIGHTNINGSTORM,
|
||||
OT_SB_WINDSHIELD,
|
||||
// -- elemental - fire
|
||||
OT_SB_BLADEBURN,
|
||||
OT_SB_BURNINGWAVE,
|
||||
OT_SB_FIREDART,
|
||||
OT_SB_FIREBALL,
|
||||
OT_SB_FLAMEPILLAR,
|
||||
OT_SB_FLAMEBURST,
|
||||
OT_SB_SPARK,
|
||||
// -- elemental - ice
|
||||
OT_SB_CHILL,
|
||||
OT_SB_CONECOLD,
|
||||
OT_SB_COLDBURST,
|
||||
OT_SB_FREEZEOB,
|
||||
OT_SB_FROSTBITE,
|
||||
OT_SB_ICEEDGE,
|
||||
OT_SB_ICICLE,
|
||||
OT_SB_WALLOFICE,
|
||||
// -- elemental - earth
|
||||
OT_SB_DIG,
|
||||
// -- gravity
|
||||
OT_SB_GRAVLOWER,
|
||||
OT_SB_GRAVBOOST,
|
||||
OT_SB_HASTE,
|
||||
OT_SB_FLIGHT,
|
||||
OT_SB_SLOW,
|
||||
OT_SB_LEVITATION,
|
||||
// -- life
|
||||
OT_SB_HEALING,
|
||||
OT_SB_HEALINGMIN,
|
||||
OT_SB_HEALINGMAJ,
|
||||
OT_SB_TURNUNDEAD,
|
||||
// -- mental / psionic
|
||||
OT_SB_MINDSCAN,
|
||||
OT_SB_SLEEP,
|
||||
OT_SB_TELEKINESIS,
|
||||
OT_SB_PACIFY,
|
||||
OT_SB_PSYARMOUR,
|
||||
OT_SB_CHARM,
|
||||
// -- modification
|
||||
OT_SB_GASEOUSFORM,
|
||||
OT_SB_GREASE,
|
||||
OT_SB_KNOCK,
|
||||
OT_SB_HOLDPORTAL,
|
||||
OT_SB_INSCRIBE,
|
||||
OT_SB_INVISIBILITY,
|
||||
OT_SB_LIGHT,
|
||||
OT_SB_DARKNESS,
|
||||
OT_SB_MENDING,
|
||||
OT_SB_PASSWALL,
|
||||
OT_SB_PETRIFY,
|
||||
OT_SB_POLYMORPH,
|
||||
OT_SB_STICKTOSNAKE,
|
||||
// -- summoning
|
||||
OT_SB_CREATEMONSTER,
|
||||
OT_SB_SUMMONWEAPON,
|
||||
// -- translocation
|
||||
OT_SB_BLINK,
|
||||
OT_SB_DISPERSAL,
|
||||
OT_SB_GATE,
|
||||
OT_SB_TELEPORT,
|
||||
OT_SB_TWIDDLE,
|
||||
// -- wild can't be learned from books
|
||||
*/
|
||||
// spells
|
||||
// -- allomancy
|
||||
OT_S_ABSORBMETAL,
|
||||
|
@ -1051,6 +912,7 @@ enum OBTYPE {
|
|||
// -- elemental - air
|
||||
OT_S_JOLT,
|
||||
OT_S_AIRBLAST,
|
||||
OT_S_CHAINLIGHTNING,
|
||||
OT_S_CLOUDKILL,
|
||||
OT_S_GUSTOFWIND,
|
||||
OT_S_MIST,
|
||||
|
@ -1506,6 +1368,7 @@ enum FLAG {
|
|||
F_NONE, // dummy flag
|
||||
// map flags
|
||||
F_MAPCOORDS, // v0+v1 are x/y coords for this map area
|
||||
F_ROOMEXIT, // there is an exit from room v0 at x=v1,y=v2
|
||||
// object flags
|
||||
F_DEAD, // object will be removed
|
||||
F_CREATEDBY, // object was made by lf id v0, text=real lfname
|
||||
|
@ -1525,6 +1388,7 @@ enum FLAG {
|
|||
// v2 = enum sense used to see this (ie. s_smell, s_sight)
|
||||
// (optional) text = lfid of lf who left this.
|
||||
// should only be used for SCENT, not footprints.
|
||||
F_NOFEEL, // when blind, don't show "you can feel xxx"
|
||||
// for items in shops
|
||||
F_SHOPITEM, // causes shops to show this item as identified
|
||||
F_VALUE, // how much an item is worth (over its base weight+material)
|
||||
|
@ -1946,7 +1810,8 @@ enum FLAG {
|
|||
// next to the attacker
|
||||
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
|
||||
F_MORALE, // gain +v0 in morale checks.
|
||||
F_SPOTTED, // you have spotted hiding lf id v0
|
||||
F_SPOTTED, // you have spotted hiding lf id v0. you lsoe this if they
|
||||
// go out of sight.
|
||||
// INTRINSICS
|
||||
F_MAGICARMOUR,// armour is magically boosted. f->text is the description
|
||||
// ie 'magic armour', 'force field'
|
||||
|
@ -2107,6 +1972,7 @@ enum FLAG {
|
|||
F_VAULTATLF, // v0/1=x/y, v1=pctchance, text=lfname
|
||||
F_VAULTATCELL, // v0/1=x/y, v1=pctchance, text=cellname
|
||||
F_VAULTBOX, // v0=thingtype, v1=pctchance, v2=fill?, text=x1,y1,x2,y2,thingname
|
||||
F_VAULTEXIT, // v0/1=x,y for exit.
|
||||
F_VAULTSCATTER, // v0=thingtype, v1=pctchance
|
||||
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
||||
// if maxcount is PCT, mincount is a percentage
|
||||
|
@ -2363,6 +2229,7 @@ enum VAULTSTATE {
|
|||
|
||||
enum VAULTTHING {
|
||||
VT_NONE,
|
||||
VT_EXIT,
|
||||
VT_OB,
|
||||
VT_LF,
|
||||
VT_CELL,
|
||||
|
|
|
@ -38,3 +38,13 @@ Z = undead
|
|||
---
|
||||
C
|
||||
hybrid human animal?
|
||||
|
||||
----------
|
||||
~ = deep liquid (water / lava)
|
||||
[ = tool
|
||||
] = armour
|
||||
} = gas
|
||||
, = small puddle
|
||||
{ = large puddle/pool
|
||||
( = barrel
|
||||
\ = furniture
|
||||
|
|
|
@ -17,6 +17,9 @@ General format:
|
|||
|
||||
Legend is:
|
||||
c:type:what[:pct]
|
||||
OR
|
||||
c:exit
|
||||
|
||||
|
||||
c = any letter
|
||||
type = ob, mon or cell
|
||||
|
@ -28,6 +31,8 @@ Flags can be:
|
|||
'type' can be: ob, mon, cell
|
||||
coords can be negative ("count back from right/bottom")
|
||||
|
||||
exitat(x,y) // vault exit is at position x,y
|
||||
|
||||
box(x,y,x2,y2) type:what[:pct] // outline box with what
|
||||
fill(x,y,x2,y2) type:what[:pct] // filled box with what
|
||||
coords can be negative ("count back from right/bottom")
|
||||
|
|
58
io.c
58
io.c
|
@ -285,6 +285,59 @@ void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char c
|
|||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour) {
|
||||
glyph_t gl;
|
||||
int i;
|
||||
cell_t *retcell[MAXRETCELLS];
|
||||
int ndst;
|
||||
|
||||
calcbresnham(src->map, src->x, src->y, dst->x, dst->y, retcell, &ndst);
|
||||
|
||||
gl.ch = ch;
|
||||
gl.colour = colour;
|
||||
|
||||
// hide cursor
|
||||
curs_set(0);
|
||||
for (i = 0; i < ndst; i++) {
|
||||
int n;
|
||||
|
||||
if ((i % 2) == 0) {
|
||||
gl.ch = ch;
|
||||
} else {
|
||||
gl.ch = ch2;
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
// update screen each time
|
||||
updateviewfor(src);
|
||||
drawlevelfor(player);
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
// draw one at a time
|
||||
for (n = 0; n <= i; n++) {
|
||||
drawglyph(&gl, retcell[n]->x - viewx, retcell[n]->y - viewy);
|
||||
}
|
||||
} else {
|
||||
drawglyph(&gl, retcell[i]->x - viewx, retcell[i]->y - viewy);
|
||||
}
|
||||
|
||||
if (gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gradual) {
|
||||
wrefresh(gamewin);
|
||||
usleep(ANIMDELAY);
|
||||
}
|
||||
// show cursor
|
||||
curs_set(1);
|
||||
|
||||
needredraw = B_TRUE;
|
||||
}
|
||||
|
||||
void animradial(cell_t *src, int radius, char ch, int colour) {
|
||||
glyph_t gl;
|
||||
int i;
|
||||
|
@ -759,7 +812,7 @@ cell_t *askcoords(char *prompt, int targettype, lifeform_t *srclf, int maxrange,
|
|||
gettopobname(c, buf);
|
||||
}
|
||||
} else {
|
||||
// can't see objects or lf there
|
||||
// can't see this cell
|
||||
void *thing;
|
||||
char desc[BUFLEN];
|
||||
switch (isinscanrange(c, &thing, desc, NULL)) {
|
||||
|
@ -7106,11 +7159,14 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol);
|
||||
|
||||
mvwprintw(mainwin, y2, x2, ftext, "Armour Rating");
|
||||
/*
|
||||
if (arating > 0) {
|
||||
wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++;
|
||||
} else {
|
||||
wprintw(mainwin, "%d", arating); y2++;
|
||||
}
|
||||
*/
|
||||
wprintw(mainwin, "%d", arating); y2++;
|
||||
if (lorelev >= PR_NOVICE) unsetcol(mainwin, lorecol);
|
||||
}
|
||||
|
||||
|
|
1
io.h
1
io.h
|
@ -5,6 +5,7 @@ void addheading(prompt_t *p, char *text);
|
|||
void addmsghist(char *text);
|
||||
void addpromptq(prompt_t *p, char *q);
|
||||
void anim(cell_t *src, cell_t *dst, char ch, int colour);
|
||||
void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour);
|
||||
void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char ch2, int colour);
|
||||
void animradial(cell_t *src, int radius, char ch, int colour);
|
||||
void animradialorth(cell_t *src, int radius, char ch, int colour);
|
||||
|
|
33
lf.c
33
lf.c
|
@ -4005,9 +4005,11 @@ int getmaxattacks(lifeform_t *lf) {
|
|||
|
||||
// if we have high unarmed skill and our second hand is free,
|
||||
// we get one more attack
|
||||
if (getskill(lf, SK_UNARMED) >= PR_ADEPT) {
|
||||
if (!getequippedob(lf->pack, BP_SECWEAPON)) {
|
||||
maxattacks++;
|
||||
if (lfhasflag(lf, F_HUMANOID)) {
|
||||
if (getskill(lf, SK_UNARMED) >= PR_SKILLED) {
|
||||
if (hasbp(lf, BP_SECWEAPON) && !getequippedob(lf->pack, BP_SECWEAPON)) {
|
||||
maxattacks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5504,6 +5506,14 @@ int giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
msg("You can now deflect attacks with your second weapon.");
|
||||
}
|
||||
}
|
||||
} else if (id == SK_UNARMED) {
|
||||
if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) {
|
||||
if (f->val[1] == PR_SKILLED) {
|
||||
if (hasbp(lf, BP_SECWEAPON)) {
|
||||
msg("You can now make melee attacks with your off-hand.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id == SK_SS_ALLOMANCY) {
|
||||
// give all allomantic spells
|
||||
mayusespellschool(lf->flags, SS_ALLOMANCY, F_CANCAST);
|
||||
|
@ -7268,7 +7278,6 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTOBCLASS, 40, OC_POTION, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-3 darts");
|
||||
addflag(lastrace->flags, F_STARTOB, 33, NA, NA, "javelin");
|
||||
addflag(lastrace->flags, F_STARTOB, 33, NA, NA, "leather armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 33, NA, NA, "buckler");
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 gold coins");
|
||||
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -10089,12 +10098,9 @@ flag_t *levelabilityready(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
void loseconcentration(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
// stop sprinting
|
||||
f = lfhasflag(lf, F_SPRINTING);
|
||||
if (f && f->val[0]) {
|
||||
killflag(f);
|
||||
}
|
||||
stopsprinting(lf);
|
||||
|
||||
// boost spells end
|
||||
stopallspells(lf);
|
||||
|
||||
|
@ -12393,6 +12399,11 @@ void stoprunning(lifeform_t *lf) {
|
|||
if (f) {
|
||||
killflag(f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void stopsprinting(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
f = lfhasflag(lf, F_SPRINTING);
|
||||
if (f && f->val[0]) {
|
||||
killflag(f);
|
||||
|
@ -12863,7 +12874,7 @@ void turneffectslf(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// secret doors, traps, etc?
|
||||
if (isplayer(lf) && !isinbattle(lf) && !isblind(lf)) {
|
||||
if (isplayer(lf) && !isinbattle(lf) && !isblind(lf) && !lfhasflag(lf, F_TRAINING)) {
|
||||
for (i = 0; i < lf->nlos; i++) {
|
||||
if (!lf->los[i]->lf) {
|
||||
object_t *o;
|
||||
|
@ -13548,6 +13559,7 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
// move player to new map
|
||||
moveto(lf, newcell, B_TRUE, B_TRUE);
|
||||
if ((dir == D_UP) && !isairborne(lf)) {
|
||||
stopsprinting(adjally[n]); // you can sprint down stairs, but not up
|
||||
taketime(lf, getmovespeed(lf)*2); // takes longer to climb
|
||||
} else {
|
||||
taketime(lf, getmovespeed(lf));
|
||||
|
@ -13559,6 +13571,7 @@ int usestairs(lifeform_t *lf, object_t *o) {
|
|||
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
if (!initiatemove(adjally[n], NULL, NULL)) {
|
||||
stopsprinting(adjally[n]);
|
||||
movelf(adjally[n], c);
|
||||
if ((dir == D_UP) && !isairborne(adjally[n])) {
|
||||
taketime(adjally[n], getmovespeed(adjally[n])*2); // takes longer to climb
|
||||
|
|
1
lf.h
1
lf.h
|
@ -281,6 +281,7 @@ int stone(lifeform_t *lf);
|
|||
void stopeating(lifeform_t *lf);
|
||||
void stopresting(lifeform_t *lf);
|
||||
void stoprunning(lifeform_t *lf);
|
||||
void stopsprinting(lifeform_t *lf);
|
||||
int testammo(lifeform_t *lf, object_t *o);
|
||||
int takeoff(lifeform_t *lf, object_t *o);
|
||||
void taketime(lifeform_t *lf, long howlong);
|
||||
|
|
44
map.c
44
map.c
|
@ -1213,7 +1213,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
if (rnd(1,100) <= getvaultchance(map)) {
|
||||
vault_t *v;
|
||||
v = getvaulttype(map);
|
||||
if (!createvault(map, i, v, &roomw[i],&roomh[i])) {
|
||||
if (createvault(map, i, v, &roomw[i],&roomh[i])) {
|
||||
// failed
|
||||
} else {
|
||||
// success
|
||||
roomvault[i] = v;
|
||||
}
|
||||
|
@ -1309,7 +1311,9 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
while (!done) {
|
||||
c = getrandomroomcell(map, i);
|
||||
// if nothing there
|
||||
if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||
//if (c && isempty(c) && !countobs(c->obpile, B_TRUE)) {
|
||||
if (c && cellwalkable(NULL, c, NULL)) {
|
||||
|
||||
int obchance;
|
||||
int nadded = 0;
|
||||
|
||||
|
@ -1330,6 +1334,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir) {
|
|||
}
|
||||
|
||||
if (ntries >= numobs) {
|
||||
done = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1654,6 +1659,11 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth) {
|
|||
int w,h,x,y;
|
||||
int minx,miny,maxx,maxy;
|
||||
flag_t *f;
|
||||
|
||||
// default
|
||||
if (retw) *retw = -1;
|
||||
if (reth) *reth = -1;
|
||||
|
||||
if (!v) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1670,8 +1680,6 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth) {
|
|||
// get width/height from vault
|
||||
w = v->w;
|
||||
h = v->h;
|
||||
if (retw) *retw = w;
|
||||
if (reth) *reth = h;
|
||||
// find vault position
|
||||
if (calcroompos(map, w, h, &minx, &miny)) {
|
||||
dblog("** couldn't make vault room!\n");
|
||||
|
@ -1698,6 +1706,9 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth) {
|
|||
}
|
||||
}
|
||||
|
||||
if (retw) *retw = w;
|
||||
if (reth) *reth = h;
|
||||
|
||||
// add other stuff to the vault
|
||||
addvaultcontents(map, v, minx, miny, maxx, maxy);
|
||||
|
||||
|
@ -1706,19 +1717,19 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth) {
|
|||
autodoors(map, roomid, minx, miny, maxx, maxy);
|
||||
}
|
||||
|
||||
linkdoors(map, roomid, minx, miny, maxx,maxy);
|
||||
linkexits(map, roomid, minx, miny, maxx,maxy);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// make sure doors in a given room link up to the rest of the map.
|
||||
void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
|
||||
// make sure exits/doors in a given room link up to the rest of the map.
|
||||
void linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
|
||||
int x,y,i;
|
||||
cell_t *poss[MAXCANDIDATES],*c;
|
||||
int nposs = 0;
|
||||
int db = B_FALSE;
|
||||
|
||||
if (db) dblog("linkdoors for roomid %d", roomid);
|
||||
if (db) dblog("linkexits for roomid %d", roomid);
|
||||
|
||||
// find all doors // TODO: ...or "exits"
|
||||
for (y = miny; y <= maxy; y++) {
|
||||
|
@ -1726,14 +1737,14 @@ void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
|
|||
c = getcellat(m, x, y);
|
||||
if (!c) continue;
|
||||
|
||||
if (hasobwithflag(c->obpile, F_DOOR)) {
|
||||
if (db) dblog("found door at %d,%d",x,y);
|
||||
if (hasobwithflag(c->obpile, F_DOOR) || hasflagval(m->flags, F_ROOMEXIT, roomid, x, y, NULL)) {
|
||||
if (db) dblog("found door/exit at %d,%d",x,y);
|
||||
poss[nposs++] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (db) dblog("%d doors found.",nposs);
|
||||
if (db) dblog("%d doors/exits found.",nposs);
|
||||
|
||||
// for each door, make sure it links to at least one cell which isn't
|
||||
// part of this room
|
||||
|
@ -1794,12 +1805,12 @@ void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy) {
|
|||
c = getcellindir(poss[i], whichway);
|
||||
while (c && !cellwalkable(NULL, c, NULL)) {
|
||||
setcelltype(c, getemptycelltype(c->map->habitat));
|
||||
c = getcellindir(poss[i], whichway);
|
||||
c = getcellindir(c, whichway);
|
||||
}
|
||||
}
|
||||
} // end if ncorridors = 0
|
||||
} // end for each door
|
||||
if (db) dblog("linkdoors complete.");
|
||||
if (db) dblog("linkexits complete.");
|
||||
}
|
||||
|
||||
// room w/h are returned in *w and *h if given.
|
||||
|
@ -2459,7 +2470,7 @@ cell_t *getrandomcell(map_t *map) {
|
|||
return cell;
|
||||
}
|
||||
|
||||
cell_t *getrandomcelloftype(map_t *map, int id) {
|
||||
cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id) {
|
||||
cell_t *cell;
|
||||
cell = getrandomcell(map);
|
||||
while (cell->type->id != id) {
|
||||
|
@ -2491,7 +2502,10 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
|
|||
for (x = 0; x < map->w; x++) {
|
||||
c = getcellat(map, x, y);
|
||||
// is this cell in the correct room and not a wall?
|
||||
if (c && isempty(c)) {
|
||||
// using c->type->solid in case we have a room
|
||||
// filled with boulders
|
||||
//if (c && cellwalkable(NULL, c, NULL)) {
|
||||
if (c && !c->type->solid) {
|
||||
int ok = B_FALSE;
|
||||
if (c->roomid == roomid) {
|
||||
ok = B_TRUE;
|
||||
|
|
4
map.h
4
map.h
|
@ -53,7 +53,7 @@ int getthingchance(int habitat);
|
|||
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
|
||||
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob);
|
||||
cell_t *getrandomcell(map_t *map);
|
||||
cell_t *getrandomcelloftype(map_t *map, int id);
|
||||
cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id);
|
||||
int getrandomdir(int dirtype);
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid);
|
||||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
||||
|
@ -76,7 +76,7 @@ int isnewcellok(cell_t *cell, char *err);
|
|||
int isonmap(map_t *map, int x, int y);
|
||||
int isoutdoors(map_t *m);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
void linkdoors(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||
void linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||
int linkstairs(object_t *o);
|
||||
void makedoor(cell_t *cell);
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||
|
|
6
move.c
6
move.c
|
@ -917,7 +917,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
didmsg = B_TRUE;
|
||||
}
|
||||
// stop sprinting
|
||||
stoprunning(lf);
|
||||
stopsprinting(lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1295,7 +1295,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
|
|||
touch(lf, o);
|
||||
|
||||
// stop sprinting
|
||||
stoprunning(lf);
|
||||
stopsprinting(lf);
|
||||
/*
|
||||
sf = lfhasflag(lf, F_SPRINTING);
|
||||
if (sf && sf->val[0]) {
|
||||
|
@ -1455,7 +1455,7 @@ int closedoor(lifeform_t *lf, object_t *o) {
|
|||
|
||||
if (lf) {
|
||||
// stop sprinting
|
||||
stoprunning(lf);
|
||||
stopsprinting(lf);
|
||||
|
||||
if (isplayer(lf)) {
|
||||
msg("You close %s.", obname);
|
||||
|
|
102
objects.c
102
objects.c
|
@ -427,7 +427,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
enum FLAG doorflag[5];
|
||||
int ndoorflags = 0;
|
||||
|
||||
addedob[0] = NULL; // just in case we don't add any
|
||||
// just in case we don't add any
|
||||
addedob[0] = NULL;
|
||||
nadded = 0;
|
||||
nretobs = 0;
|
||||
|
||||
localname = strdup(name);
|
||||
|
||||
|
@ -686,6 +689,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|||
if (!ot) {
|
||||
//if (gamestarted) msg("DB: No match for object name '%s'", p );
|
||||
if (db) dblog("DB: No match for object name '%s'", p );
|
||||
nretobs = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2046,6 +2050,10 @@ int canseeob(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isblind(player) && hasflag(o->flags, F_NOFEEL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -2939,9 +2947,9 @@ int getobvalue(object_t *o) {
|
|||
// do nothing
|
||||
price += (pow(getspelllevel(f->val[0]), 2) * 2);
|
||||
} else if (o->type->obclass->id == OC_POTION) {
|
||||
price += (pow(getspelllevel(f->val[0]), 2) * 15);
|
||||
price += (pow(getspelllevel(f->val[0]), 2) * 5);
|
||||
} else if (o->type->obclass->id == OC_WAND) {
|
||||
price += (pow(getspelllevel(f->val[0]), 2) * 22);
|
||||
price += (pow(getspelllevel(f->val[0]), 2) * 15);
|
||||
}
|
||||
} else if (f->id == F_MANUALOF) {
|
||||
price *= 124;
|
||||
|
@ -4554,21 +4562,32 @@ int getthrowdam(object_t *o) {
|
|||
return (int)dam;
|
||||
}
|
||||
|
||||
// get either name of top object, or cell type if solid
|
||||
char *gettopobname(cell_t *c, char *retbuf) {
|
||||
char buf[BUFLEN];
|
||||
object_t *o;
|
||||
o = gettopobject(c);
|
||||
if (o) {
|
||||
int nother;
|
||||
getobname(o, buf, o->amt);
|
||||
strcat(retbuf, buf);
|
||||
// other obs here too?
|
||||
nother = countnoncosmeticobs(c->obpile, B_TRUE) - 1;
|
||||
if (nother >= 1) {
|
||||
int nother;
|
||||
if (c->type->solid) {
|
||||
strcpy(retbuf, c->type->name);
|
||||
nother = countnoncosmeticobs(c->obpile, B_TRUE);
|
||||
if (nother) {
|
||||
sprintf(buf, " (+%d other thing%s)", nother, (nother == 1) ? "" : "s");
|
||||
strcat(retbuf, buf);
|
||||
}
|
||||
return retbuf;
|
||||
} else {
|
||||
object_t *o;
|
||||
o = gettopobject(c);
|
||||
if (o) {
|
||||
getobname(o, buf, o->amt);
|
||||
strcat(retbuf, buf);
|
||||
// other obs here too?
|
||||
nother = countnoncosmeticobs(c->obpile, B_TRUE) - 1;
|
||||
if (nother >= 1) {
|
||||
sprintf(buf, " (+%d other thing%s)", nother, (nother == 1) ? "" : "s");
|
||||
strcat(retbuf, buf);
|
||||
}
|
||||
return retbuf;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5074,7 +5093,7 @@ void initobjects(void) {
|
|||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_OBHPDRAIN, 1, DT_DECAY, NA, NULL); // ie. corpses last for 50 turns
|
||||
addoc(OC_TECH, "Technology", "A strange piece of futuristic technology.", '~', C_GREY);
|
||||
addoc(OC_TECH, "Technology", "A strange piece of futuristic technology.", '[', C_GREY);
|
||||
addocnoun(lastobjectclass, "technology");
|
||||
addocnoun(lastobjectclass, "tech");
|
||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5208,7 +5227,7 @@ void initobjects(void) {
|
|||
addot(OT_WATERSHALLOW, "shallow water", "Waist-deep water.", MT_WATER, 150, OC_TERRAIN);
|
||||
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{");
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "~");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DEEPWATER, DP_WAIST, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice");
|
||||
|
@ -5220,7 +5239,7 @@ void initobjects(void) {
|
|||
addot(OT_WATERDEEP, "deep water", "Very deep water.", MT_WATER, 300, OC_TERRAIN);
|
||||
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDBLUE, NA, NA, "{");
|
||||
addflag(lastot->flags, F_GLYPH, C_BOLDBLUE, NA, NA, "~");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice");
|
||||
addflag(lastot->flags, F_DTCREATEOB, DT_FIRE, 1, DT_COMPASS, "cloud of steam");
|
||||
|
@ -5246,9 +5265,16 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||
addflag(lastot->flags, F_SECRET, 25, NA, NA, NULL);
|
||||
addot(OT_TRAPTELEPORT, "teleportation trap", "A magical dispersal field.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, NA, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_MAGENTA, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
||||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5257,7 +5283,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||
addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, 25, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5266,7 +5291,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||
addot(OT_TRAPGAS, "gas trap", "A pressure plate which releases poisonous gas.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, 27, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5275,7 +5299,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||
addot(OT_TRAPFIRE, "fire trap", "A pressure plate which fires a pillar of flame.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5284,7 +5307,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SECRET, 30, NA, NA, NULL);
|
||||
addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_TRAP);
|
||||
addflag(lastot->flags, F_TRAP, 30, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_TRAP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 20, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "^");
|
||||
|
@ -5846,6 +5868,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs between all nearby enemies.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
||||
///////////////////
|
||||
// elemental - fire
|
||||
///////////////////
|
||||
|
@ -6080,13 +6108,12 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
||||
// l5
|
||||
// l6
|
||||
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
// l6
|
||||
addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
|
@ -7153,7 +7180,7 @@ void initobjects(void) {
|
|||
addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
|
||||
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
||||
|
@ -7204,7 +7231,7 @@ void initobjects(void) {
|
|||
addot(OT_MUDPOOL, "pool of mud", "A large puddle of wet mud.", MT_WATER, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ",");
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "{");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7231,7 +7258,7 @@ void initobjects(void) {
|
|||
addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, ",");
|
||||
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_FOREST, 85, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7249,6 +7276,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_BLOODCSPLASH, "splash of cockatrice blood", "A small pool of cockatrice blood.", MT_BLOOD, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7280,23 +7308,24 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_BLOODPOOL, "pool of blood", "A large pool of blood.", MT_BLOOD, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SLIPPERY, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "blood stain");
|
||||
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up");
|
||||
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up");
|
||||
addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 45, 45, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
|
||||
|
||||
addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 20, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
||||
|
@ -7341,6 +7370,7 @@ void initobjects(void) {
|
|||
addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC);
|
||||
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NO_PLURAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
|
||||
|
@ -8003,7 +8033,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, 1.5, OC_MISSILE);
|
||||
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 6.5, 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, "");
|
||||
|
@ -12560,9 +12590,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
throwdam = getthrowdam(o);
|
||||
dam = (int)((float)throwdam * multiplier);
|
||||
takedamage(shield, dam, DT_PROJECTILE);
|
||||
|
||||
youhit = B_FALSE;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12832,7 +12860,7 @@ void timeeffectsob(object_t *o) {
|
|||
|
||||
if (haslos(player, location)) {
|
||||
getobname(sg, sgname, sg->amt);
|
||||
canseeloc = B_FALSE;
|
||||
canseeloc = B_TRUE;
|
||||
msg("The %s pulses %s!", noprefix(sgname),
|
||||
(o->blessed == B_CURSED) ? "white" : "black");
|
||||
}
|
||||
|
@ -13177,6 +13205,14 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf) {
|
|||
losehp(lf, roll("1d4"), DT_BASH, NULL, "a falling rock trap");
|
||||
}
|
||||
addob(lf->cell->obpile, "stone");
|
||||
} else if (oid == OT_TRAPTELEPORT) {
|
||||
cell_t *newc;
|
||||
// move somewhere else!
|
||||
newc = getrandomcelloftype(lf->cell->map, getemptycelltype(lf->cell->map->habitat));
|
||||
if (newc) {
|
||||
teleportto(lf, newc, B_TRUE);
|
||||
}
|
||||
|
||||
} else if ((oid == OT_TRAPARROW) || (oid == OT_TRAPARROWP)) {
|
||||
int dir,bestdir = D_NONE;
|
||||
cell_t *src;
|
||||
|
|
106
spell.c
106
spell.c
|
@ -1766,6 +1766,92 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (isplayer(caster)) {
|
||||
msg("A relaxing aroma surrounds you.");
|
||||
}
|
||||
} else if (spellid == OT_S_CHAINLIGHTNING) {
|
||||
cell_t *hitcell[MAXRETCELLS]; // all cells which have been hit in total
|
||||
cell_t *arccell[MAXRETCELLS]; // cells hit this time
|
||||
cell_t *arccell2[MAXRETCELLS]; // cells hit this time
|
||||
int nhitcells = 0, narccells,narccells2;
|
||||
int i;
|
||||
int range;
|
||||
int nsides = 6;
|
||||
|
||||
range = getspellrange(spellid, power);
|
||||
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
|
||||
// create a line of fire towards the target cell
|
||||
animline(caster->cell, targcell, B_FALSE, '/', '\\', C_WHITE);
|
||||
|
||||
if (cansee(player, caster)) {
|
||||
msg("%s shoot%s a bolt of electricity!",castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
if (targcell->lf) {
|
||||
arccell[0] = targcell;
|
||||
narccells = 1;
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
|
||||
nhitcells = 0;
|
||||
while (narccells) {
|
||||
int stillseen = B_FALSE;
|
||||
// everyone takes damage, and mark cells as hit
|
||||
for (i = 0; i < narccells; i++) {
|
||||
losehp(arccell[i]->lf, rolldie(2,nsides), DT_ELECTRIC, caster, "an electricity bolt");
|
||||
hitcell[nhitcells++] = arccell[i];
|
||||
|
||||
if (haslos(player, arccell[i])) {
|
||||
stillseen = B_TRUE;
|
||||
needredraw = B_TRUE;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// now range gets halved and damage lowered
|
||||
range /= 2;
|
||||
if (range <= 0) break;
|
||||
if (--nsides <= 0) break; // ie. max of 5 arcs
|
||||
|
||||
// now arc to other cells with lfs still within range
|
||||
narccells2 = 0;
|
||||
for (i = 0; i < narccells; i++) {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
for (y = arccell[i]->y - range ; y <= arccell[i]->y + range; y++) {
|
||||
for (x = arccell[i]->x - range ; x <= arccell[i]->x + range; x++) {
|
||||
c = getcellat(targcell->map, x, y);
|
||||
if (c && c->lf && (c->lf != caster)
|
||||
&& haslof(arccell[i], c, LOF_NEED, NULL)) {
|
||||
int n,found = B_FALSE;
|
||||
// if this cell hasn't been hit...
|
||||
for (n = 0; n < nhitcells; n++) {
|
||||
if (hitcell[n] == c) {
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// will arc to here
|
||||
arccell2[narccells2++] = c;
|
||||
animline(arccell[i], c, B_FALSE, '/', '\\', C_WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// replace arccells
|
||||
for (i = 0; i < narccells2; i++) {
|
||||
arccell[i] = arccell2[i];
|
||||
}
|
||||
narccells = narccells2;
|
||||
|
||||
if (narccells && stillseen) {
|
||||
msg("The electricity arcs!");
|
||||
}
|
||||
} // end while narccells
|
||||
} else if (spellid == OT_S_CLOUDKILL) {
|
||||
int radius;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power)) return B_TRUE;
|
||||
|
@ -5062,7 +5148,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (o = targcell->obpile->first ; o ; o = o->next) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_SECRET);
|
||||
if (f) {
|
||||
if (f && (f->val[0] != NA)) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s is magically revealed!", obname);
|
||||
|
@ -5072,7 +5158,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
|
||||
// remove invisibility
|
||||
// remove invisibility/hiding
|
||||
if (targcell->lf) {
|
||||
flag_t *f, *nextf;
|
||||
for (f = targcell->lf->flags->first ; f ; f = nextf) {
|
||||
|
@ -5082,9 +5168,22 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
killflag(f);
|
||||
// player can see whoever just appeared, and the caster?
|
||||
if (cansee(player, targcell->lf) && cansee(player, caster)) {
|
||||
char tname[BUFLEN];
|
||||
seen = B_TRUE;
|
||||
getlfname(targcell->lf, tname);
|
||||
msg("%s becomes visible!", tname);
|
||||
}
|
||||
}
|
||||
} else if ( (f->id == F_HIDING) &&
|
||||
!lfhasflagval(caster, F_SPOTTED, targcell->lf->id, NA, NA, NULL)) {
|
||||
addflag(caster->flags, F_SPOTTED, targcell->lf->id, NA, NA, NULL);
|
||||
// player can see whoever just appeared, and the caster?
|
||||
if (cansee(player, targcell->lf) && cansee(player, caster)) {
|
||||
char tname[BUFLEN];
|
||||
seen = B_TRUE;
|
||||
getlfname(targcell->lf, tname);
|
||||
msg("A hiding %s is revealed!", noprefix(tname));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6574,6 +6673,9 @@ int getspellrange(enum OBTYPE spellid, int power) {
|
|||
case OT_S_LIGHTNINGBOLT:
|
||||
range = (power*3);
|
||||
break;
|
||||
case OT_S_CHAINLIGHTNING:
|
||||
range = (power*3);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue