Skip to content

Commit

Permalink
Allow setting attitude of cloned monsters (damerell, #11171) (#608)
Browse files Browse the repository at this point in the history
Matches the attitude of a cloned monster to the cloner. This also
removes the (currently never-used) option of setting the position of the 
cloned monster on call.

For _mons_summon_monster_illusion:
By passing the cloned monster's attitude to clone_mons, we don't have to
do all of the gymnastics that previously had to be done to properly set
the cloned monster attitude and not adversely affect arena bookkeeping.

for _phantom_mirror, we can now simply set ATT_FRIENDLY in the
clone_mons call directly.
  • Loading branch information
jmbjr authored and rawlins committed Oct 20, 2018
1 parent 6fd5563 commit 6ff198f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 32 deletions.
3 changes: 1 addition & 2 deletions crawl-ref/source/evoke.cc
Expand Up @@ -1413,7 +1413,7 @@ static spret_type _phantom_mirror()
const int surge = pakellas_surge_devices();
surge_power(you.spec_evoke() + surge);

monster* mon = clone_mons(victim, true);
monster* mon = clone_mons(victim, true, nullptr, ATT_FRIENDLY);
if (!mon)
{
canned_msg(MSG_NOTHING_HAPPENS);
Expand All @@ -1427,7 +1427,6 @@ static spret_type _phantom_mirror()
surge)
* (100 - victim->check_res_magic(power)) / 100));

mon->attitude = ATT_FRIENDLY;
mon->mark_summoned(dur, true, SPELL_PHANTOM_MIRROR);

mon->summoner = MID_PLAYER;
Expand Down
63 changes: 34 additions & 29 deletions crawl-ref/source/mon-clone.cc
Expand Up @@ -86,25 +86,12 @@ static void _mons_summon_monster_illusion(monster* caster,
return;

bool cloning_visible = false;
monster *clone = nullptr;

// [ds] Bind the original target's attitude before calling
// clone_mons, since clone_mons also updates arena bookkeeping.
//
// If an enslaved caster creates a clone from a regular hostile,
// the clone should still be friendly.
//
// This is all inside its own block so the unwind_var will be unwound
// before we use foe->name below.
{
const mon_attitude_type clone_att =
caster->friendly() ? ATT_FRIENDLY : caster->attitude;

unwind_var<mon_attitude_type> att(foe->attitude, clone_att);
clone = clone_mons(foe, true, &cloning_visible);
}

if (clone)
if (monster *clone = clone_mons(foe, true, &cloning_visible,
caster->friendly() ?
ATT_FRIENDLY : caster->attitude))
{
const string clone_id = _monster_clone_id_for(foe);
clone->props[CLONE_SLAVE_KEY] = clone_id;
Expand Down Expand Up @@ -268,37 +255,55 @@ bool mons_clonable(const monster* mon, bool needs_adjacent)
return true;
}

/*
* @param orig The original monster to clone.
* @param quiet If true, suppress messages
* @param obvious If true, player can see the orig & cloned monster
* @return Returns the cloned monster
*/
monster* clone_mons(const monster* orig, bool quiet, bool* obvious)
{
// Pass temp_attitude to handle enslaved monsters cloning monsters
return clone_mons(orig, quiet, obvious, orig->temp_attitude());
}

/**
* @param orig The original monster to clone.
* @param quiet If true, suppress messages
* @param obvious If true, player can see the orig & cloned monster
* @param mon_att The attitude to set for the cloned monster
* @return Returns the cloned monster
*/
monster* clone_mons(const monster* orig, bool quiet, bool* obvious,
coord_def pos)
mon_attitude_type mon_att)
{
// Is there an open slot in menv?
monster* mons = get_free_monster();
coord_def pos(0, 0);

if (!mons)
return nullptr;

if (!in_bounds(pos))
for (fair_adjacent_iterator ai(orig->pos()); ai; ++ai)
{
for (fair_adjacent_iterator ai(orig->pos()); ai; ++ai)
if (in_bounds(*ai)
&& !actor_at(*ai)
&& monster_habitable_grid(orig, grd(*ai)))
{
if (in_bounds(*ai)
&& !actor_at(*ai)
&& monster_habitable_grid(orig, grd(*ai)))
{
pos = *ai;
}
pos = *ai;
}

if (!in_bounds(pos))
return nullptr;
}

if (!in_bounds(pos))
return nullptr;

ASSERT(!actor_at(pos));
ASSERT_IN_BOUNDS(pos);

*mons = *orig;
mons->set_new_monster_id();
mons->move_to_pos(pos);
mons->attitude = mon_att;

// The monster copy constructor doesn't copy constriction, so no need to
// worry about that.

Expand Down
7 changes: 6 additions & 1 deletion crawl-ref/source/mon-clone.h
@@ -1,12 +1,17 @@
#pragma once

#include "mon-attitude-type.h"

#define CLONE_MASTER_KEY "mcloneorig"
#define CLONE_SLAVE_KEY "mclonedupe"

// Formerly in mon-stuff:
bool mons_clonable(const monster* orig, bool needs_adjacent = true);
monster *clone_mons(const monster* orig, bool quiet = false,
bool* obvious = nullptr, coord_def pos = coord_def(0, 0));
bool* obvious = nullptr);

monster *clone_mons(const monster* orig, bool quiet,
bool* obvious, mon_attitude_type mon_att);

void mons_summon_illusion_from(monster* mons, actor *foe,
spell_type spell_cast = SPELL_NO_SPELL,
Expand Down

0 comments on commit 6ff198f

Please sign in to comment.