-
-
Save Bonuspunkt/3d6f86af2c70728c5a6a to your computer and use it in GitHub Desktop.
Guitar Hero style item timers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "base/internal/ui/reflexcore" | |
-------------------------------------------------------------------------------- | |
-- HELPER | |
-------------------------------------------------------------------------------- | |
local function add(array, value) | |
array[#array + 1] = value | |
end | |
local trueStack = function(player) | |
return math.min( | |
player.armor, | |
player.health * (player.armorProtection + 1) | |
) + player.health; | |
end | |
local canPickup = function(player, itemType) | |
if itemType == _G.PICKUP_TYPE_HEALTH100 then | |
return player.health < 200 | |
elseif itemType == _G.PICKUP_TYPE_ARMOR150 then | |
return player.armorProtection < 2 | |
or player.armor < 200 | |
elseif itemType == _G.PICKUP_TYPE_ARMOR100 then | |
return player.armorProtection == 2 and player.armor < 133 | |
or player.armorProtection ~= 2 and player.armor < 150 | |
elseif itemType == _G.PICKUP_TYPE_ARMOR50 then | |
return player.armorProtection == 2 and player.armor < 66 | |
or player.armorProtection == 1 and player.armor < 75 | |
or player.armorProtection == 0 and player.armor < 100 | |
elseif itemType == _G.PICKUP_TYPE_POWERUPCARNAGE then | |
return player.carnageTimer == 0 | |
end | |
return false | |
end | |
local take = function(player, itemType) | |
if not canPickup(player, itemType) then | |
return { | |
armorProtection = player.armorProtection, | |
armor = player.armor, | |
health = player.health | |
} | |
elseif itemType == _G.PICKUP_TYPE_HEALTH100 then | |
return { | |
armorProtection = player.armorProtection, | |
armor = player.armor, | |
health = math.min(200, player.health + 100) | |
} | |
elseif itemType == _G.PICKUP_TYPE_ARMOR150 then | |
return { | |
armorProtection = 2, | |
armor = math.min(200, player.armor + 150), | |
health = player.health | |
} | |
elseif itemType == _G.PICKUP_TYPE_ARMOR100 then | |
return { | |
armorProtection = 1, | |
armor = math.min(150, player.armor + 100), | |
health = player.health | |
} | |
elseif itemType == _G.PICKUP_TYPE_ARMOR50 then | |
return { | |
armorProtection = 0, | |
armor = math.min(100, player.armor + 50), | |
health = player.health | |
} | |
end | |
end | |
local priorize = function(player, itemType) | |
if itemType == _G.PICKUP_TYPE_POWERUPCARNAGE then | |
return 401; | |
end | |
return trueStack(take(player, itemType)) | |
end | |
local armorColors = { | |
_G.Color(0, 255, 0, 255), | |
_G.Color(255, 255, 0, 255), | |
_G.Color(255, 0, 0, 255) | |
} | |
local function colorLerp(colorA, colorB, k) | |
return _G.Color( | |
_G.lerp(colorA.r, colorB.r, k), | |
_G.lerp(colorA.g, colorB.g, k), | |
_G.lerp(colorA.b, colorB.b, k), | |
_G.lerp(colorA.a, colorB.a, k) | |
) | |
end | |
local drawArmor = function(x, y, size, armorProtection, lerpColor) | |
local color = armorColors[armorProtection + 1]; | |
if lerpColor then | |
color = colorLerp(color, lerpColor, .75) | |
end | |
_G.nvgSave() | |
_G.nvgFillColor(color); | |
_G.nvgSvg("internal/ui/icons/armor", x, y, size) | |
_G.nvgRestore() | |
end | |
local drawMega = function(x, y, size, hasMega) | |
local healthColor | |
if hasMega then | |
healthColor = _G.Color(60,80,255) | |
else | |
healthColor = _G.Color(64,64,64) | |
end | |
_G.nvgSave() | |
_G.nvgFillColor(healthColor); | |
_G.nvgSvg("internal/ui/icons/health", x, y, size) | |
_G.nvgRestore() | |
end | |
local drawCarnage = function(x, y, size, carnageTimer) | |
if carnageTimer <= 0 then return end | |
_G.nvgSave() | |
_G.nvgFillColor(_G.Color(255,120,128)) | |
_G.nvgSvg("internal/ui/icons/carnage", x, y, size) | |
_G.nvgRestore() | |
end | |
local function funcArray(array) | |
return { | |
map = function(func) | |
local newTable = {} | |
for i = 1, #array do | |
newTable[i] = func(array[i], i, array) | |
end | |
return funcArray(newTable) | |
end, | |
filter = function(func) | |
local newTable = {} | |
for i = 1, #array do | |
if func(array[i], i) then | |
newTable[#newTable+1] = array[i] | |
end | |
end | |
return funcArray(newTable) | |
end, | |
forEach = function(func) | |
for i = 1, #array do | |
func(array[i], i, array) | |
end | |
end, | |
reduce = function(func, initialValue) | |
for i = 1, #array do | |
initialValue = func(initialValue, array[i], i, array); | |
end | |
return initialValue | |
end, | |
sort = function(func) | |
local newArray = {} | |
for i = 1, #array do | |
newArray[i] = array[i] | |
end | |
table.sort(newArray, func) | |
return funcArray(newArray) | |
end, | |
first = function(func) | |
for i = 1, #array do | |
if func(array[i], i, array) then | |
return array[i] | |
end | |
end | |
end, | |
groupBy = function(func) | |
local newArray = funcArray({}) | |
for i = 1, #array do | |
local key = func(array[i], i, array); | |
local match = newArray.first(function(other) return other.key == key end) | |
if not match then | |
match = { key = key, values = funcArray({ array[i] }) } | |
add(newArray.raw, match) | |
else | |
add(match.values.raw, array[i]); | |
end | |
end | |
return newArray | |
end, | |
concat = function(otherArray) | |
local result = {} | |
for i = 1, #array do | |
add(result, array[i]) | |
end | |
if otherArray.raw then otherArray = otherArray.raw end | |
for j = 1, #otherArray do | |
add(result, otherArray[j]) | |
end | |
return funcArray(result) | |
end, | |
-- escape the fancyness | |
raw = array | |
} | |
end | |
-------------------------------------------------------------------------------- | |
-- CONFIG | |
-------------------------------------------------------------------------------- | |
local lineHeight = 40 | |
local iconRad = lineHeight/2 - 2 | |
local fontSize = 50 | |
local showTime = true | |
local showTrueStack = true | |
-------------------------------------------------------------------------------- | |
-- WIDGET | |
-------------------------------------------------------------------------------- | |
_G.ItemHero = | |
{ | |
draw = function() | |
if not _G.shouldShowHUD() then return end; | |
local player = _G.getPlayer() | |
-- draw spawn area | |
local pickupCount = #_G.pickupTimers | |
_G.nvgBeginPath(); | |
_G.nvgRoundedRect( | |
-100 - iconRad/2, | |
lineHeight/2, | |
iconRad*2, | |
lineHeight * pickupCount, | |
5 | |
) | |
_G.nvgFillColor(_G.Color(0,0,0,128)) | |
_G.nvgFill() | |
_G.nvgTextAlign(_G.NVG_ALIGN_CENTER, _G.NVG_ALIGN_MIDDLE) | |
_G.nvgFontSize(fontSize); | |
_G.nvgFillColor(_G.Color(255,255,255,127)) | |
funcArray(_G.pickupTimers) | |
.groupBy(function(pickup) return pickup.type end) | |
.map(function(group) | |
return group.values.map( | |
function(pickup, i, array) | |
local index = 0 | |
if #array > 1 then | |
index =i | |
end | |
return { | |
index = index, | |
respawn = pickup.timeUntilRespawn, | |
type = pickup.type, | |
canSpawn = pickup.canSpawn, | |
priority = priorize(player, pickup.type), | |
canPickup = canPickup(player, pickup.type) | |
} | |
end) | |
end) | |
.reduce(function(prev, curr) | |
return prev.concat(curr) | |
end, funcArray({})) | |
.sort(function(a, b) | |
return a.type > b.type | |
end) | |
.forEach(function(pickup, i) | |
-- draw time | |
if showTime then | |
local time | |
_G.nvgTextAlign(_G.NVG_ALIGN_RIGHT, _G.NVG_ALIGN_MIDDLE) | |
if pickup.respawn ~= 0 then | |
time = math.ceil(pickup.respawn / 1000) | |
elseif pickup.canSpawn then | |
time = "-" | |
else | |
time = "held" | |
end | |
_G.nvgText(-140, lineHeight * i, time) | |
end | |
-- draw icon | |
local x = pickup.respawn/100 + iconRad/2 | |
if pickup.type == 60 then | |
drawCarnage(-100 + x, lineHeight * i, iconRad, 1) | |
elseif pickup.type < 50 then | |
if not pickup.canSpawn then x = 300 end | |
drawMega(-100 + x, lineHeight * i, iconRad, pickup.canSpawn) | |
else | |
local lerpColor | |
if not pickup.canPickup then | |
lerpColor = _G.Color(0,0,0) | |
end | |
drawArmor(-100 + x, lineHeight * i, iconRad, pickup.type - _G.PICKUP_TYPE_ARMOR50, lerpColor) | |
end | |
if pickup.index > 0 then | |
_G.nvgSave() | |
for blur, color in pairs({_G.Color(0,0,0), _G.Color(255,255,255)}) do | |
_G.nvgFillColor(color) | |
_G.nvgFontBlur((2 - blur) * 10) | |
_G.nvgFontSize(fontSize * 2 / 3); | |
_G.nvgTextAlign(_G.NVG_ALIGN_CENTER, _G.NVG_ALIGN_MIDDLE) | |
_G.nvgText(-100 + x + iconRad/2, lineHeight * i + iconRad/2, pickup.index) | |
end | |
_G.nvgRestore() | |
end | |
end) | |
end | |
}; | |
_G.registerWidget("ItemHero"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment