-
${symbol}
-
${crypto.name}
+
-
$${crypto.price.toFixed(2)}
-
${changeSign}${(crypto.change * 100).toFixed(2)}%
-
-
Купить
-
Продать
+
+ Купить на $100
+ Купить на $1000
+ 10%
+ Продать всё
+ ${hasPortfolio ? `
+
+ У вас: ${myState.portfolio[symbol].toFixed(6)} ${symbol}
+ (≈$${(myState.portfolio[symbol] * crypto.price).toFixed(2)})
+
+ ` : ''}
`;
}
@@ -430,13 +530,22 @@
let html = '';
for (let symbol in myState.portfolio) {
const amount = myState.portfolio[symbol];
+ if (amount < 0.000001) continue;
const value = amount * cryptos[symbol].price;
totalValue += value;
html += `
-
${symbol}
-
${amount.toFixed(6)}
-
$${value.toFixed(2)}
+
+
+ ${amount.toFixed(6)} ${symbol}
+
+
+ Продать всё за $${value.toFixed(2)}
+
`;
}
@@ -447,33 +556,43 @@
document.getElementById('cryptoValue').textContent = '$' + Math.floor(totalValue).toLocaleString();
}
- function buyCrypto(symbol) {
- const amount = parseFloat(prompt(`Сколько ${symbol} купить? (цена: $${cryptos[symbol].price.toFixed(2)})`));
- if (!amount || amount <= 0) return;
- const cost = amount * cryptos[symbol].price;
- if (myState.cash < cost) {
- log('Недостаточно средств', 'error');
+ // Покупка на указанную сумму в долларах (ИСПРАВЛЕНО!)
+ function buyCryptoAmount(symbol, amountUsd) {
+ const price = cryptos[symbol].price;
+ if (myState.cash < amountUsd) {
+ log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${amountUsd})`, 'error');
return;
}
- myState.cash -= cost;
+ const amount = amountUsd / price;
+ myState.cash -= amountUsd;
myState.portfolio[symbol] = (myState.portfolio[symbol] || 0) + amount;
- log(`Куплено ${amount} ${symbol} за $${cost.toFixed(2)}`, 'success');
+ log(`Куплено ${amount.toFixed(6)} ${symbol} за $${amountUsd}`, 'success');
+ saveState();
renderCrypto();
updateUI();
}
- function sellCrypto(symbol) {
- const amount = parseFloat(prompt(`Сколько ${symbol} продать? (есть: ${myState.portfolio[symbol]})`));
- if (!amount || amount <= 0) return;
- if (myState.portfolio[symbol] < amount) {
- log('Недостаточно криптовалюты', 'error');
+ // Покупка на процент от денег
+ function buyCryptoPercent(symbol, percent) {
+ const amountUsd = myState.cash * percent;
+ buyCryptoAmount(symbol, amountUsd);
+ }
+
+ // Продажа процента от криптовалюты
+ function sellCryptoPercent(symbol, percent) {
+ if (!myState.portfolio[symbol] || myState.portfolio[symbol] < 0.000001) {
+ log(`У вас нет ${symbol}`, 'error');
return;
}
+ const amount = myState.portfolio[symbol] * percent;
const revenue = amount * cryptos[symbol].price;
myState.cash += revenue;
myState.portfolio[symbol] -= amount;
- if (myState.portfolio[symbol] < 0.000001) delete myState.portfolio[symbol];
- log(`Продано ${amount} ${symbol} за $${revenue.toFixed(2)}`, 'success');
+ if (myState.portfolio[symbol] < 0.000001) {
+ delete myState.portfolio[symbol];
+ }
+ log(`Продано ${amount.toFixed(6)} ${symbol} за $${revenue.toFixed(2)}`, 'success');
+ saveState();
renderCrypto();
updateUI();
}
@@ -482,10 +601,10 @@
// ПЕРЕВОДЫ
// ═══════════════════════════════════════════════════════════
async function transferFrom(source) {
- if (!api) { log('API недоступен', 'error'); return; }
+ if (!api) { log('API недоступен для переводов', 'error'); return; }
const input = document.getElementById(source === 'clicker' ? 'fromClicker' : 'fromInvestor');
const amount = parseFloat(input.value);
- if (!amount || amount <= 0) { log('Введите сумму', 'error'); return; }
+ if (!amount || amount <= 0) { log('Введите корректную сумму', 'error'); return; }
try {
let sourceTable, sourceSave, sourceKey;
@@ -509,7 +628,7 @@
const available = source === 'clicker' ? state.score : state.capital;
if (available < amount) {
- log('Недостаточно средств в источнике', 'error');
+ log(`Недостаточно средств в источнике (есть ${Math.floor(available)}, нужно ${amount})`, 'error');
return;
}
@@ -527,8 +646,9 @@
}, sourceSave, source);
myState.cash += amount;
- log(`Получено $${amount} из ${source}`, 'success');
+ log(`Получено $${amount.toLocaleString()} из ${source}`, 'success');
input.value = '';
+ saveState();
updateUI();
await refreshAvailable();
} catch (e) {
@@ -537,11 +657,14 @@
}
async function transferTo(target) {
- if (!api) { log('API недоступен', 'error'); return; }
+ if (!api) { log('API недоступен для переводов', 'error'); return; }
const input = document.getElementById(target === 'clicker' ? 'toClicker' : 'toInvestor');
const amount = parseFloat(input.value);
- if (!amount || amount <= 0) { log('Введите сумму', 'error'); return; }
- if (myState.cash < amount) { log('Недостаточно средств', 'error'); return; }
+ if (!amount || amount <= 0) { log('Введите корректную сумму', 'error'); return; }
+ if (myState.cash < amount) {
+ log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${amount})`, 'error');
+ return;
+ }
try {
let targetTable, targetSave, targetKey;
@@ -576,8 +699,9 @@
}, targetSave, target);
myState.cash -= amount;
- log(`Отправлено $${amount} в ${target}`, 'success');
+ log(`Отправлено $${amount.toLocaleString()} в ${target}`, 'success');
input.value = '';
+ saveState();
updateUI();
} catch (e) {
log('Ошибка перевода: ' + e.message, 'error');
@@ -616,12 +740,17 @@
container.innerHTML += `
-
+
${stage.name}
Стоимость: $${stage.cost.toLocaleString()} | Время: ${stage.time}с
- ${isActive ? `
Строить ` : ''}
+ ${isActive && !isCompleted ? `
+
+ ${myState.house.progress > 0 ? '⚡ Ускорить' : '🏗️ Начать строить'}
+
+ ` : ''}
${isCompleted ? '
✓ Готово
' : ''}
${isActive ? `
@@ -641,12 +770,19 @@
}
const stage = houseStages[myState.house.stage];
if (myState.cash < stage.cost) {
- log('Недостаточно средств', 'error');
+ log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${stage.cost})`, 'error');
return;
}
- myState.cash -= stage.cost;
- myState.house.progress = 0;
- log(`Начато строительство: ${stage.name}`, 'success');
+ if (myState.house.progress === 0) {
+ myState.cash -= stage.cost;
+ }
+ myState.house.progress += 10;
+ if (myState.house.progress >= 100) {
+ myState.house.stage++;
+ myState.house.progress = 0;
+ log(`Этап "${stage.name}" завершён!`, 'success');
+ }
+ saveState();
renderHouse();
updateUI();
}
@@ -663,7 +799,10 @@
${biz.name}
-
Доход: $${biz.income}/сек
+
+ Доход: $${biz.income}/сек
+ ${owned ? ` | Работников: ${myState.businesses[biz.id].workers} | Эффективность: x${myState.businesses[biz.id].efficiency.toFixed(1)}` : ''}
+
$${biz.cost.toLocaleString()}
b.id === id);
if (myState.cash < biz.cost) {
- log('Недостаточно средств', 'error');
+ log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${biz.cost})`, 'error');
return;
}
myState.cash -= biz.cost;
myState.businesses[id] = { workers: 1, efficiency: 1 };
log(`Куплен бизнес: ${biz.name}`, 'success');
+ saveState();
renderBusinesses();
updateUI();
}
function manageBusiness(id) {
const biz = businesses.find(b => b.id === id);
- const action = prompt(`Управление: ${biz.name}\n1. Нанять работника ($${biz.cost / 10})\n2. Уволить работника\n3. Улучшить эффективность ($${biz.cost / 5})\nВведите номер:`);
+ const hireCost = Math.floor(biz.cost / 10);
+ const upgradeCost = Math.floor(biz.cost / 5);
+
+ const action = prompt(
+ `Управление: ${biz.name}\n\n` +
+ `Текущее состояние:\n` +
+ `- Работников: ${myState.businesses[id].workers}\n` +
+ `- Эффективность: x${myState.businesses[id].efficiency.toFixed(1)}\n` +
+ `- Доход: $${Math.floor(biz.income * myState.businesses[id].workers * myState.businesses[id].efficiency)}/сек\n\n` +
+ `Действия:\n` +
+ `1. Нанять работника ($${hireCost.toLocaleString()})\n` +
+ `2. Уволить работника (бесплатно)\n` +
+ `3. Улучшить эффективность x1.5 ($${upgradeCost.toLocaleString()})\n\n` +
+ `Введите номер действия:`
+ );
if (action === '1') {
- const cost = biz.cost / 10;
- if (myState.cash < cost) { log('Недостаточно средств', 'error'); return; }
- myState.cash -= cost;
+ if (myState.cash < hireCost) {
+ log(`Недостаточно средств (нужно $${hireCost})`, 'error');
+ return;
+ }
+ myState.cash -= hireCost;
myState.businesses[id].workers++;
log(`Нанят работник в ${biz.name}`, 'success');
} else if (action === '2') {
@@ -707,12 +863,15 @@
log('Нельзя уволить последнего работника', 'error');
}
} else if (action === '3') {
- const cost = biz.cost / 5;
- if (myState.cash < cost) { log('Недостаточно средств', 'error'); return; }
- myState.cash -= cost;
+ if (myState.cash < upgradeCost) {
+ log(`Недостаточно средств (нужно $${upgradeCost})`, 'error');
+ return;
+ }
+ myState.cash -= upgradeCost;
myState.businesses[id].efficiency *= 1.5;
- log(`Улучшена эффективность ${biz.name}`, 'success');
+ log(`Улучшена эффективность ${biz.name} до x${myState.businesses[id].efficiency.toFixed(1)}`, 'success');
}
+ saveState();
renderBusinesses();
updateUI();
}
@@ -744,13 +903,18 @@
function buyLuxury(id) {
const item = luxuryItems.find(i => i.id === id);
+ if (myState.luxury[id]) {
+ log('У вас уже есть этот предмет', 'error');
+ return;
+ }
if (myState.cash < item.cost) {
- log('Недостаточно средств', 'error');
+ log(`Недостаточно средств (есть $${Math.floor(myState.cash)}, нужно $${item.cost})`, 'error');
return;
}
myState.cash -= item.cost;
myState.luxury[id] = true;
log(`Куплено: ${item.name}`, 'success');
+ saveState();
renderLuxury();
updateUI();
}
@@ -759,7 +923,6 @@
// ИГРОВОЙ ЦИКЛ
// ═══════════════════════════════════════════════════════════
function tick() {
- // Доход от бизнесов
let totalIncome = 0;
for (let id in myState.businesses) {
const biz = businesses.find(b => b.id === id);
@@ -771,7 +934,6 @@
myState.cash += totalIncome;
}
- // Строительство дома
if (myState.house.stage < houseStages.length && myState.house.progress > 0) {
const stage = houseStages[myState.house.stage];
myState.house.progress += (100 / stage.time);