/* * 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); }
// 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; }
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); } }
/** * 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; }
/*! * @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); } }
/* * 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);; }
/* * 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 ); } }
/** * 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; } } }
/** * 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; }
/* * 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); } }
/** * 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; }
/* * 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)
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(); }
/** * 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; }
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; }
/** * 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; }
/* * 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; } } }
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; }
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; } }
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; }
/** * 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; }
/* * 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); } }
/* * 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; }
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); } } }