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 | |
parent | 09caff2b2a06d1f8ac8203567035a21c612165f9 (diff) |
events and satisfaction
-rw-r--r-- | .env.example | 1 | ||||
-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 |
7 files changed, 199 insertions, 14 deletions
diff --git a/.env.example b/.env.example index 9281323..ffe11a1 100644 --- a/.env.example +++ b/.env.example @@ -12,3 +12,4 @@ BASE_UNIT_TRAVEL_TIME_FACTOR=60 BASE_UNIT_RESOURCE_REQUIREMENT_FACTOR=64 BASE_RESOURCE_GENERATION_FACTOR=128 BASE_STORAGE_CAPACITY_FACTOR=2048 +SATISFACTION_FOOD_THRESHOLD=10 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( |