Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "MF_ISMoodle"
- ISNeonMoodleLevels = {}
- function ISNeonMoodleLevels:new()
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.defaultMoodleSize = 48
- o.moodleAlpha = 1.0
- o.active = false
- o.hidden = false
- o.cache = {indicator = {} , background = {}}
- o.moodleSlotsDesiredPos = {};
- o.moodleSlotsPos = {};
- o.moodleLevel = {}
- o.options = {alwaysOnTop = false}
- o.moodlesCount = 0
- o.useCharacter = {}
- o.characterASleep = false
- o.goodBadNeutral = {}
- o.moodleLevel = {}
- o.panelY = 0
- o.panelX = 0
- o.currentMoodleSize = nil
- o.trackedMoodleFrameworkObjects = {}
- o.moodleParked = {}
- o.emptyPath = "media/ui/neonMoodleIndicator_empty.png"
- o.backgroundPathUnformatted = "media/ui/neonMoodleIndicator_%d_%d.png"
- o.indicatorPathUnformatted = "media/ui/neonMoodleIndicator_%d_%d_i.png"
- o.moodleFrameworkIntegrated = false
- o.moodleSlotsRestPos = 10000 -- digged from java zombie.ui.MoodlesUI.class #24 and other hardcoded lines
- o.moodleSlotsStartPos = 500 -- digged from java zombie.ui.MoodlesUI.class #421
- o.verticalMargin = 10 -- digged from java zombie.ui.MoodlesUI.class #379 , can be set with ISNeonMoodleLevels:setVerticalMargin(size)
- return o
- end
- function ISNeonMoodleLevels:setCharacter(character)
- self.useCharacter[1] = character
- end
- function ISNeonMoodleLevels:setCharacter2(character)
- self.useCharacter[2] = character
- end
- function ISNeonMoodleLevels:clearCache()
- self.cache = {}
- self.indicator = {}
- self.background = {}
- end
- function ISNeonMoodleLevels:hide()
- self.hidden = true
- end
- function ISNeonMoodleLevels:show()
- self.hidden = true
- end
- function ISNeonMoodleLevels:cacheTextureIfNeeded(object, texturePath, goodBadNeutralId, moodleLevel)
- if object[goodBadNeutralId] == nil or object[goodBadNeutralId][moodleLevel] == nil or object[goodBadNeutralId][moodleLevel].texture == nil and object[goodBadNeutralId][moodleLevel].texture ~= false then
- if goodBadNeutralId and goodBadNeutralId > 0 and goodBadNeutralId < 3 and moodleLevel > 0 and moodleLevel < 5 and texturePath then
- if object[goodBadNeutralId] == nil then
- object[goodBadNeutralId] = {}
- end
- if object[goodBadNeutralId][moodleLevel] == nil then
- object[goodBadNeutralId][moodleLevel] = {}
- object[goodBadNeutralId][moodleLevel].texture = nil
- object[goodBadNeutralId][moodleLevel].width = 128
- object[goodBadNeutralId][moodleLevel].height = 128
- object[goodBadNeutralId][moodleLevel].realWidth = 128
- object[goodBadNeutralId][moodleLevel].realHeight = 128
- object[goodBadNeutralId][moodleLevel].currentWidth = 128
- object[goodBadNeutralId][moodleLevel].moodleSize = 128
- end
- object[goodBadNeutralId][moodleLevel].texture = getTexture(texturePath)
- if object[goodBadNeutralId][moodleLevel].texture == nil then
- object[goodBadNeutralId][moodleLevel].texture = false
- else
- object[goodBadNeutralId][moodleLevel].realWidth = object[goodBadNeutralId][moodleLevel].texture:getWidth()
- object[goodBadNeutralId][moodleLevel].realHeight = object[goodBadNeutralId][moodleLevel].texture:getHeight()
- object[goodBadNeutralId][moodleLevel].width = object[goodBadNeutralId][moodleLevel].realWidth
- object[goodBadNeutralId][moodleLevel].height = object[goodBadNeutralId][moodleLevel].realHeight
- end
- else
- error("Check arguments")
- end
- end
- end
- function ISNeonMoodleLevels:start()
- self.active = true
- end
- function ISNeonMoodleLevels:stop()
- self.active = false
- end
- function ISNeonMoodleLevels:resetMoodlePosition(moodleId)
- self.moodleSlotsDesiredPos[moodleId] = self.moodleSlotsRestPos;
- self.moodleSlotsPos[moodleId] = self.moodleSlotsRestPos;
- end
- function ISNeonMoodleLevels:cacheSizes(object, moodleSize)
- object.height = moodleSize
- object.moodleSize = moodleSize
- object.realWidth = object.texture:getWidth()
- object.realHeight = object.texture:getHeight()
- if object.realWidth ~= object.realHeight then
- if object.realWidth == moodleSize then
- object.width = moodleSize
- else
- object.width = round(object.realWidth * moodleSize / object.realHeight, 0)
- end
- else
- object.width = moodleSize
- end
- end
- function ISNeonMoodleLevels:update(isGlobalPrerender)
- for _,player in pairs(self.useCharacter) do
- if player then
- self.moodlesCount = MoodleType.ToIndex(MoodleType.MAX)
- self.characterASleep = player:isAsleep()
- if isGlobalPrerender then
- self:prerender()
- end
- self:render(isGlobalPrerender)
- end
- end
- end
- function ISNeonMoodleLevels:render(isGlobalPrerender)
- if self.hidden then
- return
- end
- local moodlesUI = MoodlesUI.getInstance()
- if not self.useCharacter[1] or not self.active or not self.active or moodlesUI == nil or moodlesUI ~= nil and not moodlesUI:isVisible() then
- return
- end
- for moodleId = 0, self.moodlesCount -1 do
- if self.moodleSlotsPos[moodleId] ~= self.moodleSlotsRestPos and self.goodBadNeutral[moodleId] ~= nil and self.moodleLevel[moodleId] ~= nil then
- local goodBadNeutralId = self.goodBadNeutral[moodleId]
- local moodleLevel = self.moodleLevel[moodleId]
- if goodBadNeutralId and moodleLevel then
- local background = self.cache.background[goodBadNeutralId] and self.cache.background[goodBadNeutralId][moodleLevel] or nil
- local indicator = self.cache.indicator[goodBadNeutralId] and self.cache.indicator[goodBadNeutralId][moodleLevel] or nil
- if self:isRenderIndicatorOnly() or (not isGlobalPrerender and ( self.characterASleep or self.options.alwaysOnTop)) then
- UIManager.DrawTexture(indicator.texture, self.panelX, self.moodleSlotsPos[moodleId], indicator.width, indicator.height, self.moodleAlpha)
- elseif self:isRenderBackground() and isGlobalPrerender then
- UIManager.DrawTexture(background.texture, self.panelX, self.moodleSlotsPos[moodleId], background.width, background.height, self.moodleAlpha)
- end
- end
- end
- end
- end
- function ISNeonMoodleLevels:prerender()
- local moodlesUI = MoodlesUI.getInstance()
- if not self.active or moodlesUI ~= nil and not moodlesUI:isVisible() then
- return
- end
- local moodleSize = self:getMoodleSize()
- for _,player in pairs(self.useCharacter) do
- if player ~= nil and player:getMoodles() ~= nil then
- local moodles = player:getMoodles()
- local moodlesUI = MoodlesUI.getInstance()
- local renderedId = 0
- self.panelY = moodlesUI:getAbsoluteY()
- self.panelX = moodlesUI:getAbsoluteX()
- for moodleId = 0, self.moodlesCount - 1 do
- local moodleType = MoodleType.FromIndex(moodleId)
- local moodleLevel = moodles:getMoodleLevel(moodleType)
- local goodBadNeutralId = moodles:getGoodBadNeutral(moodleId)
- self.goodBadNeutral[moodleId] = goodBadNeutralId
- self.moodleLevel[moodleId] = moodleLevel
- if self.moodleSlotsDesiredPos[moodleId] == nil and self.moodleSlotsPos[moodleId] == nil then
- self:resetMoodlePosition(moodleId)
- end
- if (moodleType == MoodleType.FoodEaten) and moodleLevel < 3 then
- -- reset positions
- self:resetMoodlePosition(moodleId)
- self.moodleLevel[moodleId] = moodleLevel -- but keep real level?
- elseif moodleLevel > 0 then
- -- Cache background texture
- self:cacheTextureIfNeeded(self.cache.background,string.format(self.backgroundPathUnformatted, goodBadNeutralId, moodleLevel), goodBadNeutralId, moodleLevel)
- -- Cache indicator texture
- self:cacheTextureIfNeeded(self.cache.indicator,string.format(self.indicatorPathUnformatted, goodBadNeutralId, moodleLevel), goodBadNeutralId, moodleLevel)
- local background = self.cache.background[goodBadNeutralId][moodleLevel]
- local indicator = self.cache.indicator[goodBadNeutralId][moodleLevel]
- -- Cache background sizes
- if background and background.texture and background.moodleSize ~= moodleSize then
- self:cacheSizes(background, moodleSize)
- end
- -- Cache indicator sizes
- if indicator and indicator.texture and indicator.moodleSize ~= moodleSize then
- self:cacheSizes(indicator, moodleSize)
- end
- -- Recalculate position
- if self.moodleLevel[moodleId] ~= moodleLevel then
- self.moodleLevel[moodleId] = moodleLevel
- end
- self.moodleParked[moodleId] = self.moodleSlotsPos[moodleId] == self.moodleSlotsDesiredPos[moodleId]
- self.moodleSlotsDesiredPos[moodleId] = self.panelY + (self.verticalMargin + moodleSize) * renderedId
- if self.moodleSlotsPos[moodleId] == self.moodleSlotsRestPos then
- self.moodleSlotsPos[moodleId] = self.moodleSlotsDesiredPos[moodleId] + self.moodleSlotsStartPos
- end
- if math.abs(self.moodleSlotsPos[moodleId] - self.moodleSlotsDesiredPos[moodleId]) > 0.8 then
- if not self.moodleParked[moodleId] then
- self.moodleSlotsPos[moodleId] = self.moodleSlotsPos[moodleId] + (self.moodleSlotsDesiredPos[moodleId] - self.moodleSlotsPos[moodleId]) * 0.15
- end
- else
- self.moodleSlotsPos[moodleId] = self.moodleSlotsDesiredPos[moodleId]
- end
- renderedId = renderedId + 1
- else
- self:resetMoodlePosition(moodleId)
- self.moodleLevel[moodleId] = 0
- end
- end
- end
- end
- end
- function ISNeonMoodleLevels:setVerticalMargin(size)
- if size and size >= 0 then
- self.verticalMargin = size
- else
- error("Wrong value. Should be positive number")
- end
- end
- function ISNeonMoodleLevels:getVerticalMargin()
- return self.verticalMargin
- end
- function ISNeonMoodleLevels:setDefaultMoodleSize(size)
- if size and size >= 0 then
- self.defaultMoodleSize = size
- else
- error("Wrong value. Should be positive number")
- end
- end
- function ISNeonMoodleLevels:getDefaultMoodleSize()
- return self.defaultMoodleSize
- end
- function ISNeonMoodleLevels:getMoodleSize()
- -- Get Preset
- if self.currentMoodleSize then
- return self.currentMoodleSize
- end
- local moodleSize = getCore():getOptionMoodleSize()
- -- Auto size
- if moodleSize == 7 then
- local fontEnum = UIFont.Small
- return getTextManager():getFontFromEnum(fontEnum):getLineHeight()*3 -- from java zombie.ui.MoodlesUI.class #205
- elseif moodleSize == 6 then
- moodleSize = moodleSize + 1
- elseif moodleSize > 7 then
- return self.defaultMoodleSize
- end
- self.currentMoodleSize = (moodleSize + 1) * 16
- return self.currentMoodleSize
- end
- function ISNeonMoodleLevels:applyOptions()
- local newOptions = PZAPI.ModOptions:getOptions("neonMoodleLevels")
- self.options.alwaysOnTop = newOptions:getOption("alwaysOnTop"):getValue()
- self.options.renderBackground = newOptions:getOption("renderBackground"):getValue()
- self.options.renderIndicator = newOptions:getOption("renderIndicator"):getValue()
- self.options.integrateMoodleFramework = newOptions:getOption("integrateMoodleFramework"):getValue()
- if self.moodleFrameworkIntegrated or self.options.integrateMoodleFramework then
- for i, object in pairs(self.trackedMoodleFrameworkObjects) do
- self:updateMoodleFrameworkObjectTextures(object)
- end
- if not self.options.integrateMoodleFramework then
- self.moodleFrameworkIntegrated = false
- end
- end
- end
- function ISNeonMoodleLevels:initConfig()
- local PZOptions = PZAPI.ModOptions:create("neonMoodleLevels", "Neon Moodle Levels")
- PZOptions:addTickBox("renderBackground", getText("UI_nML_renderBackground"), true, "UI_nML_renderBackground_tooltip")
- PZOptions:addTickBox("renderIndicator", getText("UI_nML_renderIndicator"), true, "UI_nML_renderIndicator_tooltip")
- PZOptions:addTickBox("alwaysOnTop", getText("UI_nML_alwaysOnTop"), false, "UI_nML_alwaysOnTop_tooltip")
- PZOptions:addTickBox("integrateMoodleFramework", getText("UI_nML_integrateMoodleFramework"), true, "UI_nML_integrateMoodleFramework_tooltip")
- local s = self
- PZOptions.apply = function (self)
- s:applyOptions()
- end
- Events.OnMainMenuEnter.Add(function()
- PZOptions:apply()
- end)
- self:applyOptions()
- end
- function ISNeonMoodleLevels:isRenderIndicatorOnly()
- return not self.options.renderBackground and (self.options.alwaysOnTop or self.options.renderIndicator)
- end
- function ISNeonMoodleLevels:isRenderBackground()
- return self.options.renderBackground
- end
- -- moodleFrameWork integration api
- function ISNeonMoodleLevels:trackMoodleFrameworkObject(object)
- table.insert(self.trackedMoodleFrameworkObjects, object)
- end
- function ISNeonMoodleLevels:updateMoodleFrameworkObjectTextures(object)
- if object == nil or object.setBackground == nil then
- return
- end
- if self.options.integrateMoodleFramework then
- local empty = true
- local indicatorOnly = false
- local unformated = ""
- if self:isRenderIndicatorOnly() then
- empty = false
- indicatorOnly = true
- unformated = self.indicatorPathUnformatted
- elseif self:isRenderBackground() then
- empty = false
- unformated = self.backgroundPathUnformatted
- end
- for g = 1, 2 do
- for l = 1, 4 do
- if empty then
- object:setBackground(g,l,getTexture(self.emptyPath))
- else
- object:setBackground(g,l,getTexture(string.format(unformated,g,l)))
- end
- end
- end
- self.moodleFrameworkIntegrated = true
- elseif self.moodleFrameworkIntegrated then
- for g = 1, 2 do
- for l = 1, 4 do
- if object.bkg and object.bkg[g] then
- object.bkg[g][l] = nil
- end
- end
- end
- end
- end
- -- handler
- ISNeonMoodleLevelsHandle = ISNeonMoodleLevels:new()
- ISNeonMoodleLevelsHandle:initConfig()
- ISNeonMoodleLevelsHandle:start()
- local function onPreUIDraw()
- if isServer() then return end
- ISNeonMoodleLevelsHandle:update(true)
- end
- local function onPostUIDraw()
- if isServer() then return end
- ISNeonMoodleLevelsHandle:update(false)
- end
- local function updateCharacter(id,player)
- if player == getSpecificPlayer(0) then
- ISNeonMoodleLevelsHandle:setCharacter(player)
- elseif player == getSpecificPlayer(1) then
- ISNeonMoodleLevelsHandle:setCharacter2(player)
- end
- end
- local function onloadMoodles ()
- ISNeonMoodleLevelsHandle.currentMoodleSize = nil
- end
- Events.OnPreUIDraw.Add(onPreUIDraw)
- Events.OnPostUIDraw.Add(onPostUIDraw)
- Events.OnCreatePlayer.Add(updateCharacter)
- Events.OnLoad.Add(onloadMoodles)
- -- moodleFramework settings integration
- if MF ~= nil then
- local oldNew = MF.ISMoodle.new
- function MF.ISMoodle.new(self,moodleName,character)
- local o = oldNew(self,moodleName,character)
- ISNeonMoodleLevelsHandle:trackMoodleFrameworkObject(o)
- ISNeonMoodleLevelsHandle:updateMoodleFrameworkObjectTextures(o)
- return o
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement