<?php
namespace App\Controller;
use App\Entity\Area;
use App\Entity\Location\Town;
use App\Entity\User;
use App\Form\Type\SignupType;
use App\Model\AreaService;
use App\Model\GameService;
use App\Model\Helper\AccountHelper;
use App\Model\HeroService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/area")
*/
class AreaController extends AbstractController
{
/**
* @var AreaService
*/
private $areaService;
/**
* @var GameService
*/
private $gameService;
/**
* @var AccountHelper
*/
private $accountHelper;
/**
* @var HeroService
*/
private $heroService;
public function __construct(AreaService $areaService, GameService $gameService, AccountHelper $accountHelper, HeroService $heroService)
{
$this->areaService = $areaService;
$this->gameService = $gameService;
$this->accountHelper = $accountHelper;
$this->heroService = $heroService;
}
/**
* @Route("", name="area_index")
*
* @return Response
*/
public function index(): Response
{
$areas = $this->areaService->getActiveAreas();
unset($areas['c1outbreakinvasion2']);
return $this->render('area/index.html.twig', [
'areas' => $areas,
'page' => 'areas',
]);
}
/**
* @Route("/{areaId}/news", name="area_news", requirements={"area"="\d+"})
*
* @param int $areaId
*
* @return Response
*/
public function news(int $areaId): Response
{
$area = $this->areaService->getArea($areaId);
$this->gameService->setArea($area);
return $this->render('area/news.html.twig', [
'area' => $area,
'page' => 'areas',
'news' => $this->gameService->fairgroundService->getNews(),
]);
}
/**
* @Route("/{areaId}/map-preview", name="area_map_preview", requirements={"areaId"="\d+"})
*
* @param int $areaId
*
* @return Response
*/
public function mapPreview(int $areaId): Response
{
$area = $this->areaService->getArea($areaId);
$this->gameService->setArea($area);
$acres = $this->gameService->locationService->getAcres();
$government = $this->gameService->locationService->getGovernmentLocations();
return $this->render('area/map_preview.html.twig', [
'area' => $area,
'govLocations' => $government,
'acres' => $acres,
'page' => 'areas',
]);
}
/**
* @Route("/{areaId}/info", name="area_info", requirements={"areaId"="\d+"})
*
* @param int $areaId
*
* @return Response
*/
public function info(int $areaId): Response
{
$area = $this->areaService->getArea($areaId);
$this->gameService->setArea($area);
return $this->render('area/info.html.twig', [
'area' => $area,
'page' => 'areas',
'towns' => $this->gameService->townService->findTowns(),
]);
}
/**
* @Route("/{areaId}/signup", name="area_signup", requirements={"areaId"="\d+"})
*
* @param int $areaId
* @param Request $request
*
* @return Response
*/
public function signup(int $areaId, Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
if (!$user instanceof User) {
return $this->redirectToRoute('area_index');
}
// If user already is in the area, redirect to game
$area = $this->areaService->getArea($areaId);
if ($user->isInArea($area)) {
return $this->redirectToRoute('game_index');
}
return $this->createSignupForm($areaId, $request, false);
}
/**
* @Route("/{areaId}/signup-premium", name="area_signup_premium", requirements={"areaId"="\d+"})
*
* @param int $areaId
* @param Request $request
*
* @return Response
*/
public function signupPremium(int $areaId, Request $request): Response
{
// If user already has an area, redirect to game
/** @var User $user */
$user = $this->getUser();
if (!$user instanceof User) {
return $this->redirectToRoute('area_index');
}
$area = $this->areaService->getArea($areaId);
if ($user->isInArea($area)) {
return $this->redirectToRoute('game_index');
}
return $this->createSignupForm($areaId, $request, true);
}
/**
* @param int $areaId
* @param Request $request
* @param bool $isPremium
*
* @return Response
*/
private function createSignupForm(int $areaId, Request $request, bool $isPremium = false): Response
{
/** @var User $user */
$user = $this->getUser();
$area = $this->areaService->getArea($areaId);
$this->gameService->setArea($area);
// Get heroes available for picking
$defaultHeroes = $this->heroService->getDefaultHeroes();
$customHeroes= [];
if ($isPremium) {
$customHeroes = $this->heroService->getCustomHeroes($user);
}
// Create form
$form = $this->createForm(SignupType::class, null, [
'heroes' => count($customHeroes) > 0 ? ['Custom heroes' => $customHeroes, 'Base heroes' => $defaultHeroes] : $defaultHeroes,
'premium' => $isPremium,
'area' => $area,
'user' => $user,
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid() && $user instanceof User && $area->isActive()) {
$formData = $form->getData();
$formData['townName'] = trim($formData['townName']);
if (is_numeric($formData['townName'])) {
$form->addError(new FormError("Invalid town name"));
}
// Check if town name is already in use or reserved
$existingTown = $this->gameService->townService->getTownByName($formData['townName']);
if ($existingTown instanceof Town || $this->accountHelper->isReservedTownName($formData['townName'])) {
$form->addError(new FormError("Town name is not available"));
}
// Check if mayor name is already in use
$existingTown = $this->gameService->townService->getTownByName($formData['mayorName']);
if ($existingTown instanceof Town) {
$form->addError(new FormError("Mayor name is not available"));
}
// Check that area has room
if ($area->getTowns() >= $area->getPlayers()) {
$form->addError(new FormError("The area is full, contact us for more information!"));
}
// Check if round has ended
if ($area->getSettings()->turn >= $area->getSettings()->end_turn) {
$form->addError(new FormError("This round has ended a new one will start soon."));
}
// If premium check that account has credit
if ($isPremium && $user->getPremium() == 0) {
$form->addError(new FormError("You don't have enough credits."));
}
$extraWildcard = false;
if ($user->getExtraWildcard() > 0 && $formData['extraWildcard']) {
$extraWildcard = true;
}
if ($form->isValid()) {
$this->accountHelper->signup($area, $user, $formData['hero'], $formData, $extraWildcard, $isPremium);
$this->gameService->setArea($area);
return $this->redirectToRoute('game_index');
}
}
return $this->render('area/signup.html.twig', [
'errors' => $form->getErrors(),
'form' => $form->createView(),
'area' => $this->areaService->getArea($areaId),
'mod' => min($area->getSettings()->turn > 24 ? round(($area->getSettings()->turn / 250) + 1) : 1, 5),
'isPremium' => $isPremium,
'defaultHeroes' => $defaultHeroes,
'townTypes' => $area->getType() === Area::TYPE_PVE ? Town::TOWN_TYPES_PVE : Town::TOWN_TYPES_PVP,
'page' => 'areas',
]);
}
}