12152 lines
400 KiB
C
12152 lines
400 KiB
C
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "attack.h"
|
|
#include "defs.h"
|
|
#include "flag.h"
|
|
#include "io.h"
|
|
#include "lf.h"
|
|
#include "map.h"
|
|
#include "move.h"
|
|
#include "nexus.h"
|
|
#include "objects.h"
|
|
#include "spell.h"
|
|
#include "text.h"
|
|
|
|
extern knowledge_t *knowledge, *lastknowledge;
|
|
extern hiddenname_t *firsthiddenname, *lasthiddenname;
|
|
extern objecttype_t *objecttype,*lastobjecttype;
|
|
extern objectclass_t *objectclass,*lastobjectclass;
|
|
extern brand_t *firstbrand,*lastbrand;
|
|
extern obmod_t *firstobmod,*lastobmod;
|
|
extern material_t *material,*lastmaterial;
|
|
extern skill_t *firstskill, *lastskill;
|
|
|
|
extern object_t *retobs[MAXPILEOBS+1];
|
|
extern int retobscount[MAXPILEOBS+1];
|
|
extern int nretobs;
|
|
|
|
extern glyph_t tempglyph;
|
|
|
|
extern map_t *firstmap;
|
|
|
|
extern enum GAMEMODE gamemode;
|
|
|
|
extern long curtime;
|
|
|
|
extern lifeform_t *player;
|
|
|
|
extern int reason;
|
|
|
|
extern int needredraw;
|
|
extern int statdirty;
|
|
|
|
|
|
char letorder[MAXPILEOBS] = {
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
|
|
};
|
|
|
|
objecttype_t *lastot = NULL;
|
|
|
|
enum OBCLASS sortorder[] = {
|
|
OC_EFFECT,
|
|
OC_MONEY,
|
|
OC_WEAPON,
|
|
OC_MISSILE,
|
|
OC_ARMOUR,
|
|
OC_POTION,
|
|
OC_SCROLL,
|
|
OC_WAND,
|
|
OC_FOOD,
|
|
OC_CORPSE,
|
|
OC_RING,
|
|
OC_TECH,
|
|
OC_TOOLS,
|
|
OC_BOOK,
|
|
OC_ROCK,
|
|
OC_DFEATURE,
|
|
OC_MISC,
|
|
// omitting OC_SPELL and OC_JUMP because it shouldn't ever be displayed
|
|
OC_NULL
|
|
};
|
|
|
|
|
|
|
|
char *techadjective[] = {
|
|
"crazy",
|
|
"mysterious",
|
|
"odd",
|
|
"strange",
|
|
"weird",
|
|
"",
|
|
};
|
|
char *technoun[] = {
|
|
"contraption",
|
|
"device",
|
|
"doodad",
|
|
"doohickey",
|
|
"gadget",
|
|
"thing",
|
|
"object",
|
|
"",
|
|
};
|
|
|
|
|
|
char *bookadjective[] = {
|
|
"ancient",
|
|
"clean",
|
|
"creepy",
|
|
"damp",
|
|
"dog-eared",
|
|
"dusty",
|
|
"eerie",
|
|
"fancy",
|
|
"frosty",
|
|
"furry",
|
|
"glowing",
|
|
"hot",
|
|
"humming",
|
|
"icy",
|
|
"jiggling",
|
|
"leatherbound",
|
|
"luminous",
|
|
"mouldy",
|
|
"papyrus",
|
|
"plain",
|
|
"quivering",
|
|
"muddy",
|
|
"slimy",
|
|
"small",
|
|
"soggy",
|
|
"thin",
|
|
"thick",
|
|
"tiny",
|
|
"vibrating",
|
|
"vine-covered",
|
|
"warm",
|
|
"worn",
|
|
"wrinkled",
|
|
"",
|
|
};
|
|
|
|
char *potadjective[] = {
|
|
"bubbling",
|
|
"effervescent",
|
|
"fizzy",
|
|
"fuming",
|
|
"gluggy",
|
|
"luminous", // should produce light
|
|
"steaming",
|
|
"",
|
|
};
|
|
|
|
typedef struct hiddennamewithcol_s {
|
|
char *name;
|
|
enum COLOUR col;
|
|
} hiddennamewithcol_t;
|
|
|
|
hiddennamewithcol_t colour[] = {
|
|
{ "aqua", C_CYAN, },
|
|
{ "azure",C_BOLDBLUE },
|
|
{ "black",C_BLUE },
|
|
{ "blue",C_BLUE },
|
|
{ "brown",C_BROWN },
|
|
{ "cyan",C_CYAN },
|
|
{ "green",C_GREEN },
|
|
{ "indigo",C_MAGENTA },
|
|
{ "magenta",C_BOLDMAGENTA },
|
|
{ "night-black",C_BLUE },
|
|
{ "orange",C_ORANGE },
|
|
{ "pink",C_MAGENTA },
|
|
{ "rainbow-coloured",C_ORANGE },
|
|
{ "red",C_RED },
|
|
{ "violet",C_MAGENTA },
|
|
{ "yellow",C_YELLOW },
|
|
{ "",C_GREY },
|
|
};
|
|
|
|
hiddennamewithcol_t gemtype[] = {
|
|
{ "agate", C_MAGENTA, },
|
|
{ "amethyst", C_MAGENTA, }, // should be purple
|
|
{ "brass",C_BROWN },
|
|
{ "bronze",C_BROWN },
|
|
{ "copper",C_BROWN },
|
|
{ "diamond",C_BOLDCYAN },
|
|
{ "emerald",C_GREEN },
|
|
{ "flourite",C_GREY },
|
|
{ "garnet",C_ORANGE },
|
|
{ "gold",C_YELLOW },
|
|
{ "iridium",C_WHITE },
|
|
{ "jade",C_GREEN },
|
|
{ "lapis lazuli",C_BOLDBLUE },
|
|
{ "malachite",C_BOLDCYAN },
|
|
{ "onyx",C_BLUE },
|
|
{ "opal",C_CYAN },
|
|
{ "pearl",C_WHITE },
|
|
{ "quartz",C_GREY },
|
|
{ "ruby",C_RED },
|
|
{ "sapphire",C_BLUE },
|
|
{ "zinc",C_GREY },
|
|
{ "",C_GREY },
|
|
};
|
|
|
|
|
|
long nextoid = 0;
|
|
|
|
brand_t *addbrand(enum BRAND id, char *suffix, enum BODYPART bp) {
|
|
brand_t *a, *om;
|
|
char buf[BUFLEN];
|
|
//flag_t *f;
|
|
|
|
// does this modj already exist?
|
|
om = findbrand(id);
|
|
assert(!om);
|
|
|
|
// add to the end of the list
|
|
if (firstbrand == NULL) {
|
|
firstbrand = malloc(sizeof(brand_t));
|
|
a = firstbrand;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastbrand;
|
|
a->next = malloc(sizeof(brand_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastbrand = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
a->bp = bp;
|
|
sprintf(buf, " %s",suffix);
|
|
a->suffix = strdup(buf);
|
|
|
|
a->flags = addflagpile(NULL, NULL);
|
|
|
|
return a;
|
|
}
|
|
|
|
|
|
object_t *addemptyob(obpile_t *where, object_t *o) {
|
|
char buf[BUFLEN];
|
|
object_t *empty;
|
|
// determine what kind of empty container to drop
|
|
if (strstr(o->type->name, "vial")) {
|
|
strcpy(buf, "empty vial");
|
|
} else {
|
|
strcpy(buf, "empty flask");
|
|
}
|
|
|
|
empty = addob(where, buf);
|
|
if (!empty) {
|
|
// try to drop on ground
|
|
if (where->owner) {
|
|
empty = addob(where->owner->cell->obpile, buf);
|
|
if (empty) {
|
|
char emptyname[BUFLEN];
|
|
getobname(empty, emptyname, 1);
|
|
if (isplayer(where->owner)) {
|
|
msg("You drop the %s on the ground.", noprefix(emptyname));
|
|
} else if (cansee(player, where->owner)) {
|
|
getlfname(where->owner, buf);
|
|
capitalise(buf);
|
|
msg("%s drops the %s on the ground.", buf, noprefix(emptyname));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return empty;
|
|
}
|
|
|
|
hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text) {
|
|
hiddenname_t *a;
|
|
|
|
// add to the end of the list
|
|
if (firsthiddenname == NULL) {
|
|
firsthiddenname = malloc(sizeof(hiddenname_t));
|
|
a = firsthiddenname;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lasthiddenname;
|
|
a->next = malloc(sizeof(hiddenname_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lasthiddenname = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->obclass = obclass;
|
|
a->text = strdup(text);
|
|
a->used = B_FALSE;
|
|
|
|
return a;
|
|
}
|
|
|
|
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known) {
|
|
knowledge_t *a;
|
|
|
|
// add to the end of the list
|
|
if (knowledge == NULL) {
|
|
knowledge = malloc(sizeof(knowledge_t));
|
|
a = knowledge;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastknowledge;
|
|
a->next = malloc(sizeof(knowledge_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastknowledge = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
a->hiddenname = strdup(hiddenname);
|
|
a->known = known;
|
|
|
|
return a;
|
|
}
|
|
|
|
|
|
|
|
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating) {
|
|
material_t *a;
|
|
|
|
// add to the end of the list
|
|
if (material == NULL) {
|
|
material = malloc(sizeof(material_t));
|
|
a = material;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastmaterial;
|
|
a->next = malloc(sizeof(material_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastmaterial = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
a->name = strdup(name);
|
|
a->weightrating = weightrating;
|
|
|
|
a->flags = addflagpile(NULL, NULL);
|
|
return a;
|
|
}
|
|
|
|
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour) {
|
|
objectclass_t *a;
|
|
|
|
// add to the end of the list
|
|
if (objectclass == NULL) {
|
|
objectclass = malloc(sizeof(objectclass_t));
|
|
a = objectclass;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastobjectclass;
|
|
a->next = malloc(sizeof(objectclass_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastobjectclass = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
a->name = strdup(name);
|
|
a->desc = strdup(desc);
|
|
a->glyph.ch = glyph;
|
|
a->glyph.colour = glyphcolour;
|
|
a->flags = addflagpile(NULL, NULL);
|
|
|
|
return a;
|
|
}
|
|
|
|
|
|
|
|
// create a new object, stacking ok
|
|
object_t *addob(obpile_t *where, char *name) {
|
|
return addobject(where, name, B_TRUE);
|
|
}
|
|
|
|
// create a new object
|
|
// if canstack is true, we are allwoed
|
|
// to join similar objects together instead of
|
|
// creating new obejct entries.
|
|
object_t *addobject(obpile_t *where, char *name, int canstack) {
|
|
objecttype_t *ot;
|
|
object_t *o = NULL;
|
|
char *p,*nsp,*p2;
|
|
char numstringmin[BUFLEN];
|
|
char numstringmax[BUFLEN];
|
|
int howmany = 1;
|
|
int i;
|
|
int db = B_FALSE;
|
|
flag_t *f;
|
|
char *localname;
|
|
int wantblessed = B_UNCURSED;
|
|
race_t *corpserace = NULL;
|
|
brand_t *br;
|
|
obmod_t *om;
|
|
obmod_t *wantom[MAXOBMODS];
|
|
int nom = 0;
|
|
int n;
|
|
|
|
|
|
localname = strdup(name);
|
|
|
|
|
|
// check for premods. eg. "flaming xxx" "frozen xxx" etc
|
|
for (om = firstobmod ; om ; om = om->next) {
|
|
if (db) dblog("DB: checking for '%s' in '%s'",om->prefix, localname);
|
|
if (strstr(localname, om->prefix)) {
|
|
localname = strrep(localname, om->prefix, "", NULL);
|
|
if (db) dblog("DB: found obmod prefix '%s'",om->prefix);
|
|
|
|
wantom[nom] = om;
|
|
nom++;
|
|
}
|
|
}
|
|
|
|
if (db) {
|
|
dblog("DB: called addobject() for %s, canstack = %d",localname, canstack);
|
|
}
|
|
|
|
if (where->owner && hasflag(where->owner->flags, F_NOPACK)) {
|
|
if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name);
|
|
return NULL;
|
|
}
|
|
|
|
// we CAN place objects in solid cells - for example,
|
|
// placing a fire on top of a wooden door.
|
|
/*
|
|
if (where->where) {
|
|
if (where->where->type != (celltype_t *)DUMMYCELLTYPE) {
|
|
assert(!where->where->type->solid);
|
|
}
|
|
}
|
|
*/
|
|
|
|
// parse name string
|
|
nsp = numstringmin;
|
|
for (p = localname ; isdigit(*p) ; p++) {
|
|
*nsp = *p;
|
|
nsp++;
|
|
}
|
|
*nsp = '\0';
|
|
|
|
// we have a range...
|
|
if (*p == '-') {
|
|
nsp = numstringmax;
|
|
p++;
|
|
for ( ; isdigit(*p) ; p++) {
|
|
*nsp = *p;
|
|
nsp++;
|
|
}
|
|
*nsp = '\0';
|
|
} else {
|
|
strcpy(numstringmax,numstringmin);
|
|
}
|
|
|
|
|
|
// are we giving multiple objects?
|
|
if (strlen(numstringmin) > 0) {
|
|
int min,max;
|
|
// first increment name string pointer
|
|
// past any spaces
|
|
while (!isalpha(*p)) p++;
|
|
|
|
// now figure out how many
|
|
min = atoi(numstringmin);
|
|
max = atoi(numstringmax);
|
|
if (min == max) {
|
|
howmany = min;
|
|
} else {
|
|
howmany = rnd(min,max);
|
|
}
|
|
} else {
|
|
howmany = 1;
|
|
}
|
|
|
|
// new objects after the game starts have unknown
|
|
// blessed/cursed status, so we can never stack them
|
|
// if (gamestarted && !hasflag(player->flags, F_DETECTAURAS)) {
|
|
if (strstr(p, "blessed") || strstr(p, "holy water")) {
|
|
if (db) dblog("DB: ob is blessed (%s)",p);
|
|
wantblessed = B_BLESSED;
|
|
//canstack = B_FALSE;
|
|
} else if (strstr(p, "uncursed")) {
|
|
if (db) dblog("DB: ob is uncursed (%s)",p);
|
|
wantblessed = B_UNCURSED;
|
|
} else if (strstr(p, "cursed") || strstr(p, "incompetence")) {
|
|
if (db) dblog("DB: ob is cursed (%s)",p);
|
|
wantblessed = B_CURSED;
|
|
//canstack = B_FALSE;
|
|
}
|
|
// }
|
|
|
|
if (strstr(p, "corpse")) {
|
|
int len;
|
|
char racename[BUFLEN];
|
|
p2 = strstr(p, "corpse");
|
|
len = p2 - p;
|
|
snprintf(racename, len, "%s",p);
|
|
|
|
corpserace = findracebyname(racename);
|
|
ot = findot(OT_CORPSE);
|
|
} else if (strstr(p, "statue of ")) {
|
|
char racename[BUFLEN];
|
|
|
|
// go to end
|
|
p2 = strstr(p, "statue of ");
|
|
p2 += 10; // now on either 'a' or 'an'
|
|
p2++; // now on either ' ' or 'n'
|
|
for (;*p2 != ' ';p2++);
|
|
p2++;
|
|
// now at start of name
|
|
sprintf(racename, "%s",p2);
|
|
|
|
corpserace = findracebyname(racename);
|
|
ot = findot(OT_STATUE);
|
|
} else if (strstr(p, " head")) {
|
|
int len;
|
|
char racename[BUFLEN];
|
|
p2 = strstr(p, " head");
|
|
len = p2 - p + 1;
|
|
snprintf(racename, len, "%s",p);
|
|
|
|
corpserace = findracebyname(racename);
|
|
ot = findot(OT_HEAD);
|
|
} else {
|
|
// make sure we can find the requested object type
|
|
if (db) dblog("DB: Looking for object name '%s'", p );
|
|
ot = findotn(p);
|
|
if (!ot) {
|
|
//if (gamestarted) msg("DB: No match for object name '%s'", p );
|
|
if (db) dblog("DB: No match for object name '%s'", p );
|
|
return NULL;
|
|
}
|
|
}
|
|
if (db) dblog("DB: FOUND: ot->name = '%s'", ot->name );
|
|
|
|
// override blessed status from flags...
|
|
f = hasflag(ot->flags, F_STARTBLESSED);
|
|
if (f) {
|
|
wantblessed = f->val[0];
|
|
}
|
|
|
|
// don't give nopickup objects to lifeforms
|
|
if (hasflag(ot->flags, F_NOPICKUP) && where->owner) {
|
|
return NULL;
|
|
}
|
|
|
|
if (ot->obclass->id == OC_SPELL) {
|
|
if (db) dblog("DB: Cannot give a spell object! object name '%s'", p );
|
|
return NULL;
|
|
}
|
|
|
|
// override canstack if required
|
|
if (!hasflag(ot->flags, F_STACKABLE)) {
|
|
if (db) dblog("DB: setting canstack = false, objecttype '%s' not stackable", ot->name );
|
|
canstack = B_FALSE;
|
|
}
|
|
|
|
|
|
// special checks for unique objects
|
|
if (hasflag(ot->flags, F_UNIQUE)) {
|
|
// does this unique ob already exist?
|
|
if (obexists(ot->id)) {
|
|
if (db) dblog("DB: Unique ob %s already exists!", p );
|
|
return NULL;
|
|
}
|
|
|
|
// otherwise make sure we are only getting one
|
|
howmany = 1;
|
|
}
|
|
|
|
if (db) dblog("DB: '%s' -> adding %d x %s",name, howmany, ot->name);
|
|
|
|
for (i = 0; i < howmany; i++) {
|
|
int added = B_FALSE;
|
|
if (canstack) {
|
|
object_t *existob;
|
|
if (db) dblog("DB: Looking for stacks...");
|
|
// TODO: if object is stackable
|
|
// TODO: if (hasflag(ob,stackable) && hasobject(where, ot)) {
|
|
// does the pile already contain one?
|
|
existob = canstacknewot(where, ot);
|
|
if (existob) {
|
|
if (db) dblog("DB: STACK FOUND (%d x %s). Adding %d obs to existing stack.",existob->amt, existob->type->name, howmany);
|
|
existob->amt++;
|
|
added = B_TRUE;
|
|
o = existob;
|
|
} else {
|
|
if (db) dblog("DB: No stacks found.");
|
|
}
|
|
}
|
|
|
|
if (!added) {
|
|
flag_t *f;
|
|
if (db) dblog("DB: Creating new object (%s).",ot->name);
|
|
|
|
// otherwise add to list
|
|
if (where->first == NULL) {
|
|
where->first = malloc(sizeof(object_t));
|
|
o = where->first;
|
|
o->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
o = where->last;
|
|
o->next = malloc(sizeof(object_t));
|
|
o->next->prev = o;
|
|
o = o->next;
|
|
}
|
|
where->last = o;
|
|
|
|
o->next = NULL;
|
|
|
|
// fill in props
|
|
o->id = nextoid++; // increment next ob id
|
|
o->type = ot;
|
|
o->pile = where;
|
|
|
|
o->birthtime = curtime;
|
|
|
|
// inherit props from objecttype
|
|
o->material = ot->material;
|
|
assert(o->material);
|
|
o->weight = ot->weight;
|
|
o->flags = addflagpile(NULL, o);
|
|
|
|
o->inscription = NULL; // non-inherited
|
|
|
|
// inherit flags from objecttype
|
|
copyflags(o->flags, ot->flags, NA);
|
|
|
|
// random flags...
|
|
f = hasflag(o->flags, F_RNDCHARGES);
|
|
if (f) {
|
|
int amt;
|
|
flag_t *chargeflag;
|
|
amt = rnd(f->val[0], f->val[1]);
|
|
chargeflag = hasflag(o->flags, F_CHARGES);
|
|
if (chargeflag) {
|
|
chargeflag->val[0] = amt;
|
|
chargeflag->val[1] = amt;
|
|
chargeflag->known = B_FALSE;
|
|
} else {
|
|
chargeflag = addflag_real(o->flags, F_CHARGES, amt, amt, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
}
|
|
}
|
|
|
|
// charge flag always starts unknown.
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f) {
|
|
f->known = B_FALSE;
|
|
}
|
|
|
|
|
|
|
|
// non-inherited from here on:
|
|
// if adding to a player...
|
|
if (where->owner) {
|
|
if (o->type->obclass->id == OC_MONEY) {
|
|
o->letter = '$';
|
|
} else {
|
|
o->letter = getnextletter(where, NULL);
|
|
}
|
|
} else {
|
|
// new object on the ground - has no letter yet.
|
|
o->letter = '\0';
|
|
}
|
|
|
|
if (canstack) {
|
|
// add the full amount!
|
|
o->amt = howmany;
|
|
} else {
|
|
o->amt = 1;
|
|
}
|
|
|
|
|
|
if (hasflag(o->flags, F_NOBLESS)) {
|
|
setblessed(o, B_UNCURSED);
|
|
} else {
|
|
setblessed(o, wantblessed);
|
|
}
|
|
o->blessknown = B_FALSE;
|
|
if (canstack) {
|
|
// stop looping through
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// other special changes we need to make based on what was
|
|
// asked for
|
|
if ((gamemode != GM_LOADING) && o) {
|
|
char *p2;
|
|
int bonus = 0;
|
|
|
|
// corpses - fill in details
|
|
if (o->type->id == OT_CORPSE) {
|
|
flag_t *rf, *cf;
|
|
|
|
assert(corpserace);
|
|
|
|
o->weight = corpserace->weight;
|
|
o->material = corpserace->material;
|
|
|
|
// remember the race type
|
|
addflag(o->flags, F_CORPSEOF, corpserace->id, NA, NA, NULL);
|
|
|
|
// override ot_corpse nutrition flag based on race's size
|
|
rf = hasflag(corpserace->flags, F_SIZE);
|
|
if (rf) {
|
|
cf = hasflag(o->flags, F_EDIBLE);
|
|
if (cf) {
|
|
switch (rf->val[0]) {
|
|
case SZ_MINI:
|
|
cf->val[1] = 1;
|
|
break;
|
|
case SZ_TINY:
|
|
cf->val[1] = 10;
|
|
break;
|
|
case SZ_SMALL:
|
|
cf->val[1] = 25;
|
|
break;
|
|
case SZ_MEDIUM:
|
|
cf->val[1] = 75;
|
|
break;
|
|
case SZ_HUMAN:
|
|
cf->val[1] = 120;
|
|
break;
|
|
case SZ_LARGE:
|
|
cf->val[1] = 150;
|
|
break;
|
|
case SZ_HUGE:
|
|
cf->val[1] = 200;
|
|
break;
|
|
case SZ_ENORMOUS:
|
|
cf->val[1] = 250;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else if (o->type->id == OT_STATUE) {
|
|
flag_t *f, *rf;
|
|
float ratio;
|
|
|
|
if (!corpserace) {
|
|
cell_t *where;
|
|
where = getoblocation(o);
|
|
// select random race
|
|
if (where) {
|
|
corpserace = getrandomrace(where->map, 0);
|
|
} else {
|
|
// ie. vending machine
|
|
corpserace = getrandomrace(NULL, 0);
|
|
}
|
|
}
|
|
|
|
ratio = o->material->weightrating / corpserace->material->weightrating;
|
|
|
|
o->weight = corpserace->weight * ratio;
|
|
|
|
// remember the race type
|
|
addflag(o->flags, F_CORPSEOF, corpserace->id, NA, NA, NULL);
|
|
|
|
// set impassable size
|
|
f = hasflag(o->flags, F_IMPASSABLE);
|
|
if (f) {
|
|
rf = hasflag(corpserace->flags, F_SIZE);
|
|
if (rf) {
|
|
f->val[0] = rf->val[0];
|
|
} else {
|
|
killflag(f);
|
|
}
|
|
}
|
|
|
|
// set ob hp
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
rf = hasflag(corpserace->flags, F_HITDICE);
|
|
if (rf) {
|
|
int maxhp;
|
|
maxhp = (rf->val[0] * 4) + rf->val[1];
|
|
f->val[0] = maxhp;
|
|
f->val[1] = maxhp;
|
|
}
|
|
}
|
|
|
|
} else if (o->type->id == OT_HEAD) {
|
|
flag_t *rf, *cf;
|
|
|
|
assert(corpserace);
|
|
|
|
o->weight = corpserace->weight;
|
|
o->material = corpserace->material;
|
|
|
|
// remember the race type
|
|
addflag(o->flags, F_CORPSEOF, corpserace->id, NA, NA, NULL);
|
|
|
|
// override ot_corpse nutrition flag based on race's size
|
|
rf = hasflag(corpserace->flags, F_SIZE);
|
|
if (rf) {
|
|
cf = hasflag(o->flags, F_EDIBLE);
|
|
if (cf) {
|
|
switch (rf->val[0]) {
|
|
case SZ_MINI:
|
|
cf->val[1] = 1;
|
|
break;
|
|
case SZ_TINY:
|
|
cf->val[1] = 2;
|
|
break;
|
|
case SZ_SMALL:
|
|
cf->val[1] = 5;
|
|
break;
|
|
case SZ_MEDIUM:
|
|
cf->val[1] = 25;
|
|
break;
|
|
case SZ_HUMAN:
|
|
cf->val[1] = 50;
|
|
break;
|
|
case SZ_LARGE:
|
|
cf->val[1] = 75;
|
|
break;
|
|
case SZ_HUGE:
|
|
cf->val[1] = 100;
|
|
break;
|
|
case SZ_ENORMOUS:
|
|
cf->val[1] = 150;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for (n = 0; n < nom; n++) {
|
|
// add flags from obmod
|
|
applyobmod(o, wantom[n]);
|
|
// other effects...
|
|
switch (wantom[n]->id) {
|
|
case OM_FLAMING: // flaming weapons are immune to fire
|
|
if (o->type->obclass->id == OC_WEAPON) {
|
|
if (!isimmuneto(o->flags, DT_FIRE)) {
|
|
addflag(o->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
|
}
|
|
}
|
|
break;
|
|
case OM_FROZEN:
|
|
// made of ice
|
|
// note: not using changemat() here to avoid adding f_frozen twice.
|
|
o->material = findmaterial(MT_ICE);
|
|
break;
|
|
case OM_MASTERWORK:
|
|
if (isweapon(o) || isarmour(o)) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
f->val[0] *= 2;
|
|
f->val[1] *= 2;
|
|
}
|
|
}
|
|
if (isweapon(o)) {
|
|
flag_t *f;
|
|
// always does near high end of damage range
|
|
f = hasflag(o->flags, F_DAM);
|
|
if (f) {
|
|
int ndice,dsides,bonus;
|
|
texttodice(f->text, &ndice,&dsides,&bonus);
|
|
// half the number of sides on the dice (dsides).
|
|
dsides /= 2; if (dsides < 1) dsides = 1;
|
|
// increase modifier by (ndice * dsides)
|
|
bonus += (ndice * dsides);
|
|
if (bonus <= 0) {
|
|
bonus = NA;
|
|
}
|
|
dicetotext(ndice,dsides,bonus,NULL,NULL,f->text, NULL);
|
|
}
|
|
}
|
|
break;
|
|
case OM_SHODDY:
|
|
if (isweapon(o) || isarmour(o)) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
f->val[0] /= 2; if (f->val[0] < 1) f->val[0] = 1;
|
|
f->val[1] /= 2; if (f->val[1] < 1) f->val[1] = 1;
|
|
|
|
}
|
|
}
|
|
if (isweapon(o)) {
|
|
flag_t *f;
|
|
// half the damage
|
|
f = hasflag(o->flags, F_DAM);
|
|
if (f) {
|
|
int ndice, dsides,bonus;
|
|
texttodice(f->text, &ndice, &dsides, &bonus);
|
|
// half the number of sides on the dice (dsides).
|
|
dsides /= 2;
|
|
// half modifier
|
|
if (bonus > 0) {
|
|
bonus /= 2; if (bonus <= 0) bonus = NA;
|
|
}
|
|
dicetotext(ndice,dsides,bonus,NULL,NULL,f->text, NULL);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// check for bonuses. eg. "+1"
|
|
p2 = strchr(p, '+');
|
|
if (p2) {
|
|
char *p3;
|
|
char numbuf[BUFLENSMALL];
|
|
p3 = numbuf;
|
|
|
|
p2++;
|
|
|
|
while (isdigit(*p2)) {
|
|
*p3 = *p2;
|
|
p2++;
|
|
p3++;
|
|
}
|
|
*p3 = '\0';
|
|
|
|
bonus += atoi(numbuf);
|
|
}
|
|
// check for penalties. eg. "-1"
|
|
p2 = strchr(p, '-');
|
|
if (p2) {
|
|
char *p3;
|
|
char numbuf[BUFLENSMALL];
|
|
p3 = numbuf;
|
|
|
|
p2++;
|
|
|
|
while (isdigit(*p2)) {
|
|
*p3 = *p2;
|
|
p2++;
|
|
p3++;
|
|
}
|
|
*p3 = '\0';
|
|
|
|
bonus -= atoi(numbuf);
|
|
}
|
|
|
|
if (bonus) {
|
|
if (hasflag(o->flags, F_ENCHANTABLE)) {
|
|
// for swords, armour etc
|
|
addflag_real(o->flags, F_BONUS, bonus, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
}
|
|
}
|
|
|
|
// special rings which get randomized...
|
|
if (o->type->id == OT_RING_CON) {
|
|
flag_t *f;
|
|
f = hasflagval(o->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, NA, NULL);
|
|
if (f) {
|
|
if (bonus) f->val[2] = bonus;
|
|
else f->val[2] = rnd(1,3);
|
|
}
|
|
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
|
} else if (o->type->id == OT_RING_DEX) {
|
|
flag_t *f;
|
|
f = hasflagval(o->flags, F_EQUIPCONFER, F_ATTRMOD, A_DEX, NA, NULL);
|
|
if (f) {
|
|
if (bonus) f->val[2] = bonus;
|
|
else f->val[2] = rnd(1,3);
|
|
}
|
|
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
|
} else if (o->type->id == OT_RING_IQ) {
|
|
flag_t *f;
|
|
f = hasflagval(o->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, NA, NULL);
|
|
if (f) {
|
|
if (bonus) f->val[2] = bonus;
|
|
else f->val[2] = rnd(1,3);
|
|
}
|
|
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
|
} else if (o->type->id == OT_RING_STR) {
|
|
flag_t *f;
|
|
f = hasflagval(o->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, NA, NULL);
|
|
if (f) {
|
|
if (bonus) f->val[2] = bonus;
|
|
else f->val[2] = rnd(1,3);
|
|
}
|
|
|
|
if (o->blessed == B_CURSED) f->val[2] *= -1;
|
|
}
|
|
|
|
// check for postmods. eg. "xxx of pyromania"
|
|
for (br = firstbrand ; br ; br = br->next) {
|
|
if (strstr(name, br->suffix)) {
|
|
// does this brand apply to this objecttype?
|
|
if (brandappliesto(br, o->type)) {
|
|
copyflags(o->flags, br->flags, FROMBRAND);
|
|
addflag(o->flags, F_HASBRAND, br->id, NA, NA, NULL);
|
|
} else {
|
|
// doesn't exist!
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
free(localname);
|
|
|
|
if (where->owner) {
|
|
// new owner gains "hold confer" flags conferred by this object
|
|
giveobflags(where->owner, o, F_HOLDCONFER);
|
|
}
|
|
|
|
// special cases
|
|
if (o->type->id == OT_VENDINGMACHINE) {
|
|
char buf[BUFLEN];
|
|
cell_t *loc;
|
|
loc = getoblocation(o);
|
|
// populate with objects
|
|
for (i = 0; i < 10; i++) {
|
|
objecttype_t *ot2;
|
|
strcpy(buf, "");
|
|
while (!strcmp(buf, "")) {
|
|
real_getrandomob(loc->map, buf, RO_NONE, NA, loc->map->depth + rnd(10,15));
|
|
// replace "1 potion" with "a potion"
|
|
if (strstr(buf, "1 ") == buf) {
|
|
char temp[BUFLEN];
|
|
strcpy(temp, buf);
|
|
sprintf(buf, "a %s",temp + 2);
|
|
}
|
|
// make sure you can hold it
|
|
ot2 = findotn(buf);
|
|
if (!ot2 ||
|
|
hasflag(ot2->flags, F_NOPICKUP) ||
|
|
hasflag(ot2->flags, F_IMPASSABLE) ) {
|
|
strcpy(buf, "");
|
|
}
|
|
}
|
|
|
|
addflag(o->flags, F_CONTAINSOB, 'a' + i, NA, NA, buf);
|
|
}
|
|
}
|
|
|
|
// return the last object given
|
|
return o;
|
|
}
|
|
|
|
|
|
// add objects in a circle
|
|
// returns # added.
|
|
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf) {
|
|
int (*distfunc)(cell_t *, cell_t *);
|
|
int x,y;
|
|
cell_t *c;
|
|
int nadded = 0;
|
|
|
|
if (!where) return 0;
|
|
|
|
if (dirtype == DT_ORTH) {
|
|
distfunc = getcelldistorth;
|
|
} else {
|
|
distfunc = getcelldist;
|
|
}
|
|
|
|
for (y = where->y - range; y <= where->y + range; y++) {
|
|
for (x = where->x - range; x <= where->x + range; x++) {
|
|
c = getcellat(where->map, x,y);
|
|
if (distfunc(where, c) <= range) {
|
|
if (!c->type->solid) {
|
|
object_t *o;
|
|
o = addob(c->obpile, name);
|
|
if (o) {
|
|
if (fromlf) setobcreatedby(o, fromlf);
|
|
nadded++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nadded;
|
|
}
|
|
|
|
|
|
obmod_t *addobmod(enum OBMOD id, char *prefix) {
|
|
obmod_t *a, *om;
|
|
char buf[BUFLEN];
|
|
//flag_t *f;
|
|
|
|
// does this modj already exist?
|
|
om = findobmod(id);
|
|
assert(!om);
|
|
|
|
// add to the end of the list
|
|
if (firstobmod == NULL) {
|
|
firstobmod = malloc(sizeof(obmod_t));
|
|
a = firstobmod;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastobmod;
|
|
a->next = malloc(sizeof(obmod_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastobmod = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
sprintf(buf, "%s ",prefix);
|
|
a->prefix = strdup(buf);
|
|
|
|
a->flags = addflagpile(NULL, NULL);
|
|
|
|
return a;
|
|
}
|
|
|
|
obpile_t *addobpile(lifeform_t *owner, cell_t *where) {
|
|
obpile_t *op;
|
|
op = malloc(sizeof(obpile_t));
|
|
op->first = NULL;
|
|
op->last = NULL;
|
|
op->owner = owner;
|
|
op->where = where;
|
|
|
|
return op;
|
|
}
|
|
|
|
|
|
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes) {
|
|
int x,y;
|
|
objecttype_t *ot;
|
|
ot = findotn(name);
|
|
if (!ot) return;
|
|
|
|
for (y = centre->y - radius ; y <= centre->y + radius; y++) {
|
|
for (x = centre->x - radius ; x <= centre->x + radius; x++) {
|
|
int valid = B_FALSE;
|
|
cell_t *c;
|
|
c = getcellat(centre->map, x, y);
|
|
if (c && !c->type->solid && haslof(centre, c, LOF_WALLSTOP, NULL)) {
|
|
if (allowdupes || !hasob(c->obpile, ot->id)) {
|
|
if ((dirtype == DT_COMPASS) && (getcelldist(centre, c) <= radius)) {
|
|
valid = B_TRUE;
|
|
} else if ((dirtype == DT_ORTH) && (getcelldistorth(centre, c) <= radius)) {
|
|
valid = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
if (valid) {
|
|
addob(c->obpile, name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
objecttype_t *addot(enum OBTYPE id, char *name, char *description, int material, float weight, int obclassid) {
|
|
objecttype_t *a, *ot;
|
|
//flag_t *f;
|
|
|
|
// does this ob already exist?
|
|
ot = findot(id);
|
|
assert(!ot);
|
|
|
|
// add to the end of the list
|
|
if (objecttype == NULL) {
|
|
objecttype = malloc(sizeof(objecttype_t));
|
|
a = objecttype;
|
|
a->prev = NULL;
|
|
} else {
|
|
// go to end of list
|
|
a = lastobjecttype;
|
|
a->next = malloc(sizeof(objecttype_t));
|
|
a->next->prev = a;
|
|
a = a->next;
|
|
}
|
|
lastobjecttype = a;
|
|
a->next = NULL;
|
|
|
|
// props
|
|
a->id = id;
|
|
if (a->id == OT_BERRY) {
|
|
int a;
|
|
a = 2;
|
|
}
|
|
a->name = strdup(name);
|
|
a->desc = strdup(description);
|
|
a->material = findmaterial(material);
|
|
a->weight = weight;
|
|
a->obclass = findoc(obclassid);
|
|
a->flags = addflagpile(NULL, NULL);
|
|
// inherit flags from object class
|
|
/*
|
|
for (f = a->obclass->flags->first ; f ; f = f->next) {
|
|
addflag(a->flags, f->id, f->val[0], f->val[1], f->val[2], f->text);
|
|
}
|
|
*/
|
|
copyflags(a->flags, a->obclass->flags, NA);
|
|
if (a->material) {
|
|
// inherit flags from material
|
|
/*
|
|
for (f = a->material->flags->first ; f ; f = f->next) {
|
|
addflag(a->flags, f->id, f->val[0], f->val[1], f->val[2], f->text);
|
|
}
|
|
*/
|
|
copyflags(a->flags, a->material->flags, FROMMAT);
|
|
}
|
|
|
|
// for easy addition of flags
|
|
lastot = a;
|
|
return a;
|
|
}
|
|
|
|
// adjust damage based on material being damaged
|
|
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat) {
|
|
// adjust based on material
|
|
if (mat == MT_MAGIC) {
|
|
switch (damtype) {
|
|
case DT_DIRECT:
|
|
case DT_NONE:
|
|
break;
|
|
default:
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
} else if (mat == MT_GAS) {
|
|
switch (damtype) {
|
|
case DT_HOLY:
|
|
case DT_DIRECT:
|
|
case DT_NONE:
|
|
break;
|
|
default:
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// adjust based on damage type
|
|
if (damtype == DT_FIRE) {
|
|
switch (mat) {
|
|
case MT_PAPER:
|
|
*dam *= 3;
|
|
break;
|
|
case MT_WOOD:
|
|
case MT_ICE:
|
|
case MT_SLIME:
|
|
*dam *= 2;
|
|
break;
|
|
case MT_METAL:
|
|
case MT_BONE:
|
|
case MT_STONE:
|
|
case MT_BLOOD:
|
|
case MT_FIRE: // immune to itself
|
|
*dam = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (damtype == DT_CHOP) {
|
|
switch (mat) {
|
|
case MT_WOOD:
|
|
*dam *= 2;
|
|
break;
|
|
case MT_SLIME:
|
|
*dam /= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (damtype == DT_SLASH) {
|
|
switch (mat) {
|
|
case MT_WOOD:
|
|
case MT_SLIME:
|
|
case MT_BONE:
|
|
*dam /= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (damtype == DT_PIERCE) {
|
|
switch (mat) {
|
|
case MT_WOOD:
|
|
case MT_SLIME:
|
|
case MT_BONE:
|
|
*dam /= 2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (damtype == DT_BASH) {
|
|
switch (mat) {
|
|
case MT_PAPER:
|
|
*dam = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (damtype == DT_WATER) {
|
|
switch (mat) {
|
|
case MT_WATER: // immune to itself
|
|
*dam = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype) {
|
|
// objects can't get hurt the turn they
|
|
// were created.
|
|
if (o->birthtime == curtime) {
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
|
|
// only some objects can be hurt
|
|
if (!hasflag(o->flags, F_DAMAGABLE)) {
|
|
if (damtype != DT_DIRECT) {
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
}
|
|
// immune?
|
|
if (isimmuneto(o->flags, damtype)) {
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
if (isresistantto(o->flags, damtype)) {
|
|
*dam /= 2;
|
|
}
|
|
if (isvulnto(o->flags, damtype)) {
|
|
*dam *= 2;
|
|
}
|
|
// some damage types never hurts objects
|
|
if (damtype == DT_POISONGAS) {
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
|
|
if (damtype == DT_WATER) {
|
|
if (!isvulnto(o->flags, damtype)) {
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
// adjust damage
|
|
if (o->blessed == B_BLESSED) {
|
|
// chance of no hp loss
|
|
if (onein(2)) {
|
|
lifeform_t *owner;
|
|
owner = o->pile->owner;
|
|
if (owner && isplayer(owner)) {
|
|
// become known if owned by player
|
|
if (!isblessknown(o)) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, o->amt);
|
|
msg("Your %s pulses with holy light as it is struck!",noprefix(obname));
|
|
}
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
*dam = 0;
|
|
return;
|
|
}
|
|
} else if (o->blessed == B_CURSED) {
|
|
// chance of double damage!
|
|
if (onein(2)) {
|
|
lifeform_t *owner;
|
|
(*dam) *= 2;
|
|
owner = o->pile->owner;
|
|
if (owner && isplayer(owner)) {
|
|
// become known if a player's
|
|
if (!isblessknown(o)) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, o->amt);
|
|
msg("Your %s emits a wave of dread as it is struck!",noprefix(obname));
|
|
}
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// adjust damage for material too
|
|
adjustdammaterial(dam, damtype, o->material->id);
|
|
}
|
|
|
|
// adjust price for magical effects etc
|
|
/*
|
|
void adjustprice(objecttype_t *ot, float *price) {
|
|
int min,max;
|
|
flag_t *f;
|
|
|
|
// bonuses/penalties
|
|
|
|
}
|
|
*/
|
|
|
|
// adjusts armour's evasion penalty based on skill
|
|
int adjustarmourpenalty(lifeform_t *lf, float amt) {
|
|
enum SKILLLEVEL slev;
|
|
|
|
// no penalties for monsters
|
|
if (!isplayer(lf)) {
|
|
return 0;
|
|
}
|
|
// only adjust if it is a NEGATIVE penalty!
|
|
if (amt < 0) {
|
|
slev = getskill(lf, SK_ARMOUR);
|
|
switch (slev) {
|
|
case PR_INEPT:
|
|
amt *= 2; // double penalty!
|
|
break;
|
|
case PR_NOVICE:
|
|
break;
|
|
case PR_BEGINNER:
|
|
amt *= 0.8;
|
|
break;
|
|
case PR_ADEPT:
|
|
amt *= 0.6;
|
|
break;
|
|
case PR_SKILLED:
|
|
amt *= 0.4;
|
|
break;
|
|
case PR_EXPERT:
|
|
amt *= 0.2;
|
|
break;
|
|
case PR_MASTER: // no penalty!
|
|
amt = 0;
|
|
break;
|
|
}
|
|
}
|
|
return amt;
|
|
}
|
|
|
|
// adjusts shield's accuracy penalty based on skill
|
|
int adjustshieldpenalty(lifeform_t *lf, float amt) {
|
|
enum SKILLLEVEL slev;
|
|
|
|
// monsters suffer no penalties
|
|
if (!isplayer(lf)) {
|
|
return 0;
|
|
}
|
|
|
|
slev = getskill(lf, SK_SHIELDS);
|
|
switch (slev) {
|
|
case PR_INEPT:
|
|
amt *= 10;
|
|
break;
|
|
case PR_NOVICE:
|
|
break;
|
|
case PR_BEGINNER:
|
|
amt *= 0.8;
|
|
break;
|
|
case PR_ADEPT:
|
|
amt *= 0.6;
|
|
break;
|
|
case PR_SKILLED:
|
|
amt *= 0.4;
|
|
break;
|
|
case PR_EXPERT:
|
|
amt *= 0.2;
|
|
break;
|
|
case PR_MASTER:
|
|
amt = 0;
|
|
break;
|
|
}
|
|
return amt;
|
|
}
|
|
|
|
void appendinscription(object_t *o, char *text) {
|
|
if (o->inscription) {
|
|
int len;
|
|
char *buf;
|
|
len = strlen(o->inscription) + strlen(text) + 1;
|
|
if (len > BUFLEN) len = BUFLEN;
|
|
buf = malloc(len * sizeof(char));
|
|
snprintf(buf, len, "%s%s",o->inscription, text);
|
|
setinscription(o, buf);
|
|
free(buf);
|
|
} else {
|
|
setinscription(o, text);
|
|
}
|
|
}
|
|
|
|
|
|
void applyobmod(object_t *o, obmod_t *om) {
|
|
flag_t *f;
|
|
|
|
if ((om->id == OM_MASTERWORK) || (om->id == OM_SHODDY)) {
|
|
if (hasflag(o->flags, F_NOQUALITY)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (om->id == OM_FROZEN) {
|
|
// frozen things don't decay...
|
|
f = hasflagval(o->flags, F_OBHPDRAIN, NA, DT_DECAY, NA, NULL);
|
|
if (f) {
|
|
killflag(f);
|
|
}
|
|
|
|
// ...but they do melt!
|
|
f = addtempflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL, FROMOBMOD);
|
|
|
|
// it needs HP to melt
|
|
if (!hasflag(o->flags, F_OBHP)) {
|
|
int myhp;
|
|
// give hp
|
|
myhp = getobweight(o) * 20;
|
|
if (myhp <= 0) myhp = 2;
|
|
|
|
addtempflag(o->flags, F_OBHP, myhp, myhp, NA, NULL, FROMOBMOD);
|
|
}
|
|
if (!hasflag(o->flags, F_DAMAGABLE)) {
|
|
addtempflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL, FROMOBMOD);
|
|
}
|
|
}
|
|
copyflags(o->flags, om->flags, FROMOBMOD);
|
|
}
|
|
|
|
int blessob(object_t *o) {
|
|
char obname[BUFLEN];
|
|
int rv = B_FALSE;
|
|
lifeform_t *owner;
|
|
|
|
if (hasflag(o->flags, F_NOBLESS)) return B_TRUE;
|
|
|
|
getobname(o, obname, o->amt);
|
|
|
|
switch (o->blessed) {
|
|
case B_BLESSED:
|
|
rv = B_TRUE;
|
|
break;
|
|
case B_CURSED:
|
|
case B_UNCURSED:
|
|
setblessed(o, B_BLESSED);
|
|
break;
|
|
}
|
|
|
|
if (rv == B_FALSE) {
|
|
int seen = B_FALSE;
|
|
owner = o->pile->owner;
|
|
if (owner) {
|
|
if (isplayer(owner)) {
|
|
msg("Your %s is bathed in a divine glow!", noprefix(obname));
|
|
seen = B_TRUE;
|
|
} else if (cansee(player, owner)) {
|
|
char ownername[BUFLEN];
|
|
msg("%s%s %s is bathed in a divine glow!", ownername, getpossessive(ownername),
|
|
noprefix(obname));
|
|
seen = B_TRUE;
|
|
}
|
|
} else if (haslos(player, o->pile->where)) {
|
|
msg("%s is bathed in a divine glow!", obname);
|
|
seen = B_TRUE;
|
|
}
|
|
|
|
if (seen) {
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
void brightflash(cell_t *centre, int range, lifeform_t *immunelf) {
|
|
int x,y;
|
|
cell_t *c;
|
|
|
|
animradial(centre, range, '}', C_WHITE);
|
|
|
|
// announce
|
|
if (haslos(player, centre) && !isblind(player)) {
|
|
msg("You see an intense flash of light!");
|
|
more();
|
|
}
|
|
/*
|
|
if (getcelldist(player->cell, centre) <= range) {
|
|
// player is in range but can't see - announce it beacuse it
|
|
// will make you deaf!
|
|
youhear(centre, "a deafening bang!");
|
|
} else { // not in range of the flash
|
|
youhear(centre, "a loud bang!");
|
|
}
|
|
*/
|
|
// blind monsters
|
|
for (y = centre->y - range; y <= centre->y + range; y++) {
|
|
for (x = centre->x - range; x <= centre->x + range; x++) {
|
|
c = getcellat(centre->map, x, y);
|
|
if (c) {
|
|
lifeform_t *lf;
|
|
lf = haslf(c);
|
|
if (lf && (lf != immunelf)) {
|
|
if (haslos(lf, centre) && !isblind(lf)) {
|
|
if (!isplayer(lf)) { // we'll blind the player last
|
|
if (!eyesshaded(lf)) {
|
|
if (lfhasflag(lf, F_SEEINDARK)) {
|
|
// blind for 20-30 turns
|
|
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(20,30));
|
|
} else {
|
|
// blind for 5-10 turns
|
|
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(5,10));
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// TODO: deafen
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// handle the player last, so that you see all the
|
|
// 'xx is blinded' messages before losing your own
|
|
// sight.
|
|
if (player != immunelf) {
|
|
if (haslos(player, centre) && (getcelldist(player->cell, centre) <= range) && !isblind(player)) {
|
|
if (!eyesshaded(player)) {
|
|
if (lfhasflag(player, F_SEEINDARK)) {
|
|
msg("You eyes feel like they are burning!");
|
|
addtempflag(player->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(20,30));
|
|
} else {
|
|
addtempflag(player->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(5,10));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int canbepoisoned(enum OBTYPE oid) {
|
|
flag_t *f;
|
|
objecttype_t *ot;
|
|
ot = findot(oid);
|
|
|
|
if (!ot) return B_FALSE;
|
|
if (ot->obclass->id != OC_WEAPON) return B_FALSE;
|
|
|
|
f = hasflag(ot->flags, F_DAM);
|
|
if (f) {
|
|
switch (f->val[0]) {
|
|
case DT_SLASH:
|
|
case DT_PIERCE:
|
|
return B_TRUE;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasflagval(ot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL)) {
|
|
return B_TRUE;
|
|
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
// does the pile "op" have an object we can
|
|
// stack "o" with
|
|
object_t *canstackob(obpile_t *op, object_t *match) {
|
|
object_t *o;
|
|
if (!hasflag(match->flags, F_STACKABLE)) {
|
|
return NULL;
|
|
}
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o != match) {
|
|
if (obpropsmatch(o, match)) return o;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// does the pile "op" have an object we can
|
|
// stack a new object of type "ot" with
|
|
object_t *canstacknewot(obpile_t *op, objecttype_t *match) {
|
|
object_t *o;
|
|
if (!hasflag(match->flags, F_STACKABLE)) {
|
|
return NULL;
|
|
}
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->type == match) {
|
|
if (isplainob(o)) return o;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int changemat(object_t *o, enum MATERIAL mat) {
|
|
material_t *m;
|
|
flag_t *f, *nextf;
|
|
|
|
|
|
m = findmaterial(mat);
|
|
if (!m) {
|
|
return E_FAILED;
|
|
}
|
|
|
|
if (o->material->id == mat) return E_NOEFFECT;
|
|
|
|
// won't work on pyromania objects
|
|
f = hasflag(o->flags, F_FLAMESTRIKE);
|
|
if (f) {
|
|
if (isplayer(o->pile->owner)) {
|
|
f->known = B_TRUE;
|
|
} else if (o->pile->owner && cansee(player, o->pile->owner)) {
|
|
f->known = B_TRUE;
|
|
} else if (haslos(player, o->pile->where)) {
|
|
f->known = B_TRUE;
|
|
}
|
|
return E_NOEFFECT;
|
|
}
|
|
|
|
// remove flags which came from old material
|
|
for (f = o->flags->first ; f; f = nextf) {
|
|
nextf = f->next;
|
|
if (f->lifetime == FROMMAT) {
|
|
killflag(f);
|
|
}
|
|
}
|
|
|
|
// change material
|
|
o->material = m;
|
|
|
|
// inherit flags from new material
|
|
copyflags(m->flags, o->flags, FROMMAT);
|
|
|
|
if (mat == MT_ICE) {
|
|
obmod_t *om;
|
|
// if it turned to ice..
|
|
|
|
// it stops burning
|
|
extinguish(o);
|
|
// it will melt...
|
|
// note that it is frozen
|
|
om = findobmod(OM_FROZEN);
|
|
applyobmod(o, om);
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
objecttype_t *checkobnames(char *haystack, char *needle) {
|
|
objecttype_t *ot;
|
|
char *pluralname;
|
|
int db = B_FALSE;
|
|
|
|
// search for exact match
|
|
if (!strcmp(haystack, needle)) {
|
|
// found it!
|
|
if (db) dblog("checkobnames(): got exact match: '%s'",haystack);
|
|
return ot;
|
|
}
|
|
|
|
// search for words ending in "s" (eg. "swords")
|
|
pluralname = strdup(needle);
|
|
//if (db) dblog("findotn(): plural is '%s'",pluralname);
|
|
if (pluralname[strlen(pluralname)-1] == 's') {
|
|
// remove trailing 's'
|
|
pluralname[strlen(pluralname)-1] = '\0';
|
|
// search again (for exact matches)
|
|
if (!strcmp(haystack, pluralname)) {
|
|
if (db) dblog("checkobnames(): got match after stripping 's': '%s' -> '%s'",pluralname, needle);
|
|
free(pluralname);
|
|
return ot;
|
|
}
|
|
|
|
// search for words ending in "es" (eg. tomatoes)
|
|
if ((pluralname[strlen(pluralname)-1] == 'e') &&
|
|
(pluralname[strlen(pluralname)-2] == 'o')
|
|
) {
|
|
// remove trailing 'es'
|
|
pluralname[strlen(pluralname)-1] = '\0';
|
|
pluralname[strlen(pluralname)-2] = '\0';
|
|
//if (db) dblog("findotn(): pluralname without 'es' is '%s'",pluralname);
|
|
// search again
|
|
if (!strcmp(haystack, pluralname)) {
|
|
if (db) dblog("checkobnames(): got match after stripping 'es': '%s' -> '%s'",pluralname, needle);
|
|
free(pluralname);
|
|
return ot;
|
|
}
|
|
}
|
|
}
|
|
free(pluralname);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void colourmatchob(object_t *o, lifeform_t *lf) {
|
|
flag_t *f;
|
|
glyph_t *lfglyph;
|
|
lfglyph = getlfglyph(lf);
|
|
|
|
f = hasflag(o->flags, F_GLYPH);
|
|
if (f) {
|
|
|
|
f->val[0] = lfglyph->colour;
|
|
} else {
|
|
glyph_t *obglyph;
|
|
char buf[2];
|
|
|
|
obglyph = getglyph(o);
|
|
buf[0] = obglyph->ch;
|
|
buf[1] = '\0';
|
|
addflag(o->flags, F_GLYPH, lfglyph->colour, NA, NA, buf);
|
|
}
|
|
}
|
|
|
|
void copyobprops(object_t *dst, object_t *src) {
|
|
dst->material = src->material;
|
|
dst->weight = src->weight;
|
|
if (src->inscription) {
|
|
dst->inscription = strdup(src->inscription);
|
|
}
|
|
setblessed(dst, src->blessed);
|
|
dst->blessknown = src->blessknown;
|
|
|
|
// copy flags
|
|
while (dst->flags->first) {
|
|
killflag(dst->flags->first);
|
|
}
|
|
copyflags(dst->flags, src->flags, NA);
|
|
|
|
}
|
|
|
|
int countnames(char **list) {
|
|
int count;
|
|
for (count = 0; list[count]; count++);
|
|
return count;
|
|
}
|
|
|
|
int countobs(obpile_t *op) {
|
|
object_t *o;
|
|
|
|
int count = 0;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int countnoncosmeticobs(obpile_t *op) {
|
|
object_t *o;
|
|
|
|
int count = 0;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (!hasflag(o->flags, F_COSMETIC)) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
int curseob(object_t *o) {
|
|
int rv = B_FALSE;
|
|
lifeform_t *lf;
|
|
|
|
lf = o->pile->owner;
|
|
|
|
// announce
|
|
if (gamemode == GM_GAMESTARTED) {
|
|
if (lf) {
|
|
if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
char obname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
getobname(o, obname,o->amt);
|
|
msg("A black aura surrounds %s%s %s.",lfname,getpossessive(lfname),noprefix(obname));
|
|
}
|
|
} else { // not held
|
|
cell_t *loc = NULL;
|
|
loc = getoblocation(o);
|
|
if (haslos(player, loc)) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname,o->amt);
|
|
msg("A black aura surrounds %s.",obname);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (o->blessed) {
|
|
case B_BLESSED: // uncurse it
|
|
setblessed(o, B_UNCURSED);
|
|
break;
|
|
case B_CURSED: // nothing happens
|
|
rv = B_TRUE;
|
|
break;
|
|
case B_UNCURSED: // curse it
|
|
setblessed(o, B_CURSED);
|
|
break;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
void damageallobs(object_t *exception, obpile_t *op, int howmuch, int damtype) {
|
|
object_t *o, *nexto;
|
|
for (o = op->first ; o ; o = nexto) {
|
|
nexto = o->next;
|
|
if ((o != exception) && !hasflag(o->flags, F_DEAD)) {
|
|
takedamage(o, howmuch, damtype);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void explodeob(object_t *o, flag_t *f, int bigness) {
|
|
cell_t *c;
|
|
int dam;
|
|
char obname[BUFLEN];
|
|
|
|
dam = roll(f->text);
|
|
c = getoblocation(o);
|
|
getobname(o, obname, o->amt);
|
|
|
|
// announce
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s explode%s!", noprefix(obname), (o->amt == 1) ? "s" : "");
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(o->pile->owner, lfname);
|
|
msg("%s%s %s explode%s!", lfname, getpossessive(lfname), noprefix(obname), (o->amt == 1) ? "s" : "");
|
|
}
|
|
} else if (haslos(player, c)) {
|
|
msg("%s explode%s!", obname, (o->amt == 1) ? "s" : "");
|
|
}
|
|
explodecells(c, dam * o->amt, bigness ? B_TRUE : B_FALSE, o, bigness ? 1 : 0, DT_COMPASS, B_FALSE);
|
|
|
|
// hurt everything!
|
|
/*
|
|
if (bigness) {
|
|
int dir;
|
|
cell_t *cc;
|
|
explodecell(c, dam, (bigness) ? B_TRUE : B_FALSE, NULL);
|
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
|
cc = getcellindir(c, dir);
|
|
}
|
|
} else {
|
|
explodecell(c, dam, (bigness) ? B_TRUE : B_FALSE, NULL);
|
|
}
|
|
*/
|
|
// object dies.
|
|
removeob(o, o->amt);
|
|
}
|
|
|
|
void extinguish(object_t *o) {
|
|
flag_t *f;
|
|
char obname[BUFLEN];
|
|
f = hasflag(o->flags, F_ONFIRE);
|
|
getobname(o, obname, o->amt);
|
|
if (f) {
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s %s extinguished.", noprefix(obname),
|
|
(o->amt == 1) ? "is" : "are");
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(o->pile->owner, lfname);
|
|
msg("%s%s %s %s extinguished.", lfname, getpossessive(lfname), noprefix(obname),
|
|
(o->amt == 1) ? "is" : "are");
|
|
}
|
|
} else if (o->pile->where && haslos(player, o->pile->where)) {
|
|
getobname(o, obname, o->amt);
|
|
msg("%s %s extinguished.", obname,
|
|
(o->amt == 1) ? "is" : "are");
|
|
}
|
|
killflag(f);
|
|
}
|
|
}
|
|
|
|
material_t *findmaterial(int id) {
|
|
material_t *m;
|
|
for (m = material ; m ; m = m->next) {
|
|
if (m->id == id) return m;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
objectclass_t *findoc(int id) {
|
|
objectclass_t *oc;
|
|
for (oc = objectclass ; oc ; oc = oc->next) {
|
|
if (oc->id == id) return oc;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *findobbyid(obpile_t *op, long oid) {
|
|
object_t *o;
|
|
for (o = op->first; o ; o = o->next) {
|
|
if (o->id == oid) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *findobl(obpile_t *op, char let) {
|
|
object_t *o;
|
|
for (o = op->first; o ; o = o->next) {
|
|
if (o->letter == let) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
brand_t *findbrand(enum BRAND id) {
|
|
brand_t *om;
|
|
for (om = firstbrand ; om ; om = om->next) {
|
|
if (om->id == id) return om;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
obmod_t *findobmod(enum OBMOD id) {
|
|
obmod_t *om;
|
|
for (om = firstobmod ; om ; om = om->next) {
|
|
if (om->id == id) return om;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
objecttype_t *findot(enum OBTYPE id) {
|
|
objecttype_t *ot;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if (ot->id == id) return ot;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
objecttype_t *findotn(char *name) {
|
|
objecttype_t *ot;
|
|
knowledge_t *k;
|
|
char *modname;
|
|
char *p;
|
|
int db = B_FALSE;
|
|
brand_t *om;
|
|
|
|
if (!strlen(name)) {
|
|
return NULL;
|
|
}
|
|
|
|
modname = strdup(name);
|
|
|
|
// make some replacements
|
|
//replace scrolls with scroll etc
|
|
modname = strrep(modname, "berries ", "berry ", NULL);
|
|
modname = strrep(modname, "blocks ", "block ", NULL);
|
|
modname = strrep(modname, "cans ", "can ", NULL);
|
|
modname = strrep(modname, "chunks ", "chunk ", NULL);
|
|
modname = strrep(modname, "flasks ", "flask ", NULL);
|
|
modname = strrep(modname, "gems ", "gem ", NULL);
|
|
modname = strrep(modname, "loaves ", "load ", NULL);
|
|
modname = strrep(modname, "lumps ", "lump ", NULL);
|
|
modname = strrep(modname, "pieces ", "piece ", NULL);
|
|
modname = strrep(modname, "piles ", "pile ", NULL);
|
|
modname = strrep(modname, "pools ", "pool ", NULL);
|
|
modname = strrep(modname, "potions ", "potion ", NULL);
|
|
modname = strrep(modname, "puddles ", "puddle ", NULL);
|
|
modname = strrep(modname, "rings ", "ring ", NULL);
|
|
modname = strrep(modname, "scrolls ", "scroll ", NULL);
|
|
modname = strrep(modname, "sets ", "set ", NULL);
|
|
modname = strrep(modname, "splashes ", "splash ", NULL);
|
|
modname = strrep(modname, "suits ", "suit ", NULL);
|
|
modname = strrep(modname, "vials ", "vial ", NULL);
|
|
|
|
// only at start...
|
|
if (strstr(modname, "the ") == modname) modname = strrep(modname, "the ", "", NULL);
|
|
if (strstr(modname, "an ") == modname) modname = strrep(modname, "an ", "", NULL);
|
|
if (strstr(modname, "a ") == modname) modname = strrep(modname, "a ", "", NULL);
|
|
|
|
modname = strrep(modname, "blessed ", "", NULL);
|
|
modname = strrep(modname, "uncursed ", "", NULL);
|
|
modname = strrep(modname, "cursed ", "", NULL);
|
|
//realloc(modname, strlen(temp)); strcpy(modname, temp); free(temp); // swap
|
|
|
|
// strip out pre mods
|
|
modname = strrep(modname, "flaming ", "", NULL);
|
|
modname = strrep(modname, "headless ", "", NULL);
|
|
|
|
// strip out brands (but not only for certain object classes)
|
|
for (om = firstbrand; om ; om = om->next) {
|
|
modname = strrep(modname, om->suffix, "", NULL);
|
|
}
|
|
|
|
// special cases
|
|
modname = strrep(modname, "holy water", "water", NULL);
|
|
modname = strrep(modname, "incompetence", "competence", NULL);
|
|
|
|
// skip past bonusses
|
|
p = strchr(modname, '+');
|
|
if (p) {
|
|
while (!isalpha(*p)) {
|
|
p++;
|
|
}
|
|
strcpy(modname, p);
|
|
}
|
|
p = strchr(modname, '-');
|
|
if (p) {
|
|
while (!isalpha(*p)) {
|
|
p++;
|
|
}
|
|
strcpy(modname, p);
|
|
}
|
|
|
|
if (db) dblog("findotn(): modname is '%s'",modname);
|
|
|
|
// check for exact matches on real name (and plural versions) first
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if ((ot->obclass->id != OC_SPELL) && (ot->obclass->id != OC_ABILITY)) {
|
|
if (checkobnames(ot->name, modname)) {
|
|
free(modname);
|
|
return ot;
|
|
}
|
|
}
|
|
}
|
|
|
|
// then matches on hidden name
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (checkobnames(k->hiddenname, modname)) {
|
|
free(modname);
|
|
// found it!
|
|
return findot(k->id);
|
|
}
|
|
}
|
|
|
|
// then partial matches on real name
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if ((ot->obclass->id != OC_SPELL) && (ot->obclass->id != OC_ABILITY)) {
|
|
if (strstr(ot->name, modname)) {
|
|
free(modname);
|
|
// found it!
|
|
return ot;
|
|
}
|
|
}
|
|
}
|
|
|
|
free(modname);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// ie. "the apple is xxx"
|
|
// ie. "the apples are xxx"
|
|
char *getfillingname(int nutrition) {
|
|
if (nutrition > 100) {
|
|
return "extremely substantial";
|
|
} else if (nutrition >= 90) {
|
|
return "very filling";
|
|
} else if (nutrition >= 70) {
|
|
return "ample for a meal";
|
|
} else if (nutrition >= 50) {
|
|
return "enough for a light meal";
|
|
} else if (nutrition >= 25) {
|
|
return "snack-sized";
|
|
} else if (nutrition > 0) {
|
|
return "barely worth eating";
|
|
}
|
|
// ie. < 0
|
|
return "of zero nutritional substance";
|
|
}
|
|
|
|
int getfirearmrange(object_t *o) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_RANGE);
|
|
if (f) {
|
|
return f->val[0];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int getfirearmspeed(object_t *o) {
|
|
int firespeed;
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_FIRESPEED);
|
|
if (f) {
|
|
firespeed = f->val[0];
|
|
} else {
|
|
// default to very slow
|
|
firespeed = 1;
|
|
}
|
|
return firespeed;
|
|
}
|
|
|
|
glyph_t *getglyph(object_t *o) {
|
|
flag_t *f;
|
|
int isopen;
|
|
char g = ' '; // default
|
|
int col = C_GREY;
|
|
if (isdoor(o, &isopen)) {
|
|
if (isopen) {
|
|
g = '-';
|
|
} else {
|
|
g = '+';
|
|
}
|
|
col = getmaterialcolour(o->material->id);
|
|
} else {
|
|
f = hasflag(o->flags, F_GLYPH);
|
|
if (f) {
|
|
g = f->text[0];
|
|
if (f->val[0] != NA) {
|
|
col = f->val[0];
|
|
}
|
|
} else {
|
|
g = o->type->obclass->glyph.ch;
|
|
//col = o->type->obclass->glyph.colour;
|
|
col = getmaterialcolour(o->material->id);
|
|
}
|
|
}
|
|
tempglyph.ch = g;
|
|
tempglyph.colour = col;
|
|
return &tempglyph;
|
|
}
|
|
|
|
void fragments(cell_t *centre, char *what, int speed, int howfar) {
|
|
cell_t *c,*dst;
|
|
int n;
|
|
int dir;
|
|
|
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
|
int wantdist = 0;
|
|
int maxdist = 0;
|
|
int done = B_FALSE;
|
|
// get max distance
|
|
c = centre;
|
|
done = B_FALSE;
|
|
while (!done) {
|
|
c = getcellindir(c, dir);
|
|
if (c && cellwalkable(NULL, c, NULL)) {
|
|
maxdist++;
|
|
} else {
|
|
done = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// pick random distance
|
|
if (maxdist == 0) {
|
|
wantdist = 0;
|
|
} else {
|
|
wantdist = rnd(1,(howfar > maxdist) ? maxdist : howfar);
|
|
}
|
|
// go that far
|
|
dst = centre;
|
|
for (n = 0; n < wantdist; n++) {
|
|
dst = getcellindir(dst, dir);
|
|
}
|
|
// add object
|
|
addob(dst->obpile, what);
|
|
}
|
|
}
|
|
|
|
void genhiddennames(void) {
|
|
objecttype_t *ot;
|
|
flag_t *f;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
f = hasflag(ot->flags, F_HASHIDDENNAME);
|
|
if (f) {
|
|
int n;
|
|
int gotcolour = B_FALSE;
|
|
char *thisname;
|
|
if (strlen(f->text)) {
|
|
thisname = strdup(f->text);
|
|
} else {
|
|
thisname = genhiddenname(ot->obclass->id);
|
|
}
|
|
addknowledge(ot->id, thisname, B_UNKNOWN);
|
|
// some descriptions confer other effecst too...
|
|
if (strstr(thisname, "glowing")) {
|
|
addflag(ot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
|
} else if (strstr(thisname, "flourescent")) {
|
|
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
|
} else if (strstr(thisname, "luminous")) {
|
|
addflag(ot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
|
}
|
|
|
|
// set colour based on hiddenname
|
|
for (n = 0; strlen(colour[n].name); n++) {
|
|
if (strstr(thisname, colour[n].name)) {
|
|
flag_t *gf;
|
|
gf = hasflag(ot->flags, F_GLYPH);
|
|
if (gf) {
|
|
gf->val[0] = colour[n].col;
|
|
} else {
|
|
char buf[2];
|
|
|
|
buf[0] = ot->obclass->glyph.ch;
|
|
buf[1] = '\0';
|
|
addflag(ot->flags, F_GLYPH, colour[n].col, NA, NA, buf);
|
|
gotcolour = B_TRUE;
|
|
//dblog("assigning colour %s to %s (%s)",colour[n].name, thisname, ot->name);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!gotcolour) {
|
|
for (n = 0; strlen(gemtype[n].name); n++) {
|
|
if (strstr(thisname, gemtype[n].name)) {
|
|
flag_t *gf;
|
|
gf = hasflag(ot->flags, F_GLYPH);
|
|
if (gf) {
|
|
gf->val[0] = gemtype[n].col;
|
|
} else {
|
|
char buf[2];
|
|
|
|
buf[0] = ot->obclass->glyph.ch;
|
|
buf[1] = '\0';
|
|
addflag(ot->flags, F_GLYPH, gemtype[n].col, NA, NA, buf);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
free(thisname);
|
|
}
|
|
}
|
|
}
|
|
|
|
char *genhiddenname(enum OBCLASS id) {
|
|
hiddenname_t *hn;
|
|
|
|
for (hn = firsthiddenname ; hn ; hn = hn->next) {
|
|
if (hn->obclass == id) {
|
|
if (!hn->used) {
|
|
// found one
|
|
hn->used = B_TRUE;
|
|
return hn->text;
|
|
}
|
|
}
|
|
}
|
|
|
|
assert("out of hidden names" == 0);
|
|
return NULL;
|
|
}
|
|
|
|
// returns -1 if object doesn't have the flag
|
|
int getcharges(object_t *o) {
|
|
flag_t *f;
|
|
int amt = -1;
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f) {
|
|
amt = f->val[0];
|
|
}
|
|
return amt;
|
|
}
|
|
|
|
int getobaccuracy(object_t *wep, lifeform_t *weilder) {
|
|
int acc;
|
|
flag_t *f;
|
|
|
|
acc = 100; // default accuracy of 100%
|
|
|
|
if (wep) {
|
|
// blessed weapons have better base accuracy
|
|
if (wep->blessed == B_BLESSED) acc += 50;
|
|
|
|
// override with weapon's (lack of) accuracy
|
|
f = hasflag(wep->flags, F_ACCURACY);
|
|
if (f) {
|
|
// ie. accuracy of 100% means no penalty
|
|
// ie. accuracy of 75% means 25% penalty
|
|
// etc
|
|
acc = f->val[0];
|
|
}
|
|
|
|
if (weilder) {
|
|
skill_t *sk;
|
|
// modify for weilder's skill
|
|
sk = getobskill(wep);
|
|
if (sk) {
|
|
enum SKILLLEVEL slev;
|
|
|
|
slev = getskill(weilder, sk->id);
|
|
if (hasflag(wep->flags, F_MASTERWORK)) {
|
|
if (slev < PR_ADEPT) slev++;
|
|
}
|
|
|
|
switch (slev) {
|
|
case PR_INEPT:
|
|
acc -= 30;
|
|
break;
|
|
case PR_NOVICE:
|
|
acc -= 10;
|
|
break;
|
|
case PR_BEGINNER:
|
|
acc -= 5;
|
|
break;
|
|
case PR_ADEPT:
|
|
break;
|
|
case PR_SKILLED:
|
|
acc += 25;
|
|
break;
|
|
case PR_EXPERT:
|
|
acc += 50;
|
|
break;
|
|
case PR_MASTER:
|
|
acc += 75;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// modify for attacker's level
|
|
if (wep->pile->owner) {
|
|
acc += (wep->pile->owner->level * 2);
|
|
}
|
|
}
|
|
return acc;
|
|
}
|
|
|
|
int getobbonus(object_t *o) {
|
|
flag_t *f;
|
|
int bonus = 0;
|
|
for (f = o->flags->first ; f ; f = f->next) {
|
|
if (f->id == F_BONUS) {
|
|
bonus += f->val[0];
|
|
}
|
|
}
|
|
return bonus;
|
|
}
|
|
|
|
// returns the skill associated with this object
|
|
skill_t *getobskill(object_t *o) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_USESSKILL);
|
|
if (f) {
|
|
return findskill(f->val[0]);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// returns value of obejcts, in gold
|
|
int getobvalue(object_t *o) {
|
|
float price;
|
|
flag_t *f;
|
|
int rarity = 0;
|
|
|
|
if (o->type->id == OT_GOLD) {
|
|
return o->amt;
|
|
}
|
|
|
|
// base value: weight * material value
|
|
price = (float)getobweight(o) * (float)getmaterialvalue(o->material->id);
|
|
//adjustprice(o->type, &price);
|
|
|
|
// fixed prices
|
|
f = hasflag(o->flags, F_VALUE);
|
|
if (f) {
|
|
price += f->val[0];
|
|
}
|
|
|
|
for (f = o->flags->first ; f ; f = f->next) {
|
|
// damage
|
|
if (f->id == F_DAM) {
|
|
int min,max;
|
|
getdamrange(f, &min, &max);
|
|
price += (max*5);
|
|
}
|
|
// armour rating
|
|
if (f->id == F_ARMOURRATING) {
|
|
float rating;
|
|
rating = (float)f->val[0];
|
|
price += (rating * 20.0);
|
|
}
|
|
// bonus/penalties
|
|
if (f->id == F_BONUS) {
|
|
price += (f->val[0] * 100);
|
|
}
|
|
// food
|
|
if (f->id == F_EDIBLE) {
|
|
price += ((float)f->val[1] / 5.0);
|
|
}
|
|
// one-off magical effects (linkspell) - use spell price
|
|
if (f->id == F_LINKSPELL) {
|
|
// spelllevel^2 * 20
|
|
price += (pow(getspelllevel(f->val[0]), 2) * 20);
|
|
// ...and spellbooks then cost triple
|
|
if (o->type->obclass->id == OC_BOOK) {
|
|
price *= 3;
|
|
} else if (o->type->obclass->id == OC_SCROLL) {
|
|
// do nothing
|
|
} else if (o->type->obclass->id == OC_WAND) {
|
|
price *= 2.25;
|
|
}
|
|
} else if (f->id == F_MANUALOF) {
|
|
price *= 124;
|
|
}
|
|
}
|
|
|
|
// rarity
|
|
rarity = getobrarity(o);
|
|
|
|
// potions
|
|
if (o->type->obclass->id == OC_POTION) {
|
|
// potion value is based on rarity
|
|
price += ((100 - rarity)*2.75);
|
|
} else if (o->type->obclass->id == OC_TOOLS) {
|
|
// tool value is based on rarity
|
|
price += ((100 - rarity)*5.75);
|
|
} else if (o->type->obclass->id == OC_TECH) {
|
|
// tech value is based on tech level & rarity
|
|
float multiplier = 1;
|
|
switch (gettechlevel(o)) {
|
|
case PR_INEPT:
|
|
multiplier = 3.25;
|
|
break; // do nothing
|
|
case PR_NOVICE:
|
|
multiplier = 5.25;
|
|
break;
|
|
case PR_BEGINNER:
|
|
multiplier = 6.25;
|
|
break;
|
|
case PR_ADEPT:
|
|
multiplier = 7.25;
|
|
break;
|
|
case PR_SKILLED:
|
|
multiplier = 8.25;
|
|
break;
|
|
case PR_EXPERT:
|
|
multiplier = 9.25;
|
|
break;
|
|
case PR_MASTER:
|
|
multiplier = 10.25;
|
|
break;
|
|
}
|
|
price += ((100 - rarity)*multiplier);
|
|
}
|
|
|
|
|
|
// TODO: conferred intrinsics - depends on which one
|
|
|
|
// TODO: conferred spells - use spell price * multiplier
|
|
|
|
// speical material prices like velvet, silk
|
|
if (strstr(o->type->name, "velvet")) {
|
|
price *= 1.5;
|
|
}
|
|
if (strstr(o->type->name, "silk")) {
|
|
price *= 2;
|
|
}
|
|
|
|
// rarity
|
|
if (rarity >= 70) {
|
|
price /= 1.5;
|
|
} else if (rarity <= 40) {
|
|
price *= 1.5;
|
|
} else if (rarity <= 20) {
|
|
price *= 2;
|
|
} else if (rarity <= 10) {
|
|
price *= 5;
|
|
}
|
|
|
|
// blessed/cursed
|
|
if (isblessed(o)) price *= 1.5;
|
|
if (iscursed(o)) price /= 3;
|
|
|
|
// minimum
|
|
if (price < 1) price = 1;
|
|
return (int) price;
|
|
}
|
|
|
|
/*
|
|
int getobtypevalue(objecttype_t *ot) {
|
|
float price;
|
|
if (ot->id == OT_GOLD) {
|
|
return 1;
|
|
}
|
|
// base value: weight * material value
|
|
price = (float)ot->weight * (float)getmaterialvalue(ot->material->id);
|
|
|
|
adjustprice(ot, &price);
|
|
return (int) price;
|
|
}
|
|
*/
|
|
|
|
// ie. "it has xxx accuracy"
|
|
char *getaccuracyname(int accpct) {
|
|
if (accpct >= 200) {
|
|
return "godlike";
|
|
} else if (accpct >= 150) {
|
|
return "incredible";
|
|
} else if (accpct >= 100) {
|
|
return "very good";
|
|
} else if (accpct >= 70) {
|
|
return "good";
|
|
} else if (accpct >= 50) {
|
|
return "average";
|
|
} else if (accpct >= 30) {
|
|
return "poor";
|
|
} else if (accpct >= 20) {
|
|
return "very poor";
|
|
} else if (accpct >= 0) {
|
|
return "incredibly poor";
|
|
} else {
|
|
return "a complete lack of";
|
|
}
|
|
}
|
|
|
|
|
|
object_t *getammo(lifeform_t *lf) {
|
|
object_t *o;
|
|
o = hasobwithflag(lf->pack, F_CURAMMO);
|
|
return o;
|
|
}
|
|
|
|
object_t *getrandomammo(lifeform_t *lf) {
|
|
object_t *gun;
|
|
object_t *o;
|
|
flag_t *f;
|
|
|
|
gun = getfirearm(lf);
|
|
if (!gun) {
|
|
return NULL;
|
|
}
|
|
// TODO: at the moment we are jsut picking the first
|
|
// possible ammo. Need to allow the player to
|
|
// pick a specific ammo to use. USe a flag on wep
|
|
// to do this? Or a flag on the player?
|
|
for (f = gun->flags->first ; f ; f = f->next) {
|
|
if (f->id == F_AMMOOB) {
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (o->type->id == f->val[0]) {
|
|
return o;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *getdamname(enum DAMTYPE damtype) {
|
|
switch (damtype) {
|
|
case DT_ALL: return "all damage";
|
|
case DT_ACID: return "acid";
|
|
case DT_BASH: return "bludgeoning";
|
|
case DT_BITE: return "bite";
|
|
case DT_CHOP: return "chopping";
|
|
case DT_COLD: return "cold";
|
|
case DT_CRUSH: return "crushing";
|
|
case DT_DIRECT: return "direct";
|
|
case DT_DECAY: return "decay";
|
|
case DT_ELECTRIC: return "electricity";
|
|
case DT_EXPLOSIVE: return "explosive";
|
|
case DT_FALL: return "falling";
|
|
case DT_FIRE: return "fire";
|
|
case DT_HOLY: return "holy";
|
|
case DT_LIGHT: return "light";
|
|
case DT_MAGIC: return "magical";
|
|
case DT_MELT: return "melting";
|
|
case DT_NECROTIC: return "lifedrain";
|
|
case DT_PETRIFY: return "petrification";
|
|
case DT_PIERCE: return "piercing";
|
|
case DT_POISON: return "poison";
|
|
case DT_POISONGAS: return "poison gas";
|
|
case DT_PROJECTILE: return "projectile";
|
|
case DT_SLASH: return "slashing";
|
|
case DT_TOUCH: return "touch";
|
|
case DT_UNARMED: return "unarmed";
|
|
case DT_WATER: return "water";
|
|
default: return "unknown";
|
|
}
|
|
return "unknown";
|
|
}
|
|
|
|
char *getdamnamenoun(enum DAMTYPE damtype) {
|
|
switch (damtype) {
|
|
case DT_ALL: return "all damage";
|
|
case DT_ACID: return "acid";
|
|
case DT_MELT: return "melting";
|
|
case DT_PETRIFY: return "petrification";
|
|
case DT_PIERCE: return "piercing damage";
|
|
case DT_POISONGAS: return "poison gas";
|
|
case DT_POISON: return "poison";
|
|
case DT_SLASH: return "slashing damage";
|
|
case DT_ELECTRIC: return "electricity";
|
|
case DT_EXPLOSIVE: return "explosives";
|
|
case DT_FIRE: return "fire";
|
|
case DT_BITE: return "bite";
|
|
case DT_BASH: return "bludgeoning";
|
|
case DT_CHOP: return "chopping";
|
|
case DT_COLD: return "cold";
|
|
case DT_PROJECTILE: return "projectiles";
|
|
case DT_HOLY: return "holy damage";
|
|
case DT_DIRECT: return "direct damage";
|
|
case DT_DECAY: return "decay damage";
|
|
case DT_WATER: return "water";
|
|
case DT_MAGIC: return "magical damage";
|
|
case DT_NECROTIC: return "lifedrain damage";
|
|
case DT_TOUCH: return "touch effects";
|
|
case DT_UNARMED: return "unarmed damage";
|
|
case DT_LIGHT: return "light damage";
|
|
case DT_CRUSH: return "crushing damage";
|
|
case DT_FALL: return "damage from falling";
|
|
default: return "unknown";
|
|
}
|
|
return "unkmown";
|
|
}
|
|
|
|
char *gethiddenname(object_t *o) {
|
|
knowledge_t *k;
|
|
// if id'd, return the full name
|
|
if (hasflag(o->flags, F_IDENTIFIED)) {
|
|
return o->type->name;
|
|
}
|
|
// otherwise check if it has a hidden name
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (k->id == o->type->id) {
|
|
// it DOES have a hidden name.
|
|
// does the player know about it?
|
|
if (k->known == B_KNOWN) {
|
|
// if so, return real name
|
|
return o->type->name;
|
|
} else {
|
|
// otherwise return hidden one
|
|
return k->hiddenname;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// no hidden name, return real one
|
|
return o->type->name;
|
|
}
|
|
|
|
int getobattackdelay(object_t *o) {
|
|
int delay = 100; // ie. 100%
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_OBATTACKDELAY);
|
|
if (f) {
|
|
delay = f->val[0];
|
|
}
|
|
return delay;
|
|
}
|
|
|
|
float getobhppct(object_t *o) {
|
|
float pct;
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
pct = ((float) f->val[0] / (float) f->val[1]) * 100.0;
|
|
} else {
|
|
pct = 100;
|
|
}
|
|
return pct;
|
|
}
|
|
|
|
int getletidx(char let) {
|
|
int i;
|
|
for (i = 0; i < MAXPILEOBS; i++) {
|
|
if (letorder[i] == let) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int getmaterialvalue(enum MATERIAL mat) {
|
|
switch (mat) {
|
|
case MT_NOTHING:
|
|
case MT_MAGIC:
|
|
case MT_FIRE:
|
|
case MT_GAS:
|
|
case MT_ACID:
|
|
return 0;
|
|
case MT_FOOD:
|
|
case MT_ICE:
|
|
case MT_STONE:
|
|
return 1;
|
|
case MT_WATER:
|
|
return 1;
|
|
case MT_FLESH:
|
|
case MT_BONE:
|
|
case MT_BLOOD:
|
|
case MT_SLIME:
|
|
case MT_WAX:
|
|
case MT_OIL:
|
|
return 2;
|
|
case MT_CLOTH:
|
|
case MT_LEATHER:
|
|
return 2;
|
|
case MT_WOOD:
|
|
return 3;
|
|
case MT_PAPER:
|
|
case MT_WETPAPER:
|
|
return 4;
|
|
case MT_PLASTIC:
|
|
case MT_RUBBER:
|
|
case MT_GLASS:
|
|
case MT_SILK:
|
|
return 5;
|
|
case MT_METAL:
|
|
return 6;
|
|
case MT_GOLD:
|
|
return 7;
|
|
}
|
|
// default
|
|
return 1;
|
|
}
|
|
|
|
int getmaxthrowrange(lifeform_t *lf, object_t *o) {
|
|
int maxdist;
|
|
float strmod;
|
|
float modobweight;
|
|
// adjust for lifeform strength
|
|
// mighty = div by 10
|
|
|
|
// this will give us a number in range -44 - 50
|
|
strmod = getstatmod(lf, A_STR);
|
|
// this will give us a number in range 1 - 10
|
|
strmod /= 5;
|
|
if (strmod < 1) strmod = 1;
|
|
|
|
modobweight = getobunitweight(o) / 2;
|
|
modobweight /= strmod;
|
|
|
|
maxdist = 10 - modobweight;
|
|
|
|
if (maxdist < 0) maxdist = 0;
|
|
return maxdist;
|
|
}
|
|
|
|
// select lowest possible letter
|
|
char getnextletter(obpile_t *op, char *wantletter) {
|
|
int curidx = -1;
|
|
char let;
|
|
//int db = B_FALSE;
|
|
|
|
// try 'wantletter' first
|
|
if (wantletter && (*wantletter != '\0')) {
|
|
if (!pilehasletter(op, *wantletter)) {
|
|
return *wantletter;
|
|
}
|
|
}
|
|
|
|
curidx = 0; // ie 'a'
|
|
|
|
for (curidx = 0; curidx < MAXPILEOBS; curidx++) {
|
|
// does any other object in the pile have this letter?
|
|
let = letorder[curidx];
|
|
if (!pilehasletter(op, let)) {
|
|
// if we didn't find it, this letter is okay.
|
|
return let;
|
|
}
|
|
}
|
|
|
|
return '\0';
|
|
}
|
|
|
|
|
|
int getnumshards(object_t *o) {
|
|
int numshards,maxshards;
|
|
maxshards = ceil(getobunitweight(o)) * 10;
|
|
if (maxshards < 1) maxshards = 1;
|
|
numshards = rnd(1,maxshards);
|
|
numshards *= o->amt;
|
|
return numshards;
|
|
}
|
|
|
|
int getnutritionbase(object_t *o) {
|
|
float basenutr;
|
|
flag_t *f;
|
|
if (o->material->id == MT_ICE) {
|
|
// use the object's weight
|
|
basenutr = getobweight(o) * 10;
|
|
} else {
|
|
// use nutrition flag
|
|
f = hasflag(o->flags, F_EDIBLE);
|
|
if (!f) {
|
|
f = hasflag(o->flags, F_DRINKABLE);
|
|
}
|
|
|
|
if (f) {
|
|
basenutr = (float)f->val[1];
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return basenutr;
|
|
}
|
|
|
|
int getnutrition(object_t *o) {
|
|
float nutrpct;
|
|
float nutrition;
|
|
|
|
if (isrotting(o)) {
|
|
nutrition = -(HUNGERCONST/2);
|
|
} else {
|
|
nutrpct = getnutritionbase(o);
|
|
|
|
if (nutrpct <= 0) {
|
|
nutrition = 0;
|
|
} else {
|
|
nutrition = pctof(nutrpct, (float) HUNGERCONST);
|
|
}
|
|
}
|
|
|
|
if (hasflag(o->flags, F_HEADLESS)) {
|
|
// -25% nutrition
|
|
nutrition *= 0.75;
|
|
}
|
|
|
|
return (int)nutrition;
|
|
}
|
|
|
|
char *getobdesc(object_t *o, char *buf) {
|
|
if (isknown(o)) {
|
|
if (o->type->id == OT_CORPSE) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(buf, "The dead body of %s %s.", isvowel(corpserace->name[0]) ? "an" : "a",
|
|
corpserace->name);
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else if (o->type->id == OT_HEAD) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(buf, "The decapitated head of %s %s.", isvowel(corpserace->name[0]) ? "an" : "a",
|
|
corpserace->name);
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else if (o->type->id == OT_STATUE) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(buf, "A stone statue of %s %s.", isvowel(corpserace->name[0]) ? "an" : "a",
|
|
corpserace->name);
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else if (o->type->id == OC_SCROLL) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_LINKSPELL);
|
|
if (f) {
|
|
objecttype_t *spelltype;
|
|
spelltype = findot(f->val[0]);
|
|
if (spelltype) {
|
|
sprintf(buf, "%s", spelltype->desc);
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else {
|
|
sprintf(buf, "%s", o->type->desc);
|
|
}
|
|
} else {
|
|
sprintf(buf, "%s", o->type->obclass->desc);
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
char *getobequipinfo(object_t *o, char *buf) {
|
|
object_t *ammo = NULL;
|
|
flag_t *f;
|
|
|
|
strcpy(buf, "");
|
|
|
|
if (o->pile->owner) {
|
|
ammo = getammo(o->pile->owner);
|
|
}
|
|
|
|
f = hasflag(o->flags,F_EQUIPPED);
|
|
if (f) {
|
|
if (f->val[0] == BP_WEAPON) {
|
|
if (hasflag(o->flags, F_TWOHANDED)) {
|
|
strcat(buf, " (two-handed weapon)");
|
|
} else {
|
|
strcat(buf, " (weapon)");
|
|
}
|
|
} else if (f->val[0] == BP_SECWEAPON) {
|
|
if (isshield(o)) {
|
|
strcat(buf, " (shield)");
|
|
} else if (ismeleeweapon(o)) {
|
|
strcat(buf, " (second weapon)");
|
|
} else if (isfirearm(o)) {
|
|
strcat(buf, " (firearm)");
|
|
} else {
|
|
strcat(buf, " (in left hand)");
|
|
}
|
|
} else {
|
|
strcat(buf, " (");
|
|
strcat(buf, getbodypartequipname(f->val[0]));
|
|
strcat(buf, " ");
|
|
strcat(buf, getbodypartname(f->val[0]));
|
|
strcat(buf, ")");
|
|
}
|
|
}
|
|
|
|
// ammo?
|
|
if (ammo && (ammo == o)) {
|
|
strcat(buf, " (current ammo)");
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
char *getobextrainfo(object_t *o, char *buf) {
|
|
object_t *ammo = NULL;
|
|
flag_t *f;
|
|
|
|
strcpy(buf, "");
|
|
|
|
if (o->pile->owner) {
|
|
ammo = getammo(o->pile->owner);
|
|
}
|
|
|
|
// charges
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f && f->known) {
|
|
if (!hasflag(o->flags, F_DONTSHOWCHARGES)) {
|
|
char chargestr[BUFLEN];
|
|
if (f->val[0] > 0) {
|
|
sprintf(chargestr, " (%d charges left)",f->val[0]);
|
|
} else {
|
|
sprintf(chargestr, " (empty)");
|
|
}
|
|
strcat(buf, chargestr);
|
|
}
|
|
}
|
|
|
|
// activated
|
|
f = hasflag(o->flags, F_ACTIVATED);
|
|
if (f) {
|
|
strcat(buf, " [activated]");
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
cell_t *getoblocation(object_t *o) {
|
|
if (o->pile->owner) return o->pile->owner->cell;
|
|
else return o->pile->where;
|
|
}
|
|
|
|
char *getobname(object_t *o, char *buf, int count) {
|
|
return real_getobname(o, buf, count, B_TRUE, B_TRUE, B_TRUE, B_TRUE, B_FALSE);
|
|
}
|
|
|
|
char *getobnametrue(object_t *o, char *buf, int count) {
|
|
return real_getobname(o, buf, count, B_TRUE, B_TRUE, B_FALSE, B_TRUE, B_TRUE);
|
|
}
|
|
|
|
// buf must already be allocated
|
|
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall) {
|
|
char *pluralname;
|
|
char prefix[BUFLEN];
|
|
char basename[BUFLEN];
|
|
char localbuf[BUFLEN];
|
|
char buf2[BUFLEN];
|
|
char triedbuf[BUFLEN];
|
|
int shopitem = B_FALSE;
|
|
flag_t *f;
|
|
brand_t *br;
|
|
obmod_t *om;
|
|
int hasunknownmod = B_FALSE;
|
|
cell_t *where;
|
|
|
|
// default to normal name
|
|
if (hasflag(o->flags, F_SHOPITEM)) {
|
|
shopitem = B_TRUE;
|
|
}
|
|
|
|
where = getoblocation(o);
|
|
|
|
if (shopitem) {
|
|
showall = B_TRUE;
|
|
}
|
|
|
|
if (showall) {
|
|
strcpy(basename,o->type->name);
|
|
} else {
|
|
strcpy(basename,gethiddenname(o));
|
|
}
|
|
|
|
if (!showall) {
|
|
if ((gamemode == GM_GAMESTARTED) && adjustforblind && !haslos(player, where) ) {
|
|
// override with obclass names
|
|
switch (o->type->obclass->id) {
|
|
case OC_BOOK:
|
|
strcpy(basename, "book");
|
|
break;
|
|
case OC_POTION:
|
|
strcpy(basename, "potion");
|
|
break;
|
|
case OC_RING:
|
|
strcpy(basename, "ring");
|
|
break;
|
|
case OC_SCROLL:
|
|
strcpy(basename, "scroll");
|
|
break;
|
|
case OC_WAND:
|
|
strcpy(basename, "wand");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (o->type->obclass->id == OC_RING) {
|
|
strcpy(basename, "ring");
|
|
} else if (o->type->obclass->id == OC_SCROLL) {
|
|
strcpy(basename, "scroll");
|
|
} else if (o->type->obclass->id == OC_POTION) {
|
|
strcpy(basename, "potion");
|
|
} else if (o->type->obclass->id == OC_RING) {
|
|
strcpy(basename, "ring");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if ((o->type->id == OT_POT_WATER) && (o->blessed == B_BLESSED) && isblessknown(o) && isknown(o)) {
|
|
strcpy(basename, "potion of holy water");
|
|
}
|
|
if ((o->type->id == OT_POT_COMPETENCE) && (o->blessed == B_CURSED) && isblessknown(o) && isknown(o)) {
|
|
strcpy(basename, "potion of incompetence");
|
|
}
|
|
|
|
// override corpse name
|
|
if (o->type->id == OT_CORPSE) {
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(basename, "%s corpse",corpserace->name);
|
|
}
|
|
} else if (o->type->id == OT_HEAD) {
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(basename, "%s head",corpserace->name);
|
|
}
|
|
} else if (o->type->id == OT_STATUE) {
|
|
f = hasflag(o->flags, F_CORPSEOF);
|
|
if (f) {
|
|
race_t *corpserace;
|
|
corpserace = findrace(f->val[0]);
|
|
sprintf(basename, "statue of a %s",corpserace->name);
|
|
}
|
|
}
|
|
|
|
// handle ALL
|
|
if (count == ALL) {
|
|
count = o->amt;
|
|
}
|
|
strcpy(localbuf, "");
|
|
|
|
// figure out pluralname
|
|
if ((count == 1) && !hasflag(o->flags, F_NO_A)) {
|
|
pluralname = strdup(basename);
|
|
} else {
|
|
// multiple objects?
|
|
if (hasflag(o->flags, F_NO_PLURAL)) {
|
|
pluralname = strdup(basename);
|
|
} else {
|
|
pluralname = makeplural(basename);
|
|
}
|
|
}
|
|
|
|
|
|
// blessed status
|
|
if (!hasflag(o->flags, F_NOBLESS) && wantblesscurse) {
|
|
if (showall || isblessknown(o)) {
|
|
switch (o->blessed) {
|
|
case B_BLESSED:
|
|
// blessed water is known as "holy water"
|
|
if ((o->type->id == OT_POT_WATER) && isknown(o)) {
|
|
} else {
|
|
strcat(localbuf, "blessed ");
|
|
}
|
|
break;
|
|
case B_UNCURSED:
|
|
strcat(localbuf, "uncursed ");
|
|
break;
|
|
case B_CURSED:
|
|
if ((o->type->id == OT_POT_COMPETENCE) && isknown(o)) {
|
|
} else {
|
|
strcat(localbuf, "cursed ");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// material changed?
|
|
if (o->material != o->type->material) {
|
|
switch (o->material->id) {
|
|
case MT_GOLD:
|
|
strcat(localbuf, "golden ");
|
|
break;
|
|
case MT_WOOD:
|
|
strcat(localbuf, "wooden ");
|
|
break;
|
|
default:
|
|
// strcat(localbuf, o->material->name);
|
|
// strcat(localbuf, " ");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// include mods (ie. a flaming sword)
|
|
if (wantpremods) {
|
|
for (om = firstobmod ; om; om = om->next) {
|
|
flag_t *omf;
|
|
int found = B_FALSE;
|
|
for (omf = om->flags->first ; omf ; omf = omf->next){
|
|
if (hasflagval(o->flags, omf->id, omf->val[0], omf->val[1], omf->val[2], NULL)) {
|
|
found = B_TRUE;
|
|
}
|
|
}
|
|
if (found) {
|
|
strcat(localbuf, om->prefix);
|
|
}
|
|
}
|
|
}
|
|
|
|
// condition
|
|
if (wantcondition) {
|
|
if (!hasflag(o->flags, F_NOOBDAMTEXT)) {
|
|
getobconditionname(o, buf2);
|
|
if (strlen(buf2) > 0) {
|
|
strcat(localbuf, buf2);
|
|
strcat(localbuf, " ");
|
|
}
|
|
}
|
|
}
|
|
|
|
// include enchantments (ie. a blessed +5 sword)
|
|
f = hasflag(o->flags, F_BONUS);
|
|
if (f && (f->known || showall)) {
|
|
char buf2[BUFLENSMALL];
|
|
int bonus;
|
|
bonus = f->val[0];
|
|
if (bonus != 0) {
|
|
sprintf(buf2, "%s%d ", (bonus < 0) ? "" : "+", bonus);
|
|
strcat(localbuf, buf2);
|
|
}
|
|
}
|
|
|
|
// special rings
|
|
if (isidentified(o)) {
|
|
switch (o->type->id) {
|
|
char buf2[BUFLENSMALL];
|
|
case OT_RING_CON:
|
|
case OT_RING_DEX:
|
|
case OT_RING_IQ:
|
|
case OT_RING_STR:
|
|
f = hasflag(o->flags, F_EQUIPCONFER);
|
|
if (f) {
|
|
sprintf(buf2, "+%d ",f->val[2]);
|
|
strcat(localbuf, buf2);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (issecretdoor(o)) {
|
|
strcat(localbuf, "secret ");
|
|
}
|
|
|
|
// object name
|
|
strcat(localbuf, pluralname);
|
|
free(pluralname);
|
|
|
|
// include mods if identified - ie. xxx of pyromania
|
|
for (br = firstbrand; br; br = br->next) {
|
|
if (hasflagval(o->flags, F_HASBRAND, br->id, NA, NA, NULL)) {
|
|
flag_t *brf;
|
|
int ok = B_TRUE;
|
|
// are all of the brand flags known?
|
|
for (brf = br->flags->first ; brf ; brf = brf->next) {
|
|
for (f = o->flags->first; f ; f = f->next) {
|
|
if ((f->id == brf->id) && (f->lifetime == FROMBRAND)) {
|
|
if (f->known || showall) {
|
|
} else {
|
|
ok = B_FALSE;
|
|
hasunknownmod = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ok) {
|
|
strcat(localbuf, br->suffix);
|
|
}
|
|
}
|
|
}
|
|
|
|
// make sure obname doesn't start with a space
|
|
while (localbuf[0] == ' ') {
|
|
strcpy(localbuf, localbuf + 1);
|
|
}
|
|
|
|
// show portal/stair destination
|
|
f = hasflag(o->flags, F_MAPLINK);
|
|
if (f && f->known) {
|
|
map_t *newmap;
|
|
newmap = findmap(f->val[0]);
|
|
if (newmap) {
|
|
char buf2[BUFLEN];
|
|
sprintf(buf2, " to level %d", newmap->depth);
|
|
strcat(localbuf, buf2);
|
|
}
|
|
}
|
|
|
|
// append inscription
|
|
if (o->inscription) {
|
|
strcat(localbuf, " {");
|
|
strcat(localbuf, o->inscription);
|
|
strcat(localbuf, "}");
|
|
}
|
|
|
|
// show if we've tried this
|
|
if (gamemode == GM_GAMESTARTED) {
|
|
strcpy(triedbuf, "");
|
|
if (istried(o)) {
|
|
if (strlen(triedbuf)) strcat(triedbuf, ", ");
|
|
else strcpy(triedbuf, " [");
|
|
strcat(triedbuf, "tried");
|
|
}
|
|
if (lfhasflagval(player, F_FAILEDINSPECT, o->type->id, NA, NA, NULL)) {
|
|
if (strlen(triedbuf)) strcat(triedbuf, ", ");
|
|
else strcpy(triedbuf, " [");
|
|
strcat(triedbuf, "inspected");
|
|
}
|
|
if (strlen(triedbuf)) {
|
|
strcat(triedbuf, "]");
|
|
strcat(localbuf, triedbuf);
|
|
}
|
|
|
|
// detect magic - append [magic]
|
|
if (lfhasflag(player, F_DETECTMAGIC)) {
|
|
if (ismagical(o)) {
|
|
strcat(localbuf, " [magic]");
|
|
}
|
|
}
|
|
}
|
|
|
|
// apply prefix now!
|
|
if ((count == 1) && !hasflag(o->flags, F_NO_A)) {
|
|
if (hasflag(o->flags, F_UNIQUE)) { // TODO: && o->identified
|
|
strcpy(prefix, "The");
|
|
} else {
|
|
if (needan(localbuf)) {
|
|
strcpy(prefix, "an");
|
|
} else {
|
|
strcpy(prefix, "a");
|
|
}
|
|
}
|
|
} else {
|
|
// multiple objects?
|
|
sprintf(prefix, "%d",count);
|
|
}
|
|
|
|
// prepend prefix on to buf
|
|
sprintf(buf, "%s %s", prefix, localbuf);
|
|
|
|
return buf;
|
|
}
|
|
|
|
float getobpileweight(obpile_t *op) {
|
|
object_t *o;
|
|
float weight = 0;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
weight += getobweight(o);
|
|
}
|
|
return weight;
|
|
}
|
|
|
|
char *getobconditionname(object_t *o, char *buf) {
|
|
float pct;
|
|
enum IQBRACKET iqb;
|
|
if (player) {
|
|
iqb = getiqname(getattr(player, A_IQ), NULL);
|
|
} else {
|
|
iqb = IQ_AVERAGE; // this should be sufficient to show everything
|
|
}
|
|
|
|
if (iscorpse(o)) {
|
|
// you only know it's rotting if you are smart
|
|
if (isrotting(o) && (iqb >= IQ_SMART)) {
|
|
sprintf(buf, "rotting");
|
|
} else {
|
|
strcpy(buf, "");
|
|
}
|
|
} else {
|
|
if (iqb >= IQ_DIMWITTED) {
|
|
|
|
pct = getobhppct(o);
|
|
|
|
if (pct >= 100) {
|
|
strcpy(buf, "");
|
|
} else if (pct >= 75) {
|
|
sprintf(buf, "battered");
|
|
} else if (pct >= 50) {
|
|
sprintf(buf, "damaged");
|
|
} else if (pct >= 25) {
|
|
sprintf(buf, "very damaged");
|
|
} else {
|
|
sprintf(buf, "critically damaged");
|
|
}
|
|
} else {
|
|
strcpy(buf, "");
|
|
}
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
char *getobhurtname(object_t *o, enum DAMTYPE damtype) {
|
|
switch (damtype) {
|
|
case DT_ACID:
|
|
if (o->amt == 1) {
|
|
return "corrodes";
|
|
} else {
|
|
return "corrode";
|
|
}
|
|
case DT_DECAY:
|
|
if (o->amt == 1) {
|
|
return "decays";
|
|
} else {
|
|
return "decay";
|
|
}
|
|
case DT_FIRE:
|
|
if (o->amt == 1) {
|
|
return "burns";
|
|
} else {
|
|
return "burn";
|
|
}
|
|
case DT_MELT:
|
|
if (o->amt == 1) {
|
|
return "is melting";
|
|
} else {
|
|
return "are melting";
|
|
}
|
|
default:
|
|
if (o->amt == 1) {
|
|
return "is damaged";
|
|
} else {
|
|
return "are damaged";
|
|
}
|
|
}
|
|
return "is damaged";
|
|
}
|
|
|
|
float getobweight(object_t *o) {
|
|
float weight;
|
|
|
|
weight = getobunitweight(o) * o->amt;
|
|
|
|
return weight;
|
|
}
|
|
|
|
float getobunitweight(object_t *o) {
|
|
float weight;
|
|
flag_t *f;
|
|
|
|
weight = o->weight;
|
|
|
|
// has its material been changed?
|
|
if (o->material != o->type->material) {
|
|
// changed - some materials will
|
|
// modify the item's weight
|
|
float ratio;
|
|
ratio = o->material->weightrating / o->type->material->weightrating;
|
|
|
|
weight *= ratio;
|
|
}
|
|
|
|
f = hasflag(o->flags, F_WET);
|
|
if (f) {
|
|
switch (f->val[0]) {
|
|
case W_DAMP:
|
|
weight *= 1.05;
|
|
break;
|
|
case W_WET:
|
|
weight *= 1.25;
|
|
break;
|
|
case W_SOAKED:
|
|
weight *= 1.5;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return weight;
|
|
}
|
|
|
|
objecttype_t *getoppositestairs(objecttype_t *ot) {
|
|
flag_t *f;
|
|
f = hasflag(ot->flags, F_OPPOSITESTAIRS);
|
|
assert(f);
|
|
return findot(f->val[0]);
|
|
}
|
|
|
|
char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth) {
|
|
objecttype_t *ot;
|
|
objecttype_t *poss[MAXRANDOMOBCANDIDATES];
|
|
int nposs = 0;
|
|
int selidx;
|
|
int amt;
|
|
flag_t *f;
|
|
int db = B_FALSE;
|
|
char *pluralname;
|
|
char brandname[BUFLEN];
|
|
char cursestr[BUFLEN];
|
|
int raritymin,raritymax;
|
|
int depth;
|
|
int done = B_FALSE;
|
|
obmod_t *om;
|
|
flag_t *omposs[MAXCANDIDATES];
|
|
int noms = 0;
|
|
|
|
|
|
if (forcedepth != NA) {
|
|
depth = forcedepth;
|
|
} else if (map) {
|
|
depth = map->depth;
|
|
} else {
|
|
depth = rnd(1,MAXDEPTH);
|
|
}
|
|
|
|
getrarity(depth, &raritymin, &raritymax, RARITYVARIANCEOB, B_TRUE);
|
|
|
|
while (!done) {
|
|
if (db) dblog("adding random object with rarity value between %d - %d",raritymin,raritymax);
|
|
if (db) {
|
|
objectclass_t *oc;
|
|
switch (cond) {
|
|
case RO_DAMTYPE:
|
|
dblog(" (must have damtype = %s)",getdamname(cval));
|
|
break;
|
|
case RO_OBCLASS:
|
|
oc = findoc(cval);
|
|
dblog(" (must have obclass = %s)",oc->name);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// try to find an object of this type which will
|
|
// fit in the map's habitat
|
|
nposs = 0;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
int rarok = B_FALSE, condok = B_FALSE;
|
|
flag_t *rarflag = NULL;
|
|
// correct rarity?
|
|
|
|
rarflag = hasflagval(ot->flags, F_RARITY, H_ALL, NA, NA, NULL);
|
|
if (!rarflag) {
|
|
if (map) {
|
|
rarflag = hasflagval(ot->flags, F_RARITY, map->habitat, NA, NA, NULL);
|
|
} else {
|
|
rarflag = hasflagval(ot->flags, F_RARITY, NA, NA, NA, NULL);
|
|
}
|
|
}
|
|
if (rarflag) {
|
|
if ((rarflag->val[1] >= raritymin) && (rarflag->val[1] <= raritymax)) {
|
|
rarok = B_TRUE;
|
|
}
|
|
}
|
|
|
|
if (rarok) {
|
|
// matches condition?
|
|
if (cond == RO_NONE) {
|
|
condok = B_TRUE;
|
|
} else if (cond == RO_DAMTYPE) {
|
|
if (hasflagval(ot->flags, F_DAM, cval, NA, NA, NULL)) {
|
|
condok = B_TRUE;
|
|
}
|
|
} else if (cond == RO_OBCLASS) {
|
|
if (ot->obclass->id == cval) {
|
|
condok = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (rarok && condok) {
|
|
//if (db) dblog("-> possibility: %s, rarity=%d",ot->name, rarflag->val[1]);
|
|
poss[nposs] = ot;
|
|
nposs++;
|
|
if (nposs >= MAXRANDOMOBCANDIDATES) break;
|
|
}
|
|
}
|
|
|
|
// nothing found?
|
|
if (nposs == 0) {
|
|
// already at lowest rarity?
|
|
if ((raritymax >= 100) && (raritymin <= 0)) {
|
|
// give up
|
|
strcpy(buf, "");
|
|
if (db) dblog("no possible objects at all! giving up.");
|
|
return NULL;
|
|
}
|
|
|
|
// expand range and try again
|
|
raritymax += 10; if (raritymax > 100) raritymax = 100;
|
|
raritymin -= 10; if (raritymin < 0) raritymin = 0;
|
|
if (db) dblog("no possible objects like this. trying again with rarity %d-%d\n",raritymin,raritymax);
|
|
} else {
|
|
// something found
|
|
done = B_TRUE;
|
|
}
|
|
} // end while !done
|
|
|
|
if (db) dblog("got %d possibilities.",nposs);
|
|
// pick a random object from our possiblities
|
|
selidx = rnd(0,nposs-1);
|
|
ot = poss[selidx];
|
|
// handle objects which appear in multiples (ie. rocks)
|
|
f = hasflag(ot->flags, F_NUMAPPEAR);
|
|
if (f) {
|
|
amt = rnd(f->val[0], f->val[1]);
|
|
} else {
|
|
amt = 1;
|
|
}
|
|
|
|
if (amt > 1) {
|
|
pluralname = makeplural(ot->name);
|
|
} else {
|
|
pluralname = strdup(ot->name);
|
|
}
|
|
|
|
// blessed or cursed?
|
|
strcpy(cursestr, "");
|
|
if (!hasflag(ot->flags, F_NOBLESS)) {
|
|
int num;
|
|
num = rnd(1,100);
|
|
if (num <= 15) {
|
|
strcpy(cursestr, "blessed ");
|
|
} else if (num <= 30) {
|
|
strcpy(cursestr, "cursed ");
|
|
}
|
|
}
|
|
|
|
|
|
if (hasflag(ot->flags, F_ENCHANTABLE)) {
|
|
char buf2[BUFLENSMALL];
|
|
int bonus = 0;
|
|
int dir,chance;
|
|
|
|
if (strstr(cursestr, "cursed")){ // cursed WILL have a negative bonus
|
|
bonus = -1; // always at least -1
|
|
chance = 25;
|
|
dir = -1;
|
|
} else if (strstr(cursestr, "blessed")) { // blessed/uncursed MAY have a bonus
|
|
chance = 30;
|
|
dir = 1;
|
|
} else {
|
|
chance = 25;
|
|
dir = 1;
|
|
}
|
|
while (rnd(1,100) <= chance) {
|
|
bonus += dir;
|
|
}
|
|
sprintf(buf2, "%s%d ", (bonus >= 0) ? "+" : "", bonus);
|
|
strcat(cursestr, buf2);
|
|
}
|
|
|
|
// random chance of having an obmod
|
|
for (om = firstobmod ; om ; om = om->next) {
|
|
if (!hasflag(ot->flags, F_NOQUALITY)) {
|
|
f = hasflagval(ot->flags, F_CANHAVEOBMOD, om->id, NA, NA, NULL);
|
|
if (f && (f->val[1] != NA)) {
|
|
omposs[noms] = f;
|
|
noms++;
|
|
}
|
|
}
|
|
}
|
|
if (noms) {
|
|
// pick a random one to maybe apply
|
|
f = omposs[rnd(0,noms-1)];
|
|
if (rnd(1,100) <= f->val[1]) {
|
|
om = findobmod(f->val[0]);
|
|
if (om) {
|
|
strcat(cursestr, om->prefix);
|
|
}
|
|
}
|
|
}
|
|
|
|
// get random chance of having a brand (1% per depth)...
|
|
// if so...
|
|
strcpy(brandname, "");
|
|
if (rnd(1,100) <= depth) {
|
|
brand_t *om, **poss;
|
|
int numom;
|
|
int nposs = 0;
|
|
|
|
// count number of brands
|
|
numom = 0;
|
|
for (om = firstbrand ; om ; om = om->next) {
|
|
numom++;
|
|
}
|
|
poss = malloc(numom * sizeof(brand_t *));
|
|
|
|
for (om = firstbrand ; om ; om = om->next) {
|
|
if (brandappliesto(om, ot)) {
|
|
poss[nposs] = om;
|
|
nposs++;
|
|
}
|
|
}
|
|
|
|
if (nposs > 0) {
|
|
om = poss[rnd(0,nposs-1)];
|
|
strcpy(brandname, om->suffix);
|
|
}
|
|
free(poss);
|
|
}
|
|
|
|
|
|
sprintf(buf, "%d %s%s%s", amt, cursestr, pluralname,brandname);
|
|
|
|
|
|
if (db) dblog("random ob: %d x %s ('%s')", amt, ot->name,pluralname);
|
|
free(pluralname);
|
|
return buf;
|
|
}
|
|
|
|
char *getrandomob(map_t *map, char *buf) {
|
|
return real_getrandomob(map, buf, RO_NONE, NA, NA);
|
|
}
|
|
|
|
char *getrandomobwithdt(map_t *map, enum DAMTYPE damtype, char *buf) {
|
|
return real_getrandomob(map, buf, RO_DAMTYPE, damtype, NA);
|
|
}
|
|
|
|
char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf) {
|
|
return real_getrandomob(map, buf, RO_OBCLASS, cid, NA);
|
|
}
|
|
|
|
int getobrarity(object_t *o) {
|
|
cell_t *c;
|
|
map_t *m = NULL;
|
|
flag_t *f;
|
|
// check for rarity on this object's map first
|
|
c = getoblocation(o);
|
|
if (c) {
|
|
m = c->map;
|
|
}
|
|
if (m) {
|
|
f = hasflagval(o->flags, F_RARITY,m->habitat, NA, NA, NULL);
|
|
if (f) {
|
|
return f->val[0];
|
|
}
|
|
}
|
|
// any rarity value at all?
|
|
f = hasflag(o->flags, F_RARITY);
|
|
if (f) {
|
|
return f->val[0];
|
|
}
|
|
// ie. doesn't randomly appear
|
|
return 0;
|
|
}
|
|
|
|
enum SPELLSCHOOL getschool(enum OBTYPE sid) {
|
|
objecttype_t *ot;
|
|
ot = findot(sid);
|
|
if (ot) {
|
|
flag_t *f;
|
|
f = hasflag(ot->flags, F_SPELLSCHOOL);
|
|
if (f) {
|
|
return f->val[0];
|
|
}
|
|
}
|
|
return SS_NONE;
|
|
}
|
|
|
|
char *getschoolname(enum SPELLSCHOOL sch) {
|
|
switch (sch) {
|
|
case SS_ABILITY: return "Abilities";
|
|
case SS_ALLOMANCY: return "Allomancy";
|
|
case SS_DIVINE: return "Divine Powers";
|
|
case SS_WILD: return "Wild Magic";
|
|
case SS_MENTAL: return "Psionic Powers";
|
|
case SS_AIR: return "Elemental/Air Magic";
|
|
case SS_FIRE: return "Elemental/Fire Magic";
|
|
case SS_COLD: return "Elemental/Cold Magic";
|
|
case SS_MODIFICATION: return "Modification Magic";
|
|
case SS_DEATH: return "Necromancy";
|
|
case SS_NATURE: return "Nature";
|
|
case SS_LIFE: return "Life Magic";
|
|
case SS_DIVINATION: return "Divination Magic";
|
|
case SS_TRANSLOCATION: return "Translocation Magic";
|
|
case SS_SUMMONING: return "Summoning Magic";
|
|
case SS_GRAVITY: return "Gravitation Magic";
|
|
case SS_LAST: return "!invalid school!";
|
|
default:
|
|
break;
|
|
}
|
|
return "unknown school";
|
|
}
|
|
|
|
char *getschoolnameshort(enum SPELLSCHOOL sch) {
|
|
switch (sch) {
|
|
case SS_ABILITY: return "Abilities";
|
|
case SS_ALLOMANCY: return "Allomancy";
|
|
case SS_DIVINE: return "Divine Powers";
|
|
case SS_WILD: return "Wild Magic";
|
|
case SS_AIR: return "Air Magic";
|
|
case SS_FIRE: return "Fire Magic";
|
|
case SS_COLD: return "Cold Magic";
|
|
case SS_DEATH: return "Necromancy";
|
|
case SS_LIFE: return "Life Magic";
|
|
case SS_MENTAL: return "Psionic Powers";
|
|
case SS_MODIFICATION: return "Modification";
|
|
case SS_NATURE: return "Nature";
|
|
case SS_DIVINATION: return "Divination";
|
|
case SS_TRANSLOCATION: return "Translocation";
|
|
case SS_SUMMONING: return "Summoning";
|
|
case SS_GRAVITY: return "Gravitation";
|
|
case SS_LAST: return "!invalid school!";
|
|
default:
|
|
break;
|
|
}
|
|
return "unknown school";
|
|
}
|
|
|
|
int getshatterdam(object_t *o) {
|
|
int shatterdam = 0;
|
|
if (willshatter(o->material->id)) {
|
|
int maxshatterdam;
|
|
maxshatterdam = ceil(getobweight(o));
|
|
if (maxshatterdam < 1) maxshatterdam = 1;
|
|
|
|
shatterdam = rnd(1, maxshatterdam);
|
|
}
|
|
return shatterdam;
|
|
}
|
|
|
|
enum SKILLLEVEL gettechlevel(object_t *o) {
|
|
flag_t *f;
|
|
enum SKILLLEVEL tlev = PR_INEPT;
|
|
f = hasflag(o->flags, F_TECHLEVEL);
|
|
if (f) {
|
|
tlev = f->val[0];
|
|
}
|
|
return tlev;
|
|
}
|
|
|
|
int getthrowdam(object_t *o) {
|
|
double dam = 0;
|
|
flag_t *f;
|
|
|
|
// modify if it has a damage value
|
|
f = hasflag(o->flags, F_MISSILEDAM);
|
|
if (f) {
|
|
dam = f->val[0];
|
|
} else {
|
|
// base damage is = kilograms.
|
|
// ie. 1 kg object does 1 damage
|
|
// ie. 5 kg object does 5 damage
|
|
// ie. 100 kg object does 100 damage (person)
|
|
// ie. 1 tonne object does 1000 damage (car)
|
|
dam = ceil((double)getobunitweight(o));
|
|
// missile objects do extra damage
|
|
if (hasflag(o->flags, F_THROWMISSILE)) {
|
|
dam *= 2;
|
|
}
|
|
// max
|
|
if (dam > 20) dam = 20;
|
|
}
|
|
|
|
// modify for bonus
|
|
f = hasflag(o->flags, F_BONUS);
|
|
if (f) {
|
|
dam += f->val[0];
|
|
}
|
|
|
|
// note: damage will also be modified based on speed in fireat()
|
|
|
|
// adjust for material
|
|
switch (o->material->id) {
|
|
// soft materials do less damage
|
|
case MT_PAPER:
|
|
case MT_WETPAPER:
|
|
case MT_CLOTH:
|
|
dam /= 2;
|
|
break;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return (int)dam;
|
|
}
|
|
|
|
enum BODYPART getweildloc(object_t *o, enum BODYPART *otherloc, int *twohanded) {
|
|
enum BODYPART weildloc;
|
|
if (o) {
|
|
if (hasflag(o->flags, F_FIREARM)) {
|
|
weildloc = BP_SECWEAPON;
|
|
} else {
|
|
weildloc = BP_WEAPON;
|
|
}
|
|
if (twohanded) {
|
|
if (hasflag(o->flags, F_TWOHANDED)) {
|
|
*twohanded = B_TRUE;
|
|
} else {
|
|
*twohanded = B_FALSE;
|
|
}
|
|
}
|
|
} else {
|
|
// ie. unarmed
|
|
weildloc = BP_WEAPON;
|
|
if (twohanded) *twohanded = B_FALSE;
|
|
}
|
|
|
|
|
|
if (otherloc) {
|
|
if (weildloc == BP_WEAPON) {
|
|
*otherloc = BP_SECWEAPON;
|
|
} else {
|
|
*otherloc = BP_WEAPON;
|
|
}
|
|
}
|
|
|
|
return weildloc;
|
|
}
|
|
|
|
int hasedibleob(obpile_t *op) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (isedible(o)) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
object_t *hasknownob(obpile_t *op, enum OBTYPE oid) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->type->id == oid) {
|
|
if (isknown(o)) {
|
|
return o;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *hasob(obpile_t *op, enum OBTYPE oid) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->type->id == oid) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *hasobletter(obpile_t *op, char letter) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->letter == letter) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *hasobofclass(obpile_t *op, enum OBCLASS cid) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->type->obclass->id == cid) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *hasobmulti(obpile_t *op, enum OBTYPE *oid, int noids) {
|
|
object_t *o;
|
|
int n;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
for (n = 0; n < noids; n++) {
|
|
if (o->type->id == oid[n]) return o;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
object_t *hasobwithflag(obpile_t *op, enum FLAG flagid) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (hasflag(o->flags, flagid)) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
object_t *hasobwithflagval(obpile_t *op, enum FLAG flagid, int val0, int val1, int val2, char *text) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (hasflagval(o->flags, flagid, val0, val1, val2, text)) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
object_t *hasobid(obpile_t *op, int id) {
|
|
object_t *o;
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->id == id) return o;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// fully identify a single object.
|
|
void identify(object_t *o) {
|
|
flag_t *f;
|
|
if (!isknown(o)) {
|
|
makeknown(o->type->id);
|
|
}
|
|
addflag(o->flags, F_IDENTIFIED, B_TRUE, -1, -1, NULL);
|
|
o->blessknown = B_TRUE;
|
|
for (f = o->flags->first ; f ; f = f->next) {
|
|
if (!f->known) f->known = B_TRUE;
|
|
}
|
|
}
|
|
|
|
void ignite(object_t *o) {
|
|
flag_t *f,*ff;
|
|
char convertto[BUFLEN];
|
|
int howlong = 3; // default
|
|
|
|
strcpy(convertto, ""); // default
|
|
ff = hasflag(o->flags, F_FLAMMABLE);
|
|
if (ff) {
|
|
howlong = ff->val[0];
|
|
strcpy(convertto, ff->text);
|
|
}
|
|
|
|
|
|
f = hasflag(o->flags, F_ONFIRE);
|
|
if (!f) {
|
|
if (strlen(convertto)) {
|
|
cell_t *where;
|
|
object_t *newob;
|
|
|
|
where = getoblocation(o);
|
|
// change
|
|
newob = addob(where->obpile, convertto);
|
|
|
|
if (newob) {
|
|
// announce
|
|
if (haslos(player, where)) {
|
|
char obname[BUFLEN];
|
|
char newobname[BUFLEN];
|
|
getobname(o, obname, o->amt);
|
|
getobname(newob, newobname, newob->amt);
|
|
msg("%s ignites into %s!",obname,newobname);
|
|
}
|
|
// kill old ob
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
addflag(o->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
}
|
|
} else {
|
|
// make it damagable, if it isn't already.
|
|
if (!hasflag(o->flags, F_DAMAGABLE)) {
|
|
addflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
}
|
|
// on fire for 3 turns
|
|
addtempflag(o->flags, F_ONFIRE, B_TRUE, NA, NA, NULL, howlong);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void initobjects(void) {
|
|
//int ch;
|
|
int i,n;
|
|
objecttype_t *ot;
|
|
|
|
// generate hidden names
|
|
for (n = 0; strlen(colour[n].name); n++) {
|
|
char buf[BUFLEN];
|
|
// add it without an adjective
|
|
sprintf(buf, "%s book", colour[n].name);
|
|
addhiddenname(OC_BOOK, buf);
|
|
// add it with all known adjectives
|
|
for (i = 0; strlen(bookadjective[i]) ; i++) {
|
|
sprintf(buf, "%s %s book",bookadjective[i], colour[n].name);
|
|
addhiddenname(OC_BOOK, buf);
|
|
}
|
|
}
|
|
|
|
addhiddenname(OC_SCROLL, "scroll titled ABRA CA DABRA");
|
|
addhiddenname(OC_SCROLL, "scroll titled BARBAR");
|
|
addhiddenname(OC_SCROLL, "scroll titled CRATOL JEM");
|
|
addhiddenname(OC_SCROLL, "scroll titled DELENTH YIN");
|
|
addhiddenname(OC_SCROLL, "scroll titled ETEE NOM");
|
|
addhiddenname(OC_SCROLL, "scroll titled FIE JOOHM");
|
|
addhiddenname(OC_SCROLL, "scroll titled GREE VII");
|
|
addhiddenname(OC_SCROLL, "scroll titled HERE HERE");
|
|
addhiddenname(OC_SCROLL, "scroll titled HTEB IH");
|
|
addhiddenname(OC_SCROLL, "scroll titled HOCUS POCUS");
|
|
addhiddenname(OC_SCROLL, "scroll titled ILU-MA ZEE");
|
|
addhiddenname(OC_SCROLL, "scroll titled JUNIPO CHECK");
|
|
addhiddenname(OC_SCROLL, "scroll titled KARELS");
|
|
addhiddenname(OC_SCROLL, "scroll titled LUMLEE GWON");
|
|
addhiddenname(OC_SCROLL, "scroll titled MARIGON");
|
|
addhiddenname(OC_SCROLL, "scroll titled MAXIMOR BLATHUS");
|
|
addhiddenname(OC_SCROLL, "scroll titled NORTH");
|
|
addhiddenname(OC_SCROLL, "scroll titled ORI GREEBLE");
|
|
addhiddenname(OC_SCROLL, "scroll titled POCUS HOCUS");
|
|
addhiddenname(OC_SCROLL, "scroll titled QUANDRILAR");
|
|
addhiddenname(OC_SCROLL, "scroll titled REZZ KINETO");
|
|
addhiddenname(OC_SCROLL, "scroll titled SHAZZARIO");
|
|
addhiddenname(OC_SCROLL, "scroll titled THERIUM LARGOS");
|
|
addhiddenname(OC_SCROLL, "scroll titled TAKA TAKA TAKA");
|
|
addhiddenname(OC_SCROLL, "scroll titled UNDWEL");
|
|
addhiddenname(OC_SCROLL, "scroll titled VOLTR YI MEN");
|
|
addhiddenname(OC_SCROLL, "scroll titled WII");
|
|
addhiddenname(OC_SCROLL, "scroll titled XAND");
|
|
addhiddenname(OC_SCROLL, "scroll titled YES");
|
|
addhiddenname(OC_SCROLL, "scroll titled ZAREL NOR");
|
|
|
|
addhiddenname(OC_POTION, "clear potion");
|
|
|
|
for (n = 0; strlen(colour[n].name); n++) {
|
|
char buf[BUFLEN];
|
|
// add it without an adjective
|
|
sprintf(buf, "%s potion", colour[n].name);
|
|
addhiddenname(OC_POTION, buf);
|
|
// add it with all known adjectives
|
|
for (i = 0; strlen(potadjective[i]) ; i++) {
|
|
sprintf(buf, "%s %s potion",potadjective[i], colour[n].name);
|
|
addhiddenname(OC_POTION, buf);
|
|
}
|
|
}
|
|
|
|
for (n = 0; strlen(gemtype[n].name); n++) {
|
|
char buf[BUFLEN];
|
|
// add it without an adjective
|
|
sprintf(buf, "%s wand", gemtype[n].name);
|
|
addhiddenname(OC_WAND, buf);
|
|
}
|
|
|
|
for (n = 0; strlen(gemtype[n].name); n++) {
|
|
char buf[BUFLEN];
|
|
// add it without an adjective
|
|
sprintf(buf, "%s ring", gemtype[n].name);
|
|
addhiddenname(OC_RING, buf);
|
|
}
|
|
|
|
for (n = 0; strlen(technoun[n]); n++) {
|
|
// add it without an adjective
|
|
addhiddenname(OC_TECH, technoun[n]);
|
|
// add it with all known adjectives
|
|
for (i = 0; strlen(techadjective[i]) ; i++) {
|
|
char buf[BUFLEN];
|
|
sprintf(buf, "%s %s",techadjective[i], technoun[n]);
|
|
addhiddenname(OC_TECH, buf);
|
|
}
|
|
}
|
|
|
|
shufflehiddennames();
|
|
|
|
|
|
// object modifiers - flags can be either known or not, depending on if it's obvious
|
|
addobmod(OM_BLOODSTAINED,"bloodstained");
|
|
addflag_real(lastobmod->flags, F_SCARY, 2, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_FLAMING,"flaming");
|
|
addflag_real(lastobmod->flags, F_ONFIRE, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_FROZEN,"frozen");
|
|
addflag_real(lastobmod->flags, F_FROZEN, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_HEADLESS,"headless");
|
|
addflag_real(lastobmod->flags, F_HEADLESS, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_MASTERWORK,"masterwork");
|
|
addflag_real(lastobmod->flags, F_MASTERWORK, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_SHODDY,"shoddy");
|
|
addflag_real(lastobmod->flags, F_SHODDY, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_POISONED,"poisoned");
|
|
addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, "15-30", PERMENANT, B_KNOWN, -1);
|
|
addflag_real(lastobmod->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_WET1,"damp");
|
|
addflag_real(lastobmod->flags, F_WET, W_DAMP, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_WET2,"wet");
|
|
addflag_real(lastobmod->flags, F_WET, W_WET, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_WET3,"soaked");
|
|
addflag_real(lastobmod->flags, F_WET, W_SOAKED, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_RUSTY1,"rusty");
|
|
addflag_real(lastobmod->flags, F_RUSTED, R_RUSTY, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_RUSTY2,"very rusty");
|
|
addflag_real(lastobmod->flags, F_RUSTED, R_VRUSTY, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
addobmod(OM_RUSTY3,"thoroughly rusty");
|
|
addflag_real(lastobmod->flags, F_RUSTED, R_TRUSTY, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
|
|
|
// brands modifiers - flags should be UNKNOWN!
|
|
// also don't double up with names of scrolls etc.
|
|
// ie. spellbook of flight, boots of flight.
|
|
addbrand(BR_BALANCE, "of balance", BP_WEAPON);
|
|
addflag_real(lastbrand->flags, F_BALANCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_PYROMANIA, "of pyromania", BP_WEAPON);
|
|
addflag_real(lastbrand->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_REVENGE, "of revenge", BP_WEAPON);
|
|
addflag_real(lastbrand->flags, F_REVENGE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_SHARPNESS, "of sharpness", BP_WEAPON);
|
|
addflag_real(lastbrand->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
|
|
addbrand(BR_LEVITATION, "of hovering", BP_FEET);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_LEVITATING, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_FEATHERFALL, "of featherfall", BP_FEET);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FALL, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
|
|
addbrand(BR_SWIFTNESS, "of swiftness", BP_FEET);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FASTMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_SLOTH, "of sloth", BP_FEET);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SLOWMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
|
|
addbrand(BR_POWER, "of power", BP_HANDS);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, 3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_WEAKNESS, "of feebleness", BP_HANDS);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, -3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_NIMBLENESS, "of nimbleness", BP_HANDS);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRMOD, A_DEX, 3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_IMPACT, "of impact", BP_WEAPON); // TODO: make thisonly go ont obashing weapons
|
|
addflag_real(lastbrand->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_THINKING, "of thinking", BP_HEAD);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_KNOWLEDGE, "of knowledge", BP_HEAD);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_DETECTAURAS, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_DETECTMAGIC, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_TELEPATHY, "of telepathy", BP_HEAD);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_DETECTLIFE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_TELEKINESIS, "of the poltergeist", BP_HEAD);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_CANWILL, OT_S_TELEKINESIS, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_GIANTSTRENGTH, "of giant strength", BP_WAIST);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRSET, A_STR, 18, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_FEEBLENESS, "of feebleness", BP_WAIST);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRSET, A_STR, 3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_FLIGHT, "of the eagle", BP_WAIST);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FLYING, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_SPEED, "of swiftness", BP_WAIST);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FASTACT, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_CONCEALMENT, "of concealment", BP_SHOULDERS);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_INVISIBLE, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_ANTIMAG, "of antimagic", BP_SHOULDERS);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_RESISTMAG, 10, NA, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
addbrand(BR_HEALTH, "of health", BP_BODY);
|
|
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 3, NULL, PERMENANT, B_UNKNOWN, -1);
|
|
|
|
// materials
|
|
addmaterial(MT_NOTHING, "nothing", 0);
|
|
addmaterial(MT_MAGIC, "magical energy", 0);
|
|
addmaterial(MT_FIRE, "fire", 0);
|
|
addmaterial(MT_GAS, "gas", 0.5);
|
|
addmaterial(MT_PAPER, "paper", 1);
|
|
addflag(lastmaterial->flags, F_MATCONVERT, MT_WATER, NA, NA, "lump of soggy paper");
|
|
addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_WATER, NA, NA, "goes soggy");
|
|
addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy");
|
|
addflag(lastmaterial->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL);
|
|
addmaterial(MT_SILK, "silk", 1);
|
|
addflag(lastmaterial->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); // doesn't catch on fire, but IS vulnerable to it
|
|
addflag(lastmaterial->flags, F_DTVULN, DT_ACID, NA, NA, NULL);
|
|
addmaterial(MT_FLESH, "flesh", 2);
|
|
addmaterial(MT_WETPAPER, "wet paper", 3);
|
|
addmaterial(MT_CLOTH, "cloth", 3);
|
|
addflag(lastmaterial->flags, F_FLAMMABLE, 3, NA, NA, NULL);
|
|
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_FOOD, "food", 3);
|
|
addmaterial(MT_PLASTIC, "plastic", 3);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, 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");
|
|
addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_FIRE, NA, NA, "melt");
|
|
addmaterial(MT_RUBBER, "rubber", 4);
|
|
addmaterial(MT_LEATHER, "leather", 4);
|
|
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_BONE, "bone", 5);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_OIL, "oil", 5);
|
|
addmaterial(MT_ICE, "ice",6);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_WOOD, "wood", 6);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, 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);
|
|
addmaterial(MT_WATER, "water", 7);
|
|
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);
|
|
addmaterial(MT_METAL, "metal", 13);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_GLASS, "glass", 13);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
|
addmaterial(MT_GOLD, "gold", 16);
|
|
addflag(lastmaterial->flags, F_HARD, B_TRUE, NA, NA, NULL);
|
|
//addmaterial(MT_GOLD, "gold", 16);
|
|
|
|
// object classes
|
|
addoc(OC_DFEATURE, "Dungeon Features", "Doors, etc.", '\\', C_GREY);
|
|
addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY);
|
|
addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY);
|
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
//addflag(lastobjectclass->flags, F_DTCONVERT, DT_WATER, NA, NA, "lump of soggy paper");
|
|
//addflag(lastobjectclass->flags, F_MATCONVERT, MT_WATER, NA, NA, "lump of soggy paper");
|
|
//addflag(lastobjectclass->flags, F_MATCONVERTTEXT, MT_WATER, NA, NA, "goes soggy");
|
|
//addflag(lastobjectclass->flags, F_MATCONVERTTEXTPL, MT_WATER, NA, NA, "go soggy");
|
|
|
|
addoc(OC_WAND, "Wands", "A limited-use magical wand which casts the imbued spell.", '/', C_GREY);
|
|
addflag(lastobjectclass->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_OPERUSECHARGE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_RNDCHARGES, 1, 8, NA, NULL);
|
|
|
|
addoc(OC_POTION, "Potions", "A strange concoction contained within a small flask.", '!', C_GREY);
|
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_POURABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_RING, "Rings", "A circular band, worn on the finger.", '=', C_GREY);
|
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_GOESON, BP_RIGHTHAND, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_GOESON, BP_LEFTHAND, NA, NA, NULL);
|
|
addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
|
addoc(OC_ARMOUR, "Armour/Clothing", "Protective gear.", ']', C_GREY);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_BLOODSTAINED, 17, NA, NULL);
|
|
addoc(OC_MISSILE, "Missiles/Ammunition", "An instrument used for the purpose of causing harm or death.", ';', C_GREY);
|
|
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_ROCK, "Rocks/Gems", "Boring (or not so boring) rocks.", '*', C_GREY);
|
|
addoc(OC_FOOD, "Food", "Yum!", '%', C_GREY);
|
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY);
|
|
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_OBHP, 50, 50, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_OBHPDRAIN, 1, DT_DECAY, NA, NULL); // ie. corpses last for 50 turns
|
|
addoc(OC_TECH, "Technology", "A strange piece of futuristic technology.", '~', C_GREY);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_TOOLS, "Tools", "Useful items, from the common to the obscure.", '[', C_GREY);
|
|
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_MISC, "Miscellaneous", "This could be anything.", '\\', C_GREY);
|
|
addoc(OC_EFFECT, "Environmental Effects", "Smoke, fire, etc.", '}', C_GREY);
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_BOOK, "Books", "Spellbooks, tomes or manuals.", '+', C_GREY);
|
|
addflag(lastobjectclass->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addoc(OC_SPELL, "Spells", "A magical spell", '&', C_GREY); // this is a "virtual" object class
|
|
addoc(OC_ABILITY, "Abilities", "A special ability", '&', C_GREY); // this is a "virtual" object class
|
|
|
|
|
|
// object types
|
|
|
|
// dungeon features
|
|
addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 150, OC_DFEATURE);
|
|
// GLYPH here is a special case in getglyph
|
|
addflag(lastot->flags, F_DOOR, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSTHROW, 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, 20, 20, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
|
|
|
addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE);
|
|
// GLYPH here is a special case in getglyph
|
|
addflag(lastot->flags, F_DOOR, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSTHROW, 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, 60, 60, NA, NULL);
|
|
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_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_DFEATURE);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "\\");
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_HUMAN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
|
//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, 10, 10, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, 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, "");
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "'");
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSTHROW, B_TRUE, NA, NA, NULL);
|
|
// 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_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones");
|
|
|
|
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_GLYPH, NA, NA, NA, "'");
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSTHROW, 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, 80, 80, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "20-50 stones");
|
|
|
|
addot(OT_STAIRSDOWN, "staircase going down", "A stone staircase winding downwards.", MT_STONE, 3000, OC_DFEATURE);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ">");
|
|
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_STAIRSUP, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_STAIRSUP, "staircase going up", "A stone staircase climbing upwards.", MT_STONE, 3000, OC_DFEATURE);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "<");
|
|
addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_STAIRSDOWN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_VENDINGMACHINE, "vending machine", "A gold-operated vending machine.", MT_METAL, 500, OC_MISC);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
|
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "_");
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_MISC);
|
|
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, NA, NA, "&");
|
|
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
|
|
// money etc
|
|
addot(OT_GOLD, "gold coin", "Sparkling nuggets of gold, the standard currency of Nexus.", MT_GOLD, 0.1, OC_MONEY);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 100, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 100, NA, "");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addot(OT_STONE, "stone", "A medium-sized roundish stone.", MT_STONE, 0.5, OC_ROCK);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
|
addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
|
|
addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
|
|
addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_XRAYVIS, 2, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_SEEINVIS, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_ENHANCESEARCH, 20, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_DETECTAURAS, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_DETECTMAGIC, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
|
|
// food
|
|
addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_ORANGE, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 8, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, "");
|
|
addot(OT_NUT, "peanut", "A species in the legume family.", MT_FOOD, 0.1, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 12, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, "");
|
|
addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
|
|
addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPMOVE, 15, NA, NA, NULL);
|
|
|
|
addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
addot(OT_MUSHROOM, "mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD);
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
|
addot(OT_BREADSTALE, "loaf of stale bread", "A small loaf of old, stale bread.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 80, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addot(OT_CHEESE, "chunk of cheese", "A chunk of hard cheese.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_YELLOW, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 85, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD); // weight normally comes from corpse type
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addot(OT_BREADFRESH, "loaf of fresh bread", "A freshly-baked loaf of bread.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addot(OT_CLOVER, "four leafed clover", "A rare 4-leafed clover.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_EXTRALUCK, 1, NA, NULL);
|
|
addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 110, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL);
|
|
// corpses
|
|
addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE);
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
|
|
addot(OT_HEAD, "head", "xxx", MT_FLESH, 1, OC_CORPSE);
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
|
|
addot(OT_FLESHCHUNK, "chunk of flesh", "A chunk of flesh from something.", MT_FLESH, 1, OC_FOOD);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%");
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
|
|
|
|
|
|
// potions (sorted by rarity)
|
|
addot(OT_POT_JUICE, "potion of fruit juice", "Tasty (but not very fresh) fruit juice!", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water");
|
|
addot(OT_POT_HEALING, "potion of healing", "Restores 10-20 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_HEALINGMAJ, "potion of major healing", "Restores 20-30 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 72, NA, NULL);
|
|
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_OIL, "potion of oil", "A bottle of cooking oil.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of oil");
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_RUM, "potion of rum", "String liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
|
|
addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addot(OT_POT_SPEED, "potion of haste", "Temporarily increasees the drinker's speed.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_MAGIC, "potion of magic", "Fully restores the drinker's magical energy.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_ACROBATICS, "potion of acrobatics", "Allows the drinker to leap large distances.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addot(OT_POT_INVIS, "potion of invisibility", "Temporarily renders the drinker invisible.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_POISON, "potion of poison", "Poisons the drinker.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_ACID, "flask of battery acid", "Causes massive internal burning if ingested.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puddle of acid");
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_ELEMENTIMMUNE, "potion of elemental immunity", "Grants the imbiber temporary immunity to both fire and cold.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addot(OT_POT_BLOOD, "potion of blood", "A small quantity of blood.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of blood");
|
|
addot(OT_POT_SANCTUARY, "potion of sanctuary", "Creates a temporary magical barrier abour the drinker.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
|
|
addot(OT_POT_ETHEREALNESS, "potion of etherealness", "Allows the walker to temporarily pass through walls.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addot(OT_POT_EXPERIENCE, "potion of experience", "Instantly grants the imbiber the next experience level.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL);
|
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, 40, NA, NULL);
|
|
|
|
addot(OT_POT_BLOODC, "potion of cockatrice blood", "A small quantity of cockatrice blood.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of cockatrice blood");
|
|
|
|
addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's strength, intelligence or dexterity.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
|
|
addot(OT_POT_GASEOUSFORM, "potion of gaseous form", "Turns the drinker into a cloud of gas.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_POT_POLYMORPH, "potion of polymorph self", "Transmutes the drinker into another living race.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_INVULN, "potion of invulnerability", "Grants the drinker temporary immunity to physical harm.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 40, NA, NULL);
|
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_POT_AMBROSIA, "vial of ambrosia", "The nectar of the gods, said to completely restore the drinker's health.", MT_GLASS, 1, OC_POTION);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 35, NA, NULL);
|
|
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
|
|
|
|
|
|
|
|
|
// scrolls
|
|
|
|
addot(OT_SCR_REMOVECURSE, "scroll of remove curse", "Removes curses from all weilded equipment.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
|
|
addot(OT_SCR_IDENTIFY, "scroll of identify", "Completely identifies any one item.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_IDENTIFY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
|
|
addot(OT_SCR_MENDING, "scroll of mending", "Repairs damage to objects.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MENDING, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 98, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL);
|
|
|
|
addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 84, NA, NULL);
|
|
|
|
addot(OT_MAP, "piece of graph paper", "Paper containing a set of grid-lines, intended for mapping.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
|
|
|
|
addot(OT_SCR_CREATEMONSTER, "scroll of create monster", "Summons a (probably hostile) monster to a nearby location.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, 4, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_SCR_DETECTAURA, "scroll of detect aura", "Senses holiness or evil near the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTAURA, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
|
|
|
|
addot(OT_SCR_DETECTLIFE, "scroll of detect life", "Senses life near the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTLIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
|
|
addot(OT_SCR_DETECTOBS, "scroll of detect objects", "Senses objects near the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTOBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
|
|
|
|
addot(OT_SCR_DETECTMAGIC, "scroll of detect magic", "Allows the reader to detect magical enchantments.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTMAGIC, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
|
|
addot(OT_SCR_FLAMEPILLAR, "scroll of flame pillar", "Creates a tall pillar of flame.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEPILLAR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
|
|
addot(OT_SCR_FLAMEBURST, "scroll of flame burst", "Creates a radial blast of fire out from the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEBURST, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
|
|
addot(OT_SCR_ENCHANT, "scroll of enchantment", "Magically enhances a weapon or piece of armour.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_ENCHANT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
|
|
addot(OT_SCR_FREEZEOB, "scroll of freezing touch", "Permenantly changes the next object touched into solid ice.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FREEZEOB, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
|
|
addot(OT_SCR_KNOCK, "scroll of knock", "Magically opens a barrier.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_KNOCK, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
|
|
addot(OT_SCR_LIGHT, "scroll of light", "Creates a permenant light source centred on the caster.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_SCR_MAPPING, "scroll of sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, 4, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
|
|
addot(OT_SCR_MINDSCAN, "scroll of mind scan", "Reveals detailed information about the target.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MINDSCAN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
|
|
addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
|
|
addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, 4, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_SCR_TURNUNDEAD, "scroll of turn undead", "Instills fear in undead creatures.", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
|
|
addot(OT_SCR_WISH, "scroll of wishing", "Grants the caster any item of their choice (with some limitations).", MT_PAPER, 0.5, OC_SCROLL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_WISH, NA, NA, NULL);
|
|
|
|
|
|
// spells - actually defined as object types
|
|
// MUST DEFINE THESE _AFTER_ SCROLLS
|
|
|
|
///////////////////
|
|
// allomancy
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_ABSORBMETAL, "absorb metal", "Draws mana from nearby metallic objects.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MPCOST, 0, NA, NA, NULL);
|
|
// l2
|
|
addot(OT_S_PULLMETAL, "pull metal", "Pulls metal objects to the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, 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_WALLSTOP, NA, NULL);
|
|
addot(OT_S_ACCELMETAL, "accelerate metal", "Greatly accelerates a metal object thrown by the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_WALLSTOP, NA, NULL);
|
|
addot(OT_S_METALHEAL, "metal healing", "Uses nearby metal for accelerated healing.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
// l3
|
|
addot(OT_S_EXPLODEMETAL, "explode metal", "Causes all metal objects in a location explode.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_MAGSHIELD, "magnetic shield", "Surrounds the caster with magnetic force, repelling metal objects and attacks.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
// l4
|
|
addot(OT_S_ANIMATEMETAL, "animate metal", "Imbues a metallic weapon with temporary life, enabling it to fight on its own.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
|
|
///////////////////
|
|
// death
|
|
///////////////////
|
|
// l2
|
|
addot(OT_S_BLINDNESS, "blindness", "Temporarily blinds the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_FEAR, "cause fear", "Causes intense fear in the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, 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);
|
|
// l3
|
|
addot(OT_S_POISONBOLT, "poison bolt", "Fires a glob of venom at the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
addot(OT_S_DRAINLIFE, "drain life", "Draws life force from the victim in order to heal the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
addot(OT_S_PAIN, "pain", "Causes extreme pain in the target whenever they move.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
// l4
|
|
addot(OT_S_WEAKEN, "weaken", "Temporarily lowers the target's muscle strength.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_PARALYZE, "paralyze", "Disables the target's muscles, leaving them unable to move.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_ANIMATEDEAD, "animate dead", "Imbues nearby corpses with life, creating an undead zombie.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
// TODO: should be "castnearob ot_corpse"
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
// l5
|
|
addot(OT_S_FEEBLEMIND, "feeblemind", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
// l7
|
|
addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
// l8
|
|
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_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
///////////////////
|
|
// divination
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_DETECTLIFE, "detect life", "Senses the size of creatures near the caster. At Power V, it will detect exact creature types.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
// l2
|
|
addot(OT_S_MAPPING, "sense surroundings", "Magically imbues the caster with a map of his/her surroundings.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
|
|
// l3
|
|
addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
// l4
|
|
addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
// l8
|
|
addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 8, NA, NA, NULL);
|
|
///////////////////
|
|
// elemental - air
|
|
///////////////////
|
|
// l2
|
|
addot(OT_S_GUSTOFWIND, "gust of wind", "Causes a gust of wind to blow the target's objects away.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
|
// l3
|
|
addot(OT_S_AIRBLAST, "airblast", "Knocks enemies back with a powerful blast of air.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
|
addot(OT_S_WINDSHIELD, "cyclonic shield", "Surrounds the caster with a whirling cyclone to repel missiles.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, 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);
|
|
// l4
|
|
addot(OT_S_CLOUDKILL, "cloudkill", "Creates a cloud of poisonous gas.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
///////////////////
|
|
// elemental - fire
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_SPARK, "spark", "Creates a tiny spark of flame, sufficient to ignite flammable objects but not enough to deal direct damage.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, 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_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 2-6 fire damage.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, 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_FALSE, LOF_NEED, NA, NULL);
|
|
// l3
|
|
addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
|
// l4
|
|
addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
|
// l5
|
|
addot(OT_S_BURNINGWAVE, "burning wave", "Fire bursts from the ground in a line towards the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
|
|
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
///////////////////
|
|
// elemental - ice
|
|
///////////////////
|
|
// l2
|
|
addot(OT_S_CONECOLD, "cone of cold", "Shoots a blast of ice cold air, dealing 2-6 cold damage.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, 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_FALSE, LOF_NEED, NA, NULL);
|
|
addot(OT_S_FREEZEOB, "freezing touch", "Permenantly changes the next object touched into solid ice.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
// l3
|
|
addot(OT_S_COLDBURST, "cold burst", "Creates a radial blast of coldness out from the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
|
///////////////////
|
|
// nature
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_CALMANIMALS, "calm animals", "Makes animals within the casters line of sight become peaceful.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addot(OT_S_DETECTPOISON, "detect poison", "Detects any poisoned object in sight of the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addot(OT_S_PURIFYFOOD, "purify food", "Removes rot or poison from food or drink.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addot(OT_S_STICKTOSNAKE, "sticks to snakes", "Transforms all seen wooden weapons into snakes.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
// l2
|
|
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);
|
|
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_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_LESSENPOISON, "lessen poison", "Reduces the effects of poison within the caster's bloodstream.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_REPELINSECTS, "repel insects", "Surrounds the caster with an insect-repelling smell.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addot(OT_S_SOFTENEARTH, "soften earth", "Converts earth into mud, slowing down.", 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_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", 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_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
addot(OT_S_WARPWOOD, "warp wood", "Causes damage to all wooden object in the target area.", 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, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
// l3
|
|
addot(OT_S_CALLLIGHTNING, "call lightning", "Blasts a single enemy with a bolt of lightning from the sky.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, 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_ENDUREELEMENTS, "endure elements", "Provides resistance to fire and cold.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_QUENCH, "quench", "Extinguishes all fires within the given area.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_THORNS, "thorns", "Sharp thorns grow from your skin, dealing 1d4 damage to attackers.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_WEB, "web", "Slows down pursuers with a burst of sticky spider web.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
|
|
// l4
|
|
addot(OT_S_DIG, "dig", "Blasts away earth to create passages.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addot(OT_S_ENTANGLE, "entangle", "Causes magical vines to hold enemies.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_CALMINGSCENT, "calming scent", "Automatically calms any nearby animals.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addot(OT_S_CUREPOISON, "cure poison", "Cures the target of all poisons.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_HAILSTORM, "hail storm", "Creates an intense storm of hail, causing damage to all within.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
addot(OT_S_WATERJET, "water spray", "Fires a high pressure blast of water from the caster's hands.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
// l5
|
|
addot(OT_S_LIGHTNINGSTORM, "lightning storm", "Blasts all visible enemies bolts of lightning from the sky.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
// l6
|
|
addot(OT_S_SUMMONANIMALSLG, "summon large animals", "Summons 2-3 large animals.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
///////////////////
|
|
// gravity
|
|
///////////////////
|
|
// l3
|
|
addot(OT_S_GRAVLOWER, "lessen gravity", "Causes the caster to fall very slowly.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
// l4
|
|
addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_SLOW, "slowness", "Decreases the speed of the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
// l5
|
|
// l6
|
|
addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addot(OT_S_HASTE, "haste", "Increases the speed of the target.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
///////////////////
|
|
// life
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_HEALINGMIN, "minor healing", "Restores 1-8 health to the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_TURNUNDEAD, "turn undead", "Instills fear in undead creatures. Power depends on caster's skill.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
// l3
|
|
addot(OT_S_HEALING, "healing", "Restores 10-20 health to the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
///////////////////
|
|
// mental/psionic
|
|
///////////////////
|
|
// l1
|
|
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);
|
|
// 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);
|
|
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);
|
|
// 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);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, 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);
|
|
// TODO: hardcode how ai casts this
|
|
// l4
|
|
addot(OT_S_PACIFY, "pacify", "Induces calmness in another, preventing them from attacking.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_HEALINGMAJ, "major healing", "Restores 20-30 health to the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
///////////////////
|
|
// modification
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_INSCRIBE, "inscribe", "Creates a magical inscription viewable to anyone standing nearby.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addot(OT_S_KNOCK, "knock", "Magically opens doors or other such barriers.\nAt Power VII, this spell will also knock back living creatures.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_LIGHT, "light", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
addot(OT_S_MENDING, "mending", "Repairs minor damage to objects.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
// l3
|
|
addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
// l6
|
|
addot(OT_S_PETRIFY, "petrify", "Causes the target mosnter to turn into stone.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.\nBecomes semi-controlled at Power V, and fully-controlled at power VIII.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
// l7
|
|
addot(OT_S_GASEOUSFORM, "gaseous form", "Changes the caster into a cloud of gas.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
|
|
addot(OT_S_ENCHANT, "enchantment", "Magically enhances a weapon or piece of armour.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 7, NA, NA, NULL);
|
|
// TODO: hardcode how ai casts this spell
|
|
///////////////////
|
|
// summoning
|
|
///////////////////
|
|
// l2
|
|
addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.\nAt Power V you can control where the monster appears.\nAt Power VII, you can control the type of monster created.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
|
///////////////////
|
|
// translocation
|
|
///////////////////
|
|
// l2
|
|
addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
|
addot(OT_S_PULL, "pull", "Pulls lifeforms towards the caster.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, 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_WALLSTOP, NA, NULL);
|
|
// l4
|
|
addot(OT_S_TELEPORT, "teleportation", "Teleports the caster (and Power-1 adjacent allies) to a new location within the same level.\nBecomes semi-controlled at Power V, and fully controlled at Power VII.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
// l5
|
|
addot(OT_S_DISPERSAL, "dispersal", "Scatters everything in the target cell around the area.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
|
// l6
|
|
addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
|
|
///////////////////
|
|
// wild
|
|
///////////////////
|
|
// l1
|
|
addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d2 magical damage per power level.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
// l2
|
|
addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 1d4 damage per power level.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
|
|
// l3
|
|
addot(OT_S_ENERGYBLAST, "energy blast", "Causes a ring of energy to expand from the caster, causing 2-6 damage to anything in sight.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
|
addot(OT_S_FLASH, "flash", "Causes a very bright flash, stunning anyone who sees it.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
// l6
|
|
addot(OT_S_DETONATE, "detonate", "Causes a given area to explode with massive force.", MT_NOTHING, 0, OC_SPELL);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
|
|
|
|
// divine powers (spells/abilities)
|
|
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);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addot(OT_A_LEARN, "learn", "Learn new skills.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addot(OT_A_LEVELUP, "levelup", "Bestow the given xp level.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addot(OT_S_WISH, "wish", "Grants the caster 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_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_A_EMPLOY, "employ", "Assigns a job to the target lifeform.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
|
|
// abilities
|
|
addot(OT_A_CHARGE, "charge", "You can quickly charge into close quarters for battle.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_A_CRUSH, "crush", "You can crush enemies after grabbing them.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NEEDSGRAB, B_TRUE, NA, NA, NULL);
|
|
addot(OT_A_FLURRY, "flurry", "Perform a flurry of attacks, forcing your opponent backwards.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_XPVAL, 10, NA, NA, NULL);
|
|
addot(OT_A_HEAVYBLOW, "heavy blow", "Mighty blow which knocks enemies backwards.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addot(OT_A_HIDE, "hide", "You can hide in the shadows.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addot(OT_A_INSPECT, "inspect", "Try to identify an unknown object from your pack.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addot(OT_A_HURRICANESTRIKE, "hurricane strike", "A sweeping attack aginst everything nearby.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
|
addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_A_RAGE, "rage", "Enter a state of berzerker rage, gaining attack and defence bonuses.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
|
addot(OT_A_SPRINT, "sprint", "You can run at high speed over short distances.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
|
addot(OT_A_STINGACID, "sting (acid)", "You can sting your enemies.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
|
|
addot(OT_A_SUCKBLOOD, "suck blood", "You can suck the blood from enemies after attaching to them.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
|
addot(OT_A_SWOOP, "swoop", "You can attack an enemy while flying past them.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_A_WARCRY, "warcry", "Inspire fear in your enemies with a mighty war cry.", MT_NOTHING, 0, OC_ABILITY);
|
|
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
|
|
|
|
|
// manuals
|
|
addot(OT_MAN_ARMOUR, "manual of armour", "Teaches you the skill 'armour'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_ARMOUR, NA, NA, NULL);
|
|
addot(OT_MAN_ATHLETICS, "manual of athletics", "Teaches you the skill 'athletics'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_ATHLETICS, NA, NA, NULL);
|
|
addot(OT_MAN_BACKSTAB, "manual of stabbing", "Teaches you the skill 'backstab'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_BACKSTAB, NA, NA, NULL);
|
|
addot(OT_MAN_FIRSTAID, "manual of first aid", "Teaches you the skill 'first aid'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_FIRSTAID, NA, NA, NULL);
|
|
addot(OT_MAN_LISTEN, "manual of listening", "Teaches you the skill 'listen'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LISTEN, NA, NA, NULL);
|
|
addot(OT_MAN_LOCKPICKING, "manual of lockpicking", "Teaches you the skill 'lockpicking'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LOCKPICKING, NA, NA, NULL);
|
|
addot(OT_MAN_MAGITEMUSAGE, "manual of channeling", "Teaches you the skill 'channeling'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_CHANNELING, NA, NA, NULL);
|
|
addot(OT_MAN_SHIELDS, "manual of shields", "Teaches you the skill 'shields'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SHIELDS, NA, NA, NULL);
|
|
addot(OT_MAN_SPELLCASTING, "manual of spellcasting", "Teaches you the skill 'spellcasting'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SPELLCASTING, NA, NA, NULL);
|
|
addot(OT_MAN_SPOTHIDDEN, "manual of searching", "Teaches you the skill 'searching'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SPOTHIDDEN, NA, NA, NULL);
|
|
addot(OT_MAN_STEALTH, "manual of stealth", "Teaches you the skill 'stealth'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_STEALTH, NA, NA, NULL);
|
|
addot(OT_MAN_TECHUSAGE, "manual of technology", "Teaches you the skill 'technology'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_TECHUSAGE, NA, NA, NULL);
|
|
addot(OT_MAN_TWOWEAPON, "manual of dual weilding", "Teaches you the skill 'dual weilding'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_TWOWEAPON, NA, NA, NULL);
|
|
// knowledge manuals
|
|
addot(OT_MAN_LORE_ARCANA, "tome of arcane lore", "Teaches you the skill 'lore:arcana'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LORE_ARCANA, NA, NA, NULL);
|
|
addot(OT_MAN_LORE_NATURE, "tome of nature lore", "Teaches you the skill 'lore:nature'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LORE_NATURE, NA, NA, NULL);
|
|
addot(OT_MAN_LORE_DEMONS, "tome of demonology", "Teaches you the skill 'lore:demonology'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LORE_DEMONS, NA, NA, NULL);
|
|
addot(OT_MAN_LORE_HUMANOID, "tome of human lore", "Teaches you the skill 'lore:humanoids'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LORE_HUMANOID, NA, NA, NULL);
|
|
addot(OT_MAN_LORE_UNDEAD, "tome of undead lore", "Teaches you the skill 'lore:undead'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LORE_UNDEAD, NA, NA, NULL);
|
|
// weapon manuals
|
|
addot(OT_MAN_AXES, "manual of axes", "Teaches you the skill 'axes'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_AXES, NA, NA, NULL);
|
|
addot(OT_MAN_CLUBS, "manual of clubs", "Teaches you the skill 'clubs'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_CLUBS, NA, NA, NULL);
|
|
addot(OT_MAN_LONGBLADES, "manual of long blades", "Teaches you the skill 'long blades'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_LONGBLADES, NA, NA, NULL);
|
|
addot(OT_MAN_POLEARMS, "manual of polearms", "Teaches you the skill 'polearms'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_POLEARMS, NA, NA, NULL);
|
|
addot(OT_MAN_SHORTBLADES, "manual of short blades", "Teaches you the skill 'short blades'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_MAN_STAVES, "manual of staves", "Teaches you the skill 'staves'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_STAVES, NA, NA, NULL);
|
|
addot(OT_MAN_UNARMED, "manual of unarmed combat", "Teaches you the skill 'unarmed combat'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_UNARMED, NA, NA, NULL);
|
|
// spell manuals
|
|
addot(OT_MAN_SS_ALLOMANCY, "manual of allomancy", "Teaches you the skill 'allomancy'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_ALLOMANCY, NA, NA, NULL);
|
|
addot(OT_MAN_SS_AIR, "manual of air magic", "Teaches you the skill 'air magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_AIR, NA, NA, NULL);
|
|
addot(OT_MAN_SS_DEATH, "manual of necromancy", "Teaches you the skill 'necromancy'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_DEATH, NA, NA, NULL);
|
|
addot(OT_MAN_SS_DIVINATION, "manual of divination", "Teaches you the skill 'divination'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_DIVINATION, NA, NA, NULL);
|
|
addot(OT_MAN_SS_NATURE, "manual of nature", "Teaches you the skill 'nature magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_NATURE, NA, NA, NULL);
|
|
addot(OT_MAN_SS_FIRE, "manual of fire magic", "Teaches you the skill 'fire magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_FIRE, NA, NA, NULL);
|
|
addot(OT_MAN_SS_COLD, "manual of ice magic", "Teaches you the skill 'ice magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_COLD, NA, NA, NULL);
|
|
addot(OT_MAN_SS_GRAVITY, "manual of gravitation magic", "Teaches you the skill 'gravitation magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_GRAVITY, NA, NA, NULL);
|
|
addot(OT_MAN_SS_LIFE, "manual of life magic", "Teaches you the skill 'life magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_LIFE, NA, NA, NULL);
|
|
addot(OT_MAN_SS_MODIFICATION, "manual of modification magic", "Teaches you the skill 'modification magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_MODIFICATION, NA, NA, NULL);
|
|
addot(OT_MAN_SS_MENTAL, "manual of psionics", "Teaches you the skill 'psionics'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_MENTAL, NA, NA, NULL);
|
|
addot(OT_MAN_SS_SUMMONING, "manual of summoning", "Teaches you the skill 'summoning'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_SUMMONING, NA, NA, NULL);
|
|
addot(OT_MAN_SS_TRANSLOCATION, "manual of translocation", "Teaches you the skill 'translocation'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_TRANSLOCATION, NA, NA, NULL);
|
|
addot(OT_MAN_SS_WILD, "manual of wild magic", "Teaches you the skill 'wild magic'.", MT_PAPER, 3, OC_BOOK);
|
|
addflag(lastot->flags, F_MANUALOF, SK_SS_WILD, NA, NA, NULL);
|
|
|
|
// spellbooks
|
|
addot(OT_SB_ANIMATEDEAD, "spellbook of animate dead", "Teaches the spell 'animate dead'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_ANIMATEDEAD, NA, NA, NULL);
|
|
addot(OT_SB_DRAINLIFE, "spellbook of drain life", "Teaches the spell 'drain life'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DRAINLIFE, NA, NA, NULL);
|
|
addot(OT_SB_FEAR, "spellbook of cause fear", "Teaches the spell 'cause fear'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FEAR, NA, NA, NULL);
|
|
addot(OT_SB_FEEBLEMIND, "spellbook of feeblemind", "Teaches the spell 'feeblemind'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FEEBLEMIND, NA, NA, NULL);
|
|
addot(OT_SB_PAIN, "spellbook of pain", "Teaches the spell 'pain'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PAIN, NA, NA, NULL);
|
|
addot(OT_SB_PARALYZE, "spellbook of paralyze", "Teaches the spell 'paralyze'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PARALYZE, NA, NA, NULL);
|
|
addot(OT_SB_POISONBOLT, "spellbook of poison bolt", "Teaches the spell 'poison bolt'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_POISONBOLT, NA, NA, NULL);
|
|
addot(OT_SB_WEAKEN, "spellbook of weaken", "Teaches the spell 'weaken'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_WEAKEN, NA, NA, NULL);
|
|
addot(OT_SB_BLINDNESS, "spellbook of blindness", "Teaches the spell 'blindness'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_BLINDNESS, NA, NA, NULL);
|
|
addot(OT_SB_INFINITEDEATH, "spellbook of infinite death", "Teaches the spell 'infinite death'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_INFINITEDEATH, NA, NA, NULL);
|
|
// divination
|
|
addot(OT_SB_DETECTLIFE, "spellbook of detect life", "Teaches the spell 'detect life'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTLIFE, NA, NA, NULL);
|
|
addot(OT_SB_DETECTOBS, "spellbook of detect objects", "Teaches the spell 'detect objects'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTOBS, NA, NA, NULL);
|
|
addot(OT_SB_MAPPING, "spellbook of sense surroundings", "Teaches the spell 'surroundings'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, NA, NA, NULL);
|
|
addot(OT_SB_DETECTAURA, "spellbook of detect aura", "Teaches the spell 'detect aura'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTAURA, NA, NA, NULL);
|
|
addot(OT_SB_REVEALHIDDEN, "spellbook of reveal hidden", "Teaches the spell 'reveal hidden'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL);
|
|
addot(OT_SB_IDENTIFY, "spellbook of identification", "Teaches the spell 'identification'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_IDENTIFY, NA, NA, NULL);
|
|
// elemental - air
|
|
addot(OT_SB_AIRBLAST, "spellbook of airblast", "Teaches the spell 'airblast'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_AIRBLAST, NA, NA, NULL);
|
|
addot(OT_SB_CALLLIGHTNING, "spellbook of call lightning", "Teaches the spell 'call lightning'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CALLLIGHTNING, NA, NA, NULL);
|
|
addot(OT_SB_CLOUDKILL, "spellbook of cloudkill", "Teaches the spell 'cloudkill'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CLOUDKILL, NA, NA, NULL);
|
|
addot(OT_SB_GUSTOFWIND, "spellbook of gust of wind", "Teaches the spell 'gust of wind'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_GUSTOFWIND, NA, NA, NULL);
|
|
addot(OT_SB_LIGHTNINGSTORM, "spellbook of lightning storm", "Teaches the spell 'lightning storm'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHTNINGSTORM, NA, NA, NULL);
|
|
addot(OT_SB_WINDSHIELD, "spellbook of cyclonic shield", "Teaches the spell 'cyclonic shield'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_WINDSHIELD, NA, NA, NULL);
|
|
// elemental - fire
|
|
addot(OT_SB_SPARK, "spellbook of spark", "Teaches the spell 'spark'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_SPARK, NA, NA, NULL);
|
|
addot(OT_SB_FIREDART, "spellbook of flame dart", "Teaches the spell 'flame dart'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FIREDART, NA, NA, NULL);
|
|
addot(OT_SB_FLAMEPILLAR, "spellbook of flame pillar", "Teaches the spell 'flame pillar'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEPILLAR, NA, NA, NULL);
|
|
addot(OT_SB_FLAMEBURST, "spellbook of flame burst", "Teaches the spell 'flame burst'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FLAMEBURST, NA, NA, NULL);
|
|
addot(OT_SB_FIREBALL, "spellbook of fireball", "Teaches the spell 'fireball'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FIREBALL, NA, NA, NULL);
|
|
addot(OT_SB_SLOW, "spellbook of slowness", "Teaches the spell 'slowness'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_SLOW, NA, NA, NULL);
|
|
addot(OT_SB_GRAVLOWER, "spellbook of lessen gravity", "Teaches the spell 'lessen gravity'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_GRAVLOWER, NA, NA, NULL);
|
|
addot(OT_SB_GRAVBOOST, "spellbook of boost gravity", "Teaches the spell 'boost gravity'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_GRAVBOOST, NA, NA, NULL);
|
|
addot(OT_SB_FLIGHT, "spellbook of fly", "Teaches the spell 'fly'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FLIGHT, NA, NA, NULL);
|
|
addot(OT_SB_HASTE, "spellbook of haste", "Teaches the spell 'haste'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_HASTE, NA, NA, NULL);
|
|
addot(OT_SB_LEVITATION, "spellbook of levitation", "Teaches the spell 'levitation'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_LEVITATION, NA, NA, NULL);
|
|
// elemental - ice
|
|
addot(OT_SB_CONECOLD, "spellbook of cone of cold", "Teaches the spell 'cone of cold'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CONECOLD, NA, NA, NULL);
|
|
// life
|
|
addot(OT_SB_HEALINGMIN, "spellbook of minor healing", "Teaches the spell 'minor healing'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_HEALINGMIN, NA, NA, NULL);
|
|
addot(OT_SB_TURNUNDEAD, "spellbook of turn undead", "Teaches the spell 'turn undead'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_TURNUNDEAD, NA, NA, NULL);
|
|
addot(OT_SB_HEALING, "spellbook of healing", "Teaches the spell 'healing'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_HEALING, NA, NA, NULL);
|
|
// mental
|
|
addot(OT_SB_MINDSCAN, "spellbook of mind scan", "Teaches the spell 'mind scan'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MINDSCAN, NA, NA, NULL);
|
|
addot(OT_SB_SLEEP, "spellbook of sleep", "Teaches the spell 'sleep'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_SLEEP, NA, NA, NULL);
|
|
addot(OT_SB_TELEKINESIS, "spellbook of telekinesis", "Teaches the spell 'telekinesis'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEKINESIS, NA, NA, NULL);
|
|
addot(OT_SB_PACIFY, "spellbook of pacify", "Teaches the spell 'pacify'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PACIFY, NA, NA, NULL);
|
|
addot(OT_SB_PSYARMOUR, "spellbook of psychic armour", "Teaches the spell 'psychic armour'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PSYARMOUR, NA, NA, NULL);
|
|
addot(OT_SB_CHARM, "spellbook of charm", "Teaches the spell 'charm'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CHARM, NA, NA, NULL);
|
|
// modification
|
|
addot(OT_SB_INSCRIBE, "spellbook of inscribe", "Teaches the spell 'inscribe'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_INSCRIBE, NA, NA, NULL);
|
|
addot(OT_SB_INVISIBILITY, "spellbook of invisibility", "Teaches the spell 'invisibility'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_INVISIBILITY, NA, NA, NULL);
|
|
addot(OT_SB_KNOCK, "spellbook of knock", "Teaches the spell 'knock'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_KNOCK, NA, NA, NULL);
|
|
addot(OT_SB_LIGHT, "spellbook of light", "Teaches the spell 'light'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, NA, NA, NULL);
|
|
addot(OT_SB_DARKNESS, "spellbook of darkness", "Teaches the spell 'darkness'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DARKNESS, NA, NA, NULL);
|
|
addot(OT_SB_FREEZEOB, "spellbook of freezing touch", "Teaches the spell 'freezing touch'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FREEZEOB, NA, NA, NULL);
|
|
addot(OT_SB_COLDBURST, "spellbook of cold burst", "Teaches the spell 'cold burst'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_COLDBURST, NA, NA, NULL);
|
|
addot(OT_SB_DIG, "spellbook of dig", "Teaches the spell 'dig'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DIG, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
|
addot(OT_SB_GASEOUSFORM, "spellbook of gaseous form", "Teaches the spell 'gaseous form'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_GASEOUSFORM, NA, NA, NULL);
|
|
|
|
addot(OT_SB_MENDING, "spellbook of mending", "Teaches the spell 'mending'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_MENDING, NA, NA, NULL);
|
|
addot(OT_SB_PASSWALL, "spellbook of passwall", "Teaches the spell 'passwall'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PASSWALL, NA, NA, NULL);
|
|
|
|
addot(OT_SB_PETRIFY, "spellbook of petrify", "Teaches the spell 'petrify'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_PETRIFY, NA, NA, NULL);
|
|
addot(OT_SB_POLYMORPH, "spellbook of polymorph", "Teaches the spell 'polymorph'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_POLYMORPH, NA, NA, NULL);
|
|
addot(OT_SB_STICKTOSNAKE, "spellbook of sticks to snakes", "Teaches the spell 'sticks to snakes'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_STICKTOSNAKE, NA, NA, NULL);
|
|
// summoning
|
|
addot(OT_SB_CREATEMONSTER, "spellbook of create monster", "Teaches the spell 'create monster'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CREATEMONSTER, NA, NA, NULL);
|
|
// translocation
|
|
addot(OT_SB_BLINK, "spellbook of blink", "Teaches the spell 'blink'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_BLINK, NA, NA, NULL);
|
|
addot(OT_SB_DISPERSAL, "spellbook of dispersal", "Teaches the spell 'dispersal'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DISPERSAL, NA, NA, NULL);
|
|
addot(OT_SB_TELEPORT, "spellbook of teleportation", "Teaches the spell 'teleportation'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_TELEPORT, NA, NA, NULL);
|
|
addot(OT_SB_GATE, "spellbook of gate", "Teaches the spell 'gate'.", MT_PAPER, 1.5, OC_BOOK);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_GATE, NA, NA, NULL);
|
|
|
|
|
|
// assign rarity to books
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if ((ot->obclass->id == OC_BOOK) && !hasflag(ot->flags, F_RARITY)) {
|
|
flag_t *f;
|
|
f = hasflag(ot->flags, F_LINKSPELL);
|
|
if (f) {
|
|
// find the linked spell
|
|
objecttype_t *spelltype;
|
|
spelltype = findot(f->val[0]);
|
|
if (spelltype) {
|
|
flag_t *f2;
|
|
f2 = hasflag(spelltype->flags, F_SPELLLEVEL);
|
|
if (f2) {
|
|
int rarity;
|
|
rarity = 90 - (f2->val[0]*12) - rnd(1,10);
|
|
addflag(ot->flags, F_RARITY, H_ALL, rarity, NA, NULL);
|
|
} else {
|
|
dblog("Spell %s has no spell level - can't determine rarity for spellbook.", spelltype->name);
|
|
exit(1);
|
|
}
|
|
} else {
|
|
dblog("Spellbook %s linked to a spell id that doesn't exist.",ot->name);
|
|
exit(1);
|
|
}
|
|
} else if (hasflag(ot->flags, F_MANUALOF)) {
|
|
addflag(ot->flags, F_RARITY, H_ALL, 50, NA, NULL);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// wands
|
|
addot(OT_WAND_KNOCK, "wand of opening", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_KNOCK, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_DOOR, NA, NA, NULL);
|
|
addot(OT_WAND_LIGHT, "wand of light", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 83, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, 3, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addot(OT_WAND_REVEALHIDDEN, "wand of reveal hidden", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL);
|
|
addot(OT_WAND_SLOW, "wand of slowness", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_SLOW, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_DIGGING, "wand of digging", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DIG, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL);
|
|
addot(OT_WAND_COLD, "wand of cold", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_CONECOLD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_FIRE, "wand of fire", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FIREDART, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_HASTE, "wand of haste", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_HASTE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addot(OT_WAND_WEAKNESS, "wand of enfeeblement", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_WEAKEN, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_WONDER, "wand of wonder", "Produces random effects.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_INVIS, "wand of invisibility", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_INVISIBILITY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
|
addot(OT_WAND_DISPERSAL, "wand of dispersal", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DISPERSAL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER|TT_OBJECT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
|
|
addot(OT_WAND_FIREBALL, "wand of fireball", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_FIREBALL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
addot(OT_WAND_DETONATION, "wand of detonation", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_DETONATE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER|TT_DOOR, 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_WAND_POLYMORPH, "wand of polymorph", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_LINKSPELL, OT_S_POLYMORPH, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
|
|
|
// tools
|
|
addot(OT_BLANKET, "wool blanket", "A warm wool blanket for those cold winter nights.", MT_CLOTH, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_HELPSREST, 10, NA, NA, NULL);
|
|
|
|
addot(OT_BLINDFOLD, "blindfold", "Short length of wide cloth, used for blocking eyesight.", MT_CLOTH, 0.01, OC_TOOLS);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_BLIND, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_VALUE, 20, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
|
|
addot(OT_BUGLAMP, "glowing flask", "A glass flask with a glowbug corpse inside.", MT_GLASS, 0.3, OC_TOOLS);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "!");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_PRODUCESLIGHT, 2, IFKNOWN, NULL);
|
|
|
|
addot(OT_CANDLE, "candle", "A short wax candle.", MT_WAX, 0.2, OC_TOOLS);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, IFACTIVE, NULL);
|
|
addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL);
|
|
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
|
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
|
|
|
|
addot(OT_GUNPOWDER, "pile of gunpowder", "A black metallic powder.", MT_METAL, 0.5, OC_TOOLS);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of black powder");
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "8d2");
|
|
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
|
|
addflag(lastot->flags, F_FLAMMABLE, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_LAMPOIL, "oil lamp", "An oil-powered lamp which produces light.", MT_METAL, 1, OC_TOOLS);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
|
addflag(lastot->flags, F_RNDCHARGES, 100, 200, NA, NULL);
|
|
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
|
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
|
|
|
|
addot(OT_LANTERNOIL, "oil lantern", "An oil-powered lantern which produces a lot of light.", MT_METAL, 1, OC_TOOLS);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, IFACTIVE, NULL);
|
|
addflag(lastot->flags, F_RNDCHARGES, 200, 300, NA, NULL);
|
|
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LIGHTSOURCE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGELOWMSG, B_TRUE, NA, NA, "flickers");
|
|
addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out");
|
|
|
|
addot(OT_LOCKPICK, "lockpick", "An angled piece of metal, used to open locks.", MT_METAL, 0.05, OC_TOOLS);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 10, B_DIEONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_PANPIPES, "set of panpipes", "A set of musical pipes.", MT_METAL, 0.5, OC_TOOLS);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_PICKAXE, "pickaxe", "A heavy tool for breaking rock.", MT_METAL, 8, OC_TOOLS);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
|
addflag(lastot->flags, F_RNDCHARGES, 50, 100, NA, NULL);
|
|
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_FIRE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
|
|
// tech - l0
|
|
addot(OT_CREDITCARD, "credit card", "A rectangular plastic card.", MT_PLASTIC, 0.01, OC_TECH);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_PAPERCLIP, "paperclip", "A thin, looped wire for holding paper together.", MT_METAL, 0.01, OC_TECH);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 4, B_DIEONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
// can use as a (very bad) weapon too...
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d1");
|
|
addflag(lastot->flags, F_ACCURACY, 50, NA, NA, NULL);
|
|
|
|
addot(OT_SLEEPINGBAG, "sleeping bag", "An insulated bag for sleeping in. Very comfortable.", MT_CLOTH, 4, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_HELPSREST, 15, NA, NA, NULL);
|
|
|
|
// tech - l1
|
|
addot(OT_POCKETWATCH, "pocket watch", "A portable timekeeping device made to be carried in a pocket.", MT_METAL, 0.1, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_DIGITALWATCH, "digital watch", "An electronic timekeeping device which shows the time as a number.", MT_METAL, 0.1, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_INSECTICIDE, "can of insecticide", "A spraycan containing poisonous chemicals.", MT_METAL, 0.5, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERUSECHARGE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, "Where will you spray?");
|
|
addflag(lastot->flags, F_RNDCHARGES, 1, 5, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_LANTERNLED, "LED lantern", "A low-powered but efficient lantern which will last almost forever.", MT_METAL, 0.5, OC_TECH);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 2, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, IFACTIVE, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_TENT, "tent", "A easy to use, portable shelter made of fabric.", MT_CLOTH, 10, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL);
|
|
addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_NOVICE, NA, NA, NULL);
|
|
|
|
// tech - l2
|
|
addot(OT_FLASHBANG, "flashbang", "A stun grenade which temporarily blinds all within sight.", MT_METAL, 1, OC_TECH);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGES, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_DONTSHOWCHARGES, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, 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_FLASHONDEATH, 4, NA, B_IFACTIVATED, NULL);
|
|
addflag(lastot->flags, F_FLASHONDAM, 4, NA, B_IFACTIVATED, NULL);
|
|
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_GRENADE, "grenade", "An explosive weapon which explodes a short time after activation.", MT_METAL, 1, OC_TECH);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGES, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_DONTSHOWCHARGES, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, 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_EXPLODEONDEATH, NA, NA, B_IFACTIVATED, "8d2");
|
|
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, B_IFACTIVATED, "5d2");
|
|
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_C4, "block of c4", "A highly explosive plastic which explodes a medium time after activation.", MT_PLASTIC, 1, OC_TECH);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CHARGES, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_DONTSHOWCHARGES, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, 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_EXPLODEONDEATH, NA, B_BIG, B_IFACTIVATED, "15d2");
|
|
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_MOTIONSCANNER, "motion scanner", "Small scanning device which detects nearby lifeforms.", MT_METAL, 1.5, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL);
|
|
addflag(lastot->flags, F_HOLDCONFER, F_DETECTLIFE, 10, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
|
|
// tech - l3
|
|
addot(OT_JETPACK, "jet pack", "A portable ion-thruster which allows the wearer to fly.", MT_METAL, 10, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RNDCHARGES, 10, 30, NA, NULL);
|
|
addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_FLYING, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 1, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_ADEPT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
|
|
// tech - l4
|
|
addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAINFO, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_LOCKHACKER, "lock hacker", "A sophisticated machine to manipulate physical locks.", MT_METAL, 3, OC_TECH);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
|
|
// tech - l5
|
|
addot(OT_TELEPAD, "teleport beacon", "A metal cone which will teleport the user to the nearest similar cone.", MT_METAL, 3, OC_TECH);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_EXPERT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
addot(OT_XRAYGOGGLES, "pair of xray goggles", "Bulky looking goggles which allow you to see through walls.", MT_METAL, 0.3, OC_TECH);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_XRAYVIS, 2, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_TECHLEVEL, PR_EXPERT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
|
|
|
// tech - l6 ???
|
|
|
|
|
|
|
|
// misc
|
|
|
|
|
|
addot(OT_EMPTYFLASK, "empty flask", "An empty glass flask.", MT_GLASS, 0.2, 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_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_EMPTYVIAL, "empty vial", "An empty glass vial.", MT_GLASS, 0.1, 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_RARITY, H_DUNGEON, 82, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addot(OT_BROKENGLASS, "piece of broken glass", "Sharp shards of broken glass.", MT_GLASS, 0.1, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 8, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "^");
|
|
addflag(lastot->flags, F_SHARP, 1, 2, NA, NULL);
|
|
addflag(lastot->flags, F_CRUSHABLE, SZ_MEDIUM, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addot(OT_CALTROP, "caltrop", "Connected metal spikes arranged such that one will always point upwards.", MT_METAL, 0.2, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "^");
|
|
addflag(lastot->flags, F_SHARP, 2, 5, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addot(OT_ICESHEET, "sheet of ice", "A large sheet of slippery ice.", MT_ICE, 0.5, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, NA, 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_DTCONVERT, DT_FIRE, NA, NA, "large puddle of water");
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "large puddle of water");
|
|
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "melts");
|
|
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "melt");
|
|
addflag(lastot->flags, F_OBHP, 50, 50, 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_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL);
|
|
addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC);
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 3, NA, NULL);
|
|
addflag(lastot->flags, F_STACKABLE, NA, 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_DIECONVERT, NA, NA, NA, "small puddle of water");
|
|
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "melts");
|
|
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "melt");
|
|
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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, NA, 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_NOMATCONVERT, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_SOGGYPAPER, "lump of soggy paper", "A useless lump of soggy paper.", MT_WETPAPER, 0.1, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, NA, 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_NOMATCONVERT, NA, NA, NA, NULL);
|
|
|
|
addot(OT_VOMITPOOL, "pool of vomit", "A disgusting pool of regurgitated food.", MT_WATER, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, ",");
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL);
|
|
addflag(lastot->flags, F_TAINTED, B_TRUE, NA, NA, NULL);
|
|
|
|
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_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");
|
|
addflag(lastot->flags, F_OBHP, 4, 4, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_ACID, FALLTHRU, "2d4");
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL);
|
|
|
|
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_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
|
|
addflag(lastot->flags, F_OBHP, 4, 4, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_ACID, FALLTHRU, "1d4");
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL);
|
|
|
|
addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
|
|
addflag(lastot->flags, F_OBHP, 2, 2, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_ACID, FALLTHRU, "1d2");
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_ACID, NA, NA, NULL);
|
|
|
|
addot(OT_SLIMEPOOL, "pool of slime", "A disgusting mass of sticky slime.", MT_WATER, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EDIBLE, B_TRUE, 2, NA, NULL);
|
|
|
|
addot(OT_PUDDLEOIL, "puddle of oil", "A slippery puddle of oil.", MT_OIL, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "{");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FLAMMABLE, 5, NA, NA, "medium fire");
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_OIL, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 13, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
|
|
// this isn't made out of water, so that it won't put out fire etc
|
|
addot(OT_SPLASHWATER, "splash of water", "A small splash of water.", MT_NOTHING, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, ",");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
|
|
addflag(lastot->flags, F_OBHP, 5, 5, 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_DTVULN, DT_FIRE, NA, NA, "0d1+100");
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
|
|
|
|
addot(OT_MUDPOOL, "pool of mud", "A large puddle of wet mud.", MT_WATER, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, ",");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_REDUCEMOVEMENT, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
//addflag(lastot->flags, F_WALKDAM, DT_WATER, NA, NA, "0d1+1");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1");
|
|
|
|
addot(OT_PUDDLEWATER, "small puddle of water", "A small puddle of water.", MT_WATER, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, 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, "puff of steam");
|
|
addflag(lastot->flags, F_DRINKABLE, 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");
|
|
|
|
addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_BLUE, NA, NA, "{");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, 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_LINKOB, OT_POT_WATER, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+2");
|
|
|
|
addot(OT_BLOODSTAIN, "blood stain", "A dried stain 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, C_RED, NA, NA, ",");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_BLOODCSPLASH, "splash of cockatrice blood", "A small pool of cockatrice blood.", MT_BLOOD, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
|
|
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
|
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_BLOODC, NA, NA, NULL);
|
|
|
|
addot(OT_BLOODSPLASH, "splash of blood", "A small 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_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "blood stain");
|
|
//addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up");
|
|
//addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up");
|
|
addflag(lastot->flags, F_NODIECONVERTTEXT, 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_LINKOB, OT_POT_BLOOD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_COSMETIC, B_TRUE, NA, NA, NULL);
|
|
|
|
|
|
addot(OT_BLOODPOOL, "pool of blood", "A large pool of blood.", MT_BLOOD, 0, OC_MISC);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SLIPPERY, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "blood stain");
|
|
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up");
|
|
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up");
|
|
addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL);
|
|
addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL);
|
|
|
|
addot(OT_WOODENBARREL, "wooden barrel", "A solid wooden barrel.", MT_WOOD, 20, OC_MISC);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "(");
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_LARGE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CRUSHABLE, SZ_HUGE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
|
|
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_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_MISC);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "\\");
|
|
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, 4, 4, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
|
|
|
|
addot(OT_BONE, "bone", "A bone from an unknown creature.", MT_BONE, 0.1, OC_MISC);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
|
|
// 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_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);
|
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "2d4+4");
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
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_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);
|
|
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
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_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);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
|
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of steam");
|
|
addflag(lastot->flags, F_OBHP, 3, 3, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
addot(OT_STEAMPUFF, "puff of steam", "A small puff of scalding steam.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, C_GREY, NA, NA, "{");
|
|
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses");
|
|
addflag(lastot->flags, F_OBHP, 2, 2, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d1+1");
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
|
|
addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, C_CYAN, NA, NA, "{");
|
|
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, 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_BLOCKSVIEW, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_REDUCEMOVEMENT, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_HEAD, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_SHOULDERS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_BODY, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_HANDS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2");
|
|
|
|
addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
|
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of smoke");
|
|
addflag(lastot->flags, F_OBHP, 3, 3, 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_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
addot(OT_SMOKEPUFF, "puff of smoke", "A small puff of black smoke.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "{");
|
|
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses");
|
|
addflag(lastot->flags, F_OBHP, 2, 2, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_BLOCKSVIEW, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, ".");
|
|
|
|
addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "{");
|
|
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "thins out a little");
|
|
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of gas");
|
|
addflag(lastot->flags, F_OBHP, 3, 3, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_POISONGAS, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
addflag(lastot->flags, F_BLOCKSVIEW, 2, NA, NA, NULL);
|
|
|
|
addot(OT_POISONPUFF, "puff of poison gas", "A small puff of poisonous gas.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "{");
|
|
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "disperses");
|
|
addflag(lastot->flags, F_OBHP, 2, 2, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_WALKDAM, DT_POISONGAS, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
addot(OT_HAILSTORM, "hail storm", "An intense storm of damaging hail.", MT_GAS, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "{");
|
|
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, 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_BLOCKSVIEW, 5, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
addflag(lastot->flags, F_WALKDAM, DT_COLD, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_HEAD, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_SHOULDERS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_BODY, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_HANDS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_LEGS, DT_WATER, NA, "1d2");
|
|
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, NA, "1d2");
|
|
|
|
addot(OT_MAGICBARRIER, "magical barrier", "A glowing, impassable barrier of magical energy.", MT_MAGIC, 0, OC_EFFECT);
|
|
addflag(lastot->flags, F_GLYPH, NA, NA, NA, "#");
|
|
addflag(lastot->flags, F_IMPASSABLE, SZ_MAX, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, 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_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
|
|
addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL);
|
|
|
|
addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "^");
|
|
addflag(lastot->flags, F_RESTRICTMOVEMENT, 30, B_FALSE, NA, NULL);// the value here will be filled in by the spell.
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_ACID, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
addot(OT_WEB, "web", "A huge, sticky spider web.", MT_SILK, 0.1, OC_EFFECT);
|
|
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_GREY, NA, NA, "^");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 86, NA, NULL);
|
|
addflag(lastot->flags, F_RESTRICTMOVEMENT, 25, B_TRUE, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DTVULN, DT_ACID, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
|
|
|
|
// armour - body
|
|
addot(OT_COTTONSHIRT, "cotton shirt", "A comfortable white cotton shirt.", MT_CLOTH, 0.7, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addot(OT_ARMOURLEATHER, "leather armour", "Body armour created from soft leather.", MT_LEATHER, 10, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
|
addot(OT_ARMOURRING, "suit of ring mail", "Body armour formed by a series of metallic rings sewn to a leather foundation.", MT_METAL, 15, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
|
addot(OT_ARMOURSCALE, "suit of scale armour", "Body armour consisting of many small scales attached to leather.", MT_METAL, 20, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 72, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -15, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 35, 35, NA, NULL);
|
|
addot(OT_ARMOURCHAIN, "suit of chainmail", "Heavy body armour consisting of tightly meshed metal rings.", MT_METAL, 25, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 15, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -20, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 45, 45, NA, NULL);
|
|
addot(OT_ARMOURSPLINT, "suit of splint mail", "Heavy armour, consisting of strips of metal attached to a leather backing.", MT_METAL, 35, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 67, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 20, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -25, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
|
|
addot(OT_ARMOURPLATE, "suit of plate mail", "Heavy armour with embedded metal plates.", MT_METAL, 40, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 25, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -30, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 60, 60, NA, NULL);
|
|
|
|
addot(OT_FLAKJACKET, "flak jacket", "Heavy metal body armour, designed to stop a bullet.", MT_METAL, 30, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
|
addot(OT_OVERALLS, "pair of overalls", "Well-made, brightly coloured workman overalls.", MT_CLOTH, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
|
addot(OT_SILKSHIRT, "silk shirt", "A lightweight, comfortable white silk shirt.", MT_SILK, 0.5, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addot(OT_ROBE, "robe", "A plain robe.", MT_CLOTH, 4, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
|
|
addot(OT_VELVETROBE, "velvet robe", "A luxurious velvet robe.", MT_CLOTH, 4, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
|
|
// armour - shoulders
|
|
addot(OT_CLOAK, "cloak", "A standard leather cloak.", MT_LEATHER, 4, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_SHOULDERS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 6, 6, NA, NULL);
|
|
addflag(lastot->flags, F_WATERPROOF, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HELPSREST, 5, NA, NA, NULL);
|
|
// armour - waist
|
|
addot(OT_BELTLEATHER, "leather belt", "A plain leather belt.", MT_LEATHER, 0.2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_WAIST, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
// armour - legs
|
|
addot(OT_CLOTHTROUSERS, "pair of cloth trousers", "A rough pair of cloth trousers.", MT_CLOTH, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addot(OT_RIDINGTROUSERS, "pair of riding trousers", "A fitted pair of leather trousers.", MT_LEATHER, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addot(OT_COMBATPANTS, "pair of combat pants", "An armoured pair of camoflauged trousers.", MT_CLOTH, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_LEGS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 8, 8, NA, NULL);
|
|
// armour - feet
|
|
addot(OT_SANDALS, "pair of sandals", "Comfortable pair of open leather sandals.", MT_LEATHER, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addot(OT_SHOESLEATHER, "pair of leather shoes", "Cheap and rather uncomfortable leather shoes.", MT_LEATHER, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
|
|
addot(OT_BOOTSRUBBER, "pair of rubber boots", "A waterproof (but somewhat cumbersome) pair of rubber boots.", MT_RUBBER, 6, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL); // bulky
|
|
addflag(lastot->flags, F_OBHP, 8, 8, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_DTRESIST, DT_ELECTRIC, NA, NULL);
|
|
addot(OT_BOOTSSPIKED, "pair of spiked boots", "A plain pair of leather boots with spikes on the bottom.", MT_LEATHER, 3, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_STABILITY, NA, NA, NULL);
|
|
addot(OT_BOOTSLEATHER, "pair of leather boots", "A stout pair of leather boots.", MT_LEATHER, 4, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_FEET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
// armour - gloves
|
|
addot(OT_GLOVESCLOTH, "pair of cloth gloves", "A pair of soft cloth gloves.", MT_CLOTH, 0.15, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addot(OT_GLOVESLEATHER, "pair of leather gloves", "A pair of coarse leather gloves.", MT_LEATHER, 0.25, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addot(OT_GAUNTLETS, "pair of gauntlets", "A durable pair of metal gauntlets.", MT_METAL, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HANDS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
|
// armour - head
|
|
addot(OT_SUNHAT, "sun hat", "Wide-brimmed hat made for working in the sun.", MT_CLOTH, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addot(OT_PIRATEHAT, "tricorne", "A three cornered hat with a skull and crossbones emblem.", MT_CLOTH, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
|
|
addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
|
addot(OT_GASMASK, "gas mask", "A full face mask which protects the wearer from toxic gasses.", MT_METAL, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -5, NA, NULL);
|
|
addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
|
addot(OT_HELMFOOTBALL, "football helmet", "A metal helmet with a grill in front of the face.", MT_METAL, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, -10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL);
|
|
addot(OT_GOLDCROWN, "golden crown", "A heavy gold crown, encrusted with jewels.", MT_GOLD, 5, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
|
addot(OT_HELMBONE, "bone helmet", "Scary-looking helmet made from the bones of an animal (?).", MT_BONE, 1, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
|
addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL);
|
|
|
|
|
|
|
|
// armour - eyes
|
|
addot(OT_SUNGLASSES, "sunglasses", "Tinted eyewear to protect against sunlight.", MT_PLASTIC, 0.01, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 0, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -4, NA, NULL);
|
|
addflag(lastot->flags, F_TINTED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
|
addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
|
|
addot(OT_NVGOGGLES, "nightvis goggles", "Special goggles which allow the wear to see in the dark.", MT_METAL, 1.5, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 5, NA, NULL);
|
|
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
|
|
|
|
|
// armour - shields
|
|
addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 83, NA, NULL);
|
|
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
|
addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 76, NA, NULL);
|
|
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 6, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
|
|
addot(OT_SHIELDLARGE, "large shield", "A large (if somewhat cumbersome) shield.", MT_METAL, 6.00, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 78, NA, NULL);
|
|
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 8, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 20, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
|
|
addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 65, NA, NULL);
|
|
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ARMOURRATING, 12, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 30, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
|
|
|
|
// rings
|
|
addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 3, NA, NULL);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL);
|
|
addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAMP, 10, NA, NULL);
|
|
addot(OT_RING_LUCK, "ring of luck", "Makes the wearer more lucky.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRALUCK, 5, NA, NULL);
|
|
addot(OT_RING_PROTFIRE, "ring of fire immunity", "Grants the caster complete immunity to fire.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FIRE, NA, NULL);
|
|
addot(OT_RING_PROTCOLD, "ring of cold immunity", "Grants the caster complete immunity to cold.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_COLD, NA, NULL);
|
|
|
|
addot(OT_RING_STR, "ring of strength", "Increases the wearer's strength.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_STR, 1, NULL); // '1' is randomized during generation
|
|
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
|
addot(OT_RING_IQ, "ring of intelligence", "Increases the wearer's intelligence.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_IQ, 1, NULL); // '1' is randomized during generation
|
|
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
|
addot(OT_RING_CON, "ring of constitution", "Increases the wearer's constitution.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation
|
|
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
|
addot(OT_RING_DEX, "ring of dexterity", "Increases the wearer's dexterity.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_DEX, 1, NULL); // '1' is randomized during generation
|
|
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_RING_HUNGER, "ring of hunger", "Greatly increases the metabolic rate of the wearer.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_FASTMETAB, 4, NA, NULL);
|
|
addflag(lastot->flags, F_STARTBLESSED, B_CURSED, NA, NA, NULL);
|
|
addot(OT_RING_WOUNDING, "ring of wounding", "Increases the damage output of the wearer.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 73, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRADAM, NA, NA, "0d0+4");
|
|
addflag(lastot->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
|
addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 60, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_INVISIBLE, NA, NA, NULL);
|
|
addot(OT_RING_INVULN, "ring of invulnerability", "Grants the caster complete immunity to physical harm.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_INVULNERABLE, NA, NA, NULL);
|
|
addot(OT_RING_MPREGEN, "ring of recharging", "Slowly regenerates the wearer's mana.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_MPREGEN, 1, NA, NULL);
|
|
addot(OT_RING_CONTROL, "ring of control", "Allows the wearer control over teleportation and polymorphic effects.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_CONTROL, NA, NA, NULL);
|
|
addot(OT_RING_REGENERATION, "ring of regeneration", "Slowly regenerates the wearer's health, even when not resting.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_REGENERATES, 1, NA, NULL);
|
|
addot(OT_RING_RESISTMAG, "ring of magic resistance", "Renders the wearer immune to most magical effects.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 50, NA, "");
|
|
addflag(lastot->flags, F_EQUIPCONFER, F_RESISTMAG, 5, NA, NULL);
|
|
addot(OT_RING_MIRACLES, "ring of miracles", "Grants a limited number of miracles to the wearer.", MT_METAL, 0.1, OC_RING);
|
|
addflag(lastot->flags, F_RARITY, H_ALL, 40, NA, "");
|
|
addflag(lastot->flags, F_CHARGES, 3, 3, NA, NULL);
|
|
|
|
// unarmed weapons - note these damage/accuracys can be
|
|
// overridded with the lifeform flag F_HASATTACK
|
|
//
|
|
// DAMTYPE _cannot_ be overridden (yet)!
|
|
addot(OT_FISTS, "fists", "human fists", MT_FLESH, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_UNARMED, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
// this one if for the pirate
|
|
addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, 5, NA, "scratch");
|
|
addflag(lastot->flags, F_ATTACKVERB, 6, 15, NA, "scrape");
|
|
addflag(lastot->flags, F_ATTACKVERB, 16, NA, NA, "rake");
|
|
|
|
|
|
addot(OT_TEETH, "teeth", "teeth object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_BITE, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_CLAWS, "claws", "claws object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, 5, NA, "scratch");
|
|
addflag(lastot->flags, F_ATTACKVERB, 6, 15, NA, "claw");
|
|
addflag(lastot->flags, F_ATTACKVERB, 16, 30, NA, "tear");
|
|
addflag(lastot->flags, F_ATTACKVERB, 31, 40, NA, "rake");
|
|
addflag(lastot->flags, F_ATTACKVERB, 41, 50, NA, "gouge");
|
|
addflag(lastot->flags, F_ATTACKVERB, 51, NA, NA, "eviscerate");
|
|
addflag(lastot->flags, F_KILLVERB, 70, NA, NA, "disembowel");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_HOOF, "hooves", "hoof object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "kick");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_BUTT, "headbutt", "headbutt object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "butt");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_STING, "sting", "sting object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting");
|
|
addflag(lastot->flags, F_DAM, DT_ACID, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_TAIL, "tail", "tail object", MT_FLESH, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "tailslap");
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_ELECTRIC, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
// monster weapons
|
|
addot(OT_ACIDATTACK, "acidattack", "acid attack object", MT_WATER, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_ACID, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
addot(OT_TOUCHPARALYZE, "paralyzing touch", "paralyzing touch object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_TOUCH, NA, NA, "0d1");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 22, "2-4");
|
|
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
addot(OT_TOUCHPARALYZE2, "strong paralyzing touch", "strong paralyzing touch object", MT_BONE, 0, OC_WEAPON);
|
|
addflag(lastot->flags, F_DAM, DT_TOUCH, NA, NA, "0d1");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "5-10");
|
|
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
|
|
|
|
// missiles
|
|
addot(OT_DART, "dart", "A small, sharp projectile weapon.", MT_WOOD, 0.5, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, "");
|
|
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
|
|
|
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 1.5, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_MISSILEDAM, 3, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 2, NA, "");
|
|
addflag(lastot->flags, F_OBHP, 3, 3, NA, "");
|
|
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
|
|
|
addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.5, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 1, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
|
|
|
|
|
addot(OT_BULLET, "bullet", "A regular gun bullet.", MT_STONE, 0.1, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
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, 1, 1, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_STONE, 0.1, OC_MISSILE);
|
|
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
|
|
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
|
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, 1, 1, NA, NULL);
|
|
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
|
|
|
|
// axes
|
|
addot(OT_AXE, "axe", "A short pole with a heavy, wedge-shaped blade for chopping.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addot(OT_BATTLEAXE, "battleaxe", "An axe specifically designed for combat.", MT_METAL, 5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9");
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_GREATAXE, "greataxe", "An enormous axe made designed for combat.", MT_METAL, 8, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d10");
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL);
|
|
addot(OT_HANDAXE, "hand axe", "A fast one-handed axe made for combat.", MT_METAL, 2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d6+1");
|
|
addflag(lastot->flags, F_ACCURACY, 85, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_AXES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
|
|
// short blades
|
|
addot(OT_COMBATKNIFE, "combat knife", "A sharp knife designed for military use.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4+1");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_DAGGER, "dagger", "A short stabbing weapon with a pointed blade.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_KNIFE, "knife", "A moderately sharp stabbing tool.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d3");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_ORNDAGGER, "ornamental dagger", "This dagger is pretty, but not particularly effective.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d3");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_PICKLOCKS, 7, B_BLUNTONFAIL, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_QUICKBLADE, "quickblade", "A short blade of exceptional quality, which somehow allows its bearer to attack faster.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 90, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_RAPIER, "rapier", "A long, narrow French sword lacking a cutting edge. Made for stabbing.", MT_METAL, 2.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8");
|
|
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
|
addot(OT_SAI, "sai", "A dagger with two long prongs on either side, made to trap opponents' weapons.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 81, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL);
|
|
addot(OT_SHORTSWORD, "short sword", "A short blade for fighting. Better for stabbing.", MT_METAL, 2.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
|
addot(OT_SICKLE, "sickle", "A hand-held agricultural tool with a curved blade.", MT_METAL, 0.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
addot(OT_STEAKKNIFE, "steak knife", "A common kitchen knife.", MT_METAL, 0.2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 5, 5, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL);
|
|
|
|
// long blades
|
|
addot(OT_FALCHION, "falchion", "A single-edged heavy sword made for chopping.", MT_METAL, 4.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 61, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 135, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d8+3");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_GREATSWORD, "greatsword", "A massive two-handed sword.", MT_METAL, 10, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 55, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d12+6");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_LONGSWORD, "longsword", "Standard issue long slashing weapon.", MT_METAL, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8+4");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 10, NA, NULL);
|
|
addot(OT_ORNSWORD, "ornamental sword", "A gleaming (but quite blunt) blade.", MT_METAL, 2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_SHINY, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addot(OT_SCIMITAR, "scimitar", "A fast, sharp, curved blade.", MT_METAL, 2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d8+2");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
|
|
addot(OT_CUTLASS, "cutlass", "An accuracte, light-weight pirate blade.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7");
|
|
addflag(lastot->flags, F_ACCURACY, 90, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_LONGBLADES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 8, NA, NULL);
|
|
|
|
// polearms
|
|
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7+3");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
|
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 7, NA, NULL);
|
|
addot(OT_HALBERD, "halberd", "A spiked axe blade mounted on a long shaft, with a hook on the back.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 71, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_CHOP, NA, NA, "1d9+2");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
|
addot(OT_LANCE, "lance", "A pole weapon designed for use while mounted.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8+2");
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_RANSEUR, "ranseur", "A long spear and cross hilt, resembling a pole-mounted sai. Good for disarming.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 67, NA, NULL);
|
|
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
|
addot(OT_SCYTHE, "scythe", "An agricultural hand tool for mowing grass, or reaping crops.", MT_METAL, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addot(OT_SPEAR, "spear", "A long pole with a sharpened head.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d8");
|
|
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
|
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
addot(OT_TRIDENT, "trident", "A three-pronged stabbing weapon.", MT_METAL, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_PIERCE, NA, NA, "1d10");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
|
|
// staves
|
|
addot(OT_QUARTERSTAFF, "quarterstaff", "A long, stout pole.", MT_WOOD, 2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d8");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_BAMBOOSTAFF, "bamboo staff", "A long hard pole made from bamboo.", MT_WOOD, 1.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 6, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_BLADEDSTAFF, "bladed staff", "A long wooden pole with blades on either end.", MT_WOOD, 2, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 130, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "2d4+3");
|
|
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 9, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_IRONSTAFF, "iron staff", "A long, stout metal pole.", MT_METAL, 4, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 135, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "3d4+1");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
|
|
// clubs (bashing)
|
|
addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 1.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 7, NA, NULL);
|
|
addot(OT_FLAIL, "flail", "A flexible chain attached to a heavy weight.", MT_METAL, 6, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d4");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addot(OT_FLAILHEAVY, "heavy flail", "A flexible chain attached to a very heavy weight.", MT_METAL, 12, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 155, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "2d6");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_GREATCLUB, "great club", "An enormous, very heavy, blunt instrument to hit things with.", MT_STONE, 5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 180, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d10+5");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 16, NA, NULL);
|
|
addot(OT_MACE, "mace", "A weapon with a heavy head on a solid shaft used to bludgeon opponents.", MT_METAL, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 140, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d7+1");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addot(OT_MORNINGSTAR, "morningstar", "A heavy, spiked mace.", MT_METAL, 3.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d9+1");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
addot(OT_NUNCHAKU, "nunchaku", "Two stout sticks connected with a short or rope. Good for disarming.", MT_WOOD, 1.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DISARMATTACK, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d6+1");
|
|
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_DEX, 10, NA, NULL);
|
|
addot(OT_SPANNER, "spanner", "A long, heavy metal wrench.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
|
addflag(lastot->flags, F_OBATTACKDELAY, 120, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4");
|
|
addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERNEEDDIR, B_TRUE, NA, NA, "Use your spanner in which direction");
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addot(OT_STICK, "stick", "A sturdy wooden stick.", MT_WOOD, 0.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d2");
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL);
|
|
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
// projectile weapons
|
|
addot(OT_BOW, "bow", "A weapon which projects arrows via its elasticity.", MT_WOOD, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 9, NA, NULL);
|
|
addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL);
|
|
|
|
addot(OT_CROSSBOW, "crossbow", "A standard crossbow. Very powerful, but needs high strength to use.", MT_WOOD, 5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 9, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
|
|
addot(OT_CROSSBOWHAND, "hand crossbow", "A small one-handed crossbow. Lightweight, but less powerful than a full-sized one.", MT_WOOD, 3, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_BOLT, NA, NA, NULL);
|
|
|
|
addot(OT_LONGBOW, "longbow", "A very large (human-sized) bow, capable of firing arrows with great power.", MT_WOOD, 6, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 7, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_ARROW, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ATTREQ, A_STR, 13, NA, NULL);
|
|
|
|
addot(OT_REVOLVER, "revolver", "Basic one-handed firearm.", MT_METAL, 1, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
//addflag(lastot->flags, F_DAMTYPE, DT_BASH, NA, NA, NULL);
|
|
//addflag(lastot->flags, F_DAM, 3, 4, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 10, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_BULLET, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_RUBBERBULLET, NA, NA, NULL);
|
|
|
|
addot(OT_SLING, "sling", "Stretchy piece of rubber for launching projectiles.", MT_RUBBER, 0.5, OC_WEAPON);
|
|
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
|
addflag(lastot->flags, F_FIREARM, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_FIRESPEED, 3, NA, NA, NULL);
|
|
addflag(lastot->flags, F_ACCURACY, 70, NA, NA, NULL);
|
|
addflag(lastot->flags, F_RANGE, 5, NA, NA, NULL);
|
|
addflag(lastot->flags, F_AMMOOB, OT_STONE, NA, NA, NULL);
|
|
|
|
|
|
// holy weapons
|
|
addot(OT_HANDOFGOD, "hand of god", "The ultimate power.", MT_FLESH, 0.1, OC_WEAPON);
|
|
//addflag(lastot->flags, F_RARITY, H_DUNGEON, RR_UNIQUE, NA, NULL);
|
|
//addflag(lastot->flags, F_DAMTYPE, DT_HOLY, NA, NA, NULL);
|
|
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d6+100");
|
|
addflag(lastot->flags, F_ACCURACY, 500, NA, NA, NULL);
|
|
addflag(lastot->flags, F_UNIQUE, B_TRUE, NA, NA, NULL);
|
|
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
|
|
|
|
}
|
|
|
|
// returns the 'armourrating' flag
|
|
flag_t *isarmour(object_t *o) {
|
|
flag_t *f;
|
|
if (hasflag(o->flags, F_GOESON)) {
|
|
f = hasflag(o->flags, F_ARMOURRATING);
|
|
if (f) {
|
|
return f;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int isactivated(object_t *o) {
|
|
if (hasflag(o->flags, F_ACTIVATED)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isammofor(object_t *ammo, object_t *gun) {
|
|
if (hasflagval(gun->flags, F_AMMOOB, ammo->type->id, NA, NA, NULL)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
// is armour 'a' better than armour 'b'?
|
|
int isbetterarmourthan(object_t *a, object_t *b) {
|
|
int arma, armb;
|
|
flag_t *f;
|
|
if (!a) return B_FALSE;
|
|
if (!b) return B_TRUE;
|
|
|
|
f = isarmour(a);
|
|
if (f) {
|
|
arma = f->val[0];
|
|
} else {
|
|
arma = 0;
|
|
}
|
|
f = isarmour(b);
|
|
if (f) {
|
|
armb = f->val[0];
|
|
} else {
|
|
armb = 0;
|
|
}
|
|
if (arma > armb) return B_TRUE;
|
|
return B_FALSE;
|
|
|
|
}
|
|
|
|
// compare weapons using max damage
|
|
int isbetterwepthan(object_t *a, object_t *b) {
|
|
//flag_t *f;
|
|
int dama,damb;
|
|
float acca,accb;
|
|
int db = B_FALSE;
|
|
char namea[BUFLEN];
|
|
char nameb[BUFLEN];
|
|
|
|
if (!a) return B_FALSE;
|
|
if (!b) return B_TRUE;
|
|
|
|
/* if (a->pile->owner && lfhasflag(a->pile->owner, F_DEBUG)) {
|
|
db = B_TRUE;
|
|
}
|
|
if (b->pile->owner && lfhasflag(b->pile->owner, F_DEBUG)) {
|
|
db = B_TRUE;
|
|
} */
|
|
|
|
|
|
if (db) {
|
|
getobname(a, namea, a->amt);
|
|
getobname(b, nameb, b->amt);
|
|
}
|
|
|
|
getdamrange(hasflag(a->flags, F_DAM), NULL, &dama);
|
|
getdamrange(hasflag(b->flags, F_DAM), NULL, &damb);
|
|
|
|
// modify based on extra props
|
|
if (hasflag(a->flags, F_HASBRAND)) {
|
|
dama *= 3;
|
|
}
|
|
if (hasflag(a->flags, F_ONFIRE)) {
|
|
dama += 8;
|
|
}
|
|
|
|
|
|
if (hasflag(b->flags, F_HASBRAND)) {
|
|
damb *= 3;
|
|
}
|
|
if (hasflag(b->flags, F_ONFIRE)) {
|
|
damb += 8;
|
|
}
|
|
|
|
// modify with accuracy
|
|
acca = getobaccuracy(a, a->pile->owner);
|
|
accb = getobaccuracy(b, b->pile->owner);
|
|
|
|
|
|
if (db) {
|
|
msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
|
|
}
|
|
|
|
dama = (int)((float)dama * (acca/100));
|
|
damb = (int)((float)damb * (accb/100));
|
|
|
|
if (db) {
|
|
msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb);
|
|
}
|
|
|
|
if (dama > damb) return B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isblessed(object_t *o) {
|
|
if (o->blessed == B_BLESSED) return B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isblessknown(object_t *o) {
|
|
if (o->blessknown) return B_TRUE;
|
|
if ((gamemode == GM_GAMESTARTED) && hasflag(player->flags, F_DETECTAURAS)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
int iscorpse(object_t *o) {
|
|
if (o->type->obclass->id == OC_CORPSE) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int iscursed(object_t *o) {
|
|
if (o->blessed == B_CURSED) return B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isdangerousob(object_t *o, lifeform_t *lf, int onlyifknown) {
|
|
enum IQBRACKET iqb;
|
|
iqb = getiqname(getattr(lf, A_IQ), NULL);
|
|
|
|
if (!onlyifknown || (iqb >= IQ_AVERAGE)) {
|
|
if (hasflag(o->flags, F_SHARP)) {
|
|
if (!getequippedob(lf->pack, BP_HANDS) && !isimmuneto(lf->flags, DT_SLASH)) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!onlyifknown || (iqb >= IQ_ANIMAL)) {
|
|
if (hasflag(o->flags, F_ONFIRE)) {
|
|
if (!isimmuneto(lf->flags, DT_FIRE)) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// undead won't touch blessed things - don't worry about
|
|
// onlyifknown, they can sense this.
|
|
if (hasflag(lf->flags, F_UNDEAD) && isblessed(o)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isdeadob(object_t *o) {
|
|
if (hasflag(o->flags, F_DEAD)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isdrinkable(object_t *o) {
|
|
switch (o->type->obclass->id) {
|
|
case OC_POTION:
|
|
return B_TRUE;
|
|
default: break;
|
|
}
|
|
|
|
if (hasflag(o->flags, F_DRINKABLE)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isedible(object_t *o) {
|
|
if (hasflag(o->flags, F_EDIBLE)) {
|
|
return B_TRUE;
|
|
}
|
|
if (o->material->id == MT_ICE) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
flag_t *isequipped(object_t *o) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_EQUIPPED);
|
|
if (f) {
|
|
return f;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int isequippedon(object_t *o, enum BODYPART bp) {
|
|
if (hasflagval(o->flags, F_EQUIPPED, bp, NA, NA, NULL)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isfirearm(object_t *o) {
|
|
if (hasflag(o->flags, F_FIREARM)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isflammable(object_t *o) {
|
|
if (hasflag(o->flags, F_WET)) {
|
|
return B_FALSE;
|
|
}
|
|
if (hasflag(o->flags, F_FLAMMABLE)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isknown(object_t *o) {
|
|
// if id'd, return the full name
|
|
if (hasflag(o->flags, F_IDENTIFIED)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
return isknownot(o->type);
|
|
}
|
|
|
|
int isknownot(objecttype_t *ot) {
|
|
knowledge_t *k;
|
|
// if id'd, return the full name
|
|
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (k->id == ot->id) {
|
|
// it DOES have a hidden name.
|
|
// does the player know about it?
|
|
if (k->known == B_KNOWN) {
|
|
return B_TRUE;
|
|
} else {
|
|
return B_FALSE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// no hidden name, return real one
|
|
return B_TRUE;
|
|
}
|
|
|
|
|
|
|
|
// is the object fully identified?
|
|
// ie. its type is known ("potion of healing" rather than "red potion")
|
|
// AND
|
|
// you know whether it is cursed or not
|
|
int isidentified(object_t *o) {
|
|
flag_t *f;
|
|
if (!isblessknown(o)) return B_FALSE;
|
|
if (!isknown(o)) return B_FALSE;
|
|
for (f = o->flags->first ; f ; f = f->next) {
|
|
if (!f->known) return B_FALSE;
|
|
}
|
|
|
|
return B_TRUE;
|
|
}
|
|
|
|
int isimpassableob(object_t *o, lifeform_t *lf) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_IMPASSABLE);
|
|
if (f) {
|
|
enum LFSIZE lfsize;
|
|
enum LFSIZE blocksize;
|
|
|
|
if (!lf) return B_TRUE;
|
|
|
|
lfsize = getlfsize(lf);
|
|
blocksize = f->val[0];
|
|
|
|
if (lfsize <= blocksize) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int ismagical(object_t *o) {
|
|
if (hasflag(o->flags, F_HASBRAND)) {
|
|
return B_TRUE;
|
|
}
|
|
switch (o->type->obclass->id) {
|
|
case OC_SCROLL:
|
|
switch (o->type->id) {
|
|
case OT_MAP:
|
|
case OT_SCR_NOTHING:
|
|
// these scrolls are non-magical
|
|
break;
|
|
default:
|
|
return B_TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
case OC_RING:
|
|
case OC_WAND:
|
|
// all rings/wands are magical
|
|
return B_TRUE;
|
|
break;
|
|
case OC_POTION:
|
|
switch (o->type->id) {
|
|
case OT_POT_ACID:
|
|
case OT_POT_OIL:
|
|
case OT_POT_WATER:
|
|
case OT_POT_BLOOD:
|
|
case OT_POT_RUM:
|
|
case OT_POT_JUICE:
|
|
// these potions are non-magical
|
|
break;
|
|
default:
|
|
return B_TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
case OC_BOOK:
|
|
if (hasflag(o->flags, F_LINKSPELL)) {
|
|
// ie. spellbooks
|
|
return B_TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (hasflag(o->flags, F_ENCHANTABLE) && hasflag(o->flags, F_BONUS)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int ismeleeweapon(object_t *o) {
|
|
if (hasflag(o->flags, F_DAM)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
int ismetal(enum MATERIAL mat) {
|
|
int metal = B_FALSE;
|
|
switch (mat) {
|
|
case MT_METAL:
|
|
case MT_GOLD:
|
|
metal = B_TRUE;
|
|
break;
|
|
default:
|
|
metal = B_FALSE;
|
|
break;
|
|
}
|
|
return metal;
|
|
}
|
|
|
|
int isthrowmissile(object_t *o) {
|
|
if (hasflag(o->flags, F_THROWMISSILE)) {
|
|
return B_TRUE;
|
|
}
|
|
// special cases...
|
|
switch (o->type->id) {
|
|
case OT_EMPTYFLASK: // (because it will shatter)
|
|
case OT_EMPTYVIAL: // (because it will shatter)
|
|
case OT_BROKENGLASS: // (because it will cut)
|
|
case OT_ICECHUNK: // (because it will cut)
|
|
return B_TRUE;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
// shoudl we append {tried} to this object?
|
|
int istried(object_t *o) {
|
|
if (hasflag(o->flags, F_IDENTIFIED)) {
|
|
return B_FALSE;
|
|
}
|
|
|
|
return istriedot(o->type);
|
|
}
|
|
|
|
int istriedot(objecttype_t *ot) {
|
|
knowledge_t *k;
|
|
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (k->id == ot->id) {
|
|
// it DOES have a hidden name.
|
|
// has the player tried it?
|
|
if (k->known == B_TRIED) {
|
|
return B_TRUE;
|
|
} else {
|
|
return B_FALSE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// no hidden name, so can't be "tried"
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isoperable(object_t *o) {
|
|
if (hasflag(o->flags, F_OPERABLE)) return B_TRUE;
|
|
//if (o->type->obclass->id == OC_TECH) return B_TRUE;
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
// has this object changed proerties from its
|
|
// parent objecttype?
|
|
int isplainob(object_t *o) {
|
|
if (o->material != o->type->material) return B_FALSE;
|
|
if (o->weight != o->type->weight) return B_FALSE;
|
|
if (o->inscription) return B_FALSE;
|
|
if (o->blessed != B_UNCURSED) return B_FALSE;
|
|
if (isblessknown(o)) return B_FALSE;
|
|
|
|
return B_TRUE;
|
|
}
|
|
|
|
int ispourable(object_t *o) {
|
|
if (hasflag(o->flags, F_POURABLE)) {
|
|
if (o->material->id != MT_ICE) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
int ispushable(object_t *o) {
|
|
if (hasflag(o->flags, F_PUSHABLE)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isreadable(object_t *o) {
|
|
switch (o->type->obclass->id) {
|
|
case OC_SCROLL:
|
|
case OC_BOOK:
|
|
return B_TRUE;
|
|
default: break;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isrotting(object_t *o) {
|
|
flag_t *f;
|
|
float pct;
|
|
|
|
if (hasflag(o->flags, F_TAINTED)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
if (!iscorpse(o)) return B_FALSE;
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
pct = ((float) f->val[0] / (float) f->val[1]) * 100.0;
|
|
} else {
|
|
pct = 100;
|
|
}
|
|
if (pct < 25) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
flag_t *issecretdoor(object_t *o) {
|
|
if (isdoor(o, NULL)) {
|
|
return hasflag(o->flags, F_SECRETDOOR);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// returns the 'shield' flag
|
|
flag_t *isshield(object_t *o) {
|
|
return hasflag(o->flags, F_SHIELD);
|
|
}
|
|
|
|
int isthrownmissile(object_t *o) {
|
|
if (hasflag(o->flags, F_THROWMISSILE)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int isweapon(object_t *o) {
|
|
if (o->type->obclass->id == OC_WEAPON) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int iswearable(object_t *o) {
|
|
if (hasflag(o->flags, F_GOESON)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
void killmaterial(material_t *m) {
|
|
material_t *nextone, *lastone;
|
|
|
|
// free mem
|
|
free(m->name);
|
|
killflagpile(m->flags);
|
|
|
|
// remove from list
|
|
nextone = m->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = m->prev;
|
|
} else { /* last */
|
|
lastmaterial = m->prev;
|
|
}
|
|
|
|
if (m->prev == NULL) {
|
|
/* first */
|
|
nextone = m->next;
|
|
free(material);
|
|
material = nextone;
|
|
} else {
|
|
lastone = m->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
}
|
|
|
|
void killob(object_t *o) {
|
|
object_t *nextone, *lastone;
|
|
|
|
// remove flags conferred by this object
|
|
if (o->pile->owner) {
|
|
loseobflags(o->pile->owner, o, ALLCONFERRED);
|
|
}
|
|
|
|
// free mem
|
|
if (o->inscription) free(o->inscription);
|
|
|
|
// remove from list
|
|
nextone = o->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = o->prev;
|
|
} else { /* last */
|
|
o->pile->last = o->prev;
|
|
}
|
|
|
|
if (o->prev == NULL) {
|
|
/* first */
|
|
nextone = o->next;
|
|
o->pile->first = nextone;
|
|
free(o);
|
|
} else {
|
|
lastone = o->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
}
|
|
|
|
void killobpile(obpile_t *op) {
|
|
while (op->first) {
|
|
killob(op->first);
|
|
}
|
|
free(op);
|
|
}
|
|
|
|
void killoc(objectclass_t *oc) {
|
|
objectclass_t *nextone, *lastone;
|
|
|
|
// free mem
|
|
free(oc->name);
|
|
free(oc->desc);
|
|
if (oc->flags) killflagpile(oc->flags);
|
|
|
|
// remove from list
|
|
nextone = oc->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = oc->prev;
|
|
} else { /* last */
|
|
lastobjectclass = oc->prev;
|
|
}
|
|
|
|
if (oc->prev == NULL) {
|
|
/* first */
|
|
nextone = oc->next;
|
|
free(objectclass);
|
|
objectclass = nextone;
|
|
} else {
|
|
lastone = oc->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
}
|
|
|
|
void killot(objecttype_t *ot) {
|
|
objecttype_t *nextone, *lastone;
|
|
|
|
// free mem
|
|
free(ot->name);
|
|
free(ot->desc);
|
|
if (ot->flags) killflagpile(ot->flags);
|
|
|
|
// remove from list
|
|
nextone = ot->next;
|
|
if (nextone != NULL) {
|
|
nextone->prev = ot->prev;
|
|
} else { /* last */
|
|
lastobjecttype = ot->prev;
|
|
}
|
|
|
|
if (ot->prev == NULL) {
|
|
/* first */
|
|
nextone = ot->next;
|
|
free(objecttype);
|
|
objecttype = nextone;
|
|
} else {
|
|
lastone = ot->prev;
|
|
free (lastone->next );
|
|
lastone->next = nextone;
|
|
}
|
|
}
|
|
|
|
int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher) {
|
|
int i;
|
|
char obname[BUFLEN];
|
|
int seen;
|
|
cell_t *obcell, *c;
|
|
|
|
getobname(o,obname, o->amt);
|
|
obcell = getoblocation(o);
|
|
if (haslos(player, obcell)) {
|
|
seen = B_TRUE;
|
|
} else {
|
|
seen = B_FALSE;
|
|
}
|
|
|
|
if (dir == D_NONE) {
|
|
// failed!
|
|
return B_TRUE;
|
|
}
|
|
|
|
c = obcell;
|
|
for (i = 0; i < howfar; i++) {
|
|
cell_t *newcell;
|
|
newcell = getcellindir(c, dir);
|
|
if (!newcell) {
|
|
// hit a wall - stop here
|
|
break;
|
|
} else if (newcell->lf) {
|
|
// hit them - stop here
|
|
c = newcell;
|
|
break;
|
|
} else if (!cellwalkable(NULL, newcell, NULL)) {
|
|
// hit a wall - stop here
|
|
break;
|
|
}
|
|
c = newcell;
|
|
}
|
|
fireat(NULL, o, o->amt, c, power, NULL);
|
|
return B_FALSE;
|
|
}
|
|
|
|
// animate a weapon
|
|
lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) {
|
|
cell_t *where;
|
|
flag_t *f;
|
|
lifeform_t *newlf;
|
|
|
|
where = getrandomadjcell(lf->cell, WE_EMPTY, B_NOEXPAND);
|
|
if (!where) return NULL;
|
|
|
|
newlf = addlf(where, R_DANCINGWEAPON, level);
|
|
if (newlf) {
|
|
if (isplayer(lf)) {
|
|
addflag(newlf->flags, F_FRIENDLY, B_TRUE, NA, NA, NULL);
|
|
} else if (hasflag(lf->flags, F_HOSTILE)) {
|
|
addflag(newlf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
|
|
}
|
|
|
|
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
|
|
|
|
o = relinkob(o, newlf->pack);
|
|
weild(newlf, o);
|
|
|
|
f = hasflag(o->flags, F_OBHP);
|
|
if (f) {
|
|
newlf->maxhp = f->val[1];
|
|
newlf->hp = newlf->maxhp;
|
|
}
|
|
f = hasflag(o->flags, F_OBATTACKDELAY);
|
|
if (f) {
|
|
int origspeed;
|
|
int newspeed;
|
|
origspeed = getmovespeed(newlf);
|
|
killflagsofid(newlf->flags, F_MOVESPEED);
|
|
newspeed = (int)((float)origspeed * ((float)f->val[0] / 100.0));
|
|
addflag(newlf->flags, F_MOVESPEED, newspeed, NA, NA, NULL);
|
|
}
|
|
}
|
|
if (newlf) {
|
|
addflag(newlf->flags, F_PETOF, lf->id, NA, NA, NULL);
|
|
}
|
|
return newlf;
|
|
}
|
|
|
|
// returns true if something hapepned
|
|
int makeduller(object_t *o, int howmuch) {
|
|
char obname[BUFLEN];
|
|
int oldbonus,newbonus;
|
|
int rv = B_FALSE;
|
|
|
|
// get object name before changing the bonus
|
|
getobname(o,obname, 1);
|
|
|
|
oldbonus = getobbonus(o);
|
|
modbonus(o, -howmuch);
|
|
newbonus = getobbonus(o);
|
|
|
|
if (newbonus < oldbonus) {
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s seems duller!",noprefix(obname));
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(o->pile->owner, lfname);
|
|
msg("%s%s %s seems duller!",lfname, getpossessive(lfname), noprefix(obname));
|
|
}
|
|
} else {
|
|
cell_t *obloc;
|
|
obloc = getoblocation(o);
|
|
if (haslos(player, obloc)) {
|
|
msg("%s seems duller!",obname);
|
|
}
|
|
}
|
|
rv = B_TRUE;
|
|
} else {
|
|
rv = B_FALSE;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
void makeknown(enum OBTYPE otid) {
|
|
knowledge_t *k;
|
|
object_t *o;
|
|
flag_t *f;
|
|
object_t *srcob[MAXPILEOBS*3];
|
|
enum FLAG fttogive[MAXPILEOBS*3];
|
|
int nobs = 0;
|
|
int i;
|
|
|
|
if (player) {
|
|
// if player is holding an object of that type with F_CONFER.. IFKNOWN... and isn't known...
|
|
// then by making the object known, we also need to give them the flag.
|
|
//
|
|
// keep a list of objects and flags here, then give them afterwards.
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (o->type->id == otid) {
|
|
if (!isknown(o)) {
|
|
for (f = o->flags->first ; f ; f = f->next) {
|
|
if ((f->id == F_HOLDCONFER) && (f->val[2] == IFKNOWN)) {
|
|
srcob[nobs] = o;
|
|
fttogive[nobs] = F_HOLDCONFER;
|
|
nobs++;
|
|
} else if ((f->id == F_EQUIPCONFER) && (f->val[2] == IFKNOWN) && isequipped(o)) {
|
|
srcob[nobs] = o;
|
|
fttogive[nobs] = F_EQUIPCONFER;
|
|
nobs++;
|
|
} else if ((f->id == F_ACTIVATECONFER) && (f->val[2] == IFKNOWN) && isactivated(o)) {
|
|
srcob[nobs] = o;
|
|
fttogive[nobs] = F_ACTIVATECONFER;
|
|
nobs++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (k->id == otid) {
|
|
k->known = B_KNOWN;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < nobs; i++) {
|
|
giveobflags(player, srcob[i], fttogive[i]);
|
|
}
|
|
}
|
|
|
|
void maketried(enum OBTYPE otid) {
|
|
knowledge_t *k;
|
|
|
|
for (k = knowledge; k ; k = k->next) {
|
|
if (k->id == otid) {
|
|
if (k->known == B_UNKNOWN) {
|
|
k->known = B_TRIED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void makewet(object_t *o, int amt) {
|
|
cell_t *loc;
|
|
lifeform_t *owner;
|
|
char ownername[BUFLEN];
|
|
char obname[BUFLEN];
|
|
char obnamefull[BUFLEN];
|
|
flag_t *f;
|
|
|
|
if (hasflag(o->flags, F_WATERPROOF)) {
|
|
return;
|
|
}
|
|
|
|
loc = getoblocation(o);
|
|
owner = o->pile->owner;
|
|
if (owner) {
|
|
getlfname(owner, ownername);
|
|
}
|
|
getobname(o,obname,o->amt);
|
|
|
|
if (owner) {
|
|
sprintf(obnamefull, "%s%s %s",ownername, getpossessive(ownername), noprefix(obname));
|
|
} else {
|
|
strcpy(obnamefull, obname);
|
|
}
|
|
|
|
if (o->material->id == MT_METAL) {
|
|
if (amt < R_RUSTY) amt = R_RUSTY;
|
|
if (amt > R_TRUSTY) amt = R_TRUSTY;
|
|
f = hasflag(o->flags, F_RUSTED);
|
|
if (f) {
|
|
if (f->val[0] < R_TRUSTY) {
|
|
// make more rusty
|
|
f->val[0] += amt;
|
|
}
|
|
} else {
|
|
// rust
|
|
if (haslos(player, loc)) {
|
|
msg("%s rust%s.",obnamefull, (o->amt == 1) ? "s" : "");
|
|
}
|
|
f = addflag(o->flags, F_RUSTED, amt, NA, NA, NULL);
|
|
}
|
|
} else {
|
|
if (hasflag(o->flags, F_CANGETWET)) {
|
|
if (amt < W_DAMP) amt = W_DAMP;
|
|
if (amt > W_SOAKED) amt = W_SOAKED;
|
|
f = hasflag(o->flags, F_WET);
|
|
if (f) {
|
|
if (f->val[0] < W_SOAKED) {
|
|
// make wetter
|
|
/*
|
|
if (haslos(player, loc)) {
|
|
msg("%s get%s wetter.",obnamefull, (o->amt == 1) ? "s" : "");
|
|
}
|
|
*/
|
|
f->val[0] += amt;
|
|
f->val[1] = WETTIME;
|
|
} else {
|
|
// jsut reset wettime
|
|
f->val[1] = WETTIME;
|
|
}
|
|
} else {
|
|
|
|
// get wet
|
|
if (haslos(player, loc)) {
|
|
msg("%s get%s wet.",obnamefull, (o->amt == 1) ? "s" : "");
|
|
}
|
|
f = addflag(o->flags, F_WET, amt, WETTIME, NA, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
object_t *moveob(object_t *src, obpile_t *dst, int howmany) {
|
|
object_t *o, *existob;
|
|
int i;
|
|
int db = B_FALSE;
|
|
|
|
reason = E_OK;
|
|
|
|
|
|
if (db) dblog("DB: moveob() - moving %d x %s",howmany, src->type->name);
|
|
existob = canstackob(dst, src);
|
|
if (existob) {
|
|
if (db) dblog("DB: moveob() - found stack to join");
|
|
if (howmany == ALL) howmany = src->amt;
|
|
existob->amt += howmany;
|
|
src->amt -= howmany;
|
|
if (src->amt == 0) {
|
|
killob(src);
|
|
}
|
|
|
|
o = existob;
|
|
} else {
|
|
if (db) dblog("DB: moveob() - no stack to join");
|
|
|
|
// space in destination pile?
|
|
if (getnextletter(dst, NULL) == '\0') {
|
|
reason = E_NOSPACE;
|
|
return NULL;
|
|
}
|
|
|
|
// no similar objects in the dest pile.
|
|
if ((howmany == ALL) || (howmany == src->amt)) {
|
|
if (db) dblog("DB: dropping ALL - relinking object to new pile");
|
|
// just move the whole object to the new pile
|
|
o = relinkob(src, dst);
|
|
} else {
|
|
obpile_t *tempop;
|
|
if (db) dblog("DB: moving only some of a stack.");
|
|
|
|
|
|
// create temporary object pile
|
|
tempop = addobpile(NULL, NULL);
|
|
// add new object to the temporary pile
|
|
o = addob(tempop, src->type->name);
|
|
// copy props from original object
|
|
copyobprops(o, src);
|
|
|
|
// just move some of them
|
|
for (i = 0; i < howmany; i++ ) {
|
|
// the first one is already there!
|
|
if (i != 0) {
|
|
// inc counter in temp pile
|
|
o->amt++;
|
|
}
|
|
// dec counter on original
|
|
src->amt--;
|
|
}
|
|
if (src->amt <= 0) {
|
|
killob(src);
|
|
}
|
|
// now move the object entry from the temporary pile to the
|
|
// real destination pile.
|
|
while (tempop->first) {
|
|
o = relinkob(tempop->first, dst);
|
|
}
|
|
free(tempop);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (o) {
|
|
//if (dst->owner && isplayer(dst->owner) && lfhasflag(dst->owner, F_DETECTAURAS)) {
|
|
if (dst->owner && isplayer(dst->owner) && isblessknown(o)) {
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
|
|
if (hasflag(o->flags, F_DOOR)) {
|
|
killflagsofid(o->flags, F_LOCKED);
|
|
killflagsofid(o->flags, F_JAMMED);
|
|
killflagsofid(o->flags, F_SECRETDOOR);
|
|
if (!hasflag(o->flags, F_OPEN)) {
|
|
addflag(o->flags, F_OPEN, B_TRUE, NA, NA, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dst->where && !dst->where->lf && haslos(player, dst->where)) {
|
|
needredraw = B_TRUE;
|
|
drawscreen();
|
|
}
|
|
|
|
// in case you picked up money, something which changes your AR, etc
|
|
if (dst->owner && isplayer(dst->owner)) {
|
|
statdirty = B_TRUE;
|
|
}
|
|
|
|
//o = newobeffects(o);
|
|
|
|
return o;
|
|
}
|
|
|
|
void modbonus(object_t *o, int amt) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_BONUS);
|
|
if (f) {
|
|
f->val[0] += amt;
|
|
} else {
|
|
cell_t *loc;
|
|
int known;
|
|
loc = getoblocation(o);
|
|
if (haslos(player, loc)) {
|
|
known = B_TRUE;
|
|
} else {
|
|
known = B_FALSE;
|
|
}
|
|
f = addflag_real(o->flags, F_BONUS, amt, NA, NA, NULL, PERMENANT, known, -1);
|
|
}
|
|
// enforce limit
|
|
limit(&f->val[0], -7, 7);
|
|
}
|
|
|
|
void obaction(object_t *o, char *text) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, o->amt);
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s %s!", noprefix(obname), text);
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(o->pile->owner, lfname);
|
|
msg("%s%s %s %s!", lfname, getpossessive(lfname),
|
|
noprefix(obname), text);
|
|
}
|
|
} else if (haslos(player, o->pile->where)) { // on ground
|
|
msg("%s %s!", obname, text);
|
|
}
|
|
}
|
|
|
|
object_t *obexists(enum OBTYPE obid) {
|
|
map_t *m;
|
|
int x,y;
|
|
object_t *o;
|
|
lifeform_t *lf;
|
|
|
|
// do any objects of this id already exist?
|
|
for (m = firstmap ; m ; m = m->next) {
|
|
// check cells
|
|
for (y = 0; y < m->h; y++) {
|
|
for (x = 0; x < m->w; x++) {
|
|
cell_t *c;
|
|
c = getcellat(m, x, y);
|
|
if (c) {
|
|
o = hasob(c->obpile, obid);
|
|
if (o) return o;
|
|
}
|
|
}
|
|
}
|
|
// check lifeforms
|
|
for (lf = m->lf ; lf ; lf = lf->next) {
|
|
o = hasob(lf->pack, obid);
|
|
if (o) return o;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void obdie(object_t *o) {
|
|
char obname[BUFLEN];
|
|
flag_t *f;
|
|
cell_t *obloc;
|
|
|
|
obloc = o->pile->where;
|
|
|
|
f = hasflag(o->flags, F_DIECONVERT);
|
|
if (f) {
|
|
flag_t *f2;
|
|
object_t *newob;
|
|
char desc[BUFLEN];
|
|
if (!hasflag(o->flags, F_NODIECONVERTTEXT)) {
|
|
// announce the change
|
|
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
|
|
|
f2 = NULL;
|
|
if (o->amt > 1) {
|
|
f2 = hasflag(o->flags, F_DIECONVERTTEXTPL);
|
|
}
|
|
if (!f2) {
|
|
f2 = hasflag(o->flags, F_DIECONVERTTEXT);
|
|
}
|
|
if (f2) {
|
|
sprintf(desc, "%s", f2->text);
|
|
} else if (oblastdamtype(o) == DT_DECAY) {
|
|
sprintf(desc, "%s completed rotted away", (o->amt == 1) ? "has" : "have");
|
|
} else {
|
|
sprintf(desc, "%s destroyed", (o->amt == 1) ? "is" : "are");
|
|
}
|
|
if (strstr(o->type->name, "stain") || (o->type->id == OT_ROASTMEAT)) {
|
|
assert(0 == 1);
|
|
}
|
|
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s %s!",noprefix(obname), desc);
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
// don't announce decay death unless we are holding it
|
|
if (oblastdamtype(o) != DT_DECAY) {
|
|
char monname[BUFLEN];
|
|
getlfname(o->pile->owner, monname);
|
|
msg("%s's %s %s!",monname, noprefix(obname), desc);
|
|
}
|
|
}
|
|
} else if (haslos(player, o->pile->where)) {
|
|
// don't announce decay death unless we are holding it
|
|
if (oblastdamtype(o) != DT_DECAY) {
|
|
capitalise(obname);
|
|
msg("%s %s.",obname, desc);
|
|
}
|
|
}
|
|
}
|
|
|
|
// change into something else
|
|
newob = addob(o->pile, f->text);
|
|
// only set amt if text wasn't "x-y somethings"
|
|
if (!strchr(f->text, '-')) {
|
|
newob->amt = o->amt;
|
|
}
|
|
} else {
|
|
char desc[BUFLEN];
|
|
|
|
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
|
if (!hasflag(o->flags, F_NOOBDIETEXT)) {
|
|
// announce the death
|
|
f = hasflag(o->flags, F_OBDIETEXT);
|
|
if (f) {
|
|
sprintf(desc, "%s", f->text);
|
|
} else if (oblastdamtype(o) == DT_DECAY) {
|
|
sprintf(desc, "%s completely rotted away", (o->amt == 1) ? "has" : "have" );
|
|
} else {
|
|
sprintf(desc, "%s destroyed", (o->amt == 1) ? "is" : "are");
|
|
}
|
|
|
|
if (o->pile->owner) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s %s!",noprefix(obname), desc);
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
char monname[BUFLEN];
|
|
getlfname(o->pile->owner, monname);
|
|
msg("%s's %s %s!",monname, noprefix(obname), desc);
|
|
}
|
|
} else if (haslos(player, o->pile->where)) {
|
|
msg("%s %s.",obname, desc);
|
|
}
|
|
}
|
|
|
|
// explodes?
|
|
f = hasflag(o->flags, F_EXPLODEONDEATH);
|
|
if (f) {
|
|
if (f->val[2] == B_IFACTIVATED) {
|
|
if (isactivated(o)) {
|
|
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
|
}
|
|
} else {
|
|
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// flashes?
|
|
f = hasflag(o->flags, F_FLASHONDEATH);
|
|
if (f) {
|
|
if (f->val[2] == B_IFACTIVATED) {
|
|
if (isactivated(o)) {
|
|
brightflash(getoblocation(o),f->val[0], NULL);
|
|
}
|
|
} else {
|
|
brightflash(getoblocation(o),f->val[0], NULL);
|
|
}
|
|
}
|
|
|
|
// corpse decaying and on the ground?
|
|
if ((oblastdamtype(o) == DT_DECAY) && (o->type->id == OT_CORPSE)) {
|
|
if (o->pile->where) {
|
|
int minbones,maxbones;
|
|
char bonestr[BUFLEN];
|
|
minbones = o->weight / 10;
|
|
maxbones = o->weight / 5;
|
|
if (minbones <= 0) minbones = 1;
|
|
if (maxbones <= minbones) maxbones = 2;
|
|
sprintf(bonestr, "%d-%d bones",minbones,maxbones);
|
|
addob(o->pile, bonestr);
|
|
}
|
|
}
|
|
}
|
|
|
|
killob(o);
|
|
// redraw
|
|
if (obloc && !obloc->lf && haslos(player, obloc)) {
|
|
needredraw = B_TRUE;
|
|
drawscreen();
|
|
}
|
|
}
|
|
|
|
int obfits(object_t *o, obpile_t *op) {
|
|
if (countobs(op) >= MAXPILEOBS) {
|
|
return B_FALSE;
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
enum DAMTYPE oblastdamtype(object_t *o) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_LASTDAMTYPE);
|
|
if (f) {
|
|
return f->val[0];
|
|
}
|
|
return DT_NONE;
|
|
}
|
|
|
|
int brandappliesto(brand_t *om, objecttype_t *ot) {
|
|
if (om->bp == BP_WEAPON) {
|
|
if (ot->obclass->id == OC_WEAPON) {
|
|
return B_TRUE;
|
|
}
|
|
} else {
|
|
// TODO: how do we differentiate shields from guns?
|
|
if (hasflagval(ot->flags, F_GOESON, om->bp, NA, NA, NULL)) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
|
|
int obmatchescondition(object_t *o, long opts) {
|
|
int ok;
|
|
|
|
if (opts) {
|
|
// default to not ok
|
|
ok = B_FALSE;
|
|
} else {
|
|
// default to ok
|
|
ok = B_TRUE;
|
|
}
|
|
if ((opts & AO_ONLYEQUIPPED) && hasflag(o->flags, F_EQUIPPED)) {
|
|
ok = B_TRUE;
|
|
}
|
|
if ((opts & AO_EQUIPPEDNONWEAPON)) {
|
|
flag_t *ff;
|
|
ff = hasflag(o->flags, F_EQUIPPED);
|
|
if (ff) {
|
|
if ((ff->val[0] != BP_WEAPON) &&
|
|
(ff->val[0] != BP_SECWEAPON)) {
|
|
ok = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
if ((opts & AO_EDIBLE) && isedible(o)) ok = B_TRUE;
|
|
if ((opts & AO_DRINKABLE) && isdrinkable(o)) ok = B_TRUE;
|
|
if ((opts & AO_READABLE) && isreadable(o)) ok = B_TRUE;
|
|
if ((opts & AO_ARMOUR) && (o->type->obclass->id == OC_ARMOUR)) ok = B_TRUE;
|
|
if (opts & AO_DAMAGED) {
|
|
flag_t *ff;
|
|
ff = hasflag(o->flags, F_OBHP);
|
|
if (ff && (ff->val[0] < ff->val[1])) {
|
|
ok = B_TRUE;
|
|
}
|
|
}
|
|
if ((opts & AO_WEARABLE) && iswearable(o)) ok = B_TRUE;
|
|
if ((opts & AO_WEILDABLE) && isweapon(o)) ok = B_TRUE;
|
|
if ((opts & AO_OPERABLE) && isoperable(o)) ok = B_TRUE;
|
|
if ((opts & AO_POURABLE) && ispourable(o)) ok = B_TRUE;
|
|
if ((opts & AO_NOTIDENTIFIED) && !isidentified(o)) ok = B_TRUE;
|
|
if ((opts & AO_NOTKNOWN) && !isknown(o)) ok = B_TRUE;
|
|
|
|
return ok;
|
|
}
|
|
|
|
// returns the amount of light produced
|
|
int obproduceslight(object_t *o) {
|
|
flag_t *f;
|
|
int amt = 0;
|
|
f = hasflag(o->flags, F_PRODUCESLIGHT);
|
|
if (f) {
|
|
int thisamt = 0;
|
|
if (f->val[2] == IFACTIVE) {
|
|
if (isactivated(o)) {
|
|
sumflags(o->flags, F_PRODUCESLIGHT, &thisamt, NULL, NULL);
|
|
}
|
|
} else {
|
|
sumflags(o->flags, F_PRODUCESLIGHT, &thisamt, NULL, NULL);
|
|
}
|
|
amt += thisamt;
|
|
}
|
|
// flaming things should produce fire
|
|
if (amt == 0) {
|
|
if (hasflag(o->flags, F_ONFIRE) || (o->material->id == MT_FIRE)) {
|
|
amt += 1;
|
|
}
|
|
}
|
|
return amt;
|
|
}
|
|
|
|
// has this object changed proerties from its
|
|
// parent objecttype?
|
|
int obpropsmatch(object_t *a, object_t *b) {
|
|
if (a->type != b->type) return B_FALSE;
|
|
if (a->material != b->material) return B_FALSE;
|
|
if (a->weight != b->weight) return B_FALSE;
|
|
if (a->inscription || b->inscription) return B_FALSE;
|
|
// only really need to check one of them, because at this point
|
|
// we know they are of the same type.
|
|
if (!hasflag(a->flags, F_NOBLESS) && !hasflag(b->flags, F_NOBLESS)) {
|
|
if (a->blessed != b->blessed) return B_FALSE;
|
|
if (isblessknown(a) != isblessknown(b)) return B_FALSE;
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|
char buf[BUFLEN],obname[BUFLEN];
|
|
int playercansee;
|
|
flag_t *f;
|
|
int willid = B_FALSE;
|
|
|
|
if (!lfhasflag(lf, F_HUMANOID) || !hasbp(lf, BP_HANDS)) {
|
|
// only humanoids can zap things
|
|
return B_TRUE;
|
|
}
|
|
|
|
getobname(o, obname, 1);
|
|
|
|
if ((isplayer(lf)) || cansee(player, lf)) {
|
|
playercansee = B_TRUE;
|
|
} else {
|
|
playercansee = B_FALSE;
|
|
}
|
|
|
|
|
|
// if not a wand, must know what a tool is before you can use it
|
|
if (!isknown(o) && (o->type->obclass->id != OC_WAND)) {
|
|
if (isplayer(lf)) {
|
|
msg("You don't know how to use %s!", obname);
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
if (gettechlevel(o) > getskill(lf, SK_TECHUSAGE)) {
|
|
if (isplayer(lf)) {
|
|
msg("This technology is beyond your understanding.");
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
// objects with charges...
|
|
if (hasflag(o->flags, F_OPERUSECHARGE)) { // operating toggles on/off
|
|
int chargesleft;
|
|
chargesleft = getcharges(o);
|
|
if (chargesleft > 0) {
|
|
chargesleft = usecharge(o);
|
|
// TODO: notify if getting low
|
|
} else {
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
// you know it's out
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
f->known = B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ask for target, if required
|
|
f = hasflag(o->flags, F_OPERNEEDTARGET);
|
|
if (f && !where) {
|
|
int ttype = TT_NONE;
|
|
// don't give hints about the object
|
|
if (isknown(o)) {
|
|
ttype = f->val[0];
|
|
}
|
|
|
|
if (isplayer(lf)) {
|
|
if (strlen(f->text) > 0) {
|
|
where = askcoords(f->text, ttype);
|
|
} else {
|
|
sprintf(buf, "Where will you aim %s?",obname);
|
|
where = askcoords(buf, ttype);
|
|
if (!haslos(lf, where)) {
|
|
// exception - wand of digging doesn't need los
|
|
if (isknown(o) && (o->type->id == OT_WAND_DIGGING)) {
|
|
} else {
|
|
msg("You can't see there!");
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
dblog("BUG - ai (%s, id %d) using wand (%s) without target.",
|
|
lfname, lf->id, obname);
|
|
where = NULL;
|
|
}
|
|
|
|
if (!where) {
|
|
// cancel.
|
|
if (isplayer(lf)) msg("Cancelled.");
|
|
return B_TRUE;
|
|
} else {
|
|
if (f->val[1] != NA) {
|
|
cell_t *newwhere = NULL;
|
|
if ((f->val[1] & TR_NEEDLOS) && !haslos(lf, where)) {
|
|
if (isplayer(lf)) msg("You can't see there!");
|
|
return B_TRUE;
|
|
}
|
|
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf->cell, where, B_TRUE, &newwhere)) {
|
|
if (newwhere) {
|
|
// update destination
|
|
where = newwhere;
|
|
} else {
|
|
if (isplayer(lf)) msg("You have no line of fire to there!");
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
f = hasflag(o->flags, F_OPERNEEDDIR);
|
|
if (f) {
|
|
char ch;
|
|
int dir;
|
|
// ask direction
|
|
ch = askchar(f->text, "yuhjklbn-","-", B_FALSE);
|
|
if (ch == '-') {
|
|
msg("Cancelled.");
|
|
return B_TRUE;
|
|
} else {
|
|
dir = chartodir(ch);
|
|
where = getcellindir(lf->cell, dir);
|
|
}
|
|
}
|
|
|
|
if (touch(lf, o)) {
|
|
return B_TRUE;
|
|
}
|
|
if (hasflag(o->flags, F_DEAD)) return B_TRUE;
|
|
|
|
// TODO: change to be based on item type
|
|
// TODO: move this to the end in case 'operate' fails
|
|
taketime(lf, getactspeed(lf));
|
|
|
|
// mark obejct as tried
|
|
maketried(o->type->id);
|
|
|
|
/*
|
|
if (lf->controller != C_PLAYER) {
|
|
|
|
if (haslos(player, lf->cell)) {
|
|
getlfname(lf, buf);
|
|
capitalise(buf);
|
|
msg("%s operates %s.", buf, obname);
|
|
}
|
|
}
|
|
*/
|
|
|
|
if (hasflag(o->flags, F_OPERONOFF)) { // operating toggles on/off
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_ACTIVATED);
|
|
if (f) {
|
|
turnoff(lf, o);
|
|
} else {
|
|
turnon(lf, o);
|
|
}
|
|
} else if (hasflag(o->flags, F_FIREARM)) { // special case - change ammo
|
|
object_t *oo;
|
|
// construct list of possible ammo
|
|
clearretobs();
|
|
for (oo = lf->pack->first ; oo ; oo = oo->next) {
|
|
if (isammofor(oo, o)) {
|
|
retobs[nretobs] = oo;
|
|
nretobs++;
|
|
}
|
|
}
|
|
if (nretobs <= 0) {
|
|
sprintf(buf, "You have no ammo for your %s!",noprefix(obname));
|
|
msg(buf);
|
|
return B_TRUE;
|
|
} else {
|
|
sprintf(buf, "Load %s with what ammo",obname);
|
|
oo = askobject(lf->pack, buf, NULL, AO_SPECIFIED);
|
|
if (oo) {
|
|
setammo(lf, oo);
|
|
}
|
|
}
|
|
} else if (o->type->obclass->id == OC_WAND) {
|
|
if (!isplayer(lf) && cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s zaps %s.",lfname,obname);
|
|
}
|
|
|
|
|
|
f = hasflag(o->flags, F_LINKSPELL);
|
|
if (f) {
|
|
enum OBTYPE spelltocast;
|
|
int power;
|
|
|
|
spelltocast = f->val[0];
|
|
power = f->val[1];
|
|
|
|
if (power == NA) power = 1;
|
|
|
|
if (isblessed(o)) power += 4;
|
|
power += (getskill(lf, SK_CHANNELING)*2);
|
|
|
|
// certain wands always used the blessed version of spells
|
|
// certain wands have different effects when cursed
|
|
switch (o->type->id) {
|
|
case OT_WAND_LIGHT:
|
|
if (iscursed(o)) {
|
|
spelltocast = OT_S_DARKNESS;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
dospelleffects(lf, spelltocast, power, where ? where->lf : NULL, NULL, where, isblessed(o), &willid);
|
|
// special wands
|
|
} else if (o->type->id == OT_WAND_WONDER) {
|
|
int power;
|
|
// random power
|
|
power = rnd(1,10);
|
|
// 1 in 3 chance of targetting yourself
|
|
if (onein(3)) {
|
|
where = lf->cell;
|
|
}
|
|
|
|
// random effect
|
|
switch (rnd(0,21)) {
|
|
case 0: // butterflies around user
|
|
willid = B_TRUE;
|
|
where = getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
|
addmonster(where, R_BUTTERFLY, B_FALSE, rnd(10,20), B_FALSE);
|
|
if (haslos(player, where)) {
|
|
msg("A swarm of butterflies appears!");
|
|
}
|
|
break;
|
|
case 1: // summon monster
|
|
dospelleffects(lf, OT_S_CREATEMONSTER, rnd(1,4), NULL, NULL, NULL, B_UNCURSED, &willid);
|
|
break;
|
|
case 2: // animate dead
|
|
dospelleffects(lf, OT_S_ANIMATEDEAD, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 3: // blindness
|
|
dospelleffects(lf, OT_S_BLINDNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 4: // levitate
|
|
dospelleffects(lf, OT_S_LEVITATION, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 5: // dispersal
|
|
dospelleffects(lf, OT_S_DISPERSAL, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 6: // flash
|
|
dospelleffects(lf, OT_S_FLASH, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 7: // light
|
|
dospelleffects(lf, OT_S_LIGHT, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 8: // heal
|
|
dospelleffects(lf, OT_S_HEALING, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 9: // minor heal
|
|
dospelleffects(lf, OT_S_HEALINGMIN, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 10: // invis
|
|
dospelleffects(lf, OT_S_INVISIBILITY, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 11: // haste
|
|
dospelleffects(lf, OT_S_HASTE, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 12: // pull
|
|
dospelleffects(lf, OT_S_PULL, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 13: // blast
|
|
dospelleffects(lf, OT_S_AIRBLAST, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 14: // slow
|
|
dospelleffects(lf, OT_S_SLOW, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 15: // sleep
|
|
dospelleffects(lf, OT_S_SLEEP, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 16: // gas
|
|
dospelleffects(lf, OT_S_CLOUDKILL, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 17: // dark
|
|
dospelleffects(lf, OT_S_DARKNESS, power, where ? where->lf : NULL, NULL, where, B_UNCURSED, &willid);
|
|
break;
|
|
case 18: // stone
|
|
dospelleffects(lf, OT_S_PETRIFY, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 19: // fireball
|
|
dospelleffects(lf, OT_S_FIREBALL, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 20: // poly
|
|
dospelleffects(lf, OT_S_POLYMORPH, power, where ? where->lf : NULL, NULL, where, o->blessed, &willid);
|
|
break;
|
|
case 21: // teleport
|
|
dospelleffects(lf, OT_S_TELEPORT, power, lf , NULL, lf->cell, o->blessed, &willid);
|
|
break;
|
|
//oooooooooo
|
|
}
|
|
}
|
|
|
|
if (!isknown(o) && willid) {
|
|
if (isplayer(lf) || cansee(player, lf)) {
|
|
// tell player
|
|
makeknown(o->type->id);
|
|
if (iscursed(o)) {
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
if (isplayer(lf)) {
|
|
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_TRUE, B_FALSE); // don't adjust for blindness
|
|
msg("This is %s!",obname);
|
|
}
|
|
}
|
|
}
|
|
// FROM HERE ON ARE INDIVIDUAL ones
|
|
} else if (o->type->id == OT_INSECTICIDE) {
|
|
int seen = B_FALSE;
|
|
// if above half charges, big spray
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f->val[0] >= (f->val[1] / 2)) {
|
|
// big spray
|
|
int dir;
|
|
cell_t *c;
|
|
for (dir = DC_N; dir <= DC_W; dir += 2) {
|
|
c = getcellindir(where, dir);
|
|
if (c && cellwalkable(NULL, c, NULL)) {
|
|
o = addob(c->obpile, "puff of gas");
|
|
}
|
|
}
|
|
// big spray
|
|
addob(where->obpile, "cloud of poison gas");
|
|
if (isplayer(lf)) {
|
|
msg("Psssssssst!");
|
|
seen = B_TRUE;
|
|
} else if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
msg("%s%s %s emits a spray of gas.", buf, getpossessive(buf), noprefix(obname));
|
|
seen = B_TRUE;
|
|
}
|
|
} else {
|
|
// little spray
|
|
addob(where->obpile, "puff of gas");
|
|
if (isplayer(lf)) {
|
|
msg("Psst!");
|
|
seen = B_TRUE;
|
|
} else if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
msg("%s%s %s emits a puff of gas.", buf, getpossessive(buf), noprefix(obname));
|
|
seen = B_TRUE;
|
|
}
|
|
}
|
|
// announce
|
|
if (!seen) {
|
|
noise(where, NULL, "something spraying.", NULL);
|
|
}
|
|
} else if ((o->type->id == OT_EMPTYFLASK) || (o->type->id == OT_EMPTYVIAL)) {
|
|
object_t *oo,*nextoo;
|
|
if (isplayer(lf)) {
|
|
int donedip = B_FALSE;
|
|
// anything here to fill with?
|
|
for (oo = lf->cell->obpile->first ; (oo && !donedip); oo = nextoo) {
|
|
int dippable = B_FALSE;
|
|
nextoo = oo->next;
|
|
switch (oo->type->id) {
|
|
case OT_BLOODSPLASH:
|
|
case OT_SPLASHWATER:
|
|
if (oo->amt >= 5) {
|
|
dippable = B_TRUE;
|
|
}
|
|
break;
|
|
case OT_BLOODPOOL:
|
|
case OT_PUDDLEWATER:
|
|
case OT_PUDDLEWATERL:
|
|
dippable = B_TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (dippable) {
|
|
char ch;
|
|
char ques[BUFLEN];
|
|
char liquidname[BUFLEN];
|
|
object_t *newob;
|
|
getobname(oo, liquidname, 1);
|
|
sprintf(ques, "Fill your %s from %s?", noprefix(obname), liquidname);
|
|
ch = askchar(ques, "yn", "y", B_TRUE);
|
|
if (ch == 'y') {
|
|
char newobname[BUFLEN];
|
|
switch (oo->material->id) {
|
|
case MT_BLOOD:
|
|
strcpy(newobname, "potion of blood");
|
|
break;
|
|
case MT_WATER:
|
|
strcpy(newobname, "potion of water");
|
|
break;
|
|
default:
|
|
strcpy(newobname, "");
|
|
break;
|
|
}
|
|
if (strlen(newobname)) {
|
|
// kill the empty flask
|
|
removeob(o, 1);
|
|
// give the new potion
|
|
newob = addob(lf->pack, newobname);
|
|
if (newob) {
|
|
// overwrite newobname
|
|
getobname(newob, newobname, newob->amt);
|
|
msgnocap("%c - %s.",newob->letter, newobname);
|
|
}
|
|
// kill the ground object?
|
|
switch (oo->id) {
|
|
case OT_SPLASHWATER:
|
|
case OT_BLOODSPLASH:
|
|
removeob(oo, 5);
|
|
break;
|
|
case OT_PUDDLEWATER:
|
|
removeob(oo, 1);
|
|
break;
|
|
}
|
|
} else {
|
|
msg("That doesn't seem like a very good idea.");
|
|
}
|
|
donedip = B_TRUE;
|
|
} // if (ch == y)
|
|
}
|
|
}
|
|
|
|
if (!donedip) {
|
|
msg("There is nothing here to fill your %s from.",noprefix(obname));
|
|
}
|
|
}
|
|
} else if (o->type->id == OT_POCKETWATCH) {
|
|
if (isplayer(lf)) {
|
|
// TODO: if above ground, use wantpm (ie. can see the sun)
|
|
gettimetextfuzzy(buf, B_FALSE);
|
|
msg("It is currently %s.",buf);
|
|
} else if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
msg("%s looks at %s.",buf, obname);
|
|
}
|
|
} else if (o->type->id == OT_DIGITALWATCH) {
|
|
if (isplayer(lf)) {
|
|
gettimetext(buf);
|
|
msg("It is currently %s.",buf);
|
|
} else if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
capitalise(buf);
|
|
msg("%s looks at %s.",buf, obname);
|
|
}
|
|
} else if ((o->type->id == OT_LOCKPICK)
|
|
|| (o->type->id == OT_PAPERCLIP)
|
|
|| (o->type->id == OT_CREDITCARD)) {
|
|
char ch;
|
|
int dir;
|
|
// ask direction
|
|
ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
|
dir = chartodir(ch);
|
|
if (dir == D_NONE) {
|
|
clearmsg();
|
|
return B_TRUE;
|
|
} else {
|
|
cell_t *c;
|
|
c = getcellindir(player->cell, dir);
|
|
if (c) {
|
|
object_t *targ;
|
|
// something to lockpick there?
|
|
targ = hasobwithflag(c->obpile, F_LOCKED);
|
|
if (targ) {
|
|
lockpick(player, targ, o);
|
|
} else {
|
|
// fail
|
|
msg("There is nothing locked there!");
|
|
}
|
|
} else {
|
|
clearmsg();
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
} else if (o->type->id == OT_LOCKHACKER) {
|
|
char ch;
|
|
int dir;
|
|
// ask direction
|
|
ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
|
dir = chartodir(ch);
|
|
if (dir == D_NONE) {
|
|
clearmsg();
|
|
return B_TRUE;
|
|
} else {
|
|
cell_t *c;
|
|
c = getcellindir(lf->cell, dir);
|
|
if (c) {
|
|
object_t *oo,*nextoo;
|
|
// lock/unlock everything there
|
|
for (oo = c->obpile->first ; oo ; oo = nextoo) {
|
|
nextoo = oo->next;
|
|
if (hasflag(oo->flags, F_LOCKABLE)) {
|
|
flag_t *f;
|
|
f = hasflag(oo->flags, F_LOCKED);
|
|
if (f) {
|
|
killflag(f);
|
|
if (isplayer(lf)) {
|
|
msg("Your %s beeps.", noprefix(obname));
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s%s %s beeps.", lfname, getpossessive(lfname),
|
|
noprefix(obname));
|
|
}
|
|
} else {
|
|
addflag(oo->flags, F_LOCKED, B_TRUE, NA, NA, NULL);
|
|
if (isplayer(lf)) {
|
|
msg("Your %s buzzes.", noprefix(obname));
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s%s %s buzzes.", lfname, getpossessive(lfname),
|
|
noprefix(obname));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
clearmsg();
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
} else if (o->type->id == OT_PANPIPES) {
|
|
// announce
|
|
if (isplayer(lf)) {
|
|
msg("You play a few notes on your panpipes.");
|
|
} else {
|
|
noise(lf->cell, lf, "the sound of panpipes.", "plays a tune on its panpipes.");
|
|
}
|
|
} else if (o->type->id == OT_PICKAXE) {
|
|
int ch,dir;
|
|
cell_t *c;
|
|
ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE);
|
|
dir = chartodir(ch);
|
|
c = getcellindir(player->cell, dir);
|
|
|
|
if (!c) {
|
|
// cancel
|
|
clearmsg();
|
|
return B_TRUE;
|
|
}
|
|
if (c->type->solid) {
|
|
if (isdiggable(c)) {
|
|
if (isplayer(lf)) {
|
|
msg("You dig through the wall.");
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s digs through a wall.",lfname);
|
|
}
|
|
// replace wall
|
|
setcelltype(c, getemptycelltype(c->map->habitat));
|
|
// redraw screen
|
|
needredraw = B_TRUE;
|
|
drawscreen();
|
|
// takes extra time
|
|
taketime(lf, getactspeed(lf)*9);
|
|
} else {
|
|
// fail
|
|
if (isplayer(lf)) {
|
|
msg("This wall is too hard to dig.");
|
|
}
|
|
}
|
|
} else { // not solid
|
|
int failed = B_FALSE;
|
|
object_t *door;
|
|
|
|
door = hasobwithflag(c->obpile, F_DOOR);
|
|
if (door) {
|
|
int dooropen;
|
|
// only closed doors!
|
|
isdoor(door, &dooropen);
|
|
if (dooropen) {
|
|
door = NULL;
|
|
}
|
|
}
|
|
|
|
if (door) {
|
|
// TODO: metal doors are immune to CHOP damage
|
|
if (!isimmuneto(door->flags, DT_CHOP)) {
|
|
taketime(lf, getactspeed(lf));
|
|
if (isplayer(lf)) {
|
|
msg("You smash open a door!");
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s smashes open a door.",lfname);
|
|
}
|
|
removeob(door, door->amt);
|
|
needredraw = B_TRUE;
|
|
drawscreen();
|
|
failed = B_FALSE;
|
|
}
|
|
} else if (hasob(c->obpile, OT_STATUE)) {
|
|
int dam;
|
|
object_t *so;
|
|
char statname[BUFLEN];
|
|
|
|
so = hasob(c->obpile, OT_STATUE);
|
|
getobname(so, statname, so->amt);
|
|
|
|
taketime(lf, getactspeed(lf));
|
|
|
|
// statue takes 1/2 damage
|
|
f = hasflag(so->flags, F_OBHP);
|
|
if (f) {
|
|
dam = (f->val[1] / 2); // ie. half max hp
|
|
} else {
|
|
dam = 1;
|
|
}
|
|
// statue ?
|
|
if (isplayer(lf)) {
|
|
msg("You hit %s with your %s.", statname, noprefix(obname));
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s hits %s with %s.", lfname, statname, obname);
|
|
}
|
|
takedamage(so, dam, DT_CHOP);
|
|
} else {
|
|
if (isplayer(lf)) {
|
|
msg("You swing your %s through the air.",noprefix(obname));
|
|
}
|
|
taketime(lf, getactspeed(lf));
|
|
}
|
|
}
|
|
} else if (o->type->id == OT_SPANNER) {
|
|
int donesomething = B_FALSE;
|
|
if (!where) {
|
|
if (isplayer(lf)) msg("There is nothing to use your spanner on there!");
|
|
} else {
|
|
object_t *o;
|
|
char ch;
|
|
flag_t *f;
|
|
for (o = where->obpile->first ; o ; o = o->next) {
|
|
int isopen;
|
|
if (isdoor(o, &isopen)) {
|
|
if (!isopen) { // ie. if closed.
|
|
f = hasflag(o->flags, F_JAMMED);
|
|
if (f) {
|
|
ch = askchar("The hinges seem jammed. Loosen them", "yn", "y", B_TRUE);
|
|
if (ch == 'y') {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, 1);
|
|
msg("You loosen the hinges on %s.", obname);
|
|
killflag(f);
|
|
taketime(lf, getactspeed(lf));
|
|
donesomething = B_TRUE;
|
|
}
|
|
} else {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, 1);
|
|
sprintf(buf, "Tighten the hinges on %s",obname);
|
|
ch = askchar(buf, "yn", "y", B_TRUE);
|
|
if (ch == 'y') {
|
|
msg("You tighten the hinges on %s.", obname);
|
|
addflag(o->flags, F_JAMMED, rnd(1,5), NA, NA, NULL);
|
|
taketime(lf, getactspeed(lf));
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!donesomething) {
|
|
if (isplayer(lf)) msg("There is nothing to use your spanner on there!");
|
|
}
|
|
} else if (o->type->id == OT_TELEPAD) {
|
|
map_t *m;
|
|
cell_t *c,*dst = NULL;
|
|
int x,y;
|
|
int closest = 99999;
|
|
m = lf->cell->map;
|
|
// find closest pad
|
|
for (y = 0; y < m->h; y++) {
|
|
for (x = 0; x < m->w; x++) {
|
|
c = getcellat(m, x, y);
|
|
if (hasob(c->obpile, OT_TELEPAD)) {
|
|
int thisdist;
|
|
thisdist = getcelldist(lf->cell, c);
|
|
if (thisdist < closest) {
|
|
closest = thisdist;
|
|
dst = c;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dst) {
|
|
// teleport there
|
|
teleportto(lf, dst, B_TRUE);
|
|
} else {
|
|
// nothing happens
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
}
|
|
}
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
int pilehasletter(obpile_t *op, char let) {
|
|
object_t *o;
|
|
int found = B_FALSE;
|
|
|
|
for (o = op->first ; o ; o = o->next) {
|
|
if (o->letter == let) {
|
|
found = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
int pour(lifeform_t *lf, object_t *o) {
|
|
char buf[BUFLEN],obname[BUFLEN],lfname[BUFLEN],dstname[BUFLEN];
|
|
int playercansee;
|
|
char ch;
|
|
object_t *dst;
|
|
int doneask = B_FALSE;
|
|
|
|
getobname(o, obname, 1);
|
|
getlfname(lf, lfname);
|
|
|
|
if (isplayer(lf) || cansee(player, lf)) {
|
|
playercansee = B_TRUE;
|
|
} else {
|
|
playercansee = B_FALSE;
|
|
}
|
|
|
|
// adjacent to a closed door?
|
|
if (isplayer(lf)) {
|
|
int d;
|
|
for (d = DC_N; d <= DC_NW; d++) {
|
|
cell_t *c;
|
|
c = getcellindir(lf->cell, d);
|
|
if (c) {
|
|
object_t *door;
|
|
door = hasobwithflag(c->obpile, F_DOOR);
|
|
if (door) {
|
|
sprintf(buf, "Pour %s onto the door to the %s", obname, getdirname(d));
|
|
ch = askchar(buf, "yn", "n", B_TRUE);
|
|
if (ch == 'y') {
|
|
// finished asking where to pour
|
|
doneask = B_TRUE;
|
|
dst = door;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (!doneask) {
|
|
// tip onto what?
|
|
sprintf(buf, "Pour %s onto the ground", obname);
|
|
ch = askchar(buf, "yn", "y", B_TRUE);
|
|
if (ch == 'y') {
|
|
dst = NULL;
|
|
} else {
|
|
sprintf(buf, "Pour %s onto what", obname);
|
|
// tip onto another object
|
|
dst = askobject(lf->pack, buf, NULL, AO_NONE);
|
|
if (!dst) {
|
|
msg("Cancelled.");
|
|
return B_TRUE;
|
|
} else if (dst->type->obclass->id == OC_POTION) {
|
|
getobname(dst, buf, dst->amt);
|
|
msg("%s can't hold any more liquid!",buf);
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
taketime(lf, SPEED_MOVE);
|
|
|
|
if (dst) {
|
|
cell_t *dstloc;
|
|
flag_t *refillflag;
|
|
|
|
dstloc = getoblocation(dst);
|
|
|
|
// pour 'o' onto 'dst'
|
|
getobname(dst, dstname, dst->amt);
|
|
|
|
// specal cases first...
|
|
refillflag = hasflag(dst->flags, F_REFILLWITH);
|
|
if (refillflag) {
|
|
flag_t *f;
|
|
|
|
if (refillflag->val[0] == o->type->id) {
|
|
// refill destination
|
|
f = hasflag(dst->flags, F_CHARGES);
|
|
if (f) {
|
|
f->val[0] = f->val[1];
|
|
if (isplayer(lf)) {
|
|
msg("You refill your %s.", noprefix(dstname));
|
|
// we now know what the potion was
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s refills %s with %s.", lfname, dstname, obname);
|
|
// we now know what the potion was
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
}
|
|
}
|
|
} else {
|
|
// nothing happens
|
|
if (isplayer(lf)) {
|
|
msg("You refill your %s with %s. It doesn't seem to do much.", obname);
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s refills %s with %s.", lfname, dstname, obname);
|
|
}
|
|
}
|
|
} else if ((o->type->id == OT_POT_WATER) && (o->blessed == B_BLESSED)) { // holy water!
|
|
if (isplayer(lf)) {
|
|
msg("You pour %s onto %s.", obname,dstname);
|
|
}
|
|
o->blessknown = B_TRUE;
|
|
// bless whatever we poured onto
|
|
blessob(dst);
|
|
// we now know that this is holy water
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
} else if (o->type->id == OT_POT_INVULN) {
|
|
flag_t *f;
|
|
f = hasflag(dst->flags, F_DAMAGABLE);
|
|
if (f) {
|
|
if (isplayer(lf)) {
|
|
msg("Your %s looks invulnerable!",noprefix(dstname));
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
appendinscription(dst, "invuln");
|
|
}
|
|
killflag(f);
|
|
}
|
|
} else if (o->type->id == OT_POT_RESTORATION) {
|
|
flag_t *f, *nextf;
|
|
if (isplayer(lf)) {
|
|
msg("Your %s looks as good as new!",noprefix(dstname));
|
|
}
|
|
// restore orig material
|
|
if (dst->material != dst->type->material) {
|
|
changemat(dst, dst->type->material->id);
|
|
}
|
|
// remove blessings/curses
|
|
setblessed(dst, B_UNCURSED);
|
|
dst->blessknown = B_TRUE;
|
|
// remove bonuses
|
|
killflagsofid(dst->flags, F_BONUS);
|
|
// remove temporary flags, obmod flags and modify some others
|
|
for (f = dst->flags->first ; f ; f = nextf) {
|
|
nextf = f->next;
|
|
if (f->lifetime > 0) {
|
|
killflag(f);
|
|
} else if (f->lifetime == FROMOBMOD) {
|
|
killflag(f);
|
|
} else if (f->id == F_FROZEN) {
|
|
killflag(f);
|
|
} else if (f->id == F_ONFIRE) {
|
|
killflag(f);
|
|
} else if (f->id == F_POISONED) {
|
|
killflag(f);
|
|
} else if (f->id == F_OBHP) {
|
|
f->val[0] = f->val[1];
|
|
}
|
|
|
|
}
|
|
|
|
// we now know what the potion was
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
//if (!isknown(dst)) makeknown(dst->type->id);
|
|
} else if (o->type->id == OT_POT_ACID) {
|
|
// damage destinaiton
|
|
msg("You pour %s onto %s.", obname,dstname);
|
|
takedamage(dst, rnd(5,15), DT_ACID);
|
|
makeknown(o->type->id);
|
|
} else if (isdoor(dst, NULL)) {
|
|
msg("Your pour %s all over %s.", obname, dstname);
|
|
if (o->type->id == OT_POT_OIL) {
|
|
flag_t *f;
|
|
// unjam doors
|
|
f = hasflag(dst->flags, F_JAMMED);
|
|
if (f) {
|
|
killflag(f);
|
|
}
|
|
}
|
|
} else { // default
|
|
if (isplayer(lf)) {
|
|
msg("You pour %s onto %s.", obname,dstname);
|
|
msg("%s gets wet.", dstname);
|
|
}
|
|
takedamage(dst, 0, DT_WATER);
|
|
}
|
|
} else {
|
|
flag_t *f;
|
|
// pour onto ground
|
|
if (isplayer(lf)) {
|
|
msg("You pour %s onto the ground.", obname);
|
|
} else if (haslos(player, lf->cell)) {
|
|
msg("%s pours %s onto the ground.", lfname, obname);
|
|
}
|
|
f = hasflag(o->flags, F_DIECONVERT);
|
|
if (f) {
|
|
addob(lf->cell->obpile, f->text);
|
|
} else {
|
|
if (haslos(player, lf->cell)) {
|
|
msg("The contents evaporate.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// empty the flask
|
|
addemptyob(lf->pack, o);
|
|
// remove src
|
|
removeob(o, 1);
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
void quaff(lifeform_t *lf, object_t *o) {
|
|
char buf[BUFLEN],obname[BUFLEN];
|
|
int willid = B_FALSE;
|
|
int playercansee;
|
|
int forcedrop = B_FALSE;
|
|
int seen;
|
|
|
|
getobname(o, obname, 1);
|
|
|
|
if ((isplayer(lf)) || cansee(player, lf)) {
|
|
playercansee = B_TRUE;
|
|
} else {
|
|
playercansee = B_FALSE;
|
|
}
|
|
|
|
taketime(lf, getactspeed(lf));
|
|
|
|
maketried(o->type->id);
|
|
|
|
if (touch(lf, o)) {
|
|
return;
|
|
}
|
|
if (hasflag(o->flags, F_DEAD)) return;
|
|
|
|
if (o->material->id == MT_ICE) {
|
|
if (isplayer(lf)) {
|
|
msg("You can't drink this, it's frozen!");
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (lf->controller != C_PLAYER) {
|
|
if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
capitalise(buf);
|
|
msg("%s drinks %s!", buf, obname);
|
|
}
|
|
}
|
|
|
|
// figure out whether to id the object
|
|
willid = B_FALSE;
|
|
if (playercansee) {
|
|
switch (o->type->id) {
|
|
case OT_POT_HEALING:
|
|
case OT_POT_HEALINGMIN:
|
|
if (lf->hp < lf->maxhp) {
|
|
willid = B_TRUE;
|
|
}
|
|
break;
|
|
default:
|
|
willid = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isknown(o) && willid) {
|
|
// id the potion
|
|
makeknown(o->type->id);
|
|
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness
|
|
if (isplayer(lf)) {
|
|
// tell the player
|
|
msg("This is %s!",obname);
|
|
more();
|
|
drawmsg();
|
|
}
|
|
}
|
|
|
|
if (o->type->obclass->id == OC_POTION) {
|
|
potioneffects(lf, o->type->id, o->blessed, &seen);
|
|
} else if (hasflag(o->flags, F_DRINKABLE)) {
|
|
// drinkable thing which isn't a potion?
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_LINKOB);
|
|
if (f) {
|
|
potioneffects(lf, f->val[0], o->blessed, NULL);
|
|
} else {
|
|
eat(lf, o);
|
|
}
|
|
}
|
|
|
|
if (seen) {
|
|
o->blessknown = B_TRUE;
|
|
makeknown(o->type->id);
|
|
}
|
|
|
|
if (forcedrop) {
|
|
// try to add an empty container to the ground
|
|
addemptyob(lf->cell->obpile, o);
|
|
} else {
|
|
// try to add an empty container to our pack
|
|
addemptyob(lf->pack, o);
|
|
}
|
|
// lose the potion
|
|
removeob(o, 1);
|
|
|
|
}
|
|
|
|
void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, int *seen) {
|
|
char lfname[BUFLEN];
|
|
unsigned int dam;
|
|
int i;
|
|
int first,dir;
|
|
int amt;
|
|
int failed;
|
|
int seenbyplayer;
|
|
int hpheal,mpheal;
|
|
flag_t *f;
|
|
|
|
if (isplayer(lf)) {
|
|
seenbyplayer = B_TRUE;
|
|
} else if (cansee(player, lf)) {
|
|
seenbyplayer = B_TRUE;
|
|
} else {
|
|
seenbyplayer = B_FALSE;
|
|
}
|
|
|
|
if (seen) {
|
|
*seen = seenbyplayer;
|
|
}
|
|
|
|
getlfname(lf, lfname);
|
|
|
|
switch (oid) {
|
|
case OT_POT_ACID:
|
|
dam = rnd(5,10);
|
|
losehp(lf, dam, DT_ACID, NULL, "drinking acid");
|
|
if (isplayer(lf)) {
|
|
msg("Your suffer massive internal burning!");
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s writhes in agony!", lfname);
|
|
}
|
|
break;
|
|
case OT_POT_ACROBATICS:
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel momentarily jumpy.");
|
|
}
|
|
break;
|
|
}
|
|
|
|
// how long for?
|
|
i = geteffecttime(5,10, potblessed);
|
|
|
|
if (lfhasflagval(lf, F_CANWILL, OT_A_JUMP, NA, NA, NULL)) {
|
|
nothinghappens();
|
|
seenbyplayer = B_FALSE;
|
|
if (seen) *seen = B_FALSE;
|
|
} else {
|
|
addtempflag(lf->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL, i);
|
|
}
|
|
break;
|
|
case OT_POT_AMBROSIA:
|
|
// fix hunger
|
|
i = gethungerlevel(gethungerval(lf));
|
|
if (i > 0) {
|
|
modhunger(lf, -i);
|
|
}
|
|
// fix hp
|
|
if (lf->hp < lf->maxhp) {
|
|
gainhp(lf, lf->maxhp); // ie. full hp
|
|
if (isplayer(lf)) {
|
|
msg("You feel completely healed!");
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s looks completely healed!", lfname);
|
|
}
|
|
} else {
|
|
if (isplayer(lf)) {
|
|
msg("This makes you feel incredible!");
|
|
}
|
|
}
|
|
break;
|
|
case OT_POT_COMPETENCE:
|
|
failed = B_TRUE;
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel momentarily %s.", (potblessed == B_CURSED) ? "incompetent" : "more competent");
|
|
}
|
|
break;
|
|
}
|
|
if (potblessed == B_CURSED) {
|
|
amt = -1;
|
|
} else {
|
|
amt = 1;
|
|
}
|
|
// select a random attribute
|
|
if (potblessed == B_BLESSED) {
|
|
// modify all attributes
|
|
if (!modattr(lf, A_STR, amt)) failed = B_FALSE;
|
|
if (!modattr(lf, A_DEX, amt)) failed = B_FALSE;
|
|
if (!modattr(lf, A_IQ, amt)) failed = B_FALSE;
|
|
} else {
|
|
// modify just one attribute
|
|
i = rnd(1,3);
|
|
switch (i) {
|
|
case 1:
|
|
if (!modattr(lf, A_STR, amt)) failed = B_FALSE;
|
|
break;
|
|
case 2:
|
|
if (!modattr(lf, A_DEX, amt)) failed = B_FALSE;
|
|
break;
|
|
case 3:
|
|
if (!modattr(lf, A_IQ, amt)) failed = B_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
if (failed) {
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
}
|
|
if (seen) *seen = B_FALSE;
|
|
} else {
|
|
if (seen) *seen = B_TRUE;
|
|
}
|
|
break;
|
|
case OT_POT_RUM:
|
|
// how long for?
|
|
f = lfhasflag(lf, F_DRUNK);
|
|
if (f) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel more tipsy.");
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s looks more tipsy.", lfname);
|
|
}
|
|
f->lifetime += DRUNKTIME;
|
|
} else {
|
|
addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, DRUNKTIME);
|
|
}
|
|
/*
|
|
if (!lfhasflagval(lf, F_DTRESIST, DT_FIRE, NA, NA, NULL)) {
|
|
addtempflag(lf->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL, i);
|
|
}
|
|
if (!lfhasflagval(lf, F_DTRESIST, DT_COLD, NA, NA, NULL)) {
|
|
addtempflag(lf->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, i);
|
|
}
|
|
*/
|
|
break;
|
|
case OT_POT_ELEMENTIMMUNE:
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel momentarily immune to the elements.");
|
|
}
|
|
break;
|
|
}
|
|
// how long for?
|
|
i = geteffecttime(15,25,potblessed);
|
|
|
|
if (!isimmuneto(lf->flags, DT_FIRE)) {
|
|
addtempflag(lf->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL, i);
|
|
}
|
|
if (!isimmuneto(lf->flags, DT_COLD)) {
|
|
addtempflag(lf->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL, i);
|
|
}
|
|
break;
|
|
case OT_POT_ETHEREALNESS:
|
|
dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
|
break;
|
|
case OT_POT_EXPERIENCE:
|
|
// gain xp!
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel momentarily more experienced.");
|
|
}
|
|
break;
|
|
}
|
|
if (isplayer(lf)) {
|
|
msg("You feel more experienced!");
|
|
}
|
|
gainxp(lf, getxpforlev(lf->level+1) - lf->xp);
|
|
break;
|
|
case OT_POT_GASEOUSFORM:
|
|
dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
|
break;
|
|
case OT_POT_HEALING:
|
|
dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
|
break;
|
|
case OT_POT_HEALINGMIN:
|
|
dospelleffects(lf, OT_S_HEALINGMIN,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen);
|
|
break;
|
|
case OT_POT_INVIS:
|
|
dospelleffects(lf, OT_S_INVISIBILITY,potblessed ? 6 : 3, lf, NULL, lf->cell, potblessed, seen);
|
|
break;
|
|
case OT_POT_INVULN:
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel momentarily invulnerable.");
|
|
}
|
|
break;
|
|
}
|
|
i = geteffecttime(5,15,potblessed);
|
|
|
|
if (!lfhasflagval(lf, F_INVULNERABLE, B_TRUE, NA, NA, NULL)) {
|
|
addtempflag(lf->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL, i);
|
|
}
|
|
break;
|
|
case OT_POT_MAGIC:
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, -10)) {
|
|
if (isplayer(lf)) {
|
|
msg("You feel your magical energy temporarily pulse.");
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (getmaxmp(lf) > 0) {
|
|
msg("Your magical energy is restored.");
|
|
lf->mp = getmaxmp(lf);
|
|
} else {
|
|
nothinghappens();
|
|
if (seen) *seen = B_FALSE;
|
|
}
|
|
|
|
break;
|
|
case OT_POT_OIL:
|
|
if (isplayer(lf)) {
|
|
char buf[BUFLEN];
|
|
switch (rnd(1,5)) {
|
|
case 1: strcpy(buf, "cooking"); break;
|
|
case 2: strcpy(buf, "olive"); break;
|
|
case 3: strcpy(buf, "peanut"); break;
|
|
case 4: strcpy(buf, "grapefruit"); break;
|
|
case 5: strcpy(buf, "vegetable"); break;
|
|
}
|
|
msg("Mmm, %s oil.", buf);
|
|
}
|
|
break;
|
|
case OT_POT_POISON:
|
|
poison(lf, rnd(10,20), P_FOOD, 1, "a potion of poison");
|
|
break;
|
|
case OT_POT_POLYMORPH:
|
|
if (potblessed == B_BLESSED) {
|
|
// controlled polymorph
|
|
dospelleffects(lf, OT_S_POLYMORPH, 5, lf, NULL, lf->cell, potblessed, NULL);
|
|
} else {
|
|
// random polymorph
|
|
dospelleffects(lf, OT_S_POLYMORPH, 1, lf, NULL, lf->cell, potblessed, NULL);
|
|
}
|
|
break;
|
|
case OT_POT_RESTORATION:
|
|
failed = B_TRUE;
|
|
if (getattr(lf,A_STR) < lf->baseatt[A_STR]) {
|
|
setattr(lf, A_STR, lf->baseatt[A_STR]);
|
|
failed = B_FALSE;
|
|
}
|
|
if (getattr(lf,A_DEX) < lf->baseatt[A_DEX]) {
|
|
setattr(lf, A_DEX, lf->baseatt[A_DEX]);
|
|
failed = B_FALSE;
|
|
}
|
|
if (getattr(lf,A_IQ) < lf->baseatt[A_IQ]) {
|
|
setattr(lf, A_IQ, lf->baseatt[A_IQ]);
|
|
failed = B_FALSE;
|
|
}
|
|
|
|
if (potblessed == B_BLESSED) {
|
|
hpheal = lf->maxhp;
|
|
mpheal = getmaxmp(lf);
|
|
} else if (potblessed == B_CURSED) {
|
|
hpheal = lf->maxhp / 3;
|
|
mpheal = getmaxmp(lf) / 3;
|
|
} else {
|
|
hpheal = lf->maxhp / 2;
|
|
mpheal = getmaxmp(lf) / 2;
|
|
}
|
|
|
|
// blessed restores hp/mp to full
|
|
if (lf->hp < hpheal) {
|
|
gainhp(lf, hpheal - lf->hp);
|
|
if (!isplayer(lf) && cansee(player, lf)) {
|
|
msg("%s%s health has been restored!", lfname, getpossessive(lfname));
|
|
}
|
|
failed = B_FALSE;
|
|
}
|
|
if (lf->mp < mpheal) {
|
|
gainmp(lf, mpheal - lf->mp);
|
|
failed = B_FALSE;
|
|
}
|
|
|
|
if (failed) {
|
|
if (isplayer(lf)) msg("You feel momentarily restored.");
|
|
} else {
|
|
if (isplayer(lf)) msg("You feel restored!");
|
|
}
|
|
break;
|
|
case OT_POT_SANCTUARY:
|
|
// how long for?
|
|
//i = gethealtime(lf); // TODO: change...
|
|
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
}
|
|
break;
|
|
}
|
|
i = 15;
|
|
first = B_TRUE;
|
|
|
|
// add holy barriers all around
|
|
for (dir = DC_N; dir <= DC_NW; dir++) {
|
|
cell_t *c;
|
|
c = getcellindir(lf->cell, dir);
|
|
if (c && isempty(c)) {
|
|
object_t *newob;
|
|
newob = addob(c->obpile, "magical barrier");
|
|
addflag(newob->flags, F_OBHP, i, i, NA, NULL);
|
|
if (first && haslos(player, c)) {
|
|
msg("A magical barrier appears!");
|
|
first = B_FALSE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case OT_POT_SPEED:
|
|
if (potblessed == B_BLESSED) {
|
|
dospelleffects(lf, OT_S_HASTE, 1, lf, NULL, lf->cell, B_BLESSED, NULL);
|
|
} else if (potblessed == B_CURSED) {
|
|
dospelleffects(lf, OT_S_SLOW, 1, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
|
} else { // uncursed
|
|
dospelleffects(lf, OT_S_HASTE, 1, lf, NULL, lf->cell, B_UNCURSED, NULL);
|
|
}
|
|
if (seen) *seen = B_TRUE;
|
|
break;
|
|
|
|
case OT_POT_WATER:
|
|
switch (potblessed) {
|
|
case B_BLESSED:
|
|
if (hasflag(lf->flags, F_UNDEAD)) {
|
|
if (isplayer(lf)) {
|
|
msg("This tastes like water, but burns like acid!");
|
|
} else if (cansee(player, lf)) {
|
|
msg("%s writhes in agony!", lfname);
|
|
}
|
|
losehp(lf, rnd(5,15), DT_HOLY, NULL, "drinking holy water");
|
|
} else {
|
|
msg("Mmm, holy water.");
|
|
}
|
|
break;
|
|
case B_UNCURSED:
|
|
msg("Mmm, water.");
|
|
break;
|
|
case B_CURSED:
|
|
msg("Yuck! Something is wrong with this water.");
|
|
break;
|
|
}
|
|
if (seen) {
|
|
if (isplayer(lf) || cansee(player, lf)) {
|
|
*seen = B_TRUE;
|
|
}
|
|
}
|
|
modhunger(lf, -pctof(0.05, (float)HUNGERCONST));
|
|
break;
|
|
case OT_POT_BLOOD:
|
|
msg("Yuck, this tastes like blood!");
|
|
break;
|
|
case OT_POT_BLOODC:
|
|
f = lfhasflag(lf, F_BEINGSTONED);
|
|
if (f) {
|
|
killflag(f);
|
|
} else {
|
|
msg("Yuck, this tastes like oddly-flavoured blood!");
|
|
}
|
|
break;
|
|
case OT_POT_JUICE:
|
|
if (isplayer(lf)) {
|
|
switch (potblessed) {
|
|
case B_BLESSED:
|
|
msg("Mmm, fruit juice!");
|
|
break;
|
|
case B_UNCURSED:
|
|
msg("Mmm, fruit juice!");
|
|
break;
|
|
case B_CURSED:
|
|
msg("Yuck! This tastes like rotten fruit.");
|
|
break;
|
|
}
|
|
if (seen) *seen = B_TRUE;
|
|
}
|
|
if (potblessed != B_CURSED) {
|
|
modhunger(lf, -pctof(25, (float)HUNGERCONST));
|
|
}
|
|
break;
|
|
default: // nothing happens
|
|
break;
|
|
}
|
|
}
|
|
|
|
int readsomething(lifeform_t *lf, object_t *o) {
|
|
flag_t *f;
|
|
char buf[BUFLEN],obname[BUFLEN];
|
|
int playercansee;
|
|
int willid = B_FALSE;
|
|
int needsob = B_FALSE;
|
|
objecttype_t *linkspell;
|
|
int readtime;
|
|
|
|
if (!haslos(lf, lf->cell)) {
|
|
if (isplayer(lf)) {
|
|
msg("You can't read anything, since you can't see!");
|
|
}
|
|
return B_TRUE;
|
|
}
|
|
|
|
getobname(o, obname, 1);
|
|
|
|
if ((isplayer(lf)) || cansee(player, lf)) {
|
|
playercansee = B_TRUE;
|
|
} else {
|
|
playercansee = B_FALSE;
|
|
}
|
|
|
|
|
|
if (o->type->obclass->id == OC_BOOK) {
|
|
readtime = SPEED_READ * 2;
|
|
} else {
|
|
readtime = SPEED_READ;
|
|
}
|
|
taketime(lf, readtime);
|
|
|
|
maketried(o->type->id);
|
|
|
|
// some checks first...
|
|
if (touch(lf, o)) {
|
|
return B_TRUE;
|
|
}
|
|
if (hasflag(o->flags, F_DEAD)) {
|
|
return B_TRUE;
|
|
}
|
|
|
|
|
|
if (lf->controller != C_PLAYER) {
|
|
if (cansee(player, lf)) {
|
|
getlfname(lf, buf);
|
|
capitalise(buf);
|
|
msg("%s reads %s!", buf, obname);
|
|
}
|
|
}
|
|
|
|
// find linked spell
|
|
linkspell = getlinkspell(o);
|
|
|
|
// figure out whether to id the object
|
|
willid = B_FALSE;
|
|
if (playercansee) {
|
|
if (o->type->obclass->id == OC_BOOK) {
|
|
// is this a spellbook?
|
|
if (linkspell) {
|
|
// if so, only id if we are able to read it
|
|
//if (getiqreq(linkspell->id) <= getattr(lf, A_IQ)) {
|
|
if (getspellpower(lf, linkspell->id) > 0) {
|
|
willid = B_TRUE;
|
|
} else {
|
|
willid = B_FALSE;
|
|
}
|
|
} else {
|
|
// ie. a manual
|
|
willid = B_TRUE;
|
|
}
|
|
} else {
|
|
switch (o->type->id) {
|
|
case OT_SCR_IDENTIFY: // only id if it does something
|
|
case OT_SCR_MENDING: // only id if it does something
|
|
case OT_SCR_ENCHANT: // only id if it does something
|
|
case OT_SCR_CREATEMONSTER: // only id if it does something
|
|
case OT_SCR_REMOVECURSE: // only id if it does something
|
|
willid = B_FALSE;
|
|
break;
|
|
default:
|
|
willid = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ask for a target object of any type if scroll is unknown?
|
|
switch (o->type->id) {
|
|
case OT_SCR_IDENTIFY:
|
|
case OT_SCR_MENDING:
|
|
case OT_SCR_ENCHANT:
|
|
needsob = B_TRUE;
|
|
break;
|
|
default:
|
|
needsob = B_FALSE;
|
|
break;
|
|
}
|
|
|
|
if (!isknown(o) && willid) {
|
|
// id the scroll
|
|
makeknown(o->type->id);
|
|
real_getobname(o, obname, 1, B_FALSE, B_TRUE, B_FALSE, B_FALSE, B_FALSE); // don't adjust for blindness
|
|
if (isplayer(lf)) {
|
|
// tell the player
|
|
msg("This is %s!",obname);
|
|
more();
|
|
drawmsg();
|
|
}
|
|
}
|
|
|
|
if (o->type->obclass->id == OC_SCROLL) { // cast linked spell
|
|
object_t *targob = NULL;
|
|
f = hasflag(o->flags, F_LINKSPELL);
|
|
if (f) {
|
|
int seen = B_FALSE;
|
|
int power;
|
|
|
|
power = f->val[1];
|
|
if (power == NA) power = 1;
|
|
|
|
// increase based on your magic item usage skill
|
|
power += (getskill(lf, SK_CHANNELING)*2);
|
|
|
|
// blessed scrolls are more powerful
|
|
if (isblessed(o)) power += 4;
|
|
|
|
// enforce maximum
|
|
limit(&power, NA, 10);
|
|
|
|
// for unidentified scrolls which target an object,
|
|
// let player select ANY object (even if it won't
|
|
// work).
|
|
if (needsob && isplayer(lf) && !isknown(o)) {
|
|
targob = askobject(lf->pack, "Target which object", NULL, AO_NONE);
|
|
}
|
|
|
|
dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen);
|
|
if (seen) {
|
|
// id the scroll now
|
|
makeknown(o->type->id);
|
|
}
|
|
|
|
// removeob one of the object
|
|
if (isplayer(lf)) msg("The scroll crumbles to dust.");
|
|
removeob(o, 1);
|
|
} else if (o->type->id == OT_MAP) {
|
|
if (isplayer(lf)) {
|
|
msg("You study your map for a while.");
|
|
}
|
|
} else if (o->type->id == OT_SCR_NOTHING) {
|
|
if (isplayer(lf)) {
|
|
msg("The scroll crumbles to dust.");
|
|
}
|
|
// removeob one of the object
|
|
removeob(o, 1);
|
|
} else if (o->type->id == OT_SCR_PERMENANCE) {
|
|
if (isplayer(lf)) {
|
|
targob = askobject(lf->pack, "Target which object", NULL, AO_NONE);
|
|
}
|
|
|
|
if (targob) {
|
|
flag_t *f;
|
|
for (f = targob->flags->first ; f ; f = f->next) {
|
|
f->lifetime = PERMENANT;
|
|
}
|
|
if (isplayer(lf)) {
|
|
char obname[BUFLEN];
|
|
getobname(targob, obname, targob->amt);
|
|
msg("Your %s emit%s a blinding burst of power!",noprefix(obname), (targob->amt == 1) ? "s" : "");
|
|
}
|
|
}
|
|
|
|
if (isplayer(lf)) {
|
|
msg("The scroll crumbles to dust.");
|
|
}
|
|
// removeob one of the object
|
|
removeob(o, 1);
|
|
|
|
} else if (o->type->id == OT_SCR_REMOVECURSE) {
|
|
int seen = B_FALSE;
|
|
object_t *oo;
|
|
// remove curses!
|
|
for (oo = lf->pack->first ; oo ; oo = oo->next) {
|
|
// if this object is cursed
|
|
if (iscursed(oo)) {
|
|
// blessed scrolls remove curse from everything you're holding.
|
|
// otherwise only equipped objects will be uncursed.
|
|
if (o->blessed || isequipped(oo)) {
|
|
uncurseob(oo, &seen);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (seen) {
|
|
// id the scroll now
|
|
makeknown(o->type->id);
|
|
} else {
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
}
|
|
}
|
|
if (isplayer(lf)) {
|
|
msg("The scroll crumbles to dust.");
|
|
}
|
|
// removeob one of the object
|
|
removeob(o, 1);
|
|
}
|
|
} else if (o->type->obclass->id == OC_BOOK) {
|
|
// is this a spellbook?
|
|
if (linkspell) {
|
|
// if so, can we read it?
|
|
if (getspellpower(lf, linkspell->id) > 0) {
|
|
if (lfhasflagval(lf, F_CANCAST, linkspell->id, NA, NA, NULL)) {
|
|
if (isplayer(lf)) msg("You already know how to cast this spell!");
|
|
} else {
|
|
// learn it
|
|
addflag(lf->flags, F_CANCAST, linkspell->id, NA, NA, NULL);
|
|
}
|
|
} else {
|
|
if (isplayer(lf)) msg("You cannot comprehend this book.");
|
|
}
|
|
} else {
|
|
// manuals
|
|
f = hasflag(o->flags, F_MANUALOF);
|
|
if (f) {
|
|
giveskill(lf, f->val[0]);
|
|
}
|
|
if (isplayer(lf)) {
|
|
msg("The book crumbles to dust.");
|
|
}
|
|
// removeob one of the object
|
|
removeob(o, 1);
|
|
}
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
object_t *relinkob(object_t *src, obpile_t *dst) {
|
|
flag_t *f,*nextf;
|
|
if (!obfits(src, dst)) return NULL;
|
|
|
|
if (src->pile->owner) {
|
|
// previous owner loses all flags conferred by this object
|
|
loseobflags(src->pile->owner, src, ALLCONFERRED);
|
|
}
|
|
|
|
// unweild
|
|
for (f = src->flags->first ; f ; f = nextf) {
|
|
nextf = f->next;
|
|
if (f->id == F_EQUIPPED) {
|
|
killflag(f);
|
|
} else if (f->id == F_CURAMMO) {
|
|
killflag(f);
|
|
}
|
|
}
|
|
|
|
// adjust letter...
|
|
// gold should always have letter '$'
|
|
if (src->type->obclass->id == OC_MONEY) {
|
|
src->letter = '$';
|
|
}
|
|
|
|
// adjust letter if going to player?
|
|
if (dst->owner && isplayer(dst->owner)) {
|
|
src->letter = getnextletter(dst, &src->letter);
|
|
}
|
|
|
|
|
|
|
|
// unlink this object from the current list
|
|
if (src->prev == NULL) {
|
|
// first
|
|
src->pile->first = src->next;
|
|
} else {
|
|
// not first
|
|
src->prev->next = src->next;
|
|
}
|
|
if (src->next == NULL) {
|
|
// last
|
|
src->pile->last = src->prev;
|
|
} else {
|
|
// not last
|
|
src->next->prev = src->prev;
|
|
}
|
|
|
|
// add this object to the end of the list for the new pile
|
|
if (dst->first == NULL) {
|
|
// first element in new list
|
|
dst->first = src;
|
|
src->prev = NULL;
|
|
} else {
|
|
object_t *aa;
|
|
// go to end of list
|
|
aa = dst->last;
|
|
// not first in new list
|
|
src->prev = aa;
|
|
aa->next = src;
|
|
}
|
|
|
|
|
|
dst->last = src;
|
|
src->pile = dst;
|
|
src->next = NULL;
|
|
|
|
if (src->pile->owner) {
|
|
// new owner gains "hold confer" flags conferred by this object
|
|
giveobflags(src->pile->owner, src, F_HOLDCONFER);
|
|
// new owner gains "activate confer" flags conferred by this object if it's active
|
|
if (isactivated(src)) {
|
|
giveobflags(src->pile->owner, src, F_ACTIVATECONFER);
|
|
}
|
|
}
|
|
|
|
if (obproduceslight(src)) {
|
|
calclight((getoblocation(src))->map);
|
|
drawscreen();
|
|
}
|
|
|
|
return src;
|
|
}
|
|
|
|
void removedeadobs(obpile_t *op) {
|
|
object_t *o, *nexto;
|
|
for (o = op->first ; o ; o = nexto) {
|
|
nexto = o->next;
|
|
if (hasflag(o->flags, F_DEAD)) {
|
|
obdie(o);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// returns the amount left
|
|
int removeob(object_t *o,int howmany) {
|
|
if (howmany == ALL) {
|
|
howmany = o->amt;
|
|
}
|
|
|
|
if (howmany >= o->amt) {
|
|
killob(o);
|
|
return 0;
|
|
} else {
|
|
o->amt -= howmany;
|
|
}
|
|
|
|
return o->amt;
|
|
}
|
|
|
|
void setblessed(object_t *o, enum BLESSTYPE wantbless) {
|
|
o->blessed = wantbless;
|
|
if (wantbless != B_BLESSED) {
|
|
flag_t *f,*nextf;
|
|
// remove glowing from blessings
|
|
for (f = o->flags->first ; f ; f = nextf) {
|
|
nextf = f->next;
|
|
if (f->lifetime == FROMBLESSING) {
|
|
killflag(f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void setinscription(object_t *o, char *text) {
|
|
if (o->inscription) {
|
|
free(o->inscription);
|
|
}
|
|
o->inscription = strdup(text);
|
|
}
|
|
|
|
void setobcreatedby(object_t *o, lifeform_t *lf) {
|
|
char lfname[BUFLEN];
|
|
if (!lf) {
|
|
return;
|
|
}
|
|
real_getlfnamea(lf, lfname, B_FALSE);
|
|
addflag(o->flags, F_CREATEDBY, lf->id, NA, NA, lfname);
|
|
}
|
|
|
|
|
|
void shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|
int shatterdam;
|
|
cell_t *where = NULL;
|
|
lifeform_t *target = NULL;
|
|
char buf[BUFLEN];
|
|
char obname[BUFLEN];
|
|
char targetname[BUFLEN];
|
|
int seen = B_FALSE;
|
|
|
|
getobname(o,obname,o->amt);
|
|
where = getoblocation(o);
|
|
|
|
if (hitlf) {
|
|
target = where->lf;
|
|
} else {
|
|
target = NULL;
|
|
}
|
|
|
|
if (target) {
|
|
getlfname(target, targetname);
|
|
}
|
|
|
|
// announce
|
|
if (haslos(player, where)) {
|
|
char *obcaps;
|
|
obcaps = strdup(obname);
|
|
capitalise(obcaps);
|
|
obcaps = strrep(obcaps, "An ", "The ", NULL);
|
|
obcaps = strrep(obcaps, "A ", "The ", NULL);
|
|
msg("%s shatters!",obcaps);
|
|
free(obcaps);
|
|
|
|
seen = B_TRUE;
|
|
} else {
|
|
noise(where, NULL, "shattering glass.", NULL);
|
|
}
|
|
|
|
if (target) {
|
|
shatterdam = getshatterdam(o);
|
|
if (shatterdam && !isdead(target)) {
|
|
// extra glass damage
|
|
if (seen) {
|
|
msg("%s %s showered in %s shards!", targetname, is(target),
|
|
o->material->name);
|
|
}
|
|
losehp(target, shatterdam, DT_SLASH, fromlf, damstring);
|
|
}
|
|
}
|
|
|
|
|
|
// place shards
|
|
if (o->material->id == MT_GLASS) {
|
|
int numshards;
|
|
numshards = getnumshards(o);
|
|
// place glass shards
|
|
sprintf(buf, "%d pieces of broken glass",numshards);
|
|
addob(where->obpile, buf);
|
|
} else if (o->material->id == MT_ICE) {
|
|
int numshards;
|
|
numshards = getnumshards(o) / 15;
|
|
if (numshards < 1) numshards = 1;
|
|
|
|
// ice
|
|
sprintf(buf, "%d chunks of ice",numshards);
|
|
addob(where->obpile, buf);
|
|
}
|
|
|
|
// potion effects (only if you hit)?
|
|
if (o->type->obclass->id == OC_POTION) {
|
|
// effects on lifeforms
|
|
if (hitlf && target) {
|
|
int observed;
|
|
// some potions have special effects...
|
|
switch (o->type->id) {
|
|
case OT_POT_ACID: // take acid damage
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
}
|
|
if (target) {
|
|
if (seen) {
|
|
msg("%s %s splashed with acid!", targetname,
|
|
is(target));
|
|
}
|
|
losehp(target, rnd(1,5)*o->amt, DT_ACID, fromlf, "a splash of acid");
|
|
} else {
|
|
// announce
|
|
if (seen) {
|
|
msg("Acid splashes all over the floor!");
|
|
}
|
|
}
|
|
break;
|
|
case OT_POT_BLOOD:
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
}
|
|
if (target) {
|
|
if (seen) {
|
|
msg("%s %s splashed with blood.", targetname,
|
|
is(target));
|
|
}
|
|
} else {
|
|
// announce
|
|
if (seen) {
|
|
msg("Blood splashes onto the floor.");
|
|
}
|
|
}
|
|
break;
|
|
case OT_POT_ELEMENTIMMUNE:
|
|
case OT_POT_ETHEREALNESS:
|
|
case OT_POT_GASEOUSFORM:
|
|
case OT_POT_POISON:
|
|
case OT_POT_POLYMORPH:
|
|
case OT_POT_INVIS:
|
|
case OT_POT_SANCTUARY: // apply regular potion effects, and make them known
|
|
if (target) {
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
}
|
|
potioneffects(target, o->type->id, o->blessed, &observed);
|
|
}
|
|
break;
|
|
case OT_POT_HEALING:
|
|
case OT_POT_HEALINGMIN: // only make them known if it had an effect
|
|
if (target) {
|
|
potioneffects(target, o->type->id, o->blessed, &observed);
|
|
if (observed) {
|
|
makeknown(o->type->id);
|
|
}
|
|
}
|
|
break;
|
|
case OT_POT_OIL:
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
msg("%s %s covered with oil!", targetname, is(target));
|
|
}
|
|
// target is temporarily vulnerable to fire.
|
|
addtempflag(target->flags, F_DTVULN, DT_FIRE, NA, NA, "1d6", rnd(5,10));
|
|
break;
|
|
case OT_POT_WATER:
|
|
if (seen) makeknown(o->type->id);
|
|
if (target) {
|
|
if (seen) {
|
|
msg("%s %s splashed with water.", targetname,
|
|
is(target));
|
|
}
|
|
|
|
if (hasflag(target->flags, F_UNDEAD) && isblessed(o)) {
|
|
if (isplayer(target)) {
|
|
msg("The water burns like acid!");
|
|
} else if (cansee(player, target)) {
|
|
msg("%s writhes in agony!", targetname);
|
|
}
|
|
losehp(target, o->amt*rnd(5,10), DT_HOLY, NULL, "holy water");
|
|
if (seen) {
|
|
// we now know that it is blessed
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
} else {
|
|
losehp(target, 0, DT_WATER, fromlf, "a splash of water");
|
|
}
|
|
} else {
|
|
// all objects take damage
|
|
object_t *oo,*nextoo;
|
|
// announce
|
|
if (seen) {
|
|
msg("Water splashes onto the floor.");
|
|
}
|
|
//TODO: holy water blesses everything?
|
|
// everything here takes water damage
|
|
for (oo = where->obpile->first ; oo ; oo = nextoo) {
|
|
nextoo = oo->next;
|
|
takedamage(oo, 0, DT_WATER);
|
|
}
|
|
}
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else { // ie. you didn't hit anyone
|
|
switch (o->type->id) {
|
|
case OT_POT_OIL:
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
msg("The floor is covered with oil!");
|
|
}
|
|
break;
|
|
case OT_POT_WATER:
|
|
if (seen) {
|
|
makeknown(o->type->id);
|
|
msg("The floor is covered with water!");
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// object is dead.
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
addflag(o->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
}
|
|
|
|
// randomizes hidden names
|
|
void shufflehiddennames(void) {
|
|
int i,n;
|
|
int total;
|
|
hiddenname_t *a, *temp;
|
|
int shuffleamt = 500;
|
|
|
|
|
|
total = 0;
|
|
for (a = firsthiddenname ; a ; a = a->next) {
|
|
total++;
|
|
}
|
|
|
|
if (total <= 1) {
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < shuffleamt; i++) {
|
|
int which;
|
|
|
|
// select random element (but never the first)
|
|
which = (rand() % (total-1))+1;
|
|
|
|
// go there
|
|
a = firsthiddenname;
|
|
for (n = 0; n < which; n++) {
|
|
if (a->next != NULL) a = a->next;
|
|
}
|
|
temp = a;
|
|
|
|
// remove from list
|
|
temp->prev->next = temp->next;
|
|
|
|
|
|
if (temp->next) {
|
|
temp->next->prev = temp->prev;
|
|
} else {
|
|
lasthiddenname = temp->prev;
|
|
}
|
|
|
|
// re-add this element to the start
|
|
temp->next = firsthiddenname;
|
|
temp->prev = NULL;
|
|
|
|
firsthiddenname->prev = temp;
|
|
firsthiddenname = temp;
|
|
}
|
|
}
|
|
|
|
object_t *splitob(object_t *o) {
|
|
object_t *newob;
|
|
// decrease count on original stack temporarily, in case we
|
|
// can't place the new object (at our weight limit?).
|
|
// doesn't matter if it goes down to zero, as we will put it back up soon.
|
|
o->amt--;
|
|
// give new object
|
|
newob = addobject(o->pile, o->type->name, B_NOSTACK);
|
|
// restore count
|
|
o->amt++;
|
|
if (newob) {
|
|
copyobprops(newob, o);
|
|
killflagsofid(newob->flags, F_STACKABLE);
|
|
// remove old ob
|
|
removeob(o, 1);
|
|
}
|
|
return newob;
|
|
}
|
|
// returns amount of damage taken
|
|
int takedamage(object_t *o, unsigned int howmuch, int damtype) {
|
|
return real_takedamage(o, howmuch, damtype, B_TRUE);
|
|
}
|
|
|
|
// returns amount of damage taken
|
|
int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantannounce) {
|
|
char predamname[BUFLEN],postdamname[BUFLEN];
|
|
char obname[BUFLEN];
|
|
flag_t *hpflag, *f;
|
|
int damtaken = 0;
|
|
|
|
// some checks need to happen before
|
|
// making sure the damage will happen.
|
|
// for example, even if an object is
|
|
// immune to water damage, water will
|
|
// still put out fire
|
|
|
|
// water puts out fire
|
|
if (damtype == DT_WATER) {
|
|
extinguish(o);
|
|
makewet(o, howmuch);
|
|
}
|
|
|
|
// catches on fire?
|
|
if (damtype == DT_FIRE) {
|
|
if (isflammable(o)) {
|
|
ignite(o);
|
|
if (isdeadob(o)) {
|
|
return howmuch;
|
|
}
|
|
}
|
|
}
|
|
|
|
// damage type converts this into something else?
|
|
f = hasflagval(o->flags, F_DTCONVERT, damtype, NA, NA, NULL);
|
|
if (f && !hasflag(o->flags, F_NODTCONVERT)) {
|
|
object_t *newob;
|
|
newob = addob(o->pile, f->text);
|
|
newob->amt = o->amt;
|
|
|
|
// object dies, but don't announce it
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
addflag(o->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
|
|
|
return howmuch;
|
|
}
|
|
|
|
adjustdamob(o, &howmuch, damtype);
|
|
|
|
// effects which have to happen before damage is applied...
|
|
// explodes?
|
|
f = hasflag(o->flags, F_EXPLODEONDAM);
|
|
if (f) {
|
|
if (f->val[2] == B_IFACTIVATED) {
|
|
if (hasflag(o->flags, F_ACTIVATED)) {
|
|
if (hasflag(o->flags, F_EXPLODEONDEATH)) {
|
|
// object dies!
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
} else {
|
|
// explode
|
|
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
|
return howmuch;
|
|
}
|
|
}
|
|
} else {
|
|
if (hasflag(o->flags, F_EXPLODEONDEATH)) {
|
|
// object dies!
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
} else {
|
|
// explode
|
|
explodeob(o, f, (f->val[1] == B_BIG) ? 1 : 0);
|
|
return howmuch;
|
|
}
|
|
}
|
|
}
|
|
|
|
// flashes?
|
|
f = hasflag(o->flags, F_FLASHONDAM);
|
|
if (f) {
|
|
if (f->val[2] == B_IFACTIVATED) {
|
|
if (hasflag(o->flags, F_ACTIVATED)) {
|
|
// flash, then object dies
|
|
brightflash(getoblocation(o),f->val[0], NULL);
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
}
|
|
} else {
|
|
// flash, then object dies
|
|
brightflash(getoblocation(o),f->val[0], NULL);
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
}
|
|
return howmuch;
|
|
}
|
|
|
|
if (howmuch <= 0) {
|
|
return 0;
|
|
}
|
|
|
|
// update lastdamtype
|
|
f = hasflag(o->flags, F_LASTDAMTYPE);
|
|
if (f) {
|
|
f->val[0] = damtype;
|
|
} else {
|
|
addflag(o->flags, F_LASTDAMTYPE, damtype, NA, NA, NULL);
|
|
}
|
|
|
|
|
|
|
|
real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE);
|
|
getobconditionname(o, predamname);
|
|
hpflag = hasflag(o->flags, F_OBHP);
|
|
if (hpflag) {
|
|
damtaken = MAXOF(hpflag->val[0], howmuch);
|
|
// object loses hp
|
|
hpflag->val[0] -= howmuch;
|
|
}
|
|
|
|
if (!hpflag || (hpflag->val[0] <= 0)) {
|
|
|
|
// special cases....
|
|
if (damtype == DT_FIRE) {
|
|
if (o->material->id == MT_FLESH) { // fire roasts flesh
|
|
object_t *meat;
|
|
meat = addob(o->pile, "chunk of roast meat");
|
|
// purposely don't use getweight!
|
|
meat->weight = o->weight;
|
|
} else { // fire turns other things to ash
|
|
addob(o->pile, "pile of ash");
|
|
}
|
|
} else if (damtype == DT_BASH) {
|
|
if (o->material->id == MT_GLASS) { // bashing damage breaks glass
|
|
int nshards;
|
|
char buf[BUFLEN];
|
|
nshards = getnumshards(o);
|
|
sprintf(buf, "%d pieces of broken glass", nshards);
|
|
addob(o->pile, buf);
|
|
} else if (o->material->id == MT_ICE) { // bashing breaks ice
|
|
int nshards;
|
|
char buf[BUFLEN];
|
|
nshards = getnumshards(o) / 15;
|
|
sprintf(buf, "%d chunks of ice", nshards);
|
|
addob(o->pile, buf);
|
|
}
|
|
}
|
|
|
|
// object dies!
|
|
addflag(o->flags, F_DEAD, B_TRUE, NA, NA, NULL);
|
|
} else if (hpflag) {
|
|
// object was just damaged
|
|
getobconditionname(o, postdamname);
|
|
|
|
// was it enough to change the status
|
|
if (!hasflag(o->flags, F_NOOBDAMTEXT) && strcmp(predamname, postdamname)) {
|
|
// if it was melting, drop some water here
|
|
if (damtype == DT_MELT) {
|
|
if (hasflag(o->flags, F_EQUIPPED) ) {
|
|
addob(o->pile->owner->cell->obpile, "small puddle of water");
|
|
} else {
|
|
// melts into the ob pile
|
|
addob(o->pile, "small puddle of water");
|
|
}
|
|
}
|
|
|
|
if (o->pile->owner) {
|
|
if (wantannounce) {
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s %s!",noprefix(obname), getobhurtname(o, damtype));
|
|
} else if (cansee(player, o->pile->owner)) {
|
|
// don't announce decay damage for object you aren't holding
|
|
if (damtype != DT_DECAY) {
|
|
char monname[BUFLEN];
|
|
getlfname(o->pile->owner, monname);
|
|
msg("%s's %s %s!",monname, noprefix(obname), getobhurtname(o, damtype));
|
|
}
|
|
}
|
|
}
|
|
} else if (haslos(player, o->pile->where)) {
|
|
if (wantannounce) {
|
|
// don't announce decay damage for object you aren't holding
|
|
if (damtype != DT_DECAY) {
|
|
msg("%s %s!", obname, getobhurtname(o, damtype));
|
|
}
|
|
}
|
|
// if you see a secret door get damaged, it's not secret anymore.
|
|
killflagsofid(o->flags, F_SECRETDOOR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
return damtaken;
|
|
}
|
|
|
|
// throw speed is the damage multiplier
|
|
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) {
|
|
char throwername[BUFLEN];
|
|
char throwernamea[BUFLEN];
|
|
char realthrowername[BUFLEN];
|
|
char realthrowernamea[BUFLEN];
|
|
char obname[BUFLEN];
|
|
char targetname[BUFLEN];
|
|
lifeform_t *target;
|
|
cell_t *srcloc;
|
|
int seen;
|
|
int shattered = B_FALSE;
|
|
char throwverbpast[BUFLEN];
|
|
char throwverbpres[BUFLEN];
|
|
int acc;
|
|
int youhit;
|
|
object_t *newob;
|
|
cell_t *newloc;
|
|
int db = B_TRUE;
|
|
int willcatch = B_FALSE;
|
|
int announcedmiss = B_FALSE;
|
|
|
|
reason = E_OK;
|
|
|
|
if (firearm) {
|
|
strcpy(throwverbpres, "fire");
|
|
strcpy(throwverbpast, "fired");
|
|
} else {
|
|
strcpy(throwverbpres, "throw");
|
|
strcpy(throwverbpast, "thrown");
|
|
}
|
|
|
|
|
|
if (isblind(player)) {
|
|
if (thrower && isplayer(thrower)) {
|
|
getobname(o, obname, amt);
|
|
} else {
|
|
strcpy(obname, "something");
|
|
}
|
|
} else {
|
|
getobname(o, obname, amt);
|
|
}
|
|
|
|
if (thrower) {
|
|
getlfname(thrower, throwername);
|
|
real_getlfname(thrower, realthrowername, B_FALSE);
|
|
|
|
if (isplayer(thrower)) {
|
|
strcpy(throwernamea, throwername);
|
|
} else {
|
|
if (isvowel(*(noprefix(throwername)))) {
|
|
strcpy(throwernamea, "an ");
|
|
} else {
|
|
strcpy(throwernamea, "a ");
|
|
}
|
|
strcat(throwernamea, noprefix(throwername));
|
|
|
|
|
|
if (isvowel(*(noprefix(realthrowername)))) {
|
|
strcpy(realthrowernamea, "an ");
|
|
} else {
|
|
strcpy(realthrowernamea, "a ");
|
|
}
|
|
strcat(realthrowernamea, noprefix(realthrowername));
|
|
}
|
|
} else {
|
|
strcat(throwernamea, "something");
|
|
strcat(realthrowernamea, "something");
|
|
}
|
|
|
|
srcloc = getoblocation(o);
|
|
|
|
// can't throw weilded cursed objects
|
|
if ((o->blessed == B_CURSED) && (!firearm)) {
|
|
// is object in thrower's pack? we need to check this
|
|
// because of things like telekenises which let us throw
|
|
// things we don't have.
|
|
if (thrower && (o->pile->owner == thrower)) {
|
|
// object equipped?
|
|
if (hasflag(o->flags, F_EQUIPPED)) {
|
|
// throw will fail!
|
|
if (isplayer(thrower)) {
|
|
msg("You can't release your %s - it %s cursed!", noprefix(obname),
|
|
isblessknown(o) ? "is" : "must be");
|
|
o->blessknown = B_TRUE;
|
|
} else if (cansee(player, thrower)) {
|
|
msg("%s tries to throw %s but can't!", throwername, obname);
|
|
o->blessknown = B_TRUE;
|
|
}
|
|
// take time anyway
|
|
//taketime(thrower, SPEED_THROW);
|
|
// fail.
|
|
reason = E_CURSED;
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
// otherwise does player have haslos?
|
|
|
|
// identify as cursed!
|
|
}
|
|
|
|
if (haslos(player, where)) {
|
|
seen = B_TRUE;
|
|
} else {
|
|
seen = B_FALSE;
|
|
}
|
|
|
|
|
|
target = where->lf;
|
|
if (target && isdead(target)) {
|
|
target = NULL;
|
|
}
|
|
if (thrower && target && !isprone(target)) {
|
|
if (areallies(thrower, target) && !firearm) {
|
|
willcatch = B_TRUE;
|
|
}
|
|
}
|
|
|
|
if (target) {
|
|
getlfname(target, targetname);
|
|
}
|
|
|
|
// touch effects
|
|
if (thrower && !firearm) {
|
|
if (o->pile == thrower->pack) {
|
|
if (touch(thrower, o)) {
|
|
return B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// announce it ("xx throws xx" "at yy")
|
|
if (thrower && isplayer(thrower)) {
|
|
// player is throwing something
|
|
if (target) {
|
|
msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname);
|
|
} else {
|
|
msg("You %s %s.",throwverbpres, obname);
|
|
}
|
|
} else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) {
|
|
char throwstring[BUFLEN];
|
|
|
|
// a monster is throwing something
|
|
sprintf(throwstring, "%s %ss %s", throwername, throwverbpres,
|
|
obname);
|
|
|
|
if (target && haslos(player, where)) {
|
|
strcat(throwstring, willcatch ? " to " : " at ");
|
|
strcat(throwstring, targetname);
|
|
}
|
|
strcat(throwstring, ".");
|
|
msg("%s", throwstring);
|
|
} else if (seen) {
|
|
char throwstring[BUFLEN];
|
|
// an object is moving on its own
|
|
|
|
/*
|
|
if (target) {
|
|
msg("Something %ss %s at %s.", throwverbpres, obname, targetname);
|
|
} else {
|
|
msg("Something %ss %s.",throwverbpres, obname);
|
|
}
|
|
*/
|
|
if (o->pile->owner && cansee(player, o->pile->owner)) {
|
|
char ownername[BUFLEN];
|
|
getlfname(o->pile->owner, ownername);
|
|
sprintf(throwstring, "%s%s %s %s through the air", ownername, getpossessive(ownername),
|
|
noprefix(obname), (amt == 1) ? "flies" : "fly");
|
|
} else {
|
|
sprintf(throwstring, "%s %s through the air", obname, (amt == 1) ? "flies" : "fly");
|
|
}
|
|
if (target && haslos(player, where)) {
|
|
strcat(throwstring, " toward ");
|
|
strcat(throwstring, targetname);
|
|
}
|
|
strcat(throwstring, ".");
|
|
msg("%s", throwstring);
|
|
}
|
|
|
|
|
|
// adjust destination location in case something is in the way.
|
|
haslof(srcloc, where, LOF_NEED, &newloc);
|
|
if (newloc) {
|
|
where = newloc;
|
|
target = where->lf;
|
|
if (target && isdead(target)) {
|
|
target = NULL;
|
|
}
|
|
if (target) {
|
|
getlfname(target, targetname);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//taketime(thrower, SPEED_THROW);
|
|
|
|
// some obejcts will die when thrown.
|
|
if (hasflag(o->flags, F_POWDER)) {
|
|
// special cases first
|
|
if (o->type->id == OT_ASHCONCEAL) {
|
|
int radius;
|
|
// make smoke
|
|
if (haslos(player, srcloc)) {
|
|
msg("%s dispers%s into a thick cloud of smoke!", obname,
|
|
(amt == 1) ? "es" : "e",
|
|
(amt == 1) ? "es" : "e" );
|
|
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
}
|
|
radius = o->amt * 2;
|
|
if (radius > 10) radius = 10;
|
|
addobsinradius(thrower->cell, radius, DT_COMPASS, "cloud of smoke", B_FALSE);
|
|
} else if (o->type->id == OT_ASHEXPLODE) {
|
|
char diebuf[BUFLEN];
|
|
// explosion!
|
|
sprintf(diebuf, "%dd6",o->amt);
|
|
|
|
if (haslos(player, srcloc)) {
|
|
msg("%s dispers%s and explod%s!", obname,
|
|
(amt == 1) ? "es" : "e",
|
|
(amt == 1) ? "es" : "e" );
|
|
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
}
|
|
explodecells(thrower->cell, roll(diebuf), B_FALSE, o, 1, DT_COMPASS, B_FALSE);
|
|
} else {
|
|
if (haslos(player, srcloc)) {
|
|
msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e");
|
|
if (!isknown(o)) makeknown(o->type->id);
|
|
}
|
|
}
|
|
removeob(o, amt);
|
|
return B_FALSE;
|
|
}
|
|
|
|
if (thrower) {
|
|
// gravboost?
|
|
if (lfhasflag(thrower, F_GRAVBOOSTED) && (srcloc == thrower->cell)) {
|
|
if (isplayer(thrower) || haslos(player, srcloc)) {
|
|
msg("%s drops and sticks to the ground!", obname);
|
|
}
|
|
|
|
moveob(o, thrower->cell->obpile, amt);
|
|
return B_FALSE;
|
|
}
|
|
}
|
|
|
|
// do throw animation
|
|
if (seen) {
|
|
glyph_t *gl;
|
|
gl = getglyph(o);
|
|
anim(srcloc, where, gl->ch, gl->colour);
|
|
}
|
|
|
|
// find out your chances of hitting
|
|
if (target) {
|
|
if (thrower) {
|
|
if (willcatch) {
|
|
acc = 100;
|
|
} else {
|
|
acc = getmissileaccuracy(thrower, where, o, firearm, A_DEX);
|
|
}
|
|
} else {
|
|
// purely based on saving throw...
|
|
acc = 100;
|
|
}
|
|
|
|
// roll for hit
|
|
youhit = B_FALSE;
|
|
// metal weapon versus magnetic shield?
|
|
if (target && lfhasflag(target, F_MAGSHIELD) && ismetal(o->material->id)) {
|
|
// announce
|
|
if (seen) {
|
|
msg("%s is repelled from %s!", obname, targetname);
|
|
announcedmiss = B_TRUE;
|
|
}
|
|
youhit = B_FALSE;
|
|
} else if (rnd(1,100) <= acc) {
|
|
youhit = B_TRUE;
|
|
}
|
|
|
|
if (youhit && target) {
|
|
flag_t *f;
|
|
object_t *shield;
|
|
// cyclone shield?
|
|
f = lfhasflag(target, F_WINDSHIELD);
|
|
if (f) {
|
|
if (speed <= f->val[0]) {
|
|
if (seen) {
|
|
msg("%s is repelled by air currents around %s!", obname, targetname);
|
|
announcedmiss = B_TRUE;
|
|
}
|
|
youhit = B_FALSE;
|
|
}
|
|
}
|
|
// an actual physical shield?
|
|
shield = getshield(target);
|
|
if (shield) {
|
|
// block chance based on shield skill
|
|
// ie. ST_AVERAGE = speed3 = 18
|
|
// ie. gun = speed10 = 60 = basically impossible
|
|
if (skillcheck(target, SC_SHIELDBLOCK, speed*6, 0)) {
|
|
int throwdam,dam;
|
|
if (seen) {
|
|
char shname[BUFLEN];
|
|
getobname(shield, shname, 1);
|
|
if (isplayer(target)) {
|
|
msg("You block %s with your %s.", obname, noprefix(shname));
|
|
} else {
|
|
msg("%s blocks %s with %s.", targetname, obname, shname);
|
|
}
|
|
announcedmiss = B_TRUE;
|
|
}
|
|
// damage shield
|
|
throwdam = getthrowdam(o);
|
|
dam = throwdam * speed;
|
|
takedamage(shield, dam, DT_PROJECTILE);
|
|
|
|
youhit = B_FALSE;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// saving throws
|
|
if (youhit && !willcatch && !isprone(target)) {
|
|
// can the victim see the thrower?
|
|
if (thrower && cansee(target, thrower)) {
|
|
// first check to see if you can catch it
|
|
if (!lfhasflag(target, F_NOPACK) && hasbp(target, BP_HANDS) &&
|
|
lfhasflag(target, F_HUMANOID) &&
|
|
!isimmobile(target) &&
|
|
skillcheck(target, SC_DEX, 15*speed, 0)) {
|
|
willcatch = B_TRUE;
|
|
} else if (skillcheck(target, SC_DODGE, 10*speed, 0)) {
|
|
// then check if we dodge it...
|
|
youhit = B_FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// doesn't matter wheter you hit or not...
|
|
if (lfhasflag(target, F_UNDEAD) && isblessed(o)) {
|
|
if (seen) {
|
|
msg("%s recoils in fear!", targetname);
|
|
}
|
|
o->blessknown = B_TRUE;
|
|
// ... but undead won't catch blessed things
|
|
willcatch = B_FALSE;
|
|
}
|
|
|
|
|
|
if (youhit && lfhasflag(target, F_NONCORPOREAL)) {
|
|
youhit = B_FALSE;
|
|
willcatch = B_FALSE;
|
|
if (seen) {
|
|
msg("%s passes straight through %s.", obname, targetname);
|
|
announcedmiss = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// if someone is there, they take damage and the object might die
|
|
// this should be "if target && youhit"
|
|
if (youhit) {
|
|
if (willcatch) {
|
|
if (seen) {
|
|
msg("%s catch%s %s.", targetname, isplayer(target) ? "" : "es", obname);
|
|
}
|
|
moveob(o, target->pack, amt);
|
|
return B_FALSE;
|
|
} else {
|
|
int dam = 0;
|
|
char damstring[BUFLEN];
|
|
int reduceamt = 0;
|
|
int throwdam;
|
|
|
|
throwdam = getthrowdam(o);
|
|
dam = throwdam * speed;
|
|
if (db) dblog("fireat(): dam = throwdam(%d) * speed(%d) = %d",throwdam, speed, dam);
|
|
|
|
// special case
|
|
if (o->type->id == OT_RUBBERBULLET) {
|
|
dam = 1;
|
|
}
|
|
|
|
// deal extra cutting damage afterwards?
|
|
if (willshatter(o->material->id)) {
|
|
shattered = B_TRUE;
|
|
}
|
|
|
|
// announce
|
|
if (seen) {
|
|
char buf2[BUFLEN];
|
|
sprintf(buf2, "%s hit%s %s.",obname,(amt == 1) ? "s" : "", targetname);
|
|
if (lfhasflag(player, F_EXTRAINFO)) {
|
|
char damstring[BUFLEN];
|
|
sprintf(damstring, " [%d dmg]",dam);
|
|
strcat(buf2, damstring);
|
|
}
|
|
msg("%s", buf2);
|
|
}
|
|
sprintf(damstring, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
|
|
|
reduceamt = getarmourdamreduction(target, o, dam, DT_PROJECTILE);
|
|
|
|
applyarmourdamreduction(target, o, reduceamt, &dam, DT_PROJECTILE);
|
|
|
|
if (dam > 0) {
|
|
lifeform_t *whogetsxp = NULL;
|
|
// TODO: at the moment you won't get experience if you telekenetically
|
|
// throw an object at something. is this okay?
|
|
if (thrower && (thrower->cell == srcloc)) {
|
|
whogetsxp = thrower;
|
|
}
|
|
losehp(target, dam, DT_PROJECTILE, whogetsxp, damstring);
|
|
}
|
|
|
|
if (reduceamt && (speed >= 3)) {
|
|
applyarmourdamage(target, o, reduceamt, DT_PROJECTILE);
|
|
}
|
|
|
|
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam);
|
|
}
|
|
} else { // ie. if !youhit
|
|
if (!announcedmiss) {
|
|
if (isplayer(thrower)) {
|
|
msg("Your %s misses %s.", noprefix(obname), targetname);
|
|
} else if (haslos(player, where)) {
|
|
msg("%s misses %s.", obname, targetname);
|
|
}
|
|
announcedmiss = B_TRUE;
|
|
}
|
|
}
|
|
} // end if target
|
|
|
|
// heavy ob?
|
|
if (youhit && target) {
|
|
if ((getobunitweight(o)*amt) >= getlfweight(target, B_NOOBS)) {
|
|
int dir;
|
|
dir = getdirtowards(srcloc, target->cell, target, B_FALSE, DT_COMPASS);
|
|
knockback(target, dir, 1, thrower, 0);
|
|
}
|
|
}
|
|
|
|
// move the object to the cell then take dam or kill it.
|
|
newob = moveob(o, where->obpile, amt);
|
|
// fake its birth time so that it can be damaged
|
|
newob->birthtime = -1;
|
|
if (willshatter(newob->material->id)) {
|
|
char dambuf[BUFLEN];
|
|
sprintf(dambuf, "%s (%s by %s)",obname,throwverbpast, realthrowernamea);
|
|
shatter(newob, youhit, dambuf, thrower);
|
|
} else {
|
|
// don't announce damage to the thrown object
|
|
real_takedamage(newob, speed, DT_BASH, B_FALSE);
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
void timeeffectsob(object_t *o) {
|
|
flag_t *f, *nextf;
|
|
cell_t *location;
|
|
lifeform_t *owner;
|
|
char obname[BUFLEN];
|
|
|
|
if (hasflag(o->flags, F_DEAD)) return;
|
|
|
|
getobname(o, obname, o->amt);
|
|
|
|
if (o->pile->where) {
|
|
location = o->pile->where;
|
|
} else {
|
|
location = NULL;
|
|
}
|
|
|
|
if (o->pile->owner) {
|
|
owner = o->pile->owner;
|
|
} else {
|
|
owner = NULL;
|
|
}
|
|
|
|
// expire flags
|
|
timeeffectsflags(o->flags);
|
|
|
|
// blessed weapons glow when held near undead
|
|
if (isblessed(o) && isweapon(o)) {
|
|
cell_t *ourcell;
|
|
flag_t *glowflag = NULL;
|
|
int nearundead = B_FALSE;
|
|
|
|
// are we glowing?
|
|
for (f = o->flags->first ; f ; f = nextf) {
|
|
nextf = f->next;
|
|
if ((f->id == F_PRODUCESLIGHT) && (f->lifetime == FROMBLESSING)) {
|
|
glowflag = f;
|
|
break;
|
|
}
|
|
}
|
|
if (isequipped(o)) {
|
|
// do we need to start/stop glowing?
|
|
ourcell = getoblocation(o);
|
|
if (ourcell) {
|
|
int x,y;
|
|
// check if we are near undead (ie. within 2 sq)
|
|
for (y = ourcell->y - 2; y <= ourcell->y + 2; y++) {
|
|
for (x = ourcell->x - 2; x <= ourcell->x + 2; x++) {
|
|
cell_t *c;
|
|
c = getcellat(ourcell->map, x, y);
|
|
if (c && haslf(c) && hasflag(c->lf->flags, F_UNDEAD)) {
|
|
nearundead = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nearundead) {
|
|
if (!glowflag) {
|
|
// start glowing
|
|
glowflag = addtempflag(o->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL, FROMBLESSING);
|
|
/*
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s start%s glowing!",noprefix(obname), (o->amt == 1) ? "s" : "");
|
|
if (!o->blessknown) o->blessknown = B_TRUE;
|
|
} else if (haslos(player, ourcell)) {
|
|
msg("%s start%s glowing!",obname, (o->amt == 1) ? "s" : "");
|
|
if (!o->blessknown) o->blessknown = B_TRUE;
|
|
}
|
|
*/
|
|
if (haslos(player, ourcell)) {
|
|
if (!o->blessknown) o->blessknown = B_TRUE;
|
|
}
|
|
calclight(ourcell->map);
|
|
}
|
|
} else { // not near undead
|
|
if (glowflag) {
|
|
killflag(glowflag);
|
|
glowflag = NULL;
|
|
/*
|
|
if (isplayer(o->pile->owner)) {
|
|
msg("Your %s stop%s glowing.",noprefix(obname), (o->amt == 1) ? "s" : "");
|
|
if (!o->blessknown) o->blessknown = B_TRUE;
|
|
} else if (haslos(player, ourcell)) {
|
|
msg("%s stop%s glowing.",obname, (o->amt == 1) ? "s" : "");
|
|
if (!o->blessknown) o->blessknown = B_TRUE;
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
} else { // not equipped
|
|
if (glowflag) { // if not equipped and glowing...
|
|
// stop glowing
|
|
killflag(glowflag);
|
|
glowflag = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (location) {
|
|
// does object's material change cell type?
|
|
if (o->material->id == MT_FIRE) {
|
|
if (hasflag(location->type->material->flags, F_FLAMMABLE)) {
|
|
// burn!
|
|
// TODO: change to celltype of nearby floor
|
|
// OR to default map empty type.
|
|
if (haslos(player, location)) {
|
|
msg("The %s burns!", location->type->name);
|
|
}
|
|
setcelltype(location, CT_CORRIDOR);
|
|
addob(location->obpile, "pile of ash");
|
|
}
|
|
}
|
|
|
|
|
|
// checks based on object
|
|
if (o->type->id == OT_VINE) {
|
|
lifeform_t *creator;
|
|
int willvanish = B_FALSE;
|
|
|
|
// creator no longer has los?
|
|
f = hasflag(o->flags, F_CREATEDBY);
|
|
if (f) {
|
|
creator = findlf(NULL, f->val[0]);
|
|
if (!creator || !haslos(creator, location)) {
|
|
willvanish = B_TRUE;
|
|
}
|
|
|
|
// noone there?
|
|
if (!location->lf) {
|
|
willvanish = B_TRUE;
|
|
}
|
|
|
|
if (willvanish) {
|
|
// vanish.
|
|
if (haslos(player, location)) {
|
|
msg("%s vanish%s.", obname, (o->amt == 1) ? "es" : "");
|
|
}
|
|
killob(o);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// check each flag for this object...
|
|
for (f = o->flags->first ; f ; f = nextf) {
|
|
object_t *oo,*nextoo;
|
|
nextf = f->next;
|
|
|
|
// CHECKS FOR CURRENT OBJECT
|
|
if (f->id == F_ACTIVATED) {
|
|
if (o->type->id == OT_JETPACK) {
|
|
// activated jetpack on the ground?
|
|
if (location) {
|
|
if (haslos(player, location)) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname, 1);
|
|
msg("%s shoots up into the roof and explodes!",obname);
|
|
}
|
|
removeob(o, o->amt);
|
|
return;
|
|
} else {
|
|
int chargeleft;
|
|
// use up power
|
|
chargeleft = usecharge(o);
|
|
|
|
// out of power?
|
|
if (chargeleft <= 0) {
|
|
if (owner) {
|
|
// announce power loss
|
|
if (isplayer(owner)) {
|
|
msg("Your %s is out of power!",noprefix(obname));
|
|
// you know it's out
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
f->known = B_TRUE;
|
|
}
|
|
}
|
|
|
|
turnoff(NULL, o);
|
|
|
|
if (owner) {
|
|
// user will fall to the ground if not flying in some
|
|
// other way
|
|
if (!lfhasflag(owner, F_FLYING)) {
|
|
if (cansee(player, owner)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(owner, lfname);
|
|
msg("%s crash%s to the ground!",lfname,
|
|
isplayer(owner) ? "" : "es");
|
|
}
|
|
losehp(owner, rnd(1,4), DT_BASH, NULL, "falling");
|
|
}
|
|
}
|
|
} else if (chargeleft <= 10) { // about to run out of power?
|
|
if (isplayer(owner)) {
|
|
msg("Your %s splutters.", noprefix(obname));
|
|
}
|
|
// TODO: add smoke!
|
|
}
|
|
}
|
|
} else if (hasflag(o->flags, F_GRENADE)) {
|
|
flag_t *f2;
|
|
// countdown...
|
|
f2 = hasflag(o->flags, F_CHARGES);
|
|
if (f2) {
|
|
f2->val[0]--;
|
|
if (f2->val[0] <= 0) {
|
|
// blow up!
|
|
takedamage(o, 999, DT_DIRECT);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (hasflag(o->flags, F_LIGHTSOURCE)) {
|
|
flag_t *f2,*mf;
|
|
// countdown...
|
|
f2 = hasflag(o->flags, F_CHARGES);
|
|
if (f2) {
|
|
f2->val[0]--;
|
|
if (f2->val[0] <= 0) {
|
|
// turnoff
|
|
turnoff(NULL, o);
|
|
mf = hasflag(o->flags, F_CHARGEOUTMSG);
|
|
if (mf) obaction(o, mf->text);
|
|
needredraw = B_TRUE;
|
|
return;
|
|
} else if (f2->val[0] <= 50) {
|
|
if (onein(6)) {
|
|
mf = hasflag(o->flags, F_CHARGELOWMSG);
|
|
if (mf) obaction(o, mf->text);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (f->id == F_OBHPDRAIN) {
|
|
enum DAMTYPE damtype;
|
|
//takedamage(o, f->val[0] * firstlftime, DT_DIRECT);
|
|
if (f->val[1] == NA) {
|
|
damtype = DT_DIRECT;
|
|
} else {
|
|
damtype = f->val[1];
|
|
}
|
|
takedamage(o, f->val[0], damtype);
|
|
if (hasflag(o->flags, F_DEAD)) return;
|
|
}
|
|
|
|
|
|
// damaging objects here will damage other objects
|
|
if (f->id == F_WALKDAM) {
|
|
// everything here takes damage
|
|
//damageallobs(o, o->pile, f->val[0] * timespent, f->val[1]);
|
|
damageallobs(o, o->pile, roll(f->text), f->val[0]);
|
|
//if (hasflag(o->flags, F_DEAD)) return;
|
|
}
|
|
|
|
// is object on fire?
|
|
if (f->id == F_ONFIRE) {
|
|
// water puts out fire
|
|
for (oo = o->pile->first ; oo ; oo = nextoo) {
|
|
nextoo = oo->next;
|
|
if ((oo != o) && (oo->material->id == MT_WATER)) {
|
|
extinguish(o);
|
|
continue;
|
|
}
|
|
}
|
|
// if it hasn't been extinguished, fire burns
|
|
takedamage(o, 2, DT_FIRE); // TODO: don't hardcode
|
|
if (hasflag(o->flags, F_DEAD)) return;
|
|
}
|
|
|
|
// will current object convert other obs to something else?
|
|
if ((f->id == F_MATCONVERT) && !hasflag(o->flags, F_NOMATCONVERT)) {
|
|
enum MATERIAL mat;
|
|
mat = f->val[0];
|
|
|
|
for (oo = o->pile->first ; oo ; oo = nextoo) {
|
|
flag_t *f2;
|
|
nextoo = oo->next;
|
|
if ((oo != o) && (oo->material->id == mat)) {
|
|
char buf[BUFLEN];
|
|
object_t *newob;
|
|
// TODO: remove the old object first
|
|
// in case the obpile doesn't have space
|
|
// to fit both the new and old ones.
|
|
// place item of this type here!
|
|
sprintf(buf, "%d %s", o->amt, f->text);
|
|
newob = addob(o->pile, buf);
|
|
if (newob) {
|
|
int cansee;
|
|
// make the weight match.
|
|
newob->weight = o->weight;
|
|
// announce it?
|
|
cansee = B_FALSE;
|
|
if (location && haslos(player, location)) {
|
|
cansee = B_TRUE;
|
|
} else if (o->pile->owner == player) {
|
|
cansee = B_TRUE;
|
|
}
|
|
|
|
if (cansee) {
|
|
f2 = NULL;
|
|
if (o->amt > 1) {
|
|
f2 = hasflagval(o->flags, F_MATCONVERTTEXTPL, mat, NA, NA,NULL);
|
|
}
|
|
if (!f2) {
|
|
f2 = hasflagval(o->flags, F_MATCONVERTTEXT, mat, NA, NA, NULL);
|
|
}
|
|
|
|
if (f2) {
|
|
char *locbuf;
|
|
getobname(o, buf, o->amt);
|
|
locbuf = strdup(buf);
|
|
capitalise(locbuf);
|
|
if (o->pile->owner == player) {
|
|
// Remove prefix
|
|
locbuf = strrep(locbuf, "An ", "", NULL);
|
|
locbuf = strrep(locbuf, "A ", "", NULL);
|
|
}
|
|
msg("%s%s %s.", (o->pile->owner == player) ? "Your " : "", locbuf, f2->text);
|
|
free(locbuf);
|
|
}
|
|
}
|
|
// remove original object
|
|
removeob(o, o->amt);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (f->id == F_WET) {
|
|
if (isequipped(o) || !o->pile->owner) {
|
|
cell_t *ourcell;
|
|
object_t *splash;
|
|
ourcell = getoblocation(o);
|
|
// drip
|
|
splash = addob(ourcell->obpile, "splash of water");
|
|
}
|
|
}
|
|
|
|
} // end for each object flag
|
|
}
|
|
|
|
void turnoff(lifeform_t *lf, object_t *o) {
|
|
char obname[BUFLEN];
|
|
flag_t *f;
|
|
|
|
f = hasflag(o->flags, F_ACTIVATED);
|
|
if (!f) {
|
|
// already off
|
|
return;
|
|
}
|
|
|
|
// reset charges
|
|
if (hasflag(o->flags, F_RECHARGEWHENOFF)) {
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f) {
|
|
f->val[0] = f->val[1];
|
|
}
|
|
}
|
|
|
|
getobname(o, obname, 1);
|
|
if (lf) {
|
|
if (isplayer(lf)) {
|
|
msg("You deactivate your %s.",noprefix(obname));
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s deactivates %s.",lfname, obname);
|
|
}
|
|
}
|
|
|
|
if (hasflag(o->flags, F_GRENADE)) {
|
|
object_t *stackob;
|
|
// make it stackable again
|
|
addflag(o->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
|
// other stacks to join?
|
|
stackob = canstackob(o->pile, o);
|
|
if (stackob) {
|
|
char stackname[BUFLEN];
|
|
// remove it, and inc amt on the stack
|
|
removeob(o, 1);
|
|
stackob->amt++;
|
|
getobname(stackob, stackname, stackob->amt);
|
|
msgnocap("%c - %s.",stackob->letter, stackname);
|
|
} else {
|
|
// just turn off
|
|
killflag(f);
|
|
}
|
|
} else {
|
|
killflag(f);
|
|
}
|
|
|
|
if (o->pile->owner) {
|
|
loseobflags(o->pile->owner, o, F_ACTIVATECONFER);
|
|
}
|
|
}
|
|
|
|
void turnon(lifeform_t *lf, object_t *o) {
|
|
char obname[BUFLEN];
|
|
flag_t *f;
|
|
|
|
|
|
f = hasflag(o->flags, F_ACTIVATED);
|
|
if (f) {
|
|
// already on
|
|
if (isplayer(lf)) {
|
|
msg("Your %s is already activated!\n", noprefix(obname));
|
|
}
|
|
return;
|
|
}
|
|
|
|
// check charges
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f && (f->val[0] <= 0)) {
|
|
// out of power
|
|
if (isplayer(lf)) {
|
|
nothinghappens();
|
|
}
|
|
return;
|
|
}
|
|
|
|
getobname(o, obname, 1);
|
|
if (isplayer(lf)) {
|
|
msg("You activate your %s.",noprefix(obname));
|
|
} else if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
msg("%s activates %s.",lfname, obname);
|
|
}
|
|
|
|
// for grenades, give a new object which is activated
|
|
if (hasflag(o->flags, F_GRENADE)) {
|
|
object_t *newob;
|
|
|
|
newob = splitob(o);
|
|
|
|
if (newob) {
|
|
char newobname[BUFLEN];
|
|
// announce new ob
|
|
addflag(newob->flags, F_ACTIVATED, B_TRUE, NA, NA, NULL);
|
|
getobname(newob, newobname, 1);
|
|
msgnocap("%c - %s [activated].",newob->letter, newobname);
|
|
} else {
|
|
if (isplayer(lf)) {
|
|
msg("You don't have room for an activated %s!",noprefix(obname));
|
|
}
|
|
}
|
|
} else {
|
|
addflag(o->flags, F_ACTIVATED, B_TRUE, NA, NA, NULL);
|
|
}
|
|
|
|
giveobflags(lf, o, F_ACTIVATECONFER);
|
|
}
|
|
|
|
|
|
int uncurseob(object_t *o, int *seen) {
|
|
lifeform_t *lf = NULL;
|
|
|
|
// default
|
|
if (seen) *seen = B_FALSE;
|
|
|
|
if (o->blessed != B_CURSED) {
|
|
return B_TRUE;
|
|
}
|
|
lf = o->pile->owner;
|
|
|
|
// announce
|
|
if (lf) {
|
|
if (cansee(player, lf)) {
|
|
char lfname[BUFLEN];
|
|
char obname[BUFLEN];
|
|
getlfname(lf, lfname);
|
|
getobname(o, obname,o->amt);
|
|
msg("A black aura breaks away from %s%s %s.",lfname,getpossessive(lfname),noprefix(obname));
|
|
if (seen) *seen = B_TRUE;
|
|
}
|
|
} else { // not held
|
|
cell_t *loc = NULL;
|
|
loc = getoblocation(o);
|
|
if (haslos(player, loc)) {
|
|
char obname[BUFLEN];
|
|
getobname(o, obname,o->amt);
|
|
msg("A black aura breaks away from %s.",obname);
|
|
if (seen) *seen = B_TRUE;
|
|
}
|
|
}
|
|
// uncurse it
|
|
o->blessed = B_UNCURSED;
|
|
o->blessknown = B_TRUE;
|
|
return B_FALSE;
|
|
}
|
|
|
|
// returns charges remaining, -1 if object doesn't have the flag
|
|
int usecharge(object_t *o) {
|
|
flag_t *f;
|
|
f = hasflag(o->flags, F_CHARGES);
|
|
if (f) {
|
|
f->val[0]--;
|
|
return f->val[0];
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int validateobs(void) {
|
|
objecttype_t *ot;
|
|
skill_t *sk;
|
|
int foundspells = B_FALSE;
|
|
int goterror = B_FALSE;
|
|
flag_t *f;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
|
|
// fix up glyphs
|
|
f = hasflag(ot->flags, F_GLYPH);
|
|
if (f) {
|
|
if (f->val[0] == NA) {
|
|
f->val[0] = getmaterialcolour(ot->material->id);
|
|
}
|
|
}
|
|
|
|
if ((ot->obclass->id == OC_SPELL) || (ot->obclass->id == OC_ABILITY)) {
|
|
if (!foundspells) foundspells = B_TRUE;
|
|
if (!hasflag(ot->flags, F_SPELLSCHOOL)) {
|
|
printf("ERROR - spell %s doesn't have F_SPELLSCHOOL.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
/*
|
|
if (!hasflag(ot->flags, F_SPELLLETTER)) {
|
|
printf("ERROR - spell %s doesn't have F_SPELLLETTER.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
*/
|
|
|
|
if ((ot->obclass->id == OC_SPELL) && !hasflag(ot->flags, F_SPELLLEVEL)) {
|
|
printf("ERROR - spell %s doesn't have F_SPELLLEVEL.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
} else if (ot->obclass->id == OC_SCROLL) {
|
|
if (foundspells) {
|
|
printf("ERROR in object '%s' - all Scrolls must be defined before Spells.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
} else if (ot->obclass->id == OC_WEAPON) {
|
|
if (!hasflag(ot->flags, F_USESSKILL) && !hasflag(ot->flags, F_FIREARM)) {
|
|
printf("ERROR in object '%s' - weapon has no associated skill.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
}
|
|
if (hasflagval(ot->flags, F_PICKLOCKS, NA, B_BLUNTONFAIL, NA, NULL) && hasflag(ot->flags, F_STACKABLE)) {
|
|
printf("ERROR in object '%s' - cannot have F_BLUNTONFAIL on stackable objects.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
if (hasflag(ot->flags, F_FIREARM) && !hasflag(ot->flags, F_RANGE)) {
|
|
printf("ERROR in object '%s' - firearms need to have F_RANGE.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
f = hasflag(ot->flags, F_TECHLEVEL);
|
|
if (f && (f->val[0] != PR_INEPT)) {
|
|
if (!hasflag(ot->flags, F_HASHIDDENNAME)) {
|
|
printf("ERROR in object '%s' - has a techlevel but doesn't have a hidden name.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
}
|
|
f = hasflag(ot->flags, F_MANUALOF);
|
|
if (f && !findskill(f->val[0])) {
|
|
printf("ERROR in object '%s' - teachs a skill which doesn't exist.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
f = hasflag(ot->flags, F_DAM);
|
|
if (f) {
|
|
if (f->val[0] < 0) {
|
|
printf("ERROR in object '%s' - F_DAM does not specify damage type.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
if (!strlen(f->text)) {
|
|
printf("ERROR in object '%s' - F_DAM does not have dice string.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
}
|
|
f = hasflag(ot->flags, F_EXPLODEONDAM);
|
|
if (f && !strlen(f->text)) {
|
|
printf("ERROR in object '%s' - F_EXPLODEONDAM does not have damage string.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
f = hasflag(ot->flags, F_EXPLODEONDEATH);
|
|
if (f && !strlen(f->text)) {
|
|
printf("ERROR in object '%s' - F_EXPLODEONDEATH does not have damage string.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
if (hasflag(ot->flags, F_HITCONFER) && !hasflag(ot->flags, F_HITCONFERVALS)) {
|
|
printf("ERROR in object '%s' - has F_HITCONFER, but no HITCONFERVALS defined.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
if (hasflag(ot->flags, F_OBDIETEXT) && hasflag(ot->flags, F_NOOBDIETEXT)) {
|
|
printf("ERROR in object '%s' - has both dietext & noobdietext.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
f = hasflag(ot->flags, F_THEREISHERE);
|
|
if (f && !strlen(f->text)) {
|
|
printf("ERROR in object '%s' - has f_thereishere but no ->text.\n", ot->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
}
|
|
|
|
for (sk = firstskill ; sk ; sk = sk->next) {
|
|
int found = B_FALSE;
|
|
// make sure every skill have an object providing it
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if (hasflagval(ot->flags, F_MANUALOF, sk->id, NA, NA, NULL)) {
|
|
found = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
printf("ERROR - skill '%s' has no matching manual.\n", sk->name);
|
|
goterror = B_TRUE;
|
|
}
|
|
}
|
|
|
|
return goterror;
|
|
}
|
|
|
|
int willshatter(enum MATERIAL mat) {
|
|
switch (mat) {
|
|
case MT_GLASS:
|
|
case MT_ICE:
|
|
return B_TRUE;
|
|
default: break;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
// determine how long a conferred effect should last, based on its blessed/cursed status.
|
|
// blessed: always max
|
|
// uncursed: random number between min & max
|
|
// cursed: always min
|
|
int geteffecttime(int min, int max, enum BLESSTYPE isblessed) {
|
|
int howlong;
|
|
// how long for?
|
|
switch (isblessed) {
|
|
case B_BLESSED:
|
|
howlong = 15;
|
|
break;
|
|
case B_CURSED:
|
|
howlong = 5;
|
|
break;
|
|
default: // ie. B_UNCURSED
|
|
howlong = rnd(5,15);
|
|
break;
|
|
}
|
|
return howlong;
|
|
}
|
|
|
|
objecttype_t *getlinkspell(object_t *o) {
|
|
flag_t *f = NULL;
|
|
objecttype_t *spelltype = NULL;
|
|
f = hasflag(o->flags, F_LINKSPELL);
|
|
if (f) {
|
|
// find the linked spell
|
|
spelltype = findot(f->val[0]);
|
|
}
|
|
|
|
return spelltype;
|
|
}
|
|
|
|
enum COLOUR getmaterialcolour(enum MATERIAL mat) {
|
|
enum COLOUR col;
|
|
switch (mat) {
|
|
case MT_WOOD:
|
|
case MT_LEATHER:
|
|
col = C_BROWN;
|
|
break;
|
|
case MT_FIRE:
|
|
case MT_BLOOD:
|
|
col = C_RED;
|
|
break;
|
|
case MT_GLASS:
|
|
case MT_MAGIC:
|
|
col = C_CYAN;
|
|
break;
|
|
case MT_ICE:
|
|
col = C_WHITE;
|
|
break;
|
|
case MT_GOLD:
|
|
col = C_YELLOW;
|
|
break;
|
|
case MT_WATER:
|
|
col = C_BLUE;
|
|
break;
|
|
case MT_SLIME:
|
|
case MT_ACID:
|
|
col = C_GREEN;
|
|
break;
|
|
default:
|
|
col = C_GREY;
|
|
}
|
|
return col;
|
|
}
|
|
|
|
// is the given material solid or liquid?
|
|
enum MATSTATE getmaterialstate(enum MATERIAL mat) {
|
|
switch (mat) {
|
|
case MT_FIRE:
|
|
case MT_MAGIC:
|
|
case MT_NOTHING:
|
|
return MS_OTHER;
|
|
case MT_ACID:
|
|
case MT_BLOOD:
|
|
case MT_OIL:
|
|
case MT_WATER:
|
|
return MS_LIQUID;
|
|
case MT_GAS:
|
|
return MS_GAS;
|
|
default:
|
|
return MS_SOLID;
|
|
}
|
|
return MS_OTHER; // should never happen
|
|
}
|
|
|
|
int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, object_t *firearm, enum ATTRIB whichatt) {
|
|
int acc,maxrange,howfar;
|
|
// figure out if you miss or not, based on distance and
|
|
// dexterity
|
|
// base:
|
|
// if throwing, 50%
|
|
// if firing, gun accuracy
|
|
// adjust for range:
|
|
// pointblank = +30%
|
|
// max = -30%
|
|
// then modify using dexterity/int/whatever
|
|
// then penalise for throwing non-missiles
|
|
|
|
// base accuracy
|
|
if (firearm) {
|
|
acc = getobaccuracy(firearm, thrower);
|
|
} else {
|
|
acc = 50;
|
|
}
|
|
|
|
// adjust for range
|
|
if (firearm || missile) {
|
|
if (firearm) {
|
|
maxrange = getfirearmrange(firearm);
|
|
} else {
|
|
maxrange = getmaxthrowrange(thrower, missile);
|
|
}
|
|
} else {
|
|
maxrange = getvisrange(thrower);
|
|
}
|
|
|
|
howfar = getcelldist(thrower->cell, where);
|
|
|
|
if (howfar == 1) {
|
|
acc += 30;
|
|
} else if (howfar == maxrange) {
|
|
acc -= 30;
|
|
}
|
|
|
|
|
|
// modify for dexterity
|
|
if (whichatt != A_NONE) {
|
|
acc += getstatmod(thrower, whichatt);
|
|
}
|
|
|
|
// penalty for throwing non-missiles
|
|
if (missile && !firearm && !isthrowmissile(missile)) {
|
|
acc -= 20;
|
|
}
|
|
// modify for prone throwers
|
|
if (isprone(thrower)) {
|
|
acc -= 50;
|
|
} else {
|
|
// modify for prone defenders
|
|
if (where->lf && isprone(where->lf)) {
|
|
acc -= 30;
|
|
}
|
|
}
|
|
return acc;
|
|
}
|
|
|