mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-06-28 00:24:23 +00:00
Merge branch 'master' of https://github.com/Shadowss/TravianZ
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Git files
|
||||
.git
|
||||
.gitignore
|
||||
.gitattributes
|
||||
|
||||
# Docker files
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.dockerignore
|
||||
.env
|
||||
.env.example
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
DOCKER_README.md
|
||||
CODE_OF_CONDUCT.md
|
||||
CONTRIBUTING.md
|
||||
ISSUE_TEMPLATE.md
|
||||
LICENSE
|
||||
|
||||
# IDE and editor files
|
||||
.idea
|
||||
.vscode
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
@@ -0,0 +1,11 @@
|
||||
# MySQL Database Configuration
|
||||
MYSQL_ROOT_PASSWORD=rootpassword
|
||||
MYSQL_DATABASE=travian
|
||||
MYSQL_USER=travianz
|
||||
MYSQL_PASSWORD=travianzpass
|
||||
|
||||
# Application Configuration
|
||||
# These values will be used during the installation wizard
|
||||
# Hostname for database connection (use 'db' when running in Docker)
|
||||
DB_HOST=db
|
||||
DB_PORT=3306
|
||||
@@ -39,3 +39,6 @@ GameEngine/Admin/Mods/constant_format.tpl
|
||||
# These 2 files change frequently on the server but not in the repository code.
|
||||
Templates/text.tpl
|
||||
var/log/access.log
|
||||
|
||||
# Docker environment file with sensitive credentials
|
||||
.env
|
||||
|
||||
+410
-116
@@ -10,8 +10,10 @@
|
||||
## ##
|
||||
#################################################################################
|
||||
|
||||
// ----------------- PHP (logic unchanged, except $pixelDiv = 255) -----------------
|
||||
$check1 = $check2 = $check3 = "";
|
||||
$includeSize = true;
|
||||
$criteria = "";
|
||||
|
||||
if (isset($_POST['show1']) || isset($_POST['show2']) || isset($_POST['show3'])) {
|
||||
$check1 = isset($_POST['show1']) ? "checked " : "";
|
||||
@@ -44,127 +46,419 @@ if (isset($_POST['show1']) || isset($_POST['show2']) || isset($_POST['show3']))
|
||||
}
|
||||
}
|
||||
if ($check1 == "" && $check2 == "" && $check3 == "") $criteria = "";
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title><?php echo SERVER_NAME; ?> Map</title>
|
||||
<link rel="stylesheet" href="../img/admin/map.css" type="text/css" media="all">
|
||||
<div id="start">
|
||||
|
||||
<div class="clear">
|
||||
<h2 class="left"><?php echo SERVER_NAME;?> Map!</h2>
|
||||
</div>
|
||||
<p>This is the map of <?php echo SERVER_NAME;?>. Search and find players.</p>
|
||||
<h1>Show Option</h1>
|
||||
<form id="show" name="show" action="admin.php?p=map" method="POST">
|
||||
<table width="70%">
|
||||
<tr><td>
|
||||
<input id="show1" name="show1" type="checkbox" <?php echo $check1;?>value="1">Players
|
||||
</td>
|
||||
<td>
|
||||
<input id="show2" name="show2" type="checkbox" <?php echo $check2;?>value="2"><?php echo TRIBE5; ?>
|
||||
</td>
|
||||
<td>
|
||||
<input id="show3" name="show3" type="checkbox" <?php echo $check3;?>value="2">Artifacts
|
||||
</td>
|
||||
<td>
|
||||
<input id="btnshow" type="button" value="Show" style="font-size:9px" onclick=submit()>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<style>
|
||||
:root { --map-width:510px; --map-height:510px; }
|
||||
|
||||
<div id="kaart">
|
||||
/* Container */
|
||||
#map {
|
||||
width: 510px; height: 510px; position: relative; overflow: hidden;
|
||||
border: 1px solid #333; background: #f3f3f3;
|
||||
}
|
||||
#map.grab { cursor: grab; } #map.grabbing { cursor: grabbing; }
|
||||
|
||||
<div id="map" title="">
|
||||
/* World layer that we translate/scale */
|
||||
#map_bg {
|
||||
position:absolute; inset:0; width:var(--map-width); height:var(--map-height);
|
||||
transform-origin:0 0; will-change:transform; transition: transform 80ms ease;
|
||||
--zoom:1;
|
||||
}
|
||||
|
||||
<div class="zoomlevels">
|
||||
<span id="zl">-<?php echo WORLD_MAX;?></span>
|
||||
<span id="zr"><?php echo WORLD_MAX;?></span>
|
||||
<span id="zb"><?php echo WORLD_MAX;?></span>
|
||||
<span id="zo">-<?php echo WORLD_MAX;?></span>
|
||||
<span id="zc">(0,0)</span>
|
||||
<div id="lijn_hor"></div>
|
||||
<div id="lijn_ver"></div>
|
||||
</div>
|
||||
/* CRISP GRID (SVG lines) */
|
||||
#gridSvg { position:absolute; inset:0; pointer-events:none; }
|
||||
#gridSvg line { vector-effect: non-scaling-stroke; shape-rendering: crispEdges; }
|
||||
#gridSvg .minor { stroke: rgba(0,0,0,0.12); stroke-width: 1; }
|
||||
#gridSvg .major { stroke: rgba(0,0,0,0.25); stroke-width: 1; }
|
||||
|
||||
<div style="top: 0px; left: 0px;" id="map_bg">
|
||||
<?php
|
||||
if($criteria != ""){
|
||||
$artifactsEffect = ['-', VILLAGE_EFFECT, ACCOUNT_EFFECT, UNIQUE_EFFECT];
|
||||
$array_tribe = ['-', TRIBE1, TRIBE2, TRIBE3, TRIBE4, TRIBE5, TRIBE6];
|
||||
$q = "SELECT v.wref, v.owner, v.name, v.capital, v.pop, u.username, u.tribe, u.access, w.x, w.y".($includeSize ? ", a.size" : "")." FROM ".TB_PREFIX."vdata AS v LEFT JOIN ".TB_PREFIX."users AS u ON v.owner = u.id LEFT JOIN ".TB_PREFIX."wdata AS w ON v.wref = w.id ".$criteria;
|
||||
$player_info = $database->query_return($q);
|
||||
|
||||
foreach($player_info as $p_array) {
|
||||
$p_name = htmlspecialchars(mysqli_escape_string($database->dblink, $p_array['username']));
|
||||
$p_village = htmlspecialchars(mysqli_escape_string($database->dblink, $p_array['name']));
|
||||
$p_coor = "(".$p_array['x']."|".$p_array['y'].")";
|
||||
$p_pop = $p_array['pop'];
|
||||
$p_tribe = $array_tribe[$p_array['tribe']];
|
||||
|
||||
$p_info ="<a href=\"?p=village&did=".$p_array['wref']."\" target=\"_blank\"><img src=\"../img/admin/map_".(isset($p_array['size']) ? "1".$p_array['size'] : ($p_array['access'] != ADMIN ? $p_array['tribe'] : 0)).".gif\" border=\"0\" onmouseout=\"med_closeDescription()\" onmousemove=\"med_mouseMoveHandler(arguments[0],'<ul class=\'p_info\'><li>Player name: <b>$p_name</b></li><li>Village name : <b>$p_village</b></li><li>Coordinate: <b>$p_coor</b></li><li>Population: <b>$p_pop</b></li><li>Tribe: <b>$p_tribe</b></li>".($check3 != "" && isset($p_array['size']) ? "<li>Artifact effect: <b>".$artifactsEffect[$p_array['size']]."</b></li>" : "")."</ul>')\"></a>";
|
||||
|
||||
//245px = 0
|
||||
$pixelDiv = 245;
|
||||
$xdiv = $pixelDiv / WORLD_MAX;
|
||||
if($p_array['x'] <= 0) $p_x = $pixelDiv - intval(abs($p_array['x']) * $xdiv); //-x
|
||||
elseif($p_array['x'] >= 0) $p_x = $pixelDiv + intval(abs($p_array['x']) * $xdiv); //+x
|
||||
|
||||
if($p_array['y'] <= 0) $p_y = $pixelDiv + intval(abs($p_array['y']) * $xdiv); //-y
|
||||
elseif($p_array['y'] >= 0) $p_y = $pixelDiv - intval(abs($p_array['y']) * $xdiv); //+y
|
||||
|
||||
echo '<div style="left:'.$p_x.'px; top:'.$p_y.'px; position:absolute">'.$p_info.'</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="legenda">
|
||||
<div class="content">
|
||||
<h3>Legend</h3>
|
||||
<div id="items">
|
||||
<div class="first"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_1.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE1;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_2.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE2;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_3.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE3;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_5.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE5;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_0.gif" height="11" width="11"></td><td class="show">Multihunters</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
/* Markers centered on coords; keep constant size visually */
|
||||
.marker { position:absolute; transform: translate(-50%,-50%); }
|
||||
#map_bg .pin { transform-origin:center; transform: scale(calc(1 / var(--zoom))); cursor:pointer; }
|
||||
|
||||
<div id="legenda">
|
||||
<div class="content">
|
||||
<h3>Artifacts Legend</h3>
|
||||
<div id="items">
|
||||
<div class="first"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_11.gif" height="11" width="11"></td><td class="show"><?php echo VILLAGE_EFFECT;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_12.gif" height="11" width="11"></td><td class="show"><?php echo ACCOUNT_EFFECT;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="../img/admin/map_13.gif" height="11" width="11"></td><td class="show"><?php echo UNIQUE_EFFECT;?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
/* Zoom controls */
|
||||
.zoom-controls {
|
||||
position:absolute; top:8px; right:8px; display:flex; gap:6px; align-items:center;
|
||||
z-index:1000; background:rgba(255,255,255,.9); padding:6px 8px; border-radius:8px;
|
||||
box-shadow:0 2px 6px rgba(0,0,0,.15); user-select:none;
|
||||
}
|
||||
.zoom-controls button { font-size:12px; padding:6px 10px; border-radius:6px; border:1px solid #ccc; background:#f7f7f7; cursor:pointer; }
|
||||
.zoom-controls span { min-width:56px; text-align:center; font:12px system-ui,Arial; }
|
||||
|
||||
/* Axis labels & crosshair */
|
||||
.zoomlevels span { position:absolute; font:12px Arial; color:#000; }
|
||||
#zl { left:2px; top:50%; transform:translateY(-50%); }
|
||||
#zr { right:2px; top:50%; transform:translateY(-50%); }
|
||||
#zo { right:50%; top:2px; transform:translateX(50%); }
|
||||
#zb { right:50%; bottom:2px; transform:translateX(50%); }
|
||||
#zc { left:50%; top:50%; transform:translate(-50%,-50%); background:rgba(255,255,255,.85); padding:2px 4px; border-radius:4px; }
|
||||
#lijn_hor,#lijn_ver { position:absolute; background:#666; opacity:.5; }
|
||||
#lijn_hor { left:0; right:0; top:50%; height:1px; }
|
||||
#lijn_ver { top:0; bottom:0; left:50%; width:1px; }
|
||||
|
||||
/* Ensure tooltip list looks same for hover & sticky */
|
||||
.p_info { list-style:none; margin:0; padding:0; }
|
||||
.p_info li { margin:2px 0; }
|
||||
|
||||
/* Buttons inside tooltip */
|
||||
.p_actions { margin-top:6px; display:flex; gap:6px; }
|
||||
.p_btn {
|
||||
display:inline-block; font:12px/1 Arial; padding:4px 8px;
|
||||
border:1px solid #bbb; border-radius:6px; background:#fff; color:#2a2a2a; text-decoration:none;
|
||||
}
|
||||
.p_btn:hover { background:#f2f2f2; }
|
||||
|
||||
/* Sticky tooltip (same style family as your hover) */
|
||||
#tipBackdrop { position:absolute; inset:0; display:none; z-index:1099; background:transparent; }
|
||||
#stickyTip {
|
||||
position:absolute; z-index:1100; display:none; max-width:320px;
|
||||
background:#fff; border:1px solid #aaa; border-radius:8px;
|
||||
box-shadow:0 8px 24px rgba(0,0,0,.25); padding:8px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="start">
|
||||
<div class="clear"><h2 class="left"><?php echo SERVER_NAME;?> Map!</h2></div>
|
||||
<p>This is the map of <?php echo SERVER_NAME;?>. Search and find players.</p>
|
||||
|
||||
<h1>Show Option</h1>
|
||||
<form id="show" name="show" action="admin.php?p=map" method="POST">
|
||||
<table width="70%"><tr>
|
||||
<td><input id="show1" name="show1" type="checkbox" <?php echo $check1;?> value="1">Players</td>
|
||||
<td><input id="show2" name="show2" type="checkbox" <?php echo $check2;?> value="2"><?php echo TRIBE5; ?></td>
|
||||
<td><input id="show3" name="show3" type="checkbox" <?php echo $check3;?> value="2">Artifacts</td>
|
||||
<td><input id="btnshow" type="submit" value="Show" style="font-size:9px"></td>
|
||||
</tr></table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="kaart">
|
||||
<div id="map" class="grab" title="">
|
||||
<!-- Zoom UI -->
|
||||
<div class="zoom-controls">
|
||||
<button type="button" id="zoomOut">−</button>
|
||||
<span id="zoomLabel">100%</span>
|
||||
<button type="button" id="zoomIn">+</button>
|
||||
<button type="button" id="zoomReset">Reset</button>
|
||||
</div>
|
||||
|
||||
<div class="zoomlevels">
|
||||
<span id="zl">-<?php echo WORLD_MAX;?></span>
|
||||
<span id="zr"><?php echo WORLD_MAX;?></span>
|
||||
<span id="zb"><?php echo WORLD_MAX;?></span>
|
||||
<span id="zo">-<?php echo WORLD_MAX;?></span>
|
||||
<span id="zc">(0,0)</span>
|
||||
<div id="lijn_hor"></div>
|
||||
<div id="lijn_ver"></div>
|
||||
</div>
|
||||
|
||||
<!-- World layer -->
|
||||
<div id="map_bg">
|
||||
<!-- Grid -->
|
||||
<svg id="gridSvg" width="510" height="510" aria-hidden="true"></svg>
|
||||
|
||||
<?php
|
||||
if ($criteria != "") {
|
||||
$artifactsEffect = ['-', VILLAGE_EFFECT, ACCOUNT_EFFECT, UNIQUE_EFFECT];
|
||||
$array_tribe = ['-', TRIBE1, TRIBE2, TRIBE3, TRIBE4, TRIBE5, TRIBE6];
|
||||
|
||||
$q = "SELECT v.wref, v.owner, v.name, v.capital, v.pop, u.username, u.tribe, u.access, w.x, w.y"
|
||||
. ($includeSize ? ", a.size" : "")
|
||||
. " FROM ".TB_PREFIX."vdata AS v"
|
||||
. " LEFT JOIN ".TB_PREFIX."users AS u ON v.owner = u.id"
|
||||
. " LEFT JOIN ".TB_PREFIX."wdata AS w ON v.wref = w.id "
|
||||
. $criteria;
|
||||
|
||||
$player_info = $database->query_return($q);
|
||||
|
||||
foreach ($player_info as $p_array) {
|
||||
$p_name = htmlspecialchars($p_array['username'], ENT_QUOTES);
|
||||
$p_village= htmlspecialchars($p_array['name'], ENT_QUOTES);
|
||||
$p_pop = (int)$p_array['pop'];
|
||||
$p_tribe = $array_tribe[$p_array['tribe']];
|
||||
$did = (int)$p_array['wref'];
|
||||
$uid = (int)$p_array['owner'];
|
||||
$x = (int)$p_array['x'];
|
||||
$y = (int)$p_array['y'];
|
||||
|
||||
$imgName = "../img/admin/map_".(isset($p_array['size']) ? "1".$p_array['size'] : ($p_array['access'] != ADMIN ? $p_array['tribe'] : 0)).".gif";
|
||||
|
||||
// world to pixels (510x510 world; center 255,255)
|
||||
$pixelDiv = 255;
|
||||
$xdiv = $pixelDiv / WORLD_MAX;
|
||||
$p_x = $pixelDiv + ($x * $xdiv);
|
||||
$p_y = $pixelDiv - ($y * $xdiv);
|
||||
|
||||
// Tooltip HTML (shared by hover & sticky)
|
||||
$tooltip = "<ul class='p_info'>";
|
||||
$tooltip .= "<li>Player name: <b>{$p_name}</b></li>";
|
||||
$tooltip .= "<li>Village name : <b>{$p_village}</b></li>";
|
||||
$tooltip .= "<li>Coordinate: <b>({$x}|{$y})</b></li>";
|
||||
$tooltip .= "<li>Population: <b>{$p_pop}</b></li>";
|
||||
$tooltip .= "<li>Tribe: <b>{$p_tribe}</b></li>";
|
||||
if ($check3 != "" && isset($p_array['size'])) {
|
||||
$tooltip .= "<li>Artifact effect: <b>".$artifactsEffect[$p_array['size']]."</b></li>";
|
||||
}
|
||||
$tooltip .= "</ul>";
|
||||
$tooltip .= "<div class='p_actions'>"
|
||||
. "<a class='p_btn' href='?p=village&did={$did}' target='_blank' rel='noopener'>Open village</a>"
|
||||
. "<a class='p_btn' href='?p=player&uid={$uid}' target='_blank' rel='noopener'>Open profile</a>"
|
||||
. "</div>";
|
||||
|
||||
// JS string version for hover (escape quotes and backslashes)
|
||||
$tooltipHover = str_replace(["\\", "'"], ["\\\\", "\\'"], $tooltip);
|
||||
// Attribute version for sticky (HTML-encode quotes)
|
||||
$tooltipAttr = htmlspecialchars($tooltip, ENT_QUOTES);
|
||||
|
||||
echo '<div class="marker" style="left:'.$p_x.'px; top:'.$p_y.'px;" data-tip="'.$tooltipAttr.'">'
|
||||
. '<img class="pin" src="'.$imgName.'" border="0" '
|
||||
. ' onmouseout="med_closeDescription()" '
|
||||
. " onmousemove=\"med_mouseMoveHandler(arguments[0], '".$tooltipHover."')\" "
|
||||
. '>'
|
||||
. '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- Sticky tooltip containers -->
|
||||
<div id="tipBackdrop"></div>
|
||||
<div id="stickyTip"></div>
|
||||
</div>
|
||||
|
||||
<div id="legenda">
|
||||
<div class="content">
|
||||
<h3>Legend</h3>
|
||||
<div id="items">
|
||||
<div class="first"></div>
|
||||
<table>
|
||||
<tr><td><img src="../img/admin/map_1.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE1;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_2.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE2;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_3.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE3;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_5.gif" height="11" width="11"></td><td class="show"><?php echo TRIBE5;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_0.gif" height="11" width="11"></td><td class="show">Multihunters</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="legenda">
|
||||
<div class="content">
|
||||
<h3>Artifacts Legend</h3>
|
||||
<div id="items">
|
||||
<div class="first"></div>
|
||||
<table>
|
||||
<tr><td><img src="../img/admin/map_11.gif" height="11" width="11"></td><td class="show"><?php echo VILLAGE_EFFECT;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_12.gif" height="11" width="11"></td><td class="show"><?php echo ACCOUNT_EFFECT;?></td></tr>
|
||||
<tr><td><img src="../img/admin/map_13.gif" height="11" width="11"></td><td class="show"><?php echo UNIQUE_EFFECT;?></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================== JS: crisp SVG grid + clamped pan + cursor zoom + sticky tooltip ===================== -->
|
||||
<script>
|
||||
(function () {
|
||||
const map = document.getElementById('map');
|
||||
const layer = document.getElementById('map_bg');
|
||||
const grid = document.getElementById('gridSvg');
|
||||
|
||||
const zl = document.getElementById('zl');
|
||||
const zr = document.getElementById('zr');
|
||||
const zo = document.getElementById('zo');
|
||||
const zb = document.getElementById('zb');
|
||||
const zc = document.getElementById('zc');
|
||||
|
||||
const zoomInBtn = document.getElementById('zoomIn');
|
||||
const zoomOutBtn = document.getElementById('zoomOut');
|
||||
const zoomResetBtn = document.getElementById('zoomReset');
|
||||
const zoomLabel = document.getElementById('zoomLabel');
|
||||
|
||||
const sticky = document.getElementById('stickyTip');
|
||||
const stickyBackdrop = document.getElementById('tipBackdrop');
|
||||
|
||||
const WORLD_MAX = <?php echo json_encode(WORLD_MAX); ?>;
|
||||
|
||||
// Base sizes (match CSS)
|
||||
const baseW = parseFloat(getComputedStyle(layer).getPropertyValue('--map-width')) || 510;
|
||||
const baseH = parseFloat(getComputedStyle(layer).getPropertyValue('--map-height')) || 510;
|
||||
|
||||
// World->pixel conversion (0,0 at center)
|
||||
const pixelDiv = baseW / 2; // 255
|
||||
const xdiv = pixelDiv / WORLD_MAX; // px per world unit
|
||||
|
||||
// Build SVG grid (even, crisp)
|
||||
function buildGrid() {
|
||||
const MAJOR_UNIT = 10;
|
||||
grid.setAttribute('viewBox', `0 0 ${baseW} ${baseH}`);
|
||||
grid.innerHTML = "";
|
||||
|
||||
for (let x = -WORLD_MAX; x <= WORLD_MAX; x++) {
|
||||
const px = pixelDiv + x * xdiv;
|
||||
const v = document.createElementNS('http://www.w3.org/2000/svg','line');
|
||||
v.setAttribute('x1',px); v.setAttribute('y1',0);
|
||||
v.setAttribute('x2',px); v.setAttribute('y2',baseH);
|
||||
v.setAttribute('class', (x % MAJOR_UNIT === 0) ? 'major' : 'minor');
|
||||
grid.appendChild(v);
|
||||
}
|
||||
for (let y = -WORLD_MAX; y <= WORLD_MAX; y++) {
|
||||
const py = pixelDiv - y * xdiv;
|
||||
const h = document.createElementNS('http://www.w3.org/2000/svg','line');
|
||||
h.setAttribute('x1',0); h.setAttribute('y1',py);
|
||||
h.setAttribute('x2',baseW); h.setAttribute('y2',py);
|
||||
h.setAttribute('class', (y % MAJOR_UNIT === 0) ? 'major' : 'minor');
|
||||
grid.appendChild(h);
|
||||
}
|
||||
}
|
||||
buildGrid();
|
||||
|
||||
// Zoom levels
|
||||
const STEP_SCALE = 1.25;
|
||||
const MAX_Z = 16;
|
||||
let MIN_Z = 0;
|
||||
function sFromLvl(lvl){ return Math.pow(STEP_SCALE, lvl); }
|
||||
|
||||
// Clamp pan to avoid blank
|
||||
function clampPan() {
|
||||
const s = sFromLvl(zoomLevel);
|
||||
const scaledW = baseW * s;
|
||||
const scaledH = baseH * s;
|
||||
|
||||
if (scaledW <= map.clientWidth) {
|
||||
tx = (map.clientWidth - scaledW) / 2;
|
||||
} else {
|
||||
const minTx = map.clientWidth - scaledW;
|
||||
tx = Math.max(minTx, Math.min(tx, 0));
|
||||
}
|
||||
|
||||
if (scaledH <= map.clientHeight) {
|
||||
ty = (map.clientHeight - scaledH) / 2;
|
||||
} else {
|
||||
const minTy = map.clientHeight - scaledH;
|
||||
ty = Math.max(minTy, Math.min(ty, 0));
|
||||
}
|
||||
}
|
||||
|
||||
function applyTransform(){
|
||||
clampPan();
|
||||
const s = sFromLvl(zoomLevel);
|
||||
layer.style.setProperty('--zoom', s);
|
||||
layer.style.transform = `translate(${tx}px, ${ty}px) scale(${s})`;
|
||||
zoomLabel.textContent = Math.round(s*100) + '%';
|
||||
updateAxes();
|
||||
}
|
||||
|
||||
// Map-local px -> world coords
|
||||
function screenToWorld(localX, localY){
|
||||
const s = sFromLvl(zoomLevel);
|
||||
const lx = (localX - tx) / s;
|
||||
const ly = (localY - ty) / s;
|
||||
return { x: (lx - pixelDiv) / xdiv, y: (pixelDiv - ly) / xdiv };
|
||||
}
|
||||
|
||||
function updateAxes(){
|
||||
const w=map.clientWidth, h=map.clientHeight;
|
||||
const left = screenToWorld(0,h/2).x, right = screenToWorld(w,h/2).x;
|
||||
const top = screenToWorld(w/2,0).y, bottom = screenToWorld(w/2,h).y;
|
||||
const center = screenToWorld(w/2,h/2);
|
||||
zl.textContent=Math.round(left); zr.textContent=Math.round(right);
|
||||
zo.textContent=Math.round(top); zb.textContent=Math.round(bottom);
|
||||
zc.textContent=`(${Math.round(center.x)},${Math.round(center.y)})`;
|
||||
}
|
||||
|
||||
function computeMinLevel(){
|
||||
const fit = Math.max(map.clientWidth / baseW, map.clientHeight / baseH);
|
||||
let lvl=0, s=1;
|
||||
if (fit >= 1) { while (s < fit) { s *= STEP_SCALE; lvl++; } }
|
||||
else { while (s / STEP_SCALE >= fit) { s /= STEP_SCALE; lvl--; } }
|
||||
MIN_Z = lvl;
|
||||
}
|
||||
|
||||
function clampLevel(next){ return Math.min(MAX_Z, Math.max(MIN_Z, next)); }
|
||||
|
||||
function toLocal(e){ const r = map.getBoundingClientRect(); return { x:e.clientX-r.left, y:e.clientY-r.top }; }
|
||||
|
||||
// Zoom toward cursor
|
||||
function zoomAt(deltaLevel, localX, localY){
|
||||
const newLevel = clampLevel(zoomLevel + deltaLevel);
|
||||
if (newLevel === zoomLevel) return;
|
||||
const oldS = sFromLvl(zoomLevel), newS = sFromLvl(newLevel);
|
||||
const lx = (localX - tx) / oldS, ly = (localY - ty) / oldS;
|
||||
tx = localX - lx * newS; ty = localY - ly * newS;
|
||||
zoomLevel = newLevel; applyTransform();
|
||||
}
|
||||
function zoomBy(delta){ zoomAt(delta, map.clientWidth/2, map.clientHeight/2); }
|
||||
|
||||
// State
|
||||
let zoomLevel = 0, tx = 0, ty = 0;
|
||||
|
||||
// Controls
|
||||
zoomInBtn.addEventListener('click', ()=>zoomBy(+1));
|
||||
zoomOutBtn.addEventListener('click', ()=>zoomBy(-1));
|
||||
zoomResetBtn.addEventListener('click', ()=>{
|
||||
computeMinLevel(); zoomLevel = MIN_Z;
|
||||
const s = sFromLvl(zoomLevel);
|
||||
tx = (map.clientWidth - baseW * s) / 2;
|
||||
ty = (map.clientHeight - baseH * s) / 2;
|
||||
applyTransform();
|
||||
});
|
||||
|
||||
// Wheel / dblclick
|
||||
map.addEventListener('wheel', (e)=>{ e.preventDefault(); const p=toLocal(e); zoomAt(e.deltaY<0?+1:-1, p.x,p.y); }, {passive:false});
|
||||
map.addEventListener('dblclick', (e)=>{ e.preventDefault(); const p=toLocal(e); zoomAt(e.shiftKey?-1:+1, p.x,p.y); });
|
||||
|
||||
// Drag pan
|
||||
let dragging=false, lastX=0, lastY=0;
|
||||
map.addEventListener('mousedown',(e)=>{ if(e.button!==0) return; dragging=true; map.classList.add('grabbing'); const p=toLocal(e); lastX=p.x; lastY=p.y; });
|
||||
window.addEventListener('mousemove',(e)=>{ if(!dragging) return; const p=toLocal(e); tx+=(p.x-lastX); ty+=(p.y-lastY); lastX=p.x; lastY=p.y; applyTransform(); });
|
||||
window.addEventListener('mouseup',()=>{ dragging=false; map.classList.remove('grabbing'); });
|
||||
map.addEventListener('mouseleave',()=>{ dragging=false; map.classList.remove('grabbing'); });
|
||||
|
||||
// Touch
|
||||
map.addEventListener('touchstart',(e)=>{ if(e.touches.length===1){ const t=e.touches[0], r=map.getBoundingClientRect(); dragging=true; map.classList.add('grabbing'); lastX=t.clientX-r.left; lastY=t.clientY-r.top; } }, {passive:true});
|
||||
map.addEventListener('touchmove',(e)=>{ if(dragging && e.touches.length===1){ const t=e.touches[0], r=map.getBoundingClientRect(); const x=t.clientX-r.left, y=t.clientY-r.top; tx+=(x-lastX); ty+=(y-lastY); lastX=x; lastY=y; applyTransform(); e.preventDefault(); } }, {passive:false});
|
||||
map.addEventListener('touchend',()=>{ dragging=false; map.classList.remove('grabbing'); });
|
||||
|
||||
// Init
|
||||
computeMinLevel(); zoomLevel = MIN_Z;
|
||||
tx = (map.clientWidth - baseW) / 2; ty = (map.clientHeight - baseH) / 2; applyTransform();
|
||||
window.addEventListener('resize', ()=>{ computeMinLevel(); if(zoomLevel<MIN_Z) zoomLevel=MIN_Z; applyTransform(); });
|
||||
|
||||
// Sticky tooltip behavior
|
||||
function openSticky(html, localX, localY){
|
||||
sticky.innerHTML = html;
|
||||
sticky.style.display = 'block';
|
||||
const rect = sticky.getBoundingClientRect();
|
||||
const W = rect.width || 280, H = rect.height || 140;
|
||||
let left = localX + 12, top = localY + 12;
|
||||
left = Math.max(8, Math.min(left, map.clientWidth - W - 8));
|
||||
top = Math.max(8, Math.min(top, map.clientHeight - H - 8));
|
||||
sticky.style.left = left + 'px';
|
||||
sticky.style.top = top + 'px';
|
||||
stickyBackdrop.style.display = 'block';
|
||||
}
|
||||
function closeSticky(){ sticky.style.display='none'; stickyBackdrop.style.display='none'; sticky.innerHTML=''; }
|
||||
stickyBackdrop.addEventListener('click', closeSticky);
|
||||
document.addEventListener('keydown', (e)=>{ if(e.key==='Escape') closeSticky(); });
|
||||
sticky.addEventListener('click', (e)=> e.stopPropagation());
|
||||
|
||||
// Click marker -> sticky tooltip (uses clean HTML from data-tip)
|
||||
layer.addEventListener('click', (e)=>{
|
||||
const marker = e.target.closest('.marker'); if(!marker) return;
|
||||
const html = marker.getAttribute('data-tip'); if(!html) return;
|
||||
const r = map.getBoundingClientRect();
|
||||
openSticky(html, e.clientX - r.left, e.clientY - r.top);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
# TravianZ Docker Setup
|
||||
|
||||
This guide will help you set up TravianZ using Docker and Docker Compose for easy deployment.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker Engine 20.10 or higher
|
||||
- Docker Compose 1.29 or higher
|
||||
- At least 2GB of free RAM
|
||||
- At least 5GB of free disk space
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Clone the Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Shadowss/TravianZ.git
|
||||
cd TravianZ
|
||||
```
|
||||
|
||||
### 2. Configure Environment Variables
|
||||
|
||||
Copy the example environment file and customize it if needed:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` file to set your database credentials:
|
||||
|
||||
```env
|
||||
MYSQL_ROOT_PASSWORD=yourStrongRootPassword
|
||||
MYSQL_DATABASE=travian
|
||||
MYSQL_USER=travianz
|
||||
MYSQL_PASSWORD=yourStrongPassword
|
||||
```
|
||||
|
||||
### 3. Start the Containers
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
This command will:
|
||||
- Build the TravianZ web application container
|
||||
- Start a MySQL 5.7 database container
|
||||
- Start a phpMyAdmin container for database management
|
||||
- Set up a network for all containers to communicate
|
||||
|
||||
### 4. Access the Installation Wizard
|
||||
|
||||
Once the containers are running, open your browser and navigate to:
|
||||
|
||||
```
|
||||
http://localhost:8080/install
|
||||
```
|
||||
|
||||
### 5. Complete the Installation
|
||||
|
||||
During the installation wizard, use these database settings:
|
||||
|
||||
- **SQL Hostname:** `db` (this is the Docker container name)
|
||||
- **Port:** `3306`
|
||||
- **Username:** `travianz` (or the value from your `.env` file)
|
||||
- **Password:** `travianzpass` (or the value from your `.env` file)
|
||||
- **DB name:** `travian` (or the value from your `.env` file)
|
||||
- **Prefix:** `s1_` (or customize as needed)
|
||||
- **Type:** `MYSQLi`
|
||||
|
||||
Complete the rest of the installation wizard with your preferred server settings.
|
||||
|
||||
## Services and Ports
|
||||
|
||||
After starting the containers, the following services will be available:
|
||||
|
||||
- **TravianZ Web Application:** http://localhost:8080
|
||||
- **phpMyAdmin:** http://localhost:8081
|
||||
- **MySQL Database:** localhost:3306 (for external connections)
|
||||
|
||||
## Container Management
|
||||
|
||||
### View Running Containers
|
||||
|
||||
```bash
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# All containers
|
||||
docker-compose logs
|
||||
|
||||
# Specific container
|
||||
docker-compose logs web
|
||||
docker-compose logs db
|
||||
docker-compose logs phpmyadmin
|
||||
|
||||
# Follow logs in real-time
|
||||
docker-compose logs -f web
|
||||
```
|
||||
|
||||
### Stop Containers
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Stop and Remove All Data
|
||||
|
||||
**WARNING:** This will delete all database data!
|
||||
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
### Restart Containers
|
||||
|
||||
```bash
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
### Rebuild Containers
|
||||
|
||||
If you make changes to the Dockerfile or application code:
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
## Accessing the Containers
|
||||
|
||||
### Access Web Container Shell
|
||||
|
||||
```bash
|
||||
docker exec -it travianz-web bash
|
||||
```
|
||||
|
||||
### Access MySQL Container
|
||||
|
||||
```bash
|
||||
docker exec -it travianz-db mysql -u root -p
|
||||
```
|
||||
|
||||
Enter the root password from your `.env` file.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Installation Files Not Writable
|
||||
|
||||
If you get permission errors during installation:
|
||||
|
||||
```bash
|
||||
docker exec -it travianz-web chown -R www-data:www-data /var/www/html
|
||||
docker exec -it travianz-web chmod -R 777 /var/www/html/var
|
||||
```
|
||||
|
||||
### Database Connection Failed
|
||||
|
||||
1. Make sure the database container is running:
|
||||
```bash
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
2. Check database logs:
|
||||
```bash
|
||||
docker-compose logs db
|
||||
```
|
||||
|
||||
3. Verify the hostname is set to `db` (not `localhost` or `127.0.0.1`)
|
||||
|
||||
### Reset Installation
|
||||
|
||||
If you need to start the installation over:
|
||||
|
||||
1. Stop containers:
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
2. Remove the installed flag:
|
||||
```bash
|
||||
rm -f var/installed
|
||||
rm -f GameEngine/config.php
|
||||
```
|
||||
|
||||
3. Start containers again:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4. Access the installation wizard again at http://localhost:8080/install
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
If port 8080 or 8081 is already in use, edit `docker-compose.yml` and change the ports:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
ports:
|
||||
- "9080:80" # Change 8080 to any available port
|
||||
phpmyadmin:
|
||||
ports:
|
||||
- "9081:80" # Change 8081 to any available port
|
||||
```
|
||||
|
||||
## Backup and Restore
|
||||
|
||||
### Backup Database
|
||||
|
||||
```bash
|
||||
docker exec travianz-db mysqldump -u root -p travian > backup_$(date +%Y%m%d).sql
|
||||
```
|
||||
|
||||
### Restore Database
|
||||
|
||||
```bash
|
||||
docker exec -i travianz-db mysql -u root -p travian < backup_20231125.sql
|
||||
```
|
||||
|
||||
### Backup Application Files
|
||||
|
||||
```bash
|
||||
tar -czf travianz_backup_$(date +%Y%m%d).tar.gz \
|
||||
--exclude='./var/db' \
|
||||
--exclude='./.git' \
|
||||
.
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
For production environments, consider the following:
|
||||
|
||||
1. **Use Strong Passwords:** Change all default passwords in `.env`
|
||||
|
||||
2. **Use SSL/TLS:** Set up a reverse proxy (nginx/traefik) with Let's Encrypt
|
||||
|
||||
3. **Limit Database Access:** Remove the database port exposure in `docker-compose.yml`
|
||||
|
||||
4. **Regular Backups:** Set up automated backup scripts
|
||||
|
||||
5. **Resource Limits:** Add resource constraints to containers:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
6. **Monitoring:** Consider adding monitoring tools like Prometheus and Grafana
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### MySQL Tuning
|
||||
|
||||
Edit `docker-compose.yml` to add MySQL configuration:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
command: >
|
||||
--default-authentication-plugin=mysql_native_password
|
||||
--sql_mode=""
|
||||
--max_connections=200
|
||||
--innodb_buffer_pool_size=512M
|
||||
--query_cache_size=32M
|
||||
--query_cache_limit=2M
|
||||
```
|
||||
|
||||
### PHP Tuning
|
||||
|
||||
Create a custom PHP configuration file `php-custom.ini`:
|
||||
|
||||
```ini
|
||||
memory_limit = 256M
|
||||
upload_max_filesize = 20M
|
||||
post_max_size = 20M
|
||||
max_execution_time = 300
|
||||
```
|
||||
|
||||
Then mount it in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
volumes:
|
||||
- ./php-custom.ini:/usr/local/etc/php/conf.d/custom.ini
|
||||
```
|
||||
|
||||
## Updates
|
||||
|
||||
To update TravianZ to the latest version:
|
||||
|
||||
```bash
|
||||
git pull origin main
|
||||
docker-compose down
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For issues and questions:
|
||||
- GitHub Issues: https://github.com/Shadowss/TravianZ/issues
|
||||
- Gitter Chat: https://gitter.im/TravianZ-V8/Lobby
|
||||
|
||||
## License
|
||||
|
||||
TravianZ Project - See LICENSE file for details
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
FROM php:7.4-apache
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libpng-dev \
|
||||
libjpeg-dev \
|
||||
libfreetype6-dev \
|
||||
libzip-dev \
|
||||
zip \
|
||||
unzip \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Configure and install PHP extensions
|
||||
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install -j$(nproc) \
|
||||
gd \
|
||||
mysqli \
|
||||
pdo \
|
||||
pdo_mysql \
|
||||
zip
|
||||
|
||||
# Enable Apache modules
|
||||
RUN a2enmod rewrite headers
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Copy application files
|
||||
COPY . /var/www/html/
|
||||
|
||||
# Set permissions
|
||||
RUN chown -R www-data:www-data /var/www/html \
|
||||
&& chmod -R 755 /var/www/html \
|
||||
&& chmod -R 777 /var/www/html/var
|
||||
|
||||
# Configure Apache to use /var/www/html as DocumentRoot
|
||||
RUN sed -i 's!/var/www/html!/var/www/html!g' /etc/apache2/sites-available/000-default.conf
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Start Apache
|
||||
CMD ["apache2-foreground"]
|
||||
Executable → Regular
+738
-286
File diff suppressed because it is too large
Load Diff
+233
-91
@@ -619,26 +619,25 @@ class MYSQLi_DB implements IDbConnection {
|
||||
References: lietuvis10
|
||||
***************************/
|
||||
|
||||
public function getBestOasisCropBonus($x, $y) {
|
||||
$x = (int)$x;
|
||||
$y = (int)$y;
|
||||
|
||||
// Adjust oasis type codes if your fork differs:
|
||||
// - 50% crop only: type IN (12)
|
||||
// - 25% crop (pure or mixed w/ wood/clay/iron): type IN (4,9,10,11)
|
||||
|
||||
$sql = "SELECT COALESCE(SUM(bonus), 0) AS total FROM (SELECT CASE
|
||||
WHEN o.type IN (12) THEN 50 WHEN o.type IN (4,9,10,11) THEN 25 ELSE 0
|
||||
END AS bonus FROM " . TB_PREFIX . "wdata w JOIN " . TB_PREFIX . "odata o ON o.wref = w.id
|
||||
WHERE w.fieldtype = 0 AND ABS(w.x - $x) <= 3 AND ABS(w.y - $y) <= 3
|
||||
AND o.type IN (12,4,9,10,11) -- only crop-giving oases ORDER BY bonus DESC LIMIT 3) t";
|
||||
public function getBestOasisCropBonus($x, $y) {
|
||||
$x = (int)$x;
|
||||
$y = (int)$y;
|
||||
|
||||
$q = mysqli_query($this->dblink, $sql);
|
||||
$row = mysqli_fetch_assoc($q);
|
||||
$total = (int)($row['total'] ?? 0);
|
||||
if ($total > 150) $total = 150; // safety cap
|
||||
return $total;
|
||||
}
|
||||
// Adjust oasis type codes if your fork differs:
|
||||
// - 50% crop only: type IN (12)
|
||||
// - 25% crop (pure or mixed w/ wood/clay/iron): type IN (4,9,10,11)
|
||||
$sql = "SELECT COALESCE(SUM(bonus), 0) AS total FROM (SELECT CASE
|
||||
WHEN o.type IN (12) THEN 50 WHEN o.type IN (4,9,10,11) THEN 25 ELSE 0
|
||||
END AS bonus FROM " . TB_PREFIX . "wdata w JOIN " . TB_PREFIX . "odata o ON o.wref = w.id
|
||||
WHERE w.fieldtype = 0 AND ABS(w.x - $x) <= 3 AND ABS(w.y - $y) <= 3 AND o.type IN (12,4,9,10,11)
|
||||
ORDER BY bonus DESC LIMIT 3) t";
|
||||
|
||||
$q = mysqli_query($this->dblink, $sql);
|
||||
$row = mysqli_fetch_assoc($q);
|
||||
$total = (int)($row['total'] ?? 0);
|
||||
if ($total > 150) $total = 150; // safety cap
|
||||
return $total;
|
||||
}
|
||||
|
||||
/***************************
|
||||
Function to process MYSQLi->fetch_all (Only exist in MYSQL)
|
||||
@@ -7014,94 +7013,237 @@ References: User ID/Message ID, Mode
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*** Build/rebuild the croppers precompute table from wdata. */
|
||||
|
||||
public function TotalCroppers(): int {
|
||||
$TBP = defined('TB_PREFIX') ? TB_PREFIX : 's1_';
|
||||
$WDATA = $TBP . 'wdata';
|
||||
|
||||
$res = mysqli_query($this->dblink, "SELECT COUNT(*) AS cnt FROM `$WDATA` WHERE fieldtype IN (1,6)");
|
||||
if (!$res) {
|
||||
throw new Exception('Count query failed: ' . mysqli_error($this->dblink));
|
||||
}
|
||||
|
||||
$row = mysqli_fetch_assoc($res);
|
||||
return (int)($row['cnt'] ?? 0);
|
||||
}
|
||||
|
||||
public function populateCroppers(int $countTotal = 0, bool $truncateFirst = false, int $batch = 20000, ?callable $reporter = null ): array {
|
||||
|
||||
@set_time_limit(0);
|
||||
@ini_set('memory_limit', '1G');
|
||||
|
||||
$TBP = defined('TB_PREFIX') ? TB_PREFIX : 's1_';
|
||||
$CROP_TABLE = $TBP . 'croppers';
|
||||
$WDATA = $TBP . 'wdata';
|
||||
|
||||
// Count once if caller didn't
|
||||
if ($countTotal <= 0) {
|
||||
$row = mysqli_fetch_assoc(mysqli_query($this->dblink,
|
||||
"SELECT COUNT(*) cnt FROM `$WDATA` WHERE fieldtype IN (1,6)"));
|
||||
$countTotal = (int)($row['cnt'] ?? 0);
|
||||
}
|
||||
|
||||
if ($truncateFirst) {
|
||||
if (!mysqli_query($this->dblink, "TRUNCATE TABLE `$CROP_TABLE`")) {
|
||||
return ['ok'=>false,'msg'=>'TRUNCATE failed: '.mysqli_error($this->dblink)];
|
||||
}
|
||||
}
|
||||
|
||||
// Session-level speed knobs (local to this connection)
|
||||
@mysqli_query($this->dblink, "SET innodb_flush_log_at_trx_commit=2");
|
||||
@mysqli_query($this->dblink, "SET sync_binlog=0");
|
||||
@mysqli_query($this->dblink, "SET unique_checks=0");
|
||||
@mysqli_query($this->dblink, "SET foreign_key_checks=0");
|
||||
|
||||
// Read big windows; write in safe slices to avoid max_allowed_packet
|
||||
if ($batch < 1000) $batch = 1000;
|
||||
if ($batch > 100000) $batch = 100000;
|
||||
if($countTotal < 1000) $sliceSize = 200;
|
||||
elseif($countTotal < 5000) $sliceSize = 500;
|
||||
elseif($countTotal > 5000) $sliceSize = 1000;
|
||||
|
||||
$total = 0;
|
||||
$lastId = 0;
|
||||
|
||||
// Cursor pagination (no OFFSET)
|
||||
while (true) {
|
||||
$res = mysqli_query(
|
||||
$this->dblink,
|
||||
"SELECT id AS wref, x, y, fieldtype
|
||||
FROM `$WDATA`
|
||||
WHERE fieldtype IN (1,6) AND id > $lastId
|
||||
ORDER BY id ASC
|
||||
LIMIT $batch"
|
||||
);
|
||||
if (!$res) {
|
||||
return ['ok'=>false,'msg'=>'SELECT failed: '.mysqli_error($this->dblink),'processed'=>$total,'target'=>$countTotal];
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
while ($r = mysqli_fetch_assoc($res)) { $rows[] = $r; }
|
||||
if (!$rows) break;
|
||||
|
||||
mysqli_begin_transaction($this->dblink);
|
||||
|
||||
$n = count($rows);
|
||||
for ($i = 0; $i < $n; $i += $sliceSize) {
|
||||
$chunk = array_slice($rows, $i, $sliceSize);
|
||||
$values = [];
|
||||
|
||||
foreach ($chunk as $r) {
|
||||
$x = (int)$r['x'];
|
||||
$y = (int)$r['y'];
|
||||
|
||||
// Your existing helper:
|
||||
$bonus = (int)$this->getBestOasisCropBonus($x, $y);
|
||||
if ($bonus < 0) $bonus = 0;
|
||||
if ($bonus > 150) $bonus = 150;
|
||||
|
||||
$values[] = sprintf("(%d,%d,%d,%d,%d)",
|
||||
(int)$r['wref'], $x, $y, (int)$r['fieldtype'], $bonus
|
||||
);
|
||||
}
|
||||
|
||||
if ($values) {
|
||||
// ODKU is cheaper than REPLACE (no DELETE)
|
||||
$sql = "INSERT INTO `$CROP_TABLE`
|
||||
(`wref`,`x`,`y`,`fieldtype`,`best_oasis_bonus`)
|
||||
VALUES ".implode(',', $values)."
|
||||
ON DUPLICATE KEY UPDATE
|
||||
`x`=VALUES(`x`),
|
||||
`y`=VALUES(`y`),
|
||||
`fieldtype`=VALUES(`fieldtype`),
|
||||
`best_oasis_bonus`=VALUES(`best_oasis_bonus`)";
|
||||
if (!mysqli_query($this->dblink, $sql)) {
|
||||
mysqli_rollback($this->dblink);
|
||||
return ['ok'=>false,'msg'=>'INSERT failed: '.mysqli_error($this->dblink),'processed'=>$total,'target'=>$countTotal];
|
||||
}
|
||||
}
|
||||
|
||||
// progress after each slice
|
||||
$total += count($chunk);
|
||||
if ($reporter) {
|
||||
$pct = $countTotal ? min(100, (int)floor(($total / $countTotal) * 100)) : 0;
|
||||
$reporter($total, $countTotal, $pct);
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_commit($this->dblink);
|
||||
|
||||
// advance cursor
|
||||
$lastId = (int)$rows[$n - 1]['wref'];
|
||||
}
|
||||
|
||||
// Restore checks (optional)
|
||||
@mysqli_query($this->dblink, "SET unique_checks=1");
|
||||
@mysqli_query($this->dblink, "SET foreign_key_checks=1");
|
||||
|
||||
// Analyze once at the end
|
||||
@mysqli_query($this->dblink, "ANALYZE TABLE `$CROP_TABLE`");
|
||||
|
||||
if ($reporter) { $reporter($total, $countTotal, 100); }
|
||||
return ['ok'=>true,'msg'=>'Croppers populated','processed'=>$total,'target'=>$countTotal];
|
||||
}
|
||||
|
||||
|
||||
// no need to cache, not used in any loops or more than once for each page load
|
||||
public function getAvailableExpansionTraining() {
|
||||
global $building, $session, $technology, $village;
|
||||
|
||||
$vilData = $this->getVillage($village->wid);
|
||||
$maxslots = (($vilData['exp1'] == 0 ? 1 : 0) + ($vilData['exp2'] == 0 ? 1 : 0) + ($vilData['exp3'] == 0 ? 1 : 0));
|
||||
$residence = $building->getTypeLevel(25);
|
||||
$palace = $building->getTypeLevel(26);
|
||||
$vilData = $this->getVillage($village->wid);
|
||||
$maxslots = (($vilData['exp1'] == 0 ? 1 : 0) + ($vilData['exp2'] == 0 ? 1 : 0) + ($vilData['exp3'] == 0 ? 1 : 0));
|
||||
$residence = $building->getTypeLevel(25);
|
||||
$palace = $building->getTypeLevel(26);
|
||||
|
||||
if($residence > 0) {
|
||||
$maxslots -= (3 - floor($residence / 10));
|
||||
}
|
||||
if($residence > 0) {
|
||||
$maxslots -= (3 - floor($residence / 10));
|
||||
}
|
||||
|
||||
if($palace > 0) {
|
||||
$maxslots -= (3 - floor(($palace - 5) / 5));
|
||||
}
|
||||
if($palace > 0) {
|
||||
$maxslots -= (3 - floor(($palace - 5) / 5));
|
||||
}
|
||||
|
||||
$q = "SELECT (u10+u20+u30) as R1, (u9+u19+u29) as R2 FROM " . TB_PREFIX . "units WHERE vref = ". (int) $village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
$settlers = $row['R1'];
|
||||
$chiefs = $row['R2'];
|
||||
// Units at home
|
||||
$q = "SELECT (u10+u20+u30) as R1, (u9+u19+u29) as R2
|
||||
FROM " . TB_PREFIX . "units
|
||||
WHERE vref = " . (int)$village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
$settlers = (int)$row['R1'];
|
||||
$chiefs = (int)$row['R2'];
|
||||
|
||||
$settlers += 3 * count($this->getMovement(5, $village->wid, 0));
|
||||
|
||||
$current_movement = $this->getMovement(3, $village->wid, 0);
|
||||
if(!empty($current_movement)) {
|
||||
foreach($current_movement as $build) {
|
||||
$settlers += $build['t10'];
|
||||
$chiefs += $build['t9'];
|
||||
}
|
||||
}
|
||||
// Movements
|
||||
$settlers += 3 * count($this->getMovement(5, $village->wid, 0));
|
||||
|
||||
$current_movement = $this->getMovement(4, $village->wid, 1);
|
||||
if(!empty($current_movement)) {
|
||||
foreach($current_movement as $build) {
|
||||
$settlers += $build['t10'];
|
||||
$chiefs += $build['t9'];
|
||||
}
|
||||
}
|
||||
$current_movement = $this->getMovement(3, $village->wid, 0);
|
||||
if(!empty($current_movement)) {
|
||||
foreach($current_movement as $build) {
|
||||
$settlers += (int)$build['t10'];
|
||||
$chiefs += (int)$build['t9'];
|
||||
}
|
||||
}
|
||||
|
||||
$q = "SELECT (u10+u20+u30) FROM " . TB_PREFIX . "enforcement WHERE `from` = ".(int) $village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_row($result);
|
||||
if(!empty($row)) {
|
||||
foreach($row as $reinf) {
|
||||
$settlers += $reinf[0];
|
||||
}
|
||||
}
|
||||
$current_movement = $this->getMovement(4, $village->wid, 1);
|
||||
if(!empty($current_movement)) {
|
||||
foreach($current_movement as $build) {
|
||||
$settlers += (int)$build['t10'];
|
||||
$chiefs += (int)$build['t9'];
|
||||
}
|
||||
}
|
||||
|
||||
$q = "SELECT (u9+u19+u29) FROM " . TB_PREFIX . "enforcement WHERE `from` = ".(int) $village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_row($result);
|
||||
if(!empty($row)) {
|
||||
foreach($row as $reinf) {
|
||||
$chiefs += $reinf[0];
|
||||
}
|
||||
}
|
||||
// FIX: Count ALL reinforcements properly (SUM over ALL rows)
|
||||
$q = "SELECT COALESCE(SUM(u10+u20+u30),0) AS s
|
||||
FROM " . TB_PREFIX . "enforcement
|
||||
WHERE `from` = " . (int)$village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
$settlers += (int)$row['s'];
|
||||
|
||||
$trainlist = $technology->getTrainingList(4);
|
||||
if(!empty($trainlist)) {
|
||||
foreach($trainlist as $train) {
|
||||
if($train['unit'] % 10 == 0) {
|
||||
$settlers += $train['amt'];
|
||||
}
|
||||
if($train['unit'] % 10 == 9) {
|
||||
$chiefs += $train['amt'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$q = "SELECT COALESCE(SUM(u9+u19+u29),0) AS c
|
||||
FROM " . TB_PREFIX . "enforcement
|
||||
WHERE `from` = " . (int)$village->wid;
|
||||
$result = mysqli_query($this->dblink,$q);
|
||||
$row = mysqli_fetch_array($result, MYSQLI_ASSOC);
|
||||
$chiefs += (int)$row['c'];
|
||||
|
||||
$trappedTroops = $this->getPrisoners($village->wid, 1);
|
||||
if(!empty($trappedTroops)){
|
||||
foreach($trappedTroops as $trapped){
|
||||
$settlers += $trapped['t10'];
|
||||
$chiefs += $trapped['t9'];
|
||||
}
|
||||
}
|
||||
// Training queue (your existing logic)
|
||||
$trainlist = $technology->getTrainingList(4);
|
||||
if(!empty($trainlist)) {
|
||||
foreach($trainlist as $train) {
|
||||
if($train['unit'] % 10 == 0) {
|
||||
$settlers += (int)$train['amt'];
|
||||
}
|
||||
if($train['unit'] % 10 == 9) {
|
||||
$chiefs += (int)$train['amt'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$settlerslots = ($maxslots * 3) - ($chiefs * 3) - $settlers;
|
||||
$chiefslots = $maxslots - $chiefs - floor(($settlers + 2) / 3);
|
||||
// Trapped troops
|
||||
$trappedTroops = $this->getPrisoners($village->wid, 1);
|
||||
if(!empty($trappedTroops)){
|
||||
foreach($trappedTroops as $trapped){
|
||||
$settlers += (int)$trapped['t10'];
|
||||
$chiefs += (int)$trapped['t9'];
|
||||
}
|
||||
}
|
||||
|
||||
if(!$technology->getTech(($session->tribe - 1) * 10 + 9)) {
|
||||
$chiefslots = 0;
|
||||
}
|
||||
// Slot math (unchanged, but clamp to 0 to avoid negatives)
|
||||
$settlerslots = ($maxslots * 3) - ($chiefs * 3) - $settlers;
|
||||
$chiefslots = $maxslots - $chiefs - floor(($settlers + 2) / 3);
|
||||
|
||||
if(!$technology->getTech(($session->tribe - 1) * 10 + 9)) {
|
||||
$chiefslots = 0;
|
||||
}
|
||||
|
||||
if ($settlerslots < 0) $settlerslots = 0;
|
||||
if ($chiefslots < 0) $chiefslots = 0;
|
||||
|
||||
return ["chiefs" => $chiefslots, "settlers" => $settlerslots];
|
||||
}
|
||||
|
||||
return ["chiefs" => $chiefslots, "settlers" => $settlerslots];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates how much artifacts affect troops speed, cranny efficency, etc.
|
||||
|
||||
@@ -1031,7 +1031,7 @@ define('CRANNY', 'Cranny');
|
||||
define('CURRENT_HIDDEN_UNITS', 'Currently hidden units per resource:');
|
||||
define('HIDDEN_UNITS_LEVEL', 'Hidden units per resource at level');
|
||||
define('UNITS', 'units');
|
||||
define('CRANNY_DESC', 'The cranny hides some of your resources in case the village gets attacked. These resources cannot get stolen.<br>At level 1 the cranny can hold 200 of each resource. The capacity of Gallic crannies is 1.5 times larger.<br>If a Teutonic hero attacks a village, crannies can hide only 80% of their normal capacity');
|
||||
define('CRANNY_DESC', 'The cranny hides some of your resources in case the village gets attacked. These resources cannot get stolen.<br>At level 1 the cranny can hold '.(100*((int)CRANNY_CAPACITY)).' of each resource. The capacity of Gallic crannies is 1.5 times larger.<br>If a Teutonic hero attacks a village, crannies can hide only 80% of their normal capacity');
|
||||
|
||||
define('TOWNHALL', 'Town Hall');
|
||||
define('CELEBRATIONS_COMMENCE_TOWNHALL', 'Celebrations can commence when the town hall is completed.');
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
[](https://www.codetriage.com/shadowss/travianz)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://github.com/Shadowss/TravianZ)
|
||||
[](https://www.jetbrains.com/buy/opensource/?product=phpstorm)
|
||||
[](https://liberapay.com/Shadowss/donate)
|
||||
[](https://gitter.im/TravianZ-V8/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://www.youtube.com/watch?v=1XiHhpGUmQg&list=PLzV5avt1FFHorlIeoL9YX0pdb9bj-FO84)
|
||||
======
|
||||
@@ -17,13 +16,33 @@
|
||||
[](https://twitter.com/cata7007)
|
||||
======
|
||||
|
||||
TravianZ Version **v.8.3.5**
|
||||
TravianZ Version **v.8.3.5** - BETA 1
|
||||
======
|
||||
**Note:** this game is still in a pre-release state, although at this point it is very playable, tested and found to be fairly stable
|
||||
|
||||
**WARNING:** please note that ***this is in no way an upgrade*** from the old 8.3.2 version, so please ***do not try to just copy your files over***,
|
||||
**WARNING:** please note that ***this is in no way an upgrade*** from the old 8.3.2 version, so please ***do not try to just copy your files over***,
|
||||
since the installer logic has changed and you would just crash your old version
|
||||
|
||||
**Docker Quick Start:**
|
||||
|
||||
Get up and running quickly with Docker:
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/Shadowss/TravianZ.git
|
||||
cd TravianZ
|
||||
|
||||
# Copy environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Start containers
|
||||
docker-compose up -d
|
||||
|
||||
# Open browser to http://localhost:8080/install
|
||||
```
|
||||
|
||||
For detailed Docker setup instructions, see [DOCKER_README.md](DOCKER_README.md)
|
||||
|
||||
**Quick links:**
|
||||
* [Download and Updates](https://github.com/Shadowss/TravianZ) »» https://github.com/Shadowss/TravianZ
|
||||
* [Wiki](https://github.com/Shadowss/TravianZ/wiki)
|
||||
@@ -54,6 +73,7 @@ or you have a feature request to be included in the play.
|
||||
|
||||
**The team**
|
||||
* [Shadowss](https://github.com/Shadowss) - project owner and an occasional developer / tester
|
||||
* [lietuvis10](https://github.com/lietuvis10) - active developer
|
||||
* [iopietro](https://github.com/iopietro) - alumni developer
|
||||
* [AL-Kateb](https://github.com/AL-Kateb) - alumni developer
|
||||
* [martinambrus](https://github.com/martinambrus) - alumni developer
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
## ##
|
||||
#################################################################################
|
||||
|
||||
|
||||
if(isset($_GET['z'])){
|
||||
$currentcoor = $database->getCoor($_GET['z']);
|
||||
$y = $currentcoor['y'];
|
||||
@@ -316,8 +317,7 @@ $targetalliance=$donnees["aliance_id"];
|
||||
$friendarray=$database->getAllianceAlly($donnees["aliance_id"],1);
|
||||
$neutralarray=$database->getAllianceAlly($donnees["aliance_id"],2);
|
||||
$enemyarray=$database->getAllianceWar2($donnees["aliance_id"]);
|
||||
//var_dump($friendarray);
|
||||
//echo "(".$friendarray[0]['alli1'].">0 or ".$donnees["aliance_id"].">0) and (".$friendarray[0]['alli1']."==".$donnees["aliance_id"]." or ".$friendarray[0]['alli2']."==".$donnees["aliance_id"].") and (".$session->alliance." != ".$targetalliance." and ".$session->alliance." and ".$targetalliance.")<br>\n";
|
||||
|
||||
if (isset($friendarray[0])) {
|
||||
$friend = (($friendarray[0]['alli1']>0 and $friendarray[0]['alli2']>0 and $donnees["aliance_id"]>0) and ($friendarray[0]['alli1']==$session->alliance or $friendarray[0]['alli2']==$session->alliance) and ($session->alliance != $targetalliance and $session->alliance and $targetalliance)) ? '1':'0';
|
||||
}else $friend='0';
|
||||
@@ -328,11 +328,6 @@ if (isset($neutralarray[0])) {
|
||||
$neutral = (($neutralarray[0]['alli1']>0 and $neutralarray[0]['alli2']>0 and $donnees["aliance_id"]>0) and ($neutralarray[0]['alli1']==$session->alliance or $neutralarray[0]['alli2']==$session->alliance) and ($session->alliance != $targetalliance and $session->alliance and $targetalliance)) ? '1':'0';
|
||||
}else $neutral='0';
|
||||
|
||||
//echo $targetalliance.">>";
|
||||
//var_dump($friendarray);
|
||||
//echo"|||<br>";
|
||||
//var_dump($arraydiplo);
|
||||
//echo in_array($targetalliance,$friendarray);
|
||||
$image = ($donnees['map_occupied'] == 1 && $donnees['map_fieldtype'] > 0)?(($donnees['ville_user'] == $session->uid)? ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b30': 'b20' :'b10' : 'b00') : (($targetalliance != 0)? ($friend==1? ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b31': 'b21' :'b11' : 'b01') : ($war==1? ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b32': 'b22' :'b12' : 'b02') : ($neutral==1? ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b35': 'b25' :'b15' : 'b05') : ($targetalliance == $session->alliance? ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b33': 'b23' :'b13' : 'b03') : ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b34': 'b24' :'b14' : 'b04'))))) : ($donnees['ville_pop']>=100? $donnees['ville_pop']>= 250?$donnees['ville_pop']>=500? 'b34': 'b24' :'b14' : 'b04'))) : $donnees['map_image'];
|
||||
|
||||
// Map Attacks by Shadow and MisterX - Fixed by iopietro
|
||||
@@ -441,6 +436,7 @@ if (isset($neutralarray[0])) {
|
||||
m_c.ad = [[<?php echo $map_js?>];
|
||||
m_c.z = {"x":<?php echo $x ?>,"y":<?php echo $y ?>};
|
||||
m_c.size = 13;
|
||||
m_c.world_max = <?php echo WORLD_MAX; ?>; //lietuvis10 fix
|
||||
var mdim = {"x":13,"y":13,"rad":6}
|
||||
var mmode = 0;
|
||||
function init_local(){map_init();}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: travianz-web
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- ./:/var/www/html
|
||||
- ./var:/var/www/html/var
|
||||
environment:
|
||||
- APACHE_DOCUMENT_ROOT=/var/www/html
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- travianz-network
|
||||
restart: unless-stopped
|
||||
|
||||
db:
|
||||
image: mysql:5.7
|
||||
container_name: travianz-db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE:-travian}
|
||||
MYSQL_USER: ${MYSQL_USER:-travianz}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-travianzpass}
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
- ./var/db:/docker-entrypoint-initdb.d:ro
|
||||
ports:
|
||||
- "3306:3306"
|
||||
networks:
|
||||
- travianz-network
|
||||
restart: unless-stopped
|
||||
command: --default-authentication-plugin=mysql_native_password --sql_mode=""
|
||||
|
||||
phpmyadmin:
|
||||
image: phpmyadmin/phpmyadmin:latest
|
||||
container_name: travianz-phpmyadmin
|
||||
environment:
|
||||
PMA_HOST: db
|
||||
PMA_PORT: 3306
|
||||
PMA_USER: root
|
||||
PMA_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
|
||||
ports:
|
||||
- "8081:80"
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- travianz-network
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
travianz-network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
// install/ajax_croppers.php
|
||||
// Streams croppers build progress via SSE
|
||||
|
||||
// --- Includes ---
|
||||
require_once __DIR__ . '/../GameEngine/config.php';
|
||||
require_once __DIR__ . '/../GameEngine/Database.php';
|
||||
require_once __DIR__ . '/../GameEngine/Admin/database.php';
|
||||
|
||||
// --- Headers for SSE and no buffering ---
|
||||
header('Content-Type: text/event-stream; charset=utf-8');
|
||||
header('Cache-Control: no-cache, no-store, must-revalidate');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: 0');
|
||||
header('Connection: keep-alive');
|
||||
// Disable nginx proxy buffering if present
|
||||
header('X-Accel-Buffering: no');
|
||||
|
||||
@ini_set('zlib.output_compression', '0');
|
||||
@ini_set('output_buffering', 'off');
|
||||
@ini_set('implicit_flush', '1');
|
||||
@set_time_limit(0);
|
||||
|
||||
// Kill any output buffers
|
||||
while (ob_get_level() > 0) { @ob_end_flush(); }
|
||||
ob_implicit_flush(true);
|
||||
|
||||
// If any installer/session code might lock the session, release it
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
@session_write_close();
|
||||
}
|
||||
|
||||
function sse_send(array $payload) {
|
||||
echo "data: " . json_encode($payload, JSON_UNESCAPED_SLASHES) . "\n\n";
|
||||
@flush();
|
||||
@ob_flush();
|
||||
}
|
||||
|
||||
function sse_ping() {
|
||||
// Comment line per SSE spec, keeps connection alive
|
||||
echo ":\n\n";
|
||||
@flush();
|
||||
@ob_flush();
|
||||
}
|
||||
|
||||
global $database;
|
||||
|
||||
// 1) Count total croppers
|
||||
try {
|
||||
$total = $database->TotalCroppers();
|
||||
} catch (Throwable $e) {
|
||||
sse_send(['pct'=>0,'done'=>0,'total'=>0,'msg'=>'Count failed: '.$e->getMessage()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
sse_send(['pct'=>0,'done'=>0,'total'=>$total,'msg'=>"Starting croppers build (found $total tiles)…"]);
|
||||
|
||||
// 2) Build with live reporter (pings to keep proxies happy)
|
||||
$lastPing = time();
|
||||
$reporter = function($done, $target, $pct) use (&$lastPing) {
|
||||
sse_send(['pct'=>(int)$pct,'done'=>(int)$done,'total'=>(int)$target]);
|
||||
// send keep-alive every ~10s
|
||||
if (time() - $lastPing >= 10) {
|
||||
sse_ping();
|
||||
$lastPing = time();
|
||||
}
|
||||
if (connection_aborted()) { exit; } // client left
|
||||
};
|
||||
|
||||
// Run it (fresh world => truncateFirst=true; big batch on dedicated server)
|
||||
$out = $database->populateCroppers($total, true, 20000, $reporter);
|
||||
|
||||
if (!empty($out['ok'])) {
|
||||
sse_send([
|
||||
'pct'=>100,
|
||||
'done'=>(int)$out['processed'],
|
||||
'total'=>(int)$out['target'],
|
||||
'msg'=>'Done building croppers.'
|
||||
]);
|
||||
} else {
|
||||
sse_send([
|
||||
'pct'=>0,
|
||||
'done'=>0,
|
||||
'total'=>(int)$total,
|
||||
'msg'=>'Error: '.($out['msg'] ?? 'unknown')
|
||||
]);
|
||||
}
|
||||
exit;
|
||||
+17
-17
@@ -207,26 +207,26 @@ class Process {
|
||||
/**
|
||||
* Generates map data and populates it with oasis.
|
||||
*/
|
||||
function createWdata() {
|
||||
global $database;
|
||||
function createWdata() {
|
||||
global $database;
|
||||
|
||||
include ("../GameEngine/config.php");
|
||||
include ("../GameEngine/Database.php");
|
||||
include ("../GameEngine/Admin/database.php");
|
||||
include ("../GameEngine/config.php");
|
||||
include ("../GameEngine/Database.php");
|
||||
include ("../GameEngine/Admin/database.php");
|
||||
|
||||
// populate world data
|
||||
$result = $database->populateWorldData();
|
||||
if ($result === false) {
|
||||
header("Location: index.php?s=3&err=1");
|
||||
exit;
|
||||
} else if ($result === -1) {
|
||||
header("Location: index.php?s=3&c=1");
|
||||
exit;
|
||||
}
|
||||
// 1) Populate world data
|
||||
$result = $database->populateWorldData();
|
||||
if ($result === false) {
|
||||
header("Location: index.php?s=3&err=1");
|
||||
exit;
|
||||
} else if ($result === -1) {
|
||||
header("Location: index.php?s=3&c=1");
|
||||
exit;
|
||||
}
|
||||
|
||||
header("Location: index.php?s=4");
|
||||
exit;
|
||||
}
|
||||
header("Location: index.php?s=3&startCroppers=1");
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
+186
-34
@@ -1,54 +1,206 @@
|
||||
<?php
|
||||
|
||||
#################################################################################
|
||||
## -= YOU MAY NOT REMOVE OR CHANGE THIS NOTICE =- ##
|
||||
## --------------------------------------------------------------------------- ##
|
||||
## Project: TravianZ ##
|
||||
## Version: 22.06.2015 ##
|
||||
## Version: 28.10.2025 ##
|
||||
## Filename wdata.tpl ##
|
||||
## Developed by: Mr.php , Advocaite , brainiacX , yi12345 , Shadow , ronix ##
|
||||
## Fixed by: Shadow - STARVATION , HERO FIXED COMPL. ##
|
||||
## Fixed by: InCube - double troops ##
|
||||
## Fixed by: Shadow - STARVATION , HERO FIXED COMPL. ##
|
||||
## Fixed by: InCube - double troops ##
|
||||
## Fixed by: lietuvis10 - crop finder ##
|
||||
## License: TravianZ Project ##
|
||||
## Copyright: TravianZ (c) 2010-2015. All rights reserved. ##
|
||||
## URLs: http://travian.shadowss.ro ##
|
||||
## Source code: https://github.com/Shadowss/TravianZ ##
|
||||
## URLs: http://travian.shadowss.ro ##
|
||||
## Source code: https://github.com/Shadowss/TravianZ ##
|
||||
## ##
|
||||
#################################################################################
|
||||
|
||||
?>
|
||||
|
||||
<?php
|
||||
// install/wdata.tpl
|
||||
|
||||
include_once('../GameEngine/config.php');
|
||||
|
||||
if(isset($_GET['c']) && $_GET['c'] == 1) {
|
||||
echo "<br /><hr /><br /><div class=\"headline\"><span class=\"f10 c5\">Error creating wdata. Check configuration or file.</span></div><br><br>";
|
||||
if (isset($_GET['c']) && $_GET['c'] == '1') {
|
||||
echo '<br /><hr /><br /><div class="headline"><span class="f10 c5">Error creating wdata. Check configuration or file.</span></div><br><br>';
|
||||
}
|
||||
if (isset($_GET['err']) && $_GET['err'] == '1') {
|
||||
echo '<br /><hr /><br /><div class="headline"><span class="f10 c5">Existing World Data found in the database! Please empty tables <i>'
|
||||
. TB_PREFIX . 'odata, ' . TB_PREFIX . 'units, ' . TB_PREFIX . 'vdata, ' . TB_PREFIX . 'wdata</i> before continuing.</span></div><br /><br />';
|
||||
}
|
||||
|
||||
if(isset($_GET['err']) && $_GET['err'] == 1) {
|
||||
echo "<br /><hr /><br /><div class=\"headline\"><span class=\"f10 c5\">Existing World Data found in the database! Please empty tables <i>".TB_PREFIX."odata, ".TB_PREFIX."units, ".TB_PREFIX."vdata, ".TB_PREFIX."wdata</i> before continuing.</span></div><br /><br />";
|
||||
}
|
||||
$autoStartCroppers = isset($_GET['startCroppers']) && $_GET['startCroppers'] === '1';
|
||||
?>
|
||||
|
||||
<form action="process.php" method="post" id="dataform">
|
||||
<input type="hidden" name="subwdata" value="1">
|
||||
|
||||
<p>
|
||||
<span class="f10 c">Create World Data</span>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Warning</b>: This can take some time. Please wait until the next page has been loaded. Click Create to proceed...
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<center>
|
||||
<input type="submit" name="Submit" id="Submit" value="Create..." onClick="return proceed()">
|
||||
<br>
|
||||
<br>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<input type="hidden" name="subwdata" value="1" />
|
||||
|
||||
<p>
|
||||
<span class="f10 c">Create World Data</span>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<b>Warning</b>: This can take some time. Please wait until the next page has been loaded.
|
||||
Click Create to proceed...
|
||||
<br /><br />
|
||||
|
||||
<!-- Submit block (hidden when autoStartCroppers=1) -->
|
||||
<div id="submitWrap" style="display:<?php echo $autoStartCroppers ? 'none' : 'block'; ?>;">
|
||||
<center>
|
||||
<input type="submit" name="Submit" id="Submit" value="Create..." onClick="return proceed()" />
|
||||
<br /><br />
|
||||
</center>
|
||||
</div>
|
||||
|
||||
<!-- Progress UI (shown when startCroppers=1) -->
|
||||
<div id="progressBox" style="display:<?php echo $autoStartCroppers ? 'block' : 'none'; ?>; margin-top:20px;">
|
||||
<div style="font-weight:bold;margin-bottom:6px;">Building croppers…</div>
|
||||
|
||||
<div style="background:#ddd;border-radius:8px;overflow:hidden;height:20px;max-width:500px;">
|
||||
<!-- Orange bar to match Travian vibes -->
|
||||
<div id="pbar" style="background:#f6a21a;height:100%;width:0%;transition:width .2s;"></div>
|
||||
</div>
|
||||
|
||||
<div id="pinfo" style="margin-top:6px;font-size:13px;color:#333;">Starting…</div>
|
||||
|
||||
<pre id="plog" style="margin-top:10px;background:#f9f9f9;border:1px solid #ddd;border-radius:8px;padding:8px;font-size:12px;max-height:200px;overflow:auto;"></pre>
|
||||
|
||||
<!-- Continue button appears on completion -->
|
||||
<div id="autoNext" style="display:none;margin-top:10px;">
|
||||
Proceeding to next step in <b id="cd">3</b>…
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var NEXT_URL = 'index.php?s=4'; // your next step
|
||||
var COUNTDOWN_SECS = 3;
|
||||
var finished = false;
|
||||
|
||||
function startCountdown() {
|
||||
var box = document.getElementById('autoNext');
|
||||
var cdEl = document.getElementById('cd');
|
||||
var left = COUNTDOWN_SECS;
|
||||
box.style.display = 'block';
|
||||
cdEl.textContent = left;
|
||||
var t = setInterval(function () {
|
||||
left--;
|
||||
cdEl.textContent = left;
|
||||
if (left <= 0) {
|
||||
clearInterval(t);
|
||||
window.location.href = NEXT_URL;
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function startCroppersBuild() {
|
||||
var box = document.getElementById('progressBox');
|
||||
var pbar = document.getElementById('pbar');
|
||||
var pinfo= document.getElementById('pinfo');
|
||||
var plog = document.getElementById('plog');
|
||||
|
||||
var submitWrap = document.getElementById('submitWrap');
|
||||
if (submitWrap) submitWrap.style.display = 'none';
|
||||
box.style.display = 'block';
|
||||
|
||||
if (!('EventSource' in window)) {
|
||||
plog.textContent += "Your browser does not support live progress.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
var MAX_RETRIES = 3;
|
||||
var retries = 0;
|
||||
|
||||
var es = new EventSource('ajax_croppers.php');
|
||||
|
||||
es.onopen = function () {
|
||||
// When a connection (re)opens and we had errors before, log a small note
|
||||
if (!finished && retries > 0) {
|
||||
plog.textContent += "Reconnected to server.\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
}
|
||||
};
|
||||
|
||||
es.onmessage = function (e) {
|
||||
// Ignore non-JSON messages (pings / blanks)
|
||||
if (!e.data || e.data.charCodeAt(0) !== 123 /* '{' */) return;
|
||||
|
||||
try {
|
||||
var d = JSON.parse(e.data);
|
||||
var pct = (d.pct || 0) | 0;
|
||||
var done = (d.done || 0) | 0;
|
||||
var total = (d.total|| 0) | 0;
|
||||
|
||||
// If we've already finished, ignore further events
|
||||
if (finished) return;
|
||||
|
||||
// Valid data received -> reset retry counter
|
||||
retries = 0;
|
||||
|
||||
pbar.style.width = pct + '%';
|
||||
pinfo.textContent = done + ' / ' + total + ' (' + pct + '%)';
|
||||
|
||||
if (d.msg) {
|
||||
plog.textContent += d.msg + "\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
}
|
||||
|
||||
if (pct >= 100) {
|
||||
finished = true;
|
||||
plog.textContent += "✅ Completed!\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
es.close();
|
||||
startCountdown();
|
||||
}
|
||||
|
||||
// Optional: handle explicit error flag from server if you ever send it
|
||||
if (d.error) {
|
||||
finished = true;
|
||||
plog.textContent += "❌ " + (d.msg || "Server reported an error.") + "\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
es.close();
|
||||
startCountdown();
|
||||
}
|
||||
} catch (err) {
|
||||
// Silently ignore parsing problems now that we guard by '{'
|
||||
// plog.textContent += "Parse error.\n";
|
||||
}
|
||||
};
|
||||
|
||||
es.onerror = function () {
|
||||
// Don’t spam after we’re done
|
||||
if (finished) return;
|
||||
|
||||
retries++;
|
||||
plog.textContent += "⚠ Connection hiccup (" + retries + "/" + MAX_RETRIES + "), retrying…\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
|
||||
// EventSource will auto-reconnect by itself; we just decide when to give up
|
||||
if (retries >= MAX_RETRIES) {
|
||||
finished = true;
|
||||
plog.textContent += "❌ Too many connection failures — skipping croppers build.\n";
|
||||
plog.scrollTop = plog.scrollHeight;
|
||||
es.close();
|
||||
// Reuse the same countdown UI to move on
|
||||
startCountdown();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
<?php if ($autoStartCroppers) { echo 'startCroppersBuild();'; } ?>
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -897,13 +897,13 @@ if(_i.cookie){var date=new Date();date.setTime(date.getTime()+300000);document.c
|
||||
if(_i.fest&&he('dorf2')){document.getElementById('content').innerHTML+=_i.fest;}
|
||||
window.setTimeout(ti,30);}
|
||||
function he(bj){return window.location.href.indexOf(bj+'.php')!=-1;}
|
||||
function vil_levels_toggle(){var cj=$('levels'),dj=$('lswitch');cj.toggleClass('on');dj.toggleClass('on');if(cj.hasClass('on')){document.cookie='t3l=1; expires=Wed, 1 Jan 2020 00:00:00 GMT';}
|
||||
function vil_levels_toggle(){var cj=$('levels'),dj=$('lswitch');cj.toggleClass('on');dj.toggleClass('on');if(cj.hasClass('on')){document.cookie='t3l=1; expires=Wed, 1 Jan 2030 00:00:00 GMT';}
|
||||
else{document.cookie='t3l=1; expires=Thu, 01-Jan-1970 00:00:01 GMT';}
|
||||
}
|
||||
function gmwd(){if(is_ff2&&document.getElementById("gmwi").offsetWidth<50){document.cookie="a3=2; expires=Wed, 1 Jan 2020 00:00:00 GMT";}
|
||||
else{document.cookie="a3=1; expires=Wed, 1 Jan 2020 00:00:00 GMT";}
|
||||
function gmwd(){if(is_ff2&&document.getElementById("gmwi").offsetWidth<50){document.cookie="a3=2; expires=Wed, 1 Jan 2030 00:00:00 GMT";}
|
||||
else{document.cookie="a3=1; expires=Wed, 1 Jan 2030 00:00:00 GMT";}
|
||||
}
|
||||
function gmc(){document.getElementById("gmw").style.display="none";document.cookie="a3=3; expires=Wed, 1 Jan 2020 00:00:00 GMT";}
|
||||
function gmc(){document.getElementById("gmw").style.display="none";document.cookie="a3=3; expires=Wed, 1 Jan 2030 00:00:00 GMT";}
|
||||
function documentWidth() {
|
||||
return Math.max(
|
||||
document.documentElement.clientWidth,
|
||||
@@ -922,4 +922,4 @@ function documentHeight() {
|
||||
document.body.offsetHeight,
|
||||
document.documentElement.offsetHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
-- oasis regeneration script
|
||||
-- used during installation, server reset, oasis reset & automation (nature repopulation)
|
||||
--
|
||||
-- author: martinambrus
|
||||
-- original author: martinambrus
|
||||
-- revised and improved: haki99
|
||||
-- ----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -33,25 +34,37 @@ INSERT INTO %PREFIX%oids VALUES %VILLAGEID%;
|
||||
|
||||
SET @noVillage = ((SELECT id FROM %PREFIX%oids LIMIT 1) = -1);
|
||||
|
||||
-- Get the number of players
|
||||
SELECT COUNT(*) INTO @playerCount FROM %PREFIX%users WHERE id > 6;
|
||||
|
||||
-- Calculate average progression for all real players (owner > 6) from culture points (CP) and population of villages (pop)
|
||||
SELECT IFNULL(AVG(pop + cp), 0) INTO @avgPlayerProgress FROM %PREFIX%vdata WHERE owner > 6;
|
||||
|
||||
-- ----------------------------------------------------------------
|
||||
-- Calculate growth factor based on player progression
|
||||
-- Scale between 0.3 and 3.0
|
||||
-- ----------------------------------------------------------------
|
||||
SET @growthFactor = LEAST(3.0, GREATEST(0.3, @avgPlayerProgress / 1000));
|
||||
|
||||
-- faster access to first oasis ID, so we don't need to reselect all the time below
|
||||
SET @firstVillage = (SELECT id FROM %PREFIX%oids LIMIT 1);
|
||||
|
||||
-- minimum and maximum number of units for oasis with "high" field set to 0
|
||||
SET @minUnitsForOasis0 = 15;
|
||||
SET @maxUnitsForOasis0 = 30;
|
||||
SET @minUnitsForOasis0 = GREATEST(5, FLOOR(5 * @growthFactor));
|
||||
SET @maxUnitsForOasis0 = LEAST(FLOOR(@minUnitsForOasis0 + 5 + (@playerCount * 1.5) * @growthFactor), 30);
|
||||
|
||||
-- minimum and maximum number of units for oasis with "high" field set to 1
|
||||
SET @minUnitsForOasis1 = 50;
|
||||
SET @maxUnitsForOasis1 = 70;
|
||||
SET @minUnitsForOasis1 = GREATEST(10, FLOOR(10 * @growthFactor));
|
||||
SET @maxUnitsForOasis1 = LEAST(FLOOR(@minUnitsForOasis1 + 10 + (@playerCount * 2) * @growthFactor), 60);
|
||||
|
||||
-- minimum and maximum number of units for oasis with "high" field set to 2
|
||||
SET @minUnitsForOasis2 = 90;
|
||||
SET @maxUnitsForOasis2 = 120;
|
||||
|
||||
SET @minUnitsForOasis2 = GREATEST(20, FLOOR(20 * @growthFactor));
|
||||
SET @maxUnitsForOasis2 = LEAST(FLOOR(@minUnitsForOasis2 + 15 + (@playerCount * 3) * @growthFactor), 90);
|
||||
|
||||
-- Setting a maximum for every type of Oasis so large servers won't turn oasis into fortresses
|
||||
SET @maxUnitsForOasis0 = LEAST(@maxUnitsForOasis0, 30);
|
||||
SET @maxUnitsForOasis1 = LEAST(@maxUnitsForOasis1, 60);
|
||||
SET @maxUnitsForOasis2 = LEAST(@maxUnitsForOasis2, 90);
|
||||
|
||||
-- ----------------------------------------
|
||||
-- reset oasis data (conquered > unoccupied)
|
||||
@@ -106,444 +119,286 @@ WHERE
|
||||
|
||||
-- +25% lumber oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u.u35 = u.u35 + (FLOOR(5 + RAND() * 10)),
|
||||
u36 = u36 + (FLOOR(0 + RAND() * 5)),
|
||||
u37 = u37 + (FLOOR(0 + RAND() * 5))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(1,2)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND
|
||||
(
|
||||
u35 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
OR u36 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
OR u37 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u.u35 = LEAST(u.u35 + FLOOR((5 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u.u36 = LEAST(u.u36 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u.u37 = LEAST(u.u37 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype IN (1,2)))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% lumber and +25% crop oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u35 = u35 + (FLOOR(5 + RAND() * 15)),
|
||||
u36 = u36 + (FLOOR(0 + RAND() * 5)),
|
||||
u37 = u37 + (FLOOR(0 + RAND() * 5)),
|
||||
u38 = u38 + (FLOOR(0 + RAND() * 5)),
|
||||
u40 = u40 + (FLOOR(0 + RAND() * 3))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(3)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND
|
||||
(
|
||||
u36 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
OR u37 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
OR u38 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u35 = LEAST(u35 + FLOOR((5 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u36 = LEAST(u36 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u37 = LEAST(u37 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u38 = LEAST(u38 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u40 = LEAST(u40 + FLOOR((0 + RAND() * 3) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype = 3))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% clay oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(10 + RAND() * 15)),
|
||||
u32 = u32 + (FLOOR(5 + RAND() * 15)),
|
||||
u35 = u35 + (FLOOR(0 + RAND() * 10))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(4,5)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u32 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u35 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((10 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u32 = LEAST(u32 + FLOOR((5 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u35 = LEAST(u35 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype IN (4,5)))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% clay and +25% crop oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(15 + RAND() * 20)),
|
||||
u32 = u32 + (FLOOR(10 + RAND() * 15)),
|
||||
u35 = u35 + (FLOOR(0 + RAND() * 10)),
|
||||
u40 = u40 + (FLOOR(0 + RAND() * 3))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(6)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u32 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u35 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((15 + RAND() * 20) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u32 = LEAST(u32 + FLOOR((10 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u35 = LEAST(u35 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u40 = LEAST(u40 + FLOOR((0 + RAND() * 3) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype = 6))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% iron oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(10 + RAND() * 15)),
|
||||
u32 = u32 + (FLOOR(5 + RAND() * 15)),
|
||||
u34 = u34 + (FLOOR(0 + RAND() * 10))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(7,8)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u32 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u34 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((10 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u32 = LEAST(u32 + FLOOR((5 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u34 = LEAST(u34 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype IN (7,8)))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% iron and +25% crop oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(15 + RAND() * 20)),
|
||||
u32 = u32 + (FLOOR(10 + RAND() * 15)),
|
||||
u34 = u34 + (FLOOR(0 + RAND() * 10)),
|
||||
u39 = u39 + (FLOOR(0 + RAND() * 3))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(9)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u32 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u34 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((15 + RAND() * 20) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u32 = LEAST(u32 + FLOOR((10 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u34 = LEAST(u34 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u39 = LEAST(u39 + FLOOR((0 + RAND() * 3) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype = 9))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +25% crop oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(5 + RAND() * 15)),
|
||||
u33 = u33 + (FLOOR(5 + RAND() * 10)),
|
||||
u37 = u37 + (FLOOR(0 + RAND() * 10)),
|
||||
u38 = u38 + (FLOOR(0 + RAND() * 5)),
|
||||
u39 = u39 + (FLOOR(0 + RAND() * 5))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(10,11)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u33 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u37 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u38 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((5 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u33 = LEAST(u33 + FLOOR((5 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u37 = LEAST(u37 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u38 = LEAST(u38 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u39 = LEAST(u39 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype IN (10,11)))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
-- +50% crop oasis
|
||||
UPDATE %PREFIX%units u
|
||||
JOIN %PREFIX%odata o
|
||||
ON u.vref = o.wref
|
||||
SET
|
||||
u31 = u31 + (FLOOR(10 + RAND() * 15)),
|
||||
u33 = u33 + (FLOOR(5 + RAND() * 10)),
|
||||
u37 = u37 + (FLOOR(0 + RAND() * 10)),
|
||||
u38 = u38 + (FLOOR(0 + RAND() * 5)),
|
||||
u39 = u39 + (FLOOR(0 + RAND() * 5)),
|
||||
u40 = u40 + (FLOOR(0 + RAND() * 3))
|
||||
WHERE
|
||||
(
|
||||
(
|
||||
@firstVillage = -1
|
||||
AND
|
||||
vref IN(
|
||||
SELECT
|
||||
id
|
||||
FROM
|
||||
%PREFIX%wdata
|
||||
WHERE
|
||||
oasistype IN(12)
|
||||
)
|
||||
)
|
||||
OR
|
||||
(
|
||||
@firstVillage > -1
|
||||
AND
|
||||
vref IN ( SELECT id FROM %PREFIX%oids )
|
||||
)
|
||||
)
|
||||
AND u31 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u33 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u37 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u38 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
)
|
||||
AND u39 <= (
|
||||
CASE o.high
|
||||
WHEN 0 THEN (FLOOR(@minUnitsForOasis0 + RAND() * @maxUnitsForOasis0))
|
||||
WHEN 1 THEN (FLOOR(@minUnitsForOasis1 + RAND() * @maxUnitsForOasis1))
|
||||
WHEN 2 THEN (FLOOR(@minUnitsForOasis2 + RAND() * @maxUnitsForOasis2))
|
||||
END
|
||||
);
|
||||
JOIN %PREFIX%odata o ON u.vref = o.wref
|
||||
SET
|
||||
u31 = LEAST(u31 + FLOOR((10 + RAND() * 15) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u33 = LEAST(u33 + FLOOR((5 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u37 = LEAST(u37 + FLOOR((0 + RAND() * 10) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u38 = LEAST(u38 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u39 = LEAST(u39 + FLOOR((0 + RAND() * 5) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END),
|
||||
u40 = LEAST(u40 + FLOOR((0 + RAND() * 3) * @growthFactor),
|
||||
CASE o.high
|
||||
WHEN 0 THEN FLOOR(@minUnitsForOasis0 + RAND() * (@maxUnitsForOasis0 - @minUnitsForOasis0))
|
||||
WHEN 1 THEN FLOOR(@minUnitsForOasis1 + RAND() * (@maxUnitsForOasis1 - @minUnitsForOasis1))
|
||||
WHEN 2 THEN FLOOR(@minUnitsForOasis2 + RAND() * (@maxUnitsForOasis2 - @minUnitsForOasis2))
|
||||
END)
|
||||
WHERE
|
||||
(
|
||||
(@firstVillage = -1 AND u.vref IN (SELECT id FROM %PREFIX%wdata WHERE oasistype = 12))
|
||||
OR
|
||||
(@firstVillage > -1 AND u.vref IN (SELECT id FROM %PREFIX%oids))
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user