Source Code
Raid Seed Generator by Gengar
The documentation below explains the source code of our raid seed generator and how to use it. This code is free to use, just leave the credits in the footer, please.
The Script
This is the script that makes everything work.
The Script
// Save the users bot prefix in a cookie
function saveBotPrefix() {
const botPrefix = document.getElementById("botPrefix").value;
document.cookie = `botPrefix=${botPrefix}; path=/; max-age=${30 * 24 * 60 * 60}`; // Save for 30 days
}
function loadBotPrefix() {
const botPrefixInput = document.getElementById("botPrefix");
const cookieValue = document.cookie
.split("; ")
.find((row) => row.startsWith("botPrefix="));
if (cookieValue) {
const botPrefix = cookieValue.split("=")[1];
botPrefixInput.value = botPrefix;
}
}
// Add an event listener for the 'botPrefix' input element to save the user's choice
document.getElementById("botPrefix").addEventListener("change", saveBotPrefix);
let currentPage = 1;
const itemsPerPage = 10;
async function fetchJsonData() {
const game = document.getElementById("game").value;
const response = await fetch(
`path/to/${game.toLowerCase()}_data.json` //replace with your path here. file names should be scarlet_data.json and violet_data.json
);
data = await response.json();
displayRewards();
}
fetchJsonData();
function prevPage() {
if (currentPage > 1) {
currentPage--;
displayRewards();
}
}
function nextPage() {
const filteredData = getFilteredData();
if (currentPage < Math.ceil(filteredData.length / itemsPerPage)) {
currentPage++;
displayRewards();
}
}
function updatePagination() {
const prevPageButton = document.getElementById("prevPage");
const nextPageButton = document.getElementById("nextPage");
const pageInfo = document.getElementById("pageInfo");
const filteredData = getFilteredData();
prevPageButton.disabled = currentPage === 1;
nextPageButton.disabled =
currentPage === Math.ceil(filteredData.length / itemsPerPage);
pageInfo.textContent = `${currentPage} / ${Math.ceil(
filteredData.length / itemsPerPage
)}`;
}
function getFilteredData() {
const rewardFilterValue = document.getElementById("rewardFilter").value;
const pokemonFilterValue = document.getElementById("pokemonFilter").value;
const teraFilterValue = document.getElementById("teraFilter").value;
const genderFilterValue = document.getElementById("genderFilter").value;
return data.filter((reward) => {
const rewardFilterMatch =
rewardFilterValue === "all" || reward.Rewards === rewardFilterValue;
const pokemonFilterMatch =
pokemonFilterValue === "all" || reward.Pokemon === pokemonFilterValue;
const teraFilterMatch =
teraFilterValue === "all" || reward.Tera === teraFilterValue;
const genderFilterMatch =
genderFilterValue === "all" || reward.Gender === genderFilterValue;
return (
rewardFilterMatch &&
pokemonFilterMatch &&
teraFilterMatch &&
genderFilterMatch
);
});
}
function populatePokemonFilter() {
currentPage = 1; // Take us back to page 1 on filter change
const pokemonFilter = document.getElementById("pokemonFilter");
const rewardFilterValue = document.getElementById("rewardFilter").value;
pokemonFilter.innerHTML = "<option value='all'>All</option>";
if (rewardFilterValue === "all") {
pokemonFilter.disabled = true;
return;
}
pokemonFilter.disabled = false;
const pokemonSet = new Set();
data.forEach((reward) => {
if (reward.Rewards === rewardFilterValue) {
pokemonSet.add(reward.Pokemon);
}
});
// Create and append an option for each unique Pokémon in alphabetical order
Array.from(pokemonSet)
.sort((a, b) => a.localeCompare(b))
.forEach((pokemon) => {
const option = document.createElement("option");
option.value = pokemon;
option.textContent = pokemon;
pokemonFilter.appendChild(option);
});
populateTeraFilter(); // Update the Tera filter as well
displayRewards();
}
function populateTeraFilter() {
currentPage = 1; // Take us back to page 1 on filter change
const teraFilter = document.getElementById('teraFilter');
const rewardFilterValue = document.getElementById('rewardFilter').value;
const pokemonFilterValue = document.getElementById('pokemonFilter').value;
const teraSet = new Set(
data
.filter(
reward =>
(rewardFilterValue === 'all' || reward.Rewards === rewardFilterValue) &&
reward.Pokemon === pokemonFilterValue
)
.map(reward => reward.Tera)
);
const sortedTera = [...teraSet].sort();
teraFilter.innerHTML = '<option value="all">All</option>';
sortedTera.forEach(tera => {
const option = document.createElement('option');
option.value = option.textContent = tera;
teraFilter.appendChild(option);
});
teraFilter.disabled = false;
populateGenderFilter();
}
function populateGenderFilter() {
currentPage = 1; // Take us back to page 1 on filter change
const genderFilter = document.getElementById('genderFilter');
const rewardFilterValue = document.getElementById('rewardFilter').value;
const pokemonFilterValue = document.getElementById('pokemonFilter').value;
const teraFilterValue = document.getElementById('teraFilter').value;
const genderSet = new Set(
data
.filter(
reward =>
(rewardFilterValue === 'all' || reward.Rewards === rewardFilterValue) &&
(pokemonFilterValue === 'all' || reward.Pokemon === pokemonFilterValue) &&
(teraFilterValue === 'all' || reward.Tera === teraFilterValue)
)
.map(reward => reward.Gender)
);
const sortedGender = [...genderSet].sort();
genderFilter.innerHTML = '<option value="all">All</option>';
sortedGender.forEach(gender => {
const option = document.createElement('option');
option.value = option.textContent = gender;
genderFilter.appendChild(option);
});
genderFilter.disabled = false;
}
function displayRewards() {
const tableBody = document.getElementById("tableBody");
tableBody.innerHTML = "";
const rewardFilterValue = document.getElementById("rewardFilter").value;
const pokemonFilterValue = document.getElementById("pokemonFilter").value;
const teraFilterValue = document.getElementById("teraFilter").value;
const genderFilterValue = document.getElementById("genderFilter").value;
const botPrefix = document.getElementById("botPrefix").value;
const filteredData = data.filter((reward) => {
const rewardFilterMatch =
rewardFilterValue === "all" || reward.Rewards === rewardFilterValue;
const pokemonFilterMatch =
pokemonFilterValue === "all" || reward.Pokemon === pokemonFilterValue;
const teraFilterMatch =
teraFilterValue === "all" || reward.Tera === teraFilterValue;
const genderFilterMatch =
genderFilterValue === "all" || reward.Gender === genderFilterValue;
return (
rewardFilterMatch &&
pokemonFilterMatch &&
teraFilterMatch &&
genderFilterMatch
);
});
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const paginatedData = filteredData.slice(startIndex, endIndex);
paginatedData.forEach((reward) => {
const row = tableBody.insertRow();
const rewardCell = row.insertCell();
rewardCell.textContent = reward.Rewards;
const pokemonCell = row.insertCell();
const pokemonImg = document.createElement("img");
const pokemonName = reward.Pokemon.toLowerCase();
pokemonImg.src = `/path/to/sprites/${pokemonName}.png`; //change to your url
pokemonImg.alt = reward.Pokemon;
pokemonImg.width = "80"; // set width
pokemonCell.appendChild(pokemonImg);
const teraCell = row.insertCell();
const teraImg = document.createElement("img");
const teraName = reward.Tera.toLowerCase();
teraImg.src = `/path/to/tera_icons/${teraName}.png`; //change to your url
teraImg.alt = reward.Tera;
teraImg.width = "45"; // set width
teraCell.appendChild(teraImg);
const seedWithDifficulty = `${reward.Seed} ${reward.Difficulty}`;
const seedCell = row.insertCell();
seedCell.textContent = `${botPrefix} ${seedWithDifficulty}`;
const genderCell = row.insertCell();
genderCell.textContent = reward.Gender;
const copyButton = document.createElement("button");
copyButton.textContent = "Copy";
copyButton.addEventListener("click", () => {
const seedWithPrefix = `${botPrefix} ${seedWithDifficulty}`;
navigator.clipboard
.writeText(seedWithPrefix)
.then(() => {
alert("Seed copied to clipboard: " + seedWithPrefix);
})
.catch((err) => {
console.error("Error copying seed to clipboard:", err);
});
});
const actionsCell = row.insertCell();
actionsCell.appendChild(copyButton);
});
updatePagination();
}
function sortTable(columnIndex) {
data.sort((a, b) => {
const keys = Object.keys(a);
const key = keys[columnIndex];
return a[key].localeCompare(b[key]);
});
displayRewards();
}
function resetFilters() {
const rewardFilter = document.getElementById("rewardFilter");
const pokemonFilter = document.getElementById("pokemonFilter");
const teraFilter = document.getElementById("teraFilter");
rewardFilter.value = "all";
pokemonFilter.value = "all";
teraFilter.value = "all";
pokemonFilter.disabled = true;
teraFilter.disabled = true;
displayRewards();
}
// Call the `loadBotPrefix()` function at the end of your script to load the saved 'BotPrefix' value when the page loads
loadBotPrefix();
The HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
/* Horizontal layout for dropdowns on desktop */
.dropdown-wrapper {
display: flex;
flex-wrap: wrap;
}
.dropdown-container {
margin: 5px;
}
/* Vertical layout for dropdowns on mobile */
@media (max-width: 768px) {
.dropdown-wrapper {
display: block;
}
.dropdown-container {
margin-bottom: 10px;
}
}
button#resetFilters {
background-color: darkred;
}
select, button {
background-color: #333;
color: #fff;
border: 1px solid #444;
padding: 5px;
margin: 5px 0;
}
select:focus, button:focus {
outline: none;
border-color: #777;
}
select:disabled {
background-color: #222;
}
#pagination {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
#pagination button[disabled] {
background-color: #222;
cursor: not-allowed;
}
footer {
color: #aaa;
font-size: 0.8em;
margin-top: 20px;
}
footer a {
color: #aaa;
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
@media only screen and (max-width: 600px) {
/* Hide the "Reward" and "Gender" column on small screens */
th:nth-child(1),
td:nth-child(1),
th:nth-child(5),
td:nth-child(5) {
display: none;
}
}
</style>
</head>
<body class="dark">
<h1>Raid Seed Generator for S/V</h1>
<div class="dropdown-wrapper">
<div class="dropdown-container">
<label for="game">Bots game version:</label>
<select id="game" onchange="fetchJsonData()">
<option value="Scarlet">Pokémon Scarlet</option>
<option value="Violet">Pokémon Violet</option>
</select>
</div>
<div class="dropdown-container">
<label for="rewardFilter">Filter by Rewards:</label>
<select id="rewardFilter" onchange="populatePokemonFilter();">
<option value="all">All</option>
<option value="Reward 1">Reward 1</option>
<option value="Reward 2">Reward 2</option>
<option value="Reward 3">Reward 3</option>
</select>
</div>
<div class="dropdown-container">
<label for="pokemonFilter">Filter by Pokémon:</label>
<select id="pokemonFilter" onchange="populateTeraFilter(); displayRewards();" disabled>
<option value="all">All</option>
</select>
</div>
<div class="dropdown-container">
<label for="teraFilter">Filter by Tera Type:</label>
<select id="teraFilter" onchange="displayRewards()" disabled>
<option value="all">All</option>
</select>
</div>
<div class="dropdown-container">
<label for="genderFilter">Filter by Gender:</label>
<select id="genderFilter" onchange="displayRewards()">
<option value="all">All</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Genderless">Genderless</option>
</select>
</div>
<div class="dropdown-container">
<label for="botPrefix">Bot Prefix:</label>
<select id="botPrefix" onchange="displayRewards()">
<option value="$ra">$ra</option>
<option value=".ra">.ra</option>
<option value="!ra">!ra</option>
<option value="?ra">?ra</option>
<option value=";ra">;ra</option>
</select>
</div>
<button id="resetFilters" onclick="resetFilters()">Reset Filters</button>
<table id="rewardsTable">
<thead>
<tr>
<th onclick="sortTable(0)">Rewards</th>
<th onclick="sortTable(1)">Pokémon</th>
<th onclick="sortTable(2)">Tera</th>
<th onclick="sortTable(3)">Seed</th>
<th onclick="sortTable(4)">Gender</th> <!-- Added Gender header cell -->
<th>Actions</th>
</tr>
</thead>
<tbody id="tableBody"></tbody>
</table>
<!-- Please do not remove credits -->
<footer>
<p><center>
Made with love by Gengar of Mewtwos Pokemon Cloning.
<a href="https://genpkm.com" target="_blank" rel="noopener noreferrer">https://genpkm.com</a>
</p></center>
</footer>
<div id="pagination">
<button id="prevPage" onclick="prevPage()" disabled>Prev</button>
<span id="pageInfo">1 / 1</span>
<button id="nextPage" onclick="nextPage()" disabled>Next</button>
</div>
</body>
<script>
<!-- Script From Above Goes Here -->
</script>
</html>
What Each Function Does
fetchJsonData() - this function fetches JSON data based on user input from the web and stores it in the data variable.
It then calls the displayRewards() function to show the rewards based on the fetched data.
prevPage() - this function decrements the currentPage variable by 1 and
calls the displayRewards() function to show the previous page of rewards.
nextPage() - this function increments the currentPage variable by 1 and
calls the displayRewards() function to show the next page of rewards.
updatePagination() - this function updates the pagination UI by disabling the "Prev" and "Next" buttons
based on the current page number and the filtered data. It also displays the current
page number and total number of pages.
getFilteredData() - this function filters the data based on user-selected
filter values and returns the filtered data.
populatePokemonFilter() - this function populates the Pokemon filter dropdown
with unique Pokemon names based on the selected reward filter value.
populateTeraFilter() - this function populates the Tera filter dropdown with unique
Tera names based on the selected reward and Pokemon filter values.
populateGenderFilter() - this function populates the Gender filter dropdown with
unique gender values based on the selected reward, Pokemon, and Tera filter values.
displayRewards() - this function displays the rewards in a table based on the filtered data,
current page number, and items per page. It also updates the pagination UI.
sortTable() - this function sorts the data based on the column index passed as a
parameter and then calls the displayRewards() function to show the sorted data.
resetFilters() - this function resets all filters to their default values, disables the Pokemon
and Tera filters, and calls the displayRewards() function to show the rewards based on
the default filter values.
Downloads
Images and Icons used for this project.
Updates
Keep track of change logs here.
4/3/23
I’ve updated the script to include pagination based on the current filter selections. In addition, I’ve made some improvements to the filtering code to make it more efficient and maintainable.
I’ve introduced a new function getFilteredData() which returns the data based on the current filter selections. This function is now used in both nextPage() and updatePagination() functions to ensure the correct pagination values are calculated and displayed.
Updated Tera Icon for Fighting and re-uploaded file to downloads.
4/4/23
Added currentPage = 1; to filters to take us back to page when when we change our options.
Save botprefix selection in a cookie, that way when the user reloads the page, it will stay.
Added styling to display filter drop downs side by side on desktop and vertically on mobile.
Resources
Links to helpful sites
Grab the latest RaidCalc from here.
Use raidcalc to find your seeds, then export them to csv.
CSV to JSON: Go to the website here to convert your csv to JSON format. You will need the following for this script: Seed, Species needs to be changed to “Pokemon”, Gender, Tera Type needs to be changed to just “Tera”, and Difficulty needs to be added. Your JSON data should look like this example:
{
“Rewards”: “Shiny Max Herba Drops”,
“Difficulty”: 6,
“Pokemon”: “Cetitan”,
“Tera”: “Grass”,
“Gender”: “Female”,
“Seed”: “10DB01FE”
},
BEST WEB HOSTING PROVIDER AROUND:
Use my link here to purchase web hosting from Shock Hosting