Always show Attack column for your faction; toggle all grey "Attack" labels into real links (both teams).
// ==UserScript==
// @name FreeForAll - AttackButtons
// @namespace http://tampermonkey.net/
// @version 5.2
// @description Always show Attack column for your faction; toggle all grey "Attack" labels into real links (both teams).
// @match https://www.torn.com/factions.php*
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
// --- settings ---
const DEBUG = true;
// toggle state: when true, convert grey Attack spans to real links; when false, revert to grey spans
let linksEnabled = true;
const log = (...a) => DEBUG && console.log('[AttackToggle]', ...a);
// --- CSS: keep your-faction Attack column visible; style our links ---
(function addStyles() {
const css = `
/* Force show Attack column in your-faction (header + cells) */
.tab-menu-cont.your-faction .attack,
.tab-menu-cont.your-faction .attack.left,
.tab-menu-cont.your-faction .attack___wBWp2 {
display: inline-block !important;
visibility: visible !important;
opacity: 1 !important;
pointer-events: auto !important;
}
/* Make sure header keeps space for Attack */
.tab-menu-cont.your-faction .members-cont > .white-grad .attack {
display: inline-block !important;
}
/* Our injected attack link */
a.custom-attack-button {
text-decoration: none !important;
padding: 0px 2px;
border-radius: 2px;
cursor: pointer;
margin-left: 4px;
color: white !important;
background: #0078d4 !important;
display: inline-block;
}
`;
const s = document.createElement('style');
s.textContent = css;
document.head.appendChild(s);
})();
function fixYourFactionWidth() {
const faction = document.querySelector('.tab-menu-cont.your-faction');
if (!faction) return;
// Shrink the container width to leave room for the Attack column
//faction.style.width = 'calc(50%)'; // tweak 40px as needed
//faction.style.boxSizing = 'border-box';
faction.querySelectorAll(`div[class*="points"]`).forEach(cell => {
cell.style.width = '10%'; // adjust % as needed
cell.style.minWidth = '0'; // allow shrinking
});
faction.querySelectorAll(`div[class*="attack"]`).forEach(cell => {
cell.style.width = '3%'; // adjust % as needed
cell.style.minWidth = '0'; // allow shrinking
});
faction.querySelectorAll(`div[class*="level"]`).forEach(cell => {
cell.style.width = '8%'; // adjust % as needed
cell.style.minWidth = '0'; // allow shrinking
});
}
// --- helpers ---
function showElementHard(el) {
if (!el) return;
el.style.setProperty('display', 'inline-block', 'important');
el.style.setProperty('visibility', 'visible', 'important');
el.style.setProperty('opacity', '1', 'important');
el.style.setProperty('pointer-events', 'auto', 'important');
}
function ensureYourFactionHeader() {
const root = document.querySelector('.tab-menu-cont.your-faction');
if (!root) return;
const header = root.querySelector('.members-cont > .white-grad');
if (!header) return;
let attackHeader = header.querySelector('.attack');
if (!attackHeader) {
attackHeader = document.createElement('div');
attackHeader.className = 'attack left attack___wBWp2 tab___UztMc';
attackHeader.textContent = 'Attack';
header.appendChild(attackHeader);
log('Created Attack header for your faction');
}
showElementHard(attackHeader);
}
function ensureYourFactionCells() {
// Make sure each teammate row has an attack cell so the column keeps shape.
const yourRows = document.querySelectorAll('.tab-menu-cont.your-faction ul.members-list li.your');
yourRows.forEach(li => {
let attackCell = li.querySelector('.attack');
if (!attackCell) {
attackCell = document.createElement('div');
attackCell.className = 'attack left attack___wBWp2';
// Insert near the end like Torn usually does
const clearEl = li.querySelector('.clear');
li.insertBefore(attackCell, clearEl || null);
}
showElementHard(attackCell);
});
}
function xidFromRow(li) {
const profileLink = li.querySelector('a[href^="/profiles.php?XID="]');
if (!profileLink) return null;
const m = profileLink.href.match(/XID=(\d+)/);
return m ? m[1] : null;
}
// Convert the attack cell for a single row according to linksEnabled
function transformAttackCellForRow(li) {
let attackCell = li.querySelector('.attack');
if (!attackCell) return;
// Always keep the cell visible
if (li.classList.contains('your')) showElementHard(attackCell);
// Only create the link once
let link = attackCell.querySelector('a.custom-attack-button');
if (!link && linksEnabled) {
const xid = xidFromRow(li);
if (!xid) return;
link = document.createElement('a');
link.href = `https://www.torn.com/loader.php?sid=attack&user2ID=${xid}`;
link.textContent = 'Attack';
link.className = 'custom-attack-button';
link.target = '_blank';
link.rel = 'noopener noreferrer';
attackCell.appendChild(link);
// Hide the grey span if present
attackCell.querySelectorAll('span.t-gray-9').forEach(s => s.style.display = 'none');
}
// Instead of removing/adding nodes, just show/hide via style
if (link) link.style.display = linksEnabled ? 'inline-block' : 'none';
attackCell.querySelectorAll('span.t-gray-9').forEach(span => {
span.style.display = linksEnabled ? 'none' : 'inline-block';
});
}
function transformAllRows() {
// Always keep your-faction column visible
fixYourFactionWidth();
ensureYourFactionHeader();
ensureYourFactionCells();
// Apply toggle behavior to ALL rows (both teams)
const rows = document.querySelectorAll('ul.members-list > li');
rows.forEach(transformAttackCellForRow);
}
// --- toggle button ---
function createToggleButton() {
const button = document.createElement('button');
button.textContent = 'Attack Links: ON';
button.style.position = 'fixed';
button.style.bottom = '5%';
button.style.right = '10px';
button.style.zIndex = '2147483647';
button.style.padding = '6px 10px';
button.style.backgroundColor = '#008CBA';
button.style.color = 'white';
button.style.border = 'none';
button.style.borderRadius = '5px';
button.style.cursor = 'pointer';
button.style.fontSize = '14px';
button.style.boxShadow = '0 0 5px rgba(0,0,0,0.3)';
button.addEventListener('click', () => {
linksEnabled = !linksEnabled;
button.textContent = `Attack Links: ${linksEnabled ? 'ON' : 'OFF'}`;
button.style.backgroundColor = linksEnabled ? '#008CBA' : '#777';
// This now only toggles visibility, no DOM removal
transformAllRows();
});
document.body.appendChild(button);
}
// --- observers / boot ---
let debounce;
const mo = new MutationObserver(() => {
clearTimeout(debounce);
debounce = setTimeout(transformAllRows, 200);
});
function start() {
createToggleButton();
transformAllRows();
mo.observe(document.body, { childList: true, subtree: true });
log('Initialized');
}
// Delay a touch to let Torn render
setTimeout(start, 600);
})();