- [+] thrown objects taking no damage due to hardness
* [+] DIETY is slow. - [+] map bug - from 0,0, walk NE (off top edge). i end up at 0,0 again!!! * [+] ALLOW ROTATING OF VAULTS - [+] BUG: dig X only goes 1 cell. - [+] add a U shaped turn vault. - [+] change wehre i apply HADRNESS for lfs! - don't use adjustdammaterial cause we inherit there - [+] make obchance/thingchance part of habitat_t - [+] make sense surroundings take cartography skill into account * [+] BUG: rotated at() etc not working. - [+] if you fail stealing, the target should get angry!!! - [+] make sure to redraw stat bar when mind scan finishes. - [+] villages - [+] initial code * [+] town gaurds. stand next to the gate - [+] potion shop vault - [+] implement - [+] potion shop isn't getting potions!! - [+] and getting wrong floor type. * [+] stop shop from always being at the top left. - [+] make sure its x/y arent too close to edge of map (at least 5 away) - [+] vault param. f_mapmargin, 5 - [+] make calcroompos take x/y margin - [+] don't put auto obs inside vaults - [+] town walls - [+] more kinds of shops * [+] signs outside shops - [+] bug with ai swapping between firearms and twohanded weapons. fixed. * [+] make _CELLS_ have habitats! - [+] move vaultchance to a habitat param instead of getvaultchance() * [+] shopkeepers (special race) village things: - [+] barrels, - [+] guards, - [+] statue - [+] thrown objects should still take damage if blocked via a shield * [+] hardness (must do dam >= xx to hurt) * [+] WATER spread mods * [+] very powerful spells have casttime - [+] allow linkstairs() to take a parameter rather than always jsut searching for the other end - [+] when digging holes, only use getrandomadjcell if there is an lf in the way. and then use WE_NOLF. clear out solid cells - [+] show armour EVASION penalty in describeob - [+] teleportation trap. You reintegrate inside a solid object! You die.--More--. - [+] riverroom vault * [+] water: swap { and ~ again?? - [+] make "large puddle of water" evaporate more quickly * [+] special glyph case: for deep water
This commit is contained in:
parent
cf328f849f
commit
7dfeb42e5a
2
Makefile
2
Makefile
|
@ -1,2 +1,2 @@
|
|||
nexus: Makefile defs.h nexus.c nexus.h ai.c ai.h attack.c attack.h flag.c flag.h io.c io.h lf.c lf.h map.c map.h move.c move.h objects.c objects.h text.c text.h save.c save.h spell.c spell.h vault.c vault.h
|
||||
gcc -Wall -g -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c vault.c vault.h -lncurses
|
||||
gcc -Wall -g -pg -o nexus nexus.c ai.c attack.c flag.c io.c lf.c map.c move.c objects.c text.c save.c spell.c vault.c vault.h -lncurses
|
||||
|
|
19
ai.c
19
ai.c
|
@ -771,6 +771,12 @@ int aipickup(lifeform_t *lf, object_t *o) {
|
|||
|
||||
int aipickupok(lifeform_t *lf, object_t *o) {
|
||||
int ok = B_FALSE;
|
||||
|
||||
if (hasflag(o->flags, F_SHOPITEM)) {
|
||||
// && (getiqname(getattr(lf, A_IQ), NULL) > IQ_ANIMAL)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (isedible(o)) {
|
||||
if (caneat(lf, o) && !isinbattle(lf)) {
|
||||
ok = B_TRUE;
|
||||
|
@ -944,6 +950,8 @@ void aiturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// do we have a better firearm ?
|
||||
if (curwep && hasflag(curwep->flags, F_TWOHANDED)) {
|
||||
} else {
|
||||
curgun = getfirearm(lf);
|
||||
bestgun = getbestfirearm(lf);
|
||||
|
||||
|
@ -952,6 +960,7 @@ void aiturn(lifeform_t *lf) {
|
|||
// weild better one
|
||||
if (!weild(lf, bestgun)) return;
|
||||
}
|
||||
}
|
||||
|
||||
// do we have better ammo?
|
||||
if (curgun) {
|
||||
|
@ -1693,7 +1702,7 @@ int lookforobs(lifeform_t *lf) {
|
|||
// if we are in battle only go for it if we covet it
|
||||
if (!target || (f->val[1] == B_COVETS)) {
|
||||
o = hasbetterweapon(lf, lf->cell->obpile);
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) {
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) && canpickup(lf, o, 1)) {
|
||||
if (db) dblog(".oO { current cell has better weapon (%s) }",o->type->name);
|
||||
// try to pick it up
|
||||
if (!aipickup(lf, o)) return B_TRUE;
|
||||
|
@ -1710,7 +1719,7 @@ int lookforobs(lifeform_t *lf) {
|
|||
// if we are in battle only go for it if we covet it
|
||||
if (!target || (f->val[1] == B_COVETS)) {
|
||||
o = hasbetterarmour(lf, lf->cell->obpile);
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) {
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) && canpickup(lf, o, 1)) {
|
||||
if (db) dblog(".oO { current cell has better armour (%s) }",o->type->name);
|
||||
// try to pick it up
|
||||
if (!aipickup(lf, o)) return B_TRUE;
|
||||
|
@ -1774,7 +1783,8 @@ int lookforobs(lifeform_t *lf) {
|
|||
if (!target ||
|
||||
((f->val[1] != B_COVETS) && (celldist <= targdist)) ) {
|
||||
o = hasbetterweapon(lf, c->obpile);
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) {
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) &&
|
||||
canpickup(lf, o, 1)) {
|
||||
if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name);
|
||||
gothere = B_TRUE;
|
||||
}
|
||||
|
@ -1791,7 +1801,8 @@ int lookforobs(lifeform_t *lf) {
|
|||
((f->val[1] != B_COVETS) && (celldist <= targdist)) ) {
|
||||
|
||||
o = hasbetterarmour(lf, c->obpile);
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && canpickup(lf, o, 1)) {
|
||||
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) &&
|
||||
canpickup(lf, o, 1)) {
|
||||
if (db) dblog(".oO { remote cell has better armour (%s). setting f_targetcell }",o->type->name);
|
||||
gothere = B_TRUE;
|
||||
}
|
||||
|
|
2
attack.c
2
attack.c
|
@ -1046,7 +1046,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
noise(lf->cell, NULL, 3, "sounds of fighting.", NULL);
|
||||
}
|
||||
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARD)) {
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(o->flags, F_HARDNESS)) {
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "punching %s", obname);
|
||||
if ( losehp(lf, 1, DT_BASH, lf, buf)) {
|
||||
|
|
90
defs.h
90
defs.h
|
@ -36,6 +36,15 @@ enum COLOUR {
|
|||
C_BOLDGREEN = 14,
|
||||
};
|
||||
|
||||
enum SPEECHVOL {
|
||||
SV_SILENT = 0,
|
||||
SV_WHISPER = 1,
|
||||
SV_TALK = 2,
|
||||
SV_SHOUT = 3,
|
||||
SV_ROAR = 4,
|
||||
SV_BELLOW = 3,
|
||||
};
|
||||
|
||||
enum SKILL {
|
||||
SK_NONE = 0,
|
||||
SK_ARMOUR = 1,
|
||||
|
@ -158,6 +167,7 @@ enum CHECKTYPE {
|
|||
SC_POISON,
|
||||
SC_RESISTMAG,
|
||||
SC_SEARCH,
|
||||
SC_STEAL,
|
||||
SC_STEALTH,
|
||||
SC_WILL,
|
||||
};
|
||||
|
@ -263,7 +273,9 @@ enum MODTYPE {
|
|||
|
||||
#define MAXRETCELLS 80
|
||||
|
||||
#define MAXCHOICES 200
|
||||
#define MAXFLAGS 500
|
||||
|
||||
#define MAXCHOICES 400
|
||||
|
||||
#define MAXDEPTH 25 // max dungeon depth
|
||||
|
||||
|
@ -425,10 +437,14 @@ enum CELLTYPE {
|
|||
CT_WALL,
|
||||
CT_WALLGLASS,
|
||||
CT_WALLMETAL,
|
||||
CT_WALLWOOD,
|
||||
CT_ROOMWALL,
|
||||
// empty
|
||||
CT_CORRIDOR,
|
||||
CT_DIRT,
|
||||
CT_VILLAGEGROUND,
|
||||
CT_FLOORSHOP,
|
||||
CT_FLOORWOOD,
|
||||
CT_GRASS,
|
||||
CT_LOOPCORRIDOR,
|
||||
CT_LOWFLOOR,
|
||||
|
@ -619,6 +635,7 @@ enum RACE {
|
|||
// human monsters
|
||||
R_HUMAN,
|
||||
R_BANDIT,
|
||||
R_TOWNGUARD,
|
||||
// monsters
|
||||
R_BEHOLDER,
|
||||
R_BUGBEAR,
|
||||
|
@ -728,6 +745,7 @@ enum JOB {
|
|||
J_PLUMBER,
|
||||
J_PRINCE,
|
||||
J_ROGUE,
|
||||
J_SHOPKEEPER,
|
||||
J_WIZARD,
|
||||
};
|
||||
|
||||
|
@ -778,7 +796,10 @@ enum OBTYPE {
|
|||
OT_STATUE,
|
||||
OT_DOORWOOD,
|
||||
OT_DOORIRON,
|
||||
OT_IRONGATE,
|
||||
OT_GATEIRON,
|
||||
OT_GATEWOOD,
|
||||
OT_FENCEWOOD,
|
||||
OT_SIGN,
|
||||
OT_WOODENTABLE,
|
||||
OT_WOODENBARREL,
|
||||
OT_WOODENSTOOL,
|
||||
|
@ -1014,6 +1035,7 @@ enum OBTYPE {
|
|||
OT_S_WATERJET,
|
||||
// -- summoning
|
||||
OT_S_FLOATINGDISC,
|
||||
OT_S_CLEARLEVEL,
|
||||
OT_S_CREATEMONSTER,
|
||||
OT_S_SUMMONWEAPON,
|
||||
// -- translocation
|
||||
|
@ -1034,6 +1056,7 @@ enum OBTYPE {
|
|||
OT_S_CREATEVAULT,
|
||||
OT_S_GIFT,
|
||||
OT_S_WISH,
|
||||
OT_A_BLINDALL,
|
||||
OT_A_DEBUG,
|
||||
OT_A_ENHANCE,
|
||||
OT_A_LEARN,
|
||||
|
@ -1365,6 +1388,7 @@ enum DEPTH {
|
|||
#define WE_EMPTY 2
|
||||
#define WE_PORTAL 3
|
||||
#define WE_NOTWALL 4
|
||||
#define WE_NOLF 5
|
||||
|
||||
enum NOISETYPE {
|
||||
N_GETANGRY,
|
||||
|
@ -1427,6 +1451,7 @@ enum FLAG {
|
|||
F_NO_A, // this obname doesn't need to start with 'a' for singular (eg. gold)
|
||||
F_CONTAINSOB, // for vending machiens. v0 is ob letter
|
||||
// text is an object it contains.
|
||||
F_SIGNTEXT, // for 'sign' objects. f->text is what is says.
|
||||
F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc
|
||||
F_STARTBLESSED, // v0 = b_blessed or b_cursed
|
||||
F_REPELBLESSED, // v0 = b_blessed or b_cursed. repels other obejcts
|
||||
|
@ -1440,7 +1465,11 @@ enum FLAG {
|
|||
F_NOFEEL, // when blind, don't show "you can feel xxx"
|
||||
F_FEELTEXT, // when blind, show "you can feel"+f->text
|
||||
// for items in shops
|
||||
F_SHOPITEM, // causes shops to show this item as identified
|
||||
F_VENDITEM, // causes vending machine to show this item as identified
|
||||
F_SHOPITEM, // v0 is object value.
|
||||
// v1 is the shop it is from
|
||||
// causes shops to show (worth $xx) after the ob's name.
|
||||
// also used for detecting theft!
|
||||
F_VALUE, // how much an item is worth (over its base weight+material)
|
||||
// weapon/armour flags
|
||||
F_EQUIPPED, // val0 = where it is equipped. CLEAR WHEN OB MOVED!
|
||||
|
@ -1568,7 +1597,6 @@ enum FLAG {
|
|||
// text = obid to link to
|
||||
|
||||
// ob interaction flags
|
||||
F_HARD, // object is hard (ie. punching it will hurt!)
|
||||
F_REDUCEMOVEMENT, // time to move off here is multiplied by v0.
|
||||
F_RESTRICTMOVEMENT, // must pass a diff=v0 STR check to move off it.
|
||||
// if v1 is B_TRUE, then it takes 1 damage if you fail.
|
||||
|
@ -1683,6 +1711,7 @@ enum FLAG {
|
|||
F_MAXPOWER, // val0 = max power of this spell (1-10)
|
||||
F_MPCOST, // v0=mp cost of spell. if missing, mpcost if splev^2
|
||||
F_ONGOING, // this spell has an ongoing cost
|
||||
F_CASTINGTIME, // this spell takes v0 turns to cast
|
||||
//F_SPELLLETTER, // text[0] = letter to cast this spell
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee/heal
|
||||
// v0 is who to target
|
||||
|
@ -1693,9 +1722,10 @@ enum FLAG {
|
|||
F_AIHEALITEM, // ai will use this item when low on hp
|
||||
F_AIFLEEITEM, // ai will use this item when fleeing
|
||||
// if using this on wands, update aiobok() !
|
||||
// object _AND_ lifeform flags
|
||||
// object AND lifeform flags
|
||||
F_NOSTRDAMMOD, // this object/lf does not have attacks modified
|
||||
// using their strength
|
||||
F_HARDNESS, // must do >= v0 damage to hurt this
|
||||
// player only flags
|
||||
F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
|
||||
F_DONELISTEN, // supress further 'you hear xx' messages this turn.
|
||||
|
@ -1740,6 +1770,7 @@ enum FLAG {
|
|||
// text can be:
|
||||
// x (single number)
|
||||
// x-y (range)
|
||||
F_DONTSTARTASLEEP, // this mosnter never starts off asleep
|
||||
F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will
|
||||
// start off hidden
|
||||
F_CORPSETYPE, // text field specifies what corpse obtype to leave
|
||||
|
@ -1753,9 +1784,18 @@ enum FLAG {
|
|||
F_VISRANGEMOD, // modifications to visrange
|
||||
F_GUNTARGET, // current projectile weapon target
|
||||
F_CASTINGSPELL, // set while the player is casting a spell
|
||||
// for instant spells:
|
||||
// v0 is spell id
|
||||
// for noninstant spells:
|
||||
// v0 is spell id
|
||||
// v1 is spell power
|
||||
// v2 is counter until casting
|
||||
// text is: "targlfid;targobid;mapid;cellx;celly;"
|
||||
|
||||
F_AVOIDCURSEDOB, // for AI animals - they will avoid walking on obid 'text'
|
||||
// (text is a long)
|
||||
F_STAYINHABITAT, // lf will not walk onto a cell of a different
|
||||
// habitat
|
||||
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
|
||||
|
@ -1787,6 +1827,8 @@ enum FLAG {
|
|||
// vanish.
|
||||
// v1 is lifetime left. this decrements each turn.
|
||||
// when at zero, lf vanishes.
|
||||
F_OWNSSHOP, // v0 is roomid of the shop which this shopkeeper owns.
|
||||
F_GUARD, // this lf is a guard, who can be called by shopkeepers
|
||||
F_HATESRACE, // lf will attack lfs with race=v0 or baseid=v0 on
|
||||
// sight
|
||||
F_HARMLESS, // it is safe to rest around this lf
|
||||
|
@ -2012,7 +2054,8 @@ enum FLAG {
|
|||
// nutrition
|
||||
F_HUNGER, // val0 = hunger, higher = hungrier
|
||||
|
||||
// for jobs
|
||||
// for jobs (job flags)
|
||||
F_NOPLAYER, // players can't pick this job
|
||||
F_HASPET, // this job starts with a pet of race f->text
|
||||
F_IFPCT, // only add the NEXT job flag if rnd(1,100) <= v0.
|
||||
F_ELSE,
|
||||
|
@ -2048,13 +2091,18 @@ enum FLAG {
|
|||
F_VAULTGOESIN, // this vault randomly appears in habitat type v0.
|
||||
// can be repeated multiple times
|
||||
// if a vault doesnt have this flag, it can go anywhere
|
||||
F_VAULTISSHOP, // this vault is a shop, so add f_shopitem to objects
|
||||
// here.
|
||||
F_VAULTSCATTER, // v0=thingtype, v1=pctchance
|
||||
// text=x1,y1,x2,y2,mincount-maxcount,thingname
|
||||
// if maxcount is PCT, mincount is a percentage
|
||||
// of the total space.
|
||||
F_VAULTMAYROTATE, // may rotate this vault in 90degree increments.
|
||||
F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is
|
||||
// v0/1 can be NA.
|
||||
// just a normal random room
|
||||
F_KEEPMARGIN, // this vault must be at least v0 from e/w of map
|
||||
// and at least v1 from n/s of map
|
||||
F_NULL = -1
|
||||
};
|
||||
|
||||
|
@ -2263,6 +2311,11 @@ enum COMMAND {
|
|||
CMD_WEILD,
|
||||
};
|
||||
|
||||
|
||||
typedef struct coord_s {
|
||||
int x,y;
|
||||
} coord_t;
|
||||
|
||||
// command types
|
||||
typedef struct command_s {
|
||||
enum COMMAND id;
|
||||
|
@ -2281,6 +2334,7 @@ enum HABITAT {
|
|||
H_DUNGEON = 1,
|
||||
H_FOREST = 2,
|
||||
H_PIT = 3,
|
||||
H_VILLAGE = 4,
|
||||
H_ALL = 999
|
||||
};
|
||||
|
||||
|
@ -2290,6 +2344,7 @@ typedef struct regiontype_s {
|
|||
int maxdepth;
|
||||
int stairsperlev;
|
||||
int deeperdir;
|
||||
int majorbranch;
|
||||
struct regiontype_s *next, *prev;
|
||||
} regiontype_t;
|
||||
|
||||
|
@ -2328,6 +2383,9 @@ typedef struct region_s {
|
|||
typedef struct habitat_s {
|
||||
enum HABITAT id;
|
||||
char *name;
|
||||
int randthingpct; // % chance each empty cell has something
|
||||
int randobpct; // % chance that 'something' is an ob rather than monster
|
||||
int randvaultpct; // % chance that a room will be a vault
|
||||
enum CELLTYPE emptycelltype,solidcelltype;
|
||||
struct habitat_s *next, *prev;
|
||||
} habitat_t;
|
||||
|
@ -2380,14 +2438,22 @@ typedef struct vlegend_s {
|
|||
struct vlegend_s *next, *prev;
|
||||
} vlegend_t;
|
||||
|
||||
// in map[0], data is the real data
|
||||
// in others, data is an index into map[0]
|
||||
typedef struct vaultmap_s {
|
||||
int data[MAX_MAPW*MAX_MAPH];
|
||||
int mlen;
|
||||
int w,h;
|
||||
} vaultmap_t;
|
||||
|
||||
typedef struct vault_s {
|
||||
char *filename;
|
||||
char *id;
|
||||
int numid;
|
||||
int valid;
|
||||
int state;
|
||||
char map[MAX_MAPW*MAX_MAPH];
|
||||
int mlen;
|
||||
int w,h;
|
||||
struct vaultmap_s map[4];
|
||||
int nmaps;
|
||||
struct vlegend_s *legend, *lastlegend;
|
||||
struct vault_s *next, *prev;
|
||||
struct flagpile_s *flags;
|
||||
|
@ -2402,11 +2468,13 @@ typedef struct cell_s {
|
|||
map_t *map; // pointer back to map
|
||||
int x,y; // map coords
|
||||
int roomid;
|
||||
vault_t *vault;
|
||||
struct celltype_s *type;
|
||||
struct obpile_s *obpile;
|
||||
enum LIGHTLEV lit;
|
||||
enum LIGHTLEV origlit; // for timed light
|
||||
enum LIGHTLEV lastlit;
|
||||
habitat_t *habitat;
|
||||
int origlittimer;
|
||||
int littimer;
|
||||
|
||||
|
@ -2475,6 +2543,7 @@ typedef struct lifeform_s {
|
|||
int mp,maxmp;
|
||||
int alive;
|
||||
char *lastdam;
|
||||
struct material_s *material;
|
||||
enum DAMTYPE lastdamtype;
|
||||
|
||||
int timespent;
|
||||
|
@ -2526,6 +2595,9 @@ typedef struct flagpile_s {
|
|||
lifeform_t *owner;
|
||||
struct object_s *ob;
|
||||
struct flag_s *first,*last;
|
||||
|
||||
struct flag_s *item[MAXFLAGS];
|
||||
int nitems;
|
||||
} flagpile_t;
|
||||
|
||||
typedef struct flag_s {
|
||||
|
|
|
@ -43,13 +43,15 @@ Flags can be:
|
|||
- a range (x-y)
|
||||
- a pct of the total region cells (x%)
|
||||
coords can be negative ("count back from right/bottom")
|
||||
pct is optional
|
||||
|
||||
autodoors:pct // automatically add at least one door to the edges of
|
||||
// this room.
|
||||
// pct is chance of the exit being a door as opposed
|
||||
// to jsut an opening.
|
||||
|
||||
autopop // automatically add obs/mons/pillars to this room
|
||||
autopop // automatically add obs/mons/pillars to this vault as
|
||||
// if it were a normal room.
|
||||
|
||||
dlevmin:xxx // can only randomly appear at or below dungeon
|
||||
// level xxx (or map difficulty xxx for world map)
|
||||
|
@ -58,6 +60,10 @@ Flags can be:
|
|||
|
||||
goesin:xxx // can only randomly appear in habitat xxx
|
||||
|
||||
margin:x,y // must be x/y away from edges of map
|
||||
|
||||
mayrotate // vault can be rotated randomly
|
||||
|
||||
norandom // this vault doesn't appear randomly. it will only
|
||||
// appear when specifically requested via a region's
|
||||
// outline.
|
||||
|
|
226
flag.c
226
flag.c
|
@ -82,27 +82,65 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
}
|
||||
}
|
||||
|
||||
// override values sometimes
|
||||
/*
|
||||
if ((id == F_WET) && (val2 == NA)) {
|
||||
val2 = WETTIME;
|
||||
}
|
||||
*/
|
||||
////////////////////////////////
|
||||
// ACTUAL FLAG ADDITION IS HERE
|
||||
////////////////////////////////
|
||||
|
||||
if (fp->first == NULL) {
|
||||
fp->first = malloc(sizeof(flag_t));
|
||||
f = fp->first;
|
||||
f->prev = NULL;
|
||||
|
||||
// also the last
|
||||
fp->last = f;
|
||||
f->next = NULL;
|
||||
|
||||
} else {
|
||||
flag_t *ff;
|
||||
// we will keep flags sorted.
|
||||
// find correct position in list...
|
||||
ff = fp->first;
|
||||
while (ff && (ff->id < id)) {
|
||||
ff = ff->next;
|
||||
}
|
||||
|
||||
if (ff) {
|
||||
// start or middle of list
|
||||
// insert BEFORE this one
|
||||
flag_t *prev;
|
||||
prev = ff->prev;
|
||||
|
||||
// link to previous element
|
||||
if (prev) {
|
||||
prev->next = malloc(sizeof(flag_t));
|
||||
f = prev->next;
|
||||
} else {
|
||||
// first one
|
||||
fp->first = malloc(sizeof(flag_t));
|
||||
f = fp->first;
|
||||
}
|
||||
f->prev = prev;
|
||||
|
||||
// link to next element
|
||||
f->next = ff;
|
||||
ff->prev = f;
|
||||
} else {
|
||||
// last one. insert at end of list.
|
||||
f = fp->last;
|
||||
f->next = malloc(sizeof(flag_t));
|
||||
f->next->prev = f;
|
||||
f = f->next;
|
||||
fp->last = f;
|
||||
f->next = NULL;
|
||||
}
|
||||
/*
|
||||
// go to end of list
|
||||
f = fp->last;
|
||||
f->next = malloc(sizeof(flag_t));
|
||||
f->next->prev = f;
|
||||
f = f->next;
|
||||
*/
|
||||
}
|
||||
fp->last = f;
|
||||
|
||||
f->next = NULL;
|
||||
|
||||
// fill in props
|
||||
f->id = id;
|
||||
|
@ -133,6 +171,8 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
|
||||
f->pile = fp;
|
||||
|
||||
updatefpindex(fp);
|
||||
|
||||
// notify
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (f->pile->owner) {
|
||||
|
@ -232,6 +272,7 @@ flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
|
|||
fp->last = NULL;
|
||||
fp->owner = owner;
|
||||
fp->ob = ob;
|
||||
fp->nitems = 0;
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
@ -239,6 +280,8 @@ flagpile_t *addflagpile(lifeform_t *owner, object_t *ob) {
|
|||
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id) {
|
||||
flag_t *f;
|
||||
for (f = src->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
if (f->id == id) {
|
||||
addflag_real(dst, f->id, f->val[0], f->val[1], f->val[2], f->text,
|
||||
f->lifetime, f->known, -1);
|
||||
|
@ -355,11 +398,79 @@ flag_t *hasflagknown(flagpile_t *fp, int id) {
|
|||
}
|
||||
|
||||
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) {
|
||||
flag_t *f;
|
||||
flag_t *f,*foundflag = NULL, *searchfrom = NULL;
|
||||
lifeform_t *owner;
|
||||
owner = fp->owner;
|
||||
int pos;
|
||||
int l,r;
|
||||
int iter = 0;
|
||||
int db = B_FALSE;
|
||||
|
||||
if (db) dblog("hasflag %d in flagpile with %d entries", id, fp->nitems);
|
||||
// binary search for this flag id.
|
||||
l = 0;
|
||||
r = fp->nitems-1;
|
||||
while (!searchfrom) {
|
||||
if (db) dblog(" iter#%d: l=%d,r=%d", iter, l, r);
|
||||
if (r < l) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" r < l: not found!");
|
||||
break;
|
||||
} else if (fp->item[l]->id > id) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" leftid %d > wantid %d. not found!",fp->item[l]->id, id);
|
||||
break;
|
||||
} else if (fp->item[r]->id < id) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" rightid %d > wantid %d. not found!",fp->item[r]->id, id);
|
||||
break;
|
||||
}
|
||||
// half way inbetween l and r
|
||||
pos = ((l+r)/2);
|
||||
f = fp->item[pos];
|
||||
if (db) dblog(" iter#%d: pos=%d. item here is %d (looking for %d)", iter, pos, f->id, id);
|
||||
|
||||
if (f->id == id) {
|
||||
// go back to first occurence
|
||||
while (f->prev && (f->prev->id == id)) {
|
||||
f = f->prev;
|
||||
}
|
||||
searchfrom = f;
|
||||
break;
|
||||
} else if (f->id > id) {
|
||||
// go left
|
||||
r = pos-1;
|
||||
} else {
|
||||
// go right
|
||||
l = pos+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now find a valid one
|
||||
f = searchfrom;
|
||||
while (f && (f->id == id)) {
|
||||
int valid = B_TRUE;
|
||||
if (f == exception) valid = B_FALSE;
|
||||
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
|
||||
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) valid = B_FALSE;
|
||||
|
||||
if (valid) {
|
||||
foundflag = f;
|
||||
break;
|
||||
} else {
|
||||
f = f->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (db) dblog("finished - %s", foundflag ? "found it" : "NOT FOUND");
|
||||
return foundflag;
|
||||
|
||||
/*
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
|
||||
if ((f->id == id) && (f != exception)) {
|
||||
int valid = B_TRUE;
|
||||
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
|
||||
|
@ -372,6 +483,7 @@ flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -394,10 +506,82 @@ int getcounter(flagpile_t *fp) {
|
|||
}
|
||||
|
||||
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown) {
|
||||
flag_t *f;
|
||||
flag_t *f,*foundflag = NULL, *searchfrom = NULL;
|
||||
lifeform_t *owner;
|
||||
owner = fp->owner;
|
||||
int pos;
|
||||
int l,r;
|
||||
int iter = 0;
|
||||
int db = B_FALSE;
|
||||
|
||||
if (db) dblog("hasflag %d in flagpile with %d entries", id, fp->nitems);
|
||||
// binary search for this flag id.
|
||||
l = 0;
|
||||
r = fp->nitems-1;
|
||||
while (!searchfrom) {
|
||||
if (db) dblog(" iter#%d: l=%d,r=%d", iter, l, r);
|
||||
if (r < l) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" r < l: not found!");
|
||||
break;
|
||||
} else if (fp->item[l]->id > id) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" leftid %d > wantid %d. not found!",fp->item[l]->id, id);
|
||||
break;
|
||||
} else if (fp->item[r]->id < id) {
|
||||
// NOT FOUND.
|
||||
if (db) dblog(" rightid %d > wantid %d. not found!",fp->item[r]->id, id);
|
||||
break;
|
||||
}
|
||||
// half way inbetween l and r
|
||||
pos = ((l+r)/2);
|
||||
f = fp->item[pos];
|
||||
if (db) dblog(" iter#%d: pos=%d. item here is %d (looking for %d)", iter, pos, f->id, id);
|
||||
|
||||
if (f->id == id) {
|
||||
// go back to first occurence
|
||||
while (f->prev && (f->prev->id == id)) {
|
||||
f = f->prev;
|
||||
}
|
||||
searchfrom = f;
|
||||
break;
|
||||
} else if (f->id > id) {
|
||||
// go left
|
||||
r = pos-1;
|
||||
} else {
|
||||
// go right
|
||||
l = pos+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now find a valid one
|
||||
f = searchfrom;
|
||||
while (f && (f->id == id)) {
|
||||
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
|
||||
// invalid
|
||||
} else if ( ((val1 == NA) || (f->val[0] == val1)) &&
|
||||
((val2 == NA) || (f->val[1] == val2)) &&
|
||||
((val3 == NA) || (f->val[2] == val3)) &&
|
||||
((text == NULL) || strstr(f->text, text))) {
|
||||
if (!wantknown || f->known) {
|
||||
foundflag = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f = f->next;
|
||||
}
|
||||
|
||||
if (db) dblog("finished - %s", foundflag ? "found it" : "NOT FOUND");
|
||||
return foundflag;
|
||||
|
||||
|
||||
/*
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
|
||||
if (f->id == id) {
|
||||
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
|
||||
// invalid
|
||||
|
@ -414,6 +598,7 @@ flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, ch
|
|||
}
|
||||
}
|
||||
return NULL;
|
||||
*/
|
||||
}
|
||||
|
||||
// returns true if we did something
|
||||
|
@ -422,6 +607,10 @@ int killflagsofid(flagpile_t *fp, enum FLAG fid) {
|
|||
int donesomething = B_FALSE;
|
||||
for (f = fp->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > fid) break;
|
||||
|
||||
if (f->id == fid) {
|
||||
killflag(f);
|
||||
donesomething = B_TRUE;
|
||||
|
@ -536,6 +725,8 @@ void killflag(flag_t *f) {
|
|||
lastone->next = nextone;
|
||||
}
|
||||
|
||||
updatefpindex(f->pile);
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (redolight) {
|
||||
calclight(redolight);
|
||||
|
@ -752,6 +943,9 @@ void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) {
|
|||
if (val1) *val1 = 0;
|
||||
if (val2) *val2 = 0;
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
|
||||
if (f->id == id) {
|
||||
if (val0) *val0 = *val0 + f->val[0];
|
||||
if (val1) *val1 = *val1 + f->val[1];
|
||||
|
@ -766,5 +960,15 @@ void timeeffectsflags(flagpile_t *fp) {
|
|||
nextf = f->next;
|
||||
timeeffectsflag(f, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// generate an index
|
||||
void updatefpindex(flagpile_t *fp) {
|
||||
flag_t *f;
|
||||
fp->nitems = 0;
|
||||
for (f = fp->first ;f ; f = f->next) {
|
||||
fp->item[fp->nitems] = f;
|
||||
fp->nitems++;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
1
flag.h
1
flag.h
|
@ -27,3 +27,4 @@ int modcounter(flagpile_t *fp, int amt);
|
|||
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2);
|
||||
void timeeffectsflag(flag_t *f, int howlong);
|
||||
void timeeffectsflags(flagpile_t *fp);
|
||||
void updatefpindex(flagpile_t *fp);
|
||||
|
|
116
io.c
116
io.c
|
@ -85,6 +85,7 @@ void addchoice(prompt_t *p, char ch, char *text, char *desc, void *data) {
|
|||
}
|
||||
p->choice[p->nchoices].data = data;
|
||||
p->choice[p->nchoices].heading = B_FALSE;
|
||||
p->choice[p->nchoices].valid = B_TRUE;
|
||||
p->nchoices++;
|
||||
}
|
||||
|
||||
|
@ -648,11 +649,21 @@ cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *src
|
|||
// prevent showing 'prone' AND 'asleep'
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "prone");
|
||||
} else if (isairborne(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
if (lfhasflag(c->lf, F_FLYING)) {
|
||||
strcat(extrainfo, "flying");
|
||||
} else if (lfhasflag(c->lf, F_LEVITATING)) {
|
||||
strcat(extrainfo, "levitating");
|
||||
} else {
|
||||
strcat(extrainfo, "airbourne");
|
||||
}
|
||||
} else {
|
||||
if (isswimming(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "swimming");
|
||||
}
|
||||
}
|
||||
|
||||
f = lfhasflag(c->lf, F_ATTACHEDTO);
|
||||
if (lfhasflag(c->lf, F_ATTACHEDTO)) {
|
||||
|
@ -3037,11 +3048,29 @@ void describeob(object_t *o) {
|
|||
}
|
||||
mvwprintw(mainwin, y, 0, "%s",buf);
|
||||
y++;
|
||||
|
||||
f = hasflag(o->flags, F_EVASION);
|
||||
if (f) {
|
||||
int evmod;
|
||||
evmod = adjustarmourpenalty(player, f->val[0]);
|
||||
if (evmod != 0) {
|
||||
sprintf(buf, " When worn, it %s your evasion chance by %d%%.", (evmod < 0) ? "reduces" : "increases", abs(evmod));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_SCARY);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, " It may unnerve others when worn.");
|
||||
y++;
|
||||
}
|
||||
} else {
|
||||
// non armour, but still wearable.
|
||||
f = hasflag(o->flags, F_GOESON);
|
||||
if (f) {
|
||||
sprintf(buf, "It is worn %s your %s. ",getbodypartequipname(f->val[0]), getbodypartname(f->val[0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (o->type->obclass->id == OC_WAND) {
|
||||
|
@ -3538,6 +3567,13 @@ void describespell(objecttype_t *ot) {
|
|||
}
|
||||
}
|
||||
|
||||
f = hasflag(ot->flags, F_CASTINGTIME);
|
||||
if (f) {
|
||||
wprintw(mainwin, "It takes %d turns to cast.\n",f->val[0]);
|
||||
} else {
|
||||
wprintw(mainwin, "It takes effect instantly.\n");
|
||||
}
|
||||
|
||||
wprintw(mainwin, "\n");
|
||||
|
||||
if (ot->obclass->id == OC_SPELL) {
|
||||
|
@ -3645,6 +3681,7 @@ void docomms(lifeform_t *lf) {
|
|||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
char ch;
|
||||
int moneyowing = 0;
|
||||
enum IQBRACKET iqb;
|
||||
flag_t *f;
|
||||
|
||||
|
@ -3691,9 +3728,19 @@ void docomms(lifeform_t *lf) {
|
|||
addchoice(&prompt, 'r', "Rest until you are healed.", NULL, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL);
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_OWNSSHOP);
|
||||
if (f) {
|
||||
int shopid;
|
||||
shopid = f->val[0];
|
||||
moneyowing = getowing(player, shopid, NULL);
|
||||
if (moneyowing > 0) {
|
||||
sprintf(buf, "(pay $%d to the shopkeeper)",moneyowing);
|
||||
addchoice(&prompt, 'p', buf, NULL, NULL);
|
||||
}
|
||||
}
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL);
|
||||
addchoice(&prompt, 'n', "(nothing)", NULL, NULL);
|
||||
|
||||
ch = getchoice(&prompt);
|
||||
|
@ -3749,6 +3796,25 @@ void docomms(lifeform_t *lf) {
|
|||
case 'n':
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
case 'p':
|
||||
// can we afford this?
|
||||
if (givemoney(player, lf, moneyowing)) {
|
||||
// can't afford it
|
||||
msg("You can't afford to pay $%d.", moneyowing);
|
||||
} else {
|
||||
object_t *o;
|
||||
// mark all items as paid for
|
||||
for (o = player->pack->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_SHOPITEM);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
getobname(o, buf, o->amt);
|
||||
msg("You buy %s.", buf);
|
||||
}
|
||||
}
|
||||
say(lf, "Pleasure doing business with you!", SV_TALK);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
f = isresting(lf);
|
||||
if (f) {
|
||||
|
@ -3980,7 +4046,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
|
|||
// remember letter
|
||||
o->letter = ch;
|
||||
// make object fully known
|
||||
addflag(o->flags, F_SHOPITEM, B_TRUE, NA, NA, NULL);
|
||||
addflag(o->flags, F_VENDITEM, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4061,7 +4127,8 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) {
|
|||
sprintf(buf, "Buy %s for $%d?",obname, getobvalue(o));
|
||||
answer = askchar(buf, "yn","n", B_TRUE);
|
||||
if (answer == 'y') {
|
||||
gold->amt -= getobvalue(o);
|
||||
givemoney(player, NULL, getobvalue(o));
|
||||
//gold->amt -= getobvalue(o);
|
||||
// clear o->letter
|
||||
o->letter = '\0';
|
||||
// give object
|
||||
|
@ -6433,16 +6500,32 @@ void drawstatus(void) {
|
|||
|
||||
if (lfhasflag(player, F_RAGE)) {
|
||||
setcol(statwin, C_RED);
|
||||
wprintw(statwin, " Enraged");
|
||||
wprintw(statwin, " Rage");
|
||||
unsetcol(statwin, C_RED);
|
||||
}
|
||||
|
||||
if (isswimming(player)) {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
wprintw(statwin, " Swimming");
|
||||
wprintw(statwin, " Swim");
|
||||
unsetcol(statwin, C_BOLDBLUE);
|
||||
}
|
||||
|
||||
if (isairborne(player)) {
|
||||
if (lfhasflag(player, F_FLYING)) {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
wprintw(statwin, " Fly");
|
||||
unsetcol(statwin, C_BOLDBLUE);
|
||||
} else if (lfhasflag(player, F_LEVITATING)) {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
wprintw(statwin, " Lev");
|
||||
unsetcol(statwin, C_BOLDBLUE);
|
||||
} else {
|
||||
setcol(statwin, C_BOLDBLUE);
|
||||
wprintw(statwin, " Flt"); // "float"ing
|
||||
unsetcol(statwin, C_BOLDBLUE);
|
||||
}
|
||||
}
|
||||
|
||||
// paralysed somehow?
|
||||
if (isresting(player)) {
|
||||
setcol(statwin, C_CYAN);
|
||||
|
@ -6452,6 +6535,10 @@ void drawstatus(void) {
|
|||
setcol(statwin, C_BLUE);
|
||||
wprintw(statwin, " Asleep");
|
||||
unsetcol(statwin, C_BLUE);
|
||||
} else if (isprone(player)) {
|
||||
setcol(statwin, C_YELLOW);
|
||||
wprintw(statwin, " Prone");
|
||||
unsetcol(statwin, C_YELLOW);
|
||||
} else if (isimmobile(player)) {
|
||||
setcol(statwin, C_RED);
|
||||
wprintw(statwin, " Immobile");
|
||||
|
@ -6506,11 +6593,6 @@ void drawstatus(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if (isprone(player) && !lfhasflag(player, F_ASLEEP)) {
|
||||
setcol(statwin, C_YELLOW);
|
||||
wprintw(statwin, " Prone");
|
||||
unsetcol(statwin, C_YELLOW);
|
||||
}
|
||||
|
||||
// burdened somehow?
|
||||
switch (isburdened(player)) {
|
||||
|
@ -6781,6 +6863,12 @@ void setobcolour(WINDOW *win, object_t *o, int set) {
|
|||
}
|
||||
if (!o) return;
|
||||
|
||||
// unpaid?
|
||||
if (hasflag(o->flags, F_SHOPITEM)) {
|
||||
funcptr(win, C_ORANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o->blessknown) {
|
||||
if (iscursed(o)) {
|
||||
funcptr(win, C_RED);
|
||||
|
@ -7647,8 +7735,10 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
// diff materials?
|
||||
if (lf->race->material->id != MT_FLESH) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s made out of %s.",you(lf), is(lf), lf->race->material->name);
|
||||
if (getlfmaterial(lf) != MT_FLESH) {
|
||||
material_t *mt;
|
||||
mt = findmaterial(getlfmaterial(lf));
|
||||
mvwprintw(mainwin, y, 0, "%s %s made out of %s.",you(lf), is(lf), mt->name);
|
||||
y++;
|
||||
}
|
||||
|
||||
|
|
390
lf.c
390
lf.c
|
@ -414,6 +414,19 @@ int calcxprace(enum RACE rid) {
|
|||
return xpval;
|
||||
}
|
||||
|
||||
|
||||
void callguards(lifeform_t *caller, lifeform_t *victim) {
|
||||
lifeform_t *l;
|
||||
for (l = caller->cell->map->lf ; l ; l = l->next) {
|
||||
if (!isplayer(l) && (l != caller) && (l != victim) && lfhasflag(l, F_GUARD)) {
|
||||
aiattack(l, victim, PERMENANT);
|
||||
if (isplayer(victim)) {
|
||||
addflag(l->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
|
||||
int castable = B_FALSE;
|
||||
flag_t *f;
|
||||
|
@ -686,6 +699,7 @@ int canpickup(lifeform_t *lf, object_t *o, int amt) {
|
|||
reason = E_TOOBIG;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (lf) {
|
||||
if (lfhasflag(lf, F_NOPACK)) {
|
||||
reason = E_NOPACK;
|
||||
return B_FALSE;
|
||||
|
@ -715,6 +729,7 @@ int canpickup(lifeform_t *lf, object_t *o, int amt) {
|
|||
reason = E_NOSPACE;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1126,7 +1141,10 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
msg("%s %s.", lfname, f->text);
|
||||
}
|
||||
} else {
|
||||
msg("%s casts a spell.", lfname);
|
||||
if (hasflag(sp->flags, F_CASTINGTIME)) {
|
||||
} else {
|
||||
msg("%s starts casting a spell.", lfname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1145,13 +1163,56 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
limit(&power, NA, 10);
|
||||
}
|
||||
|
||||
// stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// cast the spell
|
||||
f = hasflag(sp->flags, F_CASTINGTIME);
|
||||
if (f) {
|
||||
int castingtime;
|
||||
char tempbuf[BUFLEN];
|
||||
char castingbuf[BUFLEN];
|
||||
flag_t *castingflag;
|
||||
castingtime = f->val[0];
|
||||
|
||||
strcpy(castingbuf, "");
|
||||
|
||||
if (targlf) {
|
||||
sprintf(tempbuf, "%d;",targlf->id);
|
||||
} else {
|
||||
strcpy(tempbuf, "-1;");
|
||||
}
|
||||
strcat(castingbuf, tempbuf);
|
||||
|
||||
if (targob) {
|
||||
sprintf(tempbuf, "%ld;",targob->id);
|
||||
} else {
|
||||
strcpy(tempbuf, "-1;");
|
||||
}
|
||||
strcat(castingbuf, tempbuf);
|
||||
|
||||
if (targcell) {
|
||||
sprintf(tempbuf, "%d;%d;%d;",targcell->map->id,targcell->x, targcell->y);
|
||||
} else {
|
||||
strcpy(tempbuf, "-1;-1;-1;");
|
||||
}
|
||||
strcat(castingbuf, tempbuf);
|
||||
|
||||
castingflag = addflag(lf->flags, F_CASTINGSPELL, sid, power, castingtime, castingbuf);
|
||||
rv = B_FALSE;
|
||||
|
||||
if (isplayer(lf)) {
|
||||
// announce
|
||||
msg("You start casting %s.", sp->name);
|
||||
}
|
||||
} else { // instant cast
|
||||
addflag(lf->flags, F_CASTINGSPELL, sid, NA, NA, NULL);
|
||||
rv = dospelleffects(lf, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE);
|
||||
f = lfhasflag(lf, F_CASTINGSPELL);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
|
||||
// willing this spell? reset counter!
|
||||
if (willflag) {
|
||||
|
@ -1160,9 +1221,6 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
|
|||
}
|
||||
}
|
||||
|
||||
// stop hiding
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// successful cast?
|
||||
if (!rv) {
|
||||
practice(lf, SK_SPELLCASTING, 1);
|
||||
|
@ -1209,6 +1267,8 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
|
|||
// in around 3-4 turns.
|
||||
damamt = lf->maxhp / (getattr(lf, A_CON) / 3);
|
||||
|
||||
limit(&damamt, 1, NA);
|
||||
|
||||
if (damamt >= lf->hp) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You drown.");
|
||||
|
@ -1410,7 +1470,7 @@ int demandbribe(lifeform_t *lf) {
|
|||
amtwanted = rnd(hd*25, hd*100);
|
||||
|
||||
getlfname(lf, lfname);
|
||||
if (say(lf, "Hand over all your gold!", 2)) {
|
||||
if (say(lf, "Hand over all your gold!", SV_TALK)) {
|
||||
heard = B_TRUE;
|
||||
} else {
|
||||
heard = B_FALSE;
|
||||
|
@ -1451,15 +1511,15 @@ int demandbribe(lifeform_t *lf) {
|
|||
|
||||
if ((amtgiven == totmoney) || (amtgiven >= amtwanted)) {
|
||||
// always succeed
|
||||
say(lf, "Pleasure doing business with you!", 2);
|
||||
say(lf, "Pleasure doing business with you!", SV_TALK);
|
||||
satisfied = B_TRUE;
|
||||
} else {
|
||||
say(lf, "Then die!", 3);
|
||||
say(lf, "Then die!", SV_SHOUT);
|
||||
satisfied = B_FALSE;
|
||||
}
|
||||
} else {
|
||||
// TODO: luck check to receive money ?
|
||||
say(lf, "Then die!", 3);
|
||||
say(lf, "Then die!", SV_SHOUT);
|
||||
satisfied = B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1832,7 +1892,7 @@ int digcell(lifeform_t *lf, cell_t *c, object_t *o) {
|
|||
if (c->type->solid) {
|
||||
if (isdiggable(c)) {
|
||||
// replace wall
|
||||
setcelltype(c, c->map->habitat->id);
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
if (isplayer(lf)) {
|
||||
msg("You dig through the wall.");
|
||||
needredraw = B_TRUE;
|
||||
|
@ -2773,13 +2833,25 @@ race_t *findrace(enum RACE id) {
|
|||
}
|
||||
race_t *findracebyname(char *name) {
|
||||
race_t *r;
|
||||
raceclass_t *rc;
|
||||
// first check for exact matches
|
||||
for (r = firstrace; r ; r = r->next) {
|
||||
if (!strcmp(r->name, name)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
// ...then partial matches
|
||||
|
||||
// now check raceclasses
|
||||
for (rc = firstraceclass; rc ; rc = rc->next) {
|
||||
// using strstarts rather than streq in case there is a job suffix
|
||||
if (strstarts(name, rc->name)) {
|
||||
// return a random race from this class
|
||||
return getreallyrandomrace(rc->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ...then partial matches in names
|
||||
for (r = firstrace; r ; r = r->next) {
|
||||
if (strstr(r->name, name)) {
|
||||
return r;
|
||||
|
@ -2800,6 +2872,15 @@ raceclass_t *findraceclass(enum RACECLASS id) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lifeform_t *findshopkeeper(map_t *m, int roomid) {
|
||||
lifeform_t *lf;
|
||||
for (lf = m->lf ; lf ; lf = lf->next) {
|
||||
if (lfhasflagval(lf, F_OWNSSHOP, roomid, NA, NA, NULL)) {
|
||||
return lf;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skill_t *findskill(enum SKILL id) {
|
||||
skill_t *r;
|
||||
|
@ -4180,6 +4261,25 @@ object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp) {
|
|||
return getequippedob(lf->pack, bp);
|
||||
}
|
||||
|
||||
int getowing(lifeform_t *buyer, int shopid, int *retnitems) {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
int totcost = 0;
|
||||
int nitems = 0;
|
||||
|
||||
for (o = buyer->pack->first ; o ; o = o->next) {
|
||||
f = hasflagval(o->flags, F_SHOPITEM, NA, shopid, NA, NULL);
|
||||
if (f) {
|
||||
totcost += f->val[0];
|
||||
nitems++;
|
||||
}
|
||||
}
|
||||
if (retnitems) {
|
||||
*retnitems = nitems;
|
||||
}
|
||||
return totcost;
|
||||
}
|
||||
|
||||
// return the healthiest possible hurt condition that 'lf' will
|
||||
// recognise when looking at someone else.
|
||||
//
|
||||
|
@ -4250,7 +4350,7 @@ enum MATERIAL getlfmaterial(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
return lf->race->material->id;
|
||||
return lf->material->id;
|
||||
}
|
||||
|
||||
enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid) {
|
||||
|
@ -4957,7 +5057,6 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
|
||||
if (db) dblog("finding random lf with rarity val %d-%d and rr <= %d\n",raritymin,raritymax, wantrr);
|
||||
|
||||
|
||||
// try to find a lf of this type which will
|
||||
// fit in the map's habitat
|
||||
nposs = 0;
|
||||
|
@ -4970,7 +5069,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
rarflag = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (c) {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->map->habitat->id, NA, NA, NULL);
|
||||
rarflag = hasflagval(r->flags, F_RARITY, c->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(r->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
}
|
||||
|
@ -5032,8 +5131,7 @@ race_t *getrandomrace(cell_t *c, int forcedepth) {
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
race_t *getreallyrandomrace(void) {
|
||||
race_t *getreallyrandomrace(enum RACECLASS wantrc) {
|
||||
race_t **poss;
|
||||
race_t *r;
|
||||
int nposs = 0;
|
||||
|
@ -5042,18 +5140,24 @@ race_t *getreallyrandomrace(void) {
|
|||
|
||||
// count races
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
if ((wantrc == RC_ANY) || (r->raceclass->id == wantrc)) {
|
||||
if (appearsrandomly(r->id)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
poss = malloc(count * sizeof(race_t *));
|
||||
|
||||
for (r = firstrace ; r ; r = r->next) {
|
||||
if ((wantrc == RC_ANY) || (r->raceclass->id == wantrc)) {
|
||||
if (appearsrandomly(r->id)) {
|
||||
poss[nposs] = r;
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
sel = rnd(0,nposs-1);
|
||||
r = poss[sel];
|
||||
free(poss);
|
||||
|
@ -5566,9 +5670,52 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
|
|||
if ((gamemode != GM_GAMESTARTED)) {
|
||||
autoweild(lf);
|
||||
}
|
||||
|
||||
// special cases
|
||||
if (j->id == J_PIRATE) {
|
||||
flag_t *f;
|
||||
f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL);
|
||||
if (f) {
|
||||
f->val[0] = OT_HOOKHAND;
|
||||
sprintf(f->text, "1d4");
|
||||
}
|
||||
} else if (j->id == J_SHOPKEEPER) {
|
||||
// shopkeepers are not hostile.
|
||||
killflagsofid(lf->flags, F_HOSTILE);
|
||||
killflagsofid(lf->flags, F_HATESRACE);
|
||||
// mark its home shop
|
||||
assert(isroom(lf->cell));
|
||||
addflag(lf->flags, F_OWNSSHOP, lf->cell->roomid, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int givemoney(lifeform_t *from, lifeform_t *to, int amt) {
|
||||
object_t *gold;
|
||||
gold = hasob(from->pack, OT_GOLD);
|
||||
if (!gold) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (gold->amt < amt) {
|
||||
return B_TRUE;
|
||||
}
|
||||
// lose it
|
||||
removeob(gold, amt);
|
||||
|
||||
// give it to other person
|
||||
if (to) {
|
||||
object_t *togold;
|
||||
togold = hasob(to->pack, OT_GOLD);
|
||||
if (!togold) {
|
||||
togold = addob(to->pack, "gold coin");
|
||||
amt--;
|
||||
}
|
||||
togold += amt;
|
||||
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
|
||||
int flagsknown = 0, flagsfound = 0;
|
||||
flag_t *f,*newflag;
|
||||
|
@ -6058,6 +6205,13 @@ void givestartskills(lifeform_t *lf, flagpile_t *fp) {
|
|||
killflagsofid(fp, F_STARTSKILL);
|
||||
}
|
||||
|
||||
int hasfreeaction(lifeform_t *lf) {
|
||||
if (isimmobile(lf)) return B_FALSE;
|
||||
if (lfhasflag(lf, F_ASLEEP)) return B_FALSE;
|
||||
if (lfhasflag(lf, F_CASTINGSPELL)) return B_FALSE;
|
||||
if (lfhasflag(lf, F_EATING)) return B_FALSE;
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
job_t *hasjob(lifeform_t *lf, enum JOB job) {
|
||||
job_t *j = NULL;
|
||||
|
@ -6673,6 +6827,7 @@ int haslos(lifeform_t *viewer, cell_t *dest) {
|
|||
void initjobs(void) {
|
||||
int i;
|
||||
// job definitions
|
||||
|
||||
// NOTE: try to always make the job's weapon be the first object defined.
|
||||
// this will make sure that they have the letter 'a'.
|
||||
addjob(J_GOD, "Diety");
|
||||
|
@ -6708,6 +6863,7 @@ void initjobs(void) {
|
|||
mayusespellschool(lastjob->flags, i, F_CANWILL);
|
||||
} else {
|
||||
mayusespellschool(lastjob->flags, i, F_CANCAST);
|
||||
//mayusespellschool(lastjob->flags, i, F_CANWILL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7056,6 +7212,13 @@ void initjobs(void) {
|
|||
addflag(lastjob->flags, F_IFPCT, 20, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_CANCAST, OT_S_HEALING, NA, NA, NULL);
|
||||
addflag(lastjob->flags, F_ENDIFMONSTER, NA, NA, NA, NULL);
|
||||
|
||||
// non-player jobs
|
||||
addjob(J_SHOPKEEPER, "Shopkeeper");
|
||||
addflag(lastjob->flags, F_NOPLAYER, B_TRUE, IQ_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTATT, A_IQ, IQ_AVERAGE, NA, NULL);
|
||||
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100-1000 gold coins");
|
||||
addflag(lastjob->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
|
||||
}
|
||||
|
||||
void initrace(void) {
|
||||
|
@ -7152,6 +7315,30 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOJOBTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTJOB, 15, J_WIZARD, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTJOB, 50, J_ROGUE, NA, NULL);
|
||||
addrace(R_TOWNGUARD, "town guard", 100, '@', C_GREY, MT_FLESH, RC_HUMANOID);
|
||||
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_DOPEY, NA, NULL);
|
||||
addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "12-18");
|
||||
addflag(lastrace->flags, F_DONTSTARTASLEEP, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_STAYINHABITAT, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_GUARD, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_RARITY, H_VILLAGE, 80, NA, NULL);
|
||||
addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HITDICE, 4, 4, NA, NULL);
|
||||
addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
|
||||
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good weapon");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "scale armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "bow");
|
||||
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-10 arrows");
|
||||
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_WANTSBETTERARM, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
|
||||
|
||||
// monsters
|
||||
addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC);
|
||||
|
@ -9864,12 +10051,14 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
|
|||
a->mp = 0;
|
||||
a->maxmp = a->mp;
|
||||
|
||||
a->material = findmaterial(MT_FLESH); // might be overridden in setrace
|
||||
|
||||
// init flags
|
||||
a->flags = addflagpile(a, NULL);
|
||||
|
||||
//addflag(a->flags, F_DEBUG, B_TRUE, NA, NA, NULL); // ooooooooooo
|
||||
|
||||
// set race - this will inherit race flags
|
||||
// set race - this will inherit race flags and material
|
||||
a->race = NULL;
|
||||
|
||||
setrace(a, rid, B_FALSE);
|
||||
|
@ -10127,8 +10316,9 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) {
|
|||
}
|
||||
|
||||
|
||||
// adjust for lifeform material
|
||||
//adjustdammaterial(amt, damtype, getlfmaterial(lf));
|
||||
// don't adjust for lifeform material - we inherit all the material's flags.
|
||||
//adjustdammaterial((unsigned int *)amt, damtype, getlfmaterial(lf));
|
||||
adjustdamhardness((unsigned int *)amt, damtype, getlfmaterial(lf));
|
||||
|
||||
if (isdrunk(lf)) {
|
||||
*amt -= rnd(0,3);
|
||||
|
@ -10331,6 +10521,29 @@ int areallies(lifeform_t *lf1, lifeform_t *lf2) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int askforpayment(lifeform_t *shk, lifeform_t *lf) {
|
||||
char saybuf[BUFLEN];
|
||||
int totcost = 0;
|
||||
int nitems,shopid;
|
||||
flag_t *f;
|
||||
f = lfhasflag(shk, F_OWNSSHOP);
|
||||
if (f) {
|
||||
shopid = f->val[0];
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
totcost = getowing(lf, shopid, &nitems);
|
||||
|
||||
if (nitems == 1) {
|
||||
sprintf(saybuf, "That will cost you $%d.", totcost);
|
||||
} else {
|
||||
sprintf(saybuf, "That brings your bill to $%d.", totcost);
|
||||
}
|
||||
say(shk, saybuf, SV_TALK);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// make sure player has at least novice skill in all their start weapons/armour
|
||||
void autoskill(lifeform_t *lf) {
|
||||
skill_t *sk;
|
||||
|
@ -10569,6 +10782,9 @@ void loseconcentration(lifeform_t *lf) {
|
|||
// stop sprinting
|
||||
stopsprinting(lf);
|
||||
|
||||
// stop casting spells
|
||||
killflagsofid(lf->flags, F_CASTINGSPELL);
|
||||
|
||||
// boost spells end
|
||||
stopallspells(lf);
|
||||
|
||||
|
@ -12008,7 +12224,7 @@ int say(lifeform_t *lf, char *text, int volume) {
|
|||
} else if (volume == 4) {
|
||||
strcpy(verb, "roars");
|
||||
strcpy(noun, "roaring voices!");
|
||||
} else if (volume > 4) {
|
||||
} else { // ie > 4
|
||||
strcpy(verb, "bellows");
|
||||
strcpy(noun, "bellowing voices!");
|
||||
}
|
||||
|
@ -12248,6 +12464,9 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
|
|||
// set race
|
||||
lf->race = newrace;
|
||||
|
||||
// set material
|
||||
lf->material = lf->race->material;
|
||||
|
||||
// inherit flags from race
|
||||
copyflags(lf->flags, lf->race->flags, FROMRACE);
|
||||
// don't want certain race only flags...
|
||||
|
@ -12440,6 +12659,33 @@ void setlftarget(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
*/
|
||||
|
||||
int setlfmaterial(lifeform_t *lf, enum MATERIAL id) {
|
||||
if (getlfmaterial(lf) == id) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (hasactivespell(lf, OT_S_BARKSKIN) && (id != MT_WOOD)) {
|
||||
stopspell(lf, OT_S_BARKSKIN);
|
||||
}
|
||||
|
||||
lf->material = findmaterial(id);
|
||||
|
||||
// announce
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Your body %s to %s%c", (id == lf->race->material->id) ? "reverts" : "turns", lf->material->name,
|
||||
(id == lf->race->material->id) ? '.' : '!' );
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s%s body %s to %s%c", lfname, getpossessive(lfname),
|
||||
(id == lf->race->material->id) ? "reverts" : "turns",
|
||||
lf->material->name,
|
||||
(id == lf->race->material->id) ? '.' : '!' );
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int shoot(lifeform_t *lf) {
|
||||
object_t *gun,*ammo;
|
||||
lifeform_t *targ;
|
||||
|
@ -12556,6 +12802,9 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
case SC_SEARCH:
|
||||
attrib = (getskill(lf, SK_SPOTHIDDEN)*4);
|
||||
break;
|
||||
case SC_STEAL:
|
||||
attrib = (getskill(lf, SK_THIEVERY));
|
||||
break;
|
||||
case SC_STEALTH:
|
||||
attrib = (getskill(lf, SK_STEALTH)*4);
|
||||
break;
|
||||
|
@ -12617,6 +12866,11 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
|
|||
int bonus = 0;
|
||||
sumflags(lf->flags, F_ENHANCESEARCH, &bonus, NULL, NULL);
|
||||
othermod += bonus;
|
||||
} else if (ct == SC_STEAL) {
|
||||
if (attrib > 0) {
|
||||
// ie. -3 to 3
|
||||
othermod += (getstatmod(lf, A_DEX) / 15);
|
||||
}
|
||||
} else if (ct == SC_STEALTH) {
|
||||
if (attrib > 0) {
|
||||
if (lfhasflag(lf, F_SNEAK)) {
|
||||
|
@ -12828,6 +13082,102 @@ void sortlf(map_t *map, lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// returns TRUE on failure (ie. nothing to steal)
|
||||
int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag) {
|
||||
enum SKILLLEVEL slev;
|
||||
object_t *o;
|
||||
int i,nsteals;
|
||||
int numgot = 0;
|
||||
int fromground;
|
||||
char letter = 'a';
|
||||
slev = getskill(lf, SK_THIEVERY);
|
||||
|
||||
if (op->owner) {
|
||||
fromground = B_FALSE;
|
||||
} else {
|
||||
fromground = B_TRUE;
|
||||
}
|
||||
//
|
||||
if (slev >= PR_EXPERT) {
|
||||
nsteals = 2;
|
||||
} else {
|
||||
nsteals = 1;
|
||||
}
|
||||
|
||||
// what do we steal?
|
||||
for (i = 0; i < nsteals; i++) {
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "Steal what (%d of %d)?", i+1, nsteals);
|
||||
initprompt(&prompt, buf);
|
||||
addchoice(&prompt, '-', "Nothing", NULL, NULL);
|
||||
for (o = op->first ; o ; o = o->next) {
|
||||
int ok = B_TRUE;
|
||||
if ((slev < PR_SKILLED) && (getobunitweight(o) >= 3)) {
|
||||
// too heavy to steal
|
||||
ok = B_FALSE;
|
||||
} else if ((slev < PR_MASTER) && isequipped(o)) {
|
||||
// equipped
|
||||
ok = B_FALSE;
|
||||
} else if (!canpickup(lf, o, 1)) {
|
||||
// can't pick it up
|
||||
ok = B_FALSE;
|
||||
} else if ((wantflag != F_NONE) && !hasflag(o->flags, wantflag)) {
|
||||
// don't have the right flag
|
||||
ok = B_FALSE;
|
||||
}
|
||||
if (ok) {
|
||||
getobname(o, buf, 1);
|
||||
addchoice(&prompt, fromground ? letter++ : o->letter, buf, NULL, o);
|
||||
}
|
||||
}
|
||||
if (prompt.nchoices > 1) {
|
||||
if (slev >= PR_ADEPT) {
|
||||
// pick what you want
|
||||
getchoice(&prompt);
|
||||
o = (object_t *)prompt.result;
|
||||
} else {
|
||||
// random
|
||||
o = (object_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data;
|
||||
}
|
||||
if (o) {
|
||||
killflagsofid(o->flags, F_SHOPITEM);
|
||||
o = moveob(o, lf->pack, 1);
|
||||
if (o) {
|
||||
char obname[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
char targname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
getobname(o, obname, 1);
|
||||
if (op->owner) {
|
||||
getlfname(op->owner, targname);
|
||||
if (isplayer(lf)) {
|
||||
msg("You steal %s from %s!", obname, targname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s steals %s from %s!", lfname, obname, targname);
|
||||
}
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("You steal %s!", obname);
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s steals %s!", lfname, obname);
|
||||
}
|
||||
}
|
||||
numgot++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// nothing left to steal
|
||||
|
||||
if (numgot == 0) {
|
||||
return B_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end foreach steal
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
int stone(lifeform_t *lf) {
|
||||
char lfname[BUFLEN];
|
||||
char statname[BUFLEN];
|
||||
|
@ -14199,7 +14549,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
if (newregion->id != curmap->region->id) {
|
||||
newdepth = 1;
|
||||
}
|
||||
createmap(newmap, newdepth, newregion, curmap, dir);
|
||||
createmap(newmap, newdepth, newregion, curmap, dir, o);
|
||||
// if we stayed within the same region, our stairs should
|
||||
// now have a destination, since createmap() will automatically check
|
||||
// previous/next levels in the same region.
|
||||
|
|
10
lf.h
10
lf.h
|
@ -12,6 +12,7 @@ void adjustspeedforwater(lifeform_t *lf, int *speed);
|
|||
void applywalkdam(lifeform_t *lf, int dam, enum DAMTYPE damtype, object_t *o);
|
||||
int areallies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int areenemies(lifeform_t *lf1, lifeform_t *lf2);
|
||||
int askforpayment(lifeform_t *shk, lifeform_t *lf);
|
||||
void autoskill(lifeform_t *lf);
|
||||
void autotarget(lifeform_t *lf);
|
||||
void autoweild(lifeform_t *lf);
|
||||
|
@ -22,6 +23,7 @@ void breakallgrabs(lifeform_t *lf);
|
|||
long calcscore(lifeform_t *lf);
|
||||
int calcxp(lifeform_t *lf);
|
||||
int calcxprace(enum RACE rid);
|
||||
void callguards(lifeform_t *caller, lifeform_t *victim);
|
||||
int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost);
|
||||
int candrink(lifeform_t *lf, object_t *o);
|
||||
int caneat(lifeform_t *lf, object_t *o);
|
||||
|
@ -67,6 +69,7 @@ lifeform_t *findlf(map_t *m, int lfid);
|
|||
race_t *findrace(enum RACE id);
|
||||
race_t *findracebyname(char *name);
|
||||
raceclass_t *findraceclass(enum RACECLASS id);
|
||||
lifeform_t *findshopkeeper(map_t *m, int roomid);
|
||||
skill_t *findskill(enum SKILL id);
|
||||
skill_t *findskillbyname(char *name);
|
||||
enum SKILLLEVEL findskilllevbyname(char *name);
|
||||
|
@ -119,6 +122,7 @@ int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions);
|
|||
int getnightvisrange(lifeform_t *lf);
|
||||
char *getlfconditionname(enum LFCONDITION cond);
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||
int getowing(lifeform_t *buyer, int shopid, int *retnitems);
|
||||
enum LFCONDITION getseenlfconditioncutoff(lifeform_t *lf);
|
||||
char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer);
|
||||
glyph_t *getlfglyph(lifeform_t *lf);
|
||||
|
@ -156,7 +160,7 @@ int getracerarity(map_t *map, enum RACE rid);
|
|||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
int getrandommonlevel(race_t *r, map_t *m);
|
||||
race_t *getrandomrace(cell_t *c, int forcedepth);
|
||||
race_t *getreallyrandomrace(void);
|
||||
race_t *getreallyrandomrace(enum RACECLASS wantrc);
|
||||
enum SKILL getrandomskill(void);
|
||||
object_t *getrestob(lifeform_t *lf);
|
||||
enum SKILLLEVEL getskill(lifeform_t *lf, enum SKILL id);
|
||||
|
@ -175,12 +179,14 @@ void getwantdistance(lifeform_t *lf, int *min, int *max, int attacking);
|
|||
object_t *getweapon(lifeform_t *lf);
|
||||
long getxpforlev(int level);
|
||||
void givejob(lifeform_t *lf, enum JOB jobid);
|
||||
int givemoney(lifeform_t *from, lifeform_t *to, int amt);
|
||||
void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype);
|
||||
int giveskill(lifeform_t *lf, enum SKILL id);
|
||||
int giveskilllev(lifeform_t *lf, enum SKILL id, enum SKILLLEVEL slev);
|
||||
void givestartobs(lifeform_t *lf, flagpile_t *fp);
|
||||
void givestartskills(lifeform_t *lf, flagpile_t *fp);
|
||||
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
|
||||
int hasfreeaction(lifeform_t *lf);
|
||||
job_t *hasjob(lifeform_t *lf, enum JOB job);
|
||||
int lfcanbestoned(lifeform_t *lf);
|
||||
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
|
||||
|
@ -278,12 +284,14 @@ void setguntarget(lifeform_t *lf, lifeform_t *targ);
|
|||
void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph);
|
||||
void setlastdam(lifeform_t *lf, char *buf);
|
||||
//void setlftarget(lifeform_t *lf, lifeform_t *victim);
|
||||
int setlfmaterial(lifeform_t *lf, enum MATERIAL id);
|
||||
int shoot(lifeform_t *lf);
|
||||
int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod);
|
||||
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result);
|
||||
int skillcheckvs(lifeform_t *lf1, enum CHECKTYPE ct1, int mod1, lifeform_t *lf2, enum CHECKTYPE ct2, int mod2);
|
||||
int slipon(lifeform_t *lf, object_t *o);
|
||||
void sortlf(map_t *map, lifeform_t *lf);
|
||||
int steal(lifeform_t *lf, obpile_t *op, enum FLAG wantflag);
|
||||
int stone(lifeform_t *lf);
|
||||
void stopeating(lifeform_t *lf);
|
||||
void stopresting(lifeform_t *lf);
|
||||
|
|
26
map.h
26
map.h
|
@ -1,7 +1,7 @@
|
|||
#include "defs.h"
|
||||
|
||||
cell_t *addcell(map_t *map, int x, int y);
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell);
|
||||
habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance);
|
||||
void addhomeobs(lifeform_t *lf);
|
||||
map_t *addmap(void);
|
||||
lifeform_t *addmonster(cell_t *c, enum RACE raceid, int jobok, int amt, int autogen, int *nadded);
|
||||
|
@ -10,7 +10,7 @@ int addrandomthing(cell_t *c, int obchance, int *nadded);
|
|||
region_t *addregion(enum REGIONTYPE rtype, region_t *parent);
|
||||
regionoutline_t *addregionoutline(enum REGIONTYPE rtype);
|
||||
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir);
|
||||
regiontype_t *addregiontype(enum REGIONTYPE id, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major);
|
||||
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
void clearcell(cell_t *c);
|
||||
|
@ -29,19 +29,20 @@ void getradiuscells(cell_t *centre, int radius, int dirtype, enum LOFTYPE needlo
|
|||
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);
|
||||
void calclight(map_t *map);
|
||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by, int force);
|
||||
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force);
|
||||
int countadjcellsoftype(cell_t *cell, int id);
|
||||
int countadjrooms(cell_t *cell);
|
||||
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);
|
||||
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir);
|
||||
void createpit(map_t *map, int depth, map_t *parentmap, int exitdir);
|
||||
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings);
|
||||
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
|
||||
void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIONTYPE newregiontype, region_t *parent);
|
||||
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth);
|
||||
int createroom(map_t *map, int roomid, int overrideminw, int overrideminh, int xmargin, int ymargin, int *retx, int *rety, int *retw, int *reth, int doorpct, int forcewalls);
|
||||
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety);
|
||||
int dirtox(int dt, int dir);
|
||||
int dirtoy(int dt, int dir);
|
||||
void dumpmap(map_t *map);
|
||||
|
@ -66,8 +67,6 @@ cell_t *getcellindir(cell_t *cell, int dir);
|
|||
int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
|
||||
int getobchance(int habitat);
|
||||
char *getregionname(char *buf, map_t *m, int withlevel);
|
||||
int getvaultchance(map_t *m);
|
||||
char getvaultchar(vault_t *v, int x, int y);
|
||||
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);
|
||||
|
@ -96,10 +95,11 @@ int isloopdirok(cell_t *cell, int dir);
|
|||
int isnewcellok(cell_t *cell, char *err);
|
||||
int isonmap(map_t *map, int x, int y);
|
||||
int isoutdoors(map_t *m);
|
||||
int isroom(cell_t *c);
|
||||
int iswallindir(cell_t *cell, int dir);
|
||||
int linkexits(map_t *m, int roomid, int minx, int miny, int maxx, int maxy);
|
||||
void linkholes(map_t *map);
|
||||
int linkstairs(object_t *o);
|
||||
int linkstairs(object_t *o, object_t *o2);
|
||||
void makedoor(cell_t *cell, int openchance);
|
||||
void makelit(cell_t *c, enum LIGHTLEV how, int howlong);
|
||||
void makelitradius(cell_t *c, int radius, enum LIGHTLEV how, int howlong);
|
||||
|
|
125
move.c
125
move.c
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ai.h"
|
||||
#include "attack.h"
|
||||
#include "defs.h"
|
||||
#include "flag.h"
|
||||
|
@ -286,8 +287,10 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
if (isimpassableob(o, lf)) {
|
||||
if (lf) {
|
||||
if ((lf->race->material->id == MT_GAS) ||
|
||||
(lf->race->material->id == MT_SLIME)) {
|
||||
enum MATERIAL mid;
|
||||
mid = getlfmaterial(lf);
|
||||
if ((mid == MT_GAS) ||
|
||||
(mid == MT_SLIME)) {
|
||||
// ok
|
||||
} else if (lfhasflag(lf, F_NONCORPOREAL)) {
|
||||
// ok but still set error
|
||||
|
@ -601,30 +604,30 @@ int getwalkoffdir(lifeform_t *lf, int dir) {
|
|||
switch (dir) {
|
||||
case DC_NE:
|
||||
if (lf->cell->y == 0) {
|
||||
return DC_N;
|
||||
return D_N;
|
||||
} else if ( lf->cell->x == (lf->cell->map->w-1)) {
|
||||
return DC_E;
|
||||
return D_E;
|
||||
}
|
||||
break;
|
||||
case DC_SE:
|
||||
if (lf->cell->y == (lf->cell->map->h-1)) {
|
||||
return DC_S;
|
||||
return D_S;
|
||||
} else if ( lf->cell->x == (lf->cell->map->w-1)) {
|
||||
return DC_E;
|
||||
return D_E;
|
||||
}
|
||||
break;
|
||||
case DC_SW:
|
||||
if (lf->cell->y == (lf->cell->map->h-1)) {
|
||||
return DC_S;
|
||||
return D_S;
|
||||
} else if ( lf->cell->x == 0) {
|
||||
return DC_W;
|
||||
return D_W;
|
||||
}
|
||||
break;
|
||||
case DC_NW:
|
||||
if (lf->cell->y == 0) {
|
||||
return DC_N;
|
||||
return D_N;
|
||||
} else if ( lf->cell->x == 0) {
|
||||
return DC_W;
|
||||
return D_W;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -741,6 +744,24 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int makeorthogonal(int dir) {
|
||||
switch (dir) {
|
||||
case DC_N:
|
||||
case D_N:
|
||||
return D_N;
|
||||
case DC_E:
|
||||
case D_E:
|
||||
return D_E;
|
||||
case DC_S:
|
||||
case D_S:
|
||||
return D_S;
|
||||
case DC_W:
|
||||
case D_W:
|
||||
return D_W;
|
||||
}
|
||||
return D_NONE;
|
||||
}
|
||||
|
||||
// see 'movetowards' for description of dirtype
|
||||
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype ) {
|
||||
int dir;
|
||||
|
@ -870,6 +891,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
flag_t *f;
|
||||
int changedlev = B_FALSE;
|
||||
int preroom = -1, postroom = -1;
|
||||
int preshop = -1;
|
||||
int prespeed = B_FALSE, postspeed = B_FALSE;
|
||||
int prewater = B_FALSE;
|
||||
|
||||
|
@ -888,6 +910,9 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// update current cell + room id
|
||||
prespeed = getmovespeed(lf);
|
||||
preroom = lf->cell->roomid;
|
||||
if (lf->cell->vault && hasflag(lf->cell->vault->flags, F_VAULTISSHOP)) {
|
||||
preshop = lf->cell->roomid;
|
||||
}
|
||||
|
||||
// getting out of water?
|
||||
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
|
||||
|
@ -1108,7 +1133,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
|
||||
// does anyone else see you?
|
||||
if ((gamemode == GM_GAMESTARTED)) {
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
for (l = newcell->map->lf ; l ; l = l->next) {
|
||||
if (l != lf) {
|
||||
flag_t *alarm;
|
||||
|
@ -1153,6 +1178,54 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// leaving a shop
|
||||
if (preshop) {
|
||||
// are you about to go outside a shop with stolen goods?
|
||||
if ((lf->cell->roomid == preshop) && (lf->cell->type->id != CT_FLOORSHOP)) {
|
||||
lifeform_t *shk;
|
||||
shk = findshopkeeper(lf->cell->map, preshop);
|
||||
if (shk) {
|
||||
int nitems = 0;
|
||||
// do you have any unpaid items from that shop?
|
||||
if (getowing(lf, preshop, &nitems)) {
|
||||
char saybuf[BUFLEN];
|
||||
// warning...
|
||||
switch (rnd(1,3)) {
|
||||
case 1: sprintf(saybuf, "Hey! Where do you think you're going?");
|
||||
break;
|
||||
case 2: sprintf(saybuf, "AHEM!");
|
||||
break;
|
||||
case 3: sprintf(saybuf, "I hope you are going to pay for %s!",
|
||||
(nitems == 1) ? "that" : "those" );
|
||||
break;
|
||||
}
|
||||
say(shk, saybuf, SV_SHOUT);
|
||||
didmsg = B_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (lf->cell->roomid != preshop) {
|
||||
// you've left the shop
|
||||
lifeform_t *shk;
|
||||
shk = findshopkeeper(lf->cell->map, preshop);
|
||||
if (shk && getowing(lf, preshop, NULL)) {
|
||||
char saybuf[BUFLEN];
|
||||
// call the guards
|
||||
switch (rnd(1,3)) {
|
||||
case 1: sprintf(saybuf, "Stop thief!");
|
||||
break;
|
||||
case 2: sprintf(saybuf, "GUARDS!");
|
||||
break;
|
||||
case 3: sprintf(saybuf, "I've been robbed!");
|
||||
break;
|
||||
}
|
||||
say(shk, saybuf, SV_ROAR);
|
||||
didmsg = B_TRUE;
|
||||
fightback(shk, lf); // shopkeeper attacks
|
||||
callguards(shk, lf); // guards come running
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// status bar
|
||||
|
@ -1216,7 +1289,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
// tell player about things
|
||||
if (!isdead(lf)) {
|
||||
// some lifeforms can go through things
|
||||
if (lf->race->material->id == MT_GAS) {
|
||||
if (getlfmaterial(lf) == MT_GAS) {
|
||||
char obname[BUFLEN];
|
||||
for (o = newcell->obpile->first ; o ; o = o->next) {
|
||||
if (isimpassableob(o, lf)) {
|
||||
|
@ -1228,7 +1301,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (lf->race->material->id == MT_SLIME) {
|
||||
} else if (getlfmaterial(lf) == MT_SLIME) {
|
||||
char obname[BUFLEN];
|
||||
for (o = newcell->obpile->first ; o ; o = o->next) {
|
||||
if (isimpassableob(o, lf)) {
|
||||
|
@ -2274,6 +2347,10 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
int nadjallies = 0;
|
||||
int n;
|
||||
|
||||
// make sure dircetion is orthogonal
|
||||
dir = makeorthogonal(dir);
|
||||
assert(dir != D_NONE);
|
||||
|
||||
// announce
|
||||
if (isplayer(lf)) {
|
||||
char dirname[BUFLEN];
|
||||
|
@ -2300,7 +2377,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (!adjmap) {
|
||||
// make one
|
||||
adjmap = addmap();
|
||||
createmap(adjmap, thismap->depth, thismap->region, thismap, dir);
|
||||
createmap(adjmap, thismap->depth, thismap->region, thismap, dir, NULL);
|
||||
}
|
||||
|
||||
if (adjmap) {
|
||||
|
@ -2377,14 +2454,28 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
if (!cell) {
|
||||
// won't walk off map
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (cell && celldangerous(lf, cell, B_TRUE, error)) {
|
||||
if (celldangerous(lf, cell, B_TRUE, error)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (!isroom(cell) && hasjob(lf, J_SHOPKEEPER)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_STAYINHABITAT) && (cell->habitat->id != lf->cell->habitat->id)) {
|
||||
if (error) *error = E_WONT;
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// don't attack other monsters
|
||||
if (cell && cell->lf) { // if someone is in the way
|
||||
if (cell->lf) { // if someone is in the way
|
||||
if (lf->race->raceclass->id == RC_INSECT) {
|
||||
if (hasactivespell(cell->lf, OT_S_REPELINSECTS)) {
|
||||
if (error) *error = E_WONT;
|
||||
|
@ -2415,7 +2506,6 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
|
||||
// look for avoided objects (because they are cursed).
|
||||
if (cell) {
|
||||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
flag_t *f;
|
||||
sprintf(buf, "%ld",o->id);
|
||||
|
@ -2447,7 +2537,6 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
|
1
move.h
1
move.h
|
@ -12,6 +12,7 @@ int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int d
|
|||
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 makeorthogonal(int dir);
|
||||
int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype);
|
||||
int moveclear(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
int moveeffects(lifeform_t *lf);
|
||||
|
|
112
nexus.c
112
nexus.c
|
@ -16,6 +16,7 @@
|
|||
#include "nexus.h"
|
||||
#include "objects.h"
|
||||
#include "save.h"
|
||||
#include "spell.h"
|
||||
#include "text.h"
|
||||
#include "vault.h"
|
||||
|
||||
|
@ -170,8 +171,10 @@ int main(int argc, char **argv) {
|
|||
initprompt(&prompt, "Select your job:");
|
||||
ch = 'a';
|
||||
for (j = firstjob ; j ; j = j->next) {
|
||||
if (!hasflag(j->flags, F_NOPLAYER)) {
|
||||
addchoice(&prompt, ch++, j->name, NULL, j);
|
||||
}
|
||||
}
|
||||
j = NULL;
|
||||
while (!j) {
|
||||
getchoice(&prompt);
|
||||
|
@ -187,12 +190,12 @@ int main(int argc, char **argv) {
|
|||
// create world map.
|
||||
wregion = addregion(RG_WORLDMAP, NULL);
|
||||
addmap();
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE);
|
||||
createmap(firstmap, 1, wregion, NULL, D_NONE, NULL);
|
||||
//createmap(firstmap, 1, RG_FIRSTDUNGEON, H_DUNGEON, NULL, D_NONE);
|
||||
// create first dungeon
|
||||
dregion = findregionbytype(RG_FIRSTDUNGEON);
|
||||
dmap = addmap();
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN);
|
||||
createmap(dmap, 1, dregion, firstmap, D_DOWN, NULL);
|
||||
}
|
||||
|
||||
// find staircase
|
||||
|
@ -214,14 +217,8 @@ int main(int argc, char **argv) {
|
|||
addflag(player->flags, F_NAME, NA, NA, NA, "Anonymous");
|
||||
}
|
||||
givejob(player, j->id);
|
||||
// special cases for jobs:
|
||||
if (j->id == J_PIRATE) {
|
||||
flag_t *f;
|
||||
f = lfhasflagval(player, F_HASATTACK, OT_FISTS, NA, NA, NULL);
|
||||
assert(f);
|
||||
f->val[0] = OT_HOOKHAND;
|
||||
sprintf(f->text, "1d4");
|
||||
} else if (j->id == J_WIZARD) {
|
||||
// extra choices for some jobs
|
||||
if (j->id == J_WIZARD) {
|
||||
skill_t *sk;
|
||||
initprompt(&prompt, "Select your spell specialty:");
|
||||
addchoice(&prompt, 'a', getskillname(SK_SS_AIR), NULL, findskill(SK_SS_AIR));
|
||||
|
@ -572,6 +569,79 @@ void donextturn(map_t *map) {
|
|||
int donormalmove = B_TRUE;
|
||||
flag_t *f;
|
||||
|
||||
// casting a spell?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_CASTINGSPELL);
|
||||
if (f) {
|
||||
donormalmove = B_FALSE;
|
||||
|
||||
f->val[2]--;
|
||||
if (f->val[2] <= 0) {
|
||||
char *p;
|
||||
char buf[BUFLEN];
|
||||
int lfid,mapid,x,y,power;
|
||||
long obid;
|
||||
lifeform_t *targlf;
|
||||
object_t *targob;
|
||||
cell_t *targcell;
|
||||
map_t *targmap;
|
||||
enum OBTYPE sid;
|
||||
|
||||
sid = f->val[0];
|
||||
power = f->val[1];
|
||||
|
||||
|
||||
// finished!
|
||||
p = f->text;
|
||||
p = readuntil(buf, p, ';');
|
||||
lfid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
obid = atol(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
mapid = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
x = atoi(p);
|
||||
p = readuntil(buf, p, ';');
|
||||
y = atoi(p);
|
||||
|
||||
if (lfid >= 0) {
|
||||
targlf = findlf(NULL, lfid);
|
||||
} else {
|
||||
targlf = NULL;
|
||||
}
|
||||
if (obid >= 0) {
|
||||
targob = findobidinmap(who->cell->map, obid);
|
||||
} else {
|
||||
targob = NULL;
|
||||
}
|
||||
if (mapid >= 0) {
|
||||
targmap = findmap(mapid);
|
||||
targcell = getcellat(targmap, x, y);
|
||||
}
|
||||
taketime(who, getspellspeed(who));
|
||||
dospelleffects(who, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE);
|
||||
killflagsofid(who->flags, F_CASTINGSPELL);
|
||||
} else {
|
||||
if (isplayer(who)) {
|
||||
objecttype_t *sp;
|
||||
sp = findot(f->val[0]);
|
||||
msg("You continue casting %s.", sp->name);
|
||||
} else if (cansee(player, who)) {
|
||||
flag_t *f2;
|
||||
char lfname[BUFLEN];
|
||||
// still going...
|
||||
getlfname(who, lfname);
|
||||
f2 = lfhasflag(who,F_SPELLCASTTEXT);
|
||||
if (f2 && strlen(f2->text)) {
|
||||
msg("%s %s.", lfname, f2->text);
|
||||
} else {
|
||||
msg("%s continues casting a spell.", lfname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eating?
|
||||
if (donormalmove) {
|
||||
f = lfhasflag(who, F_EATING);
|
||||
|
@ -637,8 +707,14 @@ void donextturn(map_t *map) {
|
|||
// find out what player wants to do
|
||||
handleinput();
|
||||
} else {
|
||||
//char lfname[BUFLEN];
|
||||
//char buf[BUFLEN];
|
||||
// do ai move
|
||||
//real_getlfname(who, lfname, B_FALSE);
|
||||
//sprintf(buf, "aimove %s",lfname);
|
||||
//dbtimestart(buf);
|
||||
aiturn(who);
|
||||
//dbtimeend(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1332,21 +1408,9 @@ void timeeffectsworld(map_t *map) {
|
|||
if (!o) {
|
||||
o = addob(c->obpile, "water");
|
||||
}
|
||||
}
|
||||
|
||||
if (o) {
|
||||
flag_t *dflag;
|
||||
dflag = hasflag(o->flags, F_DEEPWATER);
|
||||
// adjust depth
|
||||
dflag->val[0] = f->val[2];
|
||||
}
|
||||
} else {
|
||||
// water depth is now zero.
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
if (o) {
|
||||
killob(o);
|
||||
addob(c->obpile, "large puddle of water");
|
||||
}
|
||||
}
|
||||
setwaterdepth(c, f->val[2]);
|
||||
}
|
||||
killflag(f);
|
||||
continue;
|
||||
|
|
279
objects.c
279
objects.c
|
@ -429,6 +429,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
// for doors
|
||||
enum FLAG doorflag[5];
|
||||
int ndoorflags = 0;
|
||||
char *signtext = NULL;
|
||||
|
||||
// just in case we don't add any
|
||||
addedob[0] = NULL;
|
||||
|
@ -646,6 +647,24 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
|
||||
corpserace = findracebyname(racename);
|
||||
ot = findot(OT_HEAD);
|
||||
} else if (strstarts(p, "sign ")) {
|
||||
char *pp;
|
||||
pp = strchr(p, '\"');
|
||||
if (pp) {
|
||||
char sbuf[BUFLEN];
|
||||
char *sbp;
|
||||
sbp = sbuf;
|
||||
pp++;
|
||||
|
||||
while (*pp && (*pp != '\"')) {
|
||||
*sbp = *pp;
|
||||
sbp++;
|
||||
pp++;
|
||||
}
|
||||
*sbp = '\0';
|
||||
signtext = strdup(sbuf);
|
||||
}
|
||||
ot = findot(OT_SIGN);
|
||||
} else if (strstr(p, "spellbook of ")) {
|
||||
char *pp;
|
||||
pp = p + 13;
|
||||
|
@ -718,7 +737,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
////////////////////////////////////
|
||||
// we now have the objecttype!
|
||||
////////////////////////////////////
|
||||
|
||||
if (hasflag(ot->flags, F_ONEPERCELL)) {
|
||||
if (hasob(where, ot->id)) {
|
||||
nretobs = 0;
|
||||
|
@ -901,30 +919,36 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
*/
|
||||
|
||||
for (i = 0; i < nadded; i++) {
|
||||
cell_t *obloc;
|
||||
|
||||
o = addedob[i];
|
||||
obloc = getoblocation(o);
|
||||
|
||||
// fill in sign text
|
||||
if (signtext) {
|
||||
addflag(o->flags, F_SIGNTEXT, NA, NA, NA, signtext);
|
||||
}
|
||||
|
||||
// fill in door flags
|
||||
if (ndoorflags && isdoor(o, NULL)) {
|
||||
int n;
|
||||
for (n = 0; n < ndoorflags; n++) {
|
||||
cell_t *c;
|
||||
int val[3];
|
||||
c = getoblocation(o);
|
||||
if (c) {
|
||||
if (obloc) {
|
||||
// fill in flag vals
|
||||
switch (doorflag[n]) {
|
||||
case F_LOCKED:
|
||||
val[0] = B_TRUE;
|
||||
val[1] = getdoorlockdiff(c->map->depth);
|
||||
val[1] = getdoorlockdiff(obloc->map->depth);
|
||||
val[2] = NA;
|
||||
break;
|
||||
case F_JAMMED:
|
||||
val[0] = rnd(1,c->map->depth+3);
|
||||
val[0] = rnd(1,obloc->map->depth+3);
|
||||
val[1] = NA;
|
||||
val[2] = NA;
|
||||
break;
|
||||
case F_SECRET:
|
||||
val[0] = getdoorsecretdiff(c->map->depth);
|
||||
val[0] = getdoorsecretdiff(obloc->map->depth);
|
||||
val[1] = NA;
|
||||
val[2] = NA;
|
||||
break;
|
||||
|
@ -1398,7 +1422,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
|
|||
objecttype_t *ot2;
|
||||
strcpy(buf, "");
|
||||
while (!strcmp(buf, "")) {
|
||||
real_getrandomob(loc->map, buf, RO_NONE, NA, loc->map->depth + rnd(10,15));
|
||||
real_getrandomob(loc->map, buf, RO_NONE, NA, loc->map->depth + rnd(10,15), NA);
|
||||
// replace "1 potion" with "a potion"
|
||||
if (strstr(buf, "1 ") == buf) {
|
||||
char temp[BUFLEN];
|
||||
|
@ -1601,6 +1625,22 @@ objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material,
|
|||
return a;
|
||||
}
|
||||
|
||||
|
||||
void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat) {
|
||||
// now check for hardness
|
||||
if (isphysicaldam(damtype)) {
|
||||
material_t *m;
|
||||
m = findmaterial(mat);
|
||||
if (m) {
|
||||
flag_t *f;
|
||||
f = hasflag(m->flags, F_HARDNESS);
|
||||
if (f && (*dam < f->val[0])) {
|
||||
*dam = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjust damage based on material being damaged
|
||||
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat) {
|
||||
// adjust based on material
|
||||
|
@ -1694,6 +1734,7 @@ void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype) {
|
||||
|
@ -1781,8 +1822,9 @@ void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype) {
|
|||
}
|
||||
}
|
||||
|
||||
// adjust damage for material too
|
||||
// adjust damage for material & hardness too
|
||||
adjustdammaterial(dam, damtype, o->material->id);
|
||||
adjustdamhardness(dam, damtype, o->material->id);
|
||||
}
|
||||
|
||||
// adjust price for magical effects etc
|
||||
|
@ -2715,13 +2757,22 @@ glyph_t *getglyph(object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
// override colour
|
||||
// special case
|
||||
if (o->type->id == OT_WATERDEEP) {
|
||||
cell_t *loc;
|
||||
// override colour
|
||||
if (getobdepth(o, player) >= DP_HEAD) {
|
||||
col = C_BOLDBLUE;
|
||||
} else {
|
||||
col = C_BLUE;
|
||||
}
|
||||
loc = getoblocation(o);
|
||||
if (getcellwaterdepth(loc, player) >= DP_WAIST) {
|
||||
g = '{';
|
||||
} else {
|
||||
g = '~';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tempglyph.ch = g;
|
||||
|
@ -3677,7 +3728,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
char localbuf[BUFLEN];
|
||||
char buf2[BUFLEN];
|
||||
char triedbuf[BUFLEN];
|
||||
int shopitem = B_FALSE;
|
||||
int venditem = B_FALSE;
|
||||
flag_t *f;
|
||||
brand_t *br;
|
||||
obmod_t *om;
|
||||
|
@ -3685,13 +3736,13 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
cell_t *where;
|
||||
|
||||
// default to normal name
|
||||
if (hasflag(o->flags, F_SHOPITEM)) {
|
||||
shopitem = B_TRUE;
|
||||
if (hasflag(o->flags, F_VENDITEM)) {
|
||||
venditem = B_TRUE;
|
||||
}
|
||||
|
||||
where = getoblocation(o);
|
||||
|
||||
if (shopitem) {
|
||||
if (venditem) {
|
||||
showall = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -3771,6 +3822,8 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
strcat(basename, dname);
|
||||
}
|
||||
} // end if sight/smell
|
||||
} else if ((o->type->id == OT_SIGN) && !hasflag(o->flags, F_SIGNTEXT)) {
|
||||
strcpy(basename, "blank sign");
|
||||
} else if (o->type->id == OT_WATERDEEP) {
|
||||
sprintf(basename, "%s water", getwaterdepthname(getobdepth(o, player)));
|
||||
} else {
|
||||
|
@ -4063,6 +4116,16 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
}
|
||||
}
|
||||
|
||||
// show sign text
|
||||
if (o->type->id == OT_SIGN) {
|
||||
f = hasflag(o->flags, F_SIGNTEXT);
|
||||
if (f) {
|
||||
strcat(localbuf, " reading '");
|
||||
strcat(localbuf, f->text);
|
||||
strcat(localbuf, "'");
|
||||
}
|
||||
}
|
||||
|
||||
// append inscription
|
||||
if (o->inscription) {
|
||||
strcat(localbuf, " {");
|
||||
|
@ -4102,6 +4165,14 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
}
|
||||
}
|
||||
|
||||
// in a shop?
|
||||
f = hasflag(o->flags, F_SHOPITEM);
|
||||
if (f) {
|
||||
char pricebuf[BUFLEN];
|
||||
sprintf(pricebuf, " [$%d%s]", f->val[0], o->pile->owner ? ", unpaid" : "");
|
||||
strcat(localbuf, pricebuf);
|
||||
}
|
||||
|
||||
// apply prefix now!
|
||||
if (count == 1) {
|
||||
if (hasflag(o->flags, F_NO_A)) {
|
||||
|
@ -4273,7 +4344,7 @@ objecttype_t *getoppositestairs(objecttype_t *ot) {
|
|||
return findot(f->val[0]);
|
||||
}
|
||||
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth) {
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat) {
|
||||
objecttype_t *ot;
|
||||
objecttype_t *poss[MAXRANDOMOBCANDIDATES];
|
||||
int nposs = 0;
|
||||
|
@ -4335,7 +4406,9 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
// correct rarity?
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
||||
if (!rarflag) {
|
||||
if (map) {
|
||||
if (forcehabitat != NA) {
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, forcehabitat, NA, NA, NULL);
|
||||
} else if (map) {
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
|
||||
} else {
|
||||
rarflag = hasflagval(ot->flags, F_RARITY, NA, NA, NA, NULL);
|
||||
|
@ -4394,8 +4467,6 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
|
||||
if (db) dblog("got %d possibilities. now adjusting for RR_",nposs);
|
||||
|
||||
|
||||
|
||||
// pick a random object from our possiblities
|
||||
selidx = rnd(0,nposs-1);
|
||||
ot = poss[selidx];
|
||||
|
@ -4489,17 +4560,17 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
}
|
||||
|
||||
char *getrandomob(map_t *map, char *buf) {
|
||||
return real_getrandomob(map, buf, RO_NONE, NA, NA);
|
||||
return real_getrandomob(map, buf, RO_NONE, NA, NA, NA);
|
||||
}
|
||||
|
||||
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf) {
|
||||
return real_getrandomob(map, buf, RO_DAMTYPE, damtype, NA);
|
||||
return real_getrandomob(map, buf, RO_DAMTYPE, damtype, NA, NA);
|
||||
}
|
||||
|
||||
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod) {
|
||||
//return real_getrandomob(map, buf, RO_OBCLASS, cid, map->depth + depthmod);
|
||||
if (depthmod == NA) depthmod = 0;
|
||||
return real_getrandomob(map, buf, RO_OBCLASS, cid, getmapdifficulty(map) + depthmod);
|
||||
return real_getrandomob(map, buf, RO_OBCLASS, cid, getmapdifficulty(map) + depthmod, NA);
|
||||
}
|
||||
|
||||
int getobrarity(object_t *o, enum RARITY *rr) {
|
||||
|
@ -4598,6 +4669,31 @@ char *getschoolnameshort(enum SPELLSCHOOL sch) {
|
|||
return "unknown school";
|
||||
}
|
||||
|
||||
void setwaterdepth(cell_t *c, int depth) {
|
||||
object_t *o;
|
||||
if (depth > 0) {
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
if (o) {
|
||||
flag_t *f;
|
||||
// adjust depth
|
||||
f = hasflag(o->flags, F_DEEPWATER);
|
||||
f->val[0] = depth;
|
||||
}
|
||||
} else {
|
||||
int nkilled = 0;
|
||||
// water depth is now zero.
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
while (o) {
|
||||
killob(o);
|
||||
nkilled++;
|
||||
o = hasobwithflag(c->obpile, F_DEEPWATER);
|
||||
}
|
||||
if (nkilled) {
|
||||
addob(c->obpile, "large puddle of water");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getshatterdam(object_t *o) {
|
||||
int shatterdam = 0;
|
||||
if (willshatter(o->material->id)) {
|
||||
|
@ -5090,7 +5186,7 @@ void initobjects(void) {
|
|||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_FOOD, "food", 3);
|
||||
addmaterial(MT_PLASTIC, "plastic", 3);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL);
|
||||
addmaterial(MT_WAX, "wax", 3);
|
||||
addflag(lastmaterial->flags, F_MATCONVERT, MT_FIRE, NA, NA, "lump of melted wax");
|
||||
addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_FIRE, NA, NA, "melts");
|
||||
|
@ -5100,12 +5196,12 @@ void initobjects(void) {
|
|||
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_BONE, "bone", 5);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL);
|
||||
addmaterial(MT_OIL, "oil", 5);
|
||||
addmaterial(MT_ICE, "ice",6);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL);
|
||||
addmaterial(MT_WOOD, "wood", 6);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_FLAMMABLE, 5, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
||||
addmaterial(MT_ACID, "acid", 7);
|
||||
|
@ -5113,7 +5209,7 @@ void initobjects(void) {
|
|||
addmaterial(MT_BLOOD, "blood", 7);
|
||||
addmaterial(MT_SLIME, "slime", 9);
|
||||
addmaterial(MT_STONE, "stone", 10);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BITE, NA, NA, NULL);
|
||||
|
@ -5121,7 +5217,7 @@ void initobjects(void) {
|
|||
addflag(lastmaterial->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
|
||||
addmaterial(MT_METAL, "metal", 13);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 6, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BITE, NA, NA, NULL);
|
||||
|
@ -5129,10 +5225,10 @@ void initobjects(void) {
|
|||
addflag(lastmaterial->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTRESIST, DT_PROJECTILE, NA, NA, NULL);
|
||||
addmaterial(MT_GLASS, "glass", 13);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
|
||||
addmaterial(MT_GOLD, "gold", 16);
|
||||
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL);
|
||||
//addmaterial(MT_GOLD, "gold", 16);
|
||||
|
||||
// object classes
|
||||
|
@ -5261,8 +5357,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
// blocks movement, but you can see and fire through them.
|
||||
addot(OT_IRONGATE, "iron gate", "A gate comprised of a series of vertical iron bars.", MT_METAL, 0, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "|");
|
||||
addot(OT_GATEIRON, "iron gate", "A gate comprised of a series of vertical iron bars, raised slightly above the floor.", MT_METAL, 500, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "+");
|
||||
addflag(lastot->flags, F_DOOR, SZ_MEDIUM, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MEDIUM, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5273,7 +5369,26 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
|
||||
addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "+");
|
||||
addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
addot(OT_FENCEWOOD, "wooden fence", "A tell fence created from a series of upright logs of wood.", MT_WOOD, 200, OC_DFEATURE);
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
||||
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
||||
|
||||
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
|
@ -5300,7 +5415,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
|
||||
|
||||
addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_VILLAGE, 80, NA, "");
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); // will be overridden
|
||||
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5380,7 +5496,7 @@ void initobjects(void) {
|
|||
addot(OT_WATERDEEP, "water", "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");
|
||||
|
@ -5943,6 +6059,7 @@ void initobjects(void) {
|
|||
addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
///////////////////
|
||||
// divination
|
||||
|
@ -6168,8 +6285,6 @@ void initobjects(void) {
|
|||
addot(OT_S_BARKSKIN, "barkskin", "Covers the caster with a skin of bark, reducing damage but making them vulnerable to fire.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addot(OT_S_CHARMANIMAL, "befriend animal", "Temporarily makes a single animal friendly to you.", MT_NOTHING, 0, OC_SPELL);
|
||||
|
@ -6371,15 +6486,18 @@ void initobjects(void) {
|
|||
addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_SLEEP, "sleep", "Puts the target creature to sleep.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_TELEKINESIS, "telekinesis", "Mentally move or manipulate nearby objects.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
||||
// l3
|
||||
addot(OT_S_PSYARMOUR, "psychic armour", "Mentally block incoming attacks.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
||||
|
@ -6573,6 +6691,8 @@ void initobjects(void) {
|
|||
|
||||
|
||||
// divine powers (spells/abilities)
|
||||
addot(OT_A_BLINDALL, "nosight", "Make everyone on the level blind.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_DEBUG, "debug", "You can toggle debugging for a lifeform.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_ENHANCE, "enhance", "Enhance a lifeform's stats.", MT_NOTHING, 0, OC_ABILITY);
|
||||
|
@ -6587,6 +6707,10 @@ void initobjects(void) {
|
|||
addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
|
||||
addot(OT_S_CLEARLEVEL, "blank level", "Blanks out the current map.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_CREATEVAULT, "create vault", "Create a vault of the given type.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 9, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL);
|
||||
|
@ -7083,7 +7207,7 @@ void initobjects(void) {
|
|||
addot(OT_ACIDPOOL, "pool of acid", "A pool of 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_DIECONVERTTEXT, NA, NA, NA, "evaporates");
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of acid");
|
||||
|
@ -7098,7 +7222,7 @@ void initobjects(void) {
|
|||
addot(OT_ACIDPUDDLE, "puddle of acid", "A small puddle of 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, 4, 4, NA, NULL);
|
||||
|
@ -7163,7 +7287,7 @@ void initobjects(void) {
|
|||
addot(OT_MUDPOOL, "pool of mud", "A large puddle of wet mud.", MT_WATER, 60, 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);
|
||||
|
@ -7183,6 +7307,11 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice");
|
||||
addflag(lastot->flags, F_DTCONVERT, DT_FIRE, NA, NA, "puff of steam");
|
||||
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 10, 10, 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_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
|
||||
//addflag(lastot->flags, F_WALKDAM, DT_WATER, NA, NA, "0d1+1");
|
||||
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1");
|
||||
|
@ -7190,13 +7319,18 @@ void initobjects(void) {
|
|||
addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 20, 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);
|
||||
addflag(lastot->flags, F_DTCONVERT, DT_COLD, NA, NA, "sheet of ice");
|
||||
addflag(lastot->flags, F_DTCONVERT, DT_FIRE, NA, NA, "cloud of steam");
|
||||
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 30, 30, 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_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+2");
|
||||
|
||||
|
@ -7245,7 +7379,7 @@ void initobjects(void) {
|
|||
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);
|
||||
|
@ -7259,7 +7393,15 @@ void initobjects(void) {
|
|||
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);
|
||||
addot(OT_SIGN, "sign", "A marker with something written on it.", MT_WOOD, 25, OC_MISC);
|
||||
addflag(lastot->flags, F_GLYPH, C_BROWN, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL);
|
||||
|
||||
addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 40, OC_MISC);
|
||||
addflag(lastot->flags, F_RARITY, H_VILLAGE, 75, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "(");
|
||||
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
|
||||
|
@ -7321,7 +7463,7 @@ void initobjects(void) {
|
|||
|
||||
// effects
|
||||
addot(OT_FIRELARGE, "large fire", "A large, roaring inferno.", MT_FIRE, 0, OC_EFFECT);
|
||||
addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "~");
|
||||
addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "{");
|
||||
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dies down a little");
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "medium fire");
|
||||
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
|
||||
|
@ -7332,7 +7474,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||
addot(OT_FIREMED, "medium fire", "A medium-sized roaring fire.", MT_FIRE, 0, OC_EFFECT);
|
||||
addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "~");
|
||||
addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "{");
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small fire");
|
||||
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dies down a little");
|
||||
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
|
||||
|
@ -7343,7 +7485,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
||||
addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT);
|
||||
addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "~");
|
||||
addflag(lastot->flags, F_GLYPH, C_RED, NA, NA, "{");
|
||||
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out");
|
||||
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
||||
|
@ -8981,6 +9123,12 @@ int iswearable(object_t *o) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void killallobs(obpile_t *op) {
|
||||
while (op->first) {
|
||||
killob(op->first);
|
||||
}
|
||||
}
|
||||
|
||||
void killmaterial(material_t *m) {
|
||||
material_t *nextone, *lastone;
|
||||
|
||||
|
@ -9042,9 +9190,7 @@ void killob(object_t *o) {
|
|||
}
|
||||
|
||||
void killobpile(obpile_t *op) {
|
||||
while (op->first) {
|
||||
killob(op->first);
|
||||
}
|
||||
killallobs(op);
|
||||
free(op);
|
||||
}
|
||||
|
||||
|
@ -9472,10 +9618,28 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
|
|||
drawscreen();
|
||||
}
|
||||
|
||||
// special effects if a lifeform picked up an object
|
||||
if (dst->owner) {
|
||||
flag_t *f;
|
||||
// picked up an object in a shop
|
||||
f = hasflag(o->flags, F_SHOPITEM);
|
||||
if (f) {
|
||||
lifeform_t *shk;
|
||||
shk = findshopkeeper(dst->owner->cell->map, f->val[1]);
|
||||
if (shk && cansee(shk, dst->owner)) {
|
||||
askforpayment(shk, dst->owner);
|
||||
}
|
||||
|
||||
if (!isplayer(dst->owner)) {
|
||||
msg("xxxxxxxxxxxx");
|
||||
}
|
||||
}
|
||||
|
||||
// in case you picked up money, something which changes your AR, etc
|
||||
if (dst->owner && isplayer(dst->owner)) {
|
||||
if (isplayer(dst->owner)) {
|
||||
statdirty = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//o = newobeffects(o);
|
||||
|
||||
|
@ -12242,6 +12406,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
char throwverbpres[BUFLEN];
|
||||
int acc;
|
||||
int youhit = B_FALSE;
|
||||
int missiledam = 0;
|
||||
object_t *newob;
|
||||
cell_t *newloc;
|
||||
int db = B_TRUE;
|
||||
|
@ -12347,7 +12512,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (target && isdead(target)) {
|
||||
target = NULL;
|
||||
}
|
||||
if (thrower && target && !isprone(target)) {
|
||||
if (thrower && target && !isprone(target) && !lfhasflag(target, F_CASTINGSPELL)) {
|
||||
if (areallies(thrower, target) && !firearm) {
|
||||
willcatch = B_TRUE;
|
||||
}
|
||||
|
@ -12563,7 +12728,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
// an actual physical shield?
|
||||
shield = getshield(target);
|
||||
if (shield) {
|
||||
if (shield && !lfhasflag(target, F_CASTINGSPELL)) {
|
||||
// block chance based on shield skill
|
||||
// ie. ST_AVERAGE = speed3 = 18
|
||||
// ie. gun = speed20 = 120 = impossible
|
||||
|
@ -12585,6 +12750,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
takedamage(shield, dam, DT_PROJECTILE);
|
||||
youhit = B_FALSE;
|
||||
practice(target, SK_SHIELDS, 1);
|
||||
|
||||
missiledam += ((speed*2)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12600,7 +12767,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
!isimmobile(target) &&
|
||||
skillcheck(target, SC_DEX, 15*speed, 0)) {
|
||||
willcatch = B_TRUE;
|
||||
} else if (skillcheck(target, SC_DODGE, 10*speed, 0)) {
|
||||
} else if (!lfhasflag(target, F_CASTINGSPELL) && skillcheck(target, SC_DODGE, 10*speed, 0)) {
|
||||
// then check if we dodge it...
|
||||
youhit = B_FALSE;
|
||||
}
|
||||
|
@ -12692,6 +12859,8 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
if (firearm) {
|
||||
practice(thrower, SK_RANGED, 1);
|
||||
}
|
||||
|
||||
missiledam += ((speed*2)+1);
|
||||
}
|
||||
} else { // ie. if !youhit
|
||||
if (!announcedmiss) {
|
||||
|
@ -12724,10 +12893,10 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
sprintf(dambuf, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
||||
shatter(newob, youhit, dambuf, thrower);
|
||||
} else {
|
||||
// object only gets damaged if it hit someone
|
||||
if (youhit) {
|
||||
// object only gets damaged if it hit someone/something
|
||||
if (missiledam) {
|
||||
// don't announce damage to the thrown object
|
||||
real_takedamage(newob, speed-1, DT_BASH, B_FALSE);
|
||||
real_takedamage(newob, missiledam, DT_BASH, B_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13209,7 +13378,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf) {
|
|||
} else if (oid == OT_TRAPTELEPORT) {
|
||||
cell_t *newc;
|
||||
// move somewhere else!
|
||||
newc = getrandomcelloftype(lf->cell->map, lf->cell->map->habitat->id);
|
||||
newc = getrandomcelloftype(lf->cell->map, lf->cell->map->habitat->emptycelltype);
|
||||
if (newc) {
|
||||
teleportto(lf, newc, B_TRUE);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ obmod_t *addobmod(enum OBMOD id, char *prefix);
|
|||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
|
||||
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid);
|
||||
void adjustdamhardness(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype);
|
||||
int adjustarmourpenalty(lifeform_t *lf, float amt);
|
||||
|
@ -100,7 +101,7 @@ char *getobhurtname(object_t *o, enum DAMTYPE damtype);
|
|||
float getobweight(object_t *o);
|
||||
float getobunitweight(object_t *o);
|
||||
objecttype_t *getoppositestairs(objecttype_t *ot);
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth);
|
||||
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth, int forcehabitat);
|
||||
char *getrandomob(map_t *map, char *buf);
|
||||
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf);
|
||||
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf, int depthmod);
|
||||
|
@ -165,6 +166,7 @@ int istried(object_t *o);
|
|||
int istriedot(objecttype_t *ot);
|
||||
int isweapon(object_t *o);
|
||||
int iswearable(object_t *o);
|
||||
void killallobs(obpile_t *op);
|
||||
void killmaterial(material_t *m);
|
||||
void killob(object_t *o);
|
||||
void killobpile(obpile_t *o);
|
||||
|
@ -204,6 +206,7 @@ void setblessed(object_t *o, enum BLESSTYPE wantbless);
|
|||
int sethiddenname(objecttype_t *o, char *text);
|
||||
void setinscription(object_t *o, char *text);
|
||||
void setobcreatedby(object_t *o, lifeform_t *lf);
|
||||
void setwaterdepth(cell_t *c, int depth);
|
||||
int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf);
|
||||
void shufflehiddennames(void);
|
||||
object_t *splitob(object_t *o);
|
||||
|
|
21
save.c
21
save.c
|
@ -13,6 +13,7 @@
|
|||
#include "nexus.h"
|
||||
#include "objects.h"
|
||||
#include "save.h"
|
||||
#include "vault.h"
|
||||
|
||||
extern long curtime;
|
||||
|
||||
|
@ -144,6 +145,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
map_t *m;
|
||||
int x,y,level,newlevel;
|
||||
int db = B_TRUE;
|
||||
int matid;
|
||||
|
||||
if (db) dblog("--> Loading lifeform...\n");
|
||||
|
||||
|
@ -191,6 +193,8 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
buf[strlen(buf)-1] = '\0'; // strip newline
|
||||
l->lastdam = strdup(buf + 9); // after 'lastdam: '
|
||||
|
||||
fscanf(f, "material: %d\n",&matid);
|
||||
l->material = findmaterial(matid);
|
||||
fscanf(f, "timespent: %d\n",&l->timespent);
|
||||
|
||||
fscanf(f, "sorted: %d\n",&l->sorted);
|
||||
|
@ -318,6 +322,8 @@ map_t *loadmap(char *basefile) {
|
|||
celltype_t *ct;
|
||||
int celltypeid;
|
||||
long obid;
|
||||
int temphab;
|
||||
int vid;
|
||||
|
||||
//if (db) dblog("cell %d,%d...",x,y);
|
||||
|
||||
|
@ -334,8 +340,14 @@ map_t *loadmap(char *basefile) {
|
|||
*/
|
||||
|
||||
// cell info
|
||||
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
&c->roomid, &celltypeid, &c->known, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer);
|
||||
fscanf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
&c->roomid, &celltypeid, &c->known, &c->knownglyph.ch, &c->knownglyph.colour, &c->visited, &c->lit, &c->origlit, &c->littimer,&temphab,&vid);
|
||||
c->habitat = findhabitat(temphab);
|
||||
if (vid == -1) {
|
||||
c->vault = NULL;
|
||||
} else {
|
||||
c->vault = findvaultbyid(vid);
|
||||
}
|
||||
|
||||
|
||||
ct = findcelltype(celltypeid);
|
||||
|
@ -655,6 +667,7 @@ int savelf(FILE *f, lifeform_t *l) {
|
|||
fprintf(f, "alive: %d\n",l->alive);
|
||||
fprintf(f, "lastdamtype: %d\n",l->lastdamtype);
|
||||
fprintf(f, "lastdam: %s\n",l->lastdam);
|
||||
fprintf(f, "material: %d\n",l->material->id);
|
||||
fprintf(f, "timespent: %d\n",l->timespent);
|
||||
fprintf(f, "sorted: %d\n",l->sorted);
|
||||
fprintf(f, "polyrevert: %d\n",l->polyrevert);
|
||||
|
@ -751,8 +764,8 @@ int savemap(map_t *m) {
|
|||
cell_t *c;
|
||||
c = getcellat(m, x, y);
|
||||
// cell info
|
||||
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
c->roomid, c->type->id, c->known, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer);
|
||||
fprintf(f, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
|
||||
c->roomid, c->type->id, c->known, c->knownglyph.ch, c->knownglyph.colour, c->visited,c->lit,c->origlit,c->littimer,c->habitat->id, c->vault ? c->vault->numid : -1);
|
||||
// cell objects
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
fprintf(f, "ob:%ld\n",o->id);
|
||||
|
|
212
spell.c
212
spell.c
|
@ -1093,6 +1093,16 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
gainlevel(user);
|
||||
}
|
||||
}
|
||||
} else if (abilid == OT_A_BLINDALL) {
|
||||
lifeform_t *lf;
|
||||
for (lf = user->cell->map->lf ; lf ; lf = lf->next) {
|
||||
if (!isplayer(lf)) {
|
||||
addflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL);
|
||||
killflagsofid(lf->flags, F_WANTS);
|
||||
killflagsofid(lf->flags, F_WANTSOBFLAG);
|
||||
}
|
||||
}
|
||||
msg("all blinded!");
|
||||
return B_FALSE;
|
||||
} else if (abilid == OT_A_DEBUG) {
|
||||
cell_t *where;
|
||||
|
@ -1159,6 +1169,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
char dirch;
|
||||
char targetname[BUFLEN];
|
||||
flag_t *f;
|
||||
int heavyamt = 8;
|
||||
|
||||
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
|
||||
if (isplayer(user)) msg("You lack the stability for a heavy blow while swimming.");
|
||||
|
@ -1166,8 +1177,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
wep = getweapon(user);
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < 8)) { // ie. 8 is weight of a mace
|
||||
if (isplayer(user)) msg("You need a heavy weapon to perform a heavy blow!");
|
||||
if (!wep || !ismeleeweapon(wep) || (getobunitweight(wep) < heavyamt)) { // ie. 8 is weight of a mace
|
||||
if (isplayer(user)) msg("You need a heavy weapon (%dkg or more) to perform a heavy blow!", heavyamt);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1207,6 +1218,60 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
flag_t *penalty = NULL;
|
||||
int failed = B_TRUE;
|
||||
|
||||
slev = getskill(user, SK_THIEVERY);
|
||||
if (slev == PR_INEPT) {
|
||||
if (isplayer(user)) msg("You are too unskilled to steal anything!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// stealing shop items
|
||||
if (isroom(user->cell) && hasobwithflagval(user->cell->obpile, F_SHOPITEM, NA, user->cell->roomid, NA, NULL)) {
|
||||
// stealing from a shop
|
||||
char yn;
|
||||
yn = askchar("Steal something from this shop?", "yn","n", B_TRUE);
|
||||
if (yn == 'y') {
|
||||
object_t *o;
|
||||
flag_t *f;
|
||||
int value;
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
value = 0;
|
||||
for (o = user->cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflagval(o->flags, F_SHOPITEM, NA, user->cell->roomid, NA, NULL);
|
||||
if (f) {
|
||||
value += f->val[0];
|
||||
}
|
||||
}
|
||||
// skillcheck - difficulty based on total value of objects here
|
||||
// 15 + value/50 means:
|
||||
// $50 is diff 16
|
||||
// $100 is diff 17
|
||||
// $200 is diff 19
|
||||
// $500 is diff 25
|
||||
// $1000 is diff 35
|
||||
if (skillcheck(user, SC_STEAL, 15+(value/50), 0)) {
|
||||
// success
|
||||
if (steal(user, user->cell->obpile, F_SHOPITEM)) {
|
||||
if (isplayer(user)) {
|
||||
msg("There doesn't seem to be anything here which you could steal.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lifeform_t *shk;
|
||||
msg("You try to steal something, but fail.");
|
||||
// failed
|
||||
shk = findshopkeeper(user->cell->map, user->cell->roomid);
|
||||
if (shk) { // doesn't need to see you - he SENSES it!
|
||||
say(shk, "THIEF!", SV_ROAR);
|
||||
fightback(shk, user);
|
||||
callguards(shk, user);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// stealing from a lifeform
|
||||
// ask for direction
|
||||
if (!targcell) {
|
||||
dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
||||
|
@ -1228,12 +1293,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
|
||||
taketime(user, getactspeed(user));
|
||||
|
||||
slev = getskill(user, SK_THIEVERY);
|
||||
if (slev == PR_INEPT) {
|
||||
if (isplayer(user)) msg("You are too unskilled to steal anything!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
getlfname(target, targetname);
|
||||
|
||||
if (slev == PR_NOVICE) {
|
||||
|
@ -1245,61 +1304,15 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// use empty handed attack accuracy
|
||||
wep = getweapon(user);
|
||||
if (rolltohit(user, target, wep, NULL)) {
|
||||
object_t *o;
|
||||
int i,nsteals;
|
||||
//
|
||||
if (slev >= PR_EXPERT) {
|
||||
nsteals = 2;
|
||||
} else {
|
||||
nsteals = 1;
|
||||
}
|
||||
// what do we steal?
|
||||
for (i = 0; i < nsteals; i++) {
|
||||
sprintf(buf, "Steal what (%d of %d)?", i+1, nsteals);
|
||||
initprompt(&prompt, buf);
|
||||
addchoice(&prompt, '-', "Nothing", NULL, NULL);
|
||||
for (o = target->pack->first ; o ; o = o->next) {
|
||||
int ok = B_TRUE;
|
||||
if ((slev < PR_SKILLED) && (getobunitweight(o) >= 3)) {
|
||||
// too heavy to steal
|
||||
ok = B_FALSE;
|
||||
} else if ((slev < PR_MASTER) && isequipped(o)) {
|
||||
// equipped
|
||||
ok = B_FALSE;
|
||||
} else if (!canpickup(user, o, 1)) {
|
||||
// can't pick it up
|
||||
ok = B_FALSE;
|
||||
}
|
||||
if (ok) {
|
||||
getobname(o, buf, 1);
|
||||
addchoice(&prompt, o->letter, buf, NULL, o);
|
||||
}
|
||||
}
|
||||
if (prompt.nchoices > 1) {
|
||||
if (slev >= PR_ADEPT) {
|
||||
// pick what you want
|
||||
getchoice(&prompt);
|
||||
o = (object_t *)prompt.result;
|
||||
} else {
|
||||
// random
|
||||
o = (object_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data;
|
||||
}
|
||||
if (o) {
|
||||
o = moveob(o, user->pack, 1);
|
||||
if (o) {
|
||||
getobname(o, buf, 1);
|
||||
if (isplayer(user)) {
|
||||
msg("You steal %s from %s!", buf, targetname);
|
||||
} else if (cansee(player, user)) {
|
||||
msg("%s steals %s from %s!", username, buf, targetname);
|
||||
}
|
||||
// success!
|
||||
failed = B_FALSE;
|
||||
if (steal(user, target->pack, F_NONE)) {
|
||||
if (isplayer(user)) {
|
||||
msg("%s has nothing for you to steal!", targetname);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
||||
if (penalty) {
|
||||
|
@ -1312,9 +1325,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else if (cansee(player, user)) {
|
||||
msg("%s tries to steal from %s, but fails.", username, targetname);
|
||||
}
|
||||
// ai will get angry!
|
||||
if (cansee(target, user) && !isplayer(target)) {
|
||||
fightback(target, user);
|
||||
}
|
||||
} else {
|
||||
practice(user, SK_THIEVERY, 1);
|
||||
}
|
||||
}
|
||||
} else if (abilid == OT_A_WARCRY) {
|
||||
// announce
|
||||
if (isplayer(user)) {
|
||||
|
@ -1749,8 +1767,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_MAGICARMOUR, power*2, NA, NA, "skin of bark", FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
//f = addtempflag(caster->flags, F_MAGICARMOUR, power*2, NA, NA, "skin of bark", FROMSPELL);
|
||||
//f->obfrom = spellid;
|
||||
|
||||
setlfmaterial(target, MT_WOOD);
|
||||
f = addtempflag(caster->flags, F_DTVULN, DT_FIRE, NA, NA, "2d4", FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_BLADEBURN) {
|
||||
|
@ -2473,7 +2493,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else {
|
||||
// random one
|
||||
r = getreallyrandomrace();
|
||||
r = getreallyrandomrace(RC_ANY);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2497,16 +2517,50 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_CLEARLEVEL) {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
for (y = 0; y < caster->cell->map->h ; y++) {
|
||||
for (x = 0; x < caster->cell->map->w ; x++) {
|
||||
c = getcellat(caster->cell->map, x, y);
|
||||
if (c) {
|
||||
if (c->lf && isplayer(c->lf)) {
|
||||
} else {
|
||||
clearcell(c);
|
||||
setcelltype(c, c->map->habitat->solidcelltype);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
needredraw = B_TRUE;
|
||||
} else if (spellid == OT_S_CREATEVAULT) {
|
||||
vault_t *v;
|
||||
int vx,vy;
|
||||
int vw,vh;
|
||||
// ask for a vaulttype
|
||||
v = askvault("Create which vault?");
|
||||
|
||||
if (createvault(caster->cell->map, caster->cell->map->nrooms, v, NULL, NULL)) {
|
||||
if (createvault(caster->cell->map, caster->cell->map->nrooms, v, &vw, &vh, &vx, &vy)) {
|
||||
msg("Couldn't create a vault.");
|
||||
} else {
|
||||
msg("BAM! A vault has appeared nearby.");
|
||||
char ch;
|
||||
msg("BAM! A vault has appeared nearby."); more();
|
||||
needredraw = B_TRUE;
|
||||
ch = askchar("Teleport to the new vault", "yn","y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
// find it
|
||||
for (y = vy; y < vy+vh; y++) {
|
||||
for (x = vy; x < vx + vw; x++) {
|
||||
c = getcellat(caster->cell->map, x, y);
|
||||
if (c && cellwalkable(caster, c, NULL)) {
|
||||
teleportto(caster, c, B_TRUE);
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (spellid == OT_S_CUREPOISON) {
|
||||
|
@ -2653,6 +2707,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
ndigs++;
|
||||
// go to next cell
|
||||
c = getcellindir(c, dir);
|
||||
}
|
||||
|
||||
// announce destruction of any walls seen
|
||||
|
@ -2963,12 +3019,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
targcell = getcellat(caster->cell->map, x,y);
|
||||
if (targcell && (getcelldist(caster->cell, targcell) <= range)) {
|
||||
if (targcell->lf && (targcell->lf != caster) && haslof(caster->cell, targcell, B_FALSE, NULL)) {
|
||||
char lfname[BUFLEN];
|
||||
// automatic hit
|
||||
getlfname(targcell->lf, lfname);
|
||||
if (isplayer(targcell->lf)) {
|
||||
msg("A blast of energy hits you!");
|
||||
}
|
||||
/*
|
||||
if (haslos(caster, targcell)) {
|
||||
msg("A blast of energy hits %s.",lfname);
|
||||
}
|
||||
*/
|
||||
losehp(targcell->lf, rnd(2,6), DT_MAGIC, caster, "an energy blast");
|
||||
}
|
||||
}
|
||||
|
@ -3085,8 +3144,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int depth;
|
||||
depth = DP_SHOULDERS + power;
|
||||
|
||||
amt = ((power+1) * (power+1)) - 1;
|
||||
//amt = ((power+1) * (power+1)) - 1;
|
||||
//amt = power;
|
||||
amt = power*2;
|
||||
badoid[0] = OT_WATERDEEP;
|
||||
badoid[1] = OT_NONE;
|
||||
for (i = 0; i < amt; i++) {
|
||||
|
@ -4021,9 +4081,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
c = getcellat(m, x, y);
|
||||
if (c) {
|
||||
if (range == UNLIMITED) {
|
||||
setcellknown(c, PR_ADEPT);
|
||||
setcellknown(c, MAXOF(PR_ADEPT, getskill(caster, SK_CARTOGRAPHY)));
|
||||
} else if (getcelldist(caster->cell, c) <= range) {
|
||||
setcellknown(c, PR_ADEPT);
|
||||
setcellknown(c, MAXOF(PR_ADEPT, getskill(caster, SK_CARTOGRAPHY)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4131,6 +4191,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// restore player pointer
|
||||
player = oldplayer;
|
||||
//showlfstats(where->lf, B_TRUE);
|
||||
|
||||
needredraw = B_TRUE;
|
||||
statdirty = B_TRUE;
|
||||
} else {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
@ -4580,7 +4643,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!newmap) {
|
||||
// create new map
|
||||
newmap = addmap();
|
||||
createmap(newmap, newdepth, caster->cell->map->region, NULL, D_NONE);
|
||||
createmap(newmap, newdepth, caster->cell->map->region, NULL, D_NONE, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6945,7 +7008,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
|||
default:
|
||||
if (spellskill == PR_INEPT) {
|
||||
if (db) {
|
||||
dblog("-->power = 0 (inept in SORCERY)");
|
||||
dblog("-->power = 0 (inept in sorcery)");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -7096,9 +7159,6 @@ char *getvarpowerspelldesc(enum OBTYPE spellid, int power, char *buf) {
|
|||
// default
|
||||
strcpy(buf, "");
|
||||
switch (spellid) {
|
||||
case OT_S_BARKSKIN:
|
||||
sprintf(buf, "+%d Armour Rating, Fire Vulnerability", power*2);
|
||||
break;
|
||||
case OT_S_PSYARMOUR:
|
||||
sprintf(buf, "+%d Armour Rating", power*4);
|
||||
break;
|
||||
|
@ -7281,7 +7341,9 @@ void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
|||
killob(o);
|
||||
}
|
||||
}
|
||||
if (spellid == OT_S_FLOATINGDISC) {
|
||||
if ((spellid == OT_S_BARKSKIN) && (getlfmaterial(caster) == MT_WOOD)) {
|
||||
setlfmaterial(caster, caster->race->material->id);
|
||||
} else if (spellid == OT_S_FLOATINGDISC) {
|
||||
map_t *m;
|
||||
lifeform_t *lf;
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
@id:crosshatch
|
||||
@map
|
||||
###########
|
||||
##.#.#.#.##
|
||||
#.#.#.#.#.#
|
||||
##.#.#.#.##
|
||||
#.#.#.#.#.#
|
||||
##.#.#.#.##
|
||||
#.#.#.#.#.#
|
||||
##.#.#.#.##
|
||||
#.#.#.#.#.#
|
||||
##.#.#.#.##
|
||||
###########
|
||||
@end
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
@end
|
||||
|
||||
@flags
|
||||
! autoscale, lock xy
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
@end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
@id:diagonal_cross
|
||||
@map
|
||||
#X.#####.X#
|
||||
##..###..##
|
||||
###..#..###
|
||||
####...####
|
||||
####...####
|
||||
####.#.####
|
||||
###.###.###
|
||||
##..###..##
|
||||
#X.#####.X#
|
||||
@end
|
||||
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
X:exit
|
||||
@end
|
||||
|
||||
@flags
|
||||
! autoscale, lock xy
|
||||
goesin:dungeon
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
! Boss room for Jimbo the dungeonkeeper
|
||||
@id:jimbos_lair
|
||||
|
||||
@map
|
||||
############
|
||||
#........|,#
|
||||
#....-/-.###
|
||||
+......@.|,#
|
||||
#..-/-...###
|
||||
#........|,#
|
||||
############
|
||||
@end
|
||||
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
|:ob:locked iron gate
|
||||
,:ob:1-4 bones:50
|
||||
+:ob:wooden door
|
||||
/:ob:wooden table
|
||||
-:ob:wooden footstool
|
||||
@:mon:Jimbo
|
||||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
norandom
|
||||
scatter(1,1,-2,-2) ob:wooden footstool:0-3
|
||||
scatter(1,1,-2,-2) ob:random food:0-2
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -36,7 +36,7 @@ scatter(0,0,-1,-1) ob:gnoll corpse:1-3:33
|
|||
! scattered weapons
|
||||
scatter(0,0,-1,-1) ob:common weapon:4-5
|
||||
! TODO: scattered minions around ??
|
||||
! mayrotate
|
||||
mayrotate
|
||||
! mayscale
|
||||
@end
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
! a room split in half by a river
|
||||
@id:river_room
|
||||
@map
|
||||
##########
|
||||
#...~~...#
|
||||
#...~~...#
|
||||
#...~~...#
|
||||
#...~~...#
|
||||
#...~~...#
|
||||
##########
|
||||
@end
|
||||
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
~:cell:low rock floor
|
||||
~:ob:very deep water
|
||||
@end
|
||||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
@id:armour_shop
|
||||
@map
|
||||
.#####
|
||||
.#ppp#
|
||||
s+ppp#
|
||||
.#ppp#
|
||||
.#####
|
||||
@end
|
||||
|
||||
@legend
|
||||
.:cell:dirt
|
||||
#:cell:wooden wall
|
||||
p:cell:shop floor
|
||||
p:ob:armour
|
||||
+:cell:dirt
|
||||
+:ob:wooden door
|
||||
s:ob:sign "Armour shop"
|
||||
@end
|
||||
|
||||
@flags
|
||||
shop
|
||||
! because this is the first lf in a shop, it will
|
||||
! become the shopkeeper.
|
||||
scatter(2,1,-2,-2) mon:humanoid:1
|
||||
norandom
|
||||
mayrotate
|
||||
margin:5,5
|
||||
@end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
@id:potion_shop
|
||||
@map
|
||||
.#####
|
||||
.#ppp#
|
||||
s+ppp#
|
||||
.#ppp#
|
||||
.#####
|
||||
@end
|
||||
|
||||
@legend
|
||||
.:cell:dirt
|
||||
#:cell:wooden wall
|
||||
p:cell:shop floor
|
||||
p:ob:potion
|
||||
+:cell:dirt
|
||||
+:ob:wooden door
|
||||
s:ob:sign "Potion shop"
|
||||
@end
|
||||
|
||||
@flags
|
||||
shop
|
||||
! because this is the first lf in a shop, it will
|
||||
! become the shopkeeper.
|
||||
scatter(2,1,-2,-2) mon:humanoid:1
|
||||
norandom
|
||||
mayrotate
|
||||
margin:5,5
|
||||
@end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
@id:weapon_shop
|
||||
@map
|
||||
.#####
|
||||
.#ppp#
|
||||
s+ppp#
|
||||
.#ppp#
|
||||
.#####
|
||||
@end
|
||||
|
||||
@legend
|
||||
.:cell:dirt
|
||||
#:cell:wooden wall
|
||||
p:cell:shop floor
|
||||
p:ob:weapon
|
||||
+:cell:dirt
|
||||
+:ob:wooden door
|
||||
s:ob:sign "Weapon shop"
|
||||
@end
|
||||
|
||||
@flags
|
||||
shop
|
||||
! because this is the first lf in a shop, it will
|
||||
! become the shopkeeper.
|
||||
scatter(2,1,-2,-2) mon:humanoid:1
|
||||
norandom
|
||||
mayrotate
|
||||
margin:5,5
|
||||
@end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
@id:uturn
|
||||
@map
|
||||
###########
|
||||
###.....###
|
||||
##..###..##
|
||||
#X.#####.X#
|
||||
@end
|
||||
|
||||
@legend
|
||||
#:cell:rock wall
|
||||
X:exit
|
||||
@end
|
||||
|
||||
@flags
|
||||
! autoscale
|
||||
goesin:dungeon
|
||||
mayrotate
|
||||
@end
|
||||
|
|
@ -16,6 +16,7 @@ $:ob:25-200 gold
|
|||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
mayrotate
|
||||
! no auto doors. ie this can be in the middle of nowhere.
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in New Issue