EU-Utility/projects/EU-Utility/plugins/dpp_calculator/plugin.py

216 lines
7.2 KiB
Python

"""
EU-Utility - DPP Calculator Plugin
Calculate Damage Per PEC for weapons and setups.
"""
from decimal import Decimal, ROUND_HALF_UP
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QComboBox, QTableWidget,
QTableWidgetItem, QFrame, QGroupBox
)
from PyQt6.QtCore import Qt
from plugins.base_plugin import BasePlugin
class DPPCalculatorPlugin(BasePlugin):
"""Calculate weapon efficiency and DPP."""
name = "DPP Calculator"
version = "1.0.0"
author = "ImpulsiveFPS"
description = "Calculate Damage Per PEC and weapon efficiency"
hotkey = "ctrl+shift+d"
def initialize(self):
"""Setup DPP calculator."""
self.saved_setups = []
def get_ui(self):
"""Create DPP calculator UI."""
widget = QWidget()
widget.setStyleSheet("background: transparent;")
layout = QVBoxLayout(widget)
layout.setSpacing(15)
layout.setContentsMargins(0, 0, 0, 0)
# Title
title = QLabel("🎯 DPP Calculator")
title.setStyleSheet("color: white; font-size: 16px; font-weight: bold;")
layout.addWidget(title)
# Calculator section
calc_group = QGroupBox("Weapon Setup")
calc_group.setStyleSheet("""
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;
}
""")
calc_layout = QVBoxLayout(calc_group)
# Weapon damage
dmg_layout = QHBoxLayout()
dmg_layout.addWidget(QLabel("Damage:"))
self.dmg_input = QLineEdit()
self.dmg_input.setPlaceholderText("e.g., 45.2")
dmg_layout.addWidget(self.dmg_input)
calc_layout.addLayout(dmg_layout)
# Ammo cost
ammo_layout = QHBoxLayout()
ammo_layout.addWidget(QLabel("Ammo per shot:"))
self.ammo_input = QLineEdit()
self.ammo_input.setPlaceholderText("e.g., 100")
ammo_layout.addWidget(self.ammo_input)
calc_layout.addLayout(ammo_layout)
# Weapon decay
decay_layout = QHBoxLayout()
decay_layout.addWidget(QLabel("Decay (PEC):"))
self.decay_input = QLineEdit()
self.decay_input.setPlaceholderText("e.g., 2.5")
decay_layout.addWidget(self.decay_input)
calc_layout.addLayout(decay_layout)
# Amp/scope
amp_layout = QHBoxLayout()
amp_layout.addWidget(QLabel("Amp decay:"))
self.amp_input = QLineEdit()
self.amp_input.setPlaceholderText("0")
self.amp_input.setText("0")
amp_layout.addWidget(self.amp_input)
calc_layout.addLayout(amp_layout)
# Calculate button
calc_btn = QPushButton("Calculate DPP")
calc_btn.setStyleSheet("""
QPushButton {
background-color: #ff8c42;
color: white;
padding: 10px;
border: none;
border-radius: 4px;
font-weight: bold;
}
QPushButton:hover {
background-color: #ffa060;
}
""")
calc_btn.clicked.connect(self._calculate)
calc_layout.addWidget(calc_btn)
# Results
self.result_label = QLabel("DPP: -")
self.result_label.setStyleSheet("""
color: #4caf50;
font-size: 20px;
font-weight: bold;
""")
calc_layout.addWidget(self.result_label)
self.cost_label = QLabel("Cost per shot: -")
self.cost_label.setStyleSheet("color: rgba(255,255,255,150);")
calc_layout.addWidget(self.cost_label)
layout.addWidget(calc_group)
# Reference table
ref_group = QGroupBox("DPP Reference")
ref_group.setStyleSheet(calc_group.styleSheet())
ref_layout = QVBoxLayout(ref_group)
ref_table = QTableWidget()
ref_table.setColumnCount(3)
ref_table.setHorizontalHeaderLabels(["Rating", "DPP Range", "Efficiency"])
ref_table.setRowCount(5)
ratings = [
("Excellent", "4.0+", "95-100%"),
("Very Good", "3.5-4.0", "85-95%"),
("Good", "3.0-3.5", "75-85%"),
("Average", "2.5-3.0", "60-75%"),
("Poor", "< 2.5", "< 60%"),
]
for i, (rating, dpp, eff) in enumerate(ratings):
ref_table.setItem(i, 0, QTableWidgetItem(rating))
ref_table.setItem(i, 1, QTableWidgetItem(dpp))
ref_table.setItem(i, 2, QTableWidgetItem(eff))
ref_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;
}
""")
ref_layout.addWidget(ref_table)
layout.addWidget(ref_group)
layout.addStretch()
return widget
def _calculate(self):
"""Calculate DPP."""
try:
damage = Decimal(self.dmg_input.text() or 0)
ammo = Decimal(self.ammo_input.text() or 0)
decay = Decimal(self.decay_input.text() or 0)
amp = Decimal(self.amp_input.text() or 0)
# Convert ammo to PEC (1 ammo = 0.0001 PED = 0.01 PEC)
ammo_cost = ammo * Decimal('0.01')
# Total cost in PEC
total_cost = ammo_cost + decay + amp
if total_cost > 0:
dpp = damage / (total_cost / Decimal('100')) # Convert to PED for DPP
self.result_label.setText(f"DPP: {dpp:.3f}")
self.result_label.setStyleSheet(f"""
color: {'#4caf50' if dpp >= Decimal('3.5') else '#ffc107' if dpp >= Decimal('2.5') else '#f44336'};
font-size: 20px;
font-weight: bold;
""")
cost_ped = total_cost / Decimal('100')
self.cost_label.setText(f"Cost per shot: {cost_ped:.4f} PED ({total_cost:.2f} PEC)")
else:
self.result_label.setText("DPP: Enter values")
except Exception as e:
self.result_label.setText(f"Error: {e}")
def calculate_from_api(self, weapon_data):
"""Calculate DPP from Nexus API weapon data."""
damage = Decimal(str(weapon_data.get('damage', 0)))
decay = Decimal(str(weapon_data.get('decay', 0)))
ammo = Decimal(str(weapon_data.get('ammo', 0)))
# Calculate
ammo_cost = ammo * Decimal('0.01')
total_cost = ammo_cost + decay
if total_cost > 0:
return damage / (total_cost / Decimal('100'))
return Decimal('0')