From a998edc205b6ea8c1bfdedd18f55f74208049a3d Mon Sep 17 00:00:00 2001 From: novgorodschi catalin Date: Mon, 29 Jun 2026 08:02:09 +0300 Subject: [PATCH] Fix #294 code for brewery Fix #294 now brewery is fully coded! --- GameEngine/Automation.php | 28 +++++++++++++-- GameEngine/Data/buidata.php | 23 +++++++++---- GameEngine/Data/cel.php | 23 ++++++++----- GameEngine/Data/cp.php | 23 ++++++++----- GameEngine/Data/festival.php | 41 ++++++++++++++++++++++ GameEngine/Data/hero_full.php | 23 ++++++++----- GameEngine/Data/resdata.php | 22 ++++++++---- GameEngine/Data/unitdata.php | 24 ++++++++----- GameEngine/Database.php | 41 ++++++++++++++++++++-- GameEngine/Lang/en.php | 7 ++++ GameEngine/Lang/fr.php | 7 ++++ GameEngine/Lang/ro.php | 7 ++++ GameEngine/Session.php | 37 ++++++++++++++------ GameEngine/Units.php | 21 ++++++++--- GameEngine/Village.php | 1 + Templates/Build/35.tpl | 6 ++++ Templates/Build/35_1.tpl | 65 +++++++++++++++++++++++++++++++++++ var/db/struct.sql | 2 ++ 18 files changed, 335 insertions(+), 66 deletions(-) create mode 100644 GameEngine/Data/festival.php create mode 100644 Templates/Build/35_1.tpl diff --git a/GameEngine/Automation.php b/GameEngine/Automation.php index 1f5a810e..acc325e3 100644 --- a/GameEngine/Automation.php +++ b/GameEngine/Automation.php @@ -92,7 +92,7 @@ class Automation { $methodsArrays = ["culturePoints", "updateHero", "clearDeleting", "buildComplete", "demolitionComplete", "marketComplete", "researchComplete", - "trainingComplete", "starvation", "celebrationComplete", + "trainingComplete", "starvation", "celebrationComplete", "festivalComplete", "sendUnitsComplete", "loyaltyRegeneration", "sendreinfunitsComplete", "returnunitsComplete", "sendSettlersComplete", "spawnNatars", "spawnWWVillages", "spawnWWBuildingPlans", "activateArtifacts"]; @@ -1268,7 +1268,17 @@ class Automation { $reducedLoyalty /= $battlepart['moralBonus']; - if ($owntribe == 2 && $this->getTypeLevel(35, $data['from']) > 0) $reducedLoyalty /= 2; + // Bug fix: Brewery (35) is capital-only but empire-wide — its effect + // must be checked on the attacker's CAPITAL, not on $data['from'] (the + // launching village, which may not be the capital at all), and only + // while a Mead-Festival is actually active there, not just because + // the Brewery has been built (it has no permanent effect). + if ($owntribe == 2) { + $attackerCapital = $database->getVillage($from['owner'], 3); + if ($attackerCapital && (int)$attackerCapital['festival'] > $time && $this->getTypeLevel(35, $attackerCapital['wref']) > 0) { + $reducedLoyalty /= 2; + } + } $reducedLoyaltyTotal += $reducedLoyalty; } @@ -4178,6 +4188,20 @@ class Automation { } } + /** + * Expires Mead-Festivals (Brewery, building 35). Unlike celebrationComplete() + * this grants no reward — the festival only gated the temporary combat + * bonus / chief penalty / catapult randomization while it was active. + */ + private function festivalComplete() { + global $database; + + $varray = $database->getFestivals(); + foreach($varray as $vil){ + $database->clearFestival($vil['wref']); + } + } + private function demolitionComplete() { global $database; diff --git a/GameEngine/Data/buidata.php b/GameEngine/Data/buidata.php index b59fccfa..8c321916 100755 --- a/GameEngine/Data/buidata.php +++ b/GameEngine/Data/buidata.php @@ -1,14 +1,23 @@ 'Mead-Festival', + 'wood' => 3870, + 'clay' => 1680, + 'iron' => 215, + 'crop' => 10900, + 'time' => 259200 // 72 hours +]; +?> diff --git a/GameEngine/Data/hero_full.php b/GameEngine/Data/hero_full.php index 4347438a..71019bd4 100755 --- a/GameEngine/Data/hero_full.php +++ b/GameEngine/Data/hero_full.php @@ -3,14 +3,21 @@ ################################################################################# ## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ## ## --------------------------------------------------------------------------- ## -## Filename hero_full.php ## -## Developed by: yi12345 ## -## License: TravianZ Project ## -## Copyright: TravianZ (c) 2010-2026. All rights reserved. ## -## ## -## URLs: https://travianz.org ## -## https://github.com/Shadowss/TravianZ ## -## ## +## Filename : hero_full.php ## +## Type : Data Page for Heroes ## +## --------------------------------------------------------------------------- ## +## Developed by : Dzoki ## +## Refactored by : Shadow ## +## Redesign by : Shadow ## +## --------------------------------------------------------------------------- ## +## Contact : cata7007@gmail.com ## +## Project : TravianZ ## +## URLs: : https://travianz.org ## +## GitHub : https://github.com/Shadowss/TravianZ ## +## --------------------------------------------------------------------------- ## +## License : TravianZ Project ## +## Copyright : TravianZ (c) 2010-2026. All rights reserved. ## +## --------------------------------------------------------------------------- ## ################################################################################# $hero_levels = array(0 => 0, 100, 300, 600, 1000, 1500, 2100, 2800, 3600, 4500, 5500, 6600, 7800, 9100, 10500, 12000, 13600, 15300, 17100, 19000, 21000, 23100, 25300, 27600, 30000, 32500, 35100, 37800, 40600, 43500, 46500, 49600, 52800, 56100, 59500, 63000, 66600, 70300, 74100, 78000, 82000, 86100, 90300, 94600, 99000, 103500, 108100, 112800, 117600, 122500, 127500, 132600, 137800, 143100, 148500, 154000, 159600, 165300, 171100, 177000, 183000, 189100, 195300, 201600, 208000, 214500, 221100, 227800, diff --git a/GameEngine/Data/resdata.php b/GameEngine/Data/resdata.php index 945876e1..2ebd250a 100755 --- a/GameEngine/Data/resdata.php +++ b/GameEngine/Data/resdata.php @@ -3,13 +3,21 @@ ################################################################################# ## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ## ## --------------------------------------------------------------------------- ## -## Filename resdata.php ## -## License: TravianZ Project ## -## Copyright: TravianZ (c) 2010-2026. All rights reserved. ## -## ## -## URLs: https://travianz.org ## -## https://github.com/Shadowss/TravianZ ## -## ## +## Filename : resdata.php ## +## Type : Data Page for Resources ## +## --------------------------------------------------------------------------- ## +## Developed by : Dzoki ## +## Refactored by : Shadow ## +## Redesign by : Shadow ## +## --------------------------------------------------------------------------- ## +## Contact : cata7007@gmail.com ## +## Project : TravianZ ## +## URLs: : https://travianz.org ## +## GitHub : https://github.com/Shadowss/TravianZ ## +## --------------------------------------------------------------------------- ## +## License : TravianZ Project ## +## Copyright : TravianZ (c) 2010-2026. All rights reserved. ## +## --------------------------------------------------------------------------- ## ################################################################################# //Academy diff --git a/GameEngine/Data/unitdata.php b/GameEngine/Data/unitdata.php index f1e0f40e..4d734c87 100755 --- a/GameEngine/Data/unitdata.php +++ b/GameEngine/Data/unitdata.php @@ -1,15 +1,23 @@ array(1,2,3,11,12,13,14,21,22,31,32,33,34,41,42,43,44),'cavalry'=>array(4,5,6,15,16,23,24,25,26,35,36,45,46),'siege'=>array(7,8,17,18,27,28,37,38,47,48),'ram'=>array(7,17,27,47),'catapult'=>array(8,18,28,48),'expansion'=>array(9,10,19,20,29,30,39,40,49,50),'scout'=>array(4,14,23,44),'chief'=>array(9,19,29,49)); diff --git a/GameEngine/Database.php b/GameEngine/Database.php index 7bec4cd0..21076df1 100755 --- a/GameEngine/Database.php +++ b/GameEngine/Database.php @@ -1486,8 +1486,16 @@ class MYSQLi_DB implements IDbConnection { foreach($countedWids as $mode => $totalCount){ foreach($totalCount as $sector => $count){ $generatedWids = $this->generateBase($sector, $mode, $count); - $wids[$mode] = array_merge((array)$wids[$mode], !is_array($generatedWids) ? [$generatedWids] : $generatedWids); - if(empty($i[$mode])) $i[$mode] = 0; + // Bug fix: previously merged every sector's wids into one flat + // $wids[$mode] list and consumed it with a single shared counter + // per mode, regardless of which sector a wid actually came from. + // As soon as a batch needed more than one sector (e.g. WW + // villages spread across all 4 quadrants), villages were handed + // wids strictly in array order, not matching their own kid — so + // most ended up in the wrong quadrant. Keying by [mode][sector] + // keeps each sector's wids separate. + $wids[$mode][$sector] = !is_array($generatedWids) ? [$generatedWids] : $generatedWids; + if(empty($i[$mode][$sector])) $i[$mode][$sector] = 0; } } @@ -1495,7 +1503,7 @@ class MYSQLi_DB implements IDbConnection { foreach($villageArrays as $village){ //Check if the village wid isn't already set and assing one among the generated ones - if($village['wid'] == 0) $village['wid'] = $wids[$village['mode']][$i[$village['mode']]++]; + if($village['wid'] == 0) $village['wid'] = $wids[$village['mode']][$village['kid']][$i[$village['mode']][$village['kid']]++]; //Merge the wids into an unique array $takenWids[] = $village['wid']; @@ -4148,6 +4156,33 @@ class MYSQLi_DB implements IDbConnection { return mysqli_query($this->dblink,$q); } + /** + * Mead-Festival (Brewery, building 35 — Teutons only). + * Mirrors addCel()/getCel()/clearCel() above, but the festival grants no + * culture points: it only gates the temporary combat bonus, the chief + * persuasion penalty and the catapult randomization while it is active. + */ + function addFestival($ref, $end) { + list($ref, $end) = $this->escape_input((int) $ref, (int) $end); + + $q = "UPDATE " . TB_PREFIX . "vdata set festival = $end where wref = $ref"; + return mysqli_query($this->dblink,$q); + } + + // no need to cache this method + function getFestivals() { + $q = "SELECT * FROM " . TB_PREFIX . "vdata WHERE festival < " . time() . " AND festival != 0"; + $result = mysqli_query($this->dblink,$q); + return $this->mysqli_fetch_all($result); + } + + function clearFestival($ref) { + list($ref) = $this->escape_input((int) $ref); + + $q = "UPDATE " . TB_PREFIX . "vdata set festival = 0 where wref = $ref"; + return mysqli_query($this->dblink,$q); + } + /** * Delete a single village or multiple ones * diff --git a/GameEngine/Lang/en.php b/GameEngine/Lang/en.php index 5a535027..a1ac55fe 100755 --- a/GameEngine/Lang/en.php +++ b/GameEngine/Lang/en.php @@ -1258,6 +1258,9 @@ tz_def('BREWERY', 'Brewery'); tz_def('CURRENT_BONUS', 'Current bonus:'); tz_def('BONUS_LEVEL', 'Bonus at level'); tz_def('BREWERY_DESC', 'Tasty mead is brewed here.Drinks make your soldiers braver and stronger when attacking others (1% per Brewery level). Unfortunately, the persuasive power of leaders is reduced by 50% and catapults can only make random hits. Can only be built in the capital, but affects all your villages. The mead-festivals always last 72 hours.
Tribe-specific: Teutons only'); +tz_def('MEAD_FESTIVAL', 'Mead-Festival'); +tz_def('MEAD_FESTIVAL_IN_PROGRESS', 'Mead-Festival
in progress'); +tz_def('MEAD_FESTIVAL_COMMENCE_BREWERY', 'The Mead-Festival can be started once the Brewery is completed.'); tz_def('TRAPPER', 'Trapper'); tz_def('CURRENT_TRAPS', 'Currect maximum traps to train:'); @@ -1459,6 +1462,10 @@ tz_def('DIRECT_LINKS', 'Direct links'); tz_def('NUMBER0', 'No'); tz_def('LINK_NAME', 'Link name'); tz_def('LINK_TARGET', 'Link target'); +tz_def('TZ_LINK_GENERATOR', 'Game link generator'); +tz_def('TZ_LINK_GENERATOR_DESC', 'Builds a link by building type instead of slot location, so it works in every village regardless of where that building is built there. Copy the result below into the Link target field.'); +tz_def('TZ_TAB_OPTIONAL', 'Tab (optional)'); +tz_def('TZ_GENERATED_LINK', 'Generated link'); tz_def('AUTO_COMPL', 'Auto completion'); tz_def('AUTO_COMPL2', 'Used for rally point and marketplace'); tz_def('OWN_VILLAGES', 'own villages'); diff --git a/GameEngine/Lang/fr.php b/GameEngine/Lang/fr.php index 39b6e6d3..adbb3c5f 100644 --- a/GameEngine/Lang/fr.php +++ b/GameEngine/Lang/fr.php @@ -1254,6 +1254,9 @@ define('BREWERY', 'Brasserie'); define('CURRENT_BONUS', 'Bonus actuel :'); define('BONUS_LEVEL', 'Bonus au niveau'); define('BREWERY_DESC', 'Un savoureux hydromel est brassé ici. Les boissons rendent vos soldats plus braves et plus forts lors d\'attaques (1 % par niveau de brasserie). Malheureusement, le pouvoir de persuasion des chefs est réduit de 50 % et les catapultes ne peuvent faire que des tirs aléatoires. Ne peut être construite que dans la capitale, mais affecte tous vos villages. Les festivals d\'hydromel durent toujours 72 heures.
Spécifique à la tribu : Germains uniquement.'); +define('MEAD_FESTIVAL', 'Festival de l\'hydromel'); +define('MEAD_FESTIVAL_IN_PROGRESS', 'Festival de l\'hydromel
en cours'); +define('MEAD_FESTIVAL_COMMENCE_BREWERY', 'Le festival de l\'hydromel peut commencer une fois la brasserie terminée.'); define('TRAPPER', 'Trappeur'); define('CURRENT_TRAPS', 'Pièges maximum à entraîner actuellement :'); @@ -1778,6 +1781,10 @@ define('DIRECT_LINKS', 'Liens directs'); define('NUMBER0', 'N°'); define('LINK_NAME', 'Nom du lien'); define('LINK_TARGET', 'Cible du lien'); +define('TZ_LINK_GENERATOR', 'Générateur de liens de jeu'); +define('TZ_LINK_GENERATOR_DESC', 'Construit un lien selon le type de bâtiment plutôt que son emplacement, afin qu\'il fonctionne dans chaque village quel que soit l\'emplacement de ce bâtiment. Copiez le résultat ci-dessous dans le champ Cible du lien.'); +define('TZ_TAB_OPTIONAL', 'Onglet (optionnel)'); +define('TZ_GENERATED_LINK', 'Lien généré'); define('AUTO_COMPL', 'Auto-complétion'); define('AUTO_COMPL2', 'Utilisée pour le point de rassemblement et le marché.'); define('OWN_VILLAGES', 'Mes villages'); diff --git a/GameEngine/Lang/ro.php b/GameEngine/Lang/ro.php index 8f4d08c6..1ed8b0e8 100644 --- a/GameEngine/Lang/ro.php +++ b/GameEngine/Lang/ro.php @@ -1253,6 +1253,9 @@ define('BREWERY', 'Berărie'); define('CURRENT_BONUS', 'Bonus actual:'); define('BONUS_LEVEL', 'Bonus la nivelul'); define('BREWERY_DESC', 'Aici se fabrică hidromel gustos. Băuturile îți fac soldații mai curajoși și mai puternici la atac (1% per nivel berărie). Din păcate, puterea de convingere a conducătorilor este redusă cu 50% și catapultele pot lovi doar aleatoriu. Poate fi construită doar în capitală, dar afectează toate satele tale. Festivalurile hidromelului durează mereu 72 de ore.
Specific tribului: doar teutonii'); +define('MEAD_FESTIVAL', 'Festivalul Hidromelului'); +define('MEAD_FESTIVAL_IN_PROGRESS', 'Festivalul Hidromelului
în desfășurare'); +define('MEAD_FESTIVAL_COMMENCE_BREWERY', 'Festivalul Hidromelului poate fi pornit după finalizarea Berăriei.'); define('TRAPPER', 'Capcană'); define('CURRENT_TRAPS', 'Număr maxim actual de capcane de antrenat:'); @@ -1454,6 +1457,10 @@ define('DIRECT_LINKS', 'Linkuri directe'); define('NUMBER0', 'Nr'); define('LINK_NAME', 'Nume link'); define('LINK_TARGET', 'Țintă link'); +define('TZ_LINK_GENERATOR', 'Generator de link-uri de joc'); +define('TZ_LINK_GENERATOR_DESC', 'Construiește un link după tipul clădirii, nu după locația din sat, deci funcționează în orice sat indiferent unde e construită clădirea acolo. Copiază rezultatul de mai jos în câmpul Țintă link.'); +define('TZ_TAB_OPTIONAL', 'Tab (opțional)'); +define('TZ_GENERATED_LINK', 'Link generat'); define('AUTO_COMPL', 'Autocompletare'); define('AUTO_COMPL2', 'Folosit pentru punct de adunare și piață'); define('OWN_VILLAGES', 'satele proprii'); diff --git a/GameEngine/Session.php b/GameEngine/Session.php index 4d00a052..a7245458 100755 --- a/GameEngine/Session.php +++ b/GameEngine/Session.php @@ -44,6 +44,7 @@ include_once("Battle.php"); include_once("Data/buidata.php"); include_once("Data/cp.php"); include_once("Data/cel.php"); +include_once("Data/festival.php"); include_once("Data/resdata.php"); include_once("Data/unitdata.php"); include_once("Data/hero_full.php"); @@ -70,6 +71,7 @@ class Session { private $time; private $populated = false; var $logged_in = false; + var $inAdmin = false; var $referrer, $url; var $username, $uid, $access, $plus, $tribe, $isAdmin, $alliance, $gold, $oldrank, $gpack, $goldclub; @@ -124,7 +126,7 @@ function __construct() { if($maint['active'] == 1 && $this->access < 9) { // evita loop infinit if(strpos($_SERVER['PHP_SELF'], 'maintenance.php') === false) { - header('Location: maintenance.php'); + header('Location: /maintenance.php'); exit; } } @@ -195,11 +197,11 @@ function __construct() { $logging->addLoginLog($dbarray['id'], \App\Utils\IpResolver::getClientIp() ?? ($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0')); if ($dbarray['id'] == 1) { - header("Location: nachrichten.php"); + header("Location: /nachrichten.php"); exit; } - header("Location: dorf1.php"); + header("Location: /dorf1.php"); exit; } @@ -242,6 +244,7 @@ function __construct() { $admin = false; $inAdmin = (strpos($_SERVER['REQUEST_URI'], '/Admin') !== false); + $this->inAdmin = $inAdmin; if (!$inAdmin && isset($_SESSION['username'])) { $user = $_SESSION['username']; @@ -262,7 +265,7 @@ function __construct() { 'nachrichten.php', 'logout.php', 'statistiken.php', 'rules.php', 'karte.php', 'karte2.php', 'spieler.php' ])) { - header('Location: nachrichten.php'); + header('Location: /nachrichten.php'); exit; } } @@ -284,7 +287,7 @@ function __construct() { if ($this->access == BANNED && !in_array(basename($_SERVER['PHP_SELF']), ['banned.php', 'nachrichten.php', 'rules.php'])) { - header('Location: banned.php'); + header('Location: /banned.php'); exit; } } @@ -293,7 +296,7 @@ function __construct() { if (($_SESSION['ok'] ?? null) == 2 && basename($_SERVER['PHP_SELF']) != 'maintenance.php') { - header('Location: maintenance.php'); + header('Location: /maintenance.php'); exit; } } @@ -317,7 +320,7 @@ function __construct() { ) ) ) { - header('Location: winner.php'); + header('Location: /winner.php'); exit; } } @@ -332,7 +335,7 @@ function __construct() { if (!count($this->villages)) { $this->Logout(); - header('Location: login.php'); + header('Location: /login.php'); exit; } @@ -486,6 +489,18 @@ function __construct() { */ private function SurfControl() { + // Bug fix: GameEngine/Admin/Mods/*.php scripts (addUsers.php, gold.php, + // cp.php, editResources.php, ...) are POSTed to directly and already + // enforce their own access-level guard (access >= 9) plus CSRF. They + // are not "pages" in the player-facing $pagearray sense below, and + // routing them through this player login/page-redirect logic sent + // them to a relative "login.php" that resolved under + // GameEngine/Admin/Mods/ instead of the site root -> 404, regardless + // of whether the admin session was actually valid. + if ($this->inAdmin) { + return; + } + $page = SERVER_WEB_ROOT ? $_SERVER['SCRIPT_NAME'] : basename($_SERVER['SCRIPT_NAME']); @@ -497,18 +512,18 @@ function __construct() { if (!$this->logged_in) { if (!in_array($page, $pagearray) || $page == "logout.php") { - header("Location: login.php"); + header("Location: /login.php"); exit; } } else { if (in_array($page, $pagearray)) { if (($this->uid ?? 0) == 1) { - header("Location: nachrichten.php"); + header("Location: /nachrichten.php"); exit; } - header("Location: dorf1.php"); + header("Location: /dorf1.php"); exit; } } diff --git a/GameEngine/Units.php b/GameEngine/Units.php index 5fe038cf..9d6fc485 100755 --- a/GameEngine/Units.php +++ b/GameEngine/Units.php @@ -428,9 +428,22 @@ class Units { } } + // Bug fix: Brewery (35) is Teuton-only, capital-only, but empire-wide — + // the catapult-randomization side effect must be checked on the SENDER'S + // CAPITAL (not $village->wid, the village the rally point belongs to, + // which may not be the capital), and only while a Mead-Festival is + // actually active there — not simply because the Brewery is built. + $hasActiveBrewery = false; + if ($session->tribe == 2) { + $senderCapital = $database->getVillage($session->uid, 3); + $hasActiveBrewery = $senderCapital + && (int)$senderCapital['festival'] > time() + && $database->getFieldLevelInVillage($senderCapital['wref'], 35) > 0; + } + if(isset($post['ctar1'])) { - //Is the Brewery built? - if($session->tribe != 2 || $database->getFieldLevelInVillage($village->wid, 35) == 0){ + //Is the Mead-Festival active? + if(!$hasActiveBrewery){ if($rivalsGreatConfusion['totals'] > 0) { if($post['ctar1'] != 40 && ($post['ctar1'] != 27 || ($post['ctar1'] == 27 && $rivalsGreatConfusion['unique'] > 0))) { $post['ctar1'] = 0; @@ -442,8 +455,8 @@ class Units { else $post['ctar1'] = 0; if(isset($post['ctar2']) && $post['ctar2'] > 0) { - //Is the Brewery built? - if($session->tribe != 2 || $database->getFieldLevelInVillage($village->wid, 35) == 0){ + //Is the Mead-Festival active? + if(!$hasActiveBrewery){ if($rivalsGreatConfusion['totals'] > 0) { if ($post['ctar2'] != 40 && ($post['ctar2'] != 27 || ($post['ctar2'] == 27 && $rivalsGreatConfusion['unique'] > 0))) { $post['ctar2'] = 99; diff --git a/GameEngine/Village.php b/GameEngine/Village.php index ca50db21..85b909b2 100755 --- a/GameEngine/Village.php +++ b/GameEngine/Village.php @@ -137,6 +137,7 @@ class Village { $this->capital = $this->infoarray['capital']; $this->natar = $this->infoarray['natar']; $this->currentcel = $this->infoarray['celebration']; + $this->currentfestival = $this->infoarray['festival']; $this->wid = $this->infoarray['wref']; $this->vname = $this->infoarray['name']; diff --git a/Templates/Build/35.tpl b/Templates/Build/35.tpl index dee41e1c..2039f1f2 100644 --- a/Templates/Build/35.tpl +++ b/Templates/Build/35.tpl @@ -49,5 +49,11 @@ $current = $level > 0 ? (int)$bid35[$level]['attri'] : 0; + 0):?> + + +

+ + \ No newline at end of file diff --git a/Templates/Build/35_1.tpl b/Templates/Build/35_1.tpl new file mode 100644 index 00000000..43fa4bdf --- /dev/null +++ b/Templates/Build/35_1.tpl @@ -0,0 +1,65 @@ +currentfestival; +$now = time(); +$inProgress = $inuse > $now; + +// Unlike Town Hall celebrations, duration is fixed (not level-scaled) — only +// the combat bonus % scales with Brewery level (see $bid35 in 35.tpl). +$time = $generator->getTimeFormat(round($festival['time'] / SPEED)); +$total = $festival['wood'] + $festival['clay'] + $festival['iron'] + $festival['crop']; +$showNpc = $session->userinfo['gold'] >= 3 && $building->getTypeLevel(17) >= 1 && $village->atotal >= $total; +$canAfford = $festival['wood'] <= $village->awood && $festival['clay'] <= $village->aclay && $festival['iron'] <= $village->airon && $festival['crop'] <= $village->acrop; +?> + + + + + + + + +
+
+
+ | + | + | + | + + | + getProd("crop") > 0) { $t = $technology->calculateAvaliable(35, $festival); echo "
".ENOUGH_RESOURCES." ".$t[0]." at ".$t[1].""; } else echo "
".CROP_NEGATIVE.""; endif;?> +
+
+ timer; + ?> +
+
+ getTimeFormat($remaining);?> +
+
+ +
diff --git a/var/db/struct.sql b/var/db/struct.sql index f26a6ec0..023b0a8a 100644 --- a/var/db/struct.sql +++ b/var/db/struct.sql @@ -1692,6 +1692,7 @@ CREATE TABLE IF NOT EXISTS `%PREFIX%vdata` ( `cp` int(11) NULL, `celebration` int(11) NULL DEFAULT '0', `type` int(11) NULL DEFAULT '0', +`festival` int(11) NULL DEFAULT '0', `wood` float(12,2) NULL, `clay` float(12,2) NULL, `iron` float(12,2) NULL, @@ -1715,6 +1716,7 @@ KEY `owner-capital-pop` (`owner`,`capital`,`pop`), KEY `maxstore` (`maxstore`), KEY `maxcrop` (`maxcrop`), KEY `celebration` (`celebration`), +KEY `festival` (`festival`), KEY `wood` (`wood`), KEY `clay` (`clay`), KEY `iron` (`iron`),