summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-11-04 15:53:36 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2007-11-04 15:53:36 +0000
commit832060cd98c97e3bce6e2fe122b0a6a90fb042ed (patch)
tree22326a8b66843e6e012cceb919683bfebdf8e05d /crawl-ref/source
parenta90b4adaf06986bbf6fcd0dce08b4b122d9b9e80 (diff)
downloadcrawl-ref-832060cd98c97e3bce6e2fe122b0a6a90fb042ed.tar.gz
crawl-ref-832060cd98c97e3bce6e2fe122b0a6a90fb042ed.zip
Nets that hold you cannot be destroyed by Ely's Destroy Weapon ability.
(Fix 1825520). Monsters will be held in nets longer. Doesn't influence time needed to destroy it, so ogres and such will still get out quickly. Needs more testing, I guess. Intelligent friendlies will try to avoid traps you (the player) know about, and the chance for triggering known blade and net traps is much lower. Also, friendly casters are much less likely to spam you with "spells" if there are no enemies around. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2749 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/mon-util.cc11
-rw-r--r--crawl-ref/source/mon-util.h2
-rw-r--r--crawl-ref/source/monstuff.cc49
-rw-r--r--crawl-ref/source/mstuff2.cc18
-rw-r--r--crawl-ref/source/religion.cc3
5 files changed, 69 insertions, 14 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 9f9cd74b41..06d4b5586a 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -1685,6 +1685,13 @@ mon_intel_type mons_intel(int mc)
return (smc->intel);
}
+bool intelligent_ally(const monsters *monster)
+{
+ return (monster->attitude == ATT_FRIENDLY
+ && mons_intel(monster->type) >= I_NORMAL);
+}
+
+
int mons_power(int mc)
{
// for now, just return monster hit dice.
@@ -5165,7 +5172,7 @@ int mon_enchant::calc_duration(const monsters *mons,
cturn = std::max(100 / modded_speed(mons, 5), 3);
break;
case ENCH_HELD:
- cturn = 90 / mod_speed(25, mons->speed);
+ cturn = 120 / mod_speed(25, mons->speed);
break;
case ENCH_POISON:
cturn = 1000 * deg / mod_speed(125, mons->speed);
@@ -5360,7 +5367,7 @@ std::string do_mon_str_replacements(const std::string &in_msg,
sound_list[mons_shouts(monster->type)]);
// The proper possessive for a word ending in an "s" is to
- // put an appostraphe after the "s": "Chris" -> "Chris'",
+ // put an apostrophe after the "s": "Chris" -> "Chris'",
// not "Chris" -> "Chris's". Stupid English language...
msg = replace_all(msg, "s's", "s'");
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index 988d13499b..ef8aa03a2b 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -426,6 +426,8 @@ bool mons_is_summoned(const monsters *m);
* *********************************************************************** */
mon_intel_type mons_intel(int mclass);
+bool intelligent_ally(const monsters *mon);
+
// last updated 12may2000 {dlb}
/* ***********************************************************************
* called from: beam - fight - monstuff
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index a925b423cc..627bfe0643 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -46,6 +46,7 @@
#include "Kills.h"
#include "makeitem.h"
#include "message.h"
+#include "misc.h"
#include "monplace.h"
#include "monspeak.h"
#include "mon-pick.h"
@@ -3472,6 +3473,14 @@ static bool mons_announce_cast(monsters *monster, bool nearby,
return (true);
}
+static bool enemies_around(const monsters *monster)
+{
+ if (mons_friendly(monster))
+ return (!mons_near(monster) || !i_feel_safe());
+ else
+ return (mons_near(monster));
+}
+
//---------------------------------------------------------------
//
// handle_spell
@@ -3522,9 +3531,9 @@ static bool handle_spell( monsters *monster, bolt & beem )
spell_type spell_cast = SPELL_NO_SPELL;
monster_spells hspell_pass = monster->spells;
- // forces the casting of dig when player not visible - this is EVIL!
- if (!monsterNearby)
+ if (!enemies_around(monster))
{
+ // forces the casting of dig when player not visible - this is EVIL!
if (hspell_pass[4] == SPELL_DIG && monster->behaviour == BEH_SEEK)
{
spell_cast = SPELL_DIG;
@@ -3553,15 +3562,15 @@ static bool handle_spell( monsters *monster, bolt & beem )
finalAnswer = true;
}
}
- else if (monster->foe == MHITYOU)
+ else if (monster->foe == MHITYOU && !monsterNearby)
{
return (false);
}
}
// monsters caught in a net try to get away
- // this is only urgent if you are around
- if (!finalAnswer && monsterNearby && mons_is_caught(monster)
+ // this is only urgent if enemies are around
+ if (!finalAnswer && enemies_around(monster) && mons_is_caught(monster)
&& one_chance_in(4))
{
for (int i = 0; i < 6; i++)
@@ -3599,6 +3608,13 @@ static bool handle_spell( monsters *monster, bolt & beem )
if (!finalAnswer)
{
+ // if nothing found by now, safe friendlies will rarely cast
+ if (mons_friendly(monster) && !enemies_around(monster)
+ && !one_chance_in(8))
+ {
+ return (false);
+ }
+
// should monster not have selected dig by now, it never will:
if (hspell_pass[4] == SPELL_DIG)
hspell_pass[4] = SPELL_NO_SPELL;
@@ -4831,7 +4847,30 @@ static bool is_trap_safe(const monsters *monster, const trap_struct &trap)
if (trap.type == TRAP_SHAFT && monster->will_trigger_shaft())
return (false);
+
+ // permanent intelligent friendlies will try to avoid traps
+ // the player knows about (this could be annoying in a corridor)
+ if (grd[monster->x][monster->y] != DNGN_UNDISCOVERED_TRAP
+ && trap_category(trap.type) != DNGN_TRAP_MAGICAL // magic doesn't matter
+ && intelligent_ally(monster))
+ {
+ const int x = monster->x;
+ const int y = monster->y;
+ // test for corridor-like environment (simple hack)
+ if (!(grd[x-1][y] < DNGN_MINMOVE && grd[x+1][y] < DNGN_MINMOVE
+ || grd[x][y-1] < DNGN_MINMOVE && grd[x][y+1] < DNGN_MINMOVE))
+ {
+ return (monster->hit_points == monster->max_hit_points);
+ }
+ }
+ // friendlies will try not to be parted from you
+ if (intelligent_ally(monster) && trap.type == TRAP_TELEPORT
+ && mons_near(monster))
+ {
+ return (false);
+ }
+
// Healthy monsters don't mind a little pain. XXX: Smart humanoids
// with low hp should probably not try to go through high-damage
// traps.
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index bd118219df..4fa901ca08 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -90,7 +90,7 @@ void mons_trap(struct monsters *monster)
}
//
- // Trap damage to monsters is not a function of level, beacuse they
+ // Trap damage to monsters is not a function of level, because they
// are fairly stupid and tend to have fewer hp than players -- this
// choice prevents traps from easily killing large monsters fairly
// deep within the dungeon.
@@ -177,7 +177,8 @@ void mons_trap(struct monsters *monster)
// resulting in an "early return" from this f(x) for
// some - otherwise, blade *always* revealed: {dlb}
case TRAP_BLADE:
- if (one_chance_in(5))
+ if (one_chance_in(5)
+ || trapKnown && intelligent_ally(monster) && coinflip())
{
if (trapKnown)
{
@@ -186,7 +187,9 @@ void mons_trap(struct monsters *monster)
}
return; // early return {dlb}
}
- else if (random2(monster->ev) > 8)
+
+ if (random2(monster->ev) > 8
+ || trapKnown && intelligent_ally(monster) && random2(monster->ev) > 8)
{
if (monsterNearby && !simple_monster_message(monster,
" avoids a huge, swinging blade."))
@@ -222,7 +225,8 @@ void mons_trap(struct monsters *monster)
case TRAP_NET:
{
- if (one_chance_in(3))
+ if (one_chance_in(3)
+ || trapKnown && intelligent_ally(monster) && coinflip())
{
if (trapKnown)
{
@@ -232,7 +236,8 @@ void mons_trap(struct monsters *monster)
return;
}
- if (random2(monster->ev) > 8)
+ if (random2(monster->ev) > 8
+ || trapKnown && intelligent_ally(monster) && random2(monster->ev) > 8)
{
if (monsterNearby && !simple_monster_message(monster,
" nimbly jumps out of the way of a falling net."))
@@ -332,7 +337,8 @@ void mons_trap(struct monsters *monster)
return;
}
- if (!monster->will_trigger_shaft())
+ if (!monster->will_trigger_shaft()
+ || trapKnown && intelligent_ally(monster))
{
if (trapKnown && !monster->airborne())
simple_monster_message(monster,
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 57217e8218..093aaac8fa 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -1804,7 +1804,8 @@ bool ely_destroy_weapons()
const int next = mitm[i].link; // in case we can't get it later.
if (mitm[i].base_type != OBJ_WEAPONS
- && mitm[i].base_type != OBJ_MISSILES)
+ && mitm[i].base_type != OBJ_MISSILES
+ || item_is_stationary(mitm[i])) // held in a net
{
i = next;
continue;