fix rounding in division expressions

This commit is contained in:
Martin Michelsen
2023-09-05 22:52:49 -07:00
parent 2b2d8dfb3d
commit f771643880
4 changed files with 20 additions and 5 deletions
+16 -2
View File
@@ -1537,6 +1537,8 @@ int32_t CardSpecial::evaluate_effect_expr(
const AttackEnvStats& ast,
const char* expr,
DiceRoll& dice_roll) const {
this->debug_log("evaluate_effect_expr(ast, expr=\"%s\", dice_roll=(client_id=%02hhX, a2=%02hhX, value=%02hhX, value_used_in_expr=%s, a5=%04hX))", expr, dice_roll.client_id, dice_roll.unknown_a2, dice_roll.value, dice_roll.value_used_in_expr ? "true" : "false", dice_roll.unknown_a5);
// Note: This implementation is not based on the original code because the
// original code was hard to follow - it used a look-behind approach with lots
// of local variables instead of the look-ahead approach that this
@@ -1566,6 +1568,7 @@ int32_t CardSpecial::evaluate_effect_expr(
// Operators are evaluated left-to-right - there are no operator precedence
// rules
int32_t value = 0;
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (start)", value);
for (size_t token_index = 0; token_index < tokens.size(); token_index++) {
auto token_type = tokens[token_index].first;
int32_t token_value = tokens[token_index].second;
@@ -1574,6 +1577,7 @@ int32_t CardSpecial::evaluate_effect_expr(
}
if (token_type == ExpressionTokenType::NUMBER) {
value = token_value;
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=NUMBER, token_value=%" PRId32 ")", value, token_value);
} else {
if (token_index >= tokens.size() - 1) {
throw runtime_error("no token on right side of binary operator");
@@ -1586,19 +1590,24 @@ int32_t CardSpecial::evaluate_effect_expr(
}
switch (token_type) {
case ExpressionTokenType::ROUND_DIVIDE:
value = lround(value / right_value);
value = lround(static_cast<double>(value) / right_value);
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=ROUND_DIVIDE, right_token_value=%" PRId32 ")", value, right_value);
break;
case ExpressionTokenType::SUBTRACT:
value -= right_value;
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=SUBTRACT, right_token_value=%" PRId32 ")", value, right_value);
break;
case ExpressionTokenType::ADD:
value += right_value;
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=ADD, right_token_value=%" PRId32 ")", value, right_value);
break;
case ExpressionTokenType::MULTIPLY:
value *= right_value;
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=MULTIPLY, right_token_value=%" PRId32 ")", value, right_value);
break;
case ExpressionTokenType::FLOOR_DIVIDE:
value = floor(value / right_value);
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (token_type=FLOOR_DIVIDE, right_token_value=%" PRId32 ")", value, right_value);
break;
default:
throw logic_error("invalid binary operator");
@@ -1606,6 +1615,7 @@ int32_t CardSpecial::evaluate_effect_expr(
}
}
this->debug_log("evaluate_effect_expr: value=%" PRId32 " (result)", value);
return value;
}
@@ -1615,8 +1625,12 @@ bool CardSpecial::execute_effect(
int16_t expr_value,
int16_t unknown_p5,
ConditionType cond_type,
uint unknown_p7,
uint32_t unknown_p7,
uint16_t attacker_card_ref) {
{
string cond_str = cond.str();
this->debug_log("execute_effect(cond=%s, card=%04hX, expr_value=%hd, unknown_p5=%hd, cond_type=%s, unknown_p7=%" PRIu32 ", attacker_card_ref=%04hX)", cond_str.c_str(), ref_for_card(card), expr_value, unknown_p5, name_for_condition_type(cond_type), unknown_p7, attacker_card_ref);
}
int16_t clamped_expr_value = clamp<int16_t>(expr_value, -99, 99);
int16_t clamped_unknown_p5 = clamp<int16_t>(unknown_p5, -99, 99);
+1 -1
View File
@@ -196,7 +196,7 @@ public:
int16_t expr_value,
int16_t unknown_p5,
ConditionType cond_type,
uint unknown_p7,
uint32_t unknown_p7,
uint16_t attacker_card_ref);
const Condition* find_condition_with_parameters(
std::shared_ptr<const Card> card,
+1 -1
View File
@@ -35,7 +35,7 @@ ServerBase::ServerBase(
card_index(card_index),
map_index(map_index),
behavior_flags(behavior_flags),
log(lobby->log.prefix + "[Ep3::Server] "),
log(lobby->log.prefix + "[Ep3::Server] ", lobby->log.min_level),
random_crypt(random_crypt),
is_tournament(!!map_if_tournament),
last_chosen_map(map_if_tournament) {}
+2 -1
View File
@@ -196,7 +196,8 @@
// License manager messages describe the creation of new license files.
"LicenseManager": "INFO",
// Lobby messages describe creation and deletion of lobbies and games, as
// well as item tracking events within games.
// well as item tracking events within games. On Episode 3, debug messages
// during battles go to this stream as well; use "DEBUG" here to see them.
"Lobbies": "INFO",
// Patch file index messages describe finding and preloading the patch files
// available for download to BB and PC clients.