diff --git a/admin.php b/admin.php
index 22f6fdd..34991d2 100644
--- a/admin.php
+++ b/admin.php
@@ -523,6 +523,7 @@ $current_session_user = isset($_SESSION['user']) ? (string) $_SESSION['user'] :
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/db/scitemcustom.php b/db/scitemcustom.php
new file mode 100644
index 0000000..bc144ef
--- /dev/null
+++ b/db/scitemcustom.php
@@ -0,0 +1,54 @@
+exec(
+ "CREATE TABLE IF NOT EXISTS tbl_scitemcustom (
+ cl_scitemcustom_id INT(11) NOT NULL AUTO_INCREMENT,
+ cl_scitemcustom_obj_id INT(10) UNSIGNED NOT NULL,
+ cl_scitemcustom_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (cl_scitemcustom_id),
+ UNIQUE KEY uq_scitemcustom_obj (cl_scitemcustom_obj_id),
+ KEY idx_scitemcustom_obj (cl_scitemcustom_obj_id),
+ CONSTRAINT fk_scitemcustom_obj FOREIGN KEY (cl_scitemcustom_obj_id)
+ REFERENCES tbl_scobjs (cl_scobjs_id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
+ );
+
+ $db->exec(
+ "CREATE TABLE IF NOT EXISTS tbl_scitemcustomstat (
+ cl_scitemcustomstat_id INT(11) NOT NULL AUTO_INCREMENT,
+ cl_scitemcustomstat_itemcustom_id INT(11) NOT NULL,
+ cl_scitemcustomstat_stat_id INT(11) NOT NULL,
+ cl_scitemcustomstat_sign ENUM('+', '-') NOT NULL DEFAULT '+',
+ cl_scitemcustomstat_value DECIMAL(10,2) NOT NULL DEFAULT 0.00,
+ cl_scitemcustomstat_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (cl_scitemcustomstat_id),
+ UNIQUE KEY uq_scitemcustomstat_item_stat (cl_scitemcustomstat_itemcustom_id, cl_scitemcustomstat_stat_id),
+ KEY idx_scitemcustomstat_item (cl_scitemcustomstat_itemcustom_id),
+ KEY idx_scitemcustomstat_stat (cl_scitemcustomstat_stat_id),
+ CONSTRAINT fk_scitemcustomstat_item FOREIGN KEY (cl_scitemcustomstat_itemcustom_id)
+ REFERENCES tbl_scitemcustom (cl_scitemcustom_id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE,
+ CONSTRAINT fk_scitemcustomstat_stat FOREIGN KEY (cl_scitemcustomstat_stat_id)
+ REFERENCES tbl_scstatsitem (cl_scstatsitem_id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
+ );
+
+ $scitemcustom_bootstrap_done = true;
+}
diff --git a/scitemcustom.php b/scitemcustom.php
new file mode 100644
index 0000000..fb9d8ea
--- /dev/null
+++ b/scitemcustom.php
@@ -0,0 +1,892 @@
+prepare('SELECT cl_scobjs_id FROM tbl_scobjs WHERE cl_scobjs_id = :id');
+ $stmt_check->execute(['id' => $obj_id]);
+ if (!$stmt_check->fetch()) {
+ auth_flash_set('error', 'Objet introuvable.');
+ } else {
+ $stmt_insert = $db->prepare('INSERT INTO tbl_scitemcustom (cl_scitemcustom_obj_id) VALUES (:obj_id)');
+ $stmt_insert->execute(['obj_id' => $obj_id]);
+ auth_flash_set('success', 'Objet ajouté dans Item Custom.');
+ }
+ } catch (PDOException $e) {
+ if ((string) $e->getCode() === '23000') {
+ auth_flash_set('error', 'Cet objet est déjà présent dans Item Custom.');
+ } else {
+ auth_flash_set('error', 'Erreur lors de l\'ajout : ' . $e->getMessage());
+ }
+ }
+ }
+
+ header('Location: scitemcustom.php');
+ exit;
+ }
+
+ if ($action === 'delete_custom_item') {
+ $itemcustom_id = (int) ($_POST['itemcustom_id'] ?? 0);
+ if ($itemcustom_id > 0) {
+ try {
+ $stmt_delete_children = $db->prepare('DELETE FROM tbl_scitemcustomstat WHERE cl_scitemcustomstat_itemcustom_id = :id');
+ $stmt_delete_children->execute(['id' => $itemcustom_id]);
+
+ $stmt_delete = $db->prepare('DELETE FROM tbl_scitemcustom WHERE cl_scitemcustom_id = :id');
+ $stmt_delete->execute(['id' => $itemcustom_id]);
+ auth_flash_set('success', 'Objet Item Custom supprimé.');
+ } catch (PDOException $e) {
+ auth_flash_set('error', 'Erreur lors de la suppression : ' . $e->getMessage());
+ }
+ }
+
+ header('Location: scitemcustom.php');
+ exit;
+ }
+
+ if ($action === 'add_custom_stat') {
+ $itemcustom_id = (int) ($_POST['itemcustom_id'] ?? 0);
+ $stat_id = (int) ($_POST['stat_id'] ?? 0);
+ $sign = scitemcustom_normalize_sign($_POST['sign'] ?? '+');
+ $value = scitemcustom_normalize_value($_POST['value'] ?? '');
+
+ if ($itemcustom_id <= 0 || $stat_id <= 0 || $value === null) {
+ auth_flash_set('error', 'Données de statistique invalides.');
+ } else {
+ try {
+ $stmt_check = $db->prepare(
+ 'SELECT c.cl_scitemcustom_id, s.cl_scstatsitem_id
+ FROM tbl_scitemcustom c
+ JOIN tbl_scstatsitem s ON s.cl_scstatsitem_id = :stat_id
+ WHERE c.cl_scitemcustom_id = :itemcustom_id'
+ );
+ $stmt_check->execute([
+ 'itemcustom_id' => $itemcustom_id,
+ 'stat_id' => $stat_id,
+ ]);
+
+ if (!$stmt_check->fetch()) {
+ auth_flash_set('error', 'Objet ou statistique introuvable.');
+ } else {
+ $stmt_insert = $db->prepare(
+ 'INSERT INTO tbl_scitemcustomstat (
+ cl_scitemcustomstat_itemcustom_id,
+ cl_scitemcustomstat_stat_id,
+ cl_scitemcustomstat_sign,
+ cl_scitemcustomstat_value
+ ) VALUES (:itemcustom_id, :stat_id, :sign, :value)'
+ );
+ $stmt_insert->execute([
+ 'itemcustom_id' => $itemcustom_id,
+ 'stat_id' => $stat_id,
+ 'sign' => $sign,
+ 'value' => $value,
+ ]);
+ auth_flash_set('success', 'Statistique ajoutée à l\'objet.');
+ }
+ } catch (PDOException $e) {
+ if ((string) $e->getCode() === '23000') {
+ auth_flash_set('error', 'Cette statistique est déjà configurée pour cet objet.');
+ } else {
+ auth_flash_set('error', 'Erreur lors de l\'ajout : ' . $e->getMessage());
+ }
+ }
+ }
+
+ header('Location: scitemcustom.php');
+ exit;
+ }
+
+ if ($action === 'update_custom_stat') {
+ $custom_stat_id = (int) ($_POST['custom_stat_id'] ?? 0);
+ $stat_id = (int) ($_POST['stat_id'] ?? 0);
+ $sign = scitemcustom_normalize_sign($_POST['sign'] ?? '+');
+ $value = scitemcustom_normalize_value($_POST['value'] ?? '');
+
+ if ($custom_stat_id <= 0 || $stat_id <= 0 || $value === null) {
+ auth_flash_set('error', 'Données de mise à jour invalides.');
+ } else {
+ try {
+ $stmt_update = $db->prepare(
+ 'UPDATE tbl_scitemcustomstat
+ SET cl_scitemcustomstat_stat_id = :stat_id,
+ cl_scitemcustomstat_sign = :sign,
+ cl_scitemcustomstat_value = :value
+ WHERE cl_scitemcustomstat_id = :id'
+ );
+ $stmt_update->execute([
+ 'stat_id' => $stat_id,
+ 'sign' => $sign,
+ 'value' => $value,
+ 'id' => $custom_stat_id,
+ ]);
+ auth_flash_set('success', 'Statistique mise à jour.');
+ } catch (PDOException $e) {
+ if ((string) $e->getCode() === '23000') {
+ auth_flash_set('error', 'Cette statistique est déjà configurée pour cet objet.');
+ } else {
+ auth_flash_set('error', 'Erreur lors de la mise à jour : ' . $e->getMessage());
+ }
+ }
+ }
+
+ header('Location: scitemcustom.php');
+ exit;
+ }
+
+ if ($action === 'delete_custom_stat') {
+ $custom_stat_id = (int) ($_POST['custom_stat_id'] ?? 0);
+ if ($custom_stat_id > 0) {
+ try {
+ $stmt_delete = $db->prepare('DELETE FROM tbl_scitemcustomstat WHERE cl_scitemcustomstat_id = :id');
+ $stmt_delete->execute(['id' => $custom_stat_id]);
+ auth_flash_set('success', 'Statistique supprimée de l\'objet.');
+ } catch (PDOException $e) {
+ auth_flash_set('error', 'Erreur lors de la suppression : ' . $e->getMessage());
+ }
+ }
+
+ header('Location: scitemcustom.php');
+ exit;
+ }
+}
+
+$search = trim($_GET['search'] ?? '');
+$search_results = [];
+if ($search !== '') {
+ $stmt_search = $db->prepare(
+ "SELECT *
+ FROM tbl_scobjs
+ WHERE (cl_scobjs_name LIKE :search OR cl_scobjs_type LIKE :search OR cl_scobjs_subtype LIKE :search OR cl_scobjs_uuid LIKE :search)
+ AND cl_scobjs_id NOT IN (SELECT cl_scitemcustom_obj_id FROM tbl_scitemcustom)
+ ORDER BY cl_scobjs_name ASC
+ LIMIT 15"
+ );
+ $stmt_search->execute(['search' => '%' . $search . '%']);
+ $search_results = $stmt_search->fetchAll();
+}
+
+$stmt_stats_catalog = $db->query('SELECT * FROM tbl_scstatsitem ORDER BY cl_scstatsitem_name ASC, cl_scstatsitem_id ASC');
+$stats_catalog = $stmt_stats_catalog->fetchAll();
+$stats_by_id = [];
+foreach ($stats_catalog as $stat_catalog_row) {
+ $stats_by_id[(int) $stat_catalog_row['cl_scstatsitem_id']] = $stat_catalog_row;
+}
+
+$sql_custom_items = "SELECT c.*, o.cl_scobjs_name, o.cl_scobjs_uuid, o.cl_scobjs_type, o.cl_scobjs_subtype, o.cl_scobjs_rarity
+ FROM tbl_scitemcustom c
+ JOIN tbl_scobjs o ON o.cl_scobjs_id = c.cl_scitemcustom_obj_id
+ ORDER BY o.cl_scobjs_name ASC, c.cl_scitemcustom_id ASC";
+$stmt_custom_items = $db->query($sql_custom_items);
+$custom_items = $stmt_custom_items->fetchAll();
+
+$stmt_custom_stats = $db->query(
+ "SELECT cs.*, st.cl_scstatsitem_name, st.cl_scstatsitem_unit
+ FROM tbl_scitemcustomstat cs
+ JOIN tbl_scstatsitem st ON st.cl_scstatsitem_id = cs.cl_scitemcustomstat_stat_id
+ ORDER BY cs.cl_scitemcustomstat_itemcustom_id ASC, st.cl_scstatsitem_name ASC, cs.cl_scitemcustomstat_id ASC"
+);
+$custom_stats_rows = $stmt_custom_stats->fetchAll();
+$custom_stats_by_item = [];
+foreach ($custom_stats_rows as $custom_stat_row) {
+ $item_key = (int) $custom_stat_row['cl_scitemcustomstat_itemcustom_id'];
+ if (!isset($custom_stats_by_item[$item_key])) {
+ $custom_stats_by_item[$item_key] = [];
+ }
+ $custom_stats_by_item[$item_key][] = $custom_stat_row;
+}
+
+$current_session_user = $_SESSION['user'] ?? '';
+?>
+
+
+
+
+
+ Item Custom | R.E.A.C.T. Admin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Liste Item Custom
+ objet(s) configuré(s) dans cette liste personnalisée.
+
+
+ Aucun objet Item Custom enregistré pour le moment.
+
+
+
+
+
+
+
+
+
+
Ajouter un bonus / malus
+
+
Aucune statistique disponible. Crée d'abord des entrées dans l'onglet Stats Item.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scitems.php b/scitems.php
index 151be58..82f4926 100644
--- a/scitems.php
+++ b/scitems.php
@@ -405,6 +405,7 @@ if ($edit_id > 0) {
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scmanufactures.php b/scmanufactures.php
index 75f9d19..3eb154b 100644
--- a/scmanufactures.php
+++ b/scmanufactures.php
@@ -277,6 +277,7 @@ $current_session_user = $_SESSION['user'] ?? '';
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scmining.php b/scmining.php
index 6b4933f..9bda8c7 100644
--- a/scmining.php
+++ b/scmining.php
@@ -334,6 +334,7 @@ $current_session_user = $_SESSION['user'] ?? '';
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scnotification.php b/scnotification.php
index 075d567..c7f2f8a 100644
--- a/scnotification.php
+++ b/scnotification.php
@@ -676,6 +676,7 @@ function scnotification_old_checked(array $old, string $key, bool $default = fal
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scpreset.php b/scpreset.php
index 2300067..a7565c9 100644
--- a/scpreset.php
+++ b/scpreset.php
@@ -329,6 +329,7 @@ $presets = $stmt_list->fetchAll();
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scstatsitem.php b/scstatsitem.php
index aba258b..cfd244a 100644
--- a/scstatsitem.php
+++ b/scstatsitem.php
@@ -368,6 +368,7 @@ $current_session_user = $_SESSION['user'] ?? '';
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scvaisseaux.php b/scvaisseaux.php
index f3daac7..5fba0b4 100644
--- a/scvaisseaux.php
+++ b/scvaisseaux.php
@@ -288,6 +288,7 @@ $current_session_user = $_SESSION['user'] ?? '';
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux
diff --git a/scwebhook.php b/scwebhook.php
index 8b551e1..9814923 100644
--- a/scwebhook.php
+++ b/scwebhook.php
@@ -553,6 +553,7 @@ $banners = $stmt_banners->fetchAll();
NOTIF DISCORD
Base d'Objets
Stats Item
+ Item Custom
Scanner Minage
Manufactures
Vaisseaux