예제 #1
0
파일: wizard.c 프로젝트: mtadd/angband
/*
 * Tweak an item
 */
static void wiz_tweak_item(object_type *o_ptr)
{
	const char *p;
	char tmp_val[80];
	int i, val;

	/* Hack -- leave artifacts alone */
	if (o_ptr->artifact) return;

	p = "Enter new ego item index: ";
	strnfmt(tmp_val, sizeof(tmp_val), "0");
	if (o_ptr->ego)
		strnfmt(tmp_val, sizeof(tmp_val), "%d", o_ptr->ego->eidx);
	if (!get_string(p, tmp_val, 6)) return;
	val = atoi(tmp_val);
	if (val) {
		o_ptr->ego = &e_info[val];
		ego_apply_magic(o_ptr, p_ptr->depth);
	} else
		o_ptr->ego = 0;
	wiz_display_item(o_ptr, TRUE);

	p = "Enter new artifact index: ";
	strnfmt(tmp_val, sizeof(tmp_val), "0");
	if (o_ptr->artifact)
		strnfmt(tmp_val, sizeof(tmp_val), "%d", o_ptr->artifact->aidx);
	if (!get_string(p, tmp_val, 6)) return;
	val = atoi(tmp_val);
	if (val) {
		o_ptr->artifact = &a_info[val];
		copy_artifact_data(o_ptr, o_ptr->artifact);
	} else
		o_ptr->artifact = 0;
	wiz_display_item(o_ptr, TRUE);

#define WIZ_TWEAK(attribute) do {\
	p = "Enter new '" #attribute "' setting: ";\
	strnfmt(tmp_val, sizeof(tmp_val), "%d", o_ptr->attribute);\
	if (!get_string(p, tmp_val, 6)) return;\
	o_ptr->attribute = atoi(tmp_val);\
	wiz_display_item(o_ptr, TRUE);\
} while (0)
	for (i = 0; i < MAX_PVALS; i++) {
		WIZ_TWEAK(pval[i]);
		if (o_ptr->pval[i])
			o_ptr->num_pvals = (i + 1);
	}
	WIZ_TWEAK(to_a);
	WIZ_TWEAK(to_h);
	WIZ_TWEAK(to_d);
}
예제 #2
0
파일: wizard.c 프로젝트: mtadd/angband
/*
 * Create the artifact with the specified number
 */
static void wiz_create_artifact(int a_idx)
{
	object_type *i_ptr;
	object_type object_type_body;
	object_kind *kind;

	artifact_type *a_ptr = &a_info[a_idx];

	/* Ignore "empty" artifacts */
	if (!a_ptr->name) return;

	/* Get local object */
	i_ptr = &object_type_body;

	/* Wipe the object */
	object_wipe(i_ptr);

	/* Acquire the "kind" index */
	kind = lookup_kind(a_ptr->tval, a_ptr->sval);
	if (!kind)
		return;

	/* Create the artifact */
	object_prep(i_ptr, kind, a_ptr->alloc_min, RANDOMISE);

	/* Save the name */
	i_ptr->artifact = a_ptr;

	/* Extract the fields */
	copy_artifact_data(i_ptr, a_ptr);

	/* Mark that the artifact has been created. */
	a_ptr->created = TRUE;

	/* Mark as cheat */
	i_ptr->origin = ORIGIN_CHEAT;

	/* Drop the artifact from heaven */
	drop_near(cave, i_ptr, 0, p_ptr->py, p_ptr->px, TRUE);

	/* All done */
	msg("Allocated.");
	
	/* Redraw map */
	p_ptr->redraw |= (PR_MAP | PR_ITEMLIST);
	handle_stuff(p_ptr);
}
예제 #3
0
파일: obj-make.c 프로젝트: fizzix/angband
/**
 * Create a fake artifact directly from a blank object
 *
 * This function is used for describing artifacts, and for creating them for
 * debugging.
 *
 * Since this is now in no way marked as fake, we must make sure this function
 * is never used to create an actual game object
 */
bool make_fake_artifact(struct object *obj, const struct artifact *artifact)
{
	struct object_kind *kind;

	/* Don't bother with empty artifacts */
	if (!artifact->tval) return false;

	/* Get the "kind" index */
	kind = lookup_kind(artifact->tval, artifact->sval);
	if (!kind) return false;

	/* Create the artifact */
	object_prep(obj, kind, 0, MAXIMISE);
	obj->artifact = (struct artifact *)artifact;
	copy_artifact_data(obj, artifact);
	apply_curse_knowledge(obj);

	return (true);
}
예제 #4
0
/**
 * Create a fake artifact directly from a blank object
 *
 * This function is used for describing artifacts, and for creating them for
 * debugging.
 *
 * Since this is now in no way marked as fake, we must make sure this function
 * is never used to create an actual game object
 */
bool make_fake_artifact(struct object *obj, struct artifact *artifact)
{
	struct object_kind *kind;

	/* Don't bother with empty artifacts */
	if (!artifact->tval) return false;

	/* Get the "kind" index */
	kind = lookup_kind(artifact->tval, artifact->sval);
	if (!kind) return false;

	/* Create the artifact */
	object_prep(obj, kind, 0, MAXIMISE);

	/* Save the name */
	obj->artifact = artifact;

	/* Extract the fields */
	copy_artifact_data(obj, artifact);

	/* Success */
	return (true);
}
예제 #5
0
/*
 * Hack -- Create a "forged" artifact
 */
bool make_fake_artifact(object_type *o_ptr, struct artifact *artifact)
{
	object_kind *kind;

	/* Don't bother with empty artifacts */
	if (!artifact.tval) return false;

	/* Get the "kind" index */
	kind = lookup_kind(artifact.tval, artifact.sval);
	if (!kind) return false;

	/* Create the artifact */
	object_prep(o_ptr, kind, 0, MAXIMISE);

	/* Save the name */
	o_ptr.artifact = artifact;

	/* Extract the fields */
	copy_artifact_data(o_ptr, artifact);

	/* Success */
	o_ptr.ident |= IDENT_FAKE;
	return (true);
}
예제 #6
0
/**
 * Attempt to change an object into an artifact.  If the object is already
 * set to be an artifact, use that, or otherwise use a suitable randomly-
 * selected artifact.
 *
 * This routine should only be called by "apply_magic()"
 *
 * Note -- see "make_artifact_special()" and "apply_magic()"
 */
static bool make_artifact(struct object *obj)
{
	int i;
	bool art_ok = true;

	/* Make sure birth no artifacts isn't set */
	if (OPT(birth_no_artifacts)) art_ok = false;

	/* Special handling of quest artifacts */
	if (kf_has(obj->kind->kind_flags, KF_QUEST_ART))
		art_ok = true;

	if (!art_ok) return (false);

	/* No artifacts in the town */
	if (!player->depth) return (false);

	/* Paranoia -- no "plural" artifacts */
	if (obj->number != 1) return (false);

	/* Check the artifact list (skip the "specials") */
	for (i = 0; !obj->artifact && i < z_info->a_max; i++) {
		struct artifact *art = &a_info[i];
		struct object_kind *kind = lookup_kind(art->tval, art->sval);

		/* Skip "empty" items */
		if (!art->name) continue;

		/* Make sure the kind was found */
		if (!kind) continue;

		/* Skip special artifacts */
		if (kf_has(kind->kind_flags, KF_INSTA_ART)) continue;

		/* Cannot make an artifact twice */
		if (art->created) continue;

		/* Must have the correct fields */
		if (art->tval != obj->tval) continue;
		if (art->sval != obj->sval) continue;

		/* XXX XXX Enforce minimum "depth" (loosely) */
		if (art->alloc_min > player->depth)
		{
			/* Get the "out-of-depth factor" */
			int d = (art->alloc_min - player->depth) * 2;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Enforce maximum depth (strictly) */
		if (art->alloc_max < player->depth) continue;

		/* We must make the "rarity roll" */
		if (randint1(100) > art->alloc_prob) continue;

		/* Mark the item as an artifact */
		obj->artifact = art;
	}

	if (obj->artifact) {
		copy_artifact_data(obj, obj->artifact);
		obj->artifact->created = true;
		return true;
	}

	return false;
}
예제 #7
0
/**
 * Mega-Hack -- Attempt to create one of the "Special Objects".
 *
 * We are only called from "make_object()"
 *
 * Note -- see "make_artifact()" and "apply_magic()".
 *
 * We *prefer* to create the special artifacts in order, but this is
 * normally outweighed by the "rarity" rolls for those artifacts.
 */
static struct object *make_artifact_special(int level)
{
	int i;
	struct object *new_obj;

	/* No artifacts, do nothing */
	if (OPT(birth_no_artifacts))
		return NULL;

	/* No artifacts in the town */
	if (!player->depth)
		return NULL;

	/* Check the special artifacts */
	for (i = 0; i < z_info->a_max; ++i) {
		struct artifact *art = &a_info[i];
		struct object_kind *kind = lookup_kind(art->tval, art->sval);

		/* Skip "empty" artifacts */
		if (!art->name) continue;

		/* Make sure the kind was found */
		if (!kind) continue;

		/* Skip non-special artifacts */
		if (!kf_has(kind->kind_flags, KF_INSTA_ART)) continue;

		/* Cannot make an artifact twice */
		if (art->created) continue;

		/* Enforce minimum "depth" (loosely) */
		if (art->alloc_min > player->depth) {
			/* Get the "out-of-depth factor" */
			int d = (art->alloc_min - player->depth) * 2;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Enforce maximum depth (strictly) */
		if (art->alloc_max < player->depth) continue;

		/* Artifact "rarity roll" */
		if (randint1(100) > art->alloc_prob) continue;

		/* Enforce minimum "object" level (loosely) */
		if (kind->level > level) {
			/* Get the "out-of-depth factor" */
			int d = (kind->level - level) * 5;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Assign the template */
		new_obj = object_new();
		object_prep(new_obj, kind, art->alloc_min, RANDOMISE);

		/* Mark the item as an artifact */
		new_obj->artifact = art;

		/* Copy across all the data from the artifact struct */
		copy_artifact_data(new_obj, art);

		/* Mark the artifact as "created" */
		art->created = true;

		/* Success */
		return new_obj;
	}

	/* Failure */
	return NULL;
}
예제 #8
0
파일: obj-make.c 프로젝트: Dasaan/angband
/*
 * Attempt to change an object into an artifact.  If the object is already
 * set to be an artifact, use that, or otherwise use a suitable randomly-
 * selected artifact.
 *
 * This routine should only be called by "apply_magic()"
 *
 * Note -- see "make_artifact_special()" and "apply_magic()"
 */
static bool make_artifact(object_type *o_ptr)
{
	artifact_type *a_ptr;
	int i;
	bool art_ok = TRUE;

	/* Make sure birth no artifacts isn't set */
	if (OPT(birth_no_artifacts)) art_ok = FALSE;

	/* Special handling of Grond/Morgoth */
	if (o_ptr->artifact)
	{
		switch (o_ptr->artifact->aidx)
		{
			case ART_GROND:
			case ART_MORGOTH:
				art_ok = TRUE;
		}
	}

	if (!art_ok) return (FALSE);

	/* No artifacts in the town */
	if (!p_ptr->depth) return (FALSE);

	/* Paranoia -- no "plural" artifacts */
	if (o_ptr->number != 1) return (FALSE);

	/* Check the artifact list (skip the "specials") */
	for (i = ART_MIN_NORMAL; !o_ptr->artifact && i < z_info->a_max; i++) {
		a_ptr = &a_info[i];

		/* Skip "empty" items */
		if (!a_ptr->name) continue;

		/* Cannot make an artifact twice */
		if (a_ptr->created) continue;

		/* Must have the correct fields */
		if (a_ptr->tval != o_ptr->tval) continue;
		if (a_ptr->sval != o_ptr->sval) continue;

		/* XXX XXX Enforce minimum "depth" (loosely) */
		if (a_ptr->alloc_min > p_ptr->depth)
		{
			/* Get the "out-of-depth factor" */
			int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Enforce maximum depth (strictly) */
		if (a_ptr->alloc_max < p_ptr->depth) continue;

		/* We must make the "rarity roll" */
		if (randint1(100) > a_ptr->alloc_prob) continue;

		/* Mark the item as an artifact */
		o_ptr->artifact = a_ptr;
	}

	if (o_ptr->artifact) {
		copy_artifact_data(o_ptr, o_ptr->artifact);
		o_ptr->artifact->created = 1;
		return TRUE;
	}

	return FALSE;
}
예제 #9
0
파일: obj-make.c 프로젝트: Dasaan/angband
/*
 * Mega-Hack -- Attempt to create one of the "Special Objects".
 *
 * We are only called from "make_object()"
 *
 * Note -- see "make_artifact()" and "apply_magic()".
 *
 * We *prefer* to create the special artifacts in order, but this is
 * normally outweighed by the "rarity" rolls for those artifacts.
 */
static bool make_artifact_special(object_type *o_ptr, int level)
{
	int i;
	object_kind *kind;

	/* No artifacts, do nothing */
	if (OPT(birth_no_artifacts)) return FALSE;

	/* No artifacts in the town */
	if (!p_ptr->depth) return FALSE;

	/* Check the special artifacts */
	for (i = 0; i < ART_MIN_NORMAL; ++i) {
		artifact_type *a_ptr = &a_info[i];

		/* Skip "empty" artifacts */
		if (!a_ptr->name) continue;

		/* Cannot make an artifact twice */
		if (a_ptr->created) continue;

		/* Enforce minimum "depth" (loosely) */
		if (a_ptr->alloc_min > p_ptr->depth) {
			/* Get the "out-of-depth factor" */
			int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Enforce maximum depth (strictly) */
		if (a_ptr->alloc_max < p_ptr->depth) continue;

		/* Artifact "rarity roll" */
		if (randint1(100) > a_ptr->alloc_prob) continue;

		/* Find the base object */
		kind = lookup_kind(a_ptr->tval, a_ptr->sval);

		/* Make sure the kind was found */
		if (!kind) continue;

		/* Enforce minimum "object" level (loosely) */
		if (kind->level > level) {
			/* Get the "out-of-depth factor" */
			int d = (kind->level - level) * 5;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Assign the template */
		object_prep(o_ptr, kind, a_ptr->alloc_min, RANDOMISE);

		/* Mark the item as an artifact */
		o_ptr->artifact = a_ptr;

		/* Copy across all the data from the artifact struct */
		copy_artifact_data(o_ptr, a_ptr);

		/* Mark the artifact as "created" */
		a_ptr->created = 1;

		/* Success */
		return TRUE;
	}

	/* Failure */
	return FALSE;
}
예제 #10
0
/**
 * Creates a specific monster's drop, including any drops specified
 * in the monster.txt file.
 *
 * Returns true if anything is created, false if nothing is.
 */
static bool mon_create_drop(struct chunk *c, struct monster *mon, byte origin)
{
	struct monster_drop *drop;

	bool great, good, gold_ok, item_ok;
    bool extra_roll = false;
	bool any = false;

	int number = 0, level, j, monlevel;

	struct object *obj;

	assert(mon);

	great = (rf_has(mon->race->flags, RF_DROP_GREAT));
	good = great || (rf_has(mon->race->flags, RF_DROP_GOOD));
	gold_ok = (!rf_has(mon->race->flags, RF_ONLY_ITEM));
	item_ok = (!rf_has(mon->race->flags, RF_ONLY_GOLD));

	/* Determine how much we can drop */
	number = mon_create_drop_count(mon->race, false);

    /* Give added bonus for unique monters */
    monlevel = mon->race->level;
    if (rf_has(mon->race->flags, RF_UNIQUE)) {
        monlevel = MIN(monlevel + 15, monlevel * 2);
        extra_roll = true;
    }

	/* Take the best of (average of monster level and current depth)
	   and (monster level) - to reward fighting OOD monsters */
	level = MAX((monlevel + player->depth) / 2, monlevel);
    level = MIN(level, 100);

	/* Morgoth currently drops all artifacts with the QUEST_ART flag */
	if (rf_has(mon->race->flags, RF_QUESTOR) && (mon->race->level == 100)) {
		/* Search all the artifacts */
		for (j = 1; j < z_info->a_max; j++) {
			struct artifact *art = &a_info[j];
			struct object_kind *kind = lookup_kind(art->tval, art->sval);
			if (!kf_has(kind->kind_flags, KF_QUEST_ART)) {
				continue;
			}

			/* Allocate by hand, prep, apply magic */
			obj = mem_zalloc(sizeof(*obj));
			object_prep(obj, kind, 100, RANDOMISE);
			obj->artifact = art;
			copy_artifact_data(obj, obj->artifact);
			obj->artifact->created = true;

			/* Set origin details */
			obj->origin = origin;
			obj->origin_depth = player->depth;
			obj->origin_race = mon->race;
			obj->number = 1;

			/* Try to carry */
			if (monster_carry(c, mon, obj)) {
				any = true;
			} else {
				obj->artifact->created = false;
				object_wipe(obj);
				mem_free(obj);
			}
		}
	}

	/* Specified drops */
	for (drop = mon->race->drops; drop; drop = drop->next) {
		if ((unsigned int)randint0(100) >= drop->percent_chance)
			continue;

		/* Allocate by hand, prep, apply magic */
		obj = mem_zalloc(sizeof(*obj));
		object_prep(obj, drop->kind, level, RANDOMISE);
		apply_magic(obj, level, true, good, great, extra_roll);

		/* Set origin details */
		obj->origin = origin;
		obj->origin_depth = player->depth;
		obj->origin_race = mon->race;
		obj->number = randint0(drop->max - drop->min) + drop->min;

		/* Try to carry */
		if (monster_carry(c, mon, obj)) {
			any = true;
		} else {
			object_wipe(obj);
			mem_free(obj);
		}
	}

	/* Make some objects */
	for (j = 0; j < number; j++) {
		if (gold_ok && (!item_ok || (randint0(100) < 50))) {
			obj = make_gold(level, "any");
		} else {
			obj = make_object(c, level, good, great, extra_roll, NULL, 0);
			if (!obj) continue;
		}

		/* Set origin details */
		obj->origin = origin;
		obj->origin_depth = player->depth;
		obj->origin_race = mon->race;

		/* Try to carry */
		if (monster_carry(c, mon, obj)) {
			any = true;
		} else {
			obj->artifact->created = false;
			object_wipe(obj);
			mem_free(obj);
		}
	}

	return any;
}
예제 #11
0
/*
 * Attempt to change an object into an artifact.  If the object's name1
 * is already set, use that artifact.  Otherwise, look for a suitable
 * artifact and attempt to use it.
 *
 * This routine should only be called by "apply_magic()"
 *
 * Note -- see "make_artifact_special()" and "apply_magic()"
 */
static bool make_artifact(object_type *o_ptr)
{
	artifact_type *a_ptr;
	int i;


	/* No artifacts, do nothing */
	if (OPT(birth_no_artifacts) &&
	    o_ptr->name1 != ART_GROND &&
	    o_ptr->name1 != ART_MORGOTH)
		return (FALSE);

	/* No artifacts in the town */
	/* Commenting this out because I don't understand the reasoning behind it -Simon */
	//if (!p_ptr->depth) return (FALSE);

	/* Paranoia -- no "plural" artifacts */
	if (o_ptr->number != 1) return (FALSE);

	/* Check the artifact list (skip the "specials") */
	for (i = ART_MIN_NORMAL; !o_ptr->name1 && i < z_info->a_max; i++)
	{
		a_ptr = &a_info[i];

		/* Skip "empty" items */
		if (!a_ptr->name) continue;

		/* Cannot make an artifact twice */
		if (a_ptr->created) continue;

		/* Must have the correct fields */
		if (a_ptr->tval != o_ptr->tval) continue;
		if (a_ptr->sval != o_ptr->sval) continue;

		/* XXX XXX Enforce minimum "depth" (loosely) */
		if (a_ptr->alloc_min > p_ptr->depth)
		{
			/* Get the "out-of-depth factor" */
			int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}

		/* Enforce maximum depth (strictly) */
		if (a_ptr->alloc_max < p_ptr->depth) continue;

		/* We must make the "rarity roll" */
		if (randint1(100) > a_ptr->alloc_prob) continue;

		/* Mark the item as an artifact */
		o_ptr->name1 = i;
	}

	if (o_ptr->name1)
	{
		a_ptr = &a_info[o_ptr->name1];

		/* Copy across all the data from the artifact struct */
		copy_artifact_data(o_ptr, a_ptr);

		/* Mark the artifact as "created" */
		a_ptr->created = 1;

		return TRUE;
	}

	return FALSE;
}
예제 #12
0
파일: mon-make.c 프로젝트: seebs/angband
/**
 * Creates a specific monster's drop, including any drops specified
 * in the monster.txt file.
 *
 * Returns TRUE if anything is created, FALSE if nothing is.
 */
static bool mon_create_drop(struct monster *m_ptr, byte origin)
{
	struct monster_drop *drop;

	bool great, good, gold_ok, item_ok;
    bool extra_roll = FALSE;
	bool any = FALSE;

	int number = 0, level, j, monlevel;

	object_type *i_ptr;
	object_type object_type_body;
	
	assert(m_ptr);

	great = (rf_has(m_ptr->race->flags, RF_DROP_GREAT));
	good = great || (rf_has(m_ptr->race->flags, RF_DROP_GOOD));
	gold_ok = (!rf_has(m_ptr->race->flags, RF_ONLY_ITEM));
	item_ok = (!rf_has(m_ptr->race->flags, RF_ONLY_GOLD));

	/* Determine how much we can drop */
	if (rf_has(m_ptr->race->flags, RF_DROP_20) && randint0(100) < 20) number++;
	if (rf_has(m_ptr->race->flags, RF_DROP_40) && randint0(100) < 40) number++;
	if (rf_has(m_ptr->race->flags, RF_DROP_60) && randint0(100) < 60) number++;
	if (rf_has(m_ptr->race->flags, RF_DROP_4)) number += rand_range(2, 6);
	if (rf_has(m_ptr->race->flags, RF_DROP_3)) number += rand_range(2, 4);
	if (rf_has(m_ptr->race->flags, RF_DROP_2)) number += rand_range(1, 3);
	if (rf_has(m_ptr->race->flags, RF_DROP_1)) number++;

    /* Give added bonus for unique monters */
    monlevel = m_ptr->race->level;
    if (rf_has(m_ptr->race->flags, RF_UNIQUE)){
        monlevel = MIN(monlevel + 15, monlevel * 2);
        extra_roll = TRUE;
    }
    
	/* Take the best of (average of monster level and current depth)
	   and (monster level) - to reward fighting OOD monsters */
	level = MAX((monlevel + p_ptr->depth) / 2, monlevel);
    level = MIN(level, 100);

	/* Specified drops */
	for (drop = m_ptr->race->drops; drop; drop = drop->next) {
		if ((unsigned int)randint0(100) >= drop->percent_chance)
			continue;

		i_ptr = &object_type_body;
		if (drop->artifact) {
			object_prep(i_ptr, objkind_get(drop->artifact->tval,
				drop->artifact->sval), level, RANDOMISE);
			i_ptr->artifact = drop->artifact;
			copy_artifact_data(i_ptr, i_ptr->artifact);
			i_ptr->artifact->created = 1;
		} else {
			object_prep(i_ptr, drop->kind, level, RANDOMISE);
			apply_magic(i_ptr, level, TRUE, good, great, extra_roll);
		}

		i_ptr->origin = origin;
		i_ptr->origin_depth = p_ptr->depth;
		i_ptr->origin_xtra = m_ptr->race->ridx;
		i_ptr->number = randint0(drop->max - drop->min) + drop->min;
		if (monster_carry(m_ptr, i_ptr))
			any = TRUE;
	}

	/* Make some objects */
	for (j = 0; j < number; j++) {
		i_ptr = &object_type_body;
		object_wipe(i_ptr);

		if (gold_ok && (!item_ok || (randint0(100) < 50))) {
			make_gold(i_ptr, level, SV_GOLD_ANY);
		} else {
			if (!make_object(cave, i_ptr, level, good,
                great, extra_roll, NULL, 0)) continue;
		}

		i_ptr->origin = origin;
		i_ptr->origin_depth = p_ptr->depth;
		i_ptr->origin_xtra = m_ptr->race->ridx;
		if (monster_carry(m_ptr, i_ptr))
			any = TRUE;
	}

	return any;
}
예제 #13
0
파일: obj-make.c 프로젝트: nomadicwriter/v4
/**
 * Attempt to create an artifact.  If the object is already set to be an
 * artifact, use that. If the object kind is already set, check only artifacts
 * for that kind.
 *
 * \param o_ptr is the object to turn into an artifact
 * \param level is the effective creation level
 */
static bool make_artifact(object_type *o_ptr, int level)
{
	int i, j, basemin = 0, basemax = 0, success = 0, entry = 0;
	long total = 0L;
	bool art_ok = TRUE;
	object_kind *kind;
	alloc_entry *table;
	artifact_type *a_ptr = NULL;

	/* Make sure birth no artifacts isn't set */
	if (OPT(birth_no_artifacts)) art_ok = FALSE;

	/* Special handling of quest artifacts - these override the birth option */
	if (o_ptr->artifact) {
		switch (o_ptr->artifact->aidx) {
			case ART_GROND:
			case ART_MORGOTH:
				art_ok = TRUE;
		}
	}

	if (!art_ok) return FALSE;

	/* No artifacts in the town */
	if (!p_ptr->depth) return FALSE;

	/* Create the allocation table from allowed artifacts
	   TODO: initialise it once at init and then restrict it here */
	table = C_ZNEW(z_info->a_max, alloc_entry);

	for (i = 0; !o_ptr->artifact && i < z_info->a_max; i++) {
		a_ptr = &a_info[i];

		/* Skip non-existent entries */
		if (!a_ptr->name || !a_ptr->alloc_prob[0]) continue;

		/* Cannot make an artifact twice */
		if (a_ptr->created) continue;

		/* Find the base object if we don't already have one */
		if (!o_ptr->kind) {
			kind = lookup_kind(a_ptr->tval, a_ptr->sval);

			/* Make sure we now have a base object kind */
			if (!kind) continue;

			basemin = kind->alloc_min;
			basemax = kind->alloc_max;
		} else { /* If we do have a kind, it must match */
			if (a_ptr->tval != o_ptr->tval || a_ptr->sval != o_ptr->sval)
				continue;
			basemin = o_ptr->kind->alloc_min;
			basemax = o_ptr->kind->alloc_max;
		}

		/* Enforce minimum base object level (loosely) */
		if (basemin > level) {
			/* Get the out-of-depth factor */
			int d = (basemin - level) * 3;

			/* Roll for out-of-depth creation */
			if (randint0(d) != 0) continue;
		}
		/* Enforce maximum base object level (strictly) */
		if (basemax && basemax < p_ptr->depth) continue;

		for (j = 0; j < ART_ALLOC_MAX && a_ptr->alloc_prob[j]; j++) {
			/* Enforce minimum depth (loosely) */
			if (a_ptr->alloc_min[j] > level) {
				/* Get the out-of-depth factor */
				int d = (a_ptr->alloc_min[j] - level) * 2;

				/* Roll for out-of-depth creation */
				if (randint0(d) != 0) continue;
			}

			/* Enforce maximum depth (strictly) */
			if (a_ptr->alloc_max[j] < p_ptr->depth) continue;

			/* Looks good - add this artifact to the table */
			table[entry].index = a_ptr->aidx;
			table[entry++].prob3 = a_ptr->alloc_prob[j];
			total += a_ptr->alloc_prob[j];
		}
	}

	/* Choose an artifact from the table, then free it */
	if (!o_ptr->artifact) {
		success = table_pick(total, entry, table);
		if (success > 0) {
			a_ptr = &a_info[success];
			o_ptr->artifact = a_ptr;
		}
	}
	mem_free(table);

	if (o_ptr->artifact) {
		/* If we haven't got a base object yet, do it now */
		if (!o_ptr->kind) {
			kind = lookup_kind(a_ptr->tval, a_ptr->sval);

			/* Make sure we now have a base object kind */
			if (!kind) return FALSE;

			object_prep(o_ptr, kind, level, RANDOMISE);
			o_ptr->artifact = a_ptr;
		}
		/* Paranoia -- no artifact stacks (yet) */
		if (o_ptr->number != 1) return FALSE;

		/* Actually make the object into the chosen artifact */
		copy_artifact_data(o_ptr, o_ptr->artifact);
		o_ptr->artifact->created = 1;
		return TRUE;
	}
	/* We didn't manage to select a legal artifact */
	return FALSE;
}