예제 #1
0
파일: obj-make.c 프로젝트: Dasaan/angband
/**
 * Wipe an object clean and make it a standard object of the specified kind.
 */
void object_prep(object_type *o_ptr, struct object_kind *k, int lev,
		aspect rand_aspect)
{
	int i, flag, pval;
	bitflag flags[OF_SIZE], f2[OF_SIZE];

	/* Clean slate */
	WIPE(o_ptr, object_type);

	/* Assign the kind and copy across data */
	o_ptr->kind = k;
	o_ptr->tval = k->tval;
	o_ptr->sval = k->sval;
	o_ptr->ac = k->ac;
	o_ptr->dd = k->dd;
	o_ptr->ds = k->ds;
	o_ptr->weight = k->weight;

	/* Default number */
	o_ptr->number = 1;

	/* Apply pvals and then copy flags */
	of_copy(f2, k->flags);
    for (i = 0; i < k->num_pvals; i++) {
        of_copy(flags, k->pval_flags[i]);
        pval = randcalc(k->pval[i], lev, rand_aspect);
        for (flag = of_next(flags, FLAG_START); flag != FLAG_END;
                flag = of_next(flags, flag + 1))
			/* Prevent phantom flags */
			if (pval)
				object_add_pval(o_ptr, pval, flag);
			else
				of_off(f2, flag);
    }
	of_copy(o_ptr->flags, k->base->flags);
	of_union(o_ptr->flags, f2);

	/* Assign charges (wands/staves only) */
	if (o_ptr->tval == TV_WAND || o_ptr->tval == TV_STAFF)
		o_ptr->pval[DEFAULT_PVAL] = randcalc(k->charge, lev, rand_aspect);

	/* Assign flagless pval for food or oil */
	if (o_ptr->tval == TV_FOOD || o_ptr->tval == TV_POTION ||
			o_ptr->tval == TV_FLASK)
		o_ptr->pval[DEFAULT_PVAL]
			= randcalc(k->pval[DEFAULT_PVAL], lev, rand_aspect);

	/* Default fuel for lamps */
	if (o_ptr->tval == TV_LIGHT) {
		if (o_ptr->sval == SV_LIGHT_TORCH)
			o_ptr->timeout = DEFAULT_TORCH;
		else if (o_ptr->sval == SV_LIGHT_LANTERN)
			o_ptr->timeout = DEFAULT_LAMP;
	}

	/* Default magic */
	o_ptr->to_h = randcalc(k->to_h, lev, rand_aspect);
	o_ptr->to_d = randcalc(k->to_d, lev, rand_aspect);
	o_ptr->to_a = randcalc(k->to_a, lev, rand_aspect);
}
예제 #2
0
/**
 * Create a cache of slay combinations found on ego items, and the values of
 * these combinations. This is to speed up slay_power(), which will be called
 * many times for ego items during the game.
 *
 * \param items is the set of ego types from which we are extracting slay
 * combinations
 */
errr create_slay_cache(struct ego_item *items)
{
    int i;
    int j;
    int count = 0;
    bitflag cacheme[OF_SIZE];
    bitflag slay_mask[OF_SIZE];
    bitflag **dupcheck;
    ego_item_type *e_ptr;

    /* Build the slay mask */
	create_mask(slay_mask, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);

    /* Calculate necessary size of slay_cache */
    dupcheck = C_ZNEW(z_info->e_max, bitflag *);

    for (i = 0; i < z_info->e_max; i++) {
        dupcheck[i] = C_ZNEW(OF_SIZE, bitflag);
        e_ptr = items + i;

        /* Find the slay flags on this ego */
        of_copy(cacheme, e_ptr->flags);
        of_inter(cacheme, slay_mask);

        /* Only consider non-empty combinations of slay flags */
        if (!of_is_empty(cacheme)) {
            /* Skip previously scanned combinations */
            for (j = 0; j < i; j++)
                if (of_is_equal(cacheme, dupcheck[j])) continue;

            /* msg("Found a new slay combo on an ego item"); */
            count++;
            of_copy(dupcheck[i], cacheme);
        }
    }

    /* Allocate slay_cache with an extra empty element for an iteration stop */
    slay_cache = C_ZNEW((count + 1), struct flag_cache);
    count = 0;

    /* Populate the slay_cache */
    for (i = 0; i < z_info->e_max; i++) {
        if (!of_is_empty(dupcheck[i])) {
            of_copy(slay_cache[count].flags, dupcheck[i]);
            slay_cache[count].value = 0;
            count++;
            /*msg("Cached a slay combination");*/
        }
    }

    for (i = 0; i < z_info->e_max; i++)
        FREE(dupcheck[i]);
    FREE(dupcheck);

    /* Success */
    return 0;
}
예제 #3
0
/**
 * Match slays in flags against a chosen flag mask
 *
 * count is the number of matches
 * \param flags is the flagset to analyse for matches
 * \param mask is the flagset against which to test
 * \param desc is the array of descriptions of matching slays - can be null
 * \param brand is the array of descriptions of brands - can be null
 * \param mult is the array of multipliers of those slays - can be null
 * \param dedup is whether or not to remove duplicates
 *
 * desc[], brand[] and mult[] must be >= SL_MAX in size
 */
int list_slays(const bitflag flags[OF_SIZE], const bitflag mask[OF_SIZE],
	const char *desc[], const char *brand[], int mult[], bool dedup)
{
	int i, count = 0;
	bitflag f[OF_SIZE];

	/* We are only interested in the flags specified in mask */
	of_copy(f, flags);
	of_inter(f, mask);

	/* Remove "duplicate" flags if desired */
	if (dedup) dedup_slays(f);

	/* Collect slays */
	for (i = 0; i < SL_MAX; i++) {
		const struct slay *s_ptr = &slay_table[i];
		if (of_has(f, s_ptr->object_flag)) {
			if (mult)
				mult[count] = s_ptr->mult;
			if (brand)
				brand[count] = s_ptr->brand;
			if (desc)
				desc[count] = s_ptr->desc;
			count++;
		}
	}

	return count;
}
예제 #4
0
파일: obj-make.c 프로젝트: nomadicwriter/v4
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	int i;

	/* Extract the data */
	for (i = 0; i < a_ptr->num_pvals; i++)
		if (a_ptr->pval[i]) {
			o_ptr->pval[i] = a_ptr->pval[i];
			of_copy(o_ptr->pval_flags[i], a_ptr->pval_flags[i]);
		}
	o_ptr->num_pvals = a_ptr->num_pvals;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;
	of_union(o_ptr->flags, a_ptr->flags);

    /* Set the prefix or suffix, if the artifact has an affix */
	if (a_ptr->affix && affix_is_prefix(a_ptr->affix->eidx))
		o_ptr->prefix = a_ptr->affix;

	if (a_ptr->affix && affix_is_suffix(a_ptr->affix->eidx))
		o_ptr->suffix = a_ptr->affix;

	/* Set the theme, if it has one */
	if (a_ptr->theme)
		o_ptr->theme = a_ptr->theme;
}
예제 #5
0
/*
 * Create the artifact with the specified number
 */
static void wiz_create_artifact(int a_idx)
{
	object_type *i_ptr;
	object_type object_type_body;
	int k_idx;

	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 */
	k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);

	/* Oops */
	if (!k_idx) return;

	/* Create the artifact */
	object_prep(i_ptr, &k_info[k_idx], a_ptr->alloc_min, RANDOMISE);

	/* Save the name */
	i_ptr->name1 = a_idx;

	/* Extract the fields */
	i_ptr->pval = a_ptr->pval;
	i_ptr->ac = a_ptr->ac;
	i_ptr->dd = a_ptr->dd;
	i_ptr->ds = a_ptr->ds;
	i_ptr->to_a = a_ptr->to_a;
	i_ptr->to_h = a_ptr->to_h;
	i_ptr->to_d = a_ptr->to_d;
	i_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];
		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(i_ptr->flags, curse_flags);
	}

	/* 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(i_ptr, 0, p_ptr->py, p_ptr->px, TRUE);

	/* All done */
	msg_print("Allocated.");
}
예제 #6
0
/**
 * Known is true when the "attributes" of an object are "known".
 * These include tohit, todam, toac, cost, and pval (charges, bonuses, etc.).
 *
 * Note that "knowing" an object gives you everything that an "awareness"
 * gives you, and much more.  In fact, the player is always "aware" of any
 * item of which he has full "knowledge".
 *
 * This routine also removes any inscriptions generated by "feelings".
 */
void object_known(object_type * o_ptr)
{
    artifact_type *a_ptr = artifact_of(o_ptr);

    /* Forget the feeling */
    o_ptr->feel = FEEL_NONE;

    /* Clear the "Felt" info */
    o_ptr->ident &= ~(IDENT_SENSE);

    /* Clear the "Empty" info */
    o_ptr->ident &= ~(IDENT_EMPTY);

    /* Now we know about the item */
    o_ptr->ident |= (IDENT_KNOWN);

    /* ID knowledge is better than wearing knowledge */
    o_ptr->ident |= (IDENT_WORN);

    /* Artifact has now been seen */
    if (a_ptr)
    {
	history_add_artifact(o_ptr->name1, TRUE, TRUE);
    }

    /* Get all the id flags */
    of_copy(o_ptr->id_obj, o_ptr->flags_obj);
    flags_other(o_ptr, o_ptr->id_other);
}
예제 #7
0
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	/* Extract the other fields */
	o_ptr->pval = a_ptr->pval;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];

		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(o_ptr->flags, curse_flags);
	}

	/* Mega-Hack -- increase the level rating
	 * - a sizeable increase for any artifact (c.f. up to 30 for ego items)
	 * - a bigger increase for more powerful artifacts
	 */
	rating += 30;
	rating += object_power(o_ptr, FALSE, NULL, TRUE) / 25;

	/* Set the good item flag */
	good_item_flag = TRUE;

	/* Cheat -- peek at the item */
	if (OPT(cheat_peek)) object_mention(o_ptr);
}
예제 #8
0
/*
 * Describe miscellaneous powers.
 */
static bool describe_misc_magic(textblock * tb, const object_type * o_ptr,
								oinfo_detail_t mode)
{
	bool full = mode & OINFO_FULL;
	size_t i;
	bool printed = FALSE;
	bitflag objflags[OF_SIZE];

	of_wipe(objflags);
	of_copy(objflags, o_ptr->flags_obj);
	if (!full)
		of_inter(objflags, o_ptr->id_obj);


	for (i = 0; i < N_ELEMENTS(misc_flags); i++) {
		if (of_has(objflags, misc_flags[i].flag)) {
			if (!printed)
				textblock_append(tb, "\nPowers:  ");
			textblock_append(tb, "%s. ", misc_flags[i].name);
			printed = TRUE;
		}
	}

	if (printed)
		textblock_append(tb, "\n");

	return printed;
}
예제 #9
0
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
static void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	/* Extract the other fields */
	o_ptr->pval = a_ptr->pval;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;

	/* Hack -- extract the "cursed" flags */
	if (cursed_p(a_ptr))
	{
		bitflag curse_flags[OF_SIZE];

		of_copy(curse_flags, a_ptr->flags);
		flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
		of_union(o_ptr->flags, curse_flags);
	}

	/* Mega-Hack -- increase the rating */
	rating += 10;

	/* Mega-Hack -- increase the rating again */
	if (a_ptr->cost > 50000L) rating += 10;

	/* Set the good item flag */
	good_item_flag = TRUE;

	/* Cheat -- peek at the item */
	if (OPT(cheat_peek)) object_mention(o_ptr);
}
예제 #10
0
/**
 * Prepare an object based on an object kind.
 */
void object_prep(object_type * o_ptr, int k_idx, aspect rand_aspect)
{
    int i;

    object_kind *k_ptr = &k_info[k_idx];

    /* Clear the record */
    (void) WIPE(o_ptr, object_type);

    /* Save the kind  */
    o_ptr->k_idx = k_idx;
    o_ptr->kind = k_ptr;

    /* Efficiency -- tval/sval */
    o_ptr->tval = k_ptr->tval;
    o_ptr->sval = k_ptr->sval;

    /* Default "pval" */
    o_ptr->pval = randcalc(k_ptr->pval, k_ptr->level, rand_aspect);

    /* Default number */
    o_ptr->number = 1;

    /* Default weight */
    o_ptr->weight = k_ptr->weight;

    /* Default magic */
    o_ptr->to_h = randcalc(k_ptr->to_h, k_ptr->level, rand_aspect);
    o_ptr->to_d = randcalc(k_ptr->to_d, k_ptr->level, rand_aspect);
    o_ptr->to_a = randcalc(k_ptr->to_a, k_ptr->level, rand_aspect);

    /* Default power */
    o_ptr->ac = k_ptr->ac;
    o_ptr->dd = k_ptr->dd;
    o_ptr->ds = k_ptr->ds;

    /* Default effect and time */
    o_ptr->effect = k_ptr->effect;
    o_ptr->time = k_ptr->time;

    /* Default flags */
    of_copy(o_ptr->flags_obj, k_ptr->flags_obj);
    cf_copy(o_ptr->flags_curse, k_ptr->flags_curse);

    /* Default resists, bonuses, multiples */
    for (i = 0; i < MAX_P_RES; i++)
	o_ptr->percent_res[i] = k_ptr->percent_res[i];
    for (i = 0; i < A_MAX; i++)
	o_ptr->bonus_stat[i] = k_ptr->bonus_stat[i];
    for (i = 0; i < MAX_P_BONUS; i++)
	o_ptr->bonus_other[i] = k_ptr->bonus_other[i];
    for (i = 0; i < MAX_P_SLAY; i++)
	o_ptr->multiple_slay[i] = k_ptr->multiple_slay[i];
    for (i = 0; i < MAX_P_BRAND; i++)
	o_ptr->multiple_brand[i] = k_ptr->multiple_brand[i];
}
예제 #11
0
/**
 * Remove the "bad" spells from a spell list
 */
static void remove_bad_spells(struct monster *mon, bitflag f[RSF_SIZE])
{
	bitflag f2[RSF_SIZE], ai_flags[OF_SIZE], ai_pflags[PF_SIZE];
	struct element_info el[ELEM_MAX];

	bool know_something = false;

	/* Stupid monsters act randomly */
	if (rf_has(mon->race->flags, RF_STUPID)) return;

	/* Take working copy of spell flags */
	rsf_copy(f2, f);

	/* Don't heal if full */
	if (mon->hp >= mon->maxhp) rsf_off(f2, RSF_HEAL);
	
	/* Don't haste if hasted with time remaining */
	if (mon->m_timed[MON_TMD_FAST] > 10) rsf_off(f2, RSF_HASTE);

	/* Don't teleport to if the player is already next to us */
	if (mon->cdis == 1) rsf_off(f2, RSF_TELE_TO);

	/* Update acquired knowledge */
	of_wipe(ai_flags);
	pf_wipe(ai_pflags);
	if (OPT(birth_ai_learn)) {
		size_t i;

		/* Occasionally forget player status */
		if (one_in_(100)) {
			of_wipe(mon->known_pstate.flags);
			pf_wipe(mon->known_pstate.pflags);
			for (i = 0; i < ELEM_MAX; i++)
				mon->known_pstate.el_info[i].res_level = 0;
		}

		/* Use the memorized info */
		of_copy(ai_flags, mon->known_pstate.flags);
		pf_copy(ai_pflags, mon->known_pstate.pflags);
		if (!of_is_empty(ai_flags) || !pf_is_empty(ai_pflags))
			know_something = true;

		for (i = 0; i < ELEM_MAX; i++) {
			el[i].res_level = mon->known_pstate.el_info[i].res_level;
			if (el[i].res_level != 0)
				know_something = true;
		}
	}

	/* Cancel out certain flags based on knowledge */
	if (know_something)
		unset_spells(f2, ai_flags, ai_pflags, el, mon->race);

	/* use working copy of spell flags */
	rsf_copy(f, f2);
}
예제 #12
0
파일: obj-make.c 프로젝트: Dasaan/angband
/**
 * Apply generation magic to an ego-item.
 */
void ego_apply_magic(object_type *o_ptr, int level)
{
	int i, flag, x;

	bitflag flags[OF_SIZE], newf[OF_SIZE], f2[OF_SIZE];
	object_flags(o_ptr, flags);

	/* Extra powers */
	if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_SUSTAIN)
		create_mask(newf, FALSE, OFT_SUST, OFT_MAX);
	else if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_RESIST)
		create_mask(newf, FALSE, OFT_HRES, OFT_MAX);
	else if (o_ptr->ego->xtra == OBJECT_XTRA_TYPE_POWER)
		create_mask(newf, FALSE, OFT_PROT, OFT_MISC, OFT_MAX);

	if (o_ptr->ego->xtra)
		of_on(o_ptr->flags, get_new_attr(flags, newf));

	/* Apply extra o_ptr->ego bonuses */
	o_ptr->to_h += randcalc(o_ptr->ego->to_h, level, RANDOMISE);
	o_ptr->to_d += randcalc(o_ptr->ego->to_d, level, RANDOMISE);
	o_ptr->to_a += randcalc(o_ptr->ego->to_a, level, RANDOMISE);

	/* Apply pvals */
	of_copy(f2, o_ptr->ego->flags);
	for (i = 0; i < o_ptr->ego->num_pvals; i++) {
		of_copy(flags, o_ptr->ego->pval_flags[i]);
		x = randcalc(o_ptr->ego->pval[i], level, RANDOMISE);
		for (flag = of_next(flags, FLAG_START); flag != FLAG_END;
				flag = of_next(flags, flag + 1))
			/* Prevent phantom flags */
			if (x)
				object_add_pval(o_ptr, x, flag);
			else
				of_off(f2, flag);
	}

	/* Apply remaining flags */
	of_union(o_ptr->flags, f2);

	return;
}
예제 #13
0
파일: obj-make.c 프로젝트: Dasaan/angband
/**
 * Copy artifact data to a normal object, and set various slightly hacky
 * globals.
 */
void copy_artifact_data(object_type *o_ptr, const artifact_type *a_ptr)
{
	int i;

	/* Extract the data */
	for (i = 0; i < a_ptr->num_pvals; i++)
		if (a_ptr->pval[i]) {
			o_ptr->pval[i] = a_ptr->pval[i];
			of_copy(o_ptr->pval_flags[i], a_ptr->pval_flags[i]);
		}
	o_ptr->num_pvals = a_ptr->num_pvals;
	o_ptr->ac = a_ptr->ac;
	o_ptr->dd = a_ptr->dd;
	o_ptr->ds = a_ptr->ds;
	o_ptr->to_a = a_ptr->to_a;
	o_ptr->to_h = a_ptr->to_h;
	o_ptr->to_d = a_ptr->to_d;
	o_ptr->weight = a_ptr->weight;
	of_union(o_ptr->flags, a_ptr->flags);
}
예제 #14
0
파일: obj-power.c 프로젝트: EpicMan/angband
/*
 * Calculate the rating for a given slay combination
 */
static s32b slay_power(const object_type *o_ptr, int verbose, ang_file* log_file,
	const bitflag flags[OF_SIZE])
{
	bitflag s_index[OF_SIZE];
	s32b sv = 0;
	int i;
	int mult;
	const slay_t *s_ptr;

	/* Combine the slay bytes into an index value */
	of_copy(s_index, flags);
	flags_mask(s_index, OF_SIZE, OF_ALL_SLAY_MASK, FLAG_END);

	/* Look in the cache to see if we know this one yet */
	for (i = 0; !of_is_empty(slay_cache[i].flags); i++)
	{
		if (of_is_equal(s_index, slay_cache[i].flags))
			break;
	}

	sv = slay_cache[i].value;

	/* If it's cached (or there are no slays), return the value */
	if (sv)
	{
		LOG_PRINT("Slay cache hit\n");
		return sv;
	}

	/*
	 * Otherwise we need to calculate the expected average multiplier
	 * for this combination (multiplied by the total number of
	 * monsters, which we'll divide out later).
	 */
	for (i = 0; i < z_info->r_max; i++)
	{
		monster_race *r_ptr = &r_info[i];
		mult = 1;

		/*
		 * Do the following in ascending order so that the best
		 * multiple is retained
		 */
		for (s_ptr = slay_table; s_ptr->slay_flag; s_ptr++)
		{
			if (!of_has(flags, s_ptr->slay_flag)) continue;

			if (rf_has(r_ptr->flags, s_ptr->monster_flag) ||
			    (s_ptr->resist_flag && !rf_has(r_ptr->flags,
			    s_ptr->resist_flag)))
			{
			    mult = s_ptr->mult;
			}
		}

		/* Add the multiple to sv */
		sv += mult * r_ptr->power;
	}

	/*
	 * To get the expected damage for this weapon, multiply the
	 * average damage from base dice by sv, and divide by the
	 * total number of monsters.
	 */
	if (verbose)
	{
		/* Write info about the slay combination and multiplier */
		file_putf(log_file,"Slay multiplier for:");

		if (of_has(flags, OF_SLAY_EVIL)) file_putf(log_file,"Evl ");
		if (of_has(flags, OF_KILL_DRAGON)) file_putf(log_file,"XDr ");
		if (of_has(flags, OF_KILL_DEMON)) file_putf(log_file,"XDm ");
		if (of_has(flags, OF_KILL_UNDEAD)) file_putf(log_file,"XUn ");
		if (of_has(flags, OF_SLAY_ANIMAL)) file_putf(log_file,"Ani ");
		if (of_has(flags, OF_SLAY_UNDEAD)) file_putf(log_file,"Und ");
		if (of_has(flags, OF_SLAY_DRAGON)) file_putf(log_file,"Drg ");
		if (of_has(flags, OF_SLAY_DEMON)) file_putf(log_file,"Dmn ");
		if (of_has(flags, OF_SLAY_TROLL)) file_putf(log_file,"Tro ");
		if (of_has(flags, OF_SLAY_ORC)) file_putf(log_file,"Orc ");
		if (of_has(flags, OF_SLAY_GIANT)) file_putf(log_file,"Gia ");
		if (of_has(flags, OF_BRAND_ACID)) file_putf(log_file,"Acd ");
		if (of_has(flags, OF_BRAND_ELEC)) file_putf(log_file,"Elc ");
		if (of_has(flags, OF_BRAND_FIRE)) file_putf(log_file,"Fir ");
		if (of_has(flags, OF_BRAND_COLD)) file_putf(log_file,"Cld ");
		if (of_has(flags, OF_BRAND_POIS)) file_putf(log_file,"Poi ");

		file_putf(log_file,"sv is: %d\n", sv);
		file_putf(log_file," and t_m_p is: %d \n", tot_mon_power);

		file_putf(log_file,"times 1000 is: %d\n", (1000 * sv) / tot_mon_power);
	}

	/* Add to the cache */
	for (i = 0; !of_is_empty(slay_cache[i].flags); i++)
	{
		if (of_is_equal(s_index, slay_cache[i].flags))
		{
			slay_cache[i].value = sv;
			LOG_PRINT("Added to slay cache\n");
			break;
		}
	}

	return sv;
}
예제 #15
0
/**
 * Wipe an object clean and make it a standard object of the specified kind.
 */
void object_prep(struct object *obj, struct object_kind *k, int lev,
				 aspect rand_aspect)
{
	int i;

	/* Clean slate */
	memset(obj, 0, sizeof(*obj));

	/* Assign the kind and copy across data */
	obj->kind = k;
	obj->tval = k->tval;
	obj->sval = k->sval;
	obj->ac = k->ac;
	obj->dd = k->dd;
	obj->ds = k->ds;
	obj->weight = k->weight;
	obj->effect = k->effect;
	obj->time = k->time;

	/* Default number */
	obj->number = 1;

	/* Copy flags */
	of_copy(obj->flags, k->base->flags);
	of_copy(obj->flags, k->flags);

	/* Assign modifiers */
	for (i = 0; i < OBJ_MOD_MAX; i++)
		obj->modifiers[i] = randcalc(k->modifiers[i], lev, rand_aspect);

	/* Assign charges (wands/staves only) */
	if (tval_can_have_charges(obj))
		obj->pval = randcalc(k->charge, lev, rand_aspect);

	/* Assign pval for food, oil and launchers */
	if (tval_is_edible(obj) || tval_is_potion(obj) || tval_is_fuel(obj) ||
		tval_is_launcher(obj))
		obj->pval
			= randcalc(k->pval, lev, rand_aspect);

	/* Default fuel */
	if (tval_is_light(obj)) {
		if (of_has(obj->flags, OF_BURNS_OUT))
			obj->timeout = z_info->fuel_torch;
		else if (of_has(obj->flags, OF_TAKES_FUEL))
			obj->timeout = z_info->default_lamp;
	}

	/* Default magic */
	obj->to_h = randcalc(k->to_h, lev, rand_aspect);
	obj->to_d = randcalc(k->to_d, lev, rand_aspect);
	obj->to_a = randcalc(k->to_a, lev, rand_aspect);

	/* Default slays and brands */
	copy_slay(&obj->slays, k->slays);
	copy_brand(&obj->brands, k->brands);

	/* Default resists */
	for (i = 0; i < ELEM_MAX; i++) {
		obj->el_info[i].res_level = k->el_info[i].res_level;
		obj->el_info[i].flags = k->el_info[i].flags;
		obj->el_info[i].flags |= k->base->el_info[i].flags;
	}
}
예제 #16
0
/**
 * For a string describing the player's intrinsic racial flags.
 */
static void view_abilities_aux(char *desc)
{
    bitflag flags[OF_SIZE];

    int attr_num, attr_listed, j;
    int max = 100;

    bool res = FALSE, vul = FALSE;

    char buf[10] = "";

    of_copy(flags, rp_ptr->flags_obj);

    /* Sustain stats. */
    if ((of_has(flags, OF_SUSTAIN_STR)) || (of_has(flags, OF_SUSTAIN_INT))
	|| (of_has(flags, OF_SUSTAIN_WIS)) || (of_has(flags, OF_SUSTAIN_DEX))
	|| (of_has(flags, OF_SUSTAIN_CON)) || (of_has(flags, OF_SUSTAIN_CHR))) {
	/* Clear number of items to list, and items listed. */
	attr_num = 0;
	attr_listed = 0;

	/* How many attributes need to be listed? */
	if (of_has(flags, OF_SUSTAIN_STR))
	    attr_num++;
	if (of_has(flags, OF_SUSTAIN_INT))
	    attr_num++;
	if (of_has(flags, OF_SUSTAIN_WIS))
	    attr_num++;
	if (of_has(flags, OF_SUSTAIN_DEX))
	    attr_num++;
	if (of_has(flags, OF_SUSTAIN_CON))
	    attr_num++;
	if (of_has(flags, OF_SUSTAIN_CHR))
	    attr_num++;

	/* Special case: sustain all stats */
	if (attr_num == 6) {
	    my_strcat(desc, "Your stats are all sustained.  ", max);
	} else {
	    my_strcat(desc, "Your", max);

	    /* Loop for number of attributes in this group. */
	    for (j = 0; j < 6; j++) {
		bool list_ok = FALSE;

		if ((j == 0) && (of_has(flags, OF_SUSTAIN_STR)))
		    list_ok = TRUE;
		if ((j == 1) && (of_has(flags, OF_SUSTAIN_INT)))
		    list_ok = TRUE;
		if ((j == 2) && (of_has(flags, OF_SUSTAIN_WIS)))
		    list_ok = TRUE;
		if ((j == 3) && (of_has(flags, OF_SUSTAIN_DEX)))
		    list_ok = TRUE;
		if ((j == 4) && (of_has(flags, OF_SUSTAIN_CON)))
		    list_ok = TRUE;
		if ((j == 5) && (of_has(flags, OF_SUSTAIN_CHR)))
		    list_ok = TRUE;

		if (!list_ok)
		    continue;

		/* Listing another attribute. */
		attr_listed++;

		/* Commas separate members of a list of more than two. */
		if ((attr_num > 2) && (attr_listed > 1))
		    my_strcat(desc, ",", max);

		/* "and" before final member of a list of more than one. */
		if ((attr_num > 1) && (j != 0)) {
		    if (attr_num == attr_listed)
			my_strcat(desc, " and", max);
		}

		/* List the attribute description, in its proper place. */
		if (j == 0)
		    my_strcat(desc, " strength", max);
		if (j == 1)
		    my_strcat(desc, " intelligence", max);
		if (j == 2)
		    my_strcat(desc, " wisdom", max);
		if (j == 3)
		    my_strcat(desc, " dexterity", max);
		if (j == 4)
		    my_strcat(desc, " constitution", max);
		if (j == 5)
		    my_strcat(desc, " charisma", max);
	    }
	}

	/* Pluralize the verb. */
	if (attr_num > 1)
	    my_strcat(desc, " are", max);
	else
	    my_strcat(desc, " is", max);

	/* End sentence.  Go to next line. */
	my_strcat(desc, " sustained. ", max);
    }

    /* Clear number of items to list, and items listed. */
    attr_num = 0;
    attr_listed = 0;

    /* Elemental immunities. */
    for (j = 0; j < 4; j++)
	if (rp_ptr->percent_res[j] == RES_BOOST_IMMUNE)
	    attr_num++;

    if (attr_num > 0) {
	my_strcat(desc, "You are immune to ", max);

	/* Loop for number of attributes in this group. */
	for (j = 0; j < 4; j++) {
	    if (rp_ptr->percent_res[j] > RES_BOOST_IMMUNE)
		continue;

	    /* List the attribute description, in its proper place. */
	    if (j == 0)
		my_strcat(desc, "acid", max);
	    if (j == 1)
		my_strcat(desc, "electricity", max);
	    if (j == 2)
		my_strcat(desc, "fire", max);
	    if (j == 3)
		my_strcat(desc, "frost", max);
	    if (attr_num >= 3)
		my_strcat(desc, ", ", max);
	    if (attr_num == 2)
		my_strcat(desc, " and ", max);
	    if (attr_num == 1)
		my_strcat(desc, ". ", max);
	    attr_num--;
	}

	/* End sentence.  Go to next line. */
	my_strcat(desc, ". ", max);
    }


    /* Check for resists and vulnerabilities */
    for (j = 0; j < MAX_P_RES; j++) {
	if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0))
	    res = TRUE;
	else if (rp_ptr->percent_res[j] > 100)
	    vul = TRUE;
    }


    /* Resistances. */
    if (res) {
	/* Clear number of items to list, and items listed. */
	attr_num = 0;
	attr_listed = 0;

	for (j = 0; j < MAX_P_RES; j++) {
	    if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0))
		attr_num++;
	}

	/* How many attributes need to be listed? */
	my_strcat(desc, "You resist", max);

	/* Loop for number of attributes in this group. */
	for (j = 0; j < MAX_P_RES; j++) {
	    bool list_ok = FALSE;

	    if ((rp_ptr->percent_res[j] < 100) && (rp_ptr->percent_res[j] > 0))
		list_ok = TRUE;
	    if (!list_ok)
		continue;

	    /* Listing another attribute. */
	    attr_listed++;

	    /* Commas separate members of a list of more than two. */
	    if ((attr_num > 2) && (attr_listed > 1))
		my_strcat(desc, ",", max);

	    /* "and" before final member of a list of more than one. */
	    if ((attr_num > 1) && (j != 0)) {
		if (attr_num == attr_listed)
		    my_strcat(desc, " and", max);
	    }

	    /* List the attribute description, in its proper place. */
	    if (j == P_RES_ACID)
		my_strcat(desc, " acid", max);
	    if (j == P_RES_ELEC)
		my_strcat(desc, " electricity", max);
	    if (j == P_RES_FIRE)
		my_strcat(desc, " fire", max);
	    if (j == P_RES_COLD)
		my_strcat(desc, " frost", max);
	    if (j == P_RES_POIS)
		my_strcat(desc, " poison", max);
	    if (j == P_RES_LIGHT)
		my_strcat(desc, " light", max);
	    if (j == P_RES_DARK)
		my_strcat(desc, " darkness", max);
	    if (j == P_RES_CONFU)
		my_strcat(desc, " confusion", max);
	    if (j == P_RES_SOUND)
		my_strcat(desc, " sound", max);
	    if (j == P_RES_SHARD)
		my_strcat(desc, " shards", max);
	    if (j == P_RES_NEXUS)
		my_strcat(desc, " nexus", max);
	    if (j == P_RES_NETHR)
		my_strcat(desc, " nether", max);
	    if (j == P_RES_CHAOS)
		my_strcat(desc, " chaos", max);
	    if (j == P_RES_DISEN)
		my_strcat(desc, " disenchantment", max);

	    sprintf(buf, "(%d%%)", 100 - rp_ptr->percent_res[j]);
	    my_strcat(desc, buf, max);
	}

	/* End sentence.  Go to next line. */
	my_strcat(desc, ". ", max);
    }


    /* Vulnerabilities. */
    if (vul) {
	/* Clear number of items to list, and items listed. */
	attr_num = 0;
	attr_listed = 0;

	for (j = 0; j < MAX_P_RES; j++) {
	    if (rp_ptr->percent_res[j] > 100)
		attr_num++;
	}

	my_strcat(desc, "You are vulnerable to", max);

	/* Loop for number of attributes in this group. */
	for (j = 0; j < MAX_P_RES; j++) {
	    bool list_ok = FALSE;

	    if (rp_ptr->percent_res[j] > 100)
		list_ok = TRUE;

	    if (!list_ok)
		continue;

	    /* Listing another attribute. */
	    attr_listed++;

	    /* Commas separate members of a list of more than two. */
	    if ((attr_num > 2) && (attr_listed > 1))
		my_strcat(desc, ",", max);

	    /* "and" before final member of a list of more than one. */
	    if ((attr_num > 1) && (j != 0)) {
		if (attr_num == attr_listed)
		    my_strcat(desc, " and", max);
	    }

	    /* List the attribute description, in its proper place. */
	    if (j == P_RES_ACID)
		my_strcat(desc, " acid", max);
	    if (j == P_RES_ELEC)
		my_strcat(desc, " electricity", max);
	    if (j == P_RES_FIRE)
		my_strcat(desc, " fire", max);
	    if (j == P_RES_COLD)
		my_strcat(desc, " frost", max);
	    if (j == P_RES_POIS)
		my_strcat(desc, " poison", max);
	    if (j == P_RES_LIGHT)
		my_strcat(desc, " light", max);
	    if (j == P_RES_DARK)
		my_strcat(desc, " darkness", max);
	    if (j == P_RES_SOUND)
		my_strcat(desc, " sound", max);
	    if (j == P_RES_SHARD)
		my_strcat(desc, " shards", max);
	    if (j == P_RES_NEXUS)
		my_strcat(desc, " nexus", max);
	    if (j == P_RES_NETHR)
		my_strcat(desc, " nether", max);
	    if (j == P_RES_CHAOS)
		my_strcat(desc, " chaos", max);
	    if (j == P_RES_DISEN)
		my_strcat(desc, " disenchantment", max);

	    sprintf(buf, "(%d%%)", rp_ptr->percent_res[j] - 100);
	    my_strcat(desc, buf, max);
	}

	/* End sentence.  Go to next line. */
	my_strcat(desc, ". ", max);
    }




    /* Clear a listing variable. */
    attr_num = 0;

    /* Special processing for two "survival resists" */
    if (of_has(flags, OF_FEARLESS))
	attr_num++;
    if (of_has(flags, OF_SEEING))
	attr_num++;

    if (of_has(flags, OF_FEARLESS)) {
	my_strcat(desc, "You are fearless", max);
	if (attr_num == 1)
	    my_strcat(desc, ".  ", max);
	else
	    my_strcat(desc, ", and", max);
    }

    if (of_has(flags, OF_SEEING)) {
	if ((attr_num > 1) && (of_has(flags, OF_FEARLESS)))
	    my_strcat(desc, " can not be blinded.  ", max);
	else
	    my_strcat(desc, "You can not be blinded.  ", max);
    }

    /* Miscellaneous abilities. */
    if ((of_has(flags, OF_SLOW_DIGEST)) || (of_has(flags, OF_FEATHER))
	|| (of_has(flags, OF_LIGHT)) || (of_has(flags, OF_REGEN))
	|| (of_has(flags, OF_TELEPATHY)) || (of_has(flags, OF_SEE_INVIS))
	|| (of_has(flags, OF_FREE_ACT)) || (of_has(flags, OF_HOLD_LIFE))) {
	/* Clear number of items to list, and items listed. */
	attr_num = 0;
	attr_listed = 0;

	/* How many attributes need to be listed? */
	if (of_has(flags, OF_SLOW_DIGEST))
	    attr_num++;
	if (of_has(flags, OF_FEATHER))
	    attr_num++;
	if (of_has(flags, OF_LIGHT))
	    attr_num++;
	if (of_has(flags, OF_REGEN))
	    attr_num++;
	if (of_has(flags, OF_TELEPATHY))
	    attr_num++;
	if (of_has(flags, OF_SEE_INVIS))
	    attr_num++;
	if (of_has(flags, OF_FREE_ACT))
	    attr_num++;
	if (of_has(flags, OF_HOLD_LIFE))
	    attr_num++;

	my_strcat(desc, "You", max);

	/* Loop for number of attributes in this group. */
	for (j = 0; j < 8; j++) {
	    bool list_ok = FALSE;

	    if ((j == 0) && (of_has(flags, OF_SLOW_DIGEST)))
		list_ok = TRUE;
	    if ((j == 1) && (of_has(flags, OF_FEATHER)))
		list_ok = TRUE;
	    if ((j == 2) && (of_has(flags, OF_LIGHT)))
		list_ok = TRUE;
	    if ((j == 3) && (of_has(flags, OF_REGEN)))
		list_ok = TRUE;
	    if ((j == 4) && (of_has(flags, OF_TELEPATHY)))
		list_ok = TRUE;
	    if ((j == 5) && (of_has(flags, OF_SEE_INVIS)))
		list_ok = TRUE;
	    if ((j == 6) && (of_has(flags, OF_FREE_ACT)))
		list_ok = TRUE;
	    if ((j == 7) && (of_has(flags, OF_HOLD_LIFE)))
		list_ok = TRUE;

	    if (!list_ok)
		continue;

	    /* Listing another attribute. */
	    attr_listed++;

	    /* Commas separate members of a list of more than two. */
	    if ((attr_num > 2) && (attr_listed > 1))
		my_strcat(desc, ",", max);

	    /* "and" before final member of a list of more than one. */
	    if ((attr_num > 1) && (j != 0)) {
		if (attr_num == attr_listed)
		    my_strcat(desc, " and", max);
	    }

	    /* List the attribute description, in its proper place. */
	    if (j == 0)
		my_strcat(desc, " digest slowly", max);
	    if (j == 1)
		my_strcat(desc, " falling gently", max);
	    if (j == 2)
		my_strcat(desc, " glow with permanent light", max);
	    if (j == 3)
		my_strcat(desc, " regenerative quickly", max);
	    if (j == 4)
		my_strcat(desc, " have telepathic powers", max);
	    if (j == 5)
		my_strcat(desc, " can see invisible monsters", max);
	    if (j == 6)
		my_strcat(desc, " are immune to paralysis", max);
	    if (j == 7)
		my_strcat(desc, " are resistant to life draining", max);
	}

	/* End sentence.  Go to next line. */
	my_strcat(desc, ".", max);
    }

}
예제 #17
0
/**
 * Carry an object and delete it.
 */
extern void py_pickup_aux(int o_idx, bool msg)
{
    int slot, quiver_slot = 0;

    char o_name[120];
    object_type *o_ptr = &o_list[o_idx];
    object_type *i_ptr = &p_ptr->inventory[INVEN_LIGHT];
    bitflag f[OF_SIZE], obvious_mask[OF_SIZE];


    flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);
    of_copy(f, o_ptr->flags_obj);
    
    /* Carry the object */
    slot = inven_carry(p_ptr, o_ptr);

    /* Handle errors (paranoia) */
    if (slot < 0) return;

    /* If we have picked up ammo which matches something in the quiver, note
     * that it so that we can wield it later (and suppress pick up message) */
    if (obj_is_quiver_obj(o_ptr)) 
    {
	int i;
	for (i = QUIVER_START; i < QUIVER_END; i++) 
	{
	    if (!p_ptr->inventory[i].k_idx) continue;
	    if (!object_similar(&p_ptr->inventory[i], o_ptr,
				OSTACK_QUIVER)) continue;
	    quiver_slot = i;
	    break;
	}
    }

    /* Get the object again */
    o_ptr = &p_ptr->inventory[slot];

    /* Set squelch status */
    p_ptr->notice |= PN_SQUELCH;

    /* Stone of Lore gives id on pickup */
    if (!object_known_p(o_ptr)) {
	if (i_ptr->sval == SV_STONE_LORE)
	    identify_object(o_ptr);

	/* Otherwise pseudo-ID */
	else {
	    bool heavy = FALSE;
	    int feel;

	    /* Heavy sensing */
	    heavy = (player_has(PF_PSEUDO_ID_HEAVY));

	    /* Type of feeling */
	    feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));

	    /* We have "felt" it */
	    o_ptr->ident |= (IDENT_SENSE);

	    /* Inscribe it textually */
	    o_ptr->feel = feel;

	    /* Set squelch flag as appropriate */
	    p_ptr->notice |= PN_SQUELCH;
	}
    }

    /* Log artifacts if found */
    if (artifact_p(o_ptr))
	history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE);

    /* Notice dice and other obvious stuff */
    notice_other(IF_DD_DS, slot + 1);
    (void) of_inter(f, obvious_mask);
    of_union(o_ptr->id_obj, f);

    /* Average things are average */
    if ((o_ptr->feel == FEEL_AVERAGE) && (is_weapon(o_ptr) || is_armour(o_ptr))){
	notice_other(IF_AC, slot + 1);
	notice_other(IF_TO_A, slot + 1);
	notice_other(IF_TO_H, slot + 1);
	notice_other(IF_TO_D, slot + 1);
    }

    /* Recalculate the bonuses */
    p_ptr->update |= (PU_BONUS);

    /* Optionally, display a message */
    if (msg && !quiver_slot)
    {
	/* Describe the object */
	object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);

	/* Message */
	msg_format("You have %s (%c).", o_name, index_to_label(slot));
    }


    /* Delete the object */
    delete_object_idx(o_idx);

    /* If we have a quiver slot that this item matches, use it */
    if (quiver_slot) wield_item(o_ptr, slot, quiver_slot);
}
예제 #18
0
/**
 * Complete object creation by applying magic to it.
 *
 * Magic includes rolling for random bonuses, applying flags to ego-items,
 * charging charged items, fuelling lights, and trapping chests.
 *
 * 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.  See the function itself for the specifics of the
 * calculations involved.
 */
void apply_magic(object_type *o_ptr, int lev, bool allow_artifacts, bool good, bool great)
{
	int power = 0;
	/*u32b xtra = 0;*/
	/*bool new = FALSE;*/

	/* Chance of being `good` and `great` */
	int good_chance = (lev+2) * 3;
	int great_chance = MIN(lev/4 + lev, 50);


	/* Limit depth */
	if (lev > MAX_DEPTH - 1) lev = MAX_DEPTH - 1;

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

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

	/* Roll for "cursed" */
	else if (randint0(100) < good_chance)
	{
		/* Assume "cursed" */
		power = -1;

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


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

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

		/* Get four rolls if forced great */
		if (great) rolls = 4;

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


	/* Apply magic */
	switch (o_ptr->tval)
	{
		case TV_DIGGING:
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_BOW:
		case TV_SHOT:
		case TV_ARROW:
		case TV_BOLT:
		{
			if (power == 2 || power == -2)
			{
				int ego_power;

				ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0));

				if (ego_power) power = ego_power;
			}

			if (power) a_m_aux_1(o_ptr, lev, power);

			break;
		}

		case TV_DRAG_ARMOR:
		case TV_HARD_ARMOR:
		case TV_SOFT_ARMOR:
		case TV_SHIELD:
		case TV_HELM:
		case TV_CROWN:
		case TV_CLOAK:
		case TV_GLOVES:
		case TV_BOOTS:
		{
			if (power == 2 || power == -2)
			{
				int ego_power;

				ego_power = make_ego_item(o_ptr, lev, (bool)(power > 0));

				if (ego_power) power = ego_power;
			}

			if (power) a_m_aux_2(o_ptr, lev, power);

			break;
		}

		case TV_RING:
		case TV_AMULET:
		{
			if (!power && (randint0(100) < 50)) power = -1;
			a_m_aux_3(o_ptr, lev, power);
			break;
		}

		case TV_LIGHT:
		{
			if (power == 2 || power == -2)
				make_ego_item(o_ptr, lev, (bool)(power > 0));

			/* Fuel it */
			a_m_aux_4(o_ptr, lev, power);
			break;
		}

		default:
		{
			a_m_aux_4(o_ptr, lev, power);
			break;
		}
	}


	/* Hack -- analyze ego-items */
	if (o_ptr->name2)
	{
		ego_item_type *e_ptr = &e_info[o_ptr->name2];
		bitflag flags[OF_SIZE];

		object_flags(o_ptr, flags);

		/* Extra powers */
		if (e_ptr->xtra == OBJECT_XTRA_TYPE_SUSTAIN)
			of_on(o_ptr->flags, get_new_attr(flags, ego_sustains,
											N_ELEMENTS(ego_sustains)));
		else if (e_ptr->xtra == OBJECT_XTRA_TYPE_RESIST)
			of_on(o_ptr->flags, get_new_attr(flags, ego_resists,
											N_ELEMENTS(ego_resists)));
		else if (e_ptr->xtra == OBJECT_XTRA_TYPE_POWER)
			of_on(o_ptr->flags, get_new_attr(flags, ego_powers,
											N_ELEMENTS(ego_powers)));

		/* Hack -- acquire "cursed" flags */
		if (cursed_p(e_ptr))
		{
			bitflag curse_flags[OF_SIZE];

			of_copy(curse_flags, e_ptr->flags);
			flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
			of_union(o_ptr->flags, curse_flags);
		}

		/* Hack -- apply extra penalties if needed */
		if (cursed_p(o_ptr))
		{
			/* Apply extra ego bonuses */
			o_ptr->to_h -= randcalc(e_ptr->to_h, lev, RANDOMISE);
			o_ptr->to_d -= randcalc(e_ptr->to_d, lev, RANDOMISE);
			o_ptr->to_a -= randcalc(e_ptr->to_a, lev, RANDOMISE);

			/* Apply ego pval */
			o_ptr->pval -= randcalc(e_ptr->pval, lev, RANDOMISE);

			/* Apply minimums */
			if (o_ptr->to_h > -1 * e_ptr->min_to_h) o_ptr->to_h = -1 * e_ptr->min_to_h;
			if (o_ptr->to_d > -1 * e_ptr->min_to_d) o_ptr->to_d = -1 * e_ptr->min_to_d;
			if (o_ptr->to_a > -1 * e_ptr->min_to_a) o_ptr->to_a = -1 * e_ptr->min_to_a;
			if (o_ptr->pval > -1 * e_ptr->min_pval) o_ptr->pval = -1 * e_ptr->min_pval;
		}

		/* Hack -- apply extra bonuses if needed */
		else
		{
			/* Apply extra ego bonuses */
			o_ptr->to_h += randcalc(e_ptr->to_h, lev, RANDOMISE);
			o_ptr->to_d += randcalc(e_ptr->to_d, lev, RANDOMISE);
			o_ptr->to_a += randcalc(e_ptr->to_a, lev, RANDOMISE);

			/* Apply ego pval */
			o_ptr->pval += randcalc(e_ptr->pval, lev, RANDOMISE);

			/* Apply minimums */
			if (o_ptr->to_h < e_ptr->min_to_h) o_ptr->to_h = e_ptr->min_to_h;
			if (o_ptr->to_d < e_ptr->min_to_d) o_ptr->to_d = e_ptr->min_to_d;
			if (o_ptr->to_a < e_ptr->min_to_a) o_ptr->to_a = e_ptr->min_to_a;
			if (o_ptr->pval < e_ptr->min_pval) o_ptr->pval = e_ptr->min_pval;
		}

		/* Hack -- apply rating bonus */
		rating += e_ptr->rating;

		/* Cheat -- describe the item */
		if (OPT(cheat_peek)) object_mention(o_ptr);

		/* Done */
		return;
	}


	/* Examine real objects */
	if (o_ptr->k_idx)
	{
		object_kind *k_ptr = &k_info[o_ptr->k_idx];

		/* Hack -- acquire "cursed" flag */
		if (cursed_p(k_ptr))
		{
			bitflag curse_flags[OF_SIZE];

			of_copy(curse_flags, k_ptr->flags);
			flags_mask(curse_flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
			of_union(o_ptr->flags, curse_flags);
		}
	}
}
예제 #19
0
파일: obj-make.c 프로젝트: nomadicwriter/v4
/**
 * Apply an affix to an ego-item, checking minima as we go.
 *
 * \param o_ptr is the object we're modifying
 * \param level is the generation level
 * \param affix is the affix we're applying
 */
void ego_apply_magic(object_type *o_ptr, int level, int affix)
{
	int i, j, flag, pval, amt;
	bitflag flags[OF_SIZE], f2[OF_SIZE];
	ego_item_type *ego;

	ego = &e_info[affix];

	/* Random powers */
	for (i = 0; i < ego->num_randlines; i++)
		for (j = 0; j < ego->num_randflags[i]; j++)
			of_on(o_ptr->flags,	get_new_attr(o_ptr->flags, ego->randmask[i]));

	/* Apply extra combat bonuses */
	amt = randcalc(ego->to_h, level, RANDOMISE);
	o_ptr->to_h += amt;
	if (ego->min_to_h != NO_MINIMUM) {
		if (amt < ego->min_to_h)
			o_ptr->to_h += ego->min_to_h - amt;
		if (o_ptr->to_h < ego->min_to_h)
			o_ptr->to_h = ego->min_to_h;
	}

	amt = randcalc(ego->to_d, level, RANDOMISE);
	o_ptr->to_d += amt;
	if (ego->min_to_d != NO_MINIMUM) {
		if (amt < ego->min_to_d)
			o_ptr->to_d += ego->min_to_d - amt;
		if (o_ptr->to_d < ego->min_to_d)
			o_ptr->to_d = ego->min_to_d;
	}

	amt = randcalc(ego->to_a, level, RANDOMISE);
	o_ptr->to_a += amt;
	if (ego->min_to_a != NO_MINIMUM) {
		if (amt < ego->min_to_a)
			o_ptr->to_a += ego->min_to_a - amt;
		if (o_ptr->to_a < ego->min_to_a)
			o_ptr->to_a = ego->min_to_a;
	}

	/* Apply pvals */
	of_copy(f2, ego->flags);
	for (i = 0; i < ego->num_pvals; i++) {
		of_copy(flags, ego->pval_flags[i]);
		pval = randcalc(ego->pval[i], level, RANDOMISE);
		if (ego->min_pval[i] != NO_MINIMUM && pval < ego->min_pval[i])
			pval = ego->min_pval[i];
		for (flag = of_next(flags, FLAG_START); flag != FLAG_END;
				flag = of_next(flags, flag + 1))
			/* Prevent phantom flags, and check minima after adding */
			if (pval) {
				object_add_pval(o_ptr, pval, flag);
				if (ego->min_pval[i] != NO_MINIMUM && of_has(o_ptr->flags,
						flag))
					if (o_ptr->pval[which_pval(o_ptr, flag)] < ego->min_pval[i])
						object_add_pval(o_ptr, ego->min_pval[i] -
							o_ptr->pval[which_pval(o_ptr, flag)], flag);
			} else
				of_off(f2, flag);
	}

	/* Apply remaining flags */
	of_union(o_ptr->flags, f2);

	/* Adjust AC, weight, dice and sides */
	if (o_ptr->ac && ego->ac_mod)
		o_ptr->ac = ((100 + ego->ac_mod) * o_ptr->ac) / 100;

	o_ptr->weight = ((100 + ego->wgt_mod) * o_ptr->weight) / 100;

	o_ptr->dd += ego->dd;
	if (o_ptr->dd < 1)
		o_ptr->dd = 1;

	o_ptr->ds += ego->ds;
	if (o_ptr->ds < 1)
		o_ptr->ds = 1;

	/* Tidy up and de-duplicate flags, and set the correct prefix/suffix */
	check_flags(o_ptr);
	obj_affix_names(o_ptr);

	return;
}
예제 #20
0
bool wiz_create_item_subaction(menu_type * m, const ui_event * e, int oid)
{
	int *choices = menu_priv(m);

	object_type *i_ptr;
	object_type object_type_body;

	/* Artifacts */
	if (choose_artifact) {
		int i;
		int o_idx;
		artifact_type *a_ptr = &a_info[choices[oid]];

		/* Get the artifact info */
		//a_ptr = &a_info[choices[oid]];

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

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

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

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

		/* Create the base object */
		object_prep(i_ptr, o_idx, RANDOMISE);

		/* Mark the object as an artifact. */
		i_ptr->name1 = choices[oid];

		/* Extract the fields */
		i_ptr->pval = a_ptr->pval;
		i_ptr->ac = a_ptr->ac;
		i_ptr->dd = a_ptr->dd;
		i_ptr->ds = a_ptr->ds;
		i_ptr->to_a = a_ptr->to_a;
		i_ptr->to_h = a_ptr->to_h;
		i_ptr->to_d = a_ptr->to_d;
		i_ptr->weight = a_ptr->weight;

		of_copy(i_ptr->flags_obj, a_ptr->flags_obj);
		cf_copy(i_ptr->flags_curse, a_ptr->flags_curse);

		for (i = 0; i < MAX_P_RES; i++)
			i_ptr->percent_res[i] = a_ptr->percent_res[i];
		for (i = 0; i < A_MAX; i++)
			i_ptr->bonus_stat[i] = a_ptr->bonus_stat[i];
		for (i = 0; i < MAX_P_BONUS; i++)
			i_ptr->bonus_other[i] = a_ptr->bonus_other[i];
		for (i = 0; i < MAX_P_SLAY; i++)
			i_ptr->multiple_slay[i] = a_ptr->multiple_slay[i];
		for (i = 0; i < MAX_P_BRAND; i++)
			i_ptr->multiple_brand[i] = a_ptr->multiple_brand[i];


		/* Transfer the activation information. */
		if (a_ptr->effect)
			i_ptr->effect = a_ptr->effect;
	}
	/* Regular objects */
	else {
		object_kind *kind = &k_info[choices[oid]];

		if (e->type != EVT_SELECT)
			return TRUE;

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

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

		/* Create the item */
		object_prep(i_ptr, kind->kidx, RANDOMISE);

		/* Apply magic (no messages, no artifacts) */
		apply_magic(i_ptr, p_ptr->danger, FALSE, FALSE, FALSE);

		/* Hack -- Since treasure objects are not effected by apply_magic, they
		 * need special processing. */
		if (i_ptr->tval == TV_GOLD) {
			i_ptr->pval = kind->cost / 2 + randint1((kind->cost + 1) / 2);
		}

		/* Mark as cheat, and where created */
		i_ptr->origin = ORIGIN_CHEAT;
		i_ptr->origin_z = chunk_list[p_ptr->stage].z_pos;
		i_ptr->origin_y = chunk_list[p_ptr->stage].y_pos;
		i_ptr->origin_x = chunk_list[p_ptr->stage].x_pos;

	}

	/* Drop from heaven */
	drop_near(i_ptr, -1, p_ptr->py, p_ptr->px, TRUE);

	/* All done */
	msg("Allocated.");

	return FALSE;
}
예제 #21
0
/**
 * Calculate the rating for a given slay combination
 */
static s32b slay_power(const object_type *o_ptr, int verbose, ang_file*
	log_file, bool known)
{
	bitflag s_index[OF_SIZE], f[OF_SIZE], f2[OF_SIZE];
	u32b sv = 0;
	int i, j;
	int mult;
	const struct slay *best_s_ptr = NULL;
	monster_race *r_ptr;
	monster_type *m_ptr;
	monster_type monster_type_body;
	const char *desc[SL_MAX] = { 0 }, *brand[SL_MAX] = { 0 };
	int s_mult[SL_MAX] = { 0 };

	if (known)
		object_flags(o_ptr, f);
	else
		object_flags_known(o_ptr, f);

	/* Combine the slay bytes into an index value, return if there are none */
	of_copy(s_index, f);
	create_mask(f2, FALSE, OFT_SLAY, OFT_KILL, OFT_BRAND, OFT_MAX);

	if (!of_is_inter(s_index, f2))
		return tot_mon_power;
	else
		of_inter(s_index, f2);

	/* Look in the cache to see if we know this one yet */
	sv = check_slay_cache(s_index);

	/* If it's cached (or there are no slays), return the value */
	if (sv)	{
		file_putf(log_file, "Slay cache hit\n");
		return sv;
	}

	/*
	 * Otherwise we need to calculate the expected average multiplier
	 * for this combination (multiplied by the total number of
	 * monsters, which we'll divide out later).
	 */
	for (i = 0; i < z_info->r_max; i++)	{
		best_s_ptr = NULL;
		mult = 1;
		r_ptr = &r_info[i];
		m_ptr = &monster_type_body;
		m_ptr->r_idx = i;

		/* Find the best multiplier against this monster */
		improve_attack_modifier((object_type *)o_ptr, m_ptr, &best_s_ptr,
				FALSE, !known);
		if (best_s_ptr)
			mult = best_s_ptr->mult;

		/* Add the multiple to sv */
		sv += mult * r_ptr->scaled_power;
	}

	/*
	 * To get the expected damage for this weapon, multiply the
	 * average damage from base dice by sv, and divide by the
	 * total number of monsters.
	 */
	if (verbose) {
		/* Write info about the slay combination and multiplier */
		file_putf(log_file, "Slay multiplier for: ");

		j = list_slays(s_index, s_index, desc, brand, s_mult, FALSE);

		for (i = 0; i < j; i++) {
			if (brand[i]) {
				file_putf(log_file, brand[i]);
			} else {
				file_putf(log_file, desc[i]);
			}
			file_putf(log_file, "x%d ", s_mult[i]); 
		}
		file_putf(log_file, "\nsv is: %d\n", sv);
		file_putf(log_file, " and t_m_p is: %d \n", tot_mon_power);
		file_putf(log_file, "times 1000 is: %d\n", (1000 * sv) / tot_mon_power);
	}

	/* Add to the cache */
	if (fill_slay_cache(s_index, sv))
		file_putf(log_file, "Added to slay cache\n");

	return sv;
}