fix $dicerange
This commit is contained in:
+4
-4
@@ -1873,11 +1873,11 @@ static void server_command_ep3_set_dice_range(shared_ptr<Client> c, const std::s
|
||||
}
|
||||
|
||||
auto& rules = l->ep3_server->map_and_rules->rules;
|
||||
rules.def_dice_range = def_dice_range;
|
||||
rules.atk_dice_range_2v1 = atk_dice_range_2v1;
|
||||
rules.def_dice_range_2v1 = def_dice_range_2v1;
|
||||
rules.def_dice_value_range = def_dice_range;
|
||||
rules.atk_dice_value_range_2v1 = atk_dice_range_2v1;
|
||||
rules.def_dice_value_range_2v1 = def_dice_range_2v1;
|
||||
|
||||
if (!def_dice_range || !atk_dice_range_2v1 || !def_dice_range_2v1) {
|
||||
if (!def_dice_range && !atk_dice_range_2v1 && !def_dice_range_2v1) {
|
||||
send_text_message_printf(l, "$C7Dice ranges reset\nto defaults");
|
||||
} else {
|
||||
send_text_message_printf(l, "$C7Dice ranges changed:");
|
||||
|
||||
+158
-168
@@ -1263,8 +1263,8 @@ Rules::Rules(const JSON& json) {
|
||||
this->overall_time_limit = json.get_int("overall_time_limit", this->overall_time_limit);
|
||||
this->phase_time_limit = json.get_int("phase_time_limit", this->phase_time_limit);
|
||||
this->allowed_cards = json.get_enum("allowed_cards", this->allowed_cards);
|
||||
this->min_dice = json.get_int("min_dice", this->min_dice);
|
||||
this->max_dice = json.get_int("max_dice", this->max_dice);
|
||||
this->min_dice_value = json.get_int("min_dice", this->min_dice_value);
|
||||
this->max_dice_value = json.get_int("max_dice", this->max_dice_value);
|
||||
this->disable_deck_shuffle = json.get_bool("disable_deck_shuffle", this->disable_deck_shuffle);
|
||||
this->disable_deck_loop = json.get_bool("disable_deck_loop", this->disable_deck_loop);
|
||||
this->char_hp = json.get_int("char_hp", this->char_hp);
|
||||
@@ -1273,15 +1273,15 @@ Rules::Rules(const JSON& json) {
|
||||
this->disable_dialogue = json.get_bool("disable_dialogue", this->disable_dialogue);
|
||||
this->dice_exchange_mode = json.get_enum("dice_exchange_mode", this->dice_exchange_mode);
|
||||
this->disable_dice_boost = json.get_bool("disable_dice_boost", this->disable_dice_boost);
|
||||
uint8_t min_dice = json.get_int("min_def_dice", (this->def_dice_range >> 4) & 0x0F);
|
||||
uint8_t max_dice = json.get_int("max_def_dice", this->def_dice_range & 0x0F);
|
||||
this->def_dice_range = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
min_dice = json.get_int("min_atk_dice_2v1", (this->atk_dice_range_2v1 >> 4) & 0x0F);
|
||||
max_dice = json.get_int("max_atk_dice_2v1", this->atk_dice_range_2v1 & 0x0F);
|
||||
this->atk_dice_range_2v1 = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
min_dice = json.get_int("min_def_dice_2v1", (this->def_dice_range_2v1 >> 4) & 0x0F);
|
||||
max_dice = json.get_int("max_def_dice_2v1", this->def_dice_range_2v1 & 0x0F);
|
||||
this->def_dice_range_2v1 = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
uint8_t min_dice = json.get_int("min_def_dice", (this->def_dice_value_range >> 4) & 0x0F);
|
||||
uint8_t max_dice = json.get_int("max_def_dice", this->def_dice_value_range & 0x0F);
|
||||
this->def_dice_value_range = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
min_dice = json.get_int("min_atk_dice_2v1", (this->atk_dice_value_range_2v1 >> 4) & 0x0F);
|
||||
max_dice = json.get_int("max_atk_dice_2v1", this->atk_dice_value_range_2v1 & 0x0F);
|
||||
this->atk_dice_value_range_2v1 = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
min_dice = json.get_int("min_def_dice_2v1", (this->def_dice_value_range_2v1 >> 4) & 0x0F);
|
||||
max_dice = json.get_int("max_def_dice_2v1", this->def_dice_value_range_2v1 & 0x0F);
|
||||
this->def_dice_value_range_2v1 = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
}
|
||||
|
||||
JSON Rules::json() const {
|
||||
@@ -1289,8 +1289,8 @@ JSON Rules::json() const {
|
||||
{"overall_time_limit", this->overall_time_limit},
|
||||
{"phase_time_limit", this->phase_time_limit},
|
||||
{"allowed_cards", name_for_enum(this->allowed_cards)},
|
||||
{"min_dice", this->min_dice},
|
||||
{"max_dice", this->max_dice},
|
||||
{"min_dice", this->min_dice_value},
|
||||
{"max_dice", this->max_dice_value},
|
||||
{"disable_deck_shuffle", static_cast<bool>(this->disable_deck_shuffle)},
|
||||
{"disable_deck_loop", static_cast<bool>(this->disable_deck_loop)},
|
||||
{"char_hp", this->char_hp},
|
||||
@@ -1299,12 +1299,12 @@ JSON Rules::json() const {
|
||||
{"disable_dialogue", static_cast<bool>(this->disable_dialogue)},
|
||||
{"dice_exchange_mode", name_for_enum(this->dice_exchange_mode)},
|
||||
{"disable_dice_boost", static_cast<bool>(this->disable_dice_boost)},
|
||||
{"min_def_dice", ((this->def_dice_range >> 4) & 0x0F)},
|
||||
{"max_def_dice", (this->def_dice_range & 0x0F)},
|
||||
{"min_atk_dice_2v1", ((this->atk_dice_range_2v1 >> 4) & 0x0F)},
|
||||
{"max_atk_dice_2v1", (this->atk_dice_range_2v1 & 0x0F)},
|
||||
{"min_def_dice_2v1", ((this->def_dice_range_2v1 >> 4) & 0x0F)},
|
||||
{"max_def_dice_2v1", (this->def_dice_range_2v1 & 0x0F)},
|
||||
{"min_def_dice", ((this->def_dice_value_range >> 4) & 0x0F)},
|
||||
{"max_def_dice", (this->def_dice_value_range & 0x0F)},
|
||||
{"min_atk_dice_2v1", ((this->atk_dice_value_range_2v1 >> 4) & 0x0F)},
|
||||
{"max_atk_dice_2v1", (this->atk_dice_value_range_2v1 & 0x0F)},
|
||||
{"min_def_dice_2v1", ((this->def_dice_value_range_2v1 >> 4) & 0x0F)},
|
||||
{"max_def_dice_2v1", (this->def_dice_value_range_2v1 & 0x0F)},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1312,8 +1312,8 @@ void Rules::set_defaults() {
|
||||
this->clear();
|
||||
this->overall_time_limit = 24; // 2 hours
|
||||
this->phase_time_limit = 30;
|
||||
this->min_dice = 1;
|
||||
this->max_dice = 6;
|
||||
this->min_dice_value = 1;
|
||||
this->max_dice_value = 6;
|
||||
this->char_hp = 15;
|
||||
}
|
||||
|
||||
@@ -1321,8 +1321,8 @@ void Rules::clear() {
|
||||
this->overall_time_limit = 0;
|
||||
this->phase_time_limit = 0;
|
||||
this->allowed_cards = AllowedCards::ALL;
|
||||
this->min_dice = 0;
|
||||
this->max_dice = 0;
|
||||
this->min_dice_value = 0;
|
||||
this->max_dice_value = 0;
|
||||
this->disable_deck_shuffle = 0;
|
||||
this->disable_deck_loop = 0;
|
||||
this->char_hp = 0;
|
||||
@@ -1331,10 +1331,52 @@ void Rules::clear() {
|
||||
this->disable_dialogue = 0;
|
||||
this->dice_exchange_mode = DiceExchangeMode::HIGH_ATK;
|
||||
this->disable_dice_boost = 0;
|
||||
this->def_dice_range = 0;
|
||||
this->def_dice_value_range = 0;
|
||||
this->atk_dice_value_range_2v1 = 0;
|
||||
this->def_dice_value_range_2v1 = 0;
|
||||
this->unused.clear(0);
|
||||
}
|
||||
|
||||
pair<uint8_t, uint8_t> Rules::atk_dice_range(bool is_1p_2v1) const {
|
||||
pair<uint8_t, uint8_t> ret;
|
||||
if (is_1p_2v1 && this->atk_dice_value_range_2v1 && (this->atk_dice_value_range_2v1 != 0xFF)) {
|
||||
ret = make_pair((this->atk_dice_value_range_2v1 >> 4) & 0x0F, this->atk_dice_value_range_2v1 & 0x0F);
|
||||
} else {
|
||||
ret = make_pair(this->min_dice_value, this->max_dice_value);
|
||||
}
|
||||
if (ret.first == 0) {
|
||||
ret.first = 1;
|
||||
}
|
||||
if (ret.second == 0) {
|
||||
ret.second = 6;
|
||||
}
|
||||
if (ret.first > ret.second) {
|
||||
ret = make_pair(ret.second, ret.first);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
pair<uint8_t, uint8_t> Rules::def_dice_range(bool is_1p_2v1) const {
|
||||
pair<uint8_t, uint8_t> ret;
|
||||
if (is_1p_2v1 && this->def_dice_value_range_2v1 && (this->def_dice_value_range_2v1 != 0xFF)) {
|
||||
ret = make_pair((this->def_dice_value_range_2v1 >> 4) & 0x0F, this->def_dice_value_range_2v1 & 0x0F);
|
||||
} else if (this->def_dice_value_range && (this->def_dice_value_range != 0xFF)) {
|
||||
ret = make_pair((this->def_dice_value_range >> 4) & 0x0F, this->def_dice_value_range & 0x0F);
|
||||
} else {
|
||||
ret = make_pair(this->min_dice_value, this->max_dice_value);
|
||||
}
|
||||
if (ret.first == 0) {
|
||||
ret.first = 1;
|
||||
}
|
||||
if (ret.second == 0) {
|
||||
ret.second = 6;
|
||||
}
|
||||
if (ret.first > ret.second) {
|
||||
ret = make_pair(ret.second, ret.first);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
string Rules::str() const {
|
||||
vector<string> tokens;
|
||||
|
||||
@@ -1364,52 +1406,33 @@ string Rules::str() const {
|
||||
break;
|
||||
}
|
||||
|
||||
if (this->min_dice == 0xFF) {
|
||||
tokens.emplace_back("min_dice=(open)");
|
||||
} else if (this->min_dice == 0x00) {
|
||||
tokens.emplace_back("min_dice=1 (default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("min_dice=%hhu", this->min_dice));
|
||||
auto format_dice_range = +[](std::pair<uint8_t, uint8_t> range) -> string {
|
||||
string s = "[";
|
||||
if (range.first == 0xFF) {
|
||||
s += "min=(open), ";
|
||||
} else if (range.first == 0x00) {
|
||||
s += "min=(default), ";
|
||||
} else {
|
||||
s += string_printf("min=%hhu, ", range.first);
|
||||
}
|
||||
if (range.second == 0xFF) {
|
||||
s += "max=(open)]";
|
||||
} else if (range.second == 0x00) {
|
||||
s += "max=(default)]";
|
||||
} else {
|
||||
s += string_printf("max=%hhu]", range.second);
|
||||
}
|
||||
return s;
|
||||
};
|
||||
tokens.emplace_back("dice_range=" + format_dice_range(make_pair(this->min_dice_value, this->max_dice_value)));
|
||||
if (this->def_dice_value_range) {
|
||||
tokens.emplace_back("def_dice_range=" + format_dice_range(this->def_dice_range(false)));
|
||||
}
|
||||
if (this->max_dice == 0xFF) {
|
||||
tokens.emplace_back("max_dice=(open)");
|
||||
} else if (this->max_dice == 0x00) {
|
||||
tokens.emplace_back("max_dice=6 (default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("max_dice=%hhu", this->max_dice));
|
||||
if (this->atk_dice_value_range_2v1) {
|
||||
tokens.emplace_back("atk_dice_range_2v1=" + format_dice_range(this->atk_dice_range(true)));
|
||||
}
|
||||
|
||||
if (this->min_def_dice() == 0) {
|
||||
tokens.emplace_back("min_def_dice=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("min_def_dice=%hhu", this->min_def_dice()));
|
||||
}
|
||||
if (this->max_def_dice() == 0) {
|
||||
tokens.emplace_back("max_def_dice=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("max_def_dice=%hhu", this->max_def_dice()));
|
||||
}
|
||||
|
||||
if (this->min_atk_dice_2v1() == 0) {
|
||||
tokens.emplace_back("min_atk_dice_2v1=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("min_atk_dice_2v1=%hhu", this->min_atk_dice_2v1()));
|
||||
}
|
||||
if (this->max_atk_dice_2v1() == 0) {
|
||||
tokens.emplace_back("max_atk_dice_2v1=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("max_atk_dice_2v1=%hhu", this->max_atk_dice_2v1()));
|
||||
}
|
||||
|
||||
if (this->min_def_dice_2v1() == 0) {
|
||||
tokens.emplace_back("min_def_dice_2v1=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("min_def_dice_2v1=%hhu", this->min_def_dice_2v1()));
|
||||
}
|
||||
if (this->max_def_dice_2v1() == 0) {
|
||||
tokens.emplace_back("max_def_dice_2v1=(default)");
|
||||
} else {
|
||||
tokens.emplace_back(string_printf("max_def_dice_2v1=%hhu", this->max_def_dice_2v1()));
|
||||
if (this->def_dice_value_range_2v1) {
|
||||
tokens.emplace_back("def_dice_range_2v1=" + format_dice_range(this->def_dice_range(true)));
|
||||
}
|
||||
|
||||
switch (this->dice_exchange_mode) {
|
||||
@@ -1497,15 +1520,30 @@ RulesTrial::RulesTrial(const Rules& r)
|
||||
: overall_time_limit(r.overall_time_limit),
|
||||
phase_time_limit(r.phase_time_limit),
|
||||
allowed_cards(r.allowed_cards),
|
||||
atk_die_behavior((r.max_dice == r.min_dice) ? r.max_dice : 0),
|
||||
def_die_behavior(r.def_dice_range == 0xFF ? 0xFF : ((r.min_def_dice() == r.max_def_dice()) ? r.max_def_dice() : 0)),
|
||||
// ATK/DEF behaviors set below
|
||||
disable_deck_shuffle(r.disable_deck_shuffle),
|
||||
disable_deck_loop(r.disable_deck_loop),
|
||||
char_hp(r.char_hp),
|
||||
hp_type(r.hp_type),
|
||||
no_assist_cards(r.no_assist_cards),
|
||||
disable_dialogue(r.disable_dialogue),
|
||||
dice_exchange_mode(r.dice_exchange_mode) {}
|
||||
dice_exchange_mode(r.dice_exchange_mode) {
|
||||
if (r.max_dice_value == r.min_dice_value) {
|
||||
this->atk_die_behavior = r.max_dice_value;
|
||||
} else {
|
||||
this->atk_die_behavior = 0; // Random
|
||||
}
|
||||
if (r.def_dice_value_range == 0xFF) {
|
||||
this->atk_die_behavior = 0xFF;
|
||||
} else {
|
||||
auto def_range = r.def_dice_range(false);
|
||||
if (def_range.first == def_range.second) {
|
||||
this->def_die_behavior = def_range.first;
|
||||
} else {
|
||||
this->def_die_behavior = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RulesTrial::operator Rules() const {
|
||||
Rules ret;
|
||||
@@ -1513,11 +1551,11 @@ RulesTrial::operator Rules() const {
|
||||
ret.phase_time_limit = this->phase_time_limit;
|
||||
ret.allowed_cards = this->allowed_cards;
|
||||
if (this->atk_die_behavior) {
|
||||
ret.min_dice = this->atk_die_behavior;
|
||||
ret.max_dice = this->atk_die_behavior;
|
||||
ret.min_dice_value = this->atk_die_behavior;
|
||||
ret.max_dice_value = this->atk_die_behavior;
|
||||
} else {
|
||||
ret.min_dice = 1;
|
||||
ret.max_dice = 6;
|
||||
ret.min_dice_value = 1;
|
||||
ret.max_dice_value = 6;
|
||||
}
|
||||
ret.disable_deck_shuffle = this->disable_deck_shuffle;
|
||||
ret.disable_deck_loop = this->disable_deck_loop;
|
||||
@@ -1528,10 +1566,12 @@ RulesTrial::operator Rules() const {
|
||||
ret.dice_exchange_mode = this->dice_exchange_mode;
|
||||
ret.disable_dice_boost = 0;
|
||||
if (this->def_die_behavior) {
|
||||
ret.def_dice_range = (this->def_die_behavior << 4) | this->def_die_behavior;
|
||||
ret.def_dice_value_range = (this->def_die_behavior << 4) | this->def_die_behavior;
|
||||
} else {
|
||||
ret.def_dice_range = 0x16;
|
||||
ret.def_dice_value_range = 0x16;
|
||||
}
|
||||
ret.atk_dice_value_range_2v1 = 0x00;
|
||||
ret.def_dice_value_range_2v1 = 0x00;
|
||||
ret.unused.clear(0);
|
||||
return ret;
|
||||
}
|
||||
@@ -2079,82 +2119,48 @@ bool Rules::check_and_reset_invalid_fields() {
|
||||
this->allowed_cards = AllowedCards::ALL;
|
||||
ret = true;
|
||||
}
|
||||
if (this->min_dice > 9) {
|
||||
this->min_dice = 0;
|
||||
if (this->min_dice_value > 9) {
|
||||
this->min_dice_value = 0;
|
||||
ret = true;
|
||||
}
|
||||
if (this->max_dice > 9) {
|
||||
this->max_dice = 0;
|
||||
if (this->max_dice_value > 9) {
|
||||
this->max_dice_value = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((this->min_dice != 0) && (this->max_dice != 0) && (this->max_dice < this->min_dice)) {
|
||||
uint8_t t = this->min_dice;
|
||||
this->min_dice = this->max_dice;
|
||||
this->max_dice = t;
|
||||
if ((this->min_dice_value != 0) && (this->max_dice_value != 0) && (this->max_dice_value < this->min_dice_value)) {
|
||||
uint8_t t = this->min_dice_value;
|
||||
this->min_dice_value = this->max_dice_value;
|
||||
this->max_dice_value = t;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
uint8_t min_def_dice = this->min_def_dice();
|
||||
uint8_t max_def_dice = this->max_def_dice();
|
||||
if (min_def_dice > 9) {
|
||||
min_def_dice = 0;
|
||||
ret = true;
|
||||
}
|
||||
if (max_def_dice > 9) {
|
||||
max_def_dice = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((min_def_dice != 0) && (max_def_dice != 0) && (max_def_dice < min_def_dice)) {
|
||||
uint8_t t = min_def_dice;
|
||||
min_def_dice = max_def_dice;
|
||||
max_def_dice = t;
|
||||
ret = true;
|
||||
}
|
||||
this->def_dice_range = ((min_def_dice << 4) & 0xF0) | (max_def_dice & 0x0F);
|
||||
if (this->disable_deck_shuffle > 1) {
|
||||
this->disable_deck_shuffle = 0;
|
||||
ret = true;
|
||||
}
|
||||
// These ranges are a newserv-specific extension and are not part of the
|
||||
// original implementation.
|
||||
auto check_compressed_dice_range = +[](uint8_t* range) -> bool {
|
||||
bool ret = false;
|
||||
uint8_t min_dice = ((*range) >> 4) & 0x0F;
|
||||
uint8_t max_dice = (*range) & 0x0F;
|
||||
if (min_dice > 9) {
|
||||
min_dice = 0;
|
||||
ret = true;
|
||||
}
|
||||
if (max_dice > 9) {
|
||||
max_dice = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((min_dice != 0) && (max_dice != 0) && (max_dice < min_dice)) {
|
||||
uint8_t t = min_dice;
|
||||
min_dice = max_dice;
|
||||
max_dice = t;
|
||||
ret = true;
|
||||
}
|
||||
*range = ((min_dice << 4) & 0xF0) | (max_dice & 0x0F);
|
||||
return ret;
|
||||
};
|
||||
ret |= check_compressed_dice_range(&this->def_dice_value_range);
|
||||
ret |= check_compressed_dice_range(&this->atk_dice_value_range_2v1);
|
||||
ret |= check_compressed_dice_range(&this->def_dice_value_range_2v1);
|
||||
|
||||
uint8_t min_atk_dice_2v1 = this->min_atk_dice_2v1();
|
||||
uint8_t max_atk_dice_2v1 = this->max_atk_dice_2v1();
|
||||
if (min_atk_dice_2v1 > 9) {
|
||||
min_atk_dice_2v1 = 0;
|
||||
ret = true;
|
||||
}
|
||||
if (max_atk_dice_2v1 > 9) {
|
||||
max_atk_dice_2v1 = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((min_atk_dice_2v1 != 0) && (max_atk_dice_2v1 != 0) && (max_atk_dice_2v1 < min_atk_dice_2v1)) {
|
||||
uint8_t t = min_atk_dice_2v1;
|
||||
min_atk_dice_2v1 = max_atk_dice_2v1;
|
||||
max_atk_dice_2v1 = t;
|
||||
ret = true;
|
||||
}
|
||||
this->def_dice_range = ((min_atk_dice_2v1 << 4) & 0xF0) | (max_atk_dice_2v1 & 0x0F);
|
||||
if (this->disable_deck_shuffle > 1) {
|
||||
this->disable_deck_shuffle = 0;
|
||||
ret = true;
|
||||
}
|
||||
|
||||
uint8_t min_def_dice_2v1 = this->min_def_dice_2v1();
|
||||
uint8_t max_def_dice_2v1 = this->max_def_dice_2v1();
|
||||
if (min_def_dice_2v1 > 9) {
|
||||
min_def_dice_2v1 = 0;
|
||||
ret = true;
|
||||
}
|
||||
if (max_def_dice_2v1 > 9) {
|
||||
max_def_dice_2v1 = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((min_def_dice_2v1 != 0) && (max_def_dice_2v1 != 0) && (max_def_dice_2v1 < min_def_dice_2v1)) {
|
||||
uint8_t t = min_def_dice_2v1;
|
||||
min_def_dice_2v1 = max_def_dice_2v1;
|
||||
max_def_dice_2v1 = t;
|
||||
ret = true;
|
||||
}
|
||||
this->def_dice_range = ((min_def_dice_2v1 << 4) & 0xF0) | (max_def_dice_2v1 & 0x0F);
|
||||
if (this->disable_deck_shuffle > 1) {
|
||||
this->disable_deck_shuffle = 0;
|
||||
ret = true;
|
||||
@@ -2184,32 +2190,16 @@ bool Rules::check_and_reset_invalid_fields() {
|
||||
this->disable_dice_boost = 0;
|
||||
ret = true;
|
||||
}
|
||||
if ((this->max_dice != 0) && (this->max_dice < 3)) {
|
||||
this->disable_dice_boost = 1;
|
||||
ret = true;
|
||||
}
|
||||
// Due to newserv's custom range overrides, it doesn't make sense to disable
|
||||
// Dice Boost for everyone based on the Rules struct. Instead, we skip setting
|
||||
// the flag at roll time.
|
||||
// if ((this->max_dice_value != 0) && (this->max_dice_value < 3)) {
|
||||
// this->disable_dice_boost = 1;
|
||||
// ret = true;
|
||||
// }
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t Rules::min_def_dice() const {
|
||||
return (this->def_dice_range >> 4) & 0x0F;
|
||||
}
|
||||
uint8_t Rules::max_def_dice() const {
|
||||
return this->def_dice_range & 0x0F;
|
||||
}
|
||||
uint8_t Rules::min_atk_dice_2v1() const {
|
||||
return (this->atk_dice_range_2v1 >> 4) & 0x0F;
|
||||
}
|
||||
uint8_t Rules::max_atk_dice_2v1() const {
|
||||
return this->atk_dice_range_2v1 & 0x0F;
|
||||
}
|
||||
uint8_t Rules::min_def_dice_2v1() const {
|
||||
return (this->def_dice_range_2v1 >> 4) & 0x0F;
|
||||
}
|
||||
uint8_t Rules::max_def_dice_2v1() const {
|
||||
return this->def_dice_range_2v1 & 0x0F;
|
||||
}
|
||||
|
||||
CardIndex::CardIndex(
|
||||
const string& filename,
|
||||
const string& decompressed_filename,
|
||||
|
||||
@@ -940,8 +940,8 @@ struct Rules {
|
||||
/* 00 */ uint8_t overall_time_limit = 0;
|
||||
/* 01 */ uint8_t phase_time_limit = 0; // In seconds; 0 = unlimited
|
||||
/* 02 */ AllowedCards allowed_cards = AllowedCards::ALL;
|
||||
/* 03 */ uint8_t min_dice = 1; // 0 = default (1)
|
||||
/* 04 */ uint8_t max_dice = 6; // 0 = default (6)
|
||||
/* 03 */ uint8_t min_dice_value = 1; // 0 = default (1)
|
||||
/* 04 */ uint8_t max_dice_value = 6; // 0 = default (6)
|
||||
/* 05 */ uint8_t disable_deck_shuffle = 0; // 0 = shuffle on, 1 = off
|
||||
/* 06 */ uint8_t disable_deck_loop = 0; // 0 = loop on, 1 = off
|
||||
/* 07 */ uint8_t char_hp = 15;
|
||||
@@ -952,10 +952,10 @@ struct Rules {
|
||||
/* 0C */ uint8_t disable_dice_boost = 0; // 0 = dice boost on, 1 = off
|
||||
// NOTE: The following fields are unused in PSO's implementation, but newserv
|
||||
// uses them to implement extended rules.
|
||||
/* 0D */ uint8_t def_dice_range = 0; // High 4 bits = min, low 4 = max
|
||||
/* 0D */ uint8_t def_dice_value_range = 0; // High 4 bits = min, low 4 = max
|
||||
// These fields specify override dice ranges for the 1-player team in 2v1
|
||||
/* 0E */ uint8_t atk_dice_range_2v1 = 0; // High 4 bits = min, low 4 = max
|
||||
/* 0F */ uint8_t def_dice_range_2v1 = 0; // High 4 bits = min, low 4 = max
|
||||
/* 0E */ uint8_t atk_dice_value_range_2v1 = 0; // High 4 bits = min, low 4 = max
|
||||
/* 0F */ uint8_t def_dice_value_range_2v1 = 0; // High 4 bits = min, low 4 = max
|
||||
/* 10 */ parray<uint8_t, 4> unused;
|
||||
/* 14 */
|
||||
|
||||
@@ -976,12 +976,8 @@ struct Rules {
|
||||
bool check_invalid_fields() const;
|
||||
bool check_and_reset_invalid_fields();
|
||||
|
||||
uint8_t min_def_dice() const;
|
||||
uint8_t max_def_dice() const;
|
||||
uint8_t min_atk_dice_2v1() const;
|
||||
uint8_t max_atk_dice_2v1() const;
|
||||
uint8_t min_def_dice_2v1() const;
|
||||
uint8_t max_def_dice_2v1() const;
|
||||
std::pair<uint8_t, uint8_t> atk_dice_range(bool is_1p_2v1) const;
|
||||
std::pair<uint8_t, uint8_t> def_dice_range(bool is_1p_2v1) const;
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -1987,44 +1987,21 @@ void PlayerState::roll_main_dice_or_apply_after_effects() {
|
||||
|
||||
bool is_1p_2v1 = (s->team_client_count.at(this->get_team_id()) < s->team_client_count[this->get_team_id() ^ 1]);
|
||||
|
||||
uint8_t min_atk_dice = (is_1p_2v1 && rules.min_atk_dice_2v1()) ? rules.min_atk_dice_2v1() : rules.min_dice;
|
||||
uint8_t max_atk_dice = (is_1p_2v1 && rules.max_atk_dice_2v1()) ? rules.max_atk_dice_2v1() : rules.max_dice;
|
||||
if (min_atk_dice == 0) {
|
||||
min_atk_dice = 1;
|
||||
}
|
||||
if (max_atk_dice == 0) {
|
||||
max_atk_dice = 6;
|
||||
}
|
||||
if (max_atk_dice < min_atk_dice) {
|
||||
uint8_t t = max_atk_dice;
|
||||
max_atk_dice = min_atk_dice;
|
||||
min_atk_dice = t;
|
||||
}
|
||||
uint8_t atk_dice_range_width = (max_atk_dice - min_atk_dice) + 1;
|
||||
auto atk_range = rules.atk_dice_range(is_1p_2v1);
|
||||
auto def_range = rules.def_dice_range(is_1p_2v1);
|
||||
|
||||
uint8_t atk_dice_range_width = (atk_range.second - atk_range.first) + 1;
|
||||
if (atk_dice_range_width < 2) {
|
||||
this->dice_results[0] = min_atk_dice;
|
||||
this->dice_results[0] = atk_range.first;
|
||||
} else {
|
||||
this->dice_results[0] = min_atk_dice + s->get_random(atk_dice_range_width);
|
||||
this->dice_results[0] = atk_range.first + s->get_random(atk_dice_range_width);
|
||||
}
|
||||
|
||||
uint8_t min_def_dice = (is_1p_2v1 && rules.min_def_dice_2v1()) ? rules.min_def_dice_2v1() : (rules.min_def_dice() ? rules.min_def_dice() : rules.min_dice);
|
||||
uint8_t max_def_dice = (is_1p_2v1 && rules.max_def_dice_2v1()) ? rules.max_def_dice_2v1() : (rules.max_def_dice() ? rules.max_def_dice() : rules.max_dice);
|
||||
if (min_def_dice == 0) {
|
||||
min_def_dice = 1;
|
||||
}
|
||||
if (max_def_dice == 0) {
|
||||
max_def_dice = 6;
|
||||
}
|
||||
if (max_def_dice < min_def_dice) {
|
||||
uint8_t t = max_def_dice;
|
||||
max_def_dice = min_def_dice;
|
||||
min_def_dice = t;
|
||||
}
|
||||
uint8_t def_dice_range_width = (max_def_dice - min_def_dice) + 1;
|
||||
uint8_t def_dice_range_width = (def_range.second - def_range.first) + 1;
|
||||
if (def_dice_range_width < 2) {
|
||||
this->dice_results[1] = min_def_dice;
|
||||
this->dice_results[1] = def_range.first;
|
||||
} else {
|
||||
this->dice_results[1] = min_def_dice + s->get_random(def_dice_range_width);
|
||||
this->dice_results[1] = def_range.first + s->get_random(def_dice_range_width);
|
||||
}
|
||||
|
||||
bool should_exchange = false;
|
||||
|
||||
+17
-3
@@ -1363,6 +1363,13 @@ void Server::set_battle_started() {
|
||||
this->send_6xB4x05();
|
||||
}
|
||||
|
||||
bool Server::player_can_receive_dice_boost(uint8_t client_id) const {
|
||||
auto ps = this->player_states[client_id];
|
||||
bool is_1p_2v1 = (this->team_client_count.at(ps->get_team_id()) < this->team_client_count[ps->get_team_id() ^ 1]);
|
||||
const auto& rules = this->map_and_rules->rules;
|
||||
return (rules.atk_dice_range(is_1p_2v1).second >= 3) || (rules.def_dice_range(is_1p_2v1).second >= 3);
|
||||
}
|
||||
|
||||
void Server::set_client_id_ready_to_advance_phase(uint8_t client_id, BattlePhase battle_phase) {
|
||||
if (client_id >= 4) {
|
||||
return;
|
||||
@@ -1377,7 +1384,10 @@ void Server::set_client_id_ready_to_advance_phase(uint8_t client_id, BattlePhase
|
||||
ps->assist_flags |= AssistFlag::READY_TO_END_PHASE;
|
||||
ps->update_hand_and_equip_state_and_send_6xB4x02_if_needed();
|
||||
if (this->battle_phase == BattlePhase::DICE) {
|
||||
if (is_nte || !(ps->assist_flags & AssistFlag::ELIGIBLE_FOR_DICE_BOOST) || this->map_and_rules->rules.disable_dice_boost) {
|
||||
if (is_nte ||
|
||||
!(ps->assist_flags & AssistFlag::ELIGIBLE_FOR_DICE_BOOST) ||
|
||||
this->map_and_rules->rules.disable_dice_boost ||
|
||||
!this->player_can_receive_dice_boost(client_id)) {
|
||||
ps->assist_flags &= (~AssistFlag::ELIGIBLE_FOR_DICE_BOOST);
|
||||
ps->roll_main_dice_or_apply_after_effects();
|
||||
if (!is_nte && (ps->get_atk_points() < 3) && (ps->get_def_points() < 3)) {
|
||||
@@ -2149,9 +2159,13 @@ void Server::handle_CAx13_update_map_during_setup_t(shared_ptr<Client>, const st
|
||||
// newserv's extended rules are stored in unused parts of the Rules struct,
|
||||
// and clients will probably overwrite them with zeroes if we allow them to.
|
||||
// So, we preserve the extended rules manually here.
|
||||
uint8_t def_dice_range = this->map_and_rules->rules.def_dice_range;
|
||||
uint8_t def_dice_value_range = this->map_and_rules->rules.def_dice_value_range;
|
||||
uint8_t atk_dice_value_range_2v1 = this->map_and_rules->rules.atk_dice_value_range_2v1;
|
||||
uint8_t def_dice_value_range_2v1 = this->map_and_rules->rules.def_dice_value_range_2v1;
|
||||
*this->map_and_rules = in_cmd.map_and_rules_state;
|
||||
this->map_and_rules->rules.def_dice_range = def_dice_range;
|
||||
this->map_and_rules->rules.def_dice_value_range = def_dice_value_range;
|
||||
this->map_and_rules->rules.atk_dice_value_range_2v1 = atk_dice_value_range_2v1;
|
||||
this->map_and_rules->rules.def_dice_value_range_2v1 = def_dice_value_range_2v1;
|
||||
|
||||
// If this match is part of a tournament, ignore the rules sent by the
|
||||
// client and use the tournament rules instead.
|
||||
|
||||
@@ -205,6 +205,7 @@ public:
|
||||
void send_set_card_updates_and_6xB4x04_if_needed();
|
||||
void set_battle_ended();
|
||||
void set_battle_started();
|
||||
bool player_can_receive_dice_boost(uint8_t client_id) const;
|
||||
void set_client_id_ready_to_advance_phase(uint8_t client_id, BattlePhase battle_phase);
|
||||
void set_phase_after();
|
||||
void move_phase_before();
|
||||
|
||||
+46
-18
@@ -204,9 +204,13 @@ Server commands:\n\
|
||||
shuffle: Shuffle entries when starting the tournament\n\
|
||||
resize: If the tournament is less than half full when it starts, reduce\n\
|
||||
the number of rounds to fit the existing entries\n\
|
||||
dice=MIN-MAX: Set minimum and maximum dice rolls\n\
|
||||
dice=MIN-MAX:MIN-MAX: Set minimum and maximum dice rolls for ATK and DEF\n\
|
||||
dice separately\n\
|
||||
dice=A-B: Set minimum and maximum dice rolls\n\
|
||||
dice=A-B:C-D: Set minimum and maximum dice rolls for ATK dice (A-B) and\n\
|
||||
DEF dice (C-D) separately\n\
|
||||
dice=A-B:C-D:E-F: Set minimum and maximum dice rolls for ATK dice, DEF\n\
|
||||
dice, and solo vs. 2P ATK and DEF dice (E-F) separately\n\
|
||||
dice=A-B:C-D:E-F:G-H: Set minimum and maximum dice rolls for ATK dice,\n\
|
||||
DEF dice, solo vs. 2P ATK (E-F) and DEF (G-H) dice separately\n\
|
||||
overall-time-limit=N: Set battle time limit (in multiples of 5 minutes)\n\
|
||||
phase-time-limit=N: Set phase time limit (in seconds)\n\
|
||||
allowed-cards=ALL/N/NR/NRS: Set ranks of allowed cards\n\
|
||||
@@ -490,24 +494,48 @@ Proxy session commands:\n\
|
||||
} else if (token == "resize") {
|
||||
flags |= Episode3::Tournament::Flag::RESIZE_ON_START;
|
||||
} else if (starts_with(token, "dice=")) {
|
||||
auto subtokens = split(token.substr(5), ':');
|
||||
if (subtokens.size() == 1) {
|
||||
rules.def_dice_range = 0x00;
|
||||
} else if (subtokens.size() == 2) {
|
||||
auto subsubtokens = split(subtokens[1], '-');
|
||||
if (subsubtokens.size() != 2) {
|
||||
throw runtime_error("dice option must be of the form dice=A-B or dice=A-B:C-D");
|
||||
auto parse_range_c = +[](const string& s) -> uint8_t {
|
||||
auto tokens = split(s, '-');
|
||||
if (tokens.size() != 2) {
|
||||
throw runtime_error("dice spec must be of the form MIN-MAX");
|
||||
}
|
||||
return (stoul(tokens[0]) << 4) | (stoul(tokens[1]) & 0x0F);
|
||||
};
|
||||
auto parse_range_p = +[](const string& s) -> pair<uint8_t, uint8_t> {
|
||||
auto tokens = split(s, '-');
|
||||
if (tokens.size() != 2) {
|
||||
throw runtime_error("dice spec must be of the form MIN-MAX");
|
||||
}
|
||||
return make_pair(stoul(tokens[0]), stoul(tokens[1]));
|
||||
};
|
||||
|
||||
auto subtokens = split(token.substr(5), ':');
|
||||
if (subtokens.size() < 1) {
|
||||
throw runtime_error("no dice ranges specified in dice= option");
|
||||
}
|
||||
auto atk_range = parse_range_p(tokens[0]);
|
||||
rules.min_dice_value = atk_range.first;
|
||||
rules.max_dice_value = atk_range.second;
|
||||
if (subtokens.size() >= 2) {
|
||||
rules.def_dice_value_range = parse_range_c(tokens[1]);
|
||||
if (subtokens.size() >= 3) {
|
||||
rules.atk_dice_value_range_2v1 = parse_range_c(tokens[2]);
|
||||
if (subtokens.size() == 3) {
|
||||
rules.def_dice_value_range_2v1 = rules.atk_dice_value_range_2v1;
|
||||
} else if (subtokens.size() == 4) {
|
||||
rules.def_dice_value_range_2v1 = parse_range_c(tokens[3]);
|
||||
} else {
|
||||
throw runtime_error("too many range specs given");
|
||||
}
|
||||
} else {
|
||||
rules.atk_dice_value_range_2v1 = 0;
|
||||
rules.def_dice_value_range_2v1 = 0;
|
||||
}
|
||||
rules.def_dice_range = ((stoul(subsubtokens[0]) << 4) & 0xF0) | (stoul(subsubtokens[1]) & 0x0F);
|
||||
} else {
|
||||
throw runtime_error("dice option must be of the form dice=A-B or dice=A-B:C-D");
|
||||
rules.def_dice_value_range = 0;
|
||||
rules.atk_dice_value_range_2v1 = 0;
|
||||
rules.def_dice_value_range_2v1 = 0;
|
||||
}
|
||||
auto subsubtokens = split(subtokens[0], '-');
|
||||
if (subsubtokens.size() != 2) {
|
||||
throw runtime_error("dice option must be of the form dice=A-B or dice=A-B:C-D");
|
||||
}
|
||||
rules.min_dice = stoul(subsubtokens[0]);
|
||||
rules.max_dice = stoul(subsubtokens[1]);
|
||||
} else if (starts_with(token, "overall-time-limit=")) {
|
||||
uint32_t limit = stoul(token.substr(19));
|
||||
if (limit > 600) {
|
||||
|
||||
Reference in New Issue
Block a user