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