summaryrefslogtreecommitdiff
path: root/src/Model/Event
diff options
context:
space:
mode:
Diffstat (limited to 'src/Model/Event')
-rw-r--r--src/Model/Event/SendResources.php150
-rw-r--r--src/Model/Event/SendResourcesMerchants.php154
2 files changed, 304 insertions, 0 deletions
diff --git a/src/Model/Event/SendResources.php b/src/Model/Event/SendResources.php
new file mode 100644
index 0000000..5c751fd
--- /dev/null
+++ b/src/Model/Event/SendResources.php
@@ -0,0 +1,150 @@
+<?php
+
+namespace App\Model\Event;
+
+use App\DB;
+use App\Model\Event;
+use App\Model\Unit;
+use App\Model\Unit\Merchant;
+use App\Model\Village;
+
+class SendResources extends BaseEvent
+{
+ public int $wood = 0;
+ public int $clay = 0;
+ public int $iron = 0;
+ public int $food = 0;
+
+ public int $source;
+ public int $destination;
+
+ public bool $isCanceled = false;
+
+ /**
+ * @return void
+ */
+ public function __invoke(): void
+ {
+ if ($this->isCanceled) {
+ // TODO: switch destination and source
+ // TODO: add resources back to "destination"
+ // TODO: add merchants back to "destination"
+ }
+
+ else {
+ // TODO: account for storage capacity
+ DB::query(
+ 'update villages set wood=wood+:wood, clay=clay+:clay, iron=iron+:iron, food=food+:food where id=:id',
+ [
+ 'wood' => $this->wood,
+ 'clay' => $this->clay,
+ 'iron' => $this->iron,
+ 'food' => $this->food,
+ 'id' => $this->destination,
+ ]
+ );
+
+ $source = Village::get($this->source);
+ $destination = Village::get($this->destination);
+
+ $event = new Event();
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Unit::getTravelTime(new Merchant(), Village::getDistance($source->x, $source->y, $destination->x, $destination->y))
+ . ' seconds'
+ )
+ );
+ $event->villageId = $this->source;
+
+ $sendResourcesMerchants = new SendResourcesMerchants();
+ $sendResourcesMerchants->dbInsert($this->id);
+
+
+ // TODO: add resources to destination
+ // (TODO: add foreign merchants to destination)?
+ // TODO: create SendUnits event with merchants back to source
+ }
+ }
+
+ public function dbInsert(): void
+ {
+ DB::query(
+ 'insert into events (time, village_id) VALUES (:time, :village_id)',
+ ['time' => $this->event->time->format('c'), 'village_id' => $this->event->villageId]
+ );
+
+ DB::query(
+ <<<SQL
+ insert into events_send_resources (event_id, wood, clay, iron, food, source, destination, is_canceled)
+ VALUES (:event_id, :wood, :clay, :iron, :food, :source, :destination, :is_canceled)
+ SQL,
+ [
+ 'event_id' => DB::$connection->lastInsertId(),
+ 'wood' => $this->wood,
+ 'clay' => $this->clay,
+ 'iron' => $this->iron,
+ 'food' => $this->food,
+ 'source' => $this->source, 'destination' => $this->destination,
+ 'is_canceled' => $this->isCanceled ?: 0, // @see https://www.php.net/manual/de/pdostatement.execute.php#126013
+ ]
+ );
+ $sendResourcesEventId = DB::$connection->lastInsertId();
+
+ $resourceCapabilities = Merchant::getResourceCapabilities($this->event->villageId);
+ $resourcesTotal = $this->wood + $this->clay + $this->iron + $this->food;
+ $necessaryMerchants = ceil($resourcesTotal / $resourceCapabilities);
+
+ $merchantsAccountedFor = 0;
+ while ($merchantsAccountedFor < $necessaryMerchants) {
+ $merchants = DB::fetch(
+ Merchant::class,
+ 'select * from village_units where type=:type and residence_village_id=:villageId and is_traveling=false',
+ ['type' => 'Merchant', 'villageId' => $this->source]
+ );
+ foreach ($merchants as $merchant) {
+ /**@type Merchant $merchant*/
+
+ $currentlyNecessaryMerchants = $necessaryMerchants - $merchantsAccountedFor;
+ $currentlyUseableMerchants = $currentlyNecessaryMerchants - $merchant->amount < 0 ? $currentlyNecessaryMerchants : $merchant->amount;
+ $merchantsAccountedFor += $currentlyUseableMerchants;
+
+ DB::query(
+ <<<SQL
+ insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id)
+ VALUES (:amount, :type, true, :home, :residence)
+ on conflict (type, home_village_id, residence_village_id, is_traveling)
+ do update set is_traveling=true
+ SQL,
+ [
+ 'amount' => $currentlyUseableMerchants,
+ 'type' => 'Merchant',
+ 'home' => $merchant->homeVillageId,
+ 'residence' => $merchant->residenceVillageId,
+ ]
+ );
+ DB::query('update village_units set amount=amount-:amount where id=:unitId', ['amount' => $necessaryMerchants, 'unitId' => $merchant->id]);
+
+ DB::query(
+ <<<SQL
+ insert into events_send_resources_merchants (event_id, unit_id, amount)
+ VALUES (:event_id, :unit_id, :amount)
+ SQL,
+ [
+ 'event_id' => $sendResourcesEventId,
+ 'unit_id' => $merchant->id,
+ 'amount' => $necessaryMerchants,
+ ]
+ );
+ }
+ }
+
+ // TODO: remove resources from source
+ }
+
+ public function dbDelete(): void
+ {
+ DB::query('delete from events where id=:id', ['id' => $this->eventId]);
+ DB::query('delete from events_send_resources where id=:id', ['id' => $this->id]);
+ #DB::query('delete from events_send_resources_merchants where event_id=:id', ['id' => $this->id]);
+ }
+}
diff --git a/src/Model/Event/SendResourcesMerchants.php b/src/Model/Event/SendResourcesMerchants.php
new file mode 100644
index 0000000..a50b2bc
--- /dev/null
+++ b/src/Model/Event/SendResourcesMerchants.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace App\Model\Event;
+
+use App\DB;
+use App\Model\Event;
+use App\Model\Unit;
+use App\Model\Unit\Merchant;
+use App\Model\Village;
+
+class SendResourcesMerchants extends BaseEvent
+{
+ public int $wood = 0;
+ public int $clay = 0;
+ public int $iron = 0;
+ public int $food = 0;
+
+ public int $source;
+ public int $destination;
+
+ public bool $isCanceled = false;
+
+ /**
+ * @return void
+ */
+ public function __invoke(): void
+ {
+ if ($this->isCanceled) {
+ // TODO: switch destination and source
+ // TODO: add resources back to "destination"
+ // TODO: add merchants back to "destination"
+ }
+
+ else {
+ // TODO: account for storage capacity
+ DB::query(
+ 'update villages set wood=wood+:wood, clay=clay+:clay, iron=iron+:iron, food=food+:food where id=:id',
+ [
+ 'wood' => $this->wood,
+ 'clay' => $this->clay,
+ 'iron' => $this->iron,
+ 'food' => $this->food,
+ 'id' => $this->destination,
+ ]
+ );
+
+ // TODO: foreach send_resources_merchants
+ $source = Village::get($this->source);
+ $destination = Village::get($this->destination);
+ $event = new Event();
+ $event->time = (new \DateTime())->add(
+ \DateInterval::createFromDateString(
+ Unit::getTravelTime(new Merchant(), Village::getDistance($source->x, $source->y, $destination->x, $destination->y))
+ . ' seconds'
+ )
+ );
+ $event->villageId = $this->source;
+ $sendUnitsEvent = new SendUnits();
+ $sendUnitsEvent->event = $event;
+ $sendUnitsEvent->type = 'SendBack';
+ $sendUnitsEvent->unit = 'Merchant';
+ $sendUnitsEvent->amount = $amount;
+ $sendUnitsEvent->source = $village->id;
+ $sendUnitsEvent->destination = $destination->id;
+ $sendUnitsEvent->dbInsert();
+
+ // TODO: add resources to destination
+ // (TODO: add foreign merchants to destination)?
+ // TODO: create SendUnits event with merchants back to source
+ }
+ }
+
+ public function dbInsert(int $previouId): void
+ {
+ DB::query(
+ 'update events_send_resources_merchants set event_id=:new_id where event_id=:old_id',
+ ['old_id' => $previouId, 'new_id' => $this->id]
+ );
+
+ /*
+ DB::query(
+ 'insert into events (time, village_id) VALUES (:time, :village_id)',
+ ['time' => $this->event->time->format('c'), 'village_id' => $this->event->villageId]
+ );
+
+ DB::query(
+ <<<SQL
+ insert into events_send_resources (event_id, wood, clay, iron, food, source, destination, is_canceled)
+ VALUES (:event_id, :wood, :clay, :iron, :food, :source, :destination, :is_canceled)
+ SQL,
+ [
+ 'event_id' => DB::$connection->lastInsertId(),
+ 'wood' => $this->wood,
+ 'clay' => $this->clay,
+ 'iron' => $this->iron,
+ 'food' => $this->food,
+ 'source' => $this->source, 'destination' => $this->destination,
+ 'is_canceled' => $this->isCanceled ?: 0, // @see https://www.php.net/manual/de/pdostatement.execute.php#126013
+ ]
+ );
+ $sendResourcesEventId = DB::$connection->lastInsertId();
+
+ $resourceCapabilities = Merchant::getResourceCapabilities($this->event->villageId);
+ $resourcesTotal = $this->wood + $this->clay + $this->iron + $this->food;
+ $necessaryMerchants = ceil($resourcesTotal / $resourceCapabilities);
+
+ $merchantsAccountedFor = 0;
+ while ($merchantsAccountedFor < $necessaryMerchants) {
+ $merchants = DB::fetch(
+ Merchant::class,
+ 'select * from village_units where type=:type and residence_village_id=:villageId and is_traveling=false',
+ ['type' => 'Merchant', 'villageId' => $this->source]
+ );
+ foreach ($merchants as $merchant) {
+ $currentlyNecessaryMerchants = $necessaryMerchants - $merchantsAccountedFor;
+ $currentlyUseableMerchants = $currentlyNecessaryMerchants - $merchant->amount < 0 ? $currentlyNecessaryMerchants : $merchant->amount;
+ $merchantsAccountedFor += $currentlyUseableMerchants;
+
+ DB::query(
+ <<<SQL
+ insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id)
+ VALUES (:amount, :type, true, :home, :residence)
+ on conflict (type, home_village_id, residence_village_id, is_traveling)
+ do update set is_traveling=true
+ SQL,
+ [
+ 'amount' => $currentlyUseableMerchants,
+ 'type' => 'Merchant',
+ 'home' => $merchant->homeVillageId,
+ 'residence' => $merchant->residenceVillageId,
+ ]
+ );
+ DB::query('update village_units set amount=amount-:amount where id=:unitId', ['amount' => $necessaryMerchants, 'unitId' => $merchant->id]);
+
+ DB::query(
+ <<<SQL
+ insert into events_send_resources_merchants (event_id, unit_id, amount)
+ VALUES (:event_id, :unit_id, :amount)
+ SQL,
+ [
+ 'event_id' => $sendResourcesEventId,
+ 'unit_id' => $merchant->id,
+ 'amount' => $necessaryMerchants,
+ ]
+ );
+ }
+ }*/
+ }
+
+ public function dbDelete(): void
+ {
+ DB::query('delete from events_send_resources_merchants where event_id=:id', ['id' => $this->id]);
+ }
+}