on crawl-ref-discuss.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7263 c06c8d41-db1a-0410-9941-cceddc491573
BNRY5YIXLFE2TDNU2JQHWWXJQVWNSEWQ52DU7XUWIT5DZWKGBDDAC HOUSHQ4DQK4MVKTCJ56MKYGYPDTF77HJCFVB5PYV7ALNZZJWFYFQC YPQ24FG2TT6IX454HDF5QT7P6NKDNIZK4LB4YIJPCLQBMEXMCBBQC FU3BLBSYBDAK6UVFT4EWO5ZTUFCYFPHYNZNFFF27AX7PWHOCHURAC K7EIE5VJDKRYBAZRDFEEEKST2P2B7HFPH2AJVER5JUUQVTYXZWHQC MSRJ3N4NX255RVISUOPTTTY2GG4JVVNNM76HWUZ2EKCYESNI6MLQC TJ72NVTRNJKF55RTH5MRLTHHVPOJ2M5OOYEWF4UFLTO2PPPTU6PQC QC6O26QFCH75KANQDWNY6X7BYKPKF63NFBBSHDUWZ6AUPIMYRB2QC FTGL3RHC2ARWUOOMWO6TI2F2HSGCHKET7OHDBWCHARQCPCHHQERQC EHL7B5UIYYHSFX3KXQ43C4GNFJSEUEXFF7U3IL7XU6E5R675WS7AC WFMQVPMMOPG5SBJD5LUBOIYWRMXVWK3FXENK7SAEGZ5T6XWFKERQC ABA7GPRHJ6M5CA2AJSZM2PZCL7CDOBEMM6QZJFRLKLS4CVMEUV6AC GGDX26OLH2EBB2ZBJCBIE3UDPHWEMTMSOEJBJIWCBLUK3HEY3PKQC LM764EO6YIFOKMRXWZ5S4GYZB4BHZQDTEFP7MEVYO4NN4EDOFGNQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC JW2KRJHES33W7UTWZ6NDO4TLMK4EFU4HKZXBWR2UJOMPCCOTR4CQC NNQPJEMQAJC6V45OOHEX7OA54DE5IEQI73SJTS5O6PPU3KMHF4WQC 62CWUC7WKYRODVOOUFHRPDZXGTBUIU7XPR3EHJWESPG2XVUM7SDAC IGNQ3YSGMW6NG7GPYYXWXW6XPM4YWKNUJ5IU55QCWZ2AEHHO3L3QC 5PNVRKZFGGUKPYADIXIJSBTBGX26NDGSNGYS6WGSBP3JGT5NCCKAC 2NFFQ4TCADDVDWUNH3YXIPLDQ566TPF5WZ2YAZLDM5UEWPVUKNZQC B47CVG54WZNP3CQ7HOTKTWQA26GCOIKQADX2EK4ZOEYRRQ4T5W2AC CQ24AVAI6SW3AHTIDMLPSTRRBEU6FHRF5I5FD6G5QIYE6PO4BQMQC 5FBOE2QNRLKUNOP54CZD6LFAMM7LX6NNLHJRJHRDDIUTQ7J723DQC KAOE5HB3THUKVGFZRO5EZESHEB3Q34WUO5DFMLWIKOBF47LZTIYAC T7CUIVICB74342RA32BR37T36FOX4RBSQIB5PNOHTGTGUYGDKSTQC 2YL37AGHLFOMIF3GCTVQGGV2RNNWETWM6ZMUHO3QEWDVBFFSFAKQC EFWEYIB2R3DPD3JWIPU6LS6SFLPMYN7J7X4GBZR7DJWKHJ3UELSAC NLQNXH3SVJ52CWXEV35FSSZP32VHC4QFGN3HINF4KO5GZHZMOBKQC Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC YA24HFHVUI2LDWFOZR5QSHRIVTAWGSGPAH5E2FPP6ANCL2MTUSTAC V7IKAPO5OY7CJTT62GMHQOD3EQW42FTTY3KDBOTJUODPS5WMBCHAC BLN5LDH5NRRJPBY77A36Q4THEY75N42MVCJMZRUZ2D5YSXTDL4HQC QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC 5FHWTG7M6FW4B3I33YI7QSM3OZIB6ZGC6TI6JISSLY5Y43HI56VAC J6APXOT4QOGQFONWB7G546VTVF6QG42HVOROMHF7YBDJPR4K26OAC 4SWAT5KCKQV527NKELAXFQ5XA4Q5HONQXD4VBXMUZNPVPQKPCPNAC HOPP345EQLSF24XJYE3625VKU23PBKM5ZZKNCXBXUWYYORYPMDAAC PVLLIAYFIAU4TQFBIP7B4ARIBUX2CVTSBQECEU6VTONJV4ANHVFAC TN2D3PHU7VSGUND2BDIC2F4U6O2HFSV3JXLF7HMYYMY7GZXM6IFAC QYQKV4R47PTERXVFQNNWWQVICGSOMBHW6WM5TAZAKLIYOLLPUAJAC VXWDDKBETFFMU7LMGN4UGB74NNKXW456KFJMWWEVOTWH35NZZZHAC W2KRIXSCRJPS6WDIYTHVF5IRMF3V5DWECRAWUPVTB7VZ6A2BLD4QC CK5VYF5GP4KDA7KC3RABE5DAY2E4372TJB5K2A3SCWDM44R2W4XAC OEHJJ5X5CBOHTXISZLJHVLCAPH77RYSVKKBGW3US2GGXZMZJ5CEQC N3BRDQWPEHQZWIX2CDM2O2VLD6DJONGILDXVCSCAVWOGIOUU5IGAC DENP72AB5VYMFLNU3VQULFIAWZAXOK4K554O5GBMZPHMVBUTO53AC WXSNNK2RXP3DQFAEQGQUZJHFWXJC7ZKG2WURZGL566UDM4YXFSWQC OYANFNGKCXG2NLQMYW4TNFU3LFK3533XQ3HFGI3LNMY4JGMDMK5QC static bool _yred_enslaved_souls_on_level_disappear(){bool success = false;for (int i = 0; i < MAX_MONSTERS; ++i){monsters *monster = &menv[i];if (_is_yred_enslaved_soul(monster)){#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Undead soul disappearing: %s on level %d, branch %d",monster->name(DESC_PLAIN).c_str(),static_cast<int>(you.your_level),static_cast<int>(you.where_are_you));#endifsimple_monster_message(monster, " is freed.");// The monster disappears.monster_die(monster, KILL_DISMISSED, NON_MONSTER);success = true;}}return (success);}
if (is_yred_undead_slave(monster))
if (_is_yred_enslaved_body_and_soul(monster)){#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Undead soul abandoning: %s on level %d, branch %d",monster->name(DESC_PLAIN).c_str(),static_cast<int>(you.your_level),static_cast<int>(you.where_are_you));#endifyred_make_enslaved_soul(monster, true, true, false);success = true;}else if (is_yred_undead_slave(monster))
monster->attitude = ATT_HOSTILE;behaviour_event(monster, ME_ALERT, MHITYOU);// For now CREATED_FRIENDLY stays.
if (_is_yred_enslaved_body_and_soul(monster))yred_make_enslaved_soul(monster, true, true, false);else{monster->attitude = ATT_HOSTILE;behaviour_event(monster, ME_ALERT, MHITYOU);// For now CREATED_FRIENDLY stays.}
const int type = mon->type;const std::string name_cap_the = mon->name(DESC_CAP_THE);const std::string name_plain = mon->name(DESC_PLAIN);bool twisted = false;if ((allow_fail || mons_unusable_items(mon) > 0) && coinflip())twisted = true;if (!quiet){mprf("%s's soul %s.", name_cap_the.c_str(),twisted ? "becomes twisted" : "remains intact");}if (twisted){mon->type = mons_zombie_size(type) == Z_BIG ?MONS_ABOMINATION_LARGE : MONS_ABOMINATION_SMALL;mon->base_monster = mons_species(mon->type);}else{mon->type = MONS_SPECTRAL_THING;mon->base_monster = mons_species(type);}define_monster(*mon);if (twisted){// Mark abominations as undead.mon->flags |= MF_HONORARY_UNDEAD;monster_drop_ething(mon);}mon->flags |= MF_ENSLAVED_SOUL;if (mons_is_unique(type)){mon->mname = name_plain;// Special case for Blork the orc: shorten his name to "Blork"// to avoid mentions of "Blork the orc the spectral orc" or// "Blork the orc the small abomination".if (type == MONS_BLORK_THE_ORC)mon->mname = "Blork";}// Wow, permanent enslaving!mon->attitude = !force_hostile ? ATT_FRIENDLY : ATT_HOSTILE;mon->flags |= MF_CREATED_FRIENDLY;behaviour_event(mon, ME_ALERT, !force_hostile ? MHITNOT : MHITYOU);mons_make_god_gift(mon, GOD_YREDELEMNUL);if (!quiet){mprf("%s's soul %s.", name_cap_the.c_str(),!force_hostile ? "is now yours" : "fights you");}}
static int _scan_mon_inv_items(const monsters *mon,bool (*item_type)(const item_def&)){int ret = 0;if (mons_itemuse(mon) >= MONUSE_STARTING_EQUIPMENT){const int weapon = mon->inv[MSLOT_WEAPON];const int second = mon->inv[MSLOT_ALT_WEAPON]; // Two-headed ogres, etc.const int misc = mon->inv[MSLOT_MISCELLANY];const int potion = mon->inv[MSLOT_POTION];const int wand = mon->inv[MSLOT_WAND];const int scroll = mon->inv[MSLOT_SCROLL];if (weapon != NON_ITEM && mitm[weapon].base_type == OBJ_WEAPONS&& item_type(mitm[weapon])){ret++;}
if (second != NON_ITEM && mitm[second].base_type == OBJ_WEAPONS&& item_type(mitm[second])){ret++;}if (misc != NON_ITEM && mitm[misc].base_type == OBJ_MISCELLANY&& item_type(mitm[misc])){ret++;}if (potion != NON_ITEM && mitm[potion].base_type == OBJ_POTIONS&& item_type(mitm[potion])){ret++;}if (wand != NON_ITEM && mitm[misc].base_type == OBJ_WANDS&& item_type(mitm[wand])){ret++;}if (scroll != NON_ITEM && mitm[scroll].base_type == OBJ_SCROLLS&& item_type(mitm[scroll])){ret++;}}return (ret);}static bool _mons_has_undrinkable_potion(const monsters *mon){bool ret = false;if (mons_itemuse(mon) >= MONUSE_STARTING_EQUIPMENT){const int potion = mon->inv[MSLOT_POTION];if (potion != NON_ITEM && mitm[potion].base_type == OBJ_POTIONS){const potion_type ptype =static_cast<potion_type>(mitm[potion].sub_type);if (!mon->can_drink_potion(ptype))ret = true;}}return (ret);}int mons_unusable_items(const monsters *mon){int ret = 0;if (mons_is_holy(mon))ret += _scan_mon_inv_items(mon, is_evil_item) > 0;else if (mons_is_unholy(mon)){ret += _scan_mon_inv_items(mon, is_holy_item) > 0;if (mons_holiness(mon) == MH_UNDEAD&& _mons_has_undrinkable_potion(mon)){ret++;}}return (ret);}
&& !mons_is_summoned(mon));
&& !mons_is_summoned(mon)&& !mons_enslaved_body_and_soul(mon));}bool mons_enslaved_body_and_soul(const monsters *mon){return (testbits(mon->flags, MF_ENSLAVED_SOUL)&& mons_holiness(mon) == MH_NATURAL);}bool mons_enslaved_twisted_soul(const monsters *mon){return (testbits(mon->flags, MF_ENSLAVED_SOUL)&& (mon->type == MONS_ABOMINATION_SMALL|| mon->type == MONS_ABOMINATION_LARGE));}bool mons_enslaved_intact_soul(const monsters *mon){return (testbits(mon->flags, MF_ENSLAVED_SOUL)&& mon->type == MONS_SPECTRAL_THING);}bool mons_enslaved_soul(const monsters *mon){return (mons_enslaved_twisted_soul(mon)|| mons_enslaved_intact_soul(mon));
MF_CREATED_FRIENDLY = 0x01, // no benefit from killingMF_BATTY = 0x02, // flutters like a batMF_JUST_SUMMONED = 0x04, // monster skips next available actionMF_TAKING_STAIRS = 0x08, // is following player through stairs
MF_CREATED_FRIENDLY = 0x01, // no benefit from killingMF_BATTY = 0x02, // flutters like a batMF_JUST_SUMMONED = 0x04, // monster skips next available actionMF_TAKING_STAIRS = 0x08, // is following player through stairs
MF_INTERESTING = 0x10, // Player finds monster interestingMF_SEEN = 0x20, // Player has already seen monsterMF_DIVINE_PROTECTION = 0x40, // Monster has divine protection.
MF_INTERESTING = 0x10, // Player finds monster interestingMF_SEEN = 0x20, // Player has already seen monsterMF_DIVINE_PROTECTION = 0x40, // Monster has divine protection.
MF_KNOWN_MIMIC = 0x80, // Mimic that has taken a swing at the PC,// or that the player has inspected with ?MF_BANISHED = 0x100, // Monster that has been banished.MF_HARD_RESET = 0x200, // Summoned, should not drop gear on resetMF_WAS_NEUTRAL = 0x400, // mirror to CREATED_FRIENDLY for neutralsMF_ATT_CHANGE_ATTEMPT = 0x800, // Saw player and attitude changed (or// not); currently used for holy beings// (good god worshippers -> neutral)// and orcs (Beogh worshippers -> friendly)MF_WAS_IN_VIEW = 0x1000, // Was in view during previous turnMF_BAND_MEMBER = 0x2000, // Created as a member of a bandMF_GOT_HALF_XP = 0x4000, // Player already got half xp value earlierMF_HONORARY_UNDEAD = 0x8000 // Consider this monster to have MH_UNDEAD// holiness, regardless of its actual type;// currently used for abominations created// via Twisted Resurrection
MF_KNOWN_MIMIC = 0x80, // Mimic that has taken a swing at the PC,// or that the player has inspected with ?MF_BANISHED = 0x100, // Monster that has been banished.MF_HARD_RESET = 0x200, // Summoned, should not drop gear on resetMF_WAS_NEUTRAL = 0x400, // mirror to CREATED_FRIENDLY for neutralsMF_ATT_CHANGE_ATTEMPT = 0x800, // Saw player and attitude changed (or// not); currently used for holy beings// (good god worshippers -> neutral)// and orcs (Beogh worshippers -> friendly)MF_WAS_IN_VIEW = 0x1000, // Was in view during previous turnMF_BAND_MEMBER = 0x2000, // Created as a member of a bandMF_GOT_HALF_XP = 0x4000, // Player already got half xp value earlierMF_HONORARY_UNDEAD = 0x8000, // Consider this monster to have MH_UNDEAD// holiness, regardless of its actual type;// currently used for abominations created// via Twisted ResurrectionMF_ENSLAVED_SOUL = 0x10000 // An undead monster soul enslaved by// Yredelemnul's power, or the natural// monster from whom the soul is taken
Yredelemnul gives you the power to raise corpses to fight on your side, to recall your undead followers to your vicinity, and to drain the life force of living creatures. Eventually, you'll gain the power to sway hostile undead ceatures' loyalties, and make them fight for you instead. Yredelemnul will sporadically gift you with stronger undead servants. Under prayer, with sufficient piety, Yredelemnul will mirror any injury you have to suffer onto the attacker.
Yredelemnul gives you the power to raise corpses to fight on your side, to recall your undead followers to your vicinity, and to drain the life force of living creatures. Eventually, you'll gain the power to bind a monster's soul, and make it fight for you instead. Yredelemnul will sporadically gift you with stronger undead servants. Under prayer, with sufficient piety, Yredelemnul will mirror any injury you have to suffer onto the attacker.
Attempt to temporarily enslave undead monsters around you.
Mark a monster's living soul as yours, once the monster dies. The soul will retain at least some of the monster's faculties, and sometimes even the monster's equipment. However, you can only enslave one soul at any given time.
case BEAM_ENSLAVE_SOUL:#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS,"HD: %d; pow: %d", mon->hit_dice, beam.ench_power);#endifif (!mons_can_be_zombified(mon) || mons_intel(mon) < I_NORMAL){simple_monster_message(mon, " is unaffected.");return (MON_OTHER);}if (mon->hit_dice >= random2(beam.ench_power / 2))return (MON_RESIST);beam.obvious_effect = true;mon->flags |= MF_ENSLAVED_SOUL;simple_monster_message(mon, "'s soul is now ripe for the taking.");return (MON_AFFECTED);
// degeneration / sleepif (beam.flavour == BEAM_DEGENERATE || beam.flavour == BEAM_SLEEP)
// degeneration / sleep / enslave soulif (beam.flavour == BEAM_DEGENERATE || beam.flavour == BEAM_SLEEP|| beam.flavour == BEAM_ENSLAVE_SOUL){
case ABIL_YRED_CONTROL_UNDEAD:mass_enchantment(ENCH_CHARM, you.skills[SK_INVOCATIONS] * 8, MHITYOU);exercise(SK_INVOCATIONS, 3 + random2(4));
case ABIL_YRED_ENSLAVE_SOUL:{god_acting gdact;if (!spell_direction(spd, beam))return (false);if (!zapping(ZAP_ENSLAVE_SOUL, you.skills[SK_INVOCATIONS] * 4, beam,true)){return (false);}exercise(SK_INVOCATIONS, 8 + random2(10));