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; }
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; }
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; }