Long swords are overused, and Knights already start with a long sword. No other roles start with a spear. Lawful Valks shouldn't have an easy way to get Excalibur. There's also historical precedence for valkyries with spears, see eg. Wagner's Ring Cycle. This makes Valks early game damage slightly lower, although dwarven spear does the same damage to small monsters as long sword, and there should be plenty of chances to get one from the mines. Spears can also be thrown. This change has been done in several variants, eg. xNetHack and Fourk.
1194 lines
39 KiB
C
1194 lines
39 KiB
C
/* NetHack 3.7 u_init.c $NHDT-Date: 1621131203 2021/05/16 02:13:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */
|
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
|
/*-Copyright (c) Robert Patrick Rankin, 2017. */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "hack.h"
|
|
|
|
struct trobj {
|
|
short trotyp;
|
|
schar trspe;
|
|
char trclass;
|
|
Bitfield(trquan, 6);
|
|
Bitfield(trbless, 2);
|
|
};
|
|
|
|
static void ini_inv(struct trobj *);
|
|
static void knows_object(int);
|
|
static void knows_class(char);
|
|
static boolean restricted_spell_discipline(int);
|
|
|
|
#define UNDEF_TYP 0
|
|
#define UNDEF_SPE '\177'
|
|
#define UNDEF_BLESS 2
|
|
|
|
/*
|
|
* Initial inventory for the various roles.
|
|
*/
|
|
|
|
static struct trobj Archeologist[] = {
|
|
/* if adventure has a name... idea from tan@uvm-gen */
|
|
{ BULLWHIP, 2, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ LEATHER_JACKET, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ FEDORA, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ FOOD_RATION, 0, FOOD_CLASS, 3, 0 },
|
|
{ PICK_AXE, UNDEF_SPE, TOOL_CLASS, 1, UNDEF_BLESS },
|
|
{ TINNING_KIT, UNDEF_SPE, TOOL_CLASS, 1, UNDEF_BLESS },
|
|
{ TOUCHSTONE, 0, GEM_CLASS, 1, 0 },
|
|
{ SACK, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Barbarian[] = {
|
|
#define B_MAJOR 0 /* two-handed sword or battle-axe */
|
|
#define B_MINOR 1 /* matched with axe or short sword */
|
|
{ TWO_HANDED_SWORD, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ AXE, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ RING_MAIL, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ FOOD_RATION, 0, FOOD_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Cave_man[] = {
|
|
#define C_AMMO 2
|
|
{ CLUB, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ SLING, 2, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ FLINT, 0, GEM_CLASS, 15, UNDEF_BLESS }, /* quan is variable */
|
|
{ ROCK, 0, GEM_CLASS, 3, 0 }, /* yields 18..33 */
|
|
{ LEATHER_ARMOR, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Healer[] = {
|
|
{ SCALPEL, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ LEATHER_GLOVES, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ STETHOSCOPE, 0, TOOL_CLASS, 1, 0 },
|
|
{ POT_HEALING, 0, POTION_CLASS, 4, UNDEF_BLESS },
|
|
{ POT_EXTRA_HEALING, 0, POTION_CLASS, 4, UNDEF_BLESS },
|
|
{ WAN_SLEEP, UNDEF_SPE, WAND_CLASS, 1, UNDEF_BLESS },
|
|
/* always blessed, so it's guaranteed readable */
|
|
{ SPE_HEALING, 0, SPBOOK_CLASS, 1, 1 },
|
|
{ SPE_EXTRA_HEALING, 0, SPBOOK_CLASS, 1, 1 },
|
|
{ SPE_STONE_TO_FLESH, 0, SPBOOK_CLASS, 1, 1 },
|
|
{ APPLE, 0, FOOD_CLASS, 5, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Knight[] = {
|
|
{ LONG_SWORD, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ LANCE, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ RING_MAIL, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ HELMET, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ SMALL_SHIELD, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ LEATHER_GLOVES, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ APPLE, 0, FOOD_CLASS, 10, 0 },
|
|
{ CARROT, 0, FOOD_CLASS, 10, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Monk[] = {
|
|
#define M_BOOK 2
|
|
{ LEATHER_GLOVES, 2, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ ROBE, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, 1 },
|
|
{ UNDEF_TYP, UNDEF_SPE, SCROLL_CLASS, 1, UNDEF_BLESS },
|
|
{ POT_HEALING, 0, POTION_CLASS, 3, UNDEF_BLESS },
|
|
{ FOOD_RATION, 0, FOOD_CLASS, 3, 0 },
|
|
{ APPLE, 0, FOOD_CLASS, 5, UNDEF_BLESS },
|
|
{ ORANGE, 0, FOOD_CLASS, 5, UNDEF_BLESS },
|
|
/* Yes, we know fortune cookies aren't really from China. They were
|
|
* invented by George Jung in Los Angeles, California, USA in 1916.
|
|
*/
|
|
{ FORTUNE_COOKIE, 0, FOOD_CLASS, 3, UNDEF_BLESS },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Priest[] = {
|
|
{ MACE, 1, WEAPON_CLASS, 1, 1 },
|
|
{ ROBE, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ SMALL_SHIELD, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ POT_WATER, 0, POTION_CLASS, 4, 1 }, /* holy water */
|
|
{ CLOVE_OF_GARLIC, 0, FOOD_CLASS, 1, 0 },
|
|
{ SPRIG_OF_WOLFSBANE, 0, FOOD_CLASS, 1, 0 },
|
|
{ UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 2, UNDEF_BLESS },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Ranger[] = {
|
|
#define RAN_BOW 1
|
|
#define RAN_TWO_ARROWS 2
|
|
#define RAN_ZERO_ARROWS 3
|
|
{ DAGGER, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ BOW, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ ARROW, 2, WEAPON_CLASS, 50, UNDEF_BLESS },
|
|
{ ARROW, 0, WEAPON_CLASS, 30, UNDEF_BLESS },
|
|
{ CLOAK_OF_DISPLACEMENT, 2, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ CRAM_RATION, 0, FOOD_CLASS, 4, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Rogue[] = {
|
|
#define R_DAGGERS 1
|
|
{ SHORT_SWORD, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ DAGGER, 0, WEAPON_CLASS, 10, 0 }, /* quan is variable */
|
|
{ LEATHER_ARMOR, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ POT_SICKNESS, 0, POTION_CLASS, 1, 0 },
|
|
{ LOCK_PICK, 0, TOOL_CLASS, 1, 0 },
|
|
{ SACK, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Samurai[] = {
|
|
#define S_ARROWS 3
|
|
{ KATANA, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ SHORT_SWORD, 0, WEAPON_CLASS, 1, UNDEF_BLESS }, /* wakizashi */
|
|
{ YUMI, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ YA, 0, WEAPON_CLASS, 25, UNDEF_BLESS }, /* variable quan */
|
|
{ SPLINT_MAIL, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Tourist[] = {
|
|
#define T_DARTS 0
|
|
{ DART, 2, WEAPON_CLASS, 25, UNDEF_BLESS }, /* quan is variable */
|
|
{ UNDEF_TYP, UNDEF_SPE, FOOD_CLASS, 10, 0 },
|
|
{ POT_EXTRA_HEALING, 0, POTION_CLASS, 2, UNDEF_BLESS },
|
|
{ SCR_MAGIC_MAPPING, 0, SCROLL_CLASS, 4, UNDEF_BLESS },
|
|
{ HAWAIIAN_SHIRT, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ EXPENSIVE_CAMERA, UNDEF_SPE, TOOL_CLASS, 1, 0 },
|
|
{ CREDIT_CARD, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Valkyrie[] = {
|
|
{ SPEAR, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ DAGGER, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
|
|
{ SMALL_SHIELD, 3, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ FOOD_RATION, 0, FOOD_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
static struct trobj Wizard[] = {
|
|
#define W_MULTSTART 2
|
|
#define W_MULTEND 6
|
|
{ QUARTERSTAFF, 1, WEAPON_CLASS, 1, 1 },
|
|
{ CLOAK_OF_MAGIC_RESISTANCE, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
|
|
{ UNDEF_TYP, UNDEF_SPE, WAND_CLASS, 1, UNDEF_BLESS },
|
|
{ UNDEF_TYP, UNDEF_SPE, RING_CLASS, 2, UNDEF_BLESS },
|
|
{ UNDEF_TYP, UNDEF_SPE, POTION_CLASS, 3, UNDEF_BLESS },
|
|
{ UNDEF_TYP, UNDEF_SPE, SCROLL_CLASS, 3, UNDEF_BLESS },
|
|
{ SPE_FORCE_BOLT, 0, SPBOOK_CLASS, 1, 1 },
|
|
{ UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, UNDEF_BLESS },
|
|
{ 0, 0, 0, 0, 0 }
|
|
};
|
|
|
|
/*
|
|
* Optional extra inventory items.
|
|
*/
|
|
|
|
static struct trobj Tinopener[] = { { TIN_OPENER, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Magicmarker[] = { { MAGIC_MARKER, UNDEF_SPE, TOOL_CLASS,
|
|
1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Lamp[] = { { OIL_LAMP, 1, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Blindfold[] = { { BLINDFOLD, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Instrument[] = { { WOODEN_FLUTE, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Xtra_food[] = { { UNDEF_TYP, UNDEF_SPE, FOOD_CLASS, 2, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Leash[] = { { LEASH, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Towel[] = { { TOWEL, 0, TOOL_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Wishing[] = { { WAN_WISHING, 3, WAND_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
static struct trobj Money[] = { { GOLD_PIECE, 0, COIN_CLASS, 1, 0 },
|
|
{ 0, 0, 0, 0, 0 } };
|
|
|
|
/* race-based substitutions for initial inventory;
|
|
the weaker cloak for elven rangers is intentional--they shoot better */
|
|
static struct inv_sub {
|
|
short race_pm, item_otyp, subs_otyp;
|
|
} inv_subs[] = {
|
|
{ PM_ELF, DAGGER, ELVEN_DAGGER },
|
|
{ PM_ELF, SPEAR, ELVEN_SPEAR },
|
|
{ PM_ELF, SHORT_SWORD, ELVEN_SHORT_SWORD },
|
|
{ PM_ELF, BOW, ELVEN_BOW },
|
|
{ PM_ELF, ARROW, ELVEN_ARROW },
|
|
{ PM_ELF, HELMET, ELVEN_LEATHER_HELM },
|
|
/* { PM_ELF, SMALL_SHIELD, ELVEN_SHIELD }, */
|
|
{ PM_ELF, CLOAK_OF_DISPLACEMENT, ELVEN_CLOAK },
|
|
{ PM_ELF, CRAM_RATION, LEMBAS_WAFER },
|
|
{ PM_ORC, DAGGER, ORCISH_DAGGER },
|
|
{ PM_ORC, SPEAR, ORCISH_SPEAR },
|
|
{ PM_ORC, SHORT_SWORD, ORCISH_SHORT_SWORD },
|
|
{ PM_ORC, BOW, ORCISH_BOW },
|
|
{ PM_ORC, ARROW, ORCISH_ARROW },
|
|
{ PM_ORC, HELMET, ORCISH_HELM },
|
|
{ PM_ORC, SMALL_SHIELD, ORCISH_SHIELD },
|
|
{ PM_ORC, RING_MAIL, ORCISH_RING_MAIL },
|
|
{ PM_ORC, CHAIN_MAIL, ORCISH_CHAIN_MAIL },
|
|
{ PM_ORC, CRAM_RATION, TRIPE_RATION },
|
|
{ PM_ORC, LEMBAS_WAFER, TRIPE_RATION },
|
|
{ PM_DWARF, SPEAR, DWARVISH_SPEAR },
|
|
{ PM_DWARF, SHORT_SWORD, DWARVISH_SHORT_SWORD },
|
|
{ PM_DWARF, HELMET, DWARVISH_IRON_HELM },
|
|
/* { PM_DWARF, SMALL_SHIELD, DWARVISH_ROUNDSHIELD }, */
|
|
/* { PM_DWARF, PICK_AXE, DWARVISH_MATTOCK }, */
|
|
{ PM_DWARF, LEMBAS_WAFER, CRAM_RATION },
|
|
{ PM_GNOME, BOW, CROSSBOW },
|
|
{ PM_GNOME, ARROW, CROSSBOW_BOLT },
|
|
{ NON_PM, STRANGE_OBJECT, STRANGE_OBJECT }
|
|
};
|
|
|
|
static const struct def_skill Skill_A[] = {
|
|
{ P_DAGGER, P_BASIC },
|
|
{ P_KNIFE, P_BASIC },
|
|
{ P_PICK_AXE, P_EXPERT },
|
|
{ P_SHORT_SWORD, P_BASIC },
|
|
{ P_SCIMITAR, P_SKILLED },
|
|
{ P_SABER, P_EXPERT },
|
|
{ P_CLUB, P_SKILLED },
|
|
{ P_QUARTERSTAFF, P_SKILLED },
|
|
{ P_SLING, P_SKILLED },
|
|
{ P_DART, P_BASIC },
|
|
{ P_BOOMERANG, P_EXPERT },
|
|
{ P_WHIP, P_EXPERT },
|
|
{ P_UNICORN_HORN, P_SKILLED },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_HEALING_SPELL, P_BASIC },
|
|
{ P_DIVINATION_SPELL, P_EXPERT },
|
|
{ P_MATTER_SPELL, P_BASIC },
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_TWO_WEAPON_COMBAT, P_BASIC },
|
|
{ P_BARE_HANDED_COMBAT, P_EXPERT },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_B[] = {
|
|
{ P_DAGGER, P_BASIC },
|
|
{ P_AXE, P_EXPERT },
|
|
{ P_PICK_AXE, P_SKILLED },
|
|
{ P_SHORT_SWORD, P_EXPERT },
|
|
{ P_BROAD_SWORD, P_SKILLED },
|
|
{ P_LONG_SWORD, P_SKILLED },
|
|
{ P_TWO_HANDED_SWORD, P_EXPERT },
|
|
{ P_SCIMITAR, P_SKILLED },
|
|
{ P_SABER, P_BASIC },
|
|
{ P_CLUB, P_SKILLED },
|
|
{ P_MACE, P_SKILLED },
|
|
{ P_MORNING_STAR, P_SKILLED },
|
|
{ P_FLAIL, P_BASIC },
|
|
{ P_HAMMER, P_EXPERT },
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_SPEAR, P_SKILLED },
|
|
{ P_TRIDENT, P_SKILLED },
|
|
{ P_BOW, P_BASIC },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_ESCAPE_SPELL, P_BASIC }, /* special spell is haste self */
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_TWO_WEAPON_COMBAT, P_BASIC },
|
|
{ P_BARE_HANDED_COMBAT, P_MASTER },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_C[] = {
|
|
{ P_DAGGER, P_BASIC },
|
|
{ P_KNIFE, P_SKILLED },
|
|
{ P_AXE, P_SKILLED },
|
|
{ P_PICK_AXE, P_BASIC },
|
|
{ P_CLUB, P_EXPERT },
|
|
{ P_MACE, P_EXPERT },
|
|
{ P_MORNING_STAR, P_BASIC },
|
|
{ P_FLAIL, P_SKILLED },
|
|
{ P_HAMMER, P_SKILLED },
|
|
{ P_QUARTERSTAFF, P_EXPERT },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_EXPERT },
|
|
{ P_TRIDENT, P_SKILLED },
|
|
{ P_BOW, P_SKILLED },
|
|
{ P_SLING, P_EXPERT },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_MATTER_SPELL, P_SKILLED },
|
|
{ P_BOOMERANG, P_EXPERT },
|
|
{ P_UNICORN_HORN, P_BASIC },
|
|
{ P_BARE_HANDED_COMBAT, P_MASTER },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_H[] = {
|
|
{ P_DAGGER, P_SKILLED },
|
|
{ P_KNIFE, P_EXPERT },
|
|
{ P_SHORT_SWORD, P_SKILLED },
|
|
{ P_SCIMITAR, P_BASIC },
|
|
{ P_SABER, P_BASIC },
|
|
{ P_CLUB, P_SKILLED },
|
|
{ P_MACE, P_BASIC },
|
|
{ P_QUARTERSTAFF, P_EXPERT },
|
|
{ P_POLEARMS, P_BASIC },
|
|
{ P_SPEAR, P_BASIC },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_SLING, P_SKILLED },
|
|
{ P_DART, P_EXPERT },
|
|
{ P_SHURIKEN, P_SKILLED },
|
|
{ P_UNICORN_HORN, P_EXPERT },
|
|
{ P_HEALING_SPELL, P_EXPERT },
|
|
{ P_BARE_HANDED_COMBAT, P_BASIC },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_K[] = {
|
|
{ P_DAGGER, P_BASIC },
|
|
{ P_KNIFE, P_BASIC },
|
|
{ P_AXE, P_SKILLED },
|
|
{ P_PICK_AXE, P_BASIC },
|
|
{ P_SHORT_SWORD, P_SKILLED },
|
|
{ P_BROAD_SWORD, P_SKILLED },
|
|
{ P_LONG_SWORD, P_EXPERT },
|
|
{ P_TWO_HANDED_SWORD, P_SKILLED },
|
|
{ P_SCIMITAR, P_BASIC },
|
|
{ P_SABER, P_SKILLED },
|
|
{ P_CLUB, P_BASIC },
|
|
{ P_MACE, P_SKILLED },
|
|
{ P_MORNING_STAR, P_SKILLED },
|
|
{ P_FLAIL, P_BASIC },
|
|
{ P_HAMMER, P_BASIC },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_SKILLED },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_LANCE, P_EXPERT },
|
|
{ P_BOW, P_BASIC },
|
|
{ P_CROSSBOW, P_SKILLED },
|
|
{ P_ATTACK_SPELL, P_SKILLED },
|
|
{ P_HEALING_SPELL, P_SKILLED },
|
|
{ P_CLERIC_SPELL, P_SKILLED },
|
|
{ P_RIDING, P_EXPERT },
|
|
{ P_TWO_WEAPON_COMBAT, P_SKILLED },
|
|
{ P_BARE_HANDED_COMBAT, P_EXPERT },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_Mon[] = {
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_SPEAR, P_BASIC },
|
|
{ P_CROSSBOW, P_BASIC },
|
|
{ P_SHURIKEN, P_BASIC },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_HEALING_SPELL, P_EXPERT },
|
|
{ P_DIVINATION_SPELL, P_BASIC },
|
|
{ P_ENCHANTMENT_SPELL, P_BASIC },
|
|
{ P_CLERIC_SPELL, P_SKILLED },
|
|
{ P_ESCAPE_SPELL, P_SKILLED },
|
|
{ P_MATTER_SPELL, P_BASIC },
|
|
{ P_MARTIAL_ARTS, P_GRAND_MASTER },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_P[] = {
|
|
{ P_CLUB, P_EXPERT },
|
|
{ P_MACE, P_EXPERT },
|
|
{ P_MORNING_STAR, P_EXPERT },
|
|
{ P_FLAIL, P_EXPERT },
|
|
{ P_HAMMER, P_EXPERT },
|
|
{ P_QUARTERSTAFF, P_EXPERT },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_SKILLED },
|
|
{ P_TRIDENT, P_SKILLED },
|
|
{ P_LANCE, P_BASIC },
|
|
{ P_BOW, P_BASIC },
|
|
{ P_SLING, P_BASIC },
|
|
{ P_CROSSBOW, P_BASIC },
|
|
{ P_DART, P_BASIC },
|
|
{ P_SHURIKEN, P_BASIC },
|
|
{ P_BOOMERANG, P_BASIC },
|
|
{ P_UNICORN_HORN, P_SKILLED },
|
|
{ P_HEALING_SPELL, P_EXPERT },
|
|
{ P_DIVINATION_SPELL, P_EXPERT },
|
|
{ P_CLERIC_SPELL, P_EXPERT },
|
|
{ P_BARE_HANDED_COMBAT, P_BASIC },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_R[] = {
|
|
{ P_DAGGER, P_EXPERT },
|
|
{ P_KNIFE, P_EXPERT },
|
|
{ P_SHORT_SWORD, P_EXPERT },
|
|
{ P_BROAD_SWORD, P_SKILLED },
|
|
{ P_LONG_SWORD, P_SKILLED },
|
|
{ P_TWO_HANDED_SWORD, P_BASIC },
|
|
{ P_SCIMITAR, P_SKILLED },
|
|
{ P_SABER, P_SKILLED },
|
|
{ P_CLUB, P_SKILLED },
|
|
{ P_MACE, P_SKILLED },
|
|
{ P_MORNING_STAR, P_BASIC },
|
|
{ P_FLAIL, P_BASIC },
|
|
{ P_HAMMER, P_BASIC },
|
|
{ P_POLEARMS, P_BASIC },
|
|
{ P_SPEAR, P_BASIC },
|
|
{ P_CROSSBOW, P_EXPERT },
|
|
{ P_DART, P_EXPERT },
|
|
{ P_SHURIKEN, P_SKILLED },
|
|
{ P_DIVINATION_SPELL, P_SKILLED },
|
|
{ P_ESCAPE_SPELL, P_SKILLED },
|
|
{ P_MATTER_SPELL, P_SKILLED },
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_TWO_WEAPON_COMBAT, P_EXPERT },
|
|
{ P_BARE_HANDED_COMBAT, P_EXPERT },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_Ran[] = {
|
|
{ P_DAGGER, P_EXPERT },
|
|
{ P_KNIFE, P_SKILLED },
|
|
{ P_AXE, P_SKILLED },
|
|
{ P_PICK_AXE, P_BASIC },
|
|
{ P_SHORT_SWORD, P_BASIC },
|
|
{ P_MORNING_STAR, P_BASIC },
|
|
{ P_FLAIL, P_SKILLED },
|
|
{ P_HAMMER, P_BASIC },
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_EXPERT },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_BOW, P_EXPERT },
|
|
{ P_SLING, P_EXPERT },
|
|
{ P_CROSSBOW, P_EXPERT },
|
|
{ P_DART, P_EXPERT },
|
|
{ P_SHURIKEN, P_SKILLED },
|
|
{ P_BOOMERANG, P_EXPERT },
|
|
{ P_WHIP, P_BASIC },
|
|
{ P_HEALING_SPELL, P_BASIC },
|
|
{ P_DIVINATION_SPELL, P_EXPERT },
|
|
{ P_ESCAPE_SPELL, P_BASIC },
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_BARE_HANDED_COMBAT, P_BASIC },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_S[] = {
|
|
{ P_DAGGER, P_BASIC },
|
|
{ P_KNIFE, P_SKILLED },
|
|
{ P_SHORT_SWORD, P_EXPERT },
|
|
{ P_BROAD_SWORD, P_SKILLED },
|
|
{ P_LONG_SWORD, P_EXPERT },
|
|
{ P_TWO_HANDED_SWORD, P_EXPERT },
|
|
{ P_SCIMITAR, P_BASIC },
|
|
{ P_SABER, P_BASIC },
|
|
{ P_FLAIL, P_SKILLED },
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_SKILLED },
|
|
{ P_LANCE, P_SKILLED },
|
|
{ P_BOW, P_EXPERT },
|
|
{ P_SHURIKEN, P_EXPERT },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_DIVINATION_SPELL, P_BASIC }, /* special spell is clairvoyance */
|
|
{ P_CLERIC_SPELL, P_SKILLED },
|
|
{ P_RIDING, P_SKILLED },
|
|
{ P_TWO_WEAPON_COMBAT, P_EXPERT },
|
|
{ P_MARTIAL_ARTS, P_MASTER },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_T[] = {
|
|
{ P_DAGGER, P_EXPERT },
|
|
{ P_KNIFE, P_SKILLED },
|
|
{ P_AXE, P_BASIC },
|
|
{ P_PICK_AXE, P_BASIC },
|
|
{ P_SHORT_SWORD, P_EXPERT },
|
|
{ P_BROAD_SWORD, P_BASIC },
|
|
{ P_LONG_SWORD, P_BASIC },
|
|
{ P_TWO_HANDED_SWORD, P_BASIC },
|
|
{ P_SCIMITAR, P_SKILLED },
|
|
{ P_SABER, P_SKILLED },
|
|
{ P_MACE, P_BASIC },
|
|
{ P_MORNING_STAR, P_BASIC },
|
|
{ P_FLAIL, P_BASIC },
|
|
{ P_HAMMER, P_BASIC },
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_POLEARMS, P_BASIC },
|
|
{ P_SPEAR, P_BASIC },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_LANCE, P_BASIC },
|
|
{ P_BOW, P_BASIC },
|
|
{ P_SLING, P_BASIC },
|
|
{ P_CROSSBOW, P_BASIC },
|
|
{ P_DART, P_EXPERT },
|
|
{ P_SHURIKEN, P_BASIC },
|
|
{ P_BOOMERANG, P_BASIC },
|
|
{ P_WHIP, P_BASIC },
|
|
{ P_UNICORN_HORN, P_SKILLED },
|
|
{ P_DIVINATION_SPELL, P_BASIC },
|
|
{ P_ENCHANTMENT_SPELL, P_BASIC },
|
|
{ P_ESCAPE_SPELL, P_SKILLED },
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_TWO_WEAPON_COMBAT, P_SKILLED },
|
|
{ P_BARE_HANDED_COMBAT, P_SKILLED },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_V[] = {
|
|
{ P_DAGGER, P_EXPERT },
|
|
{ P_AXE, P_EXPERT },
|
|
{ P_PICK_AXE, P_SKILLED },
|
|
{ P_SHORT_SWORD, P_SKILLED },
|
|
{ P_BROAD_SWORD, P_SKILLED },
|
|
{ P_LONG_SWORD, P_EXPERT },
|
|
{ P_TWO_HANDED_SWORD, P_EXPERT },
|
|
{ P_SCIMITAR, P_BASIC },
|
|
{ P_SABER, P_BASIC },
|
|
{ P_HAMMER, P_EXPERT },
|
|
{ P_QUARTERSTAFF, P_BASIC },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_EXPERT },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_LANCE, P_SKILLED },
|
|
{ P_SLING, P_BASIC },
|
|
{ P_ATTACK_SPELL, P_BASIC },
|
|
{ P_ESCAPE_SPELL, P_BASIC },
|
|
{ P_RIDING, P_SKILLED },
|
|
{ P_TWO_WEAPON_COMBAT, P_SKILLED },
|
|
{ P_BARE_HANDED_COMBAT, P_EXPERT },
|
|
{ P_NONE, 0 }
|
|
};
|
|
static const struct def_skill Skill_W[] = {
|
|
{ P_DAGGER, P_EXPERT },
|
|
{ P_KNIFE, P_SKILLED },
|
|
{ P_AXE, P_SKILLED },
|
|
{ P_SHORT_SWORD, P_BASIC },
|
|
{ P_CLUB, P_SKILLED },
|
|
{ P_MACE, P_BASIC },
|
|
{ P_QUARTERSTAFF, P_EXPERT },
|
|
{ P_POLEARMS, P_SKILLED },
|
|
{ P_SPEAR, P_BASIC },
|
|
{ P_TRIDENT, P_BASIC },
|
|
{ P_SLING, P_SKILLED },
|
|
{ P_DART, P_EXPERT },
|
|
{ P_SHURIKEN, P_BASIC },
|
|
{ P_ATTACK_SPELL, P_EXPERT },
|
|
{ P_HEALING_SPELL, P_SKILLED },
|
|
{ P_DIVINATION_SPELL, P_EXPERT },
|
|
{ P_ENCHANTMENT_SPELL, P_SKILLED },
|
|
{ P_CLERIC_SPELL, P_SKILLED },
|
|
{ P_ESCAPE_SPELL, P_EXPERT },
|
|
{ P_MATTER_SPELL, P_EXPERT },
|
|
{ P_RIDING, P_BASIC },
|
|
{ P_BARE_HANDED_COMBAT, P_BASIC },
|
|
{ P_NONE, 0 }
|
|
};
|
|
|
|
static void
|
|
knows_object(int obj)
|
|
{
|
|
discover_object(obj, TRUE, FALSE);
|
|
objects[obj].oc_pre_discovered = 1; /* not a "discovery" */
|
|
}
|
|
|
|
/* Know ordinary (non-magical) objects of a certain class,
|
|
like all gems except the loadstone and luckstone. */
|
|
static void
|
|
knows_class(char sym)
|
|
{
|
|
struct obj odummy, *o;
|
|
int ct;
|
|
|
|
odummy = cg.zeroobj;
|
|
odummy.oclass = sym;
|
|
o = &odummy; /* for use in various obj.h macros */
|
|
|
|
/*
|
|
* Note: the exceptions here can be bypassed if necessary by
|
|
* calling knows_object() directly. So an elven ranger,
|
|
* for example, knows all elven weapons despite the bow,
|
|
* arrow, and spear limitation below.
|
|
*/
|
|
|
|
for (ct = g.bases[(uchar) sym]; ct < g.bases[(uchar) sym + 1]; ct++) {
|
|
/* not flagged as magic but shouldn't be pre-discovered */
|
|
if (ct == CORNUTHAUM || ct == DUNCE_CAP)
|
|
continue;
|
|
if (sym == WEAPON_CLASS) {
|
|
odummy.otyp = ct; /* update 'o' */
|
|
/* arbitrary: only knights and samurai recognize polearms */
|
|
if ((!Role_if(PM_KNIGHT) && !Role_if(PM_SAMURAI)) && is_pole(o))
|
|
continue;
|
|
/* rangers know all launchers (bows, &c), ammo (arrows, &c),
|
|
and spears regardless of race/species, but not other weapons */
|
|
if (Role_if(PM_RANGER)
|
|
&& (!is_launcher(o) && !is_ammo(o) && !is_spear(o)))
|
|
continue;
|
|
/* rogues know daggers, regardless of racial variations */
|
|
if (Role_if(PM_ROGUE) && (objects[o->otyp].oc_skill != P_DAGGER))
|
|
continue;
|
|
}
|
|
|
|
if (objects[ct].oc_class == sym && !objects[ct].oc_magic)
|
|
knows_object(ct);
|
|
}
|
|
}
|
|
|
|
void
|
|
u_init(void)
|
|
{
|
|
register int i;
|
|
struct u_roleplay tmpuroleplay = u.uroleplay; /* set by rcfile options */
|
|
|
|
flags.female = flags.initgend;
|
|
flags.beginner = 1;
|
|
|
|
/* zero u, including pointer values --
|
|
* necessary when aborting from a failed restore */
|
|
(void) memset((genericptr_t) &u, 0, sizeof(u));
|
|
u.ustuck = (struct monst *) 0;
|
|
(void) memset((genericptr_t) &ubirthday, 0, sizeof(ubirthday));
|
|
(void) memset((genericptr_t) &urealtime, 0, sizeof(urealtime));
|
|
|
|
u.uroleplay = tmpuroleplay; /* restore options set via rcfile */
|
|
|
|
#if 0 /* documentation of more zero values as desirable */
|
|
u.usick_cause[0] = 0;
|
|
u.uluck = u.moreluck = 0;
|
|
uarmu = 0;
|
|
uarm = uarmc = uarmh = uarms = uarmg = uarmf = 0;
|
|
uwep = uball = uchain = uleft = uright = 0;
|
|
uswapwep = uquiver = 0;
|
|
u.twoweap = FALSE; /* bypass set_twoweap() */
|
|
u.ublessed = 0; /* not worthy yet */
|
|
u.ugangr = 0; /* gods not angry */
|
|
u.ugifts = 0; /* no divine gifts bestowed */
|
|
u.uevent.uhand_of_elbereth = 0;
|
|
u.uevent.uheard_tune = 0;
|
|
u.uevent.uopened_dbridge = 0;
|
|
u.uevent.udemigod = 0; /* not a demi-god yet... */
|
|
u.udg_cnt = 0;
|
|
u.mh = u.mhmax = u.mtimedone = 0;
|
|
u.uz.dnum = u.uz0.dnum = 0;
|
|
u.utotype = UTOTYPE_NONE;
|
|
#endif /* 0 */
|
|
|
|
u.uz.dlevel = 1;
|
|
u.uz0.dlevel = 0;
|
|
u.utolev = u.uz;
|
|
|
|
u.umoved = FALSE;
|
|
u.umortality = 0;
|
|
u.ugrave_arise = NON_PM;
|
|
|
|
u.umonnum = u.umonster = g.urole.mnum;
|
|
u.ulycn = NON_PM;
|
|
set_uasmon();
|
|
|
|
u.ulevel = 0; /* set up some of the initial attributes */
|
|
u.uhp = u.uhpmax = u.uhppeak = newhp();
|
|
u.uen = u.uenmax = u.uenpeak = newpw();
|
|
u.uspellprot = 0;
|
|
adjabil(0, 1);
|
|
u.ulevel = u.ulevelmax = 1;
|
|
|
|
init_uhunger();
|
|
for (i = 0; i <= MAXSPELL; i++)
|
|
g.spl_book[i].sp_id = NO_SPELL;
|
|
u.ublesscnt = 300; /* no prayers just yet */
|
|
u.ualignbase[A_CURRENT] = u.ualignbase[A_ORIGINAL] = u.ualign.type =
|
|
aligns[flags.initalign].value;
|
|
|
|
#if defined(BSD) && !defined(POSIX_TYPES)
|
|
(void) time((long *) &ubirthday);
|
|
#else
|
|
(void) time(&ubirthday);
|
|
#endif
|
|
|
|
/*
|
|
* For now, everyone starts out with a night vision range of 1 and
|
|
* their xray range disabled.
|
|
*/
|
|
u.nv_range = 1;
|
|
u.xray_range = -1;
|
|
|
|
/*** Role-specific initializations ***/
|
|
switch (Role_switch) {
|
|
/* rn2(100) > 50 necessary for some choices because some
|
|
* random number generators are bad enough to seriously
|
|
* skew the results if we use rn2(2)... --KAA
|
|
*/
|
|
case PM_ARCHEOLOGIST:
|
|
ini_inv(Archeologist);
|
|
if (!rn2(10))
|
|
ini_inv(Tinopener);
|
|
else if (!rn2(4))
|
|
ini_inv(Lamp);
|
|
else if (!rn2(10))
|
|
ini_inv(Magicmarker);
|
|
knows_object(SACK);
|
|
knows_object(TOUCHSTONE);
|
|
skill_init(Skill_A);
|
|
break;
|
|
case PM_BARBARIAN:
|
|
if (rn2(100) >= 50) { /* see above comment */
|
|
Barbarian[B_MAJOR].trotyp = BATTLE_AXE;
|
|
Barbarian[B_MINOR].trotyp = SHORT_SWORD;
|
|
}
|
|
ini_inv(Barbarian);
|
|
if (!rn2(6))
|
|
ini_inv(Lamp);
|
|
knows_class(WEAPON_CLASS); /* excluding polearms */
|
|
knows_class(ARMOR_CLASS);
|
|
skill_init(Skill_B);
|
|
break;
|
|
case PM_CAVE_DWELLER:
|
|
Cave_man[C_AMMO].trquan = rn1(11, 10); /* 10..20 */
|
|
ini_inv(Cave_man);
|
|
skill_init(Skill_C);
|
|
break;
|
|
case PM_HEALER:
|
|
u.umoney0 = rn1(1000, 1001);
|
|
ini_inv(Healer);
|
|
if (!rn2(25))
|
|
ini_inv(Lamp);
|
|
knows_object(POT_FULL_HEALING);
|
|
skill_init(Skill_H);
|
|
break;
|
|
case PM_KNIGHT:
|
|
ini_inv(Knight);
|
|
knows_class(WEAPON_CLASS); /* all weapons */
|
|
knows_class(ARMOR_CLASS);
|
|
/* give knights chess-like mobility--idea from wooledge@..cwru.edu */
|
|
HJumping |= FROMOUTSIDE;
|
|
skill_init(Skill_K);
|
|
break;
|
|
case PM_MONK: {
|
|
static short M_spell[] = { SPE_HEALING, SPE_PROTECTION, SPE_CONFUSE_MONSTER };
|
|
|
|
Monk[M_BOOK].trotyp = M_spell[rn2(90) / 30]; /* [0..2] */
|
|
ini_inv(Monk);
|
|
if (!rn2(5))
|
|
ini_inv(Magicmarker);
|
|
else if (!rn2(10))
|
|
ini_inv(Lamp);
|
|
knows_class(ARMOR_CLASS);
|
|
/* sufficiently martial-arts oriented item to ignore language issue */
|
|
knows_object(SHURIKEN);
|
|
skill_init(Skill_Mon);
|
|
break;
|
|
}
|
|
case PM_CLERIC:
|
|
ini_inv(Priest);
|
|
if (!rn2(10))
|
|
ini_inv(Magicmarker);
|
|
else if (!rn2(10))
|
|
ini_inv(Lamp);
|
|
knows_object(POT_WATER);
|
|
skill_init(Skill_P);
|
|
/* KMH, conduct --
|
|
* Some may claim that this isn't agnostic, since they
|
|
* are literally "priests" and they have holy water.
|
|
* But we don't count it as such. Purists can always
|
|
* avoid playing priests and/or confirm another player's
|
|
* role in their YAAP.
|
|
*/
|
|
break;
|
|
case PM_RANGER:
|
|
Ranger[RAN_TWO_ARROWS].trquan = rn1(10, 50);
|
|
Ranger[RAN_ZERO_ARROWS].trquan = rn1(10, 30);
|
|
ini_inv(Ranger);
|
|
knows_class(WEAPON_CLASS); /* bows, arrows, spears only */
|
|
skill_init(Skill_Ran);
|
|
break;
|
|
case PM_ROGUE:
|
|
Rogue[R_DAGGERS].trquan = rn1(10, 6);
|
|
u.umoney0 = 0;
|
|
ini_inv(Rogue);
|
|
if (!rn2(5))
|
|
ini_inv(Blindfold);
|
|
knows_object(SACK);
|
|
knows_class(WEAPON_CLASS); /* daggers only */
|
|
skill_init(Skill_R);
|
|
break;
|
|
case PM_SAMURAI:
|
|
Samurai[S_ARROWS].trquan = rn1(20, 26);
|
|
ini_inv(Samurai);
|
|
if (!rn2(5))
|
|
ini_inv(Blindfold);
|
|
knows_class(WEAPON_CLASS); /* all weapons */
|
|
knows_class(ARMOR_CLASS);
|
|
skill_init(Skill_S);
|
|
break;
|
|
case PM_TOURIST:
|
|
Tourist[T_DARTS].trquan = rn1(20, 21);
|
|
u.umoney0 = rnd(1000);
|
|
ini_inv(Tourist);
|
|
if (!rn2(25))
|
|
ini_inv(Tinopener);
|
|
else if (!rn2(25))
|
|
ini_inv(Leash);
|
|
else if (!rn2(25))
|
|
ini_inv(Towel);
|
|
else if (!rn2(25))
|
|
ini_inv(Magicmarker);
|
|
skill_init(Skill_T);
|
|
break;
|
|
case PM_VALKYRIE:
|
|
ini_inv(Valkyrie);
|
|
if (!rn2(6))
|
|
ini_inv(Lamp);
|
|
knows_class(WEAPON_CLASS); /* excludes polearms */
|
|
knows_class(ARMOR_CLASS);
|
|
skill_init(Skill_V);
|
|
break;
|
|
case PM_WIZARD:
|
|
ini_inv(Wizard);
|
|
if (!rn2(5))
|
|
ini_inv(Magicmarker);
|
|
if (!rn2(5))
|
|
ini_inv(Blindfold);
|
|
skill_init(Skill_W);
|
|
break;
|
|
|
|
default: /* impossible */
|
|
break;
|
|
}
|
|
|
|
/*** Race-specific initializations ***/
|
|
switch (Race_switch) {
|
|
case PM_HUMAN:
|
|
/* Nothing special */
|
|
break;
|
|
|
|
case PM_ELF:
|
|
/*
|
|
* Elves are people of music and song, or they are warriors.
|
|
* Non-warriors get an instrument. We use a kludge to
|
|
* get only non-magic instruments.
|
|
*/
|
|
if (Role_if(PM_CLERIC) || Role_if(PM_WIZARD)) {
|
|
static int trotyp[] = { WOODEN_FLUTE, TOOLED_HORN, WOODEN_HARP,
|
|
BELL, BUGLE, LEATHER_DRUM };
|
|
Instrument[0].trotyp = trotyp[rn2(SIZE(trotyp))];
|
|
ini_inv(Instrument);
|
|
}
|
|
|
|
/* Elves can recognize all elvish objects */
|
|
knows_object(ELVEN_SHORT_SWORD);
|
|
knows_object(ELVEN_ARROW);
|
|
knows_object(ELVEN_BOW);
|
|
knows_object(ELVEN_SPEAR);
|
|
knows_object(ELVEN_DAGGER);
|
|
knows_object(ELVEN_BROADSWORD);
|
|
knows_object(ELVEN_MITHRIL_COAT);
|
|
knows_object(ELVEN_LEATHER_HELM);
|
|
knows_object(ELVEN_SHIELD);
|
|
knows_object(ELVEN_BOOTS);
|
|
knows_object(ELVEN_CLOAK);
|
|
break;
|
|
|
|
case PM_DWARF:
|
|
/* Dwarves can recognize all dwarvish objects */
|
|
knows_object(DWARVISH_SPEAR);
|
|
knows_object(DWARVISH_SHORT_SWORD);
|
|
knows_object(DWARVISH_MATTOCK);
|
|
knows_object(DWARVISH_IRON_HELM);
|
|
knows_object(DWARVISH_MITHRIL_COAT);
|
|
knows_object(DWARVISH_CLOAK);
|
|
knows_object(DWARVISH_ROUNDSHIELD);
|
|
break;
|
|
|
|
case PM_GNOME:
|
|
break;
|
|
|
|
case PM_ORC:
|
|
/* compensate for generally inferior equipment */
|
|
if (!Role_if(PM_WIZARD))
|
|
ini_inv(Xtra_food);
|
|
/* Orcs can recognize all orcish objects */
|
|
knows_object(ORCISH_SHORT_SWORD);
|
|
knows_object(ORCISH_ARROW);
|
|
knows_object(ORCISH_BOW);
|
|
knows_object(ORCISH_SPEAR);
|
|
knows_object(ORCISH_DAGGER);
|
|
knows_object(ORCISH_CHAIN_MAIL);
|
|
knows_object(ORCISH_RING_MAIL);
|
|
knows_object(ORCISH_HELM);
|
|
knows_object(ORCISH_SHIELD);
|
|
knows_object(URUK_HAI_SHIELD);
|
|
knows_object(ORCISH_CLOAK);
|
|
break;
|
|
|
|
default: /* impossible */
|
|
break;
|
|
}
|
|
|
|
if (discover)
|
|
ini_inv(Wishing);
|
|
|
|
if (wizard)
|
|
read_wizkit();
|
|
|
|
if (u.umoney0)
|
|
ini_inv(Money);
|
|
u.umoney0 += hidden_gold(TRUE); /* in case sack has gold in it */
|
|
|
|
find_ac(); /* get initial ac value */
|
|
init_attr(75); /* init attribute values */
|
|
max_rank_sz(); /* set max str size for class ranks */
|
|
/*
|
|
* Do we really need this?
|
|
*/
|
|
for (i = 0; i < A_MAX; i++)
|
|
if (!rn2(20)) {
|
|
register int xd = rn2(7) - 2; /* biased variation */
|
|
|
|
(void) adjattrib(i, xd, TRUE);
|
|
if (ABASE(i) < AMAX(i))
|
|
AMAX(i) = ABASE(i);
|
|
}
|
|
|
|
/* make sure you can carry all you have - especially for Tourists */
|
|
while (inv_weight() > 0) {
|
|
if (adjattrib(A_STR, 1, TRUE))
|
|
continue;
|
|
if (adjattrib(A_CON, 1, TRUE))
|
|
continue;
|
|
/* only get here when didn't boost strength or constitution */
|
|
break;
|
|
}
|
|
|
|
/* If we have at least one spell, force starting Pw to be enough,
|
|
so hero can cast the level 1 spell they should have */
|
|
if (num_spells() && (u.uenmax < SPELL_LEV_PW(1)))
|
|
u.uen = u.uenmax = u.uenpeak = u.ueninc[u.ulevel] = SPELL_LEV_PW(1);
|
|
|
|
return;
|
|
}
|
|
|
|
/* skills aren't initialized, so we use the role-specific skill lists */
|
|
static boolean
|
|
restricted_spell_discipline(int otyp)
|
|
{
|
|
const struct def_skill *skills;
|
|
int this_skill = spell_skilltype(otyp);
|
|
|
|
switch (Role_switch) {
|
|
case PM_ARCHEOLOGIST:
|
|
skills = Skill_A;
|
|
break;
|
|
case PM_BARBARIAN:
|
|
skills = Skill_B;
|
|
break;
|
|
case PM_CAVE_DWELLER:
|
|
skills = Skill_C;
|
|
break;
|
|
case PM_HEALER:
|
|
skills = Skill_H;
|
|
break;
|
|
case PM_KNIGHT:
|
|
skills = Skill_K;
|
|
break;
|
|
case PM_MONK:
|
|
skills = Skill_Mon;
|
|
break;
|
|
case PM_CLERIC:
|
|
skills = Skill_P;
|
|
break;
|
|
case PM_RANGER:
|
|
skills = Skill_Ran;
|
|
break;
|
|
case PM_ROGUE:
|
|
skills = Skill_R;
|
|
break;
|
|
case PM_SAMURAI:
|
|
skills = Skill_S;
|
|
break;
|
|
case PM_TOURIST:
|
|
skills = Skill_T;
|
|
break;
|
|
case PM_VALKYRIE:
|
|
skills = Skill_V;
|
|
break;
|
|
case PM_WIZARD:
|
|
skills = Skill_W;
|
|
break;
|
|
default:
|
|
skills = 0; /* lint suppression */
|
|
break;
|
|
}
|
|
|
|
while (skills && skills->skill != P_NONE) {
|
|
if (skills->skill == this_skill)
|
|
return FALSE;
|
|
++skills;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
ini_inv(struct trobj *trop)
|
|
{
|
|
struct obj *obj;
|
|
int otyp, i;
|
|
boolean got_sp1 = FALSE; /* got a level 1 spellbook? */
|
|
|
|
while (trop->trclass) {
|
|
otyp = (int) trop->trotyp;
|
|
if (otyp != UNDEF_TYP) {
|
|
obj = mksobj(otyp, TRUE, FALSE);
|
|
} else { /* UNDEF_TYP */
|
|
int trycnt = 0;
|
|
/*
|
|
* For random objects, do not create certain overly powerful
|
|
* items: wand of wishing, ring of levitation, or the
|
|
* polymorph/polymorph control combination. Specific objects,
|
|
* i.e. the discovery wishing, are still OK.
|
|
* Also, don't get a couple of really useless items. (Note:
|
|
* punishment isn't "useless". Some players who start out with
|
|
* one will immediately read it and use the iron ball as a
|
|
* weapon.)
|
|
*/
|
|
obj = mkobj(trop->trclass, FALSE);
|
|
otyp = obj->otyp;
|
|
while (otyp == WAN_WISHING || otyp == g.nocreate
|
|
|| otyp == g.nocreate2 || otyp == g.nocreate3
|
|
|| otyp == g.nocreate4 || otyp == RIN_LEVITATION
|
|
/* 'useless' items */
|
|
|| otyp == POT_HALLUCINATION
|
|
|| otyp == POT_ACID
|
|
|| otyp == SCR_AMNESIA
|
|
|| otyp == SCR_FIRE
|
|
|| otyp == SCR_BLANK_PAPER
|
|
|| otyp == SPE_BLANK_PAPER
|
|
|| otyp == RIN_AGGRAVATE_MONSTER
|
|
|| otyp == RIN_HUNGER
|
|
|| otyp == WAN_NOTHING
|
|
/* orcs start with poison resistance */
|
|
|| (otyp == RIN_POISON_RESISTANCE && Race_if(PM_ORC))
|
|
/* Monks don't use weapons */
|
|
|| (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
|
|
/* wizard patch -- they already have one */
|
|
|| (otyp == SPE_FORCE_BOLT && Role_if(PM_WIZARD))
|
|
/* powerful spells are either useless to
|
|
low level players or unbalancing; also
|
|
spells in restricted skill categories */
|
|
|| (obj->oclass == SPBOOK_CLASS
|
|
&& (objects[otyp].oc_level > (got_sp1 ? 3 : 1)
|
|
|| restricted_spell_discipline(otyp)))
|
|
|| otyp == SPE_NOVEL) {
|
|
dealloc_obj(obj);
|
|
obj = mkobj(trop->trclass, FALSE);
|
|
otyp = obj->otyp;
|
|
if (++trycnt > 1000)
|
|
break;
|
|
}
|
|
|
|
/* Don't start with +0 or negative rings */
|
|
if (objects[otyp].oc_charged && obj->spe <= 0)
|
|
obj->spe = rne(3);
|
|
|
|
/* Heavily relies on the fact that 1) we create wands
|
|
* before rings, 2) that we create rings before
|
|
* spellbooks, and that 3) not more than 1 object of a
|
|
* particular symbol is to be prohibited. (For more
|
|
* objects, we need more nocreate variables...)
|
|
*/
|
|
switch (otyp) {
|
|
case WAN_POLYMORPH:
|
|
case RIN_POLYMORPH:
|
|
case POT_POLYMORPH:
|
|
g.nocreate = RIN_POLYMORPH_CONTROL;
|
|
break;
|
|
case RIN_POLYMORPH_CONTROL:
|
|
g.nocreate = RIN_POLYMORPH;
|
|
g.nocreate2 = SPE_POLYMORPH;
|
|
g.nocreate3 = POT_POLYMORPH;
|
|
}
|
|
/* Don't have 2 of the same ring or spellbook */
|
|
if (obj->oclass == RING_CLASS || obj->oclass == SPBOOK_CLASS)
|
|
g.nocreate4 = otyp;
|
|
}
|
|
|
|
if (g.urace.mnum != PM_HUMAN) {
|
|
/* substitute race-specific items; this used to be in
|
|
the 'if (otyp != UNDEF_TYP) { }' block above, but then
|
|
substitutions didn't occur for randomly generated items
|
|
(particularly food) which have racial substitutes */
|
|
for (i = 0; inv_subs[i].race_pm != NON_PM; ++i)
|
|
if (inv_subs[i].race_pm == g.urace.mnum
|
|
&& otyp == inv_subs[i].item_otyp) {
|
|
debugpline3("ini_inv: substituting %s for %s%s",
|
|
OBJ_NAME(objects[inv_subs[i].subs_otyp]),
|
|
(trop->trotyp == UNDEF_TYP) ? "random " : "",
|
|
OBJ_NAME(objects[otyp]));
|
|
otyp = obj->otyp = inv_subs[i].subs_otyp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* nudist gets no armor */
|
|
if (u.uroleplay.nudist && obj->oclass == ARMOR_CLASS) {
|
|
dealloc_obj(obj);
|
|
trop++;
|
|
continue;
|
|
}
|
|
|
|
if (trop->trclass == COIN_CLASS) {
|
|
/* no "blessed" or "identified" money */
|
|
obj->quan = u.umoney0;
|
|
} else {
|
|
if (objects[otyp].oc_uses_known)
|
|
obj->known = 1;
|
|
obj->dknown = obj->bknown = obj->rknown = 1;
|
|
if (Is_container(obj) || obj->otyp == STATUE) {
|
|
obj->cknown = obj->lknown = 1;
|
|
obj->otrapped = 0;
|
|
}
|
|
obj->cursed = 0;
|
|
if (obj->opoisoned && u.ualign.type != A_CHAOTIC)
|
|
obj->opoisoned = 0;
|
|
if (obj->oclass == WEAPON_CLASS || obj->oclass == TOOL_CLASS) {
|
|
obj->quan = (long) trop->trquan;
|
|
trop->trquan = 1;
|
|
} else if (obj->oclass == GEM_CLASS && is_graystone(obj)
|
|
&& obj->otyp != FLINT) {
|
|
obj->quan = 1L;
|
|
}
|
|
if (trop->trspe != UNDEF_SPE)
|
|
obj->spe = trop->trspe;
|
|
if (trop->trbless != UNDEF_BLESS)
|
|
obj->blessed = trop->trbless;
|
|
}
|
|
/* defined after setting otyp+quan + blessedness */
|
|
obj->owt = weight(obj);
|
|
obj = addinv(obj);
|
|
|
|
/* Make the type known if necessary */
|
|
if (OBJ_DESCR(objects[otyp]) && obj->known)
|
|
discover_object(otyp, TRUE, FALSE);
|
|
if (otyp == OIL_LAMP)
|
|
discover_object(POT_OIL, TRUE, FALSE);
|
|
|
|
if (obj->oclass == ARMOR_CLASS) {
|
|
if (is_shield(obj) && !uarms && !(uwep && bimanual(uwep))) {
|
|
setworn(obj, W_ARMS);
|
|
/* Prior to 3.6.2 this used to unset uswapwep if it was set,
|
|
but wearing a shield doesn't prevent having an alternate
|
|
weapon ready to swap with the primary; just make sure we
|
|
aren't two-weaponing (academic; no one starts that way) */
|
|
set_twoweap(FALSE); /* u.twoweap = FALSE */
|
|
} else if (is_helmet(obj) && !uarmh)
|
|
setworn(obj, W_ARMH);
|
|
else if (is_gloves(obj) && !uarmg)
|
|
setworn(obj, W_ARMG);
|
|
else if (is_shirt(obj) && !uarmu)
|
|
setworn(obj, W_ARMU);
|
|
else if (is_cloak(obj) && !uarmc)
|
|
setworn(obj, W_ARMC);
|
|
else if (is_boots(obj) && !uarmf)
|
|
setworn(obj, W_ARMF);
|
|
else if (is_suit(obj) && !uarm)
|
|
setworn(obj, W_ARM);
|
|
}
|
|
|
|
if (obj->oclass == WEAPON_CLASS || is_weptool(obj)
|
|
|| otyp == TIN_OPENER || otyp == FLINT || otyp == ROCK) {
|
|
if (is_ammo(obj) || is_missile(obj)) {
|
|
if (!uquiver)
|
|
setuqwep(obj);
|
|
} else if (!uwep && (!uarms || !bimanual(obj))) {
|
|
setuwep(obj);
|
|
} else if (!uswapwep) {
|
|
setuswapwep(obj);
|
|
}
|
|
}
|
|
if (obj->oclass == SPBOOK_CLASS && obj->otyp != SPE_BLANK_PAPER)
|
|
initialspell(obj);
|
|
|
|
/* First spellbook should be level 1 - did we get it? */
|
|
if (obj->oclass == SPBOOK_CLASS && objects[obj->otyp].oc_level == 1)
|
|
got_sp1 = TRUE;
|
|
|
|
if (--trop->trquan)
|
|
continue; /* make a similar object */
|
|
trop++;
|
|
}
|
|
}
|
|
|
|
/*u_init.c*/
|