level >= $building->maxLevel) { return false; } $resourceRequirements = $building->getResourceRequirements(); foreach ($resourceRequirements as $resourceType => $requirement) { if ($village->$resourceType < $requirement) { return false; } } return true; } public static function canTrain(Village $village, Unit $unit, int $amount): bool { $resourceRequirements = Unit::getResourceRequirements($unit, $amount); foreach ($resourceRequirements as $resourceType => $requirement) { if ($village->$resourceType < $requirement) { return false; } } return true; } public static function canSendResources(Village $village): bool { $marketplace = Village::getBuilding($village->id, 'Marketplace'); if (! $marketplace) { return false; } $merchants = Village::getUnit($village, $marketplace->unitType, Village::FETCH_UNIT_RESIDENCE, Village::RETURN_UNIT_EXISTING); if (! $merchants || $merchants->amount === 0) { return false; } return true; } /* DB - Actions */ public static function get(int $id): ?Village { return DB::fetch(Village::class, 'select * from villages where id=:id', ['id' => $id])[0] ?? null; } public static function getByCoordinates(int $x, int $y): ?Village { return DB::fetch(Village::class, 'select * from villages where x=:x and y=:y', ['x' => $x, 'y' => $y])[0] ?? null; } public function updateResources(): mixed { return DB::query( 'update villages set wood=:wood,clay=:clay,iron=:iron,food=:food where id=:id', ['wood' => $this->wood, 'clay' => $this->clay, 'iron' => $this->iron, 'food' => $this->food, 'id' => $this->id] ); } public static function getDistance(int $x, int $y, int $dx, int $dy): int { return abs($x - $dx) + abs($y - $dy); } /* DB - Relations */ public static function getBuildings(int $villageId, bool $withEmpty = false): array { $buildings = DB::fetch(Building::class, 'select * from village_buildings where village_id=:id', ['id' => $villageId]); if ($withEmpty) { $nonBuiltBuildings = array_diff( ['TownHall', 'Embassy', 'Marketplace', 'Storage', 'WoodCutter', 'ClayPit', 'IronMine', 'Farm'], array_column($buildings, 'type'), ); foreach ($nonBuiltBuildings as $type) { $buildings[] = Building::getEmpty($villageId, $type); } } return array_map(function (Building $building) { return $building->cast(); }, $buildings); } public static function getBuilding(int $villageId, string $buildingType): ?Building { $results = DB::fetch( Building::resolveType($buildingType), 'select * from village_buildings where village_id=:id and type=:type', ['id' => $villageId, 'type' => $buildingType] ); return isset($results[0]) ? $results[0]->cast() : null; } public static function getStorage(int $villageId): ?Storage { return Village::getBuilding($villageId, 'Storage'); } public static function getStorageConfig(int $villageId): ?StorageConfig { $results = DB::fetch( StorageConfig::class, 'select * from village_storage_config where village_id=:id', ['id' => $villageId] ); return $results[0] ?? null; } public const FETCH_UNIT_HOME_AT_HOME = 1; public const FETCH_UNIT_HOME_AT_SUPPORT = 2; public const FETCH_UNIT_SUPPORT_AT_HOME = 3; public const FETCH_UNIT_RESIDENCE = 4; public const RETURN_UNIT_EXISTING = 1; public const RETURN_UNIT_ALL = 2; public const RETURN_UNIT_TRAINABLE = 3; public static function getUnit(Village $village, string $unitType, int $fetchFlag = Village::FETCH_UNIT_RESIDENCE, int $returnFlag = Village::RETURN_UNIT_EXISTING): ?Unit { if ($fetchFlag == Village::FETCH_UNIT_RESIDENCE) { $query = 'select * from village_units where residence_village_id=:id and type=:type and is_traveling=false'; } $results = DB::fetch(Unit::class, $query, ['id' => $village->id, 'type' => $unitType]); if (isset($results[0])) { $unit = $results[0]->cast(); } else { return null; } return $unit; } /** * @param int $fetchFlag * * @return array */ public static function getUnits(int $villageId, int $fetchFlag = Village::FETCH_UNIT_ALL, int $returnFlag = Village::RETURN_UNIT_EXISTING): array { if ($fetchFlag == Village::FETCH_UNIT_HOME_AT_HOME) { $units = DB::fetch(Unit::class, 'select * from village_units where home_village_id=:id and residence_village_id=:id', ['id' => $villageId]); } else if ($fetchFlag == Village::FETCH_UNIT_HOME_AT_SUPPORT) { $units = DB::fetch(Unit::class, 'select * from village_units where home_village_id=:id and residence_village_id!=:id', ['id' => $villageId]); } else if ($fetchFlag == Village::FETCH_UNIT_SUPPORT_AT_HOME) { $units = DB::fetch(Unit::class, 'select * from village_units where home_village_id!=:id and residence_village_id=:id', ['id' => $villageId]); } else if ($fetchFlag == Village::FETCH_UNIT_RESIDENCE) { $units = DB::fetch(Unit::class, 'select * from village_units where residence_village_id=:id', ['id' => $villageId]); } if ($returnFlag == Village::RETURN_UNIT_ALL || $returnFlag == Village::RETURN_UNIT_TRAINABLE) { $nonExistingUnits = array_diff( ['WoodCutter', 'PitWorker', 'Miner', 'Farmer', 'Merchant', 'Diplomat'], array_column($units, 'type'), ); foreach ($nonExistingUnits as $type) { $units[] = Unit::getEmpty($villageId, $type); } if ($returnFlag == Village::RETURN_UNIT_TRAINABLE) { $units = array_filter($units, function (Unit $unit) { return !! $unit->cast()->getBuilding(); }); } } else if ($returnFlag == Village::RETURN_UNIT_EXISTING) { $units = array_filter($units, function (Unit $unit) { return ! $unit->isTraveling; }); } return array_map(function (Unit $unit) { return $unit->cast(); }, $units); } }