summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2009-11-03 16:30:34 +0100
committerAdam Borowski <kilobyte@angband.pl>2009-11-03 16:30:34 +0100
commit2cba7ec21c6dab38df61ee06c5dacc78c0b218c7 (patch)
tree4766f1552c31e1da45975299e4c2ea4fa3d5383e
parent41e35978a7f48612ef9d8017379f8b2536739e43 (diff)
downloadcrawl-ref-2cba7ec21c6dab38df61ee06c5dacc78c0b218c7.tar.gz
crawl-ref-2cba7ec21c6dab38df61ee06c5dacc78c0b218c7.zip
Make Chain Lightning a monster spell, add an user of it (Nikola).
-rw-r--r--crawl-ref/source/dat/database/monspeak.txt11
-rw-r--r--crawl-ref/source/dat/descript/monsters.txt4
-rw-r--r--crawl-ref/source/dungeon.cc6
-rw-r--r--crawl-ref/source/enum.h2
-rw-r--r--crawl-ref/source/makeitem.cc36
-rw-r--r--crawl-ref/source/mon-cast.cc6
-rw-r--r--crawl-ref/source/mon-data.h12
-rw-r--r--crawl-ref/source/mon-spll.h11
-rw-r--r--crawl-ref/source/monster.cc8
-rw-r--r--crawl-ref/source/spells1.cc12
-rw-r--r--crawl-ref/source/spells1.h2
-rw-r--r--crawl-ref/source/spl-cast.cc2
12 files changed, 98 insertions, 14 deletions
diff --git a/crawl-ref/source/dat/database/monspeak.txt b/crawl-ref/source/dat/database/monspeak.txt
index 8611f974b0..792bad715a 100644
--- a/crawl-ref/source/dat/database/monspeak.txt
+++ b/crawl-ref/source/dat/database/monspeak.txt
@@ -2398,6 +2398,17 @@ w:1
@The_monster@ tries to tell @foe@ a complicated story about hydras, @possessive@ blood, and marriage.
## END NESSOS
%%%%
+############ NIKOLA ### A brilliant scientist obsessed with electricity.
+Nikola
+
+@The_monster@ yells, "Danger! Danger! High voltage!"
+
+@The_monster@ says, "Theres a spark of magic in your eyes."
+
+@The_monster@ raves, "Can you feel it? Can you feel it? CAN YOU FEEL IT?"
+
+@The_monster@ warns, "If you see one of my golems, approach with caution, they bite."
+%%%%
############ NORBERT ### A skilled warrior looking for some fame. More kills = more fame.
Norbert
diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt
index 540ea21b1b..772509d5af 100644
--- a/crawl-ref/source/dat/descript/monsters.txt
+++ b/crawl-ref/source/dat/descript/monsters.txt
@@ -244,6 +244,10 @@ Nessos
A black centaur warrior with a malicious look in the eyes.
%%%%
+Nikola
+
+A brilliant scientist obsessed with electricity. In his attempts to perfect his electric golem he was involved in a terrible accident, and now phases in and out of reality.
+%%%%
Norbert
A skilled warrior, looking to further develop his reputation as a great slayer of monsters. Be warned: he defines 'monster' rather more liberally than most dictionaries.
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index fcbcf9fb82..ece327f7b3 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -3354,19 +3354,19 @@ static monster_type _choose_unique_by_depth(int step)
ret = random_choose(MONS_URUG, MONS_MICHAEL, MONS_EUSTACHIO, MONS_SONJA,
MONS_SNORG, MONS_ERICA, MONS_JOSEPHINE, MONS_HAROLD,
MONS_ROXANNE, MONS_RUPERT, MONS_NORBERT, MONS_JOZEF,
- MONS_AZRAEL, MONS_NESSOS, MONS_AGNES,
+ MONS_AZRAEL, MONS_NESSOS, MONS_AGNES, MONS_NIKOLA,
MONS_MAUD, MONS_LOUISE, MONS_NERGALLE, MONS_KIRKE, -1);
break;
case 5: // depth <= 19
ret = random_choose(MONS_SNORG, MONS_LOUISE, MONS_FRANCIS, MONS_FRANCES,
MONS_RUPERT, MONS_WAYNE, MONS_DUANE, MONS_NORRIS,
- MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE,
+ MONS_AZRAEL, MONS_NESSOS, MONS_NERGALLE, MONS_NIKOLA,
MONS_ROXANNE, MONS_SAINT_ROKA, MONS_KIRKE, -1);
break;
case 6: // depth > 19
default:
ret = random_choose(MONS_FRANCIS, MONS_FRANCES, MONS_WAYNE, MONS_DUANE,
- MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK,
+ MONS_XTAHUA, MONS_NORRIS, MONS_FREDERICK, MONS_NIKOLA,
MONS_MARGERY, MONS_BORIS, MONS_SAINT_ROKA, -1);
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 2e188e3021..e675ff2059 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2093,6 +2093,7 @@ enum monster_type // (int) menv[].type
MONS_GASTRONOK,
MONS_MAURICE,
MONS_KHUFU,
+ MONS_NIKOLA,
// Testing monsters
MONS_TEST_SPAWNER,
@@ -2320,6 +2321,7 @@ enum mon_spellbook_type
MST_GASTRONOK,
MST_MAURICE,
MST_KHUFU,
+ MST_NIKOLA,
MST_TEST_SPAWNER = 170,
NUM_MSTYPES,
diff --git a/crawl-ref/source/makeitem.cc b/crawl-ref/source/makeitem.cc
index 6b2daa84c5..af4b77a81d 100644
--- a/crawl-ref/source/makeitem.cc
+++ b/crawl-ref/source/makeitem.cc
@@ -3831,6 +3831,16 @@ static item_make_species_type _give_weapon(monsters *mon, int level,
item.sub_type = (one_chance_in(3) ? WPN_FALCHION : WPN_SABRE);
break;
+ case MONS_NIKOLA:
+ force_item = true;
+ item_race = MAKE_ITEM_NO_RACE;
+ item.base_type = OBJ_WEAPONS;
+ item.sub_type = WPN_SABRE;
+ set_item_ego_type(item, OBJ_WEAPONS, SPWPN_ELECTROCUTION);
+ item.plus = random2(5);
+ item.plus2 = random2(5);
+ break;
+
case MONS_CEREBOV:
force_item = true;
make_item_unrandart(item, UNRAND_CEREBOV);
@@ -4194,7 +4204,16 @@ void give_shield(monsters *mon, int level)
make_item_for_monster(mon, OBJ_ARMOUR, ARM_SHIELD,
level * 2 + 1, MAKE_ITEM_RANDOM_RACE, 1);
break;
-
+ case MONS_NIKOLA:
+ {
+ make_item_for_monster(mon, OBJ_ARMOUR, ARM_GLOVES,
+ level * 2 + 1, MAKE_ITEM_NO_RACE, 1);
+
+ item_def *gaunt = mon->mslot_item(MSLOT_SHIELD);
+ if (gaunt)
+ gaunt->plus2 = TGLOV_DESC_GAUNTLETS;
+ }
+ break;
default:
break;
}
@@ -4462,6 +4481,13 @@ void give_armour(monsters *mon, int level)
force_colour = DARKGREY;
break;
+ case MONS_NIKOLA:
+ item_race = MAKE_ITEM_NO_RACE;
+ item.base_type = OBJ_ARMOUR;
+ item.sub_type = ARM_CLOAK;
+ force_colour = LIGHTCYAN;
+ break;
+
default:
return;
}
@@ -4487,6 +4513,14 @@ void give_armour(monsters *mon, int level)
// mv: All items with force_colour = 0 are colored via items().
if (force_colour)
mitm[thing_created].colour = force_colour;
+ switch(mon->type)
+ {
+ case MONS_NIKOLA:
+ mitm[thing_created].plus2 = TGLOV_DESC_GAUNTLETS;
+ break;
+ default:
+ break;
+ }
}
static void _give_gold(monsters *mon, int level)
diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc
index 619e719d2e..c621237be5 100644
--- a/crawl-ref/source/mon-cast.cc
+++ b/crawl-ref/source/mon-cast.cc
@@ -686,6 +686,7 @@ void setup_mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast)
case SPELL_BLINK:
case SPELL_CONTROLLED_BLINK:
case SPELL_TOMB_OF_DOROKLOHE:
+ case SPELL_CHAIN_LIGHTNING: // the only user is reckless
return;
default:
break;
@@ -1942,6 +1943,11 @@ void mons_cast(monsters *monster, bolt &pbolt, spell_type spell_cast,
monster->number = 1; // mark Khufu as entombed
return;
}
+ case SPELL_CHAIN_LIGHTNING:
+ if (!monsterNearby || mons_friendly(monster))
+ return;
+ cast_chain_lightning(4 * monster->hit_dice, monster);
+ return;
}
// If a monster just came into view and immediately cast a spell,
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index 73a6429d81..c9c16afc90 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -4593,6 +4593,18 @@ static monsterentry mondata[] = {
HT_LAND, 11, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, MONEAT_NOTHING, SIZE_MEDIUM
},
+{
+ MONS_NIKOLA, '@', LIGHTCYAN, "Nikola",
+ M_UNIQUE | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD
+ | M_SEE_INVIS | M_SPEAKS,
+ MR_NO_FLAGS, // Xom would hate MR_RES_ELEC here
+ 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5,
+ { {AT_HIT, AF_PLAIN, 20}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK },
+ { 18, 0, 0, 190 },
+ 1, 9, MST_NIKOLA, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL,
+ HT_LAND, 9, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, MONEAT_NOTHING, SIZE_MEDIUM
+},
+
// unique major demons ('&')
{
MONS_MNOLEG, '&', LIGHTGREEN, "Mnoleg",
diff --git a/crawl-ref/source/mon-spll.h b/crawl-ref/source/mon-spll.h
index 9f0fd017e1..1c1948dce4 100644
--- a/crawl-ref/source/mon-spll.h
+++ b/crawl-ref/source/mon-spll.h
@@ -1243,6 +1243,17 @@
}
},
+ { MST_NIKOLA,
+ {
+ SPELL_SHOCK,
+ SPELL_CHAIN_LIGHTNING,
+ SPELL_BLINK,
+ SPELL_LIGHTNING_BOLT,
+ SPELL_CHAIN_LIGHTNING,
+ SPELL_BLINK
+ }
+ },
+
{ MST_TEST_SPAWNER,
{
SPELL_SHADOW_CREATURES,
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index fd448b8fee..67df8f42ab 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -1482,9 +1482,13 @@ bool monsters::pickup_armour(item_def &item, int near, bool force)
eq = EQ_BODY_ARMOUR;
break;
case ARM_CLOAK:
- if (this->type == MONS_MAURICE)
+ if (this->type == MONS_MAURICE || this->type == MONS_NIKOLA)
eq = EQ_BODY_ARMOUR;
break;
+ case ARM_GLOVES:
+ if (this->type == MONS_NIKOLA)
+ eq = EQ_SHIELD;
+ break;
default:
eq = get_armour_slot(item);
}
@@ -2708,7 +2712,7 @@ bool monsters::caught() const
int monsters::shield_bonus() const
{
const item_def *shld = const_cast<monsters*>(this)->shield();
- if (shld)
+ if (shld && get_armour_slot(*shld) == EQ_SHIELD)
{
// Note that 0 is not quite no-blocking.
if (incapacitated())
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 798b639003..0a304bc908 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -349,15 +349,15 @@ bool _lightning_los(const coord_def& source, const coord_def& target)
return (exists_ray(source, target, opc_solid, bds_maxlos));
}
-void cast_chain_lightning(int pow)
+void cast_chain_lightning(int pow, const actor *caster)
{
bolt beam;
// initialise beam structure
beam.name = "lightning arc";
beam.aux_source = "chain lightning";
- beam.beam_source = MHITYOU;
- beam.thrower = KILL_YOU_MISSILE;
+ beam.beam_source = caster->mindex();
+ beam.thrower = (caster == &you) ? KILL_YOU_MISSILE : KILL_MON_MISSILE;
beam.range = 8;
beam.hit = AUTOMATIC_HIT;
beam.type = dchar_glyph(DCHAR_FIRED_ZAP);
@@ -369,7 +369,7 @@ void cast_chain_lightning(int pow)
coord_def source, target;
- for (source = you.pos(); pow > 0; pow -= 8 + random2(13), source = target)
+ for (source = caster->pos(); pow > 0; pow -= 8 + random2(13), source = target)
{
// infinity as far as this spell is concerned
// (Range - 1) is used because the distance is randomised and
@@ -477,8 +477,8 @@ void cast_chain_lightning(int pow)
beam.colour = LIGHTBLUE;
beam.damage = calc_dice(5, 12 + pow * 2 / 3);
- // Be kinder to the player.
- if (target == you.pos())
+ // Be kinder to the caster.
+ if (target == caster->pos())
{
if (!(beam.damage.num /= 2))
beam.damage.num = 1;
diff --git a/crawl-ref/source/spells1.h b/crawl-ref/source/spells1.h
index b32d719c24..dccf6f543f 100644
--- a/crawl-ref/source/spells1.h
+++ b/crawl-ref/source/spells1.h
@@ -41,7 +41,7 @@ void cast_deaths_door(int pow);
void setup_fire_storm(const actor *source, int pow, bolt &beam);
void cast_fire_storm(int pow, bolt &beam);
bool cast_hellfire_burst(int pow, bolt &beam);
-void cast_chain_lightning(int pow);
+void cast_chain_lightning(int pow, const actor *caster);
bool cast_revivification(int pow);
void cast_berserk(void);
void cast_ring_of_flames(int power);
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index 3794bfcb08..333c15ed39 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -1609,7 +1609,7 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail)
break;
case SPELL_CHAIN_LIGHTNING:
- cast_chain_lightning(powc);
+ cast_chain_lightning(powc, &you);
break;
case SPELL_DISPERSAL: