diff --git a/GameEngine/Data/hero_items.php b/GameEngine/Data/hero_items.php index 9d14d00e..04e2d997 100644 --- a/GameEngine/Data/hero_items.php +++ b/GameEngine/Data/hero_items.php @@ -305,3 +305,19 @@ if (!function_exists('heroItemName')) { return isset($heroItemCatalog[$itemid]['name']) ? $heroItemCatalog[$itemid]['name'] : 'Unknown item'; } } + +/** + * Tribe an item belongs to: 0 = universal (helmets, armors, boots, etc.), + * 1/2/3 = Romans/Teutons/Gauls for the unit-bound right-hand weapons + * (u1-10 -> 1, u11-20 -> 2, u21-30 -> 3). Single source for both the + * adventure drop filter and the tribe-filtered auction listing. + */ +if (!function_exists('heroItemTribe')) { + function heroItemTribe($itemid) { + global $heroItemCatalog; + if (!isset($heroItemCatalog[$itemid]['unit'])) { + return 0; + } + return intdiv((int) $heroItemCatalog[$itemid]['unit'] - 1, 10) + 1; + } +} diff --git a/GameEngine/HeroAdventure.php b/GameEngine/HeroAdventure.php index 2e84a42f..6435d2d2 100644 --- a/GameEngine/HeroAdventure.php +++ b/GameEngine/HeroAdventure.php @@ -398,7 +398,7 @@ class HeroAdventure // if no gear dropped, roll the consumable pool. One item max. $itemId = 0; $itemQty = 0; if (mt_rand(1, 100) <= (int) ($cfg['equip_chance'] ?? 0)) { - $itemId = $this->rollEquipment(); + $itemId = $this->rollEquipment($uid); $itemQty = ($itemId > 0) ? 1 : 0; } if ($itemId === 0 && mt_rand(1, 100) <= (int) $cfg['item_chance']) { @@ -531,16 +531,19 @@ class HeroAdventure } /** - * Roll one random piece of EQUIPMENT (any non-bag catalog item, including - * weapons for other tribes - unusable finds feed the auction house, same - * as T4). Tier picked by 'equip_tier_weights' (T1 common, T3 very rare), - * then a uniform pick inside that tier. Returns an itemid, or 0 if the - * rolled tier happens to be empty (defensive; never true with the - * shipped catalog). + * Roll one random piece of EQUIPMENT. Universal gear (helmets, armors, + * boots, horses, left-hand) drops for everyone; right-hand WEAPONS only + * drop for the owner's own tribe (T4 behavior - a Roman never finds a + * Teuton club). Tier picked by 'equip_tier_weights' (T1 common, T3 very + * rare), then a uniform pick inside that tier. Returns an itemid, or 0 + * if the rolled tier happens to be empty (defensive; never true with + * the shipped catalog). */ - public function rollEquipment() + public function rollEquipment($uid = 0) { - global $heroItemCatalog, $heroAdventureConfig; + global $database, $heroItemCatalog, $heroAdventureConfig; + + $tribe = ((int) $uid > 0) ? (int) $database->getUserField((int) $uid, 'tribe', 0) : 0; $weights = $heroAdventureConfig['equip_tier_weights']; $roll = mt_rand(1, 100); $acc = 0; $tier = 1; @@ -551,9 +554,14 @@ class HeroAdventure $pool = array(); foreach ($heroItemCatalog as $iid => $def) { - if ((int) $def['slot'] !== HSLOT_BAG && (int) $def['tier'] === $tier) { - $pool[] = $iid; + if ((int) $def['slot'] === HSLOT_BAG || (int) $def['tier'] !== $tier) { + continue; } + $itemTribe = heroItemTribe($iid); + if ($itemTribe !== 0 && $tribe > 0 && $itemTribe !== $tribe) { + continue; // foreign-tribe weapon + } + $pool[] = $iid; } return count($pool) ? (int) $pool[array_rand($pool)] : 0; } diff --git a/GameEngine/HeroAuction.php b/GameEngine/HeroAuction.php index 61816fa1..f3d10019 100644 --- a/GameEngine/HeroAuction.php +++ b/GameEngine/HeroAuction.php @@ -83,10 +83,22 @@ class HeroAuction * READS * ===================================================================== */ - /** All open, unexpired auctions (newest ending first optional; default: ending soonest). */ - public function getOpenAuctions($limit = 50) + /** + * All open, unexpired auctions, ending soonest first. + * When $viewerUid is given, right-hand WEAPONS of other tribes are + * hidden (T4 behavior: a Roman only sees Roman weapon lots). Universal + * gear and consumables are always shown. The SQL over-fetches slightly + * so the filter still fills the page. + */ + public function getOpenAuctions($limit = 50, $viewerUid = 0) { + global $database; $now = time(); $limit = max(1, (int) $limit); + + $viewerTribe = ((int) $viewerUid > 0) + ? (int) $database->getUserField((int) $viewerUid, 'tribe', 0) : 0; + $fetch = $viewerTribe > 0 ? $limit * 2 : $limit; + $stmt = $this->db->prepare( "SELECT id, seller, itemid, slot, stat_value, quantity, silver_start, silver_current, bidder, created, time_end, status @@ -94,14 +106,23 @@ class HeroAuction WHERE status = " . self::ST_OPEN . " AND time_end > ? ORDER BY time_end ASC LIMIT ?" ); - $stmt->bind_param('ii', $now, $limit); + $stmt->bind_param('ii', $now, $fetch); $stmt->execute(); $res = $stmt->get_result(); $out = array(); while ($row = $res->fetch_assoc()) { + if ($viewerTribe > 0) { + $itemTribe = heroItemTribe($row['itemid']); + if ($itemTribe !== 0 && $itemTribe !== $viewerTribe) { + continue; // foreign-tribe weapon lot + } + } $row['name'] = heroItemName($row['itemid']); // bid_max intentionally NOT selected - it's the bidder's secret. $out[] = $row; + if (count($out) >= $limit) { + break; + } } $stmt->close(); return $out; diff --git a/Templates/Build/37_auction.tpl b/Templates/Build/37_auction.tpl index 8a7f2071..04083e23 100644 --- a/Templates/Build/37_auction.tpl +++ b/Templates/Build/37_auction.tpl @@ -32,7 +32,7 @@ if (isset($_POST['t4action'])) { } } -$t4Open = $t4Auction->getOpenAuctions(); +$t4Open = $t4Auction->getOpenAuctions(50, $session->uid); $t4MyBids = $t4Auction->getMyBids($session->uid); $t4MySales = $t4Auction->getMySales($session->uid); $t4Now = time();