Add custom achievements
Co-Authored-By: Vlad Loktionov <13555921+VladWinner@users.noreply.github.com>
This commit is contained in:
parent
73fdf79321
commit
e43ae321c0
21
data/cdata/scripts/ending/achievements.gsc
Normal file
21
data/cdata/scripts/ending/achievements.gsc
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
25
data/cdata/scripts/gulag/achievements.gsc
Normal file
25
data/cdata/scripts/gulag/achievements.gsc
Normal 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");
|
||||||
|
}
|
@ -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
|
||||||
|
|
BIN
data/zonetool/h2_mod_ui/images/trophy_51.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/trophy_51.dds
Normal file
Binary file not shown.
BIN
data/zonetool/h2_mod_ui/images/trophy_52.dds
Normal file
BIN
data/zonetool/h2_mod_ui/images/trophy_52.dds
Normal file
Binary file not shown.
26
data/zonetool/h2_mod_ui/materials/trophy_51.json
Normal file
26
data/zonetool/h2_mod_ui/materials/trophy_51.json
Normal 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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
data/zonetool/h2_mod_ui/materials/trophy_52.json
Normal file
26
data/zonetool/h2_mod_ui/materials/trophy_52.json
Normal 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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -227,5 +227,9 @@
|
|||||||
"ACHIEVEMENT_NAME_49": "Clown in Training",
|
"ACHIEVEMENT_NAME_49": "Clown in Training",
|
||||||
"ACHIEVEMENT_DETAIL_49": "The U.S. Army Rangers ain’t no place for clowns.",
|
"ACHIEVEMENT_DETAIL_49": "The U.S. Army Rangers ain’t 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'"
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user