diff options
| -rw-r--r-- | .env.example | 1 | ||||
| -rw-r--r-- | bin/db.php | 18 | ||||
| -rw-r--r-- | composer.lock | 236 | ||||
| -rw-r--r-- | docker-compose.yml | 5 | ||||
| -rw-r--r-- | public/assets/style.css | 44 | ||||
| -rw-r--r-- | shell.nix | 5 | ||||
| -rw-r--r-- | src/Model/Event/BaseEvent.php | 7 | ||||
| -rw-r--r-- | src/Model/Event/SendResources.php | 2 | ||||
| -rw-r--r-- | src/Model/Event/SendUnits.php | 2 | ||||
| -rw-r--r-- | src/Model/Event/TrainUnits.php | 2 | ||||
| -rw-r--r-- | src/Model/Event/UpgradeBuilding.php | 52 | ||||
| -rw-r--r-- | src/Model/Village.php | 2 | ||||
| -rw-r--r-- | src/Support/BuildingType.php | 0 | ||||
| -rw-r--r-- | src/http/Controller/Building.php | 10 | ||||
| -rw-r--r-- | src/http/Controller/Login.php | 49 | ||||
| -rw-r--r-- | src/http/Controller/Map.php | 6 | ||||
| -rw-r--r-- | src/http/Controller/User.php | 1 | ||||
| -rw-r--r-- | src/http/Controller/Village.php | 33 | ||||
| -rw-r--r-- | src/http/Router.php | 1 | ||||
| -rw-r--r-- | views/http/map.twig | 12 | ||||
| -rw-r--r-- | views/http/village.twig | 16 | 
21 files changed, 280 insertions, 224 deletions
| diff --git a/.env.example b/.env.example index ffe11a1..0d176c7 100644 --- a/.env.example +++ b/.env.example @@ -13,3 +13,4 @@ BASE_UNIT_RESOURCE_REQUIREMENT_FACTOR=64  BASE_RESOURCE_GENERATION_FACTOR=128  BASE_STORAGE_CAPACITY_FACTOR=2048  SATISFACTION_FOOD_THRESHOLD=10 +MAP_DEFAULT_RANGE=3 @@ -117,12 +117,12 @@ DB::query(<<<SQL      constraint "relation_event"        foreign key ("event_id") references events("id") on delete cascade, -    "village_id" bigint not null, -    constraint "relation_village" -      foreign key ("village_id") references villages("id") on delete cascade, -      "type" character varying(255) not null, +    "wood" bigint not null, +    "clay" bigint not null, +    "iron" bigint not null, +      "created_at" timestamp(0) not null default current_timestamp,      "updated_at" timestamp(0) not null default current_timestamp    ); @@ -136,13 +136,13 @@ DB::query(<<<SQL      constraint "relation_event"        foreign key ("event_id") references events("id") on delete cascade, -    "village_id" bigint not null, -    constraint "relation_village" -      foreign key ("village_id") references villages("id") on delete cascade, -      "amount" bigint not null,      "type" character varying(255) not null, +    "wood" bigint not null, +    "clay" bigint not null, +    "iron" bigint not null, +      "created_at" timestamp(0) not null default current_timestamp,      "updated_at" timestamp(0) not null default current_timestamp    ); @@ -220,7 +220,7 @@ DB::query(<<<SQL      "unit_id" bigint not null,      constraint "relation_unit" -      foreign key ("unit") references village_units("id"), +      foreign key ("unit_id") references village_units("id"),      "amount" bigint not null, diff --git a/composer.lock b/composer.lock index 2524e07..0cf0a5d 100644 --- a/composer.lock +++ b/composer.lock @@ -12,7 +12,7 @@              "source": {                  "type": "git",                  "url": "https://git.dweipert.de/gemini-foundation", -                "reference": "3776ab80f23c07943d2228f2975e515c494f930a" +                "reference": "faf9ddfc29676b86621bdc3033e05d63df5c2a93"              },              "default-branch": true,              "type": "library", @@ -30,7 +30,7 @@                      "email": "code@drogueronin.de"                  }              ], -            "time": "2024-01-02T19:39:07+00:00" +            "time": "2024-01-15T12:54:52+00:00"          },          {              "name": "symfony/config", @@ -38,12 +38,12 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/config.git", -                "reference": "5d33e0fb707d603330e0edfd4691803a1253572e" +                "reference": "4e55e7e4ffddd343671ea972216d4509f46c22ef"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/config/zipball/5d33e0fb707d603330e0edfd4691803a1253572e", -                "reference": "5d33e0fb707d603330e0edfd4691803a1253572e", +                "url": "https://api.github.com/repos/symfony/config/zipball/4e55e7e4ffddd343671ea972216d4509f46c22ef", +                "reference": "4e55e7e4ffddd343671ea972216d4509f46c22ef",                  "shasum": ""              },              "require": { @@ -105,7 +105,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-11-09T08:28:32+00:00" +            "time": "2024-11-04T11:33:53+00:00"          },          {              "name": "symfony/deprecation-contracts", @@ -113,12 +113,12 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/deprecation-contracts.git", -                "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" +                "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", -                "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", +                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", +                "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",                  "shasum": ""              },              "require": { @@ -127,12 +127,12 @@              "default-branch": true,              "type": "library",              "extra": { -                "branch-alias": { -                    "dev-main": "3.4-dev" -                },                  "thanks": { -                    "name": "symfony/contracts", -                    "url": "https://github.com/symfony/contracts" +                    "url": "https://github.com/symfony/contracts", +                    "name": "symfony/contracts" +                }, +                "branch-alias": { +                    "dev-main": "3.6-dev"                  }              },              "autoload": { @@ -157,7 +157,7 @@              "description": "A generic function and convention to trigger deprecation notices",              "homepage": "https://symfony.com",              "support": { -                "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" +                "source": "https://github.com/symfony/deprecation-contracts/tree/main"              },              "funding": [                  { @@ -173,7 +173,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-05-23T14:45:45+00:00" +            "time": "2024-09-25T14:21:43+00:00"          },          {              "name": "symfony/dotenv", @@ -181,12 +181,12 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/dotenv.git", -                "reference": "835f8d2d1022934ac038519de40b88158798c96f" +                "reference": "1ac5e7e7e862d4d574258daf08bd569ba926e4a5"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/dotenv/zipball/835f8d2d1022934ac038519de40b88158798c96f", -                "reference": "835f8d2d1022934ac038519de40b88158798c96f", +                "url": "https://api.github.com/repos/symfony/dotenv/zipball/1ac5e7e7e862d4d574258daf08bd569ba926e4a5", +                "reference": "1ac5e7e7e862d4d574258daf08bd569ba926e4a5",                  "shasum": ""              },              "require": { @@ -247,20 +247,20 @@                      "type": "tidelift"                  }              ], -            "time": "2023-12-28T19:16:56+00:00" +            "time": "2024-11-27T11:08:19+00:00"          },          {              "name": "symfony/filesystem", -            "version": "7.1.x-dev", +            "version": "7.3.x-dev",              "source": {                  "type": "git",                  "url": "https://github.com/symfony/filesystem.git", -                "reference": "2d3a1adb578bd4e783b5f1cbfc4e2c12ae05b466" +                "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/filesystem/zipball/2d3a1adb578bd4e783b5f1cbfc4e2c12ae05b466", -                "reference": "2d3a1adb578bd4e783b5f1cbfc4e2c12ae05b466", +                "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", +                "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",                  "shasum": ""              },              "require": { @@ -268,6 +268,9 @@                  "symfony/polyfill-ctype": "~1.8",                  "symfony/polyfill-mbstring": "~1.8"              }, +            "require-dev": { +                "symfony/process": "^6.4|^7.0" +            },              "type": "library",              "autoload": {                  "psr-4": { @@ -294,7 +297,7 @@              "description": "Provides basic utilities for the filesystem",              "homepage": "https://symfony.com",              "support": { -                "source": "https://github.com/symfony/filesystem/tree/7.1" +                "source": "https://github.com/symfony/filesystem/tree/v7.2.0"              },              "funding": [                  { @@ -310,7 +313,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-12-19T09:30:49+00:00" +            "time": "2024-10-25T15:15:23+00:00"          },          {              "name": "symfony/http-foundation", @@ -318,12 +321,12 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/http-foundation.git", -                "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271" +                "reference": "d0492d6217e5ab48f51fca76f64cf8e78919d0db"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/172d807f9ef3fc3fbed8377cc57c20d389269271", -                "reference": "172d807f9ef3fc3fbed8377cc57c20d389269271", +                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d0492d6217e5ab48f51fca76f64cf8e78919d0db", +                "reference": "d0492d6217e5ab48f51fca76f64cf8e78919d0db",                  "shasum": ""              },              "require": { @@ -333,12 +336,12 @@                  "symfony/polyfill-php83": "^1.27"              },              "conflict": { -                "symfony/cache": "<6.3" +                "symfony/cache": "<6.4.12|>=7.0,<7.1.5"              },              "require-dev": {                  "doctrine/dbal": "^2.13.1|^3|^4",                  "predis/predis": "^1.1|^2.0", -                "symfony/cache": "^6.3|^7.0", +                "symfony/cache": "^6.4.12|^7.1.5",                  "symfony/dependency-injection": "^5.4|^6.0|^7.0",                  "symfony/expression-language": "^5.4|^6.0|^7.0",                  "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", @@ -387,7 +390,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-12-27T22:16:42+00:00" +            "time": "2025-01-09T15:48:56+00:00"          },          {              "name": "symfony/polyfill-ctype", @@ -395,16 +398,16 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/polyfill-ctype.git", -                "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" +                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", -                "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", +                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", +                "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",                  "shasum": ""              },              "require": { -                "php": ">=7.1" +                "php": ">=7.2"              },              "provide": {                  "ext-ctype": "*" @@ -415,12 +418,9 @@              "default-branch": true,              "type": "library",              "extra": { -                "branch-alias": { -                    "dev-main": "1.28-dev" -                },                  "thanks": { -                    "name": "symfony/polyfill", -                    "url": "https://github.com/symfony/polyfill" +                    "url": "https://github.com/symfony/polyfill", +                    "name": "symfony/polyfill"                  }              },              "autoload": { @@ -454,7 +454,7 @@                  "portable"              ],              "support": { -                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" +                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"              },              "funding": [                  { @@ -470,7 +470,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-01-26T09:26:14+00:00" +            "time": "2024-09-09T11:45:10+00:00"          },          {              "name": "symfony/polyfill-mbstring", @@ -478,16 +478,17 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/polyfill-mbstring.git", -                "reference": "42292d99c55abe617799667f454222c54c60e229" +                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", -                "reference": "42292d99c55abe617799667f454222c54c60e229", +                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", +                "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",                  "shasum": ""              },              "require": { -                "php": ">=7.1" +                "ext-iconv": "*", +                "php": ">=7.2"              },              "provide": {                  "ext-mbstring": "*" @@ -498,12 +499,9 @@              "default-branch": true,              "type": "library",              "extra": { -                "branch-alias": { -                    "dev-main": "1.28-dev" -                },                  "thanks": { -                    "name": "symfony/polyfill", -                    "url": "https://github.com/symfony/polyfill" +                    "url": "https://github.com/symfony/polyfill", +                    "name": "symfony/polyfill"                  }              },              "autoload": { @@ -538,7 +536,7 @@                  "shim"              ],              "support": { -                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" +                "source": "https://github.com/symfony/polyfill-mbstring/tree/1.x"              },              "funding": [                  { @@ -554,91 +552,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-07-28T09:04:16+00:00" -        }, -        { -            "name": "symfony/polyfill-php80", -            "version": "1.x-dev", -            "source": { -                "type": "git", -                "url": "https://github.com/symfony/polyfill-php80.git", -                "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" -            }, -            "dist": { -                "type": "zip", -                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", -                "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", -                "shasum": "" -            }, -            "require": { -                "php": ">=7.1" -            }, -            "default-branch": true, -            "type": "library", -            "extra": { -                "branch-alias": { -                    "dev-main": "1.28-dev" -                }, -                "thanks": { -                    "name": "symfony/polyfill", -                    "url": "https://github.com/symfony/polyfill" -                } -            }, -            "autoload": { -                "files": [ -                    "bootstrap.php" -                ], -                "psr-4": { -                    "Symfony\\Polyfill\\Php80\\": "" -                }, -                "classmap": [ -                    "Resources/stubs" -                ] -            }, -            "notification-url": "https://packagist.org/downloads/", -            "license": [ -                "MIT" -            ], -            "authors": [ -                { -                    "name": "Ion Bazan", -                    "email": "ion.bazan@gmail.com" -                }, -                { -                    "name": "Nicolas Grekas", -                    "email": "p@tchwork.com" -                }, -                { -                    "name": "Symfony Community", -                    "homepage": "https://symfony.com/contributors" -                } -            ], -            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", -            "homepage": "https://symfony.com", -            "keywords": [ -                "compatibility", -                "polyfill", -                "portable", -                "shim" -            ], -            "support": { -                "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" -            }, -            "funding": [ -                { -                    "url": "https://symfony.com/sponsor", -                    "type": "custom" -                }, -                { -                    "url": "https://github.com/fabpot", -                    "type": "github" -                }, -                { -                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", -                    "type": "tidelift" -                } -            ], -            "time": "2023-01-26T09:26:14+00:00" +            "time": "2024-12-23T08:48:59+00:00"          },          {              "name": "symfony/polyfill-php83", @@ -646,27 +560,23 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/polyfill-php83.git", -                "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" +                "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", -                "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", +                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", +                "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491",                  "shasum": ""              },              "require": { -                "php": ">=7.1", -                "symfony/polyfill-php80": "^1.14" +                "php": ">=7.2"              },              "default-branch": true,              "type": "library",              "extra": { -                "branch-alias": { -                    "dev-main": "1.28-dev" -                },                  "thanks": { -                    "name": "symfony/polyfill", -                    "url": "https://github.com/symfony/polyfill" +                    "url": "https://github.com/symfony/polyfill", +                    "name": "symfony/polyfill"                  }              },              "autoload": { @@ -703,7 +613,7 @@                  "shim"              ],              "support": { -                "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0" +                "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0"              },              "funding": [                  { @@ -719,7 +629,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-08-16T06:22:46+00:00" +            "time": "2024-09-09T11:45:10+00:00"          },          {              "name": "symfony/routing", @@ -727,12 +637,12 @@              "source": {                  "type": "git",                  "url": "https://github.com/symfony/routing.git", -                "reference": "98eab13a07fddc85766f1756129c69f207ffbc21" +                "reference": "e9bfc94953019089acdfb9be51c1b9142c4afa68"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/symfony/routing/zipball/98eab13a07fddc85766f1756129c69f207ffbc21", -                "reference": "98eab13a07fddc85766f1756129c69f207ffbc21", +                "url": "https://api.github.com/repos/symfony/routing/zipball/e9bfc94953019089acdfb9be51c1b9142c4afa68", +                "reference": "e9bfc94953019089acdfb9be51c1b9142c4afa68",                  "shasum": ""              },              "require": { @@ -802,7 +712,7 @@                      "type": "tidelift"                  }              ], -            "time": "2023-12-29T15:34:34+00:00" +            "time": "2025-01-09T08:51:02+00:00"          },          {              "name": "twig/twig", @@ -810,24 +720,24 @@              "source": {                  "type": "git",                  "url": "https://github.com/twigphp/Twig.git", -                "reference": "b4c3c1c448583e9ffa24933675c01f4be3435b41" +                "reference": "8432946eeeca009d75fc7fc568f3c3f4650f5a0f"              },              "dist": {                  "type": "zip", -                "url": "https://api.github.com/repos/twigphp/Twig/zipball/b4c3c1c448583e9ffa24933675c01f4be3435b41", -                "reference": "b4c3c1c448583e9ffa24933675c01f4be3435b41", +                "url": "https://api.github.com/repos/twigphp/Twig/zipball/8432946eeeca009d75fc7fc568f3c3f4650f5a0f", +                "reference": "8432946eeeca009d75fc7fc568f3c3f4650f5a0f",                  "shasum": ""              },              "require": { -                "php": ">=7.2.5", +                "php": ">=8.1.0",                  "symfony/deprecation-contracts": "^2.5|^3",                  "symfony/polyfill-ctype": "^1.8", -                "symfony/polyfill-mbstring": "^1.3", -                "symfony/polyfill-php80": "^1.22" +                "symfony/polyfill-mbstring": "^1.3"              },              "require-dev": { +                "phpstan/phpstan": "^2.0",                  "psr/container": "^1.0|^2.0", -                "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" +                "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"              },              "default-branch": true,              "type": "library", @@ -882,7 +792,7 @@                      "type": "tidelift"                  }              ], -            "time": "2024-01-01T14:44:03+00:00" +            "time": "2025-02-04T11:35:15+00:00"          }      ],      "packages-dev": [], @@ -896,6 +806,6 @@      "platform": {          "php": "^8.0"      }, -    "platform-dev": [], +    "platform-dev": {},      "plugin-api-version": "2.6.0"  } diff --git a/docker-compose.yml b/docker-compose.yml index c2a6b6a..3ee2d28 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,6 @@ -version: "3" -  services:    db:      image: postgres -    restart: unless-stopped      ports:        - "5432:5432"      environment: @@ -19,7 +16,7 @@ services:      volumes:        - "./:/var/www/html" -  web: +  http:      build:        context: docker/nginx      ports: diff --git a/public/assets/style.css b/public/assets/style.css index a6b425b..b17d5ae 100644 --- a/public/assets/style.css +++ b/public/assets/style.css @@ -14,7 +14,8 @@ body {  } -button, input[type="submit"] { +button, +input[type="submit"] {    background-color: #1e362e;    color: #fff;    border: none; @@ -22,11 +23,13 @@ button, input[type="submit"] {    cursor: pointer;  } -button:hover:not(:disabled), input[type="submit"]:hover:not(:disabled) { +button:hover:not(:disabled), +input[type="submit"]:hover:not(:disabled) {    background-color: #000;  } -button:disabled, input[type="submit"]:disabled { +button:disabled, +input[type="submit"]:disabled {    color: #606060;  } @@ -72,14 +75,17 @@ button:disabled, input[type="submit"]:disabled {  .icon-arrow-up {    background-image: url("/assets/img/icons/openmojis/1F53A.svg");  } +  .icon-arrow-down {    background-image: url("/assets/img/icons/openmojis/1F53A.svg");    transform: rotate(180deg);  } +  .icon-arrow-left {    background-image: url("/assets/img/icons/openmojis/1F53A.svg");    transform: rotate(270deg);  } +  .icon-arrow-right {    background-image: url("/assets/img/icons/openmojis/1F53A.svg");    transform: rotate(90deg); @@ -109,7 +115,7 @@ button:disabled, input[type="submit"]:disabled {    grid-template-columns: 2fr 2fr 2fr 2fr 1fr;  } -.resources > div { +.resources>div {    padding: 0.25rem;    border: 1px solid #000; @@ -117,7 +123,7 @@ button:disabled, input[type="submit"]:disabled {    align-items: center;  } -.resources > div > *:not(:first-child) { +.resources>div>*:not(:first-child) {    margin-left: 0.25rem;  } @@ -125,6 +131,10 @@ button:disabled, input[type="submit"]:disabled {    font-size: 1.25em;  } +.resources .icon-storage { +  cursor: pointer; +} +  /* Map */ @@ -134,7 +144,8 @@ button:disabled, input[type="submit"]:disabled {    padding: 2rem;  } -.map__up, .map__down { +.map__up, +.map__down {    position: absolute;    width: 100%;    text-align: center; @@ -150,7 +161,8 @@ button:disabled, input[type="submit"]:disabled {    left: 0;  } -.map__left, .map__right { +.map__left, +.map__right {    position: absolute;    height: 100%; @@ -194,11 +206,27 @@ button:disabled, input[type="submit"]:disabled {    display: flex;    justify-content: center;    align-items: center; + +  position: relative; +} + +.map__village--center, +.map__village:hover { +  border-color: #999;  } -.map__village a { +.map__village a:not(.center-anchor) {    text-decoration: none;    border: 2px solid #fff;    padding: 0 0.25rem;    background: rgba(255, 255, 255, 0.8);  } + +.map__village .center-anchor { +  position: absolute; +  left: 5px; +  top: 0; + +  text-decoration: none; +  color: #fff; +}
\ No newline at end of file @@ -3,7 +3,12 @@ mkShell {  	buildInputs = [  		php  		phpPackages.composer +    phpactor  		nodejs +    nodePackages.typescript-language-server +    vscode-langservers-extracted +		dockerfile-language-server-nodejs +		docker-compose-language-service  		just      entr  	]; diff --git a/src/Model/Event/BaseEvent.php b/src/Model/Event/BaseEvent.php index 2e2564b..0d50458 100644 --- a/src/Model/Event/BaseEvent.php +++ b/src/Model/Event/BaseEvent.php @@ -15,16 +15,15 @@ abstract class BaseEvent    public Event $event; +  abstract function create(): void; +  abstract function cancel(): void;    abstract function dbInsert(): void;    abstract function dbDelete(): void; -  abstract function cancel(): void; -  public function getEvent(): Event +  public function populateEvent(): void    {      if (! isset($this->event)) {        $this->event = DB::fetch(Event::class, 'select * from events where id=:id', ['id' => $this->eventId])[0];      } - -    return $this->event;    }  } diff --git a/src/Model/Event/SendResources.php b/src/Model/Event/SendResources.php index ea9361c..d8e4f85 100644 --- a/src/Model/Event/SendResources.php +++ b/src/Model/Event/SendResources.php @@ -94,7 +94,7 @@ class SendResources extends BaseEvent    public function cancel(): void    { -    $this->event = $this->getEvent(); +    $this->populateEvent();      $cancelTimeDiff = $this->event->createdAt->diff(new \DateTime());      $cancelTime = (new \DateTime())->add($cancelTimeDiff); diff --git a/src/Model/Event/SendUnits.php b/src/Model/Event/SendUnits.php index c9afd6e..1b04333 100644 --- a/src/Model/Event/SendUnits.php +++ b/src/Model/Event/SendUnits.php @@ -104,7 +104,7 @@ class SendUnits extends BaseEvent    public function cancel(): void    { -    $this->event = $this->getEvent(); +    $this->populateEvent();      $cancelTimeDiff = $this->event->createdAt->diff(new \DateTime());      $cancelTime = (new \DateTime())->add($cancelTimeDiff); diff --git a/src/Model/Event/TrainUnits.php b/src/Model/Event/TrainUnits.php index 59b169f..a94a5a8 100644 --- a/src/Model/Event/TrainUnits.php +++ b/src/Model/Event/TrainUnits.php @@ -14,7 +14,7 @@ class TrainUnits extends BaseEvent     */    public function __invoke(): void    { -    $this->getEvent(); +    $this->populateEvent();      DB::query(        <<<SQL diff --git a/src/Model/Event/UpgradeBuilding.php b/src/Model/Event/UpgradeBuilding.php index a3f3984..5993105 100644 --- a/src/Model/Event/UpgradeBuilding.php +++ b/src/Model/Event/UpgradeBuilding.php @@ -3,17 +3,21 @@  namespace App\Model\Event;  use App\DB; +use App\Model\Village;  class UpgradeBuilding extends BaseEvent  {    public string $type; +  public int $wood; +  public int $clay; +  public int $iron;    /**     * @return void     */    public function __invoke(): void    { -    $this->getEvent(); +    $this->populateEvent();      DB::query(        <<<SQL @@ -26,8 +30,44 @@ class UpgradeBuilding extends BaseEvent      );    } +  /*public function populateEvent(): void +  { +    parent::populateEvent(); +     +    $event = DB::fetch(UpgradeBuilding::class, 'select * from events_upgrade_building where id=:id', ['id' => $this->id])[0]; +    $this->type = $event->type; +    $this->wood = $event->wood; +    $this->clay = $event->clay; +    $this->iron = $event->iron; +  }*/ +  +  public function create(): void +  { +    $this->populateEvent(); + +    // remove resources +    $village = Village::get($this->event->villageId); +    $village->wood -= $this->wood; +    $village->clay -= $this->clay; +    $village->iron -= $this->iron; +    $village->updateResources(); + +    // add to db +    $this->dbInsert(); +  } +    public function cancel(): void    { +    $this->populateEvent(); +     +    // add resources +    $village = Village::get($this->event->villageId); +    $village->wood += $this->wood; +    $village->clay += $this->clay; +    $village->iron += $this->iron; +    $village->updateResources(); + +    // remove from db      $this->dbDelete();    } @@ -39,8 +79,14 @@ class UpgradeBuilding extends BaseEvent      );      DB::query( -      'insert into events_upgrade_building (event_id, type) VALUES (:event_id, :type)', -      ['event_id' => DB::$connection->lastInsertId(), 'type' => $this->type] +      'insert into events_upgrade_building (event_id, type, wood, clay, iron) VALUES (:event_id, :type, :wood, :clay, :iron)', +      [ +        'event_id' => DB::$connection->lastInsertId(), +        'type' => $this->type, +        'wood' => $this->wood, +        'clay' => $this->clay, +        'iron' => $this->iron, +      ]      );    } diff --git a/src/Model/Village.php b/src/Model/Village.php index ff0b7e8..8ecee2a 100644 --- a/src/Model/Village.php +++ b/src/Model/Village.php @@ -184,7 +184,7 @@ class Village     *     * @return array<int, Unit>     */ -  public static function getUnits(int $villageId, int $fetchFlag = Village::FETCH_UNIT_ALL, int $returnFlag = Village::RETURN_UNIT_EXISTING): array +  public static function getUnits(int $villageId, int $fetchFlag = Village::FETCH_UNIT_RESIDENCE, 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]); diff --git a/src/Support/BuildingType.php b/src/Support/BuildingType.php new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/Support/BuildingType.php diff --git a/src/http/Controller/Building.php b/src/http/Controller/Building.php index 4a59f0e..d434fe8 100644 --- a/src/http/Controller/Building.php +++ b/src/http/Controller/Building.php @@ -21,10 +21,7 @@ class Building      $building = Model::getByVillage($village->id, $request->get('type')) ?? Model::getEmpty($village->id, $request->get('type'));      // resources -    foreach ($building->getResourceRequirements() as $resourceType => $resourceValue) { -      $village->{$resourceType} -= $resourceValue; -    } -    $village->updateResources(); +    $resourceRequirements = $building->getResourceRequirements();      // event      $event = new Event(); @@ -35,7 +32,10 @@ class Building      $upgradeBuildingEvent = new UpgradeBuilding();      $upgradeBuildingEvent->event = $event;      $upgradeBuildingEvent->type = $building->type; -    $upgradeBuildingEvent->dbInsert(); +    $upgradeBuildingEvent->wood = $resourceRequirements['wood']; +    $upgradeBuildingEvent->clay = $resourceRequirements['clay']; +    $upgradeBuildingEvent->iron = $resourceRequirements['iron']; +    $upgradeBuildingEvent->create();      return new RedirectResponse(        Router::generate( diff --git a/src/http/Controller/Login.php b/src/http/Controller/Login.php index 8c04d85..37680a7 100644 --- a/src/http/Controller/Login.php +++ b/src/http/Controller/Login.php @@ -3,6 +3,7 @@  namespace App\http\Controller;  use App\DB; +use App\Model\Building\Farm;  use App\View;  use Symfony\Component\HttpFoundation\RedirectResponse;  use Symfony\Component\HttpFoundation\Request; @@ -26,15 +27,59 @@ class Login      if (empty($user)) {        $password = password_hash($request->get('password'), PASSWORD_DEFAULT);        DB::query('insert into users (username, password, email) values (:username, :password, :email)', ['username' => $email, 'password' => $password, 'email' => $email]); +       +      $userId = DB::$connection->lastInsertId(); -      // TODO: also insert new village at random free coordinates +      // insert new village at random free coordinates +      # TODO: check if coords are free +      DB::query( +        'insert into villages (name, x, y, wood, clay, iron, food, satisfaction) values (:name, :x, :y, 100, 100, 100, 100, 100)', +        [ +          'name' => $email, +          'x' => random_int(-10, 10), +          'y' => random_int(-10, 10), +        ] +      ); +      $villageId = DB::$connection->lastInsertId(); + +      DB::query('insert into user_villages (user_id, village_id) values (:user_id, :village_id)', [ +        'user_id' => $userId, +        'village_id' => $villageId, +      ]); + +      DB::query('insert into village_storage_config (wood, clay, iron, food, village_id) values (:wood, :clay, :iron, :food, :village_id)', [ +        'wood' => 25, +        'clay' => 25, +        'iron' => 25, +        'food' => 25, +        'village_id' => $village->id, +       ]); + +      $initialBuildings = ['TownHall', 'Storage', 'WoodCutter', 'ClayPit', 'IronMine', 'Farm']; +      foreach ($initialBuildings as $buildingType) { +         DB::query('insert into village_buildings (level, type, village_id) values (:level, :type, :village_id)', [ +          'level' => 1, +          'type' => $buildingType, +          'village_id' => $villageId, +        ]);        +      } + +      $initialUnits = ['WoodCutter', 'PitWorker', 'Miner', 'Farmer']; +      foreach ($initialUnits as $unitType) { +        DB::query('insert into village_units (amount, type, home_village_id, residence_village_id) values (:amount, :type, :village_id, :village_id)', [ +          'amount' => 1, +          'type' => $unitType, +          'village_id' => $villageId, +        ]); +      }      } else {        $password = $user['password']; +      $userId = $user['id'];      }      if (password_verify($request->get('password'), $password)) {        $_SESSION['user'] = [ -        'id' => $user['id'], +        'id' => $userId,          'username' => $user['username'],        ]; diff --git a/src/http/Controller/Map.php b/src/http/Controller/Map.php index 69d23e1..3b0773f 100644 --- a/src/http/Controller/Map.php +++ b/src/http/Controller/Map.php @@ -10,13 +10,17 @@ use Symfony\Component\Routing\Annotation\Route;  class Map  { -  #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 1], methods: ['GET'])] +  #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 0], methods: ['GET'])]    public function region(Request $request): Response    {      $x = $request->get('x');      $y = $request->get('y');      $range = $request->get('range'); +    if ($range <= 0) { +      $range = $_ENV['MAP_DEFAULT_RANGE']; +    } +      $statement = DB::query(        'select * from villages where x>=:x1 and x<=:x2 and y>=:y1 and y<=:y2',        [ diff --git a/src/http/Controller/User.php b/src/http/Controller/User.php index c47e32e..e38780f 100644 --- a/src/http/Controller/User.php +++ b/src/http/Controller/User.php @@ -21,6 +21,7 @@ class User        'user' => $user,      ]));    } +    #[Route(path: '/account', methods: ['POST'])]    public function accountSave(Request $request): Response    { diff --git a/src/http/Controller/Village.php b/src/http/Controller/Village.php index 2d6aa39..22713b1 100644 --- a/src/http/Controller/Village.php +++ b/src/http/Controller/Village.php @@ -57,26 +57,32 @@ class Village      )->fetchAll();      foreach ($eventsBuilding as $row) { -      $events['UpgradeBuilding'][$row['type']][] = DB::convertToModel(UpgradeBuilding::class, $row); +      $model = DB::convertToModel(UpgradeBuilding::class, $row); +      $model->populateEvent(); + +      $events['UpgradeBuilding'][$row['type']][] = $model;      }      $eventsUnits = DB::query(        <<<SQL        select * from events_train_units as event        left join events on event.event_id = events.id -      where village_id=:id +      where events.village_id=:id        SQL, ['id' => $village->id]      )->fetchAll();      foreach ($eventsUnits as $row) { -      $events['TrainUnits'][] = DB::convertToModel(TrainUnits::class, $row); +      $model = DB::convertToModel(TrainUnits::class, $row); +      $model->populateEvent(); + +      $events['TrainUnits'][] = $model;      }      $eventsUnitsSendOwn = DB::query(        <<<SQL        select * from events_send_units as event        left join events on event.event_id = events.id -      where village_id=:id +      where events.village_id=:id        SQL, ['id' => $village->id]      )->fetchAll(); @@ -89,14 +95,17 @@ class Village      )->fetchAll();      foreach ([...$eventsUnitsSendOwn, ...$eventsUnitsSendOther] as $row) { -      $events['SendUnits'][] = DB::convertToModel(SendUnits::class, $row);; +      $model = DB::convertToModel(SendUnits::class, $row); +      $model->populateEvent(); + +      $events['SendUnits'][] = DB::convertToModel(SendUnits::class, $row);      }      $eventsResourcesSendOwn = DB::query(        <<<SQL        select * from events_send_resources as event        left join events on event.event_id = events.id -      where village_id=:id +      where events.village_id=:id        SQL, ['id' => $village->id]      )->fetchAll(); @@ -109,14 +118,17 @@ class Village      )->fetchAll();      foreach ([...$eventsResourcesSendOwn, ...$eventsResourcesSendOther] as $row) { -      $events['SendResources'][] = DB::convertToModel(SendResources::class, $row);; +      $model = DB::convertToModel(SendResources::class, $row); +      $model->populateEvent(); + +      $events['SendResources'][] = DB::convertToModel(SendResources::class, $row);      }      $eventsResourcesCarriersSendOwn = DB::query(        <<<SQL        select * from events_send_resources_carriers as event        left join events on event.event_id = events.id -      where village_id=:id +      where events.village_id=:id        SQL, ['id' => $village->id]      )->fetchAll(); @@ -129,7 +141,10 @@ class Village      )->fetchAll();      foreach ([...$eventsResourcesCarriersSendOwn, ...$eventsResourcesCarriersSendOther] as $row) { -      $events['SendResourcesCarriers'][] = DB::convertToModel(SendResourcesCarriers::class, $row);; +      $model = DB::convertToModel(SendResourcesCarriers::class, $row); +      $model->populateEvent(); +       +      $events['SendResourcesCarriers'][] = $model;      }      $buildings = []; diff --git a/src/http/Router.php b/src/http/Router.php index 62f0514..f279109 100644 --- a/src/http/Router.php +++ b/src/http/Router.php @@ -9,7 +9,6 @@ use Symfony\Component\HttpFoundation\Response;  use Symfony\Component\Routing\Exception\MethodNotAllowedException;  use Symfony\Component\Routing\Exception\ResourceNotFoundException;  use Symfony\Component\Routing\Generator\UrlGenerator; -use Symfony\Component\Routing\Loader\AnnotationFileLoader;  use Symfony\Component\Routing\Loader\AttributeFileLoader;  use Symfony\Component\Routing\Matcher\UrlMatcher;  use Symfony\Component\Routing\RequestContext; diff --git a/views/http/map.twig b/views/http/map.twig index 29f0294..a05fea2 100644 --- a/views/http/map.twig +++ b/views/http/map.twig @@ -3,13 +3,13 @@  {% block main %}  <div class="map">    <div class="map__up"> -    <a href="/map/{{ x }}/{{ y - 1 }}"> +    <a href="/map/{{ x }}/{{ y - 1 }}/{{ range }}">        <i class="icon icon-arrow-up"></i>      </a>    </div>    <div>      <div class="map__left"> -      <a href="/map/{{ x - 1 }}/{{ y }}"> +      <a href="/map/{{ x - 1 }}/{{ y }}/{{ range }}">          <i class="icon icon-arrow-left"></i>        </a>      </div> @@ -17,7 +17,9 @@        {% for row in range(-range, range) %}          {% for column in range(-range, range) %}            {% set village = map[x + column][y + row] %} -            <div class="map__village"> +            <div class="map__village {% if row == 0 and column == 0 %}map__village--center{% endif %}"> +            <!-- TODO: add link to center on tile in top left --> +              <a class="center-anchor" title="move to center" href="/map/{{ x + column }}/{{ y + row }}/{{ range }}">c</a>              {% if village %}                <a href="/village/{{ village.x }}/{{ village.y }}">                  {{ map[x + column][y + row].name }} @@ -28,13 +30,13 @@        {% endfor %}      </div>      <div class="map__right"> -      <a href="/map/{{ x + 1 }}/{{ y }}"> +      <a href="/map/{{ x + 1 }}/{{ y }}/{{ range }}">          <i class="icon icon-arrow-right"></i>        </a>      </div>    </div>    <div class="map__down"> -    <a href="/map/{{ x }}/{{ y + 1 }}"> +    <a href="/map/{{ x }}/{{ y + 1 }}/{{ range }}">        <i class="icon icon-arrow-down"></i>      </a>    </div> diff --git a/views/http/village.twig b/views/http/village.twig index a498ea6..48bb16d 100644 --- a/views/http/village.twig +++ b/views/http/village.twig @@ -92,9 +92,11 @@            {% include 'components/timer.twig' with { 'time': event.event.time|date('c') } %}            </td>            <td> -            <a class="btn" href="/village/{{ village.x }}/{{ village.y }}/building/UpgradeBuilding/build/cancel"> -              Cancel -            </a> +            {% if event.event.villageId == village.id %} +              <form action="/event/{{ event.event.id }}/cancel" method="post"> +                <input type="submit" value="Cancel"> +              </form> +            {% endif %}            </td>          </tr>          {% endfor %} @@ -121,9 +123,11 @@            {% include 'components/timer.twig' with { 'time': event.event.time|date('c') } %}            </td>            <td> -            <a class="btn" href="/village/{{ village.x }}/{{ village.y }}/unit/train/cancel"> -              Cancel -            </a> +            {% if event.event.villageId == village.id %} +              <form action="/event/{{ event.event.id }}/cancel" method="post"> +                <input type="submit" value="Cancel"> +              </form> +            {% endif %}            </td>          </tr>          {% endfor %} | 
