This is o_init.c in view mode; [Download] [Up]
/* SCCS Id: @(#)o_init.c 3.0 88/07/06
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h" /* for typedefs */
static void NDECL(setgemprobs);
static void FDECL(shuffle,(int,int,BOOLEAN_P));
static boolean FDECL(interesting_to_discover,(int));
/* note that NROFOBJECTS is the number of legal objects, which does not count
* the strange object and null object that take up positions 0 and NROFOBJECTS+1
* in the objects array
*/
#define TOTAL_OBJS (NROFOBJECTS+2)
#ifdef MACOS
short *switches; /* used to allow position independent loads of app */
/* by storing the number of the description string */
/* [at startup of the game] not the pointer to the string */
#endif
const char obj_symbols[] = {
ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM,
POTION_SYM, SCROLL_SYM, WAND_SYM,
#ifdef SPELLS
SPBOOK_SYM,
#endif
RING_SYM, GEM_SYM, 0 };
int bases[sizeof(obj_symbols)] = DUMMY;
static int disco[TOTAL_OBJS] = DUMMY;
int
letindex(let) register char let; {
register int i = 0;
register char ch;
while((ch = obj_symbols[i++]) != 0)
if(ch == let) return(i);
return(0);
}
static void
setgemprobs()
{
register int j,first;
#ifdef STRONGHOLD
int lev = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel;
#endif
first = bases[letindex(GEM_SYM)];
#ifdef STRONGHOLD
for(j = 0; j < 9-lev/3; j++)
#else
for(j = 0; j < 9-dlevel/3; j++)
#endif
objects[first+j].oc_prob = 0;
first += j;
if(first >= LAST_GEM || first > NROFOBJECTS ||
objects[first].oc_olet != GEM_SYM ||
objects[first].oc_name == NULL)
Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
first, j, LAST_GEM);
for(j = first; j < LAST_GEM; j++)
objects[j].oc_prob = (184+j-first)/(LAST_GEM-first);
}
/* shuffle descriptions on objects o_low to o_high */
static void
shuffle(o_low, o_high, domaterial)
register int o_low, o_high;
register boolean domaterial;
{
register int i, j;
const char *desc;
#ifdef TEXTCOLOR
int color;
#endif /* TEXTCOLOR */
int tmp;
#ifdef MACOS
short sw;
#endif
for(j=o_low; j <= o_high; j++) {
i = o_low + rn2(j+1-o_low);
desc = objects[j].oc_descr;
objects[j].oc_descr = objects[i].oc_descr;
objects[i].oc_descr = desc;
#ifdef TEXTCOLOR
color = objects[j].oc_color;
objects[j].oc_color = objects[i].oc_color;
objects[i].oc_color = color;
#endif /* TEXTCOLOR */
/* shuffle discovery list */
tmp = disco[j];
disco[j] = disco[i];
disco[i] = tmp;
/* shuffle material */
if(domaterial) {
tmp = objects[j].oc_material;
objects[j].oc_material = objects[i].oc_material;
objects[i].oc_material = tmp;
}
#ifdef MACOS
/* keep track of shuffling of object descriptions */
sw=switches[j];
switches[j]=switches[i];
switches[i]=sw;
#endif
}
}
void
init_objects(){
register int i, j, first, last, sum, end;
register char let;
/* bug fix to prevent "initialization error" abort on Intel Xenix.
* reported by mikew@semike
*/
for(i = 0; i != sizeof(obj_symbols); i++)
bases[i] = 0;
for(i = 0; i != TOTAL_OBJS; i++)
disco[i] = i;
#ifdef NAMED_ITEMS
init_exists(); /* zero out the "artifact exists" list */
#endif
/* init base; if probs given check that they add up to 1000,
otherwise compute probs; shuffle descriptions */
end = TOTAL_OBJS;
first = 0;
while( first < end ) {
let = objects[first].oc_olet;
last = first+1;
while(last < end && objects[last].oc_olet == let
&& objects[last].oc_name != NULL) last++;
i = letindex(let);
if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0)
error("initialization error for %c", let);
bases[i] = first;
if(let == GEM_SYM) setgemprobs();
check:
sum = 0;
for(j = first; j < last; j++) sum += objects[j].oc_prob;
if(sum == 0) {
for(j = first; j < last; j++)
objects[j].oc_prob = (1000+j-first)/(last-first);
goto check;
}
if(sum != 1000)
error("init-prob error for %c (%d%%)", let, sum);
if(objects[first].oc_descr != NULL &&
let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) {
/* shuffle, also some additional descriptions */
while(last < end && objects[last].oc_olet == let)
last++;
j = last;
if (let == GEM_SYM) {
while(--j > first)
if(!strcmp(objects[j].oc_name,"turquoise")) {
if(rn2(2)) { /* change from green? */
objects[j].oc_descr = blue;
#ifdef TEXTCOLOR
objects[j].oc_color = BLUE;
#endif
}
} else if (!strcmp(objects[j].oc_name,"aquamarine")) {
if(rn2(2)) { /* change from green? */
objects[j].oc_descr = blue;
#ifdef TEXTCOLOR
objects[j].oc_color = BLUE;
#endif
}
} else if (!strcmp(objects[j].oc_name,"fluorite")) {
switch (rn2(4)) { /* change from violet? */
case 0: break;
case 1:
objects[j].oc_descr = blue;
#ifdef TEXTCOLOR
objects[j].oc_color = BLUE;
#endif
break;
case 2:
objects[j].oc_descr = white;
#ifdef TEXTCOLOR
objects[j].oc_color = WHITE;
#endif
break;
case 3:
objects[j].oc_descr = green;
#ifdef TEXTCOLOR
objects[j].oc_color = GREEN;
#endif
break;
}
}
} else {
if (let == AMULET_SYM || let == POTION_SYM)
j--; /* THE amulet doesn't have description */
/* and water is always "clear" - 3. */
shuffle(first, --j, TRUE);
}
}
first = last;
}
/* shuffle the helmets */
shuffle(HELMET, HELM_OF_TELEPATHY, FALSE);
/* shuffle the gloves */
shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE);
/* shuffle the cloaks */
shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE);
/* shuffle the boots */
shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE);
}
void
oinit() /* level dependent initialization */
{
setgemprobs();
}
void
savenames(fd)
register int fd;
{
register int i;
unsigned int len;
#ifdef MACOS
char *descr[TOTAL_OBJS];
#endif
struct objclass *now = &objects[0];
bwrite(fd, (genericptr_t)&now, sizeof now);
bwrite(fd, (genericptr_t)bases, sizeof bases);
bwrite(fd, (genericptr_t)disco, sizeof disco);
#ifdef MACOS
for (i = 0 ; i < TOTAL_OBJS; i++) {
descr[i] = objects[i].oc_descr;
objects[i].oc_descr = (const char *)switches[i];
}
#endif
bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS);
/* as long as we use only one version of Hack we
need not save oc_name and oc_descr, but we must save
oc_uname for all objects */
for(i=0; i < TOTAL_OBJS; i++) {
#ifdef MACOS
objects[i].oc_descr = descr[i];
#endif
if(objects[i].oc_uname) {
len = strlen(objects[i].oc_uname)+1;
bwrite(fd, (genericptr_t)&len, sizeof len);
bwrite(fd, (genericptr_t)objects[i].oc_uname, len);
}
}
}
void
restnames(fd)
register int fd;
{
register int i;
unsigned int len;
struct objclass *then;
long differ;
#ifdef MACOS
/* provides position-independent save & restore */
/* by giving each object a number, keep track of it */
/* when shuffled and save the numbers instead of the */
/* description strings (which can change between */
/* executions of the program) */
/* On restore, the retrieved numbers are matched with the */
/* numbers and object descriptions in the program */
struct descr {
char *name,
*descr;
} d[TOTAL_OBJS];
/* save the current object descriptions */
for (i = 0; i < TOTAL_OBJS; i++) {
d[i].name = objects[i].oc_name;
d[i].descr = objects[i].oc_descr;
}
#endif
mread(fd, (genericptr_t) &then, sizeof then);
mread(fd, (genericptr_t) bases, sizeof bases);
mread(fd, (genericptr_t) disco, sizeof disco);
mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS);
#ifdef MACOS
for (i = 0; i < TOTAL_OBJS; i++) {
objects[i].oc_name = d[i].name;
switches[i] = (short)objects[i].oc_descr;
objects[i].oc_descr = d[switches[i]].descr;
}
#else
# if !defined(MSDOS) && !defined(M_XENIX) && !defined(HPUX)
differ = (genericptr_t)&objects[0] - (genericptr_t)then;
# else
differ = (long)&objects[0] - (long)then;
# endif
#endif /* MACOS */
for(i=0; i < TOTAL_OBJS; i++) {
#ifndef MACOS
if (objects[i].oc_name) {
# if !defined(MSDOS) && !defined(M_XENIX)
objects[i].oc_name += differ;
# else
objects[i].oc_name =
(const char *)((long)(objects[i].oc_name) + differ);
# endif
}
if (objects[i].oc_descr) {
# if !defined(MSDOS) && !defined(M_XENIX)
objects[i].oc_descr += differ;
# else
objects[i].oc_descr =
(const char *)((long)(objects[i].oc_descr) + differ);
# endif
}
#endif /* MACOS */
if (objects[i].oc_uname) {
mread(fd, (genericptr_t) &len, sizeof len);
objects[i].oc_uname = (char *) alloc(len);
mread(fd, (genericptr_t)objects[i].oc_uname, len);
}
}
}
static boolean
interesting_to_discover(i)
register int i;
{
return objects[i].oc_uname != NULL ||
(objects[i].oc_name_known && objects[i].oc_descr != NULL);
}
int
dodiscovered() /* free after Robert Viduya */
{
register int i, dis;
int ct = 0;
char class = -1;
cornline(0, "Discoveries");
for (i = 0; i <= NROFOBJECTS; i++) {
if (interesting_to_discover(dis = disco[i])) {
ct++;
if (objects[dis].oc_olet != class) {
class = objects[dis].oc_olet;
cornline(1, let_to_name(class));
}
cornline(1, typename(dis));
}
}
if (ct == 0) {
You("haven't discovered anything yet...");
cornline(3, NULL);
} else
cornline(2, NULL);
return 0;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.