diff options
Diffstat (limited to 'src/Model')
-rw-r--r-- | src/Model/Building.php | 102 | ||||
-rw-r--r-- | src/Model/Building/ClayPit.php | 16 | ||||
-rw-r--r-- | src/Model/Building/Farm.php | 31 | ||||
-rw-r--r-- | src/Model/Building/IronMine.php | 16 | ||||
-rw-r--r-- | src/Model/Building/ResourceGenerator.php | 22 | ||||
-rw-r--r-- | src/Model/Building/Storage.php | 28 | ||||
-rw-r--r-- | src/Model/Building/TownHall.php | 17 | ||||
-rw-r--r-- | src/Model/Building/WoodCutter.php | 16 | ||||
-rw-r--r-- | src/Model/Event.php | 32 | ||||
-rw-r--r-- | src/Model/Event/TrainUnits.php | 27 | ||||
-rw-r--r-- | src/Model/Event/UpgradeBuilding.php | 27 | ||||
-rw-r--r-- | src/Model/Unit.php | 77 | ||||
-rw-r--r-- | src/Model/Unit/Farmer.php | 15 | ||||
-rw-r--r-- | src/Model/Unit/Miner.php | 15 | ||||
-rw-r--r-- | src/Model/Unit/PitWorker.php | 15 | ||||
-rw-r--r-- | src/Model/Unit/WoodCutter.php | 15 | ||||
-rw-r--r-- | src/Model/User.php | 7 | ||||
-rw-r--r-- | src/Model/Village.php | 135 | ||||
-rw-r--r-- | src/Model/Village/StorageConfig.php | 18 |
19 files changed, 631 insertions, 0 deletions
diff --git a/src/Model/Building.php b/src/Model/Building.php new file mode 100644 index 0000000..eb166f9 --- /dev/null +++ b/src/Model/Building.php @@ -0,0 +1,102 @@ +<?php + +namespace App\Model; + +use App\DB; +use App\Model; + +class Building +{ + public int $id; + + public int $level; + public string $type; + public int $villageId; + + public \DateTime $createdAt; + public \DateTime $updatedAt; + + public string $unitType; + public int $buildTimeFactor; + public array $resourceRequirements; + public array $buildingRequirements; + public array $techRequirements; + public int $maxLevel; + + + public static function get(int $id): ?Building + { + $results = DB::fetch(Building::class, 'select * from village_buildings where id=:id', ['id' => $id]); + + return isset($results[0]) ? $results[0]->cast() : null; + } + + public static function getByVillage(int $villageId, string $buildingType): ?Building + { + $results = DB::fetch(Building::class, '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 getByVillageCoordinates(int $x, int $y, string $buildingType): ?Building + { + $results = DB::fetch( + Building::class, + <<<SQL + select village_buildings.* + from village_buildings + join villages on (villages.x=:x and villages.y=:y) + where village_buildings.village_id=villages.id and type=:type + SQL, + ['x' => $x, 'y' => $y, 'type' => $buildingType] + ); + + return isset($results[0]) ? $results[0]->cast() : null; + } + + + public function getBuildTime(): int + { + $townHall = Village::getBuilding($this->villageId, 'TownHall'); + + $nextLevel = $this->level + 1; + + return intval($nextLevel * ($nextLevel / $townHall->level) * $_ENV['BASE_BUILDING_BUILD_TIME_FACTOR'] * $this->buildTimeFactor); + } + + /** + * @return array<string, int> + */ + public function getResourceRequirements(): array + { + return $this->getResourceRequirementsForLevel($this->level); + } + + /** + * @return array<string, int> + */ + public function getResourceRequirementsForLevel(int $level): array + { + $level += 1; + + return array_map( + fn ($resourceRequirement) => ceil(log($level * 2) * $resourceRequirement * 64 * $level), + $this->resourceRequirements + ); + } + + + /* OOP */ + + public function cast(): Building + { + $class = Building::resolveType($this->type); + + return Model::castToType($this, Building::resolveType($this->type)); + } + + public static function resolveType(string $type): string + { + return __NAMESPACE__ . '\\Building\\' . $type; + } +} diff --git a/src/Model/Building/ClayPit.php b/src/Model/Building/ClayPit.php new file mode 100644 index 0000000..8127818 --- /dev/null +++ b/src/Model/Building/ClayPit.php @@ -0,0 +1,16 @@ +<?php + +namespace App\Model\Building; + +class ClayPit extends ResourceGenerator +{ + public string $unitType = 'PitWorker'; + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; + + public string $resourceType = 'clay'; +} diff --git a/src/Model/Building/Farm.php b/src/Model/Building/Farm.php new file mode 100644 index 0000000..aaa58b5 --- /dev/null +++ b/src/Model/Building/Farm.php @@ -0,0 +1,31 @@ +<?php + +namespace App\Model\Building; + +use App\Model\Unit; +use App\Model\Village; + +class Farm extends ResourceGenerator +{ + public string $unitType = 'Farmer'; + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; + + public string $resourceType = 'food'; + + public function getResourceIncrementor(): int + { + $populationDemand = array_reduce( + Village::getUnits($this->villageId, Village::FETCH_UNIT_RESIDENCE), + function ($carry, Unit $unit) { + return $carry + $unit->getPopulationDemand(); + } + ); + + return parent::getResourceIncrementor() - $populationDemand; + } +} diff --git a/src/Model/Building/IronMine.php b/src/Model/Building/IronMine.php new file mode 100644 index 0000000..4bf5cc6 --- /dev/null +++ b/src/Model/Building/IronMine.php @@ -0,0 +1,16 @@ +<?php + +namespace App\Model\Building; + +class IronMine extends ResourceGenerator +{ + public string $unitType = 'Miner'; + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; + + public string $resourceType = 'iron'; +} diff --git a/src/Model/Building/ResourceGenerator.php b/src/Model/Building/ResourceGenerator.php new file mode 100644 index 0000000..5f1a6bb --- /dev/null +++ b/src/Model/Building/ResourceGenerator.php @@ -0,0 +1,22 @@ +<?php + +namespace App\Model\Building; + +use App\Model\Building; +use App\Model\Unit; + +class ResourceGenerator extends Building +{ + public string $resourceType; + + public function getResourceIncrementor(): int + { + $amountResiding = Unit::getAmountResiding($this->unitType, $this->villageId); + + return (int)ceil( + log( + ($this->level * $amountResiding) + 1 + ) * $_ENV['BASE_RESOURCE_GENERATION_FACTOR'] + ); + } +} diff --git a/src/Model/Building/Storage.php b/src/Model/Building/Storage.php new file mode 100644 index 0000000..fde4c4e --- /dev/null +++ b/src/Model/Building/Storage.php @@ -0,0 +1,28 @@ +<?php + +namespace App\Model\Building; + +use App\Model\Building; +use App\Model\Village; + +class Storage extends Building +{ + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; + + public function getCapacity(): int + { + return $this->level * 2560; + } + + public function getResourceCapacity(string $resourceType): int + { + $p = Village::getStorageConfig($this->villageId)->$resourceType / 100; + + return ceil($this->getCapacity() * $p); + } +} diff --git a/src/Model/Building/TownHall.php b/src/Model/Building/TownHall.php new file mode 100644 index 0000000..608f083 --- /dev/null +++ b/src/Model/Building/TownHall.php @@ -0,0 +1,17 @@ +<?php + +namespace App\Model\Building; + +use App\Model\Building; + +class TownHall extends Building +{ + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + 'clay' => 1.0, + 'iron' => 1.0, + ]; +} diff --git a/src/Model/Building/WoodCutter.php b/src/Model/Building/WoodCutter.php new file mode 100644 index 0000000..86bde9b --- /dev/null +++ b/src/Model/Building/WoodCutter.php @@ -0,0 +1,16 @@ +<?php + +namespace App\Model\Building; + +class WoodCutter extends ResourceGenerator +{ + public string $unitType = 'WoodCutter'; + public int $buildTimeFactor = 1; + public int $maxLevel = 25; + + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; + + public string $resourceType = 'wood'; +} diff --git a/src/Model/Event.php b/src/Model/Event.php new file mode 100644 index 0000000..aa235f9 --- /dev/null +++ b/src/Model/Event.php @@ -0,0 +1,32 @@ +<?php + +namespace App\Model; + +use App\Model; + +class Event +{ + public int $id; + + public string $type; + public \DateTime $time; + public string $payload; + + public int $villageId; + + + /* OOP */ + + public function cast(): Event + { + $class = Event::resolveType($this->type); + $object = new $class(); + + return Model::castToType($this, Event::resolveType($this->type)); + } + + public static function resolveType(string $type): string + { + return __NAMESPACE__ . '\\Event\\' . $type; + } +} diff --git a/src/Model/Event/TrainUnits.php b/src/Model/Event/TrainUnits.php new file mode 100644 index 0000000..0c7e0de --- /dev/null +++ b/src/Model/Event/TrainUnits.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Model\Event; + +use App\DB; +use App\Model\Event; + +class TrainUnits extends Event +{ + /** + * @return void + */ + public function __invoke(): void + { + $payload = json_decode($this->payload, true); + + DB::query( + <<<SQL + insert into village_units (amount, type, is_traveling, home_village_id, residence_village_id) + values (:amount, :type, false, :id, :id) + on conflict (type, home_village_id, residence_village_id) + do update set amount = excluded.amount+:amount + SQL, + ['amount' => $payload['amount'], 'type' => $payload['type'], 'id' => $this->villageId] + ); + } +} diff --git a/src/Model/Event/UpgradeBuilding.php b/src/Model/Event/UpgradeBuilding.php new file mode 100644 index 0000000..c014cfe --- /dev/null +++ b/src/Model/Event/UpgradeBuilding.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Model\Event; + +use App\DB; +use App\Model\Event; + +class UpgradeBuilding extends Event +{ + /** + * @return void + */ + public function __invoke(): void + { + $payload = json_decode($this->payload, true); + + DB::query( + 'update village_buildings set level=level+1 where id=:id', + ['id' => $payload['id']] + ); + + DB::query( + 'delete from events where id=:id', + ['id' => $this->id] + ); + } +} diff --git a/src/Model/Unit.php b/src/Model/Unit.php new file mode 100644 index 0000000..a0d1a35 --- /dev/null +++ b/src/Model/Unit.php @@ -0,0 +1,77 @@ +<?php + +namespace App\Model; + +use App\DB; +use App\Model; + +class Unit +{ + public int $id; + + public int $amount; + public string $type; + public bool $isTraveling; + + public int $homeVillageId; + public int $residenceVillageId; + + public string $createdAt; + public string $updatedAt; + + public string $buildingType; + public int $travelTime; + public int $populationDemandFactor; + public array $resourceRequirements = []; + + + public function getBuildTime(int $amount): int + { + return intval(($_ENV['BASE_UNIT_BUILD_TIME_FACTOR'] / ($this->getBuilding()->level ?: 1)) * $amount); + } + + public function getPopulationDemand(): int + { + return $this->getPopulationDemandForAmount($this->amount); + } + + public function getPopulationDemandForAmount(int $amount): int + { + return $amount * $this->populationDemandFactor; + } + + + /* Relations */ + + public function getBuilding(): ?Building + { + return Village::getBuilding($this->homeVillageId, $this->buildingType); + } + + public function cast(): Unit + { + $class = Unit::resolveType($this->type); + + return Model::castToType($this, Unit::resolveType($this->type)); + } + + public static function resolveType(string $type): string + { + return __NAMESPACE__ . '\\Unit\\' . $type; + } + + + /* Static */ + + public static function getAmountResiding(string $unitType, int $villageId): int + { + $statement = DB::query( + 'select SUM(amount) from village_units where type=:type and residence_village_id=:id', + ['type' => $unitType, 'id' => $villageId] + ); + $result = $statement->fetch()['sum']; + + return intval($result); + } + +} diff --git a/src/Model/Unit/Farmer.php b/src/Model/Unit/Farmer.php new file mode 100644 index 0000000..de37802 --- /dev/null +++ b/src/Model/Unit/Farmer.php @@ -0,0 +1,15 @@ +<?php + +namespace App\Model\Unit; + +use App\Model\Unit; + +class Farmer extends Unit +{ + public string $buildingType = 'Farm'; + public int $travelTime = 1; + public int $populationDemandFactor = 1; + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; +} diff --git a/src/Model/Unit/Miner.php b/src/Model/Unit/Miner.php new file mode 100644 index 0000000..ae6c00a --- /dev/null +++ b/src/Model/Unit/Miner.php @@ -0,0 +1,15 @@ +<?php + +namespace App\Model\Unit; + +use App\Model\Unit; + +class Miner extends Unit +{ + public string $buildingType = 'IronMine'; + public int $travelTime = 1; + public int $populationDemandFactor = 1; + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; +} diff --git a/src/Model/Unit/PitWorker.php b/src/Model/Unit/PitWorker.php new file mode 100644 index 0000000..4f873b4 --- /dev/null +++ b/src/Model/Unit/PitWorker.php @@ -0,0 +1,15 @@ +<?php + +namespace App\Model\Unit; + +use App\Model\Unit; + +class PitWorker extends Unit +{ + public string $buildingType = 'ClayPit'; + public int $travelTime = 1; + public int $populationDemandFactor = 1; + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; +} diff --git a/src/Model/Unit/WoodCutter.php b/src/Model/Unit/WoodCutter.php new file mode 100644 index 0000000..17923ca --- /dev/null +++ b/src/Model/Unit/WoodCutter.php @@ -0,0 +1,15 @@ +<?php + +namespace App\Model\Unit; + +use App\Model\Unit; + +class WoodCutter extends Unit +{ + public string $buildingType = 'WoodCutter'; + public int $travelTime = 1; + public int $populationDemandFactor = 1; + public array $resourceRequirements = [ + 'wood' => 1.0, + ]; +} diff --git a/src/Model/User.php b/src/Model/User.php new file mode 100644 index 0000000..fcb1869 --- /dev/null +++ b/src/Model/User.php @@ -0,0 +1,7 @@ +<?php + +namespace App\Model; + +class User +{ +} diff --git a/src/Model/Village.php b/src/Model/Village.php new file mode 100644 index 0000000..cd1c749 --- /dev/null +++ b/src/Model/Village.php @@ -0,0 +1,135 @@ +<?php + +namespace App\Model; + +use App\DB; +use App\Model\Building\Storage; +use App\Model\Village\StorageConfig; + +class Village +{ + public int $id; + + public string $name; + + public int $x; + public int $y; + + public int $wood; + public int $clay; + public int $iron; + public int $food; + + public int $satisfaction; + + public string $createdAt; + public string $updatedAt; + + public static function canBuild(Village $village, Building $building): bool + { + if ($building->level >= $building->maxLevel) { + return false; + } + + $resourceRequirements = $building->getResourceRequirements(); + foreach ($resourceRequirements as $resourceType => $requirement) { + if ($village->$resourceType < $requirement) { + 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] + ); + } + + /* DB - Relations */ + + public static function getBuildings(int $villageId): array + { + $buildings = DB::fetch(Building::class, 'select * from village_buildings where village_id=:id', ['id' => $villageId]); + + 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 static function getUnit(string $unitType, int $flag): ?Unit + { + } + + /** + * @param int $flag + * + * @return array<int, Unit> + */ + public static function getUnits(int $villageId, $flag = Village::FETCH_UNIT_ALL): array + { + if ($flag == 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 ($flag == 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 ($flag == 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 ($flag == Village::FETCH_UNIT_RESIDENCE) { + $units = DB::fetch(Unit::class, 'select * from village_units where residence_village_id=:id', ['id' => $villageId]); + } + + return array_map(function (Unit $unit) { + return $unit->cast(); + }, $units); + } +} diff --git a/src/Model/Village/StorageConfig.php b/src/Model/Village/StorageConfig.php new file mode 100644 index 0000000..272eaf5 --- /dev/null +++ b/src/Model/Village/StorageConfig.php @@ -0,0 +1,18 @@ +<?php + +namespace App\Model\Village; + +class StorageConfig +{ + public int $id; + + public int $wood; + public int $clay; + public int $iron; + public int $food; + + public int $villageId; + + public string $createdAt; + public string $updatedAt; +} |