Skip to content

Commit

Permalink
clean up some logic
Browse files Browse the repository at this point in the history
  • Loading branch information
DubbleClick committed Nov 17, 2023
1 parent 8ba3443 commit dc07db4
Showing 1 changed file with 108 additions and 143 deletions.
251 changes: 108 additions & 143 deletions GWToolboxdll/Windows/EnemyWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
#include <GWCA/Managers/AgentMgr.h>
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Managers/PartyMgr.h>

#include <Color.h>
#include <Utils/GuiUtils.h>
#include <Windows/EnemyWindow.h>

Expand All @@ -21,48 +18,41 @@
using namespace GW::Agents;

namespace {

bool hide_when_nothing = true;
bool show_enemies_counter = true;
float enemies_threshhold = 1.0f;
float range = 1248.0f;
float triangleSpacing = 22.0f;
int triangleYOffset = 3;
float triangleSizeMultiplier = 1.0f;

struct enemyinfo {
enemyinfo(const GW::AgentID agent_id) : agent_id(agent_id) {}
struct Enemyinfo {
Enemyinfo(const GW::AgentID agent_id)
: agent_id(agent_id) {}

GW::AgentID agent_id;
clock_t last_casted = 0;
uint16_t last_skill;
float distance = FLT_MAX;
};

GW::AgentLiving* GetAgentLivingByID(const uint32_t agent_id)
{
const auto a = GW::Agents::GetAgentByID(agent_id);
return a ? a->GetAsAgentLiving() : nullptr;
}

void drawStatusTriangle(int triangleCount, ImVec2 position, ImU32 triangleColor, bool upsidedown)
void draw_status_triangle(int triangleCount, ImVec2 position, ImU32 triangleColor, bool upsidedown)
{
ImVec2 point1, point2, point3;

if (upsidedown) {
point1 = ImVec2(position.x - (triangleCount * triangleSpacing), position.y + triangleYOffset);
point2 = ImVec2(position.x + (20 * triangleSizeMultiplier) - (triangleCount * triangleSpacing), position.y + triangleYOffset);
point3 = ImVec2(position.x + (10 * triangleSizeMultiplier) - (triangleCount * triangleSpacing), position.y + triangleYOffset + (10 * triangleSizeMultiplier));
point1 = ImVec2(position.x - triangleCount * triangleSpacing, position.y + triangleYOffset);
point2 = ImVec2(position.x + 20 * triangleSizeMultiplier - triangleCount * triangleSpacing, position.y + triangleYOffset);
point3 = ImVec2(position.x + 10 * triangleSizeMultiplier - triangleCount * triangleSpacing, position.y + triangleYOffset + 10 * triangleSizeMultiplier);
}
else {
point1 = ImVec2(position.x - (triangleCount * triangleSpacing), position.y + triangleYOffset + (10 * triangleSizeMultiplier));
point2 = ImVec2(position.x + (20 * triangleSizeMultiplier) - (triangleCount * triangleSpacing), position.y + triangleYOffset + (10 * triangleSizeMultiplier));
point3 = ImVec2(position.x + (10 * triangleSizeMultiplier) - (triangleCount * triangleSpacing), position.y + triangleYOffset);
point1 = ImVec2(position.x - triangleCount * triangleSpacing, position.y + triangleYOffset + 10 * triangleSizeMultiplier);
point2 = ImVec2(position.x + 20 * triangleSizeMultiplier - triangleCount * triangleSpacing, position.y + triangleYOffset + 10 * triangleSizeMultiplier);
point3 = ImVec2(position.x + 10 * triangleSizeMultiplier - triangleCount * triangleSpacing, position.y + triangleYOffset);
}

ImGui::GetWindowDrawList()->AddTriangleFilled(point1, point2, point3, triangleColor);
}


uint32_t GetAgentMaxHP(const GW::AgentLiving* agent)
{
if (!agent) {
Expand All @@ -78,36 +68,105 @@ namespace {
{
const auto max_hp = GetAgentMaxHP(agent);
if (!(max_hp && agent->hp_pips != .0f)) {
return 0;
return 0;
}
const float health_regen_per_second = max_hp * agent->hp_pips;
const float pips = std::ceil(health_regen_per_second / 2.f); // 1 pip = 2 health per second
return static_cast<int>(pips);
}

bool OrderEnemyInfo(const enemyinfo& a, const enemyinfo& b)
std::vector<Enemyinfo> enemies{};
std::set<GW::AgentID> all_enemies;

void clear_enemies()
{
return a.distance < b.distance;
}
} // namespace

void DrawDuping(const char* label, const std::vector<enemyinfo>& vec)
{
void EnemyWindow::Terminate()
{
ToolboxWindow::Terminate();
clear_enemies();
}

void EnemyWindow::Draw(IDirect3DDevice9*)
{
if (!visible) {
return;
}

if (GW::Map::GetInstanceType() == GW::Constants::InstanceType::Outpost) {
clear_enemies();
}

all_enemies.clear();

const GW::AgentArray* agents = GW::Agents::GetAgentArray();

if (const GW::Agent* player = agents ? GW::Agents::GetPlayer() : nullptr) {
for (auto* agent : *agents) {
const GW::AgentLiving* living = agent ? agent->GetAsAgentLiving() : nullptr;

if (!living || living->allegiance != GW::Constants::Allegiance::Enemy || !living->GetIsAlive()) {
continue;
}

switch (living->player_number) {
case 2338:
case 2325:
continue;
default:
break;
}

if (living->hp <= enemies_threshhold) {
all_enemies.insert(living->agent_id);

if (vec.empty()) {
const bool is_casting = living->skill != static_cast<uint16_t>(GW::Constants::SkillID::No_Skill);

auto found_enemy = std::ranges::find_if(enemies, [living](const Enemyinfo& info) {
return info.agent_id == living->agent_id;
});
if (found_enemy == enemies.end()) {
enemies.push_back(living->agent_id);
found_enemy = enemies.end() - 1;
}
if (is_casting) {
found_enemy->last_casted = TIMER_INIT();
found_enemy->last_skill = living->skill;
}

found_enemy->distance = GW::GetSquareDistance(player->pos, living->pos);
}
}

std::erase_if(enemies, [](auto& info) {
return !all_enemies.contains(info.agent_id);
});

std::ranges::sort(enemies, [](const Enemyinfo& a, const Enemyinfo& b) {
return a.distance < b.distance;
});
}

ImGui::SetNextWindowCenter(ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(300, 0), ImGuiCond_FirstUseEver);
if (ImGui::Begin(Name(), GetVisiblePtr(), GetWinFlags())) {
if (enemies.empty()) {
return;
}

ImGui::Spacing();
if (ImGui::BeginTable(label, 4)) {
if (ImGui::BeginTable("enemies", 4)) {
ImGui::TableSetupColumn("Selection", ImGuiTableColumnFlags_WidthFixed, 0, 0);
ImGui::TableSetupColumn("HP", ImGuiTableColumnFlags_WidthStretch, -1, 0);
ImGui::TableSetupColumn("Regen", ImGuiTableColumnFlags_WidthFixed, 70, 1);
ImGui::TableSetupColumn("Last Casted", ImGuiTableColumnFlags_WidthFixed, 40, 2);

const GW::Agent* target = GW::Agents::GetTarget();

for (const auto& dupe_info : vec) {
const auto living = GetAgentLivingByID(dupe_info.agent_id);
for (const auto& dupe_info : enemies) {
const auto living = GW::Agents::GetAgentByID(dupe_info.agent_id) ? GW::Agents::GetAgentByID(dupe_info.agent_id)->GetAsAgentLiving() : nullptr;
if (!living || dupe_info.distance > range * range) {
continue;
}
Expand All @@ -129,20 +188,20 @@ namespace {

if (ImGui::Selectable("", selected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap, ImVec2(0, 23))) {
if (ImGui::IsMouseReleased(ImGuiMouseButton_Left)) {
GW::GameThread::Enqueue([living] {
GW::Agents::ChangeTarget(living);
GW::GameThread::Enqueue([id = living->agent_id] {
GW::Agents::ChangeTarget(id);
});
}
}

// Progress bar
ImGui::TableSetColumnIndex(1);
ImVec2 progressBarPos = ImGui::GetCursorScreenPos();
ImVec2 Pos1 = ImVec2(progressBarPos.x + ImGui::GetContentRegionAvail().x * 0.025f, progressBarPos.y + 3);
ImVec2 Pos2 = ImVec2(progressBarPos.x + ImGui::GetContentRegionAvail().x - 25, progressBarPos.y + 3);
ImU32 HexedColor = IM_COL32(253, 113, 255, 255);
ImU32 ConditionedColor = IM_COL32(160, 117, 85, 255);
ImU32 EnchantedColor = IM_COL32(224, 253, 94, 255);
const auto progress_bar_pos = ImGui::GetCursorScreenPos();
auto pos1 = ImVec2(progress_bar_pos.x + ImGui::GetContentRegionAvail().x * 0.025f, progress_bar_pos.y + 3);
const auto pos2 = ImVec2(progress_bar_pos.x + ImGui::GetContentRegionAvail().x - 25, progress_bar_pos.y + 3);
constexpr ImU32 hexed_color = IM_COL32(253, 113, 255, 255);
constexpr ImU32 conditioned_color = IM_COL32(160, 117, 85, 255);
constexpr ImU32 enchanted_color = IM_COL32(224, 253, 94, 255);

int triangles = 0;

Expand All @@ -158,29 +217,29 @@ namespace {
if (dupe_info.last_skill != 0) {
const GW::Skill* skill_data = GW::SkillbarMgr::GetSkillConstantData(static_cast<GW::Constants::SkillID>(dupe_info.last_skill));
ASSERT(skill_data);
auto enc_skillname = new GuiUtils::EncString(skill_data->name);
const auto enc_skillname = new GuiUtils::EncString(skill_data->name);
skillname = enc_skillname->string();
}

if (TIMER_DIFF(dupe_info.last_casted) < 3000) {
ImGui::GetWindowDrawList()->AddText(Pos1, IM_COL32(253, 255, 255, 255), (agent_name_str + " - " + skillname).c_str());
ImGui::GetWindowDrawList()->AddText(pos1, IM_COL32(253, 255, 255, 255), (agent_name_str + " - " + skillname).c_str());
}
else {
ImGui::GetWindowDrawList()->AddText(Pos1, IM_COL32(253, 255, 255, 255), (agent_name_str).c_str());
ImGui::GetWindowDrawList()->AddText(pos1, IM_COL32(253, 255, 255, 255), (agent_name_str).c_str());
}

if (living->GetIsEnchanted()) {
drawStatusTriangle(triangles, Pos2, EnchantedColor, false);
draw_status_triangle(triangles, pos2, enchanted_color, false);
triangles++;
}

if (living->GetIsHexed()) {
drawStatusTriangle(triangles, Pos2, HexedColor, true);
draw_status_triangle(triangles, pos2, hexed_color, true);
triangles++;
}

if (living->GetIsConditioned()) {
drawStatusTriangle(triangles, Pos2, ConditionedColor, true);
draw_status_triangle(triangles, pos2, conditioned_color, true);
}

//Health pips
Expand All @@ -205,105 +264,12 @@ namespace {
ImGui::EndTable();
}
}

std::vector<enemyinfo> enemies{};
std::set<GW::AgentID> all_enemies;

void clearenemies()
{
enemies.clear();
all_enemies.clear();
}

} // namespace

void EnemyWindow::Terminate()
{
ToolboxWindow::Terminate();
clearenemies();
}

void EnemyWindow::Draw(IDirect3DDevice9*)
{
if (!visible) {
return;
}

const bool is_in_outpost = GW::Map::GetInstanceType() == GW::Constants::InstanceType::Outpost;
if (is_in_outpost) {
clearenemies();
}

int enemy_count = 0;
all_enemies.clear();

const GW::AgentArray* agents = GW::Agents::GetAgentArray();
const GW::Agent* player = agents ? GW::Agents::GetPlayer() : nullptr;

if (player) {
std::vector<enemyinfo>* enemyinfoarray = nullptr;
std::set<GW::AgentID>* all_agents_of_type = nullptr;
for (auto* agent : *agents) {
const GW::AgentLiving* living = agent ? agent->GetAsAgentLiving() : nullptr;

if (!living || living->allegiance != GW::Constants::Allegiance::Enemy || !living->GetIsAlive()) {
continue;
}

switch (living->player_number) {
case 2338:
case 2325:
continue;
default:
break;
}

all_agents_of_type = &all_enemies;
enemyinfoarray = &enemies;
enemy_count++;

if (living->hp <= enemies_threshhold) {
all_agents_of_type->insert(living->agent_id);

const bool is_casting = living->skill != static_cast<uint16_t>(GW::Constants::SkillID::No_Skill);

auto found_enemy = std::ranges::find_if(*enemyinfoarray, [living](const enemyinfo& info) {
return info.agent_id == living->agent_id;
});
if (found_enemy == enemyinfoarray->end()) {
enemyinfoarray->push_back(living->agent_id);
found_enemy = enemyinfoarray->end() - 1;
}
if (is_casting) {
found_enemy->last_casted = TIMER_INIT();
found_enemy->last_skill = living->skill;

}

found_enemy->distance = GW::GetSquareDistance(player->pos, living->pos);
}
}

std::erase_if(enemies, [](auto& info) {
return !all_enemies.contains(info.agent_id);
});

std::ranges::sort(enemies, &OrderEnemyInfo);

}

ImGui::SetNextWindowCenter(ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(300, 0), ImGuiCond_FirstUseEver);
if (ImGui::Begin(Name(), GetVisiblePtr(), GetWinFlags())) {

DrawDuping("enemies", enemies);
}
ImGui::End();
}

void EnemyWindow::DrawSettingsInternal()
{
ImGui::DragFloat("Range", &range, 50, 0, 5000);
ImGui::DragFloat("Range", &range, 50.f, 0.f, 5000.f);
ImGui::Separator();
ImGui::Text("Enemy Counters:");
ImGui::StartSpacedElements(275.f);
Expand All @@ -312,14 +278,14 @@ void EnemyWindow::DrawSettingsInternal()
ImGui::Separator();
ImGui::Text("HP thresholds:");
ImGui::ShowHelp("Threshold HP below which enemy duping info is displayed");
ImGui::DragFloat("Percent", &enemies_threshhold, 0.01f, 0, 1);
ImGui::DragFloat("Percent", &enemies_threshhold, 0.01f, 0.f, 1.f);
ImGui::Separator();
ImGui::Text("Status triange size multiplier:");
ImGui::ShowHelp("Hex, condition, enchanted");
ImGui::DragFloat("Multiplier", &triangleSizeMultiplier, 0.25f, 0, 5);
ImGui::DragFloat("Multiplier", &triangleSizeMultiplier, 0.25f, 0.f, 5.f);
ImGui::Separator();
ImGui::Text("Status triange spacing");
ImGui::DragFloat("Spacing", &triangleSpacing, 0.01, 0, 100);
ImGui::DragFloat("Spacing", &triangleSpacing, 0.01f, 0.f, 100.f);
}

void EnemyWindow::LoadSettings(ToolboxIni* ini)
Expand All @@ -340,5 +306,4 @@ void EnemyWindow::SaveSettings(ToolboxIni* ini)
SAVE_FLOAT(range);
SAVE_FLOAT(triangleSizeMultiplier);
SAVE_FLOAT(triangleSpacing);

}

0 comments on commit dc07db4

Please sign in to comment.