mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-07-24 05:26:19 +00:00
Last fix for Hero T4 & V11
/* |-------------------------------------------------------------------------- | FIX List |-------------------------------------------------------------------------- | | 1. Hero Attribute Points | - When adding attribute points to the hero, the page currently refreshes | after every click on the "+" button. | - Implement a faster allocation method (AJAX or similar) so multiple | points can be assigned without a full page refresh. | - The implementation must remain secure and not be exploitable | (validate requests server-side, prevent double submissions, | verify available points, etc.). | | 2. Hero Equipment Restrictions (Original Travian Behavior) | - Prevent equipping or unequipping hero items while the hero is: | • On an adventure. | • Attacking (alone or with troops). | • Away as reinforcements. | | 3. Oasis Navigation | - When opening an oasis (37_land.tpl), the 37_t4nav.tpl navigation | disappears. | - Include the navigation menu on the oasis page as well. | | 4. Auction House Redesign | - Redesign 37_auction.tpl to match the Merchant.png mockup. | - Keep the existing auction functionality exactly as it is. | - Only improve the UI/UX. | - You may crop and reuse graphics from Merchant.png. | - Add Gold ⇄ Silver exchange functionality. | | 5. Hero Item Bonuses (Highest Priority) | - Verify that hero equipment bonuses are applied correctly. | - Example: | • Helmet of the Ruler should reduce Barracks training time by 20%. | • Currently, training time remains unchanged whether the helmet | is equipped or not. | - Also verify: | • Stable training speed bonuses. | • Boots bonuses. | • Any other related hero equipment effects. | | 6. Adventures Page Redesign | - Redesign 37_adventures.tpl to match the Adventure.png mockup. | - Keep the "Expires in" column intact. | */
This commit is contained in:
@@ -264,11 +264,100 @@ class HeroItems
|
||||
* - anything already in that slot is unequipped first (atomic enough for
|
||||
* a per-user action; both statements touch only this user's rows)
|
||||
*/
|
||||
/* =========================================================================
|
||||
* DISPONIBILITATEA EROULUI PENTRU SCHIMBAREA ECHIPAMENTULUI
|
||||
* ===================================================================== */
|
||||
|
||||
/** @var array cache per request: uid => motiv ('' = eroul e acasa) */
|
||||
private static $awayCache = array();
|
||||
|
||||
/**
|
||||
* Motivul pentru care eroul NU poate schimba echipamentul acum.
|
||||
*
|
||||
* Intoarce '' cand eroul e acasa si poate fi echipat, sau una dintre:
|
||||
* 'adventure' - plecat intr-o aventura
|
||||
* 'attack' - plecat intr-un atac (singur sau cu trupe), dus sau intors
|
||||
* 'reinforcement' - trimis ca intarire in alt sat
|
||||
*
|
||||
* Comportament ca in Travian original: echipamentul se schimba doar cat timp
|
||||
* eroul e in sat. Eroul MORT nu e blocat - e "acasa", doar fara viata, si in
|
||||
* T4 iti poti pregati echipamentul cat timp astepti invierea.
|
||||
*/
|
||||
public function heroAwayReason($uid)
|
||||
{
|
||||
$uid = (int) $uid;
|
||||
|
||||
if (isset(self::$awayCache[$uid])) {
|
||||
return self::$awayCache[$uid];
|
||||
}
|
||||
|
||||
$p = TB_PREFIX;
|
||||
|
||||
// ATENTIE: aliasul pentru miscarea de intoarcere NU poate fi "returning" -
|
||||
// e cuvant rezervat in MariaDB (clauza RETURNING) si strica query-ul.
|
||||
// Un singur query, cu motive separate, ca interfata sa poata afisa
|
||||
// exact de ce e blocat. Coloanele `from`/`to` sunt cuvinte rezervate,
|
||||
// de aceea sunt in backticks.
|
||||
$q = "SELECT
|
||||
(SELECT COUNT(*) FROM {$p}hero
|
||||
WHERE uid = ? AND COALESCE(intraining, 0) = 0) AS hero_exists,
|
||||
(SELECT COUNT(*) FROM {$p}hero_adventure
|
||||
WHERE uid = ? AND status = 1) AS adventure,
|
||||
(SELECT IFNULL(SUM(e.hero), 0) FROM {$p}enforcement e
|
||||
INNER JOIN {$p}vdata v ON v.wref = e.`from`
|
||||
WHERE v.owner = ?) AS reinforcement,
|
||||
(SELECT IFNULL(SUM(a.t11), 0) FROM {$p}movement m
|
||||
INNER JOIN {$p}attacks a ON a.id = m.ref
|
||||
INNER JOIN {$p}vdata v ON v.wref = m.`from`
|
||||
WHERE v.owner = ? AND m.proc = 0 AND m.sort_type = 3) AS outgoing,
|
||||
(SELECT IFNULL(SUM(a.t11), 0) FROM {$p}movement m
|
||||
INNER JOIN {$p}attacks a ON a.id = m.ref
|
||||
INNER JOIN {$p}vdata v ON v.wref = m.`to`
|
||||
WHERE v.owner = ? AND m.proc = 0 AND m.sort_type = 4) AS atk_return";
|
||||
|
||||
$stmt = $this->db->prepare($q);
|
||||
|
||||
if (!$stmt) {
|
||||
// daca query-ul nu se poate pregati, nu blocam jucatorul
|
||||
return self::$awayCache[$uid] = '';
|
||||
}
|
||||
|
||||
$stmt->bind_param('iiiii', $uid, $uid, $uid, $uid, $uid);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($heroExists, $adventure, $reinforcement, $outgoing, $atkReturn);
|
||||
$stmt->fetch();
|
||||
$stmt->close();
|
||||
|
||||
$reason = '';
|
||||
|
||||
// Fara erou antrenat nu exista pe cine echipa. Se numara si eroii morti
|
||||
// (randul exista, doar dead = 1): in T4 iti poti pregati echipamentul cat
|
||||
// astepti invierea. Eroii aflati INCA in antrenament (intraining = 1) nu
|
||||
// conteaza - inca nu exista cu adevarat.
|
||||
if ((int) $heroExists === 0) {
|
||||
$reason = 'nohero';
|
||||
} elseif ((int) $adventure > 0) {
|
||||
$reason = 'adventure';
|
||||
} elseif (((int) $outgoing + (int) $atkReturn) > 0) {
|
||||
$reason = 'attack';
|
||||
} elseif ((int) $reinforcement > 0) {
|
||||
$reason = 'reinforcement';
|
||||
}
|
||||
|
||||
return self::$awayCache[$uid] = $reason;
|
||||
}
|
||||
|
||||
public function equipItem($uid, $rowId)
|
||||
{
|
||||
global $database;
|
||||
$uid = (int) $uid; $rowId = (int) $rowId;
|
||||
|
||||
// Eroul trebuie sa fie in sat. Verificarea e AICI, nu doar in interfata,
|
||||
// ca un POST trimis manual sa nu poata ocoli regula.
|
||||
if ($this->heroAwayReason($uid) !== '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$row = $this->findRowById($uid, $rowId);
|
||||
if (!$row || $row['orphan'] || (int) $row['def']['slot'] === HSLOT_BAG) {
|
||||
return false;
|
||||
@@ -314,6 +403,11 @@ class HeroItems
|
||||
/** Unequip a specific owned row. Returns true on success. */
|
||||
public function unequipItem($uid, $rowId)
|
||||
{
|
||||
// Acelasi gard ca la echipare (vezi heroAwayReason).
|
||||
if ($this->heroAwayReason($uid) !== '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$uid = (int) $uid; $rowId = (int) $rowId;
|
||||
$stmt = $this->db->prepare(
|
||||
"UPDATE " . TB_PREFIX . "hero_items SET equipped = 0 WHERE uid = ? AND id = ? AND equipped = 1 LIMIT 1"
|
||||
|
||||
Reference in New Issue
Block a user