added use_prng preference which adds a new experimental pseudo-RNG for casual campaign play
This commit is contained in:
parent
b89b89abea
commit
3886228447
4 changed files with 58 additions and 1 deletions
|
@ -847,6 +847,11 @@ private:
|
|||
|
||||
bool update_display_;
|
||||
bool OOS_error_;
|
||||
|
||||
bool use_prng_;
|
||||
|
||||
std::vector<bool> prng_attacker_;
|
||||
std::vector<bool> prng_defender_;
|
||||
};
|
||||
|
||||
attack::unit_info::unit_info(const map_location& loc, int weapon, unit_map& units)
|
||||
|
@ -908,7 +913,13 @@ attack::attack(const map_location& attacker,
|
|||
, errbuf_()
|
||||
, update_display_(update_display)
|
||||
, OOS_error_(false)
|
||||
|
||||
//new experimental prng mode.
|
||||
, use_prng_(preferences::get("use_prng") == "yes" && randomness::generator->is_networked() == false)
|
||||
{
|
||||
if(use_prng_) {
|
||||
std::cerr << "Using experimental PRNG for combat\n";
|
||||
}
|
||||
}
|
||||
|
||||
void attack::fire_event(const std::string& n)
|
||||
|
@ -1032,7 +1043,39 @@ bool attack::perform_hit(bool attacker_turn, statistics::attack_context& stats)
|
|||
int& abs_n = attacker_turn ? abs_n_attack_ : abs_n_defend_;
|
||||
bool& update_fog = attacker_turn ? update_def_fog_ : update_att_fog_;
|
||||
|
||||
int ran_num = randomness::generator->get_random_int(0, 99);
|
||||
int ran_num;
|
||||
|
||||
if(use_prng_) {
|
||||
|
||||
std::vector<bool>& prng_seq = attacker_turn ? prng_attacker_ : prng_defender_;
|
||||
|
||||
if(prng_seq.empty()) {
|
||||
const int ntotal = attacker.cth_*attacker.n_attacks_;
|
||||
int num_hits = ntotal/100;
|
||||
const int additional_hit_chance = ntotal%100;
|
||||
if(additional_hit_chance > 0 && randomness::generator->get_random_int(0, 99) < additional_hit_chance) {
|
||||
++num_hits;
|
||||
}
|
||||
|
||||
std::vector<int> indexes;
|
||||
for(int i = 0; i != attacker.n_attacks_; ++i) {
|
||||
prng_seq.push_back(false);
|
||||
indexes.push_back(i);
|
||||
}
|
||||
|
||||
for(int i = 0; i != num_hits; ++i) {
|
||||
int n = randomness::generator->get_random_int(0, static_cast<int>(indexes.size())-1);
|
||||
prng_seq[indexes[n]] = true;
|
||||
indexes.erase(indexes.begin() + n);
|
||||
}
|
||||
}
|
||||
|
||||
bool does_hit = prng_seq.back();
|
||||
prng_seq.pop_back();
|
||||
ran_num = does_hit ? 0 : 99;
|
||||
} else {
|
||||
ran_num = randomness::generator->get_random_int(0, 99);
|
||||
}
|
||||
bool hits = (ran_num < attacker.cth_);
|
||||
|
||||
int damage = 0;
|
||||
|
|
|
@ -81,6 +81,13 @@ namespace randomness
|
|||
uint32_t operator()() { return next_random(); }
|
||||
|
||||
static rng& default_instance();
|
||||
|
||||
/**
|
||||
* Is this random source networked? If it is it's very important we do actually use
|
||||
* this random source to stay in-sync.
|
||||
*/
|
||||
virtual bool is_networked() const { return false; }
|
||||
|
||||
protected:
|
||||
virtual uint32_t next_random_impl() = 0;
|
||||
unsigned int random_calls_;
|
||||
|
|
|
@ -50,4 +50,9 @@ namespace randomness
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
bool synced_rng::is_networked() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace randomness
|
|||
synced_rng(std::function<std::string()> seed_generator);
|
||||
virtual ~synced_rng();
|
||||
|
||||
virtual bool is_networked() const;
|
||||
|
||||
protected:
|
||||
virtual uint32_t next_random_impl();
|
||||
private:
|
||||
|
|
Loading…
Add table
Reference in a new issue