From 6d57cd7fe176e47b300b54295ca1f6a14d65e66d Mon Sep 17 00:00:00 2001 From: Ferywir Date: Fri, 12 Jun 2026 08:42:44 +0200 Subject: [PATCH] feat(preferences): apply auto-completion (village name suggestions) [#198] Honour the per-user auto-completion checkboxes on the rally point and the marketplace, where the target village is typed by name (dname field): - v1: own villages - v2: villages in the surroundings of the active village - v3: villages of the player's alliance members A new Database::getAutoCompleteVillages() builds the bounded, de-duplicated name list from the enabled categories (system accounts excluded). A shared Templates/villageAutocomplete.tpl renders a native consumed by the dname input via list="dnameSuggest"; nothing is emitted when every box is unchecked, keeping the previous behaviour. Removes the "not coded yet" tag from the auto-completion section in the preferences form. Co-Authored-By: Claude Opus 4.8 --- GameEngine/Database.php | 61 +++++++++++++++++++++++++++++++ Templates/Build/17.tpl | 2 +- Templates/Profile/preference.tpl | 5 +-- Templates/a2b/search.tpl | 3 +- Templates/villageAutocomplete.tpl | 32 ++++++++++++++++ 5 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 Templates/villageAutocomplete.tpl diff --git a/GameEngine/Database.php b/GameEngine/Database.php index c2ce376a..fc4dd3f5 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -5377,6 +5377,67 @@ $q = "INSERT INTO ".TB_PREFIX."demolition VALUES ( return $this->getVillage($name, 1, $use_cache)['wref']; } + /** + * Build the village-name autocomplete suggestions for the rally point and + * the marketplace, honouring the player's auto-completion preferences + * (issue #198): + * v1 -> own villages + * v2 -> villages in the surroundings of the active village + * v3 -> villages of the player's alliance members + * System accounts (Nature, Natars, Multihunter, ...) are excluded. + * + * @param int $uid Player id (own villages / self). + * @param int $alliance Player's alliance id (0 = none). + * @param int $x Active village X coordinate (vicinity center). + * @param int $y Active village Y coordinate (vicinity center). + * @param bool $v1 Include own villages. + * @param bool $v2 Include surrounding villages. + * @param bool $v3 Include alliance villages. + * @param int $radius Vicinity radius in fields (v2). + * @param int $limit Max number of names returned. + * @return string[] Distinct village names. + */ + function getAutoCompleteVillages($uid, $alliance, $x, $y, $v1, $v2, $v3, $radius = 25, $limit = 100) { + $uid = (int) $uid; + $alliance = (int) $alliance; + $x = (int) $x; + $y = (int) $y; + $radius = (int) $radius; + $limit = (int) $limit; + + $joins = "JOIN " . TB_PREFIX . "users u ON u.id = v.owner "; + $conds = []; + + if ($v1) { + $conds[] = "v.owner = $uid"; + } + if ($v3 && $alliance > 0) { + $conds[] = "u.alliance = $alliance"; + } + if ($v2) { + $joins .= "JOIN " . TB_PREFIX . "wdata w ON w.id = v.wref "; + $conds[] = "(ABS(w.x - $x) <= $radius AND ABS(w.y - $y) <= $radius)"; + } + + if (!count($conds)) { + return []; + } + + $q = "SELECT DISTINCT v.name FROM " . TB_PREFIX . "vdata v " . + $joins . + "WHERE u.id > 5 AND (" . implode(' OR ', $conds) . ") " . + "ORDER BY v.name LIMIT $limit"; + + $result = mysqli_query($this->dblink, $q); + $names = []; + if ($result) { + while ($row = mysqli_fetch_assoc($result)) { + $names[] = $row['name']; + } + } + return $names; + } + function getVillageByOwner($uid, $use_cache = true) { $uid = (int) $uid; diff --git a/Templates/Build/17.tpl b/Templates/Build/17.tpl index 1f909596..6f911c73 100644 --- a/Templates/Build/17.tpl +++ b/Templates/Build/17.tpl @@ -134,7 +134,7 @@ if (isset($_GET['z'])) { - + diff --git a/Templates/a2b/search.tpl b/Templates/a2b/search.tpl index 607bc0a6..3b9a0aef 100644 --- a/Templates/a2b/search.tpl +++ b/Templates/a2b/search.tpl @@ -44,7 +44,8 @@ if (isset($_GET['z'])) { diff --git a/Templates/villageAutocomplete.tpl b/Templates/villageAutocomplete.tpl new file mode 100644 index 00000000..84c2edae --- /dev/null +++ b/Templates/villageAutocomplete.tpl @@ -0,0 +1,32 @@ + consumed by the dname input via + * list="dnameSuggest". Nothing is emitted when every box is unchecked. + */ +global $database, $session, $village; + +$acV1 = !empty($session->userinfo['v1']); +$acV2 = !empty($session->userinfo['v2']); +$acV3 = !empty($session->userinfo['v3']); + +if ($acV1 || $acV2 || $acV3) { + $acNames = $database->getAutoCompleteVillages( + $session->uid, + $session->alliance, + $village->coor['x'] ?? 0, + $village->coor['y'] ?? 0, + $acV1, + $acV2, + $acV3 + ); + + echo ''; + foreach ($acNames as $acName) { + echo ''; +} +?>
/
:
:
diff --git a/Templates/Profile/preference.tpl b/Templates/Profile/preference.tpl index 7e695c67..8fdf4c3e 100644 --- a/Templates/Profile/preference.tpl +++ b/Templates/Profile/preference.tpl @@ -350,10 +350,7 @@ if(isset($_POST['lang']))
- Auto completion - - - +
- + +