fix map loading mismatches
This commit is contained in:
@@ -51,7 +51,8 @@ With that said, I offer no guarantees on how or when this project will advance.
|
|||||||
|
|
||||||
Current known issues / missing features / things to do:
|
Current known issues / missing features / things to do:
|
||||||
- Implement the rest of PSOBB. Major areas of work:
|
- Implement the rest of PSOBB. Major areas of work:
|
||||||
- Find any remaining mismatches in enemy IDs / experience (Episode 1 is mostly fixed now, except for Dark Falz)
|
- Find any remaining mismatches in enemy IDs / experience
|
||||||
|
- Sale prices for non-rare weapons with specials are computed incorrectly when buying/selling at shops
|
||||||
- Replace enemy list, game episode, etc. with quest data when loading a quest
|
- Replace enemy list, game episode, etc. with quest data when loading a quest
|
||||||
- Implement trade window
|
- Implement trade window
|
||||||
- Fix some edge cases on the BB proxy server (e.g. make sure Change Ship does the right thing, which is not the same as what it should do on other versions).
|
- Fix some edge cases on the BB proxy server (e.g. make sure Change Ship does the right thing, which is not the same as what it should do on other versions).
|
||||||
|
|||||||
+34
-27
@@ -26,6 +26,10 @@ const char* name_for_enum<EnemyType>(EnemyType type) {
|
|||||||
return "BARBA_RAY";
|
return "BARBA_RAY";
|
||||||
case EnemyType::BARBAROUS_WOLF:
|
case EnemyType::BARBAROUS_WOLF:
|
||||||
return "BARBAROUS_WOLF";
|
return "BARBAROUS_WOLF";
|
||||||
|
case EnemyType::BEE_L:
|
||||||
|
return "BEE_L";
|
||||||
|
case EnemyType::BEE_R:
|
||||||
|
return "BEE_R";
|
||||||
case EnemyType::BOOMA:
|
case EnemyType::BOOMA:
|
||||||
return "BOOMA";
|
return "BOOMA";
|
||||||
case EnemyType::BOOTA:
|
case EnemyType::BOOTA:
|
||||||
@@ -58,6 +62,10 @@ const char* name_for_enum<EnemyType>(EnemyType type) {
|
|||||||
return "DARVANT";
|
return "DARVANT";
|
||||||
case EnemyType::DE_ROL_LE:
|
case EnemyType::DE_ROL_LE:
|
||||||
return "DE_ROL_LE";
|
return "DE_ROL_LE";
|
||||||
|
case EnemyType::DE_ROL_LE_BODY:
|
||||||
|
return "DE_ROL_LE_BODY";
|
||||||
|
case EnemyType::DE_ROL_LE_MINE:
|
||||||
|
return "DE_ROL_LE_MINE";
|
||||||
case EnemyType::DEATH_GUNNER:
|
case EnemyType::DEATH_GUNNER:
|
||||||
return "DEATH_GUNNER";
|
return "DEATH_GUNNER";
|
||||||
case EnemyType::DEL_LILY:
|
case EnemyType::DEL_LILY:
|
||||||
@@ -90,6 +98,8 @@ const char* name_for_enum<EnemyType>(EnemyType type) {
|
|||||||
return "DUBWITCH";
|
return "DUBWITCH";
|
||||||
case EnemyType::EGG_RAPPY:
|
case EnemyType::EGG_RAPPY:
|
||||||
return "EGG_RAPPY";
|
return "EGG_RAPPY";
|
||||||
|
case EnemyType::EPSIGUARD:
|
||||||
|
return "EPSIGUARD";
|
||||||
case EnemyType::EPSILON:
|
case EnemyType::EPSILON:
|
||||||
return "EPSILON";
|
return "EPSILON";
|
||||||
case EnemyType::EVIL_SHARK:
|
case EnemyType::EVIL_SHARK:
|
||||||
@@ -178,6 +188,8 @@ const char* name_for_enum<EnemyType>(EnemyType type) {
|
|||||||
return "PAZUZU";
|
return "PAZUZU";
|
||||||
case EnemyType::PAZUZU_ALT:
|
case EnemyType::PAZUZU_ALT:
|
||||||
return "PAZUZU_ALT";
|
return "PAZUZU_ALT";
|
||||||
|
case EnemyType::PIG_RAY:
|
||||||
|
return "PIG_RAY";
|
||||||
case EnemyType::POFUILLY_SLIME:
|
case EnemyType::POFUILLY_SLIME:
|
||||||
return "POFUILLY_SLIME";
|
return "POFUILLY_SLIME";
|
||||||
case EnemyType::POUILLY_SLIME:
|
case EnemyType::POUILLY_SLIME:
|
||||||
@@ -228,6 +240,14 @@ const char* name_for_enum<EnemyType>(EnemyType type) {
|
|||||||
return "VOL_OPT_1";
|
return "VOL_OPT_1";
|
||||||
case EnemyType::VOL_OPT_2:
|
case EnemyType::VOL_OPT_2:
|
||||||
return "VOL_OPT_2";
|
return "VOL_OPT_2";
|
||||||
|
case EnemyType::VOL_OPT_AMP:
|
||||||
|
return "VOL_OPT_AMP";
|
||||||
|
case EnemyType::VOL_OPT_CORE:
|
||||||
|
return "VOL_OPT_CORE";
|
||||||
|
case EnemyType::VOL_OPT_MONITOR:
|
||||||
|
return "VOL_OPT_MONITOR";
|
||||||
|
case EnemyType::VOL_OPT_PILLAR:
|
||||||
|
return "VOL_OPT_PILLAR";
|
||||||
case EnemyType::YOWIE:
|
case EnemyType::YOWIE:
|
||||||
return "YOWIE";
|
return "YOWIE";
|
||||||
case EnemyType::YOWIE_ALT:
|
case EnemyType::YOWIE_ALT:
|
||||||
@@ -255,6 +275,8 @@ EnemyType enum_for_name<EnemyType>(const char* name) {
|
|||||||
{"BA_BOOTA", EnemyType::BA_BOOTA},
|
{"BA_BOOTA", EnemyType::BA_BOOTA},
|
||||||
{"BARBA_RAY", EnemyType::BARBA_RAY},
|
{"BARBA_RAY", EnemyType::BARBA_RAY},
|
||||||
{"BARBAROUS_WOLF", EnemyType::BARBAROUS_WOLF},
|
{"BARBAROUS_WOLF", EnemyType::BARBAROUS_WOLF},
|
||||||
|
{"BEE_L", EnemyType::BEE_L},
|
||||||
|
{"BEE_R", EnemyType::BEE_R},
|
||||||
{"BOOMA", EnemyType::BOOMA},
|
{"BOOMA", EnemyType::BOOMA},
|
||||||
{"BOOTA", EnemyType::BOOTA},
|
{"BOOTA", EnemyType::BOOTA},
|
||||||
{"BULCLAW", EnemyType::BULCLAW},
|
{"BULCLAW", EnemyType::BULCLAW},
|
||||||
@@ -272,6 +294,8 @@ EnemyType enum_for_name<EnemyType>(const char* name) {
|
|||||||
{"DARVANT", EnemyType::DARVANT},
|
{"DARVANT", EnemyType::DARVANT},
|
||||||
{"DARVANT_ULTIMATE", EnemyType::DARVANT_ULTIMATE},
|
{"DARVANT_ULTIMATE", EnemyType::DARVANT_ULTIMATE},
|
||||||
{"DE_ROL_LE", EnemyType::DE_ROL_LE},
|
{"DE_ROL_LE", EnemyType::DE_ROL_LE},
|
||||||
|
{"DE_ROL_LE_BODY", EnemyType::DE_ROL_LE_BODY},
|
||||||
|
{"DE_ROL_LE_MINE", EnemyType::DE_ROL_LE_MINE},
|
||||||
{"DEATH_GUNNER", EnemyType::DEATH_GUNNER},
|
{"DEATH_GUNNER", EnemyType::DEATH_GUNNER},
|
||||||
{"DEL_LILY", EnemyType::DEL_LILY},
|
{"DEL_LILY", EnemyType::DEL_LILY},
|
||||||
{"DEL_RAPPY", EnemyType::DEL_RAPPY},
|
{"DEL_RAPPY", EnemyType::DEL_RAPPY},
|
||||||
@@ -288,6 +312,7 @@ EnemyType enum_for_name<EnemyType>(const char* name) {
|
|||||||
{"DUBCHIC", EnemyType::DUBCHIC},
|
{"DUBCHIC", EnemyType::DUBCHIC},
|
||||||
{"DUBWITCH", EnemyType::DUBWITCH},
|
{"DUBWITCH", EnemyType::DUBWITCH},
|
||||||
{"EGG_RAPPY", EnemyType::EGG_RAPPY},
|
{"EGG_RAPPY", EnemyType::EGG_RAPPY},
|
||||||
|
{"EPSIGUARD", EnemyType::EPSIGUARD},
|
||||||
{"EPSILON", EnemyType::EPSILON},
|
{"EPSILON", EnemyType::EPSILON},
|
||||||
{"EVIL_SHARK", EnemyType::EVIL_SHARK},
|
{"EVIL_SHARK", EnemyType::EVIL_SHARK},
|
||||||
{"GAEL", EnemyType::GAEL},
|
{"GAEL", EnemyType::GAEL},
|
||||||
@@ -332,6 +357,7 @@ EnemyType enum_for_name<EnemyType>(const char* name) {
|
|||||||
{"PAN_ARMS", EnemyType::PAN_ARMS},
|
{"PAN_ARMS", EnemyType::PAN_ARMS},
|
||||||
{"PAZUZU", EnemyType::PAZUZU},
|
{"PAZUZU", EnemyType::PAZUZU},
|
||||||
{"PAZUZU_ALT", EnemyType::PAZUZU_ALT},
|
{"PAZUZU_ALT", EnemyType::PAZUZU_ALT},
|
||||||
|
{"PIG_RAY", EnemyType::PIG_RAY},
|
||||||
{"POFUILLY_SLIME", EnemyType::POFUILLY_SLIME},
|
{"POFUILLY_SLIME", EnemyType::POFUILLY_SLIME},
|
||||||
{"POUILLY_SLIME", EnemyType::POUILLY_SLIME},
|
{"POUILLY_SLIME", EnemyType::POUILLY_SLIME},
|
||||||
{"POISON_LILY", EnemyType::POISON_LILY},
|
{"POISON_LILY", EnemyType::POISON_LILY},
|
||||||
@@ -357,6 +383,10 @@ EnemyType enum_for_name<EnemyType>(const char* name) {
|
|||||||
{"UL_GIBBON", EnemyType::UL_GIBBON},
|
{"UL_GIBBON", EnemyType::UL_GIBBON},
|
||||||
{"VOL_OPT_1", EnemyType::VOL_OPT_1},
|
{"VOL_OPT_1", EnemyType::VOL_OPT_1},
|
||||||
{"VOL_OPT_2", EnemyType::VOL_OPT_2},
|
{"VOL_OPT_2", EnemyType::VOL_OPT_2},
|
||||||
|
{"VOL_OPT_AMP", EnemyType::VOL_OPT_AMP},
|
||||||
|
{"VOL_OPT_CORE", EnemyType::VOL_OPT_CORE},
|
||||||
|
{"VOL_OPT_MONITOR", EnemyType::VOL_OPT_MONITOR},
|
||||||
|
{"VOL_OPT_PILLAR", EnemyType::VOL_OPT_PILLAR},
|
||||||
{"YOWIE", EnemyType::YOWIE},
|
{"YOWIE", EnemyType::YOWIE},
|
||||||
{"YOWIE_ALT", EnemyType::YOWIE_ALT},
|
{"YOWIE_ALT", EnemyType::YOWIE_ALT},
|
||||||
{"ZE_BOOTA", EnemyType::ZE_BOOTA},
|
{"ZE_BOOTA", EnemyType::ZE_BOOTA},
|
||||||
@@ -399,8 +429,6 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
return 0x0E;
|
return 0x0E;
|
||||||
case EnemyType::DE_ROL_LE:
|
case EnemyType::DE_ROL_LE:
|
||||||
return 0x0F;
|
return 0x0F;
|
||||||
case EnemyType::DEATH_GUNNER:
|
|
||||||
throw runtime_error("DEATH_GUNNER entry is not specified");
|
|
||||||
case EnemyType::DRAGON:
|
case EnemyType::DRAGON:
|
||||||
return 0x12;
|
return 0x12;
|
||||||
case EnemyType::SINOW_GOLD:
|
case EnemyType::SINOW_GOLD:
|
||||||
@@ -413,8 +441,6 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
return 0x1A;
|
return 0x1A;
|
||||||
case EnemyType::DUBCHIC:
|
case EnemyType::DUBCHIC:
|
||||||
return 0x1B;
|
return 0x1B;
|
||||||
case EnemyType::DUBWITCH:
|
|
||||||
throw runtime_error("no battle params for DUBWITCH");
|
|
||||||
case EnemyType::GILLCHIC:
|
case EnemyType::GILLCHIC:
|
||||||
return 0x1C;
|
return 0x1C;
|
||||||
case EnemyType::GARANZ:
|
case EnemyType::GARANZ:
|
||||||
@@ -425,8 +451,6 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
return 0x1F;
|
return 0x1F;
|
||||||
case EnemyType::CLAW:
|
case EnemyType::CLAW:
|
||||||
return 0x20;
|
return 0x20;
|
||||||
case EnemyType::VOL_OPT_1:
|
|
||||||
throw runtime_error("no battle params for VOL_OPT_1");
|
|
||||||
case EnemyType::VOL_OPT_2:
|
case EnemyType::VOL_OPT_2:
|
||||||
return 0x25;
|
return 0x25;
|
||||||
case EnemyType::POUILLY_SLIME:
|
case EnemyType::POUILLY_SLIME:
|
||||||
@@ -476,7 +500,7 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
case EnemyType::SO_DIMENIAN:
|
case EnemyType::SO_DIMENIAN:
|
||||||
return 0x55;
|
return 0x55;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("incorrect enemy type for Episode 1");
|
throw runtime_error(string_printf("%s does not have battle parameters in Episode 1", name_for_enum(enemy_type)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Episode::EP2:
|
case Episode::EP2:
|
||||||
@@ -520,8 +544,6 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
return 0x1A;
|
return 0x1A;
|
||||||
case EnemyType::DUBCHIC:
|
case EnemyType::DUBCHIC:
|
||||||
return 0x1B;
|
return 0x1B;
|
||||||
case EnemyType::DUBWITCH:
|
|
||||||
throw runtime_error("no battle params for DUBWITCH");
|
|
||||||
case EnemyType::GILLCHIC:
|
case EnemyType::GILLCHIC:
|
||||||
return 0x1C;
|
return 0x1C;
|
||||||
case EnemyType::GARANZ:
|
case EnemyType::GARANZ:
|
||||||
@@ -593,7 +615,7 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
case EnemyType::SO_DIMENIAN:
|
case EnemyType::SO_DIMENIAN:
|
||||||
return 0x55;
|
return 0x55;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("incorrect enemy type for Episode 2");
|
throw runtime_error(string_printf("%s does not have battle parameters in Episode 2", name_for_enum(enemy_type)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Episode::EP4:
|
case Episode::EP4:
|
||||||
@@ -651,7 +673,7 @@ uint8_t battle_param_index_for_enemy_type(Episode episode, EnemyType enemy_type)
|
|||||||
case EnemyType::KONDRIEU:
|
case EnemyType::KONDRIEU:
|
||||||
return 0x22;
|
return 0x22;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("incorrect enemy type for Episode 4");
|
throw runtime_error(string_printf("%s does not have battle parameters in Episode 4", name_for_enum(enemy_type)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -691,21 +713,14 @@ uint8_t rare_table_index_for_enemy_type(EnemyType enemy_type) {
|
|||||||
return 0x26;
|
return 0x26;
|
||||||
case EnemyType::DARK_BELRA:
|
case EnemyType::DARK_BELRA:
|
||||||
return 0x25;
|
return 0x25;
|
||||||
case EnemyType::DARK_FALZ_1:
|
|
||||||
throw runtime_error("DARK_FALZ_1 does not have a rare table entry");
|
|
||||||
case EnemyType::DARK_FALZ_2:
|
case EnemyType::DARK_FALZ_2:
|
||||||
return 0x2F;
|
return 0x2F;
|
||||||
case EnemyType::DARK_FALZ_3:
|
case EnemyType::DARK_FALZ_3:
|
||||||
return 0x2F;
|
return 0x2F;
|
||||||
case EnemyType::DARK_GUNNER:
|
case EnemyType::DARK_GUNNER:
|
||||||
return 0x22;
|
return 0x22;
|
||||||
case EnemyType::DARVANT:
|
|
||||||
case EnemyType::DARVANT_ULTIMATE:
|
|
||||||
throw runtime_error("DARVANT and DARVANT_ULTIMATE do not have rare table entries");
|
|
||||||
case EnemyType::DE_ROL_LE:
|
case EnemyType::DE_ROL_LE:
|
||||||
return 0x2D;
|
return 0x2D;
|
||||||
case EnemyType::DEATH_GUNNER:
|
|
||||||
throw runtime_error("DEATH_GUNNER does not have a rare table entry");
|
|
||||||
case EnemyType::DEL_LILY:
|
case EnemyType::DEL_LILY:
|
||||||
return 0x53;
|
return 0x53;
|
||||||
case EnemyType::DEL_RAPPY:
|
case EnemyType::DEL_RAPPY:
|
||||||
@@ -731,16 +746,12 @@ uint8_t rare_table_index_for_enemy_type(EnemyType enemy_type) {
|
|||||||
return 0x2C;
|
return 0x2C;
|
||||||
case EnemyType::DUBCHIC:
|
case EnemyType::DUBCHIC:
|
||||||
return 0x18;
|
return 0x18;
|
||||||
case EnemyType::DUBWITCH:
|
|
||||||
throw runtime_error("DUBWITCH does not have a rare table entry");
|
|
||||||
case EnemyType::EGG_RAPPY:
|
case EnemyType::EGG_RAPPY:
|
||||||
return 0x51;
|
return 0x51;
|
||||||
case EnemyType::EPSILON:
|
case EnemyType::EPSILON:
|
||||||
return 0x54;
|
return 0x54;
|
||||||
case EnemyType::EVIL_SHARK:
|
case EnemyType::EVIL_SHARK:
|
||||||
return 0x10;
|
return 0x10;
|
||||||
case EnemyType::GAEL:
|
|
||||||
throw runtime_error("GAEL does not have a rare table entry");
|
|
||||||
case EnemyType::GAL_GRYPHON:
|
case EnemyType::GAL_GRYPHON:
|
||||||
return 0x4D;
|
return 0x4D;
|
||||||
case EnemyType::GARANZ:
|
case EnemyType::GARANZ:
|
||||||
@@ -811,8 +822,6 @@ uint8_t rare_table_index_for_enemy_type(EnemyType enemy_type) {
|
|||||||
return 0x0F;
|
return 0x0F;
|
||||||
case EnemyType::NAR_LILY:
|
case EnemyType::NAR_LILY:
|
||||||
return 0x0E;
|
return 0x0E;
|
||||||
case EnemyType::OLGA_FLOW_1:
|
|
||||||
throw runtime_error("OLGA_FLOW_1 does not have a rare table entry");
|
|
||||||
case EnemyType::OLGA_FLOW_2:
|
case EnemyType::OLGA_FLOW_2:
|
||||||
return 0x4E;
|
return 0x4E;
|
||||||
case EnemyType::PAL_SHARK:
|
case EnemyType::PAL_SHARK:
|
||||||
@@ -866,8 +875,6 @@ uint8_t rare_table_index_for_enemy_type(EnemyType enemy_type) {
|
|||||||
return 0x2B;
|
return 0x2B;
|
||||||
case EnemyType::UL_GIBBON:
|
case EnemyType::UL_GIBBON:
|
||||||
return 0x3B;
|
return 0x3B;
|
||||||
case EnemyType::VOL_OPT_1:
|
|
||||||
throw runtime_error("VOL_OPT_1 does not have a rare table entry");
|
|
||||||
case EnemyType::VOL_OPT_2:
|
case EnemyType::VOL_OPT_2:
|
||||||
return 0x2E;
|
return 0x2E;
|
||||||
case EnemyType::YOWIE:
|
case EnemyType::YOWIE:
|
||||||
@@ -881,6 +888,6 @@ uint8_t rare_table_index_for_enemy_type(EnemyType enemy_type) {
|
|||||||
case EnemyType::ZU_ALT:
|
case EnemyType::ZU_ALT:
|
||||||
return 0x08;
|
return 0x08;
|
||||||
default:
|
default:
|
||||||
throw logic_error("invalid enemy type");
|
throw runtime_error(string_printf("%s does not have a rare table entry", name_for_enum(enemy_type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ enum class EnemyType {
|
|||||||
BA_BOOTA,
|
BA_BOOTA,
|
||||||
BARBA_RAY,
|
BARBA_RAY,
|
||||||
BARBAROUS_WOLF,
|
BARBAROUS_WOLF,
|
||||||
|
BEE_L,
|
||||||
|
BEE_R,
|
||||||
BOOMA,
|
BOOMA,
|
||||||
BOOTA,
|
BOOTA,
|
||||||
BULCLAW,
|
BULCLAW,
|
||||||
@@ -31,6 +33,8 @@ enum class EnemyType {
|
|||||||
DARVANT,
|
DARVANT,
|
||||||
DARVANT_ULTIMATE,
|
DARVANT_ULTIMATE,
|
||||||
DE_ROL_LE,
|
DE_ROL_LE,
|
||||||
|
DE_ROL_LE_BODY,
|
||||||
|
DE_ROL_LE_MINE,
|
||||||
DEATH_GUNNER,
|
DEATH_GUNNER,
|
||||||
DEL_LILY,
|
DEL_LILY,
|
||||||
DEL_RAPPY,
|
DEL_RAPPY,
|
||||||
@@ -47,6 +51,7 @@ enum class EnemyType {
|
|||||||
DUBCHIC,
|
DUBCHIC,
|
||||||
DUBWITCH, // Has no entry in battle params
|
DUBWITCH, // Has no entry in battle params
|
||||||
EGG_RAPPY,
|
EGG_RAPPY,
|
||||||
|
EPSIGUARD,
|
||||||
EPSILON,
|
EPSILON,
|
||||||
EVIL_SHARK,
|
EVIL_SHARK,
|
||||||
GAEL,
|
GAEL,
|
||||||
@@ -91,6 +96,7 @@ enum class EnemyType {
|
|||||||
PAN_ARMS,
|
PAN_ARMS,
|
||||||
PAZUZU,
|
PAZUZU,
|
||||||
PAZUZU_ALT,
|
PAZUZU_ALT,
|
||||||
|
PIG_RAY,
|
||||||
POFUILLY_SLIME,
|
POFUILLY_SLIME,
|
||||||
POUILLY_SLIME,
|
POUILLY_SLIME,
|
||||||
POISON_LILY,
|
POISON_LILY,
|
||||||
@@ -116,6 +122,10 @@ enum class EnemyType {
|
|||||||
UL_GIBBON,
|
UL_GIBBON,
|
||||||
VOL_OPT_1,
|
VOL_OPT_1,
|
||||||
VOL_OPT_2,
|
VOL_OPT_2,
|
||||||
|
VOL_OPT_AMP,
|
||||||
|
VOL_OPT_CORE,
|
||||||
|
VOL_OPT_MONITOR,
|
||||||
|
VOL_OPT_PILLAR,
|
||||||
YOWIE,
|
YOWIE,
|
||||||
YOWIE_ALT,
|
YOWIE_ALT,
|
||||||
ZE_BOOTA,
|
ZE_BOOTA,
|
||||||
|
|||||||
+4
-4
@@ -235,11 +235,11 @@ ItemData ItemCreator::check_rare_specs_and_create_rare_box_item(
|
|||||||
for (const auto& spec : rare_specs) {
|
for (const auto& spec : rare_specs) {
|
||||||
item = this->check_rate_and_create_rare_item(spec);
|
item = this->check_rate_and_create_rare_item(spec);
|
||||||
if (!item.empty()) {
|
if (!item.empty()) {
|
||||||
this->log.info("Box spec %08" PRIX32 " => %02hhX%02hhX%02hhX produced an item",
|
this->log.info("Box spec %08" PRIX32 " produced item %02hhX%02hhX%02hhX",
|
||||||
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->log.info("Box spec %08" PRIX32 " => %02hhX%02hhX%02hhX did not produce",
|
this->log.info("Box spec %08" PRIX32 " did not produce item %02hhX%02hhX%02hhX",
|
||||||
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@@ -289,11 +289,11 @@ ItemData ItemCreator::check_rare_spec_and_create_rare_enemy_item(
|
|||||||
for (const auto& spec : rare_specs) {
|
for (const auto& spec : rare_specs) {
|
||||||
item = this->check_rate_and_create_rare_item(spec);
|
item = this->check_rate_and_create_rare_item(spec);
|
||||||
if (!item.empty()) {
|
if (!item.empty()) {
|
||||||
this->log.info("Enemy spec %08" PRIX32 " => %02hhX%02hhX%02hhX did not produce",
|
this->log.info("Enemy spec %08" PRIX32 " produced item %02hhX%02hhX%02hhX",
|
||||||
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->log.info("Enemy spec %08" PRIX32 " => %02hhX%02hhX%02hhX did not produce",
|
this->log.info("Enemy spec %08" PRIX32 " did not produce item %02hhX%02hhX%02hhX",
|
||||||
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
spec.probability, spec.item_code[0], spec.item_code[1], spec.item_code[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+100
-66
@@ -9,25 +9,23 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
uint64_t Map::Enemy::next_enemy_id = 1;
|
|
||||||
|
|
||||||
Map::Enemy::Enemy(EnemyType type)
|
Map::Enemy::Enemy(EnemyType type)
|
||||||
: id(Map::Enemy::next_enemy_id++),
|
: type(type),
|
||||||
type(type),
|
|
||||||
flags(0),
|
flags(0),
|
||||||
last_hit_by_client_id(0) {}
|
last_hit_by_client_id(0) {}
|
||||||
|
|
||||||
string Map::Enemy::str() const {
|
string Map::Enemy::str() const {
|
||||||
return string_printf("[Map::Enemy E-%" PRIX64 " type=%s flags=%02hhX last_hit_by_client_id=%hu]",
|
return string_printf("[Map::Enemy %s flags=%02hhX last_hit_by_client_id=%hu]",
|
||||||
this->id, name_for_enum(this->type), this->flags, this->last_hit_by_client_id);
|
name_for_enum(this->type), this->flags, this->last_hit_by_client_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EnemyEntry {
|
struct EnemyEntry {
|
||||||
/* 00 */ le_uint32_t base;
|
/* 00 */ le_uint16_t base_type;
|
||||||
/* 04 */ le_uint16_t unknown_a1;
|
/* 02 */ le_uint16_t unknown_a0; // Overwritten by client at load time
|
||||||
|
/* 04 */ le_uint16_t enemy_index; // Overwritten by client at load time
|
||||||
/* 06 */ le_uint16_t num_clones;
|
/* 06 */ le_uint16_t num_clones;
|
||||||
/* 08 */ le_uint16_t area;
|
/* 08 */ le_uint16_t area;
|
||||||
/* 0A */ le_uint16_t unknown_a2;
|
/* 0A */ le_uint16_t entity_id; // == enemy_index + 0x1000
|
||||||
/* 0C */ le_uint16_t section;
|
/* 0C */ le_uint16_t section;
|
||||||
/* 0E */ le_uint16_t wave_number;
|
/* 0E */ le_uint16_t wave_number;
|
||||||
/* 10 */ le_uint32_t wave_number2;
|
/* 10 */ le_uint32_t wave_number2;
|
||||||
@@ -47,9 +45,9 @@ struct EnemyEntry {
|
|||||||
/* 48 */
|
/* 48 */
|
||||||
|
|
||||||
string str() const {
|
string str() const {
|
||||||
return string_printf("EnemyEntry(base=%" PRIX32 ", a1=%hX, num_clones=%hX, area=%hX, a2=%hX, section=%hX, wave_number=%hX, wave_number2=%" PRIX32 ", x=%g, y=%g, z=%g, x_angle=%" PRIX32 ", y_angle=%" PRIX32 ", z_angle=%" PRIX32 ", a3=%" PRIX32 ", a4=%" PRIX32 ", a5=%" PRIX32 ", a6=%" PRIX32 ", a7=%" PRIX32 ", skin=%" PRIX32 ", a8=%" PRIX32 ")",
|
return string_printf("EnemyEntry(base_type=%hX, a0=%hX, enemy_index=%hX, num_clones=%hX, area=%hX, entity_id=%hX, section=%hX, wave_number=%hX, wave_number2=%" PRIX32 ", x=%g, y=%g, z=%g, x_angle=%" PRIX32 ", y_angle=%" PRIX32 ", z_angle=%" PRIX32 ", a3=%" PRIX32 ", a4=%" PRIX32 ", a5=%" PRIX32 ", a6=%" PRIX32 ", a7=%" PRIX32 ", skin=%" PRIX32 ", a8=%" PRIX32 ")",
|
||||||
this->base.load(), this->unknown_a1.load(), this->num_clones.load(), this->area.load(),
|
this->base_type.load(), this->unknown_a0.load(), this->enemy_index.load(), this->num_clones.load(), this->area.load(),
|
||||||
this->unknown_a2.load(), this->section.load(), this->wave_number.load(),
|
this->entity_id.load(), this->section.load(), this->wave_number.load(),
|
||||||
this->wave_number2.load(), this->x.load(), this->y.load(), this->z.load(), this->x_angle.load(),
|
this->wave_number2.load(), this->x.load(), this->y.load(), this->z.load(), this->x_angle.load(),
|
||||||
this->y_angle.load(), this->z_angle.load(), this->unknown_a3.load(), this->unknown_a4.load(),
|
this->y_angle.load(), this->z_angle.load(), this->unknown_a3.load(), this->unknown_a4.load(),
|
||||||
this->unknown_a5.load(), this->unknown_a6.load(), this->unknown_a7.load(), this->skin.load(),
|
this->unknown_a5.load(), this->unknown_a6.load(), this->unknown_a7.load(), this->skin.load(),
|
||||||
@@ -58,7 +56,7 @@ struct EnemyEntry {
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct ObjectEntry {
|
struct ObjectEntry {
|
||||||
/* 00 */ le_uint16_t type;
|
/* 00 */ le_uint16_t base_type;
|
||||||
/* 02 */ le_uint16_t unknown_a1;
|
/* 02 */ le_uint16_t unknown_a1;
|
||||||
/* 04 */ le_uint32_t unknown_a2;
|
/* 04 */ le_uint32_t unknown_a2;
|
||||||
/* 08 */ le_uint16_t id;
|
/* 08 */ le_uint16_t id;
|
||||||
@@ -81,8 +79,8 @@ struct ObjectEntry {
|
|||||||
/* 44 */
|
/* 44 */
|
||||||
|
|
||||||
string str() const {
|
string str() const {
|
||||||
return string_printf("ObjectEntry(type=%hX, a1=%hX, a2=%" PRIX32 ", id=%hX, group=%hX, section=%hX, a3=%hX, x=%g, y=%g, z=%g, x_angle=%" PRIX32 ", y_angle=%" PRIX32 ", z_angle=%" PRIX32 ", a3=%" PRIX32 ", a4=%" PRIX32 ", a5=%" PRIX32 ", a6=%" PRIX32 ", a7=%" PRIX32 ", a8=%" PRIX32 ", a9=%" PRIX32 ")",
|
return string_printf("ObjectEntry(base_type=%hX, a1=%hX, a2=%" PRIX32 ", id=%hX, group=%hX, section=%hX, a3=%hX, x=%g, y=%g, z=%g, x_angle=%" PRIX32 ", y_angle=%" PRIX32 ", z_angle=%" PRIX32 ", a3=%" PRIX32 ", a4=%" PRIX32 ", a5=%" PRIX32 ", a6=%" PRIX32 ", a7=%" PRIX32 ", a8=%" PRIX32 ", a9=%" PRIX32 ")",
|
||||||
this->type.load(), this->unknown_a1.load(), this->unknown_a2.load(), this->id.load(), this->group.load(),
|
this->base_type.load(), this->unknown_a1.load(), this->unknown_a2.load(), this->id.load(), this->group.load(),
|
||||||
this->section.load(), this->unknown_a3.load(), this->x.load(), this->y.load(), this->z.load(), this->x_angle.load(),
|
this->section.load(), this->unknown_a3.load(), this->x.load(), this->y.load(), this->z.load(), this->x_angle.load(),
|
||||||
this->y_angle.load(), this->z_angle.load(), this->unknown_a3.load(), this->unknown_a4.load(),
|
this->y_angle.load(), this->z_angle.load(), this->unknown_a3.load(), this->unknown_a4.load(),
|
||||||
this->unknown_a5.load(), this->unknown_a6.load(), this->unknown_a7.load(), this->unknown_a8.load(),
|
this->unknown_a5.load(), this->unknown_a6.load(), this->unknown_a7.load(), this->unknown_a8.load(),
|
||||||
@@ -103,16 +101,13 @@ void Map::add_enemies_from_map_data(
|
|||||||
throw runtime_error("data size is not a multiple of entry size");
|
throw runtime_error("data size is not a multiple of entry size");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto create_clones = [&](size_t count) {
|
|
||||||
for (; count > 0; count--) {
|
|
||||||
this->enemies.emplace_back(EnemyType::NONE);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (size_t y = 0; y < entry_count; y++) {
|
for (size_t y = 0; y < entry_count; y++) {
|
||||||
const auto& e = map[y];
|
const auto& e = map[y];
|
||||||
|
|
||||||
switch (e.base) {
|
string hex = format_data_string(&e, sizeof(e));
|
||||||
|
fprintf(stderr, "[%04zX] %s\n", y, hex.c_str());
|
||||||
|
|
||||||
|
switch (e.base_type) {
|
||||||
case 0x40:
|
case 0x40:
|
||||||
enemies.emplace_back((e.skin & 0x01) ? EnemyType::HILDEBLUE : EnemyType::HILDEBEAR);
|
enemies.emplace_back((e.skin & 0x01) ? EnemyType::HILDEBLUE : EnemyType::HILDEBEAR);
|
||||||
break;
|
break;
|
||||||
@@ -123,18 +118,22 @@ void Map::add_enemies_from_map_data(
|
|||||||
enemies.emplace_back(is_rare ? EnemyType::AL_RAPPY : EnemyType::RAG_RAPPY);
|
enemies.emplace_back(is_rare ? EnemyType::AL_RAPPY : EnemyType::RAG_RAPPY);
|
||||||
break;
|
break;
|
||||||
case Episode::EP2:
|
case Episode::EP2:
|
||||||
switch (event) {
|
if (is_rare) {
|
||||||
case 0x01:
|
switch (event) {
|
||||||
enemies.emplace_back(EnemyType::SAINT_RAPPY);
|
case 0x01:
|
||||||
break;
|
enemies.emplace_back(EnemyType::SAINT_RAPPY);
|
||||||
case 0x04:
|
break;
|
||||||
enemies.emplace_back(EnemyType::EGG_RAPPY);
|
case 0x04:
|
||||||
break;
|
enemies.emplace_back(EnemyType::EGG_RAPPY);
|
||||||
case 0x05:
|
break;
|
||||||
enemies.emplace_back(EnemyType::HALLO_RAPPY);
|
case 0x05:
|
||||||
break;
|
enemies.emplace_back(EnemyType::HALLO_RAPPY);
|
||||||
default:
|
break;
|
||||||
enemies.emplace_back(EnemyType::LOVE_RAPPY);
|
default:
|
||||||
|
enemies.emplace_back(EnemyType::LOVE_RAPPY);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enemies.emplace_back(EnemyType::RAG_RAPPY);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Episode::EP4:
|
case Episode::EP4:
|
||||||
@@ -149,14 +148,15 @@ void Map::add_enemies_from_map_data(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x42:
|
case 0x42: {
|
||||||
enemies.emplace_back(EnemyType::MONEST);
|
enemies.emplace_back(EnemyType::MONEST);
|
||||||
for (size_t x = 0; x < e.num_clones; x++) {
|
for (size_t x = 0; x < 30; x++) {
|
||||||
enemies.emplace_back((x < 30) ? EnemyType::MOTHMANT : EnemyType::UNKNOWN);
|
enemies.emplace_back(EnemyType::MOTHMANT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0x43: {
|
case 0x43: {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::BARBAROUS_WOLF : EnemyType::SAVAGE_WOLF);
|
enemies.emplace_back(e.unknown_a4 ? EnemyType::BARBAROUS_WOLF : EnemyType::SAVAGE_WOLF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x44:
|
case 0x44:
|
||||||
@@ -170,7 +170,7 @@ void Map::add_enemies_from_map_data(
|
|||||||
if ((episode == Episode::EP2) && (e.area > 0x0F)) {
|
if ((episode == Episode::EP2) && (e.area > 0x0F)) {
|
||||||
enemies.emplace_back(EnemyType::DEL_LILY);
|
enemies.emplace_back(EnemyType::DEL_LILY);
|
||||||
} else {
|
} else {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::NAR_LILY : EnemyType::POISON_LILY);
|
enemies.emplace_back((e.skin & 1) ? EnemyType::NAR_LILY : EnemyType::POISON_LILY);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x62:
|
case 0x62:
|
||||||
@@ -182,9 +182,9 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x64: {
|
case 0x64: {
|
||||||
bool is_common = ((e.unknown_a4 & 0x800000) ? true : false);
|
bool is_rare = (e.skin & 1);
|
||||||
for (size_t x = 0; x < 5; x++) { // Main slime + 4 clones
|
for (size_t x = 0; x < 5; x++) { // Main slime + 4 clones
|
||||||
enemies.emplace_back(is_common ? EnemyType::POFUILLY_SLIME : EnemyType::POUILLY_SLIME);
|
enemies.emplace_back(is_rare ? EnemyType::POFUILLY_SLIME : EnemyType::POUILLY_SLIME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -199,19 +199,21 @@ void Map::add_enemies_from_map_data(
|
|||||||
case 0x81:
|
case 0x81:
|
||||||
enemies.emplace_back(EnemyType::GARANZ);
|
enemies.emplace_back(EnemyType::GARANZ);
|
||||||
break;
|
break;
|
||||||
case 0x82:
|
case 0x82: {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::SINOW_GOLD : EnemyType::SINOW_BEAT);
|
EnemyType type = e.unknown_a4 ? EnemyType::SINOW_GOLD : EnemyType::SINOW_BEAT;
|
||||||
if (e.num_clones == 0) {
|
size_t count = (e.num_clones == 0) ? 5 : (e.num_clones + 1);
|
||||||
create_clones(4);
|
for (size_t z = 0; z < count; z++) {
|
||||||
|
enemies.emplace_back(type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0x83:
|
case 0x83:
|
||||||
enemies.emplace_back(EnemyType::CANADINE);
|
enemies.emplace_back(EnemyType::CANADINE);
|
||||||
break;
|
break;
|
||||||
case 0x84:
|
case 0x84:
|
||||||
enemies.emplace_back(EnemyType::CANANE);
|
enemies.emplace_back(EnemyType::CANANE);
|
||||||
for (size_t x = 0; x < 8; x++) {
|
for (size_t x = 0; x < 8; x++) {
|
||||||
enemies.emplace_back(EnemyType::CANADINE);
|
enemies.emplace_back(EnemyType::CANADINE_GROUP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x85:
|
case 0x85:
|
||||||
@@ -222,7 +224,8 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
case 0xA1:
|
case 0xA1:
|
||||||
enemies.emplace_back(EnemyType::CHAOS_SORCERER);
|
enemies.emplace_back(EnemyType::CHAOS_SORCERER);
|
||||||
create_clones(2);
|
enemies.emplace_back(EnemyType::BEE_R);
|
||||||
|
enemies.emplace_back(EnemyType::BEE_L);
|
||||||
break;
|
break;
|
||||||
case 0xA2:
|
case 0xA2:
|
||||||
enemies.emplace_back(EnemyType::DARK_GUNNER);
|
enemies.emplace_back(EnemyType::DARK_GUNNER);
|
||||||
@@ -261,9 +264,27 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
case 0xC1:
|
case 0xC1:
|
||||||
enemies.emplace_back(EnemyType::DE_ROL_LE);
|
enemies.emplace_back(EnemyType::DE_ROL_LE);
|
||||||
|
for (size_t z = 0; z < 0x0A; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::DE_ROL_LE_BODY);
|
||||||
|
}
|
||||||
|
for (size_t z = 0; z < 0x09; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::DE_ROL_LE_MINE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xC2:
|
case 0xC2:
|
||||||
enemies.emplace_back(EnemyType::VOL_OPT_1);
|
enemies.emplace_back(EnemyType::VOL_OPT_1);
|
||||||
|
for (size_t z = 0; z < 6; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::VOL_OPT_PILLAR);
|
||||||
|
}
|
||||||
|
for (size_t z = 0; z < 24; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::VOL_OPT_MONITOR);
|
||||||
|
}
|
||||||
|
for (size_t z = 0; z < 2; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::NONE);
|
||||||
|
}
|
||||||
|
enemies.emplace_back(EnemyType::VOL_OPT_AMP);
|
||||||
|
enemies.emplace_back(EnemyType::VOL_OPT_CORE);
|
||||||
|
enemies.emplace_back(EnemyType::NONE);
|
||||||
break;
|
break;
|
||||||
case 0xC5:
|
case 0xC5:
|
||||||
enemies.emplace_back(EnemyType::VOL_OPT_2);
|
enemies.emplace_back(EnemyType::VOL_OPT_2);
|
||||||
@@ -274,26 +295,36 @@ void Map::add_enemies_from_map_data(
|
|||||||
} else {
|
} else {
|
||||||
enemies.emplace_back(EnemyType::DARK_FALZ_2);
|
enemies.emplace_back(EnemyType::DARK_FALZ_2);
|
||||||
}
|
}
|
||||||
for (size_t x = 0; x < 510; x++) {
|
for (size_t x = 0; x < 0x1FD; x++) {
|
||||||
enemies.emplace_back(difficulty == 3 ? EnemyType::DARVANT_ULTIMATE : EnemyType::DARVANT);
|
enemies.emplace_back(difficulty == 3 ? EnemyType::DARVANT_ULTIMATE : EnemyType::DARVANT);
|
||||||
}
|
}
|
||||||
|
enemies.emplace_back(EnemyType::DARK_FALZ_3);
|
||||||
|
enemies.emplace_back(EnemyType::DARK_FALZ_2);
|
||||||
|
enemies.emplace_back(EnemyType::DARK_FALZ_1);
|
||||||
break;
|
break;
|
||||||
case 0xCA:
|
case 0xCA:
|
||||||
enemies.emplace_back(EnemyType::OLGA_FLOW_2);
|
for (size_t z = 0; z < 0x201; z++) {
|
||||||
create_clones(0x200);
|
enemies.emplace_back(EnemyType::OLGA_FLOW_2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xCB:
|
case 0xCB:
|
||||||
enemies.emplace_back(EnemyType::BARBA_RAY);
|
enemies.emplace_back(EnemyType::BARBA_RAY);
|
||||||
create_clones(0x2F);
|
for (size_t z = 0; z < 0x2F; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::PIG_RAY);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xCC:
|
case 0xCC:
|
||||||
enemies.emplace_back(EnemyType::GOL_DRAGON);
|
for (size_t z = 0; z < 6; z++) {
|
||||||
create_clones(5);
|
enemies.emplace_back(EnemyType::GOL_DRAGON);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0xD4:
|
case 0xD4: {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::SINOW_SPIGELL : EnemyType::SINOW_BERILL);
|
EnemyType type = (e.skin & 1) ? EnemyType::SINOW_SPIGELL : EnemyType::SINOW_BERILL;
|
||||||
create_clones(4);
|
for (size_t z = 0; z < 5; z++) {
|
||||||
|
enemies.emplace_back(type);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0xD5:
|
case 0xD5:
|
||||||
enemies.emplace_back((e.skin & 0x01) ? EnemyType::MERILTAS : EnemyType::MERILLIA);
|
enemies.emplace_back((e.skin & 0x01) ? EnemyType::MERILTAS : EnemyType::MERILLIA);
|
||||||
break;
|
break;
|
||||||
@@ -337,7 +368,9 @@ void Map::add_enemies_from_map_data(
|
|||||||
case 0xE0:
|
case 0xE0:
|
||||||
if ((episode == Episode::EP2) && (e.area > 0x0F)) {
|
if ((episode == Episode::EP2) && (e.area > 0x0F)) {
|
||||||
enemies.emplace_back(EnemyType::EPSILON);
|
enemies.emplace_back(EnemyType::EPSILON);
|
||||||
create_clones(4);
|
for (size_t z = 0; z < 4; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::EPSIGUARD);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
enemies.emplace_back((e.skin & 0x01) ? EnemyType::SINOW_ZELE : EnemyType::SINOW_ZOA);
|
enemies.emplace_back((e.skin & 0x01) ? EnemyType::SINOW_ZELE : EnemyType::SINOW_ZOA);
|
||||||
}
|
}
|
||||||
@@ -350,9 +383,9 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
case 0x0111:
|
case 0x0111:
|
||||||
if (e.area > 0x05) {
|
if (e.area > 0x05) {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::YOWIE_ALT : EnemyType::SATELLITE_LIZARD_ALT);
|
enemies.emplace_back(e.unknown_a4 ? EnemyType::YOWIE_ALT : EnemyType::SATELLITE_LIZARD_ALT);
|
||||||
} else {
|
} else {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::YOWIE : EnemyType::SATELLITE_LIZARD);
|
enemies.emplace_back(e.unknown_a4 ? EnemyType::YOWIE : EnemyType::SATELLITE_LIZARD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0112:
|
case 0x0112:
|
||||||
@@ -363,9 +396,9 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
case 0x0114:
|
case 0x0114:
|
||||||
if (e.area > 0x05) {
|
if (e.area > 0x05) {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::PAZUZU_ALT : EnemyType::ZU_ALT);
|
enemies.emplace_back((e.skin & 1) ? EnemyType::PAZUZU_ALT : EnemyType::ZU_ALT);
|
||||||
} else {
|
} else {
|
||||||
enemies.emplace_back((e.unknown_a4 & 0x800000) ? EnemyType::PAZUZU : EnemyType::ZU);
|
enemies.emplace_back((e.skin & 1) ? EnemyType::PAZUZU : EnemyType::ZU);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0115:
|
case 0x0115:
|
||||||
@@ -384,20 +417,21 @@ void Map::add_enemies_from_map_data(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x0119: // Saint-Million, Shambertin, Kondrieu
|
case 0x0119: // Saint-Million, Shambertin, Kondrieu
|
||||||
if (e.unknown_a4 & 0x800000) {
|
if (e.unknown_a4) {
|
||||||
enemies.emplace_back(EnemyType::KONDRIEU);
|
enemies.emplace_back(EnemyType::KONDRIEU);
|
||||||
} else {
|
} else {
|
||||||
enemies.emplace_back((e.skin & 1) ? EnemyType::SHAMBERTIN : EnemyType::SAINT_MILLION);
|
enemies.emplace_back((e.skin & 1) ? EnemyType::SHAMBERTIN : EnemyType::SAINT_MILLION);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
enemies.emplace_back(EnemyType::UNKNOWN);
|
for (size_t z = 0; z < e.num_clones + 1; z++) {
|
||||||
|
enemies.emplace_back(EnemyType::UNKNOWN);
|
||||||
|
}
|
||||||
static_game_data_log.warning(
|
static_game_data_log.warning(
|
||||||
"(Entry %zu, offset %zX in file) Unknown enemy type %08" PRIX32 " %08" PRIX32,
|
"(Entry %zu, offset %zX in file) Unknown enemy type %04hX",
|
||||||
y, y * sizeof(EnemyEntry), e.base.load(), e.skin.load());
|
y, y * sizeof(EnemyEntry), e.base_type.load());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
create_clones(e.num_clones);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
struct Map {
|
struct Map {
|
||||||
struct Enemy {
|
struct Enemy {
|
||||||
static uint64_t next_enemy_id;
|
|
||||||
|
|
||||||
enum Flag {
|
enum Flag {
|
||||||
HIT_BY_PLAYER0 = 0x01,
|
HIT_BY_PLAYER0 = 0x01,
|
||||||
HIT_BY_PLAYER1 = 0x02,
|
HIT_BY_PLAYER1 = 0x02,
|
||||||
@@ -25,7 +23,6 @@ struct Map {
|
|||||||
DEFEATED = 0x10,
|
DEFEATED = 0x10,
|
||||||
ITEM_DROPPED = 0x20,
|
ITEM_DROPPED = 0x20,
|
||||||
};
|
};
|
||||||
uint64_t id;
|
|
||||||
EnemyType type;
|
EnemyType type;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t last_hit_by_client_id;
|
uint8_t last_hit_by_client_id;
|
||||||
|
|||||||
@@ -1237,10 +1237,10 @@ static void on_enemy_killed_bb(shared_ptr<ServerState> s,
|
|||||||
|
|
||||||
auto& e = l->map->enemies[cmd.enemy_id];
|
auto& e = l->map->enemies[cmd.enemy_id];
|
||||||
string e_str = e.str();
|
string e_str = e.str();
|
||||||
c->log.info("Enemy killed: entry %hu => %s", cmd.enemy_id.load(), e_str.c_str());
|
c->log.info("Enemy killed: E-%hX => %s", cmd.enemy_id.load(), e_str.c_str());
|
||||||
if (e.flags & Map::Enemy::Flag::DEFEATED) {
|
if (e.flags & Map::Enemy::Flag::DEFEATED) {
|
||||||
if (c->options.debug) {
|
if (c->options.debug) {
|
||||||
send_text_message_printf(c, "$C5E-%hX (already defeated)", cmd.enemy_id.load());
|
send_text_message_printf(c, "$C5E-%hX __DEFEATED__", cmd.enemy_id.load());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1250,7 +1250,7 @@ static void on_enemy_killed_bb(shared_ptr<ServerState> s,
|
|||||||
experience = s->battle_params->get(l->mode == GameMode::SOLO, l->episode, l->difficulty, e.type).experience;
|
experience = s->battle_params->get(l->mode == GameMode::SOLO, l->episode, l->difficulty, e.type).experience;
|
||||||
} catch (const exception& e) {
|
} catch (const exception& e) {
|
||||||
if (c->options.debug) {
|
if (c->options.debug) {
|
||||||
send_text_message_printf(c, "$C5E-%hX (missing definition)\n%s", cmd.enemy_id.load(), e.what());
|
send_text_message_printf(c, "$C5E-%hX __MISSING__\n%s", cmd.enemy_id.load(), e.what());
|
||||||
} else {
|
} else {
|
||||||
send_text_message_printf(c, "$C4Unknown enemy type killed:\n%s", e.what());
|
send_text_message_printf(c, "$C4Unknown enemy type killed:\n%s", e.what());
|
||||||
}
|
}
|
||||||
@@ -1279,7 +1279,7 @@ static void on_enemy_killed_bb(shared_ptr<ServerState> s,
|
|||||||
other_c->game_data.player()->disp.experience += player_exp;
|
other_c->game_data.player()->disp.experience += player_exp;
|
||||||
send_give_experience(l, other_c, player_exp);
|
send_give_experience(l, other_c, player_exp);
|
||||||
if (other_c->options.debug) {
|
if (other_c->options.debug) {
|
||||||
send_text_message_printf(other_c, "$C5+%" PRIu32 " E-%hX (%s)",
|
send_text_message_printf(other_c, "$C5+%" PRIu32 " E-%hX %s",
|
||||||
player_exp, cmd.enemy_id.load(), name_for_enum(e.type));
|
player_exp, cmd.enemy_id.load(), name_for_enum(e.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user