void mjolinitchr(struct mjolchr *chr, long lvl) { chr->hp = 16 + ((lvl > 0) ? (mjolrand() % lvl) : 0); chr->maxhp = chr->hp; chr->gold = mjolrand() & 0xff; chr->str = 4 + ((lvl > 0) ? (mjolrand() % lvl) : 0); chr->maxstr = chr->str; chr->arm = 0; chr->exp = 0; chr->speed = 1; chr->turn = 0; chr->nturn = 0; /* dex, lock, intl, def */ return; }
struct mjolobj * mjolmkstair(long type) { struct mjolobj *obj = calloc(1, sizeof(struct mjolobj)); long l = mjolrand() & 0x0f; if (!obj) { fprintf(stderr, "memory allocation failure\n"); exit(1); } obj->data.type = type; if (!l) { /* 1/16 chance of a hidden stairway */ obj->data.flg |= MJOL_OBJ_HIDDEN; } return obj; }
struct mjolobj * mjolmkcorridor(void) { struct mjolobj *obj = calloc(1, sizeof(struct mjolobj)); long l = mjolrand() & 0x0f; if (!obj) { fprintf(stderr, "memory allocation failure\n"); exit(1); } obj->data.type = MJOL_OBJ_CORRIDOR; if (!l) { /* 1/16 chance of a hidden door */ obj->data.flg |= MJOL_OBJ_HIDDEN; } return obj; }
long mjolfindmove(struct mjolchr *src, struct mjolchr *dest, hitfunc *func, long mindist) { long retval = 0; struct mjolchr ***chrtab = mjolgame->chrtab[mjolgame->lvl]; struct mjolobj ***objtab = mjolgame->objtab[mjolgame->lvl]; struct mjolchr *chr; struct mjolobj *obj; struct mjolobj *item; long destx = dest->data.x; long desty = dest->data.y; long srcx = src->data.x; long srcy = src->data.y; long dx = destx - srcx; long dy = desty - srcy; long type; long val; if (srcx == destx && srcy == desty) { return retval; } if (((labs(dx) == 1 && labs(dy) <= 1) || (labs(dy) == 1 && labs(dx) <= 1)) && (func)) { /* attack */ retval = func(src, dest); } else { /* TODO: make collision-checking/path-finding actually work... =) */ if (labs(dx) > mindist) { if (dx < -mindist) { /* dest is to the left of src */ dx = -1; } else { /* dest is to the right of src */ dx = 1; } srcx += dx; if (dy < -mindist) { /* dest is above src */ dy = -1; } else if (dy > mindist) { /* dest is below src */ dy = 1; } chr = chrtab[srcy + dy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* src can moves horizontally and vertically */ srcy += dy; } else { chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* src moves horizontally but not vertically */ ; } else { srcx -= dx; chr = chrtab[srcy + dy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* src moves vertically but not horizontally */ srcy += dy; } } } } else if (labs(dy) > mindist) { /* vertical movement only */ if (dy < -mindist) { dy = -1; } else { dy = 1; } srcy += dy; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* src moves vertically */ } else { srcy -= dy; val = mjolrand() & 0x01; if (val) { /* try to move left */ dx = -1; } else { /* try to move right */ dx = 1; } srcx += dx; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* move into chosen direction */ ; } else { /* change horizontal direction */ dx = -dx; srcx += dx << 1; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* valid move */ ; } else { /* change vertical direction */ srcx -= dx; dy = -dy; srcy += dy << 1; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* valid move */ ; } else { /* try vertical and horizontal */ srcx -= dx; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* valid move */ ; } else { srcx += 2 * dx; chr = chrtab[srcy][srcx]; type = chr->data.type; if (mjolcanmoveto(type)) { /* valid move */ } else { /* no move found */ return retval; } } } } } } } if (!mindist && srcx == destx && srcy == desty && !(src->data.flg & MJOL_CHR_NO_PICK)) { item = objtab[destx][desty]; while (item) { type = item->data.type; if (mjolcanpickup(type)) { obj = item->data.next; if (obj) { obj->data.prev = item->data.prev; } obj = item->data.prev; if (obj) { obj->data.next = item->data.next; } else { chrtab[destx][desty] = item->data.next; } mjoladditem(dest, item); } item = item->data.next; } item = objtab[destx][desty]; while (item) { type = item->data.type; if (type == MJOL_OBJ_TRAP) { retval += mjoltrap(item, dest); } item = item->data.next; } } obj = src->data.next; if (obj) { obj->data.prev = src->data.prev; } obj = src->data.prev; if (obj) { obj->data.next = src->data.next; } else { objtab[src->data.y][src->data.x] = src->data.next; } src->data.prev = NULL; src->data.next = objtab[srcy][srcx]; obj = src->data.next; if (obj) { obj->data.prev = src; } src->data.x = srcx; src->data.y = srcy; chrtab[srcy][srcx] = src; } return retval; }