Give mission achievements at game start
This commit is contained in:
parent
e45324ad32
commit
8a56923a7d
@ -188,6 +188,127 @@ namespace achievements
|
|||||||
{
|
{
|
||||||
give_achievement(game::Scr_GetString(0));
|
give_achievement(game::Scr_GetString(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void give_mission_achievements()
|
||||||
|
{
|
||||||
|
game::GamerProfileData data{};
|
||||||
|
game::GamerProfile_GetDataByName(&data, 0, "missionhighestdifficulty", 0xFFFFFFFF);
|
||||||
|
|
||||||
|
if (data.type != game::TYPE_STRING)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
achievement_file_t file{};
|
||||||
|
achievements::get_achievements(&file);
|
||||||
|
|
||||||
|
const auto completed_mission = [&](const game::level_number level, const std::string& achievement)
|
||||||
|
{
|
||||||
|
const auto id = get_achievement_id(achievement);
|
||||||
|
if (!id.has_value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id_value = id.value();
|
||||||
|
const auto highest_difficulty = data.u.stringVal[level] - '0';
|
||||||
|
if (highest_difficulty)
|
||||||
|
{
|
||||||
|
file.achievements[id_value] = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<achievement_id, std::vector<game::level_number>> veteran_achievements;
|
||||||
|
|
||||||
|
const auto add_veteran_achievement = [&](const game::level_number level, const std::string& achievement)
|
||||||
|
{
|
||||||
|
const auto id = get_achievement_id(achievement);
|
||||||
|
if (!id.has_value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id_value = static_cast<achievement_id>(id.value());
|
||||||
|
veteran_achievements[id_value].push_back(level);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto give_veteran_achievements = [&]()
|
||||||
|
{
|
||||||
|
for (const auto& achievement : veteran_achievements)
|
||||||
|
{
|
||||||
|
auto has_veteran = true;
|
||||||
|
for (const auto& mission : achievement.second)
|
||||||
|
{
|
||||||
|
if (data.u.stringVal[mission] != '3')
|
||||||
|
{
|
||||||
|
has_veteran = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_veteran)
|
||||||
|
{
|
||||||
|
file.achievements[achievement.first] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto give_completed_campaign_achievement = [&](const std::string& achievement)
|
||||||
|
{
|
||||||
|
const auto id = get_achievement_id(achievement);
|
||||||
|
if (!id.has_value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto id_value = static_cast<achievement_id>(id.value());
|
||||||
|
for (auto i = 0; i < game::LEVEL_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (data.u.stringVal[i] - '0' < 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.achievements[id_value] = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
completed_mission(game::LEVEL_TRAINER, "BACK_IN_THE_SADDLE");
|
||||||
|
completed_mission(game::LEVEL_ROADKILL, "DANGER_CLOSE");
|
||||||
|
completed_mission(game::LEVEL_CLIFFHANGER, "COLD_SHOULDER");
|
||||||
|
completed_mission(game::LEVEL_FAVELA, "TAGEM_AND_BAGEM");
|
||||||
|
completed_mission(game::LEVEL_INVASION, "ROYAL_WITH_CHEESE");
|
||||||
|
completed_mission(game::LEVEL_GULAG, "SOAP_ON_A_ROPE");
|
||||||
|
completed_mission(game::LEVEL_CONTINGENCY, "DESPERATE_TIMES");
|
||||||
|
completed_mission(game::LEVEL_DC_WHITEHOUSE, "HOUSTON_WE_HAVE_A_PROBLEM");
|
||||||
|
completed_mission(game::LEVEL_ESTATE, "THE_PAWN");
|
||||||
|
completed_mission(game::LEVEL_BONEYARD, "OUT_OF_THE_FRYING_PAN");
|
||||||
|
completed_mission(game::LEVEL_ENDING, "FOR_THE_RECORD");
|
||||||
|
|
||||||
|
add_veteran_achievement(game::LEVEL_TRAINER, "FIRST_DAY_OF_SCHOOL");
|
||||||
|
add_veteran_achievement(game::LEVEL_ROADKILL, "FIRST_DAY_OF_SCHOOL");
|
||||||
|
add_veteran_achievement(game::LEVEL_CLIFFHANGER, "BLACK_DIAMOND");
|
||||||
|
add_veteran_achievement(game::LEVEL_FAVELA, "TURISTAS");
|
||||||
|
add_veteran_achievement(game::LEVEL_INVASION, "RED_DAWN");
|
||||||
|
add_veteran_achievement(game::LEVEL_FAVELA_ESCAPE, "TURISTAS");
|
||||||
|
add_veteran_achievement(game::LEVEL_ARCADIA, "RED_DAWN");
|
||||||
|
add_veteran_achievement(game::LEVEL_OILRIG, "PRISONER_627");
|
||||||
|
add_veteran_achievement(game::LEVEL_GULAG, "PRISONER_627");
|
||||||
|
add_veteran_achievement(game::LEVEL_DCBURNING, "HOME_COMING");
|
||||||
|
add_veteran_achievement(game::LEVEL_CONTINGENCY, "ENDS_JUSTIFY_THE_MEANS");
|
||||||
|
add_veteran_achievement(game::LEVEL_DCEMP, "HOME_COMING");
|
||||||
|
add_veteran_achievement(game::LEVEL_DC_WHITEHOUSE, "HOME_COMING");
|
||||||
|
add_veteran_achievement(game::LEVEL_ESTATE, "QUEEN_TAKES_ROOK");
|
||||||
|
add_veteran_achievement(game::LEVEL_BONEYARD, "QUEEN_TAKES_ROOK");
|
||||||
|
add_veteran_achievement(game::LEVEL_AF_CAVES, "OFF_THE_GRID");
|
||||||
|
add_veteran_achievement(game::LEVEL_AF_CHASE, "OFF_THE_GRID");
|
||||||
|
add_veteran_achievement(game::LEVEL_ENDING, "OFF_THE_GRID");
|
||||||
|
|
||||||
|
give_veteran_achievements();
|
||||||
|
give_completed_campaign_achievement("THE_PRICE_OF_WAR");
|
||||||
|
|
||||||
|
write_achievements(&file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_achievements(achievement_file_t* file)
|
void get_achievements(achievement_file_t* file)
|
||||||
@ -252,6 +373,8 @@ namespace achievements
|
|||||||
{
|
{
|
||||||
utils::hook::jump(0x1404B6240, scr_give_achievement_stub);
|
utils::hook::jump(0x1404B6240, scr_give_achievement_stub);
|
||||||
|
|
||||||
|
scheduler::once(give_mission_achievements, scheduler::main);
|
||||||
|
|
||||||
command::add("reset_achievements", []
|
command::add("reset_achievements", []
|
||||||
{
|
{
|
||||||
achievement_file_t file{};
|
achievement_file_t file{};
|
||||||
|
@ -1728,6 +1728,63 @@ namespace game
|
|||||||
|
|
||||||
static_assert(sizeof(physical_memory) == 0x530);
|
static_assert(sizeof(physical_memory) == 0x530);
|
||||||
|
|
||||||
|
union GamerProfileDataUnion
|
||||||
|
{
|
||||||
|
unsigned __int8 byteVal;
|
||||||
|
bool boolVal;
|
||||||
|
__int16 shortVal;
|
||||||
|
int intVal;
|
||||||
|
float floatVal;
|
||||||
|
const char* stringVal;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum level_number
|
||||||
|
{
|
||||||
|
LEVEL_TRAINER,
|
||||||
|
LEVEL_ROADKILL,
|
||||||
|
LEVEL_CLIFFHANGER,
|
||||||
|
LEVEL_AIRPORT,
|
||||||
|
LEVEL_FAVELA,
|
||||||
|
|
||||||
|
LEVEL_INVASION,
|
||||||
|
LEVEL_FAVELA_ESCAPE,
|
||||||
|
LEVEL_ARCADIA,
|
||||||
|
LEVEL_OILRIG,
|
||||||
|
LEVEL_GULAG,
|
||||||
|
LEVEL_DCBURNING,
|
||||||
|
|
||||||
|
LEVEL_CONTINGENCY,
|
||||||
|
LEVEL_DCEMP,
|
||||||
|
LEVEL_DC_WHITEHOUSE,
|
||||||
|
LEVEL_ESTATE,
|
||||||
|
LEVEL_BONEYARD,
|
||||||
|
LEVEL_AF_CAVES,
|
||||||
|
LEVEL_AF_CHASE,
|
||||||
|
|
||||||
|
LEVEL_ENDING,
|
||||||
|
|
||||||
|
LEVEL_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GamerProfileDataType : __int32
|
||||||
|
{
|
||||||
|
TYPE_INVALID = 0x0,
|
||||||
|
TYPE_BYTE = 0x1,
|
||||||
|
TYPE_BOOL = 0x2,
|
||||||
|
TYPE_SHORT = 0x3,
|
||||||
|
TYPE_INT = 0x4,
|
||||||
|
TYPE_FLOAT = 0x5,
|
||||||
|
TYPE_STRING = 0x6,
|
||||||
|
TYPE_BUFFER = 0x7,
|
||||||
|
TYPE_FLAG = 0x8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GamerProfileData
|
||||||
|
{
|
||||||
|
GamerProfileDataType type;
|
||||||
|
GamerProfileDataUnion u;
|
||||||
|
};
|
||||||
|
|
||||||
namespace hks
|
namespace hks
|
||||||
{
|
{
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
|
Loading…
Reference in New Issue
Block a user