Add custom achievements

Co-Authored-By: Vlad Loktionov <13555921+VladWinner@users.noreply.github.com>
This commit is contained in:
fed 2023-04-14 18:43:31 +02:00
parent 73fdf79321
commit e43ae321c0
11 changed files with 118 additions and 17 deletions

View File

@ -0,0 +1,21 @@
main()
{
replacefunc(maps\char_museum::ramirez_jukebox, ::ramirez_jukebox);
}
ramirez_jukebox()
{
common_scripts\utility::flag_wait("museum_ready");
wait 4;
jukebox = getent("ramirez_jukebox", "targetname");
jukebox makeusable();
for (;;)
{
jukebox waittill("trigger");
index = randomint(37);
jukebox maps\_utility::play_sound_on_entity("museum_ramirez_ee_" + index);
maps\_utility::giveachievement_wrapper("RAMIREZ");
}
}

View File

@ -0,0 +1,25 @@
main()
{
replacefunc(maps\gulag_code::surprise, ::surprise);
}
surprise()
{
level endon("cancel_surprise");
tv = getent("surprise_tv", "script_noteworthy");
tv thread maps\gulag_code::surprise_tv();
common_scripts\utility::flag_wait("player_nears_cell_door3");
maps\gulag_code::surprise_damage_trigger();
maps\gulag_code::surprise_flag_touching();
tv thread maps\_utility::play_sound_on_entity("h2_zombie_easter_egg");
tv.screen = spawn("script_model", tv.origin);
tv.screen.angles = tv.angles;
tv.screen setmodel("com_tv1_pho_zombie");
wait 3.3;
tv.screen delete();
maps\_utility::giveachievement_wrapper("BRAINS");
}

View File

@ -88,5 +88,7 @@ material,trophy_47
material,trophy_48 material,trophy_48
material,trophy_49 material,trophy_49
material,trophy_50 material,trophy_50
material,trophy_51
material,trophy_52
localize,english localize,english
sound,ui_achievement_unlocked sound,ui_achievement_unlocked

1 material h2_ui_featured_pip_focused
88 material trophy_50
89 localize material english trophy_51
90 sound material ui_achievement_unlocked trophy_52
91 localize english
92 sound ui_achievement_unlocked
93
94

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,26 @@
{
"name": "trophy_51",
"techniqueSet->name": "2d",
"gameFlags": 0,
"sortKey": 60,
"renderFlags": 0,
"textureAtlasRowCount": 1,
"textureAtlasColumnCount": 1,
"textureAtlasFrameBlend": 0,
"textureAtlasAsArray": 0,
"surfaceTypeBits": 0,
"cameraRegion": 12,
"materialType": 0,
"assetFlags": 0,
"constantTable": null,
"textureTable": [
{
"image": "trophy_51",
"semantic": 0,
"samplerState": 226,
"lastCharacter": 112,
"firstCharacter": 99,
"typeHash": 2695565377
}
]
}

View File

@ -0,0 +1,26 @@
{
"name": "trophy_52",
"techniqueSet->name": "2d",
"gameFlags": 0,
"sortKey": 60,
"renderFlags": 0,
"textureAtlasRowCount": 1,
"textureAtlasColumnCount": 1,
"textureAtlasFrameBlend": 0,
"textureAtlasAsArray": 0,
"surfaceTypeBits": 0,
"cameraRegion": 12,
"materialType": 0,
"assetFlags": 0,
"constantTable": null,
"textureTable": [
{
"image": "trophy_52",
"semantic": 0,
"samplerState": 226,
"lastCharacter": 112,
"firstCharacter": 99,
"typeHash": 2695565377
}
]
}

View File

@ -227,5 +227,9 @@
"ACHIEVEMENT_NAME_49": "Clown in Training", "ACHIEVEMENT_NAME_49": "Clown in Training",
"ACHIEVEMENT_DETAIL_49": "The U.S. Army Rangers aint no place for clowns.", "ACHIEVEMENT_DETAIL_49": "The U.S. Army Rangers aint no place for clowns.",
"ACHIEVEMENT_NAME_50": "Headbanger", "ACHIEVEMENT_NAME_50": "Headbanger",
"ACHIEVEMENT_DETAIL_50": "Kill an enemy with the impact damage from a frag grenade to the head." "ACHIEVEMENT_DETAIL_50": "Kill an enemy with the impact damage from a frag grenade to the head.",
"ACHIEVEMENT_NAME_51": "BRAAAINS...",
"ACHIEVEMENT_DETAIL_51": "Check out Prisoner 227's cell in 'The Gulag'",
"ACHIEVEMENT_NAME_52": "Ramirez!",
"ACHIEVEMENT_DETAIL_52": "Turn on the radio in 'Museum'"
} }

View File

@ -25,7 +25,7 @@ namespace achievements
{ {
std::mutex file_mutex; std::mutex file_mutex;
std::array<achievement_t, ACHIEVEMENT_COUNT> achievements = std::array<achievement_t, ACHIEVEMENT_TOTAL_COUNT> achievements =
{ {
achievement_t(ACHIEVEMENT_ALL_ACHIEVEMENTS, "ACHIEVEMENTS_COMPLETED", ACHIEVEMENT_RARITY_3), achievement_t(ACHIEVEMENT_ALL_ACHIEVEMENTS, "ACHIEVEMENTS_COMPLETED", ACHIEVEMENT_RARITY_3),
achievement_t(ACHIEVEMENT_1, "BACK_IN_THE_SADDLE", ACHIEVEMENT_RARITY_0), achievement_t(ACHIEVEMENT_1, "BACK_IN_THE_SADDLE", ACHIEVEMENT_RARITY_0),
@ -78,6 +78,8 @@ namespace achievements
achievement_t(ACHIEVEMENT_48, "HOT_POTATO", ACHIEVEMENT_RARITY_0), achievement_t(ACHIEVEMENT_48, "HOT_POTATO", ACHIEVEMENT_RARITY_0),
achievement_t(ACHIEVEMENT_49, "CLOWN_IN_TRAINING", ACHIEVEMENT_RARITY_0), achievement_t(ACHIEVEMENT_49, "CLOWN_IN_TRAINING", ACHIEVEMENT_RARITY_0),
achievement_t(ACHIEVEMENT_50, "HEADBANGER", ACHIEVEMENT_RARITY_0), achievement_t(ACHIEVEMENT_50, "HEADBANGER", ACHIEVEMENT_RARITY_0),
achievement_t(ACHIEVEMENT_51, "BRAINS", ACHIEVEMENT_RARITY_2),
achievement_t(ACHIEVEMENT_52, "RAMIREZ", ACHIEVEMENT_RARITY_2),
}; };
std::filesystem::path get_achievements_path() std::filesystem::path get_achievements_path()
@ -85,8 +87,6 @@ namespace achievements
return utils::properties::get_appdata_path() / "player/achievements.bin"; return utils::properties::get_appdata_path() / "player/achievements.bin";
} }
void write_achievements(achievement_file_t* data) void write_achievements(achievement_file_t* data)
{ {
std::lock_guard _0(file_mutex); std::lock_guard _0(file_mutex);
@ -101,7 +101,7 @@ namespace achievements
bool has_achievement(achievement_file_t* file, int id) bool has_achievement(achievement_file_t* file, int id)
{ {
if (id >= ACHIEVEMENT_COUNT) if (id >= ACHIEVEMENT_TOTAL_COUNT)
{ {
return false; return false;
} }
@ -111,7 +111,7 @@ namespace achievements
std::optional<int> get_achievement_id(const std::string& name) std::optional<int> get_achievement_id(const std::string& name)
{ {
for (auto i = 0; i < ACHIEVEMENT_COUNT; i++) for (auto i = 0; i < ACHIEVEMENT_TOTAL_COUNT; i++)
{ {
const auto achievement = &achievements[i]; const auto achievement = &achievements[i];
if (name == achievement->code) if (name == achievement->code)
@ -138,7 +138,7 @@ namespace achievements
return false; return false;
} }
for (auto i = static_cast<int>(ACHIEVEMENT_START); i < ACHIEVEMENT_COUNT; i++) for (auto i = static_cast<int>(ACHIEVEMENT_START); i < ACHIEVEMENT_ORIGINAL_COUNT; i++)
{ {
if (!file->achievements[i]) if (!file->achievements[i])
{ {
@ -206,7 +206,7 @@ namespace achievements
return; return;
} }
std::memcpy(file, data.data(), sizeof(achievement_file_t)); std::memcpy(file, data.data(), std::min(data.size(), sizeof(achievement_file_t)));
if (file->signature != ACHIEVEMENT_FILE_SIGNATURE) if (file->signature != ACHIEVEMENT_FILE_SIGNATURE)
{ {
std::memset(file, 0, sizeof(achievement_file_t)); std::memset(file, 0, sizeof(achievement_file_t));
@ -215,7 +215,7 @@ namespace achievements
int get_count() int get_count()
{ {
return ACHIEVEMENT_COUNT; return ACHIEVEMENT_TOTAL_COUNT;
} }
bool has_achievement(int id) bool has_achievement(int id)
@ -237,7 +237,7 @@ namespace achievements
int get_rarity(int id) int get_rarity(int id)
{ {
if (id >= ACHIEVEMENT_COUNT) if (id >= ACHIEVEMENT_TOTAL_COUNT)
{ {
return 0; return 0;
} }

View File

@ -64,9 +64,10 @@ namespace achievements
ACHIEVEMENT_48, ACHIEVEMENT_48,
ACHIEVEMENT_49, ACHIEVEMENT_49,
ACHIEVEMENT_50, ACHIEVEMENT_50,
ACHIEVEMENT_COUNT = 51, ACHIEVEMENT_ORIGINAL_COUNT = 51,
ACHIEVEMENT_51, ACHIEVEMENT_51 = 51,
ACHIEVEMENT_52, ACHIEVEMENT_52,
ACHIEVEMENT_TOTAL_COUNT,
}; };
struct achievement_t struct achievement_t
@ -80,7 +81,7 @@ namespace achievements
{ {
std::uint32_t signature; std::uint32_t signature;
std::uint8_t version; std::uint8_t version;
bool achievements[ACHIEVEMENT_COUNT]; bool achievements[ACHIEVEMENT_TOTAL_COUNT];
}; };
void get_achievements(achievement_file_t* file); void get_achievements(achievement_file_t* file);

View File

@ -39,10 +39,6 @@ namespace database
utils::memory::allocator handle_allocator; utils::memory::allocator handle_allocator;
using sound_file_t = std::unordered_map<uint64_t, std::string>;
std::unordered_map<unsigned short, sound_file_t> sound_files = {};
std::unordered_map<std::string, uint64_t> sound_sizes = {};
game::dvar_t* db_filesysImpl = nullptr; game::dvar_t* db_filesysImpl = nullptr;
utils::hook::detour db_fs_initialize_hook; utils::hook::detour db_fs_initialize_hook;