Fix ai usage of unit::type()

This commit is contained in:
Dominic Bolin 2006-07-29 19:34:46 +00:00
parent 2700ade58a
commit c989fe09b0
8 changed files with 41 additions and 13 deletions

View File

@ -356,7 +356,11 @@ void ai::attack_analysis::analyze(const gamemap& map, unit_map& units,
// This cache is only about 99% correct, but speeds up evaluation by about 1000 times.
// We recalculate when we actually attack.
std::map<std::pair<location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >::iterator usc;
usc = ai_obj.unit_stats_cache_.find(std::pair<location, const unit_type *>(target, &up->second.type()));
if(up->second.type()) {
usc = ai_obj.unit_stats_cache_.find(std::pair<location, const unit_type *>(target, up->second.type()));
} else {
usc = ai_obj.unit_stats_cache_.end();
}
// Just check this attack is valid for this attacking unit (may be modified)
if (usc != ai_obj.unit_stats_cache_.end() && usc->second.first.attack_num < (int)up->second.attacks().size()) {
from_cache = true;
@ -371,9 +375,9 @@ void ai::attack_analysis::analyze(const gamemap& map, unit_map& units,
prev_bc = bc;
prev_def = &bc->get_defender_combatant(prev_def);
if (!from_cache) {
if (!from_cache && up->second.type()) {
ai_obj.unit_stats_cache_.insert(std::pair<std::pair<location, const unit_type *>,std::pair<battle_context::unit_stats,battle_context::unit_stats> >
(std::pair<location, const unit_type *>(target, &up->second.type()),
(std::pair<location, const unit_type *>(target, up->second.type()),
std::pair<battle_context::unit_stats,battle_context::unit_stats>(bc->get_attacker_stats(),
bc->get_defender_stats())));
}

View File

@ -546,7 +546,8 @@ static PyObject* wrapper_unit_type( wesnoth_unit* unit, PyObject* args )
return NULL;
if (!running_instance->is_unit_valid(unit->unit_))
return NULL;
return wrap_unittype(unit->unit_->type());
wassert(unit->unit_->type());
return wrap_unittype(*unit->unit_->type());
}
static PyObject* wrapper_unit_attacks( wesnoth_unit* unit, PyObject* args )

View File

@ -54,6 +54,24 @@ config& config::operator=(const config& cfg)
return *this;
}
namespace {
config* pre_allocated_configs[200000];
int n_pre_allocated = 0;
}
void* config::operator new(size_t) throw(std::bad_alloc)
{
if(! n_pre_allocated) {
log_scope("pre-allocating configs");
for(int a=0;a<200000;++a) {
pre_allocated_configs[a] = ::new config();
}
n_pre_allocated = 200000;
}
config* res = pre_allocated_configs[--n_pre_allocated];
return res;
}
// Note this isn't a real copy. The children are still in both config trees
// and updating them will affect both trees.
void config::append(const config& cfg)

View File

@ -42,6 +42,7 @@ public:
~config();
config& operator=(const config& cfg);
void* operator new(size_t) throw(std::bad_alloc);
typedef std::vector<config*> child_list;
typedef std::map<std::string,child_list> child_map;

View File

@ -640,7 +640,8 @@ namespace events{
current_team.set_action_bonus_count(1 + current_team.action_bonus_count());
redo_stack_.clear();
if(new_unit.type().genders().size() > 1 || new_unit.type().has_random_traits()) {
wassert(new_unit.type());
if(new_unit.type()->genders().size() > 1 || new_unit.type()->has_random_traits()) {
clear_undo_stack(team_num);
} else {
undo_stack_.push_back(undo_action(new_unit,loc,RECRUIT_POS));
@ -806,7 +807,8 @@ namespace events{
const unit& un = units_.find(action.recall_loc)->second;
statistics::un_recruit_unit(un);
current_team.spend_gold(-un.type().cost());
wassert(un.type());
current_team.spend_gold(-un.type()->cost());
//MP_COUNTDOWN take away recruit bonus
if(action.countdown_time_bonus)
@ -936,7 +938,7 @@ namespace events{
//unit new_unit(action.affected_unit.type(),team_num_,true);
const std::string& msg = recruit_unit(map_,team_num,units_,new_unit,loc,gui_);
if(msg.empty()) {
current_team.spend_gold(new_unit.type().cost());
current_team.spend_gold(new_unit.type()->cost());
statistics::recruit_unit(new_unit);
//MP_COUNTDOWN: restore recruitment bonus

View File

@ -451,8 +451,8 @@ void un_recruit_unit(const unit& u)
return;
stats& s = get_stats(u.side());
s.recruits[u.type().id()]--;
s.recruit_cost -= u.type().cost();
s.recruits[u.id()]--;
s.recruit_cost -= u.cost();
}

View File

@ -443,12 +443,14 @@ const std::string& unit::id() const
{
return id_;
}
const unit_type& unit::type() const
const unit_type* unit::type() const
{
wassert(gamedata_ != NULL);
std::map<std::string,unit_type>::const_iterator i = gamedata_->unit_types.find(id());
wassert(i != gamedata_->unit_types.end());
return i->second;
if(i != gamedata_->unit_types.end()) {
return &i->second;
}
return NULL;
}
// the actual name of the unit
const std::string& unit::name() const

View File

@ -69,7 +69,7 @@ class unit
// the current type id
const std::string& id() const;
const unit_type& type() const;
const unit_type* type() const;
// the actual name of the unit
const std::string& name() const;
void rename(const std::string& name);