300 lines
8.4 KiB
JavaScript
300 lines
8.4 KiB
JavaScript
// ====== NUCLEAR MOD - v3.0 - WITH IMPROVED RADIATION SYSTEM ======
|
|
// Advanced nuclear mod with realistic radiation spread and material weakening
|
|
|
|
function irradiateNearby(pixel, radius = 1, intensity = 1) {
|
|
// List of elements to explicitly exclude
|
|
const excludedElements = new Set([
|
|
"deuterium",
|
|
"tritium",
|
|
"fusion_reactor_core",
|
|
"uranium",
|
|
"enriched_uranium",
|
|
"uranium_depleted",
|
|
"plutonium",
|
|
"nuclear_waste_mixed",
|
|
"nuclear_waste_pu",
|
|
"minor_actinides",
|
|
"fission_products",
|
|
]);
|
|
|
|
for (let dx = -radius; dx <= radius; dx++) {
|
|
for (let dy = -radius; dy <= radius; dy++) {
|
|
if (dx === 0 && dy === 0) continue;
|
|
let nx = pixel.x + dx;
|
|
let ny = pixel.y + dy;
|
|
let p = getPixel(nx, ny);
|
|
if (
|
|
p &&
|
|
!elements[p.element].radioactive && // not radioactive
|
|
!elements[p.element].shielding && // not shielded
|
|
!excludedElements.has(p.element) && // not in excluded list
|
|
!elements[p.element].antiRadiation && // not anti-radiation
|
|
Math.random() < 0.1 * intensity
|
|
) {
|
|
p.temp += 15 * intensity;
|
|
p.irradiated = (p.irradiated || 0) + intensity;
|
|
if (p.irradiated > 10 && Math.random() < 0.2) {
|
|
changePixel(p, "irradiated_matter");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Irradiated matter (weakened)
|
|
elements.irradiated_matter = {
|
|
color: "#777733",
|
|
behavior: behaviors.POWDER,
|
|
category: "nuclear",
|
|
tempHigh: 400,
|
|
state: "solid",
|
|
density: 900,
|
|
burn: 80,
|
|
burnTime: 250,
|
|
hardness: 5
|
|
};
|
|
|
|
elements.uranium = {
|
|
color: "#4a5d23",
|
|
behavior: behaviors.POWDER,
|
|
tempHigh: 1132,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 19050,
|
|
radioactive: true,
|
|
radioactivity: 0.3,
|
|
tick(pixel) {
|
|
irradiateNearby(pixel, 1, 0.3);
|
|
}
|
|
};
|
|
|
|
elements.enriched_uranium = {
|
|
color: "#556b2f",
|
|
behavior: behaviors.POWDER,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 19050,
|
|
radioactive: true,
|
|
radioactivity: 1.0,
|
|
fissionable: true,
|
|
fissionTemp: 1200,
|
|
fissionEnergy: 140,
|
|
tick(pixel) {
|
|
irradiateNearby(pixel, 1, 1.0);
|
|
|
|
// Check for neutron contact
|
|
let neighbors = [
|
|
getPixel(pixel.x + 1, pixel.y),
|
|
getPixel(pixel.x - 1, pixel.y),
|
|
getPixel(pixel.x, pixel.y + 1),
|
|
getPixel(pixel.x, pixel.y - 1)
|
|
];
|
|
if (neighbors.some(p => p && p.element === "neutron")) {
|
|
pixel.temp += 2000; // Strong heating
|
|
}
|
|
|
|
if (!pixel.fissionCooldown) pixel.fissionCooldown = 0;
|
|
if (pixel.temp > this.fissionTemp && Math.random() < 0.002 && pixel.fissionCooldown <= 0) {
|
|
explodeAt(pixel.x, pixel.y, this.fissionEnergy);
|
|
nuclearIrradiateRay(pixel.x, pixel.y, 8); // Nuclear irradiation ray
|
|
changePixel(pixel, "uranium_depleted");
|
|
if (Math.random() < 0.3) {
|
|
createPixel("nuclear_waste_mixed", pixel.x + 1, pixel.y);
|
|
}
|
|
pixel.fissionCooldown = 60;
|
|
} else {
|
|
pixel.fissionCooldown = Math.max(0, pixel.fissionCooldown - 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
elements.uranium_depleted = {
|
|
color: "#6d7265",
|
|
behavior: behaviors.POWDER,
|
|
tempHigh: 1132,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 18900,
|
|
radioactive: true,
|
|
radioactivity: 0.05,
|
|
tick(pixel) {
|
|
irradiateNearby(pixel, 1, 0.05);
|
|
}
|
|
};
|
|
|
|
elements.plutonium = {
|
|
color: "#4e3629",
|
|
behavior: behaviors.POWDER,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 19800,
|
|
radioactive: true,
|
|
radioactivity: 0.8,
|
|
fissionable: true,
|
|
fissionTemp: 800,
|
|
fissionEnergy: 110,
|
|
tick(pixel) {
|
|
irradiateNearby(pixel, 1, 0.8);
|
|
|
|
// Check for neutron contact
|
|
let neighbors = [
|
|
getPixel(pixel.x + 1, pixel.y),
|
|
getPixel(pixel.x - 1, pixel.y),
|
|
getPixel(pixel.x, pixel.y + 1),
|
|
getPixel(pixel.x, pixel.y - 1)
|
|
];
|
|
if (neighbors.some(p => p && p.element === "neutron")) {
|
|
pixel.temp += 2000; // Strong heating
|
|
}
|
|
|
|
if (!pixel.fissionCooldown) pixel.fissionCooldown = 0;
|
|
if (pixel.temp > this.fissionTemp && Math.random() < 0.003 && pixel.fissionCooldown <= 0) {
|
|
explodeAt(pixel.x, pixel.y, this.fissionEnergy);
|
|
nuclearIrradiateRay(pixel.x, pixel.y, 8); // Nuclear irradiation ray
|
|
changePixel(pixel, "nuclear_waste_pu");
|
|
pixel.fissionCooldown = 60;
|
|
} else {
|
|
pixel.fissionCooldown = Math.max(0, pixel.fissionCooldown - 1);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Mixed nuclear waste
|
|
elements.nuclear_waste_mixed = {
|
|
color: "#6b5d6e",
|
|
behavior: behaviors.STURDYPOWDER,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 21000,
|
|
radioactive: true,
|
|
radioactivity: 0.5
|
|
};
|
|
|
|
// Plutonium waste
|
|
elements.nuclear_waste_pu = {
|
|
color: "#5b4d5e",
|
|
behavior: behaviors.STURDYPOWDER,
|
|
state: "solid",
|
|
category: "nuclear",
|
|
density: 22000,
|
|
radioactive: true,
|
|
radioactivity: 0.6
|
|
};
|
|
|
|
elements.minor_actinides = {
|
|
color: "#493d3d",
|
|
behavior: behaviors.POWDER,
|
|
category: "nuclear",
|
|
state: "solid",
|
|
density: 19500,
|
|
radioactive: true,
|
|
radioactivity: 0.4
|
|
};
|
|
|
|
elements.fission_products = {
|
|
color: "#7c6d7d",
|
|
behavior: behaviors.STURDYPOWDER,
|
|
category: "nuclear",
|
|
state: "solid",
|
|
density: 18000,
|
|
radioactive: true,
|
|
radioactivity: 0.3
|
|
};
|
|
|
|
// Lead shield
|
|
elements.lead_shield = {
|
|
color: "#5c5c5c",
|
|
behavior: behaviors.WALL,
|
|
category: "nuclear",
|
|
density: 11340,
|
|
conduct: 0.01,
|
|
shielding: true,
|
|
insulate: true
|
|
};
|
|
|
|
// Concrete containment
|
|
elements.concrete = {
|
|
color: "#a9a9a9",
|
|
behavior: behaviors.WALL,
|
|
category: "nuclear",
|
|
state: "solid",
|
|
density: 2400,
|
|
shielding: true
|
|
};
|
|
|
|
elements.deuterium = {
|
|
color: "#aaffff",
|
|
behavior: behaviors.LIQUID,
|
|
category: "nuclear",
|
|
state: "liquid",
|
|
density: 150
|
|
};
|
|
|
|
elements.tritium = {
|
|
color: "#88ddee",
|
|
behavior: behaviors.LIQUID,
|
|
category: "nuclear",
|
|
state: "liquid",
|
|
density: 180,
|
|
radioactive: true,
|
|
radioactivity: 0.7,
|
|
tick(pixel) {
|
|
irradiateNearby(pixel, 1, 0.7);
|
|
}
|
|
};
|
|
|
|
// Fusion reactor core
|
|
elements.fusion_reactor_core = {
|
|
color: "#ff4400",
|
|
behavior: behaviors.WALL,
|
|
category: "nuclear",
|
|
tick: function(pixel) {
|
|
let n = [
|
|
getPixel(pixel.x + 1, pixel.y),
|
|
getPixel(pixel.x - 1, pixel.y),
|
|
getPixel(pixel.x, pixel.y + 1),
|
|
getPixel(pixel.x, pixel.y - 1)
|
|
];
|
|
let hasD = n.some(p => p && p.element === "deuterium");
|
|
let hasT = n.some(p => p && p.element === "tritium");
|
|
|
|
if (hasD && hasT && pixel.temp > 3000) {
|
|
explodeAt(pixel.x, pixel.y, 222);
|
|
nuclearIrradiateRay(pixel.x, pixel.y, 10); // Stronger irradiation for fusion
|
|
pixel.temp += 3000;
|
|
for (let i = 0; i < 4; i++) {
|
|
let dx = pixel.x + (Math.floor(Math.random() * 3) - 1);
|
|
let dy = pixel.y + (Math.floor(Math.random() * 3) - 1);
|
|
if (isEmpty(dx, dy)) createPixel("plasma", dx, dy);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
elements.plasma = {
|
|
color: "#ff00ff",
|
|
behavior: behaviors.GAS,
|
|
category: "energy",
|
|
state: "gas",
|
|
temp: 1e7,
|
|
density: 0.1
|
|
};
|
|
|
|
function nuclearIrradiateRay(x, y, radius = 20) {
|
|
// List of particle elements to ignore
|
|
const ignore = new Set([
|
|
"neutron", "photon", "electron", "proton", "muon", "tau", "positron", "plasma"
|
|
]);
|
|
for (let dx = -radius; dx <= radius; dx++) {
|
|
for (let dy = -radius; dy <= radius; dy++) {
|
|
let dist = Math.sqrt(dx*dx + dy*dy);
|
|
if (dist > radius) continue;
|
|
let px = x + dx;
|
|
let py = y + dy;
|
|
let p = getPixel(px, py);
|
|
if (p && !ignore.has(p.element) && p.element !== "irradiated_matter") {
|
|
changePixel(p, "irradiated_matter");
|
|
}
|
|
}
|
|
}
|
|
} |