made AI know the basics of backstab
This commit is contained in:
parent
fccc5f91a2
commit
0767a4172f
8 changed files with 52 additions and 5 deletions
|
@ -383,6 +383,8 @@ message="Message"
|
|||
describe_unit="Describe Unit"
|
||||
rename_unit="Rename Unit"
|
||||
scenario_objectives="Scenario Objectives"
|
||||
mp_objectives="Victory
|
||||
@Defeat enemy leader(s)"
|
||||
recruit="Recruit"
|
||||
recall="Recall"
|
||||
recall_disallowed="You are seperated from your soldiers and may not recall them"
|
||||
|
|
|
@ -73,6 +73,17 @@ void ai::do_attack_analysis(
|
|||
const unit_map::const_iterator unit_itor = units_.find(current_unit);
|
||||
assert(unit_itor != units_.end());
|
||||
|
||||
//see if the unit has the backstab ability -- units with backstab
|
||||
//will want to try to have a friendly unit opposite the position they move to
|
||||
bool backstab = false;
|
||||
const std::vector<attack_type>& attacks = unit_itor->second.attacks();
|
||||
for(std::vector<attack_type>::const_iterator a = attacks.begin(); a != attacks.end(); ++a) {
|
||||
if(a->backstab()) {
|
||||
backstab = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double best_vulnerability = 0.0, best_support = 0.0;
|
||||
int best_rating = 0;
|
||||
int cur_position = -1;
|
||||
|
@ -99,8 +110,24 @@ void ai::do_attack_analysis(
|
|||
continue;
|
||||
}
|
||||
|
||||
//check to see whether this move would be a backstab
|
||||
int backstab_bonus = 1;
|
||||
|
||||
if(backstab && tiles[(j+3)%6] != current_unit) {
|
||||
const unit_map::const_iterator itor = units_.find(tiles[(j+3)%6]);
|
||||
|
||||
//note that we *could* also check if a unit plans to move there before we're
|
||||
//at this stage, but we don't because, since the attack calculations don't
|
||||
//actually take backstab into account (too complicated), this could actually
|
||||
//make our analysis look *worse* instead of better.
|
||||
//so we only check for 'concrete' backstab opportunities.
|
||||
if(itor != units_.end() && itor->second.side() == unit_itor->second.side()) {
|
||||
backstab_bonus = 2;
|
||||
}
|
||||
}
|
||||
|
||||
//see if this position is the best rated we've seen so far
|
||||
const int rating = rate_terrain(unit_itor->second,tiles[j]);
|
||||
const int rating = rate_terrain(unit_itor->second,tiles[j]) * backstab_bonus;
|
||||
if(cur_position >= 0 && rating < best_rating) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -732,8 +732,8 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
|
|||
const int size = lexical_cast_default<int>(cfg["size"],12);
|
||||
const int lifetime = lexical_cast_default<int>(cfg["duration"],20);
|
||||
const int red = lexical_cast_default<int>(cfg["red"],0);
|
||||
const int green = lexical_cast_default<int>(cfg["red"],0);
|
||||
const int blue = lexical_cast_default<int>(cfg["red"],0);
|
||||
const int green = lexical_cast_default<int>(cfg["green"],0);
|
||||
const int blue = lexical_cast_default<int>(cfg["blue"],0);
|
||||
|
||||
SDL_Color colour = {red,green,blue,255};
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
|
|||
int cur_xpmod = 100;
|
||||
|
||||
// Dialog width and height
|
||||
int width = 640;
|
||||
int width = 740;
|
||||
int height = 440;
|
||||
const int left = (disp.x()-width)/2;
|
||||
const int top = (disp.y()-height)/2;
|
||||
|
|
|
@ -239,7 +239,7 @@ int mp_connect::load_map(const std::string& era, int map, int num_turns, int vil
|
|||
|
||||
if ((*level_)["objectives"] == "")
|
||||
{
|
||||
(*level_)["objectives"] = "Victory:\n@Defeat enemy leader(s)\n";
|
||||
(*level_)["objectives"] = string_table["mp_objectives"];
|
||||
}
|
||||
|
||||
(*level_)["experience_modifier"] = lexical_cast<std::string>(xpmodifier);
|
||||
|
|
|
@ -623,6 +623,12 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
|
|||
throw replay::error();
|
||||
}
|
||||
|
||||
if(u_type->second.cost() > current_team.gold()) {
|
||||
std::cerr << "unit '" << u_type->second.name() << "' is too expensive to recruit: "
|
||||
<< u_type->second.cost() << "/" << current_team.gold() << "\n";
|
||||
throw replay::error();
|
||||
}
|
||||
|
||||
statistics::recruit_unit(new_unit);
|
||||
|
||||
current_team.spend_gold(u_type->second.cost());
|
||||
|
|
|
@ -33,6 +33,7 @@ attack_type::attack_type(const config& cfg)
|
|||
name_ = cfg["name"];
|
||||
type_ = cfg["type"];
|
||||
special_ = cfg["special"];
|
||||
backstab_ = special_ == "backstab";
|
||||
icon_ = cfg["icon"];
|
||||
if(icon_.empty())
|
||||
icon_ = "misc/" + name_ + ".png";
|
||||
|
@ -139,6 +140,11 @@ double attack_type::defense_weight() const
|
|||
return defense_weight_;
|
||||
}
|
||||
|
||||
bool attack_type::backstab() const
|
||||
{
|
||||
return backstab_;
|
||||
}
|
||||
|
||||
int attack_type::get_first_frame(attack_type::FRAME_TYPE type) const
|
||||
{
|
||||
if(frames_[type].empty())
|
||||
|
|
|
@ -40,6 +40,8 @@ public:
|
|||
double attack_weight() const;
|
||||
double defense_weight() const;
|
||||
|
||||
bool backstab() const;
|
||||
|
||||
enum FRAME_TYPE { UNIT_FRAME, MISSILE_FRAME };
|
||||
enum FRAME_DIRECTION { VERTICAL, DIAGONAL };
|
||||
|
||||
|
@ -74,6 +76,10 @@ private:
|
|||
double attack_weight_;
|
||||
double defense_weight_;
|
||||
|
||||
//caches whether the unit can backstab. This is important
|
||||
//because the AI queries it alot.
|
||||
bool backstab_;
|
||||
|
||||
struct frame {
|
||||
frame(int i1, int i2, const std::string& img, int offset)
|
||||
: start(i1), end(i2), xoffset(offset), image(img)
|
||||
|
|
Loading…
Add table
Reference in a new issue