Caught a bug in the definition of shadows (isn't it lucky that BLACK == MST_NO_SPELLS?)
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1788 c06c8d41-db1a-0410-9941-cceddc491573
PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC
SORP3HABJJHQ7QGFJA52PNE46XCD243GP7NGTKMBY6IMODNFIHJAC
YATODO2EN3AW7IXW5PL25HHK34YHF6Y32QBMOUZXEATZZ4YQQWZQC
YQ5IYBHW2ICYKOC2M6CI5BNOZKST3DIMMZRQN72LUQCHDAPVYQCQC
QS3ZRS3E6KL3YJHPKYEWCWJYRBJSXD5OOYF6Y25HZVECGPJRDB5QC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
XRZPPYWPWUOM4SFNI6BHKH2UKJQNLKOV6Y7XIEPEZXE5QYRT26PAC
6KCWO7XCDBGOYSUWVEXC74XC6RZ7ZJQLLSES5IIPCTILTECYMFZAC
CQ24AVAI6SW3AHTIDMLPSTRRBEU6FHRF5I5FD6G5QIYE6PO4BQMQC
X3RDT655FEYO6XEVPIUAPEPJZAFE55KZBH2AZOLK3NGHINMVIGFQC
ANOEQTM6IGCBTESKKQ5PCBSDTZ7VGRCMDIOAFEH4R7DJHKWKDFAAC
YAAJ6PTN6QUSWE52URI5AENOGD366FIHOIFUOXFUJLVZYE4OG6HQC
NQMXQ6OQVUSC7Y7F7IL252QW4A5JED224EECNHWAM4ZZYVNY745AC
C7ZG3QMG2CDCRQFCCC5BAY7Q7EQ2I634BXGVOOTMSR7EYBARJ6MAC
LS3DAZVRDCXVN2BKBC6RGCKO3R43Z7HKG4GXJWLBK4AKBL2G6QDQC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC
YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC
R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC
ZCPJIAG7SEY2TUBAGOFWCEJYXSBT36CZU5VO7BWEGSLJ4K24B4TAC
MOT3YZFRY3JG2MH3GN2VD6IY3IJSAXJUXMXS222TXWKRFCENOCDQC
CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC
DDU4A3JGN5IUIPP5IASOODKPR2WBHSDSV4FITZ6HNXNSXXQACWAQC
W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC
7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC
7KWDC7XFNMBLSUO2HISIROBINZBX5T67LJEEXTAORXW2YZ7VWFGAC
Y56C5OMUQ5XF2G6DKDV4R5MED44UOIUPTBBQVWQBUHYIXYA5MOZAC
IPQ63XIUPHFMCQOZZAVSGCJOZFDRDWZTUUJSAUMARNDUFLBEMYIAC
6GT5JAWOIIL4SQ5MWIID6ZVO3KKQFWDQDZNVFHZ6DNK5QCBXJ4UAC
GVCGKTH5IJ4VSQEIN4CRC7ZFVZW26JPIYNCPTO7GY66CSZZEW3ZQC
TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC
YHSVOROKPYS33Y4RYZRVZTE3G5LXOFX52HEDNLV6HIXOJYNOKH3QC
4PUWNQO7QMEWY3GSUHLBKMYOAI7ASYSRM32KDGTA7DLNDIGFAWFAC
X2FMEN4E345XD26Z2X7JMJ7VGHOGCGIELMHQRE2ITLVNQACP3NOQC
3KAINFIXO7WNWGUGZB43EUNFRS2ZPBLQZDTY456QACMRHYIJ7WDAC
static void beogh_follower_convert(monsters *monster)
{
// for followers of Beogh, decide whether orcs will join you
if (mons_species(monster->type) == MONS_ORC
&& you.religion == GOD_BEOGH
&& !(monster->flags & MF_CONVERT_ATTEMPT)
// && !mons_is_unique(monster->type) // does not work on Blork
&& monster->foe == MHITYOU
&& mons_player_visible(monster) && !mons_is_sleeping(monster)
&& !mons_is_confused(monster) && !mons_is_paralysed(monster))
{
monster->flags |= MF_CONVERT_ATTEMPT;
const int hd = monster->hit_dice;
if (you.piety >= 75 && !you.penance[GOD_BEOGH] &&
random2(you.piety/9) > random2(hd) + hd + random2(5))
{
int wpn = you.equip[EQ_WEAPON];
if (wpn != -1
&& you.inv[wpn].base_type == OBJ_WEAPONS
&& get_weapon_brand( you.inv[wpn] ) == SPWPN_ORC_SLAYING
&& coinflip()) // 50% chance of conversion failing
{
msg::stream << monster->name(DESC_CAP_THE)
<< " flinches from your weapon."
<< std::endl;
return;
}
if (player_monster_visible(monster)) // show reaction
{
std::ostream& chan = msg::streams(MSGCH_MONSTER_ENCHANT);
chan << monster->name(DESC_CAP_THE);
// FIXME what about female monsters?
switch (random2(3))
{
case 0:
chan << " stares at you in amazement and kneels.";
break;
case 1:
chan << " relaxes his fighting stance and smiles at you.";
break;
case 2:
chan << " falls on his knees before you.";
break;
}
chan << std::endl;
if (!one_chance_in(3))
{
std::ostream& tchan = msg::streams(MSGCH_TALK);
tchan << "He ";
switch (random2(4))
{
case 0:
tchan << "shouts, \"I'll follow thee gladly!\"";
break;
case 1:
tchan << "shouts, \"Surely Beogh must have "
"sent you!\"";
break;
case 2:
tchan << "asks, \"Are you our saviour?\"";
break;
case 3:
tchan << "says, \"I'm so glad you are here now.\"";
break;
}
tchan << std::endl;
}
}
monster->attitude = ATT_FRIENDLY;
monster->behaviour = BEH_GOD_GIFT; // alternative to BEH_FRIENDLY
// not really "created" friendly, but should it become
// hostile later on, it won't count as a good kill
monster->flags |= MF_CREATED_FRIENDLY;
monster->flags |= MF_GOD_GIFT;
// to avoid immobile "followers"
behaviour_event(monster, ME_ALERT, MHITYOU);
}
}
else if (mons_species(monster->type) == MONS_ORC
&& you.species == SP_HILL_ORC
&& !(you.religion == GOD_BEOGH)
// && monster->foe == MHITYOU
&& monster->attitude == ATT_FRIENDLY
&& (monster->flags & MF_CONVERT_ATTEMPT)
&& (monster->flags & MF_GOD_GIFT)
&& mons_player_visible(monster) && !mons_is_sleeping(monster)
&& !mons_is_confused(monster) && !mons_is_paralysed(monster))
{ // reconversion if no longer Beogh
monster->attitude = ATT_HOSTILE;
monster->behaviour = BEH_HOSTILE;
// CREATED_FRIENDLY stays -> no piety bonus on killing these
// give message only sometimes
if (player_monster_visible(monster) && random2(4))
{
msg::streams(MSGCH_MONSTER_ENCHANT)
<< monster->name(DESC_CAP_THE)
<< " deserts you."
<< std::endl;
}
}
}
static void handle_monster_shouts(monsters* monster)
{
if (you.turn_is_over
&& mons_shouts(monster->type) != S_SILENT
&& random2(30) >= you.skills[SK_STEALTH])
{
int noise_level = 8;
if (!mons_friendly(monster)
&& (!silenced(you.x_pos, you.y_pos)
&& !silenced(monster->x, monster->y)))
{
if (mons_is_demon( monster->type ) && coinflip())
{
if (monster->type == MONS_IMP
|| monster->type == MONS_WHITE_IMP
|| monster->type == MONS_SHADOW_IMP)
{
imp_taunt( monster );
}
else
{
demon_taunt( monster );
}
}
else
{
std::string msg = "You hear ";
switch (mons_shouts(monster->type))
{
case S_SILENT:
case NUM_SHOUTS:
case S_RANDOM:
msg += "buggy behaviour!";
break;
case S_SHOUT:
msg += "a shout!";
break;
case S_BARK:
msg += "a bark!";
break;
case S_SHOUT2:
msg += "two shouts!";
noise_level = 12;
break;
case S_ROAR:
msg += "a roar!";
noise_level = 12;
break;
case S_SCREAM:
msg += "a hideous shriek!";
break;
case S_BELLOW:
msg += "a bellow!";
break;
case S_SCREECH:
msg += "a screech!";
break;
case S_BUZZ:
msg += "an angry buzzing noise.";
break;
case S_MOAN:
msg += "a chilling moan.";
break;
case S_WHINE:
msg += "an irritating high-pitched whine.";
break;
case S_CROAK:
if (coinflip())
msg += "a loud, deep croak!";
else
msg += "a croak.";
break;
case S_GROWL:
msg += "an angry growl!";
break;
case S_HISS:
msg += "an angry hiss!";
noise_level = 4; // not very loud -- bwr
break;
}
msg::streams(MSGCH_SOUND) << msg << std::endl;
}
}
noisy( noise_level, monster->x, monster->y );
}
}
if (you.turn_is_over
&& mons_shouts(monster->type) > 0
&& random2(30) >= you.skills[SK_STEALTH])
{
int noise_level = 8;
if (!mons_friendly(monster)
&& (!silenced(you.x_pos, you.y_pos)
&& !silenced(monster->x, monster->y)))
{
if (mons_is_demon( monster->type ) && coinflip())
{
if (monster->type == MONS_IMP
|| monster->type == MONS_WHITE_IMP
|| monster->type == MONS_SHADOW_IMP)
{
imp_taunt( monster );
}
else
{
demon_taunt( monster );
}
}
else
{
std::string msg = "You hear ";
switch (mons_shouts(monster->type))
{
case S_SILENT:
default:
msg += "buggy behaviour!";
break;
case S_SHOUT:
msg += "a shout!";
break;
case S_BARK:
msg += "a bark!";
break;
case S_SHOUT2:
msg += "two shouts!";
noise_level = 12;
break;
case S_ROAR:
msg += "a roar!";
noise_level = 12;
break;
case S_SCREAM:
msg += "a hideous shriek!";
break;
case S_BELLOW:
msg += "a bellow!";
break;
case S_SCREECH:
msg += "a screech!";
break;
case S_BUZZ:
msg += "an angry buzzing noise.";
break;
case S_MOAN:
msg += "a chilling moan.";
break;
case S_WHINE:
msg += "an irritating high-pitched whine.";
break;
case S_CROAK:
if (coinflip())
msg += "a loud, deep croak!";
else
msg += "a croak.";
break;
case S_GROWL:
msg += "an angry growl!";
break;
case S_HISS:
msg += "an angry hiss!";
noise_level = 4; // not very loud -- bwr
break;
}
mpr(msg.c_str(), MSGCH_SOUND);
}
}
noisy( noise_level, monster->x, monster->y );
}
handle_monster_shouts(monster);
// for followers of Beogh, decide whether orcs will join you
if (mons_species(monster->type) == MONS_ORC
&& you.religion == GOD_BEOGH
&& !(monster->flags & MF_CONVERT_ATTEMPT)
// && !mons_is_unique(monster->type) // does not work on Blork
&& monster->foe == MHITYOU
&& mons_player_visible(monster) && !mons_is_sleeping(monster)
&& !mons_is_confused(monster) && !mons_is_paralysed(monster))
{
monster->flags |= MF_CONVERT_ATTEMPT;
int hd = monster->hit_dice;
if (you.piety >= 75 && !you.penance[GOD_BEOGH] &&
random2(you.piety/9) > random2(hd) + hd + random2(5))
{
int wpn = you.equip[EQ_WEAPON];
if (wpn != -1
&& you.inv[wpn].base_type == OBJ_WEAPONS
&& get_weapon_brand( you.inv[wpn] ) == SPWPN_ORC_SLAYING
&& coinflip()) // 50% chance of conversion failing
{
snprintf(info, INFO_SIZE, "%s flinches from your weapon.",
monster->name(DESC_CAP_THE).c_str());
mpr(info);
continue;
}
if (player_monster_visible(monster)) // show reaction
{
std::string reaction;
switch (random2(3))
{
case 1: reaction = " stares at you in amazement and kneels.";
break;
case 2: reaction = " relaxes his fighting stance and smiles at you.";
break;
default: reaction = " falls on his knees before you.";
}
snprintf(info, INFO_SIZE, "%s%s",
monster->name(DESC_CAP_THE).c_str(),reaction.c_str());
mpr(info, MSGCH_MONSTER_ENCHANT);
if (random2(3))
{
switch (random2(4))
{
case 0: reaction = "shouts, \"I'll follow thee gladly!\"";
break;
case 1: reaction = "shouts, \"Surely Beogh must have sent you!\"";
break;
case 2: reaction = "asks, \"Are you our saviour?\"";
break;
default: reaction = "says, \"I'm so glad you are here now.\"";
}
snprintf(info, INFO_SIZE, "He %s", reaction.c_str());
mpr(info, MSGCH_TALK);
}
}
monster->attitude = ATT_FRIENDLY;
monster->behaviour = BEH_GOD_GIFT; // alternative to BEH_FRIENDLY
// not really "created" friendly, but should it become
// hostile later on, it won't count as a good kill
monster->flags |= MF_CREATED_FRIENDLY;
monster->flags |= MF_GOD_GIFT;
// to avoid immobile "followers"
behaviour_event(monster, ME_ALERT, MHITYOU);
}
}
else if (mons_species(monster->type) == MONS_ORC
&& you.species == SP_HILL_ORC
&& !(you.religion == GOD_BEOGH)
// && monster->foe == MHITYOU
&& monster->attitude == ATT_FRIENDLY
&& (monster->flags & MF_CONVERT_ATTEMPT)
&& (monster->flags & MF_GOD_GIFT)
&& mons_player_visible(monster) && !mons_is_sleeping(monster)
&& !mons_is_confused(monster) && !mons_is_paralysed(monster))
{ // reconversion if no longer Beogh
monster->attitude = ATT_HOSTILE;
monster->behaviour = BEH_HOSTILE;
// CREATED_FRIENDLY stays -> no piety bonus on killing these
// give message only sometimes
if (player_monster_visible(monster) && random2(4))
{
snprintf(info, INFO_SIZE, "%s deserts you.",
monster->name(DESC_CAP_THE).c_str());
mpr(info, MSGCH_MONSTER_ENCHANT);
}
} // end of Beogh routine
} // end "if (monster->type != -1 && mons_ner)"
} // end "for s"
} // end monster_grid()
beogh_follower_convert(monster);
}
}
}
char spell_direction( struct dist &spelld, struct bolt &pbolt,
targeting_type restrict, int mode,
// Select a spell direction and fill dist and pbolt appropriately.
// Return false if the user canceled, true otherwise.
bool spell_direction( dist &spelld, bolt &pbolt,
targeting_type restrict, targ_mode_type mode,
// This is a hack until we set an is_beast flag in the monster data
// (which we might never do, this is sort of minor.)
// It's a list of monster types which can be affected by beast taming.
static bool is_domesticated_animal(int type)
{
const monster_type types[] = {
MONS_GIANT_BAT, MONS_HOUND, MONS_JACKAL, MONS_RAT,
MONS_YAK, MONS_WYVERN, MONS_HIPPOGRIFF, MONS_GRIFFON,
MONS_DEATH_YAK, MONS_WAR_DOG, MONS_GREY_RAT,
MONS_GREEN_RAT, MONS_ORANGE_RAT, MONS_SHEEP,
MONS_HOG, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG,
MONS_SPINY_FROG, MONS_BLINK_FROG, MONS_WOLF, MONS_WARG,
MONS_BEAR, MONS_GRIZZLY_BEAR, MONS_POLAR_BEAR, MONS_BLACK_BEAR
};
for ( unsigned int i = 0; i < ARRAYSIZE(types); ++i )
if ( types[i] == type )
return true;
return false;
}
if (mons_holiness(monster) != MH_NATURAL) return 0;
if (mons_intel_type(monster->type) != I_ANIMAL) return 0;
if (mons_friendly(monster)) return 0;
if (!is_domesticated_animal(monster->type) || mons_friendly(monster))
return 0;
// 50% bonus for dogs, add cats if they get implemented
if (monster->type == MONS_HOUND || monster->type == MONS_WAR_DOG
|| monster->type == MONS_BLACK_BEAR)
{
// 50% bonus for dogs
if (monster->type == MONS_HOUND || monster->type == MONS_WAR_DOG )
case I_HIGH:
memory = 100 + random2(200);
break;
case I_NORMAL:
memory = 50 + random2(100);
break;
case I_ANIMAL:
default:
memory = 25 + random2(75);
break;
case I_INSECT:
memory = 10 + random2(50);
break;
case I_HIGH:
memory = 100 + random2(200);
break;
case I_NORMAL:
memory = 50 + random2(100);
break;
case I_ANIMAL:
case I_PLANT:
memory = 25 + random2(75);
break;
case I_INSECT:
memory = 10 + random2(50);
break;
// shout
#define S_RANDOM -1
#define S_SILENT 0
#define S_SHOUT 1 //1=shout
#define S_BARK 2 //2=bark
#define S_SHOUT2 3 //3=shout twice
#define S_ROAR 4 //4=roar
#define S_SCREAM 5 //5=scream
#define S_BELLOW 6 //6=bellow (?)
#define S_SCREECH 7 //7=screech
#define S_BUZZ 8 //8=buzz
#define S_MOAN 9 //9=moan
#define S_WHINE 10 //10=irritating whine (mosquito)
#define S_CROAK 11 //11=frog croak
#define S_GROWL 12 //jmf: for bears
#define S_HISS 13 //bwr: for snakes and lizards
// ai
// So far this only affects a) chance to see stealthy player and b) chance to
// walk through damaging clouds (LRH)
//jmf: now has relevence to mind-affecting spells, maybe soon behaviour
#define I_PLANT 0
#define I_INSECT 1
#define I_ANIMAL 2
#define I_NORMAL 3
#define I_HIGH 4
#define I_ANIMAL_LIKE 5
#define I_REPTILE 6
// 0=no zombie, 1=small zombie (z) 107, 2=_BIG_ zombie (Z) 108
char zombie_size;
// 0-12: see above, -1=random one of (0-7)
char shouts;
// AI things?
char intel; // 0=none, 1=worst...4=best
char gmon_use;
zombie_size_type zombie_size;
shout_type shouts;
mon_intel_type intel;
mon_itemuse_type gmon_use;
#ifdef DEBUG_DIAGNOSTICS
// last updated 25sep2001 {dlb}
/* ***********************************************************************
* called from: describe
* *********************************************************************** */
extern const char *mons_spell_name(spell_type);
#endif
}
#ifdef DEBUG_DIAGNOSTICS
const char *mons_spell_name( spell_type spell )
{
return (spell_title(spell));
int mons_intel(int mc) //jmf: "fixed" to work with new I_ types
{
switch (smc->intel)
{
case I_PLANT:
return (I_PLANT);
case I_INSECT:
case I_REPTILE:
return (I_INSECT);
case I_ANIMAL:
case I_ANIMAL_LIKE:
return (I_ANIMAL);
case I_NORMAL:
return (I_NORMAL);
case I_HIGH:
return (I_HIGH);
default:
return (I_NORMAL);
}
} // ens mons_intel()
#define S_RANDOM -1
#define S_SILENT 0
#define S_SHOUT 1 //1=shout
#define S_BARK 2 //2=bark
#define S_SHOUT2 3 //3=shout twice - eg 2-headed ogres
#define S_ROAR 4 //4=roar
#define S_SCREAM 5 //5=scream
#define S_BELLOW 6 //6=bellow (?)
#define S_SCREECH 7 //7=screech
#define S_BUZZ 8 //8=buzz
#define S_MOAN 9 //9=moan
void direction( struct dist &moves, targeting_type restricts = DIR_NONE,
int mode = TARG_ANY, bool just_looking = false,
void direction( dist &moves, targeting_type restricts = DIR_NONE,
targ_mode_type mode = TARG_ANY, bool just_looking = false,