summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2025-03-24 13:28:57 +0100
committerDaniel Weipert <git@mail.dweipert.de>2025-03-24 13:28:57 +0100
commita21b030abd4d5cd88f914f79574e425c7908553a (patch)
treec4eca5ff8e3dd5b12c4a151045ebb0991b211a9b
parentd58f61770463aab2c71464c11f902f0074b49b62 (diff)
various changesHEADmain
-rw-r--r--.env.example1
-rw-r--r--bin/db.php18
-rw-r--r--composer.lock236
-rw-r--r--docker-compose.yml5
-rw-r--r--public/assets/style.css44
-rw-r--r--shell.nix5
-rw-r--r--src/Model/Event/BaseEvent.php7
-rw-r--r--src/Model/Event/SendResources.php2
-rw-r--r--src/Model/Event/SendUnits.php2
-rw-r--r--src/Model/Event/TrainUnits.php2
-rw-r--r--src/Model/Event/UpgradeBuilding.php52
-rw-r--r--src/Model/Village.php2
-rw-r--r--src/Support/BuildingType.php0
-rw-r--r--src/http/Controller/Building.php10
-rw-r--r--src/http/Controller/Login.php49
-rw-r--r--src/http/Controller/Map.php6
-rw-r--r--src/http/Controller/User.php1
-rw-r--r--src/http/Controller/Village.php33
-rw-r--r--src/http/Router.php1
-rw-r--r--views/http/map.twig12
-rw-r--r--views/http/village.twig16
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
diff --git a/bin/db.php b/bin/db.php
index 66258cc..914ff5f 100644
--- a/bin/db.php
+++ b/bin/db.php
@@ -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
diff --git a/shell.nix b/shell.nix
index 358ee54..38541a9 100644
--- a/shell.nix
+++ b/shell.nix
@@ -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 %}