First concept Demo, just in the upper left corner without scaling, call skript function showPanel() to activate. This is my first time coding in Lua, so any hints appreciated
Code: Select all
function showPanel()
party.party:addConnector('onDrawGui', self.go.id, "renderRunePanel")
end
function hidePanel()
party.party:removeConnector('onDrawGui', self.go.id, "renderRunePanel")
end
-- definition of spells
QDMF_Spell = {}
QDMF_Spell.__index = QDMF_Spell
-- definition of runes
QDMF_Rune = {}
QDMF_Rune.__index = QDMF_Rune
QDMF_Rune.tiers = 3
QDMF_Rune.ways = 9
-- the spellphrase-pseudoclass-ctor
function QDMF_PhraseCreate(runestring)
local phrase = {}
--[[
# clear this phrase ]]--
function phrase.clear(self)
self.name = ""
self.align = ""
self.runes = {}
self.power = 0
self.cost = 0
self.minimum = 0
self._length = 0
self._valid = false
self._tested = false
self.string = ""
end
--[[
# add a rune to the phrase, invalidating it ]]--
function phrase.add(self, rune, pos)
local word
if (rune == nil) then
return false end
if (type(rune) ~= "table") then
rune = QDMF_Rune[rune]
if (rune == nil) then return false end
end
if self:hasRuneIndex(rune.index) then
return false end
if (rune.tier == 0) then
self.power = rune.way + 1 -- need 0 for "no powerrune selected"
return true end
if (pos ~= nil and pos > 0) then
self.runes[pos - 1] = rune
else
self.runes[self._length] = rune
self._length = self._length + 1
end
self._tested = false
self._valid = false
end
--[[
# get effective length including optional power rune ]]--
function phrase.getLength(self)
if (self.power == 0) then
return self._length
else
return self._length + 1
end
end
--[[
# get the phrases rune-tier by index ]]--
function phrase.getTierAt(self, index)
local rune = self:getRuneAt(index)
if (rune == nil) then
return -1
end
return rune.tier
end
--[[
# get the phrases rune by index ]]--
function phrase.getRuneAt(self, index)
if (self.power > 0) then
index = index - 1 end
if (index < -1) then
return nil end
if (index == -1) then
return QDMF_Rune[self.power - 1] end
if (index < self._length) then
return self.runes[index] end
return nil
end
--[[
# check whether a certain rune is part of the spell ]]--
function phrase.hasRuneIndex(self, idx)
if (self == nil or idx == nil) then return nil end
-- a power rune?
if idx < QDMF_Rune.ways then
if self.power == idx + 1 then
return true
else
return false
end
end
for k,v in pairs(self.runes) do
if v.index == idx then return true end
end
return false
end
--[[
# check if the phrase is a valid spell and if: update name and alignment ]]--
function phrase.isValid(self)
if (self._tested) then return self._valid end
self.string = ""
self.cost = 0
if (self.power) > 0 then
self.string = QDMF_Rune[self.power - 1]
end
for k,v in pairs(self.runes) do
if (self.string ~="") then
self.string = self.string .. " "
end
self.string = self.string .. v.name
self.cost = self.cost + v.cost
end
local spell = QDMF_Spell[self.string]
self._tested = true
if spell == nil then
self.name = ""
self.align = ""
self._valid = false
return false
end
self.name = spell.name
self.aligh = spell.align
self._valid = true
return true
end
--[[
# convert the phrase to a full string with power rune ]]--
function phrase.toString(self)
local str = "", rune
if self.power > 0 and self.power <= QDMF_Rune.ways then
rune = QDMF_Rune[self.power - 1]
if rune ~=nil then
str = QDMF_Rune[self.power - 1].name .. " "
end
end
return str .. self.string
end
function phrase.getNextTier(self)
if (self.power == 0) then return 0 end
if (self._length > 5) then return -1 end
return (self._length % 3) + 1
end
phrase:clear()
if runestring == nil then
return phrase end
for i in string.gmatch(runestring, "%S+") do
phrase:add(QDMF_Rune[i])
end
return phrase
end
function QDMF_Rune:new(name,tier,way,cost,effect)
local rune = {}
rune.name = name
rune.tier = tier
rune.way = way
rune.index = tier * QDMF_Rune.ways + way
rune.cost = cost
-- make accessible by name and position, in lua, this
-- is automatically a ref to the object, not a copy
QDMF_Rune[name] = rune
QDMF_Rune[rune.index] = rune
return rune
end
--[[
# Definition of a spell.
# minimum : the least possible power-rune to cast this spell
# ]]--
function QDMF_Spell:new(name, align, runestring, minimum)
local spell = QDMF_PhraseCreate(runestring)
spell.name = name
spell.align = align
QDMF_Spell[name] = spell
QDMF_Spell[spell.string] = spell
return spell
end
QDMF_Rune:new("Sha", 0,0,3, "Neophyte")
QDMF_Rune:new("Lo", 0,1,3, "Novice")
QDMF_Rune:new("Beth", 0,2,3, "Apprentice")
QDMF_Rune:new("Um", 0,3,3, "Journeyman")
QDMF_Rune:new("On", 0,4,3, "Craftsman")
QDMF_Rune:new("Ee", 0,5,3, "Artisan")
QDMF_Rune:new("Pal", 0,6,3, "Adept")
QDMF_Rune:new("Mon", 0,7,3, "Expert")
QDMF_Rune:new("Arch", 0,8,3, "Master")
QDMF_Rune:new("Fri", 1,0,3, "Cold")
QDMF_Rune:new("Ya", 1,1,3, "Earth")
QDMF_Rune:new("Vi", 1,2,3, "Water")
QDMF_Rune:new("Oh", 1,3,3, "Air")
QDMF_Rune:new("Ful", 1,4,3, "Fire")
QDMF_Rune:new("Eck", 1,5,3, "Energy")
QDMF_Rune:new("Man", 1,6,3, "Mind")
QDMF_Rune:new("Des", 1,7,3, "Void")
QDMF_Rune:new("Zo", 1,8,3, "Negation")
QDMF_Rune:new("Sta", 2,0,3, "Unity")
QDMF_Rune:new("Ven", 2,1,3, "Time")
QDMF_Rune:new("Des", 2,2,3, "Life")
QDMF_Rune:new("Kath", 2,3,3, "Expand")
QDMF_Rune:new("Ir", 2,4,3, "Flight")
QDMF_Rune:new("Het", 2,5,3, "Twist")
QDMF_Rune:new("Bro", 2,6,3, "Peace")
QDMF_Rune:new("Trans", 2,7,3, "Transit")
QDMF_Rune:new("Gor", 2,8,3, "War")
QDMF_Rune:new("Lyr", 3,0,3, "Artistry")
QDMF_Rune:new("Ku", 3,1,3, "Strenght")
QDMF_Rune:new("Ros", 3,2,3, "Dexterity")
QDMF_Rune:new("Dain", 3,3,3, "Magic")
QDMF_Rune:new("Neta", 3,4,3, "Belief")
QDMF_Rune:new("Ing", 3,5,3, "Insight")
QDMF_Rune:new("Ra", 3,6,3, "Order")
QDMF_Rune:new("Sar", 3,7,3, "Chaos")
QDMF_Rune:new("Woo", 3,8,3, "Balace")
QDMF_Spell:new("Fireball", "Mage", "Ful Ir", 0)
file_runes = "mod_assets/textures/runes.dds"
file_runes_h = "mod_assets/textures/runes_h.dds"
file_runes_s = "mod_assets/textures/runes_s.dds"
function renderRunePanel(self,context)
runePanel:render(context)
end
function runePanelCreate(runestring)
local panel = {}
panel.phrase = QDMF_PhraseCreate(runestring)
panel.runesize = 30
panel.phrase_h = 20
panel.X = 0
panel.Y = 0
panel.clickcycle = false
panel.click = -1
panel.select = -1
panel.hover = -1
panel.tier = panel.phrase:getNextTier()
panel.base = panel.tier * QDMF_Rune.ways
function panel.checkHover(self,context)
for r = 0, self.phrase:getLength() do
if (context.button("", self.X + r*self.phrase_h, self.Y, self.phrase_h, self.phrase_h) ~= nil) then
self.hover = r
return
end
end
local yy = self.Y + self.phrase_h
for r = 0, 8 do
y = math.floor(r / 3)
x = self.X + (r - (y * 3)) * self.runesize
y = yy + y * self.runesize
if (context.button("", x, y, self.runesize, self.runesize) ~= nil) then
self.hover = r + 50 + self.base
return
end
end
self.hover = -1
end
function panel.drawPhrase(self, context, x, y)
local len = self.phrase:getLength()
for r = 0, len do
rune = self.phrase:getRuneAt(r)
if (rune ~= nil) then
if (self.click == r or self.select == r) then
file = file_runes_s
elseif (self.hover == r) then
file = file_runes_h
else
file = file_runes
end
context.drawImage2(file, x + r * self.phrase_h, y, rune.way * 100 + 10,
rune.tier * 100 + 10, 80, 80, self.phrase_h, self.phrase_h)
end
end
end
function panel.drawTiles(self, context, x, y)
if (self.tier == -1) then
return
end
local hover = self.hover - 50
local click = self.click - 50
local rx = 0
local ry = 0
local rr
for r = 0, 8 do
ry = math.floor(r / 3)
rx = x + (r - (ry * 3)) * self.runesize
ry = y + ry * self.runesize
rr = r + self.base
if (hover == rr) then
if (click == rr) then
file = file_runes_s
else
file = file_runes_h
end
elseif (self.phrase:hasRuneIndex(rr)) then
file = file_runes_s
else
file = file_runes
end
context.drawImage2(file, rx, ry, r * 100, self.tier * 100, 100, 100, self.runesize, self.runesize)
end
end
function panel.render(self, context)
self:checkHover(context)
if (context.mouseDown(0)) then
-- mousebutton pressed, save click position if valid
if (not self.clickcycle and self.hover > -1) then
self.clickcycle = true
self.click = self.hover
end
else
-- mousebutton released, act if position is still the same
if (self.clickcycle) then
self.clickcycle = false
if (self.hover == self.click) then
if (self.click > -1 and self.click < 50) then
-- click into spell-phrase
self.select = self.click
self.tier = self.phrase:getTierAt(self.click)
self.base = self.tier * QDMF_Rune.ways
elseif (self.click > 49 and self.click < 100) then
-- click into tile-zone
if (self.select > -1 and self.select < 50) then
self.phrase:add(self.click - 50, self.select)
else
self.phrase:add(self.click - 50)
end
self.tier = self.phrase:getNextTier()
self.base = self.tier * QDMF_Rune.ways
self.select = -1
end
end
self.click = -1
end
end
self:drawPhrase(context, self.X, self.Y)
self:drawTiles(context, self.X, self.Y + self.phrase_h)
end
return panel
end
runePanel = runePanelCreate()