--! 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 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';