ep3 debugging helpers
This commit is contained in:
@@ -257,6 +257,8 @@ bool CardSpecial::apply_defense_condition(
|
||||
if ((when == 2) && (defender_cond->type == ConditionType::GUOM) && (flags & 4)) {
|
||||
CardShortStatus stat = defender_card->get_short_status();
|
||||
if (stat.card_flags & 4) {
|
||||
this->server()->base()->log.debug("(when=2) @%04hX clearing GUOM from @%04hX",
|
||||
attacker_card_ref, defender_card->get_card_ref());
|
||||
G_ApplyConditionEffect_GC_Ep3_6xB4x06 cmd;
|
||||
cmd.effect.flags = 0x04;
|
||||
cmd.effect.attacker_card_ref = this->send_6xB4x06_if_card_ref_invalid(attacker_card_ref, 0x0E);
|
||||
@@ -276,6 +278,8 @@ bool CardSpecial::apply_defense_condition(
|
||||
(defender_cond->type == ConditionType::ACID)) {
|
||||
int16_t hp = defender_card->get_current_hp();
|
||||
if (hp > 0) {
|
||||
this->server()->base()->log.debug("(when=2) @%04hX has ACID; removing 1 HP",
|
||||
defender_cond->card_ref.load());
|
||||
this->send_6xB4x06_for_stat_delta(
|
||||
defender_card, defender_cond->card_ref, 0x20, -1, 0, 1);
|
||||
defender_card->set_current_hp(hp - 1);
|
||||
@@ -3502,6 +3506,13 @@ void CardSpecial::unknown_8024C2B0(
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
string as_s = as.str();
|
||||
string eff_s = card_effect.str();
|
||||
this->server()->base()->log.debug("(when=%" PRIu32 ") set=@%04hX sc=@%04hX as=%s att=@%04hX eff=%s",
|
||||
when, set_card_ref, sc_card_ref, as_s.c_str(), as_attacker_card_ref, eff_s.c_str());
|
||||
}
|
||||
|
||||
int16_t arg3_value = atoi(&card_effect.arg3[1]);
|
||||
auto targeted_cards = this->get_targeted_cards_for_condition(
|
||||
set_card_ref, def_effect_index, sc_card_ref, as, arg3_value, 1);
|
||||
@@ -3570,6 +3581,7 @@ void CardSpecial::unknown_8024C2B0(
|
||||
card_effect, target_card, dice_cmd.effect.target_card_ref, sc_card_ref)) {
|
||||
applied_cond_index = target_card->apply_abnormal_condition(
|
||||
card_effect, def_effect_index, dice_cmd.effect.target_card_ref, sc_card_ref, value, dice_roll.value, random_percent);
|
||||
// This debug_print call is in the original code.
|
||||
// this->debug_print(when, 4, &env_stats, "!set_abnormal..", target_card, card_effect.type);
|
||||
}
|
||||
|
||||
|
||||
+176
-127
@@ -18,6 +18,25 @@ namespace Episode3 {
|
||||
|
||||
|
||||
|
||||
const char* name_for_attack_medium(AttackMedium medium) {
|
||||
switch (medium) {
|
||||
case AttackMedium::UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
case AttackMedium::PHYSICAL:
|
||||
return "PHYSICAL";
|
||||
case AttackMedium::TECH:
|
||||
return "TECH";
|
||||
case AttackMedium::UNKNOWN_03:
|
||||
return "UNKNOWN_03";
|
||||
case AttackMedium::INVALID_FF:
|
||||
return "INVALID_FF";
|
||||
default:
|
||||
return "__INVALID__";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Location::Location() : Location(0, 0) { }
|
||||
Location::Location(uint8_t x, uint8_t y) : Location(x, y, Direction::RIGHT) { }
|
||||
Location::Location(uint8_t x, uint8_t y, Direction direction)
|
||||
@@ -33,6 +52,11 @@ bool Location::operator!=(const Location& other) const {
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
std::string Location::str() const {
|
||||
return string_printf("Location[x=%hhu, y=%hhu, dir=%s, u=%hhu]",
|
||||
this->x, this->y, name_for_direction(this->direction), this->unused);
|
||||
}
|
||||
|
||||
void Location::clear() {
|
||||
this->x = 0;
|
||||
this->y = 0;
|
||||
@@ -107,7 +131,7 @@ const char* name_for_direction(Direction d) {
|
||||
case Direction::INVALID_FF:
|
||||
return "INVALID_FF";
|
||||
default:
|
||||
return "__unknown__";
|
||||
return "__INVALID__";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,134 +307,159 @@ struct ConditionDescription {
|
||||
};
|
||||
|
||||
static const vector<ConditionDescription> description_for_condition_type({
|
||||
/* 0x00 */ {false, nullptr, nullptr},
|
||||
/* 0x01 */ {true, "AP Boost", "Temporarily increase AP by N"},
|
||||
/* 0x02 */ {false, "Rampage", "Rampage"},
|
||||
/* 0x03 */ {true, "Multi Strike", "Duplicate attack N times"},
|
||||
/* 0x04 */ {true, "Damage Modifier 1", "Set attack damage / AP to N after action cards applied (step 1)"},
|
||||
/* 0x05 */ {false, "Immobile", "Give Immobile condition"},
|
||||
/* 0x06 */ {false, "Hold", "Give Hold condition"},
|
||||
/* 0x07 */ {false, nullptr, nullptr},
|
||||
/* 0x08 */ {true, "TP Boost", "Add N TP temporarily during attack"},
|
||||
/* 0x09 */ {true, "Give Damage", "Cause direct N HP loss"},
|
||||
/* 0x0A */ {false, "Guom", "Give Guom condition"},
|
||||
/* 0x0B */ {false, "Paralyze", "Give Paralysis condition"},
|
||||
/* 0x0C */ {false, nullptr, nullptr},
|
||||
/* 0x0D */ {false, "A/H Swap", "Swap AP and HP temporarily"},
|
||||
/* 0x0E */ {false, "Pierce", "Attack SC directly even if they have items equipped"},
|
||||
/* 0x0F */ {false, nullptr, nullptr},
|
||||
/* 0x10 */ {true, "Heal", "Increase HP by N"},
|
||||
/* 0x11 */ {false, "Return to Hand", "Return card to hand"},
|
||||
/* 0x12 */ {false, nullptr, nullptr},
|
||||
/* 0x13 */ {false, nullptr, nullptr},
|
||||
/* 0x14 */ {false, "Acid", "Give Acid condition"},
|
||||
/* 0x15 */ {false, nullptr, nullptr},
|
||||
/* 0x16 */ {true, "Mighty Knuckle", "Temporarily increase AP by N, and set ATK dice to zero"},
|
||||
/* 0x17 */ {true, "Unit Blow", "Temporarily increase AP by N * number of this card set within phase"},
|
||||
/* 0x18 */ {false, "Curse", "Give Curse condition"},
|
||||
/* 0x19 */ {false, "Combo (AP)", "Temporarily increase AP by number of this card set within phase"},
|
||||
/* 0x1A */ {false, "Pierce/Rampage Block", "Block attack if Pierce/Rampage (?)"},
|
||||
/* 0x1B */ {false, "Ability Trap", "Temporarily disable opponent abilities"},
|
||||
/* 0x1C */ {false, "Freeze", "Give Freeze condition"},
|
||||
/* 0x1D */ {false, "Anti-Abnormality", "Cure all conditions"},
|
||||
/* 0x1E */ {false, nullptr, nullptr},
|
||||
/* 0x1F */ {false, "Explosion", "Damage all SCs and FCs by number of this same card set * 2"},
|
||||
/* 0x20 */ {false, nullptr, nullptr},
|
||||
/* 0x21 */ {false, nullptr, nullptr},
|
||||
/* 0x22 */ {false, nullptr, nullptr},
|
||||
/* 0x23 */ {false, "Return to Deck", "Cancel discard and move to bottom of deck instead"},
|
||||
/* 0x24 */ {false, "Aerial", "Give Aerial status"},
|
||||
/* 0x25 */ {true, "AP Loss", "Make attacker temporarily lose N AP during defense"},
|
||||
/* 0x26 */ {true, "Bonus From Leader", "Gain AP equal to the number of cards of type N on the field"},
|
||||
/* 0x27 */ {false, "Free Maneuver", "Enable movement over occupied tiles"},
|
||||
/* 0x28 */ {false, "Haste", "Make move actions free"},
|
||||
/* 0x29 */ {true, "Clone", "Make setting this card free if at least one card of type N is already on the field"},
|
||||
/* 0x2A */ {true, "DEF Disable by Cost", "Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive"},
|
||||
/* 0x2B */ {true, "Filial", "Increase controlling SC\'s HP by N when this card is destroyed"},
|
||||
/* 0x2C */ {true, "Snatch", "Steal N EXP during attack"},
|
||||
/* 0x2D */ {true, "Hand Disrupter", "Discard N cards from hand immediately"},
|
||||
/* 0x2E */ {false, "Drop", "Give Drop condition"},
|
||||
/* 0x2F */ {false, "Action Disrupter", "Destroy all action cards used by attacker"},
|
||||
/* 0x30 */ {true, "Set HP", "Set HP to N"},
|
||||
/* 0x31 */ {false, "Native Shield", "Block attacks from Native creatures"},
|
||||
/* 0x32 */ {false, "A.Beast Shield", "Block attacks from A.Beast creatures"},
|
||||
/* 0x33 */ {false, "Machine Shield", "Block attacks from Machine creatures"},
|
||||
/* 0x34 */ {false, "Dark Shield", "Block attacks from Dark creatures"},
|
||||
/* 0x35 */ {false, "Sword Shield", "Block attacks from Sword items"},
|
||||
/* 0x36 */ {false, "Gun Shield", "Block attacks from Gun items"},
|
||||
/* 0x37 */ {false, "Cane Shield", "Block attacks from Cane items"},
|
||||
/* 0x38 */ {false, nullptr, nullptr},
|
||||
/* 0x39 */ {false, nullptr, nullptr},
|
||||
/* 0x3A */ {false, "Defender", "Make attacks go to setter of this card instead of original target"},
|
||||
/* 0x3B */ {false, "Survival Decoys", "Redirect damage for multi-sided attack"},
|
||||
/* 0x3C */ {true, "Give/Take EXP", "Give N EXP, or take if N is negative"},
|
||||
/* 0x3D */ {false, nullptr, nullptr},
|
||||
/* 0x3E */ {false, "Death Companion", "If this card has 1 or 2 HP, set its HP to N"},
|
||||
/* 0x3F */ {true, "EXP Decoy", "If defender has EXP, lose EXP instead of getting damage when attacked"},
|
||||
/* 0x40 */ {true, "Set MV", "Set MV to N"},
|
||||
/* 0x41 */ {true, "Group", "Temporarily increase AP by N * number of this card on field, excluding itself"},
|
||||
/* 0x42 */ {false, "Berserk", "User of this card receives the same damage as target, and isn\'t helped by target\'s defense cards"},
|
||||
/* 0x43 */ {false, "Guard Creature", "Attacks on controlling SC damage this card instead"},
|
||||
/* 0x44 */ {false, "Tech", "Technique cards cost 1 fewer ATK point"},
|
||||
/* 0x45 */ {false, "Big Swing", "Increase all attacking ATK costs by 1"},
|
||||
/* 0x46 */ {false, nullptr, nullptr},
|
||||
/* 0x47 */ {false, "Shield Weapon", "Limit attacker\'s choice of target to guard items"},
|
||||
/* 0x48 */ {false, "ATK Dice Boost", "Increase ATK dice roll by 1"},
|
||||
/* 0x49 */ {false, nullptr, nullptr},
|
||||
/* 0x4A */ {false, "Major Pierce", "If SC has over half of max HP, attacks target SC instead of equipped items"},
|
||||
/* 0x4B */ {false, "Heavy Pierce", "If SC has 3 or more items equipped, attacks target SC instead of equipped items"},
|
||||
/* 0x4C */ {false, "Major Rampage", "If SC has over half of max HP, attacks target SC and all equipped items"},
|
||||
/* 0x4D */ {false, "Heavy Rampage", "If SC has 3 or more items equipped, attacks target SC and all equipped items"},
|
||||
/* 0x4E */ {true, "AP Growth", "Permanently increase AP by N"},
|
||||
/* 0x4F */ {true, "TP Growth", "Permanently increase TP by N"},
|
||||
/* 0x50 */ {true, "Reborn", "If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded"},
|
||||
/* 0x51 */ {true, "Copy", "Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent\'s values"},
|
||||
/* 0x52 */ {false, nullptr, nullptr},
|
||||
/* 0x53 */ {true, "Misc. Guards", "Add N to card\'s defense value"},
|
||||
/* 0x54 */ {true, "AP Override", "Set AP to N temporarily"},
|
||||
/* 0x55 */ {true, "TP Override", "Set TP to N temporarily"},
|
||||
/* 0x56 */ {false, "Return", "Return card to hand on destruction instead of discarding"},
|
||||
/* 0x57 */ {false, "A/T Swap Perm", "Permanently swap AP and TP"},
|
||||
/* 0x58 */ {false, "A/H Swap Perm", "Permanently swap AP and HP"},
|
||||
/* 0x59 */ {true, "Slayers/Assassins", "Temporarily increase AP during attack"},
|
||||
/* 0x5A */ {false, "Anti-Abnormality", "Remove all conditions"},
|
||||
/* 0x5B */ {false, "Fixed Range", "Use SC\'s range instead of weapon or attack card ranges"},
|
||||
/* 0x5C */ {false, "Elude", "SC does not lose HP when equipped items are destroyed"},
|
||||
/* 0x5D */ {false, "Parry", "Forward attack to a random FC within one tile of original target, excluding attacker and original target"},
|
||||
/* 0x5E */ {false, "Block Attack", "Completely block attack"},
|
||||
/* 0x5F */ {false, nullptr, nullptr},
|
||||
/* 0x60 */ {false, nullptr, nullptr},
|
||||
/* 0x61 */ {true, "Combo (TP)", "Gain TP equal to the number of cards of type N on the field"},
|
||||
/* 0x62 */ {true, "Misc. AP Bonuses", "Temporarily increase AP by N"},
|
||||
/* 0x63 */ {true, "Misc. TP Bonuses", "Temporarily increase TP by N"},
|
||||
/* 0x64 */ {false, nullptr, nullptr},
|
||||
/* 0x65 */ {true, "Misc. Defense Bonuses", "Decrease damage by N"},
|
||||
/* 0x66 */ {true, "Mostly Halfguards", "Reduce damage from incoming attack by N"},
|
||||
/* 0x67 */ {false, "Periodic Field", "Swap immunity to tech or physical attacks"},
|
||||
/* 0x68 */ {false, "FC Limit by Count", "Change FC limit from 8 ATK points total to 4 FCs total"},
|
||||
/* 0x69 */ {false, nullptr, nullptr},
|
||||
/* 0x6A */ {true, "MV Bonus", "Increase MV by N"},
|
||||
/* 0x6B */ {true, "Forward Damage", "Give N damage back to attacker during defense (?) (TODO)"},
|
||||
/* 0x6C */ {true, "Weak Spot / Influence", "Temporarily decrease AP by N"},
|
||||
/* 0x6D */ {true, "Damage Modifier 2", "Set attack damage / AP after action cards applied (step 2)"},
|
||||
/* 0x6E */ {true, "Weak Hit Block", "Block all attacks of N damage or less"},
|
||||
/* 0x6F */ {true, "AP Silence", "Temporarily decrease AP of opponent by N"},
|
||||
/* 0x70 */ {true, "TP Silence", "Temporarily decrease TP of opponent by N"},
|
||||
/* 0x71 */ {false, "A/T Swap", "Temporarily swap AP and TP"},
|
||||
/* 0x72 */ {true, "Halfguard", "Halve damage from attacks that would inflict N or more damage"},
|
||||
/* 0x73 */ {false, nullptr, nullptr},
|
||||
/* 0x74 */ {true, "Rampage AP Loss", "Temporarily reduce AP by N"},
|
||||
/* 0x75 */ {false, nullptr, nullptr},
|
||||
/* 0x76 */ {false, "Reflect", "Generate reverse attack"},
|
||||
/* 0x77 */ {false, nullptr, nullptr},
|
||||
/* 0x78 */ {false, nullptr, nullptr}, // Treated as "any condition" in find functions
|
||||
/* 0x79 */ {false, nullptr, nullptr},
|
||||
/* 0x7A */ {false, nullptr, nullptr},
|
||||
/* 0x7B */ {false, nullptr, nullptr},
|
||||
/* 0x7C */ {false, nullptr, nullptr},
|
||||
/* 0x7D */ {false, nullptr, nullptr},
|
||||
/* 0x00 */ {false, "NONE", nullptr},
|
||||
/* 0x01 */ {true, "AP_BOOST", "Temporarily increase AP by N"},
|
||||
/* 0x02 */ {false, "RAMPAGE", "Rampage"},
|
||||
/* 0x03 */ {true, "MULTI_STRIKE", "Duplicate attack N times"},
|
||||
/* 0x04 */ {true, "DAMAGE_MOD_1", "Set attack damage / AP to N after action cards applied (step 1)"},
|
||||
/* 0x05 */ {false, "IMMOBILE", "Give Immobile condition"},
|
||||
/* 0x06 */ {false, "HOLD", "Give Hold condition"},
|
||||
/* 0x07 */ {false, "UNKNOWN_07", nullptr},
|
||||
/* 0x08 */ {true, "TP_BOOST", "Add N TP temporarily during attack"},
|
||||
/* 0x09 */ {true, "GIVE_DAMAGE", "Cause direct N HP loss"},
|
||||
/* 0x0A */ {false, "GUOM", "Give Guom condition"},
|
||||
/* 0x0B */ {false, "PARALYZE", "Give Paralysis condition"},
|
||||
/* 0x0C */ {false, "UNKNOWN_0C", nullptr},
|
||||
/* 0x0D */ {false, "A_H_SWAP", "Swap AP and HP temporarily"},
|
||||
/* 0x0E */ {false, "PIERCE", "Attack SC directly even if they have items equipped"},
|
||||
/* 0x0F */ {false, "UNKNOWN_0F", nullptr},
|
||||
/* 0x10 */ {true, "HEAL", "Increase HP by N"},
|
||||
/* 0x11 */ {false, "RETURN_TO_HAND", "Return card to hand"},
|
||||
/* 0x12 */ {false, "UNKNOWN_12", nullptr},
|
||||
/* 0x13 */ {false, "UNKNOWN_13", nullptr},
|
||||
/* 0x14 */ {false, "ACID", "Give Acid condition"},
|
||||
/* 0x15 */ {false, "UNKNOWN_15", nullptr},
|
||||
/* 0x16 */ {true, "MIGHTY_KNUCKLE", "Temporarily increase AP by N, and set ATK dice to zero"},
|
||||
/* 0x17 */ {true, "UNIT_BLOW", "Temporarily increase AP by N * number of this card set within phase"},
|
||||
/* 0x18 */ {false, "CURSE", "Give Curse condition"},
|
||||
/* 0x19 */ {false, "COMBO_AP", "Temporarily increase AP by number of this card set within phase"},
|
||||
/* 0x1A */ {false, "PIERCE_RAMPAGE_BLOCK", "Block attack if Pierce/Rampage (?)"},
|
||||
/* 0x1B */ {false, "ABILITY_TRAP", "Temporarily disable opponent abilities"},
|
||||
/* 0x1C */ {false, "FREEZE", "Give Freeze condition"},
|
||||
/* 0x1D */ {false, "ANTI_ABNORMALITY_1", "Cure all conditions"},
|
||||
/* 0x1E */ {false, "UNKNOWN_1E", nullptr},
|
||||
/* 0x1F */ {false, "EXPLOSION", "Damage all SCs and FCs by number of this same card set * 2"},
|
||||
/* 0x20 */ {false, "UNKNOWN_20", nullptr},
|
||||
/* 0x21 */ {false, "UNKNOWN_21", nullptr},
|
||||
/* 0x22 */ {false, "UNKNOWN_22", nullptr},
|
||||
/* 0x23 */ {false, "RETURN_TO_DECK", "Cancel discard and move to bottom of deck instead"},
|
||||
/* 0x24 */ {false, "AERIAL", "Give Aerial status"},
|
||||
/* 0x25 */ {true, "AP_LOSS", "Make attacker temporarily lose N AP during defense"},
|
||||
/* 0x26 */ {true, "BONUS_FROM_LEADER", "Gain AP equal to the number of cards of type N on the field"},
|
||||
/* 0x27 */ {false, "FREE_MANEUVER", "Enable movement over occupied tiles"},
|
||||
/* 0x28 */ {false, "HASTE", "Make move actions free"},
|
||||
/* 0x29 */ {true, "CLONE", "Make setting this card free if at least one card of type N is already on the field"},
|
||||
/* 0x2A */ {true, "DEF_DISABLE_BY_COST", "Disable use of any defense cards costing between (N / 10) and (N % 10) points, inclusive"},
|
||||
/* 0x2B */ {true, "FILIAL", "Increase controlling SC\'s HP by N when this card is destroyed"},
|
||||
/* 0x2C */ {true, "SNATCH", "Steal N EXP during attack"},
|
||||
/* 0x2D */ {true, "HAND_DISRUPTER", "Discard N cards from hand immediately"},
|
||||
/* 0x2E */ {false, "DROP", "Give Drop condition"},
|
||||
/* 0x2F */ {false, "ACTION_DISRUPTER", "Destroy all action cards used by attacker"},
|
||||
/* 0x30 */ {true, "SET_HP", "Set HP to N"},
|
||||
/* 0x31 */ {false, "NATIVE_SHIELD", "Block attacks from Native creatures"},
|
||||
/* 0x32 */ {false, "A_BEAST_SHIELD", "Block attacks from A.Beast creatures"},
|
||||
/* 0x33 */ {false, "MACHINE_SHIELD", "Block attacks from Machine creatures"},
|
||||
/* 0x34 */ {false, "DARK_SHIELD", "Block attacks from Dark creatures"},
|
||||
/* 0x35 */ {false, "SWORD_SHIELD", "Block attacks from Sword items"},
|
||||
/* 0x36 */ {false, "GUN_SHIELD", "Block attacks from Gun items"},
|
||||
/* 0x37 */ {false, "CANE_SHIELD", "Block attacks from Cane items"},
|
||||
/* 0x38 */ {false, "UNKNOWN_38", nullptr},
|
||||
/* 0x39 */ {false, "UNKNOWN_39", nullptr},
|
||||
/* 0x3A */ {false, "DEFENDER", "Make attacks go to setter of this card instead of original target"},
|
||||
/* 0x3B */ {false, "SURVIVAL_DECOYS", "Redirect damage for multi-sided attack"},
|
||||
/* 0x3C */ {true, "GIVE_OR_TAKE_EXP", "Give N EXP, or take if N is negative"},
|
||||
/* 0x3D */ {false, "UNKNOWN_3D", nullptr},
|
||||
/* 0x3E */ {false, "DEATH_COMPANION", "If this card has 1 or 2 HP, set its HP to N"},
|
||||
/* 0x3F */ {true, "EXP_DECOY", "If defender has EXP, lose EXP instead of getting damage when attacked"},
|
||||
/* 0x40 */ {true, "SET_MV", "Set MV to N"},
|
||||
/* 0x41 */ {true, "GROUP", "Temporarily increase AP by N * number of this card on field, excluding itself"},
|
||||
/* 0x42 */ {false, "BERSERK", "User of this card receives the same damage as target, and isn\'t helped by target\'s defense cards"},
|
||||
/* 0x43 */ {false, "GUARD_CREATURE", "Attacks on controlling SC damage this card instead"},
|
||||
/* 0x44 */ {false, "TECH", "Technique cards cost 1 fewer ATK point"},
|
||||
/* 0x45 */ {false, "BIG_SWING", "Increase all attacking ATK costs by 1"},
|
||||
/* 0x46 */ {false, "UNKNOWN_46", nullptr},
|
||||
/* 0x47 */ {false, "SHIELD_WEAPON", "Limit attacker\'s choice of target to guard items"},
|
||||
/* 0x48 */ {false, "ATK_DICE_BOOST", "Increase ATK dice roll by 1"},
|
||||
/* 0x49 */ {false, "UNKNOWN_49", nullptr},
|
||||
/* 0x4A */ {false, "MAJOR_PIERCE", "If SC has over half of max HP, attacks target SC instead of equipped items"},
|
||||
/* 0x4B */ {false, "HEAVY_PIERCE", "If SC has 3 or more items equipped, attacks target SC instead of equipped items"},
|
||||
/* 0x4C */ {false, "MAJOR_RAMPAGE", "If SC has over half of max HP, attacks target SC and all equipped items"},
|
||||
/* 0x4D */ {false, "HEAVY_RAMPAGE", "If SC has 3 or more items equipped, attacks target SC and all equipped items"},
|
||||
/* 0x4E */ {true, "AP_GROWTH", "Permanently increase AP by N"},
|
||||
/* 0x4F */ {true, "TP_GROWTH", "Permanently increase TP by N"},
|
||||
/* 0x50 */ {true, "REBORN", "If any card of type N is on the field, this card goes to the hand when destroyed instead of being discarded"},
|
||||
/* 0x51 */ {true, "COPY", "Temporarily set AP/TP to N percent (or 100% if N is 0) of opponent\'s values"},
|
||||
/* 0x52 */ {false, "UNKNOWN_52", nullptr},
|
||||
/* 0x53 */ {true, "MISC_GUARDS", "Add N to card\'s defense value"},
|
||||
/* 0x54 */ {true, "AP_OVERRIDE", "Set AP to N temporarily"},
|
||||
/* 0x55 */ {true, "TP_OVERRIDE", "Set TP to N temporarily"},
|
||||
/* 0x56 */ {false, "RETURN", "Return card to hand on destruction instead of discarding"},
|
||||
/* 0x57 */ {false, "A_T_SWAP_PERM", "Permanently swap AP and TP"},
|
||||
/* 0x58 */ {false, "A_H_SWAP_PERM", "Permanently swap AP and HP"},
|
||||
/* 0x59 */ {true, "SLAYERS_ASSASSINS", "Temporarily increase AP during attack"},
|
||||
/* 0x5A */ {false, "ANTI_ABNORMALITY_2", "Remove all conditions"},
|
||||
/* 0x5B */ {false, "FIXED_RANGE", "Use SC\'s range instead of weapon or attack card ranges"},
|
||||
/* 0x5C */ {false, "ELUDE", "SC does not lose HP when equipped items are destroyed"},
|
||||
/* 0x5D */ {false, "PARRY", "Forward attack to a random FC within one tile of original target, excluding attacker and original target"},
|
||||
/* 0x5E */ {false, "BLOCK_ATTACK", "Completely block attack"},
|
||||
/* 0x5F */ {false, "UNKNOWN_5F", nullptr},
|
||||
/* 0x60 */ {false, "UNKNOWN_60", nullptr},
|
||||
/* 0x61 */ {true, "COMBO_TP", "Gain TP equal to the number of cards of type N on the field"},
|
||||
/* 0x62 */ {true, "MISC_AP_BONUSES", "Temporarily increase AP by N"},
|
||||
/* 0x63 */ {true, "MISC_TP_BONUSES", "Temporarily increase TP by N"},
|
||||
/* 0x64 */ {false, "UNKNOWN_64", nullptr},
|
||||
/* 0x65 */ {true, "MISC_DEFENSE_BONUSES", "Decrease damage by N"},
|
||||
/* 0x66 */ {true, "MOSTLY_HALFGUARDS", "Reduce damage from incoming attack by N"},
|
||||
/* 0x67 */ {false, "PERIODIC_FIELD", "Swap immunity to tech or physical attacks"},
|
||||
/* 0x68 */ {false, "FC_LIMIT_BY_COUNT", "Change FC limit from 8 ATK points total to 4 FCs total"},
|
||||
/* 0x69 */ {false, "UNKNOWN_69", nullptr},
|
||||
/* 0x6A */ {true, "MV_BONUS", "Increase MV by N"},
|
||||
/* 0x6B */ {true, "FORWARD_DAMAGE", "Give N damage back to attacker during defense (?) (TODO)"},
|
||||
/* 0x6C */ {true, "WEAK_SPOT_INFLUENCE", "Temporarily decrease AP by N"},
|
||||
/* 0x6D */ {true, "DAMAGE_MODIFIER_2", "Set attack damage / AP after action cards applied (step 2)"},
|
||||
/* 0x6E */ {true, "WEAK_HIT_BLOCK", "Block all attacks of N damage or less"},
|
||||
/* 0x6F */ {true, "AP_SILENCE", "Temporarily decrease AP of opponent by N"},
|
||||
/* 0x70 */ {true, "TP_SILENCE", "Temporarily decrease TP of opponent by N"},
|
||||
/* 0x71 */ {false, "A_T_SWAP", "Temporarily swap AP and TP"},
|
||||
/* 0x72 */ {true, "HALFGUARD", "Halve damage from attacks that would inflict N or more damage"},
|
||||
/* 0x73 */ {false, "UNKNOWN_73", nullptr},
|
||||
/* 0x74 */ {true, "RAMPAGE_AP_LOSS", "Temporarily reduce AP by N"},
|
||||
/* 0x75 */ {false, "UNKNOWN_75", nullptr},
|
||||
/* 0x76 */ {false, "REFLECT", "Generate reverse attack"},
|
||||
/* 0x77 */ {false, "UNKNOWN_77", nullptr},
|
||||
/* 0x78 */ {false, "ANY", nullptr}, // Treated as "any condition" in find functions
|
||||
/* 0x79 */ {false, "UNKNOWN_79", nullptr},
|
||||
/* 0x7A */ {false, "UNKNOWN_7A", nullptr},
|
||||
/* 0x7B */ {false, "UNKNOWN_7B", nullptr},
|
||||
/* 0x7C */ {false, "UNKNOWN_7C", nullptr},
|
||||
/* 0x7D */ {false, "UNKNOWN_7D", nullptr},
|
||||
});
|
||||
|
||||
const char* name_for_condition_type(ConditionType cond_type) {
|
||||
try {
|
||||
return description_for_condition_type.at(static_cast<size_t>(cond_type)).name;
|
||||
} catch (const out_of_range&) {
|
||||
return "__INVALID__";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const char* name_for_action_subphase(ActionSubphase subphase) {
|
||||
switch (subphase) {
|
||||
case ActionSubphase::ATTACK:
|
||||
return "ATTACK";
|
||||
case ActionSubphase::DEFENSE:
|
||||
return "DEFENSE";
|
||||
case ActionSubphase::INVALID_FF:
|
||||
return "INVALID_FF";
|
||||
default:
|
||||
return "__INVALID__";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CardDefinition::Stat::decode_code() {
|
||||
this->type = static_cast<Type>(this->code / 1000);
|
||||
int16_t value = this->code - (this->type * 1000);
|
||||
|
||||
@@ -58,6 +58,8 @@ enum class AttackMedium : uint8_t {
|
||||
INVALID_FF = 0xFF,
|
||||
};
|
||||
|
||||
const char* name_for_attack_medium(AttackMedium medium);
|
||||
|
||||
enum class CriterionCode : uint8_t {
|
||||
NONE = 0x00,
|
||||
HU_CLASS_SC = 0x01,
|
||||
@@ -293,6 +295,8 @@ enum class ConditionType : uint8_t {
|
||||
ANY_FF = 0xFF, // Used as a wildcard in some search functions
|
||||
};
|
||||
|
||||
const char* name_for_condition_type(ConditionType cond_type);
|
||||
|
||||
enum class AssistEffect : uint16_t {
|
||||
NONE = 0x0000,
|
||||
DICE_HALF = 0x0001,
|
||||
@@ -389,6 +393,8 @@ enum class ActionSubphase : uint8_t {
|
||||
INVALID_FF = 0xFF,
|
||||
};
|
||||
|
||||
const char* name_for_action_subphase(ActionSubphase subphase);
|
||||
|
||||
enum class SetupPhase : uint8_t {
|
||||
REGISTRATION = 0,
|
||||
STARTER_ROLLS = 1,
|
||||
@@ -434,6 +440,8 @@ struct Location {
|
||||
bool operator==(const Location& other) const;
|
||||
bool operator!=(const Location& other) const;
|
||||
|
||||
std::string str() const;
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -8,6 +8,24 @@ namespace Episode3 {
|
||||
|
||||
|
||||
|
||||
template <size_t Count>
|
||||
std::string string_for_refs(const parray<le_uint16_t, Count>& card_refs) {
|
||||
string ret = "[";
|
||||
for (size_t z = 0; z < Count; z++) {
|
||||
if (card_refs[z] != 0xFFFF) {
|
||||
ret += string_printf("%zu:@$%04X ", z, card_refs[z].load());
|
||||
}
|
||||
}
|
||||
if (!ret.empty()) {
|
||||
ret.back() = ']'; // Replace the ' ' from the last added item
|
||||
} else {
|
||||
ret.push_back(']');
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Condition::Condition() {
|
||||
this->clear();
|
||||
}
|
||||
@@ -63,6 +81,26 @@ void Condition::clear_FF() {
|
||||
this->unknown_a8 = 0xFF;
|
||||
}
|
||||
|
||||
std::string Condition::str() const {
|
||||
return string_printf(
|
||||
"Condition[type=%s, turns=%hhu, a_arg=%hhd, dice=%hhu, flags=%02hhX, "
|
||||
"def_eff_index=%hhu, ref=@%04hX, value=%hd, giver_ref=@%04hX "
|
||||
"percent=%hhu value8=%hd order=%hu a8=%hu]",
|
||||
name_for_condition_type(this->type),
|
||||
this->remaining_turns,
|
||||
this->a_arg_value,
|
||||
this->dice_roll_value,
|
||||
this->flags,
|
||||
this->card_definition_effect_index,
|
||||
this->card_ref.load(),
|
||||
this->value.load(),
|
||||
this->condition_giver_card_ref.load(),
|
||||
this->random_percent,
|
||||
this->value8,
|
||||
this->order,
|
||||
this->unknown_a8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EffectResult::EffectResult() {
|
||||
@@ -82,6 +120,23 @@ void EffectResult::clear() {
|
||||
this->dice_roll_value = 0;
|
||||
}
|
||||
|
||||
std::string EffectResult::str() const {
|
||||
return string_printf(
|
||||
"EffectResult[att_ref=@%04hX, target_ref=@%04hX, value=%hhd, "
|
||||
"cur_hp=%hhd, ap=%hhd, tp=%hhd, flags=%02hhX, op=%hhd, "
|
||||
"cond_index=%hhu, dice=%hhu]",
|
||||
this->attacker_card_ref.load(),
|
||||
this->target_card_ref.load(),
|
||||
this->value,
|
||||
this->current_hp,
|
||||
this->ap,
|
||||
this->tp,
|
||||
this->flags,
|
||||
this->operation,
|
||||
this->condition_index,
|
||||
this->dice_roll_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CardShortStatus::CardShortStatus() {
|
||||
@@ -101,6 +156,20 @@ bool CardShortStatus::operator!=(const CardShortStatus& other) const {
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
std::string CardShortStatus::str() const {
|
||||
string loc_s = this->loc.str();
|
||||
return string_printf(
|
||||
"CardShortStatus[ref=@%04hX, cur_hp=%hd, flags=%08" PRIX32 ", loc=%s, "
|
||||
"u1=%04hX, max_hp=%hhd, u2=%hhu]",
|
||||
this->card_ref.load(),
|
||||
this->current_hp.load(),
|
||||
this->card_flags.load(),
|
||||
loc_s.c_str(),
|
||||
this->unused1.load(),
|
||||
this->max_hp,
|
||||
this->unused2);
|
||||
}
|
||||
|
||||
void CardShortStatus::clear() {
|
||||
this->card_ref = 0xFFFF;
|
||||
this->current_hp = 0;
|
||||
@@ -138,6 +207,23 @@ void ActionState::clear() {
|
||||
this->action_card_refs.clear(0xFFFF);
|
||||
}
|
||||
|
||||
std::string ActionState::str() const {
|
||||
string target_refs_s = string_for_refs(this->target_card_refs);
|
||||
string action_refs_s = string_for_refs(this->action_card_refs);
|
||||
return string_printf(
|
||||
"ActionState[client=%hu, u=%hhu, facing=%s, attacker_ref=@%04hX, "
|
||||
"def_ref=@%04hX, target_refs=%s, action_refs=%s, "
|
||||
"orig_attacker_ref=@%04hX]",
|
||||
this->client_id.load(),
|
||||
this->unused,
|
||||
name_for_direction(this->facing_direction),
|
||||
this->attacker_card_ref.load(),
|
||||
this->defense_card_ref.load(),
|
||||
target_refs_s.c_str(),
|
||||
action_refs_s.c_str(),
|
||||
this->original_attacker_card_ref.load());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ActionChain::ActionChain() {
|
||||
@@ -171,6 +257,40 @@ bool ActionChain::operator!=(const ActionChain& other) const {
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
std::string ActionChain::str() const {
|
||||
string attack_action_card_refs_s = string_for_refs(this->attack_action_card_refs);
|
||||
string target_card_refs_s = string_for_refs(this->target_card_refs);
|
||||
return string_printf(
|
||||
"ActionChain[eff_ap=%hhd, eff_tp=%hhd, ap_bonus=%hhd, damage=%hhd, "
|
||||
"acting_ref=@%04hX, unknown_ref_a3=@%04hX, "
|
||||
"attack_action_refs=%s, attack_action_ref_count=%hhu, "
|
||||
"medium=%s, target_ref_count=%hhu, subphase=%s, "
|
||||
"strikes=%hhu, damage_mult=%hhd, attack_num=%hhu, "
|
||||
"tp_bonus=%hhd, u1=%hhu, u2=%hhu, card_ap=%hhd, "
|
||||
"card_tp=%hhd, flags=%08" PRIX32 ", target_refs=%s]",
|
||||
this->effective_ap,
|
||||
this->effective_tp,
|
||||
this->ap_effect_bonus,
|
||||
this->damage,
|
||||
this->acting_card_ref.load(),
|
||||
this->unknown_card_ref_a3.load(),
|
||||
attack_action_card_refs_s.c_str(),
|
||||
this->attack_action_card_ref_count,
|
||||
name_for_attack_medium(this->attack_medium),
|
||||
this->target_card_ref_count,
|
||||
name_for_action_subphase(this->action_subphase),
|
||||
this->strike_count,
|
||||
this->damage_multiplier,
|
||||
this->attack_number,
|
||||
this->tp_effect_bonus,
|
||||
this->unused1,
|
||||
this->unused2,
|
||||
this->card_ap,
|
||||
this->card_tp,
|
||||
this->flags.load(),
|
||||
target_card_refs_s.c_str());
|
||||
}
|
||||
|
||||
void ActionChain::clear() {
|
||||
this->effective_ap = 0;
|
||||
this->effective_tp = 0;
|
||||
@@ -232,6 +352,23 @@ bool ActionChainWithConds::operator!=(const ActionChainWithConds& other) const {
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
std::string ActionChainWithConds::str() const {
|
||||
string ret = "ActionChainWithConds[chain=";
|
||||
ret += this->chain.str();
|
||||
ret += ", conds=[";
|
||||
for (size_t z = 0; z < this->conditions.size(); z++) {
|
||||
if (this->conditions[z].type != ConditionType::NONE) {
|
||||
if (ret.back() != '=') {
|
||||
ret += ", ";
|
||||
}
|
||||
ret += string_printf("%zu:", z);
|
||||
ret += this->conditions[z].str();
|
||||
}
|
||||
}
|
||||
ret += "]]";
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ActionChainWithConds::clear() {
|
||||
this->chain.effective_ap = 0;
|
||||
this->chain.effective_tp = 0;
|
||||
@@ -381,6 +518,28 @@ bool ActionMetadata::operator!=(const ActionMetadata& other) const {
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
std::string ActionMetadata::str() const {
|
||||
string target_card_refs_s = string_for_refs(this->target_card_refs);
|
||||
string defense_card_refs_s = string_for_refs(this->defense_card_refs);
|
||||
string original_attacker_card_refs_s = string_for_refs(this->original_attacker_card_refs);
|
||||
return string_printf(
|
||||
"ActionMetadata[ref=@%04hX, target_ref_count=%hhu, def_ref_count=%hhu, "
|
||||
"subphase=%s, def_power=%hhd, def_bonus=%hhd, "
|
||||
"att_bonus=%hhd, flags=%08" PRIX32 ", target_refs=%s, "
|
||||
"defense_refs=%s, original_attacker_refs=%s]",
|
||||
this->card_ref.load(),
|
||||
this->target_card_ref_count,
|
||||
this->defense_card_ref_count,
|
||||
name_for_action_subphase(this->action_subphase),
|
||||
this->defense_power,
|
||||
this->defense_bonus,
|
||||
this->attack_bonus,
|
||||
this->flags.load(),
|
||||
target_card_refs_s.c_str(),
|
||||
defense_card_refs_s.c_str(),
|
||||
original_attacker_card_refs_s.c_str());
|
||||
}
|
||||
|
||||
void ActionMetadata::clear() {
|
||||
this->card_ref = 0xFFFF;
|
||||
this->target_card_ref_count = 0;
|
||||
@@ -457,6 +616,46 @@ HandAndEquipState::HandAndEquipState() {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
std::string HandAndEquipState::str() const {
|
||||
string hand_card_refs_s = string_for_refs(this->hand_card_refs);
|
||||
string set_card_refs_s = string_for_refs(this->set_card_refs);
|
||||
string hand_card_refs2_s = string_for_refs(this->hand_card_refs2);
|
||||
string set_card_refs2_s = string_for_refs(this->set_card_refs2);
|
||||
return string_printf(
|
||||
"HandAndEquipState[dice=[%hhu, %hhu], atk=%hhu, def=%hhu, atk2=%hhu, "
|
||||
"a1=%hhu, total_set_cost=%hhu, is_cpu=%hhu, "
|
||||
"assist_flags=%08" PRIX32 ", hand_refs=%s, "
|
||||
"assist_ref=@%04hX, set_refs=%s, sc_ref=@%04hX, "
|
||||
"hand_refs2=%s, set_refs2=%s, assist_ref2=@%04hX, "
|
||||
"assist_set_num=%hu, assist_card_id=%04hX, "
|
||||
"assist_turns=%hhu, assit_dely=%hhu, atk_bonus=%hhu, "
|
||||
"def_bonus=%hhu, u2=[%hhu, %hhu]]",
|
||||
this->dice_results[0],
|
||||
this->dice_results[1],
|
||||
this->atk_points,
|
||||
this->def_points,
|
||||
this->atk_points2,
|
||||
this->unknown_a1,
|
||||
this->total_set_cards_cost,
|
||||
this->is_cpu_player,
|
||||
this->assist_flags.load(),
|
||||
hand_card_refs_s.c_str(),
|
||||
this->assist_card_ref.load(),
|
||||
set_card_refs_s.c_str(),
|
||||
this->sc_card_ref.load(),
|
||||
hand_card_refs2_s.c_str(),
|
||||
set_card_refs2_s.c_str(),
|
||||
this->assist_card_ref2.load(),
|
||||
this->assist_card_set_number.load(),
|
||||
this->assist_card_id.load(),
|
||||
this->assist_remaining_turns,
|
||||
this->assist_delay_turns,
|
||||
this->atk_bonuses,
|
||||
this->def_bonuses,
|
||||
this->unused2[0],
|
||||
this->unused2[1]);
|
||||
}
|
||||
|
||||
void HandAndEquipState::clear() {
|
||||
this->dice_results.clear(0);
|
||||
this->atk_points = 0;
|
||||
|
||||
@@ -36,6 +36,8 @@ struct Condition {
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct EffectResult {
|
||||
@@ -54,6 +56,8 @@ struct EffectResult {
|
||||
bool operator==(const EffectResult& other) const;
|
||||
bool operator!=(const EffectResult& other) const;
|
||||
|
||||
std::string str() const;
|
||||
|
||||
void clear();
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -72,6 +76,8 @@ struct CardShortStatus {
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ActionState {
|
||||
@@ -89,6 +95,8 @@ struct ActionState {
|
||||
bool operator!=(const ActionState& other) const;
|
||||
|
||||
void clear();
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ActionChain {
|
||||
@@ -120,6 +128,8 @@ struct ActionChain {
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ActionChainWithConds {
|
||||
@@ -153,6 +163,8 @@ struct ActionChainWithConds {
|
||||
|
||||
void set_action_subphase_from_card(std::shared_ptr<const Card> card);
|
||||
bool unknown_8024DEC4() const;
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ActionMetadata {
|
||||
@@ -172,6 +184,8 @@ struct ActionMetadata {
|
||||
bool operator==(const ActionMetadata& other) const;
|
||||
bool operator!=(const ActionMetadata& other) const;
|
||||
|
||||
std::string str() const;
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
|
||||
@@ -218,6 +232,8 @@ struct HandAndEquipState {
|
||||
|
||||
void clear();
|
||||
void clear_FF();
|
||||
|
||||
std::string str() const;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PlayerStats {
|
||||
|
||||
@@ -38,6 +38,7 @@ ServerBase::ServerBase(
|
||||
shared_ptr<const DataIndex::MapEntry> map_if_tournament)
|
||||
: lobby(lobby),
|
||||
data_index(data_index),
|
||||
log(lobby->log.prefix + "[Ep3::Server] "),
|
||||
random_seed(random_seed),
|
||||
is_tournament(!!map_if_tournament),
|
||||
last_chosen_map(map_if_tournament) { }
|
||||
@@ -244,6 +245,17 @@ void Server::send_commands_for_joining_spectator(Channel& c) const {
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void Server::log_debug(const char* fmt, ...) const {
|
||||
auto l = this->base()->lobby.lock();
|
||||
if (l && (this->base()->data_index->behavior_flags & Episode3::BehaviorFlag::ENABLE_STATUS_MESSAGES)) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
this->base()->log.info_v(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void Server::send_debug_message_printf(const char* fmt, ...) const {
|
||||
auto l = this->base()->lobby.lock();
|
||||
@@ -252,6 +264,7 @@ void Server::send_debug_message_printf(const char* fmt, ...) const {
|
||||
va_start(va, fmt);
|
||||
std::string buf = string_vprintf(fmt, va);
|
||||
va_end(va);
|
||||
this->base()->log.info("%s", buf.c_str());
|
||||
std::u16string decoded = decode_sjis(buf);
|
||||
send_text_message(l, decoded.c_str());
|
||||
}
|
||||
@@ -265,6 +278,7 @@ void Server::send_info_message_printf(const char* fmt, ...) const {
|
||||
va_start(va, fmt);
|
||||
std::string buf = string_vprintf(fmt, va);
|
||||
va_end(va);
|
||||
this->base()->log.info("%s", buf.c_str());
|
||||
std::u16string decoded = decode_sjis(buf);
|
||||
send_text_message(l, decoded.c_str());
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace Episode3 {
|
||||
* in these files map very closely to how their server implementation was
|
||||
* written; notable differences (due to necessary environment differences or bug
|
||||
* fixes) are described in the comments therein.
|
||||
*
|
||||
* Some debugging functions have been added which are not part of the original
|
||||
* implementation. Notably, this applies to functions like debug message senders
|
||||
* and loggers and all str() functions.
|
||||
*
|
||||
* There are likely undiscovered bugs in this code, some originally written by
|
||||
* Sega, but more written by me as I manually transcribed and updated this code.
|
||||
@@ -74,6 +78,7 @@ public:
|
||||
|
||||
std::weak_ptr<Lobby> lobby;
|
||||
std::shared_ptr<const DataIndex> data_index;
|
||||
PrefixedLogger log;
|
||||
uint32_t random_seed;
|
||||
bool is_tournament;
|
||||
std::shared_ptr<const DataIndex::MapEntry> last_chosen_map;
|
||||
@@ -117,6 +122,9 @@ public:
|
||||
|
||||
void send_commands_for_joining_spectator(Channel& ch) const;
|
||||
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void log_debug(const char* fmt, ...) const;
|
||||
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
void send_debug_message_printf(const char* fmt, ...) const;
|
||||
__attribute__((format(printf, 2, 3)))
|
||||
|
||||
Reference in New Issue
Block a user