summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/level_design.txt9
-rw-r--r--crawl-ref/source/abl-show.cc2
-rw-r--r--crawl-ref/source/abyss.cc2
-rw-r--r--crawl-ref/source/acr.cc12
-rw-r--r--crawl-ref/source/arena.cc2
-rw-r--r--crawl-ref/source/art-data.h1316
-rw-r--r--crawl-ref/source/art-data.txt792
-rw-r--r--crawl-ref/source/artefact.cc (renamed from crawl-ref/source/randart.cc)582
-rw-r--r--crawl-ref/source/artefact.h263
-rw-r--r--crawl-ref/source/chardump.cc5
-rw-r--r--crawl-ref/source/clua.cc4
-rw-r--r--crawl-ref/source/dat/float.des2
-rw-r--r--crawl-ref/source/debug.cc98
-rw-r--r--crawl-ref/source/defines.h3
-rw-r--r--crawl-ref/source/delay.cc8
-rw-r--r--crawl-ref/source/describe.cc388
-rw-r--r--crawl-ref/source/dungeon.cc2
-rw-r--r--crawl-ref/source/effects.cc37
-rw-r--r--crawl-ref/source/enum.h2
-rw-r--r--crawl-ref/source/externs.h4
-rw-r--r--crawl-ref/source/fight.cc13
-rw-r--r--crawl-ref/source/fight.h2
-rw-r--r--crawl-ref/source/files.cc2
-rw-r--r--crawl-ref/source/food.cc4
-rw-r--r--crawl-ref/source/ghost.cc2
-rw-r--r--crawl-ref/source/invent.cc4
-rw-r--r--crawl-ref/source/it_use2.cc8
-rw-r--r--crawl-ref/source/it_use3.cc10
-rw-r--r--crawl-ref/source/item_use.cc10
-rw-r--r--crawl-ref/source/itemname.cc11
-rw-r--r--crawl-ref/source/itemprop.cc64
-rw-r--r--crawl-ref/source/itemprop.h34
-rw-r--r--crawl-ref/source/items.cc39
-rw-r--r--crawl-ref/source/makefile.mgw8
-rw-r--r--crawl-ref/source/makefile.obj2
-rw-r--r--crawl-ref/source/makefile.unix8
-rw-r--r--crawl-ref/source/makefile_tiles.mgw8
-rw-r--r--crawl-ref/source/makefile_tiles.unix8
-rw-r--r--crawl-ref/source/makeitem.cc89
-rw-r--r--crawl-ref/source/mapdef.cc11
-rw-r--r--crawl-ref/source/mon-util.cc20
-rw-r--r--crawl-ref/source/monstuff.cc2
-rw-r--r--crawl-ref/source/mstuff2.cc2
-rw-r--r--crawl-ref/source/mtransit.cc7
-rw-r--r--crawl-ref/source/newgame.cc2
-rw-r--r--crawl-ref/source/ouch.cc2
-rw-r--r--crawl-ref/source/player.cc120
-rw-r--r--crawl-ref/source/player.h1
-rw-r--r--crawl-ref/source/randart.h133
-rw-r--r--crawl-ref/source/religion.cc4
-rw-r--r--crawl-ref/source/shopping.cc14
-rw-r--r--crawl-ref/source/skills2.cc2
-rw-r--r--crawl-ref/source/spells1.cc4
-rw-r--r--crawl-ref/source/spells2.cc4
-rw-r--r--crawl-ref/source/spells3.cc2
-rw-r--r--crawl-ref/source/spells4.cc2
-rw-r--r--crawl-ref/source/spl-book.cc2
-rw-r--r--crawl-ref/source/spl-cast.cc2
-rw-r--r--crawl-ref/source/stash.cc2
-rw-r--r--crawl-ref/source/tags.cc27
-rw-r--r--crawl-ref/source/tags.h5
-rw-r--r--crawl-ref/source/tilepick.cc213
-rw-r--r--crawl-ref/source/tilesdl.cc7
-rw-r--r--crawl-ref/source/transfor.cc4
-rw-r--r--crawl-ref/source/traps.cc2
-rw-r--r--crawl-ref/source/tutorial.cc2
-rw-r--r--crawl-ref/source/unrand.h1306
-rwxr-xr-xcrawl-ref/source/util/art-data.pl680
-rw-r--r--crawl-ref/source/view.cc4
-rw-r--r--crawl-ref/source/xom.cc12
70 files changed, 3855 insertions, 2604 deletions
diff --git a/crawl-ref/docs/level_design.txt b/crawl-ref/docs/level_design.txt
index 5ba836ff9e..c3511a3d66 100644
--- a/crawl-ref/docs/level_design.txt
+++ b/crawl-ref/docs/level_design.txt
@@ -585,9 +585,12 @@ ITEM: (list of items, separated by comma)
trying "any weapon ego:vorpal" or "any armour ego:positive_energy"
will result in an error. Trying to give an ego to something which
can't accept an ego will also result in an error.
- * "fixed:item_name" will make a given fixedart by a given name,
- like "long sword fixed:singing_sword". If the unique already
- exists, the base item will be given instead.
+ * "unrand:item_name" will make a given unrandom by a given name,
+ like "long sword fixed:singing_sword". Omit any apostrophes
+ in the name (e.g, fixed:vampires_tooth). If the name has
+ something between double quotes then use that string (e.g,
+ fixed:bloodbane). If the unique already exists, the base item
+ will be given instead.
WARNING: While checks are done to make sure that an armour ego
isn't given to a weapon, a weapon ego to a missile, and so on, and
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc
index c811679bef..01bf48e49c 100644
--- a/crawl-ref/source/abl-show.cc
+++ b/crawl-ref/source/abl-show.cc
@@ -24,6 +24,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abyss.h"
+#include "artefact.h"
#include "beam.h"
#include "database.h"
#include "decks.h"
@@ -43,7 +44,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "ouch.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index b5f3b36c49..596cf3c662 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -16,6 +16,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "cloud.h"
#include "makeitem.h"
#include "mapmark.h"
@@ -28,7 +29,6 @@ REVISION("$Rev$");
#include "dungeon.h"
#include "items.h"
#include "lev-pand.h"
-#include "randart.h"
#include "stuff.h"
#include "spells3.h"
#include "terrain.h"
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index f35eb1586e..97636e3113 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -45,6 +45,7 @@ REVISION("$Rev$");
#include "abl-show.h"
#include "abyss.h"
+#include "artefact.h"
#include "arena.h"
#include "branch.h"
#include "chardump.h"
@@ -91,7 +92,6 @@ REVISION("$Rev$");
#include "overmap.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills.h"
@@ -2582,7 +2582,7 @@ void world_reacts()
mprf(MSGCH_DIAGNOSTICS, "stealth: %d", stealth );
#endif
- if (you.special_wield != SPWLD_NONE)
+ if (you.unrand_reacts != SPWLD_NONE)
special_wielded();
if (!crawl_state.arena && one_chance_in(10))
@@ -4076,6 +4076,14 @@ static void _compile_time_asserts()
//jmf: NEW ASSERTS: we ought to do a *lot* of these
COMPILE_CHECK(NUM_JOBS < JOB_UNKNOWN , c7);
+ // Make sure there's enough room in you.unique_items to hold all
+ // the unrandarts.
+ COMPILE_CHECK(NO_UNRANDARTS < MAX_UNRANDARTS, c8);
+
+ // Non-artefact brands and unrandart indexes both go into
+ // item.special, so make sure they don't overlap.
+ COMPILE_CHECK((int) NUM_SPECIAL_WEAPONS < (int) UNRAND_START, c9);
+
// Also some runtime stuff; I don't know if the order of branches[]
// needs to match the enum, but it currently does.
for (int i = 0; i < NUM_BRANCHES; ++i)
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc
index 303d93fd55..09bc41ef25 100644
--- a/crawl-ref/source/arena.cc
+++ b/crawl-ref/source/arena.cc
@@ -11,6 +11,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "arena.h"
+#include "artefact.h"
#include "chardump.h"
#include "cio.h"
#include "command.h"
@@ -28,7 +29,6 @@ REVISION("$Rev$");
#include "monplace.h"
#include "mstuff2.h"
#include "output.h"
-#include "randart.h"
#include "skills2.h"
#include "spl-mis.h"
#include "spl-util.h"
diff --git a/crawl-ref/source/art-data.h b/crawl-ref/source/art-data.h
new file mode 100644
index 0000000000..883088ac48
--- /dev/null
+++ b/crawl-ref/source/art-data.h
@@ -0,0 +1,1316 @@
+/*
+ * File: art-data.h
+ * Summary: Definitions for unrandom artefacts.
+ * Written by: ????
+ *
+ * Modified for Crawl Reference by $Author$ on $Date$
+ */
+
+/*
+ * This file is automatically generated from art-data.txt via
+ * util/art-data.pl. Do not directly edit this file, but rather change
+ * art-data.txt.
+ *
+ * If the unrandart_entry struct is changed or a new artefact property is
+ * added to artefact_prop_type, then change art-data.pl so that the
+ * art-data.h file it produces matches up with the new structure.
+ */
+
+#ifdef ART_DATA_H
+#error "art-data.h included twice!"
+#endif
+
+#define ART_DATA_H
+
+/* 1: UNRAND_DUMMY1 */
+{
+ "DUMMY UNRANDART 1", "DUMMY UNRANDART 1",
+ OBJ_UNASSIGNED, 250, 250, 250, BLACK,
+ {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 2: UNRAND_SINGING_SWORD */
+{
+ "Singing Sword", "golden long sword",
+ OBJ_WEAPONS, WPN_LONG_SWORD, +7, +7, YELLOW,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "This blessed weapon loves nothing more than to sing to its owner, whether they want it to or not.",
+ "",
+},
+
+/* 3: UNRAND_TROG */
+{
+ "Wrath of Trog", "bloodstained battleaxe",
+ OBJ_WEAPONS, WPN_BATTLEAXE, +3, +11, RED,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "This was the favourite weapon of the old god Trog, before it was lost one day. It induces a bloodthirsty berserker rage in anyone who uses it to strike another.",
+ "",
+},
+
+/* 4: UNRAND_VARIABILITY */
+{
+ "Mace of Variability", "shimmering mace",
+ OBJ_WEAPONS, WPN_MACE, 0, 0, BLACK,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It is rather unreliable.",
+ "",
+},
+
+/* 5: UNRAND_PRUNE */
+{
+ "Glaive of Prune", "purple glaive",
+ OBJ_WEAPONS, WPN_GLAIVE, 0, +12, MAGENTA,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It is the creation of a mad god, and carries a curse which transforms anyone possessing it into a prune. Fortunately, the curse works very slowly, and one can use it briefly with no consequences worse than slightly purple skin and a few wrinkles.",
+ "",
+},
+
+/* 6: UNRAND_POWER */
+{
+ "Sword of Power", "chunky great sword",
+ OBJ_WEAPONS, WPN_GREAT_SWORD, 0, 0, RED,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It rewards the powerful with power and the meek with weakness.",
+ "",
+},
+
+/* 7: UNRAND_OLGREB */
+{
+ "Staff of Olgreb", "green glowing staff",
+ OBJ_WEAPONS, WPN_QUARTERSTAFF, 0, 0, GREEN,
+ {
+ SPWPN_VENOM, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It was the magical weapon wielded by the mighty wizard Olgreb before he met his fate somewhere within these dungeons. It increases the ability of its wielder to use venomous magic, and carries magical powers which can be evoked.",
+ "",
+},
+
+/* 8: UNRAND_WUCAD_MU */
+{
+ "Staff of Wucad Mu", "ephemeral quarterstaff",
+ OBJ_WEAPONS, WPN_QUARTERSTAFF, 0, 0, BROWN,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "Its power varies in proportion to its wielder's intelligence. Using it can be a bit risky.",
+ "",
+},
+
+/* 9: UNRAND_VAMPIRES_TOOTH */
+{
+ "Vampire's Tooth", "ivory dagger",
+ OBJ_WEAPONS, WPN_DAGGER, +3, +4, WHITE,
+ {
+ SPWPN_VAMPIRICISM, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It is lethally vampiric.",
+ "",
+},
+
+/* 10: UNRAND_CURSES */
+{
+ "Scythe of Curses", "warped scythe",
+ OBJ_WEAPONS, WPN_SCYTHE, +13, +13, DARKGREY,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ -1, 0, 0,
+ },
+ "",
+ "This weapon carries a terrible and highly irritating curse.",
+ "",
+},
+
+/* 11: UNRAND_TORMENT */
+{
+ "Sceptre of Torment", "jewelled golden mace",
+ OBJ_WEAPONS, WPN_MACE, +7, +6, YELLOW,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "This truly accursed weapon is an instrument of Hell.",
+ "",
+},
+
+/* 12: UNRAND_ZONGULDROK */
+{
+ "Sword of Zonguldrok", "bone long sword",
+ OBJ_WEAPONS, WPN_LONG_SWORD, +9, +9, LIGHTGREY,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "This dreadful weapon is used at the user's peril.",
+ "",
+},
+
+/* 13: UNRAND_CEREBOV */
+{
+ "Sword of Cerebov", "great serpentine sword",
+ OBJ_WEAPONS, WPN_GREAT_SWORD, +6, +6, YELLOW,
+ {
+ SPWPN_FLAMING, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ -1, 0, 0,
+ },
+ "Eerie flames cover its twisted blade.",
+ "",
+ "",
+},
+
+/* 14: UNRAND_DISPATER */
+{
+ "Staff of Dispater", "golden staff",
+ OBJ_WEAPONS, WPN_QUARTERSTAFF, +4, +4, YELLOW,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "This legendary item can unleash the fury of Hell.",
+ "",
+},
+
+/* 15: UNRAND_ASMODEUS */
+{
+ "Sceptre of Asmodeus", "ruby sceptre",
+ OBJ_WEAPONS, WPN_QUARTERSTAFF, +7, +7, RED,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "It carries some of the powers of the arch-fiend Asmodeus.",
+ "",
+},
+
+/* 16: UNRAND_BLOODBANE */
+{
+ "long sword \"Bloodbane\"", "blackened long sword",
+ OBJ_WEAPONS, WPN_LONG_SWORD, +7, +8, DARKGREY,
+ {
+ SPWPN_VORPAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0,
+ 0, -20, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 17: UNRAND_FLAMING_DEATH */
+{
+ "scimitar of Flaming Death", "smoking scimitar",
+ OBJ_WEAPONS, WPN_SCIMITAR, +7, +5, RED,
+ {
+ SPWPN_FLAMING, 0, 0, 0, 0, 0,
+ 2, -1, 0, 1, 0, 20,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 18: UNRAND_BRILLIANCE */
+{
+ "mace of Brilliance", "brightly glowing mace",
+ OBJ_WEAPONS, WPN_MACE, +5, +5, WHITE,
+ {
+ SPWPN_HOLY_WRATH, 5, 0, 0, 5, 0,
+ 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, -20, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 19: UNRAND_LEECH */
+{
+ "demon blade \"Leech\"", "runed demon blade",
+ OBJ_WEAPONS, WPN_DEMON_BLADE, +13, +4, MAGENTA,
+ {
+ SPWPN_VAMPIRICISM, 0, -1, -1, -1, -1,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 4, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 20: UNRAND_CHILLY_DEATH */
+{
+ "dagger of Chilly Death", "sapphire dagger",
+ OBJ_WEAPONS, WPN_DAGGER, +5, +7, LIGHTBLUE,
+ {
+ SPWPN_FREEZING, 0, 0, 0, 0, 0,
+ -1, 2, 0, 1, 0, 20,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A dagger made of one huge piece of sapphire.",
+ "",
+ "",
+},
+
+/* 21: UNRAND_MORG */
+{
+ "dagger \"Morg\"", "rusty dagger",
+ OBJ_WEAPONS, WPN_DAGGER, -1, +4, LIGHTRED,
+ {
+ SPWPN_PAIN, 0, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "An ugly rusty dagger.",
+ "",
+ "Many years ago it was the property of a powerful mage called Boris. He got lost in the Dungeon while seeking the Orb.",
+},
+
+/* 22: UNRAND_FINISHER */
+{
+ "scythe \"Finisher\"", "blackened scythe",
+ OBJ_WEAPONS, WPN_SCYTHE, +3, +5, DARKGREY,
+ {
+ SPWPN_SPEED, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ -1, 0, 0,
+ },
+ "A long and sharp scythe, specially modified for combat purposes.",
+ "",
+ "",
+},
+
+/* 23: UNRAND_PUNK */
+{
+ "sling \"Punk\"", "blue sling",
+ OBJ_WEAPONS, WPN_SLING, +9, +12, LIGHTBLUE,
+ {
+ SPWPN_FROST, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A sling made of weird blue leather.",
+ "",
+ "",
+},
+
+/* 24: UNRAND_KRISHNA */
+{
+ "bow of Krishna \"Sharnga\"", "golden bow",
+ OBJ_WEAPONS, WPN_BOW, +8, +8, YELLOW,
+ {
+ SPWPN_SPEED, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A wonderful golden bow.",
+ "",
+ "It once belonged to a foreign god. It works best with special arrows which are not generally available.",
+},
+
+/* 25: UNRAND_SKULLCRUSHER */
+{
+ "giant club \"Skullcrusher\"", "brutal giant club",
+ OBJ_WEAPONS, WPN_GIANT_CLUB, +0, +5, BROWN,
+ {
+ SPWPN_SPEED, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 26: UNRAND_GUARD */
+{
+ "glaive of the Guard", "polished glaive",
+ OBJ_WEAPONS, WPN_GLAIVE, +5, +8, LIGHTCYAN,
+ {
+ SPWPN_ELECTROCUTION, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "This weapon once belonged to Gar Dogh, the guard of a king's treasures. According to legend he was lost somewhere in the Dungeon.",
+},
+
+/* 27: UNRAND_JIHAD */
+{
+ "sword of Jihad", "crystal sword",
+ OBJ_WEAPONS, WPN_LONG_SWORD, +12, +10, WHITE,
+ {
+ SPWPN_HOLY_WRATH, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 1, 20,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0,
+ 0, -50, 0,
+ },
+ "A long sword made of one huge piece of crystal.",
+ "",
+ "This sword was The Shining One's gift to a worshipper.",
+},
+
+/* 28: UNRAND_HELLFIRE */
+{
+ "crossbow \"Hellfire\"", "flaming crossbow",
+ OBJ_WEAPONS, WPN_CROSSBOW, +6, +9, LIGHTRED,
+ {
+ SPWPN_FLAME, 0, 0, 0, 0, 0,
+ 2, -1, 0, 0, 0, 40,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A flaming crossbow, forged in the fires of the Hells.",
+ "",
+ "",
+},
+
+/* 29: UNRAND_DOOM_KNIGHT */
+{
+ "sword of the Doom Knight", "adamantine great sword",
+ OBJ_WEAPONS, WPN_GREAT_SWORD, +13, +13, BLUE,
+ {
+ SPWPN_PAIN, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "An adamantine great sword.",
+ "",
+ "",
+},
+
+/* 30: UNRAND_EOS */
+{
+ "\"Eos\"", "encrusted morningstar",
+ OBJ_WEAPONS, WPN_MORNINGSTAR, +5, +5, LIGHTCYAN,
+ {
+ SPWPN_ELECTROCUTION, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 31: UNRAND_BOTONO */
+{
+ "spear of the Botono", "ebony spear",
+ OBJ_WEAPONS, WPN_SPEAR, +2, +10, DARKGREY,
+ {
+ SPWPN_VAMPIRICISM, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, -30, 0,
+ },
+ "",
+ "",
+ "A really dark and malign artefact, which no wise man would even touch.",
+},
+
+/* 32: UNRAND_OCTOPUS_KING */
+{
+ "trident of the Octopus King", "mangy trident",
+ OBJ_WEAPONS, WPN_TRIDENT, +10, +4, CYAN,
+ {
+ SPWPN_VENOM, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 0, 50,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "This trident was stolen many years ago from the Octopus King's garden by a really unimportant and already dead man. But beware of the Octopus King's wrath!",
+},
+
+/* 33: UNRAND_ARGA */
+{
+ "mithril axe \"Arga\"", "mithril axe",
+ OBJ_WEAPONS, WPN_WAR_AXE, +10, +6, WHITE,
+ {
+ SPWPN_SPEED, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A beautiful mithril axe, probably lost by some dwarven hero.",
+ "",
+ "",
+},
+
+/* 34: UNRAND_ELEMENTAL_STAFF */
+{
+ "Elemental Staff", "black staff",
+ OBJ_WEAPONS, WPN_QUARTERSTAFF, +3, +1, DARKGREY,
+ {
+ SPWPN_PROTECTION, 0, 0, 0, 0, 0,
+ 2, 2, 0, 0, 0, 60,
+ 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 2, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "This powerful staff used to belong to the leader of the Guild of Five Elements.",
+},
+
+/* 35: UNRAND_SNIPER */
+{
+ "hand crossbow \"Sniper\"", "black crossbow",
+ OBJ_WEAPONS, WPN_HAND_CROSSBOW, +10, +0, DARKGREY,
+ {
+ SPWPN_VENOM, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A hand crossbow made of some black material.",
+ "",
+ "",
+},
+
+/* 36: UNRAND_PIERCER */
+{
+ "longbow \"Piercer\"", "very long metal bow",
+ OBJ_WEAPONS, WPN_LONGBOW, +2, +10, CYAN,
+ {
+ SPWPN_VORPAL, 0, -2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "An exceptionally large metal longbow.",
+ "",
+ "",
+},
+
+/* 37: UNRAND_BLOWGUN_ASSASSIN */
+{
+ "blowgun of the Assassin", "tiny blowgun",
+ OBJ_WEAPONS, WPN_BLOWGUN, +6, +6, WHITE,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 60, 0,
+ },
+ "It is designed for easy concealment, but still packs a nasty punch.",
+ "",
+ "",
+},
+
+/* 38: UNRAND_WYRMBANE */
+{
+ "Wyrmbane", "scale-covered lance",
+ OBJ_WEAPONS, WPN_SPEAR, +9, +6, GREEN,
+ {
+ SPWPN_DRAGON_SLAYING, 5, 0, 0, 0, 0,
+ 1, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 39: UNRAND_SPRIGGANS_KNIFE */
+{
+ "Spriggan's Knife", "dainty little knife",
+ OBJ_WEAPONS, WPN_KNIFE, +4, +10, LIGHTCYAN,
+ {
+ SPWPN_NORMAL, 0, 4, 0, 0, 4,
+ 0, 0, 0, 0, 0, 20,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 50, 0,
+ },
+ "A dainty little knife.",
+ "",
+ "This knife was made by Spriggans, or for Spriggans, or possibly from Spriggans. Anyway, it's in some way associated with those fey folk.",
+},
+
+/* 40: UNRAND_PLUTONIUM_SWORD */
+{
+ "plutonium sword", "glowing long sword",
+ OBJ_WEAPONS, WPN_LONG_SWORD, +12, +16, LIGHTGREEN,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0,
+ 1, -20, 0,
+ },
+ "A long sword made of weird glowing metal.",
+ "",
+ "",
+},
+
+/* 41: UNRAND_UNDEADHUNTER */
+{
+ "great mace \"Undeadhunter\"", "great steel mace",
+ OBJ_WEAPONS, WPN_GREAT_MACE, +7, +7, LIGHTGREY,
+ {
+ SPWPN_HOLY_WRATH, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 42: UNRAND_SERPENT_SCOURGE */
+{
+ "whip \"Serpent-Scourge\"", "forked whip",
+ OBJ_WEAPONS, WPN_WHIP, +5, +10, DARKGREY,
+ {
+ SPWPN_VENOM, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "A double-ended whip made from the cured hides of the Lair of Beasts' deadly grey snakes.",
+ "",
+},
+
+/* 43: UNRAND_ACCURACY */
+{
+ "knife of Accuracy", "thin dagger",
+ OBJ_WEAPONS, WPN_DAGGER, +27, -1, LIGHTCYAN,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "It is almost unerringly accurate.",
+},
+
+/* 44: UNRAND_CRYSTAL_SPEAR */
+{
+ "Lehudib's crystal spear", "crystal spear",
+ OBJ_WEAPONS, WPN_SPEAR, +6, +6, GREEN,
+ {
+ SPWPN_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "Presumably this relic led to the invention of the famous spell.",
+},
+
+/* 45: UNRAND_IGNORANCE */
+{
+ "shield of Ignorance", "dull large shield",
+ OBJ_ARMOUR, ARM_LARGE_SHIELD, +5, 0, BROWN,
+ {
+ SPARM_NORMAL, 2, 2, 0, -6, 0,
+ 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 3, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 46: UNRAND_AUGMENTATION */
+{
+ "robe of Augmentation", "silk robe",
+ OBJ_ARMOUR, ARM_ROBE, +4, 0, LIGHTRED,
+ {
+ SPARM_NORMAL, 0, 0, 2, 2, 2,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A robe made of the finest silk.",
+ "",
+ "",
+},
+
+/* 47: UNRAND_THIEF */
+{
+ "cloak of the Thief", "tattered cloak",
+ OBJ_ARMOUR, ARM_CLOAK, +1, 0, DARKGREY,
+ {
+ SPARM_NORMAL, 0, 2, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -3,
+ 0, 60, 0,
+ },
+ "",
+ "",
+ "It allows its wearer to excel in the arts of thievery.",
+},
+
+/* 48: UNRAND_BULLSEYE */
+{
+ "shield \"Bullseye\"", "round shield",
+ OBJ_ARMOUR, ARM_SHIELD, +10, 0, RED,
+ {
+ SPARM_NORMAL, 0, -5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 49: UNRAND_DYROVEPREVA */
+{
+ "crown of Dyrovepreva", "jewelled bronze crown",
+ OBJ_ARMOUR, ARM_CAP, +3, 0, BROWN,
+ {
+ SPARM_NORMAL, 0, 0, 0, 2, 0,
+ 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A large crown of dull bronze, set with a dazzling array of gemstones.",
+ "",
+ "",
+},
+
+/* 50: UNRAND_MISFORTUNE */
+{
+ "robe of Misfortune", "fabulously ornate robe",
+ OBJ_ARMOUR, ARM_ROBE, -5, 0, MAGENTA,
+ {
+ SPARM_NORMAL, 0, -4, -2, -2, -2,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 0,
+ 0, 0, 5, 0, 0,
+ 1, -80, 0,
+ },
+ "A splendid flowing robe of fur and silk.",
+ "",
+ "",
+},
+
+/* 51: UNRAND_FLASH */
+{
+ "cloak of Flash", "vibrating cloak",
+ OBJ_ARMOUR, ARM_CLOAK, +3, 0, RED,
+ {
+ SPARM_NORMAL, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 1, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A vibrating cloak.",
+ "",
+ "",
+},
+
+/* 52: UNRAND_BOOTS_ASSASSIN */
+{
+ "boots of the Assassin", "soft boots",
+ OBJ_ARMOUR, ARM_BOOTS, +2, 0, BROWN,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 80, 0,
+ },
+ "Some soft boots.",
+ "",
+ "These boots were specially designed by the Assassin's Guild.",
+},
+
+/* 53: UNRAND_LEARS */
+{
+ "Lear's chain mail", "golden chain mail",
+ OBJ_ARMOUR, ARM_CHAIN_MAIL, -1, 0, YELLOW,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, -3,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ -1, 0, 0,
+ },
+ "A chain mail made of pure gold.",
+ "",
+ "",
+},
+
+/* 54: UNRAND_ZHOR */
+{
+ "skin of Zhor", "smelly skin",
+ OBJ_ARMOUR, ARM_ANIMAL_SKIN, +4, 0, BROWN,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "The skin of some strange animal.",
+ "",
+ "",
+},
+
+/* 55: UNRAND_SALAMANDER */
+{
+ "salamander hide armour", "red leather armour",
+ OBJ_ARMOUR, ARM_LEATHER_ARMOUR, +3, 0, RED,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A leather armour made of a salamander's skin.",
+ "",
+ "",
+},
+
+/* 56: UNRAND_WAR */
+{
+ "gauntlets of War", "thick gauntlets",
+ OBJ_ARMOUR, ARM_GLOVES, +3, 0, BROWN,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 57: UNRAND_RESISTANCE */
+{
+ "shield of Resistance", "bronze shield",
+ OBJ_ARMOUR, ARM_SHIELD, +3, 0, LIGHTRED,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, 0, 40,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A bronze shield.",
+ "",
+ "",
+},
+
+/* 58: UNRAND_FOLLY */
+{
+ "robe of Folly", "dull robe",
+ OBJ_ARMOUR, ARM_ROBE, -1, 0, LIGHTGREY,
+ {
+ SPARM_NORMAL, 0, 0, 0, -5, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 2, 0, 0,
+ },
+ "A dull grey robe.",
+ "",
+ "",
+},
+
+/* 59: UNRAND_MAXWELL */
+{
+ "Maxwell's patent armour", "weird-looking armour",
+ OBJ_ARMOUR, ARM_PLATE_MAIL, +10, 0, LIGHTGREEN,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 1,
+ 0, 0, 0, 0, 0,
+ -1, 0, 0,
+ },
+ "A weird-looking armour.",
+ "",
+ "",
+},
+
+/* 60: UNRAND_DRAGON */
+{
+ "mask of the Dragon", "blue mask",
+ OBJ_ARMOUR, ARM_CAP, 0, 0, BLUE,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 40,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 2,
+ 0, 0, 0,
+ },
+ "A blue mask.",
+ "",
+ "",
+},
+
+/* 61: UNRAND_NIGHT */
+{
+ "robe of Night", "black robe",
+ OBJ_ARMOUR, ARM_ROBE, +4, 0, DARKGREY,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 30,
+ 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 50, 0,
+ },
+ "A long black robe made of strange glossy material.",
+ "",
+ "According to legend, this robe was the gift of Ratri the Goddess of the Night to one of her followers.",
+},
+
+/* 62: UNRAND_DRAGON_KING */
+{
+ "armour of the Dragon King", "shiny dragon armour",
+ OBJ_ARMOUR, ARM_GOLD_DRAGON_ARMOUR, +5, 0, YELLOW,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 50,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 63: UNRAND_ALCHEMIST */
+{
+ "hat of the Alchemist", "dirty hat",
+ OBJ_ARMOUR, ARM_WIZARD_HAT, +2, 0, MAGENTA,
+ {
+ SPARM_NORMAL, 0, 0, 0, 0, 0,
+ 1, 1, 1, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A dirty hat.",
+ "",
+ "",
+},
+
+/* 64: UNRAND_FENCERS_GLOVES */
+{
+ "Fencer's gloves", "silk gloves",
+ OBJ_ARMOUR, ARM_GLOVES, +2, 0, WHITE,
+ {
+ SPARM_NORMAL, 0, 3, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0,
+ 0, 0, 0,
+ },
+ "A pair of gloves made of white silk.",
+ "",
+ "",
+},
+
+/* 65: UNRAND_STARLIGHT */
+{
+ "cloak of Starlight", "phosphorescent cloak",
+ OBJ_ARMOUR, ARM_CLOAK, 0, 0, WHITE,
+ {
+ SPARM_NORMAL, 0, 4, 0, 0, 0,
+ 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, -30, 0,
+ },
+ "A phosphorescent cloak.",
+ "",
+ "A cloak woven of pure light beams.",
+},
+
+/* 66: UNRAND_RATSKIN_CLOAK */
+{
+ "ratskin cloak", "motley cloak",
+ OBJ_ARMOUR, ARM_CLOAK, +1, 0, LIGHTRED,
+ {
+ SPARM_NORMAL, 0, 0, 0, -1, -1,
+ 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "An enchantress with a magic loom and way too much time on her hands stitched this cloak from the hides of hundreds of rats, most of them orange. It's a bit awkward to wear and looks rather foolish, but it provides excellent protection from rats of all kinds.",
+},
+
+/* 67: UNRAND_AIR */
+{
+ "amulet of the Air", "sky-blue amulet",
+ OBJ_JEWELLERY, AMU_CONTROLLED_FLIGHT, 0, 0, LIGHTCYAN,
+ {
+ 0, 0, 3, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 50, 0,
+ },
+ "A sky-blue amulet.",
+ "",
+ "",
+},
+
+/* 68: UNRAND_SHADOWS */
+{
+ "ring of Shadows", "black ring",
+ OBJ_JEWELLERY, RING_INVISIBILITY, 0, 0, DARKGREY,
+ {
+ 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, -3, 0,
+ 0, 40, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 69: UNRAND_CEKUGOB */
+{
+ "amulet of Cekugob", "crystal amulet",
+ OBJ_JEWELLERY, AMU_WARDING, 0, 0, LIGHTGREY,
+ {
+ 0, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1,
+ 0, 2, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 70: UNRAND_FOUR_WINDS */
+{
+ "amulet of the Four Winds", "jade amulet",
+ OBJ_JEWELLERY, AMU_CLARITY, 0, 0, LIGHTGREEN,
+ {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 100,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 71: UNRAND_BLOODLUST */
+{
+ "necklace of Bloodlust", "blood-stained necklace",
+ OBJ_JEWELLERY, AMU_RAGE, 0, 0, RED,
+ {
+ 0, 0, 0, 2, -2, 0,
+ 0, 0, 0, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 3,
+ 3, -20, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 72: UNRAND_SHAOLIN */
+{
+ "ring of Shaolin", "jade ring",
+ OBJ_JEWELLERY, RING_EVASION, +8, 0, LIGHTGREEN,
+ {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 73: UNRAND_ROBUSTNESS */
+{
+ "ring of Robustness", "steel ring",
+ OBJ_JEWELLERY, RING_PROTECTION, +8, 0, LIGHTGREY,
+ {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 74: UNRAND_MAGE */
+{
+ "ring of the Mage", "sapphire ring",
+ OBJ_JEWELLERY, RING_WIZARDRY, 0, 0, LIGHTBLUE,
+ {
+ 0, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 50,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
+/* 75: UNRAND_SHIELDING */
+{
+ "brooch of Shielding", "shield-shaped amulet",
+ OBJ_JEWELLERY, AMU_WARDING, 0, 0, LIGHTBLUE,
+ {
+ 0, 4, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "A shield-shaped amulet.",
+ "",
+ "Back in the good old days, every adventurer had one of these handy devices. That, and a pony.",
+},
+
+/* 76: UNRAND_DUMMY2 */
+{
+ "DUMMY UNRANDART 2", "DUMMY UNRANDART 2",
+ OBJ_UNASSIGNED, 250, 250, 250, BLACK,
+ {
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ },
+ "",
+ "",
+ "",
+},
+
diff --git a/crawl-ref/source/art-data.txt b/crawl-ref/source/art-data.txt
new file mode 100644
index 0000000000..ffa2dadafc
--- /dev/null
+++ b/crawl-ref/source/art-data.txt
@@ -0,0 +1,792 @@
+# This file contains the definitions of undrandarts (and what used to be
+# fixed artefacts). util/art-data.pl translates this file into
+# art-data.h, and also updates the enumeration and NO_UNRANDARTS in
+# unrand.h
+#
+# Each artefact definition is separated by one or more blanks lines.
+#
+# Each artefact definition must have the NAME, APPEAR, OBJ and COLOUR
+# fields.
+#
+# The name and appearance of each unrandart must be unique.
+#
+# Changing the name of an unrand will change it's automatically
+# generated enumeration, unless its enumeration is forced with ENUM.
+#
+# "ENUM: FOO" can be used to force the enumeration for an unrand to be
+# "UNRAND_FOO", for cases where the automatically generated enumarations
+# of different unrands conflict.
+#
+# Add new artefact definitions at the end of the file; doing so should cause
+# no problems with save-file compatibilty, but for tile builds it will
+# cause a shift of remembered tiles (since each new unrandart needs its
+# own tiles). Changing the order of the definitions will likely cause
+# strange behaviour in games saved previous to the change, and deleting
+# definitions will break savefile compatibility.
+
+# This entry must always be first.
+ENUM: DUMMY1
+NAME: DUMMY UNRANDART 1
+APPEAR: DUMMY UNRANDART 1
+OBJ: OBJ_UNASSIGNED/250
+PLUS: 250/250
+COLOUR: BLACK
+
+####################### First come the old fixed arts.
+
+NAME: Singing Sword
+APPEAR: golden long sword
+OBJ: OBJ_WEAPONS/WPN_LONG_SWORD
+PLUS: +7/+7
+COLOUR: YELLOW
+DESC_ID: This blessed weapon loves nothing more than to sing to its owner,
+ whether they want it to or not.
+
+NAME: Wrath of Trog
+APPEAR: bloodstained battleaxe
+OBJ: OBJ_WEAPONS/WPN_BATTLEAXE
+PLUS: +3/+11
+COLOUR: RED
+DESC_ID: This was the favourite weapon of the old god Trog, before it was
+ lost one day. It induces a bloodthirsty berserker rage in anyone
+ who uses it to strike another.
+
+NAME: Mace of Variability
+APPEAR: shimmering mace
+OBJ: OBJ_WEAPONS/WPN_MACE
+PLUS: 0/0 # Set on generation
+COLOUR: BLACK # Set on generation
+DESC_ID: It is rather unreliable.
+
+NAME: Glaive of Prune
+APPEAR: purple glaive
+OBJ: OBJ_WEAPONS/WPN_GLAIVE
+PLUS: 0/+12
+COLOUR: MAGENTA
+DESC_ID: It is the creation of a mad god, and carries a curse which
+ transforms anyone possessing it into a prune. Fortunately, the
+ curse works very slowly, and one can use it briefly with no
+ consequences worse than slightly purple skin and a few wrinkles.
+
+NAME: Sword of Power
+APPEAR: chunky great sword
+OBJ: OBJ_WEAPONS/WPN_GREAT_SWORD
+PLUS: 0/0 # Set on wield
+COLOUR: RED
+DESC_ID: It rewards the powerful with power and the meek with weakness.
+
+NAME: Staff of Olgreb
+APPEAR: green glowing staff
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: 0/0 # Set on wield
+COLOUR: GREEN
+BRAND: SPWPN_VENOM
+POISON: true
+DESC_ID: It was the magical weapon wielded by the mighty wizard Olgreb
+ before he met his fate somewhere within these dungeons. It
+ increases the ability of its wielder to use venomous magic, and
+ carries magical powers which can be evoked.
+
+NAME: Staff of Wucad Mu
+APPEAR: ephemeral quarterstaff
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: 0/0 # Set on wield
+COLOUR: BROWN
+DESC_ID: Its power varies in proportion to its wielder's intelligence.
+ Using it can be a bit risky.
+
+NAME: Vampire's Tooth
+APPEAR: ivory dagger
+OBJ: OBJ_WEAPONS/WPN_DAGGER
+PLUS: +3/+4
+COLOUR: WHITE
+BRAND: SPWPN_VAMPIRICISM
+DESC_ID: It is lethally vampiric.
+
+NAME: Scythe of Curses
+APPEAR: warped scythe
+OBJ: OBJ_WEAPONS/WPN_SCYTHE
+PLUS: +13/+13
+COLOUR: DARKGREY
+CURSED: -1
+DESC_ID: This weapon carries a terrible and highly irritating curse.
+
+NAME: Sceptre of Torment
+APPEAR: jewelled golden mace
+OBJ: OBJ_WEAPONS/WPN_MACE
+PLUS: +7/+6
+COLOUR: YELLOW
+DESC_ID: This truly accursed weapon is an instrument of Hell.
+
+NAME: Sword of Zonguldrok
+APPEAR: bone long sword
+OBJ: OBJ_WEAPONS/WPN_LONG_SWORD
+PLUS: +9/+9
+COLOUR: LIGHTGREY
+DESC_ID: This dreadful weapon is used at the user's peril.
+
+NAME: Sword of Cerebov
+APPEAR: great serpentine sword
+OBJ: OBJ_WEAPONS/WPN_GREAT_SWORD
+PLUS: +6/+6
+COLOUR: YELLOW
+BRAND: SPWPN_FLAMING
+CURSED: -1
+DESC: Eerie flames cover its twisted blade.
+
+NAME: Staff of Dispater
+APPEAR: golden staff
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: +4/+4
+COLOUR: YELLOW
+DESC_ID: This legendary item can unleash the fury of Hell.
+
+NAME: Sceptre of Asmodeus
+APPEAR: ruby sceptre
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: +7/+7
+COLOUR: RED
+DESC_ID: It carries some of the powers of the arch-fiend Asmodeus.
+
+##################### End of old fixed arts.
+
+NAME: long sword "Bloodbane"
+APPEAR: blackened long sword
+OBJ: OBJ_WEAPONS/WPN_LONG_SWORD
+PLUS: +7/+8
+COLOUR: DARKGREY
+BRAND: SPWPN_VORPAL
+BERSERK: true
+ANGRY: true
+STEALTH: -20
+
+NAME: scimitar of Flaming Death
+APPEAR: smoking scimitar
+OBJ: OBJ_WEAPONS/WPN_SCIMITAR
+PLUS: +7/+5
+COLOUR: RED
+BRAND: SPWPN_FLAMING
+FIRE: 2
+COLD: -1
+POISON: true
+MAGIC: 20
+
+NAME: mace of Brilliance
+APPEAR: brightly glowing mace
+OBJ: OBJ_WEAPONS/WPN_MACE
+PLUS: +5/+5
+COLOUR: WHITE
+BRAND: SPWPN_HOLY_WRATH
+AC: 5
+INT: 5
+LIFE: true
+SEEINV: true
+STEALTH: -20
+
+NAME: demon blade "Leech"
+APPEAR: runed demon blade
+OBJ: OBJ_WEAPONS/WPN_DEMON_BLADE
+PLUS: +13/+4
+COLOUR: MAGENTA
+BRAND: SPWPN_VAMPIRICISM
+EV: -1
+STR: -1
+INT: -1
+DEX: -1
+LIFE: true
+CURSED: 4
+
+NAME: dagger of Chilly Death
+APPEAR: sapphire dagger
+OBJ: OBJ_WEAPONS/WPN_DAGGER
+PLUS: +5/+7
+COLOUR: LIGHTBLUE
+BRAND: SPWPN_FREEZING
+FIRE: -1
+COLD: 2
+POISON: true
+MAGIC: 20
+DESC: A dagger made of one huge piece of sapphire.
+
+NAME: dagger "Morg"
+APPEAR: rusty dagger
+OBJ: OBJ_WEAPONS/WPN_DAGGER
+PLUS: -1/+4
+COLOUR: LIGHTRED
+BRAND: SPWPN_PAIN
+INT: 5
+MAGIC: 30
+DESC: An ugly rusty dagger.
+DESC_END: Many years ago it was the property of a powerful mage called Boris.
+ He got lost in the Dungeon while seeking the Orb.
+
+NAME: scythe "Finisher"
+APPEAR: blackened scythe
+OBJ: OBJ_WEAPONS/WPN_SCYTHE
+PLUS: +3/+5
+COLOUR: DARKGREY
+BRAND: SPWPN_SPEED
+STR: 3
+CURSED: -1
+DESC: A long and sharp scythe, specially modified for combat purposes.
+
+NAME: sling "Punk"
+APPEAR: blue sling
+OBJ: OBJ_WEAPONS/WPN_SLING
+PLUS: +9/+12
+COLOUR: LIGHTBLUE
+BRAND: SPWPN_FROST
+COLD: 1
+DESC: A sling made of weird blue leather.
+
+ENUM: KRISHNA
+NAME: bow of Krishna "Sharnga"
+APPEAR: golden bow
+OBJ: OBJ_WEAPONS/WPN_BOW
+PLUS: +8/+8
+COLOUR: YELLOW
+BRAND: SPWPN_SPEED
+DEX: 3
+SEEINV: true
+DESC: A wonderful golden bow.
+DESC_END: It once belonged to a foreign god. It works best with special
+ arrows which are not generally available.
+
+NAME: giant club "Skullcrusher"
+APPEAR: brutal giant club
+OBJ: OBJ_WEAPONS/WPN_GIANT_CLUB
+PLUS: +0/+5
+COLOUR: BROWN
+BRAND: SPWPN_SPEED
+STR: 5
+
+NAME: glaive of the Guard
+APPEAR: polished glaive
+OBJ: OBJ_WEAPONS/WPN_GLAIVE
+PLUS: +5/+8
+COLOUR: LIGHTCYAN
+BRAND: SPWPN_ELECTROCUTION
+AC: 5
+SEEINV: true
+BERSERK: true
+DESC_END: This weapon once belonged to Gar Dogh, the guard of a king's
+ treasures. According to legend he was lost somewhere in the Dungeon.
+
+NAME: sword of Jihad
+APPEAR: crystal sword
+OBJ: OBJ_WEAPONS/WPN_LONG_SWORD
+PLUS: +12/+10
+COLOUR: WHITE
+BRAND: SPWPN_HOLY_WRATH
+EV: 3
+LIFE: true
+MAGIC: 20
+ANGRY: true
+STEALTH: -50
+DESC_END: This sword was The Shining One's gift to a worshipper.
+DESC: A long sword made of one huge piece of crystal.
+
+NAME: crossbow "Hellfire"
+APPEAR: flaming crossbow
+OBJ: OBJ_WEAPONS/WPN_CROSSBOW
+PLUS: +6/+9
+COLOUR: LIGHTRED
+BRAND: SPWPN_FLAME
+FIRE: 2
+COLD: -1
+MAGIC: 40
+DESC: A flaming crossbow, forged in the fires of the Hells.
+
+NAME: sword of the Doom Knight
+APPEAR: adamantine great sword
+OBJ: OBJ_WEAPONS/WPN_GREAT_SWORD
+PLUS: +13/+13
+COLOUR: BLUE
+BRAND: SPWPN_PAIN
+MAGIC: 50
+NOSPELL: true
+DESC: An adamantine great sword.
+
+NAME: "Eos"
+APPEAR: encrusted morningstar
+OBJ: OBJ_WEAPONS/WPN_MORNINGSTAR
+PLUS: +5/+5
+COLOUR: LIGHTCYAN
+BRAND: SPWPN_ELECTROCUTION
+ELEC: true
+SEEINV: true
+NOTELEP: true
+
+# Was "spear of Voo-Doo". In the African origin, there is a distinction
+# between voodoo and bo, the latter dealing with curses, witchcraft and
+# spells designed to do harm. Priests (or rather sorcerors) of bo are
+# called botono.
+NAME: spear of the Botono
+APPEAR: ebony spear
+OBJ: OBJ_WEAPONS/WPN_SPEAR
+PLUS: +2/+10
+COLOUR: DARKGREY
+BRAND: SPWPN_VAMPIRICISM
+POISON: true
+LIFE: true
+NOISES: true
+STEALTH: -30
+DESC_END: A really dark and malign artefact, which no wise man would even touch.
+
+NAME: trident of the Octopus King
+APPEAR: mangy trident
+OBJ: OBJ_WEAPONS/WPN_TRIDENT
+PLUS: +10/+4
+COLOUR: CYAN
+BRAND: SPWPN_VENOM
+ELEC: true
+POISON: true
+MAGIC: 50
+DESC_END: This trident was stolen many years ago from the Octopus King's
+ garden by a really unimportant and already dead man. But beware
+ of the Octopus King's wrath!
+
+NAME: mithril axe "Arga"
+APPEAR: mithril axe
+OBJ: OBJ_WEAPONS/WPN_WAR_AXE
+PLUS: +10/+6
+COLOUR: WHITE
+BRAND: SPWPN_SPEED
+STR: 2
+MAGIC: 30
+DESC: A beautiful mithril axe, probably lost by some dwarven hero.
+
+NAME: Elemental Staff
+APPEAR: black staff
+OBJ: OBJ_WEAPONS/WPN_QUARTERSTAFF
+PLUS: +3/+1
+COLOUR: DARKGREY
+BRAND: SPWPN_PROTECTION
+FIRE: 2
+COLD: 2
+MAGIC: 60
+NOISES: true
+METAB: 2
+DESC_END: This powerful staff used to belong to the leader of the Guild of
+ Five Elements.
+
+NAME: hand crossbow "Sniper"
+APPEAR: black crossbow
+OBJ: OBJ_WEAPONS/WPN_HAND_CROSSBOW
+PLUS: +10/+0
+COLOUR: DARKGREY
+BRAND: SPWPN_VENOM
+SEEINV: true
+DESC: A hand crossbow made of some black material.
+
+NAME: longbow "Piercer"
+APPEAR: very long metal bow
+OBJ: OBJ_WEAPONS/WPN_LONGBOW
+PLUS: +2/+10
+COLOUR: CYAN
+BRAND: SPWPN_VORPAL
+EV: -2
+DESC: An exceptionally large metal longbow.
+
+ENUM: BLOWGUN_ASSASSIN
+NAME: blowgun of the Assassin
+APPEAR: tiny blowgun
+OBJ: OBJ_WEAPONS/WPN_BLOWGUN
+PLUS: +6/+6
+COLOUR: WHITE
+INV: true
+STEALTH: 60
+DESC: It is designed for easy concealment, but still packs a nasty punch.
+
+NAME: Wyrmbane
+APPEAR: scale-covered lance
+OBJ: OBJ_WEAPONS/WPN_SPEAR
+PLUS: +9/+6
+COLOUR: GREEN
+BRAND: SPWPN_DRAGON_SLAYING
+AC: 5
+FIRE: 1
+POISON: true
+BERSERK: true
+
+NAME: Spriggan's Knife
+APPEAR: dainty little knife
+OBJ: OBJ_WEAPONS/WPN_KNIFE
+PLUS: +4/+10
+COLOUR: LIGHTCYAN
+EV: 4
+DEX: 4
+MAGIC: 20
+STEALTH: 50
+DESC: A dainty little knife.
+DESC_END: This knife was made by Spriggans, or for Spriggans, or possibly
+ from Spriggans. Anyway, it's in some way associated with those
+ fey folk.
+
+NAME: plutonium sword
+APPEAR: glowing long sword
+OBJ: OBJ_WEAPONS/WPN_LONG_SWORD
+PLUS: +12/+16
+COLOUR: LIGHTGREEN
+MUTATE: 6
+CURSED: 1
+STEALTH: -20
+DESC: A long sword made of weird glowing metal.
+
+NAME: great mace "Undeadhunter"
+APPEAR: great steel mace
+OBJ: OBJ_WEAPONS/WPN_GREAT_MACE
+PLUS: +7/+7
+COLOUR: LIGHTGREY
+BRAND: SPWPN_HOLY_WRATH
+LIFE: true
+
+NAME: whip "Serpent-Scourge"
+APPEAR: forked whip
+OBJ: OBJ_WEAPONS/WPN_WHIP
+PLUS: +5/+10
+COLOUR: DARKGREY
+BRAND: SPWPN_VENOM
+POISON: true
+DESC_ID: A double-ended whip made from the cured hides of the Lair of Beasts'
+ deadly grey snakes.
+
+NAME: knife of Accuracy
+APPEAR: thin dagger
+OBJ: OBJ_WEAPONS/WPN_DAGGER
+PLUS: +27/-1
+COLOUR: LIGHTCYAN
+DESC_END: It is almost unerringly accurate.
+
+# A play on the spell of the same name. Colour taken from crystal walls.
+ENUM: CRYSTAL_SPEAR
+NAME: Lehudib's crystal spear
+APPEAR: crystal spear
+OBJ: OBJ_WEAPONS/WPN_SPEAR
+PLUS: +6/+6
+COLOUR: GREEN
+DESC_END: Presumably this relic led to the invention of the famous spell.
+
+NAME: shield of Ignorance
+APPEAR: dull large shield
+OBJ: OBJ_ARMOUR/ARM_LARGE_SHIELD
+PLUS: +5
+COLOUR: BROWN
+AC: 2
+EV: 2
+INT: -6
+LIFE: true
+CURSED: 3
+
+NAME: robe of Augmentation
+APPEAR: silk robe
+OBJ: OBJ_ARMOUR/ARM_ROBE
+PLUS: +4
+COLOUR: LIGHTRED
+STR: 2
+INT: 2
+DEX: 2
+DESC: A robe made of the finest silk.
+
+NAME: cloak of the Thief
+APPEAR: tattered cloak
+OBJ: OBJ_ARMOUR/ARM_CLOAK
+PLUS: +1
+COLOUR: DARKGREY
+EV: 2
+DEX: 2
+SEEINV: true
+INV: true
+LEV: true
+DAM: -3
+STEALTH: 60
+DESC_END: It allows its wearer to excel in the arts of thievery.
+
+NAME: shield "Bullseye"
+APPEAR: round shield
+OBJ: OBJ_ARMOUR/ARM_SHIELD
+PLUS: +10
+COLOUR: RED
+EV: -5
+
+NAME: crown of Dyrovepreva
+APPEAR: jewelled bronze crown
+OBJ: OBJ_ARMOUR/ARM_CAP
+PLUS: +3
+COLOUR: BROWN
+INT: 2
+ELEC: true
+SEEINV: true
+METAB: 1
+DESC: A large crown of dull bronze, set with a dazzling array of gemstones.
+
+NAME: robe of Misfortune
+APPEAR: fabulously ornate robe
+OBJ: OBJ_ARMOUR/ARM_ROBE
+PLUS: -5
+COLOUR: MAGENTA
+EV: -4
+STR: -2
+INT: -2
+DEX: -2
+NOSPELL: true
+RND_TELE: true
+MUTATE: 5
+CURSED: 1
+STEALTH: -80
+DESC: A splendid flowing robe of fur and silk.
+
+NAME: cloak of Flash
+APPEAR: vibrating cloak
+OBJ: OBJ_ARMOUR/ARM_CLOAK
+PLUS: +3
+COLOUR: RED
+EV: 4
+LEV: true
+CANTELEP: true
+DESC: A vibrating cloak.
+
+ENUM: BOOTS_ASSASSIN
+NAME: boots of the Assassin
+APPEAR: soft boots
+OBJ: OBJ_ARMOUR/ARM_BOOTS
+PLUS: +2
+COLOUR: BROWN
+DEX: 3
+INV: true
+STEALTH: 80
+DESC: Some soft boots.
+DESC_END: These boots were specially designed by the Assassin's Guild.
+
+ENUM: LEARS
+NAME: Lear's chain mail
+APPEAR: golden chain mail
+OBJ: OBJ_ARMOUR/ARM_CHAIN_MAIL
+PLUS: -1
+COLOUR: YELLOW
+DEX: -3
+NOSPELL: true
+CURSED: -1
+DESC: A chain mail made of pure gold.
+
+NAME: skin of Zhor
+APPEAR: smelly skin
+OBJ: OBJ_ARMOUR/ARM_ANIMAL_SKIN
+PLUS: +4
+COLOUR: BROWN
+COLD: 2
+DESC: The skin of some strange animal.
+
+ENUM: SALAMANDER
+NAME: salamander hide armour
+APPEAR: red leather armour
+OBJ: OBJ_ARMOUR/ARM_LEATHER_ARMOUR
+PLUS: +3
+COLOUR: RED
+FIRE: 2
+BERSERK: true
+DESC: A leather armour made of a salamander's skin.
+
+NAME: gauntlets of War
+APPEAR: thick gauntlets
+OBJ: OBJ_ARMOUR/ARM_GLOVES
+PLUS: +3
+COLOUR: BROWN
+ACC: 3
+DAM: 3
+
+NAME: shield of Resistance
+APPEAR: bronze shield
+OBJ: OBJ_ARMOUR/ARM_SHIELD
+PLUS: +3
+COLOUR: LIGHTRED
+FIRE: 1
+COLD: 1
+MAGIC: 40
+DESC: A bronze shield.
+
+NAME: robe of Folly
+APPEAR: dull robe
+OBJ: OBJ_ARMOUR/ARM_ROBE
+PLUS: -1
+COLOUR: LIGHTGREY
+INT: -5
+NOSPELL: true
+CURSED: 2
+DESC: A dull grey robe.
+
+ENUM: MAXWELL
+NAME: Maxwell's patent armour
+APPEAR: weird-looking armour
+OBJ: OBJ_ARMOUR/ARM_PLATE_MAIL
+PLUS: +10
+COLOUR: LIGHTGREEN
+NOSPELL: true
+NOTELEP: true
+CURSED: -1
+DESC: A weird-looking armour.
+
+NAME: mask of the Dragon
+APPEAR: blue mask
+OBJ: OBJ_ARMOUR/ARM_CAP
+COLOUR: BLUE
+MAGIC: 40
+SEEINV: true
+ACC: 2
+DAM: 2
+DESC: A blue mask.
+
+NAME: robe of Night
+APPEAR: black robe
+OBJ: OBJ_ARMOUR/ARM_ROBE
+PLUS: +4
+COLOUR: DARKGREY
+MAGIC: 30
+SEEINV: true
+INV: true
+STEALTH: 50
+DESC: A long black robe made of strange glossy material.
+DESC_END: According to legend, this robe was the gift of Ratri the Goddess
+ of the Night to one of her followers.
+
+NAME: armour of the Dragon King
+APPEAR: shiny dragon armour
+OBJ: OBJ_ARMOUR/ARM_GOLD_DRAGON_ARMOUR
+PLUS: +5
+COLOUR: YELLOW
+MAGIC: 50
+
+NAME: hat of the Alchemist
+APPEAR: dirty hat
+OBJ: OBJ_ARMOUR/ARM_WIZARD_HAT
+PLUS: +2
+COLOUR: MAGENTA
+FIRE: 1
+COLD: 1
+ELEC: true
+MAGIC: 30
+DESC: A dirty hat.
+
+NAME: Fencer's gloves
+APPEAR: silk gloves
+OBJ: OBJ_ARMOUR/ARM_GLOVES
+PLUS: +2
+COLOUR: WHITE
+EV: 3
+DEX: 3
+ACC: 5
+DESC: A pair of gloves made of white silk.
+
+NAME: cloak of Starlight
+APPEAR: phosphorescent cloak
+OBJ: OBJ_ARMOUR/ARM_CLOAK
+COLOUR: WHITE
+EV: 4
+COLD: 1
+ELEC: true
+STEALTH: -30
+DESC_END: A cloak woven of pure light beams.
+DESC: A phosphorescent cloak.
+
+NAME: ratskin cloak
+APPEAR: motley cloak
+OBJ: OBJ_ARMOUR/ARM_CLOAK
+PLUS: +1
+COLOUR: LIGHTRED
+INT: -1
+DEX: -1
+LIFE: true
+POISON: true
+DESC_END: An enchantress with a magic loom and way too much time on
+ her hands stitched this cloak from the hides of hundreds
+ of rats, most of them orange. It's a bit awkward to wear
+ and looks rather foolish, but it provides excellent protection
+ from rats of all kinds.
+
+NAME: amulet of the Air
+APPEAR: sky-blue amulet
+OBJ: OBJ_JEWELLERY/AMU_CONTROLLED_FLIGHT
+COLOUR: LIGHTCYAN
+EV: 3
+ELEC: true
+LEV: true
+STEALTH: 50
+DESC: A sky-blue amulet.
+
+NAME: ring of Shadows
+APPEAR: black ring
+OBJ: OBJ_JEWELLERY/RING_INVISIBILITY
+COLOUR: DARKGREY
+EV: 4
+LIFE: true
+SEEINV: true
+ACC: -3
+STEALTH: 40
+
+NAME: amulet of Cekugob
+APPEAR: crystal amulet
+OBJ: OBJ_JEWELLERY/AMU_WARDING
+COLOUR: LIGHTGREY
+AC: 1
+EV: 1
+ELEC: true
+POISON: true
+LIFE: true
+NOTELEP: true
+METAB: 2
+
+NAME: amulet of the Four Winds
+APPEAR: jade amulet
+OBJ: OBJ_JEWELLERY/AMU_CLARITY
+COLOUR: LIGHTGREEN
+LIFE: true
+MAGIC: 100
+
+NAME: necklace of Bloodlust
+APPEAR: blood-stained necklace
+OBJ: OBJ_JEWELLERY/AMU_RAGE
+COLOUR: RED
+STR: 2
+INT: -2
+MAGIC: 30
+ANGRY: true
+DAM: 3
+CURSED: 3
+STEALTH: -20
+
+NAME: ring of Shaolin
+APPEAR: jade ring
+OBJ: OBJ_JEWELLERY/RING_EVASION
+PLUS: +8
+COLOUR: LIGHTGREEN
+
+NAME: ring of Robustness
+APPEAR: steel ring
+OBJ: OBJ_JEWELLERY/RING_PROTECTION
+PLUS: +8
+COLOUR: LIGHTGREY
+
+NAME: ring of the Mage
+APPEAR: sapphire ring
+OBJ: OBJ_JEWELLERY/RING_WIZARDRY
+COLOUR: LIGHTBLUE
+INT: 3
+MAGIC: 50
+
+NAME: brooch of Shielding
+APPEAR: shield-shaped amulet
+OBJ: OBJ_JEWELLERY/AMU_WARDING
+COLOUR: LIGHTBLUE
+AC: 4
+EV: 4
+DESC: A shield-shaped amulet.
+DESC_END: Back in the good old days, every adventurer had one of these
+ handy devices. That, and a pony.
+
+# This entry must alway be last.
+ENUM: DUMMY2
+NAME: DUMMY UNRANDART 2
+APPEAR: DUMMY UNRANDART 2
+OBJ: OBJ_UNASSIGNED/250
+PLUS: 250/250
+COLOUR: BLACK
diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/artefact.cc
index 4f9906f05b..e026b73baf 100644
--- a/crawl-ref/source/randart.cc
+++ b/crawl-ref/source/artefact.cc
@@ -1,5 +1,5 @@
/*
- * File: randart.cc
+ * File: artefact.cc
* Summary: Random and unrandom artefact functions.
* Written by: Linley Henzell
*
@@ -9,7 +9,7 @@
#include "AppHdr.h"
REVISION("$Rev$");
-#include "randart.h"
+#include "artefact.h"
#include <cstdlib>
#include <climits>
@@ -35,8 +35,6 @@ REVISION("$Rev$");
#define ARTEFACT_NAME_KEY "artefact_name"
#define ARTEFACT_APPEAR_KEY "artefact_appearance"
-static const char* _get_fixedart_name(const item_def &item);
-
// The initial generation of a randart is very simple - it occurs in
// dungeon.cc and consists of giving it a few random things - plus &
// plus2 mainly.
@@ -292,49 +290,14 @@ static std::string _replace_name_parts(const std::string name_in,
// Remember: disallow unrandart creation in Abyss/Pan.
-// The following unrandart bits were taken from $pellbinder's mon-util
-// code (see mon-util.h & mon-util.cc) and modified (LRH). They're in
-// randart.cc and not randart.h because they're only used in this code
-// module.
-
-struct unrandart_entry
-{
- const char *name; // true name of unrandart (max 31 chars)
- const char *unid_name; // un-id'd name of unrandart (max 31 chars)
-
- object_class_type ura_cl; // class of ura
- int ura_ty; // type of ura
- int ura_pl; // plus of ura
- int ura_pl2; // plus2 of ura
- int ura_col; // colour of ura
- short prpty[RA_PROPERTIES];
-
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip1;
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip2;
- // special description added to 'v' command output (max 31 chars)
- const char *spec_descrip3;
-};
-
static unrandart_entry unranddata[] = {
-#include "unrand.h"
+#include "art-data.h"
};
static FixedVector < bool, NO_UNRANDARTS > unrandart_exist;
static unrandart_entry *_seekunrandart( const item_def &item );
-void set_unrandart_exist(int whun, bool is_exist)
-{
- unrandart_exist[whun] = is_exist;
-}
-
-bool does_unrandart_exist(int whun)
-{
- return (unrandart_exist[whun]);
-}
-
bool is_known_artefact( const item_def &item )
{
if (!item_type_known(item))
@@ -345,13 +308,13 @@ bool is_known_artefact( const item_def &item )
bool is_artefact( const item_def &item )
{
- return (is_random_artefact(item) || is_fixed_artefact(item));
+ return (item.flags & ISFLAG_ARTEFACT_MASK);
}
-// returns true is item is a pure randart or an unrandart
+// returns true is item is a pure randart
bool is_random_artefact( const item_def &item )
{
- return (item.flags & ISFLAG_ARTEFACT_MASK);
+ return (item.flags & ISFLAG_RANDART);
}
// returns true if item in an unrandart
@@ -360,39 +323,37 @@ bool is_unrandom_artefact( const item_def &item )
return (item.flags & ISFLAG_UNRANDART);
}
-// returns true if item is one of the original fixed artefacts
-bool is_fixed_artefact( const item_def &item )
+bool is_special_unrandom_artefact( const item_def &item )
{
- if (!is_random_artefact( item )
- && item.base_type == OBJ_WEAPONS
- && item.special >= SPWPN_START_FIXEDARTS)
- {
- return (true);
- }
+ return (item.flags & ISFLAG_UNRANDART
+ && get_unrand_specialness(item.special) == UNRANDPSEC_SPECIAL);
+}
- return (false);
+unique_item_status_type get_unique_item_status(const item_def& item)
+{
+ if (item.flags & ISFLAG_UNRANDART)
+ return get_unique_item_status(item.special);
+
+ return (UNIQ_NOT_EXISTS);
}
-unique_item_status_type get_unique_item_status( object_class_type base_type,
- int art )
+unique_item_status_type get_unique_item_status( int art )
{
- if (base_type == OBJ_WEAPONS
- && art >= SPWPN_START_FIXEDARTS && art < SPWPN_START_NOGEN_FIXEDARTS)
- {
- return (you.unique_items[art - SPWPN_START_FIXEDARTS]);
- }
- else
- return (UNIQ_NOT_EXISTS);
+ ASSERT(art > UNRAND_START && art < UNRAND_LAST);
+ return (you.unique_items[art - UNRAND_START]);
}
-void set_unique_item_status( object_class_type base_type, int art,
- unique_item_status_type status )
+void set_unique_item_status(const item_def& item,
+ unique_item_status_type status )
{
- if (base_type == OBJ_WEAPONS
- && art >= SPWPN_START_FIXEDARTS && art < SPWPN_START_NOGEN_FIXEDARTS)
- {
- you.unique_items[art - SPWPN_START_FIXEDARTS] = status;
- }
+ if (item.flags & ISFLAG_UNRANDART)
+ set_unique_item_status(item.special, status);
+}
+
+void set_unique_item_status( int art, unique_item_status_type status )
+{
+ ASSERT(art > UNRAND_START && art < UNRAND_LAST);
+ you.unique_items[art - UNRAND_START] = status;
}
static long _calc_seed( const item_def &item )
@@ -652,7 +613,7 @@ static int _randart_add_one_property( const item_def &item,
return (negench ? -1 : 1);
}
-void static _get_randart_properties(const item_def &item,
+void static _get_randart_properties(const item_def &item,
artefact_properties_t &proprt)
{
const object_class_type aclass = item.base_type;
@@ -1171,7 +1132,7 @@ static bool _redo_book(item_def &book)
return (false);
}
-static bool _init_randart_book(item_def &book)
+static bool _init_artefact_book(item_def &book)
{
ASSERT(book.sub_type == BOOK_RANDART_LEVEL
|| book.sub_type == BOOK_RANDART_THEME);
@@ -1208,36 +1169,36 @@ static bool _init_randart_book(item_def &book)
return (book_good);
}
-static bool _init_randart_properties(item_def &item)
+static bool _init_artefact_properties(item_def &item)
{
- ASSERT( is_random_artefact( item ) );
+ ASSERT( is_artefact( item ) );
CrawlHashTable &props = item.props;
if (!props.exists( ARTEFACT_PROPS_KEY ))
- props[ARTEFACT_PROPS_KEY].new_vector(SV_SHORT).resize(RA_PROPERTIES);
+ props[ARTEFACT_PROPS_KEY].new_vector(SV_SHORT).resize(ART_PROPERTIES);
CrawlVector &rap = props[ARTEFACT_PROPS_KEY];
- rap.set_max_size(RA_PROPERTIES);
+ rap.set_max_size(ART_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
rap[i] = (short) 0;
if (is_unrandom_artefact( item ))
{
const unrandart_entry *unrand = _seekunrandart( item );
- for (int i = 0; i < RA_PROPERTIES; i++)
+ for (int i = 0; i < ART_PROPERTIES; i++)
rap[i] = (short) unrand->prpty[i];
return (true);
}
if (item.base_type == OBJ_BOOKS)
- return _init_randart_book(item);
+ return _init_artefact_book(item);
artefact_properties_t prop;
_get_randart_properties(item, prop);
- for (int i = 0; i < RA_PROPERTIES; i++)
+ for (int i = 0; i < ART_PROPERTIES; i++)
{
if (i == ARTP_CURSED && prop[i] < 0)
{
@@ -1250,28 +1211,28 @@ static bool _init_randart_properties(item_def &item)
return (true);
}
-void artefact_wpn_properties( const item_def &item,
- artefact_properties_t &proprt,
- artefact_known_props_t &known)
+void artefact_wpn_properties( const item_def &item,
+ artefact_properties_t &proprt,
+ artefact_known_props_t &known)
{
- ASSERT( is_random_artefact( item ) );
+ ASSERT( is_artefact( item ) );
ASSERT( item.props.exists( KNOWN_PROPS_KEY ) );
const CrawlStoreValue &_val = item.props[KNOWN_PROPS_KEY];
ASSERT( _val.get_type() == SV_VEC );
const CrawlVector &known_vec = _val.get_vector();
ASSERT( known_vec.get_type() == SV_BOOL );
- ASSERT( known_vec.size() == RA_PROPERTIES);
- ASSERT( known_vec.get_max_size() == RA_PROPERTIES);
+ ASSERT( known_vec.size() == ART_PROPERTIES);
+ ASSERT( known_vec.get_max_size() == ART_PROPERTIES);
if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
{
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
known[i] = (bool) true;
}
else
{
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
known[i] = known_vec[i];
}
@@ -1279,17 +1240,17 @@ void artefact_wpn_properties( const item_def &item,
{
const CrawlVector &rap_vec = item.props[ARTEFACT_PROPS_KEY].get_vector();
ASSERT( rap_vec.get_type() == SV_SHORT );
- ASSERT( rap_vec.size() == RA_PROPERTIES);
- ASSERT( rap_vec.get_max_size() == RA_PROPERTIES);
+ ASSERT( rap_vec.size() == ART_PROPERTIES);
+ ASSERT( rap_vec.get_max_size() == ART_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
proprt[i] = rap_vec[i].get_short();
}
else if (is_unrandom_artefact( item ))
{
const unrandart_entry *unrand = _seekunrandart( item );
- for (int i = 0; i < RA_PROPERTIES; i++)
+ for (int i = 0; i < ART_PROPERTIES; i++)
proprt[i] = (short) unrand->prpty[i];
}
else
@@ -1362,14 +1323,14 @@ int artefact_wpn_num_props( const artefact_properties_t &proprt )
void artefact_wpn_learn_prop( item_def &item, artefact_prop_type prop )
{
- ASSERT( is_random_artefact( item ) );
+ ASSERT( is_artefact( item ) );
ASSERT( item.props.exists( KNOWN_PROPS_KEY ) );
CrawlStoreValue &_val = item.props[KNOWN_PROPS_KEY];
ASSERT( _val.get_type() == SV_VEC );
CrawlVector &known_vec = _val.get_vector();
ASSERT( known_vec.get_type() == SV_BOOL );
- ASSERT( known_vec.size() == RA_PROPERTIES);
- ASSERT( known_vec.get_max_size() == RA_PROPERTIES);
+ ASSERT( known_vec.size() == ART_PROPERTIES);
+ ASSERT( known_vec.get_max_size() == ART_PROPERTIES);
if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
return;
@@ -1434,9 +1395,6 @@ std::string artefact_name(const item_def &item, bool appearance)
|| item.base_type == OBJ_JEWELLERY
|| item.base_type == OBJ_BOOKS);
- if (is_fixed_artefact( item ))
- return _get_fixedart_name( item );
-
if (is_unrandom_artefact( item ))
{
const unrandart_entry *unrand = _seekunrandart( item );
@@ -1564,51 +1522,40 @@ std::string get_artefact_name( const item_def &item )
void set_artefact_name( item_def &item, const std::string &name )
{
- ASSERT( is_random_artefact( item ));
+ ASSERT( is_artefact( item ));
ASSERT( !name.empty() );
item.props[ARTEFACT_NAME_KEY].get_string() = name;
}
void set_artefact_appearance( item_def &item, const std::string &appear )
{
- ASSERT( is_random_artefact( item ));
+ ASSERT( is_artefact( item ));
ASSERT( !appear.empty() );
item.props[ARTEFACT_APPEAR_KEY].get_string() = appear;
}
int find_unrandart_index(const item_def& artefact)
{
- for (int i = 0; i < NO_UNRANDARTS; i++)
- {
- const unrandart_entry& candidate = unranddata[i];
- if (candidate.ura_cl == artefact.base_type
- && candidate.ura_ty == artefact.sub_type
- && candidate.ura_pl == artefact.plus
- && candidate.ura_pl2 == artefact.plus2
- && candidate.ura_col == artefact.colour)
- {
- return i;
- }
- }
-
- return (-1);
+ return (artefact.special);
}
-static unrandart_entry *_seekunrandart( const item_def &item )
+unrandart_entry* get_unrand_entry(int unrand_index)
{
- const int idx = find_unrandart_index(item);
- if (idx == -1)
+ unrand_index -= UNRAND_START;
+
+ if (unrand_index <= -1 || unrand_index >= NO_UNRANDARTS)
return &unranddata[0]; // dummy unrandart
else
- return &unranddata[idx];
+ return &unranddata[unrand_index];
}
-int find_unrandart_index(int item_number)
+static unrandart_entry *_seekunrandart( const item_def &item )
{
- return find_unrandart_index(mitm[item_number]);
+ return get_unrand_entry(item.special);
}
-int find_okay_unrandart(unsigned char aclass, unsigned char atype)
+int find_okay_unrandart(unsigned char aclass, unsigned char atype,
+ unrand_special_type specialness, bool in_abyss)
{
int ret = -1;
@@ -1616,298 +1563,82 @@ int find_okay_unrandart(unsigned char aclass, unsigned char atype)
// base_type and sub_type.
for (int i = 0, count = 0; i < NO_UNRANDARTS; i++)
{
- if (unranddata[i].ura_cl == aclass
- && !does_unrandart_exist(i)
- && (atype == OBJ_RANDOM || unranddata[i].ura_ty == atype))
- {
- count++;
-
- if (one_chance_in(count))
- ret = i;
- }
- }
-
- return (ret);
-}
-
-struct fixedart_setting
-{
- int which;
- const char* name;
- const char* appearance;
- object_class_type base;
- int subtype;
- int acc;
- int dam;
- int colour;
- bool curse;
-};
-
-const fixedart_setting fixedarts[] = {
-
- {
- SPWPN_SINGING_SWORD,
- "Singing Sword",
- "golden long sword",
- OBJ_WEAPONS,
- WPN_LONG_SWORD,
- 7,
- 7,
- YELLOW,
- false
- },
-
- {
- SPWPN_WRATH_OF_TROG,
- "Wrath of Trog",
- "bloodstained battleaxe",
- OBJ_WEAPONS,
- WPN_BATTLEAXE,
- 3,
- 11,
- RED,
- false
- },
-
- {
- SPWPN_SCYTHE_OF_CURSES,
- "Scythe of Curses",
- "warped scythe",
- OBJ_WEAPONS,
- WPN_SCYTHE,
- 13,
- 13,
- DARKGREY,
- true
- },
-
- {
- SPWPN_MACE_OF_VARIABILITY,
- "Mace of Variability",
- "shimmering mace",
- OBJ_WEAPONS,
- WPN_MACE,
- random2(16) - 4,
- random2(16) - 4,
- random_colour(),
- false
- },
-
- {
- SPWPN_GLAIVE_OF_PRUNE,
- "Glaive of Prune",
- "purple glaive",
- OBJ_WEAPONS,
- WPN_GLAIVE,
- 0,
- 12,
- MAGENTA,
- false
- },
+ const int index = i + UNRAND_START;
+ const unrandart_entry* entry = &unranddata[i];
- {
- SPWPN_SCEPTRE_OF_TORMENT,
- "Sceptre of Torment",
- "jewelled golden mace",
- OBJ_WEAPONS,
- WPN_MACE,
- 7,
- 6,
- YELLOW,
- false
- },
-
- {
- SPWPN_SWORD_OF_ZONGULDROK,
- "Sword of Zonguldrok",
- "bone long sword",
- OBJ_WEAPONS,
- WPN_LONG_SWORD,
- 9,
- 9,
- LIGHTGREY,
- false
- },
+ // Skip dummy entries.
+ if (entry->base_type == OBJ_UNASSIGNED)
+ continue;
- {
- SPWPN_SWORD_OF_POWER,
- "Sword of Power",
- "chunky great sword",
- OBJ_WEAPONS,
- WPN_GREAT_SWORD,
- 0, // set on wield
- 0, // set on wield
- RED,
- false
- },
+ const unique_item_status_type status =
+ get_unique_item_status(index);
- {
- SPWPN_STAFF_OF_OLGREB,
- "Staff of Olgreb",
- "green glowing staff",
- OBJ_WEAPONS,
- WPN_QUARTERSTAFF,
- 0, // set on wield
- 0, // set on wield
- GREEN,
- false
- },
+ if (in_abyss && status != UNIQ_LOST_IN_ABYSS
+ || !in_abyss && status != UNIQ_NOT_EXISTS)
+ {
+ continue;
+ }
- {
- SPWPN_VAMPIRES_TOOTH,
- "Vampire's Tooth",
- "ivory dagger",
- OBJ_WEAPONS,
- WPN_DAGGER,
- 3,
- 4,
- WHITE,
- false
- },
+ // Never randomly generated until lost in the abyss.
+ if ((!in_abyss || status != UNIQ_LOST_IN_ABYSS)
+ && index >= SPWPN_START_NOGEN_FIXEDARTS
+ && index <= SPWPN_END_FIXEDARTS)
+ {
+ continue;
+ }
- {
- SPWPN_STAFF_OF_WUCAD_MU,
- "Staff of Wucad Mu",
- "ephemeral quarterstaff",
- OBJ_WEAPONS,
- WPN_QUARTERSTAFF,
- 0, // set on wield
- 0, // set on wield
- BROWN,
- false
- },
+ if (entry->base_type != aclass
+ || (atype != OBJ_RANDOM && entry->sub_type != atype))
+ {
+ continue;
+ }
- {
- SPWPN_SWORD_OF_CEREBOV,
- "Sword of Cerebov",
- "great serpentine sword",
- OBJ_WEAPONS,
- WPN_GREAT_SWORD,
- 6,
- 6,
- YELLOW,
- true
- },
+ if (specialness != UNRANDSPEC_EITHER &&
+ specialness != get_unrand_specialness(index))
+ {
+ continue;
+ }
- {
- SPWPN_STAFF_OF_DISPATER,
- "Staff of Dispater",
- "golden staff",
- OBJ_WEAPONS,
- WPN_QUARTERSTAFF,
- 4,
- 4,
- YELLOW,
- false
- },
+ count++;
- {
- SPWPN_SCEPTRE_OF_ASMODEUS,
- "Sceptre of Asmodeus",
- "ruby sceptre",
- OBJ_WEAPONS,
- WPN_QUARTERSTAFF,
- 7,
- 7,
- RED,
- false
+ if (one_chance_in(count))
+ ret = index;
}
-};
-static const char* _get_fixedart_name(const item_def &item)
-{
- // Find the appropriate fixed artefact.
- for (unsigned int i = 0; i < ARRAYSZ(fixedarts); ++i)
- {
- if (fixedarts[i].which == item.special)
- {
- const fixedart_setting *fixed = &fixedarts[i];
- return (item_type_known(item) ? fixed->name : fixed->appearance);
- }
- }
- return (item_type_known(item) ? "Unnamed Artefact" : "buggy fixedart");
+ return (ret);
}
-int get_fixedart_num( const char *name )
+unrand_special_type get_unrand_specialness(int unrand_index)
{
- for (unsigned int i = 0; i < ARRAYSZ(fixedarts); ++i)
+ if (unrand_index >= UNRAND_SINGING_SWORD
+ && unrand_index <= UNRAND_ASMODEUS)
{
- std::string art = fixedarts[i].name;
- lowercase(art);
- if (replace_all(art, " ", "_") == name)
- return fixedarts[i].which;
+ return (UNRANDPSEC_SPECIAL);
}
- return SPWPN_NORMAL;
+ return (UNRANDSPEC_NORMAL);
}
-// which == 0 (default) gives random fixed artefact.
-// Returns true if successful.
-bool make_item_fixed_artefact( item_def &item, bool in_abyss, int which )
+unrand_special_type get_unrand_specialness(const item_def &item)
{
- const bool force = (which != 0);
- const fixedart_setting *fixedart = NULL;
-
- if (!force)
- {
- which = SPWPN_START_FIXEDARTS
- + random2(SPWPN_START_NOGEN_FIXEDARTS - SPWPN_START_FIXEDARTS);
- }
-
- const unique_item_status_type status =
- get_unique_item_status( OBJ_WEAPONS, which );
-
- if (!force
- && (status == UNIQ_EXISTS
- || in_abyss && status == UNIQ_NOT_EXISTS
- || !in_abyss && status == UNIQ_LOST_IN_ABYSS))
- {
- return (false);
- }
+ return get_unrand_specialness(item.special);
+}
- // Find the appropriate fixed artefact.
- for (unsigned int i = 0; i < ARRAYSZ(fixedarts); ++i)
- {
- if (fixedarts[i].which == which)
- {
- fixedart = &fixedarts[i];
- break;
- }
- }
+int get_unrandart_num( const char *name )
+{
+ std::string quoted = "\"";
+ quoted += name;
+ quoted += "\"";
- // None found?
- if (fixedart == NULL)
+ for (unsigned int i = 0; i < ARRAYSZ(unranddata); ++i)
{
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_ERROR, "Couldn't find fixed artefact %d", which);
-#endif
- return (false);
+ std::string art = unranddata[i].name;
+ art = replace_all(art, " ", "_");
+ art = replace_all(art, "'", "");
+ lowercase(art);
+ if (art == name || art.find(quoted) != std::string::npos)
+ return (UNRAND_START + i);
}
-
- // If we get here, we've made the artefact
- item.base_type = fixedart->base;
- item.sub_type = fixedart->subtype;
- item.plus = fixedart->acc;
- item.plus2 = fixedart->dam;
- item.colour = fixedart->colour;
- item.special = which;
- item.quantity = 1;
-
- // get true artefact name
- ASSERT(!item.props.exists( ARTEFACT_NAME_KEY ));
- item.props[ARTEFACT_NAME_KEY].get_string() = fixedart->name;
-
- // get artefact appearance
- ASSERT(!item.props.exists( ARTEFACT_APPEAR_KEY ));
- item.props[ARTEFACT_APPEAR_KEY].get_string() = fixedart->appearance;
-
- if (fixedart->curse)
- do_curse_item(item);
-
- // Items originally generated in the abyss and not found will be
- // shifted to "lost in abyss", and will only be found there. -- bwr
- set_unique_item_status( OBJ_WEAPONS, which, UNIQ_EXISTS );
-
- return (true);
+ return SPWPN_NORMAL;
}
static bool _randart_is_redundant( const item_def &item,
@@ -2094,17 +1825,17 @@ bool make_item_blessed_blade( item_def &item )
item.flags |= ISFLAG_RANDART;
ASSERT(!item.props.exists( KNOWN_PROPS_KEY ));
- item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(RA_PROPERTIES);
+ item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(ART_PROPERTIES);
CrawlVector &known = item.props[KNOWN_PROPS_KEY];
- known.set_max_size(RA_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ known.set_max_size(ART_PROPERTIES);
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
known[i] = (bool) false;
ASSERT(!item.props.exists( ARTEFACT_PROPS_KEY ));
- item.props[ARTEFACT_PROPS_KEY].new_vector(SV_SHORT).resize(RA_PROPERTIES);
+ item.props[ARTEFACT_PROPS_KEY].new_vector(SV_SHORT).resize(ART_PROPERTIES);
CrawlVector &rap = item.props[ARTEFACT_PROPS_KEY];
- rap.set_max_size(RA_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ rap.set_max_size(ART_PROPERTIES);
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
rap[i] = (short) 0;
// blessed blade of the Shining One
@@ -2157,10 +1888,10 @@ bool make_item_randart( item_def &item )
ASSERT(!item.props.exists( KNOWN_PROPS_KEY ));
ASSERT(!item.props.exists( ARTEFACT_NAME_KEY ));
ASSERT(!item.props.exists( ARTEFACT_APPEAR_KEY ));
- item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(RA_PROPERTIES);
+ item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(ART_PROPERTIES);
CrawlVector &known = item.props[KNOWN_PROPS_KEY];
- known.set_max_size(RA_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ known.set_max_size(ART_PROPERTIES);
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
known[i] = (bool) false;
item.flags |= ISFLAG_RANDART;
@@ -2172,7 +1903,7 @@ bool make_item_randart( item_def &item )
{
item.special = (random_int() & RANDART_SEED_MASK);
// Now that we found something, initialize the props array.
- if (!_init_randart_properties(item))
+ if (!_init_artefact_properties(item))
{
// Something went wrong that no amount of changing
// item.special will fix.
@@ -2203,35 +1934,32 @@ bool make_item_randart( item_def &item )
bool make_item_unrandart( item_def &item, int unrand_index )
{
+ ASSERT(unrand_index > UNRAND_START);
+ ASSERT(unrand_index < (UNRAND_START + NO_UNRANDARTS));
+
if (!item.props.exists( KNOWN_PROPS_KEY ))
{
- item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(RA_PROPERTIES);
+ item.props[KNOWN_PROPS_KEY].new_vector(SV_BOOL).resize(ART_PROPERTIES);
CrawlVector &known = item.props[KNOWN_PROPS_KEY];
- known.set_max_size(RA_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ known.set_max_size(ART_PROPERTIES);
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
known[i] = (bool) false;
}
- const unrandart_entry *unrand = &unranddata[unrand_index];
- item.base_type = unrand->ura_cl;
- item.sub_type = unrand->ura_ty;
- item.plus = unrand->ura_pl;
- item.plus2 = unrand->ura_pl2;
- item.colour = unrand->ura_col;
+ const unrandart_entry *unrand = &unranddata[unrand_index - UNRAND_START];
+ item.base_type = unrand->base_type;
+ item.sub_type = unrand->sub_type;
+ item.plus = unrand->plus;
+ item.plus2 = unrand->plus2;
+ item.colour = unrand->colour;
item.flags |= ISFLAG_UNRANDART;
- _init_randart_properties(item);
+ _init_artefact_properties(item);
- item.special = unrand->prpty[ARTP_BRAND];
- if (item.special != 0)
- {
+ item.special = unrand_index;
+ if (unrand->prpty[ARTP_BRAND] != 0)
do_curse_item( item );
- // If the property doesn't allow for recursing, clear it now.
- if (item.special < 0)
- item.special = 0;
- }
-
// get true artefact name
ASSERT(!item.props.exists( ARTEFACT_NAME_KEY ));
item.props[ARTEFACT_NAME_KEY].get_string() = unrand->name;
@@ -2240,7 +1968,7 @@ bool make_item_unrandart( item_def &item, int unrand_index )
ASSERT(!item.props.exists( ARTEFACT_APPEAR_KEY ));
item.props[ARTEFACT_APPEAR_KEY].get_string() = unrand->unid_name;
- set_unrandart_exist( unrand_index, true );
+ set_unique_item_status(unrand_index, UNIQ_EXISTS);
return (true);
}
@@ -2251,9 +1979,9 @@ const char *unrandart_descrip( int which_descrip, const item_def &item )
// for randarts.
const unrandart_entry *unrand = _seekunrandart( item );
- return ((which_descrip == 0) ? unrand->spec_descrip1 :
- (which_descrip == 1) ? unrand->spec_descrip2 :
- (which_descrip == 2) ? unrand->spec_descrip3
+ return ((which_descrip == 0) ? unrand->desc :
+ (which_descrip == 1) ? unrand->desc_id :
+ (which_descrip == 2) ? unrand->desc_end
: "Unknown.");
}
@@ -2261,15 +1989,14 @@ void artefact_set_properties( item_def &item,
artefact_properties_t &proprt )
{
ASSERT( is_random_artefact( item ) );
- ASSERT( !is_unrandom_artefact ( item ) );
ASSERT( item.props.exists( ARTEFACT_PROPS_KEY ) );
CrawlVector &rap_vec = item.props[ARTEFACT_PROPS_KEY].get_vector();
ASSERT( rap_vec.get_type() == SV_SHORT );
- ASSERT( rap_vec.size() == RA_PROPERTIES);
- ASSERT( rap_vec.get_max_size() == RA_PROPERTIES);
+ ASSERT( rap_vec.size() == ART_PROPERTIES);
+ ASSERT( rap_vec.get_max_size() == ART_PROPERTIES);
- for (vec_size i = 0; i < RA_PROPERTIES; i++)
+ for (vec_size i = 0; i < ART_PROPERTIES; i++)
rap_vec[i].get_short() = proprt[i];
}
@@ -2278,13 +2005,12 @@ void artefact_set_property( item_def &item,
int val )
{
ASSERT( is_random_artefact( item ) );
- ASSERT( !is_unrandom_artefact ( item ) );
ASSERT( item.props.exists( ARTEFACT_PROPS_KEY ) );
CrawlVector &rap_vec = item.props[ARTEFACT_PROPS_KEY].get_vector();
ASSERT( rap_vec.get_type() == SV_SHORT );
- ASSERT( rap_vec.size() == RA_PROPERTIES);
- ASSERT( rap_vec.get_max_size() == RA_PROPERTIES);
+ ASSERT( rap_vec.size() == ART_PROPERTIES);
+ ASSERT( rap_vec.get_max_size() == ART_PROPERTIES);
rap_vec[prop].get_short() = val;
}
diff --git a/crawl-ref/source/artefact.h b/crawl-ref/source/artefact.h
new file mode 100644
index 0000000000..58b5cf55f7
--- /dev/null
+++ b/crawl-ref/source/artefact.h
@@ -0,0 +1,263 @@
+/*
+ * File: artefact.h
+ * Summary: Random and unrandom artefact functions.
+ * Written by: Linley Henzell
+ *
+ * Modified for Crawl Reference by $Author$ on $Date$
+ */
+
+
+#ifndef RANDART_H
+#define RANDART_H
+
+#include "externs.h"
+
+// NOTE: NO_UNRANDARTS is automatically set by util/art-data.pl
+#define NO_UNRANDARTS 76
+
+#define ART_PROPERTIES ARTP_NUM_PROPERTIES
+
+// Reserving the upper bits for later expansion/versioning.
+#define RANDART_SEED_MASK 0x00ffffff
+
+#define SPWPN_SINGING_SWORD UNRAND_SINGING_SWORD
+#define SPWPN_WRATH_OF_TROG UNRAND_TROG
+#define SPWPN_SCYTHE_OF_CURSES UNRAND_CURSES
+#define SPWPN_MACE_OF_VARIABILITY UNRAND_VARIABILITY
+#define SPWPN_GLAIVE_OF_PRUNE UNRAND_PRUNE
+#define SPWPN_SCEPTRE_OF_TORMENT UNRAND_TORMENT
+#define SPWPN_SWORD_OF_ZONGULDROK UNRAND_ZONGULDROK
+#define SPWPN_SWORD_OF_POWER UNRAND_POWER
+#define SPWPN_STAFF_OF_OLGREB UNRAND_OLGREB
+#define SPWPN_VAMPIRES_TOOTH UNRAND_VAMPIRES_TOOTH
+#define SPWPN_STAFF_OF_WUCAD_MU UNRAND_WUCAD_MU
+#define SPWPN_SWORD_OF_CEREBOV UNRAND_CEREBOV
+#define SPWPN_STAFF_OF_DISPATER UNRAND_DISPATER
+#define SPWPN_SCEPTRE_OF_ASMODEUS UNRAND_ASMODEUS
+
+#define SPWPN_START_NOGEN_FIXEDARTS UNRAND_CEREBOV
+#define SPWPN_END_FIXEDARTS UNRAND_ASMODEUS
+
+enum unrand_special_type
+{
+ UNRANDSPEC_EITHER,
+ UNRANDSPEC_NORMAL,
+ UNRANDPSEC_SPECIAL
+};
+
+// NOTE: This enumeration is automatically generated from art-data.txt
+// via util/art-data.pl
+enum unrand_type
+{
+ UNRAND_START = 180,
+ UNRAND_DUMMY1 = UNRAND_START,
+ UNRAND_SINGING_SWORD, // Singing Sword
+ UNRAND_TROG, // Wrath of Trog
+ UNRAND_VARIABILITY, // Mace of Variability
+ UNRAND_PRUNE, // Glaive of Prune
+ UNRAND_POWER, // Sword of Power
+ UNRAND_OLGREB, // Staff of Olgreb
+ UNRAND_WUCAD_MU, // Staff of Wucad Mu
+ UNRAND_VAMPIRES_TOOTH, // Vampire's Tooth
+ UNRAND_CURSES, // Scythe of Curses
+ UNRAND_TORMENT, // Sceptre of Torment
+ UNRAND_ZONGULDROK, // Sword of Zonguldrok
+ UNRAND_CEREBOV, // Sword of Cerebov
+ UNRAND_DISPATER, // Staff of Dispater
+ UNRAND_ASMODEUS, // Sceptre of Asmodeus
+ UNRAND_BLOODBANE, // long sword "Bloodbane"
+ UNRAND_FLAMING_DEATH, // scimitar of Flaming Death
+ UNRAND_BRILLIANCE, // mace of Brilliance
+ UNRAND_LEECH, // demon blade "Leech"
+ UNRAND_CHILLY_DEATH, // dagger of Chilly Death
+ UNRAND_MORG, // dagger "Morg"
+ UNRAND_FINISHER, // scythe "Finisher"
+ UNRAND_PUNK, // sling "Punk"
+ UNRAND_KRISHNA, // bow of Krishna "Sharnga"
+ UNRAND_SKULLCRUSHER, // giant club "Skullcrusher"
+ UNRAND_GUARD, // glaive of the Guard
+ UNRAND_JIHAD, // sword of Jihad
+ UNRAND_HELLFIRE, // crossbow "Hellfire"
+ UNRAND_DOOM_KNIGHT, // sword of the Doom Knight
+ UNRAND_EOS, // "Eos"
+ UNRAND_BOTONO, // spear of the Botono
+ UNRAND_OCTOPUS_KING, // trident of the Octopus King
+ UNRAND_ARGA, // mithril axe "Arga"
+ UNRAND_ELEMENTAL_STAFF, // Elemental Staff
+ UNRAND_SNIPER, // hand crossbow "Sniper"
+ UNRAND_PIERCER, // longbow "Piercer"
+ UNRAND_BLOWGUN_ASSASSIN, // blowgun of the Assassin
+ UNRAND_WYRMBANE, // Wyrmbane
+ UNRAND_SPRIGGANS_KNIFE, // Spriggan's Knife
+ UNRAND_PLUTONIUM_SWORD, // plutonium sword
+ UNRAND_UNDEADHUNTER, // great mace "Undeadhunter"
+ UNRAND_SERPENT_SCOURGE, // whip "Serpent-Scourge"
+ UNRAND_ACCURACY, // knife of Accuracy
+ UNRAND_CRYSTAL_SPEAR, // Lehudib's crystal spear
+ UNRAND_IGNORANCE, // shield of Ignorance
+ UNRAND_AUGMENTATION, // robe of Augmentation
+ UNRAND_THIEF, // cloak of the Thief
+ UNRAND_BULLSEYE, // shield "Bullseye"
+ UNRAND_DYROVEPREVA, // crown of Dyrovepreva
+ UNRAND_MISFORTUNE, // robe of Misfortune
+ UNRAND_FLASH, // cloak of Flash
+ UNRAND_BOOTS_ASSASSIN, // boots of the Assassin
+ UNRAND_LEARS, // Lear's chain mail
+ UNRAND_ZHOR, // skin of Zhor
+ UNRAND_SALAMANDER, // salamander hide armour
+ UNRAND_WAR, // gauntlets of War
+ UNRAND_RESISTANCE, // shield of Resistance
+ UNRAND_FOLLY, // robe of Folly
+ UNRAND_MAXWELL, // Maxwell's patent armour
+ UNRAND_DRAGON, // mask of the Dragon
+ UNRAND_NIGHT, // robe of Night
+ UNRAND_DRAGON_KING, // armour of the Dragon King
+ UNRAND_ALCHEMIST, // hat of the Alchemist
+ UNRAND_FENCERS_GLOVES, // Fencer's gloves
+ UNRAND_STARLIGHT, // cloak of Starlight
+ UNRAND_RATSKIN_CLOAK, // ratskin cloak
+ UNRAND_AIR, // amulet of the Air
+ UNRAND_SHADOWS, // ring of Shadows
+ UNRAND_CEKUGOB, // amulet of Cekugob
+ UNRAND_FOUR_WINDS, // amulet of the Four Winds
+ UNRAND_BLOODLUST, // necklace of Bloodlust
+ UNRAND_SHAOLIN, // ring of Shaolin
+ UNRAND_ROBUSTNESS, // ring of Robustness
+ UNRAND_MAGE, // ring of the Mage
+ UNRAND_SHIELDING, // brooch of Shielding
+ UNRAND_DUMMY2, // DUMMY UNRANDART 2
+ UNRAND_LAST = UNRAND_DUMMY2
+};
+
+// The following unrandart bits were taken from $pellbinder's mon-util
+// code (see mon-util.h & mon-util.cc) and modified (LRH).
+struct unrandart_entry
+{
+ const char *name; // true name of unrandart (max 31 chars)
+ const char *unid_name; // un-id'd name of unrandart (max 31 chars)
+
+ object_class_type base_type; // class of ura
+ int sub_type; // type of ura
+ int plus; // plus of ura
+ int plus2; // plus2 of ura
+ int colour; // colour of ura
+ short prpty[ART_PROPERTIES];
+
+ // special description added to 'v' command output (max 31 chars)
+ const char *desc;
+ // special description added to 'v' command output (max 31 chars)
+ const char *desc_id;
+ // special description added to 'v' command output (max 31 chars)
+ const char *desc_end;
+};
+
+bool is_known_artefact( const item_def &item );
+bool is_artefact( const item_def &item );
+bool is_random_artefact( const item_def &item );
+bool is_unrandom_artefact( const item_def &item );
+bool is_special_unrandom_artefact( const item_def &item );
+
+unique_item_status_type get_unique_item_status(const item_def& item);
+unique_item_status_type get_unique_item_status(int unrand_index);
+void set_unique_item_status(const item_def& item,
+ unique_item_status_type status );
+void set_unique_item_status(int unrand_index,
+ unique_item_status_type status );
+
+/* ***********************************************************************
+ * called from: itemname
+ * *********************************************************************** */
+std::string get_artefact_name( const item_def &item );
+
+/* ***********************************************************************
+ * called from: spl-book
+ * *********************************************************************** */
+void set_artefact_name( item_def &item, const std::string &name );
+void set_artefact_appearance( item_def &item, const std::string &appear );
+
+/* ***********************************************************************
+ * called from: effects
+ * *********************************************************************** */
+std::string artefact_name( const item_def &item, bool appearance = false );
+
+/* ***********************************************************************
+ * called from: describe
+ * *********************************************************************** */
+const char *unrandart_descrip( int which_descrip, const item_def &item );
+
+/* ***********************************************************************
+ * called from: dungeon makeitem
+ * *********************************************************************** */
+int find_okay_unrandart(unsigned char aclass, unsigned char atype = OBJ_RANDOM,
+ unrand_special_type specialness = UNRANDSPEC_EITHER,
+ bool in_abyss = false);
+
+typedef FixedVector< int, ART_PROPERTIES > artefact_properties_t;
+typedef FixedVector< bool, ART_PROPERTIES > artefact_known_props_t;
+
+/* ***********************************************************************
+ * called from: describe - fight - it_use2 - item_use - player
+ * *********************************************************************** */
+void artefact_desc_properties( const item_def &item,
+ artefact_properties_t &proprt,
+ artefact_known_props_t &known,
+ bool force_fake_props = false);
+
+void artefact_wpn_properties( const item_def &item,
+ artefact_properties_t &proprt,
+ artefact_known_props_t &known );
+
+void artefact_wpn_properties( const item_def &item,
+ artefact_properties_t &proprt );
+
+int artefact_wpn_property( const item_def &item, artefact_prop_type prop,
+ bool &known );
+
+int artefact_wpn_property( const item_def &item, artefact_prop_type prop );
+
+int artefact_known_wpn_property( const item_def &item,
+ artefact_prop_type prop );
+
+int artefact_wpn_num_props( const item_def &item );
+int artefact_wpn_num_props( const artefact_properties_t &proprt );
+
+void artefact_wpn_learn_prop( item_def &item, artefact_prop_type prop );
+bool artefact_wpn_known_prop( const item_def &item, artefact_prop_type prop );
+
+/* ***********************************************************************
+ * called from: dungeon
+ * *********************************************************************** */
+bool make_item_blessed_blade( item_def &item );
+bool make_item_randart( item_def &item );
+bool make_item_unrandart( item_def &item, int unrand_index );
+
+/* ***********************************************************************
+ * called from: randart - debug
+ * *********************************************************************** */
+bool randart_is_bad( const item_def &item );
+bool randart_is_bad( const item_def &item, artefact_properties_t &proprt );
+
+/* ***********************************************************************
+ * called from: items
+ * *********************************************************************** */
+int find_unrandart_index(const item_def& artefact);
+
+unrandart_entry* get_unrand_entry(int unrand_index);
+
+unrand_special_type get_unrand_specialness(int unrand_index);
+unrand_special_type get_unrand_specialness(const item_def &item);
+
+/* ***********************************************************************
+ * called from: debug
+ * *********************************************************************** */
+void artefact_set_properties( item_def &item,
+ artefact_properties_t &proprt );
+void artefact_set_property( item_def &item,
+ artefact_prop_type prop,
+ int val );
+
+/* ***********************************************************************
+ * called from: mapdef
+ * *********************************************************************** */
+int get_unrandart_num( const char *name );
+#endif
diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc
index 2ee772b461..e3f62bd2bd 100644
--- a/crawl-ref/source/chardump.cc
+++ b/crawl-ref/source/chardump.cc
@@ -28,6 +28,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "debug.h"
#include "describe.h"
#include "hiscores.h"
@@ -44,7 +45,6 @@ REVISION("$Rev$");
#include "overmap.h"
#include "place.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills2.h"
@@ -671,8 +671,7 @@ static bool _dump_item_origin(const item_def &item, int value)
return (true);
if (fs(IODS_ARTEFACTS)
- && (is_random_artefact(item) || is_fixed_artefact(item))
- && item_ident(item, ISFLAG_KNOW_PROPERTIES))
+ && is_artefact(item) && item_ident(item, ISFLAG_KNOW_PROPERTIES))
{
return (true);
}
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index 6cd4b70183..f0f37d7314 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -14,6 +14,7 @@ REVISION("$Rev$");
#include "clua.h"
#include "abl-show.h"
+#include "artefact.h"
#include "command.h"
#include "chardump.h"
#include "cio.h"
@@ -39,7 +40,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spl-util.h"
@@ -1539,7 +1539,7 @@ static int l_item_artefact(lua_State *ls)
return (0);
lua_pushboolean(ls, item_ident(*item, ISFLAG_KNOW_PROPERTIES)
- && (is_random_artefact(*item) || is_fixed_artefact(*item)));
+ && is_artefact(*item));
return (1);
}
diff --git a/crawl-ref/source/dat/float.des b/crawl-ref/source/dat/float.des
index 1fb1954937..9c5add4bd0 100644
--- a/crawl-ref/source/dat/float.des
+++ b/crawl-ref/source/dat/float.des
@@ -109,7 +109,7 @@ ENDMAP
NAME: old_forge
DEPTH: D:4-12
ORIENT: float
-KITEM: ? = long sword fixed:singing_sword, damaged short sword, \
+KITEM: ? = long sword unrand:singing_sword, damaged short sword, \
damaged long sword, damaged hand axe
KITEM: ! = damaged executioner's axe, damaged short sword, \
damaged long sword, damaged morningstar
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index ebbf6955e5..c6fefc1da4 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -27,6 +27,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "branch.h"
#include "chardump.h"
@@ -67,7 +68,6 @@ REVISION("$Rev$");
#include "place.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
@@ -1465,54 +1465,24 @@ bool get_item_by_name(item_def *item, char* specs,
type_wanted = item->sub_type;
break;
+ // Search for a matching unrandart.
case OBJ_WEAPONS:
- {
- // Try for fixed artefacts matching the name.
- unique_item_status_type exists;
- for (unsigned which = SPWPN_START_FIXEDARTS;
- which <= SPWPN_END_FIXEDARTS; which++)
- {
- exists = get_unique_item_status(OBJ_WEAPONS, which);
- make_item_fixed_artefact(*item, false, which);
- strcpy(obj_name, item->name(DESC_PLAIN).c_str());
-
- ptr = strstr( strlwr(obj_name), specs );
- if (ptr != NULL)
- {
- if (create_for_real)
- mpr(obj_name);
- return(true);
- }
- else
- {
- set_unique_item_status(OBJ_WEAPONS, which, exists);
- do_uncurse_item(*item);
- item->props.clear();
- }
- }
- }
- // intentional fall-through for the unrandarts
case OBJ_ARMOUR:
case OBJ_JEWELLERY:
{
- bool exists;
for (int unrand = 0; unrand < NO_UNRANDARTS; unrand++)
{
- exists = does_unrandart_exist( unrand );
- make_item_unrandart(*item, unrand);
- strcpy(obj_name, item->name(DESC_PLAIN).c_str());
+ int index = unrand + UNRAND_START;
+ unrandart_entry* entry = get_unrand_entry(index);
- ptr = strstr( strlwr(obj_name), specs );
+ ptr = strcasestr( entry->name, specs );
if (ptr != NULL && item->base_type == class_wanted)
{
if (create_for_real)
- mpr(obj_name);
+ mpr(entry->name);
+ make_item_unrandart(*item, index);
return(true);
}
-
- set_unrandart_exist(unrand, exists);
- do_uncurse_item(*item);
- item->props.clear();
}
// Reset base type to class_wanted, if nothing found.
@@ -1810,7 +1780,7 @@ static void _tweak_randart(item_def &item)
mprf(MSGCH_PROMPT, "Toggling %s to %s.", _prop_name[choice],
props[choice] ? "off" : "on");
artefact_set_property(item, static_cast<artefact_prop_type>(choice),
- !props[choice]);
+ !props[choice]);
break;
case ARTP_VAL_POS:
@@ -1824,13 +1794,13 @@ static void _tweak_randart(item_def &item)
return;
}
artefact_set_property(item, static_cast<artefact_prop_type>(choice),
- val);
+ val);
break;
case ARTP_VAL_ANY:
mprf(MSGCH_PROMPT, "%s was %d.", _prop_name[choice], props[choice]);
val = _debug_prompt_for_int("New value? ", false);
artefact_set_property(item, static_cast<artefact_prop_type>(choice),
- val);
+ val);
break;
}
}
@@ -1979,15 +1949,22 @@ void wizard_value_artefact()
void wizard_create_all_artefacts()
{
- // Create all unrandarts. Start at 1; the unrandart at 0 is a dummy.
- for (int i = 1; i < NO_UNRANDARTS; ++i)
+ // Create all unrandarts.
+ for (int i = 0; i < NO_UNRANDARTS; ++i)
{
+ const int index = i + UNRAND_START;
+ const unrandart_entry* entry = get_unrand_entry(index);
+
+ // Skip dummy entries.
+ if (entry->base_type == OBJ_UNASSIGNED)
+ continue;
+
int islot = get_item_slot();
if (islot == NON_ITEM)
break;
item_def& item = mitm[islot];
- make_item_unrandart(item, i);
+ make_item_unrandart(item, index);
item.quantity = 1;
set_ident_flags(item, ISFLAG_IDENT_MASK);
@@ -1996,27 +1973,6 @@ void wizard_create_all_artefacts()
move_item_to_grid(&islot, you.pos());
}
- // Create all fixed artefacts.
- for (int i = SPWPN_START_FIXEDARTS; i < SPWPN_START_NOGEN_FIXEDARTS; ++i)
- {
- int islot = get_item_slot();
- if (islot == NON_ITEM)
- break;
-
- item_def& item = mitm[islot];
- if (make_item_fixed_artefact(item, false, i))
- {
- item.quantity = 1;
- item_colour(item);
- set_ident_flags(item, ISFLAG_IDENT_MASK);
- move_item_to_grid( &islot, you.pos() );
-
- msg::streams(MSGCH_DIAGNOSTICS) << "Made "
- << item.name(DESC_NOCAP_A)
- << std::endl;
- }
- }
-
// Create Horn of Geryon
int islot = get_item_slot();
if (islot != NON_ITEM)
@@ -2884,19 +2840,18 @@ void debug_item_scan( void )
else if ((mitm[i].base_type == OBJ_WEAPONS
&& (abs(mitm[i].plus) > 30
|| abs(mitm[i].plus2) > 30
- || !is_random_artefact( mitm[i] )
- && mitm[i].special >= 30
- && mitm[i].special < 181))
+ || !is_artefact( mitm[i] )
+ && mitm[i].special >= NUM_SPECIAL_WEAPONS))
|| (mitm[i].base_type == OBJ_MISSILES
&& (abs(mitm[i].plus) > 25
- || !is_random_artefact( mitm[i] )
- && mitm[i].special >= 30))
+ || !is_artefact( mitm[i] )
+ && mitm[i].special >= NUM_SPECIAL_MISSILES))
|| (mitm[i].base_type == OBJ_ARMOUR
&& (abs(mitm[i].plus) > 25
- || !is_random_artefact( mitm[i] )
- && mitm[i].special >= 30)))
+ || !is_artefact( mitm[i] )
+ && mitm[i].special >= NUM_SPECIAL_ARMOURS)))
{
mpr("Bad plus or special value:", MSGCH_ERROR);
_dump_item( name, i, mitm[i] );
@@ -5106,7 +5061,6 @@ static void _vanish_orig_eq(monsters* mons)
if (item.orig_place != 0 || item.orig_monnum != 0
|| !item.inscription.empty()
|| is_unrandom_artefact(item)
- || is_fixed_artefact(item)
|| (item.flags & (ISFLAG_DROPPED | ISFLAG_THROWN | ISFLAG_NOTED_GET
| ISFLAG_BEEN_IN_INV) ) )
{
diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h
index 435041cddd..0cff5e5a67 100644
--- a/crawl-ref/source/defines.h
+++ b/crawl-ref/source/defines.h
@@ -168,6 +168,9 @@ const int MAX_WPN_ENCHANT = 9;
const int MAX_ARM_ENCHANT = 8;
const int MAX_SEC_ENCHANT = 2;
+// Size of unique_items in player class
+#define MAX_UNRANDARTS 100
+
// some shortcuts:
#define menv env.mons
#define mitm env.item
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index eb1cab8575..78270aee29 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -14,6 +14,7 @@ REVISION("$Rev$");
#include <string.h>
#include "abl-show.h"
+#include "artefact.h"
#include "clua.h"
#include "command.h"
#include "database.h"
@@ -36,7 +37,6 @@ REVISION("$Rev$");
#include "ouch.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "spells4.h"
#include "spl-util.h"
@@ -1425,7 +1425,7 @@ void armour_wear_effects(const int item_slot)
const bool was_known = item_type_known(arm);
set_ident_flags(arm, ISFLAG_EQ_ARMOUR_MASK);
- if (is_random_artefact(arm))
+ if (is_artefact(arm))
arm.flags |= ISFLAG_NOTED_ID;
const equipment_type eq_slot = get_armour_slot(arm);
@@ -1434,7 +1434,7 @@ void armour_wear_effects(const int item_slot)
if (!was_known)
{
- if (Options.autoinscribe_artefacts && is_random_artefact(arm))
+ if (Options.autoinscribe_artefacts && is_artefact(arm))
add_autoinscription( arm, artefact_auto_inscription(arm));
}
if (!melded)
@@ -1564,7 +1564,7 @@ void armour_wear_effects(const int item_slot)
}
}
- if (is_random_artefact(arm))
+ if (is_artefact(arm))
use_artefact(arm, melded);
if (item_cursed(arm) && !melded)
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index e23487848f..be626b3c53 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abl-show.h"
+#include "artefact.h"
#include "cio.h"
#include "debug.h"
#include "decks.h"
@@ -43,7 +44,6 @@ REVISION("$Rev$");
#include "mon-util.h"
#include "newgame.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spells3.h"
@@ -472,13 +472,20 @@ static std::string _randart_descrip( const item_def &item )
if (is_unrandom_artefact( item ))
{
- const char *desc = unrandart_descrip( 0, item );
- if (desc[0] != 0)
+ const char *desc = unrandart_descrip( 0, item );
+ const char *desc_id = unrandart_descrip( 1, item );
+
+ if (item_type_known(item) && desc_id[0] != '\0')
+ {
+ description += "$$";
+ description += desc_id;
+ }
+ else if (desc[0] != '\0')
{
description += "$$";
description += desc;
}
- }
+ }
return description;
}
@@ -723,238 +730,152 @@ static std::string _describe_weapon(const item_def &item, bool verbose)
description = "";
- if (is_fixed_artefact( item ))
+ if (verbose)
+ append_weapon_stats(description, item);
+
+ int spec_ench = get_weapon_brand( item );
+
+ if (!is_random_artefact( item ) && !verbose)
+ spec_ench = SPWPN_NORMAL;
+
+ // special weapon descrip
+ if (spec_ench != SPWPN_NORMAL && item_type_known(item))
{
- if (item_ident( item, ISFLAG_KNOW_PROPERTIES ) && item.special)
+ description += "$$";
+
+ switch (spec_ench)
{
- description += "$$";
- switch (item.special)
+ case SPWPN_FLAMING:
+ description += "It emits flame when wielded, "
+ "causing extra injury to most foes "
+ "and up to double damage against "
+ "particularly susceptible opponents.";
+ break;
+ case SPWPN_FREEZING:
+ description += "It has been specially enchanted to "
+ "freeze those struck by it, causing "
+ "extra injury to most foes and "
+ "up to double damage against "
+ "particularly susceptible opponents.";
+ break;
+ case SPWPN_HOLY_WRATH:
+ description += "It has been blessed by the Shining One "
+ "to cause great damage to the undead and the unholy "
+ "creatures of Hell or Pandemonium.";
+ break;
+ case SPWPN_ELECTROCUTION:
+ description += "Occasionally upon striking a foe "
+ "it will discharge some electrical energy "
+ "and cause terrible harm.";
+ break;
+ case SPWPN_ORC_SLAYING:
+ description += "It is especially effective against "
+ "all of orcish descent.";
+ break;
+ case SPWPN_DRAGON_SLAYING:
+ description += "This legendary weapon is deadly to all "
+ "dragonkind. It also provides some protection from the "
+ "breath attacks of dragons and other creatures.";
+ break;
+ case SPWPN_VENOM:
+ if (is_range_weapon(item))
+ description += "It poisons the unbranded ammo it fires.";
+ else
+ description += "It poisons the flesh of those it strikes.";
+ break;
+ case SPWPN_PROTECTION:
+ description += "It protects the one who wields it against "
+ "injury (+5 to AC).";
+ break;
+ case SPWPN_DRAINING:
+ description += "A truly terrible weapon, "
+ "it drains the life of those it strikes.";
+ break;
+ case SPWPN_SPEED:
+ description += "Attacks with this weapon take half as long "
+ "as usual.";
+ break;
+ case SPWPN_VORPAL:
+ if (is_range_weapon(item))
{
- case SPWPN_SINGING_SWORD:
- description += "This blessed weapon loves nothing more "
- "than to sing to its owner, "
- "whether they want it to or not.";
- break;
- case SPWPN_WRATH_OF_TROG:
- description += "This was the favourite weapon of "
- "the old god Trog, before it was lost one day. "
- "It induces a bloodthirsty berserker rage in "
- "anyone who uses it to strike another.";
- break;
- case SPWPN_SCYTHE_OF_CURSES:
- description += "This weapon carries a "
- "terrible and highly irritating curse.";
- break;
- case SPWPN_MACE_OF_VARIABILITY:
- description += "It is rather unreliable.";
- break;
- case SPWPN_GLAIVE_OF_PRUNE:
- description += "It is the creation of a mad god, and "
- "carries a curse which transforms anyone "
- "possessing it into a prune. Fortunately, "
- "the curse works very slowly, and one can "
- "use it briefly with no consequences "
- "worse than slightly purple skin and a few wrinkles.";
- break;
- case SPWPN_SCEPTRE_OF_TORMENT:
- description += "This truly accursed weapon is "
- "an instrument of Hell.";
- break;
- case SPWPN_SWORD_OF_ZONGULDROK:
- description += "This dreadful weapon is used "
- "at the user's peril.";
- break;
- case SPWPN_SWORD_OF_CEREBOV:
- description += "Eerie flames cover its twisted blade.";
- break;
- case SPWPN_STAFF_OF_DISPATER:
- description += "This legendary item can unleash "
- "the fury of Hell.";
- break;
- case SPWPN_SCEPTRE_OF_ASMODEUS:
- description += "It carries some of the powers of "
- "the arch-fiend Asmodeus.";
- break;
- case SPWPN_SWORD_OF_POWER:
- description += "It rewards the powerful with power "
- "and the meek with weakness.";
- break;
- case SPWPN_STAFF_OF_OLGREB:
- description += "It was the magical weapon wielded by the "
- "mighty wizard Olgreb before he met his "
- "fate somewhere within these dungeons. It "
- "grants its wielder resistance to the "
- "effects of poison and increases their "
- "ability to use venomous magic, and "
- "carries magical powers which can be evoked.";
- break;
- case SPWPN_VAMPIRES_TOOTH:
- description += "It is lethally vampiric.";
- break;
- case SPWPN_STAFF_OF_WUCAD_MU:
- description += "Its power varies in proportion to "
- "its wielder's intelligence. "
- "Using it can be a bit risky.";
- break;
+ description += "Any ";
+ description += ammo_name( item );
+ description += " fired from it inflicts extra damage.";
}
- description += "$";
- }
- else if (item_type_known(item))
- {
- // We know it's an artefact type weapon, but not what it does.
- description += "$This weapon may have some hidden properties.";
+ else
+ {
+ description += "It inflicts extra damage upon "
+ "your enemies.";
+ }
+ break;
+ case SPWPN_FLAME:
+ description += "It turns projectiles fired from it into "
+ "bolts of flame.";
+ break;
+ case SPWPN_FROST:
+ description += "It turns projectiles fired from it into "
+ "bolts of frost.";
+ break;
+ case SPWPN_CHAOS:
+ if (is_range_weapon(item))
+ {
+ description += "Each time it fires it turns the launched "
+ "projectile into a different, random type of bolt.";
+ }
+ else
+ {
+ description += "Each time it hits an enemy it has a "
+ "different, random effect.";
+ }
+ break;
+ case SPWPN_VAMPIRICISM:
+ description += "It inflicts no extra harm, "
+ "but heals its wielder somewhat when "
+ "it strikes a living foe.";
+ break;
+ case SPWPN_PAIN:
+ description += "In the hands of one skilled in "
+ "necromantic magic it inflicts "
+ "extra damage on living creatures.";
+ break;
+ case SPWPN_DISTORTION:
+ description += "It warps and distorts space around it. "
+ "Unwielding it can cause banishment or high damage.";
+ break;
+ case SPWPN_REACHING:
+ description += "It can be evoked to extend its reach.";
+ break;
+ case SPWPN_RETURNING:
+ description += "A skilled user can throw it in such a way "
+ "that it will return to its owner.";
+ break;
+ case SPWPN_PENETRATION:
+ description += "Ammo fired by it will pass through the "
+ "targets it hits, potentially hitting all targets in "
+ "its path until it reaches maximum range.";
+ break;
+ case SPWPN_SHADOW:
+ description += "If ammo fired by it kills a monster, "
+ "causing it to leave a corpse, the corpse will be "
+ "animated as a zombie friendly to the one who fired it.";
+ break;
}
}
- if (verbose)
- append_weapon_stats(description, item);
-
- if (!is_fixed_artefact( item ))
+ if (is_artefact( item ))
{
- int spec_ench = get_weapon_brand( item );
-
- if (!is_random_artefact( item ) && !verbose)
- spec_ench = SPWPN_NORMAL;
-
- // special weapon descrip
- if (spec_ench != SPWPN_NORMAL && item_type_known(item))
+ std::string rand_desc = _randart_descrip( item );
+ if (!rand_desc.empty())
{
description += "$$";
-
- switch (spec_ench)
- {
- case SPWPN_FLAMING:
- description += "It emits flame when wielded, "
- "causing extra injury to most foes "
- "and up to double damage against "
- "particularly susceptible opponents.";
- break;
- case SPWPN_FREEZING:
- description += "It has been specially enchanted to "
- "freeze those struck by it, causing "
- "extra injury to most foes and "
- "up to double damage against "
- "particularly susceptible opponents.";
- break;
- case SPWPN_HOLY_WRATH:
- description += "It has been blessed by the Shining One "
- "to cause great damage to the undead and the unholy "
- "creatures of Hell or Pandemonium.";
- break;
- case SPWPN_ELECTROCUTION:
- description += "Occasionally upon striking a foe "
- "it will discharge some electrical energy "
- "and cause terrible harm.";
- break;
- case SPWPN_ORC_SLAYING:
- description += "It is especially effective against "
- "all of orcish descent.";
- break;
- case SPWPN_DRAGON_SLAYING:
- description += "This legendary weapon is deadly to all "
- "dragonkind. It also provides some protection from the "
- "breath attacks of dragons and other creatures.";
- break;
- case SPWPN_VENOM:
- if (is_range_weapon(item))
- description += "It poisons the unbranded ammo it fires.";
- else
- description += "It poisons the flesh of those it strikes.";
- break;
- case SPWPN_PROTECTION:
- description += "It protects the one who wields it against "
- "injury (+5 to AC).";
- break;
- case SPWPN_DRAINING:
- description += "A truly terrible weapon, "
- "it drains the life of those it strikes.";
- break;
- case SPWPN_SPEED:
- description += "Attacks with this weapon take half as long "
- "as usual.";
- break;
- case SPWPN_VORPAL:
- if (is_range_weapon(item))
- {
- description += "Any ";
- description += ammo_name( item );
- description += " fired from it inflicts extra damage.";
- }
- else
- {
- description += "It inflicts extra damage upon "
- "your enemies.";
- }
- break;
- case SPWPN_FLAME:
- description += "It turns projectiles fired from it into "
- "bolts of flame.";
- break;
- case SPWPN_FROST:
- description += "It turns projectiles fired from it into "
- "bolts of frost.";
- break;
- case SPWPN_CHAOS:
- if (is_range_weapon(item))
- {
- description += "Each time it fires it turns the launched "
- "projectile into a different, random type of bolt.";
- }
- else
- {
- description += "Each time it hits an enemy it has a "
- "different, random effect.";
- }
- break;
- case SPWPN_VAMPIRICISM:
- description += "It inflicts no extra harm, "
- "but heals its wielder somewhat when "
- "it strikes a living foe.";
- break;
- case SPWPN_PAIN:
- description += "In the hands of one skilled in "
- "necromantic magic it inflicts "
- "extra damage on living creatures.";
- break;
- case SPWPN_DISTORTION:
- description += "It warps and distorts space around it. "
- "Unwielding it can cause banishment or high damage.";
- break;
- case SPWPN_REACHING:
- description += "It can be evoked to extend its reach.";
- break;
- case SPWPN_RETURNING:
- description += "A skilled user can throw it in such a way "
- "that it will return to its owner.";
- break;
- case SPWPN_PENETRATION:
- description += "Ammo fired by it will pass through the "
- "targets it hits, potentially hitting all targets in "
- "its path until it reaches maximum range.";
- break;
- case SPWPN_SHADOW:
- description += "If ammo fired by it kills a monster, "
- "causing it to leave a corpse, the corpse will be "
- "animated as a zombie friendly to the one who fired it.";
- break;
- }
+ description += rand_desc;
}
- if (is_random_artefact( item ))
+ // Can't happen, right? (XXX)
+ if (!item_ident(item, ISFLAG_KNOW_PROPERTIES)
+ && item_type_known(item))
{
- std::string rand_desc = _randart_descrip( item );
- if (!rand_desc.empty())
- {
- description += "$$";
- description += rand_desc;
- }
-
- // Can't happen, right? (XXX)
- if (!item_ident(item, ISFLAG_KNOW_PROPERTIES)
- && item_type_known(item))
- {
- description += "$This weapon may have some hidden properties.";
- }
+ description += "$This weapon may have some hidden properties.";
}
}
@@ -1749,27 +1670,16 @@ std::string get_item_description( const item_def &item, bool verbose,
#endif
if (is_unrandom_artefact( item )
- && strlen(unrandart_descrip(1, item)) != 0)
+ && strlen(unrandart_descrip(2, item)) != 0)
{
description << "$$";
- description << unrandart_descrip(1, item);
+ description << unrandart_descrip(2, item);
description << "$";
}
- if (is_fixed_artefact(item) && item_type_known(item))
- {
- // Known fixed artifacts are handled elsewhere.
- }
- else if (verbose && is_fixed_artefact(item))
- {
- description << "$$";
- description << article_a(item.name(DESC_CAP_A, true,
- false, false), false);
- description << ".$";
- }
- else if (verbose || (item.base_type != OBJ_WEAPONS
- && item.base_type != OBJ_ARMOUR
- && item.base_type != OBJ_BOOKS))
+ if (verbose || (item.base_type != OBJ_WEAPONS
+ && item.base_type != OBJ_ARMOUR
+ && item.base_type != OBJ_BOOKS))
{
description << "$$";
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 989d0be217..42a5abf993 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -18,6 +18,7 @@ REVISION("$Rev$");
#include <algorithm>
#include "abyss.h"
+#include "artefact.h"
#include "branch.h"
#include "chardump.h"
#include "cloud.h"
@@ -44,7 +45,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "place.h"
#include "player.h"
-#include "randart.h"
#include "spells3.h"
#include "spl-book.h"
#include "state.h"
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index fa5515efa4..dc0e4f3f20 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -18,6 +18,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "decks.h"
@@ -44,7 +45,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "ouch.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
@@ -1646,7 +1646,7 @@ bool acquirement(object_class_type class_wanted, int agent,
{
int brand = get_weapon_brand(doodad);
if (brand == SPWPN_PAIN
- || is_fixed_artefact(doodad)
+ || is_unrandom_artefact(doodad)
&& (doodad.special == SPWPN_WRATH_OF_TROG
|| doodad.special == SPWPN_STAFF_OF_WUCAD_MU))
{
@@ -1659,7 +1659,7 @@ bool acquirement(object_class_type class_wanted, int agent,
// MT - Check: god-gifted weapons and armour shouldn't kill you.
// Except Xom.
if ((agent == GOD_TROG || agent == GOD_OKAWARU)
- && is_random_artefact(doodad))
+ && is_artefact(doodad))
{
artefact_properties_t proprt;
artefact_wpn_properties( doodad, proprt );
@@ -1758,7 +1758,6 @@ bool acquirement(object_class_type class_wanted, int agent,
}
}
else if (thing.base_type == OBJ_WEAPONS
- && !is_fixed_artefact(thing)
&& !is_unrandom_artefact(thing))
{
// HACK: Make unwieldable weapons wieldable.
@@ -1773,11 +1772,7 @@ bool acquirement(object_class_type class_wanted, int agent,
int brand = get_weapon_brand(thing);
if (brand == SPWPN_HOLY_WRATH)
{
- if (!is_random_artefact(thing))
- {
- set_item_ego_type(thing, OBJ_WEAPONS, SPWPN_VORPAL);
- }
- else
+ if (is_random_artefact(thing))
{
// Keep resetting seed until it's good.
for (; brand == SPWPN_HOLY_WRATH;
@@ -1786,6 +1781,10 @@ bool acquirement(object_class_type class_wanted, int agent,
make_item_randart(thing);
}
}
+ else
+ {
+ set_item_ego_type(thing, OBJ_WEAPONS, SPWPN_VORPAL);
+ }
}
}
break;
@@ -1833,7 +1832,7 @@ bool acquirement(object_class_type class_wanted, int agent,
// More damage, less accuracy.
thing.plus -= plusmod;
thing.plus2 += plusmod;
- if (!is_random_artefact(thing))
+ if (!is_artefact(thing))
thing.plus = std::max(static_cast<int>(thing.plus), 0);
}
else if (agent == GOD_OKAWARU)
@@ -1841,26 +1840,14 @@ bool acquirement(object_class_type class_wanted, int agent,
// More accuracy, less damage.
thing.plus += plusmod;
thing.plus2 -= plusmod;
- if (!is_random_artefact(thing))
+ if (!is_artefact(thing))
thing.plus2 = std::max(static_cast<int>(thing.plus2), 0);
}
}
if (agent > GOD_NO_GOD && agent < NUM_GODS && agent == you.religion)
- {
thing.inscription = "god gift";
- if (is_random_artefact(thing))
- {
- if (!is_unrandom_artefact(thing)
- && thing.base_type != OBJ_BOOKS)
- {
- // Give another name that takes god gift into account;
- // artefact books already do that.
- thing.props["artefact_name"].get_string() =
- artefact_name(thing, false);
- }
- }
- }
+
move_item_to_grid( &thing_created, you.pos() );
// This should never actually be NON_ITEM because of the way
@@ -3437,7 +3424,7 @@ void handle_time(long time_delta)
// Exercise stealth skill:
else if (you.burden_state == BS_UNENCUMBERED
&& !you.duration[DUR_BERSERKER]
- && you.special_wield != SPWLD_SHADOW)
+ && you.unrand_reacts != SPWLD_SHADOW)
{
// Diminishing returns for stealth training by waiting.
if ((you.equip[EQ_BODY_ARMOUR] == -1
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 8ba862b72b..42cb62cc1f 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -167,6 +167,8 @@ enum attribute_type
ATTR_MISC_SPENDING, // Spending for things like ziggurats.
ATTR_RND_LVL_BOOKS, // Bitfield of level-type randart spellbooks
// player has seen.
+ ATTR_NOISES, // A noisy artefact is equipped.
+ ATTR_SHADOWS, // Lantern of shadows effect.
NUM_ATTRIBUTES
};
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index c479cc7396..068ceb0291 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -755,7 +755,7 @@ public:
runrest running; // Nonzero if running/traveling.
- char special_wield;
+ unsigned short unrand_reacts;
double elapsed_time; // total amount of elapsed time in the game
@@ -863,7 +863,7 @@ public:
int exp_available;
FixedArray<unsigned char, 6, 50> item_description;
- FixedVector<unique_item_status_type, 50> unique_items;
+ FixedVector<unique_item_status_type, MAX_UNRANDARTS> unique_items;
FixedVector<bool, NUM_MONSTERS> unique_creatures;
// NOTE: The kills member is a pointer to a KillMaster object,
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 838dbc1465..2af9d86542 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -22,6 +22,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "database.h"
@@ -46,7 +47,6 @@ REVISION("$Rev$");
#include "mutation.h"
#include "ouch.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "spells1.h"
@@ -1883,7 +1883,7 @@ void melee_attack::player_check_weapon_effects()
did_god_conduct(DID_UNHOLY, 1);
}
- if (is_fixed_artefact(*weapon))
+ if (is_unrandom_artefact(*weapon))
{
switch (weapon->special)
{
@@ -2245,7 +2245,7 @@ bool melee_attack::distortion_affects_defender()
if (defender->atype() == ACT_PLAYER && attacker_visible
&& weapon != NULL && !is_unrandom_artefact(*weapon)
- && !is_fixed_artefact(*weapon))
+ && !is_special_unrandom_artefact(*weapon))
{
// If the player is being sent to the Abyss by being attacked
// with a distortion weapon, then we have to ID it before
@@ -3191,7 +3191,7 @@ bool melee_attack::apply_damage_brand()
int hp_boost = 0;
// Thus is probably more valuable on larger weapons?
- if (weapon && is_fixed_artefact(*weapon)
+ if (weapon && is_unrandom_artefact(*weapon)
&& weapon->special == SPWPN_VAMPIRES_TOOTH)
{
hp_boost = damage_done;
@@ -3285,10 +3285,9 @@ bool melee_attack::apply_damage_brand()
if (!obvious_effect)
obvious_effect = !special_damage_message.empty();
- if (obvious_effect && attacker_visible && weapon != NULL
- && !is_unrandom_artefact(*weapon) && !is_fixed_artefact(*weapon))
+ if (obvious_effect && attacker_visible && weapon != NULL)
{
- if (is_random_artefact(*weapon))
+ if (is_artefact(*weapon))
artefact_wpn_learn_prop(*weapon, ARTP_BRAND);
else
set_ident_flags(*weapon, ISFLAG_KNOW_TYPE);
diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h
index 856be31b18..10322818eb 100644
--- a/crawl-ref/source/fight.h
+++ b/crawl-ref/source/fight.h
@@ -12,7 +12,7 @@
#include "externs.h"
-#include "randart.h"
+#include "artefact.h"
#include "mon-util.h"
enum unarmed_attack_type
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 8c77d28f48..506530b621 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -43,6 +43,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "chardump.h"
#include "cloud.h"
#include "clua.h"
@@ -69,7 +70,6 @@ REVISION("$Rev$");
#include "overmap.h"
#include "place.h"
#include "player.h"
-#include "randart.h"
#include "skills2.h"
#include "stash.h"
#include "state.h"
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 543eabffc5..f756cfbe70 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -23,6 +23,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "cio.h"
#include "clua.h"
#include "command.h"
@@ -42,7 +43,6 @@ REVISION("$Rev$");
#include "mutation.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spells2.h"
@@ -231,7 +231,7 @@ static bool _find_butchering_implement(int &butcher_tool)
&& can_wield( &tool )
// Don't even suggest autocursing items.
// Note that unknown autocursing is OK.
- && (!is_random_artefact(tool)
+ && (!is_artefact(tool)
|| (artefact_known_wpn_property(tool, ARTP_CURSED) <= 0)))
{
if (Options.easy_butcher
diff --git a/crawl-ref/source/ghost.cc b/crawl-ref/source/ghost.cc
index 31f9f96fca..a214ec67cc 100644
--- a/crawl-ref/source/ghost.cc
+++ b/crawl-ref/source/ghost.cc
@@ -13,11 +13,11 @@ REVISION("$Rev$");
#include "ghost.h"
+#include "artefact.h"
#include "externs.h"
#include "itemname.h"
#include "itemprop.h"
#include "newgame.h"
-#include "randart.h"
#include "skills2.h"
#include "stuff.h"
#include "mtransit.h"
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index 091322ac5f..c271abc2aa 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -23,6 +23,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "clua.h"
#include "decks.h"
#include "describe.h"
@@ -39,7 +40,6 @@ REVISION("$Rev$");
#include "view.h"
#include "menu.h"
#include "mon-util.h"
-#include "randart.h"
#include "state.h"
#include "tiles.h"
@@ -1754,7 +1754,7 @@ bool item_is_evokable(const item_def &item, bool known, bool all_wands,
return (true);
}
- if (is_fixed_artefact(item))
+ if (is_unrandom_artefact(item))
{
switch (item.special)
{
diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc
index 30c7db0c0e..44a56efb8d 100644
--- a/crawl-ref/source/it_use2.cc
+++ b/crawl-ref/source/it_use2.cc
@@ -16,6 +16,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "effects.h"
#include "food.h"
@@ -26,7 +27,6 @@ REVISION("$Rev$");
#include "mutation.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spells2.h"
@@ -407,7 +407,7 @@ bool unwield_item(bool showMsgs)
return (false);
you.equip[EQ_WEAPON] = -1;
- you.special_wield = SPWLD_NONE;
+ you.unrand_reacts = SPWLD_NONE;
you.wield_change = true;
you.m_quiver->on_weapon_changed();
@@ -419,7 +419,7 @@ bool unwield_item(bool showMsgs)
}
else if (item.base_type == OBJ_WEAPONS)
{
- if (is_fixed_artefact( item ))
+ if (is_unrandom_artefact( item ))
{
switch (item.special)
{
@@ -670,5 +670,5 @@ void unuse_artefact(const item_def &item)
true);
if (proprt[ARTP_NOISES] != 0)
- you.special_wield = SPWLD_NONE;
+ you.unrand_reacts = SPWLD_NONE;
}
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 58f583824a..fb978d7583 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -17,6 +17,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "database.h"
@@ -38,7 +39,6 @@ REVISION("$Rev$");
#include "monstuff.h"
#include "overmap.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
@@ -61,7 +61,7 @@ void special_wielded()
const int old_plus2 = weapon.plus2;
const char old_colour = weapon.colour;
- switch (you.special_wield)
+ switch (you.unrand_reacts)
{
case SPWLD_SING:
case SPWLD_NOISE:
@@ -70,7 +70,7 @@ void special_wielded()
{
std::string msg;
- if (you.special_wield == SPWLD_SING)
+ if (you.unrand_reacts == SPWLD_SING)
{
msg = getSpeakString("Singing Sword");
if (!msg.empty())
@@ -130,7 +130,7 @@ void special_wielded()
if (msg.empty()) // give default noises
{
- if (you.special_wield == SPWLD_SING)
+ if (you.unrand_reacts == SPWLD_SING)
msg = "@The_weapon@ sings.";
else
{
@@ -849,7 +849,7 @@ bool evoke_item(int slot)
else
return (false);
}
- else if (is_fixed_artefact(item))
+ else if (is_unrandom_artefact(item))
{
switch (item.special)
{
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index f81196f13d..1efb978e9b 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -19,6 +19,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abl-show.h"
+#include "artefact.h"
#include "beam.h"
#include "cio.h"
#include "cloud.h"
@@ -48,7 +49,6 @@ REVISION("$Rev$");
#include "ouch.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills.h"
@@ -506,7 +506,7 @@ void wield_effects(int item_wield_2, bool showMsgs)
you.current_vision -= 2;
setLOSRadius(you.current_vision);
- you.special_wield = SPWLD_SHADOW;
+ you.unrand_reacts = SPWLD_SHADOW;
}
else if (item.sub_type == MISC_HORN_OF_GERYON)
set_ident_flags(item, ISFLAG_IDENT_MASK);
@@ -759,8 +759,8 @@ void wield_effects(int item_wield_2, bool showMsgs)
default:
break;
}
- if (is_fixed_artefact(item))
- you.special_wield = item_special_wield_effect(item);
+ if (is_unrandom_artefact(item))
+ you.unrand_reacts = item_special_wield_effect(item);
}
if (item_cursed(item))
@@ -5360,7 +5360,7 @@ void use_artefact(item_def &item, bool unmeld)
}
if (proprt[ARTP_NOISES])
- you.special_wield = SPWLD_NOISE;
+ you.unrand_reacts = SPWLD_NOISE;
if (!alreadyknown && Options.autoinscribe_artefacts)
add_autoinscription(item, artefact_auto_inscription(item));
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 88186883c4..e7015ed3ba 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -23,6 +23,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "decks.h"
#include "describe.h"
#include "food.h"
@@ -38,7 +39,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spl-book.h"
@@ -1263,7 +1263,7 @@ std::string item_def::name_aux(description_level_type desc,
buff << item_base_name(*this);
- if (know_ego)
+ if (know_ego && !is_artefact(*this))
{
const special_armour_type sparm = get_armour_ego_type( *this );
@@ -2238,13 +2238,8 @@ static char retlet( int sed )
bool is_interesting_item( const item_def& item )
{
- if (fully_identified(item)
- && (is_random_artefact(item)
- || is_unrandom_artefact(item)
- || is_fixed_artefact(item)))
- {
+ if (fully_identified(item) && is_artefact(item))
return (true);
- }
const std::string iname = menu_colour_item_prefix(item, false) + " "
+ item.name(DESC_PLAIN);
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 7c54b7fd4c..6694a063f5 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -22,6 +22,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "decks.h"
#include "food.h"
#include "invent.h"
@@ -34,7 +35,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "skills2.h"
#include "stuff.h"
#include "transfor.h"
@@ -880,9 +880,7 @@ void set_helmet_random_desc( item_def &item )
//
bool set_item_ego_type( item_def &item, int item_type, int ego_type )
{
- if (item.base_type == item_type
- && !is_random_artefact( item )
- && !is_fixed_artefact( item ))
+ if (item.base_type == item_type && !is_artefact(item))
{
item.special = ego_type;
return (true);
@@ -899,27 +897,8 @@ int get_weapon_brand( const item_def &item )
if (item.base_type != OBJ_WEAPONS)
return (SPWPN_NORMAL);
- if (is_fixed_artefact( item ))
- {
- switch (item.special)
- {
- case SPWPN_SWORD_OF_CEREBOV:
- return (SPWPN_FLAMING);
-
- case SPWPN_STAFF_OF_OLGREB:
- return (SPWPN_VENOM);
-
- case SPWPN_VAMPIRES_TOOTH:
- return (SPWPN_VAMPIRICISM);
-
- default:
- return (SPWPN_NORMAL);
- }
- }
- else if (is_random_artefact( item ))
- {
+ if (is_artefact( item ))
return (artefact_wpn_property( item, ARTP_BRAND ));
- }
return (item.special);
}
@@ -1115,6 +1094,11 @@ bool jewellery_is_amulet( const item_def &item )
return (item.sub_type >= AMU_RAGE);
}
+bool jewellery_is_amulet( int sub_type )
+{
+ return (sub_type >= AMU_RAGE);
+}
+
bool check_jewellery_size( const item_def &item, size_type size )
{
ASSERT( item.base_type == OBJ_JEWELLERY );
@@ -2468,11 +2452,8 @@ bool gives_ability(const item_def &item)
// Check for evokable randart properties.
for (int rap = ARTP_INVISIBLE; rap <= ARTP_MAPPING; rap++)
- if (artefact_wpn_property( item,
- static_cast<artefact_prop_type>(rap) ))
- {
+ if (artefact_wpn_property( item, static_cast<artefact_prop_type>(rap) ))
return (true);
- }
return (false);
}
@@ -2539,11 +2520,8 @@ bool gives_resistance(const item_def &item)
if (rap == ARTP_MAGIC || rap >= ARTP_INVISIBLE && rap != ARTP_CAN_TELEPORT)
continue;
- if (artefact_wpn_property( item,
- static_cast<artefact_prop_type>(rap) ))
- {
+ if (artefact_wpn_property( item, static_cast<artefact_prop_type>(rap) ))
return (true);
- }
}
return (false);
@@ -2728,6 +2706,28 @@ size_type item_size(const item_def &item)
return (static_cast<size_type>(size));
}
+equipment_type get_item_slot(object_class_type type, int sub_type)
+{
+ switch(type)
+ {
+ case OBJ_WEAPONS:
+ case OBJ_STAVES:
+ case OBJ_MISCELLANY:
+ return (EQ_WEAPON);
+
+ case OBJ_ARMOUR:
+ return get_armour_slot(static_cast<armour_type>(sub_type));
+
+ case OBJ_JEWELLERY:
+ return (jewellery_is_amulet(sub_type) ? EQ_AMULET : EQ_RINGS);
+
+ default:
+ break;
+ }
+
+ return (EQ_NONE);
+}
+
// Returns true if we might be interested in dumping the colour.
bool is_colourful_item(const item_def &item)
{
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index a8ef9e5547..3802983335 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -116,31 +116,7 @@ enum brand_type // equivalent to (you.inv[].special or mitm[].special) % 30
SPWPN_SHADOW, // unused
SPWPN_DEBUG_RANDART = 25, // 25
NUM_SPECIAL_WEAPONS,
- SPWPN_DUMMY_CRUSHING, // ONLY TEMPORARY USAGE -- converts to VORPAL
-
- // everything above this point is a special artefact wield:
- SPWPN_START_FIXEDARTS = 181,
-
- SPWPN_SINGING_SWORD = SPWPN_START_FIXEDARTS,
- SPWPN_WRATH_OF_TROG,
- SPWPN_SCYTHE_OF_CURSES,
- SPWPN_MACE_OF_VARIABILITY,
- SPWPN_GLAIVE_OF_PRUNE,
- SPWPN_SCEPTRE_OF_TORMENT,
- SPWPN_SWORD_OF_ZONGULDROK,
- SPWPN_SWORD_OF_POWER,
- SPWPN_STAFF_OF_OLGREB,
- SPWPN_VAMPIRES_TOOTH,
- SPWPN_STAFF_OF_WUCAD_MU,
-
- // these three are not generated randomly {dlb}
- SPWPN_START_NOGEN_FIXEDARTS,
-
- SPWPN_SWORD_OF_CEREBOV = SPWPN_START_NOGEN_FIXEDARTS,
- SPWPN_STAFF_OF_DISPATER,
- SPWPN_SCEPTRE_OF_ASMODEUS,
-
- SPWPN_END_FIXEDARTS = SPWPN_SCEPTRE_OF_ASMODEUS
+ SPWPN_DUMMY_CRUSHING // ONLY TEMPORARY USAGE -- converts to VORPAL
};
enum corpse_type
@@ -358,7 +334,8 @@ enum special_armour_type
SPARM_POSITIVE_ENERGY,
SPARM_ARCHMAGI,
SPARM_PRESERVATION,
- SPARM_REFLECTION // 19
+ SPARM_REFLECTION,
+ NUM_SPECIAL_ARMOURS // 20
};
enum special_missile_type // to separate from weapons in general {dlb}
@@ -376,7 +353,8 @@ enum special_missile_type // to separate from weapons in general {dlb}
SPMSL_DISPERSAL,
SPMSL_EXPLODING, // 10
SPMSL_STEEL,
- SPMSL_SILVER
+ SPMSL_SILVER,
+ NUM_SPECIAL_MISSILES // 12
};
enum special_ring_type // jewellery mitm[].special values
@@ -662,6 +640,7 @@ equipment_type get_armour_slot( const item_def &item );
equipment_type get_armour_slot( armour_type arm );
bool jewellery_is_amulet( const item_def &item );
+bool jewellery_is_amulet( int sub_type );
bool check_jewellery_size( const item_def &item, size_type size );
bool hide2armour( item_def &item );
@@ -769,6 +748,7 @@ bool gives_ability(const item_def &item);
bool gives_resistance(const item_def &item);
int item_mass(const item_def &item);
size_type item_size(const item_def &item);
+equipment_type get_item_slot(object_class_type type, int sub_type);
bool is_colourful_item(const item_def &item);
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index fdc9592185..a9b4ff1d98 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "arena.h"
+#include "artefact.h"
#include "beam.h"
#include "branch.h"
#include "cloud.h"
@@ -53,7 +54,6 @@ REVISION("$Rev$");
#include "place.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills2.h"
@@ -179,18 +179,10 @@ static int _cull_items(void)
{
if (_item_ok_to_clean(si->index()) && x_chance_in_y(15, 100))
{
- if (is_fixed_artefact(*si))
+ if (is_unrandom_artefact(*si))
{
// 7. Move uniques to abyss.
- set_unique_item_status( OBJ_WEAPONS, si->special,
- UNIQ_LOST_IN_ABYSS );
- }
- else if (is_unrandom_artefact(*si))
- {
- // 9. Unmark unrandart.
- const int z = find_unrandart_index(*si);
- if (z != -1)
- set_unrandart_exist(z, false);
+ set_unique_item_status(*si, UNIQ_LOST_IN_ABYSS);
}
if (first_cleaned == NON_ITEM)
@@ -499,17 +491,8 @@ void destroy_item( item_def &item, bool never_created )
if (never_created)
{
- if (is_fixed_artefact(item))
- {
- set_unique_item_status(item.base_type, item.special,
- UNIQ_NOT_EXISTS);
- }
- else if (is_unrandom_artefact(item))
- {
- const int unrand = find_unrandart_index(item);
- if (unrand != -1)
- set_unrandart_exist( unrand, false );
- }
+ if (is_unrandom_artefact(item))
+ set_unique_item_status(item, UNIQ_NOT_EXISTS);
}
item.clear();
@@ -533,16 +516,8 @@ static void _handle_gone_item(const item_def &item)
&& place_type(item.orig_place) == LEVEL_ABYSS
&& !(item.flags & ISFLAG_BEEN_IN_INV))
{
- if (item.base_type == OBJ_ORBS)
- {
- set_unique_item_status(OBJ_ORBS, item.sub_type,
- UNIQ_LOST_IN_ABYSS);
- }
- else if (is_fixed_artefact(item))
- {
- set_unique_item_status(OBJ_WEAPONS, item.special,
- UNIQ_LOST_IN_ABYSS);
- }
+ if (is_unrandom_artefact(item))
+ set_unique_item_status(item, UNIQ_LOST_IN_ABYSS);
}
if (is_rune(item))
diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw
index 0ccf5ccd0c..90b755cef3 100644
--- a/crawl-ref/source/makefile.mgw
+++ b/crawl-ref/source/makefile.mgw
@@ -217,6 +217,14 @@ $(FSQLLIBA):
cd $(SQLSRC) && $(MAKE)
#############################################################################
+# Build unrandart data
+artefact.h: art-data.txt
+ util/art-data.pl
+
+art-data.h: art-data.txt util/art-data.pl
+ util/art-data.pl
+
+#############################################################################
# Build PCRE
$(PCRESRC)\$(PCRELIBA):
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index 167bbb5244..62d3018ebf 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -3,6 +3,7 @@
OBJECTS = \
abl-show.o \
abyss.o \
+artefact.o \
acr.o \
arena.o \
beam.o \
@@ -62,7 +63,6 @@ overmap.o \
place.o \
player.o \
quiver.o \
-randart.o \
religion.o \
shopping.o \
skills.o \
diff --git a/crawl-ref/source/makefile.unix b/crawl-ref/source/makefile.unix
index e005ce2667..91df39215c 100644
--- a/crawl-ref/source/makefile.unix
+++ b/crawl-ref/source/makefile.unix
@@ -290,6 +290,14 @@ $(FSQLLIBA):
cd $(SQLSRC) && $(MAKE)
#############################################################################
+# Build unrandart data
+artefact.h: art-data.txt
+ util/art-data.pl
+
+art-data.h: art-data.txt util/art-data.pl
+ util/art-data.pl
+
+#############################################################################
# Packaging a source tarball for release
#
diff --git a/crawl-ref/source/makefile_tiles.mgw b/crawl-ref/source/makefile_tiles.mgw
index a9d5e31f36..1d4af35827 100644
--- a/crawl-ref/source/makefile_tiles.mgw
+++ b/crawl-ref/source/makefile_tiles.mgw
@@ -272,6 +272,14 @@ $(FSQLLIBA):
cd $(SQLSRC) && $(MAKE)
#############################################################################
+# Build unrandart data
+artefact.h: art-data.txt
+ util/art-data.pl
+
+art-data.h: art-data.txt util/art-data.pl
+ util/art-data.pl
+
+#############################################################################
# Build PCRE
$(PCRESRC)\$(PCRELIBA):
diff --git a/crawl-ref/source/makefile_tiles.unix b/crawl-ref/source/makefile_tiles.unix
index 2584c7bf3a..9541d2a279 100644
--- a/crawl-ref/source/makefile_tiles.unix
+++ b/crawl-ref/source/makefile_tiles.unix
@@ -324,6 +324,14 @@ $(FSQLLIBA):
cd $(SQLSRC) && $(MAKE)
#############################################################################
+# Build unrandart data
+artefact.h: art-data.txt
+ util/art-data.pl
+
+art-data.h: art-data.txt util/art-data.pl
+ util/art-data.pl
+
+#############################################################################
# Packaging a source tarball for release
#
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 640c947ea4..96e4b80f85 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -15,6 +15,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "makeitem.h"
+#include "artefact.h"
#include "decks.h"
#include "describe.h"
#include "dungeon.h"
@@ -26,7 +27,6 @@ REVISION("$Rev$");
#include "misc.h"
#include "mon-util.h"
#include "player.h"
-#include "randart.h"
#include "spl-book.h"
#include "stuff.h"
#include "travel.h"
@@ -349,9 +349,8 @@ void item_colour(item_def &item)
switch (item.base_type)
{
case OBJ_WEAPONS:
- if (is_unrandom_artefact( item ) || is_fixed_artefact( item ))
- break; // unrandarts and fixed arts already coloured
-
+ if (is_unrandom_artefact(item))
+ break; // unrandarts already coloured
if (is_demonic( item ))
item.colour = random_uncommon_colour();
@@ -883,6 +882,26 @@ static weapon_type _determine_weapon_subtype(int item_level)
return rc;
}
+static bool _try_make_item_special_unrand(item_def& item, int force_type,
+ int item_level)
+{
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_DIAGNOSTICS, "Making special unrand artefact.");
+#endif
+
+ bool abyss = item_level == level_id(LEVEL_ABYSS).absdepth();
+ int idx = find_okay_unrandart(item.base_type, force_type,
+ UNRANDPSEC_SPECIAL, abyss);
+
+ if (idx != -1)
+ {
+ if (make_item_unrandart(item, idx))
+ return (true);
+ }
+
+ return (false);
+}
+
// Return whether we made an artefact.
static bool _try_make_weapon_artefact(item_def& item, int force_type,
int item_level)
@@ -897,7 +916,8 @@ static bool _try_make_weapon_artefact(item_def& item, int force_type,
&& you.level_type != LEVEL_PANDEMONIUM
&& one_chance_in(50))
{
- const int idx = find_okay_unrandart(OBJ_WEAPONS, force_type);
+ const int idx = find_okay_unrandart(OBJ_WEAPONS, force_type,
+ UNRANDSPEC_NORMAL);
if (idx != -1)
{
make_item_unrandart(item, idx);
@@ -936,18 +956,12 @@ static bool _try_make_weapon_artefact(item_def& item, int force_type,
return (true);
}
- // If it isn't an artefact yet, try to make a fixed artefact.
+ // If it isn't an artefact yet, try to make a special unrand artefact.
if (item_level > 6
&& one_chance_in(12)
&& x_chance_in_y(31 + item_level * 3, 3000))
{
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Making fixed artefact.");
-#endif
- if (make_item_fixed_artefact(
- item,
- (item_level == level_id(LEVEL_ABYSS).absdepth()) ))
- return (true);
+ return _try_make_item_special_unrand(item, force_type, item_level);
}
return (false);
@@ -1528,7 +1542,7 @@ static void _generate_weapon_item(item_def& item, bool allow_uniques,
return;
}
- ASSERT(!is_fixed_artefact(item) && !is_random_artefact(item));
+ ASSERT(!is_artefact(item));
// Artefacts handled, let's make a normal item.
const bool force_good = (item_level == MAKE_GOOD_ITEM);
@@ -1828,7 +1842,8 @@ static bool _try_make_armour_artefact(item_def& item, int force_type,
&& one_chance_in(50))
{
// The old generation code did not respect force_type here.
- const int idx = find_okay_unrandart(OBJ_ARMOUR, force_type);
+ const int idx = find_okay_unrandart(OBJ_ARMOUR, force_type,
+ UNRANDSPEC_NORMAL);
if (idx != -1)
{
make_item_unrandart(item, idx);
@@ -1874,6 +1889,14 @@ static bool _try_make_armour_artefact(item_def& item, int force_type,
return (true);
}
+ // If it isn't an artefact yet, try to make a special unrand artefact.
+ if (item_level > 6
+ && one_chance_in(12)
+ && x_chance_in_y(31 + item_level * 3, 3000))
+ {
+ return _try_make_item_special_unrand(item, force_type, item_level);
+ }
+
return (false);
}
@@ -2079,7 +2102,8 @@ static special_armour_type _determine_armour_ego(const item_def& item,
}
static void _generate_armour_item(item_def& item, bool allow_uniques,
- int force_type, int item_level, int item_race)
+ int force_type, int item_level,
+ int item_race)
{
if (force_type != OBJ_RANDOM)
item.sub_type = force_type;
@@ -2588,7 +2612,8 @@ static bool _try_make_jewellery_unrandart(item_def& item, int force_type,
&& x_chance_in_y(101 + item_level * 3, 2000))
{
// The old generation code did not respect force_type here.
- const int idx = find_okay_unrandart(OBJ_JEWELLERY, force_type);
+ const int idx = find_okay_unrandart(OBJ_JEWELLERY, force_type,
+ UNRANDSPEC_NORMAL);
if (idx != -1)
{
make_item_unrandart(item, idx);
@@ -2629,7 +2654,8 @@ static int _determine_ring_plus(int subtype)
}
static void _generate_jewellery_item(item_def& item, bool allow_uniques,
- int force_type, int item_level, int agent)
+ int force_type, int item_level,
+ int agent)
{
if (allow_uniques
&& _try_make_jewellery_unrandart(item, force_type, item_level))
@@ -2684,6 +2710,13 @@ static void _generate_jewellery_item(item_def& item, bool allow_uniques,
{
make_item_randart(item);
}
+ // If it isn't an artefact yet, try to make a special unrand artefact.
+ else if (item_level > 6
+ && one_chance_in(12)
+ && x_chance_in_y(31 + item_level * 3, 3000))
+ {
+ _try_make_item_special_unrand(item, force_type, item_level);
+ }
else if (item.sub_type == RING_HUNGER || item.sub_type == RING_TELEPORTATION
|| one_chance_in(50))
{
@@ -2771,7 +2804,7 @@ int items(int allow_uniques, // not just true-false,
const bool force_good = (item_level == MAKE_GOOD_ITEM);
- if (force_ego > 0)
+ if (force_ego != 0)
allow_uniques = false;
item.special = force_ego;
@@ -2814,11 +2847,12 @@ int items(int allow_uniques, // not just true-false,
item.quantity = 1; // generally the case
- if (force_ego >= SPWPN_START_FIXEDARTS && force_ego <= SPWPN_END_FIXEDARTS)
+ if (force_ego < SP_FORBID_EGO)
{
- if (get_unique_item_status(OBJ_WEAPONS, force_ego) == UNIQ_NOT_EXISTS)
+ force_ego = -force_ego;
+ if (get_unique_item_status(force_ego) == UNIQ_NOT_EXISTS)
{
- make_item_fixed_artefact(mitm[p], false, force_ego);
+ make_item_unrandart(mitm[p], force_ego);
return (p);
}
// the base item otherwise
@@ -2874,7 +2908,6 @@ int items(int allow_uniques, // not just true-false,
case OBJ_ORBS: // always forced in current setup {dlb}
item.sub_type = force_type;
- set_unique_item_status(OBJ_ORBS, item.sub_type, UNIQ_EXISTS);
break;
case OBJ_MISCELLANY:
@@ -2958,7 +2991,7 @@ static bool _weapon_is_visibly_special(const item_def &item)
if (get_equip_desc(item) != ISFLAG_NO_DESC)
return (false);
- if (visibly_branded || is_random_artefact(item))
+ if (visibly_branded || is_artefact(item))
return (true);
if ((item.plus || item.plus2)
@@ -2981,7 +3014,7 @@ static bool _armour_is_visibly_special(const item_def &item)
if (get_equip_desc(item) != ISFLAG_NO_DESC)
return (false);
- if (visibly_branded || is_random_artefact(item))
+ if (visibly_branded || is_artefact(item))
return (true);
if (item.plus && !one_chance_in(3))
@@ -3701,17 +3734,17 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
case MONS_CEREBOV:
force_item = true;
- make_item_fixed_artefact( item, false, SPWPN_SWORD_OF_CEREBOV );
+ make_item_unrandart( item, SPWPN_SWORD_OF_CEREBOV );
break;
case MONS_DISPATER:
force_item = true;
- make_item_fixed_artefact( item, false, SPWPN_STAFF_OF_DISPATER );
+ make_item_unrandart( item, SPWPN_STAFF_OF_DISPATER );
break;
case MONS_ASMODEUS:
force_item = true;
- make_item_fixed_artefact( item, false, SPWPN_SCEPTRE_OF_ASMODEUS );
+ make_item_unrandart( item, SPWPN_SCEPTRE_OF_ASMODEUS );
break;
case MONS_GERYON:
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 1149313c68..ae428099e8 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -16,6 +16,7 @@ REVISION("$Rev$");
#include <cstdlib>
#include <algorithm>
+#include "artefact.h"
#include "branch.h"
#include "describe.h"
#include "directn.h"
@@ -33,7 +34,6 @@ REVISION("$Rev$");
#include "monplace.h"
#include "mon-util.h"
#include "place.h"
-#include "randart.h"
#include "stuff.h"
#include "tags.h"
@@ -2843,7 +2843,7 @@ item_spec item_list::parse_single_spec(std::string s)
return (result);
}
- std::string fixed_str = strip_tag_prefix(s, "fixed:");
+ std::string unrand_str = strip_tag_prefix(s, "unrand:");
if (strip_tag(s, "good_item"))
result.level = MAKE_GOOD_ITEM;
@@ -2949,14 +2949,15 @@ item_spec item_list::parse_single_spec(std::string s)
if (!error.empty())
return (result);
- if (!fixed_str.empty())
+ if (!unrand_str.empty())
{
- result.ego = get_fixedart_num(fixed_str.c_str());
+ result.ego = get_unrandart_num(unrand_str.c_str());
if (result.ego == SPWPN_NORMAL)
{
- error = make_stringf("Unknown fixed art: %s", fixed_str.c_str());
+ error = make_stringf("Unknown unrand art: %s", unrand_str.c_str());
return result;
}
+ result.ego = -result.ego;
return result;
}
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 115f1b88e8..28e2f5185b 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "database.h"
#include "debug.h"
@@ -43,7 +44,6 @@ REVISION("$Rev$");
#include "mstuff2.h"
#include "mtransit.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h" // for item values
#include "spells3.h"
@@ -354,25 +354,25 @@ static int _scan_mon_inv_randarts(const monsters *mon,
const int shield = mon->inv[MSLOT_SHIELD];
if (weapon != NON_ITEM && mitm[weapon].base_type == OBJ_WEAPONS
- && is_random_artefact(mitm[weapon]))
+ && is_artefact(mitm[weapon]))
{
ret += artefact_wpn_property(mitm[weapon], ra_prop);
}
if (second != NON_ITEM && mitm[second].base_type == OBJ_WEAPONS
- && is_random_artefact(mitm[second]))
+ && is_artefact(mitm[second]))
{
ret += artefact_wpn_property(mitm[second], ra_prop);
}
if (armour != NON_ITEM && mitm[armour].base_type == OBJ_ARMOUR
- && is_random_artefact(mitm[armour]))
+ && is_artefact(mitm[armour]))
{
ret += artefact_wpn_property(mitm[armour], ra_prop);
}
if (shield != NON_ITEM && mitm[shield].base_type == OBJ_ARMOUR
- && is_random_artefact(mitm[shield]))
+ && is_artefact(mitm[shield]))
{
ret += artefact_wpn_property(mitm[shield], ra_prop);
}
@@ -3983,8 +3983,8 @@ bool monsters::could_wield(const item_def &item, bool ignore_brand,
if (type == MONS_DANCING_WEAPON)
return (false);
- // Monsters can't use fixed artefacts.
- if (is_fixed_artefact(item) && !crawl_state.arena)
+ // Monsters can't use unrandarts with special effects.
+ if (is_special_unrandom_artefact(item) && !crawl_state.arena)
return (false);
// Wimpy monsters (e.g. kobold, goblin) can't use halberds, etc.
@@ -4178,7 +4178,7 @@ void monsters::equip_weapon(item_def &item, int near, bool msg)
if (message_given)
{
- if (is_random_artefact(item))
+ if (is_artefact(item) && !is_special_unrandom_artefact(item))
artefact_wpn_learn_prop(item, ARTP_BRAND);
else
set_ident_flags(item, ISFLAG_KNOW_TYPE);
@@ -4277,7 +4277,7 @@ void monsters::unequip_weapon(item_def &item, int near, bool msg)
}
if (message_given)
{
- if (is_random_artefact(item))
+ if (is_artefact(item) && !is_special_unrandom_artefact(item))
artefact_wpn_learn_prop(item, ARTP_BRAND);
else
set_ident_flags(item, ISFLAG_KNOW_TYPE);
@@ -4617,7 +4617,7 @@ static bool _is_signature_weapon(monsters *monster, const item_def &weapon)
if (monster->type == MONS_SIGMUND)
return (weapon.sub_type == WPN_SCYTHE);
- if (is_fixed_artefact(weapon))
+ if (is_unrandom_artefact(weapon))
{
switch (weapon.special)
{
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 622309d23c..a7acbe5c0e 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -22,6 +22,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "arena.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "database.h"
@@ -49,7 +50,6 @@ REVISION("$Rev$");
#include "mstuff2.h"
#include "notes.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "spl-mis.h"
#include "spl-util.h"
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 56acbc2177..38a93a53d0 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -19,6 +19,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "arena.h"
+#include "artefact.h"
#include "beam.h"
#include "database.h"
#include "debug.h"
@@ -36,7 +37,6 @@ REVISION("$Rev$");
#include "monstuff.h"
#include "mon-util.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "spells1.h"
#include "spells3.h"
diff --git a/crawl-ref/source/mtransit.cc b/crawl-ref/source/mtransit.cc
index 5ce6d678a0..0899103834 100644
--- a/crawl-ref/source/mtransit.cc
+++ b/crawl-ref/source/mtransit.cc
@@ -13,12 +13,12 @@ REVISION("$Rev$");
#include "mtransit.h"
+#include "artefact.h"
#include "dungeon.h"
#include "items.h"
#include "monplace.h"
#include "mon-util.h"
#include "monstuff.h"
-#include "randart.h"
#include "stuff.h"
#define MAX_LOST 100
@@ -52,7 +52,7 @@ static void cull_lost_mons(m_transit_list &mlist, int how_many)
static void cull_lost_items(i_transit_list &ilist, int how_many)
{
- // First pass, drop non-artifacts.
+ // First pass, drop non-artefacts.
for (i_transit_list::iterator i = ilist.begin(); i != ilist.end(); )
{
i_transit_list::iterator finger = i++;
@@ -82,7 +82,8 @@ static void cull_lost_items(i_transit_list &ilist, int how_many)
for (i_transit_list::iterator i = ilist.begin(); i != ilist.end(); )
{
i_transit_list::iterator finger = i++;
- if (is_unrandom_artefact(*finger))
+ if (is_unrandom_artefact(*finger)
+ && !is_special_unrandom_artefact(*finger))
{
ilist.erase(finger);
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index 2b147050d4..54819b1257 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -32,6 +32,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abl-show.h"
+#include "artefact.h"
#include "branch.h"
#include "cio.h"
#include "command.h"
@@ -52,7 +53,6 @@ REVISION("$Rev$");
#include "misc.h"
#include "place.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 0a071ee46c..2bb95ce7d6 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -36,6 +36,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "chardump.h"
#include "delay.h"
#include "files.h"
@@ -53,7 +54,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills2.h"
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 0a7f16c50e..86c6540f8b 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -24,6 +24,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "branch.h"
#include "cio.h"
#include "cloud.h"
@@ -49,7 +50,6 @@ REVISION("$Rev$");
#include "output.h"
#include "place.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "skills2.h"
@@ -953,9 +953,6 @@ int player_equip_ego_type( int slot, int special )
switch (slot)
{
case EQ_WEAPON:
- // This actually checks against the "branding", so it will catch
- // randart brands, but not fixed artefacts. -- bwr
-
// Hands can have more than just weapons.
wpn = you.equip[EQ_WEAPON];
if (wpn != -1
@@ -1005,6 +1002,78 @@ int player_equip_ego_type( int slot, int special )
return (ret);
}
+// Return's true if the indicated unrandart is equipped
+// [ds] There's no equivalent of calc_unid or req_id because as of now, weapons
+// and armour type-id on wield/wear.
+bool player_equip_unrand(int unrand_index)
+{
+ unrandart_entry* entry = get_unrand_entry(unrand_index);
+ equipment_type slot = get_item_slot(entry->base_type,
+ entry->sub_type);
+
+ if (!you_tran_can_wear(slot))
+ return (false);
+
+ int it;
+
+ switch (slot)
+ {
+ case EQ_WEAPON:
+ // Hands can have more than just weapons.
+ it = you.equip[EQ_WEAPON];
+ if (it != -1
+ && you.inv[it].base_type == OBJ_WEAPONS
+ && is_unrandom_artefact(you.inv[it])
+ && you.inv[it].special == unrand_index)
+ {
+ return (true);
+ }
+ break;
+
+ case EQ_RINGS:
+ it = you.equip[EQ_LEFT_RING];
+ if (it != -1
+ && is_unrandom_artefact(you.inv[it])
+ && you.inv[it].special == unrand_index)
+ {
+ return (true);
+ }
+
+ it = you.equip[EQ_RIGHT_RING];
+ if (it != -1
+ && is_unrandom_artefact(you.inv[it])
+ && you.inv[it].special == unrand_index)
+ {
+ return (true);
+ }
+ break;
+
+ case EQ_NONE:
+ case EQ_STAFF:
+ case EQ_LEFT_RING:
+ case EQ_RIGHT_RING:
+ case EQ_RINGS_PLUS:
+ case EQ_RINGS_PLUS2:
+ case EQ_ALL_ARMOUR:
+ // no unrandarts for these slots.
+ break;
+
+ default:
+ // Check a specific slot.
+ it = you.equip[slot];
+ if (it != -1
+ && is_unrandom_artefact(you.inv[it])
+ && you.inv[it].special == unrand_index)
+ {
+ return (true);
+ }
+ break;
+ }
+
+ return (false);
+}
+
+
int player_damage_type( void )
{
return you.damage_type();
@@ -1031,7 +1100,7 @@ int player_teleport(bool calc_unid)
// randart weapons only
if (you.weapon()
&& you.weapon()->base_type == OBJ_WEAPONS
- && is_random_artefact(*you.weapon()))
+ && is_artefact(*you.weapon()))
{
tp += scan_artefacts(ARTP_CAUSE_TELEPORTATION, calc_unid);
}
@@ -1171,13 +1240,19 @@ int player_hunger_rate(void)
// weapon ego types
if (you.species != SP_VAMPIRE)
{
- hunger += 6 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM );
- hunger += 9 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRES_TOOTH );
+ if (player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM ))
+ {
+ hunger += 6;
+ hunger += 3 * player_equip_unrand( SPWPN_VAMPIRES_TOOTH );
+ }
}
else
{
- hunger += 1 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM );
- hunger += 2 * player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRES_TOOTH );
+ if (player_equip_ego_type( EQ_WEAPON, SPWPN_VAMPIRICISM ))
+ {
+ hunger += 1;
+ hunger += 1 * player_equip_unrand( SPWPN_VAMPIRES_TOOTH );
+ }
}
// troll leather armour
@@ -1591,14 +1666,6 @@ int player_res_poison(bool calc_unid, bool temp, bool items)
// Staves
rp += player_equip( EQ_STAFF, STAFF_POISON, calc_unid );
- // the staff of Olgreb:
- if (you.weapon()
- && you.weapon()->base_type == OBJ_WEAPONS
- && you.weapon()->special == SPWPN_STAFF_OF_OLGREB)
- {
- rp++;
- }
-
// ego armour:
rp += player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_POISON_RESISTANCE );
@@ -1789,12 +1856,8 @@ int player_spec_poison()
// Staves
sp += player_equip( EQ_STAFF, STAFF_POISON );
- if (you.weapon()
- && you.weapon()->base_type == OBJ_WEAPONS
- && you.weapon()->special == SPWPN_STAFF_OF_OLGREB)
- {
+ if (player_equip_unrand(SPWPN_STAFF_OF_OLGREB))
sp++;
- }
return sp;
}
@@ -3574,7 +3637,7 @@ int check_stealth(void)
return (1000);
#endif
- if (you.special_wield == SPWLD_SHADOW || you.duration[DUR_BERSERKER])
+ if (you.unrand_reacts == SPWLD_SHADOW || you.duration[DUR_BERSERKER])
return (0);
int stealth = you.dex * 3;
@@ -4560,7 +4623,7 @@ bool items_give_ability(const int slot, artefact_prop_type abil)
}
// other items are not evokable
- if (!is_random_artefact( you.inv[ eq ] ))
+ if (!is_artefact( you.inv[ eq ] ))
continue;
if (artefact_wpn_property(you.inv[ eq ], abil))
@@ -4589,7 +4652,7 @@ int scan_artefacts(artefact_prop_type which_property, bool calc_unid)
if (i == EQ_WEAPON && you.inv[ eq ].base_type != OBJ_WEAPONS)
continue;
- if (!is_random_artefact( you.inv[ eq ] ))
+ if (!is_artefact( you.inv[ eq ] ))
continue;
// Ignore unidentified items [TileCrawl dump enhancements].
@@ -5849,7 +5912,7 @@ void player::init()
disease = 0;
elapsed_time = 0;
rotting = 0;
- special_wield = SPWLD_NONE;
+ unrand_reacts = SPWLD_NONE;
synch_time = 0;
magic_contamination = 0;
@@ -5931,9 +5994,6 @@ void player::init()
unique_items.init(UNIQ_NOT_EXISTS);
- for (int i = 0; i < NO_UNRANDARTS; i++)
- set_unrandart_exist(i, false);
-
skills.init(0);
skill_points.init(0);
skill_order.init(MAX_SKILL_ORDER);
@@ -6509,7 +6569,7 @@ static bool _equipment_make_berserk()
if (!item)
continue;
- if (!is_random_artefact(*item))
+ if (!is_artefact(*item))
continue;
if (artefact_wpn_property(*item, ARTP_ANGRY) && one_chance_in(20))
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 6d83dfe8be..26600a22af 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -35,6 +35,7 @@ int get_player_wielded_weapon(void);
bool berserk_check_wielded_weapon(void);
int player_equip( equipment_type slot, int sub_type, bool calc_unid = true );
int player_equip_ego_type( int slot, int sub_type );
+bool player_equip_unrand( int unrand_index );
int player_damage_type( void );
int player_damage_brand( void );
bool player_can_hit_monster(const monsters *mons);
diff --git a/crawl-ref/source/randart.h b/crawl-ref/source/randart.h
deleted file mode 100644
index 5a7a630490..0000000000
--- a/crawl-ref/source/randart.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * File: randart.h
- * Summary: Random and unrandom artefact functions.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- */
-
-
-#ifndef RANDART_H
-#define RANDART_H
-
-#include "externs.h"
-
-// used in files.cc, newgame.cc, randart.cc {dlb}
-#define NO_UNRANDARTS 61
-#define RA_PROPERTIES ARTP_NUM_PROPERTIES
-
-// Reserving the upper bits for later expansion/versioning.
-#define RANDART_SEED_MASK 0x00ffffff
-
-
-bool is_known_artefact( const item_def &item );
-bool is_artefact( const item_def &item );
-bool is_random_artefact( const item_def &item );
-bool is_unrandom_artefact( const item_def &item );
-bool is_fixed_artefact( const item_def &item );
-
-unique_item_status_type get_unique_item_status( object_class_type base_type,
- int type );
-void set_unique_item_status( object_class_type base_type, int type,
- unique_item_status_type status );
-
-/* ***********************************************************************
- * called from: itemname
- * *********************************************************************** */
-std::string get_artefact_name( const item_def &item );
-
-/* ***********************************************************************
- * called from: spl-book
- * *********************************************************************** */
-void set_artefact_name( item_def &item, const std::string &name );
-void set_artefact_appearance( item_def &item, const std::string &appear );
-
-/* ***********************************************************************
- * called from: effects
- * *********************************************************************** */
-std::string artefact_name( const item_def &item, bool appearance = false );
-
-/* ***********************************************************************
- * called from: describe
- * *********************************************************************** */
-const char *unrandart_descrip( int which_descrip, const item_def &item );
-
-bool does_unrandart_exist(int whun);
-
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-int find_okay_unrandart(unsigned char aclass, unsigned char atype = OBJ_RANDOM);
-
-typedef FixedVector< int, RA_PROPERTIES > artefact_properties_t;
-typedef FixedVector< bool, RA_PROPERTIES > artefact_known_props_t;
-
-/* ***********************************************************************
- * called from: describe - fight - it_use2 - item_use - player
- * *********************************************************************** */
-void artefact_desc_properties( const item_def &item,
- artefact_properties_t &proprt,
- artefact_known_props_t &known,
- bool force_fake_props = false);
-
-void artefact_wpn_properties( const item_def &item,
- artefact_properties_t &proprt,
- artefact_known_props_t &known );
-
-void artefact_wpn_properties( const item_def &item,
- artefact_properties_t &proprt );
-
-int artefact_wpn_property( const item_def &item, artefact_prop_type prop,
- bool &known );
-
-int artefact_wpn_property( const item_def &item, artefact_prop_type prop );
-
-int artefact_known_wpn_property( const item_def &item,
- artefact_prop_type prop );
-
-int artefact_wpn_num_props( const item_def &item );
-int artefact_wpn_num_props( const artefact_properties_t &proprt );
-
-void artefact_wpn_learn_prop( item_def &item, artefact_prop_type prop );
-bool artefact_wpn_known_prop( const item_def &item, artefact_prop_type prop );
-
-/* ***********************************************************************
- * called from: dungeon
- * *********************************************************************** */
-bool make_item_fixed_artefact( item_def &item, bool in_abyss, int which = 0 );
-
-bool make_item_blessed_blade( item_def &item );
-bool make_item_randart( item_def &item );
-bool make_item_unrandart( item_def &item, int unrand_index );
-
-/* ***********************************************************************
- * called from: randart - debug
- * *********************************************************************** */
-bool randart_is_bad( const item_def &item );
-bool randart_is_bad( const item_def &item, artefact_properties_t &proprt );
-
-/* ***********************************************************************
- * called from: files - newgame
- * *********************************************************************** */
-void set_unrandart_exist(int whun, bool is_exist);
-
-/* ***********************************************************************
- * called from: items
- * *********************************************************************** */
-int find_unrandart_index(const item_def& artefact);
-int find_unrandart_index(const item_def &item);
-
-/* ***********************************************************************
- * called from: debug
- * *********************************************************************** */
-void artefact_set_properties( item_def &item,
- artefact_properties_t &proprt );
-void artefact_set_property( item_def &item,
- artefact_prop_type prop,
- int val );
-
-/* ***********************************************************************
- * called from: mapdef
- * *********************************************************************** */
-int get_fixedart_num( const char *name );
-#endif
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 62fc391103..d65e74b46f 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -25,6 +25,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abl-show.h"
+#include "artefact.h"
#include "beam.h"
#include "chardump.h"
#include "cloud.h"
@@ -59,7 +60,6 @@ REVISION("$Rev$");
#include "output.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "shopping.h"
#include "skills2.h"
#include "spells1.h"
@@ -3537,7 +3537,7 @@ bool is_chaotic_item(const item_def& item)
break;
}
- if (is_random_artefact(item) && artefact_wpn_property(item, ARTP_MUTAGENIC))
+ if (is_artefact(item) && artefact_wpn_property(item, ARTP_MUTAGENIC))
retval = true;
return (retval);
diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc
index 09ecd06ad0..2334052f0c 100644
--- a/crawl-ref/source/shopping.cc
+++ b/crawl-ref/source/shopping.cc
@@ -22,6 +22,7 @@ REVISION("$Rev$");
#endif
#include "externs.h"
+#include "artefact.h"
#include "cio.h"
#include "describe.h"
#include "food.h"
@@ -35,7 +36,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "overmap.h"
#include "player.h"
-#include "randart.h"
#include "spl-book.h"
#include "stash.h"
#include "stuff.h"
@@ -264,7 +264,7 @@ static bool _in_a_shop( int shopidx )
for (unsigned int i = 0; i < stock.size(); i++)
{
item_def& item = mitm[stock[i]];
- if (Options.autoinscribe_artefacts && is_random_artefact(item))
+ if (Options.autoinscribe_artefacts && is_artefact(item))
item.inscription = artefact_auto_inscription(item);
}
@@ -517,7 +517,7 @@ static bool _purchase( int shop, int item_got, int cost, bool id )
// the price of the artefact. -- bwr
int artefact_value( const item_def &item )
{
- ASSERT( is_random_artefact( item ) );
+ ASSERT( is_artefact( item ) );
int ret = 10;
artefact_properties_t prop;
@@ -621,7 +621,7 @@ unsigned int item_value( item_def item, bool ident )
switch (item.base_type)
{
case OBJ_WEAPONS:
- if (is_fixed_artefact( item ))
+ if (is_unrandom_artefact( item ))
{
if (item_ident( item, ISFLAG_KNOW_PROPERTIES ))
{
@@ -912,7 +912,7 @@ unsigned int item_value( item_def item, bool ident )
}
}
- if (is_random_artefact(item))
+ if (is_artefact(item))
{
if (item_type_known(item))
valued += (7 * artefact_value(item));
@@ -1225,7 +1225,7 @@ unsigned int item_value( item_def item, bool ident )
}
}
- if (is_random_artefact( item ))
+ if (is_artefact( item ))
{
if (item_type_known(item))
valued += (7 * artefact_value( item ));
@@ -1592,7 +1592,7 @@ unsigned int item_value( item_def item, bool ident )
// got to do delusion!
}
- if (is_random_artefact(item))
+ if (is_artefact(item))
{
// in this branch we're guaranteed to know
// the item type!
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index e2d2f5774e..7aa02cb739 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -23,6 +23,7 @@ REVISION("$Rev$");
#include <conio.h>
#endif
+#include "artefact.h"
#include "cio.h"
#include "describe.h"
#include "externs.h"
@@ -30,7 +31,6 @@ REVISION("$Rev$");
#include "itemprop.h"
#include "menu.h"
#include "player.h"
-#include "randart.h"
#include "stuff.h"
#include "transfor.h"
#include "tutorial.h"
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 84c4788296..c4085823d4 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -20,6 +20,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abyss.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "describe.h"
@@ -35,7 +36,6 @@ REVISION("$Rev$");
#include "monstuff.h"
#include "mon-util.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spells2.h"
@@ -456,7 +456,7 @@ void identify(int power, int item_slot)
set_ident_type(item, ID_KNOWN_TYPE);
set_ident_flags(item, ISFLAG_IDENT_MASK);
- if (Options.autoinscribe_artefacts && is_random_artefact(item))
+ if (Options.autoinscribe_artefacts && is_artefact(item))
add_autoinscription( item, artefact_auto_inscription(item));
// For scrolls, now id the scroll, unless already known.
diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc
index 76db1935e1..b584327c4b 100644
--- a/crawl-ref/source/spells2.cc
+++ b/crawl-ref/source/spells2.cc
@@ -19,6 +19,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "delay.h"
@@ -37,7 +38,6 @@ REVISION("$Rev$");
#include "mon-util.h"
#include "ouch.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "spells4.h"
#include "spl-mis.h"
@@ -1598,7 +1598,7 @@ bool cast_tukimas_dance(int pow, god_type god, bool force_hostile)
if (wpn == -1
|| you.inv[wpn].base_type != OBJ_WEAPONS
|| is_range_weapon(you.inv[wpn])
- || is_fixed_artefact(you.inv[wpn]))
+ || is_special_unrandom_artefact(you.inv[wpn]))
{
success = false;
}
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 99bed5eb38..5969ba834a 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -20,6 +20,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abyss.h"
+#include "artefact.h"
#include "beam.h"
#include "branch.h"
#include "cloud.h"
@@ -41,7 +42,6 @@ REVISION("$Rev$");
#include "place.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "spells1.h"
#include "spells4.h"
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index dc9d778111..8f0f6c8e08 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -18,6 +18,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "abyss.h"
+#include "artefact.h"
#include "beam.h"
#include "cloud.h"
#include "debug.h"
@@ -42,7 +43,6 @@ REVISION("$Rev$");
#include "ouch.h"
#include "player.h"
#include "quiver.h"
-#include "randart.h"
#include "religion.h"
#include "skills.h"
#include "spells1.h"
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index bf83e90f73..0f3a76ba23 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -21,6 +21,7 @@ REVISION("$Rev$");
#include <conio.h>
#endif
+#include "artefact.h"
#include "externs.h"
#include "cio.h"
#include "database.h"
@@ -37,7 +38,6 @@ REVISION("$Rev$");
#include "macro.h"
#include "message.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "skills2.h"
#include "spl-cast.h"
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 4c15a594a5..a73c60a9d6 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -584,7 +584,7 @@ int spell_enhancement( unsigned int typeflags )
if (typeflags & SPTYP_AIR)
enhanced += player_spec_air() - player_spec_earth();
- if (you.special_wield == SPWLD_SHADOW)
+ if (you.unrand_reacts == SPWLD_SHADOW)
enhanced -= 2;
// These are used in an exponential way, so we'll limit them a bit. -- bwr
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index 691f387289..011526c1a5 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -9,6 +9,7 @@
#include "AppHdr.h"
REVISION("$Rev$");
+#include "artefact.h"
#include "branch.h"
#include "chardump.h"
#include "cio.h"
@@ -32,7 +33,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "overmap.h"
#include "place.h"
-#include "randart.h"
#include "shopping.h"
#include "spl-book.h"
#include "stash.h"
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index ef5eaaf648..7c804299b6 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -63,6 +63,7 @@
REVISION("$Rev$");
#include "abl-show.h"
+#include "artefact.h"
#include "branch.h"
#include "describe.h"
#include "dungeon.h"
@@ -77,7 +78,6 @@ REVISION("$Rev$");
#include "mon-util.h"
#include "mtransit.h"
#include "quiver.h"
-#include "randart.h"
#include "skills.h"
#include "skills2.h"
#include "stuff.h"
@@ -837,7 +837,7 @@ static void tag_construct_you(writer &th)
marshallByte(th, you.char_direction);
marshallByte(th, you.your_level);
marshallByte(th, you.is_undead);
- marshallByte(th, you.special_wield);
+ marshallShort(th, you.unrand_reacts);
marshallByte(th, you.berserk_penalty);
marshallShort(th, you.sage_bonus_skill);
marshallLong(th, you.sage_bonus_degree);
@@ -1065,12 +1065,6 @@ static void tag_construct_you_items(writer &th)
marshallShort(th, NUM_SPELLS);
for (j = 0; j < NUM_SPELLS; ++j)
marshallByte(th,you.seen_spell[j]);
-
- // how many unrandarts?
- marshallShort(th, NO_UNRANDARTS);
-
- for (j = 0; j < NO_UNRANDARTS; ++j)
- marshallBoolean(th, does_unrandart_exist(j));
}
static void marshallPlaceInfo(writer &th, PlaceInfo place_info)
@@ -1253,7 +1247,7 @@ static void tag_read_you(reader &th, char minorVersion)
you.char_direction = static_cast<game_direction_type>(unmarshallByte(th));
you.your_level = unmarshallByte(th);
you.is_undead = static_cast<undead_state_type>(unmarshallByte(th));
- you.special_wield = unmarshallByte(th);
+ you.unrand_reacts = unmarshallShort(th);
you.berserk_penalty = unmarshallByte(th);
you.sage_bonus_skill = static_cast<skill_type>(unmarshallShort(th));
you.sage_bonus_degree = unmarshallLong(th);
@@ -1513,6 +1507,11 @@ static void tag_read_you_items(reader &th, char minorVersion)
static_cast<unique_item_status_type>(unmarshallByte(th));
}
+ // # of unrandarts could certainly change.
+ // If it does, the new ones won't exist yet - zero them out.
+ for (; j < NO_UNRANDARTS; j++)
+ you.unique_items[j] = UNIQ_NOT_EXISTS;
+
// how many books?
count_c = unmarshallByte(th);
for (j = 0; j < count_c; ++j)
@@ -1522,16 +1521,6 @@ static void tag_read_you_items(reader &th, char minorVersion)
count_s = unmarshallShort(th);
for (j = 0; j < count_s; ++j)
you.seen_spell[j] = unmarshallByte(th);
-
- // how many unrandarts?
- count_s = unmarshallShort(th);
- for (j = 0; j < count_s; ++j)
- set_unrandart_exist(j, unmarshallBoolean(th));
-
- // # of unrandarts could certainly change.
- // If it does, the new ones won't exist yet - zero them out.
- for (; j < NO_UNRANDARTS; j++)
- set_unrandart_exist(j, false);
}
static PlaceInfo unmarshallPlaceInfo(reader &th)
diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h
index 3ee92cc930..41de2ed824 100644
--- a/crawl-ref/source/tags.h
+++ b/crawl-ref/source/tags.h
@@ -41,7 +41,7 @@ enum tag_file_type // file types supported by tag system
enum tag_major_version
{
TAG_MAJOR_START = 5,
- TAG_MAJOR_VERSION = 5
+ TAG_MAJOR_VERSION = 6
};
// Minor version will be reset to zero when major version changes.
@@ -63,7 +63,8 @@ enum tag_minor_version
TAG_MINOR_SVNREV = 13, // Added SVN revision
TAG_MINOR_PORTEXT = 14, // Keep track of portal vault extensions.
TAG_MINOR_RELIGION = 15, // Keep track of ghosts' religions.
- TAG_MINOR_VERSION = 15 // Current version. (Keep equal to max.)
+ TAG_MINOR_ARTEFACT = 16, // Turned fixed arts into unrandarts.
+ TAG_MINOR_VERSION = 16 // Current version. (Keep equal to max.)
};
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 965cad5ebb..99360d295d 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -10,6 +10,7 @@ REVISION("$Rev$");
#ifdef USE_TILE
#include <stdio.h>
+#include "artefact.h"
#include "decks.h"
#include "directn.h"
#include "externs.h"
@@ -22,7 +23,6 @@ REVISION("$Rev$");
#include "monstuff.h"
#include "mon-util.h"
#include "player.h"
-#include "randart.h"
#include "shopping.h"
#include "spells3.h" // for the halo
#include "stuff.h"
@@ -1079,9 +1079,9 @@ static int _tileidx_monster(int mon_idx, bool detected)
return tileidx_monster(mons, detected);
}
-static int _tileidx_fixed_artefact(int special)
+static int _tileidx_unrand_artefact(int idx)
{
- switch (special)
+ switch (idx)
{
case SPWPN_SINGING_SWORD: return TILE_SPWPN_SINGING_SWORD;
case SPWPN_WRATH_OF_TROG: return TILE_SPWPN_WRATH_OF_TROG;
@@ -1097,74 +1097,67 @@ static int _tileidx_fixed_artefact(int special)
case SPWPN_STAFF_OF_OLGREB: return TILE_SPWPN_STAFF_OF_OLGREB;
case SPWPN_VAMPIRES_TOOTH: return TILE_SPWPN_VAMPIRES_TOOTH;
case SPWPN_STAFF_OF_WUCAD_MU: return TILE_SPWPN_STAFF_OF_WUCAD_MU;
- }
-
- return TILE_ERROR;
-}
-static int _tileidx_unrand_artefact(int idx)
-{
- switch (idx)
- {
- case 2: return TILE_URAND_BLOODBANE;
- case 3: return TILE_URAND_SHADOWS;
- case 4: return TILE_URAND_FLAMING_DEATH;
- case 5: return TILE_URAND_IGNORANCE;
- case 6: return TILE_URAND_AIR;
- case 7: return TILE_URAND_AUGMENTATION;
- case 8: return TILE_URAND_BRILLIANCE;
- case 9: return TILE_URAND_THIEF;
- case 10: return TILE_URAND_BULLSEYE;
- case 11: return TILE_URAND_DYROVEPREVA;
- case 12: return TILE_URAND_LEECH;
- case 13: return TILE_URAND_CEKUGOB;
- case 14: return TILE_URAND_MISFORTUNE;
- case 15: return TILE_URAND_CHILLY_DEATH;
- case 16: return TILE_URAND_FOUR_WINDS;
- case 17: return TILE_URAND_MORG;
- case 18: return TILE_URAND_FINISHER;
- case 19: return TILE_URAND_PUNK;
- case 20: return TILE_URAND_KRISHNA;
- case 21: return TILE_URAND_FLASH;
- case 22: return TILE_URAND_SKULLCRUSHER;
- case 23: return TILE_URAND_ASSASSIN;
- case 24: return TILE_URAND_GUARD;
- case 25: return TILE_URAND_JIHAD;
- case 26: return TILE_URAND_LEAR;
- case 27: return TILE_URAND_ZHOR;
- case 28: return TILE_URAND_FIERY_DEVIL;
- case 29: return TILE_URAND_SALAMANDER;
- case 30: return TILE_URAND_WAR;
- case 31: return TILE_URAND_DOOM_KNIGHT;
- case 32: return TILE_URAND_RESISTANCE;
- case 33: return TILE_URAND_FOLLY;
- case 34: return TILE_URAND_BLOODLUST;
- case 35: return TILE_URAND_EOS;
- case 36: return TILE_URAND_SHAOLIN;
- case 37: return TILE_URAND_ROBUSTNESS;
- case 38: return TILE_URAND_MAXWELL;
- case 39: return TILE_URAND_VOO_DOO;
- case 40: return TILE_URAND_OCTOPUS_KING;
- case 41: return TILE_URAND_DRAGONMASK;
- case 42: return TILE_URAND_ARGA;
- case 43: return TILE_URAND_ELEMENTAL;
- case 44: return TILE_URAND_SNIPER;
- case 45: return TILE_URAND_ERCHIDEL;
- case 46: return TILE_URAND_NIGHT;
- case 47: return TILE_URAND_PLUTONIUM;
- case 48: return TILE_URAND_UNDEADHUNTER;
- case 49: return TILE_URAND_DRAGON_KING;
- case 50: return TILE_URAND_ALCHEMIST;
- case 51: return TILE_URAND_FENCER;
- case 52: return TILE_URAND_MAGE;
- case 53: return TILE_URAND_BLOWGUN;
- case 54: return TILE_URAND_WYRMBANE;
- case 55: return TILE_URAND_SPRIGGANS_KNIFE;
- case 56: return TILE_URAND_STARLIGHT;
- case 57: return TILE_URAND_BROOCH_OF_SHIELDING;
- case 58: return TILE_URAND_SERPENT_SCOURGE;
- case 59: return TILE_URAND_KNIFE_OF_ACCURACY;
- default: return TILE_TODO;
+ case UNRAND_BLOODBANE: return TILE_URAND_BLOODBANE;
+ case UNRAND_SHADOWS: return TILE_URAND_SHADOWS;
+ case UNRAND_FLAMING_DEATH: return TILE_URAND_FLAMING_DEATH;
+ case UNRAND_IGNORANCE: return TILE_URAND_IGNORANCE;
+ case UNRAND_AIR: return TILE_URAND_AIR;
+ case UNRAND_AUGMENTATION: return TILE_URAND_AUGMENTATION;
+ case UNRAND_BRILLIANCE: return TILE_URAND_BRILLIANCE;
+ case UNRAND_THIEF: return TILE_URAND_THIEF;
+ case UNRAND_BULLSEYE: return TILE_URAND_BULLSEYE;
+ case UNRAND_DYROVEPREVA: return TILE_URAND_DYROVEPREVA;
+ case UNRAND_LEECH: return TILE_URAND_LEECH;
+ case UNRAND_CEKUGOB: return TILE_URAND_CEKUGOB;
+ case UNRAND_MISFORTUNE: return TILE_URAND_MISFORTUNE;
+ case UNRAND_CHILLY_DEATH: return TILE_URAND_CHILLY_DEATH;
+ case UNRAND_FOUR_WINDS: return TILE_URAND_FOUR_WINDS;
+ case UNRAND_MORG: return TILE_URAND_MORG;
+ case UNRAND_FINISHER: return TILE_URAND_FINISHER;
+ case UNRAND_PUNK: return TILE_URAND_PUNK;
+ case UNRAND_KRISHNA: return TILE_URAND_KRISHNA;
+ case UNRAND_FLASH: return TILE_URAND_FLASH;
+ case UNRAND_SKULLCRUSHER: return TILE_URAND_SKULLCRUSHER;
+ case UNRAND_BLOWGUN_ASSASSIN: return TILE_URAND_ASSASSIN;
+ case UNRAND_GUARD: return TILE_URAND_GUARD;
+ case UNRAND_JIHAD: return TILE_URAND_JIHAD;
+ case UNRAND_LEAR: return TILE_URAND_LEAR;
+ case UNRAND_ZHOR: return TILE_URAND_ZHOR;
+ case UNRAND_SALAMANDER: return TILE_URAND_SALAMANDER;
+ case UNRAND_WAR: return TILE_URAND_WAR;
+ case UNRAND_DOOM_KNIGHT: return TILE_URAND_DOOM_KNIGHT;
+ case UNRAND_RESISTANCE: return TILE_URAND_RESISTANCE;
+ case UNRAND_FOLLY: return TILE_URAND_FOLLY;
+ case UNRAND_BLOODLUST: return TILE_URAND_BLOODLUST;
+ case UNRAND_EOS: return TILE_URAND_EOS;
+ case UNRAND_SHAOLIN: return TILE_URAND_SHAOLIN;
+ case UNRAND_ROBUSTNESS: return TILE_URAND_ROBUSTNESS;
+ case UNRAND_MAXWELL: return TILE_URAND_MAXWELL;
+ case UNRAND_BOTONO: return TILE_URAND_VOO_DOO;
+ case UNRAND_OCTOPUS_KING: return TILE_URAND_OCTOPUS_KING;
+ case UNRAND_DRAGONMASK: return TILE_URAND_DRAGONMASK;
+ case UNRAND_ARGA: return TILE_URAND_ARGA;
+ case UNRAND_ELEMENTAL_STAFF: return TILE_URAND_ELEMENTAL;
+ case UNRAND_SNIPER: return TILE_URAND_SNIPER;
+ case UNRAND_NIGHT: return TILE_URAND_NIGHT;
+ case UNRAND_PLUTONIUM: return TILE_URAND_PLUTONIUM;
+ case UNRAND_UNDEADHUNTER: return TILE_URAND_UNDEADHUNTER;
+ case UNRAND_DRAGON_KING: return TILE_URAND_DRAGON_KING;
+ case UNRAND_ALCHEMIST: return TILE_URAND_ALCHEMIST;
+ case UNRAND_FENCER: return TILE_URAND_FENCER;
+ case UNRAND_MAGE: return TILE_URAND_MAGE;
+ case UNRAND_BLOWGUN_ASSASSIN: return TILE_URAND_BLOWGUN;
+ case UNRAND_WYRMBANE: return TILE_URAND_WYRMBANE;
+ case UNRAND_SPRIGGANS_KNIFE: return TILE_URAND_SPRIGGANS_KNIFE;
+ case UNRAND_STARLIGHT: return TILE_URAND_STARLIGHT;
+ case UNRAND_SHIELDING: return TILE_URAND_BROOCH_OF_SHIELDING;
+ case UNRAND_SERPENT_SCOURGE: return TILE_URAND_SERPENT_SCOURGE;
+ case UNRAND_ACCURACY: return TILE_URAND_KNIFE_OF_ACCURACY;
+ case UNRAND_HELLFIRE: return TILE_URAND_FIERY_DEVIL;
+ //XXX: What happened to this unrand?
+ //case UNRAND_ERCHIDEL: return TILE_URAND_ERCHIDEL;
+ default: return TILE_TODO;
}
}
@@ -2037,10 +2030,8 @@ int tileidx_item(const item_def &item)
switch (clas)
{
case OBJ_WEAPONS:
- if (is_fixed_artefact(item))
- return _tileidx_fixed_artefact(special);
- else if (is_unrandom_artefact( item ))
- return _tileidx_unrand_artefact(find_unrandart_index(item) + 1);
+ if (is_unrandom_artefact( item ))
+ return _tileidx_unrand_artefact(find_unrandart_index(item));
else
return _tileidx_weapon(item);
@@ -2049,7 +2040,7 @@ int tileidx_item(const item_def &item)
case OBJ_ARMOUR:
if (is_unrandom_artefact( item ))
- return _tileidx_unrand_artefact(find_unrandart_index(item) + 1);
+ return _tileidx_unrand_artefact(find_unrandart_index(item));
else
return _tileidx_armour(item);
@@ -2094,7 +2085,7 @@ int tileidx_item(const item_def &item)
else
{
if (is_unrandom_artefact( item ))
- return _tileidx_unrand_artefact(find_unrandart_index(item) + 1);
+ return _tileidx_unrand_artefact(find_unrandart_index(item));
else if (is_random_artefact( item ))
return TILE_AMU_RANDOM_OFFSET + colour - 1;
else if (id[ IDTYPE_JEWELLERY][type] == ID_KNOWN_TYPE
@@ -3397,9 +3388,9 @@ int tilep_equ_weapon(const item_def &item)
if (item.base_type != OBJ_WEAPONS)
return 0;
- if (is_fixed_artefact( item ))
+ if (is_unrandom_artefact( item ))
{
- switch (item.special)
+ switch (find_unrandart_index(item))
{
case SPWPN_SINGING_SWORD: return TILEP_HAND1_SINGING_SWORD;
case SPWPN_WRATH_OF_TROG: return TILEP_HAND1_AXE_TROG;
@@ -3415,69 +3406,61 @@ int tilep_equ_weapon(const item_def &item)
case SPWPN_SWORD_OF_POWER: return TILEP_HAND1_SWORD_OF_POWER;
case SPWPN_VAMPIRES_TOOTH: return TILEP_HAND1_VAMPIRES_TOOTH;
case SPWPN_STAFF_OF_WUCAD_MU: return TILEP_HAND1_WUCAD_MU;
- }
- }
-
- if (is_unrandom_artefact( item ))
- {
- switch (find_unrandart_index(item) + 1)
- {
// Bloodbane
- case 2: return TILEP_HAND1_BLOODBANE;
+ case UNRAND_BLOODBANE: return TILEP_HAND1_BLOODBANE;
// Flaming Death
- case 4: return TILEP_HAND1_FLAMING_DEATH;
+ case UNRAND_FLAMING_DEATH: return TILEP_HAND1_FLAMING_DEATH;
// mace of Brilliance
- case 8: return TILEP_HAND1_MACE_OF_BRILLIANCE;
+ case UNRAND_BRILLIANCE: return TILEP_HAND1_MACE_OF_BRILLIANCE;
// demon blade Leech
- case 12: return TILEP_HAND1_LEECH;
+ case UNRAND_LEECH: return TILEP_HAND1_LEECH;
// dagger of Chilly Death
- case 15: return TILEP_HAND1_CHILLY_DEATH;
+ case UNRAND_CHILLY_DEATH: return TILEP_HAND1_CHILLY_DEATH;
// dagger "Morg"
- case 17: return TILEP_HAND1_MORG;
+ case UNRAND_MORG: return TILEP_HAND1_MORG;
// scythe "Finisher"
- case 18: return TILEP_HAND1_FINISHER;
+ case UNRAND_FINISHER: return TILEP_HAND1_FINISHER;
// sling "Punk
- case 19: return TILEP_HAND1_PUNK;
+ case UNRAND_PUNK: return TILEP_HAND1_PUNK;
// bow of Krishna
- case 20: return TILEP_HAND1_KRISHNA;
+ case UNRAND_KRISHNA: return TILEP_HAND1_KRISHNA;
// giant club "Skullcrusher"
- case 22: return TILEP_HAND1_GIANT_CLUB_SLANT;
+ case UNRAND_SKULLCRUSHER: return TILEP_HAND1_GIANT_CLUB_SLANT;
// glaive of the Guard
- case 24: return TILEP_HAND1_GLAIVE_OF_THE_GUARD;
+ case UNRAND_GUARD: return TILEP_HAND1_GLAIVE_OF_THE_GUARD;
// sword of Jihad
- case 25: return TILEP_HAND1_JIHAD;
+ case UNRAND_JIHAD: return TILEP_HAND1_JIHAD;
// crossbow "Fiery Devil"
- case 28: return TILEP_HAND1_FIERY_DEVIL;
+ case UNRAND_HELLFIRE: return TILEP_HAND1_FIERY_DEVIL;
// sword of Doom Knight
- case 31: return TILEP_HAND1_DOOM_KNIGHT;
+ case UNRAND_DOOM_KNIGHT: return TILEP_HAND1_DOOM_KNIGHT;
// Eos
- case 35: return TILEP_HAND1_EOS;
+ case UNRAND_EOS: return TILEP_HAND1_EOS;
// spear of Voo-Doo
- case 39: return TILEP_HAND1_VOODOO;
+ case UNRAND_BOTONO: return TILEP_HAND1_VOODOO;
// trident of the Octopus king
- case 40: return TILEP_HAND1_TRIDENT_OCTOPUS_KING;
+ case UNRAND_OCTOPUS_KING: return TILEP_HAND1_TRIDENT_OCTOPUS_KING;
// mithril axe "Arga"
- case 42: return TILEP_HAND1_ARGA;
+ case UNRAND_ARGA: return TILEP_HAND1_ARGA;
// Elemental Staff
- case 43: return TILEP_HAND1_ELEMENTAL_STAFF;
+ case UNRAND_ELEMENTAL_STAFF: return TILEP_HAND1_ELEMENTAL_STAFF;
// hand crossbow "Sniper"
- case 44: return TILEP_HAND1_SNIPER;
- // bow "Erchidel"
- case 45: return TILEP_HAND1_GREAT_BOW;
+ case UNRAND_SNIPER: return TILEP_HAND1_SNIPER;
// plutonium sword
- case 47: return TILEP_HAND1_PLUTONIUM_SWORD;
- // mace "Undeadhunter"
- case 48: return TILEP_HAND1_UNDEADHUNTER;
+ case UNRAND_PLUTONIUM: return TILEP_HAND1_PLUTONIUM_SWORD;
// blowgun of the Assassin
- case 53: return TILEP_HAND1_BLOWGUN_ASSASSIN;
+ case UNRAND_BLOWGUN_ASSASSIN: return TILEP_HAND1_BLOWGUN_ASSASSIN;
// Wyrmbane
- case 54: return TILEP_HAND1_WYRMBANE;
+ case UNRAND_WYRMBANE: return TILEP_HAND1_WYRMBANE;
// Spriggan's Knife
- case 55: return TILEP_HAND1_SPRIGGANS_KNIFE;
+ case UNRAND_SPRIGGANS_KINFE: return TILEP_HAND1_SPRIGGANS_KNIFE;
// whip "Serpent Scourge"
- case 58: return TILEP_HAND1_SERPENT_SCOURGE;
+ case UNRAND_SERPENT_SCOURGE: return TILEP_HAND1_SERPENT_SCOURGE;
// knife of Accuracy
- case 59: return TILEP_HAND1_KNIFE_OF_ACCURACY;
+ case UNRAND_ACCURACY: return TILEP_HAND1_KNIFE_OF_ACCURACY;
+ // bow "Erchidel"
+ // XXX: What happened to this unrand?
+ //case UNRAND_: return TILEP_HAND1_GREAT_BOW;
}
}
diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc
index c65c540d6b..1f886ebe53 100644
--- a/crawl-ref/source/tilesdl.cc
+++ b/crawl-ref/source/tilesdl.cc
@@ -1,6 +1,7 @@
#include "AppHdr.h"
REVISION("$Rev$");
+#include "artefact.h"
#include "cio.h"
#include "itemname.h"
#include "items.h"
@@ -9,7 +10,6 @@ REVISION("$Rev$");
#include "message.h"
#include "mon-util.h"
#include "player.h"
-#include "randart.h"
#include "state.h"
#include "stuff.h"
#include "tiles.h"
@@ -1344,11 +1344,8 @@ int tile_known_weapon_brand(const item_def item)
if (item.base_type == OBJ_WEAPONS)
{
- if (!is_fixed_artefact(item)
- && get_weapon_brand(item) != SPWPN_NORMAL)
- {
+ if (get_weapon_brand(item) != SPWPN_NORMAL)
return (TILE_BRAND_FLAMING + get_weapon_brand(item) - 1);
- }
}
else if (item.base_type == OBJ_MISSILES)
{
diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc
index 4570eeb7aa..070841ae21 100644
--- a/crawl-ref/source/transfor.cc
+++ b/crawl-ref/source/transfor.cc
@@ -16,6 +16,7 @@ REVISION("$Rev$");
#include "externs.h"
+#include "artefact.h"
#include "delay.h"
#include "invent.h"
#include "it_use2.h"
@@ -25,7 +26,6 @@ REVISION("$Rev$");
#include "misc.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "skills2.h"
#include "state.h"
#include "stuff.h"
@@ -401,7 +401,7 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove,
}
}
- if (is_random_artefact(item))
+ if (is_artefact(item))
{
prop_str += artefact_known_wpn_property(item, ARTP_STRENGTH);
prop_int += artefact_known_wpn_property(item, ARTP_INTELLIGENCE);
diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc
index ced11f2d1f..6768d44cba 100644
--- a/crawl-ref/source/traps.cc
+++ b/crawl-ref/source/traps.cc
@@ -14,6 +14,7 @@ REVISION("$Rev$");
#include <algorithm>
+#include "artefact.h"
#include "beam.h"
#include "branch.h"
#include "delay.h"
@@ -32,7 +33,6 @@ REVISION("$Rev$");
#include "ouch.h"
#include "place.h"
#include "player.h"
-#include "randart.h"
#include "skills.h"
#include "spells3.h"
#include "spl-mis.h"
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index e85ce7355d..e8388a1ce9 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -19,6 +19,7 @@ REVISION("$Rev$");
#include "tutorial.h"
#include "abl-show.h"
+#include "artefact.h"
#include "cloud.h"
#include "command.h"
#include "decks.h"
@@ -41,7 +42,6 @@ REVISION("$Rev$");
#include "newgame.h"
#include "output.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "shopping.h"
#include "skills2.h"
diff --git a/crawl-ref/source/unrand.h b/crawl-ref/source/unrand.h
deleted file mode 100644
index a0590a3b17..0000000000
--- a/crawl-ref/source/unrand.h
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * File: unrand.h
- * Summary: Definitions for unrandom artefacts.
- * Written by: Linley Henzell
- *
- * Modified for Crawl Reference by $Author$ on $Date$
- */
-#ifndef UNRAND_H
-#define UNRAND_H
-
-#include "defines.h"
-#include "itemprop.h"
-
-/*
- List of "unrandom" artefacts. Not the same as "fixed" artefacts, which are
- completely hardcoded (eg Singing Sword, Wrath of Trog).
- note: the order of the list doesn't matter
- Because the list numbering starts at 1, the last entry is the highest value
- which can be given to NO_UNRANDARTS (eg if the list consists of randarts no
- 1, 2 or 3, NO_UNRANDARTS must be set to 3 or lower, but probably not to 0).
- Setting it higher could cause nasty problems.
-
- Okay, so the steps to adding a new unrandart go as follows:
- 1) - Fill in a new entry below, using the following guidelines:
- true name: The name which is displayed when the item is id'd
- un-id'd name: obvious
- class: weapon, armour etc
- type: long sword, plate mail etc. Jewellery unrandarts have the powers of
- their base types in addition to anything else.
- plus: For weapons, plus to-hit. For armour, plus. For jewellery, irrelevant.
- But add 100 to make the item stickycursed. Note that the values for
- wpns and armr are +50.
- plus2: For wpns, plus to-dam. Curses are irrelevant here. Mostly unused
- for armr and totally for rings.
- colour: Obvious. Don't use BLACK, use DARKGREY instead.
-
- * Note * any exact combination of class, type, plus & plus2 must be unique,
- so (for example) you can't have two +5, +5 long swords in the list. Curses
- don't count as distinguishing factors.
-
- brand: Weapons only. Have a look in enum.h for a list, and look in fight.cc
- and describe.cc for the effects.
- Range of possible values: see enum.h
-
- +/- to AC, ev, str, int, dex - These are pretty obvious. Be careful - a player
- with a negative str, int or dex dies instantly, so avoid high penalties
- to these stats.
- Range: any, but be careful.
-
- res fire, res cold: Resists. Can be above 1; multiple sources of fire or cold
- resist *are* cumulative. Can also be -1 (but probably not -2 or below)
- for susceptibility.
- Range: -1 to about 5, after which you'll become almost immune.
- res elec: Resist electricity. Unlike fire and cold, resist electricity
- reduces electrical damage to 0. This makes multiple resists irrelevant.
- Also is no susceptibility, so don't use -1.
- Range: 0 or 1.
- res poison: same as res electricity.
- Range: 0 or 1.
- life prot: Stops energy draining and negative energy attacks. Not cumulative,
- and no susceptibility here either.
- Range: 0 or 1.
-
- res magic: This is cumulative, but no susceptibility. To be meaningful,
- should be set to about 20 - 60.
- Range: 0 to MAXINT probably, but about 100 is a realistic ceiling.
-
- see invis: Lets you see invisible things, but not submerged water beasts.
- Range: 0 or 1.
- turn invis: Gives you the ability to turn invisible using the 'a' menu.
- levitate, blink, go berserk, sense surroundings: like turn invis.
- Ranges for all these: 0 or 1.
-
- make noise: Irritate nearby creatures and disrupts rest. Weapons only.
- Range: 0 or 1.
- no spells: Prevents any spellcasting (but not scrolls or wands etc)
- Range: 0 or 1.
- teleport: Every now and then randomly teleports you. *Really* annoying.
- Weapons only.
- Range: 0 to about 15 (higher means more teleporting).
- no teleport: Prevents the player from teleporting, except rarely when they're
- forced to (eg banished to the Abyss).
- Range: 0 or 1.
-
- force berserk: Every time you attack, you go berserk. Weapons only.
- Range: 0 or 1.
- speed metabolism: Makes you consume food faster. No effect on mummies.
- Range: 0 to about 4. 4 would be horrible; 1 is annoying but tolerable.
- mutate: makes you mutate, sometimes after a long delay. No effect on some
- races (espec undead).
- Range: 0 to about 4.
- +/- to-hit/to-dam: Obvious. Affects both melee and missile. Should be left
- at 0 for weapons, which get +s normally.
-
- cursed: -1, 0, any positive value.
- Setting this to any value other than 0 will set the item's initial curse
- status as cursed. If the value is greater than zero, the item will also have
- one_chance_in(value) of recursing itself when re-equipped.
-
- stealth: -100 to 80. Adds to stealth value.
-
- Some currently unused properties follow, then:
-
- First string: is appended to the unrandart's description when id'd.
-
- Second string: replaces the thing at the start of a description.
- If empty, uses the description of the unrandart's base type. Note: the
- base type of a piece of unrandart jewellery is relevant to its function, so
- don't obscure it unnecessarily.
-
- Then another unused string.
-
- 2) - Add one to the #define NO_UNRANDARTS line in randart.h
-
- 3) - Maybe increase the probability of an unrandart of the appropriate
- type being created; look in dungeon.cc for this (search for "unrand").
- Forget this step if you don't understand it; it's of very little importance.
-
- Done! Now recompile and wait years for it to turn up.
-
- Note: changing NO_UNRANDARTS probably makes savefiles incompatible.
-
- */
-
-/* This is a dummy, but still counts for NO_UNRANDARTS */
-/* 1 */
-{
- "Dum", "",
-/* class, type, plus (to-hit), plus2 (depends on class), colour */
- OBJ_UNASSIGNED, 250, 250, 250, BLACK,
-/* Properties, all approx thirty of them: */
- {
-/* brand, +/- to AC, +/- to ev, +/- to str, +/- to int, +/- to dex */
- 0, 0, 0, 0, 0, 0,
-/* res fire, res cold, res elec, res poison, life protection, res magic */
- 0, 0, 0, 0, 0, 0,
-/* see invis, turn invis, levitate, blink, teleport at will, go berserk */
- 0, 0, 0, 0, 0, 0,
-/* sense surroundings, make noise, no spells, teleport, no teleport */
- 0, 0, 0, 0, 0,
-/* force berserk, speed metabolism, mutate, +/- to hit, +/- to dam (not weapons) */
- 0, 0, 0, 0, 0,
-/* cursed, stealth */
- 0, 0
- }
- ,
-/* Special description appended to the 'V' description */
- "",
-/* Base description of item */
- "",
-/* Unused string */
- ""
-}
-,
-
-
-/* 2 */
-{
- "long sword \"Bloodbane\"", "blackened long sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +7, +8, DARKGREY,
- {
- SPWPN_VORPAL, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, // go berserk
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, // force berserk
- 0, -20 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 3 */
-{
- "ring of Shadows", "black ring",
- OBJ_JEWELLERY, RING_INVISIBILITY, 0, 0, DARKGREY,
- {
- 0, 0, 4, 0, 0, 0, // EV
- 0, 0, 0, 0, 1, 0, // life prot
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, -3, 0, // to hit
- 0, 40 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 4 */
-{
- "scimitar of Flaming Death", "smoking scimitar",
- OBJ_WEAPONS, WPN_SCIMITAR, +7, +5, RED,
- {
- SPWPN_FLAMING, 0, 0, 0, 0, 0,
- 2, -1, 0, 1, 0, 20, // res fire, cold, poison, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 5 */
-{
- "shield of Ignorance", "dull large shield",
- OBJ_ARMOUR, ARM_LARGE_SHIELD, +5, 0, BROWN,
- {
- 0, 2, 2, 0, -6, 0, // AC, EV, int
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 3, 0 // cursed
- }
- ,
- "",
- "",
- ""
-}
-,
-
-
-/* 6 */
-{
- "amulet of the Air", "sky-blue amulet",
- OBJ_JEWELLERY, AMU_CONTROLLED_FLIGHT, 0, 0, LIGHTCYAN,
- {
- 0, 0, 3, 0, 0, 0, // EV
- 0, 0, 1, 0, 0, 0, // resElec
- 0, 0, 1, 0, 0, 0, // levitate
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 50 // stealth
- }
- ,
- "",
- "A sky-blue amulet.",
- ""
-}
-,
-
-/* 7 */
-{
- "robe of Augmentation", "silk robe",
- OBJ_ARMOUR, ARM_ROBE, +4, 0, LIGHTRED,
- {
- 0, 0, 0, 2, 2, 2, // str, int, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A robe made of the finest silk.",
- ""
-}
-,
-
-/* 8 */
-{
- "mace of Brilliance", "brightly glowing mace",
- OBJ_WEAPONS, WPN_MACE, +5, +5, WHITE,
- {
- SPWPN_HOLY_WRATH, 5, 0, 0, 5, 0, // AC, int
- 0, 0, 0, 0, 1, 0, // life prot
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, -20 // stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 9 */
-{
- "cloak of the Thief", "tattered cloak",
- OBJ_ARMOUR, ARM_CLOAK, +1, 0, DARKGREY,
- {
- 0, 0, 2, 0, 0, 2, // EV, dex
- 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 0, // see invis, turn invis, levitate
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, -3, // to dam
- 0, 60 // stealth
- }
- ,
- "It allows its wearer to excel in the arts of thievery.",
- "",
- ""
-}
-,
-
-/* 10 */
-{
- "shield \"Bullseye\"", "round shield",
- OBJ_ARMOUR, ARM_SHIELD, +10, 0, RED,
- {
- 0, 0, -5, 0, 0, 0, // EV
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 11 */
-{
- "crown of Dyrovepreva", "jewelled bronze crown",
- OBJ_ARMOUR, ARM_CAP, +3, 0, BROWN,
- {
- 0, 0, 0, 0, 2, 0, // int
- 0, 0, 1, 0, 0, 0, // res elec
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // speeds metabolism
- 0, 0
- }
- ,
- "",
- "A large crown of dull bronze, set with a dazzling array of gemstones.",
- ""
-}
-,
-
-
-/* 12 */
-{
- "demon blade \"Leech\"", "runed demon blade",
- OBJ_WEAPONS, WPN_DEMON_BLADE, +13, +4, MAGENTA,
- {
- SPWPN_VAMPIRICISM, 0, -1, -1, -1, -1, // AC, EV, str, int, dex
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 4, 0 // cursed
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 13 */
-{
- "amulet of Cekugob", "crystal amulet",
- OBJ_JEWELLERY, AMU_WARDING, +0, 0, LIGHTGREY,
- {
- 0, 1, 1, 0, 0, 0, // AC, EV
- 0, 0, 1, 1, 1, 0, // res elec, poison, life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, // prevent teleport
- 0, 2, 0, 0, 0, // speed metabolism
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-
-/* 14 */
-{
- "robe of Misfortune", "fabulously ornate robe",
- OBJ_ARMOUR, ARM_ROBE, -5, 0, MAGENTA,
- {
- 0, 0, -4, -2, -2, -2, // EV, str, int, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 0, // prevent spellcasting, cause teleport
- 0, 0, 5, 0, 0, // radiation
- 1, -80 // cursed, stealth
- }
- ,
- "",
- "A splendid flowing robe of fur and silk.",
- ""
-}
-
-,
-/* 15 */
-{
- "dagger of Chilly Death", "sapphire dagger",
- OBJ_WEAPONS, WPN_DAGGER, +5, +7, LIGHTBLUE,
- {
- SPWPN_FREEZING, 0, 0, 0, 0, 0,
- -1, 2, 0, 1, 0, 20, // res fire, cold, poison, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A dagger made of one huge piece of sapphire.",
- ""
-}
-,
-/* 16 */
-{
- "amulet of the Four Winds", "jade amulet",
- OBJ_JEWELLERY, AMU_CLARITY, +0, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 100, // life prot, magic resistance
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 17 */
-{
- "dagger \"Morg\"", "rusty dagger",
- OBJ_WEAPONS, WPN_DAGGER, -1, +4, LIGHTRED,
- {
- SPWPN_PAIN, 0, 0, 0, 5, 0, // int
- 0, 0, 0, 0, 0, 30, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "Many years ago it was the property of a powerful mage called "
- "Boris. He got lost in the Dungeon while seeking the Orb. ",
- "An ugly rusty dagger. ",
- ""
-}
-,
-
-/* 18 */
-{
- "scythe \"Finisher\"", "blackened scythe",
- OBJ_WEAPONS, WPN_SCYTHE, +3, +5, DARKGREY,
- {
- SPWPN_SPEED, 0, 0, 3, 0, 0, // str
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- -1, 0 // cursed
- }
- ,
- "",
- "A long and sharp scythe, specially modified for combat purposes.",
- ""
-}
-,
-
-/* 19 */
-{
- "sling \"Punk\"", "blue sling",
- OBJ_WEAPONS, WPN_SLING, +9, +12, LIGHTBLUE,
- {
- SPWPN_FROST, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, // res cold
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A sling made of weird blue leather.",
- ""
-}
-,
-/* 20 */
-{
- "bow of Krishna \"Sharnga\"", "golden bow",
- OBJ_WEAPONS, WPN_BOW, +8, +8, YELLOW,
- {
- SPWPN_SPEED, 0, 0, 0, 0, 3, // dex
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "It once belonged to a foreign god. It works best with "
- "special arrows which are not generally available.",
- "A wonderful golden bow. ",
- ""
-}
-,
-/* 21 */
-{
- "cloak of Flash", "vibrating cloak",
- OBJ_ARMOUR, ARM_CLOAK, +3, 0, RED,
- {
- 0, 0, 4, 0, 0, 0, // EV
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 1, 0, // levitate, teleport
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A vibrating cloak.",
- ""
-}
-,
-/* 22 */
-{
- "giant club \"Skullcrusher\"", "brutal giant club",
- OBJ_WEAPONS, WPN_GIANT_CLUB, +0, +5, BROWN,
- {
- SPWPN_SPEED, 0, 0, 5, 0, 0, // str
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 23 */
-{
- "boots of the Assassin", "soft boots",
- OBJ_ARMOUR, ARM_BOOTS, +2, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 3, // dex
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, // turn invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 80 // stealth
- }
- ,
- "These boots were specially designed by the Assassin's Guild.",
- "Some soft boots.",
- ""
-}
-,
-/* 24 */
-{
- "glaive of the Guard", "polished glaive",
- OBJ_WEAPONS, WPN_GLAIVE, +5, +8, LIGHTCYAN,
- {
- SPWPN_ELECTROCUTION, 5, 0, 0, 0, 0, // AC
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 1, // see invis, go berserk
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "This weapon once belonged to Gar Dogh, the guard of a king's treasures. "
- "According to legend he was lost somewhere in the Dungeon.",
- "",
- ""
-}
-,
-/* 25 */
-{
- "sword of Jihad", "crystal sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +12, +10, WHITE,
- {
- SPWPN_HOLY_WRATH, 0, 3, 0, 0, 0, // EV
- 0, 0, 0, 0, 1, 20, // life prot, res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, // force berserk
- 0, -50 // stealth (TSO hates backstab)
- }
- ,
- "This sword was The Shining One's gift to a worshipper.",
- "A long sword made of one huge piece of crystal.",
- ""
-}
-,
-/* 26 */
-{
- "Lear's chain mail", "golden chain mail",
- OBJ_ARMOUR, ARM_CHAIN_MAIL, -1, 0, YELLOW,
- {
- 0, 0, 0, 0, 0, -3, // dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- -1, 0 // cursed
- }
- ,
- "",
- "A chain mail made of pure gold.",
- ""
-}
-,
-/* 27 */
-{
- "skin of Zhor", "smelly skin",
- OBJ_ARMOUR, ARM_ANIMAL_SKIN, +4, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 2, 0, 0, 0, 0, // res cold
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "The skin of some strange animal.",
- ""
-}
-,
-/* 28 */
-{
- "crossbow \"Hellfire\"", "flaming crossbow",
- OBJ_WEAPONS, WPN_CROSSBOW, +6, +9, LIGHTRED,
- {
- SPWPN_FLAME, 0, 0, 0, 0, 0,
- 2, -1, 0, 0, 0, 40, // +2 fire, -1 cold, res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A flaming crossbow, forged in the fires of the Hells.",
- ""
-}
-,
-/* 29 */
-{
- "salamander hide armour", "red leather armour",
- OBJ_ARMOUR, ARM_LEATHER_ARMOUR, +3, 0, RED,
- {
- 0, 0, 0, 0, 0, 0,
- 2, 0, 0, 0, 0, 0, // res fire
- 0, 0, 0, 0, 0, 1, // go berserk
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A leather armour made of a salamander's skin.",
- ""
-}
-,
-/* 30 */
-{
- "gauntlets of War", "thick gauntlets",
- OBJ_ARMOUR, ARM_GLOVES, +3, 0, BROWN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 3, 3, // to hit, to dam
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 31 */
-{
- "sword of the Doom Knight", "adamantine great sword",
- OBJ_WEAPONS, WPN_GREAT_SWORD, +13, +13, BLUE,
- {
- SPWPN_PAIN, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 50, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "An adamantine great sword.",
- ""
-}
-,
-/* 32 */
-{
- "shield of Resistance", "bronze shield",
- OBJ_ARMOUR, ARM_SHIELD, +3, 0, LIGHTRED,
- {
- 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 0, 0, 40, // res fire, cold, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A bronze shield.",
- ""
-}
-,
-/* 33 */
-{
- "robe of Folly", "dull robe",
- OBJ_ARMOUR, ARM_ROBE, -1, 0, LIGHTGREY,
- {
- 0, 0, 0, 0, -5, 0, // int
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 0, // prevent spellcasting
- 0, 0, 0, 0, 0,
- 2, 0 // cursed
- }
- ,
- "",
- "A dull grey robe.",
- ""
-}
-,
-/* 34 */
-{
- "necklace of Bloodlust", "blood-stained necklace",
- OBJ_JEWELLERY, AMU_RAGE, +0, 0, RED,
- {
- 0, 0, 0, 2, -2, 0, // str, int
- 0, 0, 0, 0, 0, 30, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 3, // force berserk, to dam
- 3, -20 // cursed, stealth
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 35 */
-{
- "\"Eos\"", "encrusted morningstar",
- OBJ_WEAPONS, WPN_MORNINGSTAR, +5, +5, LIGHTCYAN,
- {
- SPWPN_ELECTROCUTION, 0, 0, 0, 0, 0, // morning -> bring light/sparks?
- 0, 0, 1, 0, 0, 0, // res elec
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 1, // prevent teleportation
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 36 */
-{
- "ring of Shaolin", "jade ring",
- OBJ_JEWELLERY, RING_EVASION, +8, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 37 */
-{
- "ring of Robustness", "steel ring",
- OBJ_JEWELLERY, RING_PROTECTION, +8, 0, LIGHTGREY,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 38 */
-{
- "Maxwell's patent armour", "weird-looking armour",
- OBJ_ARMOUR, ARM_PLATE_MAIL, +10, 0, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 1, 0, 1, // prevent spellcasting, prevent teleport
- 0, 0, 0, 0, 0,
- -1, 0 // cursed
- }
- ,
- "",
- "A weird-looking armour.",
- ""
-}
-,
-/* 39 */
-{
- // Was "spear of Voo-Doo". In the African origin, there is a distinction
- // between voodoo and bo, the latter dealing with curses, witchcraft and
- // spells designed to do harm. Priests (or rather sorcerors) of bo are
- // called botono.
- "spear of the Botono", "ebony spear",
- OBJ_WEAPONS, WPN_SPEAR, +2, +10, DARKGREY,
- {
- SPWPN_VAMPIRICISM, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 1, 0, // res poison, prot life
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // noise
- 0, 0, 0, 0, 0,
- 0, -30 // stealth
- }
- ,
- "A really dark and malign artefact, which no wise man would even touch.",
- "",
- ""
-}
-,
-/* 40 */
-{
- "trident of the Octopus King", "mangy trident",
- OBJ_WEAPONS, WPN_TRIDENT, +10, +4, CYAN,
- {
- SPWPN_VENOM, 0, 0, 0, 0, 0,
- 0, 0, 1, 1, 0, 50, // res elec, res poison, res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "This trident was stolen many years ago from the Octopus King's garden "
- "by a really unimportant and already dead man. But beware of the "
- "Octopus King's wrath!",
- "",
- ""
-}
-,
-/* 41 */
-{
- "mask of the Dragon", "blue mask",
- OBJ_ARMOUR, ARM_CAP, +0, 0, BLUE,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 40, // res magic
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 2, 2, // to hit, to dam
- 0, 0
- }
- ,
- "",
- "A blue mask.",
- ""
-}
-,
-/* 42 */
-{
- "mithril axe \"Arga\"", "mithril axe",
- OBJ_WEAPONS, WPN_WAR_AXE, +10, +6, WHITE,
- {
- SPWPN_SPEED, 0, 0, 2, 0, 0, // str
- 0, 0, 0, 0, 0, 30, // resist magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A beautiful mithril axe, probably lost by some dwarven hero.",
- ""
-}
-,
-/* 43 */
-{
- "Elemental Staff", "black staff",
- OBJ_WEAPONS, WPN_QUARTERSTAFF, +3, +1, DARKGREY,
- {
- SPWPN_PROTECTION, 0, 0, 0, 0, 0,
- 2, 2, 0, 0, 0, 60, // res fire, cold, magic
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // noise
- 0, 2, 0, 0, 0, // speed metabolism
- 0, 0
- }
- ,
- "This powerful staff used to belong to the leader of "
- "the Guild of Five Elements.",
- "A black glyphic staff.",
- ""
-}
-,
-/* 44 */
-{
- "hand crossbow \"Sniper\"", "black crossbow",
- OBJ_WEAPONS, WPN_HAND_CROSSBOW, +10, +0, DARKGREY,
- {
- SPWPN_VENOM, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, // see invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A hand crossbow made of some black material.",
- ""
-}
-,
-/* 45 */
-{
- "longbow \"Piercer\"", "very long metal bow",
- OBJ_WEAPONS, WPN_LONGBOW, +2, +10, CYAN,
- {
- SPWPN_VORPAL, 0, -2, 0, 0, 0, // ev
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "An exceptionally large metal longbow.",
- ""
-}
-,
-/* 46 */
-{
- "robe of Night", "black robe",
- OBJ_ARMOUR, ARM_ROBE, +4, 0, DARKGREY,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 30, // res magic
- 1, 1, 0, 0, 0, 0, // see invis, turn invis
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 50 // stealth
- }
- ,
- "According to legend, this robe was the gift of Ratri the Goddess of the Night "
- "to one of her followers.",
- "A long black robe made of strange flossy material.",
- ""
-}
-,
-/* 47 */
-{
- "plutonium sword", "glowing long sword",
- OBJ_WEAPONS, WPN_LONG_SWORD, +12, +16, LIGHTGREEN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 6, 0, 0, // radiation
- 1, -20 // cursed, stealth
- }
- ,
- "",
- "A long sword made of weird glowing metal.",
- ""
-}
-,
-/* 48 */
-{
- "great mace \"Undeadhunter\"", "great steel mace",
- OBJ_WEAPONS, WPN_GREAT_MACE, +7, +7, LIGHTGREY,
- {
- SPWPN_HOLY_WRATH, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, // life prot
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 49 */
-{
- "armour of the Dragon King", "shiny dragon armour",
- OBJ_ARMOUR, ARM_GOLD_DRAGON_ARMOUR, +5, 0, YELLOW,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 50, // res magic (base gives fire, cold, poison)
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-/* 50 */
-{
- "hat of the Alchemist", "dirty hat",
- OBJ_ARMOUR, ARM_WIZARD_HAT, +2, 0, MAGENTA,
- {
- 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 0, 0, 30, // res fire, cold, elec, magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A dirty hat.",
- ""
-}
-,
-/* 51 */
-{
- "Fencer's gloves", "silk gloves",
- OBJ_ARMOUR, ARM_GLOVES, +2, 0, WHITE,
- {
- 0, 0, 3, 0, 0, 3, // EV, dex
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 0, // to hit
- 0, 0
- }
- ,
- "",
- "A pair of gloves made of white silk.",
- ""
-}
-,
-/* 52 */
-{
- "ring of the Mage", "sapphire ring",
- OBJ_JEWELLERY, RING_WIZARDRY, +0, 0, LIGHTBLUE,
- {
- 0, 0, 0, 0, 3, 0, // int
- 0, 0, 0, 0, 0, 50, // res magic
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-}
-,
-
-/* 53 */
-{
- "blowgun of the Assassin", "tiny blowgun",
- OBJ_WEAPONS, WPN_BLOWGUN, +6, +6, WHITE,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, // turn invisible
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 60 // stealth
- }
- ,
- "",
- "It is designed for easy concealment, but still packs a nasty punch.",
- ""
-}
-,
-
-/* 54 */
-{
- "Wyrmbane", "scale-covered lance",
- OBJ_WEAPONS, WPN_SPEAR, +9, +6, GREEN,
- {
- SPWPN_DRAGON_SLAYING, 5, 0, 0, 0, 0, // AC
- 1, 0, 0, 1, 0, 0, // res fire, poison
- 0, 0, 0, 0, 0, 1, // go berserk
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "",
- ""
-},
-
-/* 55 */
-{
- "Spriggan's Knife", "dainty little knife",
- OBJ_WEAPONS, WPN_KNIFE, +4, +10, LIGHTCYAN,
- {
- 0, 0, 4, 0, 0, 4, // +EV, +Dex
- 0, 0, 0, 0, 0, 20, // +MR
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 50 // +stealth
- }
- ,
- "This knife was made by Spriggans, or for Spriggans, or possibly from "
- "Spriggans. Anyway, it's in some way associated with those fey folk.",
- "A dainty little knife.",
- ""
-},
-
-/* 56 */
-{
- "cloak of Starlight", "phosphorescent cloak",
- OBJ_ARMOUR, ARM_CLOAK, 0, 0, WHITE,
- {
- 0, 0, 4, 0, 0, 0, // EV
- 0, 1, 1, 0, 0, 0, // Cold, resElec
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, -30 // Stealth
- }
- ,
- "A cloak woven of pure light beams.",
- "A phosphorescent cloak.",
- ""
-},
-
-/* 57 */
-{
- "brooch of Shielding", "shield-shaped amulet",
- OBJ_JEWELLERY, AMU_WARDING, 0, 0, LIGHTBLUE,
- {
- 0, 4, 4, 0, 0, 0, // +AC, EV
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "Back in the good old days, every adventurer had one of these handy "
- "devices. That, and a pony.",
- "A shield-shaped amulet.",
- ""
-},
-
-/* 58 */
-{
- "whip \"Serpent-Scourge\"", "forked whip",
- OBJ_WEAPONS, WPN_WHIP, +5, +10, DARKGREY,
- {
- SPWPN_VENOM, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, // rPois
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "",
- "A double-ended whip made from the cured hides of the "
- "Lair of Beasts' deadly grey snakes.",
- ""
-},
-
-/* 59 */
-{
- // This used to be a fixed artefact but since it has no special
- // properties I decided it more closely fits here. (jpeg)
- "knife of Accuracy", "thin dagger",
- OBJ_WEAPONS, WPN_DAGGER, +27, -1, LIGHTCYAN,
- {
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "It is almost unerringly accurate.",
- "",
- ""
-},
-
-/* 60 */
-{
- // A play on the spell of the same name.
- // Colour taken from crystal walls.
- "Lehudib's crystal spear", "crystal spear",
- OBJ_WEAPONS, WPN_SPEAR, +6, +6, GREEN,
- {
- SPWPN_RETURNING, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, // noise
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "Presumably this relic led to the invention of the famous spell.",
- "",
- ""
-},
-
-/* 61 */
-{
- "ratskin cloak", "motley cloak",
- OBJ_ARMOUR, ARM_CLOAK, +1, 0, LIGHTRED,
- {
- 0, 0, 0, 0, -1, -1, // int, dex
- 0, 0, 0, 1, 1, 0, // life prot, pois
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0
- }
- ,
- "An enchantress with a magic loom and way too much time on "
- "her hands stitched this cloak from the hides of hundreds "
- "of rats, most of them orange. It's a bit awkward to wear "
- "and looks rather foolish, but it provides excellent protection "
- "from rats of all kinds.",
- "",
- ""
-},
-
-/* This is a dummy. */
-{
- "Dum", "",
-/* class, type, plus (to-hit), plus2 (depends on class), colour */
- OBJ_UNASSIGNED, 250, 250, 250, BLACK,
-/* Properties, all approx thirty of them: */
- {
-/* brand, +/- to AC, +/- to ev, +/- to str, +/- to int, +/- to dex */
- 0, 0, 0, 0, 0, 0,
-/* res fire, res cold, res elec, res poison, life protection, res magic */
- 0, 0, 0, 0, 0, 0,
-/* see invis, turn invis, levitate, blink, teleport at will, go berserk */
- 0, 0, 0, 0, 0, 0,
-/* sense surroundings, make noise, no spells, teleport, no teleport */
- 0, 0, 0, 0, 0,
-/* force berserk, speed metabolism, mutate, +/- to hit, +/- to dam (not weapons) */
- 0, 0, 0, 0, 0,
-/* cursed, stealth */
- 0, 0
- }
- ,
-/* 3 strings for describing the item in the 'V' display. */
- "",
- "",
- ""
-}
-#endif
diff --git a/crawl-ref/source/util/art-data.pl b/crawl-ref/source/util/art-data.pl
new file mode 100755
index 0000000000..bbd7e716dc
--- /dev/null
+++ b/crawl-ref/source/util/art-data.pl
@@ -0,0 +1,680 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $line_num = 0;
+my @errors = ();
+my @all_artefacts = ();
+my %used_names = ();
+my %used_appears = ();
+my %used_enums = ();
+
+my %field_type = (
+ AC => "num",
+ ACC => "num",
+ ANGRY => "num",
+ APPEAR => "str",
+ BERSERK => "num",
+ BLINK => "num",
+ BRAND => "enum",
+ CANTELEP => "num",
+ COLD => "num",
+ COLOUR => "enum",
+ CURSED => "num",
+ DAM => "num",
+ DESC => "str",
+ DESC_END => "str",
+ DESC_ID => "str",
+ DEX => "num",
+ ELEC => "num",
+ EV => "num",
+ FIRE => "num",
+ INT => "num",
+ INV => "num",
+ LEV => "num",
+ LIFE => "num",
+ MAGIC => "num",
+ MAPPING => "num",
+ METAB => "num",
+ MP => "num",
+ MUTATE => "num",
+ NAME => "str",
+ NOISES => "num",
+ NOSPELL => "num",
+ NOTELEP => "num",
+ POISON => "num",
+ RND_TELE => "num",
+ SEEINV => "num",
+ STEALTH => "num",
+ STR => "num",
+
+ plus => "num",
+ plus2 => "num",
+ base_type => "enum",
+ sub_type => "enum"
+);
+
+my @field_list = keys(%field_type);
+
+sub error
+{
+ my ($artefact, $str) = @_;
+
+ my $msg = "";
+
+ my $name = $artefact->{NAME} || $artefact->{APPEAR} || "NAMELESS";
+
+ if ($artefact->{_FINISHING})
+ {
+ $msg .= "Artefact $name starting at line "
+ . $artefact->{_START_LINE} . ": ";
+ }
+ else
+ {
+ $msg = "Artefact $name at line $line_num: "
+ }
+
+ $msg .= $str;
+
+ $artefact->{_ERRROR} = 1;
+
+ push(@errors, $msg);
+}
+
+sub is_number
+{
+ my ($num) = @_;
+ return ($num =~ /^[+-]?\d+$/);
+}
+
+sub finish_art
+{
+ my ($artefact) = @_;
+
+ $artefact->{_FINISHING} = 1;
+
+ my $must;
+ foreach $must ("NAME", "APPEAR", "OBJ", "COLOUR")
+ {
+ if (!defined($artefact->{$must}))
+ {
+ error($artefact, "Required field '$must' missing");
+ $artefact->{$must} = "_MISSING_";
+ }
+ }
+
+ # Prevent further errors caused by absence of OBJ
+ $artefact->{base_type} ||= "";
+ $artefact->{sub_type} ||= "";
+
+ if (!exists($artefact->{BRAND}))
+ {
+ my $type = $artefact->{base_type} || "";
+
+ if ($type eq "OBJ_WEAPONS")
+ {
+ $artefact->{BRAND} = "SPWPN_NORMAL";
+ }
+ elsif($type eq "OBJ_ARMOUR")
+ {
+ $artefact->{BRAND} = "SPARM_NORMAL";
+ }
+ else
+ {
+ $artefact->{BRAND} = "0";
+ }
+ }
+
+ my $field;
+ foreach $field (@field_list)
+ {
+ if (!exists($artefact->{$field}))
+ {
+ # Give default values for fields not specified.
+ my $type = $field_type{$field} || "";
+ if ($type eq "str")
+ {
+ $artefact->{$field} = "";
+ }
+ elsif($type eq "num")
+ {
+ $artefact->{$field} = "0";
+ }
+ elsif($type eq "enum")
+ {
+ error($artefact, "No enumeration for field '$field'");
+ }
+ else
+ {
+ error($artefact, "Unknown type '$type' for field '$field'");
+ }
+ }
+ elsif (!defined($artefact->{$field}))
+ {
+ error($artefact, "Field '$field' not defined");
+ }
+ }
+
+ delete($artefact->{_FINISHING});
+ $artefact->{_FINISHED} = 1;
+}
+
+sub process_line
+{
+ my ($artefact, $line) = @_;
+
+ # A line can start with whitespace if it's a continuation of a field
+ # with a string value.
+ if ($line =~ /^\s/)
+ {
+ my $prev_field = $artefact->{_PREV_FIELD} || "";
+ if ($field_type{$prev_field} eq "str")
+ {
+ $line =~ s/^\s*//;
+ $artefact->{$prev_field} .= " " . $line;
+ }
+ else
+ {
+ error($artefact, "line starts with whitespace");
+ }
+ return;
+ }
+
+ $artefact->{_START_LINE} ||= $line_num;
+
+ my ($field, $value) = ($line =~ /([^:]+):\s*(.*)/);
+
+ $field ||= "";
+ $value ||= "";
+
+ # Strip leading and trailing white space.
+ $field =~ s/^\s*|\s*$//g;
+ $value =~ s/^\s*|\s*$//g;
+
+ if ($field eq "")
+ {
+ error($artefact, "No field");
+ return;
+ }
+
+ if (defined($artefact->{$field}))
+ {
+ error($artefact, "Field '$field' already set");
+ return;
+ }
+
+ if ($value eq "true" && $field_type{$field} eq "num")
+ {
+ $value = "1";
+ }
+
+ $artefact->{_PREV_FIELD} = $field;
+ $artefact->{$field} = $value;
+
+ if ($value eq "")
+ {
+ error($artefact, "Field '$field' has no value");
+ return;
+ }
+
+ if ($field eq "OBJ")
+ {
+ my @parts = split(m!/!, $value);
+
+ if (@parts > 2)
+ {
+ error($artefact, "Too many parts to OBJ");
+ return;
+ }
+ elsif (@parts == 1)
+ {
+ error($artefact, "Too few parts to OBJ");
+ return;
+ }
+
+ if ($parts[0] !~ /^OBJ_/)
+ {
+ error($artefact, "OBJ base type must start with 'OBJ_'");
+ return;
+ }
+ $artefact->{base_type} = $parts[0];
+ $artefact->{sub_type} = $parts[1];
+ }
+ elsif($field eq "PLUS")
+ {
+ my @parts = split(m!/!, $value);
+
+ if (@parts > 2)
+ {
+ error($artefact, "Too many parts to PLUS");
+ return;
+ }
+
+ if (!is_number($parts[0]))
+ {
+ error($artefact, "'$parts[0]' in PLUS is not a number");
+ return;
+ }
+ if (@parts == 2 && !is_number($parts[1]))
+ {
+ error($artefact, "'$parts[1]' in PLUS is not a number");
+ return;
+ }
+ $artefact->{plus} = $parts[0];
+ $artefact->{plus2} = $parts[1] if (@parts == 2);
+ }
+ elsif ($field eq "ENUM")
+ {
+ }
+ else
+ {
+ if (!exists($field_type{$field}) || $field =~ /^[a-z]/)
+ {
+ error($artefact, "No such field as '$field'");
+ return;
+ }
+
+ my $num = is_number($value);
+ my $type = $field_type{$field} || "";
+
+ if (($type eq "num" && !$num) || ($type eq "str" && $num))
+ {
+ error($artefact, "'$value' invalid value type for field '$field'.");
+ return;
+ }
+ }
+
+ my $enum = "";
+
+ if ($field eq "NAME")
+ {
+ if (exists($used_names{$value}))
+ {
+ error($artefact, "Name \"$value\" already used at line " .
+ $used_names{$value});
+ return;
+ }
+ $used_names{$value} = $line_num;
+
+ if (!exists($artefact->{_ENUM}))
+ {
+ $enum = $value;
+ $enum =~ s/'//g;
+ # If possible, make the enum literal the part of the name between
+ # double quotes, or the part of the name after " of " or
+ # " of the ".
+ if ($enum =~ /"(.*)"/)
+ {
+ $enum = $1;
+ }
+ elsif ($enum =~ / of (?:the )?(.*)/)
+ {
+ $enum = $1;
+ }
+ $enum = uc($enum);
+ $enum =~ s/[ -]/_/g;
+ }
+ }
+ elsif ($field eq "APPEAR")
+ {
+ if (exists($used_appears{$value}))
+ {
+ error($artefact, "Name '$value' already used at line " .
+ $used_appears{$value});
+ return;
+ }
+ $used_appears{$value} = $line_num;
+ }
+ elsif ($field eq "ENUM")
+ {
+ if (exists($artefact->{NAME}))
+ {
+ eror($artefact, "ENUM must be before NAME");
+ return;
+ }
+ $enum = "$value";
+ }
+
+ if ($enum ne "")
+ {
+ if (exists($used_enums{$enum}))
+ {
+ error($artefact, "Enum \"$enum\" already used by artefact " .
+ "\"$used_enums{$enum}\"");
+ return;
+ }
+
+ $used_enums{$enum} = $value;
+ $artefact->{_ENUM} = $enum;
+ }
+}
+
+my @art_order = (
+ "NAME", "APPEAR", "\n",
+ "base_type", "sub_type", "plus", "plus2", "COLOUR",
+
+ "{", "BRAND", "AC", "EV", "STR", "INT", "DEX", "\n",
+ "FIRE", "COLD", "ELEC", "POISON", "LIFE", "MAGIC", "\n",
+ "SEEINV", "INV", "LEV", "BLINK", "CANTELEP", "BERSERK", "\n",
+ "MAPPING", "NOISES", "NOSPELL", "RND_TELE", "NOTELEP", "\n",
+ "ANGRY", "METAB", "MUTATE", "ACC", "DAM", "\n",
+ "CURSED", "STEALTH", "MP", "}",
+
+ "DESC", "\n",
+ "DESC_ID", "\n",
+ "DESC_END"
+);
+
+sub art_to_str
+{
+ my ($artefact) = @_;
+
+ my $indent = 1;
+
+ my $str = "{\n ";
+
+ my $part;
+ foreach $part (@art_order)
+ {
+ if (length($part) == 1)
+ {
+ if ($part eq "{")
+ {
+ $str .= "\n" . (" " x ($indent * 4)) . "{";
+ $indent++;
+ $str .= "\n" . (" " x ($indent * 4));
+ }
+ elsif($part eq "}")
+ {
+ $indent--;
+ $str .= "\n" . (" " x ($indent * 4)) . "},";
+ $str .= "\n" . (" " x ($indent * 4));
+ }
+ else
+ {
+ $str .= "\n" . (" " x ($indent * 4));
+ }
+ next;
+ }
+
+ if (!defined($field_type{$part}))
+ {
+ print STDERR "No field type for part '$part'\n";
+ next;
+ }
+
+ if ($field_type{$part} eq "str")
+ {
+ my $temp = $artefact->{$part};
+ $temp =~ s/"/\\"/g;
+ $str .= "\"$temp\"";
+ }
+ else
+ {
+ $str .= $artefact->{$part};
+ }
+ $str .= ", ";
+ }
+
+ $str .= "\n},\n\n";
+
+ return ($str);
+}
+
+sub write_data
+{
+ unless (open(HEADER, ">art-data.h"))
+ {
+ die "Couldn't open 'art-data.h' for writing: $!\n";
+ }
+
+ print HEADER <<"ENDofTEXT";
+/*
+ * File: art-data.h
+ * Summary: Definitions for unrandom artefacts.
+ * Written by: ????
+ *
+ * Modified for Crawl Reference by \$Author: dploog \$ on \$Date: 2009-06-17 22:29:07 -0700 (Wed, 17 Jun 2009) \$
+ */
+
+/*
+ * This file is automatically generated from art-data.txt via
+ * util/art-data.pl. Do not directly edit this file, but rather change
+ * art-data.txt.
+ *
+ * If the unrandart_entry struct is changed or a new artefact property is
+ * added to artefact_prop_type, then change art-data.pl so that the
+ * art-data.h file it produces matches up with the new structure.
+ */
+
+#ifdef ART_DATA_H
+#error "art-data.h included twice!"
+#endif
+
+#define ART_DATA_H
+
+ENDofTEXT
+
+ my $artefact;
+ my $art_num = 1;
+ foreach $artefact (@all_artefacts)
+ {
+ print HEADER "/* $art_num: UNRAND_$artefact->{_ENUM} */\n";
+ print HEADER art_to_str($artefact);
+ $art_num++;
+ }
+
+ close(HEADER);
+}
+
+sub write_enums
+{
+ unless (open(ENUM_IN, "<artefact.h"))
+ {
+ die "Couldn't open 'artefact.h' for reading: $!";
+ }
+
+ my $changed = 0;
+ my $out = "";
+
+ while(<ENUM_IN>)
+ {
+ last if (/^#define NO_UNRANDARTS/);
+ $out .= $_;
+ }
+
+ if (!/^#define NO_UNRANDARTS (\d+)/)
+ {
+ die "Couldn't find NO_UNRANDARTS in artefact.h\n";
+ }
+
+ my $orig_num = $1;
+ my $new_num = scalar(@all_artefacts);
+
+ if ($orig_num == $new_num)
+ {
+ print "Number of unrandarts unchanged.\n";
+ $out .= $_;
+ }
+ else
+ {
+ print "Number of unrandarts changed from $orig_num to $new_num\n";
+ $out .= "#define NO_UNRANDARTS $new_num\n";
+ $changed = 1;
+ }
+
+ while(<ENUM_IN>)
+ {
+ $out .= $_;
+ last if (/^enum unrand_type/);
+ }
+
+ if (!/^enum unrand_type/)
+ {
+ die "Couldn't find 'enum unrand_type' in artefact.h\n";
+ }
+
+ $out .= <ENUM_IN>; # {
+ $out .= <ENUM_IN>; # UNRAND_START = 180,
+
+ my @enum_list = ();
+ while(<ENUM_IN>)
+ {
+ last if (/\bUNRAND_LAST\b/);
+ /^\s*(\w+)/;
+ push(@enum_list, $1);
+ }
+
+ <ENUM_IN>; # discard "};"
+
+ # Suck in rest of file
+ undef($/);
+ my $remainder = <ENUM_IN>;
+ close(ENUM_IN);
+
+ if (@enum_list != @all_artefacts)
+ {
+ print "Enumeartion list changed.\n";
+ $changed = 1;
+ }
+ else
+ {
+ my $i;
+ for ($i = 0; $i < @enum_list; $i++)
+ {
+ if ($enum_list[$i] ne "UNRAND_$all_artefacts[$i]->{_ENUM}")
+ {
+ print "Enumeartion list changed.\n";
+ $changed = 1;
+ last;
+ }
+ }
+ }
+
+ if (!$changed)
+ {
+ print "No changes made to artefact.h\n";
+ return;
+ }
+
+ print "Updating artefact.h...\n";
+
+ unless(open(ENUM_OUT, ">artefact.h"))
+ {
+ die "Couldn't open 'artefact.h' for writing: $!\n";
+ }
+
+ print ENUM_OUT $out;
+
+ my $i;
+ my $longest_enum = 0;
+ for ($i = 0; $i < @all_artefacts; $i++)
+ {
+ my $enum = $all_artefacts[$i]->{_ENUM};
+ my $len = length($enum);
+ $longest_enum = $len if ($len > $longest_enum);
+ }
+
+ my $enum;
+ for ($i = 0; $i < @all_artefacts; $i++)
+ {
+ $enum = $all_artefacts[$i]->{_ENUM};
+
+ print ENUM_OUT " UNRAND_$enum";
+
+ if ($i == 0)
+ {
+ print ENUM_OUT " = UNRAND_START,\n";
+ }
+ else
+ {
+ print ENUM_OUT ", ";
+ print ENUM_OUT " " x ($longest_enum - length($enum));
+ print ENUM_OUT "// $all_artefacts[$i]->{NAME}\n";
+ }
+ }
+
+ print ENUM_OUT " UNRAND_LAST = UNRAND_$enum\n";
+ print ENUM_OUT "};\n";
+
+ print ENUM_OUT $remainder;
+
+ close(ENUM_OUT);
+}
+
+###############################################################3
+###############################################################3
+###############################################################3
+
+chdir("..") if (-e "../art-data.txt");
+chdir("source") if (-e "source/art-data.txt");
+
+die "Couldn't find art-data.txt\n" unless (-e "art-data.txt");
+die "Couldn't find artefact.h\n" unless (-e "artefact.h");
+die "Can't read art-data.txt\n" unless (-r "art-data.txt");
+die "Can't read artefact.h\n" unless (-r "artefact.h");
+die "Can't write to artefact.h\n" unless (-w "artefact.h");
+die "Can't write to art-data.h\n" if (-e "art-data.h" && !-w "art-data.h");
+
+unless(open(INPUT, "<art-data.txt"))
+{
+ die "Couldn't open art-data.txt for reading: $!\n";
+}
+
+my $prev_line = "";
+my $curr_art = {};
+
+while (<INPUT>)
+{
+ chomp;
+ $line_num++;
+
+ # Skip comment-only lines
+ next if (/^#/);
+
+ # Strip comments.
+ s/#.*//;
+
+ # Strip trailing whitspace; leading whitespace indicates the
+ # continuation of a string field.
+ s/\s*$//;
+
+ if ($_ =~ /^\s*$/)
+ {
+ if ($prev_line !~ /^\s*$/)
+ {
+ finish_art($curr_art);
+ push(@all_artefacts, $curr_art);
+ $curr_art = {};
+ }
+ }
+ else
+ {
+ process_line($curr_art, $_);
+ }
+ $prev_line = $_;
+}
+close(INPUT);
+
+if (keys(%$curr_art) > 0)
+{
+ finish_art($curr_art);
+ push(@all_artefacts, $curr_art);
+}
+
+if (@errors > 0)
+{
+ print STDERR "Error(s) processing art-data.txt:\n\n";
+
+ my $err;
+ foreach $err (@errors)
+ {
+ print STDERR "$err\n";
+ }
+ exit (1);
+}
+
+write_data();
+write_enums();
+
+exit (0);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 4f2e7d677a..054abcef1f 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -1432,7 +1432,7 @@ bool check_awaken(monsters* monster)
if (player_light_armour(true)
&& you.can_see(monster) // to avoid leaking information
&& you.burden_state == BS_UNENCUMBERED
- && you.special_wield != SPWLD_SHADOW
+ && you.unrand_reacts != SPWLD_SHADOW
&& !mons_wont_attack(monster)
&& !mons_class_flag(monster->type, M_NO_EXP_GAIN)
// If invisible, training happens much more rarely.
@@ -4966,7 +4966,7 @@ std::string screenshot( bool fullscreen )
static int _viewmap_flash_colour()
{
- if (you.special_wield == SPWLD_SHADOW)
+ if (you.unrand_reacts == SPWLD_SHADOW)
return (DARKGREY);
else if (you.duration[DUR_BERSERKER])
return (RED);
diff --git a/crawl-ref/source/xom.cc b/crawl-ref/source/xom.cc
index 872e51db31..1f1015f774 100644
--- a/crawl-ref/source/xom.cc
+++ b/crawl-ref/source/xom.cc
@@ -11,6 +11,7 @@ REVISION("$Rev$");
#include <algorithm>
+#include "artefact.h"
#include "beam.h"
#include "branch.h"
#include "database.h"
@@ -29,7 +30,6 @@ REVISION("$Rev$");
#include "notes.h"
#include "ouch.h"
#include "player.h"
-#include "randart.h"
#include "religion.h"
#include "spells1.h"
#include "spells2.h"
@@ -536,7 +536,7 @@ static void _try_brand_switch(const int item_index)
if (item.base_type != OBJ_WEAPONS || is_range_weapon(item))
return;
- if (is_unrandom_artefact(item) || is_fixed_artefact(item))
+ if (is_unrandom_artefact(item))
return;
// Only do it some of the time.
@@ -775,7 +775,7 @@ static bool _is_chaos_upgradeable(const item_def &item,
{
// Since Xom is a god he is capable of changing randarts, but not
// other artifacts.
- if (is_artefact(item) && !is_random_artefact(item))
+ if (is_unrandom_artefact(item))
return (false);
// Only upgrade permanent items, since the player should get a
@@ -914,7 +914,7 @@ static void _do_chaos_upgrade(item_def &item, const monsters* mon)
{
ASSERT(item.base_type == OBJ_MISSILES
|| item.base_type == OBJ_WEAPONS);
- ASSERT(!is_unrandom_artefact(item) && !is_fixed_artefact(item));
+ ASSERT(!is_unrandom_artefact(item));
bool seen = false;
if (mon && you.can_see(mon) && item.base_type == OBJ_WEAPONS)
@@ -3074,7 +3074,7 @@ void xom_check_lost_item(const item_def& item)
{
if (item.base_type == OBJ_ORBS)
xom_is_stimulated(255, "Xom laughs nastily.", true);
- else if (is_fixed_artefact(item))
+ else if (is_special_unrandom_artefact(item))
xom_is_stimulated(128, "Xom snickers.", true);
else if (is_rune(item))
{
@@ -3119,7 +3119,7 @@ void xom_check_destroyed_item(const item_def& item, int cause)
xom_is_stimulated(255, "Xom laughs nastily.", true);
return;
}
- else if (is_fixed_artefact(item))
+ else if (is_special_unrandom_artefact(item))
xom_is_stimulated(128, "Xom snickers.", true);
else if (is_rune(item))
{