@civ-clone/base-city-lifecycle 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +2 -0
- package/.github/workflows/build-on-push.yml +39 -0
- package/.prettierrc +4 -0
- package/LICENSE +21 -0
- package/README.md +42 -2
- package/lib/assignWorkers.d.ts +114 -0
- package/lib/assignWorkers.js +184 -0
- package/lib/assignWorkers.js.map +1 -0
- package/lib/assignWorkers.ts +372 -0
- package/lib/canBeWorked.d.ts +28 -0
- package/lib/canBeWorked.js +27 -0
- package/lib/canBeWorked.js.map +1 -0
- package/lib/canBeWorked.ts +43 -0
- package/lib/captured.d.ts +12 -0
- package/lib/captured.js +30 -0
- package/lib/captured.js.map +1 -0
- package/lib/captured.ts +31 -0
- package/lib/claimName.d.ts +12 -0
- package/lib/claimName.js +9 -0
- package/lib/claimName.js.map +1 -0
- package/lib/claimName.ts +13 -0
- package/lib/created.d.ts +41 -0
- package/lib/created.js +52 -0
- package/lib/created.js.map +1 -0
- package/lib/created.ts +110 -0
- package/lib/destroyed.d.ts +23 -0
- package/lib/destroyed.js +29 -0
- package/lib/destroyed.js.map +1 -0
- package/lib/destroyed.ts +39 -0
- package/lib/events.d.ts +39 -0
- package/lib/events.js +33 -0
- package/lib/events.js.map +1 -0
- package/lib/events.ts +51 -0
- package/lib/famine.d.ts +41 -0
- package/lib/famine.js +44 -0
- package/lib/famine.js.map +1 -0
- package/lib/famine.ts +68 -0
- package/lib/foodStorage.d.ts +21 -0
- package/lib/foodStorage.js +27 -0
- package/lib/foodStorage.js.map +1 -0
- package/lib/foodStorage.ts +30 -0
- package/lib/occupiedTiles.d.ts +39 -0
- package/lib/occupiedTiles.js +50 -0
- package/lib/occupiedTiles.js.map +1 -0
- package/lib/occupiedTiles.ts +84 -0
- package/lib/playerActions.d.ts +72 -0
- package/lib/playerActions.js +68 -0
- package/lib/playerActions.js.map +1 -0
- package/lib/playerActions.ts +114 -0
- package/lib/processYield.d.ts +30 -0
- package/lib/processYield.js +54 -0
- package/lib/processYield.js.map +1 -0
- package/lib/processYield.ts +82 -0
- package/lib/unsupported.d.ts +6 -0
- package/lib/unsupported.js +9 -0
- package/lib/unsupported.js.map +1 -0
- package/lib/unsupported.ts +8 -0
- package/package.json +45 -4
- package/tests/base-city-lifecycle.test.ts +536 -0
- package/tests/r3b.test.ts +341 -0
- package/tsconfig.json +16 -0
package/.gitattributes
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Build and test application on push to remote
|
|
2
|
+
|
|
3
|
+
on: [push]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@v4
|
|
10
|
+
- uses: pnpm/action-setup@v4
|
|
11
|
+
with:
|
|
12
|
+
version: 11
|
|
13
|
+
- uses: actions/setup-node@v4
|
|
14
|
+
with:
|
|
15
|
+
node-version: 22
|
|
16
|
+
# No lock file, so this tests what a consumer resolves. The settings match
|
|
17
|
+
# web-renderer's pnpm-workspace.yaml: several @civ-clone packages depend on
|
|
18
|
+
# each other as `github:` URLs, this project's own releases are often only
|
|
19
|
+
# minutes old, and nothing here needs a dependency's build script.
|
|
20
|
+
- run: >-
|
|
21
|
+
pnpm install --no-frozen-lockfile
|
|
22
|
+
--config.block-exotic-subdeps=false
|
|
23
|
+
--config.minimum-release-age=0
|
|
24
|
+
--config.strict-dep-builds=false
|
|
25
|
+
- run: npm run --if-present prettier:check
|
|
26
|
+
# The tests load the committed `.js`, so compile to prove the source
|
|
27
|
+
# type-checks, and fail if the committed output is stale. `--force`
|
|
28
|
+
# because a fresh checkout's timestamps can make `tsc --build` treat the
|
|
29
|
+
# committed output as up to date and skip the compile entirely.
|
|
30
|
+
- run: npm run --if-present ts:compile -- --force
|
|
31
|
+
- run: npm run --if-present prettier:format
|
|
32
|
+
# Stale *or never committed* output fails: `git diff` alone misses a new
|
|
33
|
+
# module whose `.js` was never added, which the published package would
|
|
34
|
+
# then omit. Only the compiled extensions, so the lock file the install
|
|
35
|
+
# writes cannot fail it; `node_modules` is ignored, so it stays out.
|
|
36
|
+
- run: |
|
|
37
|
+
git status --short --untracked-files=all -- '*.js' '*.d.ts' '*.js.map'
|
|
38
|
+
test -z "$(git status --porcelain --untracked-files=all -- '*.js' '*.d.ts' '*.js.map')"
|
|
39
|
+
- run: npm run --if-present test
|
package/.prettierrc
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Dom Hastings
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
-
#
|
|
1
|
+
# base-city-lifecycle
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A city's turn and what goes with it, as a library for a ruleset's city rules:
|
|
4
|
+
|
|
5
|
+
- `lib/processYield`: `storeFood(food, city, cityGrowthRegistry)` puts a city's food for the turn into its store and
|
|
6
|
+
checks it. `buildWithProduction(production, city, cityYields, ProductionSupportType, cityBuildRegistry, ruleRegistry)`
|
|
7
|
+
puts its production into its build and checks it: while production net of unit support is below 0, the units it
|
|
8
|
+
can't support go to the `Unsupported` rules, furthest from the city first, and nothing is added while a
|
|
9
|
+
`CivilDisorder` rule holds.
|
|
10
|
+
- `lib/foodStorage`: `hasFoodToGrow(cityGrowth)` and `grow(cityGrowth)`; `isFoodExhausted(cityGrowth)` (the store is
|
|
11
|
+
below 0) and `exhaustFood(cityGrowth, ruleRegistry)`, which runs the `FoodExhausted` rules.
|
|
12
|
+
- `lib/famine`: `foodSupportedUnit(cityGrowth, FoodSupportType)`, the first unit a city feeds;
|
|
13
|
+
`emitFoodStorageExhausted(cityGrowth, unit, engine)`; `loseFoodSupportedUnit(cityGrowth, FoodSupportType)`,
|
|
14
|
+
`shrinkFromFamine(cityGrowth)` and `emptyFoodStore(cityGrowth)`.
|
|
15
|
+
- `lib/canBeWorked`: `isNotWorked(tile, workedTileRegistry)`, `isNotOccupiedByEnemy(tile, city, unitRegistry)` and
|
|
16
|
+
`isNotAnotherCity(tile, city, cityRegistry)`.
|
|
17
|
+
- `lib/occupiedTiles`: `enemyWorkedTile(unit, tile, workedTileRegistry)`, a tile another player's city works (not its
|
|
18
|
+
centre), and `releaseEnemyWorkedTile(unit, tile, workedTileRegistry, ruleRegistry)`, which takes it from that city
|
|
19
|
+
and runs its `TileReassigned` rules; `releaseOccupiedWorkedTiles(player, cityRegistry, unitRegistry,
|
|
20
|
+
workedTileRegistry, ruleRegistry)` does the same at the start of a player's turn for every tile its cities work that
|
|
21
|
+
another player's unit stands on.
|
|
22
|
+
- `lib/playerActions`: the city actions a player is offered, each as a check and a list: `hasCityToChooseProduction`
|
|
23
|
+
and `chooseProductionActions`, `hasCityToChangeProduction` and `changeProductionActions`, `hasCity` and
|
|
24
|
+
`changeWorkedTileActions`, `hasSpecialist` and `changeSpecialistActions`.
|
|
25
|
+
- `lib/unsupported`: `disbandUnsupported(city, unit)`.
|
|
26
|
+
- `lib/claimName`: `claimName(city, cityNames)` and the `CityNames` type.
|
|
27
|
+
- `lib/events`: `emitTileWorked(city, tile, engine)`, `emitTileReleased(city, tile, engine)`,
|
|
28
|
+
`emitBuildingHeld(cityBuild, item, held, engine)` and `emitBuildingComplete(cityBuild, built, engine)`, for clients.
|
|
29
|
+
- `lib/assignWorkers`: placing a city's citizens on its best tiles or as specialists (`assignWorkers`, `assignWorker`,
|
|
30
|
+
`reassignWorkers`, `releaseCitizens`, `changeWorkedTile`, `addSpecialist`, `changeSpecialist`, `citizenCount` and
|
|
31
|
+
the rest), lifted unchanged from library-city.
|
|
32
|
+
- `lib/created`: `registerCityBuild`, `registerCityGrowth` and `workCityTile(city, ...)`, which takes the new city's
|
|
33
|
+
centre from any city that worked it (running that city's `TileReassigned` rules) and puts its citizens to work.
|
|
34
|
+
- `lib/captured`: `clearCapturedBuild(cityBuild)` (the new owner chooses) and `keepCapturedBuild(cityBuild)` (the item
|
|
35
|
+
stays, repriced, without the queue).
|
|
36
|
+
- `lib/destroyed`: `destroyUnits(units)` (skipping any already destroyed), `releaseWorkedTiles(city, ...)` and
|
|
37
|
+
`releaseSpecialists(city, ...)`.
|
|
38
|
+
|
|
39
|
+
The yield types a ruleset pays unit support with are passed in (`FoodSupportType`, `ProductionSupportType`: a yield
|
|
40
|
+
that knows its `unit()`).
|
|
41
|
+
|
|
42
|
+
A library: it registers no rules. The ruleset decides the rules, their ids and order, and when each runs. See
|
|
43
|
+
`civ1-city` for Civilization's.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { AvailableSpecialistRegistry } from '@civ-clone/core-city/AvailableSpecialistRegistry';
|
|
2
|
+
import { CityGrowthRegistry } from '@civ-clone/core-city-growth/CityGrowthRegistry';
|
|
3
|
+
import { PlayerWorldRegistry } from '@civ-clone/core-player-world/PlayerWorldRegistry';
|
|
4
|
+
import { SpecialistRegistry } from '@civ-clone/core-city/SpecialistRegistry';
|
|
5
|
+
import { WorkedTileRegistry } from '@civ-clone/core-city/WorkedTileRegistry';
|
|
6
|
+
import City from '@civ-clone/core-city/City';
|
|
7
|
+
import Tile from '@civ-clone/core-world/Tile';
|
|
8
|
+
import Yield from '@civ-clone/core-yield/Yield';
|
|
9
|
+
import CityGrowth from '@civ-clone/core-city-growth/CityGrowth';
|
|
10
|
+
import Specialist from '@civ-clone/core-city/Specialist';
|
|
11
|
+
/**
|
|
12
|
+
* How many citizens `city` has placed: one per worked tile, the city centre included, and one per `Specialist`. A city
|
|
13
|
+
* of size `n` has `n + 1`.
|
|
14
|
+
*/
|
|
15
|
+
export declare const citizenCount: (
|
|
16
|
+
city: City,
|
|
17
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
18
|
+
specialistRegistry?: SpecialistRegistry
|
|
19
|
+
) => number;
|
|
20
|
+
/**
|
|
21
|
+
* Makes a citizen of `city` a `Specialist` of the first available kind (an Entertainer, in Civ1). Returns `null` when
|
|
22
|
+
* the ruleset offers no specialists.
|
|
23
|
+
*/
|
|
24
|
+
export declare const addSpecialist: (
|
|
25
|
+
city: City,
|
|
26
|
+
specialistRegistry?: SpecialistRegistry,
|
|
27
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
28
|
+
) => Specialist | null;
|
|
29
|
+
/**
|
|
30
|
+
* Turns `specialist` into the next available kind, wrapping back to the first. Returns the `Specialist` that replaces
|
|
31
|
+
* it, or `specialist` itself when there is nothing to change it to.
|
|
32
|
+
*/
|
|
33
|
+
export declare const changeSpecialist: (
|
|
34
|
+
specialist: Specialist,
|
|
35
|
+
specialistRegistry?: SpecialistRegistry,
|
|
36
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
37
|
+
) => Specialist;
|
|
38
|
+
export declare const getHighestValueCityTiles: (city: City) => Tile[];
|
|
39
|
+
export declare const sortTiles: (
|
|
40
|
+
tiles: Tile[],
|
|
41
|
+
city: City,
|
|
42
|
+
weights?: [typeof Yield, number][]
|
|
43
|
+
) => Tile[];
|
|
44
|
+
export declare const getHighestValueAvailableCityTiles: (
|
|
45
|
+
city: City,
|
|
46
|
+
playerWorldRegistry?: PlayerWorldRegistry,
|
|
47
|
+
workedTileRegistry?: WorkedTileRegistry
|
|
48
|
+
) => Tile[];
|
|
49
|
+
/**
|
|
50
|
+
* Rearranges the tiles `city` works from scratch. Its specialists stay as they are.
|
|
51
|
+
*/
|
|
52
|
+
export declare const reassignWorkers: (
|
|
53
|
+
city: City,
|
|
54
|
+
playerWorldRegistry?: PlayerWorldRegistry,
|
|
55
|
+
cityGrowthRegistry?: CityGrowthRegistry,
|
|
56
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
57
|
+
specialistRegistry?: SpecialistRegistry,
|
|
58
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
59
|
+
) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Places each of `city`'s citizens that has no job on the best tile available, or makes them a specialist if there is
|
|
62
|
+
* no tile left to work.
|
|
63
|
+
*/
|
|
64
|
+
export declare const assignWorkers: (
|
|
65
|
+
city: City,
|
|
66
|
+
playerWorldRegistry?: PlayerWorldRegistry,
|
|
67
|
+
cityGrowthRegistry?: CityGrowthRegistry,
|
|
68
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
69
|
+
specialistRegistry?: SpecialistRegistry,
|
|
70
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
71
|
+
) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Places one new citizen of `city` on the best tile available, or makes them a specialist if there is no tile left.
|
|
74
|
+
*/
|
|
75
|
+
export declare const assignWorker: (
|
|
76
|
+
city: City,
|
|
77
|
+
playerWorldRegistry?: PlayerWorldRegistry,
|
|
78
|
+
cityGrowthRegistry?: CityGrowthRegistry,
|
|
79
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
80
|
+
specialistRegistry?: SpecialistRegistry,
|
|
81
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
82
|
+
) => void;
|
|
83
|
+
export type WorkedTileChange = 'removed' | 'added' | 'reassigned' | 'none';
|
|
84
|
+
/**
|
|
85
|
+
* Changes whether `tile` is worked by `city`, as a player clicking it on the city map would.
|
|
86
|
+
*
|
|
87
|
+
* A tile the city works stops being worked, and its worker becomes a specialist. Any other tile is worked by a
|
|
88
|
+
* specialist, or by a citizen with no job, if the city has one and is allowed to work it. With every citizen already
|
|
89
|
+
* working a tile, the city's workers are reassigned instead. The city centre is always worked.
|
|
90
|
+
*/
|
|
91
|
+
export declare const changeWorkedTile: (
|
|
92
|
+
city: City,
|
|
93
|
+
tile: Tile,
|
|
94
|
+
playerWorldRegistry?: PlayerWorldRegistry,
|
|
95
|
+
cityGrowthRegistry?: CityGrowthRegistry,
|
|
96
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
97
|
+
specialistRegistry?: SpecialistRegistry,
|
|
98
|
+
availableSpecialistRegistry?: AvailableSpecialistRegistry
|
|
99
|
+
) => WorkedTileChange;
|
|
100
|
+
/**
|
|
101
|
+
* Takes jobs away from `city`'s citizens until it has no more than its size allows: specialists first, then the
|
|
102
|
+
* workers on the least valuable tiles.
|
|
103
|
+
*/
|
|
104
|
+
export declare const releaseCitizens: (
|
|
105
|
+
city: City,
|
|
106
|
+
cityGrowth: CityGrowth,
|
|
107
|
+
workedTileRegistry?: WorkedTileRegistry,
|
|
108
|
+
specialistRegistry?: SpecialistRegistry
|
|
109
|
+
) => void;
|
|
110
|
+
export declare const reduceWorkers: (
|
|
111
|
+
city: City,
|
|
112
|
+
cityGrowth: CityGrowth
|
|
113
|
+
) => Tile[];
|
|
114
|
+
export default assignWorkers;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reduceWorkers = exports.releaseCitizens = exports.changeWorkedTile = exports.assignWorker = exports.assignWorkers = exports.reassignWorkers = exports.getHighestValueAvailableCityTiles = exports.sortTiles = exports.getHighestValueCityTiles = exports.changeSpecialist = exports.addSpecialist = exports.citizenCount = void 0;
|
|
4
|
+
// Lifted from library-city 0.1.4 (`lib/assignWorkers.ts`), unchanged but for where the yields come from, so a game's
|
|
5
|
+
// rules can place a city's citizens without depending on library-city (civ-clone/web-renderer Civ2 M2a, R3b).
|
|
6
|
+
// library-city re-exports this in R3b.
|
|
7
|
+
const AvailableSpecialistRegistry_1 = require("@civ-clone/core-city/AvailableSpecialistRegistry");
|
|
8
|
+
const CityGrowthRegistry_1 = require("@civ-clone/core-city-growth/CityGrowthRegistry");
|
|
9
|
+
const Food_1 = require("@civ-clone/base-terrain-yield-food/Food");
|
|
10
|
+
const Production_1 = require("@civ-clone/base-terrain-yield-production/Production");
|
|
11
|
+
const Trade_1 = require("@civ-clone/base-terrain-yield-trade/Trade");
|
|
12
|
+
const PlayerWorldRegistry_1 = require("@civ-clone/core-player-world/PlayerWorldRegistry");
|
|
13
|
+
const SpecialistRegistry_1 = require("@civ-clone/core-city/SpecialistRegistry");
|
|
14
|
+
const WorkedTileRegistry_1 = require("@civ-clone/core-city/WorkedTileRegistry");
|
|
15
|
+
const reduceYields_1 = require("@civ-clone/core-yield/lib/reduceYields");
|
|
16
|
+
const WorkedTile_1 = require("@civ-clone/core-city/WorkedTile");
|
|
17
|
+
/**
|
|
18
|
+
* How many citizens `city` has placed: one per worked tile, the city centre included, and one per `Specialist`. A city
|
|
19
|
+
* of size `n` has `n + 1`.
|
|
20
|
+
*/
|
|
21
|
+
const citizenCount = (city, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance) => workedTileRegistry.getByCity(city).length +
|
|
22
|
+
specialistRegistry.getByCity(city).length;
|
|
23
|
+
exports.citizenCount = citizenCount;
|
|
24
|
+
/**
|
|
25
|
+
* Makes a citizen of `city` a `Specialist` of the first available kind (an Entertainer, in Civ1). Returns `null` when
|
|
26
|
+
* the ruleset offers no specialists.
|
|
27
|
+
*/
|
|
28
|
+
const addSpecialist = (city, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
29
|
+
const [SpecialistType] = availableSpecialistRegistry.entries();
|
|
30
|
+
if (!SpecialistType) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const specialist = new SpecialistType(city);
|
|
34
|
+
specialistRegistry.register(specialist);
|
|
35
|
+
return specialist;
|
|
36
|
+
};
|
|
37
|
+
exports.addSpecialist = addSpecialist;
|
|
38
|
+
/**
|
|
39
|
+
* Turns `specialist` into the next available kind, wrapping back to the first. Returns the `Specialist` that replaces
|
|
40
|
+
* it, or `specialist` itself when there is nothing to change it to.
|
|
41
|
+
*/
|
|
42
|
+
const changeSpecialist = (specialist, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
43
|
+
const city = specialist.city(), types = availableSpecialistRegistry.entries(), NextType = types[(types.indexOf(specialist.constructor) + 1) %
|
|
44
|
+
types.length];
|
|
45
|
+
if (!NextType || specialist instanceof NextType) {
|
|
46
|
+
return specialist;
|
|
47
|
+
}
|
|
48
|
+
const replacement = new NextType(city);
|
|
49
|
+
specialistRegistry.unregister(specialist);
|
|
50
|
+
specialistRegistry.register(replacement);
|
|
51
|
+
return replacement;
|
|
52
|
+
};
|
|
53
|
+
exports.changeSpecialist = changeSpecialist;
|
|
54
|
+
/**
|
|
55
|
+
* Puts one of `city`'s specialists back to work, preferring the first available kind (Entertainers), and returns
|
|
56
|
+
* whether there was one to remove.
|
|
57
|
+
*/
|
|
58
|
+
const removeSpecialist = (city, specialistRegistry, availableSpecialistRegistry) => {
|
|
59
|
+
var _a;
|
|
60
|
+
const specialists = specialistRegistry.getByCity(city), [DefaultType] = availableSpecialistRegistry.entries(), specialist = (_a = specialists.find((specialist) => DefaultType && specialist instanceof DefaultType)) !== null && _a !== void 0 ? _a : specialists[specialists.length - 1];
|
|
61
|
+
if (!specialist) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
specialistRegistry.unregister(specialist);
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
const getHighestValueCityTiles = (city) => (0, exports.sortTiles)(city.tiles().entries(), city);
|
|
68
|
+
exports.getHighestValueCityTiles = getHighestValueCityTiles;
|
|
69
|
+
const sortTiles = (tiles, city, weights = [
|
|
70
|
+
[Food_1.default, 8],
|
|
71
|
+
[
|
|
72
|
+
Production_1.default,
|
|
73
|
+
3 *
|
|
74
|
+
((0, reduceYields_1.reduceYield)(city.tilesWorked().yields(city.player()), Production_1.default) === 0
|
|
75
|
+
? 3
|
|
76
|
+
: 1),
|
|
77
|
+
],
|
|
78
|
+
[
|
|
79
|
+
Trade_1.default,
|
|
80
|
+
1 *
|
|
81
|
+
((0, reduceYields_1.reduceYield)(city.tilesWorked().yields(city.player()), Trade_1.default) === 0
|
|
82
|
+
? 2
|
|
83
|
+
: 1),
|
|
84
|
+
],
|
|
85
|
+
]) => tiles.sort((a, b) => b.score(city.player(), weights) - a.score(city.player(), weights));
|
|
86
|
+
exports.sortTiles = sortTiles;
|
|
87
|
+
const getHighestValueAvailableCityTiles = (city, playerWorldRegistry = PlayerWorldRegistry_1.instance, workedTileRegistry = WorkedTileRegistry_1.instance) => (0, exports.getHighestValueCityTiles)(city).filter((tile) => workedTileRegistry.tileCanBeWorkedBy(tile, city) &&
|
|
88
|
+
playerWorldRegistry.getByPlayer(city.player()).includes(tile));
|
|
89
|
+
exports.getHighestValueAvailableCityTiles = getHighestValueAvailableCityTiles;
|
|
90
|
+
/**
|
|
91
|
+
* Rearranges the tiles `city` works from scratch. Its specialists stay as they are.
|
|
92
|
+
*/
|
|
93
|
+
const reassignWorkers = (city, playerWorldRegistry = PlayerWorldRegistry_1.instance, cityGrowthRegistry = CityGrowthRegistry_1.instance, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
94
|
+
workedTileRegistry
|
|
95
|
+
.getBy('city', city)
|
|
96
|
+
.forEach((workedTile) => workedTileRegistry.unregister(workedTile));
|
|
97
|
+
workedTileRegistry.register(new WorkedTile_1.default(city.tile(), city));
|
|
98
|
+
(0, exports.assignWorkers)(city, playerWorldRegistry, cityGrowthRegistry, workedTileRegistry, specialistRegistry, availableSpecialistRegistry);
|
|
99
|
+
};
|
|
100
|
+
exports.reassignWorkers = reassignWorkers;
|
|
101
|
+
/**
|
|
102
|
+
* Places each of `city`'s citizens that has no job on the best tile available, or makes them a specialist if there is
|
|
103
|
+
* no tile left to work.
|
|
104
|
+
*/
|
|
105
|
+
const assignWorkers = (city, playerWorldRegistry = PlayerWorldRegistry_1.instance, cityGrowthRegistry = CityGrowthRegistry_1.instance, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
106
|
+
const cityGrowth = cityGrowthRegistry.getByCity(city), placed = () => (0, exports.citizenCount)(city, workedTileRegistry, specialistRegistry) >=
|
|
107
|
+
cityGrowth.size() + 1;
|
|
108
|
+
(0, exports.getHighestValueAvailableCityTiles)(city, playerWorldRegistry, workedTileRegistry).some((tile) => {
|
|
109
|
+
if (placed()) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
workedTileRegistry.register(new WorkedTile_1.default(tile, city));
|
|
113
|
+
return false;
|
|
114
|
+
});
|
|
115
|
+
while (!placed() &&
|
|
116
|
+
(0, exports.addSpecialist)(city, specialistRegistry, availableSpecialistRegistry)) { }
|
|
117
|
+
};
|
|
118
|
+
exports.assignWorkers = assignWorkers;
|
|
119
|
+
/**
|
|
120
|
+
* Places one new citizen of `city` on the best tile available, or makes them a specialist if there is no tile left.
|
|
121
|
+
*/
|
|
122
|
+
const assignWorker = (city, playerWorldRegistry = PlayerWorldRegistry_1.instance, cityGrowthRegistry = CityGrowthRegistry_1.instance, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
123
|
+
const [newTile] = (0, exports.getHighestValueAvailableCityTiles)(city, playerWorldRegistry, workedTileRegistry);
|
|
124
|
+
if (!newTile) {
|
|
125
|
+
(0, exports.addSpecialist)(city, specialistRegistry, availableSpecialistRegistry);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
workedTileRegistry.register(new WorkedTile_1.default(newTile, city));
|
|
129
|
+
};
|
|
130
|
+
exports.assignWorker = assignWorker;
|
|
131
|
+
/**
|
|
132
|
+
* Changes whether `tile` is worked by `city`, as a player clicking it on the city map would.
|
|
133
|
+
*
|
|
134
|
+
* A tile the city works stops being worked, and its worker becomes a specialist. Any other tile is worked by a
|
|
135
|
+
* specialist, or by a citizen with no job, if the city has one and is allowed to work it. With every citizen already
|
|
136
|
+
* working a tile, the city's workers are reassigned instead. The city centre is always worked.
|
|
137
|
+
*/
|
|
138
|
+
const changeWorkedTile = (city, tile, playerWorldRegistry = PlayerWorldRegistry_1.instance, cityGrowthRegistry = CityGrowthRegistry_1.instance, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance, availableSpecialistRegistry = AvailableSpecialistRegistry_1.instance) => {
|
|
139
|
+
var _a;
|
|
140
|
+
if (tile === city.tile() || !city.tiles().includes(tile)) {
|
|
141
|
+
return 'none';
|
|
142
|
+
}
|
|
143
|
+
if (((_a = workedTileRegistry.getByTile(tile)) === null || _a === void 0 ? void 0 : _a.city()) === city) {
|
|
144
|
+
workedTileRegistry.unregisterByTile(tile);
|
|
145
|
+
(0, exports.addSpecialist)(city, specialistRegistry, availableSpecialistRegistry);
|
|
146
|
+
return 'removed';
|
|
147
|
+
}
|
|
148
|
+
const size = cityGrowthRegistry.getByCity(city).size();
|
|
149
|
+
if (workedTileRegistry.getByCity(city).length >= size + 1) {
|
|
150
|
+
(0, exports.reassignWorkers)(city, playerWorldRegistry, cityGrowthRegistry, workedTileRegistry, specialistRegistry, availableSpecialistRegistry);
|
|
151
|
+
return 'reassigned';
|
|
152
|
+
}
|
|
153
|
+
if (!workedTileRegistry.tileCanBeWorkedBy(tile, city) ||
|
|
154
|
+
!playerWorldRegistry.getByPlayer(city.player()).includes(tile)) {
|
|
155
|
+
return 'none';
|
|
156
|
+
}
|
|
157
|
+
if ((0, exports.citizenCount)(city, workedTileRegistry, specialistRegistry) >= size + 1) {
|
|
158
|
+
removeSpecialist(city, specialistRegistry, availableSpecialistRegistry);
|
|
159
|
+
}
|
|
160
|
+
workedTileRegistry.register(new WorkedTile_1.default(tile, city));
|
|
161
|
+
return 'added';
|
|
162
|
+
};
|
|
163
|
+
exports.changeWorkedTile = changeWorkedTile;
|
|
164
|
+
/**
|
|
165
|
+
* Takes jobs away from `city`'s citizens until it has no more than its size allows: specialists first, then the
|
|
166
|
+
* workers on the least valuable tiles.
|
|
167
|
+
*/
|
|
168
|
+
const releaseCitizens = (city, cityGrowth, workedTileRegistry = WorkedTileRegistry_1.instance, specialistRegistry = SpecialistRegistry_1.instance) => {
|
|
169
|
+
const specialists = specialistRegistry.getByCity(city);
|
|
170
|
+
while (specialists.length > 0 &&
|
|
171
|
+
(0, exports.citizenCount)(city, workedTileRegistry, specialistRegistry) >
|
|
172
|
+
cityGrowth.size() + 1) {
|
|
173
|
+
specialistRegistry.unregister(specialists.pop());
|
|
174
|
+
}
|
|
175
|
+
(0, exports.reduceWorkers)(city, cityGrowth).forEach((tile) => workedTileRegistry.unregisterByTile(tile));
|
|
176
|
+
};
|
|
177
|
+
exports.releaseCitizens = releaseCitizens;
|
|
178
|
+
const reduceWorkers = (city, cityGrowth) => (0, exports.sortTiles)(city
|
|
179
|
+
.tilesWorked()
|
|
180
|
+
.entries()
|
|
181
|
+
.filter((tile) => tile !== city.tile()), city).slice(cityGrowth.size());
|
|
182
|
+
exports.reduceWorkers = reduceWorkers;
|
|
183
|
+
exports.default = exports.assignWorkers;
|
|
184
|
+
//# sourceMappingURL=assignWorkers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignWorkers.js","sourceRoot":"","sources":["assignWorkers.ts"],"names":[],"mappings":"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"}
|