parent
1e93bf7ed9
commit
826210461d
@ -0,0 +1,133 @@ |
|||||||
|
--! Previous: sha1:f03c81c8d0ca3976d4b6fe4792ee7558d1c2c2f1 |
||||||
|
--! Hash: sha1:c8b959244b460096124e37cb9014d1a1b3faf7d3 |
||||||
|
--! Message: pull command gets units |
||||||
|
|
||||||
|
--- 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. |
||||||
|
--- VGNUT: No units in tier. The randomly selected tier has no units and it's impossible to summon a unit. |
||||||
|
--- VGUNF: Unit not found. The randomly selected unit was not found. |
||||||
|
--- VGTNF: Tier not found. The randomly selected tier was not found. |
||||||
|
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; |
||||||
|
tierRandom FLOAT; |
||||||
|
validUnits INTEGER[] := ARRAY []::INTEGER[]; |
||||||
|
unitRandom FLOAT; |
||||||
|
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 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 <t:%s:R> to get some more currency!', |
||||||
|
extract(EPOCH FROM NextDailyCommand(playerLastDaily))::INT) |
||||||
|
END; |
||||||
|
END IF; |
||||||
|
FOR summonIdx IN 1..count |
||||||
|
LOOP |
||||||
|
tierRandom = random(); |
||||||
|
unitRandom = random(); |
||||||
|
summonedUnitTierId = id |
||||||
|
FROM UnitTier |
||||||
|
WHERE (UnitTier.pullWeightLower <= tierRandom AND |
||||||
|
UnitTier.pullWeightUpper > tierRandom); |
||||||
|
validUnits = ARRAY(SELECT id FROM Unit WHERE (Unit.tierId = summonedUnitTierId)); |
||||||
|
IF validUnits = ARRAY []::INTEGER[] THEN |
||||||
|
RAISE EXCEPTION USING |
||||||
|
ERRCODE = 'VGNUT', |
||||||
|
MESSAGE = 'No units of tier', |
||||||
|
DETAIL = format( |
||||||
|
'The dice selected the tier with ID ''%s'', but there are no units of that tier!', |
||||||
|
summonedUnitTierId), |
||||||
|
HINT = 'This indicates a problem in the database. ' |
||||||
|
|| 'Contact an admin to fix this problem and get your justly deserved pull.'; |
||||||
|
END IF; |
||||||
|
summonedUnitId = validUnits[ |
||||||
|
floor(unitRandom::DOUBLE PRECISION * array_length(validUnits, 1)::DOUBLE PRECISION)::INTEGER + 1]; |
||||||
|
SELECT Unit.id, Unit.name, Unit.subtitle, Unit.tierId |
||||||
|
INTO summonedUnitId, summonedUnitName, summonedUnitSubtitle, summonedUnitTierId |
||||||
|
FROM Unit |
||||||
|
WHERE Unit.id = summonedUnitId; |
||||||
|
IF NOT FOUND THEN |
||||||
|
RAISE EXCEPTION USING |
||||||
|
ERRCODE = 'VGUNF', |
||||||
|
MESSAGE = 'Unit not found', |
||||||
|
DETAIL = format( |
||||||
|
'The dice selected the unit with ID ''%s'' of tier ID ''%s'', but the unit wasn''t found!', |
||||||
|
summonedUnitId, summonedUnitTierId), |
||||||
|
HINT = 'This indicates a problem in the database.' |
||||||
|
|| ' Contact an admin to fix this problem and get your justly deserved pull.'; |
||||||
|
END IF; |
||||||
|
SELECT UnitTier.id, UnitTier.name |
||||||
|
INTO summonedUnitTierId, summonedUnitTierName |
||||||
|
FROM UnitTier |
||||||
|
WHERE UnitTier.id = summonedUnitTierId; |
||||||
|
IF NOT FOUND THEN |
||||||
|
RAISE EXCEPTION USING |
||||||
|
ERRCODE = 'VGTNF', |
||||||
|
MESSAGE = 'Tier not found', |
||||||
|
DETAIL = format( |
||||||
|
'The dice selected the unit with ID ''%s'' of tier ID ''%s'', but the tier wasn''t found!', |
||||||
|
summonedUnitId, summonedUnitTierId), |
||||||
|
HINT = 'This indicates a problem in the database.' |
||||||
|
|| ' Contact an admin to fix this problem and get your justly deserved pull.'; |
||||||
|
END IF; |
||||||
|
summonedUnitInstanceId = NULL::INTEGER; |
||||||
|
summonCost = costPerSummon; |
||||||
|
resultingCurrency = oldCurrency - (costPerSummon * summonIdx); |
||||||
|
firstTimePull = NULL::BOOLEAN; |
||||||
|
wasAlreadySummoned = NULL::BOOLEAN; |
||||||
|
RETURN NEXT; |
||||||
|
END LOOP; |
||||||
|
END; |
||||||
|
|
||||||
|
$$ LANGUAGE 'plpgsql'; |
Loading…
Reference in new issue