mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-05-02 02:29:21 +02:00
380 lines
12 KiB
Lua
380 lines
12 KiB
Lua
local monsterOfTheDay = {
|
|
[8430] = { monster = 'Crocodile' },
|
|
[8431] = { monster = 'Tarantula' },
|
|
[8432] = { monster = 'Carniphila' },
|
|
[8433] = { monster = 'Merlkin' },
|
|
[8434] = { monster = 'Kongra' },
|
|
[8435] = { monster = 'Sibang' },
|
|
[8436] = { monster = 'Thornback Tortoise' },
|
|
[8437] = { monster = 'Gargoyle' },
|
|
[8438] = { monster = 'Quara Constrictor Scout' },
|
|
[8439] = { monster = 'Quara Hydromancer Scout' },
|
|
[8440] = { monster = 'Quara Mantassin Scout' },
|
|
[8441] = { monster = 'Quara Pincher Scout' },
|
|
[8442] = { monster = 'Quara Predator Scout' },
|
|
[8443] = { monster = 'Ancient Scarab' },
|
|
[8444] = { monster = 'Wyvern' },
|
|
[8445] = { monster = 'Bonebeast' },
|
|
[8446] = { monster = 'Dragon' },
|
|
[8447] = { monster = 'Quara Constrictor' },
|
|
[8448] = { monster = 'Quara Hydromancer' },
|
|
[8449] = { monster = 'Quara Mantassin' },
|
|
[8450] = { monster = 'Quara Pincher' },
|
|
[8451] = { monster = 'Quara Predator' },
|
|
[8452] = { monster = 'Giant Spider' },
|
|
[8453] = { monster = 'Banshee' },
|
|
[8454] = { monster = 'Lich' },
|
|
[8455] = { monster = 'Acolyte of The Cult' },
|
|
[8456] = { monster = 'Adept of The Cult' },
|
|
[8457] = { monster = 'Enlightened of The Cult' },
|
|
[8458] = { monster = 'Novice of The Cult' },
|
|
[8459] = { monster = 'Hydra' },
|
|
[8460] = { monster = 'Serpent Spawn' },
|
|
[8461] = { monster = 'Behemoth' },
|
|
[8462] = { monster = 'Dragon Lord' },
|
|
[8463] = { monster = 'Hand of Cursed Fate' },
|
|
[8464] = { monster = 'Juggernaut' },
|
|
[8465] = { monster = 'Frost Troll' },
|
|
[8466] = { monster = 'Swamp Troll' },
|
|
[8467] = { monster = 'Rat' },
|
|
[8468] = { monster = 'Cave Rat' },
|
|
[8469] = { monster = 'Wolf' },
|
|
[8470] = { monster = 'Winter Wolf' },
|
|
[8471] = { monster = 'Wasp' },
|
|
[8472] = { monster = 'Larva' },
|
|
[8473] = { monster = 'Dwarf' },
|
|
[8474] = { monster = 'Skeleton' },
|
|
[8475] = { monster = 'Ghoul' },
|
|
[8476] = { monster = 'Elf' },
|
|
[8477] = { monster = 'Elf Scout' },
|
|
[8478] = { monster = 'Elf Arcanist' },
|
|
[8479] = { monster = 'Bug' },
|
|
[8480] = { monster = 'Smuggler' },
|
|
[8481] = { monster = 'Wild Warrior' },
|
|
[8482] = { monster = 'Bandit' },
|
|
[8483] = { monster = 'Hyaena' },
|
|
[8484] = { monster = 'Lion' },
|
|
[8485] = { monster = 'Bear' },
|
|
[8486] = { monster = 'Slime' },
|
|
[8487] = { monster = 'Beholder' },
|
|
[8488] = { monster = 'Elder Beholder' },
|
|
[8489] = { monster = 'Green Djinn' },
|
|
[8490] = { monster = 'Blue Djinn' },
|
|
[8491] = { monster = 'Marid' },
|
|
[8492] = { monster = 'Efreet' },
|
|
[8493] = { monster = 'Pirate Skeleton' },
|
|
[8494] = { monster = 'Pirate Marauder' },
|
|
[8495] = { monster = 'Pirate Cutthroat' },
|
|
[8496] = { monster = 'Pirate Ghost' },
|
|
[8497] = { monster = 'Pirate Buccaneer' },
|
|
[8498] = { monster = 'Pirate Corsair' },
|
|
[8499] = { monster = 'Orc Spearman' },
|
|
[8500] = { monster = 'Orc Shaman' },
|
|
[8501] = { monster = 'Orc Rider' },
|
|
[8502] = { monster = 'Orc Warrior' },
|
|
[8503] = { monster = 'Orc Berserker' },
|
|
[8504] = { monster = 'Minotaur Archer' },
|
|
[8505] = { monster = 'Minotaur Guard' },
|
|
[8506] = { monster = 'Minotaur Mage' },
|
|
[8507] = { monster = 'Lizard Templar' },
|
|
[8508] = { monster = 'Lizard Sentinel' },
|
|
[8509] = { monster = 'Lizard Snakecharmer' },
|
|
[8510] = { monster = 'Dwarf Soldier' },
|
|
[8511] = { monster = 'Dwarf Guard' },
|
|
[8512] = { monster = 'Dwarf Geomancer' },
|
|
[8513] = { monster = 'Ghost' },
|
|
[8514] = { monster = 'Demon Skeleton' },
|
|
[8515] = { monster = 'Vampire' },
|
|
[8516] = { monster = 'Orc Leader' },
|
|
[8517] = { monster = 'Orc Warlord' },
|
|
[8518] = { monster = 'Hero' },
|
|
[8519] = { monster = 'Necromancer' },
|
|
[8520] = { monster = 'Priestess' },
|
|
[8521] = { monster = 'Nightmare' },
|
|
[8522] = { monster = 'Warlock' },
|
|
[8523] = { monster = 'Demon' },
|
|
[8524] = { monster = 'Troll' },
|
|
[8525] = { monster = 'Goblin' },
|
|
[8526] = { monster = 'Rotworm' },
|
|
[8527] = { monster = 'Carrion Worm' },
|
|
[8528] = { monster = 'Cyclops' },
|
|
[8529] = { monster = 'Amazon' },
|
|
[8530] = { monster = 'Minotaur' },
|
|
[8531] = { monster = 'Orc' }
|
|
}
|
|
|
|
local trainingStatues = {17724, 17725, 17726, 17727, 17728}
|
|
|
|
function Player:onLook(thing, position, distance)
|
|
local description = "You see " .. thing:getDescription(distance)
|
|
|
|
if thing:isItem() and thing:getId() == 2028 then
|
|
if isInArray(trainingStatues, thing:getActionId()) then
|
|
local trainingTime = math.min(43200 / 2, self:getOfflineTrainingTime() / 1000)
|
|
local text = "You have"
|
|
local hours = math.floor(trainingTime / 3600)
|
|
if hours > 1 then
|
|
text = string.format("%s %d hours", text, hours)
|
|
elseif hours == 1 then
|
|
text = string.format("%s 1 hour", text)
|
|
end
|
|
|
|
local minutes = math.floor((trainingTime % 3600) / 60)
|
|
if minutes ~= 0 then
|
|
if hours ~= 0 then
|
|
text = string.format("%s and", text)
|
|
end
|
|
|
|
if minutes > 1 then
|
|
text = string.format("%s %d minutes", text, minutes)
|
|
else
|
|
text = string.format("%s 1 minute", text)
|
|
end
|
|
end
|
|
|
|
text = string.format(" %s offline training time remaining.", text)
|
|
|
|
description = string.format(description .. "%s", text)
|
|
end
|
|
end
|
|
|
|
if self:getGroup():getAccess() then
|
|
if thing:isItem() then
|
|
description = string.format("%s\nItem ID: %d", description, thing:getId())
|
|
|
|
local actionId = thing:getActionId()
|
|
if actionId ~= 0 then
|
|
description = string.format("%s, Action ID: %d", description, actionId)
|
|
end
|
|
|
|
local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_MOVEMENTID)
|
|
if uniqueId > 0 and uniqueId < 65536 then
|
|
description = string.format("%s, Movement ID: %d", description, uniqueId)
|
|
end
|
|
|
|
local itemType = thing:getType()
|
|
|
|
local transformEquipId = itemType:getTransformEquipId()
|
|
local transformDeEquipId = itemType:getTransformDeEquipId()
|
|
if transformEquipId ~= 0 then
|
|
description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId)
|
|
elseif transformDeEquipId ~= 0 then
|
|
description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId)
|
|
end
|
|
|
|
local decayId = itemType:getDecayId()
|
|
if decayId ~= -1 then
|
|
description = string.format("%s\nDecays to: %d", description, decayId)
|
|
end
|
|
if thing:getAttribute(ITEM_ATTRIBUTE_DECAYSTATE) == 1 then
|
|
description = string.format("%s\nDecaying in %d minutes (%d seconds).", description, thing:getAttribute(ITEM_ATTRIBUTE_DURATION) / 1000 / 60, thing:getAttribute(ITEM_ATTRIBUTE_DURATION) / 1000)
|
|
end
|
|
elseif thing:isCreature() then
|
|
local str = "%s\nHealth: %d / %d"
|
|
if thing:isPlayer() and thing:getMaxMana() > 0 then
|
|
str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana())
|
|
end
|
|
description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. "."
|
|
end
|
|
|
|
local position = thing:getPosition()
|
|
description = string.format(
|
|
"%s\nPosition: %d, %d, %d",
|
|
description, position.x, position.y, position.z
|
|
)
|
|
|
|
if thing:isCreature() then
|
|
if thing:isPlayer() then
|
|
description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp()))
|
|
end
|
|
end
|
|
end
|
|
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
|
|
end
|
|
|
|
function Player:onLookInBattleList(creature, distance)
|
|
local description = "You see " .. creature:getDescription(distance)
|
|
if self:getGroup():getAccess() then
|
|
local str = "%s\nHealth: %d / %d"
|
|
if creature:isPlayer() and creature:getMaxMana() > 0 then
|
|
str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana())
|
|
end
|
|
description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "."
|
|
|
|
local position = creature:getPosition()
|
|
description = string.format(
|
|
"%s\nPosition: %d, %d, %d",
|
|
description, position.x, position.y, position.z
|
|
)
|
|
|
|
if creature:isPlayer() then
|
|
description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp()))
|
|
end
|
|
end
|
|
self:sendTextMessage(MESSAGE_INFO_DESCR, description)
|
|
end
|
|
|
|
function Player:onLookInTrade(partner, item, distance)
|
|
self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance))
|
|
end
|
|
|
|
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
|
|
return true
|
|
end
|
|
|
|
function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
|
|
end
|
|
|
|
function Player:onMoveCreature(creature, fromPosition, toPosition)
|
|
return true
|
|
end
|
|
|
|
function Player:onReportBug(message, position, category)
|
|
if self:getAccountType() == ACCOUNT_TYPE_NORMAL then
|
|
return false
|
|
end
|
|
|
|
local name = self:getName()
|
|
local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a")
|
|
|
|
if not file then
|
|
self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "There was an error when processing your report, please contact a gamemaster.")
|
|
return true
|
|
end
|
|
|
|
io.output(file)
|
|
io.write("------------------------------\n")
|
|
io.write("Name: " .. name)
|
|
if category == BUG_CATEGORY_MAP then
|
|
io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", " .. position.z .. "]")
|
|
end
|
|
local playerPosition = self:getPosition()
|
|
io.write(" [Player Position: " .. playerPosition.x .. ", " .. playerPosition.y .. ", " .. playerPosition.z .. "]\n")
|
|
io.write("Comment: " .. message .. "\n")
|
|
io.close(file)
|
|
|
|
self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Your report has been sent to " .. configManager.getString(configKeys.SERVER_NAME) .. ".")
|
|
return true
|
|
end
|
|
|
|
function Player:onTurn(direction)
|
|
return true
|
|
end
|
|
|
|
function Player:onTradeRequest(target, item)
|
|
return true
|
|
end
|
|
|
|
function Player:onTradeAccept(target, item, targetItem)
|
|
return true
|
|
end
|
|
|
|
local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
|
|
soulCondition:setTicks(4 * 60 * 1000)
|
|
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)
|
|
|
|
local function useStamina(player)
|
|
local staminaMinutes = player:getStamina()
|
|
if staminaMinutes == 0 then
|
|
return
|
|
end
|
|
|
|
local playerId = player:getId()
|
|
local currentTime = os.time()
|
|
local timePassed = currentTime - nextUseStaminaTime[playerId]
|
|
if timePassed <= 0 then
|
|
return
|
|
end
|
|
|
|
if timePassed > 60 then
|
|
if staminaMinutes > 2 then
|
|
staminaMinutes = staminaMinutes - 2
|
|
else
|
|
staminaMinutes = 0
|
|
end
|
|
nextUseStaminaTime[playerId] = currentTime + 120
|
|
else
|
|
staminaMinutes = staminaMinutes - 1
|
|
nextUseStaminaTime[playerId] = currentTime + 60
|
|
end
|
|
player:setStamina(staminaMinutes)
|
|
end
|
|
|
|
function Player:onGainExperience(source, exp, rawExp)
|
|
if not source or source:isPlayer() then
|
|
return exp
|
|
end
|
|
|
|
-- Soul regeneration
|
|
local vocation = self:getVocation()
|
|
if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
|
|
soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
|
|
self:addCondition(soulCondition)
|
|
end
|
|
|
|
-- Apply experience stage multiplier
|
|
if (vocation:getId() > 0 or self:getLevel() < 8) then
|
|
exp = exp * Game.getExperienceStage(self:getLevel())
|
|
end
|
|
|
|
-- Stamina modifier
|
|
if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
|
|
useStamina(self)
|
|
|
|
if self:getStorageValue(17582) > os.time() then
|
|
exp = exp * 1.1
|
|
end
|
|
|
|
local staminaMinutes = self:getStamina()
|
|
if staminaMinutes <= 840 then
|
|
exp = exp * 0.5
|
|
end
|
|
end
|
|
|
|
if getGlobalStorageValue(17589) > os.time() then
|
|
exp = exp * (1 + getGlobalStorageValue(17585) / 100)
|
|
end
|
|
|
|
if source:isMonster() and not source:getMaster() then
|
|
if getGlobalStorageValue(8420) > 0 then
|
|
if source:getName():lower() == monsterOfTheDay[getGlobalStorageValue(8420)].monster:lower() then
|
|
exp = exp * (1 + getGlobalStorageValue(8421) / 100)
|
|
end
|
|
end
|
|
end
|
|
|
|
if self:isPremium() then
|
|
exp = exp * (1 + 10 / 100)
|
|
end
|
|
|
|
return exp
|
|
end
|
|
|
|
function Player:onLoseExperience(exp)
|
|
return exp
|
|
end
|
|
|
|
function Player:onGainSkillTries(skill, tries)
|
|
if APPLY_SKILL_MULTIPLIER == false then
|
|
return tries
|
|
end
|
|
|
|
if skill == SKILL_MAGLEVEL then
|
|
tries = tries * configManager.getNumber(configKeys.RATE_MAGIC)
|
|
|
|
if getGlobalStorageValue(17591) > os.time() then
|
|
tries = tries * (1 + getGlobalStorageValue(17587) / 100)
|
|
end
|
|
|
|
return tries
|
|
end
|
|
|
|
tries = tries * configManager.getNumber(configKeys.RATE_SKILL)
|
|
|
|
if getGlobalStorageValue(17590) > os.time() then
|
|
tries = tries * (1 + getGlobalStorageValue(17586) / 100)
|
|
end
|
|
|
|
return tries
|
|
end
|