✨feature: Final mining touches, with closing contracts and negotiating new ones
This commit is contained in:
210
mining-fleet.php
210
mining-fleet.php
@@ -95,6 +95,37 @@ function buildContractDeliveryTargets( array $activeContracts ): array {
|
||||
return $targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a trade symbol represents ore cargo.
|
||||
*
|
||||
* @param string $tradeSymbol Trade symbol.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function isOreTradeSymbol( string $tradeSymbol ): bool {
|
||||
return preg_match( '/_ORE$/', strtoupper( $tradeSymbol ) ) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which ship symbol should be used for contract negotiation.
|
||||
*
|
||||
* @param array<int,array<string,mixed>> $miningShips Mining ship records.
|
||||
* @param array<int,array<string,mixed>> $ships All ship records.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getContractNegotiationShipSymbol( array $miningShips, array $ships ): string {
|
||||
if (! empty( $miningShips ) ) {
|
||||
return (string) ( $miningShips[0]['symbol'] ?? '' );
|
||||
}
|
||||
|
||||
if (! empty( $ships ) ) {
|
||||
return (string) ( $ships[0]['symbol'] ?? '' );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
$config = require __DIR__ . '/lib/project-config.php';
|
||||
|
||||
$storage = new SpacetradersStorage( $config['db_path'] );
|
||||
@@ -206,6 +237,73 @@ try {
|
||||
trim( (string) $_POST['contract_delivery_key'] ) :
|
||||
(string) ( $contractDeliveryTargets[0]['key'] ?? '' );
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['contract_action'] ) ) {
|
||||
$contractAction = (string) $_POST['contract_action'];
|
||||
|
||||
if ($contractAction === 'fulfill_contract' ) {
|
||||
$contractId = trim( (string) ( $_POST['contract_id'] ?? '' ) );
|
||||
|
||||
if ($contractId !== '' ) {
|
||||
try {
|
||||
$client->fulfillContract( $contractId );
|
||||
$statusMessage = 'Contract ' . $contractId . ' fulfilled.';
|
||||
$storage->clearAllCache();
|
||||
|
||||
$shipsResponse = $client->listMyShips();
|
||||
$contractsResponse = $client->listMyContracts();
|
||||
$ships = $shipsResponse['data'] ?? $shipsResponse;
|
||||
$contracts = $contractsResponse['data'] ?? $contractsResponse;
|
||||
$miningShips = filterMiningShips( $ships );
|
||||
$activeContracts = array_values(
|
||||
array_filter(
|
||||
(array) $contracts,
|
||||
static function ( array $contract ): bool {
|
||||
return (bool) ( $contract['accepted'] ?? false ) && ! (bool) ( $contract['fulfilled'] ?? false );
|
||||
}
|
||||
)
|
||||
);
|
||||
$contractDeliveryTargets = buildContractDeliveryTargets( $activeContracts );
|
||||
$selectedContractDeliveryKey = (string) ( $contractDeliveryTargets[0]['key'] ?? '' );
|
||||
} catch (SpacetradersApiException $e) {
|
||||
$errorMessage = 'Unable to fulfill contract: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
} elseif ($contractAction === 'negotiate_contract' ) {
|
||||
$negotiateShipSymbol = trim( (string) ( $_POST['negotiate_ship_symbol'] ?? '' ) );
|
||||
if ($negotiateShipSymbol === '' ) {
|
||||
$negotiateShipSymbol = getContractNegotiationShipSymbol( $miningShips, $ships );
|
||||
}
|
||||
|
||||
if ($negotiateShipSymbol === '' ) {
|
||||
$errorMessage = 'No available ship found to negotiate a contract.';
|
||||
} else {
|
||||
try {
|
||||
$client->negotiateContract( $negotiateShipSymbol );
|
||||
$statusMessage = 'Negotiated a new contract using ' . $negotiateShipSymbol . '.';
|
||||
$storage->clearAllCache();
|
||||
|
||||
$shipsResponse = $client->listMyShips();
|
||||
$contractsResponse = $client->listMyContracts();
|
||||
$ships = $shipsResponse['data'] ?? $shipsResponse;
|
||||
$contracts = $contractsResponse['data'] ?? $contractsResponse;
|
||||
$miningShips = filterMiningShips( $ships );
|
||||
$activeContracts = array_values(
|
||||
array_filter(
|
||||
(array) $contracts,
|
||||
static function ( array $contract ): bool {
|
||||
return (bool) ( $contract['accepted'] ?? false ) && ! (bool) ( $contract['fulfilled'] ?? false );
|
||||
}
|
||||
)
|
||||
);
|
||||
$contractDeliveryTargets = buildContractDeliveryTargets( $activeContracts );
|
||||
$selectedContractDeliveryKey = (string) ( $contractDeliveryTargets[0]['key'] ?? '' );
|
||||
} catch (SpacetradersApiException $e) {
|
||||
$errorMessage = 'Unable to negotiate contract: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['fleet_action'] ) ) {
|
||||
$fleetAction = (string) $_POST['fleet_action'];
|
||||
$successCount = 0;
|
||||
@@ -357,6 +455,35 @@ try {
|
||||
|
||||
$actionResults[] = $shipSymbol . ': jettisoned ' . $jettisonedItems . ' cargo item type(s).';
|
||||
$successCount++;
|
||||
} elseif ($fleetAction === 'jettison_non_ore_cargo_all' ) {
|
||||
if ($shipStatus === 'IN_TRANSIT' ) {
|
||||
$actionResults[] = $shipSymbol . ': skipped (in transit).';
|
||||
continue;
|
||||
}
|
||||
|
||||
$inventory = (array) ( $shipData['cargo']['inventory'] ?? array() );
|
||||
$jettisonedItems = 0;
|
||||
foreach ( $inventory as $item ) {
|
||||
$tradeSymbol = (string) ( $item['symbol'] ?? '' );
|
||||
$units = (int) ( $item['units'] ?? 0 );
|
||||
if ($tradeSymbol === '' || $units <= 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isOreTradeSymbol( $tradeSymbol ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$client->jettisonCargo( $shipSymbol, $tradeSymbol, $units );
|
||||
$jettisonedItems++;
|
||||
} catch (SpacetradersApiException $e) {
|
||||
// Continue jettisoning other items.
|
||||
}
|
||||
}
|
||||
|
||||
$actionResults[] = $shipSymbol . ': jettisoned ' . $jettisonedItems . ' non-ore cargo item type(s).';
|
||||
$successCount++;
|
||||
} elseif ($fleetAction === 'navigate_contract_delivery' ) {
|
||||
if (! is_array( $selectedContractDeliveryTarget ) ) {
|
||||
$actionResults[] = $shipSymbol . ': no contract delivery target selected.';
|
||||
@@ -475,7 +602,7 @@ try {
|
||||
(string) ( $contractDeliveryTargets[0]['key'] ?? '' );
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['ship_action'] ) && in_array( (string) $_POST['ship_action'], array( 'sell_ship_cargo', 'jettison_ship_cargo' ), true ) && isset( $_POST['ship_symbol'] )) {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['ship_action'] ) && in_array( (string) $_POST['ship_action'], array( 'sell_ship_cargo', 'jettison_ship_cargo', 'jettison_non_ore_ship_cargo' ), true ) && isset( $_POST['ship_symbol'] )) {
|
||||
$shipAction = (string) $_POST['ship_action'];
|
||||
$sellShipSymbol = trim( (string) $_POST['ship_symbol'] );
|
||||
|
||||
@@ -502,6 +629,10 @@ try {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($shipAction === 'jettison_non_ore_ship_cargo' && isOreTradeSymbol( $tradeSymbol ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($shipAction === 'sell_ship_cargo' ) {
|
||||
$client->sellCargo( $sellShipSymbol, $tradeSymbol, $units );
|
||||
@@ -516,6 +647,8 @@ try {
|
||||
|
||||
if ($shipAction === 'sell_ship_cargo' ) {
|
||||
$statusMessage = $sellShipSymbol . ': sold ' . $handledItems . ' cargo item type(s).';
|
||||
} elseif ($shipAction === 'jettison_non_ore_ship_cargo' ) {
|
||||
$statusMessage = $sellShipSymbol . ': jettisoned ' . $handledItems . ' non-ore cargo item type(s).';
|
||||
} else {
|
||||
$statusMessage = $sellShipSymbol . ': jettisoned ' . $handledItems . ' cargo item type(s).';
|
||||
}
|
||||
@@ -561,6 +694,8 @@ foreach ( $miningShips as $miningShip ) {
|
||||
$deliveryReadyByTradeSymbol[ $tradeSymbol ] += $units;
|
||||
}
|
||||
}
|
||||
|
||||
$contractNegotiationShipSymbol = getContractNegotiationShipSymbol( $miningShips, $ships );
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
@@ -601,8 +736,23 @@ foreach ( $miningShips as $miningShip ) {
|
||||
<div class="mb-6 border border-gray-600 rounded p-4">
|
||||
<h2 class="text-xl font-bold mb-3">Global Controls</h2>
|
||||
<form method="post" class="flex flex-wrap items-end gap-3">
|
||||
<button type="submit" name="fleet_action" value="excavate_all" class="px-4 py-2 bg-emerald-700 rounded hover:bg-emerald-600">
|
||||
Command All: Excavate
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="dock_refuel_all" class="px-4 py-2 bg-blue-700 rounded hover:bg-blue-600">
|
||||
Command All: Dock & Refuel
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="jettison_cargo_all" class="px-4 py-2 bg-red-800 rounded hover:bg-red-700">
|
||||
Command All: Jettison Cargo
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="jettison_non_ore_cargo_all" class="px-4 py-2 bg-red-700 rounded hover:bg-red-600">
|
||||
Command All: Jettison Non-Ore Cargo
|
||||
</button>
|
||||
|
||||
<div class="w-full border-t border-gray-600 my-4 grow"></div>
|
||||
|
||||
<div>
|
||||
<label for="market_waypoint" class="block text-sm mb-1">Market Waypoint</label>
|
||||
<label for="market_waypoint" class="block text-xl mb-1">Market Waypoint</label>
|
||||
<select id="market_waypoint" name="market_waypoint" class="px-3 py-2 rounded text-black min-w-64">
|
||||
<?php foreach ( $marketWaypoints as $waypoint ) : ?>
|
||||
<option value="<?php echo htmlspecialchars( $waypoint ); ?>" <?php echo $waypoint === $selectedMarketWaypoint ? 'selected' : ''; ?>>
|
||||
@@ -612,8 +762,17 @@ foreach ( $miningShips as $miningShip ) {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="contract_delivery_key" class="block text-sm mb-1">Contract Delivery Target</label>
|
||||
<button type="submit" name="fleet_action" value="move_and_sell_all" class="px-4 py-2 bg-amber-700 rounded hover:bg-amber-600">
|
||||
Command All: Move to Market & Sell
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="sell_cargo_here_all" class="px-4 py-2 bg-rose-700 rounded hover:bg-rose-600">
|
||||
Command All: Sell Cargo Here
|
||||
</button>
|
||||
|
||||
<div class="w-full border-t border-gray-600 my-4 grow"></div>
|
||||
|
||||
<div class="">
|
||||
<label for="contract_delivery_key" class="block text-xl mb-1">Contract Delivery Target</label>
|
||||
<select id="contract_delivery_key" name="contract_delivery_key" class="px-3 py-2 rounded text-black min-w-80">
|
||||
<?php if (empty( $contractDeliveryTargets ) ) : ?>
|
||||
<option value="">No outstanding delivery targets</option>
|
||||
@@ -638,21 +797,6 @@ foreach ( $miningShips as $miningShip ) {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" name="fleet_action" value="excavate_all" class="px-4 py-2 bg-emerald-700 rounded hover:bg-emerald-600">
|
||||
Command All: Excavate
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="dock_refuel_all" class="px-4 py-2 bg-blue-700 rounded hover:bg-blue-600">
|
||||
Command All: Dock & Refuel
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="move_and_sell_all" class="px-4 py-2 bg-amber-700 rounded hover:bg-amber-600">
|
||||
Command All: Move to Market & Sell
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="sell_cargo_here_all" class="px-4 py-2 bg-rose-700 rounded hover:bg-rose-600">
|
||||
Command All: Sell Cargo Here
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="jettison_cargo_all" class="px-4 py-2 bg-red-800 rounded hover:bg-red-700">
|
||||
Command All: Jettison Cargo
|
||||
</button>
|
||||
<button type="submit" name="fleet_action" value="navigate_contract_delivery" class="px-4 py-2 bg-indigo-700 rounded hover:bg-indigo-600">
|
||||
Command All: Navigate to Contract Delivery
|
||||
</button>
|
||||
@@ -680,7 +824,21 @@ foreach ( $miningShips as $miningShip ) {
|
||||
<div class="mb-6 border border-gray-600 rounded p-4">
|
||||
<h2 class="text-xl font-bold mb-3">Active Contracts</h2>
|
||||
<?php if (empty( $activeContracts ) ) : ?>
|
||||
<p class="text-gray-300">No active contracts.</p>
|
||||
<p class="text-gray-300 mb-3">No active contracts.</p>
|
||||
<?php if ($contractNegotiationShipSymbol !== '' ) : ?>
|
||||
<form method="post">
|
||||
<input type="hidden" name="contract_action" value="negotiate_contract">
|
||||
<input type="hidden" name="negotiate_ship_symbol" value="<?php echo htmlspecialchars( $contractNegotiationShipSymbol ); ?>">
|
||||
<button type="submit" class="px-3 py-2 bg-emerald-700 rounded hover:bg-emerald-600">
|
||||
Negotiate New Contract
|
||||
</button>
|
||||
</form>
|
||||
<p class="text-sm text-gray-400 mt-2">
|
||||
Uses ship: <?php echo htmlspecialchars( $contractNegotiationShipSymbol ); ?>
|
||||
</p>
|
||||
<?php else : ?>
|
||||
<p class="text-sm text-gray-400">No ships available to negotiate a contract.</p>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
||||
<?php foreach ( $activeContracts as $contract ) : ?>
|
||||
@@ -701,6 +859,13 @@ foreach ( $miningShips as $miningShip ) {
|
||||
+
|
||||
<?php echo number_format( (int) ( $contract['terms']['payment']['onFulfilled'] ?? 0 ) ); ?>
|
||||
</p>
|
||||
<form method="post" class="mt-3">
|
||||
<input type="hidden" name="contract_action" value="fulfill_contract">
|
||||
<input type="hidden" name="contract_id" value="<?php echo htmlspecialchars( (string) ( $contract['id'] ?? '' ) ); ?>">
|
||||
<button type="submit" class="px-3 py-1 bg-emerald-700 rounded hover:bg-emerald-600">
|
||||
Fulfill Contract
|
||||
</button>
|
||||
</form>
|
||||
<?php if (! empty( $deliveries ) ) : ?>
|
||||
<p class="mt-2 font-bold">Deliveries:</p>
|
||||
<ul class="list-disc list-inside text-sm text-gray-300">
|
||||
@@ -792,6 +957,11 @@ foreach ( $miningShips as $miningShip ) {
|
||||
<input type="hidden" name="ship_symbol" value="<?php echo htmlspecialchars( $shipSymbol ); ?>">
|
||||
<button type="submit" class="px-3 py-1 bg-red-800 rounded hover:bg-red-700">Jettison This Ship's Cargo</button>
|
||||
</form>
|
||||
<form method="post" class="mt-2">
|
||||
<input type="hidden" name="ship_action" value="jettison_non_ore_ship_cargo">
|
||||
<input type="hidden" name="ship_symbol" value="<?php echo htmlspecialchars( $shipSymbol ); ?>">
|
||||
<button type="submit" class="px-3 py-1 bg-red-700 rounded hover:bg-red-600">Jettison Non-Ore Cargo</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
Reference in New Issue
Block a user