diff --git a/src/client/UI/BuffsUI.lua b/src/client/UI/BuffsUI.lua index f518b5d..aec7cf8 100644 --- a/src/client/UI/BuffsUI.lua +++ b/src/client/UI/BuffsUI.lua @@ -131,6 +131,7 @@ playerStatePromise:andThen(function() end end) + buffTray:WaitForChild "Frame" updateBuffTray(store:getState()) store.changed:connect(updateBuffTray) while true do diff --git a/src/client/UI/Combat/BossUI.lua b/src/client/UI/Combat/BossUI.lua index 406c8d6..eca2d6b 100644 --- a/src/client/UI/Combat/BossUI.lua +++ b/src/client/UI/Combat/BossUI.lua @@ -35,7 +35,7 @@ Remotes.Client:Get("SendFightInfo"):Connect(function(info) gemsToDisplay = getMultiplierAdjustedStat(player, "Gems", gemsToDisplay) fearToDisplay = getMultiplierAdjustedStat(player, "Fear", fearToDisplay) - BossUI.Background.Frame.Health:TweenSize( + BossUI:WaitForChild("Background").Frame.Health:TweenSize( UDim2.fromScale(1.013 * info.Health / info.MaxHealth, 1.104), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, diff --git a/src/client/UI/GiftUI.lua b/src/client/UI/GiftUI.lua index 105698c..32ade3e 100644 --- a/src/client/UI/GiftUI.lua +++ b/src/client/UI/GiftUI.lua @@ -91,6 +91,9 @@ function GiftUI:_initialize(): () end) playerStatePromise:andThen(function() + store.changed:connect(function() + self:Refresh() + end) while true do self._counter = (self._counter + 1) % 2 self:Refresh(true) diff --git a/src/client/UI/RebirthUI.lua b/src/client/UI/RebirthUI.lua index 75f31dc..f8a9b5f 100644 --- a/src/client/UI/RebirthUI.lua +++ b/src/client/UI/RebirthUI.lua @@ -28,6 +28,36 @@ local function shouldRefresh(newState, oldState) ~= selectors.getStat(oldState, player.Name, "Strength") end +local function modifiedBinarySearch(array, value) + local low = 1 + local high = #array + local mid = math.floor((low + high) / 2) + while low <= high do + if array[mid].RangeStart <= value and (not array[mid + 1] or array[mid + 1].RangeStart > value) then + return mid + elseif array[mid].RangeStart > value then + high = mid - 1 + else + low = mid + 1 + end + mid = math.floor((low + high) / 2) + end + return #array +end + +local function getRebirthStrengthMultiplier(array, rebirths) + local multiplier = 1 + local index = modifiedBinarySearch(array, rebirths) + if index == 1 then + return multiplier + rebirths * array[1].Multiplier + end + for i = 1, index - 1 do + rebirths -= (array[i + 1].RangeStart - array[i].RangeStart) + multiplier += array[i].PreComputedResult + end + return multiplier + rebirths * array[index].Multiplier +end + function RebirthUI:_initialize() mainUI.Rebirth.Activated:Connect(function() playSoundEffect "UIButton" @@ -60,6 +90,25 @@ function RebirthUI:_initialize() end)) end) + self._rebirthMultipliers = {} + + for _, multiplierValue in ReplicatedStorage.Config.Rebirth.StrengthMultipliers:GetChildren() do + table.insert(self._rebirthMultipliers, { + RangeStart = tonumber(multiplierValue.Name), + Multiplier = multiplierValue.Value, + }) + end + + table.sort(self._rebirthMultipliers, function(a, b) + return a.RangeStart < b.RangeStart + end) + + for i = 1, #self._rebirthMultipliers - 1 do + self._rebirthMultipliers[i].PreComputedResult = ( + self._rebirthMultipliers[i + 1].RangeStart - self._rebirthMultipliers[i].RangeStart + ) * self._rebirthMultipliers[i].Multiplier + end + playerStatePromise:andThen(function() self:Refresh() store.changed:connect(function(newState, oldState) @@ -85,7 +134,13 @@ function RebirthUI:Refresh() self._ui.Background.Passes["2xTokens"].Visible = true end self._ui.Background.Tokens.Text = `{formatter.formatNumberWithSuffix(rebirths * tokenMultiplier)} Rebirth Tokens` - self._ui.Background.Strength.Text = `{formatter.formatNumberWithCommas(1 + 0.01 * rebirths, 2)}x Strength` + self._ui.Background.Strength.Text = `{formatter.formatNumberWithCommas( + getRebirthStrengthMultiplier( + self._rebirthMultipliers, + rebirths + selectors.getStat(store:getState(), player.Name, "Rebirths") + ), + 2 + )}x Strength` end task.spawn(RebirthUI._initialize, RebirthUI) diff --git a/src/server/Combat/Perks/Pets.lua b/src/server/Combat/Perks/Pets.lua index 596b4b8..537bd2c 100644 --- a/src/server/Combat/Perks/Pets.lua +++ b/src/server/Combat/Perks/Pets.lua @@ -154,6 +154,8 @@ end) Remotes.Server:Get("EquipBestPets"):Connect(function(player: Player) local equippedPets = selectors.getEquippedPets(store:getState(), player.Name) + local lockedPets = selectors.getLockedPets(store:getState(), player.Name) + local ownedPets = selectors.getOwnedPets(store:getState(), player.Name) local bestPets = petUtils.getBestPetNames( selectors.getOwnedPets(store:getState(), player.Name), selectors.getStat(store:getState(), player.Name, "MaxPetEquipCount") @@ -164,11 +166,21 @@ Remotes.Server:Get("EquipBestPets"):Connect(function(player: Player) end local bestPetsDict = {} + local petsToUnlock = table.clone(equippedPets) for _, bestPetName in bestPets do bestPetsDict[bestPetName] = (bestPetsDict[bestPetName] or 0) + 1 end - store:dispatch(actions.unlockPlayerPets(player.Name, equippedPets)) + for petName, count in bestPetsDict do + local lockCount = lockedPets[petName] or 0 + local equipCount = equippedPets[petName] or 0 + if ownedPets[petName] - (lockCount - equipCount) < count then + local countToUnlock = count - (ownedPets[petName] - (lockCount - equipCount)) + petsToUnlock[petName] = (petsToUnlock[petName] or 0) + countToUnlock + end + end + + store:dispatch(actions.unlockPlayerPets(player.Name, petsToUnlock)) store:dispatch(actions.unequipPlayerPets(player.Name, equippedPets)) store:dispatch(actions.equipPlayerPets(player.Name, bestPetsDict)) store:dispatch(actions.lockPlayerPets(player.Name, bestPetsDict, true)) diff --git a/src/server/Exchange/init.lua b/src/server/Exchange/init.lua index 231628a..ad7baa6 100644 --- a/src/server/Exchange/init.lua +++ b/src/server/Exchange/init.lua @@ -94,7 +94,10 @@ local function handlePunchingBag(bag: any) prompt.ActionText = "Start Training" inUse = false - if selectors.getStat(store:getState(), player.Name, "Strength") >= initialStrength then + if + selectors.isPlayerLoaded(store:getState(), player.Name) + and selectors.getStat(store:getState(), player.Name, "Strength") >= initialStrength + then humanoid.RootPart.CFrame = teleportPart.CFrame + Vector3.new(0, 1, 0) * (humanoid.RootPart.Size.Y + 3) end diff --git a/src/server/PlayerManager/GlobalLeaderboards.lua b/src/server/PlayerManager/GlobalLeaderboards.lua index 5d4ef63..7139db4 100644 --- a/src/server/PlayerManager/GlobalLeaderboards.lua +++ b/src/server/PlayerManager/GlobalLeaderboards.lua @@ -50,24 +50,19 @@ end local function updateGlobalLeaderboardStores(): () for _, player in Players:GetPlayers() do - if - not profiles[player.Name] - or permissionList.Admins[player.UserId] - or not selectors.isPlayerLoaded(store:getState(), player.Name) - or player.UserId < 0 - then + if not profiles[player.Name] or permissionList.Admins[player.UserId] or player.UserId < 0 then continue end for statName, globalLeaderboard in globalLeaderboardStores do + if not selectors.isPlayerLoaded(store:getState(), player.Name) then + continue + end pcall( globalLeaderboard.SetAsync, globalLeaderboard, tostring(player.UserId), math.floor(selectors.getStat(store:getState(), player.Name, statName)) ) - if not selectors.isPlayerLoaded(store:getState(), player.Name) then - continue - end end end end @@ -76,7 +71,7 @@ task.delay(10, function() while true do task.spawn(updateGlobalLeaderboardDisplays) task.spawn(updateGlobalLeaderboardStores) - task.wait(100) + task.wait(120) end end) diff --git a/src/server/State/Middleware/ApplyMultipliersMiddleware.lua b/src/server/State/Middleware/ApplyMultipliersMiddleware.lua index b05e380..3748b1f 100644 --- a/src/server/State/Middleware/ApplyMultipliersMiddleware.lua +++ b/src/server/State/Middleware/ApplyMultipliersMiddleware.lua @@ -8,10 +8,62 @@ local rankUtils = require(ReplicatedStorage.Common.Utils.RankUtils) local selectors = require(ReplicatedStorage.Common.State.selectors) local Count = require(ReplicatedStorage.Common.lib.Sift).Dictionary.count +local rebirthMultipliers = {} local applyMultiplierToNegativeWhitelist = {} +for _, multiplierValue in ReplicatedStorage.Config.Rebirth.StrengthMultipliers:GetChildren() do + table.insert(rebirthMultipliers, { + RangeStart = tonumber(multiplierValue.Name), + Multiplier = multiplierValue.Value, + }) +end + +table.sort(rebirthMultipliers, function(a, b) + return a.RangeStart < b.RangeStart +end) + +for i = 1, #rebirthMultipliers - 1 do + rebirthMultipliers[i].PreComputedResult = (rebirthMultipliers[i + 1].RangeStart - rebirthMultipliers[i].RangeStart) + * rebirthMultipliers[i].Multiplier +end + +local function modifiedBinarySearch(array, value) + local low = 1 + local high = #array + local mid = math.floor((low + high) / 2) + while low <= high do + if array[mid].RangeStart <= value and (not array[mid + 1] or array[mid + 1].RangeStart > value) then + return mid + elseif array[mid].RangeStart > value then + high = mid - 1 + else + low = mid + 1 + end + mid = math.floor((low + high) / 2) + end + return #array +end + +local function getRebirthStrengthMultiplier(array, rebirths) + local multiplier = 1 + local index = modifiedBinarySearch(array, rebirths) + if index == 1 then + return multiplier + rebirths * array[1].Multiplier + end + for i = 1, index - 1 do + rebirths -= (array[i + 1].RangeStart - array[i].RangeStart) + multiplier += array[i].PreComputedResult + end + return multiplier + rebirths * array[index].Multiplier +end + return function(nextDispatch, store) return function(action) + local initialMaxFearMeter = nil + if action.playerName and selectors.isPlayerLoaded(store:getState(), action.playerName) then + initialMaxFearMeter = + rankUtils.getMaxFearMeterFromRank(selectors.getStat(store:getState(), action.playerName, "Rank")) + end if action.statName and action.incrementAmount then if action.incrementAmount > 0 or applyMultiplierToNegativeWhitelist[action.statName] then local multiplierData = selectors.getMultiplierData(store:getState(), action.playerName) @@ -66,26 +118,23 @@ return function(nextDispatch, store) end if action.statName == "Strength" then - action.incrementAmount *= (1 + 0.01 * selectors.getStat( - store:getState(), - action.playerName, - "Rebirths" - )) + action.incrementAmount *= getRebirthStrengthMultiplier( + rebirthMultipliers, + selectors.getStat(store:getState(), action.playerName, "Rebirths") + ) end end end nextDispatch(action) - if action.statName == "Strength" then + local endMaxFearMeter = nil + if action.playerName and selectors.isPlayerLoaded(store:getState(), action.playerName) then + endMaxFearMeter = + rankUtils.getMaxFearMeterFromRank(selectors.getStat(store:getState(), action.playerName, "Rank")) + end + if endMaxFearMeter and initialMaxFearMeter ~= endMaxFearMeter then local multiplier = selectors.getMultiplierData(store:getState(), action.playerName).MaxFearMeterMultiplier or 1 - store:dispatch( - actions.setPlayerStat( - action.playerName, - "MaxFearMeter", - rankUtils.getMaxFearMeterFromRank(selectors.getStat(store:getState(), action.playerName, "Rank")) - * multiplier - ) - ) + store:dispatch(actions.setPlayerStat(action.playerName, "MaxFearMeter", endMaxFearMeter * multiplier)) end end end