change liminal implementation, from a night and day malus to a twilight bonus
This commit is contained in:
parent
bba1dc264b
commit
40483874ea
5 changed files with 66 additions and 11 deletions
|
@ -317,7 +317,7 @@ battle_context_unit_stats::battle_context_unit_stats(const unit_type* u_type,
|
|||
int base_damage = weapon->modified_damage(backstab_pos);
|
||||
int damage_multiplier = 100;
|
||||
damage_multiplier
|
||||
+= generic_combat_modifier(lawful_bonus, u_type->alignment(), u_type->musthave_status("fearless"));
|
||||
+= generic_combat_modifier(lawful_bonus, u_type->alignment(), u_type->musthave_status("fearless"), 0);
|
||||
damage_multiplier *= opp_type->resistance_against(weapon->type(), !attacking);
|
||||
|
||||
damage = round_damage(base_damage, damage_multiplier, 10000);
|
||||
|
@ -1608,10 +1608,10 @@ int combat_modifier(const unit_map& units,
|
|||
{
|
||||
const tod_manager& tod_m = *resources::tod_manager;
|
||||
int lawful_bonus = tod_m.get_illuminated_time_of_day(units, map, loc).lawful_bonus;
|
||||
return generic_combat_modifier(lawful_bonus, alignment, is_fearless);
|
||||
return generic_combat_modifier(lawful_bonus, alignment, is_fearless, tod_m.get_max_liminal_bonus());
|
||||
}
|
||||
|
||||
int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bool is_fearless)
|
||||
int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bool is_fearless, int max_liminal_bonus)
|
||||
{
|
||||
int bonus;
|
||||
|
||||
|
@ -1626,7 +1626,7 @@ int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bo
|
|||
bonus = -lawful_bonus;
|
||||
break;
|
||||
case unit_type::ALIGNMENT::LIMINAL:
|
||||
bonus = -std::abs(lawful_bonus);
|
||||
bonus = std::max(0, max_liminal_bonus-std::abs(lawful_bonus));
|
||||
break;
|
||||
default:
|
||||
bonus = 0;
|
||||
|
|
|
@ -282,7 +282,7 @@ int combat_modifier(const unit_map& units,
|
|||
* Returns the amount that a unit's damage should be multiplied by
|
||||
* due to a given lawful_bonus.
|
||||
*/
|
||||
int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bool is_fearless);
|
||||
int generic_combat_modifier(int lawful_bonus, unit_type::ALIGNMENT alignment, bool is_fearless, int max_liminal_bonus);
|
||||
/**
|
||||
* Function to check if an attack will satisfy the requirements for backstab.
|
||||
* Input:
|
||||
|
|
|
@ -1106,7 +1106,7 @@ static config time_of_day_at(reports::context & rc, const map_location& mouseove
|
|||
}
|
||||
|
||||
int b = tod.lawful_bonus;
|
||||
|
||||
int l = generic_combat_modifier(b, unit_type::ALIGNMENT::LIMINAL, false, rc.tod().get_max_liminal_bonus());
|
||||
std::string lawful_color("white");
|
||||
std::string chaotic_color("white");
|
||||
std::string liminal_color("white");
|
||||
|
@ -1114,7 +1114,9 @@ static config time_of_day_at(reports::context & rc, const map_location& mouseove
|
|||
if (b != 0) {
|
||||
lawful_color = (b > 0) ? "green" : "red";
|
||||
chaotic_color = (b < 0) ? "green" : "red";
|
||||
liminal_color = "red";
|
||||
}
|
||||
if (l != 0) {
|
||||
liminal_color = (l > 0) ? "green" : "red";
|
||||
}
|
||||
tooltip << tod.name << '\n'
|
||||
<< _("Lawful units: ") << "<span foreground=\"" << lawful_color << "\">"
|
||||
|
@ -1123,7 +1125,7 @@ static config time_of_day_at(reports::context & rc, const map_location& mouseove
|
|||
<< _("Chaotic units: ") << "<span foreground=\"" << chaotic_color << "\">"
|
||||
<< utils::signed_percent(-b) << "</span>\n"
|
||||
<< _("Liminal units: ") << "<span foreground=\"" << liminal_color << "\">"
|
||||
<< utils::signed_percent(-(std::abs(b))) << "</span>\n";
|
||||
<< utils::signed_percent(l) << "</span>\n";
|
||||
|
||||
std::string tod_image = tod.image;
|
||||
if(tod.bonus_modified > 0) {
|
||||
|
@ -1158,6 +1160,7 @@ static config unit_box_at(reports::context & rc, const map_location& mouseover_h
|
|||
}
|
||||
|
||||
int bonus = local_tod.lawful_bonus;
|
||||
int l = generic_combat_modifier(bonus, unit_type::ALIGNMENT::LIMINAL, false, rc.tod().get_max_liminal_bonus());
|
||||
|
||||
std::string lawful_color("white");
|
||||
std::string chaotic_color("white");
|
||||
|
@ -1166,7 +1169,9 @@ static config unit_box_at(reports::context & rc, const map_location& mouseover_h
|
|||
if (bonus != 0) {
|
||||
lawful_color = (bonus > 0) ? "green" : "red";
|
||||
chaotic_color = (bonus < 0) ? "green" : "red";
|
||||
liminal_color = "red";
|
||||
}
|
||||
if (l != 0) {
|
||||
liminal_color = (l > 0) ? "green" : "red";
|
||||
}
|
||||
tooltip << local_tod.name << '\n'
|
||||
<< _("Lawful units: ") << "<span foreground=\"" << lawful_color << "\">"
|
||||
|
@ -1175,7 +1180,7 @@ static config unit_box_at(reports::context & rc, const map_location& mouseover_h
|
|||
<< _("Chaotic units: ") << "<span foreground=\"" << chaotic_color << "\">"
|
||||
<< utils::signed_percent(-bonus) << "</span>\n"
|
||||
<< _("Liminal units: ") << "<span foreground=\"" << liminal_color << "\">"
|
||||
<< utils::signed_percent(-(std::abs(bonus))) << "</span>\n";
|
||||
<< utils::signed_percent(l) << "</span>\n";
|
||||
|
||||
std::string local_tod_image = "themes/classic/" + local_tod.image;
|
||||
std::string global_tod_image = "themes/classic/" + global_tod.image;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include "utils/functional.hpp"
|
||||
#include "actions/attack.hpp"
|
||||
|
||||
static lg::log_domain log_engine("engine");
|
||||
#define LOG_NG LOG_STREAM(info, log_engine)
|
||||
|
@ -37,10 +38,12 @@ tod_manager::tod_manager(const config& scenario_cfg):
|
|||
currentTime_(0),
|
||||
times_(),
|
||||
areas_(),
|
||||
liminal_bonus_(25),
|
||||
turn_(scenario_cfg["turn_at"].to_int(1)),
|
||||
num_turns_(scenario_cfg["turns"].to_int(-1)),
|
||||
has_turn_event_fired_(!scenario_cfg["it_is_a_new_turn"].to_bool(true)),
|
||||
has_tod_bonus_changed_ (false)
|
||||
has_tod_bonus_changed_ (false),
|
||||
has_cfg_liminal_bonus_ (false)
|
||||
{
|
||||
// ? : operator doesn't work in this case.
|
||||
if (scenario_cfg["current_time"].to_int(-17403) == -17403)
|
||||
|
@ -49,6 +52,13 @@ tod_manager::tod_manager(const config& scenario_cfg):
|
|||
random_tod_ = false;
|
||||
|
||||
time_of_day::parse_times(scenario_cfg,times_);
|
||||
int maybe_liminal_bonus = scenario_cfg["liminal_bonus"].to_int(-1);
|
||||
if (maybe_liminal_bonus < 0)
|
||||
liminal_bonus_ = calculate_best_liminal_bonus(times_);
|
||||
else {
|
||||
liminal_bonus_ = maybe_liminal_bonus;
|
||||
has_cfg_liminal_bonus_ = true;
|
||||
}
|
||||
//We need to call parse_times before calculate_current_time because otherwise the first parameter will always be 0.
|
||||
currentTime_ = calculate_current_time(times_.size(), turn_, scenario_cfg["current_time"].to_int(0), true);
|
||||
|
||||
|
@ -63,12 +73,14 @@ tod_manager& tod_manager::operator=(const tod_manager& manager)
|
|||
currentTime_ = manager.currentTime_;
|
||||
times_ = manager.times_;
|
||||
areas_ = manager.areas_;
|
||||
liminal_bonus_ = manager.liminal_bonus_;
|
||||
|
||||
turn_ = manager.turn_;
|
||||
num_turns_ = manager.num_turns_;
|
||||
|
||||
has_turn_event_fired_ = manager.has_turn_event_fired_;
|
||||
has_tod_bonus_changed_= manager.has_tod_bonus_changed_;
|
||||
has_cfg_liminal_bonus_ = manager.has_cfg_liminal_bonus_;
|
||||
|
||||
random_tod_ = manager.random_tod_;
|
||||
|
||||
|
@ -124,6 +136,8 @@ config tod_manager::to_config() const
|
|||
cfg["current_time"] = currentTime_;
|
||||
cfg["random_start_time"] = random_tod_;
|
||||
cfg["it_is_a_new_turn"] = !has_turn_event_fired_;
|
||||
if (has_cfg_liminal_bonus_)
|
||||
cfg["liminal_bonus"] = liminal_bonus_;
|
||||
|
||||
for(const time_of_day& tod : times_) {
|
||||
// Don't write the stub default ToD if it happens to be present.
|
||||
|
@ -536,3 +550,29 @@ bool tod_manager::is_time_left() const
|
|||
{
|
||||
return num_turns_ == -1 || turn_ <= num_turns_;
|
||||
}
|
||||
|
||||
int tod_manager::calculate_best_liminal_bonus(const std::vector<time_of_day>& schedule) const
|
||||
{
|
||||
int fearless_chaotic = 0;
|
||||
int fearless_lawful = 0;
|
||||
std::set<int> bonuses;
|
||||
for (const auto& tod : schedule) {
|
||||
fearless_chaotic += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::CHAOTIC, true, 0);
|
||||
fearless_lawful += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::LAWFUL, true, 0);
|
||||
bonuses.insert(std::abs(tod.lawful_bonus));
|
||||
}
|
||||
int target = std::max(fearless_chaotic, fearless_lawful);
|
||||
int delta = target;
|
||||
int result = 0;
|
||||
for (int bonus : bonuses) {
|
||||
int liminal_effect = 0;
|
||||
for (const auto& tod : schedule) {
|
||||
liminal_effect += generic_combat_modifier(tod.lawful_bonus, unit_type::ALIGNMENT::LIMINAL, false, bonus);
|
||||
}
|
||||
if (std::abs(target - liminal_effect) < delta) {
|
||||
result = bonus;
|
||||
delta = std::abs(target - liminal_effect);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,8 @@ class tod_manager
|
|||
{ has_turn_event_fired_ = true; }
|
||||
bool has_tod_bonus_changed() const
|
||||
{ return has_tod_bonus_changed_; }
|
||||
int get_max_liminal_bonus() const
|
||||
{ return liminal_bonus_; }
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -198,6 +200,10 @@ class tod_manager
|
|||
const int for_turn_number,
|
||||
const int current_time,
|
||||
const bool only_to_allowed_range = false) const;
|
||||
/**
|
||||
* Computes the maximum absolute value of lawful_bonus in the schedule.
|
||||
*/
|
||||
int calculate_best_liminal_bonus(const std::vector<time_of_day>& schedule) const;
|
||||
|
||||
/**
|
||||
* For a change of the current turn number, sets the current times of the main time
|
||||
|
@ -230,6 +236,9 @@ class tod_manager
|
|||
std::vector<time_of_day> times_;
|
||||
std::vector<area_time_of_day> areas_;
|
||||
|
||||
//max liminal bonus
|
||||
int liminal_bonus_;
|
||||
|
||||
// current turn
|
||||
int turn_;
|
||||
//turn limit
|
||||
|
@ -237,6 +246,7 @@ class tod_manager
|
|||
//Whether the "turn X" and the "new turn" events were already fired this turn.
|
||||
bool has_turn_event_fired_;
|
||||
bool has_tod_bonus_changed_;
|
||||
bool has_cfg_liminal_bonus_;
|
||||
//
|
||||
config::attribute_value random_tod_;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue