Ziggurat Zagger
Posts: 11111
Joined: Friday, 8th February 2013, 12:00
How to create Mottled Dragon?
Full Windows 64 bit version can be downloaded at https://www.dropbox.com/s/7ufdv1a2qbn6b ... 9.zip?dl=0
I play offline.
Ask fellow adventurers how to stay alive in the deep, dark, dangerous dungeon below, or share your own accumulated wisdom.
Ziggurat Zagger
Posts: 11111
Joined: Friday, 8th February 2013, 12:00
bool monster_polymorph(monster* mons, monster_type targetc,
poly_power_type power,
bool force_beh)
{
// Don't attempt to polymorph a monster that is busy using the stairs.
if (mons->flags & MF_TAKING_STAIRS)
return false;
ASSERT(!(mons->flags & MF_BANISHED) || player_in_branch(BRANCH_ABYSS));
int source_power, target_power, relax;
int source_tier, target_tier;
int tries = 1000;
// Used to be mons_power, but that just returns hit_dice
// for the monster class. By using the current hit dice
// the player gets the opportunity to use draining more
// effectively against shapeshifters. - bwr
source_power = mons->hit_dice;
source_tier = mons_demon_tier(mons->type);
// There's not a single valid target on the '&' demon tier, so unless we
// make one, let's ban this outright.
if (source_tier == -1)
{
return simple_monster_message(mons,
"'s appearance momentarily alters.");
}
relax = 1;
if (targetc == RANDOM_MONSTER)
{
do
{
// Pick a monster species that's guaranteed happy at this grid.
targetc = random_monster_at_grid(mons->pos(), true);
target_power = mons_power(targetc);
// Can't compare tiers in valid_morph, since we want to affect only
// random polymorphs, and not absolutely, too.
target_tier = mons_demon_tier(targetc);
if (one_chance_in(200))
relax++;
if (relax > 50)
return simple_monster_message(mons, " shudders.");
}
while (tries-- && (!_valid_morph(mons, targetc)
|| source_tier != target_tier && !x_chance_in_y(relax, 200)
|| _is_poly_power_unsuitable(power, source_power,
target_power, relax)));
}
bool could_see = you.can_see(mons);
bool need_note = (could_see && MONST_INTERESTING(mons));
string old_name_a = mons->full_name(DESC_A);
string old_name_the = mons->full_name(DESC_THE);
monster_type oldc = mons->type;
if (targetc == RANDOM_TOUGHER_MONSTER)
{
vector<monster_type> target_types;
for (int mc = 0; mc < NUM_MONSTERS; ++mc)
{
const monsterentry *me = get_monster_data((monster_type) mc);
int delta = (int) me->hpdice[0] - mons->hit_dice;
if (delta != 1)
continue;
if (!_valid_morph(mons, (monster_type) mc))
continue;
target_types.push_back((monster_type) mc);
}
if (target_types.empty())
return false;
shuffle_array(target_types);
targetc = target_types[0];
}
if (!_valid_morph(mons, targetc))
return simple_monster_message(mons, " looks momentarily different.");
change_monster_type(mons, targetc);
bool can_see = you.can_see(mons);
// Messaging
bool player_messaged = true;
if (could_see)
{
string verb = "";
string obj = "";
if (!can_see)
obj = "something you cannot see";
else
{
obj = mons_type_name(targetc, DESC_A);
if (targetc == MONS_PULSATING_LUMP)
obj += " of flesh";
}
if (oldc == MONS_OGRE && targetc == MONS_TWO_HEADED_OGRE)
{
verb = "grows a second head";
obj = "";
}
else if (mons->is_shapeshifter())
verb = "changes into ";
else if (targetc == MONS_PULSATING_LUMP)
verb = "degenerates into ";
else if (_jiyva_slime_target(targetc))
verb = "quivers uncontrollably and liquefies into ";
else
verb = "evaporates and reforms as ";
mprf("%s %s%s!", old_name_the.c_str(), verb.c_str(), obj.c_str());
}
else if (can_see)
{
mprf("%s appears out of thin air!", mons->name(DESC_A).c_str());
autotoggle_autopickup(false);
}
else
player_messaged = false;
if (need_note || could_see && can_see && MONST_INTERESTING(mons))
{
string new_name = can_see ? mons->full_name(DESC_A)
: "something unseen";
take_note(Note(NOTE_POLY_MONSTER, 0, 0, old_name_a.c_str(),
new_name.c_str()));
if (can_see)
mons->flags |= MF_SEEN;
}
if (!force_beh)
player_angers_monster(mons);
// Xom likes watching monsters being polymorphed.
if (can_see)
{
xom_is_stimulated(mons->is_shapeshifter() ? 12 :
power == PPT_LESS || mons->friendly() ? 25 :
power == PPT_SAME ? 50
: 100);
}
return player_messaged;
}
static bool _is_poly_power_unsuitable(poly_power_type power,
int src_pow, int tgt_pow, int relax)
{
switch (power)
{
case PPT_LESS:
return (tgt_pow > src_pow - 3 + relax * 3 / 2)
|| (power == PPT_LESS && (tgt_pow < src_pow - relax / 2));
case PPT_MORE:
return (tgt_pow < src_pow + 2 - relax)
|| (power == PPT_MORE && (tgt_pow > src_pow + relax));
default:
case PPT_SAME:
return (tgt_pow < src_pow - relax)
|| (tgt_pow > src_pow + relax * 3 / 2);
}
}
static bool _valid_morph(monster* mons, monster_type new_mclass)
{
const dungeon_feature_type current_tile = grd(mons->pos());
monster_type old_mclass = mons_base_type(mons);
// Shapeshifters cannot polymorph into glowing shapeshifters or
// vice versa.
if ((new_mclass == MONS_GLOWING_SHAPESHIFTER
&& mons->has_ench(ENCH_SHAPESHIFTER))
|| (new_mclass == MONS_SHAPESHIFTER
&& mons->has_ench(ENCH_GLOWING_SHAPESHIFTER)))
{
return false;
}
// [ds] Non-base draconians are much more trouble than their HD
// suggests.
if (mons_genus(new_mclass) == MONS_DRACONIAN
&& new_mclass != MONS_DRACONIAN
&& !player_in_branch(BRANCH_ZOT)
&& !one_chance_in(10))
{
return false;
}
// Various inappropriate polymorph targets.
if (mons_class_holiness(new_mclass) != mons_class_holiness(old_mclass)
|| mons_class_flag(new_mclass, M_UNFINISHED) // no unfinished monsters
|| mons_class_flag(new_mclass, M_CANT_SPAWN) // no dummy monsters
|| mons_class_flag(new_mclass, M_NO_POLY_TO) // explicitly disallowed
|| mons_class_flag(new_mclass, M_UNIQUE) // no uniques
|| mons_class_flag(new_mclass, M_NO_EXP_GAIN) // not helpless
|| new_mclass == MONS_PROGRAM_BUG
// 'morph targets are _always_ "base" classes, not derived ones.
|| new_mclass != mons_species(new_mclass)
|| new_mclass == mons_species(old_mclass)
// They act as separate polymorph classes on their own.
|| mons_class_is_zombified(new_mclass)
|| mons_is_zombified(mons) && !mons_zombie_size(new_mclass)
// Currently unused (no zombie shapeshifters, no polymorph).
|| mons->type == MONS_SKELETON && !mons_skeleton(new_mclass)
|| mons->type == MONS_ZOMBIE && !mons_zombifiable(new_mclass)
// These require manual setting of the ghost demon struct to
// indicate their characteristics, which we currently aren't
// smart enough to handle.
|| mons_is_ghost_demon(new_mclass)
// Other poly-unsuitable things.
|| mons_is_statue(new_mclass)
|| mons_is_projectile(new_mclass)
|| mons_is_tentacle_or_tentacle_segment(new_mclass)
// Don't polymorph things without Gods into priests.
|| (mons_class_flag(new_mclass, MF_PRIEST) && mons->god == GOD_NO_GOD)
// The spell on Prince Ribbit can't be broken so easily.
|| (new_mclass == MONS_HUMAN
&& (mons->type == MONS_PRINCE_RIBBIT
|| mons->mname == "Prince Ribbit")))
{
return false;
}
// Determine if the monster is happy on current tile.
return monster_habitable_grid(new_mclass, current_tile);
}
Spider Stomper
Posts: 243
Joined: Sunday, 28th August 2011, 14:04
Ziggurat Zagger
Posts: 11111
Joined: Friday, 8th February 2013, 12:00
Vaults Vanquisher
Posts: 486
Joined: Thursday, 28th June 2012, 17:50
Location: U.S.
Crypt Cleanser
Posts: 726
Joined: Friday, 11th February 2011, 18:46
Vestibule Violator
Posts: 1500
Joined: Monday, 3rd January 2011, 17:47
some12fat2move wrote:That is a cool list but some of that stuff isn't natural or has high MR. Basically your best targets are probably going to be ice beast, goliath beetle, crocodile, brain worm, and big kobold, since those are all natural, fairly common, and have only 20 MR. Dwarf is just as good of a target but quite rare.
Ziggurat Zagger
Posts: 4055
Joined: Tuesday, 10th January 2012, 19:49
Return to Dungeon Crawling Advice
Users browsing this forum: No registered users and 29 guests