summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2024-01-15 13:43:05 +0100
committerDaniel Weipert <git@mail.dweipert.de>2024-01-15 13:43:05 +0100
commit254eb4a9959e4c281fdeb47378a654de978cb1e4 (patch)
treec2c4bb19e2c16cddc82988f50de79c718f381b22
parent09caff2b2a06d1f8ac8203567035a21c612165f9 (diff)
events and satisfaction
-rw-r--r--.env.example1
-rw-r--r--src/EventRunner.php46
-rw-r--r--src/Model/Building/Farm.php8
-rw-r--r--src/Model/Village.php11
-rw-r--r--src/gemini/Controller/Unit.php120
-rw-r--r--src/gemini/Gemini.php24
-rw-r--r--src/http/Controller/Event.php3
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(