summaryrefslogtreecommitdiff
path: root/src/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'src/Controller')
-rw-r--r--src/Controller/Map.php43
-rw-r--r--src/Controller/Unit.php248
-rw-r--r--src/Controller/Village.php79
3 files changed, 367 insertions, 3 deletions
diff --git a/src/Controller/Map.php b/src/Controller/Map.php
new file mode 100644
index 0000000..59c1e4e
--- /dev/null
+++ b/src/Controller/Map.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Controller;
+
+use App\DB;
+use App\View;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class Map
+{
+ #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 1], methods: ['GET'])]
+ public function train(Request $request): Response
+ {
+ $x = $request->get('x');
+ $y = $request->get('y');
+ $range = $request->get('range');
+
+ $statement = DB::query(
+ 'select * from villages where x>=:x1 and x<=:x2 and y>=:y1 and y<=:y2',
+ [
+ 'x1' => $x - $range,
+ 'x2' => $x + $range,
+ 'y1' => $y - $range,
+ 'y2' => $y + $range,
+ ]
+ );
+ $villages = $statement->fetchAll();
+
+ $map = [];
+ foreach ($villages as $village) {
+ $map[$village['x']][$village['y']] = $village;
+ }
+
+ return new Response(View::render('map.twig', [
+ 'x' => $x,
+ 'y' => $y,
+ 'range' => $range,
+ 'map' => $map,
+ ]));
+ }
+}
diff --git a/src/Controller/Unit.php b/src/Controller/Unit.php
new file mode 100644
index 0000000..602c6e8
--- /dev/null
+++ b/src/Controller/Unit.php
@@ -0,0 +1,248 @@
+<?php
+
+namespace App\Controller;
+
+use App\DB;
+use App\Model\Unit as Model;
+use App\Model\Event;
+use App\Model\Village;
+use App\Router;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Annotation\Route;
+
+class Unit
+{
+ #[Route(path: '/village/{x}/{y}/unit/{type}/create', methods: ['POST'])]
+ public function train(Request $request): Response
+ {
+ $village = Village::getByCoordinates($request->get('x'), $request->get('y'));
+
+ /**@var Model $unit*/
+ $unit = new (Model::resolveType($request->get('type')))();
+ $unit->type = $request->get('type');
+ $unit->homeVillageId = $village->id;
+
+ $amount = intval($request->get('amount'));
+
+ if (! Village::canTrain($village, $unit, $amount)) {
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
+
+ // resources
+ foreach (Model::getResourceRequirements($unit, $amount) as $resourceType => $resourceValue) {
+ $village->{$resourceType} -= $resourceValue;
+ }
+ $village->updateResources();
+
+ // event
+ $event = new Event();
+ $event->type = 'TrainUnits';
+ $event->time = (new \DateTime())->add(\DateInterval::createFromDateString($unit->getBuildTime($amount) . ' seconds'));
+ $event->payload = json_encode([
+ 'type' => $request->get('type'),
+ 'amount' => $amount,
+ ]);
+
+ DB::query(
+ 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)',
+ ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id]
+ );
+
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
+
+ #[Route(path: '/village/{x}/{y}/unit/{type}/location/{lx}/{ly}/recall', methods: ['POST'])]
+ public function recall(Request $request): Response
+ {
+ $village = Village::getByCoordinates($request->get('x'), $request->get('y'));
+ $location = Village::getByCoordinates($request->get('lx'), $request->get('ly'));
+
+ /**@var Model $unit*/
+ $unit = new (Model::resolveType($request->get('type')))();
+
+ $amount = intval($request->get('amount'));
+ $amountUnits = DB::query(
+ 'select amount from village_units where home_village_id=:home and residence_village_id=:residence and type=:type',
+ ['home' => $village->id, 'residence' => $location->id, 'type' => $request->get('type')]
+ )->fetchColumn();
+
+ if ($amountUnits - $amount > 0) {
+ $statement = DB::query(
+ <<<SQL
+ update village_units set amount=:amount where home_village_id=:home and residence_village_id=:residence and type=:type
+ SQL,
+ ['amount' => $amountUnits - $amount, 'home' => $village->id, 'residence' => $location->id, 'type' => $request->get('type')]
+ );
+ } else if ($amountUnits - $amount === 0) {
+ DB::query(
+ <<<SQL
+ delete from village_units where home_village_id=:home and residence_village_id=:residence and type=:type
+ SQL,
+ ['home' => $village->id, 'residence' => $location->id, 'type' => $request->get('type')]
+ );
+ }
+
+ // event
+ $event = new Event();
+ $event->type = 'SendUnits';
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y))
+ . ' seconds'
+ )
+ );
+ $event->payload = json_encode([
+ 'type' => 'Recall',
+ 'unit' => $request->get('type'),
+ 'amount' => $amount,
+ 'source' => $location->id,
+ 'destination' => $village->id,
+ ]);
+
+ DB::query(
+ 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)',
+ ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id]
+ );
+
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
+
+ #[Route(path: '/village/{x}/{y}/unit/{type}/location/{lx}/{ly}/send-back', methods: ['POST'])]
+ public function sendBack(Request $request): Response
+ {
+ $village = Village::getByCoordinates($request->get('x'), $request->get('y'));
+ $location = Village::getByCoordinates($request->get('lx'), $request->get('ly'));
+
+ /**@var Model $unit*/
+ $unit = new (Model::resolveType($request->get('type')))();
+
+ $amount = intval($request->get('amount'));
+ $amountUnits = DB::query(
+ 'select amount from village_units where home_village_id=:home and residence_village_id=:residence and type=:type',
+ ['home' => $location->id, 'residence' => $village->id, 'type' => $request->get('type')]
+ )->fetchColumn();
+
+ if ($amountUnits - $amount > 0) {
+ $statement = DB::query(
+ <<<SQL
+ update village_units set amount=:amount where home_village_id=:home and residence_village_id=:residence and type=:type
+ SQL,
+ ['amount' => $amountUnits - $amount, 'home' => $location->id, 'residence' => $village->id, 'type' => $request->get('type')]
+ );
+ } else if ($amountUnits - $amount === 0) {
+ DB::query(
+ <<<SQL
+ delete from village_units where home_village_id=:home and residence_village_id=:residence and type=:type
+ SQL,
+ ['home' => $location->id, 'residence' => $village->id, 'type' => $request->get('type')]
+ );
+ }
+
+ // event
+ $event = new Event();
+ $event->type = 'SendUnits';
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y))
+ . ' seconds'
+ )
+ );
+ $event->payload = json_encode([
+ 'type' => 'SendBack',
+ 'unit' => $request->get('type'),
+ 'amount' => $amount,
+ 'source' => $village->id,
+ 'destination' => $location->id,
+ ]);
+
+ DB::query(
+ 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)',
+ ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id]
+ );
+
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
+
+ #[Route(path: '/village/{x}/{y}/send-units', methods: ['POST'])]
+ public function sendUnits(Request $request): Response
+ {
+ $village = Village::getByCoordinates($request->get('x'), $request->get('y'));
+ $destination = Village::get($request->get('village'));
+
+ /**@var Model $unit*/
+ $unit = new (Model::resolveType($request->get('unit')))();
+
+ $amount = intval($request->get('amount'));
+ $amountUnits = DB::query(
+ 'select amount from village_units where home_village_id=:home and residence_village_id=:home and type=:type',
+ ['home' => $village->id, 'type' => $request->get('unit')]
+ )->fetchColumn();
+
+ if ($amountUnits - $amount > 0) {
+ $statement = DB::query(
+ <<<SQL
+ update village_units set amount=:amount where home_village_id=:home and residence_village_id=:home and type=:type
+ SQL,
+ ['amount' => $amountUnits - $amount, 'home' => $village->id, 'type' => $request->get('unit')]
+ );
+ } else if ($amountUnits - $amount === 0) {
+ DB::query(
+ <<<SQL
+ delete from village_units where home_village_id=:home and residence_village_id=:home and type=:type
+ SQL,
+ ['home' => $village->id, 'type' => $request->get('unit')]
+ );
+ }
+
+ // event
+ $event = new Event();
+ $event->type = 'SendUnits';
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $destination->x, $destination->y))
+ . ' seconds'
+ )
+ );
+ $event->payload = json_encode([
+ 'type' => 'Borrow',
+ 'unit' => $request->get('unit'),
+ 'amount' => $amount,
+ 'source' => $village->id,
+ 'destination' => $destination->id,
+ ]);
+
+ DB::query(
+ 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)',
+ ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id]
+ );
+
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
+}
diff --git a/src/Controller/Village.php b/src/Controller/Village.php
index 3854d29..dfca298 100644
--- a/src/Controller/Village.php
+++ b/src/Controller/Village.php
@@ -3,9 +3,13 @@
namespace App\Controller;
use App\DB;
+use App\Model\Event\SendUnits;
+use App\Model\Event\TrainUnits;
use App\Model\Event\UpgradeBuilding;
use App\Model\Village as Model;
+use App\Router;
use App\View;
+use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@@ -26,8 +30,9 @@ class Village
public function show(Request $request): Response
{
$village = Model::getByCoordinates($request->get('x'), $request->get('y'));
+ $events = [];
- $results = DB::query(
+ $eventsBuilding = DB::query(
<<<SQL
select events.*, village_buildings.type as building from events
join village_buildings
@@ -36,8 +41,7 @@ class Village
SQL, ['id' => $village->id, 'type' => 'UpgradeBuilding']
)->fetchAll();
- $events = [];
- foreach ($results as $row) {
+ foreach ($eventsBuilding as $row) {
$events[$row['type']][] = [
'event' => DB::convertToModel(UpgradeBuilding::class, $row),
'data' => [
@@ -46,9 +50,78 @@ class Village
];
}
+ $eventsUnits = DB::query(
+ <<<SQL
+ select * from events
+ where type=:type and village_id=:id
+ SQL, ['type' => 'TrainUnits', 'id' => $village->id]
+ )->fetchAll();
+
+ foreach ($eventsUnits as $row) {
+ $events[$row['type']][] = [
+ 'event' => DB::convertToModel(TrainUnits::class, $row),
+ 'data' => json_decode($row['payload'], true),
+ ];
+ }
+
+ $eventsUnitsSend = DB::query(
+ <<<SQL
+ select * from events
+ where type=:type and (village_id=:id or (payload->>'destination')::bigint=:id)
+ SQL, ['type' => 'SendUnits', 'id' => $village->id]
+ )->fetchAll();
+
+ foreach ($eventsUnitsSend as $row) {
+ $events[$row['type']][] = [
+ 'event' => DB::convertToModel(SendUnits::class, $row),
+ 'data' => json_decode($row['payload'], true),
+ ];
+ }
+
return new Response(View::render('village.twig', [
'village' => $village,
'events' => $events,
+ 'villages' => DB::fetch(Model::class, "select * from villages where id!=:id", ['id' => $village->id]),
]));
}
+
+ #[Route(path: '/village/{x}/{y}/storage/config', methods: ['POST'])]
+ public function storageConfig(Request $request): Response
+ {
+ $village = Model::getByCoordinates($request->get('x'), $request->get('y'));
+
+ // calculate to max 100%
+ $wood = intval($request->get('wood'));
+ $clay = intval($request->get('clay'));
+ $iron = intval($request->get('iron'));
+ $food = intval($request->get('food'));
+ $total = $wood + $clay + $iron + $food;
+ $woodPercent = $wood / $total;
+ $clayPercent = $clay / $total;
+ $ironPercent = $iron / $total;
+ $foodPercent = $food / $total;
+
+ $wood = round($woodPercent * 100);
+ $clay = round($clayPercent * 100);
+ $iron = round($ironPercent * 100);
+ $food = round($foodPercent * 100);
+ $newTotal = $wood+$clay+$iron+$food;
+ $food += (100 - $newTotal);
+
+ DB::query(
+ <<<SQL
+ update village_storage_config
+ set wood=:wood, clay=:clay, iron=:iron, food=:food
+ where village_id=:id
+ SQL,
+ ['wood' => $wood, 'clay' => $clay, 'iron' => $iron, 'food' => $food, 'id' => $village->id]
+ );
+
+ return new RedirectResponse(
+ Router::generate(
+ 'village.show',
+ ['x' => $request->get('x'), 'y' => $request->get('y')]
+ )
+ );
+ }
}