/* * ring_off: * Take off a ring */ ring_off() { register int ring; register THING *obj; register char packchar; if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) { if (terse) msg("no rings"); else msg("you aren't wearing any rings"); return; } else if (cur_ring[LEFT] == NULL) ring = RIGHT; else if (cur_ring[RIGHT] == NULL) ring = LEFT; else if ((ring = gethand()) < 0) return; mpos = 0; obj = cur_ring[ring]; if (obj == NULL) { msg("not wearing such a ring"); return; } packchar = pack_char(obj); if (dropcheck(obj)) msg("was wearing %s(%c)", inv_name(obj, TRUE), packchar); }
static LLVMValueRef make_char(const char *str) { LLVMValueRef charval; /* Skip leading ' */ str += 1; charval = CONST(pack_char(&str)); return charval; }
/** tList* read_tList_fp(FILE* fp, int mode) ファイルポインタが示すファイルから一行づつ読み込んでリストのキー部に格納. 空行はリストに加えない. @param fp ファイルポインタ. @param mode 0: ファイルをそのまま読み込む. @param mode 1: 先頭が # の行はリストに加えない.また前後の空白を削除し,その他の連続する空白も1つの空白に変換する. また,タブは一個の空白として処理される. @param mode 2: 1の場合に加えて,途中の # 以降も無視する @return 格納したリストへのポインタ. @bug ディレクトリを読ませると,戻ってこない. */ tList* read_tList_fp(FILE* fp, int mode) { char val[LBUF+1]; char* str; tList* lp = NULL; tList* lt = NULL; if (fp==NULL) return NULL; fgets(val, LBUF, fp); while (!feof(fp)) { if (mode>0) { if (mode>1) { int i; for (i=0; i<(int)strlen(val); i++) { if (val[i]=='#') { val[i] = '\0'; break; } if (i>=LBUF) break; } } str = pack_char(val, ' '); } else { str = (char*)malloc(LBUF+1); if (str!=NULL) strncpy(val, str, LBUF); } if (str!=NULL) { if (strlen(str)>0) { // 空行のチェック if (mode==0 || str[0]!='#') { lt = add_tList_node_str(lt, str, NULL); if (lp==NULL) lp = lt; } } free(str); } fgets(val, LBUF, fp); } return lp; }
/** tList* bvh_get_seq_data(FILE* fp) fp の一行分のデータに含まれる項目を空白を区切りにしてリストに格納する. @param ptr 読み出しファイルの識別子 @return アイテムを格納したリストへのポインタ.失敗した場合は NULL */ tList* bvh_get_seq_data(FILE* fp) { if (fp==NULL) return NULL; char line[LBUF+1]; line[LBUF] = '\0'; fgets(line, LBUF, fp); char* pack = pack_char(line, ' '); if (pack==NULL) return NULL; // replace_str(pack, LBUF, " :", ":"); //replace_str(pack, LBUF, " {", "\n{\n"); //replace_str(pack, LBUF, " }", "\n}\n"); tList* list = awk_tList(pack, ' '); free(pack); return list; }
static LLVMValueRef make_str(const char *str) { LLVMValueRef global, strval, chars[MAX_STRSIZE]; const char *p; int size = 0; /* Skip leading " */ p = str + 1; while (p && size < MAX_STRSIZE - 1) chars[size++] = CONST(pack_char(&p)); chars[size++] = CONST(EOT); global = LLVMAddGlobal(module, TYPE_ARRAY(size), ".gstr"); LLVMSetLinkage(global, LLVMPrivateLinkage); strval = LLVMConstArray(TYPE_INT, chars, size); LLVMSetInitializer(global, strval); return lvalue_to_rvalue(global); }
/* * take_off: * Get the armor off of the players back */ take_off() { register THING *obj; if ((obj = cur_armor) == NULL) { after = FALSE; if (terse) msg("not wearing armor"); else msg("you aren't wearing any armor"); return; } if (!dropcheck(cur_armor)) return; cur_armor = NULL; if (terse) addmsg("was"); else addmsg("you used to be "); msg(" wearing %c) %s", pack_char(obj), inv_name(obj, TRUE)); }
/* * add_pack: * Pick up an object and add it to the pack. If the argument is non-null * use it as the linked_list pointer instead of gettting it off the ground. */ void add_pack(struct linked_list *item, int silent) { struct linked_list *ip, *lp; struct object *obj, *op; int exact, from_floor; if (item == NULL) { from_floor = TRUE; if ((item = find_obj(hero.y, hero.x)) == NULL) return; } else from_floor = FALSE; obj = (struct object *) ldata(item); /* * Link it into the pack. Search the pack for a object of similar type * if there isn't one, stuff it at the beginning, if there is, look for one * that is exactly the same and just increment the count if there is. * it that. Food is always put at the beginning for ease of access, but * is not ordered so that you can't tell good food from bad. First check * to see if there is something in thr same group and if there is then * increment the count. */ if (obj->o_group) { for (ip = pack; ip != NULL; ip = next(ip)) { op = (struct object *) ldata(ip); if (op->o_group == obj->o_group) { /* * Put it in the pack and notify the user */ op->o_count++; if (from_floor) { detach(lvl_obj, item); mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR)); } discard(item); item = ip; goto picked_up; } } } /* * Check if there is room */ if (inpack == MAXPACK-1) { msg("You can't carry anything else."); return; } /* * Check for and deal with scare monster scrolls */ if (obj->o_type == SCROLL && obj->o_which == S_SCARE) if (obj->o_flags & ISFOUND) { msg("The scroll turns to dust as you pick it up."); detach(lvl_obj, item); mvaddch(hero.y, hero.x, FLOOR); return; } else obj->o_flags |= ISFOUND; inpack++; if (from_floor) { detach(lvl_obj, item); mvaddch(hero.y, hero.x, (roomin(&hero) == NULL ? PASSAGE : FLOOR)); } /* * Search for an object of the same type */ exact = FALSE; for (ip = pack; ip != NULL; ip = next(ip)) { op = (struct object *) ldata(ip); if (obj->o_type == op->o_type) break; } if (ip == NULL) { /* * Put it at the end of the pack since it is a new type */ for (ip = pack; ip != NULL; ip = next(ip)) { op = (struct object *) ldata(ip); if (op->o_type != FOOD) break; lp = ip; } } else { /* * Search for an object which is exactly the same */ while (ip != NULL && op->o_type == obj->o_type) { if (op->o_which == obj->o_which) { exact = TRUE; break; } lp = ip; if ((ip = next(ip)) == NULL) break; op = (struct object *) ldata(ip); } } if (ip == NULL) { /* * Didn't find an exact match, just stick it here */ if (pack == NULL) pack = item; else { lp->l_next = item; item->l_prev = lp; item->l_next = NULL; } } else { /* * If we found an exact match. If it is a potion, food, or a * scroll, increase the count, otherwise put it with its clones. */ if (exact && ISMULT(obj->o_type)) { op->o_count++; discard(item); item = ip; goto picked_up; } if ((item->l_prev = prev(ip)) != NULL) item->l_prev->l_next = item; else pack = item; item->l_next = ip; ip->l_prev = item; } picked_up: /* * Notify the user */ obj = (struct object *) ldata(item); if (notify && !silent) { if (!terse) addmsg("You now have "); msg("%s (%c)", inv_name(obj, !terse), pack_char(obj)); } if (obj->o_type == AMULET) amulet = TRUE; }
void add_pack(THING *obj, bool silent) { THING *op, *lp; bool from_floor; from_floor = FALSE; if (obj == NULL) { if ((obj = find_obj(hero.y, hero.x)) == NULL) return; from_floor = TRUE; } /* * Check for and deal with scare monster scrolls */ if (obj->o_type == SCROLL && obj->o_which == S_SCARE) if (obj->o_flags & ISFOUND) { detach(lvl_obj, obj); mvaddch(hero.y, hero.x, floor_ch()); chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR; discard(obj); msg("the scroll turns to dust as you pick it up"); return; } if (pack == NULL) { pack = obj; obj->o_packch = pack_char(); inpack++; } else { lp = NULL; for (op = pack; op != NULL; op = next(op)) { if (op->o_type != obj->o_type) lp = op; else { while (op->o_type == obj->o_type && op->o_which != obj->o_which) { lp = op; if (next(op) == NULL) break; else op = next(op); } if (op->o_type == obj->o_type && op->o_which == obj->o_which) { if (ISMULT(op->o_type)) { if (!pack_room(from_floor, obj)) return; op->o_count++; dump_it: discard(obj); obj = op; lp = NULL; goto out; } else if (obj->o_group) { lp = op; while (op->o_type == obj->o_type && op->o_which == obj->o_which && op->o_group != obj->o_group) { lp = op; if (next(op) == NULL) break; else op = next(op); } if (op->o_type == obj->o_type && op->o_which == obj->o_which && op->o_group == obj->o_group) { op->o_count += obj->o_count; inpack--; if (!pack_room(from_floor, obj)) return; goto dump_it; } } else lp = op; } out: break; } } if (lp != NULL) { if (!pack_room(from_floor, obj)) return; else { obj->o_packch = pack_char(); next(obj) = next(lp); prev(obj) = lp; if (next(lp) != NULL) prev(next(lp)) = obj; next(lp) = obj; } } } obj->o_flags |= ISFOUND; /* * If this was the object of something's desire, that monster will * get mad and run at the hero. */ for (op = mlist; op != NULL; op = next(op)) if (op->t_dest == &obj->o_pos) op->t_dest = &hero; if (obj->o_type == AMULET) amulet = TRUE; /* * Notify the user */ if (!silent) { if (!terse) addmsg("you now have "); msg("%s (%c)", inv_name(obj, !terse), obj->o_packch); } }
/* * ring_on: * Put a ring on a hand */ ring_on() { register THING *obj; register int ring; obj = get_item("put on", RING); /* * Make certain that it is somethings that we want to wear */ if (obj == NULL) return; if (obj->o_type != RING) { if (!terse) msg("it would be difficult to wrap that around a finger"); else msg("not a ring"); return; } /* * find out which hand to put it on */ if (is_current(obj)) return; if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) { if ((ring = gethand()) < 0) return; } else if (cur_ring[LEFT] == NULL) ring = LEFT; else if (cur_ring[RIGHT] == NULL) ring = RIGHT; else { if (!terse) msg("you already have a ring on each hand"); else msg("wearing two"); return; } cur_ring[ring] = obj; /* * Calculate the effect it has on the poor guy. */ switch (obj->o_which) { case R_ADDSTR: chg_str(obj->o_ac); break; case R_SEEINVIS: invis_on(); break; case R_AGGR: aggravate(); break; } if (!terse) addmsg("you are now wearing "); msg("%s (%c)", inv_name(obj, TRUE), pack_char(obj)); }
/* * add_pack: * Pick up an object and add it to the pack. If the argument * is non-null use it as the linked_list pointer instead of * getting it off the ground. */ bool add_pack(struct linked_list *item,bool silent) { struct linked_list *ip, *lp; struct object *obj, *op; bool from_floor; char delchar; if (player.t_room == NULL) delchar = PASSAGE; else delchar = FLOOR; if (item == NULL) { from_floor = TRUE; if ((item = find_obj(hero.y, hero.x)) == NULL) { mpos = 0; msg("That object must have been an illusion."); mvaddch(hero.y, hero.x, delchar); return FALSE; } /* * Check for scare monster scrolls */ obj = OBJPTR(item); if (obj->o_type == SCROLL && obj->o_which == S_SCARE) { if (o_on(obj,ISFOUND)) { msg("The scroll turns to dust as you pick it up."); detach(lvl_obj, item); discard(item); mvaddch(hero.y, hero.x, delchar); return FALSE; } } } else from_floor = FALSE; obj = OBJPTR(item); /* * See if this guy can carry any more weight */ if (itemweight(obj) + him->s_pack > him->s_carry) { msg("You can't carry that %s.", obj->o_typname); return FALSE; } /* * Check if there is room */ if (packvol + obj->o_vol > V_PACK) { msg("That %s won't fit in your pack.", obj->o_typname); return FALSE; } if (from_floor) { detach(lvl_obj, item); mvaddch(hero.y, hero.x, delchar); } item->l_prev = NULL; item->l_next = NULL; setoflg(obj, ISFOUND); /* * start looking thru pack to find the start of items * with the same type. */ lp = pack; for (ip = pack; ip != NULL; ip = next(ip)) { op = OBJPTR(ip); /* * If we find a matching type then quit. */ if (op->o_type == obj->o_type) break; if (next(ip) != NULL) lp = next(lp); /* update "previous" entry */ } /* * If the pack was empty, just stick the item in it. */ if (pack == NULL) { pack = item; item->l_prev = NULL; } /* * If we looked thru the pack, but could not find an * item of the same type, then stick it at the end, * unless it was food, then put it in front. */ else if (ip == NULL) { if (obj->o_type == FOOD) { /* insert food at front */ item->l_next = pack; pack->l_prev = item; pack = item; item->l_prev = NULL; } else { /* insert other stuff at back */ lp->l_next = item; item->l_prev = lp; } } /* * Here, we found at least one item of the same type. * Look thru these items to see if there is one of the * same group. If so, increment the count and throw the * new item away. If not, stick it at the end of the * items with the same type. Also keep all similar * objects near each other, like all identify scrolls, etc. */ else { struct linked_list **save; while (ip != NULL && op->o_type == obj->o_type) { if (op->o_group == obj->o_group) { if (op->o_flags == obj->o_flags) { op->o_count++; discard(item); item = ip; goto picked_up; } else { goto around; } } if (op->o_which == obj->o_which) { if (obj->o_type == FOOD) ip = next(ip); break; } around: ip = next(ip); if (ip != NULL) { op = OBJPTR(ip); lp = next(lp); } } /* * If inserting into last of group at end of pack, * just tack on the end. */ if (ip == NULL) { lp->l_next = item; item->l_prev = lp; } /* * Insert into the last of a group of objects * not at the end of the pack. */ else { save = &((ip->l_prev)->l_next); item->l_next = ip; item->l_prev = ip->l_prev; ip->l_prev = item; *save = item; } } picked_up: obj = OBJPTR(item); if (!silent) msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj)); if (obj->o_type == AMULET) amulet = TRUE; updpack(); /* new pack weight & volume */ return TRUE; }
/* * get_item: * pick something out of a pack for a purpose */ struct linked_list *get_item(char *purpose,int type) { struct linked_list *obj, *pit, *savepit; struct object *pob; int ch, och, anr, cnt; if (pack == NULL) { msg("You aren't carrying anything."); return NULL; } if (type != WEAPON && (type != 0 || next(pack) == NULL)) { /* * see if we have any of the type requested */ pit = pack; anr = 0; for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) { pob = OBJPTR(pit); if (type == pob->o_type || type == 0) { ++anr; savepit = pit; /* save in case of only 1 */ } } if (anr == 0) { msg("Nothing to %s",purpose); after = FALSE; return NULL; } else if (anr == 1) { /* only found one of 'em */ do { struct object *opb; opb = OBJPTR(savepit); msg("%s what (* for the item)?",purpose); och = readchar(); if (och == '*') { mpos = 0; msg("%c) %s",pack_char(opb),inv_name(opb,FALSE)); continue; } if (och == ESCAPE) { msg(""); after = FALSE; return NULL; } if (isalpha(och) && och != pack_char(opb)) { mpos = 0; msg("You can't %s that !!", purpose); after = FALSE; return NULL; } } while(!isalpha(och)); mpos = 0; return savepit; /* return this item */ } } for (;;) { msg("%s what? (* for list): ",purpose); ch = readchar(); mpos = 0; if (ch == ESCAPE) { /* abort if escape hit */ after = FALSE; msg(""); /* clear display */ return NULL; } if (ch == '*') { wclear(hw); pit = pack; /* point to pack */ cnt = 0; for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) { pob = OBJPTR(pit); if (type == 0 || type == pob->o_type) { wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE)); if (++cnt > LINES - 2 && next(pit) != NULL) { cnt = 0; dbotline(hw, morestr); wclear(hw); } } } wmove(hw, LINES - 1,0); wprintw(hw,"%s what? ",purpose); draw(hw); /* write screen */ anr = FALSE; do { ch = readchar(); if (isalpha(ch) || ch == ESCAPE) anr = TRUE; } while(!anr); /* do till we got it right */ restscr(cw); /* redraw orig screen */ if (ch == ESCAPE) { after = FALSE; msg(""); /* clear top line */ return NULL; /* all done if abort */ } /* ch has item to get from pack */ } for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och)) if (ch == och) break; if (obj == NULL) { if (och == 'A') och = 'z'; else och -= 1; msg("Please specify a letter between 'a' and '%c'",och); continue; } else return obj; } }