238 lines
8 KiB
Lua
238 lines
8 KiB
Lua
-----------------------------------
|
|
-- Seekers of Adoulin Helpers
|
|
-----------------------------------
|
|
xi = xi or {}
|
|
xi.soa = xi.soa or {}
|
|
xi.soa.helpers = xi.soa.helpers or {}
|
|
|
|
xi.soa.helpers.imprimaturGate = function(player, gateAmount)
|
|
-- TODO: All of this
|
|
local imprimatursSpent = 0 -- TODO: Pull from DB
|
|
local fame = player:getFameLevel(xi.fameArea.ADOULIN)
|
|
local gate = 100 - (fame * gateAmount)
|
|
return imprimatursSpent >= gate
|
|
end
|
|
|
|
-- Helper Functions for Mission 3-4 and 3-5 Minigame
|
|
local function getShotHistory(player, varName)
|
|
local shotField = player:getLocalVar(varName)
|
|
local shotHistory = {}
|
|
local bitOffset = 0
|
|
local shotData = bit.band(shotField, 0x7)
|
|
|
|
while shotData ~= 0 do
|
|
table.insert(shotHistory, #shotHistory + 1, shotData)
|
|
|
|
bitOffset = bitOffset + 3
|
|
shotData = bit.band(bit.rshift(shotField, bitOffset), 0x7)
|
|
end
|
|
|
|
return shotHistory
|
|
end
|
|
|
|
local function addShot(player, varName, shotValue)
|
|
local shotHistory = getShotHistory(player, varName)
|
|
local resultField = 0
|
|
|
|
table.insert(shotHistory, #shotHistory + 1, shotValue)
|
|
|
|
for shotNum, shotAmt in ipairs(shotHistory) do
|
|
resultField = resultField + bit.lshift(shotAmt, (shotNum - 1) * 3)
|
|
end
|
|
|
|
player:setLocalVar(varName, resultField)
|
|
end
|
|
|
|
local function replaceShot(player, varName, shotValue, slot)
|
|
local shotHistory = getShotHistory(player, varName)
|
|
local resultField = 0
|
|
|
|
shotHistory[slot] = shotValue
|
|
for shotNum, shotAmt in ipairs(shotHistory) do
|
|
resultField = resultField + bit.lshift(shotAmt, (shotNum - 1) * 3)
|
|
end
|
|
|
|
player:setLocalVar(varName, resultField)
|
|
end
|
|
|
|
local function getShotTotal(player, varName)
|
|
local shotField = player:getLocalVar(varName)
|
|
local shotTotal = 0
|
|
local bitOffset = 0
|
|
local shotData = bit.band(shotField, 0x7)
|
|
|
|
while shotData ~= 0 do
|
|
shotTotal = shotTotal + shotData
|
|
|
|
bitOffset = bitOffset + 3
|
|
shotData = bit.band(bit.rshift(shotField, bitOffset), 0x7)
|
|
end
|
|
|
|
if shotTotal > 11 then
|
|
shotTotal = 0
|
|
end
|
|
|
|
return shotTotal
|
|
end
|
|
|
|
local function updateSessionScore(player, gameResult)
|
|
local packedSessionScore = player:getLocalVar('sessionScore')
|
|
local sessionTable = {} -- { Win, Lose, Tie }
|
|
|
|
for offset = 0, 2 do
|
|
sessionTable[offset + 1] = bit.band(bit.rshift(packedSessionScore, offset * 2), 0x3)
|
|
end
|
|
|
|
sessionTable[gameResult] = sessionTable[gameResult] + 1
|
|
|
|
packedSessionScore = 0
|
|
for offset = 0, 2 do
|
|
packedSessionScore = packedSessionScore + bit.lshift(sessionTable[offset + 1], offset * 2)
|
|
end
|
|
|
|
player:setLocalVar('sessionScore', packedSessionScore)
|
|
end
|
|
|
|
local function chooseTeodorAction(player)
|
|
local teodorScore = getShotTotal(player, 'teodorShots')
|
|
local teodorAction = 1
|
|
local teodorShotValue = 0
|
|
local teodorSpecial = 0
|
|
local rollThreshold = 100 - (math.max(teodorScore - 5, 0) * 20)
|
|
|
|
if
|
|
player:getLocalVar('turnNumber') > 1 and
|
|
player:getLocalVar('teodorSpecial') == 0 and
|
|
teodorScore == 0
|
|
then
|
|
-- Teodor Busted, try to Switcharoo
|
|
teodorAction = 3
|
|
|
|
local playerShotData = getShotHistory(player, 'playerShots')
|
|
local teodorShotData = getShotHistory(player, 'teodorShots')
|
|
|
|
local playerCardSlot = math.random(1, #playerShotData)
|
|
local teodorCardSlot = math.random(1, #teodorShotData)
|
|
|
|
teodorSpecial = bit.lshift(teodorShotData[teodorCardSlot], 5) + playerShotData[playerCardSlot]
|
|
|
|
replaceShot(player, 'playerShots', teodorShotData[teodorCardSlot], playerCardSlot)
|
|
replaceShot(player, 'teodorShots', playerShotData[playerCardSlot], teodorCardSlot)
|
|
player:setLocalVar('teodorSpecial', 1)
|
|
|
|
elseif
|
|
player:getLocalVar('turnNumber') > 1 and
|
|
player:getLocalVar('teodorSpecial') == 0 and
|
|
math.random(1, 100) <= 20
|
|
then
|
|
-- Crooked Die
|
|
teodorAction = 4
|
|
local chosenSlot = math.random(1, #getShotHistory(player, 'playerShots')) - 1
|
|
local newRollValue = math.random(1, 6)
|
|
|
|
teodorSpecial = bit.lshift(newRollValue, 5) + chosenSlot
|
|
|
|
replaceShot(player, 'playerShots', newRollValue, chosenSlot)
|
|
player:setLocalVar('teodorSpecial', 1)
|
|
|
|
elseif
|
|
math.random(1, 100) <= rollThreshold and
|
|
player:getLocalVar('teodorStayed') == 0 and
|
|
((teodorScore > 0 and teodorScore <= 11) or
|
|
player:getLocalVar('turnNumber') == 1)
|
|
then
|
|
-- Shoot
|
|
teodorAction = 0
|
|
teodorShotValue = math.random(1, 6)
|
|
addShot(player, 'teodorShots', teodorShotValue)
|
|
|
|
else
|
|
-- Stay
|
|
player:setLocalVar('teodorStayed', 1)
|
|
end
|
|
|
|
return teodorAction, teodorShotValue, teodorSpecial
|
|
end
|
|
|
|
xi.soa.helpers.initGameRound = function(player)
|
|
player:setLocalVar('turnNumber', 1)
|
|
player:setLocalVar('playerShots', 0)
|
|
player:setLocalVar('teodorShots', 0)
|
|
player:setLocalVar('teodorStayed', 0)
|
|
player:setLocalVar('playerSpecial', 0)
|
|
player:setLocalVar('teodorSpecial', 0)
|
|
end
|
|
|
|
xi.soa.helpers.updateMinigameEvent = function(player, csid, option, npc)
|
|
local turnNumber = player:getLocalVar('turnNumber')
|
|
local trickMask = player:getLocalVar('playerSpecial') == 0 and 128 or 4
|
|
|
|
-- Shoot
|
|
if option == 0 then
|
|
local playerShotValue = math.random(1, 6)
|
|
addShot(player, 'playerShots', playerShotValue)
|
|
|
|
local teodorAction, teodorShotValue, teodorSpecial = chooseTeodorAction(player)
|
|
|
|
player:updateEvent(0, turnNumber, playerShotValue, 0, teodorSpecial, teodorShotValue, teodorAction, trickMask)
|
|
player:setLocalVar('turnNumber', turnNumber + 1)
|
|
|
|
-- Stay
|
|
elseif option == 1 then
|
|
local gameStatus = 0 -- 1 = Win, 2 = Lose, 3 = Tie, 0 = Teodor keeps playing
|
|
local teodorAction, teodorShotValue, teodorSpecial = chooseTeodorAction(player)
|
|
|
|
-- Both players have stayed, set game status and update session score
|
|
if teodorAction == 1 then
|
|
local playerScore = getShotTotal(player, 'playerShots')
|
|
local teodorScore = getShotTotal(player, 'teodorShots')
|
|
|
|
if playerScore > teodorScore then
|
|
gameStatus = 1
|
|
elseif playerScore == teodorScore then
|
|
gameStatus = 3
|
|
else
|
|
gameStatus = 2
|
|
end
|
|
|
|
updateSessionScore(player, gameStatus)
|
|
else
|
|
player:setLocalVar('turnNumber', turnNumber + 1)
|
|
end
|
|
|
|
player:updateEvent(gameStatus, turnNumber, 0, 1, teodorSpecial, teodorShotValue, teodorAction, player:getLocalVar('sessionScore'))
|
|
|
|
if gameStatus > 0 then
|
|
xi.soa.helpers.initGameRound(player)
|
|
end
|
|
|
|
-- Peek
|
|
elseif option == 2 then
|
|
player:updateEvent(0, turnNumber, 0, 2, 1, 0, 0, 4)
|
|
player:setLocalVar('playerSpecial', 1)
|
|
|
|
-- Switcharoo
|
|
elseif bit.band(option, 0x7) == 3 then
|
|
local playerCardSlot = bit.band(bit.rshift(option, 3), 0xF) + 1
|
|
local teodorCardSlot = bit.band(bit.rshift(option, 7), 0xF) + 1
|
|
local playerShotData = getShotHistory(player, 'playerShots')
|
|
local teodorShotData = getShotHistory(player, 'teodorShots')
|
|
local swapData = bit.lshift(teodorShotData[teodorCardSlot], 5) + playerShotData[playerCardSlot]
|
|
|
|
replaceShot(player, 'playerShots', teodorShotData[teodorCardSlot], playerCardSlot)
|
|
replaceShot(player, 'teodorShots', playerShotData[playerCardSlot], teodorCardSlot)
|
|
|
|
player:setLocalVar('playerSpecial', 1)
|
|
player:updateEvent(0, turnNumber, 0, 3, 1, 0, 0, swapData)
|
|
|
|
-- Crooked Die
|
|
elseif bit.band(option, 0x7) == 4 then
|
|
local chosenSlot = bit.rshift(option, 7)
|
|
local newRollValue = math.random(1, 6)
|
|
local rerollData = bit.lshift(newRollValue, 5) + bit.lshift(chosenSlot, 1)
|
|
|
|
replaceShot(player, 'teodorShots', newRollValue, chosenSlot + 1)
|
|
player:setLocalVar('playerSpecial', 1)
|
|
player:updateEvent(0, turnNumber, 0, 4, rerollData, 0, 0, 0)
|
|
end
|
|
end
|