mirror of
https://github.com/Nereziel/cs2-WeaponPaints.git
synced 2026-03-10 16:34:38 +00:00
Implement WeaponHandler class to streamline weapon and knife selection logic in index.php, enhancing maintainability and clarity. Refactor weapon update handling to utilize the new class, improving organization and reducing code duplication. Update CSS for improved button styles and layout consistency.
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
<?php
|
||||
define('SKIN_LANGUAGE', 'skins_en');
|
||||
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_HOST', '10.0.0.24');
|
||||
define('DB_PORT', '3306');
|
||||
define('DB_NAME', '');
|
||||
define('DB_USER', '');
|
||||
define('DB_PASS', '');
|
||||
define('DB_NAME', 'weaponskins_database');
|
||||
define('DB_USER', 'root');
|
||||
define('DB_PASS', 'DoOctwqOnohFSMvxLDGhGMaLGMJXjTSZBwROQeQcvFyfhkqEZHTEWMvQprOZLVco');
|
||||
|
||||
define('WEB_STYLE_DARK', true);
|
||||
|
||||
define('STEAM_API_KEY', '');
|
||||
define('STEAM_DOMAIN_NAME', '');
|
||||
define('STEAM_LOGOUT_PAGE', '');
|
||||
define('STEAM_LOGIN_PAGE', '');
|
||||
|
||||
define('STEAM_API_KEY', 'D4EA0D36F688221050E06AF062B5EA48');
|
||||
define('STEAM_DOMAIN_NAME', 'http://10.0.0.254');
|
||||
define('STEAM_LOGOUT_PAGE', 'index.php');
|
||||
define('STEAM_LOGIN_PAGE', 'index.php');
|
||||
304
website/class/weapon_handler.php
Normal file
304
website/class/weapon_handler.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
require_once 'utils.php';
|
||||
require_once 'database.php';
|
||||
|
||||
class WeaponHandler
|
||||
{
|
||||
private $db;
|
||||
private $steamid;
|
||||
|
||||
public function __construct($steamid)
|
||||
{
|
||||
$this->db = new DataBase();
|
||||
$this->steamid = $steamid;
|
||||
}
|
||||
|
||||
public function handleWeaponUpdate($postData): bool
|
||||
{
|
||||
if (!isset($postData['forma'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$formaParts = explode("-", $postData['forma']);
|
||||
|
||||
if ($formaParts[0] === "knife") {
|
||||
return $this->handleKnifeSelection($formaParts[1]);
|
||||
} else {
|
||||
return $this->handleWeaponSkin($formaParts, $postData);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleKnifeSelection($knifeId): bool
|
||||
{
|
||||
$knifes = UtilsClass::getKnifeTypes();
|
||||
|
||||
if (!isset($knifes[$knifeId])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$knifeData = $knifes[$knifeId];
|
||||
|
||||
// Clear existing knife data
|
||||
$this->clearKnifeData();
|
||||
|
||||
// Set new knife selection (insert for both teams separately)
|
||||
$this->db->query(
|
||||
"INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES (:steamid, :knife, 2)",
|
||||
["steamid" => $this->steamid, "knife" => $knifeData['weapon_name']]
|
||||
);
|
||||
|
||||
$this->db->query(
|
||||
"INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES (:steamid, :knife, 3)",
|
||||
["steamid" => $this->steamid, "knife" => $knifeData['weapon_name']]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function handleWeaponSkin($formaParts, $postData): bool
|
||||
{
|
||||
$defindex = $formaParts[0];
|
||||
$paintId = $formaParts[1];
|
||||
|
||||
$skins = UtilsClass::skinsFromJson();
|
||||
|
||||
if (!isset($skins[$defindex][$paintId]) ||
|
||||
!isset($postData['wear']) ||
|
||||
!isset($postData['seed'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$wear = $this->validateWear($postData['wear']);
|
||||
$seed = $this->validateSeed($postData['seed']);
|
||||
|
||||
if ($wear === false || $seed === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle knife skins
|
||||
if (UtilsClass::isKnifeDefindex($defindex)) {
|
||||
$this->handleKnifeSkin($defindex, $paintId, $wear, $seed);
|
||||
} else {
|
||||
$this->handleRegularWeaponSkin($defindex, $paintId, $wear, $seed);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function handleKnifeSkin($defindex, $paintId, $wear, $seed): void
|
||||
{
|
||||
$knifeMapping = UtilsClass::getKnifeMapping();
|
||||
|
||||
// Clear existing knife data
|
||||
$this->clearKnifeData();
|
||||
|
||||
// Clear other knife skins
|
||||
$knifeDefindexes = UtilsClass::getKnifeDefindexes();
|
||||
foreach ($knifeDefindexes as $knifeDefindex) {
|
||||
if ($knifeDefindex != $defindex) {
|
||||
$this->db->query(
|
||||
"DELETE FROM `wp_player_skins` WHERE `steamid` = :steamid AND `weapon_defindex` = :weapon_defindex",
|
||||
["steamid" => $this->steamid, "weapon_defindex" => $knifeDefindex]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Set knife type in wp_player_knife table
|
||||
if (isset($knifeMapping[$defindex])) {
|
||||
$this->db->query(
|
||||
"INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES (:steamid, :knife, 2)",
|
||||
["steamid" => $this->steamid, "knife" => $knifeMapping[$defindex]]
|
||||
);
|
||||
|
||||
$this->db->query(
|
||||
"INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES (:steamid, :knife, 3)",
|
||||
["steamid" => $this->steamid, "knife" => $knifeMapping[$defindex]]
|
||||
);
|
||||
}
|
||||
|
||||
// Set knife skin
|
||||
$this->upsertWeaponSkin($defindex, $paintId, $wear, $seed);
|
||||
}
|
||||
|
||||
private function handleRegularWeaponSkin($defindex, $paintId, $wear, $seed): void
|
||||
{
|
||||
$this->upsertWeaponSkin($defindex, $paintId, $wear, $seed);
|
||||
}
|
||||
|
||||
private function upsertWeaponSkin($defindex, $paintId, $wear, $seed): void
|
||||
{
|
||||
$selectedSkins = $this->getSelectedSkins();
|
||||
|
||||
if (array_key_exists($defindex, $selectedSkins)) {
|
||||
// Update existing
|
||||
$this->db->query(
|
||||
"UPDATE wp_player_skins SET weapon_paint_id = :weapon_paint_id, weapon_wear = :weapon_wear, weapon_seed = :weapon_seed WHERE steamid = :steamid AND weapon_defindex = :weapon_defindex",
|
||||
[
|
||||
"weapon_paint_id" => $paintId,
|
||||
"weapon_wear" => $wear,
|
||||
"weapon_seed" => $seed,
|
||||
"steamid" => $this->steamid,
|
||||
"weapon_defindex" => $defindex
|
||||
]
|
||||
);
|
||||
} else {
|
||||
// Insert new for both teams
|
||||
$this->db->query(
|
||||
"INSERT INTO wp_player_skins (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`, `weapon_team`) VALUES (:steamid, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed, 2)",
|
||||
[
|
||||
"steamid" => $this->steamid,
|
||||
"weapon_defindex" => $defindex,
|
||||
"weapon_paint_id" => $paintId,
|
||||
"weapon_wear" => $wear,
|
||||
"weapon_seed" => $seed
|
||||
]
|
||||
);
|
||||
|
||||
$this->db->query(
|
||||
"INSERT INTO wp_player_skins (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`, `weapon_team`) VALUES (:steamid, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed, 3)",
|
||||
[
|
||||
"steamid" => $this->steamid,
|
||||
"weapon_defindex" => $defindex,
|
||||
"weapon_paint_id" => $paintId,
|
||||
"weapon_wear" => $wear,
|
||||
"weapon_seed" => $seed
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function clearKnifeData(): void
|
||||
{
|
||||
$knifeDefindexes = UtilsClass::getKnifeDefindexes();
|
||||
|
||||
// Clear knife skins
|
||||
foreach ($knifeDefindexes as $knifeDefindex) {
|
||||
$this->db->query(
|
||||
"DELETE FROM `wp_player_skins` WHERE `steamid` = :steamid AND `weapon_defindex` = :weapon_defindex",
|
||||
["steamid" => $this->steamid, "weapon_defindex" => $knifeDefindex]
|
||||
);
|
||||
}
|
||||
|
||||
// Clear basic knife selection
|
||||
$this->db->query(
|
||||
"DELETE FROM `wp_player_knife` WHERE `steamid` = :steamid",
|
||||
["steamid" => $this->steamid]
|
||||
);
|
||||
}
|
||||
|
||||
private function validateWear($wear)
|
||||
{
|
||||
$wear = floatval($wear);
|
||||
return ($wear >= 0.00 && $wear <= 1.00) ? $wear : false;
|
||||
}
|
||||
|
||||
private function validateSeed($seed)
|
||||
{
|
||||
$seed = intval($seed);
|
||||
return ($seed >= 0) ? $seed : false;
|
||||
}
|
||||
|
||||
public function getSelectedSkins(): array
|
||||
{
|
||||
$query = $this->db->select(
|
||||
"SELECT `weapon_defindex`, MAX(`weapon_paint_id`) AS `weapon_paint_id`, MAX(`weapon_wear`) AS `weapon_wear`, MAX(`weapon_seed`) AS `weapon_seed`
|
||||
FROM `wp_player_skins`
|
||||
WHERE `steamid` = :steamid
|
||||
GROUP BY `weapon_defindex`, `steamid`",
|
||||
["steamid" => $this->steamid]
|
||||
);
|
||||
|
||||
return UtilsClass::getSelectedSkins($query ?: []);
|
||||
}
|
||||
|
||||
public function getSelectedKnife(): array
|
||||
{
|
||||
return $this->db->select(
|
||||
"SELECT * FROM `wp_player_knife` WHERE `steamid` = :steamid LIMIT 1",
|
||||
["steamid" => $this->steamid]
|
||||
) ?: [];
|
||||
}
|
||||
|
||||
public function getLoadoutData(): array
|
||||
{
|
||||
$weapons = UtilsClass::getWeaponsFromArray();
|
||||
$knifes = UtilsClass::getKnifeTypes();
|
||||
$selectedSkins = $this->getSelectedSkins();
|
||||
$selectedKnife = $this->getSelectedKnife();
|
||||
|
||||
return [
|
||||
'weapons' => $weapons,
|
||||
'knifes' => $knifes,
|
||||
'selectedSkins' => $selectedSkins,
|
||||
'selectedKnife' => $selectedKnife,
|
||||
'displayKnife' => $this->getDisplayKnife($selectedSkins, $selectedKnife, $knifes)
|
||||
];
|
||||
}
|
||||
|
||||
private function getDisplayKnife($selectedSkins, $selectedKnife, $knifes): array
|
||||
{
|
||||
$skins = UtilsClass::skinsFromJson();
|
||||
|
||||
// Check for knife skin first
|
||||
foreach ($selectedSkins as $defindex => $selectedSkin) {
|
||||
if (UtilsClass::isKnifeDefindex($defindex) && isset($skins[$defindex][$selectedSkin['weapon_paint_id']])) {
|
||||
return [
|
||||
'data' => $skins[$defindex][$selectedSkin['weapon_paint_id']],
|
||||
'source' => 'skin'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// Check for basic knife selection
|
||||
if (!empty($selectedKnife)) {
|
||||
foreach ($knifes as $knife) {
|
||||
if ($selectedKnife[0]['knife'] === $knife['weapon_name']) {
|
||||
return [
|
||||
'data' => $knife,
|
||||
'source' => 'basic'
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default knife
|
||||
return [
|
||||
'data' => $knifes[0] ?? null,
|
||||
'source' => 'default'
|
||||
];
|
||||
}
|
||||
|
||||
public function getOrganizedWeapons(): array
|
||||
{
|
||||
$weapons = UtilsClass::getWeaponsFromArray();
|
||||
$knifes = UtilsClass::getKnifeTypes();
|
||||
$categories = UtilsClass::getWeaponCategories();
|
||||
|
||||
$organized = [
|
||||
'Knives' => [],
|
||||
'Gloves' => []
|
||||
];
|
||||
|
||||
// Add weapon categories
|
||||
foreach ($categories as $categoryName => $weaponIds) {
|
||||
$organized[$categoryName] = [];
|
||||
foreach ($weaponIds as $weaponId) {
|
||||
if (isset($weapons[$weaponId])) {
|
||||
$organized[$categoryName][$weaponId] = $weapons[$weaponId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add knives (exclude default)
|
||||
foreach ($knifes as $knifeId => $knife) {
|
||||
if ($knifeId !== 0) {
|
||||
$organized['Knives'][$knifeId] = $knife;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove empty categories
|
||||
return array_filter($organized, function($category) {
|
||||
return !empty($category);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,120 +3,25 @@ require_once 'class/config.php';
|
||||
require_once 'class/database.php';
|
||||
require_once 'steamauth/steamauth.php';
|
||||
require_once 'class/utils.php';
|
||||
require_once 'class/weapon_handler.php';
|
||||
|
||||
$db = new DataBase();
|
||||
if (isset($_SESSION['steamid'])) {
|
||||
|
||||
$steamid = $_SESSION['steamid'];
|
||||
|
||||
// Fetch Steam user information
|
||||
require_once 'steamauth/userInfo.php';
|
||||
|
||||
$weapons = UtilsClass::getWeaponsFromArray();
|
||||
$skins = UtilsClass::skinsFromJson();
|
||||
$querySelected = $db->select("
|
||||
SELECT `weapon_defindex`, MAX(`weapon_paint_id`) AS `weapon_paint_id`, MAX(`weapon_wear`) AS `weapon_wear`, MAX(`weapon_seed`) AS `weapon_seed`
|
||||
FROM `wp_player_skins`
|
||||
WHERE `steamid` = :steamid
|
||||
GROUP BY `weapon_defindex`, `steamid`
|
||||
", ["steamid" => $steamid]);
|
||||
$selectedSkins = UtilsClass::getSelectedSkins($querySelected);
|
||||
$selectedKnife = $db->select("SELECT * FROM `wp_player_knife` WHERE `wp_player_knife`.`steamid` = :steamid LIMIT 1", ["steamid" => $steamid]);
|
||||
$knifes = UtilsClass::getKnifeTypes();
|
||||
|
||||
if (isset($_POST['forma'])) {
|
||||
$ex = explode("-", $_POST['forma']);
|
||||
|
||||
if ($ex[0] == "knife") {
|
||||
// Handle knife selection - use the knife key directly
|
||||
if (isset($knifes[$ex[1]])) {
|
||||
$knifeData = $knifes[$ex[1]];
|
||||
|
||||
// Clear any existing knife skins first
|
||||
$db->query("DELETE FROM `wp_player_skins` WHERE `steamid` = :steamid AND `weapon_defindex` IN (500, 503, 505, 506, 507, 508, 509, 512, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 525, 526)", ["steamid" => $steamid]);
|
||||
|
||||
// Clear any existing basic knife selection first
|
||||
$db->query("DELETE FROM `wp_player_knife` WHERE `steamid` = :steamid", ["steamid" => $steamid]);
|
||||
|
||||
// Set the new basic knife selection
|
||||
$db->query("INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES(:steamid, :knife, 2)", ["steamid" => $steamid, "knife" => $knifeData['weapon_name']]);
|
||||
$db->query("INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES(:steamid, :knife, 3)", ["steamid" => $steamid, "knife" => $knifeData['weapon_name']]);
|
||||
}
|
||||
} else {
|
||||
if (array_key_exists($ex[1], $skins[$ex[0]]) && isset($_POST['wear']) && $_POST['wear'] >= 0.00 && $_POST['wear'] <= 1.00 && isset($_POST['seed'])) {
|
||||
$wear = floatval($_POST['wear']);
|
||||
$seed = intval($_POST['seed']);
|
||||
|
||||
// If this is a knife skin, automatically equip the corresponding knife type
|
||||
if (in_array($ex[0], [500, 503, 505, 506, 507, 508, 509, 512, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 525, 526])) {
|
||||
// Map defindex to knife weapon_name
|
||||
$knifeMapping = [
|
||||
500 => 'weapon_bayonet',
|
||||
503 => 'weapon_knife_css',
|
||||
505 => 'weapon_knife_flip',
|
||||
506 => 'weapon_knife_gut',
|
||||
507 => 'weapon_knife_karambit',
|
||||
508 => 'weapon_knife_m9_bayonet',
|
||||
509 => 'weapon_knife_tactical',
|
||||
512 => 'weapon_knife_falchion',
|
||||
514 => 'weapon_knife_survival_bowie',
|
||||
515 => 'weapon_knife_butterfly',
|
||||
516 => 'weapon_knife_push',
|
||||
517 => 'weapon_knife_cord',
|
||||
518 => 'weapon_knife_canis',
|
||||
519 => 'weapon_knife_ursus',
|
||||
520 => 'weapon_knife_gypsy_jackknife',
|
||||
521 => 'weapon_knife_outdoor',
|
||||
522 => 'weapon_knife_stiletto',
|
||||
523 => 'weapon_knife_widowmaker',
|
||||
525 => 'weapon_knife_skeleton',
|
||||
526 => 'weapon_knife_css'
|
||||
];
|
||||
|
||||
// Clear any existing basic knife selection
|
||||
$db->query("DELETE FROM `wp_player_knife` WHERE `steamid` = :steamid", ["steamid" => $steamid]);
|
||||
|
||||
// Clear ALL other knife skins (to handle switching between knife types)
|
||||
$db->query("DELETE FROM `wp_player_skins` WHERE `steamid` = :steamid AND `weapon_defindex` IN (500, 503, 505, 506, 507, 508, 509, 512, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 525, 526) AND `weapon_defindex` != :current_defindex", ["steamid" => $steamid, "current_defindex" => $ex[0]]);
|
||||
|
||||
// Set the corresponding knife type in wp_player_knife table
|
||||
if (isset($knifeMapping[$ex[0]])) {
|
||||
$knifeWeaponName = $knifeMapping[$ex[0]];
|
||||
$db->query("INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES(:steamid, :knife, 2)", ["steamid" => $steamid, "knife" => $knifeWeaponName]);
|
||||
$db->query("INSERT INTO `wp_player_knife` (`steamid`, `knife`, `weapon_team`) VALUES(:steamid, :knife, 3)", ["steamid" => $steamid, "knife" => $knifeWeaponName]);
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists($ex[0], $selectedSkins)) {
|
||||
$db->query("UPDATE wp_player_skins SET weapon_paint_id = :weapon_paint_id, weapon_wear = :weapon_wear, weapon_seed = :weapon_seed WHERE steamid = :steamid AND weapon_defindex = :weapon_defindex", ["steamid" => $steamid, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
|
||||
} else {
|
||||
$db->query("INSERT INTO wp_player_skins (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`, `weapon_team`) VALUES (:steamid, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed, 2)", ["steamid" => $steamid, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
|
||||
$db->query("INSERT INTO wp_player_skins (`steamid`, `weapon_defindex`, `weapon_paint_id`, `weapon_wear`, `weapon_seed`, `weapon_team`) VALUES (:steamid, :weapon_defindex, :weapon_paint_id, :weapon_wear, :weapon_seed, 3)", ["steamid" => $steamid, "weapon_defindex" => $ex[0], "weapon_paint_id" => $ex[1], "weapon_wear" => $wear, "weapon_seed" => $seed]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Handle weapon updates
|
||||
if (isset($_SESSION['steamid']) && isset($_POST['forma'])) {
|
||||
$weaponHandler = new WeaponHandler($_SESSION['steamid']);
|
||||
if ($weaponHandler->handleWeaponUpdate($_POST)) {
|
||||
header("Location: {$_SERVER['PHP_SELF']}");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Organize weapons by categories
|
||||
$weaponCategories = [
|
||||
'Knives' => [],
|
||||
'Gloves' => [],
|
||||
'Rifles' => [7, 8, 10, 13, 16, 60, 39, 40, 38],
|
||||
'Pistols' => [1, 2, 3, 4, 30, 32, 36, 61, 63, 64],
|
||||
'SMGs' => [17, 19, 24, 26, 33, 34],
|
||||
'Shotguns' => [25, 27, 29, 35],
|
||||
'Snipers' => [9, 11, 38],
|
||||
'Machine Guns' => [14, 28],
|
||||
'Grenades' => [43, 44, 45, 46, 47, 48]
|
||||
];
|
||||
|
||||
// Add knives to categories
|
||||
foreach ($knifes as $knifeKey => $knife) {
|
||||
if ($knifeKey != 0) {
|
||||
$weaponCategories['Knives'][$knifeKey] = $knife;
|
||||
}
|
||||
}
|
||||
// Get loadout data for logged in users
|
||||
$loadoutData = null;
|
||||
$weaponCategories = [];
|
||||
if (isset($_SESSION['steamid'])) {
|
||||
require_once 'steamauth/userInfo.php';
|
||||
$weaponHandler = new WeaponHandler($_SESSION['steamid']);
|
||||
$loadoutData = $weaponHandler->getLoadoutData();
|
||||
$weaponCategories = $weaponHandler->getOrganizedWeapons();
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -148,7 +53,7 @@ if (isset($_SESSION['steamid'])) {
|
||||
<h1>CS2 Weapon Paints</h1>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span class="user-info">Welcome, <?php echo $_SESSION['steam_personaname'] ?? 'Player'; ?></span>
|
||||
<span class="user-info">Welcome, <?php echo htmlspecialchars($_SESSION['steam_personaname'] ?? 'Player'); ?></span>
|
||||
<a href="<?php echo $_SERVER['PHP_SELF']; ?>?logout" class="logout-btn">Logout</a>
|
||||
</div>
|
||||
</header>
|
||||
@@ -164,66 +69,39 @@ if (isset($_SESSION['steamid'])) {
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<?php foreach ($weaponCategories as $categoryName => $categoryWeapons): ?>
|
||||
<?php
|
||||
// Count weapons in this category
|
||||
$weaponCount = 0;
|
||||
if ($categoryName == 'Knives') {
|
||||
$weaponCount = count($knifes) - 1; // Exclude default knife
|
||||
} else {
|
||||
foreach ($categoryWeapons as $weaponDefindex) {
|
||||
if (isset($weapons[$weaponDefindex])) {
|
||||
$weaponCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip categories with 0 items
|
||||
if ($weaponCount == 0) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<?php if (empty($categoryWeapons)) continue; ?>
|
||||
<div class="nav-category">
|
||||
<div class="nav-item category-header" data-category="<?php echo strtolower($categoryName); ?>" onclick="toggleCategory('<?php echo strtolower($categoryName); ?>')">
|
||||
<span class="nav-icon">
|
||||
<?php echo $categoryName == 'Knives' ? '🗡️' : ($categoryName == 'Gloves' ? '🧤' : ($categoryName == 'Rifles' ? '🔫' : ($categoryName == 'Pistols' ? '🔫' : ($categoryName == 'SMGs' ? '🔫' : ($categoryName == 'Shotguns' ? '🔫' : ($categoryName == 'Snipers' ? '🎯' : ($categoryName == 'Machine Guns' ? '⚡' : '💣'))))))); ?>
|
||||
</span>
|
||||
<span class="nav-icon"><?php echo getCategoryIcon($categoryName); ?></span>
|
||||
<div class="nav-content">
|
||||
<span class="nav-text"><?php echo $categoryName; ?></span>
|
||||
<span class="nav-count"><?php echo $weaponCount; ?></span>
|
||||
<span class="nav-count"><?php echo count($categoryWeapons); ?></span>
|
||||
</div>
|
||||
<span class="nav-arrow">▶</span>
|
||||
</div>
|
||||
|
||||
<div class="weapon-list" data-category="<?php echo strtolower($categoryName); ?>">
|
||||
<?php if ($categoryName == 'Knives'): ?>
|
||||
<?php foreach ($knifes as $knifeKey => $knife): ?>
|
||||
<?php if ($knifeKey != 0): ?>
|
||||
<div class="weapon-container">
|
||||
<div class="weapon-item" onclick="toggleKnifeSkins(<?php echo $knifeKey; ?>)">
|
||||
<img src="<?php echo $knife['image_url']; ?>" alt="<?php echo $knife['paint_name']; ?>" class="weapon-icon">
|
||||
<span class="weapon-name"><?php echo $knife['paint_name']; ?></span>
|
||||
<span class="weapon-arrow">▶</span>
|
||||
</div>
|
||||
<div class="weapon-skins-grid" data-weapon="knife-<?php echo $knifeKey; ?>">
|
||||
<!-- Knife skins will be populated by JavaScript -->
|
||||
</div>
|
||||
<?php if ($categoryName === 'Knives'): ?>
|
||||
<?php foreach ($categoryWeapons as $knifeId => $knife): ?>
|
||||
<div class="weapon-container">
|
||||
<div class="weapon-item" onclick="toggleKnifeSkins(<?php echo $knifeId; ?>)">
|
||||
<img src="<?php echo htmlspecialchars($knife['image_url']); ?>" alt="<?php echo htmlspecialchars($knife['paint_name']); ?>" class="weapon-icon">
|
||||
<span class="weapon-name"><?php echo htmlspecialchars($knife['paint_name']); ?></span>
|
||||
<span class="weapon-arrow">▶</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="weapon-skins-grid" data-weapon="knife-<?php echo $knifeId; ?>"></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<?php foreach ($categoryWeapons as $weaponDefindex): ?>
|
||||
<?php if (isset($weapons[$weaponDefindex])): ?>
|
||||
<div class="weapon-container">
|
||||
<div class="weapon-item" onclick="toggleWeaponSkins(<?php echo $weaponDefindex; ?>)">
|
||||
<img src="<?php echo $weapons[$weaponDefindex]['image_url']; ?>" alt="<?php echo $weapons[$weaponDefindex]['paint_name']; ?>" class="weapon-icon">
|
||||
<span class="weapon-name"><?php echo ucfirst(strtolower(str_replace('weapon_', '', $weapons[$weaponDefindex]['weapon_name']))); ?></span>
|
||||
<span class="weapon-arrow">▶</span>
|
||||
</div>
|
||||
<div class="weapon-skins-grid" data-weapon="<?php echo $weaponDefindex; ?>">
|
||||
<!-- Skins will be populated by JavaScript -->
|
||||
</div>
|
||||
<?php foreach ($categoryWeapons as $weaponId => $weapon): ?>
|
||||
<div class="weapon-container">
|
||||
<div class="weapon-item" onclick="toggleWeaponSkins(<?php echo $weaponId; ?>)">
|
||||
<img src="<?php echo htmlspecialchars($weapon['image_url']); ?>" alt="<?php echo htmlspecialchars($weapon['paint_name']); ?>" class="weapon-icon">
|
||||
<span class="weapon-name"><?php echo htmlspecialchars(ucfirst(strtolower(str_replace('weapon_', '', $weapon['weapon_name'])))); ?></span>
|
||||
<span class="weapon-arrow">▶</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="weapon-skins-grid" data-weapon="<?php echo $weaponId; ?>"></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -240,121 +118,62 @@ if (isset($_SESSION['steamid'])) {
|
||||
</div>
|
||||
|
||||
<div class="loadout-grid">
|
||||
<!-- Knife - Show the currently equipped knife (either basic knife or knife skin) -->
|
||||
<?php
|
||||
$displayKnife = null;
|
||||
$displayKnifeSkin = null;
|
||||
$knifeSource = '';
|
||||
|
||||
// Debug: Show what's in selectedKnife
|
||||
// echo "<!-- Debug: selectedKnife = " . print_r($selectedKnife, true) . " -->";
|
||||
|
||||
// Check if there's a knife skin equipped (from selectedSkins for knife defindexes)
|
||||
foreach ($selectedSkins as $defindex => $selectedSkin) {
|
||||
if (in_array($defindex, [500, 503, 505, 506, 507, 508, 509, 512, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 525, 526])) {
|
||||
if (isset($skins[$defindex][$selectedSkin['weapon_paint_id']])) {
|
||||
$displayKnifeSkin = $skins[$defindex][$selectedSkin['weapon_paint_id']];
|
||||
$knifeSource = 'skin';
|
||||
break; // Use the first knife skin found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no knife skin, check for basic knife selection
|
||||
if (!$displayKnifeSkin && $selectedKnife != null && !empty($selectedKnife)) {
|
||||
foreach ($knifes as $knifeKey => $knife) {
|
||||
if ($selectedKnife[0]['knife'] == $knife['weapon_name']) {
|
||||
$displayKnife = $knife;
|
||||
$knifeSource = 'basic';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no knife selected at all, show default knife
|
||||
if (!$displayKnifeSkin && !$displayKnife && isset($knifes[0])) {
|
||||
$displayKnife = $knifes[0]; // Default knife
|
||||
$knifeSource = 'default';
|
||||
}
|
||||
<?php
|
||||
$displayKnife = $loadoutData['displayKnife'];
|
||||
$knifeEquipped = ($displayKnife['source'] === 'skin') ? 'true' : 'false';
|
||||
?>
|
||||
|
||||
<!-- Always show a knife (either selected or default) -->
|
||||
<?php if ($displayKnifeSkin || $displayKnife): ?>
|
||||
<div class="loadout-item" data-weapon-type="knife" data-equipped="<?php echo $knifeEquipped; ?>">
|
||||
<div class="item-image-container">
|
||||
<img src="<?php echo htmlspecialchars($displayKnife['data']['image_url']); ?>"
|
||||
alt="<?php echo htmlspecialchars($displayKnife['data']['paint_name']); ?>"
|
||||
class="item-image">
|
||||
<div class="item-overlay">
|
||||
<button class="customize-btn" onclick="openCustomizeModal('knife', 0)">Customize</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<div class="item-category">Knife</div>
|
||||
<div class="item-name"><?php echo htmlspecialchars($displayKnife['data']['paint_name']); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php foreach ($loadoutData['weapons'] as $defindex => $weapon): ?>
|
||||
<?php if (UtilsClass::isKnifeWeapon($weapon)) continue; ?>
|
||||
<?php
|
||||
// Set equipped status for knife - only true if it's a custom skin
|
||||
$knifeEquipped = ($knifeSource == 'skin') ? 'true' : 'false';
|
||||
$hasCustomSkin = array_key_exists($defindex, $loadoutData['selectedSkins']);
|
||||
$isEquipped = $hasCustomSkin ? 'true' : 'false';
|
||||
?>
|
||||
<div class="loadout-item" data-weapon-type="knife" data-equipped="<?php echo $knifeEquipped; ?>">
|
||||
<div class="loadout-item" data-weapon-id="<?php echo $defindex; ?>" data-equipped="<?php echo $isEquipped; ?>">
|
||||
<div class="item-image-container">
|
||||
<?php if ($knifeSource == 'skin'): ?>
|
||||
<img src="<?php echo $displayKnifeSkin['image_url']; ?>" alt="<?php echo $displayKnifeSkin['paint_name']; ?>" class="item-image">
|
||||
<?php if ($hasCustomSkin): ?>
|
||||
<?php
|
||||
$skins = UtilsClass::skinsFromJson();
|
||||
$selectedSkin = $skins[$defindex][$loadoutData['selectedSkins'][$defindex]['weapon_paint_id']];
|
||||
?>
|
||||
<img src="<?php echo htmlspecialchars($selectedSkin['image_url']); ?>"
|
||||
alt="<?php echo htmlspecialchars($selectedSkin['paint_name']); ?>"
|
||||
class="item-image">
|
||||
<div class="item-overlay">
|
||||
<button class="customize-btn" onclick="openCustomizeModal('weapon', <?php echo $defindex; ?>)">Customize</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<img src="<?php echo $displayKnife['image_url']; ?>" alt="<?php echo $displayKnife['paint_name']; ?>" class="item-image">
|
||||
<img src="<?php echo htmlspecialchars($weapon['image_url']); ?>"
|
||||
alt="<?php echo htmlspecialchars($weapon['paint_name']); ?>"
|
||||
class="item-image">
|
||||
<?php endif; ?>
|
||||
<div class="item-overlay">
|
||||
<button class="customize-btn" onclick="openCustomizeModal('knife', 0)">Customize</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<div class="item-category">Knife</div>
|
||||
<div class="item-category"><?php echo htmlspecialchars(ucfirst(strtolower(str_replace('weapon_', '', $weapon['weapon_name'])))); ?></div>
|
||||
<div class="item-name">
|
||||
<?php if ($knifeSource == 'skin'): ?>
|
||||
<?php echo $displayKnifeSkin['paint_name']; ?>
|
||||
<?php if ($hasCustomSkin): ?>
|
||||
<?php echo htmlspecialchars($selectedSkin['paint_name']); ?>
|
||||
<?php else: ?>
|
||||
<?php echo $displayKnife['paint_name']; ?>
|
||||
<?php echo htmlspecialchars($weapon['paint_name']); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Show all weapons (exclude knives) - either with custom skin or default -->
|
||||
<?php foreach ($weapons as $defindex => $weapon): ?>
|
||||
<?php
|
||||
// Skip ALL knives - comprehensive check
|
||||
$isKnifeWeapon = in_array($defindex, [500, 503, 505, 506, 507, 508, 509, 512, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 525, 526]);
|
||||
$isDefaultKnife = ($weapon['weapon_name'] == 'weapon_knife');
|
||||
$isKnifeVariant = (strpos($weapon['weapon_name'], 'knife') !== false);
|
||||
$isKnifePaint = (strpos($weapon['paint_name'], '★') !== false); // Knife skins have ★ in name
|
||||
|
||||
// Skip ANY knife-related weapon
|
||||
if ($isKnifeWeapon || $isDefaultKnife || $isKnifeVariant || $isKnifePaint) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
$hasCustomSkin = array_key_exists($defindex, $selectedSkins);
|
||||
$isEquipped = $hasCustomSkin ? 'true' : 'false';
|
||||
?>
|
||||
<div class="loadout-item" data-weapon-id="<?php echo $defindex; ?>" data-equipped="<?php echo $isEquipped; ?>">
|
||||
<div class="item-image-container">
|
||||
<?php if ($hasCustomSkin): ?>
|
||||
<!-- Show custom skin -->
|
||||
<img src="<?php echo $skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]['image_url']; ?>"
|
||||
alt="<?php echo $skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]['paint_name']; ?>"
|
||||
class="item-image">
|
||||
<div class="item-overlay">
|
||||
<button class="customize-btn" onclick="openCustomizeModal('weapon', <?php echo $defindex; ?>)">Customize</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<!-- Show default weapon -->
|
||||
<img src="<?php echo $weapon['image_url']; ?>"
|
||||
alt="<?php echo $weapon['paint_name']; ?>"
|
||||
class="item-image">
|
||||
<!-- No overlay button for default weapons -->
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<div class="item-category"><?php echo ucfirst(strtolower(str_replace('weapon_', '', $weapon['weapon_name']))); ?></div>
|
||||
<div class="item-name">
|
||||
<?php if ($hasCustomSkin): ?>
|
||||
<?php echo $skins[$defindex][$selectedSkins[$defindex]['weapon_paint_id']]['paint_name']; ?>
|
||||
<?php else: ?>
|
||||
<?php echo $weapon['paint_name']; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</main>
|
||||
@@ -411,335 +230,311 @@ if (isset($_SESSION['steamid'])) {
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Store weapon and skin data for JavaScript
|
||||
const weaponsData = <?php echo json_encode($weapons); ?>;
|
||||
const skinsData = <?php echo json_encode($skins); ?>;
|
||||
const selectedSkinsData = <?php echo json_encode($selectedSkins); ?>;
|
||||
const knivesData = <?php echo json_encode($knifes); ?>;
|
||||
const weaponCategories = <?php echo json_encode($weaponCategories); ?>;
|
||||
// Optimized JavaScript with embedded data (restored functionality)
|
||||
const weaponsData = <?php echo json_encode($loadoutData['weapons']); ?>;
|
||||
const skinsData = <?php echo json_encode(UtilsClass::skinsFromJson()); ?>;
|
||||
const selectedSkinsData = <?php echo json_encode($loadoutData['selectedSkins']); ?>;
|
||||
const knivesData = <?php echo json_encode($loadoutData['knifes']); ?>;
|
||||
|
||||
const WeaponApp = {
|
||||
init() {
|
||||
this.bindEvents();
|
||||
},
|
||||
|
||||
|
||||
function toggleCategory(category) {
|
||||
const categoryHeader = document.querySelector(`.category-header[data-category="${category}"]`);
|
||||
const weaponList = document.querySelector(`.weapon-list[data-category="${category}"]`);
|
||||
const arrow = categoryHeader.querySelector('.nav-arrow');
|
||||
|
||||
// Toggle the weapon list
|
||||
if (weaponList.classList.contains('expanded')) {
|
||||
// Collapse
|
||||
weaponList.classList.remove('expanded');
|
||||
arrow.textContent = '▶';
|
||||
categoryHeader.classList.remove('active');
|
||||
} else {
|
||||
// Collapse all other categories first
|
||||
document.querySelectorAll('.weapon-list').forEach(list => {
|
||||
list.classList.remove('expanded');
|
||||
});
|
||||
document.querySelectorAll('.category-header').forEach(header => {
|
||||
header.classList.remove('active');
|
||||
header.querySelector('.nav-arrow').textContent = '▶';
|
||||
});
|
||||
|
||||
// Expand this category
|
||||
weaponList.classList.add('expanded');
|
||||
arrow.textContent = '▼';
|
||||
categoryHeader.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function equipKnife(knifeId) {
|
||||
// Create form and submit
|
||||
const form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.style.display = 'none';
|
||||
|
||||
const formaInput = document.createElement('input');
|
||||
formaInput.name = 'forma';
|
||||
formaInput.value = `knife-${knifeId}`;
|
||||
|
||||
form.appendChild(formaInput);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function searchWeapons(query) {
|
||||
if (!query.trim()) {
|
||||
// Reset search - show all categories and hide all weapon lists
|
||||
document.querySelectorAll('.nav-category').forEach(category => {
|
||||
category.style.display = 'block';
|
||||
});
|
||||
document.querySelectorAll('.weapon-list').forEach(list => {
|
||||
list.classList.remove('expanded');
|
||||
});
|
||||
document.querySelectorAll('.category-header').forEach(header => {
|
||||
header.classList.remove('active');
|
||||
header.querySelector('.nav-arrow').textContent = '▶';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const searchTerm = query.toLowerCase();
|
||||
|
||||
// Search through categories and weapons
|
||||
document.querySelectorAll('.nav-category').forEach(category => {
|
||||
const categoryName = category.querySelector('.nav-text').textContent.toLowerCase();
|
||||
const weaponItems = category.querySelectorAll('.weapon-item');
|
||||
let categoryMatches = categoryName.includes(searchTerm);
|
||||
let hasMatchingWeapons = false;
|
||||
|
||||
// Check if any weapons in this category match
|
||||
weaponItems.forEach(weaponItem => {
|
||||
const weaponName = weaponItem.querySelector('.weapon-name').textContent.toLowerCase();
|
||||
const matches = weaponName.includes(searchTerm);
|
||||
|
||||
if (matches) {
|
||||
hasMatchingWeapons = true;
|
||||
weaponItem.style.display = 'flex';
|
||||
} else {
|
||||
weaponItem.style.display = 'none';
|
||||
bindEvents() {
|
||||
document.addEventListener('click', (e) => {
|
||||
if (e.target.id === 'customizeModal') {
|
||||
this.closeCustomizeModal();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Show/hide category based on matches
|
||||
if (categoryMatches || hasMatchingWeapons) {
|
||||
category.style.display = 'block';
|
||||
if (hasMatchingWeapons) {
|
||||
// Expand the category to show matching weapons
|
||||
toggleCategory(category) {
|
||||
const categoryHeader = document.querySelector(`.category-header[data-category="${category}"]`);
|
||||
const weaponList = document.querySelector(`.weapon-list[data-category="${category}"]`);
|
||||
const arrow = categoryHeader.querySelector('.nav-arrow');
|
||||
|
||||
if (weaponList.classList.contains('expanded')) {
|
||||
weaponList.classList.remove('expanded');
|
||||
arrow.textContent = '▶';
|
||||
categoryHeader.classList.remove('active');
|
||||
} else {
|
||||
// Collapse other categories
|
||||
document.querySelectorAll('.weapon-list').forEach(list => list.classList.remove('expanded'));
|
||||
document.querySelectorAll('.category-header').forEach(header => {
|
||||
header.classList.remove('active');
|
||||
header.querySelector('.nav-arrow').textContent = '▶';
|
||||
});
|
||||
|
||||
weaponList.classList.add('expanded');
|
||||
arrow.textContent = '▼';
|
||||
categoryHeader.classList.add('active');
|
||||
}
|
||||
},
|
||||
|
||||
searchWeapons(query) {
|
||||
const searchTerm = query.toLowerCase().trim();
|
||||
|
||||
if (!searchTerm) {
|
||||
document.querySelectorAll('.nav-category').forEach(category => category.style.display = 'block');
|
||||
document.querySelectorAll('.weapon-list').forEach(list => list.classList.remove('expanded'));
|
||||
document.querySelectorAll('.category-header').forEach(header => {
|
||||
header.classList.remove('active');
|
||||
header.querySelector('.nav-arrow').textContent = '▶';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.nav-category').forEach(category => {
|
||||
const categoryName = category.querySelector('.nav-text').textContent.toLowerCase();
|
||||
const weaponItems = category.querySelectorAll('.weapon-item');
|
||||
let hasMatches = categoryName.includes(searchTerm);
|
||||
|
||||
weaponItems.forEach(item => {
|
||||
const weaponName = item.querySelector('.weapon-name').textContent.toLowerCase();
|
||||
const matches = weaponName.includes(searchTerm);
|
||||
item.style.display = matches ? 'flex' : 'none';
|
||||
if (matches) hasMatches = true;
|
||||
});
|
||||
|
||||
category.style.display = hasMatches ? 'block' : 'none';
|
||||
if (hasMatches) {
|
||||
const weaponList = category.querySelector('.weapon-list');
|
||||
const header = category.querySelector('.category-header');
|
||||
weaponList.classList.add('expanded');
|
||||
header.classList.add('active');
|
||||
header.querySelector('.nav-arrow').textContent = '▼';
|
||||
}
|
||||
} else {
|
||||
category.style.display = 'none';
|
||||
});
|
||||
},
|
||||
|
||||
toggleWeaponSkins(weaponId) {
|
||||
const weaponItem = event.target.closest('.weapon-item');
|
||||
const skinGrid = weaponItem.parentNode.querySelector('.weapon-skins-grid');
|
||||
|
||||
if (!skinsData[weaponId]) return;
|
||||
|
||||
if (skinGrid.classList.contains('expanded')) {
|
||||
skinGrid.classList.remove('expanded');
|
||||
weaponItem.classList.remove('expanded');
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleWeaponSkins(weaponId) {
|
||||
const weaponItem = event.target.closest('.weapon-item');
|
||||
const skinGrid = weaponItem.parentNode.querySelector('.weapon-skins-grid');
|
||||
// Collapse others
|
||||
document.querySelectorAll('.weapon-skins-grid').forEach(grid => grid.classList.remove('expanded'));
|
||||
document.querySelectorAll('.weapon-item').forEach(item => item.classList.remove('expanded'));
|
||||
|
||||
if (!skinsData[weaponId]) return;
|
||||
|
||||
// Toggle the weapon item and skin grid
|
||||
if (skinGrid.classList.contains('expanded')) {
|
||||
// Collapse
|
||||
skinGrid.classList.remove('expanded');
|
||||
weaponItem.classList.remove('expanded');
|
||||
} else {
|
||||
// Collapse all other weapon skin grids first
|
||||
document.querySelectorAll('.weapon-skins-grid').forEach(grid => {
|
||||
grid.classList.remove('expanded');
|
||||
});
|
||||
document.querySelectorAll('.weapon-item').forEach(item => {
|
||||
item.classList.remove('expanded');
|
||||
});
|
||||
|
||||
// Expand this weapon's skin grid
|
||||
populateWeaponSkins(weaponId, skinGrid);
|
||||
this.populateWeaponSkins(weaponId, skinGrid);
|
||||
skinGrid.classList.add('expanded');
|
||||
weaponItem.classList.add('expanded');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
function populateWeaponSkins(weaponId, skinGrid) {
|
||||
// Create skins container
|
||||
const skinsContainer = document.createElement('div');
|
||||
skinsContainer.className = 'skins-container';
|
||||
|
||||
// Clear previous content
|
||||
skinGrid.innerHTML = '';
|
||||
|
||||
// Populate skins in 3-column grid
|
||||
Object.entries(skinsData[weaponId]).forEach(([paintId, skin]) => {
|
||||
const skinOption = document.createElement('div');
|
||||
skinOption.className = 'skin-option';
|
||||
|
||||
// Check if this skin is currently equipped
|
||||
if (selectedSkinsData[weaponId] && selectedSkinsData[weaponId].weapon_paint_id == paintId) {
|
||||
skinOption.classList.add('active');
|
||||
toggleKnifeSkins(knifeType) {
|
||||
const weaponItem = event.target.closest('.weapon-item');
|
||||
const skinGrid = weaponItem.parentNode.querySelector('.weapon-skins-grid');
|
||||
|
||||
if (skinGrid.classList.contains('expanded')) {
|
||||
skinGrid.classList.remove('expanded');
|
||||
weaponItem.classList.remove('expanded');
|
||||
return;
|
||||
}
|
||||
|
||||
skinOption.onclick = () => equipSkin(weaponId, paintId);
|
||||
|
||||
skinOption.innerHTML = `
|
||||
<img src="${skin.image_url}" alt="${skin.paint_name}">
|
||||
<div class="skin-option-name">${skin.paint_name.replace(/.*\| /, '')}</div>
|
||||
`;
|
||||
|
||||
skinsContainer.appendChild(skinOption);
|
||||
});
|
||||
|
||||
skinGrid.appendChild(skinsContainer);
|
||||
}
|
||||
|
||||
function toggleKnifeSkins(knifeType) {
|
||||
const weaponItem = event.target.closest('.weapon-item');
|
||||
const skinGrid = weaponItem.parentNode.querySelector('.weapon-skins-grid');
|
||||
// Collapse others
|
||||
document.querySelectorAll('.weapon-skins-grid').forEach(grid => grid.classList.remove('expanded'));
|
||||
document.querySelectorAll('.weapon-item').forEach(item => item.classList.remove('expanded'));
|
||||
|
||||
// Toggle the weapon item and skin grid
|
||||
if (skinGrid.classList.contains('expanded')) {
|
||||
// Collapse
|
||||
skinGrid.classList.remove('expanded');
|
||||
weaponItem.classList.remove('expanded');
|
||||
} else {
|
||||
// Collapse all other weapon skin grids first
|
||||
document.querySelectorAll('.weapon-skins-grid').forEach(grid => {
|
||||
grid.classList.remove('expanded');
|
||||
});
|
||||
document.querySelectorAll('.weapon-item').forEach(item => {
|
||||
item.classList.remove('expanded');
|
||||
});
|
||||
|
||||
// Expand this knife type's skin grid
|
||||
populateKnifeTypeSkins(knifeType, skinGrid);
|
||||
this.populateKnifeTypeSkins(knifeType, skinGrid);
|
||||
skinGrid.classList.add('expanded');
|
||||
weaponItem.classList.add('expanded');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
function populateKnifeTypeSkins(knifeType, skinGrid) {
|
||||
// Create skins container
|
||||
const skinsContainer = document.createElement('div');
|
||||
skinsContainer.className = 'skins-container';
|
||||
|
||||
// Clear previous content
|
||||
skinGrid.innerHTML = '';
|
||||
|
||||
// ALWAYS show the basic knife option first
|
||||
const knife = knivesData[knifeType];
|
||||
if (knife) {
|
||||
const basicKnifeOption = document.createElement('div');
|
||||
basicKnifeOption.className = 'skin-option';
|
||||
populateWeaponSkins(weaponId, skinGrid) {
|
||||
const skinsContainer = document.createElement('div');
|
||||
skinsContainer.className = 'skins-container';
|
||||
|
||||
// Check if basic knife is currently selected (no knife skins equipped for this type)
|
||||
if (!selectedSkinsData[knifeType]) {
|
||||
basicKnifeOption.classList.add('active');
|
||||
}
|
||||
skinGrid.innerHTML = '';
|
||||
|
||||
basicKnifeOption.onclick = () => equipKnife(knifeType);
|
||||
|
||||
basicKnifeOption.innerHTML = `
|
||||
<img src="${knife.image_url}" alt="${knife.paint_name}">
|
||||
<div class="skin-option-name">Default</div>
|
||||
`;
|
||||
|
||||
skinsContainer.appendChild(basicKnifeOption);
|
||||
}
|
||||
|
||||
// Then show knife skins if available
|
||||
if (skinsData[knifeType]) {
|
||||
// This knife type has multiple skins
|
||||
Object.entries(skinsData[knifeType]).forEach(([paintId, skin]) => {
|
||||
// Skip the default skin (paint ID 0) since we already show it as "Default" option above
|
||||
if (paintId == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries(skinsData[weaponId]).forEach(([paintId, skin]) => {
|
||||
const skinOption = document.createElement('div');
|
||||
skinOption.className = 'skin-option';
|
||||
|
||||
// Check if this skin is currently equipped
|
||||
if (selectedSkinsData[knifeType] && selectedSkinsData[knifeType].weapon_paint_id == paintId) {
|
||||
if (selectedSkinsData[weaponId] && selectedSkinsData[weaponId].weapon_paint_id == paintId) {
|
||||
skinOption.classList.add('active');
|
||||
}
|
||||
|
||||
skinOption.onclick = () => equipSkin(knifeType, paintId);
|
||||
skinOption.onclick = () => this.equipSkin(weaponId, paintId);
|
||||
|
||||
skinOption.innerHTML = `
|
||||
<img src="${skin.image_url}" alt="${skin.paint_name}">
|
||||
<img src="${skin.image_url}" alt="${skin.paint_name}" loading="lazy">
|
||||
<div class="skin-option-name">${skin.paint_name.replace(/.*\| /, '')}</div>
|
||||
`;
|
||||
|
||||
skinsContainer.appendChild(skinOption);
|
||||
});
|
||||
}
|
||||
|
||||
skinGrid.appendChild(skinsContainer);
|
||||
}
|
||||
|
||||
function equipSkin(weaponId, paintId) {
|
||||
// Create form and submit
|
||||
const form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.style.display = 'none';
|
||||
|
||||
const formaInput = document.createElement('input');
|
||||
formaInput.name = 'forma';
|
||||
formaInput.value = `${weaponId}-${paintId}`;
|
||||
|
||||
const wearInput = document.createElement('input');
|
||||
wearInput.name = 'wear';
|
||||
wearInput.value = '0.00';
|
||||
|
||||
const seedInput = document.createElement('input');
|
||||
seedInput.name = 'seed';
|
||||
seedInput.value = '0';
|
||||
|
||||
form.appendChild(formaInput);
|
||||
form.appendChild(wearInput);
|
||||
form.appendChild(seedInput);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function openCustomizeModal(type, weaponId) {
|
||||
const modal = document.getElementById('customizeModal');
|
||||
const title = document.getElementById('modalTitle');
|
||||
const form = document.getElementById('customizeForm');
|
||||
const weaponIdInput = document.getElementById('customizeWeaponId');
|
||||
const wearSelect = document.getElementById('wearSelect');
|
||||
const wearInput = document.getElementById('wearInput');
|
||||
const seedInput = document.getElementById('seedInput');
|
||||
|
||||
if (type === 'knife') {
|
||||
title.textContent = 'Customize Knife';
|
||||
weaponIdInput.value = 'knife-0';
|
||||
} else {
|
||||
title.textContent = `Customize ${weaponsData[weaponId].weapon_name.replace('weapon_', '').toUpperCase()}`;
|
||||
weaponIdInput.value = `${weaponId}-${selectedSkinsData[weaponId]?.weapon_paint_id || 0}`;
|
||||
|
||||
// Set current values
|
||||
if (selectedSkinsData[weaponId]) {
|
||||
wearInput.value = selectedSkinsData[weaponId].weapon_wear;
|
||||
seedInput.value = selectedSkinsData[weaponId].weapon_seed;
|
||||
skinGrid.appendChild(skinsContainer);
|
||||
},
|
||||
|
||||
populateKnifeTypeSkins(knifeType, skinGrid) {
|
||||
const skinsContainer = document.createElement('div');
|
||||
skinsContainer.className = 'skins-container';
|
||||
|
||||
skinGrid.innerHTML = '';
|
||||
|
||||
// ALWAYS show the basic knife option first
|
||||
const knife = knivesData[knifeType];
|
||||
if (knife) {
|
||||
const basicKnifeOption = document.createElement('div');
|
||||
basicKnifeOption.className = 'skin-option';
|
||||
|
||||
// Set wear select based on value
|
||||
const wear = parseFloat(selectedSkinsData[weaponId].weapon_wear);
|
||||
if (wear <= 0.00) wearSelect.value = "0.00";
|
||||
else if (wear <= 0.07) wearSelect.value = "0.07";
|
||||
else if (wear <= 0.15) wearSelect.value = "0.15";
|
||||
else if (wear <= 0.38) wearSelect.value = "0.38";
|
||||
else wearSelect.value = "0.45";
|
||||
// Check if basic knife is currently selected (no knife skins equipped for this type)
|
||||
if (!selectedSkinsData[knifeType]) {
|
||||
basicKnifeOption.classList.add('active');
|
||||
}
|
||||
|
||||
basicKnifeOption.onclick = () => this.equipKnife(knifeType);
|
||||
|
||||
basicKnifeOption.innerHTML = `
|
||||
<img src="${knife.image_url}" alt="${knife.paint_name}" loading="lazy">
|
||||
<div class="skin-option-name">Default</div>
|
||||
`;
|
||||
|
||||
skinsContainer.appendChild(basicKnifeOption);
|
||||
}
|
||||
|
||||
// Then show knife skins if available
|
||||
if (skinsData[knifeType]) {
|
||||
Object.entries(skinsData[knifeType]).forEach(([paintId, skin]) => {
|
||||
// Skip the default skin (paint ID 0) since we already show it as "Default" option above
|
||||
if (paintId == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
const skinOption = document.createElement('div');
|
||||
skinOption.className = 'skin-option';
|
||||
|
||||
// Check if this skin is currently equipped
|
||||
if (selectedSkinsData[knifeType] && selectedSkinsData[knifeType].weapon_paint_id == paintId) {
|
||||
skinOption.classList.add('active');
|
||||
}
|
||||
|
||||
skinOption.onclick = () => this.equipSkin(knifeType, paintId);
|
||||
|
||||
skinOption.innerHTML = `
|
||||
<img src="${skin.image_url}" alt="${skin.paint_name}" loading="lazy">
|
||||
<div class="skin-option-name">${skin.paint_name.replace(/.*\| /, '')}</div>
|
||||
`;
|
||||
|
||||
skinsContainer.appendChild(skinOption);
|
||||
});
|
||||
}
|
||||
|
||||
skinGrid.appendChild(skinsContainer);
|
||||
},
|
||||
|
||||
equipSkin(weaponId, paintId) {
|
||||
this.submitForm(`${weaponId}-${paintId}`, { wear: '0.00', seed: '0' });
|
||||
},
|
||||
|
||||
equipKnife(knifeId) {
|
||||
this.submitForm(`knife-${knifeId}`);
|
||||
},
|
||||
|
||||
submitForm(forma, additionalData = {}) {
|
||||
const form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.style.display = 'none';
|
||||
|
||||
const formaInput = document.createElement('input');
|
||||
formaInput.name = 'forma';
|
||||
formaInput.value = forma;
|
||||
form.appendChild(formaInput);
|
||||
|
||||
Object.entries(additionalData).forEach(([name, value]) => {
|
||||
const input = document.createElement('input');
|
||||
input.name = name;
|
||||
input.value = value;
|
||||
form.appendChild(input);
|
||||
});
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
},
|
||||
|
||||
openCustomizeModal(type, weaponId) {
|
||||
const modal = document.getElementById('customizeModal');
|
||||
const title = document.getElementById('modalTitle');
|
||||
const weaponIdInput = document.getElementById('customizeWeaponId');
|
||||
const wearSelect = document.getElementById('wearSelect');
|
||||
const wearInput = document.getElementById('wearInput');
|
||||
const seedInput = document.getElementById('seedInput');
|
||||
|
||||
if (type === 'knife') {
|
||||
title.textContent = 'Customize Knife';
|
||||
weaponIdInput.value = 'knife-0';
|
||||
} else {
|
||||
const weaponName = weaponsData[weaponId] ? weaponsData[weaponId].weapon_name.replace('weapon_', '').toUpperCase() : 'Weapon';
|
||||
title.textContent = `Customize ${weaponName}`;
|
||||
weaponIdInput.value = `${weaponId}-${selectedSkinsData[weaponId]?.weapon_paint_id || 0}`;
|
||||
|
||||
if (selectedSkinsData[weaponId]) {
|
||||
const wear = parseFloat(selectedSkinsData[weaponId].weapon_wear);
|
||||
wearInput.value = selectedSkinsData[weaponId].weapon_wear;
|
||||
seedInput.value = selectedSkinsData[weaponId].weapon_seed;
|
||||
|
||||
// Set wear select
|
||||
if (wear <= 0.00) wearSelect.value = "0.00";
|
||||
else if (wear <= 0.07) wearSelect.value = "0.07";
|
||||
else if (wear <= 0.15) wearSelect.value = "0.15";
|
||||
else if (wear <= 0.38) wearSelect.value = "0.38";
|
||||
else wearSelect.value = "0.45";
|
||||
}
|
||||
}
|
||||
|
||||
modal.classList.remove('hidden');
|
||||
},
|
||||
|
||||
closeCustomizeModal() {
|
||||
document.getElementById('customizeModal').classList.add('hidden');
|
||||
},
|
||||
|
||||
updateWearValue(selectedValue) {
|
||||
document.getElementById('wearInput').value = selectedValue;
|
||||
}
|
||||
};
|
||||
|
||||
modal.classList.remove('hidden');
|
||||
}
|
||||
// Global functions for onclick handlers
|
||||
const toggleCategory = (category) => WeaponApp.toggleCategory(category);
|
||||
const searchWeapons = (query) => WeaponApp.searchWeapons(query);
|
||||
const toggleWeaponSkins = (weaponId) => WeaponApp.toggleWeaponSkins(weaponId);
|
||||
const toggleKnifeSkins = (knifeType) => WeaponApp.toggleKnifeSkins(knifeType);
|
||||
const openCustomizeModal = (type, weaponId) => WeaponApp.openCustomizeModal(type, weaponId);
|
||||
const closeCustomizeModal = () => WeaponApp.closeCustomizeModal();
|
||||
const updateWearValue = (value) => WeaponApp.updateWearValue(value);
|
||||
|
||||
function closeCustomizeModal() {
|
||||
document.getElementById('customizeModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
function updateWearValue(selectedValue) {
|
||||
document.getElementById('wearInput').value = selectedValue;
|
||||
}
|
||||
|
||||
// Close modals when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
const modal = document.getElementById('customizeModal');
|
||||
|
||||
if (e.target === modal) {
|
||||
closeCustomizeModal();
|
||||
}
|
||||
});
|
||||
// Initialize app
|
||||
WeaponApp.init();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
// Helper function for category icons
|
||||
function getCategoryIcon($categoryName) {
|
||||
$icons = [
|
||||
'Knives' => '🗡️',
|
||||
'Gloves' => '🧤',
|
||||
'Rifles' => '🔫',
|
||||
'Pistols' => '🔫',
|
||||
'SMGs' => '🔫',
|
||||
'Shotguns' => '🔫',
|
||||
'Snipers' => '🎯',
|
||||
'Machine Guns' => '⚡',
|
||||
'Grenades' => '💣'
|
||||
];
|
||||
|
||||
return $icons[$categoryName] ?? '🔫';
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/* Reset and base styles */
|
||||
* {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
/* Colors */
|
||||
--bg-primary: #1a1a1a;
|
||||
--bg-secondary: #2a2a2a;
|
||||
--bg-tertiary: #3a3a3a;
|
||||
@@ -19,10 +22,16 @@
|
||||
--accent-blue-hover: #357abd;
|
||||
--accent-orange: #ff6b35;
|
||||
--accent-green: #4caf50;
|
||||
|
||||
/* Shadows and Effects */
|
||||
--shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
--shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4);
|
||||
--border-radius: 8px;
|
||||
--transition: all 0.2s ease;
|
||||
|
||||
/* Layout */
|
||||
--sidebar-width: 320px;
|
||||
--header-height: 70px;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -33,6 +42,68 @@ body {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Common button styles */
|
||||
.btn,
|
||||
button {
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
transition: var(--transition);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
font-size: 0.9rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.customize-btn,
|
||||
.equip-btn {
|
||||
background: var(--accent-blue);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover,
|
||||
.customize-btn:hover,
|
||||
.equip-btn:hover {
|
||||
background: var(--accent-blue-hover);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.equip-btn {
|
||||
background: var(--accent-green);
|
||||
}
|
||||
|
||||
.equip-btn:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: var(--accent-orange);
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: var(--border-radius);
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background: #e55a2b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Login Page */
|
||||
.login-container {
|
||||
display: flex;
|
||||
@@ -81,6 +152,7 @@ body {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: var(--shadow);
|
||||
height: var(--header-height);
|
||||
}
|
||||
|
||||
.header-left h1 {
|
||||
@@ -100,22 +172,6 @@ body {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: var(--accent-orange);
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: var(--border-radius);
|
||||
transition: var(--transition);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background: #e55a2b;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.app-main {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
@@ -125,13 +181,11 @@ body {
|
||||
|
||||
/* Sidebar */
|
||||
.sidebar {
|
||||
width: 320px;
|
||||
width: var(--sidebar-width);
|
||||
background: var(--bg-secondary);
|
||||
border-right: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
align-self: stretch;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -177,8 +231,10 @@ body {
|
||||
padding: 1rem 0;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
/* Navigation Items */
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -188,11 +244,7 @@ body {
|
||||
border-left: 3px solid transparent;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: var(--bg-hover);
|
||||
border-left-color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.nav-item:hover,
|
||||
.nav-item.active {
|
||||
background: var(--bg-hover);
|
||||
border-left-color: var(--accent-blue);
|
||||
@@ -240,6 +292,117 @@ body {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
/* Weapon Lists */
|
||||
.nav-category {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.weapon-list {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.weapon-list.expanded {
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.weapon-container:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.weapon-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.75rem 2rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.weapon-item:hover,
|
||||
.weapon-item.expanded {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
.weapon-icon {
|
||||
width: 32px;
|
||||
height: 20px;
|
||||
object-fit: contain;
|
||||
margin-right: 0.75rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.weapon-name {
|
||||
flex: 1;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.weapon-arrow {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.7rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.weapon-item.expanded .weapon-arrow {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.weapon-skins-grid {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
background: var(--bg-primary);
|
||||
}
|
||||
|
||||
.weapon-skins-grid.expanded {
|
||||
max-height: none;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.skins-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.skin-option {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--border-color);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
text-align: center;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.skin-option:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.skin-option.active {
|
||||
border-color: var(--accent-green);
|
||||
box-shadow: 0 0 8px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.skin-option img {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
object-fit: contain;
|
||||
margin-bottom: 0.25rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.skin-option-name {
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Main Content */
|
||||
.main-content {
|
||||
flex: 1;
|
||||
@@ -279,6 +442,7 @@ body {
|
||||
overflow: hidden;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
animation: fadeInUp 0.3s ease;
|
||||
}
|
||||
|
||||
.loadout-item:hover {
|
||||
@@ -287,6 +451,14 @@ body {
|
||||
border-color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.loadout-item[data-equipped="true"] {
|
||||
border-color: var(--accent-green);
|
||||
}
|
||||
|
||||
.loadout-item[data-equipped="true"] .item-category {
|
||||
color: var(--accent-green);
|
||||
}
|
||||
|
||||
.item-image-container {
|
||||
position: relative;
|
||||
aspect-ratio: 16/10;
|
||||
@@ -322,35 +494,6 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.customize-btn,
|
||||
.equip-btn {
|
||||
background: var(--accent-blue);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
transition: var(--transition);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.customize-btn:hover,
|
||||
.equip-btn:hover {
|
||||
background: var(--accent-blue-hover);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.equip-btn {
|
||||
background: var(--accent-green);
|
||||
}
|
||||
|
||||
.equip-btn:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
padding: 1rem;
|
||||
}
|
||||
@@ -403,8 +546,7 @@ body {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Overlays and Modals */
|
||||
.overlay,
|
||||
/* Modals */
|
||||
.modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -420,13 +562,11 @@ body {
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.overlay.hidden,
|
||||
.modal.hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.overlay-content,
|
||||
.modal-content {
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--border-radius);
|
||||
@@ -437,20 +577,9 @@ body {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.overlay-content {
|
||||
width: 1400px;
|
||||
height: 800px;
|
||||
max-height: 95vh;
|
||||
max-width: 98vw;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.overlay-header,
|
||||
.modal-header {
|
||||
padding: 1.5rem;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
@@ -460,7 +589,6 @@ body {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.overlay-header h3,
|
||||
.modal-header h3 {
|
||||
color: var(--text-primary);
|
||||
font-size: 1.4rem;
|
||||
@@ -483,58 +611,13 @@ body {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Skin Grid */
|
||||
.skin-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.skin-item {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--border-color);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.skin-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow);
|
||||
border-color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.skin-item .skin-image {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
object-fit: contain;
|
||||
background: linear-gradient(145deg, #333, #222);
|
||||
padding: 1rem;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.skin-name {
|
||||
padding: 0.75rem;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
/* Modal Body */
|
||||
.modal-body {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.customize-grid {
|
||||
display: grid;
|
||||
gap: 1.5rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.customize-section {
|
||||
@@ -553,12 +636,12 @@ body {
|
||||
|
||||
.customize-section select,
|
||||
.customize-section input {
|
||||
background: var(--bg-secondary);
|
||||
background: var(--bg-tertiary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.75rem;
|
||||
color: var(--text-primary);
|
||||
font-size: 1rem;
|
||||
font-size: 0.9rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
@@ -570,127 +653,15 @@ body {
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
padding: 1rem 1.5rem;
|
||||
border-top: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
justify-content: flex-end;
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
transition: var(--transition);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--accent-blue);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--accent-blue-hover);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.app-main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.loadout-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.overlay-content {
|
||||
width: 95vw;
|
||||
height: 80vh;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 95vw;
|
||||
}
|
||||
|
||||
.app-header {
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.loadout-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
}
|
||||
|
||||
.skin-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.loadout-header h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scrollbar Styling */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--bg-hover);
|
||||
}
|
||||
|
||||
/* Animation for loadout items */
|
||||
.loadout-item {
|
||||
animation: fadeInUp 0.3s ease forwards;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -702,178 +673,93 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Special styling for equipped items */
|
||||
.loadout-item[data-equipped="true"] {
|
||||
border-color: var(--accent-green);
|
||||
/* Smooth scrolling */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.loadout-item[data-equipped="true"] .item-category {
|
||||
color: var(--accent-green);
|
||||
/* Scrollbars */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
/* Empty Loadout Message */
|
||||
.empty-loadout {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 200px;
|
||||
background: var(--bg-card);
|
||||
border-radius: var(--border-radius);
|
||||
border: 2px dashed var(--border-color);
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.empty-message h3 {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.empty-message p {
|
||||
font-size: 1rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Sidebar Weapon Lists */
|
||||
.nav-category {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.weapon-list {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--bg-tertiary);
|
||||
border-left: 3px solid var(--accent-blue);
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.weapon-list.expanded {
|
||||
max-height: 2000px;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.weapon-container {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.weapon-container:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.weapon-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.75rem 1rem;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.weapon-item:hover {
|
||||
background: var(--bg-hover);
|
||||
padding-left: 1.25rem;
|
||||
}
|
||||
|
||||
.weapon-item.expanded {
|
||||
background: var(--bg-hover);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.weapon-icon {
|
||||
width: 48px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
margin-right: 0.75rem;
|
||||
background: linear-gradient(145deg, #333, #222);
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.weapon-name {
|
||||
color: var(--text-primary);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--border-color);
|
||||
border-radius: 4px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.weapon-arrow {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.7rem;
|
||||
transition: var(--transition);
|
||||
margin-left: 0.5rem;
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-muted);
|
||||
}
|
||||
|
||||
.weapon-item.expanded .weapon-arrow {
|
||||
transform: rotate(90deg);
|
||||
color: var(--accent-blue);
|
||||
}
|
||||
|
||||
.weapon-skins-grid {
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.3s ease;
|
||||
background: var(--bg-primary);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.weapon-skins-grid.expanded {
|
||||
max-height: 2000px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.skins-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.skin-option {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid var(--border-color);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
aspect-ratio: 16/10;
|
||||
}
|
||||
|
||||
.skin-option:hover {
|
||||
border-color: var(--accent-blue);
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.skin-option.active {
|
||||
border-color: var(--accent-green);
|
||||
box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.3);
|
||||
}
|
||||
|
||||
.skin-option img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
background: linear-gradient(145deg, #333, #222);
|
||||
padding: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.skin-option-name {
|
||||
padding: 0.25rem;
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
::-webkit-scrollbar-corner {
|
||||
background: var(--bg-tertiary);
|
||||
border-top: 1px solid var(--border-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* Firefox scrollbar styling */
|
||||
.sidebar-nav,
|
||||
.weapon-skins-grid,
|
||||
.skins-container {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--border-color) var(--bg-tertiary);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 1024px) {
|
||||
.app-main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.loadout-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.app-header {
|
||||
padding: 1rem;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 90%;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.loadout-header h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.loadout-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user