Move camera to show the most possible targets in range

This commit is contained in:
2025-03-02 22:42:18 -06:00
committed by Celtic Minstrel
parent c9f79ba071
commit 3e10e2923b
3 changed files with 39 additions and 13 deletions

View File

@@ -1641,10 +1641,10 @@ void load_missile() {
ammo_inv_slot = thrown.slot;
add_string_to_buf("Throw: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
overall_mode = MODE_THROWING;
current_spell_range = 8;
if(thrown->ability == eItemAbil::DISTANCE_MISSILE)
current_spell_range += thrown->abil_strength;
handle_target_mode(MODE_THROWING, current_spell_range);
if(thrown->ability == eItemAbil::EXPLODING_WEAPON)
current_pat = radius2;
else current_pat = single;
@@ -1657,36 +1657,36 @@ void load_missile() {
} else if(bow && arrow) {
missile_inv_slot = bow.slot;
ammo_inv_slot = arrow.slot;
overall_mode = MODE_FIRING;
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
current_spell_range = 12;
if(arrow->ability == eItemAbil::DISTANCE_MISSILE)
current_spell_range += arrow->abil_strength;
handle_target_mode(MODE_FIRING, current_spell_range);
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
if(arrow->ability == eItemAbil::EXPLODING_WEAPON)
current_pat = radius2;
else current_pat = single;
} else if(crossbow && bolts) {
missile_inv_slot = crossbow.slot;
ammo_inv_slot = bolts.slot;
overall_mode = MODE_FIRING;
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
current_spell_range = 12;
if(bolts->ability == eItemAbil::DISTANCE_MISSILE)
current_spell_range += bolts->abil_strength;
handle_target_mode(MODE_FIRING, current_spell_range);
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
if(bolts->ability == eItemAbil::EXPLODING_WEAPON)
current_pat = radius2;
else current_pat = single;
} else if(no_ammo) {
missile_inv_slot = no_ammo.slot;
ammo_inv_slot = no_ammo.slot;
overall_mode = MODE_FIRING;
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
current_spell_range = 12;
if(no_ammo->ability == eItemAbil::DISTANCE_MISSILE)
current_spell_range += no_ammo->abil_strength;
handle_target_mode(MODE_FIRING, current_spell_range);
add_string_to_buf("Fire: Select a target.");
add_string_to_buf(" (Hit 's' to cancel.)");
if(no_ammo->ability == eItemAbil::EXPLODING_WEAPON)
current_pat = radius2;
else current_pat = single;
@@ -5154,8 +5154,8 @@ void start_spell_targeting(eSpell num, bool freebie, int spell_range, eSpellPat
else if(isMage(num))
add_string_to_buf(" (Hit 'm' to cancel.)");
else add_string_to_buf(" (Hit 'p' to cancel.)");
overall_mode = MODE_SPELL_TARGET;
current_spell_range = num == eSpell::NONE ? spell_range : (*num).range;
handle_target_mode(MODE_SPELL_TARGET, current_spell_range);
current_pat = single;
switch(num) { // Different spells have different messages and diff. target shapes
@@ -5217,9 +5217,9 @@ void start_fancy_spell_targeting(eSpell num, bool freebie, int spell_range, eSpe
add_string_to_buf(" (Hit 'm' to cancel.)");
else add_string_to_buf(" (Hit 'p' to cancel.)");
add_string_to_buf(" (Hit space to cast.)");
overall_mode = MODE_FANCY_TARGET;
current_pat = single;
current_spell_range = num == eSpell::NONE ? spell_range : (*num).range;
handle_target_mode(MODE_FANCY_TARGET, current_spell_range);
current_pat = single;
short bonus = univ.current_pc().stat_adj(eSkill::INTELLIGENCE);
short level = freebie ? store_item_spell_level : univ.current_pc().level;

View File

@@ -1037,3 +1037,27 @@ short scan_for_response(const char *str) {
return -1;
}
void handle_target_mode(eGameMode target_mode, int range) {
overall_mode = target_mode;
// Lock on to enemies in range:
if(get_bool_pref("TargetLock", true)){
location loc = univ.current_pc().combat_pos;
std::vector<location> enemy_locs_in_range;
for(short i = 0; i < univ.town.monst.size(); i++){
auto& monst = univ.town.monst[i];
if(monst.is_alive()) {
eAttitude att = monst.attitude;
if((att == eAttitude::HOSTILE_A || att == eAttitude::HOSTILE_B)
&& dist(loc, monst.cur_loc) <= range){
enemy_locs_in_range.push_back(monst.cur_loc);
}
}
}
if(!enemy_locs_in_range.empty()){
std::vector<location> dest_candidates = points_containing_most(enemy_locs_in_range);
center = closest_point(dest_candidates, loc);
draw_terrain();
}
}
}

View File

@@ -4,6 +4,7 @@
#include "location.hpp"
#include "scenario/item.hpp"
#include "gfx/gfxsheets.hpp"
#include "boe.consts.hpp"
#ifndef BOE_NEWGRAPH_H
#define BOE_NEWGRAPH_H
@@ -70,6 +71,7 @@ void draw_shop_graphics(bool item_pressed, bool item_help_pressed, rectangle cli
void refresh_shopping();
void click_talk_rect(word_rect_t word);
void place_talk_str(std::string str_to_place,std::string str_to_place2,short color,rectangle c_rect);
void handle_target_mode(eGameMode target_mode, int range);
short scan_for_response(const char *str);
void refresh_talking();
graf_pos calc_item_rect(int num,rectangle& to_rect);