Calculator Tools Calculator Tools
Create

Titan Selector: Engage Parameters, Choose Weapons, and Fire!

Apr 3, 2025

About this app

Engage in epic battles with your Titans! Select weapons, determine strategies, and track damage using our sophisticated app.

Titan Selector: Engage Parameters, Choose Weapons, and Fire!

Related apps

Put this on your site

Source

                    <html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">

<title>Titan Selector: Engage Parameters, Choose Weapons, and Fire!</title>
<meta name="description" content="Engage in epic battles with your Titans! Select weapons, determine strategies, and track damage using our sophisticated app."/>
<meta name="keywords" content="Titan, Board Game, Battle, Strategy, Weapons, Adaptive Games, Game Stats, Turn Based Games"/>

<!-- Libraries -->
<!-- jQuery (3.6.0) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>
<!-- Bootstrap CSS (5.3.3) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" crossorigin="anonymous">
<!-- Bootstrap JS (5.3.3) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>
<!-- Font Awesome (6.6.0) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css" crossorigin="anonymous">

<script type="text/javascript">
try {
const titans = {
warlord: [
{
name: "Eclipse Variant",
speed: "7/14",
vsg: 6,
br: 930,
weapons: {
left_arm: "Macro-cannon (1)",
right_arm: "Chain fist",
left_carapace: "Plasma gun (4)",
right_carapace: "Las-cannon (4)"
}
}
]
};

const weaponStats = {
"Macro-cannon": { short: 72, long: 0, toHitShort: 3, toHitLong: null, damage: 2 },
"Chain fist": { cc: true, toHit: 3, damage: 2 },
"Plasma gun": { short: 36, long: 72, toHitShort: 4, toHitLong: 6, damage: 1 },
"Las-cannon": { short: 30, long: 60, toHitShort: 4, toHitLong: 6, damage: 1 }
};

const hitLocations = {
1: "Left Arm",
2: "Right Arm",
3: "Carapace",
4: "Body",
5: "Body",
6: "Reactor"
};

function determineOrder(distance) {
if (distance <= 12) return "CHARGE";
if (distance <= 24) return "ADVANCE";
return "FIRST FIRE";
}

function rollDice(num) {
return Array.from({ length: num }, () => Math.ceil(Math.random() * 6));
}

document.addEventListener("DOMContentLoaded", function() {
const appElement = document.createElement('div');
appElement.className = "p-4 max-w-4xl mx-auto grid gap-6";

let numTitans = 1;
const titanList = [];

const createTitanUI = () => {
const maxTitansContainer = document.createElement('div');

const title = document.createElement('h2');
title.className = "text-xl font-bold mb-2";
title.textContent = "How Many Titans?";
maxTitansContainer.appendChild(title);

const titanInput = document.createElement('input');
titanInput.type = "number";
titanInput.min = 1;
titanInput.value = numTitans;
titanInput.className = "form-control mb-2";
titanInput.addEventListener('input', (e) => {
numTitans = parseInt(e.target.value);
});
maxTitansContainer.appendChild(titanInput);

const createButton = document.createElement('button');
createButton.className = "btn btn-primary";
createButton.textContent = "Create Titans";
createButton.onclick = initializeTitans;
maxTitansContainer.appendChild(createButton);

appElement.appendChild(maxTitansContainer);
};

const initializeTitans = () => {
while (titanList.length > 0) { titanList.pop(); }
const newTitans = Array.from({ length: numTitans }, (_, index) => ({
id: index,
variant: titans.warlord[0],
distance: 0,
order: "",
selectedWeapon: "",
rollResult: [],
hits: 0,
damage: 0,
status: "Operational",
criticalHits: []
}));
titanList.push(...newTitans);
renderTitans();
};

const updateTitan = (index, changes) => {
titanList[index] = { ...titanList[index], ...changes };
renderTitans();
};

const renderTitans = () => {
titanList.forEach((titan, i) => {
const titanCard = document.createElement('div');
titanCard.className = "card";
titanCard.innerHTML = `
<div class="card-body">
<h2 class="text-xl font-bold mb-2">Titan #${i + 1}</h2>
<p><strong>Status:</strong> ${titan.status}</p>
<p><strong>Damage:</strong> ${titan.damage}</p>
<p><strong>Speed:</strong> ${titan.variant.speed}</p>
<p><strong>Void Shields:</strong> ${titan.variant.vsg}</p>
<p><strong>Battle Rating:</strong> ${titan.variant.br}</p>
<h3 class="text-lg font-semibold mt-4">Weapons</h3>
${Object.entries(titan.variant.weapons).map(([slot, weapon]) => `<p><strong>${slot.replace("_", " ")}:</strong> ${weapon}</p>`).join('')}

<input type="number" placeholder="Distance in cm" value="${titan.distance}" class="form-control mt-4" oninput="updateTitan(${i}, {distance: parseInt(this.value), order: determineOrder(parseInt(this.value))})"/>
${titan.order ? `<p><strong>Suggested Order:</strong> ${titan.order}</p>` : ''}

<select class="form-control" onchange="updateTitan(${i}, { selectedWeapon: this.value })">
<option value="">Select weapon</option>
${Object.keys(titan.variant.weapons).map(slot => `<option value="${slot}">${slot.replace("_", " ")}</option>`).join('')}
</select>

<button class="btn btn-warning mt-2" onclick="handleFire(${i})">Fire at Titan</button>
${titan.rollResult.length > 0 ? `
<div class="mt-2">
<p><strong>Rolls:</strong> ${titan.rollResult.join(", ")}</p>
<p><strong>Hits:</strong> ${titan.hits}</p>
<p><strong>Critical Results:</strong></p>
<ul class="list-disc list-inside">
${titan.criticalHits.map((hit, idx) => `<li>${hit}</li>`).join('')}
</ul>
</div>` : ''}
</div>`;
appElement.appendChild(titanCard);
});
};

const handleFire = (index) => {
const titan = titanList[index];
const weaponName = titan.variant.weapons[titan.selectedWeapon];
if (!weaponName || titan.status === "Titan Death") return;

const baseName = weaponName.split(" (")[0];
const match = weaponName.match(/\((\d+)\)/);
const diceCount = match ? parseInt(match[1]) : 1;
const rolls = rollDice(diceCount);
const stats = weaponStats[baseName];

let requiredToHit = stats?.cc ? stats.toHit : (titan.distance <= stats.short ? stats.toHitShort : stats.toHitLong ?? 6);
if (titan.order === "FIRST FIRE") requiredToHit--;
if (titan.order === "CHARGE") requiredToHit++;

const validHits = rolls.filter((roll) => roll >= requiredToHit);
let newCrits = [...titan.criticalHits];

validHits.forEach(() => {
const locationRoll = rollDice(1)[0];
const critCheck = rollDice(1)[0];
const location = hitLocations[locationRoll];
const severity = critCheck >= 4 ? "CRITICAL" : "SUPERFICIAL";
newCrits.push(`${severity} hit to ${location}`);
});

const totalDamage = validHits.length * (stats.damage || 1);
const newDamage = titan.damage + totalDamage;

updateTitan(index, {
rollResult: rolls,
hits: validHits.length,
damage: newDamage,
status: newDamage >= 10 ? "Titan Death" : "Operational",
criticalHits: newCrits
});
};

createTitanUI();
document.getElementById('main-container').appendChild(appElement);
});

} catch (error) {
throw error;
}
</script>

<style>
body {
background: linear-gradient(to right, #FFEFBA, #FFFFFF);
color: #2D3748;
font-family: 'Arial', sans-serif;
}
.card {
background: #F3F4F6;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
.btn-primary {
background-color: #007BFF;
color: white;
border: none;
}
.btn-warning {
background-color: #FFC107;
color: #212529;
}
</style>
</head>
<body>
<div id="main-container" class="container">
<!-- App HTML Goes Here -->
</div>
</body>
</html>