Exemplo n.º 1
0
long instf_creature_cast_spell(struct Thing *creatng, long *param)
{
    struct CreatureControl *cctrl;
    struct Thing *trthing;
    struct SpellInfo *spinfo;
    long spl_idx;
    TRACE_THING(creatng);
    cctrl = creature_control_get_from_thing(creatng);
    spl_idx = *param;
    spinfo = get_magic_info(spl_idx);
    if (spinfo->cast_at_thing)
    {
        trthing = thing_get(cctrl->targtng_idx);
        if (!thing_is_invalid(trthing))
        {
            creature_cast_spell_at_thing(creatng, trthing, spl_idx, cctrl->explevel);
            return 0;
        }
    }
    creature_cast_spell(creatng, spl_idx, cctrl->explevel, cctrl->targtstl_x, cctrl->targtstl_y);
    return 0;
}
Exemplo n.º 2
0
long instf_creature_cast_spell(struct Thing *creatng, long *param)
{
    struct CreatureControl *cctrl;
    struct Thing *trthing;
    struct SpellInfo *spinfo;
    long spl_idx;
    TRACE_THING(creatng);
    cctrl = creature_control_get_from_thing(creatng);
    spl_idx = *param;
    spinfo = get_magic_info(spl_idx);
    SYNCDBG(8,"The %s index %d casts %s",thing_model_name(creatng),(int)creatng->index,spell_code_name(spl_idx));
    if (spinfo->cast_at_thing)
    {
        trthing = thing_get(cctrl->targtng_idx);
        if (!thing_is_invalid(trthing))
        {
            creature_cast_spell_at_thing(creatng, trthing, spl_idx, cctrl->explevel);
            return 0;
        }
    }
    creature_cast_spell(creatng, spl_idx, cctrl->explevel, cctrl->targtstl_x, cctrl->targtstl_y);
    return 0;
}
Exemplo n.º 3
0
void creature_t::update()
{

  if (flag & CF_SPELLCASTER)
  {
    if (spell_timer > 0)
      spell_timer--;
  }

  if (get_active_effects_for(this) & EF_CONFUSE)
  {
    random_walk();
  }
  else if (identity == IDENT_SHOPKEEPER)
  {
    update_shopkeeper(this);
  }
  else if (flag & CF_NEUTRAL)
  {
    random_walk();
  }
  else if ((flag & CF_HIDES) && (!(get_active_effects_for(this) & EF_HIDDEN)) && !player.sees(this))
  {
    hide_creature(this);
  }
  else if (flag & CF_PLAYER_ALLY)
  {
    creature_t* closest_enemy = get_closest_enemy();
    if (closest_enemy && sees(closest_enemy))
    {
      if ((flag & CF_SPELLCASTER) && spell_timer == 0)
      {
        creature_cast_spell(this, closest_enemy);
      }
      else
      {
        step_toward(closest_enemy->pos.x, closest_enemy->pos.y, closest_enemy);
      }
    }
    else
    {
      _regular_walk_around(this);
    }
  }
  else if (sees(&player))
  {
    if (seen_player == 0)
    {
      // Shout should depend on if the creature is intelligent etc.
      if ((flag & CF_SPEAKS)&& !(flag & CF_SPELLCASTER))
      {
        shout("");
      }
      seen_player = 1;
    }
    forget_player_timer = FORGETFULNESS;

    if ((flag & CF_SPELLCASTER) && spell_timer == 0)
    {
      creature_cast_spell(this, &player);
    }
    else
    {
      bool move_towards = true;

      if (flag & CF_INTELLIGENT)
      {
        if (_try_zap_wand(this))
        {
          move_towards = false;
        }
      }

      if (move_towards)
      {
        step_toward(player.pos.x, player.pos.y, nullptr);
      }
    }

    // Stop being interested in whatever noise it heard.
    heard_noise = 0;
  }
  else
  {
    // If the spell timer has reached 0 while the creature is outside player view, reset
    // it for a random value to make things more varied when a caster enters view.
    if (spell_timer == 0)
    {
      spell_timer = random(0, spell_timer_duration);
    }

    if (seen_player && forget_player_timer > 0)
    {
      forget_player_timer--;
      step_toward(player.pos.x, player.pos.y, nullptr);
    }
    else
    {
      seen_player = 0;
      if (heard_noise)
      {
        step_toward(noise_location.x, noise_location.y, nullptr);
        if (pos.x == noise_location.x && pos.y == noise_location.y)
        {
          // Found the position of the noise.
          heard_noise = 0;
        }
      }
      else
      {
        // If the player has allies and I can see one, attack it.
        creature_t* closest_enemy = get_closest_enemy();
        if (closest_enemy && sees(closest_enemy))
        {
          step_toward(closest_enemy->pos.x, closest_enemy->pos.y, closest_enemy);
        }
        else
        {
          _regular_walk_around(this);
        }
      }
    }
  }

  ap -= speed;
}