Add T4 Hero System (configurable on install)

Add T4 Hero System (configurable on install with TRUE/FALS) part of #285

-Adventures
-Merchants
-Equipment
This commit is contained in:
novgorodschi catalin
2026-07-10 09:15:42 +03:00
parent ed325b6d99
commit 3c99623a33
46 changed files with 4367 additions and 32 deletions
+5
View File
@@ -207,6 +207,11 @@ $hasRally = $village->resarray['f39'] > 0;
$set = $database->getMovement(5,$village->wid,0);
$cnt = count($set);
foreach($out as $u) if($u['vref']==$village->wid) $cnt++;
// T4 hero port: adventure legs count as troops on their way too.
if (defined('NEW_FUNCTIONS_HERO_T4') && NEW_FUNCTIONS_HERO_T4) {
$cnt += count($database->getMovement(20,$village->wid,0));
$cnt += count($database->getMovement(21,$village->wid,1));
}
?>
<?php if($cnt>=1): ?>
<h4><?= TROOPS_ON_THEIR_WAY ?></h4>
+35
View File
@@ -20,6 +20,41 @@
#################################################################################
$outgoing = $database->getMovement(3, $village->wid, 0);
// T4 hero port: hero adventure legs (out = from this village, back = to it).
$advWalking = [];
if (defined('NEW_FUNCTIONS_HERO_T4') && NEW_FUNCTIONS_HERO_T4) {
foreach ($database->getMovement(20, $village->wid, 0) as $m) { $m['t4adv'] = 'out'; $advWalking[] = $m; }
foreach ($database->getMovement(21, $village->wid, 1) as $m) { $m['t4adv'] = 'back'; $advWalking[] = $m; }
}
?>
<?php foreach ($advWalking as $m):
$session->timer++;
$action = $m['t4adv'] === 'out'
? (defined('HERO_ADV_MOV_OUT') ? HERO_ADV_MOV_OUT : 'Hero on an adventure')
: (defined('HERO_ADV_MOV_BACK') ? HERO_ADV_MOV_BACK : 'Hero returning from an adventure');
$dt = $generator->procMtime($m['endtime']);
?>
<table class="troop_details" cellpadding="1" cellspacing="1">
<thead><tr>
<td class="role"><a href="karte.php?d=<?= $village->wid?>&c=<?= $generator->getMapCheck($village->wid)?>"><?= $village->vname?></a></td>
<td colspan="2"><?= $action?></td>
</tr></thead>
<tbody class="units">
<tr><th>&nbsp;</th><td style="width:40px;"><img src="img/x.gif" class="unit uhero" title="<?php echo U0; ?>"></td><td>&nbsp;</td></tr>
<tr><th><?= TROOPS?></th><td>1</td><td>&nbsp;</td></tr>
</tbody>
<tbody class="infos"><tr>
<th><?= ARRIVAL?></th>
<td colspan="2">
<div class="in small"><span id="timer<?= $session->timer?>"><?= $generator->getTimeFormat($m['endtime']-time())?></span> h</div>
<div class="at"><?= $dt[0]!='today'?ON.' '.$dt[0].' ':''?><?= AT?> <?= $dt[1]?></div>
</td>
</tr></tbody>
</table>
<?php endforeach;?>
<?php
?>
<?php foreach ($outgoing as $m):
+16
View File
@@ -71,7 +71,23 @@
if(isset($_GET['land']) && $village->resarray['f' . $id] >= 1) {
include_once("37_land.tpl");
} else if (defined('NEW_FUNCTIONS_HERO_T4') && NEW_FUNCTIONS_HERO_T4
&& $village->resarray['f' . $id] >= 1
&& isset($_GET['t4tab'])
&& in_array($_GET['t4tab'], ['items', 'adventures', 'auction'], true)) {
// T4 hero port (Phase 6): items / adventures / auction tabs.
// The classic hero flow below stays byte-identical when the
// feature flag is off or no tab is selected.
$t4tab = $_GET['t4tab'];
include_once("37_t4nav.tpl");
include_once("37_" . $t4tab . ".tpl");
} else if ($village->resarray['f' . $id] >= 1) {
if (defined('NEW_FUNCTIONS_HERO_T4') && NEW_FUNCTIONS_HERO_T4) {
$t4tab = 'hero';
include_once("37_t4nav.tpl");
}
$include_training = true;
$include_revive = false;
if (isset($heroes) && is_array($heroes) && count($heroes)) {
+78
View File
@@ -0,0 +1,78 @@
<?php
#################################################################################
# T4 hero adventures tab (37_adventures.tpl) - Phase 6 #
# POST: t4action=startadv, advid. Countdown spans reuse the existing #
# $session->timer JS convention (same as 37.tpl's training timer). #
#################################################################################
$t4Adventures = new HeroAdventure();
$t4Msg = '';
if (isset($_POST['t4action'], $_POST['advid']) && $_POST['t4action'] === 'startadv') {
$t4Result = $t4Adventures->startAdventure($session->uid, (int) $_POST['advid']);
if ($t4Result === HeroAdventure::START_OK) {
$t4Msg = HERO_ADV_START_OK;
} elseif ($t4Result === HeroAdventure::START_NO_HERO) {
$t4Msg = HERO_ADV_START_NOHERO;
} elseif ($t4Result === HeroAdventure::START_HERO_AWAY) {
$t4Msg = HERO_ADV_START_AWAY;
} else {
$t4Msg = HERO_ADV_START_FAIL;
}
}
// Top up the list opportunistically (respects max/refresh limits internally).
$t4Adventures->generateOffers($session->uid);
$t4Offers = $t4Adventures->getOffers($session->uid);
$t4Running = $t4Adventures->getRunning($session->uid);
$t4Now = time();
?>
<?php if ($t4Msg !== '') { ?>
<p class="message" style="font-weight:bold;"><?php echo $t4Msg; ?></p>
<?php } ?>
<?php if ($t4Running) { ?>
<table id="distribution" cellpadding="1" cellspacing="1">
<thead>
<tr><th><?php echo HERO_ADV_RUNNING; ?>
<span id="timer<?php echo ++$session->timer; ?>"><?php echo $generator->getTimeFormat(max(0, $t4Running['endtime'] - $t4Now)); ?></span>
</th></tr>
</thead>
</table>
<?php } ?>
<table id="distribution" cellpadding="1" cellspacing="1" style="margin-top:10px;">
<thead>
<tr><th colspan="4"><?php echo HERO_ADV_LIST; ?></th></tr>
<tr>
<td><b><?php echo HERO_ADV_DIFFICULTY; ?></b></td>
<td><b><?php echo HERO_ADV_DURATION; ?></b></td>
<td><b><?php echo HERO_ADV_EXPIRES; ?></b></td>
<td></td>
</tr>
</thead>
<tbody>
<?php if (count($t4Offers)) { ?>
<?php foreach ($t4Offers as $t4Offer) { ?>
<tr>
<td><?php echo ((int) $t4Offer['difficulty'] === 1) ? HERO_ADV_DIFF_HARD : HERO_ADV_DIFF_NORMAL; ?></td>
<td><?php echo $generator->getTimeFormat((int) $t4Offer['duration']); ?></td>
<td><span id="timer<?php echo ++$session->timer; ?>"><?php echo $generator->getTimeFormat(max(0, $t4Offer['expire'] - $t4Now)); ?></span></td>
<td style="width:140px;text-align:center;">
<?php if (!$t4Running) { ?>
<form action="" method="POST" style="margin:0;">
<input type="hidden" name="t4action" value="startadv">
<input type="hidden" name="advid" value="<?php echo (int) $t4Offer['id']; ?>">
<input type="submit" value="<?php echo HERO_ADV_GO; ?>">
</form>
<?php } else { ?>-<?php } ?>
</td>
</tr>
<?php } ?>
<?php } else { ?>
<tr><td colspan="4"><?php echo HERO_ADV_NONE; ?></td></tr>
<?php } ?>
</tbody>
</table>
+160
View File
@@ -0,0 +1,160 @@
<?php
#################################################################################
# T4 hero auction tab (37_auction.tpl) - Phase 6 #
# POST actions: #
# t4action=bid (aucid, maxbid) #
# t4action=sell (rowid, qty, price, duration) #
# bid_max is only ever shown for the viewer's OWN bids (getMyBids). #
#################################################################################
$t4Auction = new HeroAuction();
$t4Msg = '';
if (isset($_POST['t4action'])) {
if ($_POST['t4action'] === 'bid' && isset($_POST['aucid'], $_POST['maxbid'])) {
$t4Result = $t4Auction->placeBid($session->uid, (int) $_POST['aucid'], (int) $_POST['maxbid']);
if ($t4Result === HeroAuction::BID_OK) {
$t4Msg = HERO_AUC_BID_OK;
} elseif ($t4Result === HeroAuction::BID_OUTBID) {
$t4Msg = HERO_AUC_BID_OUTBID;
} elseif ($t4Result === HeroAuction::BID_NO_SILVER) {
$t4Msg = HERO_AUC_BID_NOSILVER;
} else {
$t4Msg = HERO_AUC_BID_FAIL;
}
} elseif ($_POST['t4action'] === 'sell'
&& isset($_POST['rowid'], $_POST['qty'], $_POST['price'], $_POST['duration'])) {
$t4Result = $t4Auction->createAuction(
$session->uid, (int) $_POST['rowid'],
(int) $_POST['qty'], (int) $_POST['price'], (int) $_POST['duration']
);
$t4Msg = ($t4Result > 0) ? HERO_AUC_SELL_OK : HERO_AUC_SELL_FAIL;
}
}
$t4Open = $t4Auction->getOpenAuctions();
$t4MyBids = $t4Auction->getMyBids($session->uid);
$t4MySales = $t4Auction->getMySales($session->uid);
$t4Now = time();
// Unequipped items sellable from the inventory.
$t4Sellable = array();
foreach ($t4HeroItems->getInventory($session->uid) as $t4Row) {
if ($t4Row['equipped'] == 0 && !$t4Row['orphan']) {
$t4Sellable[] = $t4Row;
}
}
?>
<?php if ($t4Msg !== '') { ?>
<p class="message" style="font-weight:bold;"><?php echo $t4Msg; ?></p>
<?php } ?>
<table id="distribution" cellpadding="1" cellspacing="1">
<thead>
<tr><th colspan="5"><?php echo HERO_AUC_OPEN; ?></th></tr>
<tr>
<td><b><?php echo HERO_AUC_ITEM; ?></b></td>
<td><b><?php echo HERO_QUANTITY; ?></b></td>
<td><b><?php echo HERO_AUC_PRICE; ?></b></td>
<td><b><?php echo HERO_AUC_TIME_LEFT; ?></b></td>
<td><b><?php echo HERO_AUC_BID; ?></b></td>
</tr>
</thead>
<tbody>
<?php if (count($t4Open)) { ?>
<?php foreach ($t4Open as $t4A) { ?>
<tr>
<td><span class="heroT4Item item<?php echo (int) $t4A['itemid']; ?>"></span> <?php echo $t4A['name']; ?>
<?php if ((int) $t4A['seller'] === 0) { ?><small>(<?php echo HERO_AUC_SELLER_NPC; ?>)</small><?php } ?>
</td>
<td style="text-align:center;"><?php echo (int) $t4A['quantity']; ?></td>
<td style="text-align:right;"><?php echo number_format((int) $t4A['silver_current']); ?></td>
<td><span id="timer<?php echo ++$session->timer; ?>"><?php echo $generator->getTimeFormat(max(0, $t4A['time_end'] - $t4Now)); ?></span></td>
<td style="width:170px;text-align:center;">
<?php if ((int) $t4A['seller'] !== $session->uid) { ?>
<form action="" method="POST" style="margin:0;">
<input type="hidden" name="t4action" value="bid">
<input type="hidden" name="aucid" value="<?php echo (int) $t4A['id']; ?>">
<input type="text" name="maxbid" size="6" style="text-align:right;"
value="<?php echo (int) $t4A['silver_current'] + ((int) $t4A['bidder'] > 0 ? 1 : 0); ?>">
<input type="submit" value="<?php echo HERO_AUC_BID; ?>">
</form>
<?php } else { ?>-<?php } ?>
</td>
</tr>
<?php } ?>
<?php } else { ?>
<tr><td colspan="5"><?php echo HERO_AUC_NONE; ?></td></tr>
<?php } ?>
</tbody>
</table>
<?php if (count($t4MyBids)) { ?>
<table id="distribution" cellpadding="1" cellspacing="1" style="margin-top:10px;">
<thead>
<tr><th colspan="4"><?php echo HERO_AUC_MY_BIDS; ?></th></tr>
</thead>
<tbody>
<?php foreach ($t4MyBids as $t4A) { ?>
<tr>
<td><?php echo $t4A['name']; ?> (<?php echo (int) $t4A['quantity']; ?>x)</td>
<td style="text-align:right;"><?php echo HERO_AUC_PRICE; ?>: <?php echo number_format((int) $t4A['silver_current']); ?></td>
<td style="text-align:right;"><?php echo HERO_AUC_YOUR_MAX; ?>: <?php echo number_format((int) $t4A['bid_max']); ?></td>
<td><span id="timer<?php echo ++$session->timer; ?>"><?php echo $generator->getTimeFormat(max(0, $t4A['time_end'] - $t4Now)); ?></span></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } ?>
<?php if (count($t4MySales)) { ?>
<table id="distribution" cellpadding="1" cellspacing="1" style="margin-top:10px;">
<thead>
<tr><th colspan="3"><?php echo HERO_AUC_MY_SALES; ?></th></tr>
</thead>
<tbody>
<?php foreach ($t4MySales as $t4A) { ?>
<tr>
<td><?php echo $t4A['name']; ?> (<?php echo (int) $t4A['quantity']; ?>x)</td>
<td style="text-align:right;"><?php echo HERO_AUC_PRICE; ?>: <?php echo number_format((int) $t4A['silver_current']); ?></td>
<td><span id="timer<?php echo ++$session->timer; ?>"><?php echo $generator->getTimeFormat(max(0, $t4A['time_end'] - $t4Now)); ?></span></td>
</tr>
<?php } ?>
</tbody>
</table>
<?php } ?>
<?php if (count($t4Sellable)) { ?>
<table id="distribution" cellpadding="1" cellspacing="1" style="margin-top:10px;">
<thead>
<tr><th colspan="5"><?php echo HERO_AUC_SELL; ?></th></tr>
</thead>
<tbody>
<tr>
<form action="" method="POST" style="margin:0;">
<input type="hidden" name="t4action" value="sell">
<td>
<select name="rowid">
<?php foreach ($t4Sellable as $t4Row) { ?>
<option value="<?php echo (int) $t4Row['id']; ?>">
<?php echo $t4Row['name']; ?><?php if ((int) $t4Row['quantity'] > 1) echo ' (' . (int) $t4Row['quantity'] . 'x)'; ?>
</option>
<?php } ?>
</select>
</td>
<td><?php echo HERO_QUANTITY; ?>: <input type="text" name="qty" value="1" size="3" style="text-align:center;"></td>
<td><?php echo HERO_AUC_START_PRICE; ?>: <input type="text" name="price" value="10" size="5" style="text-align:right;"></td>
<td><?php echo HERO_AUC_DURATION; ?>:
<select name="duration">
<option value="14400">4h</option>
<option value="28800">8h</option>
<option value="86400">24h</option>
</select>
</td>
<td style="text-align:center;"><input type="submit" value="<?php echo HERO_AUC_LIST; ?>"></td>
</form>
</tr>
</tbody>
</table>
<?php } ?>
+112
View File
@@ -0,0 +1,112 @@
<?php
#################################################################################
# T4 hero inventory & equipment tab (37_items.tpl) - Phase 6 #
# Inline POST handling (same convention as 37_hero.tpl's rename form): #
# t4action=equip|unequip|useitem, rowid, qty #
# Law tablets target the CURRENT village ($village->wid). #
#################################################################################
$t4Msg = '';
if (isset($_POST['t4action'], $_POST['rowid'])) {
$t4RowId = (int) $_POST['rowid'];
switch ($_POST['t4action']) {
case 'equip':
$t4Msg = $t4HeroItems->equipItem($session->uid, $t4RowId)
? HERO_EQUIP_OK : HERO_EQUIP_FAIL;
break;
case 'unequip':
$t4Msg = $t4HeroItems->unequipItem($session->uid, $t4RowId)
? HERO_UNEQUIP_OK : HERO_ITEM_USE_FAIL;
break;
case 'useitem':
$t4Qty = max(1, (int) ($_POST['qty'] ?? 1));
$t4Result = $t4HeroItems->useItem($session->uid, $t4RowId, $t4Qty, $village->wid);
if ($t4Result === HeroItems::USE_OK) {
$t4Msg = HERO_ITEM_USED_OK;
} elseif ($t4Result === HeroItems::USE_DEFERRED) {
$t4Msg = HERO_ITEM_USE_BATTLE;
} else {
$t4Msg = HERO_ITEM_USE_FAIL;
}
break;
}
}
$t4Inventory = $t4HeroItems->getInventory($session->uid);
$t4Equipped = $t4HeroItems->getEquipped($session->uid);
?>
<?php if ($t4Msg !== '') { ?>
<p class="message" style="font-weight:bold;"><?php echo $t4Msg; ?></p>
<?php } ?>
<table id="distribution" cellpadding="1" cellspacing="1">
<thead>
<tr><th colspan="4"><?php echo HERO_ITEMS_EQUIPPED; ?></th></tr>
</thead>
<tbody>
<?php for ($t4Slot = 1; $t4Slot <= 6; $t4Slot++) { ?>
<tr>
<td style="width:110px;"><b><?php echo constant('HERO_SLOT_' . $t4Slot); ?></b></td>
<?php if (isset($t4Equipped[$t4Slot])) { $t4Row = $t4Equipped[$t4Slot]; ?>
<td><span class="heroT4Item item<?php echo (int) $t4Row['itemid']; ?>"></span> <?php echo $t4Row['name']; ?></td>
<td style="width:60px;text-align:center;"><?php echo 'T' . (int) $t4Row['def']['tier']; ?></td>
<td style="width:110px;text-align:center;">
<form action="" method="POST" style="margin:0;">
<input type="hidden" name="t4action" value="unequip">
<input type="hidden" name="rowid" value="<?php echo (int) $t4Row['id']; ?>">
<input type="submit" value="<?php echo HERO_UNEQUIP; ?>">
</form>
</td>
<?php } else { ?>
<td colspan="3" style="color:#888;">-</td>
<?php } ?>
</tr>
<?php } ?>
</tbody>
</table>
<table id="distribution" cellpadding="1" cellspacing="1" style="margin-top:10px;">
<thead>
<tr><th colspan="4"><?php echo HERO_ITEMS_BAG; ?></th></tr>
</thead>
<tbody>
<?php
$t4HasUnequipped = false;
foreach ($t4Inventory as $t4Row) {
if ($t4Row['equipped'] == 1 || $t4Row['orphan']) {
continue;
}
$t4HasUnequipped = true;
$t4IsBag = ((int) $t4Row['def']['slot'] === HSLOT_BAG);
?>
<tr>
<td><span class="heroT4Item item<?php echo (int) $t4Row['itemid']; ?>"></span> <?php echo $t4Row['name']; ?></td>
<td style="width:80px;text-align:center;">
<?php echo $t4IsBag ? (int) $t4Row['quantity'] . 'x' : 'T' . (int) $t4Row['def']['tier']; ?>
</td>
<td style="width:110px;text-align:center;"><?php echo constant('HERO_SLOT_' . (int) $t4Row['def']['slot']); ?></td>
<td style="width:170px;text-align:center;">
<form action="" method="POST" style="margin:0;">
<input type="hidden" name="rowid" value="<?php echo (int) $t4Row['id']; ?>">
<?php if ($t4IsBag) { ?>
<input type="hidden" name="t4action" value="useitem">
<input type="text" name="qty" value="1" size="3" style="text-align:center;">
<input type="submit" value="<?php echo HERO_USE_ITEM; ?>">
<?php } else { ?>
<input type="hidden" name="t4action" value="equip">
<input type="submit" value="<?php echo HERO_EQUIP; ?>">
<?php } ?>
</form>
</td>
</tr>
<?php } ?>
<?php if (!$t4HasUnequipped) { ?>
<tr><td colspan="4"><?php echo HERO_ITEMS_EMPTY; ?></td></tr>
<?php } ?>
</tbody>
</table>
+28
View File
@@ -0,0 +1,28 @@
<?php
#################################################################################
# T4 hero mansion tab navigation (37_t4nav.tpl) - Phase 6 #
# Included by 37.tpl with $t4tab set to 'hero'|'items'|'adventures'|'auction'. #
# Silver balance shown on the right; reuses existing anchor styling. #
#################################################################################
$t4HeroItems = new HeroItems();
$t4Silver = $t4HeroItems->getSilver($session->uid);
$t4Tabs = [
'hero' => ['label' => HERO_T4_TAB_HERO, 'url' => 'build.php?id=' . $id],
'items' => ['label' => HERO_T4_TAB_ITEMS, 'url' => 'build.php?id=' . $id . '&t4tab=items'],
'adventures' => ['label' => HERO_T4_TAB_ADVENTURES, 'url' => 'build.php?id=' . $id . '&t4tab=adventures'],
'auction' => ['label' => HERO_T4_TAB_AUCTION, 'url' => 'build.php?id=' . $id . '&t4tab=auction'],
];
?>
<link rel="stylesheet" href="css/hero_items.css" type="text/css">
<div class="heroT4Nav" style="margin:6px 0 10px 0;">
<?php foreach ($t4Tabs as $key => $tab) { ?>
<?php if ($key === $t4tab) { ?>
<span style="font-weight:bold;margin-right:14px;"><?php echo $tab['label']; ?></span>
<?php } else { ?>
<a href="<?php echo $tab['url']; ?>" style="margin-right:14px;"><?php echo $tab['label']; ?></a>
<?php } ?>
<?php } ?>
<span style="float:right;"><b><?php echo HERO_SILVER; ?>:</b> <?php echo number_format($t4Silver); ?></span>
<div style="clear:both;"></div>
</div>