public function getActiveSpyDetected() { $ownSpies = $this->ownSpies()->getResults(); $arrayActiveReports = []; foreach ($ownSpies as $oneOwnSpy) { $shForThatSpy = SpyHistory::where('spy_id', $oneOwnSpy->id)->where('detect', 1)->get()->all(); foreach ($shForThatSpy as $oneSpyHistory) { if (!empty($oneSpyHistory)) { $squad = Squad::find($oneSpyHistory->squads_id); if (!empty($squad)) { if ($squad->battle_at > \Carbon\Carbon::now()) { $arrayActiveReports[] = [$oneOwnSpy, $squad]; } } } } } return $arrayActiveReports; }
/** * Штурмовать вражеский замок. * * @throws GameException * @throws \Exception */ public function assault() { $this->continueOrException(); $now = Carbon::now(); // Пересчет ресурсов $this->goal->calcCastleIncreaseResources(); // Расчет победителя сражения... $aArmy = $this->army; // атакующая армия $dArmy = $this->goal->armyOrCreate(); // защищающиеся армия Log::info('---------------------------------------------------------------------------------------------------'); Log::info("({$now}) Штурм замка id={$this->goal->id} '{$this->goal->name}' отрядом id={$this->id} '{$this->name}'..."); // xa, ya - кол-во и уровень атакующих. // xd, yd, zd - кол-во, уровень войск и уровень фортификации защищающихся. $xa = $this->size; $ya = $aArmy->level; $xd = $dArmy->size; $yd = $dArmy->level; $zd = $this->goal->fortification()->level; // Уровень фортификации, пока остается 0; Log::info("Сила атак. отряда = {$xa} и уровень = {$ya}"); Log::info("Сила защ. армии = {$xd}, уровень = {$yd} и фортифмкация = {$zd}"); // Участие шпионов во всем этом замесе // Получаем шпионов замка $spiesHg = $this->goal->ownSpies()->getResults(); //Log::info($spiesHg->toJson()); foreach ($spiesHg as $oneSpiesHg) { // С вероятностью 50/50 шпион погибает $rand = mt_rand(0, 1); if ($rand) { $oneSpiesHg->killMe(); } } // Ищем шпиона, который проглядел нападение (если есть) $sph = SpyHistory::where('squads_id', $this->id)->where('detect', 0)->get()->all(); foreach ($sph as $oneSph) { $spy = Spy::find($oneSph->spy_id); if (!empty($spy)) { $spy->killMe(); } } if ($xd == 0) { // Защитников нет, досрочная победа атакующих... DB::beginTransaction(); try { Log::info("Досрочно победили атакующие. Осталось в живых = {$xa}"); $loots = $this->rob(); // начать грабить. $this->comeback(); // вернуться назад в замок. // Запуск события, что отряд либо победил, либо был разгроблен. event(new SquadAssaulted($this, ['status' => 'win', 'loots' => $loots])); } catch (\Exception $ex) { DB::rollBack(); throw $ex; // next... } DB::commit(); return; } // Рассчет мощностей каждой из армий и их разницы... $rand = rand(0 - $xd / 5, $xa / 5); // рандом при расчете мощностей $diff = intval($xa * $ya - $xd * $yd * (1 + $zd / 100) + $rand); Log::info("Мощность атакующих = " . $xa * $ya . ". Мощность защитников = " . $xd * $yd * (1 + $zd / 100)); Log::info("Первый рандом = {$rand}. Разница мощностей с рандомом = {$diff}"); $rand = rand(0, 150) / 1000; // рандом при вычилсение сил победителей Log::info("Второй рандом = {$rand}"); // Расчет сил победителей и награды, в случаи победы атакующих... DB::beginTransaction(); try { $loots = []; if ($diff > 0) { // Атакующий отряд победил... $left = $diff / $ya * (1 + $rand); $left = intval($left > $xa ? $xa : $left); // Оставить только выживших... $this->update(['size' => $left]); $dArmy->reset(); Log::info("Победили атакующие. Осталось в живых = {$left}"); $loots = $this->rob(); // начать грабить. $this->comeback(); // вернуться назад в замок. $status = 'win'; } elseif ($diff < 0) { // Защитники победили... $left = $diff / $yd * (1 + $zd / 100) * (1 + $rand); $left = abs(intval($left > $xd ? $xd : $left)); // Оставить только выживших... $this->delete(); $dArmy->update(['size' => $left]); Log::info("Победили защитники. Осталось в живых = {$left}"); $status = 'def'; } else { // Ничья. $this->delete(); $dArmy->reset(); Log::info("Ничья. Все умерли."); $status = 'draw'; } // Запуск события, что отряд либо победил, либо был разгроблен. event(new SquadAssaulted($this, ['status' => $status, 'loots' => $loots])); } catch (\Exception $ex) { DB::rollBack(); throw $ex; // next... } DB::commit(); }
/** * Совершить поход на вражеский замок. * * @param {string} $name имя отряда * @param {int} $count количество в отряде * @param Castle $goal замок * @return Squad * @throws GameException * @throws \Exception */ public function crusade($name, $count, Castle $goal) { if ($goal->id === $this->id) { throw new GameException('Нельзя отправить отряд на собственный замок.'); } // Есть ли возможность создать отряд? $diff = $this->size - $count; if ($count <= 0 || $diff < 0) { throw new GameException('Нельзя создать отряд для похода. Не хватает храбрых воинов.'); } $squad = new Squad(['name' => $name, 'size' => $count]); $squad->crusade_at = Carbon::now(); // Начало похода // Время на поход... $minutes = Location::howMuchTime($this->castle, $goal); $squad->battle_at = Carbon::now()->addMinutes($minutes); // Конец похода DB::beginTransaction(); try { $this->update(['size' => $diff]); $squad->goal()->associate($goal); // Вражеский замок // Сохранить отряд... $this->squads()->save($squad); // Так как отряд сохранен, внедряем сюда шпионов // Получаем их всех $enemySpies = $this->castle()->first()->enemySpies()->getResults(); foreach ($enemySpies as $oneSpy) { $spyHistory = new SpyHistory(); $spyHistory->spy_id = $oneSpy->id; $spyHistory->squads_id = $squad->id; // Пытаемся обнаружить атаку $spyHistory->detect = $oneSpy->canDetectedAttack($this->level, $squad->size) ? true : false; $spyHistory->save(); } // $now = Carbon::now(); Log::info('---------------------------------------------------------------------------------------------------'); Log::info("({$now}) Создан новый отряд - id={$squad->id} '{$squad->name}' ({$squad->size} в)..."); Log::info("Поход на вражеский замок - id={$goal->id} '{$goal->name}"); Log::info("Начало похода {$squad->crusade_at}, сражение состоится {$squad->battle_at}"); } catch (\Exception $ex) { DB::rollBack(); throw $ex; // next... } DB::commit(); return $squad; }