From f581add12554cb3bd37e71fc32011336fada520b Mon Sep 17 00:00:00 2001 From: Ferywir <65760459+Ferywir@users.noreply.github.com> Date: Mon, 22 Jun 2026 05:54:41 +0200 Subject: [PATCH] feature(rally-point): mark incoming attacks + show per-troop travel time [#245] (#248) --- GameEngine/Database.php | 21 +++++++++++++-- GameEngine/Lang/en.php | 1 + GameEngine/Lang/fr.php | 1 + GameEngine/Lang/ro.php | 1 + Templates/Build/16_incomming.tpl | 45 +++++++++++++++++++++++++++++++- ajax.php | 20 +++++++++++++- var/db/struct.sql | 1 + 7 files changed, 86 insertions(+), 4 deletions(-) diff --git a/GameEngine/Database.php b/GameEngine/Database.php index 4135fe9d..98064bb7 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -5895,7 +5895,7 @@ $q = "INSERT INTO ".TB_PREFIX."demolition VALUES ( $pairs[] = '(0, '.(int) $typeValue.', '.(int) $from[$index].', '.(int) $to[$index].', '.(int) $ref[$index].', '.(int) $ref2[$index].', '.(int) $time[$index].', '.(int) $endtime[$index].', 0, '.(int) $send[$index].', '.(int) $wood[$index].', '.(int) $clay[$index].', '.(int) $iron[$index].', '.(int) $crop[$index].')'; if ($counter++ > 25) { - $q = "INSERT INTO " . TB_PREFIX . "movement VALUES ".implode(', ', $pairs); + $q = "INSERT INTO " . TB_PREFIX . "movement (moveid, sort_type, `from`, `to`, ref, ref2, starttime, endtime, proc, send, wood, clay, iron, crop) VALUES ".implode(', ', $pairs); mysqli_query($this->dblink,$q); $pairs = []; @@ -5904,7 +5904,7 @@ $q = "INSERT INTO ".TB_PREFIX."demolition VALUES ( } if ($counter > 0) { - $q = "INSERT INTO " . TB_PREFIX . "movement VALUES " . implode( ', ', $pairs ); + $q = "INSERT INTO " . TB_PREFIX . "movement (moveid, sort_type, `from`, `to`, ref, ref2, starttime, endtime, proc, send, wood, clay, iron, crop) VALUES " . implode( ', ', $pairs ); return mysqli_query( $this->dblink, $q ); } else { return true; @@ -8039,6 +8039,23 @@ $q = "INSERT INTO ".TB_PREFIX."demolition VALUES ( return $array; } + // Rally-point attack marker (issue #245): a defender can tag an incoming + // attack green/yellow/red. The WHERE clause restricts the update to a + // movement whose target village (`to`) belongs to $uid, so a player can + // only mark attacks incoming on their own villages. + function setMovementMarker($moveid, $marker, $uid) { + $moveid = (int) $moveid; + $marker = (int) $marker; + $uid = (int) $uid; + if ($marker < 0 || $marker > 3 || $moveid <= 0 || $uid <= 0) { + return false; + } + $q = "UPDATE ".TB_PREFIX."movement SET marker = ".$marker. + " WHERE moveid = ".$moveid. + " AND `to` IN (SELECT wref FROM ".TB_PREFIX."vdata WHERE owner = ".$uid.")"; + return mysqli_query($this->dblink, $q) && mysqli_affected_rows($this->dblink) > 0; + } + // no need to cache this method function getLinks($id) { list($id) = $this->escape_input((int) $id); diff --git a/GameEngine/Lang/en.php b/GameEngine/Lang/en.php index a56ef59b..5a535027 100755 --- a/GameEngine/Lang/en.php +++ b/GameEngine/Lang/en.php @@ -805,6 +805,7 @@ tz_def('RETURNFROM', 'Return from'); tz_def('REINFORCEMENTFOR', 'Reinforcement to'); tz_def('ATTACK_ON', 'Attack to'); tz_def('RAID_ON', 'Raid to'); +tz_def('MARK_ATTACK', 'Mark this attack (severity)'); tz_def('SCOUTING', 'Scouting'); tz_def('PRISONERS', 'Prisoners'); tz_def('PRISONERSIN', 'Prisoners in'); diff --git a/GameEngine/Lang/fr.php b/GameEngine/Lang/fr.php index 03ea8b12..39b6e6d3 100644 --- a/GameEngine/Lang/fr.php +++ b/GameEngine/Lang/fr.php @@ -801,6 +801,7 @@ define('RETURNFROM', 'Retour de'); define('REINFORCEMENTFOR', 'Renfort vers'); define('ATTACK_ON', 'Attaque sur'); define('RAID_ON', 'Pillage sur'); +define('MARK_ATTACK', 'Marquer cette attaque (gravité)'); define('SCOUTING', 'Espionnage'); define('PRISONERS', 'Prisonniers'); define('PRISONERSIN', 'Prisonniers à'); diff --git a/GameEngine/Lang/ro.php b/GameEngine/Lang/ro.php index f901040f..57b6883d 100644 --- a/GameEngine/Lang/ro.php +++ b/GameEngine/Lang/ro.php @@ -801,6 +801,7 @@ define('RETURNFROM', 'Întoarcere din'); define('REINFORCEMENTFOR', 'Întărire către'); define('ATTACK_ON', 'Atac către'); define('RAID_ON', 'Raid către'); +define('MARK_ATTACK', 'Marchează acest atac (gravitate)'); define('SCOUTING', 'Explorare'); define('PRISONERS', 'Prizonieri'); define('PRISONERSIN', 'Prizonieri în'); diff --git a/Templates/Build/16_incomming.tpl b/Templates/Build/16_incomming.tpl index f5b6cba5..69f49b27 100644 --- a/Templates/Build/16_incomming.tpl +++ b/Templates/Build/16_incomming.tpl @@ -8,6 +8,33 @@ $units = $database->getMovement(34, $village->wid, 1); $artifactsSum = $database->getArtifactsSumByKind($session->uid, $village->wid, 3); ?> + + + timer++; $sort = (int)$u['sort_type']; @@ -24,6 +51,19 @@ $artifactsSum = $database->getArtifactsSumByKind($session->uid, $village->wid, 3 $start = ($tribe - 1) * 10 + 1; $end = $tribe * 10; $dt = $generator->procMtime($u['endtime']); + // Base travel time per troop type (issue #245): distance / unit speed, + // WITHOUT tournament square or artefact effects. INCREASE_SPEED is the + // server speed multiplier, matching MyGenerator::procDistanceTime(). + $mtimes = []; + if (!$isElders) { + $fromInfo = $database->getMInfo($from); + $toInfo = $database->getMInfo($u['to']); + $dist = $database->getDistance($fromInfo['x'], $fromInfo['y'], $toInfo['x'], $toInfo['y']); + for ($i = $start; $i <= $end; $i++) { + $spd = isset($GLOBALS['u'.$i]['speed']) ? $GLOBALS['u'.$i]['speed'] : 0; + $mtimes[$i] = $spd > 0 ? $generator->getTimeFormat((int) round(($dist / $spd) * 3600 / INCREASE_SPEED)) : '-'; + } + } ?> @@ -33,6 +73,9 @@ $artifactsSum = $database->getArtifactsSumByKind($session->uid, $village->wid, 3 - + diff --git a/ajax.php b/ajax.php index 7c6349de..a0e38230 100644 --- a/ajax.php +++ b/ajax.php @@ -73,7 +73,25 @@ switch($_GET['f']) { include("Templates/Ajax/quest_core.tpl"); }else{ include("Templates/Ajax/quest_core25.tpl"); - } + } break; + // Rally-point attack marker (issue #245): persist the green/yellow/red tag + // a defender sets on an incoming attack. setMovementMarker() enforces that + // the targeted village belongs to the logged-in user. + case 'marker': + header('Content-Type: application/json'); + if (!isset($_SESSION)) { + session_start(); + } + include_once($autoprefix.'GameEngine/Database.php'); + $uid = (int) ($_SESSION['id_user'] ?? 0); + if (!$uid) { + http_response_code(403); + echo json_encode(['ok' => 0]); + break; + } + $ok = $database->setMovementMarker($_POST['moveid'] ?? 0, $_POST['marker'] ?? 0, $uid); + echo json_encode(['ok' => $ok ? 1 : 0]); + break; } ?> diff --git a/var/db/struct.sql b/var/db/struct.sql index 6897a85d..98042198 100644 --- a/var/db/struct.sql +++ b/var/db/struct.sql @@ -1137,6 +1137,7 @@ CREATE TABLE IF NOT EXISTS `%PREFIX%movement` ( `clay` int(11) DEFAULT NULL, `iron` int(11) DEFAULT NULL, `crop` int(11) DEFAULT NULL, + `marker` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`moveid`), KEY `ref` (`ref`), KEY `from-proc-sort_type` (`from`,`proc`,`sort_type`),
+ + + getVillageField($u['to'],'name')?> @@ -40,7 +83,7 @@ $artifactsSum = $database->getArtifactsSumByKind($session->uid, $village->wid, 3