Skip to content

Commit a43f6f3

Browse files
committed
fix(gamestore): sell permanent weekly task expansion
Replace the obsolete hunting-task-slot offer with the 750-coin Permanent Weekly Task Expansion and describe its 6-to-9 Kill and Delivery Task entitlement. Route offer availability and purchase processing through the modular Task Board API so the store and gameplay use the same persisted flag. Disable the offer cleanly when Task Board integration is unavailable. Validation: lua tests/lua/test_gamestore_taskboard_expansion.lua (4 passed, 0 failed); StyLua check passed for the changed Lua files.
1 parent 5d1d162 commit a43f6f3

7 files changed

Lines changed: 174 additions & 19 deletions

File tree

data/libs/gamestore/constants.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ GameStore.OfferTypes = {
3131
OFFER_TYPE_HIRELING_SEXCHANGE = 22,
3232
OFFER_TYPE_HIRELING_SKILL = 23,
3333
OFFER_TYPE_HIRELING_OUTFIT = 24,
34-
OFFER_TYPE_HUNTINGSLOT = 25,
34+
OFFER_TYPE_WEEKLY_TASK_EXPANSION = 25,
3535
OFFER_TYPE_ITEM_BED = 26,
3636
OFFER_TYPE_ITEM_UNIQUE = 27,
3737
}
@@ -51,7 +51,7 @@ GameStore.SubActions = {
5151
BLESSING_ALL_PVE = 11,
5252
BLESSING_ALL_PVP = 12,
5353
CHARM_EXPANSION = 13,
54-
TASKHUNTING_THIRDSLOT = 14,
54+
WEEKLY_TASK_EXPANSION = 14,
5555
PREY_THIRDSLOT_REDIRECT = 15,
5656
}
5757

data/libs/gamestore/parsers.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ local function parseBuyStoreOffer(playerId, msg)
278278
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_EXPBOOST
279279
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYBONUS
280280
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYSLOT
281-
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT
281+
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION
282282
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_TEMPLE
283283
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE
284284
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_INSTANT_REWARD_ACCESS
@@ -343,8 +343,8 @@ local function parseBuyStoreOffer(playerId, msg)
343343
GameStore.processSexChangePurchase(player)
344344
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_EXPBOOST then
345345
GameStore.processExpBoostPurchase(player)
346-
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT then
347-
GameStore.processTaskHuntingThirdSlot(player)
346+
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION then
347+
GameStore.processWeeklyTaskExpansion(player)
348348
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYSLOT then
349349
GameStore.processPreyThirdSlot(player)
350350
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYBONUS then

data/libs/gamestore/player.lua

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local senders = require("gamestore.senders")
2+
local taskboard = require("gamestore.taskboard")
23
local player = {}
34

45
local sendStoreBalanceUpdating = senders.sendStoreBalanceUpdating
@@ -16,7 +17,7 @@ local function canBuyOffer(self, offer)
1617
offer.type ~= GameStore.OfferTypes.OFFER_TYPE_NAMECHANGE
1718
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_EXPBOOST
1819
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYSLOT
19-
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT
20+
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION
2021
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_PREYBONUS
2122
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_TEMPLE
2223
and offer.type ~= GameStore.OfferTypes.OFFER_TYPE_SEXCHANGE
@@ -102,10 +103,14 @@ local function canBuyOffer(self, offer)
102103
disabled = 1
103104
disabledReason = "You already have charm expansion."
104105
end
105-
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT then
106-
if self:taskHuntingThirdSlot() then
106+
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION then
107+
local unlocked = taskboard.isWeeklyExpansionUnlocked(self)
108+
if unlocked == nil then
107109
disabled = 1
108-
disabledReason = "You already have 3 slots released."
110+
disabledReason = "Task Board is unavailable."
111+
elseif unlocked then
112+
disabled = 1
113+
disabledReason = "You already have the Permanent Weekly Task Expansion."
109114
end
110115
elseif offer.type == GameStore.OfferTypes.OFFER_TYPE_PREYSLOT then
111116
if self:preyThirdSlot() then

data/libs/gamestore/purchases.lua

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local senders = require("gamestore.senders")
2+
local taskboard = require("gamestore.taskboard")
23
local purchases = {}
34

45
local sendStorePurchaseSuccessful = senders.sendStorePurchaseSuccessful
@@ -253,11 +254,11 @@ local function processPreyThirdSlot(player)
253254
player:preyThirdSlot(true)
254255
end
255256

256-
local function processTaskHuntingThirdSlot(player)
257-
if player:taskHuntingThirdSlot() then
258-
return error({ code = 1, message = "You already have unlocked all task hunting slots." })
257+
local function processWeeklyTaskExpansion(player)
258+
local unlocked, reason = taskboard.unlockWeeklyExpansion(player)
259+
if not unlocked then
260+
return error({ code = 1, message = reason or "Permanent Weekly Task Expansion is unavailable." })
259261
end
260-
player:taskHuntingThirdSlot(true)
261262
end
262263

263264
local function processPreyBonusReroll(player, offerCount)
@@ -483,7 +484,7 @@ purchases.processNameChangePurchase = processNameChangePurchase
483484
purchases.processSexChangePurchase = processSexChangePurchase
484485
purchases.processExpBoostPurchase = processExpBoostPurchase
485486
purchases.processPreyThirdSlot = processPreyThirdSlot
486-
purchases.processTaskHuntingThirdSlot = processTaskHuntingThirdSlot
487+
purchases.processWeeklyTaskExpansion = processWeeklyTaskExpansion
487488
purchases.processPreyBonusReroll = processPreyBonusReroll
488489
purchases.processTempleTeleportPurchase = processTempleTeleportPurchase
489490
purchases.processHirelingPurchase = processHirelingPurchase

data/libs/gamestore/taskboard.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
local taskboard = {}
2+
3+
local function getExpansion()
4+
local api = rawget(_G, "Taskboard")
5+
if type(api) ~= "table" or type(api.expansion) ~= "table" then
6+
return nil
7+
end
8+
return api.expansion
9+
end
10+
11+
function taskboard.isWeeklyExpansionUnlocked(player)
12+
local expansion = getExpansion()
13+
if not expansion or type(expansion.isUnlocked) ~= "function" then
14+
return nil
15+
end
16+
17+
local ok, unlocked = pcall(expansion.isUnlocked, player)
18+
if not ok then
19+
return nil
20+
end
21+
return unlocked == true
22+
end
23+
24+
function taskboard.unlockWeeklyExpansion(player)
25+
local expansion = getExpansion()
26+
if not expansion or type(expansion.unlock) ~= "function" then
27+
return false, "Task Board is unavailable."
28+
end
29+
30+
local ok, unlocked, reason = pcall(expansion.unlock, player)
31+
if not ok then
32+
return false, "Permanent Weekly Task Expansion could not be unlocked."
33+
end
34+
return unlocked == true, reason
35+
end
36+
37+
return taskboard

data/modules/scripts/gamestore/catalog/extras_usefull_things.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ return {
4141
},
4242
{
4343
icons = { "Permanent_Hunting_Task_Slot.png" },
44-
name = "Permanent Hunting Task Slot",
45-
price = 900,
46-
id = GameStore.SubActions.TASKHUNTING_THIRDSLOT,
47-
description = "<i>Get an additional hunting tasks slot to activate additional hunting task!</i>\n\n{character}\n{info} maximum amount that can be owned by character: 3\n{info} added directly to Hunting Task dialog",
48-
type = GameStore.OfferTypes.OFFER_TYPE_HUNTINGSLOT,
44+
name = "Permanent Weekly Task Expansion",
45+
price = 750,
46+
id = GameStore.SubActions.WEEKLY_TASK_EXPANSION,
47+
description = "<i>Permanently expand every weekly task cycle.</i>\n\n{character}\n{once}\n{info} increases Kill Tasks from 6 to 9\n{info} increases Delivery Tasks from 6 to 9",
48+
type = GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION,
4949
},
5050
{
5151
icons = { "Gold_Converter.png" },
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
-- Standalone Game Store contract tests for the Task Board expansion.
2+
-- Run from the repository root with: lua tests/lua/test_gamestore_taskboard_expansion.lua
3+
4+
package.path = "data/libs/?.lua;" .. package.path
5+
6+
local passed, failed, errors = 0, 0, {}
7+
8+
local function test(name, fn)
9+
local ok, err = pcall(fn)
10+
if ok then
11+
passed = passed + 1
12+
else
13+
failed = failed + 1
14+
table.insert(errors, { name = name, err = err })
15+
end
16+
end
17+
18+
local function assertTrue(value, message)
19+
if not value then
20+
error(message or "expected true", 2)
21+
end
22+
end
23+
24+
local function assertEqual(expected, actual, message)
25+
if expected ~= actual then
26+
error(message or string.format("expected %s, got %s", tostring(expected), tostring(actual)), 2)
27+
end
28+
end
29+
30+
package.loaded["gamestore.senders"] = {}
31+
GameStore = require("gamestore.constants")
32+
33+
local playerMethods = require("gamestore.player")
34+
local purchases = require("gamestore.purchases")
35+
36+
test("weekly expansion offer uses the official product contract", function()
37+
local category = dofile("data/modules/scripts/gamestore/catalog/extras_usefull_things.lua")
38+
local offer
39+
for _, candidate in ipairs(category.offers) do
40+
if candidate.type == GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION then
41+
offer = candidate
42+
break
43+
end
44+
end
45+
46+
assertTrue(offer ~= nil)
47+
assertEqual("Permanent Weekly Task Expansion", offer.name)
48+
assertEqual(750, offer.price)
49+
assertEqual(GameStore.SubActions.WEEKLY_TASK_EXPANSION, offer.id)
50+
end)
51+
52+
test("weekly expansion availability follows the Task Board state", function()
53+
local unlocked = false
54+
local testPlayer = {}
55+
rawset(_G, "Taskboard", {
56+
expansion = {
57+
isUnlocked = function(player)
58+
assertEqual(testPlayer, player)
59+
return unlocked
60+
end,
61+
},
62+
})
63+
local offer = { type = GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION }
64+
65+
local availability = playerMethods.canBuyOffer(testPlayer, offer)
66+
assertEqual(0, availability.disabled)
67+
assertEqual("", availability.disabledReason)
68+
69+
unlocked = true
70+
availability = playerMethods.canBuyOffer(testPlayer, offer)
71+
assertEqual(1, availability.disabled)
72+
assertEqual("You already have the Permanent Weekly Task Expansion.", availability.disabledReason)
73+
end)
74+
75+
test("weekly expansion purchase delegates to the Task Board module", function()
76+
local calls = 0
77+
local testPlayer = {}
78+
rawset(_G, "Taskboard", {
79+
expansion = {
80+
unlock = function(player)
81+
assertEqual(testPlayer, player)
82+
calls = calls + 1
83+
return true
84+
end,
85+
},
86+
})
87+
88+
purchases.processWeeklyTaskExpansion(testPlayer)
89+
assertEqual(1, calls)
90+
end)
91+
92+
test("weekly expansion offer is disabled when Task Board is unavailable", function()
93+
rawset(_G, "Taskboard", nil)
94+
local offer = { type = GameStore.OfferTypes.OFFER_TYPE_WEEKLY_TASK_EXPANSION }
95+
local availability = playerMethods.canBuyOffer({}, offer)
96+
assertEqual(1, availability.disabled)
97+
assertEqual("Task Board is unavailable.", availability.disabledReason)
98+
99+
local ok, err = pcall(purchases.processWeeklyTaskExpansion, {})
100+
assertEqual(false, ok)
101+
assertTrue(type(err) == "table")
102+
assertEqual("Task Board is unavailable.", err.message)
103+
end)
104+
105+
print(string.format("\n%d passed, %d failed", passed, failed))
106+
if #errors > 0 then
107+
print("\nFailed tests:")
108+
for _, entry in ipairs(errors) do
109+
print(string.format(" FAIL: %s\n %s", entry.name, entry.err))
110+
end
111+
os.exit(1)
112+
end

0 commit comments

Comments
 (0)