diff options
| author | Daniel Weipert <git@mail.dweipert.de> | 2024-01-15 13:43:05 +0100 | 
|---|---|---|
| committer | Daniel Weipert <git@mail.dweipert.de> | 2024-01-15 13:43:05 +0100 | 
| commit | 254eb4a9959e4c281fdeb47378a654de978cb1e4 (patch) | |
| tree | c2c4bb19e2c16cddc82988f50de79c718f381b22 /src | |
| parent | 09caff2b2a06d1f8ac8203567035a21c612165f9 (diff) | |
events and satisfaction
Diffstat (limited to 'src')
| -rw-r--r-- | src/EventRunner.php | 46 | ||||
| -rw-r--r-- | src/Model/Building/Farm.php | 8 | ||||
| -rw-r--r-- | src/Model/Village.php | 11 | ||||
| -rw-r--r-- | src/gemini/Controller/Unit.php | 120 | ||||
| -rw-r--r-- | src/gemini/Gemini.php | 24 | ||||
| -rw-r--r-- | src/http/Controller/Event.php | 3 | 
6 files changed, 198 insertions, 14 deletions
| diff --git a/src/EventRunner.php b/src/EventRunner.php index e4bdb40..439cca5 100644 --- a/src/EventRunner.php +++ b/src/EventRunner.php @@ -121,7 +121,7 @@ class EventRunner      $tickMultiplier = $diff->i + 60*$diff->h + 60*24*$diff->d;      if ($tickMultiplier > 0) { -      $villages = DB::fetch(Village::class, 'select id,wood,clay,iron,food from villages'); +      $villages = DB::fetch(Village::class, 'select id,wood,clay,iron,food,satisfaction from villages');        foreach ($villages as $village) {          /**@var Village $village*/ @@ -142,23 +142,61 @@ class EventRunner            }          } +        $foodIncrementor = 0; +          $resources = [];          foreach ($resourceGenerators as $generator) { +          /**@type ResourceGenerator $generator*/ + +          if ($generator->type === 'Farm') { +            $foodIncrementor = $generator->getResourceIncrementor(); +          } +            $village->{$generator->resourceType} = min( -            $village->{$generator->resourceType} + ($generator->getResourceIncrementor() * $tickMultiplier), +            max( +              $village->{$generator->resourceType} + ($generator->getResourceIncrementor() * $tickMultiplier), +              0 +            ),              $storage->getResourceCapacity($generator->resourceType)            );          } +        $populationDemand = Village::getPopulationDemand($village->id); +        if ( +          $foodIncrementor < 0 && +          (abs($village->food / $foodIncrementor) < $_ENV['SATISFACTION_FOOD_THRESHOLD'] || $village->food < $populationDemand) +        ) { +          $village->satisfaction = min(max($village->satisfaction - (1 * $tickMultiplier), 0), 100); +        } else if ($foodIncrementor > 0) { +          $village->satisfaction = min(max($village->satisfaction + (1 * $tickMultiplier), 0), 100); +        } +          DB::query( -          'update villages set wood=:wood, clay=:clay, iron=:iron, food=:food where id=:id', -          ['wood' => $village->wood, 'clay' => $village->clay, 'iron' => $village->iron, 'food' => $village->food, 'id' => $village->id] +          'update villages set wood=:wood, clay=:clay, iron=:iron, food=:food, satisfaction=:satisfaction where id=:id', +          [ +            'wood' => $village->wood, 'clay' => $village->clay, 'iron' => $village->iron, 'food' => $village->food, +            'satisfaction' => $village->satisfaction, +            'id' => $village->id, +          ]          );        }        DB::query('delete from system where key=:key', ['key' => 'last_resource_tick']);        $lastResourceTickMinute = (new \DateTime((new \DateTime())->format('Y-m-d H:i')))->format('c');        DB::query('insert into system (key,value) VALUES (:key,:value)', ['key' => 'last_resource_tick', 'value' => json_encode($lastResourceTickMinute)]); + + +      // Satisfaction + +      // TODO: < 75 => resource increment reduction +      // TODO: < 50 => support units go home +      // TODO: < 30 => home units walk away +      //       record which units +      //       => after X units => create new NPC village +      // +      // TODO: > 50 home units come back +      //       > 75 resource increment normal +      //       > 95 resource increment higher?      }    }  } diff --git a/src/Model/Building/Farm.php b/src/Model/Building/Farm.php index 1a69c89..7957dca 100644 --- a/src/Model/Building/Farm.php +++ b/src/Model/Building/Farm.php @@ -2,7 +2,6 @@  namespace App\Model\Building; -use App\Model\Unit;  use App\Model\Village;  class Farm extends ResourceGenerator @@ -26,12 +25,7 @@ class Farm extends ResourceGenerator    public function getResourceIncrementor(): int    { -    $populationDemand = array_reduce( -      Village::getUnits($this->villageId, Village::FETCH_UNIT_RESIDENCE, Village::RETURN_UNIT_EXISTING), -      function ($carry, Unit $unit) { -        return $carry + $unit->getPopulationDemand(); -      } -    ); +    $populationDemand = Village::getPopulationDemand($this->villageId);      return parent::getResourceIncrementor() - $populationDemand;    } diff --git a/src/Model/Village.php b/src/Model/Village.php index 03a57b7..ff0b7e8 100644 --- a/src/Model/Village.php +++ b/src/Model/Village.php @@ -143,6 +143,17 @@ class Village      return $results[0] ?? null;    } +  public static function getPopulationDemand(int $villageId): int +  { +    return array_reduce( +      Village::getUnits($villageId, Village::FETCH_UNIT_RESIDENCE, Village::RETURN_UNIT_EXISTING), +      function ($carry, Unit $unit) { +        return $carry + $unit->getPopulationDemand(); +      }, +      0 +    ); +  } +    public const FETCH_UNIT_HOME_AT_HOME = 1;    public const FETCH_UNIT_HOME_AT_SUPPORT = 2;    public const FETCH_UNIT_SUPPORT_AT_HOME = 3; diff --git a/src/gemini/Controller/Unit.php b/src/gemini/Controller/Unit.php index 9aa6968..e1f5792 100644 --- a/src/gemini/Controller/Unit.php +++ b/src/gemini/Controller/Unit.php @@ -151,4 +151,124 @@ class Unit        meta: "/village/{$village->x}/{$village->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('input')); +    if (empty($amount)) { +      return new Response(statusCode: Status::INPUT, meta: '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->time = (new \DateTime())->add( +      \DateInterval::createFromDateString( +        Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y)) +        . ' seconds' +      ) +    ); +    $event->villageId = $village->id; +    $sendUnitsEvent = new SendUnits(); +    $sendUnitsEvent->event = $event; +    $sendUnitsEvent->type = 'Recall'; +    $sendUnitsEvent->unit = $request->get('type'); +    $sendUnitsEvent->amount = $amount; +    $sendUnitsEvent->source = $location->id; +    $sendUnitsEvent->destination = $village->id; +    $sendUnitsEvent->dbInsert(); + + +    return new Response( +      statusCode: Status::REDIRECT_TEMPORARY, +      meta: "/village/{$village->x}/{$village->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('input')); +    if (empty($amount)) { +      return new Response(statusCode: Status::INPUT, meta: '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->time = (new \DateTime())->add( +      \DateInterval::createFromDateString( +        Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y)) +        . ' seconds' +      ) +    ); +    $event->villageId = $village->id; +    $sendUnitsEvent = new SendUnits(); +    $sendUnitsEvent->event = $event; +    $sendUnitsEvent->type = 'SendBack'; +    $sendUnitsEvent->unit = $request->get('type'); +    $sendUnitsEvent->amount = $amount; +    $sendUnitsEvent->source = $village->id; +    $sendUnitsEvent->destination = $location->id; +    $sendUnitsEvent->dbInsert(); + + +    return new Response( +      statusCode: Status::REDIRECT_TEMPORARY, +      meta: "/village/{$village->x}/{$village->y}" +    ); +  }  } diff --git a/src/gemini/Gemini.php b/src/gemini/Gemini.php index 23915d0..4567958 100644 --- a/src/gemini/Gemini.php +++ b/src/gemini/Gemini.php @@ -104,6 +104,30 @@ class Gemini          $response = $unitController->train($request);        } +      else if (preg_match('@village/(\d+)/(\d+)/unit/(\w+)/location/(\d+)/(\d+)/recall@', $request->getPath(), $routeMatch)) { +        $request +          ->set('x', $routeMatch[1]) +          ->set('y', $routeMatch[2]) +          ->set('type', $routeMatch[3]) +          ->set('lx', $routeMatch[4]) +          ->set('ly', $routeMatch[5]); + +        $unitController = new Unit(); +        $response = $unitController->recall($request); +      } + +      else if (preg_match('@village/(\d+)/(\d+)/unit/(\w+)/location/(\d+)/(\d+)/send-back@', $request->getPath(), $routeMatch)) { +        $request +          ->set('x', $routeMatch[1]) +          ->set('y', $routeMatch[2]) +          ->set('type', $routeMatch[3]) +          ->set('lx', $routeMatch[4]) +          ->set('ly', $routeMatch[5]); + +        $unitController = new Unit(); +        $response = $unitController->sendBack($request); +      } +        else if (preg_match('@village/(\d+)/(\d+)/send-units@', $request->getPath(), $routeMatch)) {          $request            ->set('x', $routeMatch[1]) diff --git a/src/http/Controller/Event.php b/src/http/Controller/Event.php index 46e4c22..8b9b92a 100644 --- a/src/http/Controller/Event.php +++ b/src/http/Controller/Event.php @@ -59,9 +59,6 @@ class Event        $sendResourcesEvent->cancel();      } -    else { -      DB::query('delete from event where id=:id', ['id' => $request->get('id')]); -    }      return new RedirectResponse(        Router::generate( | 
