--! Previous: sha1:2a39b3b006a8d5ec5d30ac1e5c2158d282b99acb --! Hash: sha1:1390238abcc8e013a87b670fbcb3ae127a51ece8 --! Message: daily and VGNYJ error functions --- Calculates the date at which /daily can be used again after the given timestamp. CREATE OR REPLACE FUNCTION NextDailyCommand(IN lastDaily timestamp with time zone) RETURNS timestamp with time zone CALLED ON NULL INPUT IMMUTABLE AS $$ SELECT (COALESCE(lastDaily, TIMESTAMP '-infinity' AT TIME ZONE 'UTC')::date + 1)::timestamp AT TIME ZONE 'UTC' $$ LANGUAGE 'sql'; --- Raises the VGNYJ error. CREATE OR REPLACE PROCEDURE Error_NotYetJoined() AS $$ BEGIN RAISE EXCEPTION USING ERRCODE = 'VGNYJ', MESSAGE = 'Not yet joined', DETAIL = 'You haven''t joined the game yet, and can''t use this command until you do.', HINT = 'Use the /join command to join the game!'; END; $$ LANGUAGE 'plpgsql'; --- Runs the full /daily command. --- Error codes: --- VGBCG: Bad channel (game). This is not a valid channel to send game commands in. --- VGBGG: Bad guild (game). This is not a valid guild to send game commands in. --- VGNYJ: Not yet joined. The Discord user using has not joined the game yet. --- VGDLY: Already used today. CREATE OR REPLACE FUNCTION Command_Daily( IN requestedChannel DiscordChannel.discordId%TYPE, IN requestedGuild DiscordChannel.guildId%TYPE, IN forId DiscordUser.discordId%TYPE, IN newUsername DiscordUser.username%TYPE, IN newDiscriminator DiscordUser.discriminator%TYPE, OUT newLastDaily Player.lastDaily%TYPE, OUT newNextDaily Player.lastDaily%TYPE, OUT newCurrency Player.currency%TYPE, OUT bonus Player.currency%TYPE) STRICT VOLATILE AS $$ DECLARE playerId Player.id%TYPE; playerLastDaily Player.lastDaily%TYPE; playerNextDaily Player.lastDaily%TYPE; BEGIN CALL CheckGameCommandIn(requestedChannel, requestedGuild); SELECT InvokingPlayer.id, InvokingPlayer.lastDaily, NextDailyCommand(InvokingPlayer.lastdaily) INTO playerId, playerLastDaily, playerNextDaily FROM GetInvokingPlayer(forId, newUsername, newDiscriminator) AS InvokingPlayer; IF playerId IS NULL THEN CALL Error_NotYetJoined(); END IF; bonus = 100; IF playerNextDaily > NOW() THEN RAISE EXCEPTION USING ERRCODE = 'VGDLY', MESSAGE = 'Already used today', DETAIL = format('You last used your daily command at . You can use it again at .', extract(EPOCH FROM playerLastDaily)::INT, extract(EPOCH FROM playerNextDaily)::INT), HINT = format('Wait and you can use the /daily command again to get some more currency!', extract(EPOCH FROM playerNextDaily)::INT); ELSE UPDATE Player SET currency = currency + bonus, lastDaily = NOW() WHERE id = playerId RETURNING lastDaily, currency INTO newLastDaily, newCurrency; newNextDaily = NextDailyCommand(newLastDaily); END IF; END; $$ LANGUAGE 'plpgsql'; --- Runs the full /pull command. --- Error codes: --- VGBCG: Bad channel (game). This is not a valid channel to send game commands in. --- VGBGG: Bad guild (game). This is not a valid guild to send game commands in. --- VGNYJ: Not yet joined. The Discord user using has not joined the game yet. --- VGNEC: Not enough currency. CREATE OR REPLACE FUNCTION Command_Pull( IN requestedChannel DiscordChannel.discordId%TYPE, IN requestedGuild DiscordChannel.guildId%TYPE, IN forId DiscordUser.discordId%TYPE, IN newUsername DiscordUser.username%TYPE, IN newDiscriminator DiscordUser.discriminator%TYPE, IN count INT ) RETURNS TABLE ( summonedUnitInstanceId SummonedUnit.instanceId%TYPE, summonedUnitId Unit.id%TYPE, summonedUnitName Unit.name%TYPE, summonedUnitSubtitle Unit.subtitle%TYPE, summonedUnitTierName UnitTier.name%TYPE, firstTimePull BOOLEAN, wasAlreadySummoned BOOLEAN ) STRICT VOLATILE ROWS 10 AS $$ DECLARE playerId Player.id%TYPE; cost Player.currency%TYPE; oldCurrency Player.currency%TYPE; playerLastDaily Player.lastDaily%TYPE; BEGIN CALL CheckGameCommandIn(requestedChannel, requestedGuild); SELECT InvokingPlayer.id, InvokingPlayer.currency, InvokingPlayer.lastDaily INTO playerId, oldCurrency, playerLastDaily FROM GetInvokingPlayer(forId, newUsername, newDiscriminator) AS InvokingPlayer; IF playerId IS NULL THEN CALL Error_NotYetJoined(); END IF; cost = 10 * count; UPDATE Player SET currency = currency - cost WHERE id = playerId AND currency >= cost; IF NOT FOUND THEN RAISE EXCEPTION USING ERRCODE = 'VGNEC', MESSAGE = 'Not enough currency', DETAIL = format('Pulling %s heroines would cost %s currency, but you only have %s currency.', count, cost, oldCurrency), HINT = CASE NextDailyCommand(playerLastDaily) > NOW() WHEN FALSE THEN 'You can use the /daily command to get some more currency for today!' ELSE format('You can use the /daily command again to get some more currency!', extract(EPOCH FROM NextDailyCommand(playerLastDaily))::INT) END; END IF; END; $$ LANGUAGE 'plpgsql';