220 lines
7.0 KiB
Python
220 lines
7.0 KiB
Python
"""
|
|
EU-Utility - Crafting Calculator Plugin
|
|
|
|
Calculate crafting success rates and material costs.
|
|
"""
|
|
|
|
from PyQt6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QPushButton, QComboBox, QLineEdit, QTableWidget,
|
|
QTableWidgetItem, QFrame, QGroupBox
|
|
)
|
|
from PyQt6.QtCore import Qt
|
|
|
|
from plugins.base_plugin import BasePlugin
|
|
|
|
|
|
class CraftingCalculatorPlugin(BasePlugin):
|
|
"""Calculate crafting costs and success rates."""
|
|
|
|
name = "Crafting Calc"
|
|
version = "1.0.0"
|
|
author = "ImpulsiveFPS"
|
|
description = "Crafting success rates and material costs"
|
|
hotkey = "ctrl+shift+b" # B for Blueprint
|
|
|
|
# Sample blueprints data
|
|
BLUEPRINTS = {
|
|
'Weapon': [
|
|
'ArMatrix LP-35 (L)',
|
|
'ArMatrix BP-25 (L)',
|
|
'Omegaton M83 Predator',
|
|
],
|
|
'Armor': [
|
|
'Vigiator Harness (M)',
|
|
'Vigiator Thighs (M)',
|
|
],
|
|
'Tool': [
|
|
'Ziplex Z1 Seeker',
|
|
'Ziplex Z3 Seeker',
|
|
],
|
|
'Material': [
|
|
'Metal Residue',
|
|
'Energy Matter Residue',
|
|
],
|
|
}
|
|
|
|
def initialize(self):
|
|
"""Setup crafting calculator."""
|
|
self.saved_recipes = []
|
|
|
|
def get_ui(self):
|
|
"""Create crafting calculator UI."""
|
|
widget = QWidget()
|
|
widget.setStyleSheet("background: transparent;")
|
|
layout = QVBoxLayout(widget)
|
|
layout.setSpacing(15)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
# Title
|
|
title = QLabel("🔨 Crafting Calculator")
|
|
title.setStyleSheet("color: white; font-size: 16px; font-weight: bold;")
|
|
layout.addWidget(title)
|
|
|
|
# Blueprint selector
|
|
bp_group = QGroupBox("Blueprint")
|
|
bp_group.setStyleSheet(self._group_style())
|
|
bp_layout = QVBoxLayout(bp_group)
|
|
|
|
# Category
|
|
cat_layout = QHBoxLayout()
|
|
cat_layout.addWidget(QLabel("Category:"))
|
|
self.cat_combo = QComboBox()
|
|
self.cat_combo.addItems(list(self.BLUEPRINTS.keys()))
|
|
self.cat_combo.currentTextChanged.connect(self._update_blueprints)
|
|
cat_layout.addWidget(self.cat_combo)
|
|
bp_layout.addLayout(cat_layout)
|
|
|
|
# Blueprint
|
|
bp_layout2 = QHBoxLayout()
|
|
bp_layout2.addWidget(QLabel("Blueprint:"))
|
|
self.bp_combo = QComboBox()
|
|
self._update_blueprints(self.cat_combo.currentText())
|
|
bp_layout2.addWidget(self.bp_combo)
|
|
bp_layout.addLayout(bp_layout2)
|
|
|
|
# QR
|
|
qr_layout = QHBoxLayout()
|
|
qr_layout.addWidget(QLabel("QR:"))
|
|
self.qr_input = QLineEdit()
|
|
self.qr_input.setPlaceholderText("1.0")
|
|
self.qr_input.setText("1.0")
|
|
qr_layout.addWidget(self.qr_input)
|
|
bp_layout.addLayout(qr_layout)
|
|
|
|
layout.addWidget(bp_group)
|
|
|
|
# Materials
|
|
mat_group = QGroupBox("Materials")
|
|
mat_group.setStyleSheet(self._group_style())
|
|
mat_layout = QVBoxLayout(mat_group)
|
|
|
|
self.mat_table = QTableWidget()
|
|
self.mat_table.setColumnCount(4)
|
|
self.mat_table.setHorizontalHeaderLabels(["Material", "Needed", "Have", "Buy"])
|
|
self.mat_table.setRowCount(3)
|
|
|
|
sample_mats = [
|
|
("Lysterium Ingot", 50, 0),
|
|
("Oil", 30, 10),
|
|
("Meldar Paper", 10, 5),
|
|
]
|
|
|
|
for i, (mat, needed, have) in enumerate(sample_mats):
|
|
self.mat_table.setItem(i, 0, QTableWidgetItem(mat))
|
|
self.mat_table.setItem(i, 1, QTableWidgetItem(str(needed)))
|
|
self.mat_table.setItem(i, 2, QTableWidgetItem(str(have)))
|
|
buy = needed - have if needed > have else 0
|
|
self.mat_table.setItem(i, 3, QTableWidgetItem(str(buy)))
|
|
|
|
self.mat_table.setStyleSheet("""
|
|
QTableWidget {
|
|
background-color: rgba(30, 35, 45, 200);
|
|
color: white;
|
|
border: none;
|
|
}
|
|
QHeaderView::section {
|
|
background-color: rgba(35, 40, 55, 200);
|
|
color: rgba(255,255,255,180);
|
|
padding: 6px;
|
|
font-size: 10px;
|
|
}
|
|
""")
|
|
mat_layout.addWidget(self.mat_table)
|
|
|
|
layout.addWidget(mat_group)
|
|
|
|
# Calculator
|
|
calc_group = QGroupBox("Calculator")
|
|
calc_group.setStyleSheet(self._group_style())
|
|
calc_layout = QVBoxLayout(calc_group)
|
|
|
|
# Click calculator
|
|
click_layout = QHBoxLayout()
|
|
click_layout.addWidget(QLabel("Clicks:"))
|
|
self.clicks_input = QLineEdit()
|
|
self.clicks_input.setPlaceholderText("10")
|
|
self.clicks_input.setText("10")
|
|
click_layout.addWidget(self.clicks_input)
|
|
calc_layout.addLayout(click_layout)
|
|
|
|
calc_btn = QPushButton("Calculate")
|
|
calc_btn.setStyleSheet("""
|
|
QPushButton {
|
|
background-color: #ff8c42;
|
|
color: white;
|
|
padding: 10px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
font-weight: bold;
|
|
}
|
|
""")
|
|
calc_btn.clicked.connect(self._calculate)
|
|
calc_layout.addWidget(calc_btn)
|
|
|
|
# Results
|
|
self.result_label = QLabel("Success Rate: ~45%")
|
|
self.result_label.setStyleSheet("color: #4caf50; font-weight: bold;")
|
|
calc_layout.addWidget(self.result_label)
|
|
|
|
self.cost_label = QLabel("Estimated Cost: 15.50 PED")
|
|
self.cost_label.setStyleSheet("color: #ffc107;")
|
|
calc_layout.addWidget(self.cost_label)
|
|
|
|
layout.addWidget(calc_group)
|
|
layout.addStretch()
|
|
|
|
return widget
|
|
|
|
def _group_style(self):
|
|
return """
|
|
QGroupBox {
|
|
color: rgba(255,255,255,200);
|
|
border: 1px solid rgba(100, 110, 130, 80);
|
|
border-radius: 6px;
|
|
margin-top: 10px;
|
|
font-weight: bold;
|
|
}
|
|
QGroupBox::title {
|
|
subcontrol-origin: margin;
|
|
left: 10px;
|
|
padding: 0 5px;
|
|
}
|
|
"""
|
|
|
|
def _update_blueprints(self, category):
|
|
"""Update blueprint list."""
|
|
self.bp_combo.clear()
|
|
self.bp_combo.addItems(self.BLUEPRINTS.get(category, []))
|
|
|
|
def _calculate(self):
|
|
"""Calculate crafting results."""
|
|
try:
|
|
qr = float(self.qr_input.text() or 1.0)
|
|
clicks = int(self.clicks_input.text() or 10)
|
|
|
|
# Simple formula (real one is more complex)
|
|
base_rate = 0.45
|
|
qr_bonus = (qr - 1.0) * 0.05
|
|
success_rate = min(0.95, base_rate + qr_bonus)
|
|
|
|
expected_success = int(clicks * success_rate)
|
|
|
|
self.result_label.setText(
|
|
f"Success Rate: ~{success_rate*100:.1f}% | "
|
|
f"Expected: {expected_success}/{clicks}"
|
|
)
|
|
|
|
except Exception as e:
|
|
self.result_label.setText(f"Error: {e}")
|