I am trying to have modded items in the chests of lost cites mod, and there is this problem I am facing, in which a mod called Apocalypse Now automatically injects its mod items into the chests without having a need of datapack, which suggests its being done internally within the mod. What I have found is that it is overwriting loot tables entirely and by that, lootjs/kubejs or the datapacks of the another mod does not inject their itmes.
That another mod is Timeless and Classics Zero, and I made the datapacks and the json file (later) for this mods by taking help of multiple chatbots, since I lack knowledge on making datapacks or json file for the lootjs/kubejs to overwrite or just add your loot to the loot tables without overwriting it. I will have the contents of those files written down below, by which you can see if there are errors or not in those 3 files.
- Datapack for the timeless and classics zero mod:
a. add_tacz_apartment.json
"type": "forge:add_items",
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/apartament"
}
],
"items": [
{
"item": "tacz:modern_kinetic_gun",
"weight": 100,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:glock_17\\\",GunCurrentAmmoCount:7}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "Glock 17",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 6,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:uzi\\\",GunCurrentAmmoCount:25}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "Uzi",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 6,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:db_short\\\",GunCurrentAmmoCount:2}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "Sawed-off",
"italic": false
}
}
]
},
{
"item": "tacz:sight_uh1",
"weight": 8
},
{
"item": "tacz:sight_552",
"weight": 8
},
{
"item": "tacz:muzzle_silencer_phantom_s1",
"weight": 4
},
{
"item": "tacz:muzzle_compensator_trident",
"weight": 4
},
{
"item": "tacz:ammo_9mm",
"weight": 12
},
{
"item": "tacz:ammo_12g",
"weight": 10
},
{
"item": "tacz:ammo_45acp",
"weight": 4
}
]
}
b. add_tacz_lostcitychest.json
"type": "forge:add_items",
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "lostcities:chests/lostcitychest"
}
],
"items": [
{
"item": "tacz:modern_kinetic_gun",
"weight": 4,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:ak47\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "AK-47 (abandoned)",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 6,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:db_short\\\",GunCurrentAmmoCount:2}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "Sawed-off",
"italic": false
}
}
]
},
{
"item": "tacz:sight_rmr_dot",
"weight": 4
},
{
"item": "tacz:light_extended_mag_3",
"weight": 1
},
{
"item": "tacz:ammo_9mm",
"weight": 12
},
{
"item": "tacz:ammo_45acp",
"weight": 4
},
{
"item": "tacz:ammo_12g",
"weight": 8
}
]
}
c. add_tacz_raildungeon.json
"type": "forge:add_items",
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "lostcities:chests/raildungeonchest"
}
],
"items": [
{
"item": "tacz:modern_kinetic_gun",
"weight": 6,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:ak47\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "AK-47 (abandoned)",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 3,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:sks_tactical\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "SKS (rifle)",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 3,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:type_81\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "Type 81",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 1,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:aa12\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "AA-12 (very rare)",
"italic": false
}
}
]
},
{
"item": "tacz:modern_kinetic_gun",
"weight": 1,
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{GunId:\\\"tacz:m320\\\",GunCurrentAmmoCount:0}"
},
{
"function": "minecraft:set_name",
"name": {
"text": "M320 (very rare)",
"italic": false
}
}
]
},
{
"item": "tacz:scope_acog_ta31",
"weight": 4
},
{
"item": "tacz:scope_vudu",
"weight": 3
},
{
"item": "tacz:scope_mk5hd",
"weight": 1
},
{
"item": "tacz:muzzle_brake_cyclone_d2",
"weight": 4
},
{
"item": "tacz:sight_deltapoint_pistol",
"weight": 4
},
{
"item": "tacz:ammo_556x45",
"weight": 10
},
{
"item": "tacz:ammo_762x39",
"weight": 10
},
{
"item": "tacz:ammo_30_06",
"weight": 4
},
{
"item": "tacz:ammo_45_70",
"weight": 2
}
]
}
- loot_integration.json (file for kubejs/lootjs)
// Defensive LootJS injector — tries multiple API names and catches all errors.
// Replace your existing file with this. It will not throw TypeError on missing methods.
(function() {
function log() {
try { console.log("[KubeJS-LOOTFIX]", Array.prototype.join.call(arguments, " ")); } catch (e) {}
}
// Items to inject (same lists you used)
const taczItemsApartment = [
{ item: "tacz:sight_uh1", weight: 8 },
{ item: "tacz:sight_552", weight: 8 },
{ item: "tacz:muzzle_silencer_phantom_s1", weight: 4 },
{ item: "tacz:muzzle_compensator_trident", weight: 4 },
{ item: "tacz:ammo", weight: 12, nbt: '{AmmoId:"tacz:9mm"}' },
{ item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:12g"}' },
{ item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:45acp"}' },
{ item: "tacz:modern_kinetic_gun", weight: 8, nbt: '{GunId:"tacz:glock_17",GunCurrentAmmoCount:7}' },
{ item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:uzi",GunCurrentAmmoCount:25}' },
{ item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:db_short",GunCurrentAmmoCount:2}' }
];
const taczItemsRailDungeon = [
{ item: "tacz:scope_acog_ta31", weight: 4 },
{ item: "tacz:scope_vudu", weight: 3 },
{ item: "tacz:scope_mk5hd", weight: 1 },
{ item: "tacz:muzzle_brake_cyclone_d2", weight: 4 },
{ item: "tacz:sight_deltapoint_pistol", weight: 4 },
{ item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:556x45"}' },
{ item: "tacz:ammo", weight: 10, nbt: '{AmmoId:"tacz:762x39"}' },
{ item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:30_06"}' },
{ item: "tacz:ammo", weight: 2, nbt: '{AmmoId:"tacz:45_70"}' },
{ item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:ak47",GunCurrentAmmoCount:0}' },
{ item: "tacz:modern_kinetic_gun", weight: 3, nbt: '{GunId:"tacz:sks_tactical",GunCurrentAmmoCount:0}' },
{ item: "tacz:modern_kinetic_gun", weight: 3, nbt: '{GunId:"tacz:type_81",GunCurrentAmmoCount:0}' },
{ item: "tacz:modern_kinetic_gun", weight: 1, nbt: '{GunId:"tacz:aa12",GunCurrentAmmoCount:0}' },
{ item: "tacz:modern_kinetic_gun", weight: 1, nbt: '{GunId:"tacz:m320",GunCurrentAmmoCount:0}' }
];
const taczItemsLostCity = [
{ item: "tacz:sight_rmr_dot", weight: 4 },
{ item: "tacz:light_extended_mag_3", weight: 1 },
{ item: "tacz:ammo", weight: 12, nbt: '{AmmoId:"tacz:9mm"}' },
{ item: "tacz:ammo", weight: 4, nbt: '{AmmoId:"tacz:45acp"}' },
{ item: "tacz:ammo", weight: 8, nbt: '{AmmoId:"tacz:12g"}' },
{ item: "tacz:modern_kinetic_gun", weight: 4, nbt: '{GunId:"tacz:ak47",GunCurrentAmmoCount:0}' },
{ item: "tacz:modern_kinetic_gun", weight: 6, nbt: '{GunId:"tacz:db_short",GunCurrentAmmoCount:2}' }
];
// low-level helper: safely try to call a method on event
function tryCall(event, methodName, argsArray) {
try {
const fn = event[methodName];
if (typeof fn === "function") {
return fn.apply(event, argsArray);
}
// If fn is not a JS function, still attempt to call (some Java proxies allow direct call)
if (fn !== undefined) {
try { return fn(argsArray); } catch (e) { /* ignore */ }
}
} catch (e) {
// swallow errors so script doesn't crash
}
return null;
}
// helper: add items using a table/context object
function populateTableLikeObject(tblOrCtx, items) {
try {
// preferred API: tblOrCtx.addPool(pool => { pool.addItem(...).withNBT(...) })
if (typeof tblOrCtx.addPool === "function") {
tblOrCtx.addPool(function(pool) {
// if pool.rolls exists, set single roll
try { if (typeof pool.rolls === "function") pool.rolls([1,1]); } catch(e){}
items.forEach(function(entry) {
try {
if (entry.nbt && typeof pool.addItem === "function") {
// chain withNBT if available
const e = pool.addItem(entry.item, entry.weight || 1);
// some APIs return a wrapper with withNBT, others not - guard it
try { if (typeof e.withNBT === "function") e.withNBT(entry.nbt); } catch(e){}
} else if (typeof pool.addItem === "function") {
pool.addItem(entry.item, entry.weight || 1);
} else if (typeof pool.add === "function") {
// older variant: pool.add({ item:..., weight:... })
pool.add({ item: entry.item, weight: entry.weight || 1, nbt: entry.nbt || null });
}
} catch (errEntry) {
// skip problematic entry
}
});
});
return true;
}
// fallback: if ctx/table has add or addItem methods
if (typeof tblOrCtx.add === "function") {
try { tblOrCtx.add(items); return true; } catch(e) {}
}
if (typeof tblOrCtx.addItem === "function") {
items.forEach(function(entry) {
try {
const e = tblOrCtx.addItem(entry.item, entry.weight || 1);
try { if (entry.nbt && typeof e.withNBT === "function") e.withNBT(entry.nbt); } catch(e){}
} catch(e){}
});
return true;
}
} catch (e) {
// swallow
}
return false;
}
// Tries a bunch of method names in defensive order. Returns true on first success.
function tryModifyTable(event, tableId, items) {
// candidate API names to try, in order
const candidates = [
"modifyLootTable",
"modify_table",
"modifyTable",
"modify",
"modify_loot_table"
];
for (let i = 0; i < candidates.length; i++) {
const name = candidates[i];
try {
// Attempt to call event[name](tableId, callback)
const res = tryCall(event, name, [tableId, function(tblOrCtx) {
const ok = populateTableLikeObject(tblOrCtx, items);
if (!ok) {
// As a fallback, try to call tblOrCtx.add(items)
try { if (typeof tblOrCtx.add === "function") tblOrCtx.add(items); } catch(e) {}
}
}]);
if (res !== null) {
log("Used API:", name, "for table:", tableId);
return true;
}
} catch (err) {
// continue trying next candidate
}
}
// Final fallback: maybe event has an 'add' that accepts an object like { id, items }
try {
if (typeof event.add === "function") {
try { event.add({ id: tableId, items: items }); log("Used event.add fallback for", tableId); return true; } catch(e){}
}
} catch (e) {}
// As last resort, log event keys for debugging
try {
const keys = Object.keys(event).join(", ");
log("No supported modify API found for table", tableId, " — event keys:", keys);
} catch (e) {
log("No supported modify API found and couldn't list event keys.");
}
return false;
}
// Main entry: call inside LootJS.modifiers
LootJS.modifiers(function(event) {
try {
let did1 = tryModifyTable(event, "minecraft:chests/apartament", taczItemsApartment);
let did2 = tryModifyTable(event, "lostcities:chests/raildungeonchest", taczItemsRailDungeon);
let did3 = tryModifyTable(event, "lostcities:chests/lostcitychest", taczItemsLostCity);
log("Injection results — apartament:", !!did1, "raildungeon:", !!did2, "lostcity:", !!did3);
} catch (e) {
log("Unexpected error inside LootJS.modifiers block:", String(e));
}
});
})();
I don't know if this is the place to ask this, I have asked this same question in reddit but no one replied, maybe due to this issue being too technical. Please help me with this.