summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/dat/database/quotes.txt8
-rw-r--r--crawl-ref/source/dat/descript/monsters.txt11
-rw-r--r--crawl-ref/source/mon-data.h2
-rw-r--r--crawl-ref/source/mon-pick.cc4
-rw-r--r--crawl-ref/source/mon-util.cc5
-rw-r--r--crawl-ref/source/monplace.cc4
-rw-r--r--crawl-ref/source/monplace.h2
-rw-r--r--crawl-ref/source/monstuff.cc32
-rw-r--r--crawl-ref/source/ouch.cc70
-rw-r--r--crawl-ref/source/ouch.h2
10 files changed, 98 insertions, 42 deletions
diff --git a/crawl-ref/source/dat/database/quotes.txt b/crawl-ref/source/dat/database/quotes.txt
index 850d101888..cab525f359 100644
--- a/crawl-ref/source/dat/database/quotes.txt
+++ b/crawl-ref/source/dat/database/quotes.txt
@@ -627,6 +627,14 @@ griffon
His guarded gold."
-Milton, _Paradise Lost_, Book II. 1667.
%%%%
+harpy
+
+"Bird-bodied, girl-faced things they are; abominable their droppings, their hands are talons, their faces haggard with hunger insatiable."
+ -Virgil, Aeneid 3
+
+"And Phineus had scarcely taken the first morsel up when, with as little warning as a whirlwind or a lightning flash, they dropped from the clouds proclaiming their desire for food with raucous cries. The young lords saw them coming and raised the alarm. Yet they had hardly done so before the Harpyiai had devoured the whole meal and were on the wing once more, far out at sea. All they left was an intolerable stench."
+ -Apollonius Rhodius, Argonautica 2. 179 - 434
+%%%%
hobgoblin
"A foolish consistency is the hobgoblin of little minds."
diff --git a/crawl-ref/source/dat/descript/monsters.txt b/crawl-ref/source/dat/descript/monsters.txt
index 5060800209..5fb8161f46 100644
--- a/crawl-ref/source/dat/descript/monsters.txt
+++ b/crawl-ref/source/dat/descript/monsters.txt
@@ -131,6 +131,13 @@ Harold
An evil human bounty hunter.
%%%%
+harpy
+
+Harpies have roamed these coasts as long as seafarers can remember. They
+strike fear in the hearts of all sentient beings but not for their stings
+or claws. It is their way to steal food of the unwary causing many a men
+to starve to death.
+%%%%
Ijyb
A small and twisted goblin, wearing some ugly blue rags.
@@ -949,6 +956,10 @@ mermaid
A young woman with a fish tail in place of legs. Mermaids love to sing and charm their audience.
%%%%
+siren
+
+A young woman with a fish tail in place of legs. Sirens are capable of casting a powerful spell over their audience.
+%%%%
metal gargoyle
A hideous metal statue come to life.
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index 2964d3971e..04262cb1ee 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -2158,7 +2158,7 @@ static monsterentry mondata[] = {
{
MONS_HARPY, 'H', GREEN, "harpy",
M_FLIES | M_WARM_BLOOD | M_BATTY,
- MR_NO_FLAGS,
+ MR_RES_POISON,
1000, 10, MONS_HARPY, MONS_HARPY, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 8},
{AT_CLAW, AF_STEAL_FOOD, 5}, AT_NO_ATK },
diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc
index 940bd6f1f9..80fc58d920 100644
--- a/crawl-ref/source/mon-pick.cc
+++ b/crawl-ref/source/mon-pick.cc
@@ -1710,6 +1710,7 @@ int mons_shoals_level(int mcls)
case MONS_SIREN:
case MONS_YAKTAUR:
+ case MONS_MANTICORE:
mlev += 2;
break;
@@ -1761,14 +1762,15 @@ int mons_shoals_rare(int mcls)
case MONS_CYCLOPS:
case MONS_CENTAUR_WARRIOR:
+ case MONS_HARPY:
return 20;
case MONS_STONE_GIANT:
case MONS_YAKTAUR_CAPTAIN:
- case MONS_HARPY:
return 10;
case MONS_OKLOB_PLANT:
+ case MONS_MANTICORE:
return 5;
default:
return 0;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 3e6cf8ceec..93da5b7121 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -537,7 +537,8 @@ bool mons_is_native_in_branch(const monsters *monster,
case BRANCH_SHOALS:
return (mons_species(monster->type) == MONS_CYCLOPS
|| mons_species(monster->type) == MONS_MERFOLK
- || mons_genus(monster->type) == MONS_MERMAID);
+ || mons_genus(monster->type) == MONS_MERMAID
+ || monster->type == MONS_HARPY);
case BRANCH_SLIME_PITS:
return (mons_species(monster->type) == MONS_JELLY);
@@ -2955,7 +2956,7 @@ const char *mons_pronoun(monster_type mon_type, pronoun_type variant,
{
gender_type gender = GENDER_NEUTER;
- if (mons_genus(mon_type) == MONS_MERMAID)
+ if (mons_genus(mon_type) == MONS_MERMAID || mon_type == MONS_HARPY)
gender = GENDER_FEMALE;
else if (mons_is_unique(mon_type) && mon_type != MONS_PLAYER_GHOST)
{
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 487bbd6704..2bb70188b6 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -1459,7 +1459,7 @@ static band_type _choose_band( int mon_type, int power, int &band_size )
band_size = 3 + random2(3);
break;
case MONS_HARPY:
- band = BAND_HARPYES;
+ band = BAND_HARPIES;
band_size = 2 + random2(3);
break;
@@ -1568,7 +1568,7 @@ static monster_type _band_member(band_type band, int power)
mon_type = MONS_YAK;
break;
- case BAND_HARPYES:
+ case BAND_HARPIES:
mon_type = MONS_HARPY;
case BAND_UGLY_THINGS:
diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h
index 1cc3422cd2..4ddd2d1a21 100644
--- a/crawl-ref/source/monplace.h
+++ b/crawl-ref/source/monplace.h
@@ -63,7 +63,7 @@ enum band_type
BAND_SKELETAL_WARRIORS,
BAND_DRACONIAN, // 45
BAND_PANDEMONIUM_DEMON,
- BAND_HARPYES, // 47
+ BAND_HARPIES, // 47
NUM_BANDS // always last
};
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 2d42ce61af..259dfc95f6 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -4056,6 +4056,14 @@ static bool _ranged_allied_monster_in_dir(monsters *mon, coord_def p)
if (mons_aligned(monster_index(mon), mgrd(pos)))
{
+ // Hostile monsters of normal intelligence only move aside for
+ // monsters of the same type.
+ if (mons_intel(mon) <= I_NORMAL && !mons_wont_attack(mon)
+ && mons_genus(mon->type) != mons_genus((&menv[mgrd(pos)])->type))
+ {
+ return (false);
+ }
+
monsters *m = &menv[mgrd(pos)];
if (mons_has_ranged_attack(m) || mons_has_ranged_spell(m))
return (true);
@@ -6395,8 +6403,9 @@ static void _handle_monster_move(int i, monsters *monster)
monster->shield_blocks = 0;
const int cloud_num = env.cgrid(monster->pos());
- const cloud_type cl_type =
- cloud_num == EMPTY_CLOUD ? CLOUD_NONE : env.cloud[cloud_num].type;
+ const cloud_type cl_type = cloud_num == EMPTY_CLOUD ? CLOUD_NONE
+ : env.cloud[cloud_num].type;
+
if (cloud_num != EMPTY_CLOUD)
{
if (_mons_avoids_cloud(monster, cl_type))
@@ -6456,6 +6465,23 @@ static void _handle_monster_move(int i, monsters *monster)
continue;
}
+ // Harpyes may eat food/corpses on the ground.
+ if (monster->type == MONS_HARPY && !mons_is_fleeing(monster)
+ && (mons_wont_attack(monster)
+ || (monster->pos() - you.pos()).rdist() > 1)
+ && (mons_is_wandering(monster) && one_chance_in(3)
+ || one_chance_in(5))
+ && expose_items_to_element(BEAM_STEAL_FOOD, monster->pos(), 10))
+ {
+ if (mons_near(monster) && player_monster_visible(monster))
+ {
+ simple_monster_message(monster,
+ " eats something on the ground.");
+ }
+ monster->speed_increment -= non_move_energy;
+ continue;
+ }
+
if (mons_is_zombified(monster)
&& monster->type != MONS_SPECTRAL_THING)
{
@@ -6759,7 +6785,7 @@ void handle_monsters()
_handle_monster_move(i, monster);
- if (!invalid_monster(monster) && (monster->pos() != oldpos))
+ if (!invalid_monster(monster) && monster->pos() != oldpos)
immobile_monster[i] = true;
// If the player got banished, discard pending monster actions.
diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc
index 436d24a82f..50b2dbb25f 100644
--- a/crawl-ref/source/ouch.cc
+++ b/crawl-ref/source/ouch.cc
@@ -490,6 +490,9 @@ static bool _expose_invent_to_element(beam_type flavour, int strength)
if (!num_dest)
return (false);
+ if (flavour == BEAM_STEAL_FOOD)
+ return (true);
+
switch (target_class)
{
case OBJ_SCROLLS:
@@ -506,8 +509,7 @@ static bool _expose_invent_to_element(beam_type flavour, int strength)
break;
case OBJ_FOOD:
- if (flavour == BEAM_SPORE)
- mpr("Some of your food is covered with spores!");
+ mpr("Some of your food is covered with spores!");
break;
default:
@@ -518,17 +520,18 @@ static bool _expose_invent_to_element(beam_type flavour, int strength)
}
xom_is_stimulated((num_dest > 1) ? 32 : 16);
+
return (true);
}
-void expose_items_to_element(beam_type flavour, const coord_def& where,
+bool expose_items_to_element(beam_type flavour, const coord_def& where,
int strength)
{
int num_dest = 0;
const int target_class = _get_target_class(flavour);
if (target_class == OBJ_UNASSIGNED)
- return;
+ return (false);
for (stack_iterator si(where); si; ++si)
{
@@ -550,37 +553,42 @@ void expose_items_to_element(beam_type flavour, const coord_def& where,
}
}
- if (num_dest)
+ if (!num_dest)
+ return (false);
+
+ if (flavour == BEAM_STEAL_FOOD)
+ return (true);
+
+ if (see_grid(where))
{
- if (see_grid(where))
+ switch (target_class)
{
- switch (target_class)
- {
- case OBJ_SCROLLS:
- mprf("You see %s of smoke.",
- (num_dest > 1) ? "some puffs" : "a puff");
- break;
-
- case OBJ_POTIONS:
- mprf("You see %s shatter.",
- (num_dest > 1) ? "some glass" : "glass");
- break;
-
- case OBJ_FOOD:
- mprf("You see %s of spores.",
- (num_dest > 1) ? "some clouds" : "a cloud");
- break;
-
- default:
- mprf("%s on the floor %s destroyed!",
- (num_dest > 1) ? "Some items" : "An item",
- (num_dest > 1) ? "were" : "was" );
- break;
- }
+ case OBJ_SCROLLS:
+ mprf("You see %s of smoke.",
+ (num_dest > 1) ? "some puffs" : "a puff");
+ break;
+
+ case OBJ_POTIONS:
+ mprf("You see %s shatter.",
+ (num_dest > 1) ? "some glass" : "glass");
+ break;
+
+ case OBJ_FOOD:
+ mprf("You see %s of spores.",
+ (num_dest > 1) ? "some clouds" : "a cloud");
+ break;
+
+ default:
+ mprf("%s on the floor %s destroyed!",
+ (num_dest > 1) ? "Some items" : "An item",
+ (num_dest > 1) ? "were" : "was" );
+ break;
}
-
- xom_is_stimulated((num_dest > 1) ? 32 : 16);
}
+
+ xom_is_stimulated((num_dest > 1) ? 32 : 16);
+
+ return (true);
}
// Handle side-effects for exposure to element other than damage. This
diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h
index 3bcb532387..5bf341c990 100644
--- a/crawl-ref/source/ouch.h
+++ b/crawl-ref/source/ouch.h
@@ -73,7 +73,7 @@ void ouch(int dam, int death_source, kill_method_type death_type,
void lose_level(void);
void drain_exp(bool announce_full = true);
-void expose_items_to_element(beam_type flavour, const coord_def& where,
+bool expose_items_to_element(beam_type flavour, const coord_def& where,
int strength = 0);
bool expose_player_to_element(beam_type flavour, int strength = 0);