@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.
Files changed (61) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/workflows/build-on-push.yml +39 -0
  3. package/.prettierrc +4 -0
  4. package/LICENSE +21 -0
  5. package/README.md +42 -2
  6. package/lib/assignWorkers.d.ts +114 -0
  7. package/lib/assignWorkers.js +184 -0
  8. package/lib/assignWorkers.js.map +1 -0
  9. package/lib/assignWorkers.ts +372 -0
  10. package/lib/canBeWorked.d.ts +28 -0
  11. package/lib/canBeWorked.js +27 -0
  12. package/lib/canBeWorked.js.map +1 -0
  13. package/lib/canBeWorked.ts +43 -0
  14. package/lib/captured.d.ts +12 -0
  15. package/lib/captured.js +30 -0
  16. package/lib/captured.js.map +1 -0
  17. package/lib/captured.ts +31 -0
  18. package/lib/claimName.d.ts +12 -0
  19. package/lib/claimName.js +9 -0
  20. package/lib/claimName.js.map +1 -0
  21. package/lib/claimName.ts +13 -0
  22. package/lib/created.d.ts +41 -0
  23. package/lib/created.js +52 -0
  24. package/lib/created.js.map +1 -0
  25. package/lib/created.ts +110 -0
  26. package/lib/destroyed.d.ts +23 -0
  27. package/lib/destroyed.js +29 -0
  28. package/lib/destroyed.js.map +1 -0
  29. package/lib/destroyed.ts +39 -0
  30. package/lib/events.d.ts +39 -0
  31. package/lib/events.js +33 -0
  32. package/lib/events.js.map +1 -0
  33. package/lib/events.ts +51 -0
  34. package/lib/famine.d.ts +41 -0
  35. package/lib/famine.js +44 -0
  36. package/lib/famine.js.map +1 -0
  37. package/lib/famine.ts +68 -0
  38. package/lib/foodStorage.d.ts +21 -0
  39. package/lib/foodStorage.js +27 -0
  40. package/lib/foodStorage.js.map +1 -0
  41. package/lib/foodStorage.ts +30 -0
  42. package/lib/occupiedTiles.d.ts +39 -0
  43. package/lib/occupiedTiles.js +50 -0
  44. package/lib/occupiedTiles.js.map +1 -0
  45. package/lib/occupiedTiles.ts +84 -0
  46. package/lib/playerActions.d.ts +72 -0
  47. package/lib/playerActions.js +68 -0
  48. package/lib/playerActions.js.map +1 -0
  49. package/lib/playerActions.ts +114 -0
  50. package/lib/processYield.d.ts +30 -0
  51. package/lib/processYield.js +54 -0
  52. package/lib/processYield.js.map +1 -0
  53. package/lib/processYield.ts +82 -0
  54. package/lib/unsupported.d.ts +6 -0
  55. package/lib/unsupported.js +9 -0
  56. package/lib/unsupported.js.map +1 -0
  57. package/lib/unsupported.ts +8 -0
  58. package/package.json +45 -4
  59. package/tests/base-city-lifecycle.test.ts +536 -0
  60. package/tests/r3b.test.ts +341 -0
  61. package/tsconfig.json +16 -0
@@ -0,0 +1,39 @@
1
+ import { CityRegistry } from '@civ-clone/core-city/CityRegistry';
2
+ import Player from '@civ-clone/core-player/Player';
3
+ import { RuleRegistry } from '@civ-clone/core-rule/RuleRegistry';
4
+ import Tile from '@civ-clone/core-world/Tile';
5
+ import Unit from '@civ-clone/core-unit/Unit';
6
+ import { UnitRegistry } from '@civ-clone/core-unit/UnitRegistry';
7
+ import WorkedTile from '@civ-clone/core-city/WorkedTile';
8
+ import { WorkedTileRegistry } from '@civ-clone/core-city/WorkedTileRegistry';
9
+ /**
10
+ * The `WorkedTile` for `tile` if a city of a player other than `unit`'s works it, other than as its centre (a city always
11
+ * works its own centre, even while a unit capturing it is moving in), or `null`.
12
+ */
13
+ export declare const enemyWorkedTile: (
14
+ unit: Unit,
15
+ tile: Tile,
16
+ workedTileRegistry: WorkedTileRegistry
17
+ ) => WorkedTile | null;
18
+ /**
19
+ * `unit` has moved onto `tile`: if another player's city works it (see `enemyWorkedTile`), the city stops working it,
20
+ * and its `TileReassigned` rules choose what it works instead. The tile is looked up again here rather than in a
21
+ * `Criterion`, because an earlier `Moved` effect (cargo moving with its transport, say) may already have released it.
22
+ */
23
+ export declare const releaseEnemyWorkedTile: (
24
+ unit: Unit,
25
+ tile: Tile,
26
+ workedTileRegistry: WorkedTileRegistry,
27
+ ruleRegistry: RuleRegistry
28
+ ) => void;
29
+ /**
30
+ * At the start of `player`'s turn, each of its cities stops working any tile (other than its centre) that another
31
+ * player's unit stands on, and its `TileReassigned` rules choose what it works instead.
32
+ */
33
+ export declare const releaseOccupiedWorkedTiles: (
34
+ player: Player,
35
+ cityRegistry: CityRegistry,
36
+ unitRegistry: UnitRegistry,
37
+ workedTileRegistry: WorkedTileRegistry,
38
+ ruleRegistry: RuleRegistry
39
+ ) => void;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.releaseOccupiedWorkedTiles = exports.releaseEnemyWorkedTile = exports.enemyWorkedTile = void 0;
4
+ const TileReassigned_1 = require("@civ-clone/core-city/Rules/TileReassigned");
5
+ /**
6
+ * The `WorkedTile` for `tile` if a city of a player other than `unit`'s works it, other than as its centre (a city always
7
+ * works its own centre, even while a unit capturing it is moving in), or `null`.
8
+ */
9
+ const enemyWorkedTile = (unit, tile, workedTileRegistry) => {
10
+ const workedTile = workedTileRegistry.getByTile(tile);
11
+ if (workedTile === null) {
12
+ return null;
13
+ }
14
+ const city = workedTile.city();
15
+ if (workedTile.tile() === city.tile() || city.player() === unit.player()) {
16
+ return null;
17
+ }
18
+ return workedTile;
19
+ };
20
+ exports.enemyWorkedTile = enemyWorkedTile;
21
+ /**
22
+ * `unit` has moved onto `tile`: if another player's city works it (see `enemyWorkedTile`), the city stops working it,
23
+ * and its `TileReassigned` rules choose what it works instead. The tile is looked up again here rather than in a
24
+ * `Criterion`, because an earlier `Moved` effect (cargo moving with its transport, say) may already have released it.
25
+ */
26
+ const releaseEnemyWorkedTile = (unit, tile, workedTileRegistry, ruleRegistry) => {
27
+ const workedTile = (0, exports.enemyWorkedTile)(unit, tile, workedTileRegistry);
28
+ if (workedTile === null) {
29
+ return;
30
+ }
31
+ workedTileRegistry.unregister(workedTile);
32
+ ruleRegistry.process(TileReassigned_1.default, workedTile.city(), tile);
33
+ };
34
+ exports.releaseEnemyWorkedTile = releaseEnemyWorkedTile;
35
+ /**
36
+ * At the start of `player`'s turn, each of its cities stops working any tile (other than its centre) that another
37
+ * player's unit stands on, and its `TileReassigned` rules choose what it works instead.
38
+ */
39
+ const releaseOccupiedWorkedTiles = (player, cityRegistry, unitRegistry, workedTileRegistry, ruleRegistry) => cityRegistry.getByPlayer(player).forEach((city) => workedTileRegistry
40
+ .getByCity(city)
41
+ .filter((workedTile) => workedTile.tile() !== city.tile() &&
42
+ unitRegistry
43
+ .getByTile(workedTile.tile())
44
+ .some((unit) => unit.player() !== player))
45
+ .forEach((workedTile) => {
46
+ workedTileRegistry.unregister(workedTile);
47
+ ruleRegistry.process(TileReassigned_1.default, city, workedTile.tile());
48
+ }));
49
+ exports.releaseOccupiedWorkedTiles = releaseOccupiedWorkedTiles;
50
+ //# sourceMappingURL=occupiedTiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"occupiedTiles.js","sourceRoot":"","sources":["occupiedTiles.ts"],"names":[],"mappings":";;;AAKA,8EAAuE;AAMvE;;;GAGG;AACI,MAAM,eAAe,GAAG,CAC7B,IAAU,EACV,IAAU,EACV,kBAAsC,EACnB,EAAE;IACrB,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEtD,IAAI,UAAU,KAAK,IAAI,EAAE;QACvB,OAAO,IAAI,CAAC;KACb;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAE/B,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;QACxE,OAAO,IAAI,CAAC;KACb;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAlBW,QAAA,eAAe,mBAkB1B;AAEF;;;;GAIG;AACI,MAAM,sBAAsB,GAAG,CACpC,IAAU,EACV,IAAU,EACV,kBAAsC,EACtC,YAA0B,EACpB,EAAE;IACR,MAAM,UAAU,GAAG,IAAA,uBAAe,EAAC,IAAI,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEnE,IAAI,UAAU,KAAK,IAAI,EAAE;QACvB,OAAO;KACR;IAED,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAE1C,YAAY,CAAC,OAAO,CAAC,wBAAc,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC,CAAC;AAfW,QAAA,sBAAsB,0BAejC;AAEF;;;GAGG;AACI,MAAM,0BAA0B,GAAG,CACxC,MAAc,EACd,YAA0B,EAC1B,YAA0B,EAC1B,kBAAsC,EACtC,YAA0B,EACpB,EAAE,CACR,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAU,EAAQ,EAAE,CAC5D,kBAAkB;KACf,SAAS,CAAC,IAAI,CAAC;KACf,MAAM,CACL,CAAC,UAAsB,EAAW,EAAE,CAClC,UAAU,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,EAAE;IACjC,YAAY;SACT,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;SAC5B,IAAI,CAAC,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC,CAC7D;KACA,OAAO,CAAC,CAAC,UAAsB,EAAQ,EAAE;IACxC,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAE1C,YAAY,CAAC,OAAO,CAAC,wBAAc,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC,CACL,CAAC;AAtBS,QAAA,0BAA0B,8BAsBnC"}
@@ -0,0 +1,84 @@
1
+ import City from '@civ-clone/core-city/City';
2
+ import { CityRegistry } from '@civ-clone/core-city/CityRegistry';
3
+ import Player from '@civ-clone/core-player/Player';
4
+ import { RuleRegistry } from '@civ-clone/core-rule/RuleRegistry';
5
+ import Tile from '@civ-clone/core-world/Tile';
6
+ import TileReassigned from '@civ-clone/core-city/Rules/TileReassigned';
7
+ import Unit from '@civ-clone/core-unit/Unit';
8
+ import { UnitRegistry } from '@civ-clone/core-unit/UnitRegistry';
9
+ import WorkedTile from '@civ-clone/core-city/WorkedTile';
10
+ import { WorkedTileRegistry } from '@civ-clone/core-city/WorkedTileRegistry';
11
+
12
+ /**
13
+ * The `WorkedTile` for `tile` if a city of a player other than `unit`'s works it, other than as its centre (a city always
14
+ * works its own centre, even while a unit capturing it is moving in), or `null`.
15
+ */
16
+ export const enemyWorkedTile = (
17
+ unit: Unit,
18
+ tile: Tile,
19
+ workedTileRegistry: WorkedTileRegistry
20
+ ): WorkedTile | null => {
21
+ const workedTile = workedTileRegistry.getByTile(tile);
22
+
23
+ if (workedTile === null) {
24
+ return null;
25
+ }
26
+
27
+ const city = workedTile.city();
28
+
29
+ if (workedTile.tile() === city.tile() || city.player() === unit.player()) {
30
+ return null;
31
+ }
32
+
33
+ return workedTile;
34
+ };
35
+
36
+ /**
37
+ * `unit` has moved onto `tile`: if another player's city works it (see `enemyWorkedTile`), the city stops working it,
38
+ * and its `TileReassigned` rules choose what it works instead. The tile is looked up again here rather than in a
39
+ * `Criterion`, because an earlier `Moved` effect (cargo moving with its transport, say) may already have released it.
40
+ */
41
+ export const releaseEnemyWorkedTile = (
42
+ unit: Unit,
43
+ tile: Tile,
44
+ workedTileRegistry: WorkedTileRegistry,
45
+ ruleRegistry: RuleRegistry
46
+ ): void => {
47
+ const workedTile = enemyWorkedTile(unit, tile, workedTileRegistry);
48
+
49
+ if (workedTile === null) {
50
+ return;
51
+ }
52
+
53
+ workedTileRegistry.unregister(workedTile);
54
+
55
+ ruleRegistry.process(TileReassigned, workedTile.city(), tile);
56
+ };
57
+
58
+ /**
59
+ * At the start of `player`'s turn, each of its cities stops working any tile (other than its centre) that another
60
+ * player's unit stands on, and its `TileReassigned` rules choose what it works instead.
61
+ */
62
+ export const releaseOccupiedWorkedTiles = (
63
+ player: Player,
64
+ cityRegistry: CityRegistry,
65
+ unitRegistry: UnitRegistry,
66
+ workedTileRegistry: WorkedTileRegistry,
67
+ ruleRegistry: RuleRegistry
68
+ ): void =>
69
+ cityRegistry.getByPlayer(player).forEach((city: City): void =>
70
+ workedTileRegistry
71
+ .getByCity(city)
72
+ .filter(
73
+ (workedTile: WorkedTile): boolean =>
74
+ workedTile.tile() !== city.tile() &&
75
+ unitRegistry
76
+ .getByTile(workedTile.tile())
77
+ .some((unit: Unit): boolean => unit.player() !== player)
78
+ )
79
+ .forEach((workedTile: WorkedTile): void => {
80
+ workedTileRegistry.unregister(workedTile);
81
+
82
+ ruleRegistry.process(TileReassigned, city, workedTile.tile());
83
+ })
84
+ );
@@ -0,0 +1,72 @@
1
+ import {
2
+ CityBuild as CityBuildAction,
3
+ ChangeProduction,
4
+ } from '@civ-clone/core-city-build/PlayerActions';
5
+ import ChangeSpecialist from '@civ-clone/core-city/PlayerActions/ChangeSpecialist';
6
+ import ChangeWorkedTile from '@civ-clone/core-city/PlayerActions/ChangeWorkedTile';
7
+ import { CityBuildRegistry } from '@civ-clone/core-city-build/CityBuildRegistry';
8
+ import { CityRegistry } from '@civ-clone/core-city/CityRegistry';
9
+ import Player from '@civ-clone/core-player/Player';
10
+ import { SpecialistRegistry } from '@civ-clone/core-city/SpecialistRegistry';
11
+ /**
12
+ * Whether one of `player`'s cities is building nothing.
13
+ */
14
+ export declare const hasCityToChooseProduction: (
15
+ player: Player,
16
+ cityRegistry: CityRegistry,
17
+ cityBuildRegistry: CityBuildRegistry
18
+ ) => boolean;
19
+ /**
20
+ * A `CityBuild` action for each of `player`'s cities that is building nothing, in the order of its cities.
21
+ */
22
+ export declare const chooseProductionActions: (
23
+ player: Player,
24
+ cityRegistry: CityRegistry,
25
+ cityBuildRegistry: CityBuildRegistry
26
+ ) => CityBuildAction[];
27
+ /**
28
+ * Whether one of `player`'s cities is building something.
29
+ */
30
+ export declare const hasCityToChangeProduction: (
31
+ player: Player,
32
+ cityRegistry: CityRegistry,
33
+ cityBuildRegistry: CityBuildRegistry
34
+ ) => boolean;
35
+ /**
36
+ * A `ChangeProduction` action for each of `player`'s cities that is building something, in the order of its cities.
37
+ */
38
+ export declare const changeProductionActions: (
39
+ player: Player,
40
+ cityRegistry: CityRegistry,
41
+ cityBuildRegistry: CityBuildRegistry
42
+ ) => ChangeProduction[];
43
+ /**
44
+ * Whether `player` has a city.
45
+ */
46
+ export declare const hasCity: (
47
+ player: Player,
48
+ cityRegistry: CityRegistry
49
+ ) => boolean;
50
+ /**
51
+ * A `ChangeWorkedTile` action for each of `player`'s cities.
52
+ */
53
+ export declare const changeWorkedTileActions: (
54
+ player: Player,
55
+ cityRegistry: CityRegistry
56
+ ) => ChangeWorkedTile[];
57
+ /**
58
+ * Whether one of `player`'s cities has a specialist.
59
+ */
60
+ export declare const hasSpecialist: (
61
+ player: Player,
62
+ cityRegistry: CityRegistry,
63
+ specialistRegistry: SpecialistRegistry
64
+ ) => boolean;
65
+ /**
66
+ * A `ChangeSpecialist` action for each specialist in each of `player`'s cities.
67
+ */
68
+ export declare const changeSpecialistActions: (
69
+ player: Player,
70
+ cityRegistry: CityRegistry,
71
+ specialistRegistry: SpecialistRegistry
72
+ ) => ChangeSpecialist[];
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.changeSpecialistActions = exports.hasSpecialist = exports.changeWorkedTileActions = exports.hasCity = exports.changeProductionActions = exports.hasCityToChangeProduction = exports.chooseProductionActions = exports.hasCityToChooseProduction = void 0;
4
+ const PlayerActions_1 = require("@civ-clone/core-city-build/PlayerActions");
5
+ const ChangeSpecialist_1 = require("@civ-clone/core-city/PlayerActions/ChangeSpecialist");
6
+ const ChangeWorkedTile_1 = require("@civ-clone/core-city/PlayerActions/ChangeWorkedTile");
7
+ /**
8
+ * Whether one of `player`'s cities is building nothing.
9
+ */
10
+ const hasCityToChooseProduction = (player, cityRegistry, cityBuildRegistry) => cityRegistry
11
+ .getByPlayer(player)
12
+ .map((city) => cityBuildRegistry.getByCity(city))
13
+ .some((cityBuild) => !cityBuild.building());
14
+ exports.hasCityToChooseProduction = hasCityToChooseProduction;
15
+ /**
16
+ * A `CityBuild` action for each of `player`'s cities that is building nothing, in the order of its cities.
17
+ */
18
+ const chooseProductionActions = (player, cityRegistry, cityBuildRegistry) => cityRegistry
19
+ .getByPlayer(player)
20
+ .map((city) => cityBuildRegistry.getByCity(city))
21
+ .filter((cityBuild) => !cityBuild.building())
22
+ .map((cityBuild) => new PlayerActions_1.CityBuild(player, cityBuild));
23
+ exports.chooseProductionActions = chooseProductionActions;
24
+ /**
25
+ * Whether one of `player`'s cities is building something.
26
+ */
27
+ const hasCityToChangeProduction = (player, cityRegistry, cityBuildRegistry) => cityRegistry
28
+ .getByPlayer(player)
29
+ .map((city) => cityBuildRegistry.getByCity(city))
30
+ .some((cityBuild) => !!cityBuild.building());
31
+ exports.hasCityToChangeProduction = hasCityToChangeProduction;
32
+ /**
33
+ * A `ChangeProduction` action for each of `player`'s cities that is building something, in the order of its cities.
34
+ */
35
+ const changeProductionActions = (player, cityRegistry, cityBuildRegistry) => cityRegistry
36
+ .getByPlayer(player)
37
+ .map((city) => cityBuildRegistry.getByCity(city))
38
+ .filter((cityBuild) => !!cityBuild.building())
39
+ .map((cityBuild) => new PlayerActions_1.ChangeProduction(player, cityBuild));
40
+ exports.changeProductionActions = changeProductionActions;
41
+ /**
42
+ * Whether `player` has a city.
43
+ */
44
+ const hasCity = (player, cityRegistry) => cityRegistry.getByPlayer(player).length > 0;
45
+ exports.hasCity = hasCity;
46
+ /**
47
+ * A `ChangeWorkedTile` action for each of `player`'s cities.
48
+ */
49
+ const changeWorkedTileActions = (player, cityRegistry) => cityRegistry
50
+ .getByPlayer(player)
51
+ .map((city) => new ChangeWorkedTile_1.default(player, city));
52
+ exports.changeWorkedTileActions = changeWorkedTileActions;
53
+ /**
54
+ * Whether one of `player`'s cities has a specialist.
55
+ */
56
+ const hasSpecialist = (player, cityRegistry, specialistRegistry) => cityRegistry
57
+ .getByPlayer(player)
58
+ .some((city) => specialistRegistry.getByCity(city).length > 0);
59
+ exports.hasSpecialist = hasSpecialist;
60
+ /**
61
+ * A `ChangeSpecialist` action for each specialist in each of `player`'s cities.
62
+ */
63
+ const changeSpecialistActions = (player, cityRegistry, specialistRegistry) => cityRegistry
64
+ .getByPlayer(player)
65
+ .flatMap((city) => specialistRegistry.getByCity(city))
66
+ .map((specialist) => new ChangeSpecialist_1.default(player, specialist));
67
+ exports.changeSpecialistActions = changeSpecialistActions;
68
+ //# sourceMappingURL=playerActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playerActions.js","sourceRoot":"","sources":["playerActions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import {
2
+ CityBuild as CityBuildAction,
3
+ ChangeProduction,
4
+ } from '@civ-clone/core-city-build/PlayerActions';
5
+ import ChangeSpecialist from '@civ-clone/core-city/PlayerActions/ChangeSpecialist';
6
+ import ChangeWorkedTile from '@civ-clone/core-city/PlayerActions/ChangeWorkedTile';
7
+ import City from '@civ-clone/core-city/City';
8
+ import CityBuild from '@civ-clone/core-city-build/CityBuild';
9
+ import { CityBuildRegistry } from '@civ-clone/core-city-build/CityBuildRegistry';
10
+ import { CityRegistry } from '@civ-clone/core-city/CityRegistry';
11
+ import Player from '@civ-clone/core-player/Player';
12
+ import { SpecialistRegistry } from '@civ-clone/core-city/SpecialistRegistry';
13
+
14
+ /**
15
+ * Whether one of `player`'s cities is building nothing.
16
+ */
17
+ export const hasCityToChooseProduction = (
18
+ player: Player,
19
+ cityRegistry: CityRegistry,
20
+ cityBuildRegistry: CityBuildRegistry
21
+ ): boolean =>
22
+ cityRegistry
23
+ .getByPlayer(player)
24
+ .map((city: City): CityBuild => cityBuildRegistry.getByCity(city))
25
+ .some((cityBuild: CityBuild): boolean => !cityBuild.building());
26
+
27
+ /**
28
+ * A `CityBuild` action for each of `player`'s cities that is building nothing, in the order of its cities.
29
+ */
30
+ export const chooseProductionActions = (
31
+ player: Player,
32
+ cityRegistry: CityRegistry,
33
+ cityBuildRegistry: CityBuildRegistry
34
+ ): CityBuildAction[] =>
35
+ cityRegistry
36
+ .getByPlayer(player)
37
+ .map((city: City): CityBuild => cityBuildRegistry.getByCity(city))
38
+ .filter((cityBuild: CityBuild): boolean => !cityBuild.building())
39
+ .map(
40
+ (cityBuild: CityBuild): CityBuildAction =>
41
+ new CityBuildAction(player, cityBuild)
42
+ );
43
+
44
+ /**
45
+ * Whether one of `player`'s cities is building something.
46
+ */
47
+ export const hasCityToChangeProduction = (
48
+ player: Player,
49
+ cityRegistry: CityRegistry,
50
+ cityBuildRegistry: CityBuildRegistry
51
+ ): boolean =>
52
+ cityRegistry
53
+ .getByPlayer(player)
54
+ .map((city: City): CityBuild => cityBuildRegistry.getByCity(city))
55
+ .some((cityBuild: CityBuild): boolean => !!cityBuild.building());
56
+
57
+ /**
58
+ * A `ChangeProduction` action for each of `player`'s cities that is building something, in the order of its cities.
59
+ */
60
+ export const changeProductionActions = (
61
+ player: Player,
62
+ cityRegistry: CityRegistry,
63
+ cityBuildRegistry: CityBuildRegistry
64
+ ): ChangeProduction[] =>
65
+ cityRegistry
66
+ .getByPlayer(player)
67
+ .map((city: City): CityBuild => cityBuildRegistry.getByCity(city))
68
+ .filter((cityBuild: CityBuild): boolean => !!cityBuild.building())
69
+ .map(
70
+ (cityBuild: CityBuild): ChangeProduction =>
71
+ new ChangeProduction(player, cityBuild)
72
+ );
73
+
74
+ /**
75
+ * Whether `player` has a city.
76
+ */
77
+ export const hasCity = (player: Player, cityRegistry: CityRegistry): boolean =>
78
+ cityRegistry.getByPlayer(player).length > 0;
79
+
80
+ /**
81
+ * A `ChangeWorkedTile` action for each of `player`'s cities.
82
+ */
83
+ export const changeWorkedTileActions = (
84
+ player: Player,
85
+ cityRegistry: CityRegistry
86
+ ): ChangeWorkedTile[] =>
87
+ cityRegistry
88
+ .getByPlayer(player)
89
+ .map((city: City): ChangeWorkedTile => new ChangeWorkedTile(player, city));
90
+
91
+ /**
92
+ * Whether one of `player`'s cities has a specialist.
93
+ */
94
+ export const hasSpecialist = (
95
+ player: Player,
96
+ cityRegistry: CityRegistry,
97
+ specialistRegistry: SpecialistRegistry
98
+ ): boolean =>
99
+ cityRegistry
100
+ .getByPlayer(player)
101
+ .some((city: City) => specialistRegistry.getByCity(city).length > 0);
102
+
103
+ /**
104
+ * A `ChangeSpecialist` action for each specialist in each of `player`'s cities.
105
+ */
106
+ export const changeSpecialistActions = (
107
+ player: Player,
108
+ cityRegistry: CityRegistry,
109
+ specialistRegistry: SpecialistRegistry
110
+ ): ChangeSpecialist[] =>
111
+ cityRegistry
112
+ .getByPlayer(player)
113
+ .flatMap((city: City) => specialistRegistry.getByCity(city))
114
+ .map((specialist) => new ChangeSpecialist(player, specialist));
@@ -0,0 +1,30 @@
1
+ import City from '@civ-clone/core-city/City';
2
+ import { CityBuildRegistry } from '@civ-clone/core-city-build/CityBuildRegistry';
3
+ import { CityGrowthRegistry } from '@civ-clone/core-city-growth/CityGrowthRegistry';
4
+ import { RuleRegistry } from '@civ-clone/core-rule/RuleRegistry';
5
+ import { UnitYieldType } from './famine';
6
+ import Yield from '@civ-clone/core-yield/Yield';
7
+ /**
8
+ * A city's food for the turn, net of what its citizens and units eat, goes into its food store, and the store is checked:
9
+ * its `FoodStorage` rules decide whether the city grows or its food has run out.
10
+ */
11
+ export declare const storeFood: (
12
+ food: Yield,
13
+ city: City,
14
+ cityGrowthRegistry: CityGrowthRegistry
15
+ ) => void;
16
+ /**
17
+ * A city's production for the turn goes into what it is building, and the build is checked.
18
+ *
19
+ * While the production, net of its units' support, is below 0, the units it can't support go, furthest from the city
20
+ * first: each is handed to the `Unsupported` rules, and its support (a `ProductionSupportType` yield) is given back.
21
+ * Nothing is added to the build while a `CivilDisorder` rule holds for the city.
22
+ */
23
+ export declare const buildWithProduction: (
24
+ production: Yield,
25
+ city: City,
26
+ cityYields: Yield[],
27
+ ProductionSupportType: UnitYieldType,
28
+ cityBuildRegistry: CityBuildRegistry,
29
+ ruleRegistry: RuleRegistry
30
+ ) => void;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildWithProduction = exports.storeFood = void 0;
4
+ const CivilDisorder_1 = require("@civ-clone/core-city-happiness/Rules/CivilDisorder");
5
+ const FoodStorage_1 = require("@civ-clone/core-city-growth/Yields/FoodStorage");
6
+ const Unsupported_1 = require("@civ-clone/core-unit/Rules/Unsupported");
7
+ /**
8
+ * A city's food for the turn, net of what its citizens and units eat, goes into its food store, and the store is checked:
9
+ * its `FoodStorage` rules decide whether the city grows or its food has run out.
10
+ */
11
+ const storeFood = (food, city, cityGrowthRegistry) => {
12
+ const cityGrowth = cityGrowthRegistry.getByCity(city);
13
+ cityGrowth.add(new FoodStorage_1.default(food));
14
+ cityGrowth.check();
15
+ };
16
+ exports.storeFood = storeFood;
17
+ /**
18
+ * A city's production for the turn goes into what it is building, and the build is checked.
19
+ *
20
+ * While the production, net of its units' support, is below 0, the units it can't support go, furthest from the city
21
+ * first: each is handed to the `Unsupported` rules, and its support (a `ProductionSupportType` yield) is given back.
22
+ * Nothing is added to the build while a `CivilDisorder` rule holds for the city.
23
+ */
24
+ const buildWithProduction = (production, city, cityYields, ProductionSupportType, cityBuildRegistry, ruleRegistry) => {
25
+ const cityBuild = cityBuildRegistry.getByCity(city), availableProduction = production.clone();
26
+ cityYields
27
+ .filter((cityYield) => cityYield instanceof ProductionSupportType)
28
+ .sort((yieldA, yieldB) => {
29
+ var _a, _b, _c, _d;
30
+ return ((_b = (_a = yieldB.unit()) === null || _a === void 0 ? void 0 : _a.tile().distanceFrom(city.tile())) !== null && _b !== void 0 ? _b : 0) -
31
+ ((_d = (_c = yieldA.unit()) === null || _c === void 0 ? void 0 : _c.tile().distanceFrom(city.tile())) !== null && _d !== void 0 ? _d : 0);
32
+ })
33
+ .forEach((cityYield) => {
34
+ if (availableProduction.value() >= 0) {
35
+ return;
36
+ }
37
+ const unit = cityYield.unit();
38
+ if (unit === null) {
39
+ return;
40
+ }
41
+ ruleRegistry.process(Unsupported_1.default, city, unit, cityYield);
42
+ availableProduction.subtract(cityYield);
43
+ });
44
+ const updatedCityYields = city.yields();
45
+ // No production happens when there's civil disorder.
46
+ if (!ruleRegistry
47
+ .process(CivilDisorder_1.default, city, updatedCityYields)
48
+ .some((result) => result)) {
49
+ cityBuild.add(availableProduction);
50
+ }
51
+ cityBuild.check();
52
+ };
53
+ exports.buildWithProduction = buildWithProduction;
54
+ //# sourceMappingURL=processYield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processYield.js","sourceRoot":"","sources":["processYield.ts"],"names":[],"mappings":";;;AAGA,sFAA+E;AAC/E,gFAAyE;AAGzE,wEAAiE;AAGjE;;;GAGG;AACI,MAAM,SAAS,GAAG,CACvB,IAAW,EACX,IAAU,EACV,kBAAsC,EAChC,EAAE;IACR,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEtD,UAAU,CAAC,GAAG,CAAC,IAAI,qBAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,UAAU,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC,CAAC;AATW,QAAA,SAAS,aASpB;AAEF;;;;;;GAMG;AACI,MAAM,mBAAmB,GAAG,CACjC,UAAiB,EACjB,IAAU,EACV,UAAmB,EACnB,qBAAoC,EACpC,iBAAoC,EACpC,YAA0B,EACpB,EAAE;IACR,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,EACjD,mBAAmB,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;IAE1C,UAAsD;SACpD,MAAM,CACL,CAAC,SAAS,EAA4C,EAAE,CACtD,SAAS,YAAY,qBAAqB,CAC7C;SACA,IAAI,CACH,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;;QACjB,OAAA,CAAC,MAAA,MAAA,MAAM,CAAC,IAAI,EAAE,0CAAE,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,mCAAI,CAAC,CAAC;YACtD,CAAC,MAAA,MAAA,MAAM,CAAC,IAAI,EAAE,0CAAE,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,mCAAI,CAAC,CAAC,CAAA;KAAA,CACzD;SACA,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QACrB,IAAI,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;YACpC,OAAO;SACR;QAED,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;QAE9B,IAAI,IAAI,KAAK,IAAI,EAAE;YACjB,OAAO;SACR;QAED,YAAY,CAAC,OAAO,CAAC,qBAAW,EAAE,IAAI,EAAE,IAAI,EAAE,SAAkB,CAAC,CAAC;QAElE,mBAAmB,CAAC,QAAQ,CAAC,SAAkB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEL,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAExC,qDAAqD;IACrD,IACE,CAAC,YAAY;SACV,OAAO,CAAC,uBAAa,EAAE,IAAI,EAAE,iBAAiB,CAAC;SAC/C,IAAI,CAAC,CAAC,MAAe,EAAW,EAAE,CAAC,MAAM,CAAC,EAC7C;QACA,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;KACpC;IAED,SAAS,CAAC,KAAK,EAAE,CAAC;AACpB,CAAC,CAAC;AAjDW,QAAA,mBAAmB,uBAiD9B"}
@@ -0,0 +1,82 @@
1
+ import City from '@civ-clone/core-city/City';
2
+ import { CityBuildRegistry } from '@civ-clone/core-city-build/CityBuildRegistry';
3
+ import { CityGrowthRegistry } from '@civ-clone/core-city-growth/CityGrowthRegistry';
4
+ import CivilDisorder from '@civ-clone/core-city-happiness/Rules/CivilDisorder';
5
+ import FoodStorage from '@civ-clone/core-city-growth/Yields/FoodStorage';
6
+ import { RuleRegistry } from '@civ-clone/core-rule/RuleRegistry';
7
+ import { UnitYieldType } from './famine';
8
+ import Unsupported from '@civ-clone/core-unit/Rules/Unsupported';
9
+ import Yield from '@civ-clone/core-yield/Yield';
10
+
11
+ /**
12
+ * A city's food for the turn, net of what its citizens and units eat, goes into its food store, and the store is checked:
13
+ * its `FoodStorage` rules decide whether the city grows or its food has run out.
14
+ */
15
+ export const storeFood = (
16
+ food: Yield,
17
+ city: City,
18
+ cityGrowthRegistry: CityGrowthRegistry
19
+ ): void => {
20
+ const cityGrowth = cityGrowthRegistry.getByCity(city);
21
+
22
+ cityGrowth.add(new FoodStorage(food));
23
+ cityGrowth.check();
24
+ };
25
+
26
+ /**
27
+ * A city's production for the turn goes into what it is building, and the build is checked.
28
+ *
29
+ * While the production, net of its units' support, is below 0, the units it can't support go, furthest from the city
30
+ * first: each is handed to the `Unsupported` rules, and its support (a `ProductionSupportType` yield) is given back.
31
+ * Nothing is added to the build while a `CivilDisorder` rule holds for the city.
32
+ */
33
+ export const buildWithProduction = (
34
+ production: Yield,
35
+ city: City,
36
+ cityYields: Yield[],
37
+ ProductionSupportType: UnitYieldType,
38
+ cityBuildRegistry: CityBuildRegistry,
39
+ ruleRegistry: RuleRegistry
40
+ ): void => {
41
+ const cityBuild = cityBuildRegistry.getByCity(city),
42
+ availableProduction = production.clone();
43
+
44
+ (cityYields as (Yield | InstanceType<UnitYieldType>)[])
45
+ .filter(
46
+ (cityYield): cityYield is InstanceType<UnitYieldType> =>
47
+ cityYield instanceof ProductionSupportType
48
+ )
49
+ .sort(
50
+ (yieldA, yieldB) =>
51
+ (yieldB.unit()?.tile().distanceFrom(city.tile()) ?? 0) -
52
+ (yieldA.unit()?.tile().distanceFrom(city.tile()) ?? 0)
53
+ )
54
+ .forEach((cityYield) => {
55
+ if (availableProduction.value() >= 0) {
56
+ return;
57
+ }
58
+
59
+ const unit = cityYield.unit();
60
+
61
+ if (unit === null) {
62
+ return;
63
+ }
64
+
65
+ ruleRegistry.process(Unsupported, city, unit, cityYield as Yield);
66
+
67
+ availableProduction.subtract(cityYield as Yield);
68
+ });
69
+
70
+ const updatedCityYields = city.yields();
71
+
72
+ // No production happens when there's civil disorder.
73
+ if (
74
+ !ruleRegistry
75
+ .process(CivilDisorder, city, updatedCityYields)
76
+ .some((result: boolean): boolean => result)
77
+ ) {
78
+ cityBuild.add(availableProduction);
79
+ }
80
+
81
+ cityBuild.check();
82
+ };
@@ -0,0 +1,6 @@
1
+ import City from '@civ-clone/core-city/City';
2
+ import Unit from '@civ-clone/core-unit/Unit';
3
+ /**
4
+ * A unit `city` can no longer support is lost.
5
+ */
6
+ export declare const disbandUnsupported: (city: City, unit: Unit) => void;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.disbandUnsupported = void 0;
4
+ /**
5
+ * A unit `city` can no longer support is lost.
6
+ */
7
+ const disbandUnsupported = (city, unit) => unit.destroy();
8
+ exports.disbandUnsupported = disbandUnsupported;
9
+ //# sourceMappingURL=unsupported.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsupported.js","sourceRoot":"","sources":["unsupported.ts"],"names":[],"mappings":";;;AAGA;;GAEG;AACI,MAAM,kBAAkB,GAAG,CAAC,IAAU,EAAE,IAAU,EAAQ,EAAE,CACjE,IAAI,CAAC,OAAO,EAAE,CAAC;AADJ,QAAA,kBAAkB,sBACd"}
@@ -0,0 +1,8 @@
1
+ import City from '@civ-clone/core-city/City';
2
+ import Unit from '@civ-clone/core-unit/Unit';
3
+
4
+ /**
5
+ * A unit `city` can no longer support is lost.
6
+ */
7
+ export const disbandUnsupported = (city: City, unit: Unit): void =>
8
+ unit.destroy();