diff options
Diffstat (limited to 'src/Model/Event')
-rw-r--r-- | src/Model/Event/SendResources.php | 150 | ||||
-rw-r--r-- | src/Model/Event/SendResourcesMerchants.php | 154 |
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]); + } +} |