parent
1d99caa4ea
commit
61b04327f0
@ -0,0 +1,131 @@ |
||||
--! Previous: sha1:c36f619890ff43d233e58abb4c5b9d5a4e556ca3 |
||||
--! Hash: sha1:3a9ed9f26777390a1dccadc516bade27ffddf684 |
||||
--! Message: pull command gets tiers |
||||
|
||||
ALTER TABLE UnitTier |
||||
ADD COLUMN IF NOT EXISTS pullWeightLower FLOAT NOT NULL DEFAULT 0, |
||||
ADD COLUMN IF NOT EXISTS pullWeightUpper FLOAT NOT NULL DEFAULT 0; |
||||
|
||||
--- Updates the UnitTier pull weight bounds to span from 0.0 to 1.0 and match the weights given. |
||||
CREATE OR REPLACE PROCEDURE UnitTier_UpdatePullWeightBounds() AS |
||||
$$ |
||||
WITH weights AS ( |
||||
SELECT UnitTier.id AS id, |
||||
(sum(UnitTier.pullWeight) OVER (ORDER BY UnitTier.sortOrder) - UnitTier.pullWeight)::FLOAT / |
||||
(sum(UnitTier.pullWeight) OVER ())::FLOAT AS newPullWeightLower, |
||||
(sum(pullWeight) OVER (ORDER BY sortOrder))::FLOAT / |
||||
(sum(pullWeight) OVER ())::FLOAT AS newPullWeightUpper |
||||
FROM UnitTier |
||||
) |
||||
UPDATE UnitTier |
||||
SET pullWeightLower = weights.newPullWeightLower, |
||||
pullWeightUpper = weights.newPullWeightUpper |
||||
FROM weights |
||||
WHERE weights.id = UnitTier.id; |
||||
$$ LANGUAGE 'sql'; |
||||
|
||||
CALL UnitTier_UpdatePullWeightBounds(); |
||||
|
||||
DROP TRIGGER IF EXISTS UnitTier_UpdatePullWeightBounds_Trigger ON UnitTier; |
||||
CREATE OR REPLACE FUNCTION UnitTier_UpdatePullWeightBounds_TriggerFunc() RETURNS TRIGGER AS |
||||
$$ |
||||
BEGIN |
||||
CALL UnitTier_UpdatePullWeightBounds(); |
||||
END; |
||||
$$ |
||||
LANGUAGE 'plpgsql'; |
||||
--- Automatically updates the pull weight bounds whenever the table changes. |
||||
CREATE TRIGGER UnitTier_UpdatePullWeightBounds_Trigger |
||||
AFTER INSERT OR UPDATE OF pullWeight OR DELETE |
||||
ON UnitTier |
||||
FOR EACH STATEMENT |
||||
EXECUTE PROCEDURE UnitTier_UpdatePullWeightBounds_TriggerFunc(); |
||||
|
||||
DROP FUNCTION IF EXISTS 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 |
||||
); |
||||
--- 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, |
||||
summonedUnitTierId UnitTier.id%TYPE, |
||||
summonedUnitTierName UnitTier.name%TYPE, |
||||
summonCost Player.currency%TYPE, |
||||
resultingCurrency Player.currency%TYPE, |
||||
firstTimePull BOOLEAN, |
||||
wasAlreadySummoned BOOLEAN |
||||
) |
||||
STRICT |
||||
VOLATILE |
||||
ROWS 10 |
||||
AS |
||||
$$ |
||||
DECLARE |
||||
costPerSummon CONSTANT INT := 10; |
||||
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 |
||||
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 IF; |
||||
cost = costPerSummon * 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 playerLastDaily IS NULL OR playerLastDaily < NOW() - '1 day'::interval |
||||
WHEN TRUE THEN 'Try using the /daily command to get some more currency for today!' |
||||
ELSE format('Wait %s and you can use the /daily command to get some more currency!', |
||||
(playerLastDaily + '1 day'::interval) - NOW()) |
||||
END; |
||||
END IF; |
||||
RETURN QUERY |
||||
WITH rng AS (SELECT summonId, random() AS tierRandom FROM generate_series(1, count) AS series(summonId)) |
||||
SELECT NULL::INTEGER AS summonedUnitInstanceId, |
||||
NULL::INTEGER AS summonedUnitId, |
||||
NULL::VARCHAR AS summonedUnitName, |
||||
NULL::VARCHAR AS summonedUnitSubtitle, |
||||
t.id AS summonedUnitTierId, |
||||
t.name AS summonedUnitTierName, |
||||
costPerSummon AS summonCost, |
||||
oldCurrency - (costPerSummon * r.summonId) AS resultingCurrency, |
||||
NULL::BOOLEAN AS firstTimePull, |
||||
NULL::BOOLEAN AS wasAlreadySummoned |
||||
FROM rng AS r |
||||
INNER JOIN UnitTier AS t ON (t.pullWeightLower <= r.tierRandom AND t.pullWeightUpper > r.tierRandom); |
||||
END; |
||||
$$ LANGUAGE 'plpgsql'; |
Loading…
Reference in new issue