summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-15 09:39:09 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-15 09:39:09 +0000
commit6b01f8a9a0e4d0cfbad1beb76002810d8e0203a8 (patch)
tree1291287ce0c9443d6911c4ecd0ec2d3b8ebd77ae /crawl-ref/source
parent66740a30c6be993c636285d8351ad0f50c1a8ec7 (diff)
downloadcrawl-ref-6b01f8a9a0e4d0cfbad1beb76002810d8e0203a8.tar.gz
crawl-ref-6b01f8a9a0e4d0cfbad1beb76002810d8e0203a8.zip
Add a tutorial hint for encountering an invisible monster and offer a
different healing message if you recently met an invisible monster, as suggested in FR 1964267. Killing an invisible monster does not yet reset the counter, though I guess it should. Also, disallow randart weapons to be named after Sif Muna. (Vehumet, too, maybe?) git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5052 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/beam.cc8
-rw-r--r--crawl-ref/source/delay.cc8
-rw-r--r--crawl-ref/source/enum.h10
-rw-r--r--crawl-ref/source/externs.h4
-rw-r--r--crawl-ref/source/mon-util.cc4
-rw-r--r--crawl-ref/source/mstuff2.cc4
-rw-r--r--crawl-ref/source/randart.cc4
-rw-r--r--crawl-ref/source/stuff.cc16
-rw-r--r--crawl-ref/source/stuff.h3
-rw-r--r--crawl-ref/source/tutorial.cc63
10 files changed, 99 insertions, 25 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index a7f945296e..8ceae7a4a6 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -63,6 +63,7 @@
#include "stuff.h"
#include "terrain.h"
#include "traps.h"
+#include "tutorial.h"
#include "view.h"
#include "xom.h"
@@ -2131,6 +2132,13 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
monster_name.c_str(),
player_monster_visible(monster) ? "for a moment."
: "and vanishes!" );
+
+ if (Options.tutorial_left)
+ {
+ learned_something_new(TUT_INVISIBLE_DANGER);
+ if (!player_monster_visible(monster))
+ Options.tut_seen_invisible = you.num_turns;
+ }
}
pbolt.obvious_effect = true;
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 8e9b19e5c4..8aa6fcfcec 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -1524,11 +1524,19 @@ static void paranoid_option_disable( activity_interrupt_type ai,
}
if (!deactivatees.empty())
+ {
mprf(MSGCH_WARN, "Deactivating %s; reactivate with %s.",
comma_separated_line(deactivatees.begin(),
deactivatees.end()).c_str(),
comma_separated_line(restart.begin(),
restart.end()).c_str());
+ }
+
+ if (Options.tutorial_left)
+ {
+ learned_something_new(TUT_INVISIBLE_DANGER);
+ Options.tut_seen_invisible = you.num_turns;
+ }
}
}
}
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 48453c10e3..0e64ee75ef 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2693,17 +2693,19 @@ enum tutorial_event_type
// warning
TUT_RUN_AWAY, // 38
TUT_RETREAT_CASTER,
- TUT_WIELD_WEAPON,
+ TUT_WIELD_WEAPON, // 40
TUT_NEED_HEALING,
TUT_NEED_POISON_HEALING,
+ TUT_INVISIBLE_DANGER,
+ TUT_NEED_HEALING_INVIS,
// interface
- TUT_MULTI_PICKUP, // 43
+ TUT_MULTI_PICKUP, // 45
TUT_HEAVY_LOAD,
TUT_SHIFT_RUN,
TUT_MAP_VIEW,
TUT_DONE_EXPLORE,
- TUT_EVENTS_NUM // 48
-}; // for numbers higher than 48 change size of tutorial_events in externs.h
+ TUT_EVENTS_NUM // 50
+}; // for numbers higher than 50 change size of tutorial_events in externs.h
enum tutorial_types
{
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 70fd38a5e1..ed3f164c87 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1852,8 +1852,7 @@ public:
///////////////////////////////////////////////////////////////////////
// tutorial
- FixedVector<bool, 48> tutorial_events;
-// bool tut_made_note;
+ FixedVector<bool, 50> tutorial_events;
bool tut_explored;
bool tut_stashes;
bool tut_travel;
@@ -1862,6 +1861,7 @@ public:
unsigned int tut_berserk_counter;
unsigned int tut_melee_counter;
unsigned int tut_last_healed;
+ unsigned int tut_seen_invisible;
bool tut_just_triggered;
unsigned int tutorial_type;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 5228fa6035..85d75240c0 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2230,7 +2230,7 @@ bool ms_waste_of_time( const monsters *mon, spell_type monspell )
case SPELL_INVISIBILITY:
if (mon->has_ench(ENCH_INVIS)
- || (mons_friendly(mon) && !player_see_invis(false)))
+ || mons_friendly(mon) && !player_see_invis(false))
{
ret = true;
}
@@ -4307,8 +4307,10 @@ int monsters::hurt(const actor *agent, int amount)
if (agent->atype() == ACT_PLAYER)
monster_die(this, KILL_YOU, 0);
else
+ {
monster_die(this, KILL_MON,
monster_index( dynamic_cast<const monsters*>(agent) ));
+ }
}
return (amount);
}
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index 1be90d48ca..b0f3b1cbfc 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -1124,8 +1124,8 @@ void setup_dragon(struct monsters *monster, struct bolt &pbolt)
pbolt.thrower = KILL_MON;
pbolt.is_beam = true;
- // Accuracy is lowered by one quarter if the dragon is attacking a
- // a target thatis wielding a weapon of dragon slaying (which
+ // Accuracy is lowered by one quarter if the dragon is attacking
+ // a target that is wielding a weapon of dragon slaying (which
// makes the dragon/draconian avoid looking at the foe).
// FIXME: This effect is not yet implemented for player draconians
// or characters in dragon form breathing at monsters wielding a
diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc
index d9014d9a2d..7e89bac6d7 100644
--- a/crawl-ref/source/randart.cc
+++ b/crawl-ref/source/randart.cc
@@ -109,6 +109,10 @@ static bool _god_fits_artefact(const god_type which_god, const item_def &item)
break;
case GOD_SIF_MUNA:
+ // no weapons for Sif Muna
+ if (item.base_type == OBJ_WEAPONS)
+ return (false);
+
case GOD_KIKUBAAQUDGHA:
case GOD_VEHUMET:
if (randart_wpn_property( item, RAP_PREVENT_SPELLCASTING ))
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index fb9ea9b870..92c46482ac 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -992,7 +992,7 @@ static const char* _list_allowed_keys(char yes1, char yes2,
// like yesno(), but returns 0 for no, 1 for yes, and -1 for quit
// alt_yes and alt_yes2 allow up to two synonyms for 'Y'
-int yesnoquit( const char* str, bool safe, int safeanswer,
+int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all,
bool clear_after, char alt_yes, char alt_yes2 )
{
if (!crawl_state.is_repeating_cmd())
@@ -1008,7 +1008,7 @@ int yesnoquit( const char* str, bool safe, int safeanswer,
int tmp = getchm(KC_CONFIRM);
- if ( tmp == CK_ESCAPE || tmp == 'q' || tmp == 'Q' )
+ if (tmp == CK_ESCAPE || tmp == 'q' || tmp == 'Q')
return -1;
if ((tmp == ' ' || tmp == '\r' || tmp == '\n') && safeanswer)
@@ -1016,7 +1016,7 @@ int yesnoquit( const char* str, bool safe, int safeanswer,
if (Options.easy_confirm == CONFIRM_ALL_EASY
|| tmp == safeanswer
- || (Options.easy_confirm == CONFIRM_SAFE_EASY && safe))
+ || safe && Options.easy_confirm == CONFIRM_SAFE_EASY)
{
tmp = toupper( tmp );
}
@@ -1026,8 +1026,16 @@ int yesnoquit( const char* str, bool safe, int safeanswer,
if (tmp == 'N')
return 0;
- else if (tmp == 'Y' || tmp == alt_yes)
+ else if (tmp == 'Y' || tmp == alt_yes || tmp == alt_yes2)
return 1;
+ else if (allow_all)
+ {
+ if (tmp == 'A')
+ return 2;
+ else
+ mprf("Choose [Y]es%s, [N]o, [Q]uit, or [A]ll!",
+ _list_alternative_yes(alt_yes, alt_yes2, false, true).c_str());
+ }
else
{
mprf("[Y]es%s, [N]o or [Q]uit only, please.",
diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h
index 08eba87624..87688b5a57 100644
--- a/crawl-ref/source/stuff.h
+++ b/crawl-ref/source/stuff.h
@@ -104,7 +104,8 @@ bool yesno( const char * str, bool safe = true, int safeanswer = 0,
const explicit_keymap *map = NULL );
int yesnoquit( const char* str, bool safe = true, int safeanswer = 0,
- bool clear_after = true, char alt_yes = 'Y', char alt_yes2 = 'Y' );
+ bool allow_all = false, bool clear_after = true,
+ char alt_yes = 'Y', char alt_yes2 = 'Y' );
bool in_bounds( int x, int y );
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index eea9634b97..c7765e2412 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -155,6 +155,9 @@ bool pick_tutorial()
// for occasional healing reminders
Options.tut_last_healed = 0;
+ // Did the player recently see a monster turn invisible?
+ Options.tut_seen_invisible = 0;
+
Options.random_pick = true; // random choice of starting spellbook
Options.weapon = WPN_HAND_AXE; // easiest choice for fighters
return true;
@@ -362,6 +365,10 @@ static std::string _tut_debug_list(int event)
return "needed healing";
case TUT_NEED_POISON_HEALING:
return "needed healing for poison";
+ case TUT_INVISIBLE_DANGER:
+ return "encountered an invisible foe";
+ case TUT_NEED_HEALING_INVIS:
+ return "had to heal near an unseen monster";
case TUT_POSTBERSERK:
return "learned about Berserk aftereffects";
case TUT_RUN_AWAY:
@@ -640,17 +647,22 @@ void tutorial_death_screen()
}
else
{
- int hint = random2(6);
- // If a character has been unusually busy with projectiles and spells
- // give some other hint rather than the first one.
- if (hint == 0 && Options.tut_throw_counter + Options.tut_spell_counter
+ int hint = random2(6);
+ // If a character has been unusually busy with projectiles and spells
+ // give some other hint rather than the first one.
+ if (hint == 0 && Options.tut_throw_counter + Options.tut_spell_counter
>= Options.tut_melee_counter)
- {
- hint = random2(5)+1;
- }
+ {
+ hint = random2(5)+1;
+ }
+ // FIXME: The hints below could be somewhat less random, so that e.g.
+ // the message for fighting several monsters in a corridor only happens
+ // if there's more than one monster around and you're not in a corridor,
+ // or the one about using consumable objects only if you actually have
+ // any (useful or unidentified) scrolls/wands/potions.
- switch(hint)
- {
+ switch (hint)
+ {
case 0:
text = "Always consider using projectiles, wands or spells before "
"engaging monsters in close combat.";
@@ -698,7 +710,7 @@ void tutorial_death_screen()
default:
text = "Sorry, no hint this time, though there should have been "
"one.";
- }
+ }
}
formatted_message_history(text, MSGCH_TUTORIAL, 0, _get_tutorial_cols());
more();
@@ -844,6 +856,14 @@ void tutorial_healing_reminder()
if (Options.tutorial_events[TUT_NEED_POISON_HEALING])
learned_something_new(TUT_NEED_POISON_HEALING);
}
+ else if (Options.tut_seen_invisible > 0
+ && you.num_turns < Options.tut_seen_invisible - 20)
+ {
+ // If we recently encountered an invisible monster, we need a
+ // special message.
+ learned_something_new(TUT_NEED_HEALING_INVIS);
+ // If that one was already displayed, don't print a reminder.
+ }
else
{
if (Options.tutorial_events[TUT_NEED_HEALING])
@@ -1161,7 +1181,7 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y)
case TUT_SEEN_WAND:
text << "You have picked up your first wand"
#ifndef USE_TILE
- " ('<w>/</w>'). Type"
+ " ('<w>/</w>'). Type "
#else
". Simply click on it with your <w>left mouse button</w>, or "
"type "
@@ -1789,6 +1809,27 @@ void learned_something_new(tutorial_event_type seen_what, int x, int y)
"luck!";
break;
+ case TUT_INVISIBLE_DANGER:
+ text << "Fighting against a monster you cannot see is difficult. "
+ "Your best bet is probably a strategic retreat, be it via "
+ "teleportation or by getting off the level. "
+ "Or else, luring the monster into a corridor should at least "
+ "make it easier for you to hit it.";
+
+ // to prevent this text being immediately followed by the next one
+ Options.tut_last_healed = you.num_turns - 30;
+ break;
+
+ case TUT_NEED_HEALING_INVIS:
+ text << "You recently noticed an invisible monster, so resting might "
+ "not be safe. If you still need to replenish your hitpoints "
+ "or magic, you'll have to quaff an appropriate potion. For "
+ "normal resting you will first have to get away from the "
+ "danger.";
+
+ Options.tut_last_healed = you.num_turns;
+ break;
+
case TUT_POSTBERSERK:
text << "Berserking is extremely exhausting! It burns a lot of "
"nutrition, and afterwards you are slowed down and "