// dx & dy indicates moving direction, useful for choosing melee attack targets bool PlayerInst::enqueue_io_spell_and_attack_actions(GameState* gs, float dx, float dy) { GameView& view = gs->view(); WeaponEntry& wentry = weapon().weapon_entry(); bool mouse_within = gs->mouse_x() < gs->view().width; int rmx = view.x + gs->mouse_x(), rmy = view.y + gs->mouse_y(); int level = gs->get_level()->id(), frame = gs->frame(); bool is_moving = (dx != 0.0f || dy != 0.0f); IOController& io = gs->io_controller(); bool attack_used = enqueue_io_spell_actions(gs); bool autotarget = io.query_event(IOEvent::AUTOTARGET_CURRENT_ACTION) || io.query_event(IOEvent::ACTIVATE_SPELL_N); bool mousetarget = io.query_event(IOEvent::MOUSETARGET_CURRENT_ACTION); bool weaponuse = spell_selected() == -1; // choose & use weapon if (io.query_event(IOEvent::USE_WEAPON)) { queued_actions.push_back( game_action(gs, this, GameAction::CHOSE_SPELL, -1)); autotarget = true; weaponuse = true; } if (spell_selected() >= 0 && spells_known().get_entry(spell_selected()).mp_cost > core_stats().mp) { weaponuse = true; } // weapon use if (!attack_used && weaponuse && (autotarget || mousetarget)) { bool is_projectile = wentry.uses_projectile || equipment().has_projectile(); MonsterController& mc = gs->monster_controller(); GameInst* curr_target = gs->get_instance(current_target); GameInst* target = NULL; Pos targ_pos; if (is_projectile) { if (mousetarget) { targ_pos = Pos(rmx, rmy); } else if (autotarget && curr_target) { targ_pos = curr_target->pos(); } } else { if (mousetarget) { dx = rmx - x, dy = rmy - y; } target = get_weapon_autotarget(gs, this, curr_target, dx, dy); if (target) { targ_pos = Pos(target->x, target->y); } if (!is_moving && !target && !mousetarget && spell_selected() == -1 && curr_target && !is_projectile) { int vx, vy; GameInst* closest = get_closest_monster(gs, this); if (closest && decide_attack_movement(pos(), closest->pos(), TILE_SIZE / 4, vx, vy)) { queued_actions.push_back( game_action(gs, this, GameAction::MOVE, spellselect, round(vx), round(vy))); } } } if (target || (is_projectile && (mousetarget || curr_target))) { queued_actions.push_back( game_action(gs, this, GameAction::USE_WEAPON, spellselect, targ_pos.x, targ_pos.y)); attack_used = true; } } return attack_used; }