Skip to content

Commit

Permalink
add damage type images to target info window
Browse files Browse the repository at this point in the history
  • Loading branch information
DubbleClick committed Apr 7, 2024
1 parent a1b5ade commit a776049
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
61 changes: 54 additions & 7 deletions GWToolboxdll/Modules/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,43 @@ namespace {
}
}

const char* profession_icon_urls[] = {"", "8/87/Warrior-tango-icon-48", "e/e8/Ranger-tango-icon-48", "5/53/Monk-tango-icon-48", "b/b1/Necromancer-tango-icon-48", "b/b1/Mesmer-tango-icon-48", "4/47/Elementalist-tango-icon-48",
"2/2b/Assassin-tango-icon-48", "5/5b/Ritualist-tango-icon-48", "5/5e/Paragon-tango-icon-48", "3/38/Dervish-tango-icon-48"};
constexpr std::array profession_icon_urls = {
"",
"8/87/Warrior-tango-icon-48",
"e/e8/Ranger-tango-icon-48",
"5/53/Monk-tango-icon-48",
"b/b1/Necromancer-tango-icon-48",
"b/b1/Mesmer-tango-icon-48",
"4/47/Elementalist-tango-icon-48",
"2/2b/Assassin-tango-icon-48",
"5/5b/Ritualist-tango-icon-48",
"5/5e/Paragon-tango-icon-48",
"3/38/Dervish-tango-icon-48"
};
std::map<uint32_t, IDirect3DTexture9**> profession_icons;
std::map<GW::Constants::SkillID, IDirect3DTexture9**> skill_images;
std::map<std::wstring, IDirect3DTexture9**> item_images;
std::map<std::string, IDirect3DTexture9**> guild_wars_wiki_images;
std::map<uint32_t, IDirect3DTexture9**> profession_icons;
const std::map<std::string, const char*> damagetype_icon_urls = {
{"Blunt damage", "1/19/Blunt_damage.png/60px-Blunt_damage.png"},
{"Piercing damage", "1/1a/Piercing_damage.png/60px-Piercing_damage.png"},
{"Slashing damage", "3/3c/Slashing_damage.png/60px-Slashing_damage.png"},
{"Cold damage", "4/48/Cold_damage.png/60px-Cold_damage.png"},
{"Earth damage", "b/bb/Earth_damage.png/60px-Earth_damage.png"},
{"Fire damage", "6/6a/Fire_damage.png/60px-Fire_damage.png"},
{"Lightning damage", "0/06/Lightning_damage.png/60px-Lightning_damage.png"},
};

std::map<std::string, IDirect3DTexture9**> damagetype_icons;
std::map<GW::Constants::MapID, GuiUtils::EncString*> map_names;
std::unordered_map<GW::Constants::Language, std::unordered_map<uint32_t,GuiUtils::EncString*>> encoded_string_ids;
std::unordered_map<GW::Constants::Language, std::unordered_map<uint32_t, GuiUtils::EncString*>> encoded_string_ids;
std::filesystem::path current_settings_folder;
constexpr size_t MAX_WORKERS = 5;
const wchar_t* GUILD_WARS_WIKI_FILES_PATH = L"img\\gww_files";
const wchar_t* SKILL_IMAGES_PATH = L"img\\skills";
const wchar_t* ITEM_IMAGES_PATH = L"img\\items";
const wchar_t* PROF_ICONS_PATH = L"img\\professions";
const wchar_t* DMGTYPE_ICONS_PATH = L"img\\damagetypes";

std::recursive_mutex worker_mutex;
std::recursive_mutex main_mutex;
Expand Down Expand Up @@ -779,6 +802,29 @@ IDirect3DTexture9** Resources::GetProfessionIcon(GW::Constants::Profession p)
return texture;
}

IDirect3DTexture9** Resources::GetDamagetypeImage(std::string dmg_type)
{
if (damagetype_icons.contains(dmg_type)) {
return damagetype_icons.at(dmg_type);
}
const auto texture = new IDirect3DTexture9*;
*texture = nullptr;
damagetype_icons[dmg_type] = texture;
if (damagetype_icon_urls.contains(dmg_type)) {
const auto path = GetPath(DMGTYPE_ICONS_PATH);
EnsureFolderExists(path);
const auto local_path = path / GuiUtils::SanitiseFilename(dmg_type + ".png");
const auto remote_path = std::format("https://wiki.guildwars.com/images/thumb/{}", damagetype_icon_urls.at(dmg_type));
LoadTexture(texture, local_path, remote_path, [dmg_type](const bool success, const std::wstring& error) {
if (!success) {
const auto dmg_type_wstr = GuiUtils::StringToWString(dmg_type);
Log::ErrorW(L"Failed to load icon for %d\n%s", dmg_type_wstr.c_str(), error.c_str());
}
});
}
return texture;
}

IDirect3DTexture9** Resources::GetGuildWarsWikiImage(const char* filename, size_t width)
{
ASSERT(filename && filename[0]);
Expand Down Expand Up @@ -864,8 +910,8 @@ IDirect3DTexture9** Resources::GetSkillImage(GW::Constants::SkillID skill_id)
const auto skill = GW::SkillbarMgr::GetSkillConstantData(skill_id);
ASSERT(skill && skill->icon_file_id);
return GwDatTextureModule::LoadTextureFromFileId(skill->icon_file_id);

}

IDirect3DTexture9** Resources::GetSkillImageFromGWW(GW::Constants::SkillID skill_id)
{
if (skill_images.contains(skill_id)) {
Expand Down Expand Up @@ -987,7 +1033,8 @@ GuiUtils::EncString* Resources::DecodeStringId(const uint32_t enc_str_id, GW::Co
return enc_string;
}

IDirect3DTexture9** Resources::GetItemImage(GW::Item* item) {
IDirect3DTexture9** Resources::GetItemImage(GW::Item* item)
{
if (!(item && item->model_file_id))
return nullptr;
uint32_t model_id_to_load = 0;
Expand All @@ -998,7 +1045,7 @@ IDirect3DTexture9** Resources::GetItemImage(GW::Item* item) {
if (is_composite_item) {
// Armor/runes
const auto model_file_info = GW::Items::GetCompositeModelInfo(item->model_file_id);
if(!model_id_to_load)
if (!model_id_to_load)
model_id_to_load = model_file_info->file_ids[0xa];
if (!model_id_to_load)
model_id_to_load = is_female ? model_file_info->file_ids[5] : model_file_info->file_ids[0];
Expand Down
2 changes: 2 additions & 0 deletions GWToolboxdll/Modules/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class Resources : public ToolboxModule {

// Guaranteed to return a pointer, but reference will be null until the texture has been loaded
static IDirect3DTexture9** GetProfessionIcon(GW::Constants::Profession p);
// Guaranteed to return a pointer, but reference will be null until the texture has been loaded
static IDirect3DTexture9** GetDamagetypeImage(std::string dmg_type);
// Fetches skill image from gw dat via file_id
static IDirect3DTexture9** GetSkillImage(GW::Constants::SkillID skill_id);
// Fetches skill page from GWW, parses out the image for the skill then downloads that to disk
Expand Down
36 changes: 28 additions & 8 deletions GWToolboxdll/Windows/TargetInfoWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ namespace {
std::map<GW::Constants::SkillID, GuiUtils::EncString*> skill_names_by_id;
std::unordered_map<std::string, GW::Constants::SkillID> skill_ids_by_name;


struct AgentInfo {
GuiUtils::EncString name;
std::string wiki_content;
Expand Down Expand Up @@ -85,15 +84,15 @@ namespace {
if (skill_names_by_id.empty()) {
std::map<uint32_t, GuiUtils::EncString*> skill_ids_by_name_id;
for (size_t i = 0; i < (size_t)GW::Constants::SkillID::Count; i++) {
const auto skill_data = GW::SkillbarMgr::GetSkillConstantData((GW::Constants::SkillID)i);
const auto skill_data = GW::SkillbarMgr::GetSkillConstantData(static_cast<GW::Constants::SkillID>(i));
if (!(skill_data && skill_data->name && skill_ids_by_name_id.find(skill_data->name) == skill_ids_by_name_id.end()))
continue;
auto enc = new GuiUtils::EncString();
const auto enc = new GuiUtils::EncString();
enc->language(GW::Constants::Language::English);
enc->reset(skill_data->name);
enc->wstring();
skill_ids_by_name_id[skill_data->name] = enc;
skill_names_by_id[(GW::Constants::SkillID)i] = enc;
skill_names_by_id[static_cast<GW::Constants::SkillID>(i)] = enc;
}
}
for (auto it : skill_names_by_id) {
Expand Down Expand Up @@ -126,7 +125,7 @@ namespace {

agent_info->wiki_search_term = GuiUtils::WStringToString(
GuiUtils::SanitizePlayerName(agent_info->name.wstring())
);
);
std::string wiki_url = "https://wiki.guildwars.com/wiki/?search=";
wiki_url.append(GuiUtils::UrlEncode(agent_info->wiki_search_term, '_'));
Resources::Download(wiki_url, AgentInfo::OnFetchedWikiPage, agent_info);
Expand Down Expand Up @@ -158,9 +157,10 @@ namespace {
const std::regex armor_ratings_regex("<h2><span class=\"mw-headline\" id=\"Armor_ratings\">([\\s\\S]*)</table>");
if (std::regex_search(agent_info->wiki_content, m, armor_ratings_regex)) {
std::string armor_table_found = m[1].str();
armor_table_found.erase(std::ranges::remove(armor_table_found, '\n').begin(), armor_table_found.end());

// Iterate over all skills in this list.
const auto armor_cell_regex = std::regex("<td>[\\s\\S]*title=\"([^\"]+)\"[\\s\\S]*<td>([0-9 \\(\\)]+)</td>");
const auto armor_cell_regex = std::regex(R"regex(<td>[\s\S]*?title="([^"]+)"[\s\S]*?<td>([0-9 \(\)]+).*?<\/td>)regex");
auto words_begin = std::sregex_iterator(armor_table_found.begin(), armor_table_found.end(), armor_cell_regex);
auto words_end = std::sregex_iterator();
for (std::sregex_iterator i = words_begin; i != words_end; ++i)
Expand Down Expand Up @@ -234,8 +234,28 @@ void TargetInfoWindow::Draw(IDirect3DDevice9*)
}
if (current_agent_info->wiki_armor_ratings.size()) {
ImGui::Text("Armor Ratings:");
for (const auto it : current_agent_info->wiki_armor_ratings) {
ImGui::Text("%s: %s", it.first.c_str(), it.second.c_str());
for (const auto [damage_type, armour_rating] : current_agent_info->wiki_armor_ratings) {const float btnw = ImGui::GetContentRegionAvail().x / 2.f;
const ImVec2 btn_dims = { btnw,.0f };
const auto open_wiki = [&] {
auto damage_type_wstr = GuiUtils::StringToWString(damage_type);
std::ranges::replace(damage_type_wstr, L' ', L'_');
GuiUtils::OpenWiki(damage_type_wstr.c_str());
};
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, { 0.f, .5f });
if (const auto dmgtype_img = Resources::GetDamagetypeImage(damage_type)) {
ImGui::PushID(damage_type.c_str());
if (ImGui::IconButton(armour_rating.c_str(), *dmgtype_img, btn_dims)) {
open_wiki();
}
ImGui::PopID();
}
else {
ImGui::Text("%s: %s", damage_type.c_str(), armour_rating.c_str());
if (ImGui::IsItemClicked()) {
open_wiki();
}
}
ImGui::PopStyleVar();
}
}
if (ImGui::Button("View More on Guild Wars Wiki")) {
Expand Down

0 comments on commit a776049

Please sign in to comment.