summaryrefslogtreecommitdiffstats
path: root/stone_soup/crawl-ref/source/effects.cc
diff options
context:
space:
mode:
Diffstat (limited to 'stone_soup/crawl-ref/source/effects.cc')
-rw-r--r--stone_soup/crawl-ref/source/effects.cc1508
1 files changed, 0 insertions, 1508 deletions
diff --git a/stone_soup/crawl-ref/source/effects.cc b/stone_soup/crawl-ref/source/effects.cc
deleted file mode 100644
index d021041131..0000000000
--- a/stone_soup/crawl-ref/source/effects.cc
+++ /dev/null
@@ -1,1508 +0,0 @@
-/*
- * File: effects.cc
- * Summary: Misc stuff.
- * Written by: Linley Henzell
- *
- * Change History (most recent first):
- *
- * <1> -/--/-- LRH Created
- */
-
-#include "AppHdr.h"
-#include "effects.h"
-
-#include <string.h>
-#include <stdio.h>
-
-#include "externs.h"
-
-#include "beam.h"
-#include "direct.h"
-#include "dungeon.h"
-#include "itemname.h"
-#include "itemprop.h"
-#include "items.h"
-#include "misc.h"
-#include "monplace.h"
-#include "monstuff.h"
-#include "mon-util.h"
-#include "mutation.h"
-#include "newgame.h"
-#include "ouch.h"
-#include "player.h"
-#include "randart.h"
-#include "skills2.h"
-#include "spells3.h"
-#include "spells4.h"
-#include "spl-book.h"
-#include "spl-util.h"
-#include "stuff.h"
-#include "view.h"
-#include "wpn-misc.h"
-
-// torment_monsters is called with power 0 because torment is
-// UNRESISTABLE except for being undead or having torment
-// resistance! Even if we used maximum power of 1000, high
-// level monsters and characters would save too often. (GDL)
-
-static int torment_monsters(int x, int y, int pow, int garbage)
-{
- UNUSED( pow );
- UNUSED( garbage );
-
- // is player?
- if (x == you.x_pos && y == you.y_pos)
- {
- if (you.is_undead || you.mutation[MUT_TORMENT_RESISTANCE])
- mpr("You feel a surge of unholy energy.");
- else
- {
- mpr("Your body is wracked with pain!");
- dec_hp((you.hp / 2) - 1, false);
- }
-
- return 1;
- }
-
- // check for monster in cell
- int mon = mgrd[x][y];
-
- if (mon == NON_MONSTER)
- return 0;
-
- struct monsters *monster = &menv[mon];
-
- if (monster->type == -1)
- return 0;
-
- if (mons_res_negative_energy( monster ) >= 3)
- return 0;
-
- monster->hit_points = 1 + (monster->hit_points / 2);
- simple_monster_message(monster, " convulses!");
-
- return 1;
-}
-
-void torment(int tx, int ty)
-{
- apply_area_within_radius(torment_monsters, tx, ty, 0, 8, 0);
-} // end torment()
-
-void banished(unsigned char gate_type)
-{
- you_teleport2( false );
-
- // this is to ensure that you're standing on a suitable space (67)
- grd[you.x_pos][you.y_pos] = gate_type;
-
- down_stairs(true, you.your_level, true); // heh heh
- untag_followers(); // safety
-} // end banished()
-
-bool forget_spell(void)
-{
- if (!you.spell_no)
- return (false);
-
- // find a random spell to forget:
- int slot = -1;
- int num = 0;
-
- for (int i = 0; i < 25; i++)
- {
- if (you.spells[i] != SPELL_NO_SPELL)
- {
- num++;
- if (one_chance_in( num ))
- slot = i;
- }
- }
-
- if (slot == -1) // should never happen though
- return (false);
-
- del_spell_from_memory_by_slot( slot );
-
- return (true);
-} // end forget_spell()
-
-// use player::decrease_stats() instead iff:
-// (a) player_sust_abil() should not factor in; and
-// (b) there is no floor to the final stat values {dlb}
-bool lose_stat(unsigned char which_stat, unsigned char stat_loss, bool force)
-{
- bool statLowered = false; // must initialize to false {dlb}
- char *ptr_stat = 0; // NULL {dlb}
- char *ptr_redraw = 0; // NULL {dlb}
- char newValue = 0; // holds new value, for comparison to old {dlb}
-
- // begin outputing message: {dlb}
- strcpy(info, "You feel ");
-
- // set pointers to appropriate variables: {dlb}
- if (which_stat == STAT_RANDOM)
- which_stat = random2(NUM_STATS);
-
- switch (which_stat)
- {
- case STAT_STRENGTH:
- strcat(info, "weakened");
- ptr_stat = &you.strength;
- ptr_redraw = &you.redraw_strength;
- break;
-
- case STAT_DEXTERITY:
- strcat(info, "clumsy");
- ptr_stat = &you.dex;
- ptr_redraw = &you.redraw_dexterity;
- break;
-
- case STAT_INTELLIGENCE:
- strcat(info, "dopey");
- ptr_stat = &you.intel;
- ptr_redraw = &you.redraw_intelligence;
- break;
- }
-
- // scale modifier by player_sust_abil() - right-shift
- // permissible because stat_loss is unsigned: {dlb}
- if (!force)
- stat_loss >>= player_sust_abil();
-
- // newValue is current value less modifier: {dlb}
- newValue = *ptr_stat - stat_loss;
-
- // XXX: Death by stat loss is currently handled in the redraw code. -- bwr
- if (newValue < 0)
- newValue = 0;
-
- // conceivable that stat was already *at* three
- // or stat_loss zeroed by player_sust_abil(): {dlb}
- //
- // Actually, that code was somewhat flawed. Several race-class combos
- // can start with a stat lower than three, and this block (which
- // used to say '!=' would actually cause stat gain with the '< 3'
- // check that used to be above. Crawl has stat-death code and I
- // don't see why we shouldn't be using it here. -- bwr
- if (newValue < *ptr_stat)
- {
- *ptr_stat = newValue;
- *ptr_redraw = 1;
-
- // handle burden change, where appropriate: {dlb}
- if (ptr_stat == &you.strength)
- burden_change();
-
- statLowered = true; // that is, stat was lowered (not just changed)
- }
-
- // a warning to player that s/he cut it close: {dlb}
- if (!statLowered)
- strcat(info, " for a moment");
-
- // finish outputting message: {dlb}
- strcat(info, ".");
- mpr(info);
-
- return (statLowered);
-} // end lose_stat()
-
-void direct_effect(struct bolt &pbolt)
-{
- int damage_taken = 0;
-
- switch (pbolt.type)
- {
- case DMNBM_HELLFIRE:
- mpr( "You are engulfed in a burst of hellfire!" );
- strcpy( pbolt.beam_name, "hellfire" );
- pbolt.ex_size = 1;
- pbolt.flavour = BEAM_HELLFIRE;
- pbolt.is_explosion = true;
- pbolt.type = SYM_ZAP;
- pbolt.colour = RED;
- pbolt.thrower = KILL_MON_MISSILE;
- pbolt.aux_source = NULL;
- pbolt.is_beam = false;
- pbolt.is_tracer = false;
- pbolt.hit = 20;
- pbolt.damage = dice_def( 3, 20 );
- pbolt.aux_source = "burst of hellfire";
- explosion( pbolt );
- break;
-
- case DMNBM_SMITING:
- mpr( "Something smites you!" );
- strcpy( pbolt.beam_name, "smiting" ); // for ouch
- pbolt.aux_source = "by divine providence";
- damage_taken = 7 + random2avg(11, 2);
- break;
-
- case DMNBM_BRAIN_FEED:
- // lose_stat() must come last {dlb}
- if (one_chance_in(3) && lose_stat(STAT_INTELLIGENCE, 1))
- mpr("Something feeds on your intellect!");
- else
- mpr("Something tries to feed on your intellect!");
- break;
-
- case DMNBM_MUTATION:
- mpr("Strange energies course through your body.");
- if (one_chance_in(5))
- mutate(100);
- else
- give_bad_mutation();
- break;
- }
-
- // apply damage and handle death, where appropriate {dlb}
- if (damage_taken > 0)
- ouch(damage_taken, pbolt.beam_source, KILLED_BY_BEAM, pbolt.aux_source);
-
- return;
-} // end direct_effect()
-
-// monster-to-monster
-void mons_direct_effect(struct bolt &pbolt, int i)
-{
- // note the translation here - important {dlb}
- int o = menv[i].foe;
- struct monsters *monster = &menv[o];
- int damage_taken = 0;
-
- // annoy the target
- behaviour_event(monster, ME_ANNOY, i);
-
- switch (pbolt.type)
- {
- case DMNBM_HELLFIRE:
- simple_monster_message(monster, " is engulfed in hellfire.");
- strcpy(pbolt.beam_name, "hellfire");
- pbolt.flavour = BEAM_LAVA;
-
- damage_taken = 5 + random2(10) + random2(5);
- damage_taken = mons_adjust_flavoured(monster, pbolt, damage_taken);
- break;
-
- case DMNBM_SMITING:
- simple_monster_message(monster, " is smitten.");
- strcpy(pbolt.beam_name, "smiting");
- pbolt.flavour = BEAM_MISSILE;
-
- damage_taken += 7 + random2avg(11, 2);
- break;
-
- case DMNBM_BRAIN_FEED: // not implemented here (nor, probably, can be)
- break;
-
- case DMNBM_MUTATION:
- if (mons_holiness(monster) != MH_NATURAL)
- simple_monster_message(monster, " is unaffected.");
- else if (check_mons_resist_magic( monster, pbolt.ench_power ))
- simple_monster_message(monster, " resists.");
- else
- monster_polymorph(monster, RANDOM_MONSTER, 100);
- break;
- }
-
- // apply damage and handle death, where appropriate {dlb}
- if (damage_taken > 0)
- {
- hurt_monster(monster, damage_taken);
-
- if (monster->hit_points < 1)
- monster_die(monster, KILL_MON_MISSILE, i);
- }
-
- return;
-} // end mons_direct_effect()
-
-void random_uselessness(unsigned char ru, unsigned char sc_read_2)
-{
- char wc[30];
- int temp_rand = 0; // probability determination {dlb}
-
- switch (ru)
- {
- case 0:
- strcpy(info, "The dust glows a ");
- weird_colours(random2(256), wc);
- strcat(info, wc);
- strcat(info, " colour!");
- mpr(info);
- break;
-
- case 1:
- mpr("The scroll reassembles itself in your hand!");
- inc_inv_item_quantity( sc_read_2, 1 );
- break;
-
- case 2:
- if (you.equip[EQ_WEAPON] != -1)
- {
- char str_pass[ ITEMNAME_SIZE ];
- in_name(you.equip[EQ_WEAPON], DESC_CAP_YOUR, str_pass);
- strcpy(info, str_pass);
- strcat(info, " glows ");
- weird_colours(random2(256), wc);
- strcat(info, wc);
- strcat(info, " for a moment.");
- mpr(info);
- }
- else
- {
- canned_msg(MSG_NOTHING_HAPPENS);
- }
- break;
-
- case 3:
- strcpy(info, "You hear the distant roaring of an enraged ");
-
- temp_rand = random2(8);
-
- strcat(info, (temp_rand == 0) ? "frog" :
- (temp_rand == 1) ? "pill bug" :
- (temp_rand == 2) ? "millipede" :
- (temp_rand == 3) ? "eggplant" :
- (temp_rand == 4) ? "albino dragon" :
- (temp_rand == 5) ? "dragon" :
- (temp_rand == 6) ? "human"
- : "slug");
-
- strcat(info, "!");
- mpr(info);
- break;
-
- case 4:
- // josh declares mummies can't smell {dlb}
- if (you.species != SP_MUMMY)
- {
- strcpy(info, "You smell ");
-
- temp_rand = random2(8);
-
- strcat(info, (temp_rand == 0) ? "coffee." :
- (temp_rand == 1) ? "salt." :
- (temp_rand == 2) ? "burning hair!" :
- (temp_rand == 3) ? "baking bread." :
- (temp_rand == 4) ? "something weird." :
- (temp_rand == 5) ? "wet wool." :
- (temp_rand == 6) ? "sulphur."
- : "fire and brimstone!");
- mpr(info);
- }
- break;
-
- case 5:
- mpr("You experience a momentary feeling of inescapable doom!");
- break;
-
- case 6:
- strcpy(info, "Your ");
-
- temp_rand = random2(3);
-
- strcat(info, (temp_rand == 0) ? "ears itch." :
- (temp_rand == 1) ? "brain hurts!"
- : "nose twitches suddenly!");
- mpr(info);
- break;
-
- case 7:
- mpr("You hear the tinkle of a tiny bell.");
- cast_summon_butterflies( 100 );
- break;
-
- case 8:
- strcpy(info, "You hear ");
-
- temp_rand = random2(9);
-
- strcat(info, (temp_rand == 0) ? "snatches of song" :
- (temp_rand == 1) ? "a voice call someone else's name" :
- (temp_rand == 2) ? "a very strange noise" :
- (temp_rand == 3) ? "roaring flame" :
- (temp_rand == 4) ? "a very strange noise indeed" :
- (temp_rand == 5) ? "the chiming of a distant gong" :
- (temp_rand == 6) ? "the bellowing of a yak" :
- (temp_rand == 7) ? "a crunching sound"
- : "the tinkle of an enormous bell");
- strcat(info, ".");
- mpr(info);
- break;
- }
-
- return;
-} // end random_uselessness()
-
-bool acquirement(unsigned char force_class, int agent)
-{
- int thing_created = 0;
- int iteration = 0;
-
- // Remember lava!
- unsigned char class_wanted = OBJ_RANDOM;
- unsigned char type_wanted = OBJ_RANDOM;
-
- unsigned char unique = 1;
- unsigned char acqc = 0;
-
- const int max_has_value = 100;
- FixedVector< int, max_has_value > already_has;
-
- char best_spell = 99;
- char best_any = 99;
- unsigned char keyin;
-
- for (acqc = 0; acqc < max_has_value; acqc++)
- already_has[acqc] = 0;
-
- int spell_skills = 0;
- for (int i = SK_SPELLCASTING; i <= SK_POISON_MAGIC; i++)
- spell_skills += you.skills[i];
-
- if (force_class == OBJ_RANDOM)
- {
- mpr("This is a scroll of acquirement!");
-
- query:
- mpr( "[a|A] Weapon [b|B] Armour [c|C] Jewellery [d|D] Book" );
- mpr( "[e|E] Staff [f|F] Food [g|G] Miscellaneous [h|H] Gold" );
-
- //mpr("[r|R] - Just give me something good.");
- mpr("What kind of item would you like to acquire? ", MSGCH_PROMPT);
-
- keyin = tolower( get_ch() );
-
- if (keyin == 'a')
- class_wanted = OBJ_WEAPONS;
- else if (keyin == 'b')
- class_wanted = OBJ_ARMOUR;
- else if (keyin == 'c')
- class_wanted = OBJ_JEWELLERY;
- else if (keyin == 'd')
- class_wanted = OBJ_BOOKS;
- else if (keyin == 'e')
- class_wanted = OBJ_STAVES;
- else if (keyin == 'f')
- class_wanted = OBJ_FOOD;
- else if (keyin == 'g')
- class_wanted = OBJ_MISCELLANY;
- else if (keyin == 'h')
- class_wanted = OBJ_GOLD;
- }
- else
- class_wanted = force_class;
-
- for (acqc = 0; acqc < ENDOFPACK; acqc++)
- {
- if (is_valid_item( you.inv[acqc] )
- && you.inv[acqc].base_type == class_wanted)
- {
- ASSERT( you.inv[acqc].sub_type < max_has_value );
- already_has[you.inv[acqc].sub_type] += you.inv[acqc].quantity;
- }
- }
-
- if (class_wanted == OBJ_FOOD)
- {
- // food is a little less predicatable now -- bwr
-
- if (you.species == SP_GHOUL)
- {
- type_wanted = one_chance_in(10) ? FOOD_ROYAL_JELLY
- : FOOD_CHUNK;
- }
- else
- {
- // Meat is better than bread (except for herbivors), and
- // by choosing it as the default we don't have to worry
- // about special cases for carnivorous races (ie kobold)
- type_wanted = FOOD_MEAT_RATION;
-
- if (you.mutation[MUT_HERBIVOROUS])
- type_wanted = FOOD_BREAD_RATION;
-
- // If we have some regular rations, then we're probably be more
- // interested in faster foods (escpecially royal jelly)...
- // otherwise the regular rations should be a good enough offer.
- if (already_has[FOOD_MEAT_RATION]
- + already_has[FOOD_BREAD_RATION] >= 2 || coinflip())
- {
- type_wanted = one_chance_in(5) ? FOOD_HONEYCOMB
- : FOOD_ROYAL_JELLY;
- }
- }
-
- // quantity is handled by unique for food
- unique = 3 + random2(5);
-
- // giving more of the lower food value items
- if (type_wanted == FOOD_HONEYCOMB || type_wanted == FOOD_CHUNK)
- {
- unique += random2avg(10, 2);
- }
- }
- else if (class_wanted == OBJ_WEAPONS)
- {
- // Now asking for a weapon is biased towards your skills,
- // although launchers are right out for now. -- bwr
- int count = 0;
- int skill = SK_FIGHTING;
-
- // Can't do much with launchers, so we'll avoid them for now -- bwr
- for (int i = SK_SHORT_BLADES; i < SK_DARTS; i++)
- {
- if (i == SK_UNUSED_1)
- continue;
-
- // Adding a small constant allows for the occasional
- // weapon in an untrained skill. Since the game
- // doesn't allow for much in the way of good launchers,
- // we'll lower their weight.
-
- int weight = 0;
-
- weight = you.skills[i] + 3;
- if (weight)
- {
- count += weight;
-
- if (random2(count) < weight)
- skill = i;
- }
- }
-
- if (skill == SK_STAVES)
- type_wanted = WPN_QUARTERSTAFF; // only one in this class
- else
- {
- count = 0;
-
- // skipping clubs, knives, blowguns
- for (int i = WPN_MACE; i < NUM_WEAPONS; i++)
- {
- // skipping launchers
- if (i == WPN_SLING)
- i = WPN_GLAIVE;
-
- // skipping giant clubs
- if (i == WPN_GIANT_CLUB)
- i = WPN_EVENINGSTAR;
-
- // skipping knife and blowgun
- if (i == WPN_KNIFE)
- i = WPN_FALCHION;
-
- // blessed blades can only be created by the player, never found
- if (i == WPN_BLESSED_BLADE)
- continue;
-
- // "rare" weapons are only considered some of the time...
- // still, the chance is higher than actual random creation
- int wskill = range_skill(OBJ_WEAPONS, i);
- if (wskill == SK_RANGED_COMBAT)
- wskill = weapon_skill(OBJ_WEAPONS, i);
- if (wskill == skill
- && (i < WPN_EVENINGSTAR || i > WPN_BROAD_AXE
- || (i >= WPN_HAMMER && i <= WPN_SABRE)
- || one_chance_in(4)))
- {
- count++;
- if (one_chance_in( count ))
- type_wanted = i;
- }
- }
- }
- }
- else if (class_wanted == OBJ_MISSILES)
- {
- int count = 0;
- int skill = SK_RANGED_COMBAT;
-
- for (int i = SK_SLINGS; i <= SK_DARTS; i++)
- {
- if (you.skills[i])
- {
- count += you.skills[i];
- if (random2(count) < you.skills[i])
- skill = i;
- }
- }
-
- switch (skill)
- {
- case SK_SLINGS:
- type_wanted = MI_STONE;
- break;
-
- case SK_BOWS:
- type_wanted = MI_ARROW;
- break;
-
- case SK_CROSSBOWS:
- type_wanted = MI_DART;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- // Assuming that crossbow in inventory means that they
- // want bolts for it (not darts for a hand crossbow)...
- // perhaps we should check for both and compare ammo
- // amounts on hand?
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == WPN_CROSSBOW)
- {
- type_wanted = MI_BOLT;
- break;
- }
- }
- break;
-
- case SK_DARTS:
- type_wanted = MI_DART;
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (is_valid_item( you.inv[i] )
- && you.inv[i].base_type == OBJ_WEAPONS
- && you.inv[i].sub_type == WPN_BLOWGUN)
- {
- // Assuming that blowgun in inventory means that they
- // may want needles for it (but darts might also be
- // wanted). Maybe expand this... see above comment.
- if (coinflip())
- type_wanted = MI_NEEDLE;
- break;
- }
- }
- break;
-
- default:
- type_wanted = MI_DART;
- break;
- }
- }
- else if (class_wanted == OBJ_ARMOUR)
- {
- // Increasing the representation of the non-body armour
- // slots here to make up for the fact that there's one
- // one type of item for most of them. -- bwr
- //
- // OBJ_RANDOM is body armour and handled below
- type_wanted = (coinflip()) ? OBJ_RANDOM : ARM_SHIELD + random2(5);
-
- // mutation specific problems (horns allow caps)
- if ((you.mutation[MUT_HOOVES] && type_wanted == ARM_BOOTS)
- || (you.mutation[MUT_CLAWS] >= 3 && type_wanted == ARM_GLOVES))
- {
- type_wanted = OBJ_RANDOM;
- }
-
- // some species specific fitting problems
- switch (you.species)
- {
- case SP_OGRE:
- case SP_OGRE_MAGE:
- case SP_TROLL:
- case SP_RED_DRACONIAN:
- case SP_WHITE_DRACONIAN:
- case SP_GREEN_DRACONIAN:
- case SP_GOLDEN_DRACONIAN:
- case SP_GREY_DRACONIAN:
- case SP_BLACK_DRACONIAN:
- case SP_PURPLE_DRACONIAN:
- case SP_MOTTLED_DRACONIAN:
- case SP_PALE_DRACONIAN:
- case SP_UNK0_DRACONIAN:
- case SP_UNK1_DRACONIAN:
- case SP_BASE_DRACONIAN:
- case SP_SPRIGGAN:
- if (type_wanted == ARM_GLOVES || type_wanted == ARM_BOOTS)
- {
- type_wanted = OBJ_RANDOM;
- }
- else if (type_wanted == ARM_SHIELD)
- {
- if (you.species == SP_SPRIGGAN)
- type_wanted = ARM_BUCKLER;
- else if (coinflip()) // giant races: 50/50 shield/large shield
- type_wanted = ARM_LARGE_SHIELD;
- }
- else if (type_wanted == OBJ_RANDOM)
- {
- type_wanted = ARM_ROBE; // no heavy armour, see below
- }
- break;
-
- case SP_KENKU:
- if (type_wanted == ARM_BOOTS)
- type_wanted = OBJ_RANDOM;
- break;
-
- default:
- break;
- }
-
- // Now we'll randomly pick a body armour (light only in the
- // case of ARM_ROBE). Unlike before, now we're only giving
- // out the finished products here, never the hides. -- bwr
- if (type_wanted == OBJ_RANDOM || type_wanted == ARM_ROBE)
- {
- // start with normal base armour
- if (type_wanted == ARM_ROBE)
- type_wanted = coinflip() ? ARM_ROBE : ARM_ANIMAL_SKIN;
- else
- {
- type_wanted = ARM_ROBE + random2(8);
-
- if (one_chance_in(10) && you.skills[SK_ARMOUR] >= 10)
- type_wanted = ARM_CRYSTAL_PLATE_MAIL;
-
- if (one_chance_in(10))
- type_wanted = ARM_ANIMAL_SKIN;
- }
-
- // everyone can wear things made from hides
- if (one_chance_in(20))
- {
- int rnd = random2(20);
-
- type_wanted = (rnd < 4) ? ARM_TROLL_LEATHER_ARMOUR : // 20%
- (rnd < 8) ? ARM_STEAM_DRAGON_ARMOUR : // 20%
- (rnd < 11) ? ARM_MOTTLED_DRAGON_ARMOUR : // 15%
- (rnd < 14) ? ARM_SWAMP_DRAGON_ARMOUR : // 15%
- (rnd < 16) ? ARM_DRAGON_ARMOUR : // 10%
- (rnd < 18) ? ARM_ICE_DRAGON_ARMOUR : // 10%
- (rnd < 19) ? ARM_STORM_DRAGON_ARMOUR // 5%
- : ARM_GOLD_DRAGON_ARMOUR; // 5%
- }
- }
- }
- else if (class_wanted != OBJ_GOLD)
- {
-
- do
- {
- unsigned char i;
-
- switch (class_wanted)
- {
- case OBJ_JEWELLERY:
- // Try for a base type the player hasn't identified
- for (i = 0; i < 10; i++)
- {
- type_wanted = random2(24);
-
- if (one_chance_in(3))
- type_wanted = AMU_RAGE + random2(10);
-
- if (get_ident_type(OBJ_JEWELLERY, type_wanted) == ID_UNKNOWN_TYPE)
- {
- break;
- }
- }
- break;
-
- case OBJ_BOOKS:
- // remember, put rarer books higher in the list
- iteration = 1;
- type_wanted = NUM_BOOKS;
-
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS - 1),
- best_spell );
-
- which_book:
-#if DEBUG_DIAGNOSTICS
- snprintf( info, INFO_SIZE,
- "acquirement: iteration = %d, best_spell = %d",
- iteration, best_spell );
-
- mpr( info, MSGCH_DIAGNOSTICS );
-#endif //jmf: debugging
-
- switch (best_spell)
- {
- default:
- case SK_SPELLCASTING:
- if (you.skills[SK_SPELLCASTING] <= 3
- && !you.had_book[BOOK_CANTRIPS])
- {
- // Handful of level one spells, very useful for the
- // new spellcaster who's asking for a book -- bwr
- type_wanted = BOOK_CANTRIPS;
- }
- else if (!you.had_book[BOOK_MINOR_MAGIC_I])
- type_wanted = BOOK_MINOR_MAGIC_I + random2(3);
- else if (!you.had_book[BOOK_WIZARDRY])
- type_wanted = BOOK_WIZARDRY;
- else if (!you.had_book[BOOK_CONTROL])
- type_wanted = BOOK_CONTROL;
- else if (!you.had_book[BOOK_POWER])
- type_wanted = BOOK_POWER;
- break;
-
- case SK_POISON_MAGIC:
- if (!you.had_book[BOOK_YOUNG_POISONERS])
- type_wanted = BOOK_YOUNG_POISONERS;
- else if (!you.had_book[BOOK_ENVENOMATIONS])
- type_wanted = BOOK_ENVENOMATIONS;
- break;
-
- case SK_EARTH_MAGIC:
- if (!you.had_book[BOOK_GEOMANCY])
- type_wanted = BOOK_GEOMANCY;
- else if (!you.had_book[BOOK_EARTH])
- type_wanted = BOOK_EARTH;
- break;
-
- case SK_AIR_MAGIC:
- // removed the book of clouds... all the other elements
- // (and most other spell skills) only get two.
- if (!you.had_book[BOOK_AIR])
- type_wanted = BOOK_AIR;
- else if (!you.had_book[BOOK_SKY])
- type_wanted = BOOK_SKY;
- break;
-
- case SK_ICE_MAGIC:
- if (!you.had_book[BOOK_FROST])
- type_wanted = BOOK_FROST;
- else if (!you.had_book[BOOK_ICE])
- type_wanted = BOOK_ICE;
- break;
-
- case SK_FIRE_MAGIC:
- if (!you.had_book[BOOK_FLAMES])
- type_wanted = BOOK_FLAMES;
- else if (!you.had_book[BOOK_FIRE])
- type_wanted = BOOK_FIRE;
- break;
-
- case SK_SUMMONINGS:
- if (!you.had_book[BOOK_CALLINGS])
- type_wanted = BOOK_CALLINGS;
- else if (!you.had_book[BOOK_SUMMONINGS])
- type_wanted = BOOK_SUMMONINGS;
-
- // now a Vehumet special -- bwr
- // else if (!you.had_book[BOOK_DEMONOLOGY])
- // type_wanted = BOOK_DEMONOLOGY;
- break;
-
- case SK_ENCHANTMENTS:
- best_any = best_skill(SK_FIGHTING, (NUM_SKILLS - 1), 99);
-
- // So many enchantment books! I really can't feel
- // guilty at all for dividing out the fighting
- // books and forcing the player to raise a fighting
- // skill (or enchantments in the case of Crusaders)
- // to get the remaining books... enchantments are
- // much too good (most spells, lots of books here,
- // id wand charges, gives magic resistance),
- // something will eventually have to be done. -- bwr
- if (best_any >= SK_FIGHTING
- && best_any <= SK_STAVES)
- {
- // Fighter mage's get the fighting enchantment books
- if (!you.had_book[BOOK_WAR_CHANTS])
- type_wanted = BOOK_WAR_CHANTS;
- else if (!you.had_book[BOOK_TUKIMA])
- type_wanted = BOOK_TUKIMA;
- }
- else if (!you.had_book[BOOK_CHARMS])
- type_wanted = BOOK_CHARMS;
- else if (!you.had_book[BOOK_HINDERANCE])
- type_wanted = BOOK_HINDERANCE;
- else if (!you.had_book[BOOK_ENCHANTMENTS])
- type_wanted = BOOK_ENCHANTMENTS;
- break;
-
- case SK_CONJURATIONS:
- if (!you.had_book[BOOK_CONJURATIONS_I])
- type_wanted = give_first_conjuration_book();
- else if (!you.had_book[BOOK_TEMPESTS])
- type_wanted = BOOK_TEMPESTS;
-
- // now a Vehumet special -- bwr
- // else if (!you.had_book[BOOK_ANNIHILATIONS])
- // type_wanted = BOOK_ANNIHILATIONS;
- break;
-
- case SK_NECROMANCY:
- if (!you.had_book[BOOK_NECROMANCY])
- type_wanted = BOOK_NECROMANCY;
- else if (!you.had_book[BOOK_DEATH])
- type_wanted = BOOK_DEATH;
- else if (!you.had_book[BOOK_UNLIFE])
- type_wanted = BOOK_UNLIFE;
-
- // now a Kikubaaqudgha special -- bwr
- // else if (!you.had_book[BOOK_NECRONOMICON])
- // type_wanted = BOOK_NECRONOMICON;
- break;
-
- case SK_TRANSLOCATIONS:
- if (!you.had_book[BOOK_SPATIAL_TRANSLOCATIONS])
- type_wanted = BOOK_SPATIAL_TRANSLOCATIONS;
- else if (!you.had_book[BOOK_WARP])
- type_wanted = BOOK_WARP;
- break;
-
- case SK_TRANSMIGRATION:
- if (!you.had_book[BOOK_CHANGES])
- type_wanted = BOOK_CHANGES;
- else if (!you.had_book[BOOK_TRANSFIGURATIONS])
- type_wanted = BOOK_TRANSFIGURATIONS;
- else if (!you.had_book[BOOK_MUTATIONS])
- type_wanted = BOOK_MUTATIONS;
- break;
-
- case SK_DIVINATIONS: //jmf: added 24mar2000
- if (!you.had_book[BOOK_SURVEYANCES])
- type_wanted = BOOK_SURVEYANCES;
- else if (!you.had_book[BOOK_DIVINATIONS])
- type_wanted = BOOK_DIVINATIONS;
- break;
- }
-/*
- if (type_wanted == 99 && glof == best_skill(SK_SPELLCASTING, (NUM_SKILLS - 1), 99))
-*/
- if (type_wanted == NUM_BOOKS && iteration == 1)
- {
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS - 1),
- best_skill(SK_SPELLCASTING,
- (NUM_SKILLS - 1), 99) );
- iteration++;
- goto which_book;
- }
-
- // if we don't have a book, try and get a new one.
- if (type_wanted == NUM_BOOKS)
- {
- do
- {
- type_wanted = random2(NUM_BOOKS);
- if (one_chance_in(500))
- break;
- }
- while (you.had_book[type_wanted]);
- }
-
- // if the book is invalid find any valid one.
- while (book_rarity(type_wanted) == 100
- || type_wanted == BOOK_DESTRUCTION
- || type_wanted == BOOK_MANUAL)
- {
- type_wanted = random2(NUM_BOOKS);
- }
- break;
-
- case OBJ_STAVES:
- type_wanted = random2(13);
-
- if (type_wanted >= 10)
- type_wanted = STAFF_AIR + type_wanted - 10;
-
- // Elemental preferences -- bwr
- if (type_wanted == STAFF_FIRE || type_wanted == STAFF_COLD)
- {
- if (you.skills[SK_FIRE_MAGIC] > you.skills[SK_ICE_MAGIC])
- type_wanted = STAFF_FIRE;
- else if (you.skills[SK_FIRE_MAGIC] != you.skills[SK_ICE_MAGIC])
- type_wanted = STAFF_COLD;
- }
- else if (type_wanted == STAFF_AIR || type_wanted == STAFF_EARTH)
- {
- if (you.skills[SK_AIR_MAGIC] > you.skills[SK_EARTH_MAGIC])
- type_wanted = STAFF_AIR;
- else if (you.skills[SK_AIR_MAGIC] != you.skills[SK_EARTH_MAGIC])
- type_wanted = STAFF_EARTH;
- }
-
- best_spell = best_skill( SK_SPELLCASTING, (NUM_SKILLS-1), 99 );
-
- // If we're going to give out an enhancer stave,
- // we should at least bias things towards the
- // best spell skill. -- bwr
- switch (best_spell)
- {
- case SK_FIRE_MAGIC:
- if (!already_has[STAFF_FIRE])
- type_wanted = STAFF_FIRE;
- break;
-
- case SK_ICE_MAGIC:
- if (!already_has[STAFF_COLD])
- type_wanted = STAFF_COLD;
- break;
-
- case SK_AIR_MAGIC:
- if (!already_has[STAFF_AIR])
- type_wanted = STAFF_AIR;
- break;
-
- case SK_EARTH_MAGIC:
- if (!already_has[STAFF_EARTH])
- type_wanted = STAFF_EARTH;
- break;
-
- case SK_POISON_MAGIC:
- if (!already_has[STAFF_POISON])
- type_wanted = STAFF_POISON;
- break;
-
- case SK_NECROMANCY:
- if (!already_has[STAFF_DEATH])
- type_wanted = STAFF_DEATH;
- break;
-
- case SK_CONJURATIONS:
- if (!already_has[STAFF_CONJURATION])
- type_wanted = STAFF_CONJURATION;
- break;
-
- case SK_ENCHANTMENTS:
- if (!already_has[STAFF_ENCHANTMENT])
- type_wanted = STAFF_ENCHANTMENT;
- break;
-
- case SK_SUMMONINGS:
- if (!already_has[STAFF_SUMMONING])
- type_wanted = STAFF_SUMMONING;
- break;
-
- case SK_EVOCATIONS:
- if (!one_chance_in(4))
- type_wanted = STAFF_SMITING + random2(10);
- break;
-
- default: // invocations and leftover spell schools
- switch (random2(5))
- {
- case 0:
- type_wanted = STAFF_WIZARDRY;
- break;
-
- case 1:
- type_wanted = STAFF_POWER;
- break;
-
- case 2:
- type_wanted = STAFF_ENERGY;
- break;
-
- case 3:
- type_wanted = STAFF_CHANNELING;
- break;
-
- case 4:
- break;
- }
- break;
- }
-
- // Increased chance of getting spell staff for new or
- // non-spellcasters. -- bwr
- if (one_chance_in(20)
- || (spell_skills <= 1 // short on spells
- && (type_wanted < STAFF_SMITING // already making one
- || type_wanted >= STAFF_AIR)
- && !one_chance_in(4)))
- {
- type_wanted = (coinflip() ? STAFF_STRIKING
- : STAFF_SMITING + random2(10));
- }
- break;
-
- case OBJ_MISCELLANY:
- do
- type_wanted = random2(NUM_MISCELLANY);
- while (type_wanted == MISC_HORN_OF_GERYON
- || type_wanted == MISC_RUNE_OF_ZOT
- || type_wanted == MISC_PORTABLE_ALTAR_OF_NEMELEX
- || type_wanted == MISC_CRYSTAL_BALL_OF_FIXATION
- || type_wanted == MISC_EMPTY_EBONY_CASKET);
- break;
-
- default:
- mesclr();
- goto query;
- }
-
- ASSERT( type_wanted < max_has_value );
- }
- while (already_has[type_wanted] && !one_chance_in(200));
- }
-
- if (grid_destroys_items(grd[you.x_pos][you.y_pos]))
- {
- // how sad (and stupid)
- mprf(MSGCH_SOUND,
- grid_item_destruction_message(grd[you.x_pos][you.y_pos]));
- }
- else
- {
- // BCR - unique is now used for food quantity.
- thing_created = items( unique, class_wanted, type_wanted, true,
- MAKE_GOOD_ITEM, 250 );
-
- if (thing_created == NON_ITEM)
- {
- mpr("The demon of the infinite void smiles at you.");
- return (false);
- }
-
- // remove curse flag from item
- do_uncurse_item( mitm[thing_created] );
-
- if (mitm[thing_created].base_type == OBJ_BOOKS)
- {
- if (mitm[thing_created].base_type == BOOK_MINOR_MAGIC_I
- || mitm[thing_created].base_type == BOOK_MINOR_MAGIC_II
- || mitm[thing_created].base_type == BOOK_MINOR_MAGIC_III)
- {
- you.had_book[ BOOK_MINOR_MAGIC_I ] = 1;
- you.had_book[ BOOK_MINOR_MAGIC_II ] = 1;
- you.had_book[ BOOK_MINOR_MAGIC_III ] = 1;
- }
- else if (mitm[thing_created].base_type == BOOK_CONJURATIONS_I
- || mitm[thing_created].base_type == BOOK_CONJURATIONS_II)
- {
- you.had_book[ BOOK_CONJURATIONS_I ] = 1;
- you.had_book[ BOOK_CONJURATIONS_II ] = 1;
- }
- else
- {
- you.had_book[ mitm[thing_created].sub_type ] = 1;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_JEWELLERY)
- {
- switch (mitm[thing_created].sub_type)
- {
- case RING_SLAYING:
- // make sure plus to damage is >= 1
- mitm[thing_created].plus2 = abs( mitm[thing_created].plus2 );
- if (mitm[thing_created].plus2 == 0)
- mitm[thing_created].plus2 = 1;
- // fall through...
-
- case RING_PROTECTION:
- case RING_STRENGTH:
- case RING_INTELLIGENCE:
- case RING_DEXTERITY:
- case RING_EVASION:
- // make sure plus is >= 1
- mitm[thing_created].plus = abs( mitm[thing_created].plus );
- if (mitm[thing_created].plus == 0)
- mitm[thing_created].plus = 1;
- break;
-
- case RING_HUNGER:
- case AMU_INACCURACY:
- // these are the only truly bad pieces of jewellery
- if (!one_chance_in(9))
- make_item_randart( mitm[thing_created] );
- break;
-
- default:
- break;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_WEAPONS
- && !is_fixed_artefact( mitm[thing_created] ))
- {
- // HACK: make unwieldable weapons wieldable
- // Note: messing with fixed artefacts is probably very bad.
- switch (you.species)
- {
- case SP_DEMONSPAWN:
- case SP_MUMMY:
- case SP_GHOUL:
- {
- int brand = get_weapon_brand( mitm[thing_created] );
- if (brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_DISRUPTION)
- {
- if (!is_random_artefact( mitm[thing_created] ))
- {
- set_item_ego_type( mitm[thing_created],
- OBJ_WEAPONS, SPWPN_VORPAL );
- }
- else
- {
- // keep reseting seed until it's good:
- for (; brand == SPWPN_HOLY_WRATH
- || brand == SPWPN_DISRUPTION;
- brand = get_weapon_brand(mitm[thing_created]))
- {
- make_item_randart( mitm[thing_created] );
- }
- }
- }
- }
- break;
-
- case SP_HALFLING:
- case SP_GNOME:
- case SP_KOBOLD:
- case SP_SPRIGGAN:
- switch (mitm[thing_created].sub_type)
- {
- case WPN_LONGBOW:
- mitm[thing_created].sub_type = WPN_BOW;
- break;
-
- case WPN_GREAT_SWORD:
- case WPN_TRIPLE_SWORD:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_FALCHION : WPN_LONG_SWORD);
- break;
-
- case WPN_GREAT_MACE:
- case WPN_DIRE_FLAIL:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_MACE : WPN_FLAIL);
- break;
-
- case WPN_BATTLEAXE:
- case WPN_EXECUTIONERS_AXE:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_HAND_AXE : WPN_WAR_AXE);
- break;
-
- case WPN_HALBERD:
- case WPN_GLAIVE:
- case WPN_SCYTHE:
- case WPN_LOCHABER_AXE:
- mitm[thing_created].sub_type =
- (coinflip() ? WPN_SPEAR : WPN_TRIDENT);
- break;
- }
- break;
-
- default:
- break;
- }
- }
- else if (mitm[thing_created].base_type == OBJ_ARMOUR
- && !is_fixed_artefact( mitm[thing_created] ))
- {
- // HACK: make unwearable hats and boots wearable
- // Note: messing with fixed artefacts is probably very bad.
- switch (mitm[thing_created].sub_type)
- {
- case ARM_HELMET:
- if ((get_helmet_type(mitm[thing_created]) == THELM_HELM
- || get_helmet_type(mitm[thing_created]) == THELM_HELMET)
- && ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE)
- || player_genus(GENPC_DRACONIAN)
- || you.species == SP_MINOTAUR
- || you.species == SP_KENKU
- || you.species == SP_SPRIGGAN
- || you.mutation[MUT_HORNS]))
- {
- // turn it into a cap or wizard hat
- set_helmet_type( mitm[thing_created],
- coinflip() ? THELM_CAP : THELM_WIZARD_HAT );
-
- mitm[thing_created].colour = random_colour();
- }
- break;
-
- case ARM_BOOTS:
- if (you.species == SP_NAGA)
- mitm[thing_created].sub_type = ARM_NAGA_BARDING;
- else if (you.species == SP_CENTAUR)
- mitm[thing_created].sub_type = ARM_CENTAUR_BARDING;
-
- // fix illegal barding ego types caused by above hack
- if (mitm[thing_created].sub_type != ARM_BOOTS
- && get_armour_ego_type( mitm[thing_created] )
- == SPARM_RUNNING)
- {
- set_item_ego_type(
- mitm[thing_created], OBJ_ARMOUR, SPARM_NORMAL );
- }
- break;
-
- default:
- break;
- }
- }
-
- move_item_to_grid( &thing_created, you.x_pos, you.y_pos );
-
- // This should never actually be NON_ITEM because of the way
- // move_item_to_grid works (doesn't create a new item ever),
- // but we're checking it anyways. -- bwr
- if (thing_created != NON_ITEM)
- {
- canned_msg(MSG_SOMETHING_APPEARS);
- origin_acquired(mitm[thing_created], agent);
- }
- }
-
- // Well, the item may have fallen in the drink, but the intent is
- // that acquirement happened. -- bwr
- return (true);
-} // end acquirement()
-
-bool recharge_wand(void)
-{
- if (you.equip[EQ_WEAPON] == -1)
- return (false);
-
- item_def &wand = you.inv[ you.equip[EQ_WEAPON] ];
-
- if (wand.base_type != OBJ_WANDS && !item_is_rod(wand))
- return (false);
-
- int charge_gain = 0;
- if (wand.base_type == OBJ_WANDS)
- {
- switch (wand.sub_type)
- {
- case WAND_INVISIBILITY:
- case WAND_FIREBALL:
- case WAND_HEALING:
- charge_gain = 3;
- break;
-
- case WAND_LIGHTNING:
- case WAND_DRAINING:
- charge_gain = 4;
- break;
-
- case WAND_FIRE:
- case WAND_COLD:
- charge_gain = 5;
- break;
-
- default:
- charge_gain = 8;
- break;
- }
-
- char str_pass[ ITEMNAME_SIZE ];
- item_name(wand, DESC_CAP_YOUR, str_pass);
- mprf("%s glows for a moment.", str_pass);
-
- wand.plus += 1 + random2avg( ((charge_gain - 1) * 3) + 1, 3 );
-
- if (wand.plus > charge_gain * 3)
- wand.plus = charge_gain * 3;
- }
- else
- {
- // This is a rod.
- bool work = false;
-
- if (wand.plus2 <= MAX_ROD_CHARGE * ROD_CHARGE_MULT)
- {
- wand.plus2 += ROD_CHARGE_MULT;
-
- if (wand.plus2 > MAX_ROD_CHARGE * ROD_CHARGE_MULT)
- wand.plus2 = MAX_ROD_CHARGE * ROD_CHARGE_MULT;
-
- work = true;
- }
-
- if (wand.plus < wand.plus2)
- {
- wand.plus = wand.plus2;
- work = true;
- }
-
- if (!work)
- return (false);
-
- char str_pass[ITEMNAME_SIZE];
- item_name( wand, DESC_CAP_YOUR, str_pass );
- mprf("%s glows for a moment.", str_pass);
- }
-
- you.wield_change = true;
- return (true);
-} // end recharge_wand()
-
-void yell(void)
-{
- bool targ_prev = false;
- int mons_targd = MHITNOT;
- struct dist targ;
-
- if (silenced(you.x_pos, you.y_pos))
- {
- mpr("You are unable to make a sound!");
- return;
- }
-
- mpr("What do you say?", MSGCH_PROMPT);
- mpr(" ! - Yell");
- mpr(" a - Order allies to attack a monster");
-
- if (!(you.prev_targ == MHITNOT || you.prev_targ == MHITYOU))
- {
- struct monsters *target = &menv[you.prev_targ];
-
- if (mons_near(target) && player_monster_visible(target))
- {
- mpr(" p - Order allies to attack your previous target");
- targ_prev = true;
- }
- }
-
- strcpy(info, " Anything else - Stay silent");
-
- if (one_chance_in(20))
- strcat(info, " (and be thought a fool)");
-
- mpr(info);
-
- unsigned char keyn = get_ch();
-
- switch (keyn)
- {
- case '!':
- mpr("You yell for attention!", MSGCH_SOUND);
- you.turn_is_over = 1;
- noisy( 12, you.x_pos, you.y_pos );
- return;
-
- case 'a':
- mpr("Gang up on whom?", MSGCH_PROMPT);
- direction( targ, DIR_TARGET, TARG_ENEMY );
-
- if (targ.isCancel)
- {
- canned_msg(MSG_OK);
- return;
- }
-
- if (!targ.isValid || mgrd[targ.tx][targ.ty] == NON_MONSTER)
- {
- mpr("Yeah, whatever.");
- return;
- }
-
- mons_targd = mgrd[targ.tx][targ.ty];
- break;
-
- case 'p':
- if (targ_prev)
- {
- mons_targd = you.prev_targ;
- break;
- }
- /* fall through... */
- default:
- mpr("Okely-dokely.");
- return;
- }
-
- you.pet_target = mons_targd;
-
- noisy( 10, you.x_pos, you.y_pos );
- mpr("Attack!");
-} // end yell()