196 lines
6.7 KiB
Lua
196 lines
6.7 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/>.
|
||
]]
|
||
|
||
-- This script handles fairy events in Elstree Forest.
|
||
-- The functions are hooked in the various scripts with the actual entry points.
|
||
|
||
local common = require("base.common")
|
||
local scheduledFunction = require("scheduled.scheduledFunction")
|
||
|
||
local M = {}
|
||
|
||
local function _isNumber(value)
|
||
return type(value) == "number"
|
||
end
|
||
|
||
local function _isTable(value)
|
||
return type(value) == "table"
|
||
end
|
||
|
||
local function fairyBlinkenlights(centerPos, counter, itemID, gfxID)
|
||
|
||
local amount = math.random(3, 7)
|
||
local radius = 15
|
||
|
||
-- show a few fairy lights around
|
||
for _ = 1, amount do
|
||
local dropPos = common.getFreePos(centerPos, radius)
|
||
world:gfx(gfxID, dropPos)
|
||
end
|
||
|
||
-- create a random item (i.e. flame)
|
||
if itemID ~= nil then
|
||
local dropPos = common.getFreePos(centerPos, radius)
|
||
local item = world:createItemFromId(itemID, 1, dropPos, true, 333, nil)
|
||
item.wear = 1
|
||
world:changeItem(item)
|
||
end
|
||
|
||
-- repeat effect a few times
|
||
counter = counter - 1
|
||
if counter > 0 then
|
||
scheduledFunction.registerFunction(math.random(2, 5), function() fairyBlinkenlights(centerPos, counter, itemID, gfxID) end)
|
||
end
|
||
end
|
||
|
||
local function elementNoDrop(User, itemID, gfxID)
|
||
-- player get informed s/he missed chance after a while
|
||
scheduledFunction.registerFunction(math.random(5, 10), function()
|
||
-- check if character has already logged out
|
||
if not isValidChar(User) then
|
||
return
|
||
end
|
||
|
||
User:inform("Es sieht nicht danach aus als w<>rde eine Fee heute ein Element verlieren.", "It does not look like as any fairy would drop an element today.")
|
||
end)
|
||
|
||
-- register effect
|
||
local centerPos = position(User.pos.x, User.pos.y, User.pos.z) -- deep copy original position
|
||
local counter = math.random(10, 20)
|
||
scheduledFunction.registerFunction(math.random(2, 5), function() fairyBlinkenlights(centerPos, counter, itemID, gfxID) end)
|
||
end
|
||
|
||
local function getTextForDirection(direction)
|
||
if direction == Character.dir_north then
|
||
return "n<EFBFBD>rdlich von dir", "north of you"
|
||
elseif direction == Character.dir_northeast then
|
||
return "nord<EFBFBD>stlich von dir", "northeast of you"
|
||
elseif direction == Character.dir_east then
|
||
return "<EFBFBD>stlich von dir", "east of you"
|
||
elseif direction == Character.dir_southeast then
|
||
return "s<EFBFBD>d<EFBFBD>stlich von dir", "southeast of you"
|
||
elseif direction == Character.dir_south then
|
||
return "s<EFBFBD>dlich von dir", "south of you"
|
||
elseif direction == Character.dir_southwest then
|
||
return "s<EFBFBD>dwestlich von dir", "southwest of you"
|
||
elseif direction == Character.dir_west then
|
||
return "westlich von dir", "west of you"
|
||
elseif direction == Character.dir_northwest then
|
||
return "nordwestlich von dir", "northwest of you"
|
||
else
|
||
return "unter deinen Beinen", "underneath your feet"
|
||
end
|
||
end
|
||
|
||
local function elementDrop(User, itemID, gfxID)
|
||
local radius = 10
|
||
local dropPos = common.getFreePos(User.pos, radius)
|
||
|
||
-- drop item after a while and inform user
|
||
scheduledFunction.registerFunction(math.random(1, 4), function()
|
||
-- check if character has already logged out
|
||
if not isValidChar(User) then
|
||
return
|
||
end
|
||
|
||
world:createItemFromId(itemID, 1, dropPos, true, 333, nil)
|
||
world:gfx(gfxID, dropPos)
|
||
|
||
local directionTextDe, directionTextEn = getTextForDirection(common.GetDirection(User.pos, dropPos))
|
||
User:inform(
|
||
"Ah! Eine Fee hat " .. world:getItemName(itemID, Player.german) .. " " .. directionTextDe .. " verloren.",
|
||
"Ah! A fairy lost " .. world:getItemName(itemID, Player.english) .. " " .. directionTextEn .. ".")
|
||
end)
|
||
end
|
||
|
||
function M.chanceForElementDrop(User, params)
|
||
|
||
if params ~= nil and not _isTable(params) then
|
||
error("The function requires parameters as a table.")
|
||
end
|
||
|
||
-- chance check if quest cooled down and character is player
|
||
if User:getType() ~= Character.player or User:getQuestProgress(661) ~= 0 then
|
||
return
|
||
end
|
||
-- set cooldown
|
||
User:setQuestProgress(661, math.random(60, 100))
|
||
|
||
-- fill default parameters
|
||
local probability
|
||
local successItemID
|
||
local successGfxID
|
||
local failItemID
|
||
local failGfxID
|
||
|
||
if params.probability ~= nil then
|
||
if _isNumber(params.probability) then
|
||
probability = tonumber(params.probability)
|
||
if (probability <= 0) or (probability > 1) then
|
||
error("The probability is set to a illegal value.")
|
||
end
|
||
else
|
||
error("The probability was set to something, but not to a number.")
|
||
end
|
||
else
|
||
probability = 0.1 -- 10%
|
||
end
|
||
if params.successItemID ~= nil then
|
||
if _isNumber(params.successItemID) then
|
||
successItemID = tonumber(params.successItemID)
|
||
else
|
||
error("successItemID was set to something, but not to a number.")
|
||
end
|
||
else
|
||
local elements = {2551, 2552, 2553, 2554, 3607}
|
||
successItemID = elements[math.random(1, #elements)] -- random pure element
|
||
end
|
||
if params.successGfxID ~= nil then
|
||
if _isNumber(params.successGfxID) then
|
||
successGfxID = tonumber(params.successGfxID)
|
||
else
|
||
error("successGfxID was set to something, but not to a number.")
|
||
end
|
||
else
|
||
successGfxID = 46 -- light (beam me up)
|
||
end
|
||
if params.failItemID ~= nil then
|
||
if _isNumber(params.failItemID) then
|
||
failItemID = tonumber(params.failItemID)
|
||
else
|
||
error("failItemID was set to something, but not to a number.")
|
||
end
|
||
end
|
||
if params.failGfxID ~= nil then
|
||
if _isNumber(params.failGfxID) then
|
||
failGfxID = tonumber(params.failGfxID)
|
||
else
|
||
error("failGfxID was set to something, but not to a number.")
|
||
end
|
||
else
|
||
failGfxID = 53 -- light (blue glitter)
|
||
end
|
||
|
||
-- chance to receive a nice item
|
||
if math.random() <= probability then
|
||
elementDrop(User, successItemID, successGfxID)
|
||
else
|
||
elementNoDrop(User, failItemID, failGfxID)
|
||
end
|
||
end
|
||
|
||
return M
|