Skip to content

Commit bd938b3

Browse files
committed
Give joining player starting region, game units and show welcome message
1 parent e5767b0 commit bd938b3

File tree

6 files changed

+191
-5
lines changed

6 files changed

+191
-5
lines changed

public/js/world/map-init.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@
4141
worldMap.setBombardments(playerBombardments);
4242
centerOnHomeRegion();
4343
console.log('World map loaded successfully with ' + worldRegions.length + ' regions!');
44+
45+
if (WorldApp.showWelcome) {
46+
var welcomeModal = document.getElementById('welcomeModal');
47+
if (welcomeModal) {
48+
welcomeModal.style.display = 'block';
49+
}
50+
}
4451
}).catch(function (error) {
4552
console.error('Failed to load world map:', error);
4653
showNotification('Failed to load world map. Please check the console for details.', 'error');
@@ -79,6 +86,20 @@
7986
}
8087
});
8188

89+
// ===== Welcome Modal =====
90+
var closeWelcomeModal = document.getElementById('closeWelcomeModal');
91+
var closeWelcomeBtn = document.getElementById('closeWelcomeBtn');
92+
if (closeWelcomeModal) {
93+
closeWelcomeModal.addEventListener('click', function () {
94+
document.getElementById('welcomeModal').style.display = 'none';
95+
});
96+
}
97+
if (closeWelcomeBtn) {
98+
closeWelcomeBtn.addEventListener('click', function () {
99+
document.getElementById('welcomeModal').style.display = 'none';
100+
});
101+
}
102+
82103
// ===== Unit Tooltip =====
83104
const unitTooltip = document.getElementById('unitTooltip');
84105
let tooltipRAF = null;

src/Controller/Game/WorldController.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
use FrankProjects\UltimateWarfare\Repository\PlayerRepository;
1313
use FrankProjects\UltimateWarfare\Repository\FleetRepository;
1414
use FrankProjects\UltimateWarfare\Repository\WorldRepository;
15+
use FrankProjects\UltimateWarfare\Service\PlayerSetupService;
1516
use FrankProjects\UltimateWarfare\Service\WorldGeneratorService;
1617
use Symfony\Component\HttpFoundation\JsonResponse;
1718
use Symfony\Component\HttpFoundation\Request;
19+
use Symfony\Component\HttpFoundation\RequestStack;
1820
use Symfony\Component\HttpFoundation\Response;
1921
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
2022

@@ -128,8 +130,12 @@ public function selectName(int $worldId): Response
128130
);
129131
}
130132

131-
public function start(Request $request, int $worldId): Response
132-
{
133+
public function start(
134+
Request $request,
135+
int $worldId,
136+
PlayerSetupService $playerSetupService,
137+
RequestStack $requestStack
138+
): Response {
133139
$name = (string) $request->request->get('name');
134140

135141
$user = $this->getGameUser();
@@ -152,7 +158,11 @@ public function start(Request $request, int $worldId): Response
152158

153159
$player = Player::create($user, $name, $world);
154160
$this->playerRepository->save($player);
155-
return $this->redirectToRoute('Game/Login', [], 302);
161+
162+
$playerSetupService->setupNewPlayer($player, $world);
163+
$requestStack->getSession()->set('playerId', $player->getId());
164+
165+
return $this->redirectToRoute('Game/WorldMap', ['welcome' => 1], 302);
156166
}
157167

158168
public function image(int $worldId): Response
@@ -170,7 +180,7 @@ public function image(int $worldId): Response
170180
return $response;
171181
}
172182

173-
public function worldMap(): Response
183+
public function worldMap(Request $request): Response
174184
{
175185
$player = $this->getPlayer();
176186
$world = $player->getWorld();
@@ -186,6 +196,7 @@ public function worldMap(): Response
186196
'player' => $player,
187197
'fleets' => $fleets,
188198
'bombardments' => $bombardments,
199+
'showWelcome' => $request->query->getBoolean('welcome'),
189200
]
190201
);
191202
}

src/Entity/Player.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Player
2626
private int $federationHierarchy = 0;
2727
private User $user;
2828
private World $world;
29-
private ?Federation $federation;
29+
private ?Federation $federation = null;
3030

3131
/** @var Collection<int, Report> */
3232
private Collection $reports;

src/Service/PlayerSetupService.php

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FrankProjects\UltimateWarfare\Service;
6+
7+
use FrankProjects\UltimateWarfare\Entity\Enum\GameUnitEnum;
8+
use FrankProjects\UltimateWarfare\Entity\Player;
9+
use FrankProjects\UltimateWarfare\Entity\World;
10+
use FrankProjects\UltimateWarfare\Entity\WorldRegion;
11+
use FrankProjects\UltimateWarfare\Entity\WorldRegionUnit;
12+
use FrankProjects\UltimateWarfare\Repository\WorldRegionRepository;
13+
use FrankProjects\UltimateWarfare\Repository\WorldRegionUnitRepository;
14+
use FrankProjects\UltimateWarfare\Util\DistanceCalculator;
15+
use RuntimeException;
16+
17+
final class PlayerSetupService
18+
{
19+
private WorldRegionRepository $worldRegionRepository;
20+
private WorldRegionUnitRepository $worldRegionUnitRepository;
21+
private DistanceCalculator $distanceCalculator;
22+
private NetWorthUpdaterService $netWorthUpdaterService;
23+
private IncomeUpdaterService $incomeUpdaterService;
24+
25+
public function __construct(
26+
WorldRegionRepository $worldRegionRepository,
27+
WorldRegionUnitRepository $worldRegionUnitRepository,
28+
DistanceCalculator $distanceCalculator,
29+
NetWorthUpdaterService $netWorthUpdaterService,
30+
IncomeUpdaterService $incomeUpdaterService
31+
) {
32+
$this->worldRegionRepository = $worldRegionRepository;
33+
$this->worldRegionUnitRepository = $worldRegionUnitRepository;
34+
$this->distanceCalculator = $distanceCalculator;
35+
$this->netWorthUpdaterService = $netWorthUpdaterService;
36+
$this->incomeUpdaterService = $incomeUpdaterService;
37+
}
38+
39+
public function setupNewPlayer(Player $player, World $world): void
40+
{
41+
$region = $this->findStartingRegion($world);
42+
43+
$region->setPlayer($player);
44+
$player->getWorldRegions()->add($region);
45+
$this->worldRegionRepository->save($region);
46+
47+
$this->createStartingUnits($region);
48+
49+
$this->netWorthUpdaterService->updateNetWorthForPlayer($player);
50+
$this->incomeUpdaterService->updateIncomeForPlayer($player);
51+
}
52+
53+
private function findStartingRegion(World $world): WorldRegion
54+
{
55+
$waterTypes = [
56+
WorldRegion::TYPE_DEEP_WATER,
57+
WorldRegion::TYPE_WATER,
58+
WorldRegion::TYPE_SHALLOW_WATER,
59+
];
60+
61+
$unownedRegions = $this->worldRegionRepository->findByWorldAndPlayer($world, null);
62+
63+
$landRegions = [];
64+
foreach ($unownedRegions as $region) {
65+
if (!in_array($region->getType(), $waterTypes, true)) {
66+
$landRegions[] = $region;
67+
}
68+
}
69+
70+
if ($landRegions === []) {
71+
throw new RuntimeException('No available land regions in this world!');
72+
}
73+
74+
$ownedRegions = [];
75+
foreach ($world->getWorldRegions() as $region) {
76+
if ($region->getPlayer() !== null) {
77+
$ownedRegions[] = $region;
78+
}
79+
}
80+
81+
if ($ownedRegions === []) {
82+
return $landRegions[0];
83+
}
84+
85+
$bestRegion = $landRegions[0];
86+
$bestMinDistance = 0;
87+
88+
foreach ($landRegions as $candidate) {
89+
$minDistance = PHP_INT_MAX;
90+
91+
foreach ($ownedRegions as $owned) {
92+
$distance = $this->distanceCalculator->calculateDistance(
93+
$candidate->getX(),
94+
$candidate->getY(),
95+
$owned->getX(),
96+
$owned->getY()
97+
);
98+
99+
if ($distance < $minDistance) {
100+
$minDistance = $distance;
101+
}
102+
}
103+
104+
if ($minDistance > $bestMinDistance) {
105+
$bestMinDistance = $minDistance;
106+
$bestRegion = $candidate;
107+
}
108+
}
109+
110+
return $bestRegion;
111+
}
112+
113+
private function createStartingUnits(WorldRegion $region): void
114+
{
115+
$startingUnits = [
116+
[GameUnitEnum::ECONOMIC_CENTER, 1000],
117+
[GameUnitEnum::FARM, 100],
118+
[GameUnitEnum::MINE, 100],
119+
[GameUnitEnum::WOODCUTTER, 250],
120+
[GameUnitEnum::SOLDIER, 10],
121+
];
122+
123+
foreach ($startingUnits as [$gameUnit, $amount]) {
124+
$worldRegionUnit = WorldRegionUnit::create($region, $gameUnit, $amount);
125+
$this->worldRegionUnitRepository->save($worldRegionUnit);
126+
}
127+
}
128+
}

templates/v2/game/world.html.twig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
imageBasePath: '{{ asset('images') }}',
5151
playerName: {{ player.name|json_encode|raw }},
5252
regionPrice: {{ player.regionPrice }},
53+
showWelcome: {{ showWelcome ? 'true' : 'false' }},
5354
worldMap: null,
5455
defaultTileClick: null,
5556
worldRegions: [

templates/v2/game/world/_modals.html.twig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,4 +453,29 @@
453453
<button type="button" id="closeWorldsBtn">Close</button>
454454
</div>
455455
</div>
456+
</div>
457+
458+
{# Welcome Modal #}
459+
<div id="welcomeModal" class="modal">
460+
<div class="modal-content">
461+
<div class="modal-header">
462+
<span class="modal-title">Welcome to Ultimate Warfare!</span>
463+
<span class="close" id="closeWelcomeModal">&times;</span>
464+
</div>
465+
<div class="modal-body">
466+
<p>Your empire has been established! You have been given a starting region with buildings and soldiers.</p>
467+
<p><strong>Getting started:</strong></p>
468+
<ul style="margin: 10px 0; padding-left: 20px; color: #f3e6c1;">
469+
<li>On the top left you can find the menu for all your actions</li>
470+
<li>Click on your region to build more units and expand</li>
471+
<li>Make sure you build your economy — farms, mines, and woodcutters keep your empire running</li>
472+
<li>Buy adjacent regions to grow your territory</li>
473+
<li>Train troops and fight for victory!</li>
474+
</ul>
475+
<p style="color: #ffa500;">Good luck, Commander!</p>
476+
</div>
477+
<div class="modal-footer">
478+
<button type="button" id="closeWelcomeBtn">Let's Begin!</button>
479+
</div>
480+
</div>
456481
</div>

0 commit comments

Comments
 (0)