Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into kokekanon/all-featu…
Browse files Browse the repository at this point in the history
…re-redemption
  • Loading branch information
kokekanon committed Nov 25, 2024
2 parents 687d0b2 + a77f3c3 commit dce1886
Show file tree
Hide file tree
Showing 28 changed files with 296 additions and 232 deletions.
2 changes: 2 additions & 0 deletions data-canary/scripts/actions/objects/imbuement_shrine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ function imbuement.onUse(player, item, fromPosition, target, toPosition, isHotke
return true
end

imbuement:position({ x = 1943, y = 1340, z = 7 }, 25061)

imbuement:id(25060, 25061, 25103, 25104, 25202, 25174, 25175, 25182, 25183)
imbuement:register()
6 changes: 3 additions & 3 deletions data-otservbr-global/lib/quests/soul_war.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ function Player:getSoulWarZoneMonster()
return zoneMonsterName
end

function Player:isInBoatSpot()
function Creature:isInBoatSpot()
-- Get ebb and flow zone and check if player is in zone
local zone = SoulWarQuest.ebbAndFlow.getZone()
local tile = Tile(self:getPosition())
Expand All @@ -1464,11 +1464,11 @@ function Player:isInBoatSpot()
groundId = tile:getGround():getId()
end
if zone and zone:isInZone(self:getPosition()) and tile and groundId == SoulWarQuest.ebbAndFlow.boatId then
logger.trace("Player {} is in boat spot", self:getName())
logger.trace("Creature {} is in boat spot", self:getName())
return true
end

logger.trace("Player {} is not in boat spot", self:getName())
logger.trace("Creature {} is not in boat spot", self:getName())
return false
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ monster.loot = {
{ id = 6558, chance = 10000 }, -- flask of demonic blood
{ id = 6558, chance = 10000 }, -- flask of demonic blood
{ id = 6558, chance = 10000 }, -- flask of demonic blood
{ id = 17838, chance = 1800 }, -- unknown item
{ id = 3019, chance = 1000 }, -- demonbone amulet
{ id = 3026, chance = 12000, maxCount = 8 }, -- white pearl
{ id = 3029, chance = 12000, maxCount = 9 }, -- small sapphire
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ monster.loot = {
{ name = "butcher's axe", chance = 1000 },
{ name = "dreaded cleaver", chance = 1000 },
{ name = "mercenary sword", chance = 1000 },
{ id = 28341, chance = 1000 }, -- tessellated wall
{ name = "slightly rusted shield", chance = 5880 },
{ name = "slightly rusted helmet", chance = 35290 },
{ name = "epaulette", chance = 500 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ monster.loot = {
{ name = "dreaded cleaver", chance = 30000 },
{ name = "slightly rusted shield", chance = 26670 },
{ name = "wand of inferno", chance = 30000 },
{ id = 28341, chance = 1000 }, -- tessellated wall
{ name = "sturdy book", chance = 1000 },
}

Expand Down
68 changes: 49 additions & 19 deletions data-otservbr-global/npc/hireling.lua
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,13 @@ function createHirelingType(HirelingName)

local TOPIC_FOOD = {
SKILL_CHOOSE = 1301,
SKILL_SURPRISE = 1302,
}

local GREETINGS = {
BANK = "Alright! What can I do for you and your bank business, |PLAYERNAME|?",
FOOD = "Hmm, yes! A variety of fine food awaits! However, a small expense of 15000 gold is expected to make these delicious masterpieces happen. Shall I?",
FOOD = [[Hmm, yes! A variety of fine food awaits! However, a small expense of 15000 gold is expected to make these delicious masterpieces happen.
For 90000 gold I will also serve you a specific dish. Just tell me what it shall be: a {specific} meal or a little {surprise}.]],
STASH = "Of course, here is your stash! Well-maintained and neatly sorted for your convenience!",
}

Expand Down Expand Up @@ -513,7 +515,7 @@ function createHirelingType(HirelingName)
return message
end

local function deliverFood(npc, creature, food_id)
local function deliverFood(npc, creature, food_id, cost)
local playerId = creature:getId()
local player = Player(creature)
local itType = ItemType(food_id)
Expand All @@ -523,8 +525,8 @@ function createHirelingType(HirelingName)
npcHandler:say("Sorry, but you don't have enough capacity.", npc, creature)
elseif not inbox or #inboxItems >= inbox:getMaxCapacity() then
player:getPosition():sendMagicEffect(CONST_ME_POFF)
npcHandler:say("Sorry, you don't have enough room on your inbox", npc, creature)
elseif not player:removeMoneyBank(15000) then
npcHandler:say("Sorry, you don't have enough room on your inbox.", npc, creature)
elseif not player:removeMoneyBank(cost) then
npcHandler:say("Sorry, you don't have enough money.", npc, creature)
else
local message = getDeliveredMessageByFoodId(food_id)
Expand All @@ -534,38 +536,66 @@ function createHirelingType(HirelingName)
npcHandler:setTopic(playerId, TOPIC.SERVICES)
end

local function cookFood(npc, creature)
local function cookFood(npc, creature, specificRequest)
local playerId = creature:getId()
local random = math.random(6)
if random == 6 then
-- ask for preferred skill
if specificRequest then
npcHandler:say("Very well. You may choose one of the following: {chilli con carniphila}, {svargrond salmon filet}, {carrion casserole}, {consecrated beef}, {roasted wyvern wings}, {carrot pie}, {tropical marinated tiger}, or {delicatessen salad}.", npc, creature)
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_IDS[random])
else
npcHandler:say("Alright, let me astonish you. Shall I?", npc, creature)
deliverFood(npc, creature, HIRELING_FOODS_IDS[math.random(#HIRELING_FOODS_IDS)], 15000)
end
end

local function handleFoodActions(npc, creature, message)
local playerId = creature:getId()

if npcHandler:getTopic(playerId) == TOPIC.FOOD then
if MsgContains(message, "yes") then
cookFood(npc, creature)
if MsgContains(message, "specific") then
npcHandler:setTopic(playerId, TOPIC_FOOD.SPECIFIC)
npcHandler:say("Which specific meal would you like? Choices are: {chilli con carniphila}, {svargrond salmon filet}, {carrion casserole}, {consecrated beef}, {roasted wyvern wings}, {carrot pie}, {tropical marinated tiger}, or {delicatessen salad}.", npc, creature)
elseif MsgContains(message, "surprise") then
local random = math.random(6)
if random == 6 then
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
deliverFood(npc, creature, HIRELING_FOODS_IDS[random], 15000)
end
elseif MsgContains(message, "yes") then
deliverFood(npc, creature, HIRELING_FOODS_IDS[math.random(#HIRELING_FOODS_IDS)], 15000)
elseif MsgContains(message, "no") then
npcHandler:setTopic(playerId, TOPIC.SERVICES)
npcHandler:say("Alright then, ask me for other {services}, if you want.", npc, creature)
end
elseif npcHandler:getTopic(playerId) == TOPIC_FOOD.SKILL_CHOOSE then
if MsgContains(message, "magic") then
deliverFood(npc, creature, HIRELING_FOODS_BOOST.MAGIC)
deliverFood(npc, creature, HIRELING_FOODS_BOOST.MAGIC, 15000)
elseif MsgContains(message, "melee") then
deliverFood(npc, creature, HIRELING_FOODS_BOOST.MELEE)
deliverFood(npc, creature, HIRELING_FOODS_BOOST.MELEE, 15000)
elseif MsgContains(message, "shielding") then
deliverFood(npc, creature, HIRELING_FOODS_BOOST.SHIELDING)
deliverFood(npc, creature, HIRELING_FOODS_BOOST.SHIELDING, 15000)
elseif MsgContains(message, "distance") then
deliverFood(npc, creature, HIRELING_FOODS_BOOST.DISTANCE)
deliverFood(npc, creature, HIRELING_FOODS_BOOST.DISTANCE, 15000)
else
npcHandler:say("Sorry, but you must choose a valid skill class. Would you like to boost your {magic}, {melee}, {shielding}, or {distance} skill?", npc, creature)
end
elseif npcHandler:getTopic(playerId) == TOPIC_FOOD.SPECIFIC then
local specificFoodOptions = {
["chilli con carniphila"] = 29412,
["svargrond salmon filet"] = 29413,
["carrion casserole"] = 29414,
["consecrated beef"] = 29415,
["roasted wyvern wings"] = 29408,
["carrot pie"] = 29409,
["tropical marinated tiger"] = 29410,
["delicatessen salad"] = 29411,
}

if specificFoodOptions[message:lower()] then
deliverFood(npc, creature, specificFoodOptions[message:lower()], 90000)
else
npcHandler:say("Sorry, but you must choose a valid skill class. Would you like to boost your {magic}, {melee}, {shielding} or {distance} skill?", npc, creature)
npcHandler:say("I'm sorry, but that's not a valid food option. Please choose from: {chilli con carniphila}, {svargrond salmon filet}, {carrion casserole}, {consecrated beef}, {roasted wyvern wings}, {carrot pie}, {tropical marinated tiger}, or {delicatessen salad}.", npc, creature)
end
end
end
Expand Down Expand Up @@ -656,7 +686,7 @@ function createHirelingType(HirelingName)
end
elseif npcHandler:getTopic(playerId) == TOPIC.BANK then
enableBankSystem[playerId] = true
elseif npcHandler:getTopic(playerId) == TOPIC.FOOD or npcHandler:getTopic(playerId) == TOPIC_FOOD.SKILL_CHOOSE then
elseif npcHandler:getTopic(playerId) == TOPIC.FOOD or npcHandler:getTopic(playerId) == TOPIC_FOOD.SKILL_CHOOSE or npcHandler:getTopic(playerId) == TOPIC_FOOD.SPECIFIC then
handleFoodActions(npc, creature, message)
elseif npcHandler:getTopic(playerId) == TOPIC.GOODS then
-- Ensures players cannot access other shop categories
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,3 @@ end

rewardSoulWar:position({ x = 33620, y = 31400, z = 10 })
rewardSoulWar:register()

local phantasmalJadeMount = Action()

function phantasmalJadeMount.onUse(player, item, fromPosition, target, toPosition, isHotkey)
local soulWarQuest = player:soulWarQuestKV()
if soulWarQuest:get("panthasmal-jade-mount") then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You already have Phantasmal Jade mount!")
return true
end

if table.contains({ 34072, 34073, 34074 }, item.itemid) then
if player:getItemCount(34072) >= 4 and player:getItemCount(34073) == 1 and player:getItemCount(34074) == 1 then
player:removeItem(34072, 4)
player:removeItem(34073, 1)
player:removeItem(34074, 1)
player:addMount(167)
player:addAchievement("You got Horse Power")
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Congratulations! You won Phantasmal Jade mount.")
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Congratulations! You won You got Horse Power achievement.")
player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE)
soulWarQuest:set("panthasmal-jade-mount", true)
else
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You don't have the necessary items!")
player:getPosition():sendMagicEffect(CONST_ME_POFF)
end
end

return true
end

phantasmalJadeMount:id(34072, 34073, 34074)
phantasmalJadeMount:register()
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@ local function updateWaterPoolsSize()
end

local function loadMapEmpty()
if SoulWarQuest.ebbAndFlow.getZone():countPlayers() > 0 then
local players = SoulWarQuest.ebbAndFlow.getZone():getPlayers()
for _, player in ipairs(players) do
if player:getPosition().z == 8 then
if player:isInBoatSpot() then
local teleportPosition = player:getPosition()
teleportPosition.z = 9
player:teleportTo(teleportPosition)
logger.trace("Teleporting player to down.")
local playersInZone = SoulWarQuest.ebbAndFlow.getZone():countPlayers()
local monstersInZone = SoulWarQuest.ebbAndFlow.getZone():countMonsters()
if playersInZone > 0 or monstersInZone > 0 then
local creatures = SoulWarQuest.ebbAndFlow.getZone():getCreatures()
for _, creature in ipairs(creatures) do
local creatureMaster = creature:getMaster()
local player = creature:getPlayer()
if creature:isPlayer() or (creature:isMonster() and creatureMaster and creatureMaster:getPlayer()) then
if creature:getPosition().z == 8 then
if creature:isInBoatSpot() then
local teleportPosition = creature:getPosition()
teleportPosition.z = 9
creature:teleportTo(teleportPosition)
logger.trace("Teleporting player to down.")
end
if player then
player:sendCreatureAppear()
end
end
player:sendCreatureAppear()
end
end
end
Expand Down Expand Up @@ -72,22 +80,30 @@ local function findNearestRoomPosition(playerPosition)
end

local function loadMapInundate()
if SoulWarQuest.ebbAndFlow.getZone():countPlayers() > 0 then
local players = SoulWarQuest.ebbAndFlow.getZone():getPlayers()
for _, player in ipairs(players) do
local playerPosition = player:getPosition()
if playerPosition.z == 9 then
if player:isInBoatSpot() then
local nearestCenterPosition = findNearestRoomPosition(playerPosition)
player:teleportTo(nearestCenterPosition)
logger.trace("Teleporting player to the near center position room and updating tile.")
else
player:teleportTo(SoulWarQuest.ebbAndFlow.waitPosition)
logger.trace("Teleporting player to wait position and updating tile.")
local playersInZone = SoulWarQuest.ebbAndFlow.getZone():countPlayers()
local monstersInZone = SoulWarQuest.ebbAndFlow.getZone():countMonsters()
if playersInZone > 0 or monstersInZone > 0 then
local creatures = SoulWarQuest.ebbAndFlow.getZone():getCreatures()
for _, creature in ipairs(creatures) do
local creatureMaster = creature:getMaster()
local player = creature:getPlayer()
if creature:isPlayer() or (creature:isMonster() and creatureMaster and creatureMaster:getPlayer()) then
local creaturePosition = creature:getPosition()
if creaturePosition.z == 9 then
if creature:isInBoatSpot() then
local nearestCenterPosition = findNearestRoomPosition(creaturePosition)
creature:teleportTo(nearestCenterPosition)
logger.trace("Teleporting player to the near center position room and updating tile.")
else
creature:teleportTo(SoulWarQuest.ebbAndFlow.waitPosition)
logger.trace("Teleporting player to wait position and updating tile.")
end
creaturePosition:sendMagicEffect(CONST_ME_TELEPORT)
end
if player then
player:sendCreatureAppear()
end
playerPosition:sendMagicEffect(CONST_ME_TELEPORT)
end
player:sendCreatureAppear()
end
end

Expand Down
3 changes: 2 additions & 1 deletion data/events/scripts/player.lua
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder,
end

-- Reward System
if toPosition.x == CONTAINER_POSITION then
local containerThing = tile and tile:getItemByType(ITEM_TYPE_CONTAINER)
if containerThing and toPosition.x == CONTAINER_POSITION then
local containerId = toPosition.y - 64
local container = self:getContainerById(containerId)
if not container then
Expand Down
2 changes: 1 addition & 1 deletion data/libs/functions/boss_lever.lua
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function BossLever:onUse(player)
return true
end

local isAccountNormal = creature:getAccountType() == ACCOUNT_TYPE_NORMAL
local isAccountNormal = creature:getAccountType() < ACCOUNT_TYPE_GAMEMASTER
if isAccountNormal and creature:getLevel() < self.requiredLevel then
local message = "All players need to be level " .. self.requiredLevel .. " or higher."
creature:sendTextMessage(MESSAGE_EVENT_ADVANCE, message)
Expand Down
15 changes: 8 additions & 7 deletions data/libs/systems/blessing.lua
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ Blessings.BuyAllBlesses = function(player)
local hasToF = Blessings.Config.HasToF and player:hasBlessing(1) or true
local missingBless = player:getBlessings(nil, donthavefilter)
local missingBlessAmt = #missingBless + (hasToF and 0 or 1)
local totalCost
for i, bless in ipairs(missingBless) do
local totalCost = 0

for _, bless in ipairs(missingBless) do
totalCost = totalCost + Blessings.getBlessingCost(player:getLevel(), true, bless.id >= 7)
end

Expand All @@ -274,19 +275,19 @@ Blessings.BuyAllBlesses = function(player)
end

if player:removeMoneyBank(totalCost) then
metrics.addCounter("balance_decrease", remainsPrice, {
metrics.addCounter("balance_decrease", totalCost, {
player = player:getName(),
context = "blessings",
})

for i, v in ipairs(missingBless) do
player:addBlessing(v.id, 1)
for _, bless in ipairs(missingBless) do
player:addBlessing(bless.id, 1)
end

player:sendCancelMessage("You received the remaining " .. missingBlessAmt .. " blesses for a total of " .. totalCost .. " gold.")
player:sendCancelMessage(string.format("You received the remaining %d blesses for a total of %d gold.", missingBlessAmt, totalCost))
player:getPosition():sendMagicEffect(CONST_ME_HOLYAREA)
else
player:sendCancelMessage("You don't have enough money. You need " .. totalCost .. " to buy all blesses.", cid)
player:sendCancelMessage(string.format("You don't have enough money. You need %d to buy all blesses.", totalCost))
player:getPosition():sendMagicEffect(CONST_ME_POFF)
end

Expand Down
45 changes: 45 additions & 0 deletions data/scripts/actions/items/usable_phantasmal_jade_items.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
local config = {
requiredItems = {
[34072] = { key = "spectral-horseshoes", count = 4 },
[34073] = { key = "spectral-saddle", count = 1 },
[34074] = { key = "spectral-horse-tac", count = 1 },
},

mountId = 167,
}

local usablePhantasmalJadeItems = Action()

function usablePhantasmalJadeItems.onUse(player, item, fromPosition, target, toPosition, isHotkey)
local itemInfo = config.requiredItems[item:getId()]
if not itemInfo then
return true
end

if player:hasMount(config.mountId) then
return true
end

local currentCount = (player:kv():get(itemInfo.key) or 0) + 1
player:kv():set(itemInfo.key, currentCount)
player:getPosition():sendMagicEffect(CONST_ME_HOLYDAMAGE)
item:remove(1)

for _, info in pairs(config.requiredItems) do
if (player:kv():get(info.key) or 0) < info.count then
return true
end
end

player:addMount(config.mountId)
player:addAchievement("Natural Born Cowboy")
player:addAchievement("You got Horse Power")
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Phantasmal jade is now yours!")
return true
end

for itemId, _ in pairs(config.requiredItems) do
usablePhantasmalJadeItems:id(itemId)
end

usablePhantasmalJadeItems:register()
Loading

0 comments on commit dce1886

Please sign in to comment.