Skip to content

Commit

Permalink
Groups UI: Add red glow tint depending on group damage / units lost
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due committed Aug 29, 2023
1 parent 09eb246 commit 8571bcb
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
1 change: 1 addition & 0 deletions data/base/images/intfac.img
Expand Up @@ -446,3 +446,4 @@
0,0,image_volume_mute.png
0,0,image_but_empty_up.png
0,0,image_but_empty_down.png
0,0,image_but_inner_glow.png
Binary file added data/base/images/intfac/image_but_inner_glow.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 19 additions & 8 deletions src/hci.cpp
Expand Up @@ -176,6 +176,7 @@ static enum _edit_pos_mode

OBJECT_MODE objMode;
std::shared_ptr<BaseObjectsController> interfaceController = nullptr;
std::shared_ptr<GroupsForum> groupsUI = nullptr;

/* The current stats list being used by the stats screen */
static BASE_STATS **ppsStatsList;
Expand Down Expand Up @@ -965,6 +966,8 @@ void interfaceShutDown()
replayOverlayScreen = nullptr;
}

groupsUI = nullptr;

psWScreen = nullptr;

free(apsStructStatsList);
Expand Down Expand Up @@ -1035,10 +1038,9 @@ void intDoScreenRefresh()
{
if (IntGroupsRefreshPending && getGroupButtonEnabled())
{
GroupsForum* groupsForum = (GroupsForum*)widgGetFromID(psWScreen, IDOBJ_GROUP);
if (groupsForum)
if (groupsUI)
{
groupsForum->updateData();
groupsUI->updateData();
}
IntGroupsRefreshPending = false;
}
Expand Down Expand Up @@ -1493,6 +1495,7 @@ INT_RETVAL intRunWidgets()
addIntelScreen();
// remove the groups Menu
widgDelete(psWScreen, IDOBJ_GROUP);
groupsUI.reset();
reticuleCallback(RETBUT_INTELMAP);
break;

Expand All @@ -1507,6 +1510,7 @@ INT_RETVAL intRunWidgets()
intShowPowerBar();
// remove the groups Menu
widgDelete(psWScreen, IDOBJ_GROUP);
groupsUI.reset();
intAddDesign(false);
intMode = INT_DESIGN;
gInputManager.contexts().pushState();
Expand Down Expand Up @@ -2036,23 +2040,30 @@ void intGroupsChanged(bool selectionOnly)

void intGroupDamaged(UBYTE group, uint64_t additionalDamage, bool unitKilled)
{
// FUTURE TODO: Could update the groups UI with group damage lastTime, severity, etc
if (getGroupButtonEnabled())
{
groupsUI->addGroupDamageForCurrentTick(group, additionalDamage, unitKilled);
}
}

bool intShowGroupSelectionMenu()
{
if (getGroupButtonEnabled())
{
GroupsForum* groupsForum = (GroupsForum*)widgGetFromID(psWScreen, IDOBJ_GROUP);
if (!groupsForum)
GroupsForum* groupsUIFormWidg = (GroupsForum*)widgGetFromID(psWScreen, IDOBJ_GROUP);
if (!groupsUIFormWidg)
{
auto newGroupsForum = GroupsForum::make();
psWScreen->psForm->attach(newGroupsForum);
if (!groupsUI)
{
groupsUI = GroupsForum::make();
}
psWScreen->psForm->attach(groupsUI);
}
}
else
{
widgDelete(psWScreen, IDOBJ_GROUP);
groupsUI.reset();
}
return true;
}
Expand Down
73 changes: 72 additions & 1 deletion src/hci/groups.cpp
Expand Up @@ -39,7 +39,15 @@ class GroupsUIController: public std::enable_shared_from_this<GroupsUIController
struct GroupDisplayInfo
{
size_t numberInGroup = 0;
uint64_t totalGroupMaxHealth = 0;
DROID_TEMPLATE displayDroidTemplate;

uint8_t currAttackGlowAlpha = 0;

// used for calculating display info
uint32_t lastAttackedGameTime = 0;
uint64_t lastAccumulatedDamage = 0;
uint64_t lastUnitsKilled = 0;
};
public:
GroupDisplayInfo* getGroupInfoAt(size_t index)
Expand All @@ -55,6 +63,18 @@ class GroupsUIController: public std::enable_shared_from_this<GroupsUIController

void updateData();

void addGroupDamageForCurrentTick(size_t group, uint64_t additionalDamage, bool unitKilled)
{
auto& curr = groupInfo[group];
curr.lastAttackedGameTime = gameTime;
curr.lastAccumulatedDamage += additionalDamage;
if (unitKilled)
{
++curr.lastUnitsKilled;
curr.lastAccumulatedDamage = std::max<uint64_t>(curr.lastAccumulatedDamage, 1);
}
}

void selectGroup(size_t groupNumber)
{
// select the group
Expand All @@ -77,10 +97,11 @@ class GroupButton : public DynamicIntFancyButton
std::shared_ptr<GroupsUIController> controller;
std::shared_ptr<W_LABEL> groupNumberLabel;
std::shared_ptr<W_LABEL> groupCountLabel;
size_t groupNumber;
uint32_t lastUpdatedGlowAlphaTime = 0;
protected:
GroupButton() : DynamicIntFancyButton() { }
public:
size_t groupNumber;
static std::shared_ptr<GroupButton> make(const std::shared_ptr<GroupsUIController>& controller, size_t groupNumber)
{
class make_shared_enabler: public GroupButton {};
Expand All @@ -102,6 +123,8 @@ class GroupButton : public DynamicIntFancyButton
groupCountLabel->setGeometry(OBJ_TEXTX + 40, OBJ_B1TEXTY + 20, 16, 16);
groupCountLabel->setString("");
groupCountLabel->setTransparentToMouse(true);

buttonBackgroundEmpty = true;
}

void clickPrimary() override
Expand All @@ -122,6 +145,29 @@ class GroupButton : public DynamicIntFancyButton
{
return;
}

if (groupInfo->lastAccumulatedDamage > 0)
{
groupInfo->currAttackGlowAlpha = std::max<uint8_t>(groupInfo->currAttackGlowAlpha, accumulatedDamageToTargetGlowAlpha(groupInfo->lastAccumulatedDamage, groupInfo->totalGroupMaxHealth, groupInfo->lastUnitsKilled));
lastUpdatedGlowAlphaTime = realTime;
// reset consumed values
groupInfo->lastAccumulatedDamage = 0;
groupInfo->lastUnitsKilled = 0;
}
else if (groupInfo->currAttackGlowAlpha > 0 && (realTime - lastUpdatedGlowAlphaTime) > 100)
{
auto fadeAmount = 50 * (realTime - lastUpdatedGlowAlphaTime) / GAME_TICKS_PER_SEC;
if (fadeAmount > static_cast<int32_t>(groupInfo->currAttackGlowAlpha))
{
groupInfo->currAttackGlowAlpha = 0;
}
else
{
groupInfo->currAttackGlowAlpha -= static_cast<uint8_t>(fadeAmount);
}
lastUpdatedGlowAlphaTime = realTime;
}

if (!groupInfo->numberInGroup)
{
groupCountLabel->setString("");
Expand All @@ -132,6 +178,12 @@ class GroupButton : public DynamicIntFancyButton
displayIMD(AtlasImage(), ImdObject::DroidTemplate(&(groupInfo->displayDroidTemplate)), xOffset, yOffset);
groupCountLabel->setString(WzString::fromUtf8(astringf("%u", groupInfo->numberInGroup)));
}

if (groupInfo->currAttackGlowAlpha > 0)
{
// Based on damage, display an inner glow (animated)
iV_DrawImageTint(IntImages, IMAGE_BUT_INNER_GLOW, xOffset + x(), yOffset + y(), pal_RGBA(170, 0, 0, groupInfo->currAttackGlowAlpha));
}
}
std::string getTip() override
{
Expand All @@ -141,6 +193,17 @@ class GroupButton : public DynamicIntFancyButton
{
return false;
}
private:
#define MAX_DAMAGE_GLOW_ALPHA 100
inline uint8_t accumulatedDamageToTargetGlowAlpha(uint64_t accumulatedDamage, uint64_t totalGroupMaxHealth, uint64_t unitsKilled)
{
uint64_t damageVisualPercent = (accumulatedDamage * 100) / totalGroupMaxHealth;
if (unitsKilled > 0)
{
damageVisualPercent = 100;
}
return static_cast<uint8_t>((std::min<uint64_t>(damageVisualPercent, 100) * MAX_DAMAGE_GLOW_ALPHA) / 100);
}
};

void GroupsForum::display(int xOffset, int yOffset)
Expand Down Expand Up @@ -176,6 +239,7 @@ void GroupsUIController::updateData()
struct AccumulatedGroupInfo
{
size_t numberInGroup = 0;
uint64_t totalGroupMaxHealth = 0;
DROID *displayDroid = nullptr;
std::map<std::vector<uint32_t>, size_t> unitcounter;
size_t most_droids_of_same_type_in_group = 0;
Expand All @@ -200,13 +264,15 @@ void GroupsUIController::updateData()
currGroupInfo.displayDroid = psDroid;
}
currGroupInfo.numberInGroup++;
currGroupInfo.totalGroupMaxHealth += psDroid->originalBody;
}

for (size_t idx = 0; idx < calculatedGroupInfo.size(); ++idx)
{
const auto& calculatedInfo = calculatedGroupInfo[idx];
auto& storedGroupInfo = groupInfo[idx];
storedGroupInfo.numberInGroup = calculatedInfo.numberInGroup;
storedGroupInfo.totalGroupMaxHealth = calculatedInfo.totalGroupMaxHealth;
if (calculatedInfo.numberInGroup > 0)
{
// generate a DROID_TEMPLATE from the displayDroid
Expand All @@ -220,6 +286,11 @@ void GroupsForum::updateData()
groupsUIController->updateData();
}

void GroupsForum::addGroupDamageForCurrentTick(size_t group, uint64_t additionalDamage, bool unitKilled)
{
groupsUIController->addGroupDamageForCurrentTick(group, additionalDamage, unitKilled);
}

void GroupsForum::addTabList()
{
attach(groupsList = IntListTabWidget::make(TabAlignment::RightAligned));
Expand Down
1 change: 1 addition & 0 deletions src/hci/groups.h
Expand Up @@ -52,6 +52,7 @@ class GroupsForum: public IntFormAnimated
return widget;
}
void updateData();
void addGroupDamageForCurrentTick(size_t group, uint64_t additionalDamage, bool unitKilled);
private:
std::shared_ptr<GroupButton> makeGroupButton(size_t groupNumber);
void addTabList();
Expand Down
1 change: 1 addition & 0 deletions src/intfac.h
Expand Up @@ -480,6 +480,7 @@ enum INTFAC_TYPE
IMAGE_INTFAC_VOLUME_MUTE,
IMAGE_BUT_EMPTY_UP,
IMAGE_BUT_EMPTY_DOWN,
IMAGE_BUT_INNER_GLOW
};

#endif //__INCLUDED_SRC_INTFAC_H__

0 comments on commit 8571bcb

Please sign in to comment.