isCanceled) { // add resources back to "destination" 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->source, ] ); // add mailCarriers back to "destination" $meta = DB::query('select amount, unit_id from events_meta_send_resources_carriers where event_id=:eventId', ['eventId' => $this->id])->fetchAll(); foreach ($meta as $m) { $unit = DB::query('select * from village_units where id=:unitId', ['unitId' => $m['unit_id']])->fetch(); DB::query('update village_units set amount=amount+:amount where id=:unitId', ['amount' => $m['amount'], 'unitId' => $unit['id']]); DB::query( 'update village_units set amount=amount-:amount where type=:unitType and home_village_id=:homeVillageId and residence_village_id=:residenceVillageId and is_traveling=true', [ 'amount' => $m['amount'], 'unitType' => $unit['type'], 'homeVillageId' => $unit['home_village_id'], 'residenceVillageId' => $unit['residence_village_id'], ] ); } } else { // add resources to destination // 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, ] ); // create SendResourcesCarriers event with mailCarriers back to source $source = Village::get($this->destination); $destination = Village::get($this->source); $event = new Event(); $event->time = (new \DateTime())->add( \DateInterval::createFromDateString( Unit::getTravelTime(new MailCarrier(), Village::getDistance($source->x, $source->y, $destination->x, $destination->y)) . ' seconds' ) ); $event->villageId = $this->source; $sendResourcesMailCarriers = new SendResourcesCarriers(); $sendResourcesMailCarriers->event = $event; $sendResourcesMailCarriers->sendResourcesEventId = $this->id; $sendResourcesMailCarriers->source = $source->id; $sendResourcesMailCarriers->destination = $destination->id; $sendResourcesMailCarriers->dbInsert(); } } public function cancel(): void { $this->event = $this->getEvent(); $cancelTimeDiff = $this->event->createdAt->diff(new \DateTime()); $cancelTime = (new \DateTime())->add($cancelTimeDiff); $this->isCanceled = true; DB::query( 'update events set time=:time where id=:id', ['time' => $cancelTime->format('c'), 'id' => $this->event->id] ); DB::query( 'update events_send_resources set is_canceled=:is_canceled where id=:id', ['is_canceled' => $this->isCanceled, 'id' => $this->id] ); } 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( << 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 = MailCarrier::getResourceCapabilities($this->event->villageId); $resourcesTotal = $this->wood + $this->clay + $this->iron + $this->food; $necessaryMailCarriers = ceil($resourcesTotal / $resourceCapabilities); $mailCarriersAccountedFor = 0; while ($mailCarriersAccountedFor < $necessaryMailCarriers) { $mailCarriers = DB::fetch( MailCarrier::class, 'select * from village_units where type=:type and residence_village_id=:villageId and is_traveling=false', ['type' => 'MailCarrier', 'villageId' => $this->source] ); foreach ($mailCarriers as $mailCarrier) { /**@type MailCarrier $mailCarrier*/ $currentlyNecessaryMailCarriers = $necessaryMailCarriers - $mailCarriersAccountedFor; $currentlyUseableMailCarriers = $currentlyNecessaryMailCarriers - $mailCarrier->amount < 0 ? $currentlyNecessaryMailCarriers : $mailCarrier->amount; $mailCarriersAccountedFor += $currentlyUseableMailCarriers; DB::query( << $currentlyUseableMailCarriers, 'type' => 'MailCarrier', 'home' => $mailCarrier->homeVillageId, 'residence' => $mailCarrier->residenceVillageId, ] ); DB::query('update village_units set amount=amount-:amount where id=:unitId', ['amount' => $necessaryMailCarriers, 'unitId' => $mailCarrier->id]); DB::query( << $sendResourcesEventId, 'unit_id' => $mailCarrier->id, 'amount' => $necessaryMailCarriers, ] ); } } // remove resources from source 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->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]); } }