Beispiel #1
0
static enum parser_error parse_prefs_q(struct parser *p)
{
	struct prefs_data *d = parser_priv(p);
	assert(d != NULL);
	if (d->bypass)
		return PARSE_ERROR_NONE;

	if (parser_hasval(p, "sval") && parser_hasval(p, "flag")) {
		object_kind *kind;
		int tvi, svi, idx;

		tvi = tval_find_idx(parser_getsym(p, "n"));
		if (tvi < 0)
			return PARSE_ERROR_UNRECOGNISED_TVAL;
	
		svi = lookup_sval(tvi, parser_getsym(p, "sval"));
		if (svi < 0)
			return PARSE_ERROR_UNRECOGNISED_SVAL;

		idx = lookup_kind(tvi, svi);
		if (idx < 0)
			return PARSE_ERROR_UNRECOGNISED_SVAL;

		kind = &k_info[idx];
		kind->squelch = parser_getint(p, "flag");
	}

	return PARSE_ERROR_NONE;
}
Beispiel #2
0
static enum parser_error parse_r_drop(struct parser *p) {
	struct monster_race *r = parser_priv(p);
	struct monster_drop *d;
	int tval, sval;

	if (!r)
		return PARSE_ERROR_MISSING_RECORD_HEADER;
	tval = tval_find_idx(parser_getsym(p, "tval"));
	if (tval < 0)
		return PARSE_ERROR_UNRECOGNISED_TVAL;
	sval = lookup_sval(tval, parser_getsym(p, "sval"));
	if (sval < 0)
		return PARSE_ERROR_UNRECOGNISED_SVAL;

	if (parser_getuint(p, "min") > 99 || parser_getuint(p, "max") > 99)
		return PARSE_ERROR_INVALID_ITEM_NUMBER;

	d = mem_zalloc(sizeof *d);
	d->kind = objkind_get(tval, sval);
	d->percent_chance = parser_getuint(p, "chance");
	d->min = parser_getuint(p, "min");
	d->max = parser_getuint(p, "max");
	d->next = r->drops;
	r->drops = d;
	return PARSE_ERROR_NONE;
}
Beispiel #3
0
static enum parser_error parse_prefs_k(struct parser *p)
{
	int tvi, svi, idx;
	object_kind *kind;

	struct prefs_data *d = parser_priv(p);
	assert(d != NULL);
	if (d->bypass)
		return PARSE_ERROR_NONE;

	tvi = tval_find_idx(parser_getsym(p, "tval"));
	if (tvi < 0)
		return PARSE_ERROR_UNRECOGNISED_TVAL;

	svi = lookup_sval(tvi, parser_getsym(p, "sval"));
	if (svi < 0)
		return PARSE_ERROR_UNRECOGNISED_SVAL;

	idx = lookup_kind(tvi, svi);
	if (idx < 0)
		return PARSE_ERROR_UNRECOGNISED_SVAL;

	kind = &k_info[idx];
	kind->x_attr = (byte) parser_getint(p, "attr");
	kind->x_char = (wchar_t) parser_getint(p, "char");

	return PARSE_ERROR_NONE;
}
Beispiel #4
0
static enum parser_error parse_r_mimic(struct parser *p) {
	struct monster_race *r = parser_priv(p);
	int tval, sval;
	object_kind *kind;

	if (!r)
		return PARSE_ERROR_MISSING_RECORD_HEADER;
	tval = tval_find_idx(parser_getsym(p, "tval"));
	if (tval < 0)
		return PARSE_ERROR_UNRECOGNISED_TVAL;
	sval = lookup_sval(tval, parser_getsym(p, "sval"));
	if (sval < 0)
		return PARSE_ERROR_UNRECOGNISED_SVAL;

	kind = objkind_get(tval, sval);
	if (!kind)
		return PARSE_ERROR_GENERIC;
	r->mimic_kind = kind;
	return PARSE_ERROR_NONE;
}
Beispiel #5
0
static enum parser_error parse_always(struct parser *p) {
	struct store *s = parser_priv(p);
	int tval = tval_find_idx(parser_getsym(p, "tval"));
	int sval = lookup_sval(tval, parser_getsym(p, "sval"));

	object_kind *kind = lookup_kind(tval, sval);
	if (!kind)
		return PARSE_ERROR_UNRECOGNISED_SVAL;

	/* Expand if necessary */
	if (!s->always_num) {
		s->always_size = 8;
		s->always_table = mem_zalloc(s->always_size * sizeof *s->always_table);
	} else if (s->always_num >= s->always_size) {
		s->always_size += 8; 
		s->always_table = mem_realloc(s->always_table, s->always_size * sizeof *s->always_table);
	}

	s->always_table[s->always_num++] = kind;

	return PARSE_ERROR_NONE;
}
Beispiel #6
0
/**
 * Applying magic to an object, which includes creating ego-items, and applying
 * random bonuses,
 *
 * The `good` argument forces the item to be at least `good`, and the `great`
 * argument does likewise.  Setting `allow_artifacts` to true allows artifacts
 * to be created here.
 *
 * If `good` or `great` are not set, then the `lev` argument controls the
 * quality of item.
 *
 * Returns 0 if a normal object, 1 if a good object, 2 if an ego item, 3 if an
 * artifact.
 */
int apply_magic(struct object *obj, int lev, bool allow_artifacts, bool good,
				bool great, bool extra_roll)
{
	int i;
	s16b power = 0;

	/* Chance of being `good` and `great` */
	/* This has changed over the years:
	 * 3.0.0:   good = MIN(75, lev + 10);      great = MIN(20, lev / 2); 
	 * 3.3.0:	good = (lev + 2) * 3;          great = MIN(lev / 4 + lev, 50);
     * 3.4.0:   good = (2 * lev) + 5
     * 3.4 was in between 3.0 and 3.3, 3.5 attempts to keep the same
     * area under the curve as 3.4, but make the generation chances
     * flatter.  This depresses good items overall since more items
     * are created deeper. 
     * This change is meant to go in conjunction with the changes
     * to ego item allocation levels. (-fizzix)
	 */
	int good_chance = (33 + lev);
	int great_chance = 30;

	/* Roll for "good" */
	if (good || (randint0(100) < good_chance)) {
		power = 1;

		/* Roll for "great" */
		if (great || (randint0(100) < great_chance))
			power = 2;
	}

	/* Roll for artifact creation */
	if (allow_artifacts) {
		int rolls = 0;

		/* Get one roll if excellent */
		if (power >= 2) rolls = 1;

		/* Get two rolls if forced great */
		if (great) rolls = 2;
        
        /* Give some extra rolls for uniques and acq scrolls */
        if (extra_roll) rolls += 2;

		/* Roll for artifacts if allowed */
		for (i = 0; i < rolls; i++)
			if (make_artifact(obj)) return 3;
	}

	/* Try to make an ego item */
	if (power == 2)
		make_ego_item(obj, lev);

	/* Apply magic */
	if (tval_is_weapon(obj)) {
		apply_magic_weapon(obj, lev, power);
	} else if (tval_is_armor(obj)) {
		apply_magic_armour(obj, lev, power);
	} else if (tval_is_ring(obj)) {
		if (obj->sval == lookup_sval(obj->tval, "Speed")) {
			/* Super-charge the ring */
			while (one_in_(2))
				obj->modifiers[OBJ_MOD_SPEED]++;
		}
	} else if (tval_is_chest(obj)) {
		/* Hack -- skip ruined chests */
		if (obj->kind->level > 0) {
			/* Hack -- pick a "difficulty" */
			obj->pval = randint1(obj->kind->level);

			/* Never exceed "difficulty" of 55 to 59 */
			if (obj->pval > 55)
				obj->pval = (s16b)(55 + randint0(5));
		}
	}

	/* Apply minima from ego items if necessary */
	ego_apply_minima(obj);

	return power;
}
Beispiel #7
0
/**
 * Format the object name so that the prefix is right aligned to a common
 * column.
 *
 * This uses the default logic of object_desc() in order to handle flavors,
 * artifacts, vowels and so on. It was easier to do this and then use strtok()
 * to break it up than to do anything else.
 *
 * \param entry is the object list entry that has a name to be formatted.
 * \param line_buffer is the buffer to format into.
 * \param size is the size of line_buffer.
 */
void object_list_format_name(const object_list_entry_t *entry,
							 char *line_buffer, size_t size)
{
	char name[80];
	const char *chunk;
	char *source;
	bool has_singular_prefix;
	bool los = false;
	int field;
	byte old_number;
	struct loc pgrid = player->grid;
	struct object *base_obj;
	struct loc grid;
	bool object_is_recognized_artifact;

	if (entry == NULL || entry->object == NULL || entry->object->kind == NULL)
		return;

	base_obj = cave->objects[entry->object->oidx];
	grid = entry->object->grid;
	object_is_recognized_artifact = object_is_known_artifact(base_obj);

	/* Hack - these don't have a prefix when there is only one, so just pad
	 * with a space. */
	switch (entry->object->kind->tval) {
		case TV_SOFT_ARMOR:
			if (object_is_recognized_artifact)
				has_singular_prefix = true;
			else if (base_obj->kind->sval == lookup_sval(TV_SOFT_ARMOR, "Robe"))
				has_singular_prefix = true;
			else
				has_singular_prefix = false;
			break;
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
			if (object_is_recognized_artifact)
				has_singular_prefix = true;
			else
				has_singular_prefix = false;
			break;
		default:
			has_singular_prefix = true;
			break;
	}

	if (entry->object->kind != base_obj->kind)
		has_singular_prefix = true;

	/* Work out if the object is in view */
	los = projectable(cave, pgrid, grid, PROJECT_NONE) || loc_eq(grid, pgrid);
	field = los ? OBJECT_LIST_SECTION_LOS : OBJECT_LIST_SECTION_NO_LOS;

	/*
	 * Because each entry points to a specific object and not something more
	 * general, the number of similar objects we counted has to be swapped in.
	 * This isn't an ideal way to do this, but it's the easiest way until
	 * object_desc is more flexible.
	 */
	old_number = entry->object->number;
	entry->object->number = entry->count[field];
	object_desc(name, sizeof(name), base_obj, ODESC_PREFIX | ODESC_FULL);
	entry->object->number = old_number;

	/* The source string for strtok() needs to be set properly, depending on
	 * when we use it. */
	if (!has_singular_prefix && entry->count[field] == 1) {
		chunk = " ";
		source = name;
	}
	else {
		chunk = strtok(name, " ");
		source = NULL;
	}

	/* Right alight the prefix and clip. */
	strnfmt(line_buffer, size, "%3.3s ", chunk);

	/* Get the rest of the name and clip it to fit the max width. */
	chunk = strtok(source, "\0");
	my_strcat(line_buffer, chunk, size);
}
Beispiel #8
0
/**
 * Read an object.
 */
static struct object *rd_item(void)
{
	struct object *obj = object_new();

	byte tmp8u;
	u16b tmp16u;
	byte effect;
	size_t i;
	char buf[128];
	byte ver = 1;

	rd_u16b(&tmp16u);
	rd_byte(&ver);
	if (tmp16u != 0xffff)
		return NULL;

	rd_u16b(&obj->oidx);

	/* Location */
	rd_byte(&obj->iy);
	rd_byte(&obj->ix);

	/* Type/Subtype */
	rd_string(buf, sizeof(buf));
	if (buf[0]) {
		obj->tval = tval_find_idx(buf);
	}
	rd_string(buf, sizeof(buf));
	if (buf[0]) {
		obj->sval = lookup_sval(obj->tval, buf);
	}
	rd_s16b(&obj->pval);

	rd_byte(&obj->number);
	rd_s16b(&obj->weight);

	rd_string(buf, sizeof(buf));
	if (buf[0]) {
		obj->artifact = lookup_artifact_name(buf);
		if (!obj->artifact) {
			note(format("Couldn't find artifact %s!", buf));
			return NULL;
		}
	}
	rd_string(buf, sizeof(buf));
	if (buf[0]) {
		obj->ego = lookup_ego_item(buf, obj->tval, obj->sval);
		if (!obj->ego) {
			note(format("Couldn't find ego item %s!", buf));
			return NULL;
		}
	}
	rd_byte(&effect);

	rd_s16b(&obj->timeout);

	rd_s16b(&obj->to_h);
	rd_s16b(&obj->to_d);
	rd_s16b(&obj->to_a);

	rd_s16b(&obj->ac);

	rd_byte(&obj->dd);
	rd_byte(&obj->ds);

	rd_byte(&obj->origin);
	rd_byte(&obj->origin_depth);
	rd_string(buf, sizeof(buf));
	if (buf[0]) {
		obj->origin_race = lookup_monster(buf);
	}
	rd_byte(&obj->notice);

	for (i = 0; i < of_size; i++)
		rd_byte(&obj->flags[i]);

	for (i = 0; i < obj_mod_max; i++) {
		rd_s16b(&obj->modifiers[i]);
	}

	/* Read brands */
	rd_byte(&tmp8u);
	if (tmp8u) {
		obj->brands = mem_zalloc(z_info->brand_max * sizeof(bool));
		for (i = 0; i < brand_max; i++) {
			rd_byte(&tmp8u);
			obj->brands[i] = tmp8u ? true : false;
		}
	}

	/* Read slays */
	rd_byte(&tmp8u);
	if (tmp8u) {
		obj->slays = mem_zalloc(z_info->slay_max * sizeof(bool));
		for (i = 0; i < slay_max; i++) {
			rd_byte(&tmp8u);
			obj->slays[i] = tmp8u ? true : false;
		}
	}

	/* Read curses */
	rd_byte(&tmp8u);
	if (tmp8u) {
		obj->curses = mem_zalloc(z_info->curse_max * sizeof(struct curse_data));
		for (i = 0; i < curse_max; i++) {
			rd_byte(&tmp8u);
			obj->curses[i].power = tmp8u;
			rd_u16b(&tmp16u);
			obj->curses[i].timeout = tmp16u;
		}
	}

	for (i = 0; i < elem_max; i++) {
		rd_s16b(&obj->el_info[i].res_level);
		rd_byte(&obj->el_info[i].flags);
	}

	/* Monster holding object */
	rd_s16b(&obj->held_m_idx);

	rd_s16b(&obj->mimicking_m_idx);

	/* Activation */
	rd_u16b(&tmp16u);
	if (tmp16u)
		obj->activation = &activations[tmp16u];
	rd_u16b(&tmp16u);
	obj->time.base = tmp16u;
	rd_u16b(&tmp16u);
	obj->time.dice = tmp16u;
	rd_u16b(&tmp16u);
	obj->time.sides = tmp16u;

	/* Save the inscription */
	rd_string(buf, sizeof(buf));
	if (buf[0]) obj->note = quark_add(buf);

	/* Lookup item kind */
	obj->kind = lookup_kind(obj->tval, obj->sval);

	/* Check we have a kind */
	if ((!obj->tval && !obj->sval) || !obj->kind) {
		object_delete(&obj);
		return NULL;
	}

	/* Set effect */
	if (effect && obj->ego)
		obj->effect = obj->ego->effect;

	if (effect && !obj->effect)
		obj->effect = obj->kind->effect;

	/* Success */
	return obj;
}