Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create familiars lib #182

Merged
merged 5 commits into from
Jan 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/events/scripts/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function Player:onLook(thing, position, distance)
local master = thing:getMaster()
if master and table.contains(FAMILIARSNAME, thing:getName():lower()) then
description = description..' (Master: ' .. master:getName() .. '). \z
It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time())
It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.FamiliarSummon) - os.time())
end
end

Expand Down
7 changes: 4 additions & 3 deletions data/lib/core/storages.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ Storage = {
StoreExaust = 30001,
DelayLargeSeaShell = 30002,
Promotion = 30003,
PetSummonEvent10 = 30004,
PetSummonEvent60 = 30005,
Imbuement = 30006
Imbuement = 30004,
FamiliarSummon = 30005,
FamiliarSummonEvent10 = 30006,
FamiliarSummonEvent60 = 30007
}

GlobalStorage = {
Expand Down
29 changes: 29 additions & 0 deletions data/lib/tables/familiar.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FAMILIAR_ID = {
[VOCATION.BASE_ID.SORCERER] = {id = 994, name = "Sorcerer familiar"},
[VOCATION.BASE_ID.DRUID] = {id = 993, name = "Druid familiar"},
[VOCATION.BASE_ID.PALADIN] = {id = 992, name = "Paladin familiar"},
[VOCATION.BASE_ID.KNIGHT] = {id = 991, name = "Knight familiar"}
}

FAMILIAR_TIMER = {
[1] = {storage=Storage.FamiliarSummonEvent10, countdown=10, message = "10 seconds"},
[2] = {storage=Storage.FamiliarSummonEvent60, countdown=60, message = "one minute"}
}

function sendMessageFunction(pid, message)
if Player(pid) then
Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message)
end
end

function removeFamiliar(creatureId, playerId)
local creature = Creature(creatureId)
local player = Player(playerId)
if not creature or not player then
return true
end
creature:remove()
for sendMessage = 1, #FAMILIAR_TIMER do
player:setStorageValue(timer[sendMessage].storage, -1)
end
end
3 changes: 2 additions & 1 deletion data/lib/tables/load.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dofile('data/lib/tables/vocation.lua')
dofile('data/lib/tables/door.lua')
dofile('data/lib/tables/exercise_training.lua')
dofile('data/lib/tables/familiar.lua')
dofile('data/lib/tables/npc_spells.lua')
dofile('data/lib/tables/vocation.lua')
dofile('data/lib/tables/window.lua')
3 changes: 1 addition & 2 deletions data/monster/azure_frog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ monster.flags = {
isBlockable = false,
canWalkOnEnergy = false,
canWalkOnFire = false,
canWalkOnPoison = false,
pet = false
canWalkOnPoison = false
}

monster.light = {
Expand Down
3 changes: 1 addition & 2 deletions data/monster/toad.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ monster.flags = {
isBlockable = false,
canWalkOnEnergy = false,
canWalkOnFire = false,
canWalkOnPoison = false,
pet = false
canWalkOnPoison = false
}

monster.light = {
Expand Down
20 changes: 20 additions & 0 deletions data/scripts/creaturescripts/familiar/on_advance.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
local familiarOnAdvance = CreatureEvent("AdvanceFamiliar")

function familiarOnAdvance.onAdvance(player, skill, oldLevel, newLevel)
local vocation = FAMILIAR_ID[player:getVocation():getBaseId()]
if newLevel < 200 and not player:isPremium() then
return true
end

if vocation then
if player:getFamiliarLooktype() == 0 then
player:setFamiliarLooktype(vocation.id)
end
if not player:hasFamiliar(vocation.id) then
player:addFamiliar(vocation.id)
end
end
return true
end

familiarOnAdvance:register()
21 changes: 21 additions & 0 deletions data/scripts/creaturescripts/familiar/on_death.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
local familiarOnDeath = CreatureEvent("FamiliarDeath")

function familiarOnDeath.onDeath(creature, corpse, lasthitkiller, mostdamagekiller, lasthitunjustified, mostdamageunjustified)
local player = creature:getMaster()
if not player then
return false
end

local vocation = FAMILIAR_ID[player:getVocation():getBaseId()]

if table.contains(vocation, creature:getName()) then
player:setStorageValue(Storage.FamiliarSummon, os.time())
for sendMessage = 1, #FAMILIAR_TIMER do
stopEvent(player:getStorageValue(FAMILIAR_TIMER[sendMessage].storage))
player:setStorageValue(FAMILIAR_TIMER[sendMessage].storage, -1)
end
end
return true
end

familiarOnDeath:register()
54 changes: 54 additions & 0 deletions data/scripts/creaturescripts/familiar/on_login.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
local familiarOnLogin = CreatureEvent("FamiliarLogin")

function familiarOnLogin.onLogin(player)
if not player then
return false
end

local vocation = FAMILIAR_ID[player:getVocation():getBaseId()]

local familiarName
local familiarTimeLeft = player:getStorageValue(Storage.FamiliarSummon) - player:getLastLogout()

if vocation then
if (not player:isPremium() and player:hasFamiliar(vocation.id)) or player:getLevel() < 200 then
player:removeFamiliar(vocation.id)
elseif player:isPremium() and player:getLevel() >= 200 then
if familiarTimeLeft > 0 then
familiarName = vocation.name
end
if player:getFamiliarLooktype() == 0 then
player:setFamiliarLooktype(vocation.id)
end
if not player:hasFamiliar(vocation.id) then
player:addFamiliar(vocation.id)
end
end
end

if familiarName then
local position = player:getPosition()
local familiarMonster = Game.createMonster(familiarName, position, true, false, player)
if familiarMonster then

familiarMonster:setOutfit({lookType = player:getFamiliarLooktype()})
familiarMonster:registerEvent("FamiliarDeath")
position:sendMagicEffect(CONST_ME_MAGIC_BLUE)

local deltaSpeed = math.max(player:getSpeed() - familiarMonster:getSpeed(), 0)
familiarMonster:changeSpeed(deltaSpeed)

player:setStorageValue(Storage.FamiliarSummon, os.time() + familiarTimeLeft)
addEvent(removeFamiliar, familiarTimeLeft*1000, familiarMonster:getId(), player:getId())

for sendMessage = 1, #FAMILIAR_TIMER do
if player:getStorageValue(FAMILIAR_TIMER[sendMessage].storage) == -1 and familiarTimeLeft >= FAMILIAR_TIMER[sendMessage].countdown then
player:setStorageValue(FAMILIAR_TIMER[sendMessage].storage, addEvent(sendMessageFunction, (familiarTimeLeft-FAMILIAR_TIMER[sendMessage].countdown)*1000, player:getId(), FAMILIAR_TIMER[sendMessage].message))
end
end
end
end
return true
end

familiarOnLogin:register()
4 changes: 4 additions & 0 deletions data/scripts/globalevents/startup.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ function startup.onStartup()
db.asyncQuery("DELETE FROM `ip_bans` WHERE `expires_at` != 0 AND `expires_at` <= " .. os.time())
db.asyncQuery("DELETE FROM `market_history` WHERE `inserted` <= " .. (os.time() - configManager.getNumber(configKeys.MARKET_OFFER_DURATION)))

-- reset familiars message storage
db.query('DELETE FROM `player_storage` WHERE `key` = '..Storage.FamiliarSummonEvent10)
db.query('DELETE FROM `player_storage` WHERE `key` = '..Storage.FamiliarSummonEvent60)

-- Move expired bans to ban history
local resultId = db.storeQuery("SELECT * FROM `account_bans` WHERE `expires_at` != 0 AND `expires_at` <= " .. os.time())
if resultId ~= false then
Expand Down
4 changes: 2 additions & 2 deletions data/scripts/lib/register_monster_type.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ registerMonsterType.flags = function(mtype, mask)
if mask.flags.rewardBoss then
mtype:isRewardBoss(mask.flags.rewardBoss)
end
if mask.flags.pet then
mtype:isPet(mask.flags.pet)
if mask.flags.familiar then
mtype:familiar(mask.flags.familiar)
end
if mask.flags.respawntype or mask.flags.respawnType then
Spdlog.warn(string.format("[registerMonsterType.flags] - Monster: %s. Deprecated flag 'respawnType', use instead table 'respawnType = { period = RespawnPeriod_t, underground = boolean}'",
Expand Down
36 changes: 7 additions & 29 deletions data/scripts/spells/familiars/druid_familiar.lua
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
local spell = Spell("instant")

local familiar = {
[VOCATION.BASE_ID.DRUID] = {name = "Druid familiar"}
}

local timer = {
[1] = {storage=Storage.PetSummonEvent10, countdown=10, message = "10 seconds"},
[2] = {storage=Storage.PetSummonEvent60, countdown=60, message = "one minute"}
}

local function sendMessageFunction(pid, message)
if Player(pid) then
Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message)
end
end

local function removePet(creatureId, playerId)
local creature = Creature(creatureId)
local player = Player(playerId)
if not creature or not player then
return true
end
creature:remove()
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage, -1)
end
end
local spell = Spell("instant")

function spell.onCastSpell(player, variant)
local playerPosition = player:getPosition()
if not player or not isPremium(player) then
if not player or not player:isPremium() then
playerPosition:sendMagicEffect(CONST_ME_POFF)
player:sendCancelMessage("You need a premium account.")
return false
Expand Down Expand Up @@ -68,9 +45,10 @@ function spell.onCastSpell(player, variant)
playerPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
myFamiliar:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
player:setStorageValue(Storage.PetSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removePet, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage,addEvent(sendMessageFunction, (15*60-timer[sendMessage].countdown)*1000, player:getId(),timer[sendMessage].message))
player:setStorageValue(Storage.FamiliarSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removeFamiliar, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #FAMILIAR_TIMER do
player:setStorageValue(FAMILIAR_TIMER[sendMessage].storage,addEvent(sendMessageFunction, (15*60-FAMILIAR_TIMER[sendMessage].countdown)*1000, player:getId(),FAMILIAR_TIMER[sendMessage].message))
end
return true
end
Expand All @@ -85,4 +63,4 @@ spell:cooldown(30 * 60 * 1000)
spell:groupCooldown(2 * 1000)
spell:needLearn(false)
spell:vocation("druid;true", "elder druid;true")
spell:register()
spell:register()
37 changes: 7 additions & 30 deletions data/scripts/spells/familiars/knight_familiar.lua
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
local spell = Spell("instant")

local familiar = {
[VOCATION.BASE_ID.KNIGHT] = {name = "Knight familiar"}
}

local timer = {
[1] = {storage=Storage.PetSummonEvent10, countdown=10, message = "10 seconds"},
[2] = {storage=Storage.PetSummonEvent60, countdown=60, message = "one minute"}
}

local function sendMessageFunction(pid, message)
if Player(pid) then
Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message)
end
end

local function removePet(creatureId, playerId)
local creature = Creature(creatureId)
local player = Player(playerId)
if not creature or not player then
return true
end
creature:remove()
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage, -1)
end
end
local spell = Spell("instant")

function spell.onCastSpell(player, variant)
local playerPosition = player:getPosition()
if not player or not isPremium(player) then
if not player or not player:isPremium() then
playerPosition:sendMagicEffect(CONST_ME_POFF)
player:sendCancelMessage("You need a premium account.")
return false
Expand Down Expand Up @@ -67,10 +44,10 @@ function spell.onCastSpell(player, variant)
myFamiliar:changeSpeed(deltaSpeed)
playerPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
myFamiliar:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
player:setStorageValue(Storage.PetSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removePet, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage,addEvent(sendMessageFunction, (15*60-timer[sendMessage].countdown)*1000, player:getId(),timer[sendMessage].message))
player:setStorageValue(Storage.FamiliarSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removeFamiliar, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #FAMILIAR_TIMER do
player:setStorageValue(FAMILIAR_TIMER[sendMessage].storage,addEvent(sendMessageFunction, (15*60-FAMILIAR_TIMER[sendMessage].countdown)*1000, player:getId(),FAMILIAR_TIMER[sendMessage].message))
end
return true
end
Expand All @@ -85,4 +62,4 @@ spell:cooldown(30 * 60 * 1000)
spell:groupCooldown(2 * 1000)
spell:needLearn(false)
spell:vocation("knight;true", "elite knight;true")
spell:register()
spell:register()
37 changes: 7 additions & 30 deletions data/scripts/spells/familiars/paladin_familiar.lua
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
local spell = Spell("instant")

local familiar = {
[VOCATION.BASE_ID.PALADIN] = {name = "Paladin familiar"}
}

local timer = {
[1] = {storage=Storage.PetSummonEvent10, countdown=10, message = "10 seconds"},
[2] = {storage=Storage.PetSummonEvent60, countdown=60, message = "one minute"}
}

local function sendMessageFunction(pid, message)
if Player(pid) then
Player(pid):sendTextMessage(MESSAGE_LOOT, "Your summon will disappear in less than " .. message)
end
end

local function removePet(creatureId, playerId)
local creature = Creature(creatureId)
local player = Player(playerId)
if not creature or not player then
return true
end
creature:remove()
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage, -1)
end
end
local spell = Spell("instant")

function spell.onCastSpell(player, variant)
local playerPosition = player:getPosition()
if not player or not isPremium(player) then
if not player or not player:isPremium() then
playerPosition:sendMagicEffect(CONST_ME_POFF)
player:sendCancelMessage("You need a premium account.")
return false
Expand Down Expand Up @@ -67,10 +44,10 @@ function spell.onCastSpell(player, variant)
myFamiliar:changeSpeed(deltaSpeed)
playerPosition:sendMagicEffect(CONST_ME_MAGIC_BLUE)
myFamiliar:getPosition():sendMagicEffect(CONST_ME_TELEPORT)
player:setStorageValue(Storage.PetSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removePet, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #timer do
player:setStorageValue(timer[sendMessage].storage,addEvent(sendMessageFunction, (15*60-timer[sendMessage].countdown)*1000, player:getId(),timer[sendMessage].message))
player:setStorageValue(Storage.FamiliarSummon, os.time() + 15*60) -- 15 minutes from now
addEvent(removeFamiliar, 15*60*1000, myFamiliar:getId(), player:getId())
for sendMessage = 1, #FAMILIAR_TIMER do
player:setStorageValue(FAMILIAR_TIMER[sendMessage].storage,addEvent(sendMessageFunction, (15*60-FAMILIAR_TIMER[sendMessage].countdown)*1000, player:getId(),FAMILIAR_TIMER[sendMessage].message))
end
return true
end
Expand All @@ -85,4 +62,4 @@ spell:cooldown(30 * 60 * 1000)
spell:groupCooldown(2 * 1000)
spell:needLearn(false)
spell:vocation("paladin;true", "royal paladin;true")
spell:register()
spell:register()
Loading