introduce changes from streamside fork

This commit is contained in:
ErikasKontenis
2019-09-16 20:38:16 +03:00
parent f2cbc2dc1c
commit ad03b0eb3e
162 changed files with 2485 additions and 698 deletions

View File

@@ -2,7 +2,12 @@ local drunk = Condition(CONDITION_DRUNK)
drunk:setParameter(CONDITION_PARAM_TICKS, 60000)
local poison = Condition(CONDITION_POISON)
poison:setTiming(100)
poison:setParameter(CONDITION_PARAM_DELAYED, true)
poison:setParameter(CONDITION_PARAM_MINVALUE, -50)
poison:setParameter(CONDITION_PARAM_MAXVALUE, -120)
poison:setParameter(CONDITION_PARAM_STARTVALUE, -5)
poison:setParameter(CONDITION_PARAM_TICKINTERVAL, 5000)
poison:setParameter(CONDITION_PARAM_FORCEUPDATE, true)
local messages = {
[FLUID_WATER] = "Gulp.",

View File

@@ -1,7 +1,5 @@
function onLogin(player)
if player:getLastLoginSaved() <= 0 or player:getStorageValue(30017) == 1 then
player:setStorageValue(30017, 0) -- reset storage for first items
if player:getLastLoginSaved() <= 0 then
-- Items
if player:getSex() == PLAYERSEX_FEMALE then
player:addItem(3562, 1, true, -1, CONST_SLOT_ARMOR)

28
data/events/events.xml Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<events>
<!-- Creature methods -->
<event class="Creature" method="onChangeOutfit" enabled="0" />
<event class="Creature" method="onAreaCombat" enabled="0" />
<event class="Creature" method="onTargetCombat" enabled="0" />
<!-- Party methods -->
<event class="Party" method="onJoin" enabled="0" />
<event class="Party" method="onLeave" enabled="0" />
<event class="Party" method="onDisband" enabled="0" />
<event class="Party" method="onShareExperience" enabled="1" />
<!-- Player methods -->
<event class="Player" method="onLook" enabled="1" />
<event class="Player" method="onLookInBattleList" enabled="1" />
<event class="Player" method="onLookInTrade" enabled="1" />
<event class="Player" method="onMoveItem" enabled="1" />
<event class="Player" method="onItemMoved" enabled="0" />
<event class="Player" method="onMoveCreature" enabled="0" />
<event class="Player" method="onReportBug" enabled="1" />
<event class="Player" method="onTurn" enabled="0" />
<event class="Player" method="onTradeRequest" enabled="0" />
<event class="Player" method="onTradeAccept" enabled="0" />
<event class="Player" method="onGainExperience" enabled="1" />
<event class="Player" method="onLoseExperience" enabled="0" />
<event class="Player" method="onGainSkillTries" enabled="1" />
</events>

View File

@@ -0,0 +1,11 @@
function Creature:onChangeOutfit(outfit)
return true
end
function Creature:onAreaCombat(tile, isAggressive)
return RETURNVALUE_NOERROR
end
function Creature:onTargetCombat(target)
return RETURNVALUE_NOERROR
end

View File

@@ -0,0 +1,35 @@
function Party:onJoin(player)
return true
end
function Party:onLeave(player)
return true
end
function Party:onDisband()
return true
end
function Party:onShareExperience(exp)
local sharedExperienceMultiplier = 1.20 --20%
local vocationsIds = {}
local vocationId = self:getLeader():getVocation():getBase():getId()
if vocationId ~= VOCATION_NONE then
table.insert(vocationsIds, vocationId)
end
for _, member in ipairs(self:getMembers()) do
vocationId = member:getVocation():getBase():getId()
if not table.contains(vocationsIds, vocationId) and vocationId ~= VOCATION_NONE then
table.insert(vocationsIds, vocationId)
end
end
local size = #vocationsIds
if size > 1 then
sharedExperienceMultiplier = 1.0 + ((size * (5 * (size - 1) + 10)) / 100)
end
return (exp * sharedExperienceMultiplier) / (#self:getMembers() + 1)
end

View File

@@ -0,0 +1,169 @@
function Player:onLook(thing, position, distance)
local description = "You see " .. thing:getDescription(distance)
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)
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
exp = exp * Game.getExperienceStage(self:getLevel())
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
return tries * configManager.getNumber(configKeys.RATE_MAGIC)
end
return tries * configManager.getNumber(configKeys.RATE_SKILL)
end

View File

@@ -40,4 +40,8 @@ table.contains = function(array, value)
end
end
return false
end
function isNumber(str)
return tonumber(str) ~= nil
end

View File

@@ -9,3 +9,4 @@ dofile('data/lib/core/player.lua')
dofile('data/lib/core/position.lua')
dofile('data/lib/core/teleport.lua')
dofile('data/lib/core/tile.lua')
dofile('data/lib/core/vocation.lua')

View File

@@ -9,7 +9,7 @@ function Game.removeItemsOnMap(position)
local i = 0
while i < tileCount do
local tileItem = tile:getThing(i)
if tileItem and not tileItem:isCreature() and ItemType(tileItem:getId()):isMovable() then
if tileItem and tileItem:getType():isMovable() then
tileItem:remove()
else
i = i + 1
@@ -24,10 +24,8 @@ function Game.transformItemOnMap(position, itemId, toItemId, subtype)
local tile = Tile(position)
local item = tile:getItemById(itemId)
if item ~= nil then
item:transform(toItemId, subtype)
item:decay()
end
item:transform(toItemId, subtype)
item:decay()
return item
end

View File

@@ -21,3 +21,45 @@ end
function Tile.isTile(self)
return true
end
function Tile.relocateTo(self, toPosition, pushMove, monsterPosition)
if self:getPosition() == toPosition then
return false
end
if not Tile(toPosition) then
return false
end
for i = self:getThingCount() - 1, 0, -1 do
local thing = self:getThing(i)
if thing then
if thing:isItem() then
if ItemType(thing.itemid):isMovable() then
thing:moveTo(toPosition)
end
elseif thing:isCreature() then
if monsterPosition and thing:isMonster() then
thing:teleportTo(monsterPosition, pushMove)
else
thing:teleportTo(toPosition, pushMove)
end
end
end
end
return true
end
function Tile:getPlayers()
local players = {}
local creatures = self:getCreatures()
if (creatures) then
for i = 1, #creatures do
if (creatures[i]:isPlayer()) then
table.insert(players, creatures[i])
end
end
end
return players
end

View File

@@ -0,0 +1,7 @@
function Vocation.getBase(self)
local base = self
while base:getDemotion() do
base = base:getDemotion()
end
return base
end

View File

@@ -81,8 +81,7 @@ function onStepIn(creature, item, position, fromPosition)
return false
end
doRelocate(position, relPos)
Tile(item:getPosition()):relocateTo(relPos)
if item:getId() == 293 then
item:transform(294)
item:decay()

View File

@@ -0,0 +1,65 @@
local reloadTypes = {
["all"] = { targetType = RELOAD_TYPE_ALL, name = "all" },
["action"] = { targetType = RELOAD_TYPE_ACTIONS, name = "actions" },
["actions"] = { targetType = RELOAD_TYPE_ACTIONS, name = "actions" },
["chat"] = { targetType = RELOAD_TYPE_CHAT, name = "chatchannels" },
["channel"] = { targetType = RELOAD_TYPE_CHAT, name = "chatchannels" },
["chatchannels"] = { targetType = RELOAD_TYPE_CHAT, name = "chatchannels" },
["config"] = { targetType = RELOAD_TYPE_CONFIG, name = "config" },
["configuration"] = { targetType = RELOAD_TYPE_CONFIG, name = "config" },
["creaturescript"] = { targetType = RELOAD_TYPE_CREATURESCRIPTS, name = "creature scripts" },
["creaturescripts"] = { targetType = RELOAD_TYPE_CREATURESCRIPTS, name = "creature scripts" },
["events"] = { targetType = RELOAD_TYPE_EVENTS, name = "events" },
["global"] = { targetType = RELOAD_TYPE_GLOBAL, name = "global.lua" },
["globalevent"] = { targetType = RELOAD_TYPE_GLOBALEVENTS, name = "globalevents" },
["globalevents"] = { targetType = RELOAD_TYPE_GLOBALEVENTS, name = "globalevents" },
["items"] = { targetType = RELOAD_TYPE_ITEMS, name = "items" },
["monster"] = { targetType = RELOAD_TYPE_MONSTERS, name = "monsters" },
["monsters"] = { targetType = RELOAD_TYPE_MONSTERS, name = "monsters" },
["move"] = { targetType = RELOAD_TYPE_MOVEMENTS, name = "movements" },
["movement"] = { targetType = RELOAD_TYPE_MOVEMENTS, name = "movements" },
["movements"] = { targetType = RELOAD_TYPE_MOVEMENTS, name = "movements" },
["npc"] = { targetType = RELOAD_TYPE_NPCS, name = "npcs" },
["npcs"] = { targetType = RELOAD_TYPE_NPCS, name = "npcs" },
["raid"] = { targetType = RELOAD_TYPE_RAIDS, name = "raids" },
["raids"] = { targetType = RELOAD_TYPE_RAIDS, name = "raids" },
["spell"] = { targetType = RELOAD_TYPE_SPELLS, name = "spells" },
["spells"] = { targetType = RELOAD_TYPE_SPELLS, name = "spells" },
["talk"] = { targetType = RELOAD_TYPE_TALKACTIONS, name = "talk actions" },
["talkaction"] = { targetType = RELOAD_TYPE_TALKACTIONS, name = "talk actions" },
["talkactions"] = { targetType = RELOAD_TYPE_TALKACTIONS, name = "talk actions" }
}
function onSay(player, words, param)
if not player:getGroup():getAccess() then
return true
end
if player:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then
return false
end
local reloadType = reloadTypes[param and param:lower()]
if not reloadType then
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Reload type not found.")
return false
end
Game.reload(reloadType.targetType)
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, string.format("Reloaded %s.", reloadType.name))
return true
end

View File

@@ -0,0 +1,23 @@
function onSay(player, words, param)
local function timeSave(delay, msg)
broadcastMessage(msg, MESSAGE_STATUS_WARNING)
player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, msg)
addEvent(saveServer, delay)
end
if not player:getGroup():getAccess() then
return true
end
if player:getAccountType() < ACCOUNT_TYPE_GOD then
return false
end
if isNumber(param) then
local delay = tonumber(param) * 1000
timeSave(delay, "Saving server in " .. tonumber(param) .. " seconds.")
else
saveServer()
end
end

View File

@@ -0,0 +1,19 @@
function onSay(player, words, param)
local tradePartner = Player(param)
if not tradePartner or tradePartner == player then
player:sendCancelMessage("Trade player not found.")
return false
end
local house = player:getTile():getHouse()
if not house then
player:sendCancelMessage("You must stand in your house to initiate the trade.")
return false
end
local returnValue = house:startTrade(player, tradePartner)
if returnValue ~= RETURNVALUE_NOERROR then
player:sendCancelMessage(returnValue)
end
return false
end

View File

@@ -27,7 +27,9 @@
<talkaction words="/removetutor" separator=" " script="remove_tutor.lua" />
<talkaction words="/looktype" separator=" " script="looktype.lua" />
<talkaction words="/summon" separator=" " script="place_summon.lua" />
<talkaction words="/chameleon" separator=" " script="chameleon.lua" />
<talkaction words="/reload" separator=" " script="reload.lua" />
<talkaction words="/save" script="save.lua" />
<talkaction words="/chameleon" separator=" " script="chameleon.lua" />
<talkaction words="/addskill" separator=" " script="add_skill.lua" />
<talkaction words="/mccheck" script="mccheck.lua" />
<talkaction words="/ghost" script="ghost.lua" />
@@ -37,6 +39,7 @@
<!-- player talkactions -->
<talkaction words="!buypremium" script="buyprem.lua"/>
<talkaction words="!buyhouse" script="buyhouse.lua"/>
<talkaction words="!sellhouse" separator=" " script="sellhouse.lua" />
<talkaction words="!leavehouse" script="leavehouse.lua"/>
<talkaction words="!changesex" script="changesex.lua"/>
<talkaction words="!uptime" script="uptime.lua"/>