227 lines
8.6 KiB
Lua
227 lines
8.6 KiB
Lua
local ____lualib = require("lualib_bundle")
|
|
local __TS__Class = ____lualib.__TS__Class
|
|
local Map = ____lualib.Map
|
|
local __TS__New = ____lualib.__TS__New
|
|
local __TS__Iterator = ____lualib.__TS__Iterator
|
|
local ____exports = {}
|
|
____exports.CrystalCurrency = __TS__Class()
|
|
local CrystalCurrency = ____exports.CrystalCurrency
|
|
CrystalCurrency.name = "CrystalCurrency"
|
|
CrystalCurrency.____file_path = "scripts/vscripts/crystal_currency.lua"
|
|
function CrystalCurrency.prototype.____constructor(self)
|
|
self.playerCrystals = __TS__New(Map)
|
|
self.playerTotalSpentCrystals = __TS__New(Map)
|
|
self.animationTimers = __TS__New(Map)
|
|
self.spendListeners = __TS__New(Map)
|
|
self.nextSpendListenerId = 1
|
|
self:initializePlayers()
|
|
self:setupEventListeners()
|
|
end
|
|
function CrystalCurrency.getInstance(self)
|
|
if not ____exports.CrystalCurrency.instance then
|
|
____exports.CrystalCurrency.instance = __TS__New(____exports.CrystalCurrency)
|
|
end
|
|
return ____exports.CrystalCurrency.instance
|
|
end
|
|
function CrystalCurrency.prototype.initializePlayers(self)
|
|
do
|
|
local i = 0
|
|
while i < DOTA_MAX_TEAM_PLAYERS do
|
|
if PlayerResource:IsValidPlayer(i) then
|
|
self.playerCrystals:set(i, 0)
|
|
self.playerTotalSpentCrystals:set(i, 0)
|
|
self:updateCrystalDisplay(i)
|
|
end
|
|
i = i + 1
|
|
end
|
|
end
|
|
end
|
|
function CrystalCurrency.prototype.setupEventListeners(self)
|
|
end
|
|
function CrystalCurrency.prototype.cleanupPlayerTimers(self, playerId)
|
|
local timerId = self.animationTimers:get(playerId)
|
|
if timerId then
|
|
GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_animate_" .. tostring(playerId),
|
|
nil,
|
|
0
|
|
)
|
|
self.animationTimers:delete(playerId)
|
|
end
|
|
end
|
|
function CrystalCurrency.prototype.getCrystals(self, playerId)
|
|
return self.playerCrystals:get(playerId) or 0
|
|
end
|
|
function CrystalCurrency.prototype.addCrystals(self, playerId, amount)
|
|
if amount <= 0 then
|
|
return false
|
|
end
|
|
local currentCrystals = self:getCrystals(playerId)
|
|
local newAmount = currentCrystals + amount
|
|
self.playerCrystals:set(playerId, newAmount)
|
|
local existingTimer = self.animationTimers:get(playerId)
|
|
if existingTimer then
|
|
GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_animate_" .. tostring(playerId),
|
|
nil,
|
|
0
|
|
)
|
|
end
|
|
local timerId = GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_animate_" .. tostring(playerId),
|
|
function()
|
|
local player = PlayerResource:GetPlayer(playerId)
|
|
if player then
|
|
CustomGameEventManager:Send_ServerToPlayer(player, "crystal_animate", {amount = newAmount, added = amount})
|
|
end
|
|
self.animationTimers:delete(playerId)
|
|
return -1
|
|
end,
|
|
0.1
|
|
)
|
|
self.animationTimers:set(playerId, timerId)
|
|
GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_net_table_" .. tostring(playerId),
|
|
function()
|
|
self:updateCrystalDisplay(playerId)
|
|
return -1
|
|
end,
|
|
0.2
|
|
)
|
|
self:sendCrystalNotification(playerId, amount, "crystal_gained")
|
|
return true
|
|
end
|
|
function CrystalCurrency.prototype.removeCrystals(self, playerId, amount)
|
|
if amount <= 0 then
|
|
return false
|
|
end
|
|
local currentCrystals = self:getCrystals(playerId)
|
|
if currentCrystals < amount then
|
|
print((((("[CRYSTAL] removeCrystals FAIL: player=" .. tostring(playerId)) .. ", need=") .. tostring(amount)) .. ", have=") .. tostring(currentCrystals))
|
|
return false
|
|
end
|
|
local newAmount = currentCrystals - amount
|
|
local totalSpent = (self.playerTotalSpentCrystals:get(playerId) or 0) + amount
|
|
self.playerCrystals:set(playerId, newAmount)
|
|
self.playerTotalSpentCrystals:set(playerId, totalSpent)
|
|
print((((((((("[CRYSTAL] removeCrystals OK: player=" .. tostring(playerId)) .. ", spent=") .. tostring(amount)) .. ", before=") .. tostring(currentCrystals)) .. ", after=") .. tostring(newAmount)) .. ", totalSpent=") .. tostring(totalSpent))
|
|
local existingTimer = self.animationTimers:get(playerId)
|
|
if existingTimer then
|
|
GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_animate_" .. tostring(playerId),
|
|
nil,
|
|
0
|
|
)
|
|
end
|
|
local timerId = GameRules:GetGameModeEntity():SetContextThink(
|
|
"crystal_animate_" .. tostring(playerId),
|
|
function()
|
|
local player = PlayerResource:GetPlayer(playerId)
|
|
if player then
|
|
CustomGameEventManager:Send_ServerToPlayer(player, "crystal_animate", {amount = newAmount, added = -amount})
|
|
end
|
|
self.animationTimers:delete(playerId)
|
|
return -1
|
|
end,
|
|
0.1
|
|
)
|
|
self.animationTimers:set(playerId, timerId)
|
|
self:updateCrystalDisplay(playerId)
|
|
self:notifyCrystalsSpent(playerId, amount, newAmount, totalSpent)
|
|
return true
|
|
end
|
|
function CrystalCurrency.prototype.setCrystals(self, playerId, amount)
|
|
if amount < 0 then
|
|
return false
|
|
end
|
|
self.playerCrystals:set(playerId, amount)
|
|
self:updateCrystalDisplay(playerId)
|
|
return true
|
|
end
|
|
function CrystalCurrency.prototype.canAfford(self, playerId, cost)
|
|
return self:getCrystals(playerId) >= cost
|
|
end
|
|
function CrystalCurrency.prototype.getTotalSpentCrystals(self, playerId)
|
|
return self.playerTotalSpentCrystals:get(playerId) or 0
|
|
end
|
|
function CrystalCurrency.prototype.addSpendListener(self, callback)
|
|
local ____self_0, ____nextSpendListenerId_1 = self, "nextSpendListenerId"
|
|
local ____self_nextSpendListenerId_2 = ____self_0[____nextSpendListenerId_1]
|
|
____self_0[____nextSpendListenerId_1] = ____self_nextSpendListenerId_2 + 1
|
|
local id = ____self_nextSpendListenerId_2
|
|
self.spendListeners:set(id, callback)
|
|
print((("[CRYSTAL] addSpendListener: id=" .. tostring(id)) .. ", listeners=") .. tostring(self.spendListeners.size))
|
|
return id
|
|
end
|
|
function CrystalCurrency.prototype.removeSpendListener(self, listenerId)
|
|
self.spendListeners:delete(listenerId)
|
|
print((("[CRYSTAL] removeSpendListener: id=" .. tostring(listenerId)) .. ", listeners=") .. tostring(self.spendListeners.size))
|
|
end
|
|
function CrystalCurrency.prototype.notifyCrystalsSpent(self, playerId, spentAmount, newTotal, totalSpent)
|
|
print((((((((("[CRYSTAL] notifyCrystalsSpent: player=" .. tostring(playerId)) .. ", spent=") .. tostring(spentAmount)) .. ", newTotal=") .. tostring(newTotal)) .. ", totalSpent=") .. tostring(totalSpent)) .. ", listeners=") .. tostring(self.spendListeners.size))
|
|
for ____, callback in __TS__Iterator(self.spendListeners:values()) do
|
|
callback(
|
|
nil,
|
|
playerId,
|
|
spentAmount,
|
|
newTotal,
|
|
totalSpent
|
|
)
|
|
end
|
|
end
|
|
function CrystalCurrency.prototype.updateCrystalDisplay(self, playerId)
|
|
local crystals = self:getCrystals(playerId)
|
|
local key = "crystals_" .. tostring(playerId)
|
|
local data = {amount = crystals}
|
|
CustomNetTables:SetTableValue("crystal_currency", key, data)
|
|
end
|
|
function CrystalCurrency.prototype.sendCrystalNotification(self, playerId, amount, ____type)
|
|
local player = PlayerResource:GetPlayer(playerId)
|
|
if player then
|
|
CustomGameEventManager:Send_ServerToPlayer(
|
|
player,
|
|
"crystal_currency_changed",
|
|
{
|
|
amount = amount,
|
|
type = ____type,
|
|
total = self:getCrystals(playerId)
|
|
}
|
|
)
|
|
end
|
|
end
|
|
function CrystalCurrency.prototype.giveCrystalsForKill(self, _playerId, _unitName)
|
|
end
|
|
function CrystalCurrency.prototype.convertGoldToCrystals(self, playerId, goldAmount)
|
|
local hero = PlayerResource:GetSelectedHeroEntity(playerId)
|
|
if not hero then
|
|
return false
|
|
end
|
|
local currentGold = PlayerResource:GetGold(playerId)
|
|
if currentGold < goldAmount then
|
|
return false
|
|
end
|
|
local crystalAmount = math.floor(goldAmount / 100)
|
|
if crystalAmount <= 0 then
|
|
return false
|
|
end
|
|
hero:ModifyGold(-goldAmount, true, 0)
|
|
self:addCrystals(playerId, crystalAmount)
|
|
return true
|
|
end
|
|
function CrystalCurrency.prototype.convertCrystalsToGold(self, playerId, crystalAmount)
|
|
if not self:canAfford(playerId, crystalAmount) then
|
|
return false
|
|
end
|
|
local goldAmount = crystalAmount * 100
|
|
self:removeCrystals(playerId, crystalAmount)
|
|
local hero = PlayerResource:GetSelectedHeroEntity(playerId)
|
|
if hero then
|
|
hero:ModifyGold(goldAmount, true, 0)
|
|
end
|
|
return true
|
|
end
|
|
function ____exports.GetCrystalCurrency(self)
|
|
return ____exports.CrystalCurrency:getInstance()
|
|
end
|
|
return ____exports
|