Compare commits

6 Commits
main ... pages

Author SHA1 Message Date
b961fee453 newline 2026-02-11 23:50:33 -05:00
e62d9248c1 asda 2026-02-11 23:34:43 -05:00
65d011c9c3 fix 2026-02-11 23:33:09 -05:00
634acb0d24 test 2026-02-11 23:29:29 -05:00
ab330c48f8 codeberg 2026-02-11 23:23:30 -05:00
4372fdd7ec Pages 2026-02-11 22:28:36 -05:00
28 changed files with 898 additions and 2018 deletions

1
.domains Normal file
View File

@@ -0,0 +1 @@
opinionatedfirearms.hriggs.pages.hudsonriggs.systems

1
.gitignore vendored
View File

@@ -1 +0,0 @@
source/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -1,9 +0,0 @@
name=Opinionated Firearms
id=hrsys_opinionated_firearms_testing
author=Riggs0
modversion=1.0.0
versionMin=42.12.13
require=\2788256295/ammomaker,\HBVCEFb42
description=Opinionated Firearms casing and other changes to Guns of 93, Ammomaker and Hot Brass
icon=icon.png
poster=preview.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

557
app.js Normal file
View File

@@ -0,0 +1,557 @@
"use strict";
const state = {
catalog: null,
profileByItem: {},
selectedItem: null,
};
const dom = {
statusText: document.getElementById("statusText"),
catalogFile: document.getElementById("catalogFile"),
profileFile: document.getElementById("profileFile"),
exportProfile: document.getElementById("exportProfile"),
searchInput: document.getElementById("searchInput"),
categoryFilter: document.getElementById("categoryFilter"),
spawnFilter: document.getElementById("spawnFilter"),
itemTableBody: document.getElementById("itemTableBody"),
selectedDetails: document.getElementById("selectedDetails"),
resetSelected: document.getElementById("resetSelected"),
};
function setStatus(text) {
dom.statusText.textContent = text;
}
function readFileText(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(String(reader.result || ""));
reader.onerror = () => reject(new Error(`Failed to read ${file.name}`));
reader.readAsText(file);
});
}
function safeNumber(value, fallback = 0) {
const n = Number.parseFloat(value);
return Number.isFinite(n) ? n : fallback;
}
function normalizeItemType(item) {
if (typeof item !== "string") {
return null;
}
const trimmed = item.trim();
if (!trimmed) {
return null;
}
return trimmed.includes(".") ? trimmed : `Base.${trimmed}`;
}
function normalizeCatalog(raw) {
if (!raw || !Array.isArray(raw.items)) {
throw new Error("Invalid catalog format. Missing items array.");
}
const lists = new Set(Array.isArray(raw.lists) ? raw.lists : []);
const items = [];
for (const rawItem of raw.items) {
const itemType = normalizeItemType(rawItem.item);
if (!itemType) {
continue;
}
const aggregated = Array.isArray(rawItem.aggregatedPlacements)
? rawItem.aggregatedPlacements
: [];
const placements = {};
for (const placement of aggregated) {
const listName = placement && typeof placement.list === "string" ? placement.list.trim() : "";
const weight = safeNumber(placement && placement.weight, 0);
if (!listName || weight <= 0) {
continue;
}
placements[listName] = Number(weight.toFixed(6));
lists.add(listName);
}
items.push({
item: itemType,
shortId: typeof rawItem.shortId === "string" ? rawItem.shortId : itemType.replace(/^Base\./, ""),
category: typeof rawItem.category === "string" ? rawItem.category : "unknown",
defaultEnabled: rawItem.defaultEnabled !== false,
spawnControlKeys: Array.isArray(rawItem.spawnControlKeys) ? rawItem.spawnControlKeys : [],
defaultPlacements: placements,
});
}
items.sort((a, b) => a.item.localeCompare(b.item));
return {
generatedAt: raw.generatedAt || null,
source: raw.source || {},
items,
lists: Array.from(lists).sort(),
};
}
function initializeProfileFromCatalog() {
const profileByItem = {};
for (const item of state.catalog.items) {
const placements = {};
for (const [listName, weight] of Object.entries(item.defaultPlacements)) {
placements[listName] = weight;
}
profileByItem[item.item] = {
item: item.item,
category: item.category,
enabled: item.defaultEnabled,
placements,
};
}
state.profileByItem = profileByItem;
}
function getProfileEntry(itemType) {
return state.profileByItem[itemType] || null;
}
function updateProfileEntry(itemType, updater) {
const current = getProfileEntry(itemType);
if (!current) {
return;
}
updater(current);
}
function getFilteredItems() {
if (!state.catalog) {
return [];
}
const search = dom.searchInput.value.trim().toLowerCase();
const category = dom.categoryFilter.value;
const spawnState = dom.spawnFilter.value;
return state.catalog.items.filter((item) => {
const entry = getProfileEntry(item.item);
if (!entry) {
return false;
}
if (category !== "all" && item.category !== category) {
return false;
}
if (spawnState === "enabled" && !entry.enabled) {
return false;
}
if (spawnState === "disabled" && entry.enabled) {
return false;
}
if (!search) {
return true;
}
return (
item.item.toLowerCase().includes(search) ||
item.shortId.toLowerCase().includes(search)
);
});
}
function renderItemTable() {
const filteredItems = getFilteredItems();
dom.itemTableBody.innerHTML = "";
for (const item of filteredItems) {
const entry = getProfileEntry(item.item);
const row = document.createElement("tr");
if (state.selectedItem === item.item) {
row.classList.add("selected");
}
const spawnTd = document.createElement("td");
const spawnCheck = document.createElement("input");
spawnCheck.type = "checkbox";
spawnCheck.checked = entry.enabled;
spawnCheck.addEventListener("click", (event) => event.stopPropagation());
spawnCheck.addEventListener("change", () => {
updateProfileEntry(item.item, (target) => {
target.enabled = spawnCheck.checked;
});
renderItemTable();
renderSelectedDetails();
});
spawnTd.appendChild(spawnCheck);
const itemTd = document.createElement("td");
itemTd.textContent = item.shortId;
const categoryTd = document.createElement("td");
categoryTd.textContent = item.category;
const listsTd = document.createElement("td");
listsTd.textContent = String(Object.keys(entry.placements).length);
row.appendChild(spawnTd);
row.appendChild(itemTd);
row.appendChild(categoryTd);
row.appendChild(listsTd);
row.addEventListener("click", () => {
state.selectedItem = item.item;
renderItemTable();
renderSelectedDetails();
});
dom.itemTableBody.appendChild(row);
}
}
function renderPlacementsTable(item, entry, container) {
const table = document.createElement("table");
table.className = "placements-table";
const thead = document.createElement("thead");
thead.innerHTML = "<tr><th>List</th><th>Weight</th><th></th></tr>";
table.appendChild(thead);
const tbody = document.createElement("tbody");
const placementNames = Object.keys(entry.placements).sort();
for (const listName of placementNames) {
const weight = entry.placements[listName];
const tr = document.createElement("tr");
const listTd = document.createElement("td");
listTd.textContent = listName;
const weightTd = document.createElement("td");
const weightInput = document.createElement("input");
weightInput.type = "number";
weightInput.min = "0";
weightInput.step = "0.001";
weightInput.value = String(weight);
weightInput.addEventListener("change", () => {
const next = safeNumber(weightInput.value, 0);
if (next <= 0) {
delete entry.placements[listName];
} else {
entry.placements[listName] = Number(next.toFixed(6));
}
renderItemTable();
renderSelectedDetails();
});
weightTd.appendChild(weightInput);
const actionTd = document.createElement("td");
const removeBtn = document.createElement("button");
removeBtn.type = "button";
removeBtn.className = "small-btn remove";
removeBtn.textContent = "Remove";
removeBtn.addEventListener("click", () => {
delete entry.placements[listName];
renderItemTable();
renderSelectedDetails();
});
actionTd.appendChild(removeBtn);
tr.appendChild(listTd);
tr.appendChild(weightTd);
tr.appendChild(actionTd);
tbody.appendChild(tr);
}
table.appendChild(tbody);
container.appendChild(table);
}
function renderSelectedDetails() {
const selected = state.selectedItem;
dom.selectedDetails.innerHTML = "";
if (!state.catalog || !selected) {
dom.selectedDetails.textContent = "Select an item to edit placements and spawn rate.";
dom.selectedDetails.className = "details-empty";
return;
}
const item = state.catalog.items.find((it) => it.item === selected);
const entry = getProfileEntry(selected);
if (!item || !entry) {
dom.selectedDetails.textContent = "Selected item not found.";
dom.selectedDetails.className = "details-empty";
return;
}
dom.selectedDetails.className = "details-body";
const itemHeader = document.createElement("div");
itemHeader.className = "item-header";
itemHeader.innerHTML = `
<div>
<h3 class="item-title">${item.item}</h3>
<span class="badge">${item.category}</span>
</div>
`;
dom.selectedDetails.appendChild(itemHeader);
const enabledRow = document.createElement("div");
enabledRow.className = "inline-row";
const enabledInput = document.createElement("input");
enabledInput.type = "checkbox";
enabledInput.checked = entry.enabled;
enabledInput.addEventListener("change", () => {
entry.enabled = enabledInput.checked;
renderItemTable();
});
const enabledLabel = document.createElement("label");
enabledLabel.textContent = "Spawn enabled";
enabledLabel.prepend(enabledInput);
enabledLabel.style.display = "inline-flex";
enabledLabel.style.alignItems = "center";
enabledLabel.style.gap = "0.35rem";
enabledRow.appendChild(enabledLabel);
dom.selectedDetails.appendChild(enabledRow);
const placementsLabel = document.createElement("p");
placementsLabel.textContent = "Placements (distribution list + spawn rate weight):";
placementsLabel.style.margin = "0 0 0.4rem";
dom.selectedDetails.appendChild(placementsLabel);
renderPlacementsTable(item, entry, dom.selectedDetails);
const addRow = document.createElement("div");
addRow.className = "inline-row";
const listSelect = document.createElement("select");
const usedLists = new Set(Object.keys(entry.placements));
const availableLists = state.catalog.lists.filter((listName) => !usedLists.has(listName));
for (const listName of availableLists) {
const option = document.createElement("option");
option.value = listName;
option.textContent = listName;
listSelect.appendChild(option);
}
const customInput = document.createElement("input");
customInput.type = "text";
customInput.placeholder = "or custom list name";
const weightInput = document.createElement("input");
weightInput.type = "number";
weightInput.min = "0";
weightInput.step = "0.001";
weightInput.value = "1";
const addButton = document.createElement("button");
addButton.type = "button";
addButton.className = "small-btn";
addButton.textContent = "Add Placement";
addButton.addEventListener("click", () => {
const custom = customInput.value.trim();
const selectedList = custom || listSelect.value;
const weight = safeNumber(weightInput.value, 0);
if (!selectedList || weight <= 0) {
return;
}
entry.placements[selectedList] = Number(weight.toFixed(6));
if (!state.catalog.lists.includes(selectedList)) {
state.catalog.lists.push(selectedList);
state.catalog.lists.sort();
}
renderItemTable();
renderSelectedDetails();
});
addRow.appendChild(listSelect);
addRow.appendChild(customInput);
addRow.appendChild(weightInput);
addRow.appendChild(addButton);
dom.selectedDetails.appendChild(addRow);
const resetRow = document.createElement("div");
resetRow.className = "inline-row";
const restoreButton = document.createElement("button");
restoreButton.type = "button";
restoreButton.className = "small-btn";
restoreButton.textContent = "Restore Catalog Placements";
restoreButton.addEventListener("click", () => {
entry.enabled = item.defaultEnabled;
entry.placements = { ...item.defaultPlacements };
renderItemTable();
renderSelectedDetails();
});
const clearButton = document.createElement("button");
clearButton.type = "button";
clearButton.className = "small-btn remove";
clearButton.textContent = "Clear Placements";
clearButton.addEventListener("click", () => {
entry.placements = {};
renderItemTable();
renderSelectedDetails();
});
resetRow.appendChild(restoreButton);
resetRow.appendChild(clearButton);
dom.selectedDetails.appendChild(resetRow);
const meta = document.createElement("p");
meta.className = "meta";
meta.innerHTML = `
Sandbox weight controls: ${item.spawnControlKeys.length ? item.spawnControlKeys.join(", ") : "none"}<br>
Catalog list count: ${Object.keys(item.defaultPlacements).length}
`;
dom.selectedDetails.appendChild(meta);
}
function buildExportProfile() {
const entries = Object.keys(state.profileByItem)
.sort()
.map((itemType) => {
const entry = state.profileByItem[itemType];
const placements = Object.keys(entry.placements)
.sort()
.map((listName) => ({
list: listName,
weight: Number(entry.placements[listName]),
}));
return {
item: itemType,
category: entry.category,
enabled: entry.enabled,
placements,
};
});
return {
formatVersion: 1,
generatedAt: new Date().toISOString(),
sourceCatalog: {
generatedAt: state.catalog ? state.catalog.generatedAt : null,
source: state.catalog ? state.catalog.source : {},
},
entries,
};
}
function downloadTextFile(fileName, content) {
const blob = new Blob([content], { type: "application/json" });
const url = URL.createObjectURL(blob);
const anchor = document.createElement("a");
anchor.href = url;
anchor.download = fileName;
anchor.click();
URL.revokeObjectURL(url);
}
async function onCatalogFileSelected() {
const file = dom.catalogFile.files[0];
if (!file) {
return;
}
try {
const text = await readFileText(file);
const rawCatalog = JSON.parse(text);
state.catalog = normalizeCatalog(rawCatalog);
initializeProfileFromCatalog();
state.selectedItem = state.catalog.items.length ? state.catalog.items[0].item : null;
setStatus(
`Catalog loaded (${state.catalog.items.length} items, ${state.catalog.lists.length} lists).`
);
renderItemTable();
renderSelectedDetails();
} catch (error) {
setStatus(`Catalog load failed: ${error.message}`);
} finally {
dom.catalogFile.value = "";
}
}
async function onProfileFileSelected() {
if (!state.catalog) {
setStatus("Load a catalog first.");
dom.profileFile.value = "";
return;
}
const file = dom.profileFile.files[0];
if (!file) {
return;
}
try {
const text = await readFileText(file);
const raw = JSON.parse(text);
if (!Array.isArray(raw.entries)) {
throw new Error("Profile must contain an entries array.");
}
for (const row of raw.entries) {
const itemType = normalizeItemType(row.item);
if (!itemType || !state.profileByItem[itemType]) {
continue;
}
const entry = state.profileByItem[itemType];
entry.enabled = row.enabled !== false;
entry.placements = {};
if (Array.isArray(row.placements)) {
for (const placement of row.placements) {
const listName =
placement && typeof placement.list === "string" ? placement.list.trim() : "";
const weight = safeNumber(placement && placement.weight, 0);
if (!listName || weight <= 0) {
continue;
}
entry.placements[listName] = Number(weight.toFixed(6));
if (!state.catalog.lists.includes(listName)) {
state.catalog.lists.push(listName);
}
}
}
}
state.catalog.lists.sort();
setStatus("Profile loaded and applied to current catalog.");
renderItemTable();
renderSelectedDetails();
} catch (error) {
setStatus(`Profile load failed: ${error.message}`);
} finally {
dom.profileFile.value = "";
}
}
function onExportProfile() {
if (!state.catalog) {
setStatus("Load a catalog before exporting.");
return;
}
const payload = buildExportProfile();
downloadTextFile("of-spawn-profile.json", `${JSON.stringify(payload, null, 2)}\n`);
setStatus("Profile exported.");
}
function onResetSelected() {
if (!state.catalog || !state.selectedItem) {
return;
}
const item = state.catalog.items.find((it) => it.item === state.selectedItem);
const entry = getProfileEntry(state.selectedItem);
if (!item || !entry) {
return;
}
entry.enabled = item.defaultEnabled;
entry.placements = { ...item.defaultPlacements };
renderItemTable();
renderSelectedDetails();
setStatus(`Reset ${item.shortId} to catalog defaults.`);
}
dom.catalogFile.addEventListener("change", onCatalogFileSelected);
dom.profileFile.addEventListener("change", onProfileFileSelected);
dom.exportProfile.addEventListener("click", onExportProfile);
dom.searchInput.addEventListener("input", renderItemTable);
dom.categoryFilter.addEventListener("change", renderItemTable);
dom.spawnFilter.addEventListener("change", renderItemTable);
dom.resetSelected.addEventListener("click", onResetSelected);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,368 +0,0 @@
return {
WepFire = {
"Base.83Cheetah",
"Base.AKM",
"Base.AKSport",
"Base.Anaconda",
"Base.AR15",
"Base.AR180",
"Base.AssaultRifle",
"Base.AssaultRifle2",
"Base.Auto5",
"Base.Auto5_Alt",
"Base.BenelliM3",
"Base.BenelliM3_Alt",
"Base.Beretta682",
"Base.Beretta682_Alt",
"Base.Beretta92FS",
"Base.BHP",
"Base.Bobcat",
"Base.Brown3006BAR",
"Base.Brown308BAR",
"Base.BrownCitori",
"Base.BrownCitori_Alt",
"Base.Buckmark",
"Base.CalicoPistol",
"Base.CalicoRifle",
"Base.CAR15",
"Base.Colt9mm",
"Base.ColtArmy",
"Base.ColtDet",
"Base.Command1911",
"Base.CZ75B",
"Base.DE357",
"Base.DeltaElite",
"Base.Dissy",
"Base.DoubleBarrelShotgun",
"Base.DoubleBarrelShotgun_Alt",
"Base.DoubleBarrelShotgunSawnoff",
"Base.DoubleBarrelShotgunSawnoff_Alt",
"Base.FAL",
"Base.Glock17",
"Base.Glock17L",
"Base.Glock19",
"Base.Glock20",
"Base.Glock21",
"Base.Glock22",
"Base.Glock23",
"Base.Glock24",
"Base.Gov1911",
"Base.GP100",
"Base.GP100_Alt",
"Base.GP101",
"Base.GP101_Alt",
"Base.Hammerless",
"Base.HBAR",
"Base.HK91",
"Base.HuntingRifle",
"Base.Ithaca37",
"Base.Ithaca37_Alt",
"Base.Ithaca37Riot",
"Base.Ithaca37Riot_Alt",
"Base.J22",
"Base.Javelina",
"Base.L395K",
"Base.L395K_Alt",
"Base.Longslide",
"Base.M1903",
"Base.M1917",
"Base.M1A",
"Base.M1ABush",
"Base.M1Carbine",
"Base.M1Garand",
"Base.M24",
"Base.M249",
"Base.M3GreaseGun",
"Base.M590",
"Base.M590_Alt",
"Base.M60",
"Base.M635",
"Base.M723",
"Base.M727",
"Base.M733",
"Base.M870",
"Base.M870_Alt",
"Base.MAC10",
"Base.Marlin3363030",
"Base.Marlin33644",
"Base.Marlin39A",
"Base.Marlin45",
"Base.Marlin60",
"Base.Marlin9",
"Base.Mauser98K",
"Base.Mini14",
"Base.Mini30",
"Base.Moss500",
"Base.Moss500_Alt",
"Base.Moss590",
"Base.Moss590_Alt",
"Base.MP5",
"Base.Officer1911",
"Base.P226",
"Base.P228",
"Base.P380",
"Base.P7M13",
"Base.P7M8",
"Base.Pistol",
"Base.Pistol2",
"Base.Pistol3",
"Base.PPK",
"Base.Python",
"Base.Python_Alt",
"Base.R223Rem788",
"Base.R223RugM77",
"Base.R3006Rem700",
"Base.R3006RugM77",
"Base.R3030Rem788",
"Base.R308Rem700",
"Base.R308RugM77",
"Base.R44Rem788",
"Base.Raven25",
"Base.Rem1100",
"Base.Rem1100_Alt",
"Base.Rem1187P",
"Base.Rem1187P_Alt",
"Base.Rem223760",
"Base.Rem3006760",
"Base.Rem308760",
"Base.Rem870P",
"Base.Rem870P_Alt",
"Base.Revolver",
"Base.Revolver_Long",
"Base.Revolver_Short",
"Base.Rug1022",
"Base.Rugmark",
"Base.RugP89",
"Base.RugP90",
"Base.SavageFox",
"Base.SavageFox_Alt",
"Base.SecuritySix",
"Base.SecuritySix_Alt",
"Base.Shotgun",
"Base.Shotgun_Alt",
"Base.ShotgunSawnoff",
"Base.ShotgunSawnoff_Alt",
"Base.SKS",
"Base.SOAuto5",
"Base.SOAuto5_Alt",
"Base.SOBeretta682",
"Base.SOBeretta682_Alt",
"Base.SOBrownCitori",
"Base.SOBrownCitori_Alt",
"Base.SOIthaca37",
"Base.SOIthaca37_Alt",
"Base.SOL395K",
"Base.SOL395K_Alt",
"Base.SOM24",
"Base.SOMoss500",
"Base.SOMoss500_Alt",
"Base.SOR223Rem700",
"Base.SOR223Rem788",
"Base.SOR3006Rem700",
"Base.SOR3030Rem788",
"Base.SOR308Rem700",
"Base.SOR308Rem788",
"Base.SOR44Rem788",
"Base.SORem1100",
"Base.SORem1100_Alt",
"Base.SOSavageFox",
"Base.SOSavageFox_Alt",
"Base.SOW223WinM70",
"Base.SOW3006WinM70",
"Base.SOW308WinM70",
"Base.SOWin1200",
"Base.SOWin1200_Alt",
"Base.SOWin1400",
"Base.SOWin1400_Alt",
"Base.SOWin1912",
"Base.SOWin1912_Alt",
"Base.SOWin37",
"Base.SOWin37_Alt",
"Base.SPAS12",
"Base.SPAS12_Alt",
"Base.SW10",
"Base.SW17",
"Base.SW4006",
"Base.SW4506",
"Base.SW586",
"Base.SW586_Alt",
"Base.SW5906",
"Base.SW65",
"Base.SW65_Alt",
"Base.T56",
"Base.TEC9",
"Base.USP40",
"Base.USP9",
"Base.Uzi",
"Base.Valmet",
"Base.VarmintRifle",
"Base.W223WinM70",
"Base.W3006WinM70",
"Base.W308WinM70",
"Base.Win1200",
"Base.Win1200_Alt",
"Base.Win1200Def",
"Base.Win1200Def_Alt",
"Base.Win1400",
"Base.Win1400_Alt",
"Base.Win1912",
"Base.Win1912_Alt",
"Base.Win30067400",
"Base.Win3087400",
"Base.Win37",
"Base.Win37_Alt",
"Base.Win61",
"Base.Win69",
"Base.Win943030",
"Base.Win94357",
"Base.Win94357_Alt",
"Base.Win9445",
},
WepAmmoMag = {
"Base.100CalicoMag",
"Base.1022Mag",
"Base.10M14Mag",
"Base.15BHPMag",
"Base.17BHPMag",
"Base.1908Mag",
"Base.1911MagExtend",
"Base.1911MagExtendSS",
"Base.1911MagSS",
"Base.20M16AR180Mag",
"Base.20M16Mag",
"Base.20M9Mag",
"Base.20MP5Mag",
"Base.223Rem760Mag",
"Base.223RemMag",
"Base.25Rug1022Mag",
"Base.25UziColtSMGMag",
"Base.25UziMag",
"Base.3006BARMag",
"Base.3006clip",
"Base.3006Rem760Mag",
"Base.3006WinMag",
"Base.3030RemMag",
"Base.308BARMag",
"Base.308Clip",
"Base.308Rem760Mag",
"Base.308WinMag",
"Base.30M14Mag",
"Base.30M16AR180Mag",
"Base.30M1CarMag",
"Base.30Mini14Mag",
"Base.4006Mag",
"Base.40AKMag",
"Base.40AR180Mag",
"Base.40M16AR180Mag",
"Base.44Clip",
"Base.44RemMag",
"Base.4506Mag",
"Base.45Clip",
"Base.45Moonclip",
"Base.556Clip",
"Base.5906Mag",
"Base.83Mag",
"Base.9mmClip",
"Base.AK5Mag",
"Base.AKBakeMag",
"Base.AKDrumMag",
"Base.AKMag",
"Base.AR180Mag",
"Base.BetaCMag",
"Base.BHPMag",
"Base.BHPMagSS",
"Base.BobcatMag",
"Base.BuckMag",
"Base.CalicoMag",
"Base.ColtSMGMag",
"Base.CZ75BMag",
"Base.DE357Mag",
"Base.DeltaEliteMag",
"Base.DeltaEliteMagBlue",
"Base.DeltaEliteMagExtend",
"Base.DeltaEliteMagExtendBlue",
"Base.EblocClip",
"Base.FALMag",
"Base.G17ExtMag",
"Base.G17Mag",
"Base.G17StickMag",
"Base.G19ExtMag",
"Base.G19Mag",
"Base.G20Mag",
"Base.G21Mag",
"Base.G22Mag",
"Base.G23Mag",
"Base.HK91Mag",
"Base.HKS10A357",
"Base.HKS10A38",
"Base.HKS22K",
"Base.HKS29M44",
"Base.HKS36A357",
"Base.HKS36A38",
"Base.HKS586A357",
"Base.HKS586A38",
"Base.HKSDSA38",
"Base.HKSMK3A357",
"Base.HKSMK3A38",
"Base.HKSPYA357",
"Base.HKSPYA38",
"Base.J22Mag",
"Base.L395KMag",
"Base.L395KMagSlugs",
"Base.M14Clip",
"Base.M1CarMag",
"Base.M249Box",
"Base.M3GreaseMag",
"Base.M60Box",
"Base.MAC10Mag",
"Base.MACGreaseMag",
"Base.MarkMag",
"Base.Mauserclip",
"Base.Mini14Mag",
"Base.Mini30Mag",
"Base.MP5Mag",
"Base.OfficerMag",
"Base.P226Mag",
"Base.P228Mag",
"Base.P380Mag",
"Base.P7M13Mag",
"Base.P7M8Mag",
"Base.P89Mag",
"Base.P90Mag",
"Base.PPKMag",
"Base.R25Mag",
"Base.Size3CompII357",
"Base.Size3CompII38",
"Base.Size3CompIII357",
"Base.Size3CompIII38",
"Base.Size4CompII357",
"Base.Size4CompII38",
"Base.Size4CompIII357",
"Base.Size4CompIII38",
"Base.Size5CompII357",
"Base.Size5CompII38",
"Base.Size5CompIII357",
"Base.Size5CompIII38",
"Base.Size6CompII357",
"Base.Size6CompII38",
"Base.Size6CompIII357",
"Base.Size6CompIII38",
"Base.SKSclip",
"Base.SpeedStrip357",
"Base.SpeedStrip38",
"Base.SpeedStrip44",
"Base.TEC9Mag",
"Base.TherARMag",
"Base.TherMini14Mag",
"Base.USP40Mag",
"Base.USP9Mag",
"Base.UziColtSMGMag",
"Base.UziMag",
"Base.ValmetMag",
"Base.Win69AMag",
},
}

View File

@@ -1,149 +0,0 @@
local OFBCGuns93ModPackInjector = {
installed = false,
tickHookAdded = false,
}
local APPLY_MODS_MODULE = "BetterContainers/Categorize/Categories/_applyMods"
local GUNS93_PACK_PATH = "mods/guns93_items"
local BC_MOD_IDS = {
"EURY_CONTAINERS",
"REORDER_CONTAINERS",
"\\EURY_CONTAINERS",
"\\REORDER_CONTAINERS",
}
local GUNS93_MOD_IDS = {
"guns93",
"\\guns93",
}
local function isSortingToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.AddSorting ~= nil then
return vars.AddSorting == true
end
return true
end
local function getActivatedModsList()
if type(getActivatedMods) ~= "function" then
return nil
end
local mods = getActivatedMods()
if not mods or type(mods.contains) ~= "function" then
return nil
end
return mods
end
local function isBetterContainersActive()
local mods = getActivatedModsList()
if not mods then
return nil
end
for i = 1, #BC_MOD_IDS do
if mods:contains(BC_MOD_IDS[i]) then
return true
end
end
return false
end
local function isGuns93Active()
local mods = getActivatedModsList()
if not mods then
return false
end
for i = 1, #GUNS93_MOD_IDS do
if mods:contains(GUNS93_MOD_IDS[i]) then
return true
end
end
return false
end
local function installApplyModsWrapper()
if OFBCGuns93ModPackInjector.installed then
return true
end
if not isSortingToggleEnabled() then
OFBCGuns93ModPackInjector.installed = true
return true
end
local bcState = isBetterContainersActive()
if bcState == false then
OFBCGuns93ModPackInjector.installed = true
return true
end
if bcState == nil then
return false
end
if _G.OF_GUNS93_BC_APPLYMODS_WRAPPED then
OFBCGuns93ModPackInjector.installed = true
return true
end
local ok, applyMods = pcall(require, APPLY_MODS_MODULE)
if not ok or type(applyMods) ~= "function" then
return false
end
if type(package) ~= "table" or type(package.loaded) ~= "table" then
return false
end
local function wrappedApplyMods(loadCategoryFile, dlog)
applyMods(loadCategoryFile, dlog)
if not isGuns93Active() then
return
end
if type(loadCategoryFile) == "function" then
loadCategoryFile(GUNS93_PACK_PATH)
if dlog then
dlog("Loaded category pack guns93_items")
end
end
end
package.loaded[APPLY_MODS_MODULE] = wrappedApplyMods
_G.OF_GUNS93_BC_APPLYMODS_WRAPPED = true
OFBCGuns93ModPackInjector.installed = true
return true
end
local function tryInstallOnTick()
if installApplyModsWrapper() then
OFBCGuns93ModPackInjector.tickHookAdded = false
Events.OnTick.Remove(tryInstallOnTick)
end
end
local function ensureTickHook()
if OFBCGuns93ModPackInjector.tickHookAdded then
return
end
OFBCGuns93ModPackInjector.tickHookAdded = true
Events.OnTick.Add(tryInstallOnTick)
end
if not installApplyModsWrapper() then
ensureTickHook()
end
if Events.OnMainMenuEnter and type(Events.OnMainMenuEnter.Add) == "function" then
Events.OnMainMenuEnter.Add(installApplyModsWrapper)
end

View File

@@ -1,97 +0,0 @@
local OFGGSCasingDisablePatch = {
patched = false,
hasDebugStackInfo = type(debug) == "table" and type(debug.getinfo) == "function",
}
local BLOCKED_GGS_CASING_TYPES = {
["Base.pistol_casing"] = true,
["Base.revolver_casing"] = true,
["Base.rifle_casing"] = true,
["Base.shells_casing"] = true,
}
local function isGgsShellEmitterCall()
if not OFGGSCasingDisablePatch.hasDebugStackInfo then
return false
end
for stackLevel = 3, 10 do
local info = debug.getinfo(stackLevel, "S")
if not info then
break
end
local source = info.source
if type(source) == "string" and string.find(source, "GGS_ShellCasingEmitter.lua", 1, true) then
return true
end
end
return false
end
local function isPatchToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.HandleHotBrassCasingSpawnUseAmmoMaker ~= nil then
return vars.HandleHotBrassCasingSpawnUseAmmoMaker == true
end
-- Backward compatibility for existing worlds.
if vars and vars.HBVCEFAmmoMakerPatch ~= nil then
return vars.HBVCEFAmmoMakerPatch == true
end
return true
end
local function applyPatch()
if OFGGSCasingDisablePatch.patched then
return true
end
if not isPatchToggleEnabled() then
OFGGSCasingDisablePatch.patched = true
return true
end
if type(__classmetatables) ~= "table" then
return false
end
if not zombie or not zombie.iso or not zombie.iso.IsoGridSquare or not zombie.iso.IsoGridSquare.class then
return false
end
local squareMetatable = __classmetatables[zombie.iso.IsoGridSquare.class]
if not squareMetatable or type(squareMetatable.__index) ~= "table" then
return false
end
local originalAddWorldInventoryItem = squareMetatable.__index.AddWorldInventoryItem
if type(originalAddWorldInventoryItem) ~= "function" then
return false
end
squareMetatable.__index.AddWorldInventoryItem = function(square, itemType, ...)
if BLOCKED_GGS_CASING_TYPES[itemType] and
(not OFGGSCasingDisablePatch.hasDebugStackInfo or isGgsShellEmitterCall())
then
return nil
end
return originalAddWorldInventoryItem(square, itemType, ...)
end
OFGGSCasingDisablePatch.patched = true
return true
end
local function tryPatchOnTick()
if applyPatch() then
Events.OnTick.Remove(tryPatchOnTick)
end
end
if not applyPatch() then
Events.OnTick.Add(tryPatchOnTick)
end

View File

@@ -1,221 +0,0 @@
local OFHotBrassPatch = {
patched = false,
}
local AMMO_TYPE_ALIAS_BY_ITEM = {
["Base.9x39Bullets"] = "9x39",
["Base.Bullets22LR"] = "22LR",
["Base.Bullets50Magnum"] = "50AE",
["Base.762x54rBullets"] = "762x54R",
["Base.792x57Bullets"] = "792x57Maus",
-- Common spelling variants seen in third-party weapon scripts.
["Base.308Bulets"] = "308Win",
["Base.762x54rBulets"] = "762x54R",
}
local function isPatchToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.HandleHotBrassCasingSpawnUseAmmoMaker ~= nil then
return vars.HandleHotBrassCasingSpawnUseAmmoMaker == true
end
-- Backward compatibility for existing worlds.
if vars and vars.HBVCEFAmmoMakerPatch ~= nil then
return vars.HBVCEFAmmoMakerPatch == true
end
return true
end
local function isSessionEligible()
return isPatchToggleEnabled()
end
local function getAmmoMakerFiredFromAmmoDataKey(ammoDataKey)
if type(ammoDataKey) ~= "string" or ammoDataKey == "" then
return nil
end
if type(ammoMakerAmmoData) ~= "table" or type(ammoMakerAmmoParts) ~= "table" then
return nil
end
local ammoData = ammoMakerAmmoData[ammoDataKey]
if type(ammoData) ~= "table" then
return nil
end
local casingType = ammoData.casingType
if type(casingType) ~= "string" or casingType == "" then
return nil
end
local partData = ammoMakerAmmoParts[casingType]
if type(partData) ~= "table" then
return nil
end
local firedType = partData.partFired or partData.partOld
if type(firedType) ~= "string" or firedType == "" then
return nil
end
return firedType
end
local function getAmmoMakerFiredFromItemKey(ammoType)
if type(ammoType) ~= "string" or ammoType == "" then
return nil
end
if type(ammoMakerAmmoTypes) ~= "table" then
return nil
end
local typeData = ammoMakerAmmoTypes[ammoType]
if type(typeData) ~= "table" or type(typeData.ammoTypes) ~= "table" or #typeData.ammoTypes == 0 then
return nil
end
local activeIndex = 1
if type(typeData.modIds) == "table" and type(ammoMakerCompatibleMods) == "table" then
for i = 1, #typeData.modIds do
local modId = typeData.modIds[i]
if ammoMakerCompatibleMods[modId] == true then
activeIndex = i
end
end
end
if activeIndex < 1 or activeIndex > #typeData.ammoTypes then
activeIndex = 1
end
local activeAmmoKey = typeData.ammoTypes[activeIndex]
local activeFiredType = getAmmoMakerFiredFromAmmoDataKey(activeAmmoKey)
if activeFiredType then
return activeFiredType
end
for i = 1, #typeData.ammoTypes do
local fallbackFiredType = getAmmoMakerFiredFromAmmoDataKey(typeData.ammoTypes[i])
if fallbackFiredType then
return fallbackFiredType
end
end
return nil
end
local function getAmmoMakerFiredCasing(ammoType)
if type(ammoType) ~= "string" or ammoType == "" then
return nil
end
local directFiredType = getAmmoMakerFiredFromItemKey(ammoType)
if directFiredType then
return directFiredType
end
local aliasAmmoDataKey = AMMO_TYPE_ALIAS_BY_ITEM[ammoType]
if aliasAmmoDataKey then
local aliasFiredType = getAmmoMakerFiredFromAmmoDataKey(aliasAmmoDataKey)
if aliasFiredType then
return aliasFiredType
end
end
local lowerAmmoType = string.lower(ammoType)
for aliasItemType, ammoDataKey in pairs(AMMO_TYPE_ALIAS_BY_ITEM) do
if string.lower(aliasItemType) == lowerAmmoType then
local aliasFiredType = getAmmoMakerFiredFromAmmoDataKey(ammoDataKey)
if aliasFiredType then
return aliasFiredType
end
end
end
if type(ammoMakerAmmoTypes) == "table" then
for itemType, typeData in pairs(ammoMakerAmmoTypes) do
if type(itemType) == "string" and string.lower(itemType) == lowerAmmoType then
if type(typeData) == "table" and type(typeData.ammoTypes) == "table" then
for i = 1, #typeData.ammoTypes do
local fallbackFiredType = getAmmoMakerFiredFromAmmoDataKey(typeData.ammoTypes[i])
if fallbackFiredType then
return fallbackFiredType
end
end
end
end
end
end
return nil
end
local function applyPatch()
if OFHotBrassPatch.patched then
return true
end
if not isSessionEligible() then
return false
end
if type(SpentCasingPhysics) ~= "table" then
return false
end
if type(SpentCasingPhysics.getItemToEject) ~= "function" then
return false
end
if type(SpentCasingPhysics.doSpawnCasing) ~= "function" then
return false
end
local originalGetItemToEject = SpentCasingPhysics.getItemToEject
local originalDoSpawnCasing = SpentCasingPhysics.doSpawnCasing
SpentCasingPhysics.getItemToEject = function(ammoType)
local mappedType = getAmmoMakerFiredCasing(ammoType)
if mappedType then
return mappedType
end
return originalGetItemToEject(ammoType)
end
SpentCasingPhysics.doSpawnCasing = function(player, weapon, params, racking, optionalItem)
if not optionalItem and weapon and weapon.getAmmoType then
local ammoTypeObj = weapon:getAmmoType()
local ammoType = ammoTypeObj and ammoTypeObj.getItemKey and ammoTypeObj:getItemKey() or ammoTypeObj
if ammoType then
local mappedType = getAmmoMakerFiredCasing(tostring(ammoType))
if mappedType then
optionalItem = mappedType
if racking then
-- Force rack ejects to stay as empties for this patch.
racking = false
end
end
end
end
return originalDoSpawnCasing(player, weapon, params, racking, optionalItem)
end
OFHotBrassPatch.patched = true
return true
end
local function tryPatchOnTick()
if OFHotBrassPatch.patched then
Events.OnTick.Remove(tryPatchOnTick)
return
end
applyPatch()
end
Events.OnTick.Add(tryPatchOnTick)

View File

@@ -1,75 +0,0 @@
local BLOCKED_AMMOMAKER_COMMANDS = {
returnCasingsOnAttack = true,
incrementSpendtRoundCount = true,
returnCasingsOnReload = true,
}
local function isPatchToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.HandleHotBrassCasingSpawnUseAmmoMaker ~= nil then
return vars.HandleHotBrassCasingSpawnUseAmmoMaker == true
end
-- Backward compatibility for existing worlds.
if vars and vars.HBVCEFAmmoMakerPatch ~= nil then
return vars.HBVCEFAmmoMakerPatch == true
end
return true
end
local function shouldBlockAmmoMakerCasingCommands()
return isPatchToggleEnabled()
end
local function getModuleAndCommand(...)
local argc = select("#", ...)
if argc < 2 then
return nil, nil
end
local firstArg = select(1, ...)
if type(firstArg) == "string" then
return firstArg, select(2, ...)
end
if argc >= 3 then
return select(2, ...), select(3, ...)
end
return nil, nil
end
local function installCommandGate()
if _G.OpinionatedFirearms_AmmoMakerCommandGateInstalled then
return true
end
if type(sendClientCommand) ~= "function" then
return false
end
_G.OpinionatedFirearms_AmmoMakerCommandGateInstalled = true
_G.OpinionatedFirearms_OriginalSendClientCommand = sendClientCommand
sendClientCommand = function(...)
local module, command = getModuleAndCommand(...)
if module == "ammomaker" and BLOCKED_AMMOMAKER_COMMANDS[command] and shouldBlockAmmoMakerCasingCommands() then
return
end
return _G.OpinionatedFirearms_OriginalSendClientCommand(...)
end
return true
end
local function ensureGateOnTick()
if installCommandGate() then
Events.OnTick.Remove(ensureGateOnTick)
end
end
if not installCommandGate() then
Events.OnTick.Add(ensureGateOnTick)
end

View File

@@ -1,141 +0,0 @@
local OFAmmoMakerDisplayCategoryPatch = {
patched = false,
tickHookAdded = false,
}
local SPENT_CASINGS_CATEGORY = "OFSpentCasings"
local AMMO_PART_CATEGORY = "OFAmmoPart"
local function isSortingToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.AddSorting ~= nil then
return vars.AddSorting == true
end
return true
end
local function addAmmoMakerType(typeSet, fullType)
if type(fullType) ~= "string" or fullType == "" then
return
end
if not string.find(fullType, "^ammomaker%.") then
return
end
typeSet[fullType] = true
end
local function setDisplayCategory(scriptManager, fullType, category)
local scriptItem = scriptManager:FindItem(fullType)
if not scriptItem then
return false
end
if type(scriptItem.DoParam) == "function" then
scriptItem:DoParam("DisplayCategory = " .. category)
return true
end
if type(scriptItem.setDisplayCategory) == "function" then
scriptItem:setDisplayCategory(category)
return true
end
return false
end
local function collectAmmoMakerTypes()
if type(ammoMakerAmmoParts) ~= "table" then
return nil, nil
end
local spentCasingTypes = {}
local ammoPartTypes = {}
for _, partData in pairs(ammoMakerAmmoParts) do
if type(partData) == "table" then
local partClass = partData.partClass
if partClass == "Casing" or partClass == "Hull" then
addAmmoMakerType(spentCasingTypes, partData.partOld)
addAmmoMakerType(spentCasingTypes, partData.partFired)
addAmmoMakerType(ammoPartTypes, partData.boxType)
addAmmoMakerType(ammoPartTypes, partData.bagType)
end
end
end
return spentCasingTypes, ammoPartTypes
end
local function applyCategory(scriptManager, itemTypes, category)
local patchedAny = false
for fullType in pairs(itemTypes) do
if setDisplayCategory(scriptManager, fullType, category) then
patchedAny = true
end
end
return patchedAny
end
local function applyPatch()
if OFAmmoMakerDisplayCategoryPatch.patched then
return true
end
if not isSortingToggleEnabled() then
OFAmmoMakerDisplayCategoryPatch.patched = true
return true
end
local scriptManager = ScriptManager and ScriptManager.instance
if not scriptManager or type(scriptManager.FindItem) ~= "function" then
return false
end
local spentCasingTypes, ammoPartTypes = collectAmmoMakerTypes()
if not spentCasingTypes or not ammoPartTypes then
return false
end
local patchedSpentCasings = applyCategory(scriptManager, spentCasingTypes, SPENT_CASINGS_CATEGORY)
local patchedAmmoParts = applyCategory(scriptManager, ammoPartTypes, AMMO_PART_CATEGORY)
if not patchedSpentCasings and not patchedAmmoParts then
return false
end
OFAmmoMakerDisplayCategoryPatch.patched = true
return true
end
local function tryPatchOnTick()
if applyPatch() then
OFAmmoMakerDisplayCategoryPatch.tickHookAdded = false
Events.OnTick.Remove(tryPatchOnTick)
end
end
local function ensureTickHook()
if OFAmmoMakerDisplayCategoryPatch.tickHookAdded then
return
end
OFAmmoMakerDisplayCategoryPatch.tickHookAdded = true
Events.OnTick.Add(tryPatchOnTick)
end
if not applyPatch() then
ensureTickHook()
end
if Events.OnMainMenuEnter and type(Events.OnMainMenuEnter.Add) == "function" then
Events.OnMainMenuEnter.Add(function()
OFAmmoMakerDisplayCategoryPatch.patched = false
if not applyPatch() then
ensureTickHook()
end
end)
end

View File

@@ -1,920 +0,0 @@
local OFGuns93DisplayCategoryPatch = {
patched = false,
tickHookAdded = false,
repatchQueued = false,
}
local BC_FIREARM_CATEGORY = "WepFire"
local BC_MAGAZINE_CATEGORY = "WepAmmoMag"
local GUNS93_SENTINEL_FIREARM = "Base.83Cheetah"
local GUNS93_SENTINEL_MAGAZINE = "Base.83Mag"
local GAEL_GUNSTORE_SENTINEL_FIREARM = "Base.A91"
local GAEL_GUNSTORE_SENTINEL_MAGAZINE = "Base.545x39Clip30"
local function resolveWeaponCategories()
return BC_FIREARM_CATEGORY, BC_MAGAZINE_CATEGORY
end
local function isSortingToggleEnabled()
local vars = SandboxVars and SandboxVars.OpinionatedFirearms
if vars and vars.AddSorting ~= nil then
return vars.AddSorting == true
end
return true
end
local GUNS93_FIREARMS = {
["Base.83Cheetah"] = true,
["Base.AKM"] = true,
["Base.AKSport"] = true,
["Base.Anaconda"] = true,
["Base.AR15"] = true,
["Base.AR180"] = true,
["Base.AssaultRifle"] = true,
["Base.AssaultRifle2"] = true,
["Base.Auto5"] = true,
["Base.Auto5_Alt"] = true,
["Base.BenelliM3"] = true,
["Base.BenelliM3_Alt"] = true,
["Base.Beretta682"] = true,
["Base.Beretta682_Alt"] = true,
["Base.Beretta92FS"] = true,
["Base.BHP"] = true,
["Base.Bobcat"] = true,
["Base.Brown3006BAR"] = true,
["Base.Brown308BAR"] = true,
["Base.BrownCitori"] = true,
["Base.BrownCitori_Alt"] = true,
["Base.Buckmark"] = true,
["Base.CalicoPistol"] = true,
["Base.CalicoRifle"] = true,
["Base.CAR15"] = true,
["Base.Colt9mm"] = true,
["Base.ColtArmy"] = true,
["Base.ColtDet"] = true,
["Base.Command1911"] = true,
["Base.CZ75B"] = true,
["Base.DE357"] = true,
["Base.DeltaElite"] = true,
["Base.Dissy"] = true,
["Base.DoubleBarrelShotgun"] = true,
["Base.DoubleBarrelShotgun_Alt"] = true,
["Base.DoubleBarrelShotgunSawnoff"] = true,
["Base.DoubleBarrelShotgunSawnoff_Alt"] = true,
["Base.FAL"] = true,
["Base.Glock17"] = true,
["Base.Glock17L"] = true,
["Base.Glock19"] = true,
["Base.Glock20"] = true,
["Base.Glock21"] = true,
["Base.Glock22"] = true,
["Base.Glock23"] = true,
["Base.Glock24"] = true,
["Base.Gov1911"] = true,
["Base.GP100"] = true,
["Base.GP100_Alt"] = true,
["Base.GP101"] = true,
["Base.GP101_Alt"] = true,
["Base.Hammerless"] = true,
["Base.HBAR"] = true,
["Base.HK91"] = true,
["Base.HuntingRifle"] = true,
["Base.Ithaca37"] = true,
["Base.Ithaca37_Alt"] = true,
["Base.Ithaca37Riot"] = true,
["Base.Ithaca37Riot_Alt"] = true,
["Base.J22"] = true,
["Base.Javelina"] = true,
["Base.L395K"] = true,
["Base.L395K_Alt"] = true,
["Base.Longslide"] = true,
["Base.M1903"] = true,
["Base.M1917"] = true,
["Base.M1A"] = true,
["Base.M1ABush"] = true,
["Base.M1Carbine"] = true,
["Base.M1Garand"] = true,
["Base.M24"] = true,
["Base.M249"] = true,
["Base.M3GreaseGun"] = true,
["Base.M590"] = true,
["Base.M590_Alt"] = true,
["Base.M60"] = true,
["Base.M635"] = true,
["Base.M723"] = true,
["Base.M727"] = true,
["Base.M733"] = true,
["Base.M870"] = true,
["Base.M870_Alt"] = true,
["Base.MAC10"] = true,
["Base.Marlin3363030"] = true,
["Base.Marlin33644"] = true,
["Base.Marlin39A"] = true,
["Base.Marlin45"] = true,
["Base.Marlin60"] = true,
["Base.Marlin9"] = true,
["Base.Mauser98K"] = true,
["Base.Mini14"] = true,
["Base.Mini30"] = true,
["Base.Moss500"] = true,
["Base.Moss500_Alt"] = true,
["Base.Moss590"] = true,
["Base.Moss590_Alt"] = true,
["Base.MP5"] = true,
["Base.Officer1911"] = true,
["Base.P226"] = true,
["Base.P228"] = true,
["Base.P380"] = true,
["Base.P7M13"] = true,
["Base.P7M8"] = true,
["Base.Pistol"] = true,
["Base.Pistol2"] = true,
["Base.Pistol3"] = true,
["Base.PPK"] = true,
["Base.Python"] = true,
["Base.Python_Alt"] = true,
["Base.R223Rem788"] = true,
["Base.R223RugM77"] = true,
["Base.R3006Rem700"] = true,
["Base.R3006RugM77"] = true,
["Base.R3030Rem788"] = true,
["Base.R308Rem700"] = true,
["Base.R308RugM77"] = true,
["Base.R44Rem788"] = true,
["Base.Raven25"] = true,
["Base.Rem1100"] = true,
["Base.Rem1100_Alt"] = true,
["Base.Rem1187P"] = true,
["Base.Rem1187P_Alt"] = true,
["Base.Rem223760"] = true,
["Base.Rem3006760"] = true,
["Base.Rem308760"] = true,
["Base.Rem870P"] = true,
["Base.Rem870P_Alt"] = true,
["Base.Revolver"] = true,
["Base.Revolver_Long"] = true,
["Base.Revolver_Short"] = true,
["Base.Rug1022"] = true,
["Base.Rugmark"] = true,
["Base.RugP89"] = true,
["Base.RugP90"] = true,
["Base.SavageFox"] = true,
["Base.SavageFox_Alt"] = true,
["Base.SecuritySix"] = true,
["Base.SecuritySix_Alt"] = true,
["Base.Shotgun"] = true,
["Base.Shotgun_Alt"] = true,
["Base.ShotgunSawnoff"] = true,
["Base.ShotgunSawnoff_Alt"] = true,
["Base.SKS"] = true,
["Base.SOAuto5"] = true,
["Base.SOAuto5_Alt"] = true,
["Base.SOBeretta682"] = true,
["Base.SOBeretta682_Alt"] = true,
["Base.SOBrownCitori"] = true,
["Base.SOBrownCitori_Alt"] = true,
["Base.SOIthaca37"] = true,
["Base.SOIthaca37_Alt"] = true,
["Base.SOL395K"] = true,
["Base.SOL395K_Alt"] = true,
["Base.SOM24"] = true,
["Base.SOMoss500"] = true,
["Base.SOMoss500_Alt"] = true,
["Base.SOR223Rem700"] = true,
["Base.SOR223Rem788"] = true,
["Base.SOR3006Rem700"] = true,
["Base.SOR3030Rem788"] = true,
["Base.SOR308Rem700"] = true,
["Base.SOR308Rem788"] = true,
["Base.SOR44Rem788"] = true,
["Base.SORem1100"] = true,
["Base.SORem1100_Alt"] = true,
["Base.SOSavageFox"] = true,
["Base.SOSavageFox_Alt"] = true,
["Base.SOW223WinM70"] = true,
["Base.SOW3006WinM70"] = true,
["Base.SOW308WinM70"] = true,
["Base.SOWin1200"] = true,
["Base.SOWin1200_Alt"] = true,
["Base.SOWin1400"] = true,
["Base.SOWin1400_Alt"] = true,
["Base.SOWin1912"] = true,
["Base.SOWin1912_Alt"] = true,
["Base.SOWin37"] = true,
["Base.SOWin37_Alt"] = true,
["Base.SPAS12"] = true,
["Base.SPAS12_Alt"] = true,
["Base.SW10"] = true,
["Base.SW17"] = true,
["Base.SW4006"] = true,
["Base.SW4506"] = true,
["Base.SW586"] = true,
["Base.SW586_Alt"] = true,
["Base.SW5906"] = true,
["Base.SW65"] = true,
["Base.SW65_Alt"] = true,
["Base.T56"] = true,
["Base.TEC9"] = true,
["Base.USP40"] = true,
["Base.USP9"] = true,
["Base.Uzi"] = true,
["Base.Valmet"] = true,
["Base.VarmintRifle"] = true,
["Base.W223WinM70"] = true,
["Base.W3006WinM70"] = true,
["Base.W308WinM70"] = true,
["Base.Win1200"] = true,
["Base.Win1200_Alt"] = true,
["Base.Win1200Def"] = true,
["Base.Win1200Def_Alt"] = true,
["Base.Win1400"] = true,
["Base.Win1400_Alt"] = true,
["Base.Win1912"] = true,
["Base.Win1912_Alt"] = true,
["Base.Win30067400"] = true,
["Base.Win3087400"] = true,
["Base.Win37"] = true,
["Base.Win37_Alt"] = true,
["Base.Win61"] = true,
["Base.Win69"] = true,
["Base.Win943030"] = true,
["Base.Win94357"] = true,
["Base.Win94357_Alt"] = true,
["Base.Win9445"] = true,
}
local GUNS93_MAGAZINES = {
["Base.100CalicoMag"] = true,
["Base.1022Mag"] = true,
["Base.10M14Mag"] = true,
["Base.15BHPMag"] = true,
["Base.17BHPMag"] = true,
["Base.1908Mag"] = true,
["Base.1911MagExtend"] = true,
["Base.1911MagExtendSS"] = true,
["Base.1911MagSS"] = true,
["Base.20M16AR180Mag"] = true,
["Base.20M16Mag"] = true,
["Base.20M9Mag"] = true,
["Base.20MP5Mag"] = true,
["Base.223Rem760Mag"] = true,
["Base.223RemMag"] = true,
["Base.25Rug1022Mag"] = true,
["Base.25UziColtSMGMag"] = true,
["Base.25UziMag"] = true,
["Base.3006BARMag"] = true,
["Base.3006clip"] = true,
["Base.3006Rem760Mag"] = true,
["Base.3006WinMag"] = true,
["Base.3030RemMag"] = true,
["Base.308BARMag"] = true,
["Base.308Clip"] = true,
["Base.308Rem760Mag"] = true,
["Base.308WinMag"] = true,
["Base.30M14Mag"] = true,
["Base.30M16AR180Mag"] = true,
["Base.30M1CarMag"] = true,
["Base.30Mini14Mag"] = true,
["Base.4006Mag"] = true,
["Base.40AKMag"] = true,
["Base.40AR180Mag"] = true,
["Base.40M16AR180Mag"] = true,
["Base.44Clip"] = true,
["Base.44RemMag"] = true,
["Base.4506Mag"] = true,
["Base.45Clip"] = true,
["Base.45Moonclip"] = true,
["Base.556Clip"] = true,
["Base.5906Mag"] = true,
["Base.83Mag"] = true,
["Base.9mmClip"] = true,
["Base.AK5Mag"] = true,
["Base.AKBakeMag"] = true,
["Base.AKDrumMag"] = true,
["Base.AKMag"] = true,
["Base.AR180Mag"] = true,
["Base.BetaCMag"] = true,
["Base.BHPMag"] = true,
["Base.BHPMagSS"] = true,
["Base.BobcatMag"] = true,
["Base.BuckMag"] = true,
["Base.CalicoMag"] = true,
["Base.ColtSMGMag"] = true,
["Base.CZ75BMag"] = true,
["Base.DE357Mag"] = true,
["Base.DeltaEliteMag"] = true,
["Base.DeltaEliteMagBlue"] = true,
["Base.DeltaEliteMagExtend"] = true,
["Base.DeltaEliteMagExtendBlue"] = true,
["Base.EblocClip"] = true,
["Base.FALMag"] = true,
["Base.G17ExtMag"] = true,
["Base.G17Mag"] = true,
["Base.G17StickMag"] = true,
["Base.G19ExtMag"] = true,
["Base.G19Mag"] = true,
["Base.G20Mag"] = true,
["Base.G21Mag"] = true,
["Base.G22Mag"] = true,
["Base.G23Mag"] = true,
["Base.HK91Mag"] = true,
["Base.HKS10A357"] = true,
["Base.HKS10A38"] = true,
["Base.HKS22K"] = true,
["Base.HKS29M44"] = true,
["Base.HKS36A357"] = true,
["Base.HKS36A38"] = true,
["Base.HKS586A357"] = true,
["Base.HKS586A38"] = true,
["Base.HKSDSA38"] = true,
["Base.HKSMK3A357"] = true,
["Base.HKSMK3A38"] = true,
["Base.HKSPYA357"] = true,
["Base.HKSPYA38"] = true,
["Base.J22Mag"] = true,
["Base.L395KMag"] = true,
["Base.L395KMagSlugs"] = true,
["Base.M14Clip"] = true,
["Base.M1CarMag"] = true,
["Base.M249Box"] = true,
["Base.M3GreaseMag"] = true,
["Base.M60Box"] = true,
["Base.MAC10Mag"] = true,
["Base.MACGreaseMag"] = true,
["Base.MarkMag"] = true,
["Base.Mauserclip"] = true,
["Base.Mini14Mag"] = true,
["Base.Mini30Mag"] = true,
["Base.MP5Mag"] = true,
["Base.OfficerMag"] = true,
["Base.P226Mag"] = true,
["Base.P228Mag"] = true,
["Base.P380Mag"] = true,
["Base.P7M13Mag"] = true,
["Base.P7M8Mag"] = true,
["Base.P89Mag"] = true,
["Base.P90Mag"] = true,
["Base.PPKMag"] = true,
["Base.R25Mag"] = true,
["Base.Size3CompII357"] = true,
["Base.Size3CompII38"] = true,
["Base.Size3CompIII357"] = true,
["Base.Size3CompIII38"] = true,
["Base.Size4CompII357"] = true,
["Base.Size4CompII38"] = true,
["Base.Size4CompIII357"] = true,
["Base.Size4CompIII38"] = true,
["Base.Size5CompII357"] = true,
["Base.Size5CompII38"] = true,
["Base.Size5CompIII357"] = true,
["Base.Size5CompIII38"] = true,
["Base.Size6CompII357"] = true,
["Base.Size6CompII38"] = true,
["Base.Size6CompIII357"] = true,
["Base.Size6CompIII38"] = true,
["Base.SKSclip"] = true,
["Base.SpeedStrip357"] = true,
["Base.SpeedStrip38"] = true,
["Base.SpeedStrip44"] = true,
["Base.TEC9Mag"] = true,
["Base.TherARMag"] = true,
["Base.TherMini14Mag"] = true,
["Base.USP40Mag"] = true,
["Base.USP9Mag"] = true,
["Base.UziColtSMGMag"] = true,
["Base.UziMag"] = true,
["Base.ValmetMag"] = true,
["Base.Win69AMag"] = true,
}
local GAEL_GUNSTORE_FIREARMS = {
["Base.A2000"] = true,
["Base.A91"] = true,
["Base.AA12"] = true,
["Base.ACE21"] = true,
["Base.ACE23"] = true,
["Base.ACE52_CQB"] = true,
["Base.ACE53"] = true,
["Base.ACR"] = true,
["Base.ADS"] = true,
["Base.AEK"] = true,
["Base.AEK919"] = true,
["Base.AK_minidrako"] = true,
["Base.AK101"] = true,
["Base.AK103"] = true,
["Base.AK12"] = true,
["Base.AK19"] = true,
["Base.AK47"] = true,
["Base.AK5C"] = true,
["Base.AK74"] = true,
["Base.AK74u"] = true,
["Base.AK74u_long"] = true,
["Base.AK9"] = true,
["Base.AKM"] = true,
["Base.AKU12"] = true,
["Base.AMD65"] = true,
["Base.AN94"] = true,
["Base.Anaconda"] = true,
["Base.APC9K"] = true,
["Base.AR10"] = true,
["Base.AR15"] = true,
["Base.AR160"] = true,
["Base.AR6951"] = true,
["Base.ASH_12"] = true,
["Base.AssaultRifle"] = true,
["Base.AssaultRifle2"] = true,
["Base.AUG_9mm"] = true,
["Base.AUG_A1"] = true,
["Base.AUG_A2"] = true,
["Base.Automag357"] = true,
["Base.Automag44"] = true,
["Base.Automag50AE"] = true,
["Base.AWS"] = true,
["Base.BAR"] = true,
["Base.Becker_Shotgun"] = true,
["Base.Becker_Shotgun_Short"] = true,
["Base.BenelliM4"] = true,
["Base.Beretta_A400"] = true,
["Base.Beretta_A400_Short"] = true,
["Base.Beretta_PX4"] = true,
["Base.Browning_Auto"] = true,
["Base.Browning_Auto_Short"] = true,
["Base.BrowningHP"] = true,
["Base.Carcano"] = true,
["Base.CBJ"] = true,
["Base.CETME"] = true,
["Base.CircuitJudgeRifle"] = true,
["Base.Colt9mm"] = true,
["Base.ColtNavy1851"] = true,
["Base.ColtNavyExorcist"] = true,
["Base.ColtPeacemaker1873"] = true,
["Base.Coonan357"] = true,
["Base.CS5"] = true,
["Base.CZ75"] = true,
["Base.CZ805"] = true,
["Base.CZScorpion"] = true,
["Base.DB_Condor"] = true,
["Base.DB_Condor_sawn"] = true,
["Base.DDM4"] = true,
["Base.Deagle357_gold"] = true,
["Base.Deagle50AE"] = true,
["Base.DeagleCar14"] = true,
["Base.DeLisle"] = true,
["Base.DoubleBarrelShotgun"] = true,
["Base.DoubleBarrelShotgunSawnoff"] = true,
["Base.DVB15"] = true,
["Base.ENARM_Pentagun"] = true,
["Base.Enfield"] = true,
["Base.FAL"] = true,
["Base.FAL_CQB"] = true,
["Base.FAMAS"] = true,
["Base.FiveSeven"] = true,
["Base.FN2000"] = true,
["Base.FN502_22LR"] = true,
["Base.FNX45"] = true,
["Base.G17"] = true,
["Base.G18"] = true,
["Base.G2"] = true,
["Base.G27"] = true,
["Base.G36C"] = true,
["Base.G3A3"] = true,
["Base.G43"] = true,
["Base.Galil"] = true,
["Base.Glock_tactical"] = true,
["Base.Glock23"] = true,
["Base.Glock43"] = true,
["Base.GOL"] = true,
["Base.Grizzly50AE"] = true,
["Base.Groza"] = true,
["Base.GSH18"] = true,
["Base.HK_121"] = true,
["Base.HK416"] = true,
["Base.HKG28"] = true,
["Base.HKMK23"] = true,
["Base.HoneyBadger"] = true,
["Base.HuntingRifle"] = true,
["Base.IA2"] = true,
["Base.IA2_308"] = true,
["Base.Jackhammer"] = true,
["Base.Jericho941"] = true,
["Base.JNG90"] = true,
["Base.K2"] = true,
["Base.K7"] = true,
["Base.KAC_PDW"] = true,
["Base.Kark98"] = true,
["Base.Kimber1911"] = true,
["Base.Kriss9mm"] = true,
["Base.KrissVector45"] = true,
["Base.KS23"] = true,
["Base.KSG"] = true,
["Base.L115A"] = true,
["Base.L85"] = true,
["Base.L86"] = true,
["Base.L96"] = true,
["Base.LanchesterMK1"] = true,
["Base.Lewis"] = true,
["Base.LR300"] = true,
["Base.LSAT"] = true,
["Base.LVOA"] = true,
["Base.M1"] = true,
["Base.M110"] = true,
["Base.M16A2"] = true,
["Base.M1887"] = true,
["Base.M1887_Short"] = true,
["Base.M1A1"] = true,
["Base.M200"] = true,
["Base.M21"] = true,
["Base.M24"] = true,
["Base.M240B"] = true,
["Base.M249"] = true,
["Base.M39"] = true,
["Base.M4"] = true,
["Base.M40"] = true,
["Base.M60E4"] = true,
["Base.M620"] = true,
["Base.M82A3"] = true,
["Base.M9_Samurai"] = true,
["Base.M93R"] = true,
["Base.M98B"] = true,
["Base.MAB38A"] = true,
["Base.MAC10"] = true,
["Base.MAS36"] = true,
["Base.MAT49"] = true,
["Base.MatebaGrifone"] = true,
["Base.MG131"] = true,
["Base.MG4"] = true,
["Base.MG42"] = true,
["Base.MG710"] = true,
["Base.Micro_UZI"] = true,
["Base.Mini_14"] = true,
["Base.Minimi"] = true,
["Base.MK18"] = true,
["Base.Mosin"] = true,
["Base.Mossber500"] = true,
["Base.Mossber590"] = true,
["Base.MP_R8"] = true,
["Base.MP18"] = true,
["Base.MP1911"] = true,
["Base.MP40"] = true,
["Base.MP5"] = true,
["Base.MP5K"] = true,
["Base.MP5SD"] = true,
["Base.MP7"] = true,
["Base.MP9"] = true,
["Base.MPX"] = true,
["Base.MSST"] = true,
["Base.MTAR"] = true,
["Base.MTS_255"] = true,
["Base.MTS_255_Short"] = true,
["Base.MX4"] = true,
["Base.Nagant_M1895"] = true,
["Base.Negev"] = true,
["Base.OTS_33"] = true,
["Base.P220"] = true,
["Base.P220_Elite"] = true,
["Base.P228"] = true,
["Base.P38"] = true,
["Base.P90"] = true,
["Base.P99"] = true,
["Base.P99_Kilin"] = true,
["Base.PB6P9"] = true,
["Base.Pistol"] = true,
["Base.pistol_shotgun"] = true,
["Base.Pistol2"] = true,
["Base.Pistol3"] = true,
["Base.PKP"] = true,
["Base.PP_Bizon"] = true,
["Base.PP2000"] = true,
["Base.PP93"] = true,
["Base.PPSH41"] = true,
["Base.Python357"] = true,
["Base.QBA"] = true,
["Base.QBB95"] = true,
["Base.QBS09"] = true,
["Base.QBS09_Short"] = true,
["Base.QBZ951"] = true,
["Base.R5"] = true,
["Base.Remington1100"] = true,
["Base.Remington1100_Short"] = true,
["Base.Remington121"] = true,
["Base.Remington870"] = true,
["Base.Remington870_Short"] = true,
["Base.Revolver"] = true,
["Base.Revolver_long"] = true,
["Base.Revolver_short"] = true,
["Base.Revolver38"] = true,
["Base.Revolver666"] = true,
["Base.Rhino20DS"] = true,
["Base.RMB93"] = true,
["Base.RPD"] = true,
["Base.RPK"] = true,
["Base.RPK12"] = true,
["Base.RPK16"] = true,
["Base.RSH12"] = true,
["Base.Ruger10_22"] = true,
["Base.Ruger357"] = true,
["Base.RugerLC"] = true,
["Base.SA58"] = true,
["Base.Saiga12"] = true,
["Base.Saiga9mm"] = true,
["Base.Samurai_aw"] = true,
["Base.Samurai_kendo"] = true,
["Base.SAR21"] = true,
["Base.ScarH"] = true,
["Base.ScarL"] = true,
["Base.Schofield1875"] = true,
["Base.Scout_elite"] = true,
["Base.ScrapRevolver"] = true,
["Base.Shorty"] = true,
["Base.Shotgun"] = true,
["Base.ShotgunSawnoff"] = true,
["Base.SIG_553"] = true,
["Base.SIG516"] = true,
["Base.Silenced_Sten"] = true,
["Base.Sjorgen"] = true,
["Base.Sjorgen_Short"] = true,
["Base.SKS"] = true,
["Base.SKS_carbine"] = true,
["Base.SKS_carbine_short"] = true,
["Base.Snub22LR"] = true,
["Base.SPAS12"] = true,
["Base.SPAS15"] = true,
["Base.Springfield_sniper"] = true,
["Base.SR1M"] = true,
["Base.SR338"] = true,
["Base.SR3M"] = true,
["Base.SR47"] = true,
["Base.SS2V5"] = true,
["Base.Sten_MK5"] = true,
["Base.Striker"] = true,
["Base.SV98"] = true,
["Base.SVD"] = true,
["Base.SVD_short"] = true,
["Base.SVD12"] = true,
["Base.SVDK"] = true,
["Base.SVDK_short"] = true,
["Base.SVT_40"] = true,
["Base.SVU"] = true,
["Base.SW1905"] = true,
["Base.SW1917"] = true,
["Base.SW500"] = true,
["Base.SW629"] = true,
["Base.SWM1854"] = true,
["Base.SWM1894"] = true,
["Base.SWM3"] = true,
["Base.SWM327"] = true,
["Base.SWM629_Deluxe"] = true,
["Base.SWMP_12"] = true,
["Base.Taurus_raging_bull"] = true,
["Base.Taurus_raging_bull460"] = true,
["Base.Taurus_RT85"] = true,
["Base.Taurus606"] = true,
["Base.TEC9"] = true,
["Base.Thompson"] = true,
["Base.TMP"] = true,
["Base.Type81"] = true,
["Base.Type88"] = true,
["Base.UMP45"] = true,
["Base.UMP45_long"] = true,
["Base.USAS12"] = true,
["Base.USP45"] = true,
["Base.UZI"] = true,
["Base.V_M87"] = true,
["Base.ValmetM82"] = true,
["Base.VarmintRifle"] = true,
["Base.VEPR"] = true,
["Base.Veresk"] = true,
["Base.VictorySW22"] = true,
["Base.VP70"] = true,
["Base.VR80"] = true,
["Base.VSK"] = true,
["Base.VSS"] = true,
["Base.VSS_Tactical"] = true,
["Base.VSSK"] = true,
["Base.VZ58"] = true,
["Base.VZ61"] = true,
["Base.WA2000"] = true,
["Base.Webley_MK_snub"] = true,
["Base.Webley_Revolver"] = true,
["Base.Wieger940"] = true,
["Base.Wildey"] = true,
["Base.Winchester1886"] = true,
["Base.Winchester1895"] = true,
["Base.Winchester1897"] = true,
["Base.X86"] = true,
["Base.XD"] = true,
["Base.XM8"] = true,
}
local GAEL_GUNSTORE_MAGAZINES = {
["Base.12GClip"] = true,
["Base.12GClip14"] = true,
["Base.12GDrum24"] = true,
["Base.22LRClip"] = true,
["Base.22LRClip50"] = true,
["Base.22LRDrum100"] = true,
["Base.308Box150"] = true,
["Base.308Clip"] = true,
["Base.308Clip40"] = true,
["Base.308Drum100"] = true,
["Base.308Drum60"] = true,
["Base.357Clip"] = true,
["Base.357Drum45"] = true,
["Base.44Clip"] = true,
["Base.44Clip20"] = true,
["Base.44Drum50"] = true,
["Base.45Clip"] = true,
["Base.45Clip25"] = true,
["Base.45Drum100"] = true,
["Base.45Drum50"] = true,
["Base.50Clip"] = true,
["Base.50Clip18"] = true,
["Base.50MagnumClip"] = true,
["Base.50MagnumClip18"] = true,
["Base.50MagnumDrum40"] = true,
["Base.545x39Clip30"] = true,
["Base.545x39Clip60"] = true,
["Base.545x39Drum100"] = true,
["Base.556Box150"] = true,
["Base.556Clip"] = true,
["Base.556Drum_100rnd"] = true,
["Base.556Drum_60rnd"] = true,
["Base.762x39Clip"] = true,
["Base.762x39Clip45"] = true,
["Base.762x39Drum100"] = true,
["Base.762x39Drum73"] = true,
["Base.762x54rBox150"] = true,
["Base.762x54rClip"] = true,
["Base.762x54rClip40"] = true,
["Base.792x57Box75"] = true,
["Base.792x57Box97"] = true,
["Base.792x57Clip"] = true,
["Base.792x57Clip40"] = true,
["Base.9mmClip"] = true,
["Base.9mmClip30"] = true,
["Base.9mmDrum100"] = true,
["Base.9mmDrum50"] = true,
["Base.9mmDrum75"] = true,
["Base.9x39Clip"] = true,
["Base.9x39Clip40"] = true,
["Base.9x39Drum60"] = true,
["Base.BizonClip64"] = true,
}
local function setDisplayCategory(scriptManager, fullType, category)
local scriptItem = scriptManager:FindItem(fullType)
if not scriptItem then
return false
end
if type(scriptItem.DoParam) == "function" then
scriptItem:DoParam("DisplayCategory = " .. category)
return true
end
if type(scriptItem.setDisplayCategory) == "function" then
scriptItem:setDisplayCategory(category)
return true
end
return false
end
local function areSupportedItemsReady(scriptManager)
if not scriptManager then
return false
end
local guns93Firearm = scriptManager:FindItem(GUNS93_SENTINEL_FIREARM)
local guns93Magazine = scriptManager:FindItem(GUNS93_SENTINEL_MAGAZINE)
local guns93Ready = guns93Firearm ~= nil and guns93Magazine ~= nil
local gaelFirearm = scriptManager:FindItem(GAEL_GUNSTORE_SENTINEL_FIREARM)
local gaelMagazine = scriptManager:FindItem(GAEL_GUNSTORE_SENTINEL_MAGAZINE)
local gaelReady = gaelFirearm ~= nil and gaelMagazine ~= nil
return guns93Ready or gaelReady
end
local function applyPatch()
if OFGuns93DisplayCategoryPatch.patched then
return true
end
if not isSortingToggleEnabled() then
OFGuns93DisplayCategoryPatch.patched = true
return true
end
local scriptManager = ScriptManager and ScriptManager.instance
if not scriptManager or type(scriptManager.FindItem) ~= "function" then
return false
end
local firearmCategory, magazineCategory = resolveWeaponCategories()
if not areSupportedItemsReady(scriptManager) then
return false
end
local patchedCount = 0
for fullType in pairs(GUNS93_FIREARMS) do
if setDisplayCategory(scriptManager, fullType, firearmCategory) then
patchedCount = patchedCount + 1
end
end
for fullType in pairs(GUNS93_MAGAZINES) do
if setDisplayCategory(scriptManager, fullType, magazineCategory) then
patchedCount = patchedCount + 1
end
end
for fullType in pairs(GAEL_GUNSTORE_FIREARMS) do
if setDisplayCategory(scriptManager, fullType, firearmCategory) then
patchedCount = patchedCount + 1
end
end
for fullType in pairs(GAEL_GUNSTORE_MAGAZINES) do
if setDisplayCategory(scriptManager, fullType, magazineCategory) then
patchedCount = patchedCount + 1
end
end
if patchedCount == 0 then
return false
end
OFGuns93DisplayCategoryPatch.patched = true
return true
end
local function tryPatchOnTick()
if applyPatch() then
OFGuns93DisplayCategoryPatch.tickHookAdded = false
Events.OnTick.Remove(tryPatchOnTick)
end
end
local function ensureTickHook()
if OFGuns93DisplayCategoryPatch.tickHookAdded then
return
end
OFGuns93DisplayCategoryPatch.tickHookAdded = true
Events.OnTick.Add(tryPatchOnTick)
end
local function queueRepatchNow()
OFGuns93DisplayCategoryPatch.patched = false
if not applyPatch() then
ensureTickHook()
end
end
local function runQueuedRepatch()
OFGuns93DisplayCategoryPatch.repatchQueued = false
Events.OnTick.Remove(runQueuedRepatch)
queueRepatchNow()
end
local function queueRepatch()
if OFGuns93DisplayCategoryPatch.repatchQueued then
return
end
OFGuns93DisplayCategoryPatch.repatchQueued = true
Events.OnTick.Add(runQueuedRepatch)
end
local function tryInstallBetterContainersRepatchHook()
local ok, helpers = pcall(require, "BetterContainers/Helpers")
if not ok or type(helpers) ~= "table" then
return
end
local eventName = helpers.OPTIONS_APPLIED
if type(eventName) ~= "string" then
return
end
local event = Events[eventName]
if event and type(event.Add) == "function" then
event.Add(queueRepatch)
end
end
if not applyPatch() then
ensureTickHook()
end
if Events.OnMainMenuEnter and type(Events.OnMainMenuEnter.Add) == "function" then
Events.OnMainMenuEnter.Add(queueRepatch)
end
tryInstallBetterContainersRepatchHook()

View File

@@ -1,7 +0,0 @@
IGUI_EN = {
IGUI_ItemCat_WepFire = "Weapon - Firearm",
IGUI_ItemCat_WepAmmoMag = "Weapon - Magazine",
IGUI_ItemCat_Casings = "Spent Casings",
IGUI_ItemCat_OFSpentCasings = "Spent Casings",
IGUI_ItemCat_OFAmmoPart = "Ammo Part",
}

View File

@@ -1,7 +0,0 @@
Sandbox_EN = {
Sandbox_OpinionatedFirearms = "Opinionated Firearms",
Sandbox_HandleHotBrassCasingSpawnUseAmmoMaker = "Handle Hot Brass Casing Spawn - Use Ammomaker",
Sandbox_HandleHotBrassCasingSpawnUseAmmoMaker_tooltip = "When enabled, Hot Brass ejects Ammo Maker empties for supported ammo (including Guns93 and Gael Gun Store) instead of default casings.",
Sandbox_AddSorting = "Add Sorting",
Sandbox_AddSorting_tooltip = "When enabled, apply Opinionated Firearms sorting/display categories for supported weapons, magazines, and ammo parts.",
}

View File

@@ -1,14 +0,0 @@
VERSION = 1,
option OpinionatedFirearms.HandleHotBrassCasingSpawnUseAmmoMaker {
type = boolean,
default = true,
page = OpinionatedFirearms,
translation = HandleHotBrassCasingSpawnUseAmmoMaker,
}
option OpinionatedFirearms.AddSorting {
type = boolean,
default = true,
page = OpinionatedFirearms,
translation = AddSorting,
}

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

77
index.html Normal file
View File

@@ -0,0 +1,77 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Opinionated Firearms Spawn List Builder</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<header class="topbar">
<div>
<h1>Opinionated Firearms Spawn List Builder</h1>
<p>Edit firearm/attachment spawn enablement, placement lists, and spawn rates.</p>
</div>
<div class="actions">
<label class="file-button">
Load Catalog JSON
<input id="catalogFile" type="file" accept=".json,application/json">
</label>
<label class="file-button secondary">
Load Profile JSON
<input id="profileFile" type="file" accept=".json,application/json">
</label>
<button id="exportProfile" type="button">Export Profile JSON</button>
</div>
</header>
<section class="status">
<span id="statusText">Load an extracted catalog JSON to begin.</span>
</section>
<main class="layout">
<section class="panel">
<div class="panel-head">
<h2>Items</h2>
<div class="filters">
<input id="searchInput" type="search" placeholder="Search item ID...">
<select id="categoryFilter">
<option value="all">All categories</option>
<option value="firearm">Firearms</option>
<option value="attachment">Attachments</option>
<option value="unknown">Unknown</option>
</select>
<select id="spawnFilter">
<option value="all">All spawn states</option>
<option value="enabled">Spawn enabled</option>
<option value="disabled">Spawn disabled</option>
</select>
</div>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Spawn</th>
<th>Item</th>
<th>Category</th>
<th>Spawn Loacation</th>
</tr>
</thead>
<tbody id="itemTableBody"></tbody>
</table>
</div>
</section>
<section class="panel details-panel">
<div class="panel-head">
<h2>Selected Item</h2>
<button id="resetSelected" type="button">Reset to Catalog</button>
</div>
<div id="selectedDetails" class="details-empty">Select an item to edit placements and spawn rate.</div>
</section>
</main>
<script src="./app.js"></script>
</body>
</html>

View File

@@ -1,9 +0,0 @@
name=Opinionated Firearms
id=hrsys_opinionated_firearms
author=Riggs0
modversion=1.0.0
versionMin=42.12.13
require=\2788256295/ammomaker,\HBVCEFb42
description=Opinionated Firearms casing and other changes to Guns of 93, Ammomaker and Hot Brass
icon=icon.png
poster=preview.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

263
styles.css Normal file
View File

@@ -0,0 +1,263 @@
:root {
--bg: #f4efe6;
--panel: #fffaf1;
--panel-2: #f8f0e2;
--line: #d8ccb8;
--text: #2f2418;
--muted: #7d6852;
--accent: #9c3f1f;
--accent-2: #4f6f52;
--focus: #c77800;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Trebuchet MS", "Segoe UI", sans-serif;
color: var(--text);
background:
radial-gradient(1200px 700px at 95% 0%, #e2c8a0 0%, transparent 60%),
linear-gradient(145deg, #f8f2e7 0%, var(--bg) 100%);
min-height: 100vh;
}
.topbar {
display: flex;
justify-content: space-between;
align-items: flex-end;
gap: 1rem;
padding: 1.1rem 1.3rem 1rem;
border-bottom: 1px solid var(--line);
background: rgba(255, 250, 241, 0.8);
backdrop-filter: blur(2px);
}
.topbar h1 {
margin: 0;
font-size: 1.3rem;
letter-spacing: 0.04em;
}
.topbar p {
margin: 0.25rem 0 0;
color: var(--muted);
font-size: 0.9rem;
}
.actions {
display: flex;
align-items: center;
gap: 0.55rem;
flex-wrap: wrap;
justify-content: flex-end;
}
.file-button,
button {
border: 1px solid var(--accent);
color: #fff;
background: var(--accent);
padding: 0.48rem 0.75rem;
border-radius: 0.5rem;
cursor: pointer;
font-size: 0.85rem;
font-weight: 600;
}
.file-button.secondary {
border-color: var(--accent-2);
background: var(--accent-2);
}
.file-button input {
display: none;
}
button:hover,
.file-button:hover {
filter: brightness(1.05);
}
button:focus-visible,
.file-button:focus-within {
outline: 2px solid var(--focus);
outline-offset: 2px;
}
.status {
padding: 0.5rem 1.3rem;
font-size: 0.88rem;
color: var(--muted);
border-bottom: 1px solid var(--line);
}
.layout {
display: grid;
grid-template-columns: minmax(320px, 1.1fr) minmax(320px, 0.9fr);
gap: 1rem;
padding: 1rem 1.3rem 1.3rem;
}
.panel {
background: var(--panel);
border: 1px solid var(--line);
border-radius: 0.8rem;
min-height: 66vh;
display: flex;
flex-direction: column;
}
.panel-head {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 0.8rem;
border-bottom: 1px solid var(--line);
background: var(--panel-2);
}
.panel-head h2 {
margin: 0;
font-size: 1rem;
}
.filters {
display: flex;
gap: 0.45rem;
flex-wrap: wrap;
}
input[type="search"],
select,
input[type="number"],
input[type="text"] {
border: 1px solid var(--line);
background: #fff;
color: var(--text);
border-radius: 0.45rem;
padding: 0.35rem 0.45rem;
font-size: 0.85rem;
}
input:focus-visible,
select:focus-visible {
outline: 2px solid var(--focus);
outline-offset: 1px;
}
.table-wrap {
overflow: auto;
flex: 1 1 auto;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
text-align: left;
padding: 0.45rem 0.55rem;
border-bottom: 1px solid var(--line);
font-size: 0.83rem;
vertical-align: middle;
}
tbody tr {
cursor: pointer;
}
tbody tr:hover {
background: #fff2de;
}
tbody tr.selected {
background: #f9dfbc;
}
.details-panel {
overflow: hidden;
}
.details-body {
padding: 0.8rem;
overflow: auto;
}
.details-empty {
padding: 1.1rem;
color: var(--muted);
font-size: 0.9rem;
}
.item-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.6rem;
margin-bottom: 0.7rem;
}
.item-title {
margin: 0;
font-size: 1rem;
}
.badge {
border: 1px solid var(--line);
border-radius: 999px;
padding: 0.15rem 0.5rem;
font-size: 0.75rem;
color: var(--muted);
}
.inline-row {
display: flex;
gap: 0.5rem;
align-items: center;
flex-wrap: wrap;
margin-bottom: 0.65rem;
}
.placements-table th,
.placements-table td {
font-size: 0.8rem;
padding: 0.34rem 0.4rem;
}
.small-btn {
border: 1px solid var(--line);
background: #fff;
color: var(--text);
border-radius: 0.35rem;
padding: 0.2rem 0.45rem;
font-size: 0.75rem;
cursor: pointer;
}
.small-btn.remove {
border-color: #b74a38;
color: #8f2617;
}
.meta {
margin: 0.7rem 0 0;
color: var(--muted);
font-size: 0.78rem;
line-height: 1.4;
}
@media (max-width: 980px) {
.layout {
grid-template-columns: 1fr;
}
.panel {
min-height: 45vh;
}
}