Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add bar healthbars. #5399

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
193 changes: 193 additions & 0 deletions LuaRules/Gadgets/unit_healthbars_widget_forwarding.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
function gadget:GetInfo()
return {
name = "Healthbars Widget Forwarding",
desc = "Notifies widgets that a feature reclaim or resurrect action has begun, updates GL Uniforms, and also notifies on capture start, emp damage, reload",
author = "Beherith", -- ty Sprung
date = "2021.11.25",
license = "GNU GPL, v2 or later",
layer = -1,
enabled = true
}
end


if gadgetHandler:IsSyncedCode() then

local forwardedFeatureIDs = {} -- so we only forward the start event once
local forwardedCaptureUnitIDs = {}
local weapondefsreload = {}
local unitreloadframe = {} -- maps unitID to next frame it can shoot its primary weapon, cause lasers retrigger projetileCreated every frame
local minReloadTime = 5 -- in concerto with healthbars widget

function gadget:AllowFeatureBuildStep(builderID, builderTeam, featureID, featureDefID, step)
-- VERY IMPORTANT: This also gets called on resurrect!, but its very hard to tell if its a reclaim, but we can make the mother of all assumptions:
-- features die at 100% metal value
-- step is negative if 'reclaiming'
-- step is large positive if refilling
-- step is small positive if rezzing

local gf = Spring.GetGameFrame()
--Spring.Echo("AllowFeatureBuildStep",gf,builderID, builderTeam, featureID, featureDefID, step)
if forwardedFeatureIDs[featureID] == nil or forwardedFeatureIDs[featureID] < gf then
forwardedFeatureIDs[featureID] = gf
SendToUnsynced("featureReclaimFrame", featureID, step)
end
return true
end

function gadget:AllowUnitCaptureStep(builderID, builderTeam, unitID, unitDefID, part)
if forwardedCaptureUnitIDs[unitID] == nil then
forwardedCaptureUnitIDs[unitID] = true
SendToUnsynced("unitCaptureFrame", unitID, part)
end
return true
end

function gadget:FeatureDestroyed(featureID, allyTeamID)
forwardedFeatureIDs[featureID] = nil
end

function gadget:UnitDestroyed(unitID)
forwardedCaptureUnitIDs[unitID] = nil
unitreloadframe[unitID] = nil
end

function gadget:UnitTaken(unitID)
forwardedCaptureUnitIDs[unitID] = nil
end

function gadget:Initialize()
for udefID, unitDef in pairs(UnitDefs) do
local weapons = unitDef.weapons
local watchweaponID = nil
local longestreloadtime = -1
local longestreloadindex
for i = 1, #weapons do
local WeaponDefID = weapons[i].weaponDef
local WeaponDef = WeaponDefs[WeaponDefID]
if WeaponDef.reload and WeaponDef.reload >0 and WeaponDef.reload >= longestreloadtime then
longestreloadtime = WeaponDef.reload
watchweaponID = WeaponDefID
longestreloadindex = i
end
end
if watchweaponID and longestreloadtime > minReloadTime then
--Spring.Echo("Unit with watched reload time:", unitDef.name, longestreloadtime, watchweaponID, udefID)
weapondefsreload[watchweaponID] = longestreloadindex
Script.SetWatchProjectile(watchweaponID, true)
end
end
end

function gadget:ProjectileCreated(projectileID, ownerID, weaponID) -- needs: Script.SetWatchProjectile(weaponDefID, true)
--local unitDef = Spring.GetUnitDefID(ownerID)
--Spring.Echo("gadget:ProjectileCreated(",projectileID, ownerID, weaponID,weapondefsreload[weaponID],unitreloadframe[ownerID], ")")
local weaponIndex = weapondefsreload[weaponID]

if weaponIndex then
local gf = Spring.GetGameFrame()
local reloadFrame = Spring.GetUnitWeaponState(ownerID, weaponIndex, 'reloadFrame')

if unitreloadframe[ownerID] == nil or unitreloadframe[ownerID] <= gf then
SendToUnsynced("projetileCreatedReload", projectileID, ownerID, weaponID)
unitreloadframe[ownerID] = reloadFrame
end
end
end

else

local glSetFeatureBufferUniforms = gl.SetFeatureBufferUniforms
local GetFeatureResources = Spring.GetFeatureResources
local rezreclaim = {0.0, 1.0} -- this is just a small table cache, so we dont allocate a new table for every update
local forwardedFeatureIDsResurrect = {} -- so we only forward the start event once
local forwardedFeatureIDsReclaim = {} -- so we only forward the start event once
local myTeamID = Spring.GetMyTeamID()
local myAllyTeamID = Spring.GetMyAllyTeamID()
local _, fullview = Spring.GetSpectatingState()
local IsUnitInLos = Spring.IsUnitInLos
local GetFeatureHealth = Spring.GetFeatureHealth
local headless = false

function gadget:PlayerChanged(playerID)
myTeamID = Spring.GetMyTeamID()
myAllyTeamID = Spring.GetMyAllyTeamID()
_, fullview = Spring.GetSpectatingState()
end

function featureReclaimFrame(cmd, featureID, step)
--Spring.Echo("HandleFeatureReclaimStarted", featureID)
rezreclaim[1] = select(3, GetFeatureHealth( featureID )) -- resurrect progress
rezreclaim[2] = select(5, GetFeatureResources(featureID)) -- reclaim percent

--Spring.Echo('rezreclaim', rezreclaim[1], rezreclaim[2])

if not headless then glSetFeatureBufferUniforms(featureID, rezreclaim, 1) end -- update GL, at offset of 1

if step > 0 and forwardedFeatureIDsResurrect[featureID] == nil and Script.LuaUI("FeatureReclaimStartedHealthbars") then
forwardedFeatureIDsResurrect[featureID] = true
--Spring.Echo("HandleFeatureReclaimStartedHealthbars", featureID, step)
Script.LuaUI.FeatureReclaimStartedHealthbars(featureID, step)
end

if step < 0 and forwardedFeatureIDsReclaim[featureID] == nil and Script.LuaUI("FeatureReclaimStartedHealthbars") then
forwardedFeatureIDsReclaim[featureID] = true
--Spring.Echo("HandleFeatureReclaimStartedHealthbars", featureID, step)
Script.LuaUI.FeatureReclaimStartedHealthbars(featureID, step)
end
end

function unitCaptureFrame(cmd, unitID, step)
if not fullview and not IsUnitInLos(unitID, myAllyTeamID) then return end
if Script.LuaUI("UnitCaptureStartedHealthbars") then
--Spring.Echo("UnitCaptureStartedHealthbars", unitID, step)
Script.LuaUI.UnitCaptureStartedHealthbars(unitID, step)
end
end

function projetileCreatedReload(cmd, projectileID, ownerID, weaponID)
--Spring.Echo("unsynced projetileCreatedReload", projectileID, ownerID, weaponID, fullview, Spring.GetUnitTeam(ownerID))
if fullview or Spring.GetUnitTeam(ownerID) == myTeamID then
if Script.LuaUI("ProjectileCreatedReloadHB") then
--Spring.Echo("G:ProjectileCreatedReloadHB", projectileID, ownerID, weaponID)
Script.LuaUI.ProjectileCreatedReloadHB(projectileID, ownerID, weaponID)
end
end
end

function gadget:FeatureDestroyed(featureID, allyTeamID)
forwardedFeatureIDsResurrect[featureID] = nil
forwardedFeatureIDsReclaim[featureID] = nil
end

function gadget:UnitDamaged(unitID, unitDefID, unitTeam, damage, paralyzer)
--Spring.Echo("gadget:UnitDamaged",unitID, unitDefID, unitTeam, damage, paralyzer)
if paralyzer then
if not fullview and not IsUnitInLos(unitID, myAllyTeamID) then return end

if damage > 0 then
if Script.LuaUI("UnitParalyzeDamageHealthbars") then
--Spring.Echo("UnitParalyzeDamageHealthbars", unitID, step)
Script.LuaUI.UnitParalyzeDamageHealthbars(unitID, unitDefID, damage)
end
if Script.LuaUI("UnitParalyzeDamageEffect") then
--Spring.Echo("UnitParalyzeDamageHealthbars", unitID, step)
Script.LuaUI.UnitParalyzeDamageEffect(unitID, unitDefID, damage)
end
end
end
end

function gadget:Initialize()
headless = Spring.GetConfigInt("Headless", 0) > 0
gadgetHandler:AddSyncAction("featureReclaimFrame", featureReclaimFrame)
gadgetHandler:AddSyncAction("unitCaptureFrame", unitCaptureFrame)
gadgetHandler:AddSyncAction("projetileCreatedReload", projetileCreatedReload)
end

function gadget:ShutDown()
gadgetHandler:RemoveSyncAction("featureReclaimFrame")
gadgetHandler:RemoveSyncAction("unitCaptureFrame")
gadgetHandler:RemoveSyncAction("projetileCreatedReload")
end
end
Binary file added LuaUI/Images/healthbars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 63 additions & 0 deletions LuaUI/Widgets/Shaders/HealthbarsGL4.frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#version 420
#extension GL_ARB_uniform_buffer_object : require
#extension GL_ARB_shading_language_420pack: require

// This file is going to be licensed under some sort of GPL-compatible license, but authors are dragging
// their feet. Avoid copying for now (unless this header rots for years on end), and check back later.
// See https://github.com/ZeroK-RTS/Zero-K/issues/5328

//__ENGINEUNIFORMBUFFERDEFS__
//__DEFINES__

#line 30000
in DataGS {
vec4 g_color;
vec4 g_uv;
vec4 g_rect;
vec2 g_loc;
float g_corner_radius;
};

uniform sampler2D healthbartexture;
out vec4 fragColor;

void main(void)
{
float width = g_rect.z;
float height = g_rect.w;

vec2 loc = g_loc;

float center_x = g_rect.x + (width / 2);
float center_y = g_rect.y + (height / 2);

// Map fragment pos to first quadrant, taking rect center as origin
if (loc.x > center_x) {
loc.x += 2 * (center_x - loc.x);
}

if (loc.y > center_y) {
loc.y += 2 * (center_y - loc.y);
}

vec2 r0 = vec2(g_rect.x + g_corner_radius, g_rect.y + g_corner_radius);

if (loc.x < r0.x && loc.y < r0.y) {
//discard;
/*
if (loc.x - g_rect.x + (loc.y - g_rect.y) < g_corner_radius) {
discard;
}
*/

if (distance(loc, r0) > g_corner_radius) {
discard;
}
}

vec4 texcolor = vec4(1.0);
texcolor = texture(healthbartexture, g_uv.xy);
texcolor.a *= g_color.a;
fragColor.rgba = mix(g_color, texcolor, g_uv.z);
if (fragColor.a < 0.05) discard;
}
Loading