Ejemplo n.º 1
0
/*
 * Describe the kind
 */
static void kind_info(char *buf, char *dam, char *wgt, int *lev, s32b *val,
	int k)
{
	object_type forge;
	object_type *q_ptr;

	object_kind *k_ptr;


	/* Get local object */
	q_ptr = &forge;

	/* Prepare a fake item */
	object_prep(q_ptr, k);

	/* Obtain the "kind" info */
	k_ptr = &k_info[q_ptr->k_idx];

	/* It is known */
	q_ptr->ident |= (IDENT_KNOWN);

	/* Cancel bonuses */
	q_ptr->pval = 0;
	q_ptr->to_a = 0;
	q_ptr->to_h = 0;
	q_ptr->to_d = 0;


	/* Level (is this appropriate?) */
	(*lev) = object_k_level(k_ptr);

	/* Value */
	(*val) = object_value(q_ptr, FALSE);


	/* Hack */
	if (!buf || !dam || !wgt) return;


	/* Description (too brief) */
	strnfmt(buf, ONAME_MAX, "%v", object_desc_f3, q_ptr, OD_SHOP, 0);


	/* Misc info */
	strcpy(dam, "");

	/* Damage */
	switch (q_ptr->tval)
	{
		/* Bows */
		case TV_BOW:
		{
			break;
		}

		/* Ammo */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		{
			sprintf(dam, "%dd%d", q_ptr->dd, q_ptr->ds);
			break;
		}

		/* Weapons */
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			sprintf(dam, "%dd%d", q_ptr->dd, q_ptr->ds);
			break;
		}

		/* Armour */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			sprintf(dam, "%d", q_ptr->ac);
			break;
		}
	}


	/* Weight */
	sprintf(wgt, "%3d.%d", q_ptr->weight / 10, q_ptr->weight % 10);
}
Ejemplo n.º 2
0
// Select an artifact from a list and place it in the player's inventory.
// Note that dragon armor comes out doesn't work too well, since it
// is always make into an ego item.
MakeObjectDialog::MakeObjectDialog(void)
{
    int i;
    QPointer<QVBoxLayout> vlay = new QVBoxLayout;
    obj_choice = new QComboBox;
    object_type object_type_body;
    object_type *i_ptr = &object_type_body;


    QPointer<QLabel>  obj_label = new QLabel(QString("<b><big>Please select an object:</big></b>"));
    obj_label->setAlignment(Qt::AlignCenter);

    vlay->addWidget(obj_label);
    vlay->addStretch();

    connect(obj_choice, SIGNAL(currentIndexChanged(int)), this, SLOT(update_obj_choice(int)));

    QPointer<QPushButton> close_button = new QPushButton(tr("&Close"));
    connect(close_button, SIGNAL(clicked()), this, SLOT(close()));

    int count = 0;
    obj_num = 0;

    for (i = 1; i < z_info->k_max; i++)
    {
        object_kind *k_ptr = &k_info[i];

        /* Skip "empty" items */
        if (k_ptr->k_name.isEmpty()) continue;
        // Skip artifact templates
        if (k_ptr->k_flags3 & (TR3_INSTA_ART)) continue;
        // Skip gold
        if (k_ptr->tval == TV_GOLD) continue;

        obj_choice->addItem(QString("%1") .arg(i));

        obj_choice->setItemText(count++, get_object_display_name(i));
    }

    vlay->addWidget(obj_choice);
    vlay->addStretch();
    vlay->addWidget(close_button);

    setLayout(vlay);

    setWindowTitle(tr("Make Object"));
    this->exec();

    // find the object
    count = 0;
    for (i = 1; i < z_info->k_max; i++)
    {
        object_kind *k_ptr = &k_info[i];

        /* Skip "empty" items */
        if (k_ptr->k_name.isEmpty()) continue;
        // Skip artifact templates
        if (k_ptr->k_flags3 & (TR3_INSTA_ART)) continue;
        // Skip gold
        if (k_ptr->tval == TV_GOLD) continue;

        // Found the match
        if (count == obj_num) break;
        count++;
    }

    //  This is necessary to keep the game from freezing on dragon armor
    object_level = k_info[i].k_level;

    i_ptr->object_wipe();
    object_prep(i_ptr, i);
    apply_magic(i_ptr, p_ptr->depth, FALSE, FALSE, FALSE, FALSE);
    object_history(i_ptr, ORIGIN_CHEAT, 0);
    identify_object(i_ptr, true);
    if(inven_carry(i_ptr) < 0)
    {
        drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
    }

    object_level = p_ptr->depth;
}
Ejemplo n.º 3
0
Archivo: cmd3.c Proyecto: fph/mortsil
void prise_silmaril(void)
{
	object_type   *o_ptr;
	object_type   *w_ptr;
	artefact_type *a_ptr;

	object_type object_type_body;

	cptr freed_msg = NULL; // default to soothe compiler warnings

	bool freed = FALSE;

	int slot = 0;
	
	int dam = 0;
	int prt = 0;
	int net_dam = 0;
	int prt_percent = 0;
	int hit_result = 0;
	int crit_bonus_dice = 0;
	int pd = 0;
	int noise = 0;
	u32b dummy_noticed_flag;
	
	int mds = p_ptr->mds;
	int attack_mod = p_ptr->skill_use[S_MEL];

	char o_name[80];

	// the Crown is on the ground
	o_ptr = &o_list[cave_o_idx[p_ptr->py][p_ptr->px]];
				
	switch (o_ptr->name1)
	{
		case ART_MORGOTH_3:
		{
			pd = 15;
			noise = 5;
			freed_msg = "You have freed a Silmaril!";
			break;
		}
		case ART_MORGOTH_2:
		{
			pd = 25;
			noise = 10;
						
			if (p_ptr->crown_shatter)	freed_msg = "The fates be damned! You free a second Silmaril.";
			else						freed_msg = "You free a second Silmaril.";
			
			break;
		}
		case ART_MORGOTH_1:
		{
			pd = 30;
			noise = 15;
			
			freed_msg = "You free the final Silmaril. You have a very bad feeling about this.";
			
			msg_print("Looking into the hallowed light of the final Silmaril, you are filled with a strange dread.");
			if (!get_check("Are you sure you wish to proceed? ")) return;
			
			break;
		}
	}
	
	/* Get the weapon */
	w_ptr = &inventory[INVEN_WIELD];

	// undo rapid attack penalties
	if (p_ptr->active_ability[S_MEL][MEL_RAPID_ATTACK])
	{
		// undo strength adjustment to the attack
		mds = total_mds(w_ptr, 0);
		
		// undo the dexterity adjustment to the attack
		attack_mod += 3;
	}
	
	/* Test for hit */
	hit_result = hit_roll(attack_mod, 0, PLAYER, NULL, TRUE);
	
	/* Make some noise */
	stealth_score -= noise;
	
	// Determine damage
	if (hit_result > 0)
	{
		crit_bonus_dice = crit_bonus(hit_result, w_ptr->weight, &r_info[R_IDX_MORGOTH], S_MEL, FALSE);
		
		dam = damroll(p_ptr->mdd + crit_bonus_dice, mds);
		prt = damroll(pd, 4);
		
		prt_percent = prt_after_sharpness(w_ptr, &dummy_noticed_flag);
		prt = (prt * prt_percent) / 100;
		net_dam = dam - prt;
		
		/* No negative damage */
		if (net_dam < 0) net_dam = 0;
		
		//update_combat_rolls1b(PLAYER, TRUE);
		update_combat_rolls2(p_ptr->mdd + crit_bonus_dice, mds, dam, pd, 4, prt, prt_percent, GF_HURT, TRUE);
	}
	
	
	// if you succeed in prising out a Silmaril...
	if (net_dam > 0)
	{
		freed = TRUE;
		
		switch (o_ptr->name1)
		{
			case ART_MORGOTH_3:
			{
				break;
			}
			case ART_MORGOTH_2:
			{
				if (!p_ptr->crown_shatter && one_in_(2))
				{
					shatter_weapon(2);
					freed = FALSE;
				}
				break;
			}
			case ART_MORGOTH_1:
			{
				if (!p_ptr->crown_shatter)
				{
					shatter_weapon(3);
					freed = FALSE;
				}
				else
				{
					p_ptr->cursed = TRUE;
				}
				break;
			}
		}
		
		if (freed)
		{
			// change its type to that of the crown with one less silmaril
			o_ptr->name1--;
			
			// get the details of this new crown
			a_ptr = &a_info[o_ptr->name1];
			
			// modify the existing crown
			object_into_artefact(o_ptr, a_ptr);
			
			// report success
			msg_print(freed_msg);
			
			// Get new local object
			o_ptr = &object_type_body;
			
			// Make Silmaril
			object_prep(o_ptr, lookup_kind(TV_LIGHT, SV_LIGHT_SILMARIL));
			
			// Get it
			slot = inven_carry(o_ptr);

			/* Get the object again */
			o_ptr = &inventory[slot];
			
			/* Describe the object */
			object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3);
			
			/* Message */
			msg_format("You have %s (%c).", o_name, index_to_label(slot));

			// Break the truce (always)
			break_truce(TRUE);
		
			// add a note to the notes file
			do_cmd_note("Cut a Silmaril from Morgoth's crown", p_ptr->depth);
		}
	}
	
	// if you fail to prise out a Silmaril...
	else
	{
		msg_print("Try though you might, you were unable to free a Silmaril.");
		msg_print("Perhaps you should try again or use a different weapon.");

		if (pd == 15) msg_print("(The combat rolls window shows what is happening.)");

		// Break the truce if creatures see
		break_truce(FALSE);
	}

	// check for taking of final Silmaril
	if ((pd == 30) && freed)
	{
		msg_print("Until you escape you must now roll twice for every skill check, taking the worse result each time.");
		msg_print("You hear a cry of veangance echo through the iron hells.");
		wake_all_monsters(0);
	}
}
Ejemplo n.º 4
0
/**
 * Handle player hitting a real trap.  Rewritten in Oangband to allow a
 * greater variety of traps, with effects controlled by dungeon level.
 * To allow a trap to choose one of a variety of effects consistantly,
 * the quick RNG is often used, and xy coordinates input as a seed value.
 */
extern void hit_trap(int y, int x)
{
    int i, j, k, num;
    int dam = 0;

    int nastyness, selection;

    feature_type *f_ptr = &f_info[cave_feat[y][x]];

    cptr name = f_ptr->name;

    /* Use the "simple" RNG to insure that traps are consistant. */
    Rand_quick = TRUE;

    /* Use the coordinates of the trap to seed the RNG. */
    Rand_value = y * x;

    /* Disturb the player */
    disturb(0, 0);

    /* Analyze XXX XXX XXX */
    switch (cave_feat[y][x]) {
    /* trap door. */
    case FEAT_TRAP_HEAD + 0x00:
    {
        Rand_quick = FALSE;

        /* Paranoia -NRM- */
        if (((stage_map[p_ptr->stage][STAGE_TYPE] == CAVE)
                || (stage_map[p_ptr->stage][STAGE_TYPE] == VALLEY))
                && (!stage_map[p_ptr->stage][DOWN])) {
            cave_info[y][x] &= ~(CAVE_MARK);
            cave_set_feat(y, x, FEAT_FLOOR);
            msg_print("The trap fails!");
            break;
        }


        msg_print("You fall through a trap door!");
        if (p_ptr->state.ffall) {
            notice_obj(OF_FEATHER, 0);
            msg_print("You float gently down to the next level.");
        } else {
            dam = damroll(2, 8);
            take_hit(dam, name);
        }
        /* Remember where we came from */
        p_ptr->last_stage = p_ptr->stage;

        if (!stage_map[p_ptr->stage][DOWN]) {
            /* Set the ways forward and back */
            stage_map[255][UP] = p_ptr->stage;
            stage_map[p_ptr->stage][DOWN] = 255;
            stage_map[255][DEPTH] = p_ptr->depth + 1;
        }

        /* New stage */
        p_ptr->stage = stage_map[p_ptr->stage][DOWN];

        /* New depth */
        p_ptr->depth = stage_map[p_ptr->stage][DEPTH];

        /* Leaving */
        p_ptr->leaving = TRUE;

        Rand_quick = TRUE;

        break;
    }

    /* pits. */
    case FEAT_TRAP_HEAD + 0x01:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(20) == 1)
            nastyness += 20;
        else if (randint1(5) == 1)
            nastyness += 10;

        /* Player is now in pit. */
        monster_swap(p_ptr->py, p_ptr->px, y, x);

        /* Center on player. */
        y = p_ptr->py;
        x = p_ptr->px;

        /* pit of daggers. */
        if ((nastyness > 80) && (randint1(3) != 3)) {
            msg_print("You fall into a pit of daggers!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid setting off the daggers.");
            }

            else {
                /* a trap of morgul. */
                if (randint1(6) == 1) {
                    Rand_quick = FALSE;


                    msg_print
                    ("A single coldly gleaming dagger pierces you deeply!");
                    msg_print
                    ("You feel a deadly chill slowly withering your soul.");

                    /* activate the Black Breath. */
                    p_ptr->black_breath = TRUE;

                    /* lots of damage. */
                    dam = damroll(20, 15);

                    /* undead may be attracted. */
                    if (randint1(2) == 1) {
                        msg_print
                        ("Undead suddenly appear and call you to them!");

                        k = randint1(3) + 2;
                        for (i = 0; i < k; i++) {
                            summon_specific(y, x, FALSE, p_ptr->depth,
                                            SUMMON_UNDEAD);
                        }
                    }

                    /* morgul-traps are one-time only. */
                    cave_info[y][x] &= ~(CAVE_MARK);
                    cave_set_feat(y, x, FEAT_FLOOR);

                    Rand_quick = TRUE;
                }

                else {
                    Rand_quick = FALSE;

                    /* activate the ordinary daggers. */
                    msg_print("Daggers pierce you everywhere!");

                    k = randint1(10) + 5;
                    for (i = 0; i < k; i++) {
                        dam += damroll(3, 4);
                    }

                    Rand_quick = TRUE;
                }

                /* cut the player. */
                (void) inc_timed(TMD_CUT, randint1(dam), TRUE);

                /* Take the damage. */
                take_hit(dam, name);
            }
        }

        /* poisoned spiked pit. */
        else if ((nastyness > 55) && (randint1(3) != 3)) {
            msg_print("You fall into a spiked pit!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid touching the spikes.");
            }

            else {
                Rand_quick = FALSE;

                /* Base damage */
                dam = damroll(2, 6);

                /* Extra spike damage */
                if (randint0(100) < 85) {
                    bool was_poisoned;

                    msg_print("You are impaled on poisonous spikes!");

                    dam = dam * (randint1(6) + 3);
                    (void) inc_timed(TMD_CUT, randint1(dam), TRUE);

                    was_poisoned = pois_hit(dam);

                    if (!was_poisoned)
                        msg_print("The poison does not affect you!");
                }

                /* Take the damage */
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        /* spiked pit. */
        else if ((nastyness > 30) && (randint1(3) != 3)) {
            msg_print("You fall into a spiked pit!");

            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the floor of the pit.");
                msg_print("You carefully avoid touching the spikes.");
            }

            else {
                Rand_quick = FALSE;

                /* Base damage */
                dam = damroll(2, 6);

                /* Extra spike damage */
                if (randint0(100) < 85) {
                    msg_print("You are impaled!");

                    dam = dam * (2 + randint1(4));
                    (void) inc_timed(TMD_CUT, randint1(dam), TRUE);
                }

                /* Take the damage */
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        /* ordinary pit in all other cases. */
        else {
            msg_print("You fall into a pit!");
            if (p_ptr->state.ffall) {
                notice_obj(OF_FEATHER, 0);
                msg_print("You float gently to the bottom of the pit.");
            } else {
                Rand_quick = FALSE;

                dam = damroll(2, 6);
                take_hit(dam, name);

                Rand_quick = TRUE;
            }
        }

        break;
    }

    /* stat-reducing dart traps. */
    case FEAT_TRAP_HEAD + 0x02:
    {
        /* decide if the dart hits. */
        if (check_trap_hit(50 + p_ptr->depth)) {
            /* select a stat to drain. */
            selection = randint0(6);

            Rand_quick = FALSE;

            msg_print("A small dart hits you!");
            dam = damroll(1, 4);
            take_hit(dam, name);

            /* Determine how dangerous the trap is allowed to be. */
            nastyness = randint1(p_ptr->depth);

            /* decide how much to drain the stat by. */
            if ((nastyness > 50) && (randint1(3) == 1)) {
                num = randint1(4);
            } else
                num = 1;

            /* drain the stat. */
            for (i = 0; i < num; i++) {
                (void) do_dec_stat(selection);
            }

            Rand_quick = TRUE;
        } else {
            msg_print("A small dart barely misses you.");
        }
        break;
    }

    /* discolored spots. */
    case FEAT_TRAP_HEAD + 0x03:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(5) == 1)
            nastyness += 10;

        /* pick a elemental attack type. */
        selection = randint1(4);


        /* electicity trap. */
        if (selection == 1) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are struck by lightning!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You get zapped!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            elec_dam(dam, "an electricity trap");
            Rand_quick = TRUE;

        }

        /* frost trap. */
        if (selection == 2) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are lost within a blizzard!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are coated in frost!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            cold_dam(dam, "a frost trap");
            Rand_quick = TRUE;
        }

        /* fire trap. */
        if (selection == 3) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("You are enveloped in a column of fire!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are surrounded by flames!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            fire_dam(dam, "a fire trap");
            Rand_quick = TRUE;
        }

        /* acid trap. */
        if (selection == 4) {
            if ((nastyness >= 50) && (randint1(2) == 1)) {
                Rand_quick = FALSE;

                msg_print("A cauldron of acid is tipped over your head!");
                dam = damroll(6, 30);

                Rand_quick = TRUE;
            } else {
                Rand_quick = FALSE;

                msg_print("You are splashed with acid!");
                dam = damroll(4, 8);

                Rand_quick = TRUE;
            }
            Rand_quick = FALSE;
            acid_dam(dam, "an acid trap");
            Rand_quick = TRUE;
        }

        break;
    }

    /* gas traps. */
    case FEAT_TRAP_HEAD + 0x04:
    {
        selection = randint1(4);

        /* blinding trap. */
        if (selection == 1) {
            msg_print("You are surrounded by a black gas!");
            if (!p_ptr->state.no_blind) {
                Rand_quick = FALSE;

                (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE);

                Rand_quick = TRUE;
            }
        } else
            notice_obj(OF_SEEING, 0);

        /* confusing trap. */
        if (selection == 2) {
            msg_print
            ("You are surrounded by a gas of scintillating colors!");
            if (!p_resist_good(P_RES_CONFU)) {
                Rand_quick = FALSE;

                (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);

                Rand_quick = TRUE;
            } else
                notice_other(IF_RES_CONFU, 0);
        }

        /* poisoning trap. */
        if (selection == 3) {
            msg_print("You are surrounded by a pungent green gas!");

            Rand_quick = FALSE;

            pois_hit(25);

            Rand_quick = TRUE;
        }

        /* sleeping trap. */
        if (selection == 4) {
            msg_print("You are surrounded by a strange white mist!");
            if (!p_ptr->state.free_act) {
                (void) inc_timed(TMD_PARALYZED, randint0(10) + 5, TRUE);
            } else
                notice_obj(OF_FREE_ACT, 0);
        }

        break;
    }

    /* summoning traps. */
    case FEAT_TRAP_HEAD + 0x05:
    {
        sound(MSG_SUM_MONSTER);
        /* sometimes summon thieves. */
        if ((p_ptr->depth > 8) && (randint1(5) == 1)) {
            msg_print("You have aroused a den of thieves!");

            Rand_quick = FALSE;

            num = 2 + randint1(3);
            for (i = 0; i < num; i++) {
                (void) summon_specific(y, x, FALSE, p_ptr->depth,
                                       SUMMON_THIEF);
            }

            Rand_quick = TRUE;
        }

        /* sometimes summon a nasty unique. */
        else if (randint1(8) == 1) {
            msg_print("You are enveloped in a cloud of smoke!");

            Rand_quick = FALSE;

            (void) summon_specific(y, x, FALSE, p_ptr->depth + 5,
                                   SUMMON_UNIQUE);

            Rand_quick = TRUE;
        }

        /* otherwise, the ordinary summon monsters. */
        else {
            msg_print("You are enveloped in a cloud of smoke!");

            Rand_quick = FALSE;

            num = 2 + randint1(3);
            for (i = 0; i < num; i++) {
                (void) summon_specific(y, x, FALSE, p_ptr->depth, 0);
            }

            Rand_quick = TRUE;
        }

        /* these are all one-time traps. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        break;
    }

    /* dungeon alteration traps. */
    case FEAT_TRAP_HEAD + 0x06:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint1(p_ptr->depth);
        if (randint1(5) == 1)
            nastyness += 10;

        /* make room for alterations. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        /* Everything truely random from here on. */
        Rand_quick = FALSE;

        /* dungeon destruction trap. */
        if ((nastyness > 60) && (randint1(12) == 1)) {
            msg_print
            ("A ear-splitting howl shatters your mind as the dungeon is smashed by hammer blows!");

            (void) destroy_level(FALSE);

            /* the player is hard-hit. */
            (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);
            (void) inc_timed(TMD_BLIND, randint0(30) + 15, TRUE);
            (void) inc_timed(TMD_STUN, randint1(50) + 50, TRUE);
            dam = damroll(15, 15);
            take_hit(dam, name);
        }

        /* earthquake trap. */
        else if ((nastyness > 20) && (randint1(4) == 1)) {
            msg_print("A tremor shakes the earth around you");
            earthquake(y, x, 10, FALSE);
        }

        /* falling rock trap. */
        else if ((nastyness > 4) && (randint1(2) == 1)) {
            msg_print("A rock falls on your head.");
            dam = damroll(2, 10);
            take_hit(dam, name);

            (void) inc_timed(TMD_STUN, randint1(10) + 10, TRUE);
        }

        /* a few pebbles. */
        else {
            msg_print("A bunch of pebbles rain down on you.");
            dam = damroll(1, 8);
            take_hit(dam, name);
        }

        Rand_quick = TRUE;

        break;
    }

    /* various char and equipment-alteration traps, lumped together to
     * avoid any one effect being too common (some of them can be rather
     * nasty). */
    case FEAT_TRAP_HEAD + 0x07:
    {
        /* determine how dangerous the trap is allowed to be. */
        nastyness = randint0(100);

        /* these are all one-time traps. */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_FLOOR);

        /* Everything truely random from here on. */
        Rand_quick = FALSE;

        /* trap of drain wands. */
        if (nastyness < 15) {
            /* Hold the object information. */
            object_type *o_ptr;

            /* Find an item */
            for (i = 0; i < 20; i++) {
                /* Pick an item */
                i = randint0(INVEN_PACK - p_ptr->pack_size_reduce);

                /* Obtain the item */
                o_ptr = &p_ptr->inventory[i];

                /* use "num" to decide if a item can be uncharged.  By
                 * default, assume it can't. */
                num = 0;

                /* Skip non-objects */
                if (!o_ptr->k_idx)
                    continue;

                /* Drain charged wands/staffs/rods */
                if ((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)
                        || (o_ptr->tval == TV_ROD)) {
                    /* case of charged wands/staffs. */
                    if (((o_ptr->tval == TV_STAFF)
                            || (o_ptr->tval == TV_WAND)) && (o_ptr->pval))
                        num = 1;

                    /* case of charged rods. */
                    if ((o_ptr->tval == TV_ROD)
                            && (o_ptr->timeout < randcalc(o_ptr->time, 0,
                                                          MINIMISE)))
                        num = 1;


                    if (num == 1) {
                        /* Message */
                        msg_print("Energy drains from your pack!");

                        /* Uncharge */
                        if ((o_ptr->tval == TV_STAFF)
                                || (o_ptr->tval == TV_WAND))
                            o_ptr->pval = 0;

                        if (o_ptr->tval == TV_ROD)
                            o_ptr->timeout = randcalc(o_ptr->time, 0, RANDOMISE) * o_ptr->number * 2;


                        /* Combine / Reorder the pack */
                        p_ptr->notice |= (PN_COMBINE | PN_REORDER);

                        /* not more than one inventory slot effected. */
                        break;
                    } else
                        continue;
                }
            }
        }

        /* trap of forgetting. */
        else if (nastyness < 35) {
            if (check_save(100)) {
                msg_print("You hang on to your memories!");
            } else if (lose_all_info()) {
                msg_print("Your memories fade away.");
            }
        }

        /* trap of alter reality. */
        else if (nastyness < 50) {
            if (OPT(adult_ironman))
                msg_print("Nothing happens.");
            else {
                msg_print("The world changes!");

                /* Leaving */
                p_ptr->leaving = TRUE;
            }
        }

        /* trap of remold player. */
        else if (nastyness < 75) {
            int max1, cur1, max2, cur2, ii, jj;

            msg_print("You feel yourself being twisted by wild magic!");

            if (check_save(100)) {
                msg_print("You resist the effects!");
            } else {
                msg_print("Your body starts to scramble...");

                /* Pick a pair of stats */
                ii = randint0(6);
                for (jj = ii; jj == ii; jj = randint0(6))	/* loop */
                    ;

                max1 = p_ptr->stat_max[ii];
                cur1 = p_ptr->stat_cur[ii];
                max2 = p_ptr->stat_max[jj];
                cur2 = p_ptr->stat_cur[jj];

                p_ptr->stat_max[ii] = max2;
                p_ptr->stat_cur[ii] = cur2;
                p_ptr->stat_max[jj] = max1;
                p_ptr->stat_cur[jj] = cur1;

                p_ptr->update |= (PU_BONUS);
            }
        }

        /* time ball trap. */
        else if (nastyness < 90) {
            msg_print("You feel time itself assault you!");

            /* Target the player with a radius 0 ball attack. */
            fire_meteor(0, GF_TIME, p_ptr->py, p_ptr->px, 75, 0, TRUE);
        }

        /* trap of bugs gone berserk. */
        else {
            /* explain what the dickens is going on. */
            msg_print("GRUESOME Gnawing Bugs leap out at you!");

            if (!p_resist_good(P_RES_CONFU)) {
                (void) inc_timed(TMD_CONFUSED, randint0(20) + 10, TRUE);
            } else
                notice_other(IF_RES_CONFU, 0);

            if (!p_resist_good(P_RES_CHAOS)) {
                (void) inc_timed(TMD_IMAGE, randint1(40), TRUE);
            } else
                notice_other(IF_RES_CHAOS, 0);

            /* XXX (hard coded) summon 3-6 bugs. */
            k = randint1(4) + 2;
            for (i = 0; i < k; ++i) {
                /* Look for a location */
                for (j = 0; j < 20; ++j) {
                    /* Pick a (scattered) distance. */
                    int d = (j / 10) + randint1(3);

                    /* Pick a location */
                    scatter(&y, &x, y, x, d, 0);

                    /* Require passable terrain */
                    if (!cave_passable_bold(y, x))
                        continue;

                    /* Hack -- no summon on glyph of warding */
                    if (cave_feat[y][x] == FEAT_RUNE_PROTECT)
                        continue;

                    /* Okay */
                    break;
                }

                /* Attempt to place the awake bug */
                place_monster_aux(y, x, 453, FALSE, TRUE);
            }

            /* herald the arrival of bugs. */
            msg_print("AAAAAAAHHHH! THEY'RE EVERYWHERE!");
        }

        Rand_quick = TRUE;

        break;
    }

    /* teleport trap */
    case FEAT_TRAP_HEAD + 0x08:
    {
        if (stage_map[p_ptr->stage][STAGE_TYPE] >= CAVE)
            msg_print("You teleport across the dungeon.");
        else
            msg_print("You teleport across the wilderness.");

        Rand_quick = FALSE;

        teleport_player(250, FALSE);

        Rand_quick = TRUE;

        break;
    }

    /* murder holes. */
    case FEAT_TRAP_HEAD + 0x09:
    {
        /* hold the object info. */
        object_type *o_ptr;
        object_type object_type_body;

        /* hold the missile type and name. */
        int sval = 0;
        int tval = 0;
        cptr missile_name = "";



        /* Determine the missile type and base damage. */
        if (randint1(3) == 1) {
            if (p_ptr->depth < 40) {
                missile_name = "shot";
                dam = damroll(2, 3);
                tval = TV_SHOT;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker shot";
                dam = damroll(3, 7);
                tval = TV_SHOT;
                sval = SV_AMMO_HEAVY;
            }
        }

        else if (randint1(2) == 1) {
            if (p_ptr->depth < 55) {
                missile_name = "arrow";
                dam = damroll(2, 4);
                tval = TV_ARROW;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker arrow";
                dam = damroll(3, 9);
                tval = TV_ARROW;
                sval = SV_AMMO_HEAVY;
            }
        }

        else {
            if (p_ptr->depth < 65) {
                missile_name = "bolt";
                dam = damroll(2, 5);
                tval = TV_BOLT;
                sval = SV_AMMO_NORMAL;
            } else {
                missile_name = "seeker bolt";
                dam = damroll(3, 11);
                tval = TV_BOLT;
                sval = SV_AMMO_HEAVY;
            }
        }

        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            msg_format("A %s hits you from above.", missile_name);

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was well-aimed!");
                dam *= 1 + randint1(2);
            }
            if (randint1(2) == 1) {
                msg_print("It gouges you!");
                dam = 3 * dam / 2;

                /* cut the player. */
                (void) inc_timed(TMD_CUT, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_format("A %s wizzes by your head.", missile_name);

        /* these will eventually run out of ammo. */

        Rand_quick = FALSE;

        if (randint0(8) == 0) {
            cave_info[y][x] &= ~(CAVE_MARK);
            cave_set_feat(y, x, FEAT_FLOOR);
        }

        Rand_quick = TRUE;

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

        /* Make a missile, identify it, and drop it near the player. */
        object_prep(o_ptr, lookup_kind(tval, sval), MINIMISE);
        object_aware(o_ptr);
        object_known(o_ptr);
        drop_near(o_ptr, -1, y, x, TRUE);

        break;
    }

    /* falling tree branch */
    case FEAT_TRAP_HEAD + 0x0A:
    {
        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            /* Take damage */
            dam = damroll(3, 5);
            msg_print("A branch hits you from above.");

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was heavy!");
                dam = 3 * dam / 2;

                /* stun the player. */
                (void) inc_timed(TMD_STUN, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_print("A falling branch just misses you.");

        /* No more */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_TREE);

        break;
    }

    /* falling tree branch */
    case FEAT_TRAP_HEAD + 0x0B:
    {
        /* determine if the missile hits. */
        if (check_trap_hit(75 + p_ptr->depth)) {
            /* Take damage */
            dam = damroll(3, 5);
            msg_print("A branch hits you from above.");

            Rand_quick = FALSE;

            /* critical hits. */
            if (randint1(2) == 1) {
                msg_print("It was heavy!");
                dam = 3 * dam / 2;

                /* stun the player. */
                (void) inc_timed(TMD_STUN, randint1(dam), TRUE);
            }

            Rand_quick = TRUE;

            take_hit(dam, name);
        }

        /* Explain what just happened. */
        else
            msg_print("A falling branch just misses you.");

        /* No more */
        cave_info[y][x] &= ~(CAVE_MARK);
        cave_set_feat(y, x, FEAT_TREE2);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0C:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0D:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0E:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    /* undefined trap. */
    case FEAT_TRAP_HEAD + 0x0F:
    {
        msg_print("A dagger is thrown at you from the shadows!");
        dam = damroll(3, 4);
        take_hit(dam, name);

        break;
    }

    }

    /* Revert to usage of the complex RNG. */
    Rand_quick = FALSE;
}
Ejemplo n.º 5
0
/*!
 * @brief アイテムの質を選択して再生成する /
 * Apply magic to an item or turn it into an artifact. -Bernd-
 * @param o_ptr 再生成の対象となるアイテム情報の参照ポインタ
 * @return なし
 */
static void wiz_reroll_item(object_type *o_ptr)
{
	object_type forge;
	object_type *q_ptr;

	char ch;

	bool changed = FALSE;


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


	/* Get local object */
	q_ptr = &forge;

	/* Copy the object */
	object_copy(q_ptr, o_ptr);


	/* Main loop. Ask for magification and artifactification */
	while (TRUE)
	{
		/* Display full item debug information */
		wiz_display_item(q_ptr);

		/* Ask wizard what to do. */
		if (!get_com("[a]ccept, [w]orthless, [c]ursed, [n]ormal, [g]ood, [e]xcellent, [s]pecial? ", &ch, FALSE))
		{
			/* Preserve wizard-generated artifacts */
			if (object_is_fixed_artifact(q_ptr))
			{
				a_info[q_ptr->name1].cur_num = 0;
				q_ptr->name1 = 0;
			}

			changed = FALSE;
			break;
		}

		/* Create/change it! */
		if (ch == 'A' || ch == 'a')
		{
			changed = TRUE;
			break;
		}

		/* Preserve wizard-generated artifacts */
		if (object_is_fixed_artifact(q_ptr))
		{
			a_info[q_ptr->name1].cur_num = 0;
			q_ptr->name1 = 0;
		}

		switch(ch)
		{
			/* Apply bad magic, but first clear object */
			case 'w': case 'W':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_NO_FIXED_ART | AM_GOOD | AM_GREAT | AM_CURSED);
				break;
			}
			/* Apply bad magic, but first clear object */
			case 'c': case 'C':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_NO_FIXED_ART | AM_GOOD | AM_CURSED);
				break;
			}
			/* Apply normal magic, but first clear object */
			case 'n': case 'N':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_NO_FIXED_ART);
				break;
			}
			/* Apply good magic, but first clear object */
			case 'g': case 'G':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_NO_FIXED_ART | AM_GOOD);
				break;
			}
			/* Apply great magic, but first clear object */
			case 'e': case 'E':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_NO_FIXED_ART | AM_GOOD | AM_GREAT);
				break;
			}
			/* Apply special magic, but first clear object */
			case 's': case 'S':
			{
				object_prep(q_ptr, o_ptr->k_idx);
				apply_magic(q_ptr, dun_level, AM_GOOD | AM_GREAT | AM_SPECIAL);

				/* Failed to create artifact; make a random one */
				if (!object_is_artifact(q_ptr)) create_artifact(q_ptr, FALSE);
				break;
			}
		}
		q_ptr->iy = o_ptr->iy;
		q_ptr->ix = o_ptr->ix;
		q_ptr->next_o_idx = o_ptr->next_o_idx;
		q_ptr->marked = o_ptr->marked;
	}


	/* Notice change */
	if (changed)
	{
		/* Apply changes */
		object_copy(o_ptr, q_ptr);

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

		/* Combine / Reorder the pack (later) */
		p_ptr->notice |= (PN_COMBINE | PN_REORDER);

		/* Window stuff */
		p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
	}
}
Ejemplo n.º 6
0
/*
 * Init players with some belongings
 *
 * Having an item identifies it and makes the player "aware" of its purpose.
 */
static void player_outfit(void)
{
	int i, slot, inven_slot;
	const start_item *e_ptr;
	object_type *i_ptr;
	object_type object_type_body;
	object_type *o_ptr;
	
	time_t c;       // time variables
	struct tm *tp;  //

	/* Hack -- Give the player his equipment */
	for (i = 0; i < MAX_START_ITEMS; i++)
	{
		/* Access the item */
		e_ptr = &(rp_ptr->start_items[i]);

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

		/* Hack	-- Give the player an object */
		if (e_ptr->tval > 0)
		{
			/* Get the object_kind */
			s16b k_idx = lookup_kind(e_ptr->tval, e_ptr->sval);

			/* Valid item? */
			if (!k_idx) continue;

			/* Prepare the item */
			object_prep(i_ptr, k_idx);
			i_ptr->number = (byte)rand_range(e_ptr->min, e_ptr->max);

			//object_aware(i_ptr);
			//object_known(i_ptr);
		}

		/* Check the slot */
		slot = wield_slot(i_ptr);
		
		/* give light sources a duration */
		if (slot == INVEN_LITE)
		{
			i_ptr->timeout = 2000;
		}

		/*put it in the inventory*/
		inven_slot = inven_carry(i_ptr);

		/*if player can wield an item, do so*/
		if (slot >= INVEN_WIELD)
		{
			/* Get the wield slot */
			o_ptr = &inventory[slot];

			/* Wear the new stuff */
			object_copy(o_ptr, i_ptr);

			/* Modify quantity */
			o_ptr->number = 1;

			/* Decrease the item */
			inven_item_increase(inven_slot, -1);
			inven_item_optimize(inven_slot);

			/* Increment the equip counter by hand */
			p_ptr->equip_cnt++;
		}

		/*Bugfix:  So we don't get duplicate objects*/
		object_wipe (i_ptr);

	}

	// Christmas presents:
	
	/* Make sure it is Dec 24-26 */
	c = time((time_t *)0);
	tp = localtime(&c);
	if ((tp->tm_mon == 11) && (tp->tm_mday >= 20) && (tp->tm_mday <= 31))
	{
		/* Get local object */
		i_ptr = &object_type_body;
		
		/* Get the object_kind */
		s16b k_idx = lookup_kind(TV_CHEST, SV_CHEST_PRESENT);
		
		/* Prepare the item */
		object_prep(i_ptr, k_idx);
		i_ptr->number = 1;
		i_ptr->pval = -20;
		
		//object_aware(i_ptr);
		//object_known(i_ptr);
		
		/*put it in the inventory*/
		inven_slot = inven_carry(i_ptr);
	}


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

	/* Recalculate mana */
	p_ptr->update |= (PU_MANA);

	/* Window stuff */
	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER_0);

	p_ptr->redraw |= (PR_EQUIPPY | PR_RESIST);;
}
Ejemplo n.º 7
0
/*
 * Apply magic to an item or turn it into an artifact. -Bernd-
 */
static void wiz_reroll_item(object_type *o_ptr)
{
	object_type *i_ptr;
	object_type object_type_body;

	char ch;

	bool changed = FALSE;


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


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

	/* Copy the object */
	object_copy(i_ptr, o_ptr);


	/* Main loop. Ask for magification and artifactification */
	while (TRUE)
	{
		/* Display full item debug information */
		wiz_display_item(i_ptr, TRUE);

		/* Ask wizard what to do. */
		if (!get_com("[a]ccept, [n]ormal, [g]ood, [e]xcellent? ", &ch))
			break;

		/* Create/change it! */
		if (ch == 'A' || ch == 'a')
		{
			changed = TRUE;
			break;
		}

		/* Apply normal magic, but first clear object */
		else if (ch == 'n' || ch == 'N')
		{
			object_prep(i_ptr, o_ptr->kind, p_ptr->depth, RANDOMISE);
			apply_magic(i_ptr, p_ptr->depth, FALSE, FALSE, FALSE);
		}

		/* Apply good magic, but first clear object */
		else if (ch == 'g' || ch == 'g')
		{
			object_prep(i_ptr, o_ptr->kind, p_ptr->depth, RANDOMISE);
			apply_magic(i_ptr, p_ptr->depth, FALSE, TRUE, FALSE);
		}

		/* Apply great magic, but first clear object */
		else if (ch == 'e' || ch == 'e')
		{
			object_prep(i_ptr, o_ptr->kind, p_ptr->depth, RANDOMISE);
			apply_magic(i_ptr, p_ptr->depth, FALSE, TRUE, TRUE);
		}
	}


	/* Notice change */
	if (changed)
	{
		/* Mark as cheat */
		i_ptr->origin = ORIGIN_CHEAT;

		/* Restore the position information */
		i_ptr->iy = o_ptr->iy;
		i_ptr->ix = o_ptr->ix;
		i_ptr->next_o_idx = o_ptr->next_o_idx;
		i_ptr->marked = o_ptr->marked;

		/* Apply changes */
		object_copy(o_ptr, i_ptr);

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

		/* Combine / Reorder the pack (later) */
		p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);

		/* Window stuff */
		p_ptr->redraw |= (PR_INVEN | PR_EQUIP );
	}
}
Ejemplo n.º 8
0
/**
 * 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;
}
/*
 * Allocates some objects (using "place" and "type")
 */
static void alloc_object(int set, int typ, int num)
{
    int y = 0, x = 0, k;

    /* A small level has few objects. */
    num = MAX(1, num * cur_hgt * cur_wid / (MAX_HGT*MAX_WID));

    /* Diligent players should be encouraged to explore more! */
    if (typ == ALLOC_TYP_OBJECT || typ == ALLOC_TYP_GOLD)
        num = num * (625 + virtue_current(VIRTUE_DILIGENCE)) / 625;

    for (k = 0; k < num; k++)
    {
        object_type forge;
        int         k_idx;

        if (!_get_loc(set, &x, &y))
        {
            if (cheat_room)
                msg_print("Warning! Could not place object!");

            return;
        }

        switch (typ)
        {
        case ALLOC_TYP_RUBBLE:
            place_rubble(y, x);
            cave[y][x].info &= ~(CAVE_FLOOR);
            break;

        case ALLOC_TYP_TRAP:
            place_trap(y, x);
            cave[y][x].info &= ~(CAVE_FLOOR);
            break;

        case ALLOC_TYP_GOLD:
            place_gold(y, x);
            break;

        case ALLOC_TYP_OBJECT:
            /* Comment: Monsters drop objects at (ML + DL)/2. In practice,
               this means that your best drops are just laying on the ground,
               and this encourages recall scumming for end game resources such
               as wands of rockets. Note: Vaults are not affected and we want
               to encourage these! Room templates need some thought ... */
            if (base_level > 31)
            {
               int n = base_level - 30;
               object_level = 30 + n/2 + randint1(n/2);
            }
            else
                object_level = base_level; /* paranoia */
            place_object(y, x, 0L);
            object_level = base_level;
            break;

        case ALLOC_TYP_FOOD:
            if (prace_is_(RACE_ENT))
                k_idx = lookup_kind(TV_POTION, SV_POTION_WATER);
            else
                k_idx = lookup_kind(TV_FOOD, SV_FOOD_RATION);
            object_prep(&forge, k_idx);
            obj_make_pile(&forge);
            drop_near(&forge, -1, y, x);
            break;

        case ALLOC_TYP_LIGHT:
            if (one_in_(3))
                k_idx = lookup_kind(TV_FLASK, SV_FLASK_OIL);
            else
                k_idx = lookup_kind(TV_LITE, SV_LITE_LANTERN);
            object_prep(&forge, k_idx);
            apply_magic(&forge, dun_level, 0);
            obj_make_pile(&forge);
            drop_near(&forge, -1, y, x);
            break;

        case ALLOC_TYP_RECALL:
            k_idx = lookup_kind(TV_SCROLL, SV_SCROLL_WORD_OF_RECALL);
            object_prep(&forge, k_idx);
            /*obj_make_pile(&forge);*/
            drop_near(&forge, -1, y, x);
            break;

        case ALLOC_TYP_SKELETON:
            k_idx = lookup_kind(TV_CORPSE, SV_SKELETON);
            object_prep(&forge, k_idx);
            apply_magic(&forge, dun_level, 0);
            drop_near(&forge, -1, y, x);
            break;
        }
    }
}
Ejemplo n.º 10
0
/**
 * Attempts to place a copy of the given monster at the given position in
 * the dungeon.
 *
 * All of the monster placement routines eventually call this function. This
 * is what actually puts the monster in the dungeon (i.e., it notifies the cave
 * and sets the monsters position). The dungeon loading code also calls this
 * function directly.
 *
 * `origin` is the item origin to use for any monster drops (e.g. ORIGIN_DROP,
 * ORIGIN_DROP_PIT, etc.) The dungeon loading code calls this with origin = 0,
 * which prevents the monster's drops from being generated again.
 *
 * Returns the m_idx of the newly copied monster, or 0 if the placement fails.
 */
s16b place_monster(struct chunk *c, int y, int x, struct monster *mon,
				   byte origin)
{
	s16b m_idx;
	struct monster *new_mon;

	assert(square_in_bounds(c, y, x));
	assert(!square_monster(c, y, x));

	/* Get a new record */
	m_idx = mon_pop(c);
	if (!m_idx) return 0;

	/* Copy the monster */
	new_mon = cave_monster(c, m_idx);
	memcpy(new_mon, mon, sizeof(struct monster));

	/* Set the ID */
	new_mon->midx = m_idx;

	/* Set the location */
	c->squares[y][x].mon = new_mon->midx;
	new_mon->fy = y;
	new_mon->fx = x;
	assert(square_monster(c, y, x) == new_mon);

	update_mon(new_mon, c, true);

	/* Hack -- Count the number of "reproducers" */
	if (rf_has(new_mon->race->flags, RF_MULTIPLY)) num_repro++;

	/* Count racial occurrences */
	new_mon->race->cur_num++;

	/* Create the monster's drop, if any */
	if (origin)
		(void)mon_create_drop(c, new_mon, origin);

	/* Make mimics start mimicking */
	if (origin && new_mon->race->mimic_kinds) {
		struct object *obj;
		struct object_kind *kind = new_mon->race->mimic_kinds->kind;
		struct monster_mimic *mimic_kind;
		int i = 1;

		/* Pick a random object kind to mimic */
		for (mimic_kind = new_mon->race->mimic_kinds; mimic_kind; 
				mimic_kind = mimic_kind->next, i++) {
			if (one_in_(i)) kind = mimic_kind->kind;
		}

		if (tval_is_money_k(kind)) {
			obj = make_gold(player->depth, kind->name);
		} else {
			obj = object_new();
			object_prep(obj, kind, new_mon->race->level, RANDOMISE);
			apply_magic(obj, new_mon->race->level, true, false, false, false);
			obj->number = 1;
			obj->origin = ORIGIN_DROP_MIMIC;
			obj->origin_depth = player->depth;
		}

		obj->mimicking_m_idx = m_idx;
		new_mon->mimicked_obj = obj;

		/* Put the object on the floor if it goes, otherwise no mimicry */
		if (floor_carry(c, y, x, obj, false)) {
			list_object(c, obj);
		} else {
			/* Clear the mimicry */
			obj->mimicking_m_idx = 0;
			new_mon->mimicked_obj = NULL;

			/* Give the object to the monster if appropriate */
			if (rf_has(new_mon->race->flags, RF_MIMIC_INV)) {
				monster_carry(c, new_mon, obj);
			} else {
				/* Otherwise delete the mimicked object */
				object_delete(&obj);
			}
		}
	}

	/* Result */
	return m_idx;
}
Ejemplo n.º 11
0
/*
 * Describe the kind
 */
static void kind_info(char *buf, char *dam, char *wgt, int *lev, s32b *val, int k)
{
	object_kind *k_ptr;

	object_type *i_ptr;
	object_type object_type_body;


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

	/* Prepare a fake item */
	object_prep(i_ptr, k);

	/* Obtain the "kind" info */
	k_ptr = &k_info[i_ptr->k_idx];

	/* It is known */
	i_ptr->ident |= (IDENT_KNOWN);

	/* Cancel bonuses */
	i_ptr->pval = 0;
	i_ptr->to_a = 0;
	i_ptr->to_h = 0;
	i_ptr->to_d = 0;


	/* Level */
	(*lev) = k_ptr->level;

	/* Value - use only base value with no modifications */
	(*val) = k_ptr->cost;


	/* Hack */
	if (!buf || !dam || !wgt) return;


	/* Description (too brief) */
	object_desc_store(buf, sizeof(buf), i_ptr, FALSE, 0);


	/* Misc info */
	strcpy(dam, "");

	/* Damage */
	switch (i_ptr->tval)
	{
		/* Bows */
		case TV_SLING:
		case TV_BOW:
		case TV_CROSSBOW:
		{
			break;
		}

		/* Ammo */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		{
			(void)strnfmt(dam, 32, "%dd%d", i_ptr->dd, i_ptr->ds);
			break;
		}

		/* Weapons */
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			(void)strnfmt(dam, 32, "%dd%d", i_ptr->dd, i_ptr->ds);
			break;
		}

		/* Armor */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			(void)strnfmt(dam, 32, "%d", i_ptr->ac);
			break;
		}
	}


	/* Weight */
	if (use_metric)
	{
		(void)strnfmt(wgt, 32, "%3d.%d", make_metric(i_ptr->weight) / 10,
			make_metric(i_ptr->weight) % 10);
	}
	else
	{
		(void)strnfmt(wgt, 32, "%3d.%d", i_ptr->weight / 10, i_ptr->weight % 10);
	}

}
Ejemplo n.º 12
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);

	/* 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));
		if (drop->artifact) {
			object_prep(obj, lookup_kind(drop->artifact->tval,
				drop->artifact->sval), level, RANDOMISE);
			obj->artifact = drop->artifact;
			copy_artifact_data(obj, obj->artifact);
			obj->artifact->created = true;
		} else {
			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_xtra = mon->race->ridx;
		obj->number = randint0(drop->max - drop->min) + drop->min;

		/* Try to carry */
		if (monster_carry(c, mon, obj)) {
			any = true;
		} else {
			obj->artifact->created = false;
			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_xtra = mon->race->ridx;

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

	return any;
}
Ejemplo n.º 13
0
/*
 * Handle the "death" of a monster.
 *
 * Disperse treasures centered at the monster location based on the
 * various flags contained in the monster flags fields.
 *
 * Check for "Quest" completion when a quest monster is killed.
 *
 * Note that only the player can induce "monster_death()" on Uniques or quest monsters.
 *
 * Note that monsters can now carry objects, and when a monster dies,
 * it drops all of its objects, which may disappear in crowded rooms.
 */
void monster_death(int m_idx, int who)
{
	int i, j, y, x;

	int dump_item = 0;
	int dump_gold = 0;

	int number_drops = 0;
	int total = 0;

	bool questlevel = FALSE;
	bool completed = FALSE;
	bool fixedquest = FALSE;
	bool writenote = TRUE;
	bool need_stairs = FALSE;

	s16b set_object_level;

	s16b this_o_idx, next_o_idx = 0;

	monster_type *m_ptr = &mon_list[m_idx];

	monster_race *r_ptr = &r_info[m_ptr->r_idx];

	bool visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE)));

	bool chest = (r_ptr->flags1 & (RF1_DROP_CHEST)) ? TRUE : FALSE;
	bool good = (r_ptr->flags1 & (RF1_DROP_GOOD)) ? TRUE : FALSE;
	bool great = (r_ptr->flags1 & (RF1_DROP_GREAT)) ? TRUE : FALSE;

	bool do_gold = (!(r_ptr->flags1 & (RF1_ONLY_ITEM)));
	bool do_item = (!(r_ptr->flags1 & (RF1_ONLY_GOLD)));

	int force_coin = get_coin_type(r_ptr);

	object_type *i_ptr;
	object_type object_type_body;

	/* Get the location */
	y = m_ptr->fy;
	x = m_ptr->fx;

	/* Drop objects being carried */
	for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
	{
		object_type *o_ptr;

		/* Get the object */
		o_ptr = &o_list[this_o_idx];

		/*Remove the mark to hide when monsters carry this object*/
		o_ptr->ident &= ~(IDENT_HIDE_CARRY);

		/* Get the next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Paranoia */
		o_ptr->held_m_idx = 0;

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

		/* Copy the object */
		object_copy(i_ptr, o_ptr);

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

		/* Drop it */
		drop_near(i_ptr, -1, y, x);
	}

	/* Forget objects */
	m_ptr->hold_o_idx = 0;

	/* Mega-Hack -- drop "winner" treasures */
	if (r_ptr->flags1 & (RF1_DROP_CHOSEN))
	{
		/* Get local object */
		i_ptr = &object_type_body;

		/* Mega-Hack -- Prepare to make "Grond" */
		object_prep(i_ptr, lookup_kind(TV_HAFTED, SV_GROND));

		/* Mega-Hack -- Mark this item as "Grond" */
		i_ptr->art_num = ART_GROND;

		/* Mega-Hack -- Actually create "Grond" */
		apply_magic(i_ptr, -1, TRUE, TRUE, TRUE, FALSE);

		/* Remember history */
		object_history(i_ptr, ORIGIN_MORGOTH, 0);

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);

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

		/* Mega-Hack -- Prepare to make "Morgoth's crown" */
		object_prep(i_ptr, lookup_kind(TV_CROWN, SV_MORGOTH));

		/* Mega-Hack -- Mark this item as "Morgoth" */
		i_ptr->art_num = ART_MORGOTH;

		/* Mega-Hack -- Actually create "Morgoth" */
		apply_magic(i_ptr, -1, TRUE, TRUE, TRUE, FALSE);

		/* Remember history */
		object_history(i_ptr, ORIGIN_MORGOTH, 0);

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);
	}


	/* Determine how much we can drop */
	if ((r_ptr->flags1 & (RF1_DROP_60)) && (rand_int(100) < 60)) number_drops++;
	if ((r_ptr->flags1 & (RF1_DROP_90)) && (rand_int(100) < 90)) number_drops++;
	if (r_ptr->flags1 & (RF1_DROP_1D2)) number_drops += damroll(1, 2);
	if (r_ptr->flags1 & (RF1_DROP_2D2)) number_drops += damroll(2, 2);
	if (r_ptr->flags1 & (RF1_DROP_3D2)) number_drops += damroll(3, 2);
	if (r_ptr->flags1 & (RF1_DROP_4D2)) number_drops += damroll(4, 2);

	/* Hack -- handle creeping coins */
	coin_type = force_coin;

	/* Average dungeon and monster levels */
	set_object_level = object_level = (effective_depth(p_ptr->depth) + r_ptr->level) / 2;

	/* Drop some objects */
	for (j = 0; j < number_drops; j++)
	{
		bool interesting = FALSE;

		/* Re-set the object level */
		object_level = set_object_level;

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

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

		/* work on the "too much junk" problem, large drops sometimes are less items with a "boost". */
		if ((randint(750) < (number_drops * number_drops)) && (!(r_ptr->flags1 & (RF1_UNIQUE))))
		{
			interesting = TRUE;
			number_drops -= 5;
			object_level += 5;

			/*Boundry Control*/
			if (number_drops < 0) number_drops = 0;
			if (object_level > MAX_DEPTH) object_level = MAX_DEPTH;
		}

		/* Make Gold */
		if (do_gold && (!chest) && (!do_item || (rand_int(100) < 70)))
		{
			/* Make some gold */
			if (!make_gold(i_ptr)) continue;

			/* Assume seen XXX XXX XXX */
			dump_gold++;
		}

		/* Make Object */
		else
		{
			if (chest)
			{
				if (!make_object(i_ptr, good, great, DROP_TYPE_CHEST, FALSE)) continue;
			}

			/* Make an object */
			else if (!make_object(i_ptr, good, great, DROP_TYPE_UNTHEMED, interesting)) continue;

			/* Remember history */
			if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx);
			else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0);

			/* Assume seen XXX XXX XXX */
			dump_item++;
		}

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);
	}

	/* Re-set the object level */
	object_level = set_object_level;

	/*If marked for a bonus item, create it and drop it */
	if (m_ptr->mflag & (MFLAG_BONUS_ITEM))
	{
		bool this_good = good;
		bool this_great = great;
		bool this_chest = chest;
		bool interesting = FALSE;

		char o_name[80];

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

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

		if (one_in_(50)) this_chest = TRUE;
		if (one_in_(15)) this_great = TRUE;
		if (one_in_(5)) this_good = TRUE;
		if ((!this_good) && (!this_great) && (!this_chest))
		{
			object_level += 5;
			if (object_level > MAX_DEPTH) object_level = MAX_DEPTH;
			interesting = TRUE;
		}

		if (this_chest)
		{
			while (!make_object(i_ptr, TRUE, TRUE, DROP_TYPE_CHEST, FALSE)) continue;
		}

		/* Make an object */
		else while (!make_object(i_ptr, this_good, this_good, DROP_TYPE_UNTHEMED, interesting)) continue;

		/* Remember history */
		if (visible) object_history(i_ptr, ORIGIN_DROP_KNOWN, m_ptr->r_idx);
		else object_history(i_ptr, ORIGIN_DROP_UNKNOWN, 0);

		object_desc(o_name, sizeof(o_name), i_ptr, ODESC_PREFIX | ODESC_FULL);

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);


	}

	/* Reset the object level */
	object_level = effective_depth(p_ptr->depth);

	/* Reset "coin" type */
	coin_type = 0;

	/* Take note of any dropped treasure */
	if (visible && (dump_item || dump_gold))
	{
		/* Take notes on treasure */
		lore_treasure(m_idx, dump_item, dump_gold);
	}

	/* Update monster list window */
	p_ptr->redraw |= (PR_MONLIST);

	/* Count incomplete quests */
	for (i = 0; i < z_info->q_max; i++)
	{
		quest_type *q_ptr = &q_info[i];

		/*
		 * Hack - don't count if player didn't kill, or on a town level
		 * This assumes only a player can kill quest monsters!!!!!
		 * This line is also ugly coding. :)
		 */
		if (((who != SOURCE_PLAYER) && (who != SOURCE_TRAP)) || (!p_ptr->depth)) continue;

		/* Quest level? */
		if ((q_ptr->active_level == p_ptr->depth) && (p_ptr->depth > 0))
		{
			/* One on the level */
			questlevel = TRUE;

			/* Require "Quest Monsters" */
			if 	(q_ptr->mon_idx == m_ptr->r_idx)
			{
				char race_name[80];

				/* Get the monster race name (singular)*/
				monster_desc_race(race_name, sizeof(race_name), q_ptr->mon_idx);

				/* Mark kills */
				q_ptr->cur_num++;

				/* Redraw quest indicator */
				p_ptr->redraw |= (PR_QUEST_ST);

				/* Completed quest? */
				if (q_ptr->cur_num == q_ptr->max_num)
				{
					/* Mark complete */
					q_ptr->active_level = 0;

					/* Mark fixed quests */
					if ((q_ptr->q_type == QUEST_FIXED) ||
						(q_ptr->q_type == QUEST_FIXED_U))
						fixedquest = TRUE;

					if (q_ptr->q_type == QUEST_GUARDIAN) need_stairs = TRUE;

					/* One complete */
					completed = TRUE;

					/*make a note of the completed quest, but not for fixed or
				     * fixed unique quests
					 */
					if ((adult_take_notes) && (!fixedquest))
					{
						char note[120];

						/* Multiple quest monsters */
						if (q_ptr->max_num > 1)
						{
							plural_aux(race_name, sizeof(race_name));
						}

						if (r_ptr->flags1 & (RF1_UNIQUE))
						{
							/*write note*/
							if monster_nonliving(r_ptr)
								sprintf(note, "Quest: Destroyed %s", race_name);
							else sprintf(note, "Quest: Killed %s", race_name);
						}

						else
						{
							/* Write note */
							if monster_nonliving(r_ptr)
Ejemplo n.º 14
0
void WizardModeDialog::wiz_winners_kit(void)
{
    if (!character_dungeon) return;

    if (game_mode == GAME_NPPMORIA)
    {
        // Make 2 rings of speed
        int k_idx = lookup_kind(TV_RING, SV_RING_SPEED);
        object_type object_type_body;
        object_type *i_ptr = &object_type_body;
        i_ptr->object_wipe();
        if (k_idx)
        {
            object_prep(i_ptr, k_idx);
            apply_magic(i_ptr, k_info[k_idx].k_level, FALSE, TRUE, TRUE, TRUE);
            i_ptr->number = 2;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        //Give an amulet of the magi;
        k_idx = lookup_kind(TV_AMULET, SV_AMULET_THE_MAGI);
        if (k_idx)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            apply_magic(i_ptr, k_info[k_idx].k_level, FALSE, TRUE, TRUE, TRUE);
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        //boots of speed
        k_idx = lookup_kind(TV_BOOTS, SV_PAIR_OF_SOFT_LEATHER_BOOTS);
        int ego_num = lookup_ego(TV_BOOTS, SV_PAIR_OF_SOFT_LEATHER_BOOTS, "speed");
        if (k_idx && ego_num)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            i_ptr->ego_num = ego_num;
            a_m_aux_2(i_ptr, k_info[k_idx].k_level, 2);
            apply_ego_item_magic(i_ptr, k_info[k_idx].k_level);
            i_ptr->to_a = 25;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        // Robe of Resistance
        k_idx = lookup_kind(TV_SOFT_ARMOR, SV_ROBE);
        ego_num = lookup_ego(TV_SOFT_ARMOR, SV_ROBE, "resistance");
        if (k_idx && ego_num)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            i_ptr->ego_num = ego_num;
            a_m_aux_2(i_ptr, k_info[k_idx].k_level, 2);
            apply_ego_item_magic(i_ptr, k_info[k_idx].k_level);
            i_ptr->to_a = 25;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        // super-charged holy avenger dagger
        k_idx = lookup_kind(TV_SWORD, SV_DAGGER);
        ego_num = lookup_ego(TV_SWORD, SV_DAGGER, "holy avenger");
        if (k_idx && ego_num)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            i_ptr->ego_num = ego_num;
            a_m_aux_1(i_ptr, k_info[k_idx].k_level, 2);
            apply_ego_item_magic(i_ptr, k_info[k_idx].k_level);
            i_ptr->to_a = i_ptr->to_h = i_ptr->to_d = 25;
            i_ptr->dd = i_ptr->ds = 9;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        // crown of the magi
        k_idx = lookup_kind(TV_CROWN, SV_SILVER_CROWN);
        ego_num = lookup_ego(TV_CROWN, SV_SILVER_CROWN, "magi");
        if (k_idx && ego_num)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            i_ptr->ego_num = ego_num;
            a_m_aux_2(i_ptr, k_info[k_idx].k_level, 2);
            apply_ego_item_magic(i_ptr, k_info[k_idx].k_level);
            i_ptr->to_a = 25;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        // super charged gloves of slaying
        k_idx = lookup_kind(TV_GLOVES, SV_SET_OF_LEATHER_GLOVES);
        ego_num = lookup_ego(TV_GLOVES, SV_SET_OF_LEATHER_GLOVES, "slaying");
        if (k_idx && ego_num)
        {
            i_ptr->object_wipe();
            object_prep(i_ptr, k_idx);
            i_ptr->ego_num = ego_num;
            a_m_aux_2(i_ptr, k_info[k_idx].k_level, 2);
            apply_ego_item_magic(i_ptr, k_info[k_idx].k_level);
            i_ptr->to_a = i_ptr->to_h = i_ptr->to_d = 25;
            i_ptr->mark_fully_known(TRUE);
            object_history(i_ptr, ORIGIN_CHEAT, 0);
            if(inven_carry(i_ptr) < 0)
            {
                drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
            }
        }
        //finally the Phial
        if (TRUE)
        {
            i_ptr->object_wipe();
            if (wiz_alloc_artifact(i_ptr, 1))
            {
                object_history(i_ptr, ORIGIN_CHEAT, 0);
                identify_object(i_ptr, true);
                if(inven_carry(i_ptr) < 0)
                {
                    drop_near(i_ptr, -1, p_ptr->py, p_ptr->px);
                }
            }
        }

        handle_stuff();
        this->accept();
        return;

    }

    else if (game_mode != GAME_NPPANGBAND) return;

    int artis[] = {
        47,     // RINGIL
        124,    // CUBRAGOL
        13,     // NARYA
        14,     // NENYA
        10,     // ELESSAR
        12,     // GEM OF AMON SUL
        38,     // BLADETUNDER
        113,    // COLANNON
        33,     // THORIN
        110,    // NUMENOR
        129,    // CAMBELEG
        127,    // FEANOR
        0
    };

    object_type obj;
    object_type *o_ptr = &obj;

    for (int i = 0; artis[i]; i++)
    {
        o_ptr->object_wipe();
        if (!wiz_alloc_artifact(o_ptr, artis[i])) continue;
        object_history(o_ptr, ORIGIN_CHEAT, 0);
        identify_object(o_ptr, true);
        if (inven_carry(o_ptr) < 0)
        {
            drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
        }
        QString name = object_desc(o_ptr, ODESC_PREFIX | ODESC_FULL);
        message("Allocated " + name);
    }

    //Some amazing ammo;
    int k_idx = lookup_kind(TV_BOLT, SV_AMMO_MITHRIL);
    int ego_num = lookup_ego(TV_BOLT, SV_AMMO_MITHRIL, "holy might");
    if (k_idx && ego_num)
    {
        o_ptr->object_wipe();
        object_prep(o_ptr, k_idx);
        o_ptr->ego_num = ego_num;
        a_m_aux_1(o_ptr, k_info[k_idx].k_level, 2);
        apply_ego_item_magic(o_ptr, k_info[k_idx].k_level);
        o_ptr->to_h = 99;
        o_ptr->to_d = 99;
        o_ptr->dd = 25;
        o_ptr->ds = 25;
        o_ptr->number = 99;
        o_ptr->mark_fully_known(TRUE);
        object_history(o_ptr, ORIGIN_CHEAT, 0);
        if(inven_carry(o_ptr) < 0)
        {
            drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);
        }
    }

    handle_stuff();

    this->accept();
}
Ejemplo n.º 15
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 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;
}
Ejemplo n.º 16
0
void apply_magic(object_type *o_ptr, s32b lev, bool okay, bool good, bool great)
{
	s32b i, power;
	object_kind *k_ptr = &k_info[o_ptr->k_idx];

	/* Uses level */
	flags_mbonus_level = lev;

	call_lua("objects_get_power_level", "(O,d,b,b,b)", "d", o_ptr, lev, okay, good, great, &power);

	/* Initialize books */
	if (has_flag(o_ptr, FLAG_GET_BOOK_SPELLS))
	{
		call_lua("setup_object_spells", "(O,d)", "", o_ptr, get_flag(o_ptr, FLAG_GET_BOOK_SPELLS));
	}

	/* No need to touch normal artifacts */
	if ((has_flag(k_ptr, FLAG_NORM_ART)))
	{
		/* Ahah! we tried to trick us !! */
		if (k_ptr->artifact ||
		                (((has_flag(k_ptr, FLAG_SPECIAL_GENE))) &&
		                 (!k_allow_special[o_ptr->k_idx])))
		{
			object_prep(o_ptr, lookup_kind(get_flag(k_ptr, FLAG_NORM_ART), flag_get2(&k_ptr->flags, FLAG_NORM_ART)));
			if (wizard) msg_print("We've been tricked!");
		}
		else
		{
			k_ptr->artifact = TRUE;

			if (cheat_peek || p_ptr->precognition) object_mention(o_ptr);
		}

		/* Reset to default */
		flags_mbonus_level = -1;
		return;
	}

	/* Mega hack */
	if (hack_apply_magic_power)
	{
		if (hack_apply_magic_power == -99)
			power = 0;
		else
			power = hack_apply_magic_power;
	}
	hack_apply_magic_power = 0;

	o_ptr->elevel = 1;
	o_ptr->exp = 0;

	/* Special make code */
	invoke_on_make(&k_ptr->flags, o_ptr, power);

	/* Generic on make for all items */
	invoke_on_make_all_pre(o_ptr, power);

	/* Hack -- analyze artifacts */
	if (o_ptr->artifact_id)
	{
		artifact_type *a_ptr = &a_info[o_ptr->artifact_id];

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

		/* Extract the other fields */
		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;
		o_ptr->number = 1;

                /* Transfer flags */
		flag_add(&o_ptr->flags, &a_ptr->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 ((cheat_peek) || (p_ptr->precognition)) object_mention(o_ptr);

		/* Special make code */
		invoke_on_make(&a_ptr->flags, o_ptr, power);
		invoke_on_make_all(o_ptr, power);

		/* Hack -- extract the "cursed" flag */
		if (has_flag(o_ptr, FLAG_CURSED)) o_ptr->ident |= (IDENT_CURSED);

		/* Done */
		/* Reset to default */
		flags_mbonus_level = -1;
		return;
	}


	if (o_ptr->art_name) rating += 40;

	/* Analyze ego-items */
	else
	{
		ego_item_type *e_ptr;
		s32b j;
		s16b e_idx;
		bool did_ego = FALSE;

		for (i = 0; i < MAX_EGO_PER_OBJ; i++)
		{
			e_idx = o_ptr->ego_id[i];
			if (!e_idx) continue;
			did_ego = TRUE;
			e_ptr = &e_info[e_idx];

			/* Hack -- extra powers */
			for (j = 0; j < MAX_EGO_FLAG_GROUPS; j++)
			{
				/* Rarity check */
				if (magik(e_ptr->rar[j]))
				{
					/* Copy all flags */
					flag_add(&o_ptr->flags, &e_ptr->flags[j]);

					/* Special make code */
					invoke_on_make(&e_ptr->flags[j], o_ptr, power);
				}
			}

			/* Hack -- acquire "cursed" flag */
			if (has_flag(o_ptr, FLAG_CURSED)) o_ptr->ident |= (IDENT_CURSED);

			/* Hack -- obtain bonuses */
			if (e_ptr->max_to_h > 0) o_ptr->to_h += randint(e_ptr->max_to_h);
			if (e_ptr->max_to_h < 0) o_ptr->to_h -= randint( -e_ptr->max_to_h);
			if (e_ptr->max_to_d > 0) o_ptr->to_d += randint(e_ptr->max_to_d);
			if (e_ptr->max_to_d < 0) o_ptr->to_d -= randint( -e_ptr->max_to_d);
			if (e_ptr->max_to_a > 0) o_ptr->to_a += randint(e_ptr->max_to_a);
			if (e_ptr->max_to_a < 0) o_ptr->to_a -= randint( -e_ptr->max_to_a);

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

		/* Cheat -- describe the item */
		if ((did_ego) && ((cheat_peek) || (p_ptr->precognition))) object_mention(o_ptr);
	}

	/* Generic on make for all items */
	invoke_on_make_all(o_ptr, power);

	/* Examine real objects */
	if (o_ptr->k_idx)
	{
		/* Hack -- acquire "cursed" flag */
		if (has_flag(o_ptr, FLAG_CURSED)) o_ptr->ident |= (IDENT_CURSED);
	}

	/* Reset to default */
	flags_mbonus_level = -1;
}
Ejemplo n.º 17
0
/**
 * Attempts to place a copy of the given monster at the given position in
 * the dungeon.
 *
 * All of the monster placement routines eventually call this function. This
 * is what actually puts the monster in the dungeon (i.e., it notifies the cave
 * and sets the monsters position). The dungeon loading code also calls this
 * function directly.
 *
 * `origin` is the item origin to use for any monster drops (e.g. ORIGIN_DROP,
 * ORIGIN_DROP_PIT, etc.) The dungeon loading code calls this with origin = 0,
 * which prevents the monster's drops from being generated again.
 *
 * Returns the m_idx of the newly copied monster, or 0 if the placement fails.
 */
s16b place_monster(int y, int x, monster_type *mon, byte origin)
{
	s16b m_idx;
	monster_type *m_ptr;

	assert(cave_in_bounds(cave, y, x));
	assert(!cave_monster_at(cave, y, x));

	/* Get a new record */
	m_idx = mon_pop();
	if (!m_idx) return 0;

	/* Copy the monster */
	m_ptr = cave_monster(cave, m_idx);
	COPY(m_ptr, mon, monster_type);

	/* Set the ID */
	m_ptr->midx = m_idx;

	/* Set the location */
	cave->m_idx[y][x] = m_ptr->midx;
	m_ptr->fy = y;
	m_ptr->fx = x;
	assert(cave_monster_at(cave, y, x) == m_ptr);

	update_mon(m_ptr, TRUE);

	/* Hack -- Count the number of "reproducers" */
	if (rf_has(m_ptr->race->flags, RF_MULTIPLY)) num_repro++;

	/* Count racial occurrences */
	m_ptr->race->cur_num++;

	/* Create the monster's drop, if any */
	if (origin)
		(void)mon_create_drop(m_ptr, origin);

	/* Make mimics start mimicking */
	if (origin && m_ptr->race->mimic_kinds) {
		object_type *i_ptr;
		object_type object_type_body;
		object_kind *kind = m_ptr->race->mimic_kinds->kind;
		struct monster_mimic *mimic_kind;
		int i = 1;
		
		/* Pick a random object kind to mimic */
		for (mimic_kind = m_ptr->race->mimic_kinds; mimic_kind; 
				mimic_kind = mimic_kind->next, i++) {
			if (one_in_(i)) kind = mimic_kind->kind;
		}

		i_ptr = &object_type_body;

		if (kind->tval == TV_GOLD) {
			make_gold(i_ptr, p_ptr->depth, kind->sval);
		} else {
			object_prep(i_ptr, kind, m_ptr->race->level, RANDOMISE);
			apply_magic(i_ptr, m_ptr->race->level, TRUE, FALSE, FALSE, FALSE);
			i_ptr->number = 1;
		}

		i_ptr->origin = origin;
		i_ptr->mimicking_m_idx = m_idx;
		m_ptr->mimicked_o_idx = floor_carry(cave, y, x, i_ptr);
	}

	/* Result */
	return m_idx;
}
Ejemplo n.º 18
0
/*
 * Describe the kind
 */
static void kind_info(char *buf, size_t buf_len,
                      char *dam, size_t dam_len,
                      char *wgt, size_t wgt_len,
                      int *lev, s32b *val, int k)
{
	object_kind *k_ptr;

	object_type *i_ptr;
	object_type object_type_body;
	int i;

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

	/* Prepare a fake item */
	object_prep(i_ptr, &k_info[k], 0, MAXIMISE);

	/* Obtain the "kind" info */
	k_ptr = i_ptr.kind;

	/* Cancel bonuses */
	for (i = 0; i < MAX_PVALS; i++)
		i_ptr.pval[i] = 0;
	i_ptr.to_a = 0;
	i_ptr.to_h = 0;
	i_ptr.to_d = 0;


	/* Level */
	(*lev) = k_ptr.level;

	/* Make known */
	object_notice_everything(i_ptr);

	/* Value */
	(*val) = object_value(i_ptr, 1, false);

	/* Description (too brief) */
	if (buf)
		object_desc(buf, buf_len, i_ptr, ODESC_BASE | ODESC_SPOIL);

	/* Weight */
	if (wgt)
		strnfmt(wgt, wgt_len, "%3d.%d",
				i_ptr.weight / 10, i_ptr.weight % 10);

	/* Hack */
	if (!dam)
		return;

	/* Misc info */
	dam[0] = '\0';

	/* Damage */
	switch (i_ptr.tval)
	{
		/* Bows */
		case TV_BOW:
		{
			break;
		}

		/* Ammo */
		case TV_SHOT:
		case TV_BOLT:
		case TV_ARROW:
		{
			strnfmt(dam, dam_len, "%dd%d", i_ptr.dd, i_ptr.ds);
			break;
		}

		/* Weapons */
		case TV_HAFTED:
		case TV_POLEARM:
		case TV_SWORD:
		case TV_DIGGING:
		{
			strnfmt(dam, dam_len, "%dd%d", i_ptr.dd, i_ptr.ds);
			break;
		}

		/* Armour */
		case TV_BOOTS:
		case TV_GLOVES:
		case TV_CLOAK:
		case TV_CROWN:
		case TV_HELM:
		case TV_SHIELD:
		case TV_SOFT_ARMOR:
		case TV_HARD_ARMOR:
		case TV_DRAG_ARMOR:
		{
			strnfmt(dam, dam_len, "%d", i_ptr.ac);
			break;
		}
	}
}
Ejemplo n.º 19
0
bool quest_poison_gen_hook(char *fmt)
{
	int cy = 1, cx = 1, x, y, try = 10000, r_idx;
	bool (*old_get_mon_num_hook)(int r_idx);

	if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;
	if (p_ptr->wilderness_y != wild_locs[cquest.data[0]][0]) return FALSE;
	if (p_ptr->wilderness_x != wild_locs[cquest.data[0]][1]) return FALSE;
	if (p_ptr->wild_mode) return FALSE;

	/* Find a good position */
	while (try)
	{
		/* Get a random spot */
		cy = randint(cur_hgt - 24) + 22;
		cx = randint(cur_wid - 34) + 32;

		/* Is it a good spot ? */
		if (cave_empty_bold(cy, cx)) break;

		/* One less try */
		try--;
	}

	/* Place the baddies */

	/* Backup the old hook */
	old_get_mon_num_hook = get_mon_num_hook;

	/* Require "okay" monsters */
	get_mon_num_hook = create_molds_hook;

	/* Prepare allocation table */
	get_mon_num_prep();

	/* Pick a monster, using the level calculation */
	for (x = cx - 25; x <= cx + 25; x++)
		for (y = cy - 25; y <= cy + 25; y++)
		{
			if (!in_bounds(y, x)) continue;

			if (distance(cy, cx, y, x) > 25) continue;

			if (magik(80) && ((cave[y][x].feat == FEAT_DEEP_WATER) || (cave[y][x].feat == FEAT_SHAL_WATER))) cave_set_feat(y, x, FEAT_TAINTED_WATER);

			if (distance(cy, cx, y, x) > 10) continue;

			if (magik(60))
			{
				int m_idx;

				r_idx = get_mon_num(30);
				m_idx = place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY);

				/* Sometimes make it up some levels */
				if (magik(80) && m_idx)
				{
					monster_type *m_ptr = &m_list[m_idx];

					if (m_ptr->level < p_ptr->lev)
					{
						m_ptr->exp = MONSTER_EXP(m_ptr->level + randint(p_ptr->lev - m_ptr->level));
						monster_check_experience(m_idx, TRUE);
					}
				}
			}
		}

	/* Reset restriction */
	get_mon_num_hook = old_get_mon_num_hook;

	/* Prepare allocation table */
	get_mon_num_prep();

	return FALSE;
}
bool quest_poison_finish_hook(char *fmt)
{
	object_type forge, *q_ptr;
	s32b q_idx;

	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_POISON) return FALSE;

	c_put_str(TERM_YELLOW, "The water is clean again! Thank you so much.", 8, 0);
	c_put_str(TERM_YELLOW, "The beautiful Mallorns are safe. Take this as a proof of our gratitude.", 9, 0);

	q_ptr = &forge;
	object_prep(q_ptr, lookup_kind(TV_DRAG_ARMOR, SV_DRAGON_BLUE));
	q_ptr->found = OBJ_FOUND_REWARD;
	q_ptr->number = 1;
	q_ptr->name2 = EGO_ELVENKIND;
	apply_magic(q_ptr, 1, FALSE, FALSE, FALSE);
	object_aware(q_ptr);
	object_known(q_ptr);
	q_ptr->ident |= IDENT_STOREB;
	(void)inven_carry(q_ptr, FALSE);

	/* Continue the plot */
	*(quest[q_idx].plot) = QUEST_NULL;

	del_hook(HOOK_QUEST_FINISH, quest_poison_finish_hook);
	process_hooks_restart = TRUE;

	return TRUE;
}
Ejemplo n.º 20
0
static void cmd_racial_power_aux(const mutation_type *mut_ptr)
{
	s16b        plev = p_ptr->lev;
	int         dir = 0;

	if (racial_aux(mut_ptr->level, mut_ptr->cost, mut_ptr->stat, mut_ptr->diff))
	{
		switch (p_ptr->prace)
		{
			case RACE_DWARF:
			{
				msg_print("You examine your surroundings.");
				(void)detect_traps();
				(void)detect_doors();
				(void)detect_stairs();
				break;
			}

			case RACE_HOBBIT:
			{
				object_type *q_ptr;
				object_type forge;

				/* Get local object */
				q_ptr = &forge;

				/* Create the food ration */
				object_prep(q_ptr, 21);

				/* Drop the object from heaven */
				(void)drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
				msg_print("You cook some food.");

				break;
			}

			case RACE_GNOME:
			{
				msg_print("Blink!");
				teleport_player(10 + plev);
				break;
			}

			case RACE_HALF_ORC:
			{
				msg_print("You play tough.");
				(void)set_afraid(0);
				break;
			}

			case RACE_HALF_TROLL:
			{
				msg_print("RAAAGH!");
				if (!p_ptr->shero)
				{
					(void)hp_player(30);
				}
				(void)set_afraid(0);
				(void)set_shero(p_ptr->shero + 10 + randint1(plev));

				break;
			}

			case RACE_AMBERITE:
			{
				/* Hack - use levels to choose ability */
				if (mut_ptr->level == 30)
				{
					msg_print("You picture the Pattern in your mind and walk it...");
					(void)set_poisoned(0);
					(void)set_image(0);
					(void)set_stun(0);
					(void)set_cut(0);
					(void)set_blind(0);
					(void)set_afraid(0);
					(void)do_res_stat(A_STR, 200);
					(void)do_res_stat(A_INT, 200);
					(void)do_res_stat(A_WIS, 200);
					(void)do_res_stat(A_DEX, 200);
					(void)do_res_stat(A_CON, 200);
					(void)do_res_stat(A_CHR, 200);
					(void)restore_level();
				}

				else if (mut_ptr->level == 40)
				{
					/* No effect in arena or quest */
					if (p_ptr->inside_quest)
					{
						msg_print("There is no effect.");
					}
					else
					{
						msg_print("You start walking around. Your surroundings change.");

						if (autosave_l) do_cmd_save_game(TRUE);

						/* Leaving */
						p_ptr->leaving = TRUE;
					}
				}
				break;
			}

			case RACE_BARBARIAN:
			{
				msg_print("Raaagh!");
				if (!p_ptr->shero)
				{
					(void)hp_player(30);
				}

				(void)set_afraid(0);
				(void)set_shero(p_ptr->shero + 10 + randint1(plev));
				break;
			}

			case RACE_HALF_OGRE:
			{
				msg_print("You carefully set an explosive rune...");
				(void)explosive_rune();
				break;
			}

			case RACE_HALF_GIANT:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You bash at a stone wall.");
				(void)wall_to_mud(dir);
				break;
			}

			case RACE_HALF_TITAN:
			{
				msg_print("You examine your foes...");
				(void)probing();
				break;
			}

			case RACE_CYCLOPS:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You throw a huge boulder.");
				(void)fire_bolt(GF_MISSILE, dir, (3 * plev) / 2);
				break;
			}

			case RACE_YEEK:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You make a horrible scream!");
				(void)fear_monster(dir, plev);
				break;
			}

			case RACE_KLACKON:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You spit acid.");
				if (plev < 25)
					(void)fire_bolt(GF_ACID, dir, plev);
				else
					(void)fire_ball(GF_ACID, dir, plev, 2);
				break;
			}

			case RACE_KOBOLD:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You throw a dart of poison.");
				(void)fire_bolt(GF_POIS, dir, plev);
				break;
			}

			case RACE_NIBELUNG:
			{
				msg_print("You examine your surroundings.");
				(void)detect_traps();
				(void)detect_doors();
				(void)detect_stairs();
				break;
			}

			case RACE_DARK_ELF:
			{
				if (!get_aim_dir(&dir)) break;
				msg_print("You cast a magic missile.");
				(void)fire_bolt_or_beam(10, GF_MISSILE, dir,
				    damroll(3 + ((plev - 1) / 5), 4));
				break;
			}

			case RACE_DRACONIAN:
			{
				int  Type = (one_in_(3) ? GF_COLD : GF_FIRE);
				cptr Type_desc = ((Type == GF_COLD) ? "cold" : "fire");

				if (randint1(100) < plev)
				{
					switch (p_ptr->pclass)
					{
						case CLASS_WARRIOR:
						case CLASS_RANGER:
							if (one_in_(3))
							{
								Type = GF_MISSILE;
								Type_desc = "the elements";
							}
							else
							{
								Type = GF_SHARDS;
								Type_desc = "shards";
							}
							break;
						case CLASS_MAGE:
						case CLASS_WARRIOR_MAGE:
						case CLASS_HIGH_MAGE:
							if (one_in_(3))
							{
								Type = GF_MANA;
								Type_desc = "mana";
							}
							else
							{
								Type = GF_DISENCHANT;
								Type_desc = "disenchantment";
							}
							break;
						case CLASS_CHAOS_WARRIOR:
							if (!one_in_(3))
							{
								Type = GF_CONFUSION;
								Type_desc = "confusion";
							}
							else
							{
								Type = GF_CHAOS;
								Type_desc = "chaos";
							}
							break;
						case CLASS_MONK:
							if (!one_in_(3))
							{
								Type = GF_CONFUSION;
								Type_desc = "confusion";
							}
							else
							{
								Type = GF_SOUND;
								Type_desc = "sound";
							}
							break;
						case CLASS_MINDCRAFTER:
							if (!one_in_(3))
							{
								Type = GF_CONFUSION;
								Type_desc = "confusion";
							}
							else
							{
								Type = GF_PSI;
								Type_desc = "mental energy";
							}
							break;
						case CLASS_PRIEST:
						case CLASS_PALADIN:
							if (one_in_(3))
							{
								Type = GF_HELL_FIRE;
								Type_desc = "hellfire";
							}
							else
							{
								Type = GF_HOLY_FIRE;
								Type_desc = "holy fire";
							}
							break;
						case CLASS_ROGUE:
							if (one_in_(3))
							{
								Type = GF_DARK;
								Type_desc = "darkness";
							}
							else
							{
								Type = GF_POIS;
								Type_desc = "poison";
							}
							break;
					}
				}

				if (!get_aim_dir(&dir)) break;
				msg_format("You breathe %s.", Type_desc);
				(void)fire_ball(Type, dir, plev * 2,
				    (plev / 15) + 1);
				break;
			}

			case RACE_MIND_FLAYER:
			{
				if (!get_aim_dir(&dir)) break;
				else
				{
					msg_print("You concentrate and your eyes glow red...");
					(void)fire_bolt(GF_PSI, dir, plev);
				}

				break;
			}

			case RACE_IMP:
			{
				if (!get_aim_dir(&dir)) break;
				if (plev >= 30)
				{
					msg_print("You cast a ball of fire.");
					(void)fire_ball(GF_FIRE, dir, plev, 2);
				}
				else
				{
					msg_print("You cast a bolt of fire.");
					(void)fire_bolt(GF_FIRE, dir, plev);
				}
				break;
			}

			case RACE_GOLEM:
			{
				(void)set_shield(p_ptr->shield + rand_range(30, 50));
				break;
			}

			case RACE_SKELETON:
			case RACE_ZOMBIE:
			{
				msg_print("You attempt to restore your lost energies.");
				(void)restore_level();
				break;
			}

			case RACE_VAMPIRE:
			{
				int y, x, dummy;
				cave_type *c_ptr;

				/* Only works on adjacent monsters */
				if (!get_rep_dir(&dir)) break;
				y = p_ptr->py + ddy[dir];
				x = p_ptr->px + ddx[dir];

				/* Paranoia */
				if (!in_bounds2(y, x)) break;

				c_ptr = area(y, x);

				if (!c_ptr->m_idx)
				{
					msg_print("You bite into thin air!");
					break;
				}

				msg_print("You grin and bare your fangs...");
				dummy = plev + randint1(plev) * MAX(1, plev / 10);   /* Dmg */
				if (drain_gain_life(dir, dummy))
				{
					/* Gain nutritional sustenance: 150/hp drained */
					/* A Food ration gives 5000 food points (by contrast) */
					/* Don't ever get more than "Full" this way */
					/* But if we ARE Gorged,  it won't cure us */
					dummy = p_ptr->food + MIN(5000, 100 * dummy);
					if (p_ptr->food < PY_FOOD_MAX)   /* Not gorged already */
						(void)set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy);
				}
				else
					msg_print("Yechh. That tastes foul.");
				break;
			}

			case RACE_SPECTRE:
			{
				msg_print("You emit an eldritch howl!");
				if (!get_aim_dir(&dir)) break;
				(void)fear_monster(dir, plev);
				break;
			}

			case RACE_SPRITE:
			{
				msg_print("You throw some magic dust...");
				if (plev < 25)
					(void)sleep_monsters_touch();
				else
					(void)sleep_monsters();
				break;
			}
			case RACE_GHOUL:
			{
				if (mut_ptr->level == 30)
				{
					/* Sense living */
					(void)detect_monsters_living();
				}
				else
				{
					eat_corpse();
				}
				break;
			}
			default:
				msg_print("This race has no bonus power.");
				p_ptr->energy_use = 0;
		}
	}

	/* Redraw mana and hp */
	p_ptr->redraw |= (PR_HP | PR_MANA);

	/* Window stuff */
	p_ptr->window |= (PW_PLAYER | PW_SPELL);
}
/**
 * Melee effect handler: Take the player's gold.
 */
static void melee_effect_handler_EAT_GOLD(melee_effect_handler_context_t *context)
{
	struct player *player = context->p;

    /* Take damage */
    take_hit(context->p, context->damage, context->ddesc);

    /* Obvious */
    context->obvious = TRUE;

    /* Attempt saving throw (unless paralyzed) based on dex and level */
    if (!player->timed[TMD_PARALYZED] &&
        (randint0(100) < (adj_dex_safe[player->state.stat_ind[STAT_DEX]]
						  + player->lev))) {
        /* Saving throw message */
        msg("You quickly protect your money pouch!");

        /* Occasional blink anyway */
        if (randint0(3)) context->blinked = TRUE;
    } else {
        s32b gold = (player->au / 10) + randint1(25);
        if (gold < 2) gold = 2;
        if (gold > 5000) gold = (player->au / 20) + randint1(3000);
        if (gold > player->au) gold = player->au;
        player->au -= gold;
        if (gold <= 0) {
            msg("Nothing was stolen.");
            return;
        }

        /* Let the player know they were robbed */
        msg("Your purse feels lighter.");
        if (player->au)
            msg("%d coins were stolen!", gold);
        else
            msg("All of your coins were stolen!");

        /* While we have gold, put it in objects */
        while (gold > 0) {
            int amt;

            /* Create a new temporary object */
            object_type *obj = object_new();
            object_prep(obj, money_kind("gold", gold), 0, MINIMISE);

            /* Amount of gold to put in this object */
            amt = gold > MAX_PVAL ? MAX_PVAL : gold;
            obj->pval = amt;
            gold -= amt;

            /* Set origin to stolen, so it is not confused with
             * dropped treasure in monster_death */
            obj->origin = ORIGIN_STOLEN;
			obj->origin_depth = player->depth;

            /* Give the gold to the monster */
            monster_carry(cave, context->m_ptr, obj);
        }

        /* Redraw gold */
        player->upkeep->redraw |= (PR_GOLD);

        /* Blink away */
        context->blinked = TRUE;
    }
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
Archivo: cmd3.c Proyecto: fph/mortsil
/*
 * Inscribe an object with a comment
 */
void do_cmd_inscribe(void)
{
	int item;

	object_type *o_ptr;

	char o_name[80];

	char tmp[80];

	cptr q, s;

	/* Get an item */
	q = "Inscribe which item? ";
	s = "You have nothing to inscribe.";
	if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;

	/* Get the item (in the pack) */
	if (item >= 0)
	{
		o_ptr = &inventory[item];
	}

	/* Get the item (on the floor) */
	else
	{
		o_ptr = &o_list[0 - item];
	}

	/* Describe the activity */
	object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3);

	/* Message */
	msg_format("Inscribing %s.", o_name);
	message_flush();

	/* Start with nothing */
	my_strcpy(tmp, "", sizeof(tmp));

	/* Use old inscription */
	if (o_ptr->obj_note)
	{
		/* Start with the old inscription */
		strnfmt(tmp, sizeof(tmp), "%s", quark_str(o_ptr->obj_note));
	}

	/* Get a new inscription (possibly empty) */
	if (term_get_string("Inscription: ", tmp, sizeof(tmp)))
	{
		char tmp_val[160];
		char o_name2[80];

		/*make a fake object so we can give a proper message*/
		object_type *i_ptr;
		object_type object_type_body;

		// if given an empty inscription, then uninscribe instead
		if (strlen(tmp) == 0)
		{
			uninscribe(o_ptr);
			return;
		}
		
		/* Save the inscription */
		o_ptr->obj_note = quark_add(tmp);

		/* Add an autoinscription? */
		// Sil-y: removed restriction to known items (through 'object_aware')
		if (!(k_info[o_ptr->k_idx].flags3 & (TR3_INSTA_ART)))
		{
			/* Get local object */
			i_ptr = &object_type_body;

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

			/* Create the object */
			object_prep(i_ptr, o_ptr->k_idx);

			/*make it plural*/
			i_ptr->number = 2;

			/*now describe with correct amount*/
			object_desc(o_name2, sizeof(o_name2), i_ptr, FALSE, 0);

			/* Prompt */
			strnfmt(tmp_val, sizeof(tmp_val), "Automatically inscribe all %s with '%s'? ",
					o_name2, tmp);

			/* Auto-Inscribe if they want that */
			if (get_check(tmp_val)) add_autoinscription(o_ptr->k_idx, tmp);
		}

		/* Combine the pack */
		p_ptr->notice |= (PN_COMBINE);

		/* Window stuff */
		p_ptr->window |= (PW_INVEN | PW_EQUIP);
	}
}
Ejemplo n.º 25
0
/*
 * Mega-Hack -- Attempt to create one of the "Special Objects".
 *
 * We are only called from "make_object()", and we assume that
 * "apply_magic()" is called immediately after we return.
 *
 * 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;

	int k_idx;


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

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

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

		/* Assign the template */
		object_prep(o_ptr, &k_info[k_idx], a_ptr->alloc_min, RANDOMISE);

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

		/* 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;
}
Ejemplo n.º 26
0
void chaos_warrior_reward(void)
{
    if (one_in_(6))
    {
        msg_format("%^s rewards you with a mutation!",
            chaos_patrons[p_ptr->chaos_patron]);

        mut_gain_random(NULL);
    }
    else
    {
        char        wrath_reason[32] = "";
        int         nasty_chance = 6;
        int         dummy = 0, dummy2 = 0;
        int         type, effect;
        int         count = 0;

        if (p_ptr->lev == 13) nasty_chance = 2;
        else if (!(p_ptr->lev % 13)) nasty_chance = 3;
        else if (!(p_ptr->lev % 14)) nasty_chance = 12;

        if (one_in_(nasty_chance))
            type = randint1(20); /* Allow the 'nasty' effects */
        else
            type = randint1(15) + 5; /* Or disallow them */

        if (type < 1) type = 1;
        if (type > 20) type = 20;
        type--;

        sprintf(wrath_reason, "the Wrath of %s",
            chaos_patrons[p_ptr->chaos_patron]);

        effect = chaos_rewards[p_ptr->chaos_patron][type];
        switch (effect)
        {
        case REW_POLY_SLF:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thou needst a new form, mortal!'");

            do_poly_self();
            break;
        case REW_GAIN_EXP:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Well done, mortal! Lead on!'");
            if (p_ptr->prace == RACE_ANDROID)
                msg_print("But, nothing happen.");
            else if (p_ptr->exp < PY_MAX_EXP)
            {
                s32b ee = (p_ptr->exp / 2) + 10;
                if (ee > 100000L) ee = 100000L;
                msg_print("You feel more experienced.");
                gain_exp(ee);
            }
            break;
        case REW_LOSE_EXP:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thou didst not deserve that, slave.'");

            if (p_ptr->prace == RACE_ANDROID)
                msg_print("But, nothing happen.");
            else
            {
                lose_exp(p_ptr->exp / 6);
            }
            break;
        case REW_GOOD_OBJ:
            msg_format("The voice of %s whispers:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Use my gift wisely.'");
            acquirement(py, px, 1, FALSE, FALSE);
            break;
        case REW_GREA_OBJ:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Use my gift wisely.'");

            acquirement(py, px, 1, TRUE, FALSE);
            break;
        case REW_CHAOS_WP:
        {
            object_type forge;

            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thy deed hath earned thee a worthy blade.'");

            dummy = TV_SWORD;
            switch (randint1(p_ptr->lev))
            {
                case 0: case 1:
                    dummy2 = SV_DAGGER;
                    break;
                case 2: case 3:
                    dummy2 = SV_MAIN_GAUCHE;
                    break;
                case 4:
                    dummy2 = SV_TANTO;
                    break;
                case 5: case 6:
                    dummy2 = SV_RAPIER;
                    break;
                case 7: case 8:
                    dummy2 = SV_SMALL_SWORD;
                    break;
                case 9: case 10:
                    dummy2 = SV_BASILLARD;
                    break;
                case 11: case 12: case 13:
                    dummy2 = SV_SHORT_SWORD;
                    break;
                case 14: case 15:
                    dummy2 = SV_SABRE;
                    break;
                case 16: case 17:
                    dummy2 = SV_CUTLASS;
                    break;
                case 18:
                    dummy2 = SV_WAKIZASHI;
                    break;
                case 19:
                    dummy2 = SV_KHOPESH;
                    break;
                case 20:
                    dummy2 = SV_TULWAR;
                    break;
                case 21:
                    dummy2 = SV_BROAD_SWORD;
                    break;
                case 22: case 23:
                    dummy2 = SV_LONG_SWORD;
                    break;
                case 24: case 25:
                    dummy2 = SV_SCIMITAR;
                    break;
                case 26:
                    dummy2 = SV_NINJATO;
                    break;
                case 27:
                    dummy2 = SV_KATANA;
                    break;
                case 28: case 29:
                    dummy2 = SV_BASTARD_SWORD;
                    break;
                case 30:
                    dummy2 = SV_GREAT_SCIMITAR;
                    break;
                case 31:
                    dummy2 = SV_CLAYMORE;
                    break;
                case 32:
                    dummy2 = SV_ESPADON;
                    break;
                case 33:
                    dummy2 = SV_TWO_HANDED_SWORD;
                    break;
                case 34:
                    dummy2 = SV_FLAMBERGE;
                    break;
                case 35:
                    dummy2 = SV_NO_DACHI;
                    break;
                case 36:
                    dummy2 = SV_EXECUTIONERS_SWORD;
                    break;
                case 37:
                    dummy2 = SV_ZWEIHANDER;
                    break;
                case 38:
                    dummy2 = SV_HAYABUSA;
                    break;
                default:
                    dummy2 = SV_BLADE_OF_CHAOS;
            }

            object_prep(&forge, lookup_kind(dummy, dummy2));
            forge.to_h = 3 + randint1(dun_level) % 10;
            forge.to_d = 3 + randint1(dun_level) % 10;
            one_resistance(&forge);
            forge.name2 = EGO_WEAPON_CHAOS;

            drop_near(&forge, -1, py, px);
            break;
        }
        case REW_GOOD_OBS:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thy deed hath earned thee a worthy reward.'");

            acquirement(py, px, randint1(2) + 1, FALSE, FALSE);
            break;
        case REW_GREA_OBS:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Behold, mortal, how generously I reward thy loyalty.'");

            acquirement(py, px, randint1(2) + 1, TRUE, FALSE);
            break;
        case REW_TY_CURSE:
            msg_format("The voice of %s thunders:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thou art growing arrogant, mortal.'");

            activate_ty_curse(FALSE, &count);
            break;
        case REW_SUMMON_M:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'My pets, destroy the arrogant mortal!'");
            for (dummy = 0; dummy < randint1(5) + 1; dummy++)
                summon_specific(0, py, px, dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET));
            break;
        case REW_H_SUMMON:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thou needst worthier opponents!'");
            activate_hi_summon(py, px, FALSE);
            break;
        case REW_DO_HAVOC:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Death and destruction! This pleaseth me!'");
            call_chaos(100);
            break;
        case REW_GAIN_ABL:
            msg_format("The voice of %s rings out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Stay, mortal, and let me mold thee.'");
            if (one_in_(3) && !(chaos_stats[p_ptr->chaos_patron] < 0))
                do_inc_stat(chaos_stats[p_ptr->chaos_patron]);
            else
                do_inc_stat(randint0(6));
            break;
        case REW_LOSE_ABL:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'I grow tired of thee, mortal.'");

            if (one_in_(3) && !(chaos_stats[p_ptr->chaos_patron] < 0))
                do_dec_stat(chaos_stats[p_ptr->chaos_patron]);
            else
                do_dec_stat(randint0(6));
            break;
        case REW_RUIN_ABL:
            msg_format("The voice of %s thunders:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Thou needst a lesson in humility, mortal!'");
            msg_print("You feel less powerful!");

            for (dummy = 0; dummy < 6; dummy++)
                dec_stat(dummy, 10 + randint1(15), TRUE);
            break;
        case REW_POLY_WND:
            msg_format("You feel the power of %s touch you.", chaos_patrons[p_ptr->chaos_patron]);
            do_poly_wounds();
            break;
        case REW_AUGM_ABL:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Receive this modest gift from me!'");
            for (dummy = 0; dummy < 6; dummy++)
                do_inc_stat(dummy);
            break;
        case REW_HURT_LOT:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Suffer, pathetic fool!'");
            fire_ball(GF_DISINTEGRATE, 0, p_ptr->lev * 4, 4);
            take_hit(DAMAGE_NOESCAPE, p_ptr->lev * 4, wrath_reason, -1);
            break;
       case REW_HEAL_FUL:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Rise, my servant!'");
            restore_level();
            set_poisoned(0, TRUE);
            set_blind(0, TRUE);
            set_confused(0, TRUE);
            set_image(0, TRUE);
            set_stun(0, TRUE);
            set_cut(0, TRUE);
            hp_player(5000);
            for (dummy = 0; dummy < 6; dummy++)
                do_res_stat(dummy);
            break;
        case REW_CURSE_WP:
        {
            int slot = equip_random_slot(object_is_melee_weapon);
            if (slot)
            {
                msg_format("The voice of %s booms out:",
                    chaos_patrons[p_ptr->chaos_patron]);
                msg_print("'Thou reliest too much on thy weapon.'");
                curse_weapon(FALSE, slot);
            }
            break;
        }
        case REW_CURSE_AR:
        {
            int slot = equip_random_slot(object_is_armour);
            if (slot)
            {
                msg_format("The voice of %s booms out:",
                    chaos_patrons[p_ptr->chaos_patron]);
                msg_print("'Thou reliest too much on thine equipment.'");
                curse_armor(slot);
            }
            break;
        }
        case REW_PISS_OFF:
            msg_format("The voice of %s whispers:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Now thou shalt pay for annoying me.'");
            switch (randint1(4))
            {
                case 1:
                    activate_ty_curse(FALSE, &count);
                    break;
                case 2:
                    activate_hi_summon(py, px, FALSE);
                    break;
                case 3:
                    if (one_in_(2))
                    {
                        int slot = equip_random_slot(object_is_melee_weapon);
                        if (slot)
                            curse_weapon(FALSE, slot);
                    }
                    else
                    {
                        int slot = equip_random_slot(object_is_armour);
                        if (slot)
                            curse_armor(slot);
                    }
                    break;
                default:
                    for (dummy = 0; dummy < 6; dummy++)
                        dec_stat(dummy, 10 + randint1(15), TRUE);
                    break;
            }
            break;
        case REW_WRATH:
            msg_format("The voice of %s thunders:", chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Die, mortal!'");

            take_hit(DAMAGE_LOSELIFE, p_ptr->lev * 4, wrath_reason, -1);
            for (dummy = 0; dummy < 6; dummy++)
                dec_stat(dummy, 10 + randint1(15), FALSE);
            activate_hi_summon(py, px, FALSE);
            activate_ty_curse(FALSE, &count);
            if (one_in_(2))
            {
                int slot = equip_random_slot(object_is_melee_weapon);
                if (slot)
                    curse_weapon(FALSE, slot);
            }
            if (one_in_(2))
            {
                int slot = equip_random_slot(object_is_armour);
                if (slot)
                    curse_armor(slot);
            }
            break;
        case REW_DESTRUCT:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Death and destruction! This pleaseth me!'");
            destroy_area(py, px, 25, 3 * p_ptr->lev);
            break;
        case REW_GENOCIDE:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Let me relieve thee of thine oppressors!'");
            symbol_genocide(0, FALSE);
            break;
        case REW_MASS_GEN:
            msg_format("The voice of %s booms out:",
                chaos_patrons[p_ptr->chaos_patron]);
            msg_print("'Let me relieve thee of thine oppressors!'");
            mass_genocide(0, FALSE);
            break;
        case REW_DISPEL_C:
            msg_format("You can feel the power of %s assault your enemies!",
                chaos_patrons[p_ptr->chaos_patron]);
            dispel_monsters(p_ptr->lev * 4);
            break;
        case REW_IGNORE:
            msg_format("%s ignores you.",
                chaos_patrons[p_ptr->chaos_patron]);
            break;
        case REW_SER_DEMO:
            msg_format("%s rewards you with a demonic servant!",chaos_patrons[p_ptr->chaos_patron]);
            if (!summon_specific(-1, py, px, dun_level, SUMMON_DEMON, PM_FORCE_PET))
                msg_print("Nobody ever turns up...");
            break;
        case REW_SER_MONS:
            msg_format("%s rewards you with a servant!",chaos_patrons[p_ptr->chaos_patron]);
            if (!summon_specific(-1, py, px, dun_level, 0, PM_FORCE_PET))
                msg_print("Nobody ever turns up...");
            break;
        case REW_SER_UNDE:
            msg_format("%s rewards you with an undead servant!",chaos_patrons[p_ptr->chaos_patron]);
            if (!summon_specific(-1, py, px, dun_level, SUMMON_UNDEAD, PM_FORCE_PET))
                msg_print("Nobody ever turns up...");
            break;
        default:
            msg_format("The voice of %s stammers:", chaos_patrons[p_ptr->chaos_patron]);
            msg_format("'Uh... uh... the answer's %d/%d, what's the question?'", type, effect);
        }
    }
}