Skip to content

Commit

Permalink
Merge branch 'main' into canary-upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
dudantas authored Dec 2, 2023
2 parents 797b8e6 + 466aa96 commit 0a6828b
Show file tree
Hide file tree
Showing 11 changed files with 457 additions and 266 deletions.
123 changes: 61 additions & 62 deletions data-otservbr-global/npc/hireling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ function createHirelingType(HirelingName)
{ itemName = "wooden chair kit", clientId = 2777, buy = 15 },
{ itemName = "yellow pillow", clientId = 900, buy = 25 },
{ itemName = "yellow tapestry", clientId = 2650, buy = 25 },
{ itemName = "exercise axe", clientId = 28553, buy = 262500, subType = 500 },
{ itemName = "exercise bow", clientId = 28555, buy = 262500, subType = 500 },
{ itemName = "exercise club", clientId = 28554, buy = 262500, subType = 500 },
{ itemName = "exercise rod", clientId = 28556, buy = 262500, subType = 500 },
{ itemName = "exercise sword", clientId = 28552, buy = 262500, subType = 500 },
{ itemName = "exercise wand", clientId = 28557, buy = 262500, subType = 500 },
{ itemName = "durable exercise axe", clientId = 35280, buy = 945000, subType = 1800 },
{ itemName = "durable exercise bow", clientId = 35282, buy = 945000, subType = 1800 },
{ itemName = "durable exercise club", clientId = 35281, buy = 945000, subType = 1800 },
{ itemName = "durable exercise rod", clientId = 35283, buy = 945000, subType = 1800 },
{ itemName = "durable exercise sword", clientId = 35279, buy = 945000, subType = 1800 },
{ itemName = "durable exercise wand", clientId = 35284, buy = 945000, subType = 1800 },
},
["exercise weapons"] = {
{ itemName = "exercise axe", clientId = 28553, buy = 262500, subType = 500 },
Expand Down Expand Up @@ -240,38 +252,19 @@ function createHirelingType(HirelingName)
{ itemName = "throwing star", clientId = 3287, buy = 42 },
{ itemName = "vortex bolt", clientId = 14252, buy = 6 },
},
["wands"] = {
["rods"] = {
{ itemName = "exercise rod", clientId = 28556, buy = 236250, subType = 500 },
{ itemName = "exercise wand", clientId = 28557, buy = 236250, subType = 500 },
{ itemName = "hailstorm rod", clientId = 3067, buy = 15000 },
{ itemName = "moonlight rod", clientId = 3070, buy = 1000 },
{ itemName = "necrotic rod", clientId = 3069, buy = 5000 },
{ itemName = "northwind rod", clientId = 8083, buy = 7500 },
{ itemName = "snakebite rod", clientId = 3066, buy = 500 },
{ itemName = "spellwand", clientId = 651, sell = 299 },
{ itemName = "springsprout rod", clientId = 8084, buy = 18000 },
{ itemName = "terra rod", clientId = 3065, buy = 10000 },
{ itemName = "underworld rod", clientId = 8082, buy = 22000 },
{ itemName = "wand of cosmic energy", clientId = 3073, buy = 10000 },
{ itemName = "wand of decay", clientId = 3072, buy = 5000 },
{ itemName = "wand of draconia", clientId = 8093, buy = 7500 },
{ itemName = "wand of dragonbreath", clientId = 3075, buy = 1000 },
{ itemName = "wand of inferno", clientId = 3071, buy = 15000 },
{ itemName = "wand of starstorm", clientId = 8092, buy = 18000 },
{ itemName = "wand of voodoo", clientId = 8094, buy = 22000 },
{ itemName = "wand of vortex", clientId = 3074, buy = 500 },
},
["rods"] = {
{ itemName = "exercise rod", clientId = 28556, buy = 236250, subType = 500 },
["wands"] = {
{ itemName = "exercise wand", clientId = 28557, buy = 236250, subType = 500 },
{ itemName = "hailstorm rod", clientId = 3067, buy = 15000 },
{ itemName = "moonlight rod", clientId = 3070, buy = 1000 },
{ itemName = "necrotic rod", clientId = 3069, buy = 5000 },
{ itemName = "northwind rod", clientId = 8083, buy = 7500 },
{ itemName = "snakebite rod", clientId = 3066, buy = 500 },
{ itemName = "springsprout rod", clientId = 8084, buy = 18000 },
{ itemName = "terra rod", clientId = 3065, buy = 10000 },
{ itemName = "underworld rod", clientId = 8082, buy = 22000 },
{ itemName = "wand of cosmic energy", clientId = 3073, buy = 10000 },
{ itemName = "wand of decay", clientId = 3072, buy = 5000 },
{ itemName = "wand of draconia", clientId = 8093, buy = 7500 },
Expand Down Expand Up @@ -358,6 +351,7 @@ function createHirelingType(HirelingName)
{ itemName = "torch", clientId = 2920, buy = 2 },
{ itemName = "watch", clientId = 2906, buy = 20, sell = 6 },
{ itemName = "worm", clientId = 3492, buy = 1 },
{ itemName = "spellwand", clientId = 651, sell = 299 },
},
["postal"] = {
{ itemName = "label", clientId = 3507, buy = 1 },
Expand Down Expand Up @@ -436,14 +430,14 @@ function createHirelingType(HirelingName)

local function getHirelingSkills()
local skills = {}
if hireling:hasSkill(HIRELING_SKILLS.BANKER) then
table.insert(skills, HIRELING_SKILLS.BANKER)
if hireling:hasSkill(HIRELING_SKILLS.BANKER[2]) then
table.insert(skills, HIRELING_SKILLS.BANKER[1])
end
if hireling:hasSkill(HIRELING_SKILLS.COOKING) then
table.insert(skills, HIRELING_SKILLS.COOKING)
if hireling:hasSkill(HIRELING_SKILLS.COOKING[2]) then
table.insert(skills, HIRELING_SKILLS.COOKING[1])
end
if hireling:hasSkill(HIRELING_SKILLS.STEWARD) then
table.insert(skills, HIRELING_SKILLS.STEWARD)
if hireling:hasSkill(HIRELING_SKILLS.STEWARD[2]) then
table.insert(skills, HIRELING_SKILLS.STEWARD[1])
end
-- ignoring trader skills as it shows the same message about {goods}
return skills
Expand All @@ -460,11 +454,11 @@ function createHirelingType(HirelingName)
str = str .. ", "
end

if skills[i] == HIRELING_SKILLS.BANKER then
if skills[i] == HIRELING_SKILLS.BANKER[1] then
str = str .. "to access your {bank} account" -- TODO: this setence is not official
elseif skills[i] == HIRELING_SKILLS.COOKING then
elseif skills[i] == HIRELING_SKILLS.COOKING[1] then
str = str .. "to order {food}"
elseif skills[i] == HIRELING_SKILLS.STEWARD then
elseif skills[i] == HIRELING_SKILLS.STEWARD[1] then
str = str .. "to open your {stash}"
end
end
Expand All @@ -478,21 +472,10 @@ function createHirelingType(HirelingName)
return str
end

local function sendSkillNotLearned(npc, creature, SKILL)
local function sendSkillNotLearned(npc, creature, skillName)
local message = "Sorry, but I do not have mastery in this skill yet."
local profession
if SKILL == HIRELING_SKILLS.BANKER then
profession = "banker"
elseif SKILL == HIRELING_SKILLS.COOKING then
profession = "cooker"
elseif SKILL == HIRELING_SKILLS.STEWARD then
profession = "steward"
elseif SKILL == HIRELING_SKILLS.TRADER then
profession = "trader"
end

if profession then
message = string.format("I'm not a %s and would not know how to help you with that, sorry. I can start a %s apprenticeship if you buy it for me in the store!", profession, profession)
if skillName then
message = string.format("I'm not a %s and would not know how to help you with that, sorry. I can start a %s apprenticeship if you buy it for me in the store!", skillName, skillName)
end

npcHandler:say(message, npc, creature)
Expand Down Expand Up @@ -559,7 +542,7 @@ function createHirelingType(HirelingName)
npcHandler:setTopic(playerId, TOPIC_FOOD.SKILL_CHOOSE)
npcHandler:say("Yay! I have the ingredients to make a skill boost dish. Would you rather like to boost your {magic}, {melee}, {shielding} or {distance} skill?", npc, creature)
else -- deliver the random generated index
deliverFood(npc, creature, HIRELING_FOODS[random])
deliverFood(npc, creature, HIRELING_FOODS_IDS[random])
end
end

Expand Down Expand Up @@ -614,32 +597,35 @@ function createHirelingType(HirelingName)
npcHandler:say(servicesMsg, npc, creature)
elseif npcHandler:getTopic(playerId) == TOPIC.SERVICES then
if MsgContains(message, "bank") then
if hireling:hasSkill(HIRELING_SKILLS.BANKER) then
local bankerSkillName = HIRELING_SKILLS.BANKER[2]
if hireling:hasSkill(bankerSkillName) then
npcHandler:setTopic(playerId, TOPIC.BANK)
count[playerId], transfer[playerId] = nil, nil
npcHandler:say(GREETINGS.BANK, npc, creature)
else
sendSkillNotLearned(npc, creature, HIRELING_SKILLS.BANKER)
sendSkillNotLearned(npc, creature, bankerSkillName)
end
elseif MsgContains(message, "food") then
if hireling:hasSkill(HIRELING_SKILLS.COOKING) then
local bankerSkillName = HIRELING_SKILLS.COOKING[2]
if hireling:hasSkill(bankerSkillName) then
npcHandler:setTopic(playerId, TOPIC.FOOD)
npcHandler:say(GREETINGS.FOOD, npc, creature)
else
sendSkillNotLearned(npc, creature, HIRELING_SKILLS.COOKING)
sendSkillNotLearned(npc, creature, bankerSkillName)
end
elseif MsgContains(message, "stash") then
if hireling:hasSkill(HIRELING_SKILLS.STEWARD) then
local bankerSkillName = HIRELING_SKILLS.STEWARD[2]
if hireling:hasSkill(bankerSkillName) then
npcHandler:say(GREETINGS.STASH, npc, creature)
player:setSpecialContainersAvailable(true)
player:openStash(true)
player:sendTextMessage(MESSAGE_FAILURE, "Your supply stash contains " .. player:getStashCount() .. " item" .. (player:getStashCount() > 1 and "s." or "."))
else
sendSkillNotLearned(npc, creature, HIRELING_SKILLS.STEWARD)
sendSkillNotLearned(npc, creature, bankerSkillName)
end
elseif MsgContains(message, "goods") then
local string
if not hireling:hasSkill(HIRELING_SKILLS.TRADER) then
if not hireling:hasSkill(HIRELING_SKILLS.TRADER[2]) then
string = "While I'm not a trader, I still have a collection of {various} items to sell if you like!"
else
string = "I sell a selection of {various} items, {exercise weapons}, {equipment}, " .. "{distance} weapons, {wands} and {rods}, {potions}, {runes}, " .. "{supplies}, {tools} and {postal} goods. Just ask!"
Expand All @@ -648,18 +634,18 @@ function createHirelingType(HirelingName)
npcHandler:say(string, npc, creature)
elseif MsgContains(message, "lamp") then
npcHandler:setTopic(playerId, TOPIC.LAMP)
if player:getGuid() == hireling:getOwnerId() then
npcHandler:say("Are you sure you want me to go back to my lamp?", npc, creature)
else
if player:getGuid() ~= hireling:getOwnerId() then
return false
end

npcHandler:say("Are you sure you want me to go back to my lamp?", npc, creature)
elseif MsgContains(message, "outfit") then
if player:getGuid() == hireling:getOwnerId() then
hireling:requestOutfitChange()
npcHandler:say("As you wish!", npc, creature)
else
if player:getGuid() ~= hireling:getOwnerId() then
return false
end

hireling:requestOutfitChange()
npcHandler:say("As you wish!", npc, creature)
end
elseif npcHandler:getTopic(playerId) == TOPIC.LAMP then
if MsgContains(message, "yes") then
Expand All @@ -670,12 +656,25 @@ function createHirelingType(HirelingName)
end
elseif npcHandler:getTopic(playerId) == TOPIC.BANK then
enableBankSystem[playerId] = true
elseif npcHandler:getTopic(playerId) >= TOPIC.FOOD and npcHandler:getTopic(playerId) < TOPIC.GOODS then
elseif npcHandler:getTopic(playerId) == TOPIC.FOOD then
handleFoodActions(npc, creature, message)
elseif npcHandler:getTopic(playerId) == TOPIC.GOODS then
-- Ensures players cannot access other shop categories
if not hireling:hasSkill(HIRELING_SKILLS.TRADER[2]) then
if not MsgContains(message, "various") then
local text = "While I'm not a trader, I still have a collection of {various} items to sell if you like!"
npcHandler:say(text, npc, creature)
return
end

npcHandler:say("Here are the items for the category various.", npc, creature)
npc:openShopWindowTable(player, itemsTable["various"])
return
end

local categoryTable = itemsTable[message:lower()]
if categoryTable then
npcHandler:say("Here are the items for the category " .. message, npc, creature)
npcHandler:say("Here are the items for the category " .. message .. ".", npc, creature)
npc:openShopWindowTable(player, categoryTable)
end
end
Expand All @@ -690,7 +689,7 @@ function createHirelingType(HirelingName)
return true
end

npcHandler:setMessage(MESSAGE_GREET, "It is good to see you. I'm always at your {service}")
npcHandler:setMessage(MESSAGE_GREET, "It is good to see you. I'm always at your {service}.")
npcHandler:setMessage(MESSAGE_FAREWELL, "Farewell, |PLAYERNAME|, I'll be here if you need me again.")
npcHandler:setMessage(MESSAGE_WALKAWAY, "Come back soon!")

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
local old_hirelingSkills = {
BANKER = 1, -- 1<<0
COOKING = 2, -- 1<<1
STEWARD = 4, -- 1<<2
TRADER = 8, -- 1<<3
}

local old_hirelingOutfits = {
BANKER = 1, -- 1<<0
COOKING = 2, -- 1<<1
STEWARD = 4, -- 1<<2
TRADER = 8, -- 1<<3 ...
SERVANT = 16,
HYDRA = 32,
FERUMBRAS = 64,
BONELORD = 128,
DRAGON = 256,
}

local old_hirelingStorage = {
SKILL = 28800,
OUTFIT = 28900,
}

local function getOutfits(player)
local flags = player:getStorageValue(old_hirelingStorage.OUTFIT)
local outfits = {}
if flags <= 0 then
return outfits
end
for key, value in pairs(old_hirelingOutfits) do
if hasBitSet(value, flags) then
table.insert(outfits, key)
end
end
return outfits
end

local function getSkills(player)
local flags = player:getStorageValue(old_hirelingStorage.SKILL)
local skills = {}
if flags <= 0 then
return skills
end
for key, value in pairs(old_hirelingSkills) do
if hasBitSet(value, flags) then
table.insert(skills, key)
end
end
return skills
end

local function migrateHirelingData(player)
if not player then
return false
end

local outfits = getOutfits(player)
local skills = getSkills(player)
if #outfits == 0 and #skills == 0 then
return true
end
logger.info("Migrating hireling data for player {}", player:getName())
for _, outfit in pairs(outfits) do
logger.debug("Enabling hireling outfit: {}", outfit)
local outfit = HIRELING_OUTFITS[outfit]
if outfit then
local name = outfit[2]
if name then
player:enableHirelingOutfit(name)
else
logger.error("Invalid hireling outfit name: {}", outfit[1])
end
else
logger.error("Invalid hireling outfit: {}", outfit)
end
end

for _, skill in pairs(skills) do
logger.debug("Enabling hireling skill: {}", skill)
local skill = HIRELING_SKILLS[skill]
if skill then
local name = skill[2]
if name then
player:enableHirelingSkill(name)
else
logger.error("Invalid hireling skill name: {}", skill[1])
end
else
logger.error("Invalid hireling skill: {}", skill)
end
end
end

local migration = Migration("20231128213158_move_hireling_data_to_kv")

function migration:onExecute()
self:forEachPlayer(migrateHirelingData)
end

migration:register()
Loading

0 comments on commit 0a6828b

Please sign in to comment.