384 lines
14 KiB
Lua
384 lines
14 KiB
Lua
--[[
|
||
Illarion Server
|
||
|
||
This program is free software: you can redistribute it and/or modify it under
|
||
the terms of the GNU Affero General Public License as published by the Free
|
||
Software Foundation, either version 3 of the License, or (at your option) any
|
||
later version.
|
||
|
||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||
PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||
details.
|
||
|
||
You should have received a copy of the GNU Affero General Public License along
|
||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
]]
|
||
local common = require("base.common")
|
||
local runes = require("magic.arcane.runes")
|
||
local magic = require("base.magic")
|
||
local grimoireCreation = require("magic.arcane.grimoireCreation")
|
||
|
||
local M = {}
|
||
|
||
local manaCost = 500
|
||
|
||
M.MAX_SPELL_SLOTS = 20
|
||
|
||
|
||
local function getMagicBook(user)
|
||
|
||
local leftItem = user:getItemAt(5)
|
||
local rightItem = user:getItemAt(6)
|
||
|
||
if leftItem:getData("magicBook") ~= "true" and rightItem:getData("magicBook") ~= "true" then --check for magic book data
|
||
return nil
|
||
end
|
||
|
||
for _, book in pairs(grimoireCreation.books) do --Check all valid book ids
|
||
|
||
if leftItem.id == book then
|
||
return leftItem
|
||
elseif rightItem.id == book then
|
||
return rightItem
|
||
end
|
||
end
|
||
|
||
return nil
|
||
|
||
end
|
||
|
||
local function primaryElementCheck(user, mBook, slot)
|
||
for i = 1,6 do
|
||
if runes.checkIfLearnedRune(user, mBook, i, "isSpell", "spell"..slot) then
|
||
return false
|
||
elseif i == 6 then
|
||
return true
|
||
end
|
||
end
|
||
end
|
||
|
||
local function bhonaCheck(user, mBook, slot)
|
||
|
||
local BHONA = runes.checkIfLearnedRune(user, mBook, 6, "isSpell", "spell"..slot)
|
||
|
||
if not BHONA then
|
||
return false
|
||
end
|
||
|
||
local count = 0
|
||
|
||
for i = 1, #runes.runes do
|
||
if runes.checkIfLearnedRune(user, mBook, i, "isSpell", "spell"..slot) then
|
||
count = count+1
|
||
end
|
||
end
|
||
|
||
if count >= 2 then
|
||
user:inform("Zauberspr<EFBFBD>che mit BHONA d<>rfen maximal 2 Runen enthalten.", "BHONA spells may only contain up to two runes." )
|
||
return true
|
||
end
|
||
|
||
return false
|
||
|
||
end
|
||
|
||
local function checkIfKnowsAnyMinorRune(user)
|
||
for i = 6, #runes.runes do -- for every minor rune
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") then
|
||
return true
|
||
elseif i == #runes.runes then
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
|
||
local function checkForDialogOptions(user, mBook, slot) -- Check if there are any minor runes that can be selected
|
||
for i = 6, #runes.runes do -- For every minor rune
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") and (not runes.checkIfLearnedRune(user, mBook, i, "isSpell", "spell"..slot)) and runes.runeNumberToName(i) ~= "Bhona" then -- check if user knows rune and if rune is already part of spell being created
|
||
return true
|
||
elseif i == #runes.runes then
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
|
||
function M.checkForDialogOptions2(user) -- Check if there are any primary runes that can be selected
|
||
for i = 1,5 do -- For every primary rune
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") then -- check if user knows rune
|
||
return true
|
||
elseif i == 5 then
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
|
||
local function createSpell(user, slot)
|
||
|
||
local mBook = getMagicBook(user)
|
||
local BHONA = runes.checkIfLearnedRune(user, mBook, 6, "isSpell", "spell"..slot)
|
||
local runeStart = 7
|
||
|
||
if BHONA then
|
||
runeStart = 1
|
||
end
|
||
|
||
local callback = function(dialog)
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
local index = dialog:getSelectedIndex() +1
|
||
local unknownrunes = runeStart-1 --Counter for runes that are unknown or already in use, starting at the first rune after elemental ones
|
||
for i = runeStart, #runes.runes do -- For every rune
|
||
mBook = getMagicBook(user)
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") and (not runes.checkIfLearnedRune(user, mBook, i, "isSpell", "spell"..slot)) then -- check if user knows rune and if rune is already part of spell being created
|
||
if i == 6 then -- skip BHONA
|
||
unknownrunes = unknownrunes+1
|
||
end
|
||
if index == i-unknownrunes then -- Check if selected index is the rune in question
|
||
if magic.hasSufficientMana(user,manaCost) then
|
||
user:increaseAttrib("mana", -manaCost)
|
||
world:gfx(41,user.pos)
|
||
world:makeSound(13,user.pos)
|
||
runes.learnRune(user, mBook, i, "isSpell", "spell"..slot) -- Add rune to spell
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
user:inform("Die Rune "..runes.runeNumberToName(i).." wurde dem Zauberspruch hinzugef<65>gt.", "The rune "..runes.runeNumberToName(i).." has been added to the spell.")
|
||
else
|
||
user:inform("Nicht genug Mana." ,"Not enough mana.")
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
end
|
||
end
|
||
else
|
||
unknownrunes = unknownrunes+1 -- For every rune that the user has not learned or is already part of the spell, the index numbering is corrected.
|
||
end
|
||
end
|
||
end
|
||
|
||
local dialog = SelectionDialog(common.GetNLS(user, "Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user, "W<EFBFBD>hle welche Rune du dem Zauberspruch hinzuf<75>gen m<>chtest.", "Select which rune you want to add to your spell."), callback)
|
||
|
||
|
||
for i = runeStart, #runes.runes do -- For every rune
|
||
if i ~= 6 then
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") and (not runes.checkIfLearnedRune(user, mBook, i, "isSpell", "spell"..slot)) then -- check if user knows rune and if rune is already part of spell being created
|
||
local runeName = runes.runeNumberToName(i)
|
||
local lowerCaseName = string.lower(runeName)
|
||
dialog:addOption(Item[lowerCaseName], runeName)
|
||
end
|
||
end
|
||
end
|
||
|
||
if not checkIfKnowsAnyMinorRune(user) then -- If you do not know any runes
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
user:inform("Du musst zuerst lernen wie man eine geringe Rune nutzt bevor du sie zu deinem Zauberspruch hinzuf<75>gst. ", "You must first learn how to use any minor rune before you can add it to your spell.")
|
||
|
||
elseif not checkForDialogOptions(user, mBook, slot) then
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
user:inform("Du kennst keine weiteren Runen die zum Zauberspruch hinzugef<65>gt werden k<>nnen." , "You do not know any more runes that can be added to the spell.")
|
||
|
||
else
|
||
user:requestSelectionDialog(dialog)
|
||
end
|
||
end
|
||
|
||
local function elementSelection(user, slot)
|
||
|
||
local unknownrunes = 0
|
||
|
||
local callback = function(dialog)
|
||
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
|
||
local index = dialog:getSelectedIndex() +1
|
||
|
||
for i = 1,6 do
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") then
|
||
if index == i-unknownrunes then
|
||
if magic.hasSufficientMana(user,manaCost) then
|
||
user:increaseAttrib("mana", -manaCost)
|
||
world:gfx(41,user.pos)
|
||
world:makeSound(13,user.pos)
|
||
local mBook = getMagicBook(user)
|
||
|
||
if not mBook then
|
||
return
|
||
end
|
||
|
||
runes.learnRune(user, mBook, i, "isSpell", "spell"..slot)
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
|
||
user:inform("Die Rune "..runes.runeNumberToName(i).." wurde als prim<69>re Rune dem Zauberspruch hinzugef<65>gt.", "The rune "..runes.runeNumberToName(i).." has been added as the primary rune of the spell.")
|
||
else
|
||
user:inform("Nicht genug Mana." ,"Not enough mana.")
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
end
|
||
return
|
||
end
|
||
else
|
||
unknownrunes = unknownrunes+1
|
||
end
|
||
end
|
||
end
|
||
|
||
local dialog = SelectionDialog(common.GetNLS(user,"Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user, "W<EFBFBD>hle eine prim<69>re Rune f<>r deinen Zauberspruch.", "Select a primary rune for your spell."), callback)
|
||
|
||
for i = 1,6 do
|
||
if runes.checkIfLearnedRune(user,"", i, "isQuest") then
|
||
local runeName = runes.runeNumberToName(i)
|
||
local lowerCaseName = string.lower(runeName)
|
||
dialog:addOption(Item[lowerCaseName], runeName)
|
||
end
|
||
end
|
||
|
||
user:requestSelectionDialog(dialog)
|
||
end
|
||
|
||
local function nameSpell(user, slot)
|
||
|
||
local mBook = getMagicBook(user)
|
||
|
||
if not mBook then
|
||
return
|
||
end
|
||
|
||
local theSpell = mBook:getData("spell"..slot)
|
||
|
||
if common.IsNilOrEmpty(theSpell) or tonumber(theSpell) == 0 then
|
||
user:inform("Der Zauberspruch muss Runen enthalten, damit du ihn benennen kannst.", "The spell must contain runes for you to name it.")
|
||
return
|
||
end
|
||
|
||
local callback = function(dialog)
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
local input = dialog:getInput()
|
||
mBook = getMagicBook(user)
|
||
mBook:setData("spellName"..slot,input) -- Set name for spell
|
||
world:changeItem(mBook) -- save name for spell
|
||
user:inform("Du benennst den Zauberspruch auf Seite "..slot.. ": "..input..".","You name the spell on page "..slot.. ": "..input..".")
|
||
if user:getQuestProgress(237) == 4 then
|
||
user:setQuestProgress(237, 5)
|
||
end
|
||
end
|
||
|
||
user:requestInputDialog(InputDialog(common.GetNLS(user,"Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user, "Benenne den Zauberspruch.", "Name the spell"),false,255,callback))
|
||
end
|
||
|
||
function M.spellCreationSelectionMenu(user, slot)
|
||
|
||
local callback = function(dialog)
|
||
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
|
||
local index = dialog:getSelectedIndex() +1
|
||
|
||
local mBook = getMagicBook(user)
|
||
|
||
if not mBook then
|
||
return
|
||
end
|
||
|
||
if index == 1 and primaryElementCheck(user, mBook, slot) then
|
||
elementSelection(user, slot)
|
||
elseif index == 1 and not bhonaCheck(user, mBook, slot) then
|
||
createSpell(user, slot)
|
||
elseif index == 2 then
|
||
nameSpell(user, slot)
|
||
end
|
||
end
|
||
local dialog = SelectionDialog(common.GetNLS(user,"Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user, "W<EFBFBD>hle eine M<>glichkeit.", "Pick an option."), callback)
|
||
|
||
dialog:addOption(0, common.GetNLS(user, "F<EFBFBD>ge eine Rune hinzu.", "Add rune"))
|
||
dialog:addOption(0, common.GetNLS(user, "Finalisiere den Zauber.", "Finish spell"))
|
||
|
||
user:requestSelectionDialog(dialog)
|
||
end
|
||
|
||
local function overWriteConfirmation(user, slot)
|
||
|
||
local callback = function(dialog)
|
||
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
|
||
local index = dialog:getSelectedIndex() +1
|
||
|
||
if index == 1 then
|
||
local mBook = getMagicBook(user)
|
||
if not mBook then
|
||
return
|
||
end
|
||
mBook:setData("spell"..slot,"0") -- Reset the spell slot
|
||
mBook:setData("spellName"..slot, common.GetNLS(user, "Unvollendet", "Unfinished")) -- Remove old spell name
|
||
world:changeItem(mBook) -- Save the changes above
|
||
M.spellCreationSelectionMenu(user, slot)
|
||
elseif index == 2 then
|
||
M.slotSelection(user)
|
||
end
|
||
end
|
||
|
||
local dialog = SelectionDialog(common.GetNLS(user,"Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user,"","This spell slot is already in use.\nAre you sure you want to overwrite the selected spell slot?"), callback)
|
||
dialog:addOption(0, common.GetNLS(user, "Ja, ich <20>berschreibe ihn.", "Yes, overwrite it."))
|
||
dialog:addOption(0, common.GetNLS(user, "Nein, ich w<>hle eine andere Seite.", "No, select another page."))
|
||
user:requestSelectionDialog(dialog)
|
||
|
||
end
|
||
|
||
function M.slotSelection(user)
|
||
|
||
local mBook = getMagicBook(user)
|
||
|
||
if not mBook then
|
||
return
|
||
end
|
||
|
||
local callback = function(dialog)
|
||
|
||
if not dialog:getSuccess() then
|
||
return
|
||
end
|
||
|
||
local index = dialog:getSelectedIndex() +1
|
||
|
||
for i = 1, M.MAX_SPELL_SLOTS do
|
||
|
||
local spellName = mBook:getData("spellName"..i)
|
||
local germanUnfinished = "Unvollendet"
|
||
local englishUnfinished = "Unfinished"
|
||
|
||
if index == i and spellName ~= englishUnfinished and spellName ~= germanUnfinished and spellName ~= "" then
|
||
overWriteConfirmation(user, i)
|
||
return
|
||
|
||
elseif index == i and (spellName == englishUnfinished or spellName == germanUnfinished) then
|
||
M.spellCreationSelectionMenu(user, i)
|
||
|
||
elseif index == i then
|
||
mBook:setData("spellName"..i, common.GetNLS(user, germanUnfinished, englishUnfinished)) -- Remove old spell name
|
||
mBook:setData("spell"..i,"0") -- Set a blank value for spell so it doesn't end up being NIL
|
||
world:changeItem(mBook) -- Save the changes above
|
||
M.spellCreationSelectionMenu(user, i)
|
||
end
|
||
end
|
||
end
|
||
|
||
local dialog = SelectionDialog(common.GetNLS(user,"Zauberspruch Erstellung", "Spell Creation"), common.GetNLS(user,"W<EFBFBD>hle, in welchem Zauberslot du einen Zauber speichern m<>chtest.","Select which spell slot you want to store a spell in."), callback)
|
||
|
||
for i = 1, M.MAX_SPELL_SLOTS do
|
||
if (mBook:getData("spellName"..i) ~= "") then
|
||
dialog:addOption(0,"Spell Slot "..i.."("..mBook:getData("spellName"..i)..")")
|
||
else
|
||
dialog:addOption(0,"Spell Slot "..i.."(Empty)")
|
||
end
|
||
end
|
||
|
||
user:requestSelectionDialog(dialog)
|
||
|
||
end
|
||
|
||
return M
|